[PATCH 16/20] drm/amd/display: Handle Content protection property changes

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to manage the content protection property changes for
different usecase, once cp is DESIRED we need to maintain the
ENABLED/DESIRED status for different cases.

[How]
1. Attach the content_protection property

2. HDCP enable (UNDESIRED -> DESIRED)
call into the module with the correct parameters to start
hdcp. Set cp to ENABLED

3. HDCP disable (ENABLED -> UNDESIRED)
Call the module to disable hdcp.

3. Handle Special cases (Hotplug, S3, headless S3, DPMS)
If already ENABLED: set to DESIRED on unplug/suspend/dpms,
and disable hdcp

Then on plugin/resume/dpms: enable HDCP

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 2cc95ab0b645..591b8ab9d4ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -68,6 +68,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
@@ -1466,6 +1467,11 @@ amdgpu_dm_update_connector_after_detect(struct 
amdgpu_dm_connector *aconnector)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
aconnector->edid = NULL;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   /* Set CP to DESIRED if it was ENABLED, so we can re-enable it 
again on hotplug */
+   if (connector->state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   connector->state->content_protection = 
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+#endif
}
 
mutex_unlock(&dev->mode_config.mutex);
@@ -1480,6 +1486,9 @@ static void handle_hpd_irq(void *param)
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
enum dc_connection_type new_connection_type = dc_connection_none;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct amdgpu_device *adev = dev->dev_private;
+#endif
 
/*
 * In case of failure or MST no need to update connector status or 
notify the OS
@@ -1487,6 +1496,9 @@ static void handle_hpd_irq(void *param)
 */
mutex_lock(&aconnector->hpd_lock);
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
+#endif
if (aconnector->fake_enable)
aconnector->fake_enable = false;
 
@@ -5075,6 +5087,9 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
adev->mode_info.freesync_property, 0);
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.freesync_capable_property, 0);
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   
drm_connector_attach_content_protection_property(&aconnector->base, false);
+#endif
}
 }
 
@@ -5317,6 +5332,63 @@ is_scaling_state_different(const struct 
dm_connector_state *dm_state,
return false;
 }
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+static bool is_content_protection_different(struct drm_connector_state *state,
+   const struct drm_connector_state 
*old_state,
+   const struct drm_connector 
*connector, struct hdcp_workqueue *hdcp_w)
+{
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+
+   /* CP is being re enabled, ignore this */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
+   }
+
+   /* S3 resume case, since old state will always be 0 (UNDESIRED) and the 
restored state will be ENABLED */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /* Check if something is connected/enabled, otherwise we start hdcp but 
nothing is connected/enabled
+* hot-plug, headless s3, dpms
+*/
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && 
connector->dpms == DRM_MODE_DPMS_ON &&
+   aconnector->dc_sink != NULL)
+   return true;
+
+   if (old_state->content_protection == state->content_protection)
+   return false;
+
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   return true;
+
+   return false;
+}
+
+static void update_content_protection(struct drm_connector_state

[PATCH 16/20] drm/amd/display: Handle Content protection property changes

2019-09-10 Thread Bhawanpreet Lakha
[Why]
We need to manage the content protection property changes for
different usecase, once cp is DESIRED we need to maintain the
ENABLED/DESIRED status for different cases.

[How]
1. Attach the content_protection property

2. HDCP enable (UNDESIRED -> DESIRED)
call into the module with the correct parameters to start
hdcp. Set cp to ENABLED

3. HDCP disable (ENABLED -> UNDESIRED)
Call the module to disable hdcp.

3. Handle Special cases (Hotplug, S3, headless S3, DPMS)
If already ENABLED: set to DESIRED on unplug/suspend/dpms,
and disable hdcp

Then on plugin/resume/dpms: enable HDCP

Signed-off-by: Bhawanpreet Lakha 
Reviewed-by: Harry Wentland 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 2cc95ab0b645..591b8ab9d4ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -68,6 +68,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
@@ -1466,6 +1467,11 @@ amdgpu_dm_update_connector_after_detect(struct 
amdgpu_dm_connector *aconnector)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
aconnector->edid = NULL;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   /* Set CP to DESIRED if it was ENABLED, so we can re-enable it 
again on hotplug */
+   if (connector->state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   connector->state->content_protection = 
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+#endif
}
 
mutex_unlock(&dev->mode_config.mutex);
@@ -1480,6 +1486,9 @@ static void handle_hpd_irq(void *param)
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
enum dc_connection_type new_connection_type = dc_connection_none;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct amdgpu_device *adev = dev->dev_private;
+#endif
 
/*
 * In case of failure or MST no need to update connector status or 
notify the OS
@@ -1487,6 +1496,9 @@ static void handle_hpd_irq(void *param)
 */
mutex_lock(&aconnector->hpd_lock);
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
+#endif
if (aconnector->fake_enable)
aconnector->fake_enable = false;
 
@@ -5075,6 +5087,9 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
adev->mode_info.freesync_property, 0);
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.freesync_capable_property, 0);
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   
drm_connector_attach_content_protection_property(&aconnector->base, false);
+#endif
}
 }
 
@@ -5317,6 +5332,63 @@ is_scaling_state_different(const struct 
dm_connector_state *dm_state,
return false;
 }
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+static bool is_content_protection_different(struct drm_connector_state *state,
+   const struct drm_connector_state 
*old_state,
+   const struct drm_connector 
*connector, struct hdcp_workqueue *hdcp_w)
+{
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+
+   /* CP is being re enabled, ignore this */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
+   }
+
+   /* S3 resume case, since old state will always be 0 (UNDESIRED) and the 
restored state will be ENABLED */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /* Check if something is connected/enabled, otherwise we start hdcp but 
nothing is connected/enabled
+* hot-plug, headless s3, dpms
+*/
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && 
connector->dpms == DRM_MODE_DPMS_ON &&
+   aconnector->dc_sink != NULL)
+   return true;
+
+   if (old_state->content_protection == state->content_protection)
+   return false;
+
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   return true;
+
+   return false;
+}
+
+static void update_content_protection(struct drm_connector_state

[PATCH 16/20] drm/amd/display: Handle Content protection property changes

2019-08-29 Thread Bhawanpreet Lakha
[Why]
We need to manage the content protection property changes for
different usecase, once cp is DESIRED we need to maintain the
ENABLED/DESIRED status for different cases.

[How]
1. Attach the content_protection property

2. HDCP enable (UNDESIRED -> DESIRED)
call into the module with the correct parameters to start
hdcp. Set cp to ENABLED

3. HDCP disable (ENABLED -> UNDESIRED)
Call the module to disable hdcp.

3. Handle Special cases (Hotplug, S3, headless S3, DPMS)
If already ENABLED: set to DESIRED on unplug/suspend/dpms,
and disable hdcp

Then on plugin/resume/dpms: enable HDCP

Signed-off-by: Bhawanpreet Lakha 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++
 1 file changed, 96 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index bac9cf5be473..b9281e77752f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -68,6 +68,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
@@ -1465,6 +1466,11 @@ amdgpu_dm_update_connector_after_detect(struct 
amdgpu_dm_connector *aconnector)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
aconnector->edid = NULL;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   /* Set CP to DESIRED if it was ENABLED, so we can re-enable it 
again on hotplug */
+   if (connector->state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   connector->state->content_protection = 
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+#endif
}
 
mutex_unlock(&dev->mode_config.mutex);
@@ -1479,6 +1485,9 @@ static void handle_hpd_irq(void *param)
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
enum dc_connection_type new_connection_type = dc_connection_none;
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   struct amdgpu_device *adev = dev->dev_private;
+#endif
 
/*
 * In case of failure or MST no need to update connector status or 
notify the OS
@@ -1486,6 +1495,9 @@ static void handle_hpd_irq(void *param)
 */
mutex_lock(&aconnector->hpd_lock);
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   hdcp_reset_display(adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index);
+#endif
if (aconnector->fake_enable)
aconnector->fake_enable = false;
 
@@ -5058,6 +5070,9 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
adev->mode_info.freesync_property, 0);
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.freesync_capable_property, 0);
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+   
drm_connector_attach_content_protection_property(&aconnector->base, false);
+#endif
}
 }
 
@@ -5300,6 +5315,63 @@ is_scaling_state_different(const struct 
dm_connector_state *dm_state,
return false;
 }
 
+#ifdef CONFIG_DRM_AMD_DC_HDCP
+static bool is_content_protection_different(struct drm_connector_state *state,
+   const struct drm_connector_state 
*old_state,
+   const struct drm_connector 
*connector, struct hdcp_workqueue *hdcp_w)
+{
+   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+
+   /* CP is being re enabled, ignore this */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
+   }
+
+   /* S3 resume case, since old state will always be 0 (UNDESIRED) and the 
restored state will be ENABLED */
+   if (old_state->content_protection == 
DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+   state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /* Check if something is connected/enabled, otherwise we start hdcp but 
nothing is connected/enabled
+* hot-plug, headless s3, dpms
+*/
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && 
connector->dpms == DRM_MODE_DPMS_ON &&
+   aconnector->dc_sink != NULL)
+   return true;
+
+   if (old_state->content_protection == state->content_protection)
+   return false;
+
+   if (state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   return true;
+
+   return false;
+}
+
+static void update_content_protection(struct drm_connector_state *state, const 
struct drm_co