Re: [Intel-gfx] [PATCH] drm/i915/tgl: Set drm_crtc_state.active=false for all added disconnected CRTCs sharing MST stream.

2020-10-21 Thread Mark Yacoub
On Tue, Oct 20, 2020 at 8:54 PM Almahallawy, Khaled
 wrote:
>
> On Wed, 2020-10-21 at 00:29 +, Souza, Jose wrote:
> > On Tue, 2020-10-20 at 16:25 -0700, José Roberto de Souza wrote:
> > > On Tue, 2020-10-20 at 15:41 +0300, Ville Syrjälä wrote:
> > > > On Tue, Oct 20, 2020 at 12:45:55AM -0700, Khaled Almahallawy
> > > > wrote:
> > > > > This patch avoids failing atomic commits sent by user space by
> > > > > making sure CRTC/Connector added to drm_atomic_state by the
> > > > > driver are in valid state.
> > > > >
> > > > > When disconnecting MST hub with two or more connected displays.
> > > > > The user space sends IOCTL for each MST pipe to disable.
> > > > > drm_atomic_state object sent from user space contains only the
> > > > > state of the crtc/pipe intended to disable.
> > > > > In TGL, intel_dp_mst_atomic_master_trans_check will add all
> > > > > other CRTC and connectors that share the MST stream to
> > > > > drm_atomic_state:
> > > > >
> > > > > drm_atomic_commit
> > > > >drm_atomic_helper_check_modeset
> > > > >update_connector_routing
> > > > >intel_dp_mst_atomic_check = funcs-
> > > > > >atomic_check(connector, state);
> > > > >   intel_dp_mst_atomic_master_trans_check
> > > > > intel_atomic_get_digital_connector_state
> > > > > drm_atomic_get_connector_state   <-- Add all Connectors
> > > > > drm_atomic_get_crtc_state <-- Add all CRTCs
> > > > >update_connector_routing <-- Check added Connector/CRTCs
> > > > > - Will fail
> > > > >
> > > > > However the added crtc/connector pair will be in invalid state
> > > > > (enabled state for a removed connector)
> > > > > triggering this condition in
> > > > > drm_atomic_helper.c/update_connector_routing:
> > > > >
> > > > > if (!state->duplicated &&
> > > > > drm_connector_is_unregistered(connector) &&
> > > > > crtc_state->active) {
> > > > > DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] is not registered\n",
> > > > >  connector->base.id, connector->name);
> > > > > return -EINVAL;
> > > > > }
> > > >
> > > > Yeah, I think that "reject modeset on unregistered connectors"
> > > > idea is
> > > > a bit broken given how the uapi has worked in the past. Cc:ing
> > > > danvet
> > > > and lyude who IIRC were involved with that.
> > > >
>
> Actually by removing this condition everything works fine as well.
> However we were worried about touching this part and screwing other
> stuff :-)
>
> > > > Hmm. Maybe we could add the other stuff to the state only after
> > > > the
> > > > connector .atomic_check() stuff has been done? I don't quite
> > > > remember
> > > > why we decided to do it here. José do you recall the details?
> > >
> > > Because the connector check function runs twice in
> > > drm_atomic_helper_check_modeset(), in the first iteration it will
> > > add all connectors that share the
> > > same MST stream to state, the second one will make sure all other
> > > checks passed in all connectors of the MST stream.
> > >
> > > To me looks like the Chrome userspace is not doing the right thing,
> > > it is sending asynchronous atomic commits with conflicting state
> > > between each
> > > commit.
> >
> > Oh it do not have information about other connectors so not
> > conflicting but anyways userspace should retry atomic commits
> > anyways.
> >
>
> CC: Mark and Gill for Chrome userspace input
>
> Yes Chrome is sending the atomic commits with correct states one after
> another. Matter of fact, the failure we observe in Chrome is also
> happening in Ubuntu.
>
> We checked that by printing the drm_atomic_state sent by user space
> before atomic check:
>
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1365,9 +1365,12 @@ int drm_atomic_commit(struct drm_atomic_state
> *state)
> struct drm_mode_config *config = >dev->mode_config;
> int ret;
>
> +   drm_atomic_print_state(state);
> ret = drm_atomic_check_only(state);
>
>
> Using MST with two displays and eDP connected. First MST on Pipe B and
> Second MST on Pipe C.
>
> Chrome send atomic commit to disable Pipe B first as below:
>
> [   60.406455] [drm:drm_atomic_print_state] checking c0e0cc6c
> [   60.406455] i915 :00:02.0: [drm] crtc[152]: pipe B
> [   60.406456] i915 :00:02.0: [drm] enable=0
> [   60.406457] i915 :00:02.0: [drm] active=0
> [   60.406458] i915 :00:02.0: [drm] self_refresh_active=0
> [   60.406459] i915 :00:02.0: [drm] planes_changed=0
> [   60.406460] i915 :00:02.0: [drm] mode_changed=0
> [   60.406461] i915 :00:02.0: [drm] active_changed=0
> [   60.406462] i915 :00:02.0: [drm] connectors_changed=0
> [   60.406463] i915 :00:02.0: [drm] color_mgmt_changed=0
> [   60.406464] i915 :00:02.0: [drm] plane_mask=100
> [   60.406465] i915 :00:02.0: [drm] connector_mask=0
> [   60.406466] i915 :00:02.0: [drm] encoder_mask=2000
> [   60.406467] i915 :00:02.0: [drm] mode: "": 0 0 0 0 0 0 

Re: [Intel-gfx] [PATCH i-g-t] tests/kms_dp_dsc: Avoid SIGSEGV when release DRM connector.

2021-06-07 Thread Mark Yacoub
On Fri, Jun 4, 2021 at 2:48 PM Mark Yacoub  wrote:
>
> On Mon, May 31, 2021 at 11:34 AM Lee Shawn C  wrote:
> >
> > Got SIGSEGV fault while running kms_dp_dsc test but did not
> > connect DP DSC capable monitor on eDP/DP port. This test daemon
> > should "SKIP" test without any problem. We found kms_dp_dsc
> > can't get proper drmModeConnector and caused this SIGSEGV fault
> > when release it. Make sure drmModeConnector is available before
> > free it can avoid this issue.
> >
> Tested on ChromeOS on TGL (Delbin) and JSL (Drawlat).
Tested on ChromeOS AMD (Zork) with Kernel 5.4
> Tested-by: Mark Yacoub 
> > Signed-off-by: Lee Shawn C 
> > ---
> >  tests/kms_dp_dsc.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/tests/kms_dp_dsc.c b/tests/kms_dp_dsc.c
> > index 2446fd82bba3..ea7c9f4f72ce 100644
> > --- a/tests/kms_dp_dsc.c
> > +++ b/tests/kms_dp_dsc.c
> > @@ -262,7 +262,7 @@ igt_main
> > data_t data = {};
> > igt_output_t *output;
> > drmModeRes *res;
> > -   drmModeConnector *connector;
> > +   drmModeConnector *connector = NULL;
> > int i, test_conn_cnt, test_cnt;
> > int tests[] = {DRM_MODE_CONNECTOR_eDP, 
> > DRM_MODE_CONNECTOR_DisplayPort};
> >
> > @@ -311,7 +311,8 @@ igt_main
> > }
> >
> > igt_fixture {
> > -   drmModeFreeConnector(connector);
> > +   if (connector)
> > +   drmModeFreeConnector(connector);
> > drmModeFreeResources(res);
> > close(data.debugfs_fd);
> > close(data.drm_fd);
> > --
> > 2.17.1
> >
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] tests/kms_color: Remove gamma code from degamma tests

2021-06-04 Thread Mark Yacoub
On Thu, Jun 3, 2021 at 1:04 PM Vidya Srinivas  wrote:
>
> CRC should be collected without degamma transformation
> and after drawing gradient with degamma LUT.
> This patch removes things which are not related to degamma
> and makes it similar to pipe gamma test.
>
Tested on ChromeOS on TGL (Delbin) and JSL (Drawlat)
Tested-by: Mark Yacoub 
> Signed-off-by: Vidya Srinivas 
> ---
>  tests/kms_color.c | 16 ++--
>  1 file changed, 6 insertions(+), 10 deletions(-)
>
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index 3a42532a5c27..2c9821cdecce 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -31,8 +31,7 @@ static void test_pipe_degamma(data_t *data,
>  {
> igt_output_t *output;
> igt_display_t *display = >display;
> -   gamma_lut_t *degamma_linear, *degamma_full;
> -   gamma_lut_t *gamma_linear;
> +   gamma_lut_t *degamma_full;
> color_t red_green_blue[] = {
> { 1.0, 0.0, 0.0 },
> { 0.0, 1.0, 0.0 },
> @@ -42,11 +41,8 @@ static void test_pipe_degamma(data_t *data,
> igt_require(igt_pipe_obj_has_prop(primary->pipe, 
> IGT_CRTC_DEGAMMA_LUT));
> igt_require(igt_pipe_obj_has_prop(primary->pipe, IGT_CRTC_GAMMA_LUT));
>
> -   degamma_linear = generate_table(data->degamma_lut_size, 1.0);
> degamma_full = generate_table_max(data->degamma_lut_size);
>
> -   gamma_linear = generate_table(data->gamma_lut_size, 1.0);
> -
> for_each_valid_output_on_pipe(>display, primary->pipe->pipe, 
> output) {
> drmModeModeInfo *mode;
> struct igt_fb fb_modeset, fb;
> @@ -75,8 +71,7 @@ static void test_pipe_degamma(data_t *data,
>
> igt_plane_set_fb(primary, _modeset);
> disable_ctm(primary->pipe);
> -   disable_degamma(primary->pipe);
> -   set_gamma(data, primary->pipe, gamma_linear);
> +   set_degamma(data, primary->pipe, degamma_full);
> igt_display_commit(>display);
>
> /* Draw solid colors with no degamma transformation. */
> @@ -92,7 +87,6 @@ static void test_pipe_degamma(data_t *data,
>  */
> paint_gradient_rectangles(data, mode, red_green_blue, );
> igt_plane_set_fb(primary, );
> -   set_degamma(data, primary->pipe, degamma_full);
> igt_display_commit(>display);
> igt_wait_for_vblank(data->drm_fd,
> 
> display->pipes[primary->pipe->pipe].crtc_offset);
> @@ -105,13 +99,13 @@ static void test_pipe_degamma(data_t *data,
>
> igt_plane_set_fb(primary, NULL);
> igt_output_set_pipe(output, PIPE_NONE);
> +   igt_display_commit2(>display, data->display.is_atomic ?
> +   COMMIT_ATOMIC : 
> COMMIT_LEGACY);
> igt_remove_fb(data->drm_fd, );
> igt_remove_fb(data->drm_fd, _modeset);
> }
>
> -   free_lut(degamma_linear);
> free_lut(degamma_full);
> -   free_lut(gamma_linear);
>  }
>
>  /*
> @@ -191,6 +185,8 @@ static void test_pipe_gamma(data_t *data,
>
> igt_plane_set_fb(primary, NULL);
> igt_output_set_pipe(output, PIPE_NONE);
> +   igt_display_commit2(>display, data->display.is_atomic ?
> +   COMMIT_ATOMIC : 
> COMMIT_LEGACY);
> igt_remove_fb(data->drm_fd, );
> igt_remove_fb(data->drm_fd, _modeset);
> }
> --
> 2.7.4
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [PATCH i-g-t] [RFC] tests/kms_plane_alpha_blend: Fix coverage-vs-premult-vs-constant tests

2021-06-04 Thread Mark Yacoub
On Tue, Jun 1, 2021 at 7:54 AM Vidya Srinivas  wrote:
>
> Few Gen11 systems show CRC mismatch. Make coverage-vs-premult-vs-constant
> code similar to constant_alpha_min or basic_alpha
>
Tested on ChromeOS on JSL (Drawlat)
Tested-by: Mark Yacoub 
> Signed-off-by: Vidya Srinivas 
> ---
>  tests/kms_plane_alpha_blend.c | 4 
>  1 file changed, 4 deletions(-)
>
> diff --git a/tests/kms_plane_alpha_blend.c b/tests/kms_plane_alpha_blend.c
> index a37cb27c7d62..224d79bd1749 100644
> --- a/tests/kms_plane_alpha_blend.c
> +++ b/tests/kms_plane_alpha_blend.c
> @@ -447,10 +447,6 @@ static void coverage_premult_constant(data_t *data, enum 
> pipe pipe, igt_plane_t
> igt_display_t *display = >display;
> igt_crc_t ref_crc = {}, crc = {};
>
> -   /* Set a background color on the primary fb for testing */
> -   if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> -   
> igt_plane_set_fb(igt_pipe_get_plane_type(>pipes[pipe], 
> DRM_PLANE_TYPE_PRIMARY), >gray_fb);
> -
> igt_plane_set_prop_enum(plane, IGT_PLANE_PIXEL_BLEND_MODE, 
> "Coverage");
> igt_plane_set_fb(plane, >argb_fb_cov_7e);
> igt_display_commit2(display, COMMIT_ATOMIC);
> --
> 2.7.4
>
> ___
> igt-dev mailing list
> igt-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] [RFC] tests/drm_read: Fix subtest invalid-buffer

2021-06-04 Thread Mark Yacoub
On Fri, May 28, 2021 at 12:41 AM Vidya Srinivas
 wrote:
>
> Using (void *)-1 directly in read is aborting on chrome systems.
> Following message is seen.
>
> Starting subtest: invalid-buffer
> *** buffer overflow detected ***: terminated
> Received signal SIGABRT.
> Stack trace:
> Aborted (core dumped)
>
> Patch just adds a pointer variable and uses it in read.
>
Tested on ChromeOS on TGL (Delbin) and JSL (Drawlat)
Tested-by: Mark Yacoub 
> Signed-off-by: Vidya Srinivas 
> ---
>  tests/drm_read.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/tests/drm_read.c b/tests/drm_read.c
> index ccf9d822fd8d..2fdec5be4078 100644
> --- a/tests/drm_read.c
> +++ b/tests/drm_read.c
> @@ -103,10 +103,11 @@ static void teardown(int fd)
>  static void test_invalid_buffer(int in)
>  {
> int fd = setup(in, 0);
> +   void *add = (void *)-1;
>
> alarm(1);
>
> -   igt_assert_eq(read(fd, (void *)-1, 4096), -1);
> +   igt_assert_eq(read(fd, add, 4096), -1);
> igt_assert_eq(errno, EFAULT);
>
> teardown(fd);
> --
> 2.7.4
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] [RFC] tests/kms_flip.c: Fix subtests flip-vs-suspend

2021-06-04 Thread Mark Yacoub
Tested it on ChromeOS and it runs well. But I think we should fix the
root cause instead.

On Fri, May 28, 2021 at 12:33 AM Vidya Srinivas
 wrote:
>
> Some Intel Gen11 systems are not able to do a RTC wake.
> Instead change the default SUSPEND_TEST_NONE to
> SUSPEND_TEST_PLATFORM.
>
Tested on ChromeOS on TGL (Delbin) and JSL (Drawlat)
Tested-by: Mark Yacoub 
> Signed-off-by: Vidya Srinivas 
> ---
>  tests/kms_flip.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/tests/kms_flip.c b/tests/kms_flip.c
> index 8f736652be90..8afac88c9b15 100755
> --- a/tests/kms_flip.c
> +++ b/tests/kms_flip.c
> @@ -835,7 +835,8 @@ static bool run_test_step(struct test_output *o, unsigned 
> int *events)
>
> if (o->flags & TEST_SUSPEND)
> igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
> - SUSPEND_TEST_NONE);
> + is_i915_device(drm_fd)?
> + 
> SUSPEND_TEST_PLATFORM:SUSPEND_TEST_NONE);
>
> if (do_vblank && (o->flags & TEST_EINVAL) && o->vblank_state.count > 
> 0)
> igt_assert(do_wait_for_vblank(o, o->pipe, target_seq, 
> _reply)
> --
> 2.7.4
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] tests/kms_dp_dsc: Transmit correct DRM connector structure.

2021-06-04 Thread Mark Yacoub
On Mon, May 31, 2021 at 11:36 PM Lee Shawn C  wrote:
>
> 1. Pass one more parameter (current drmModeConnector) when
>call "run_test()". Use it to retrieve proper connector_type.
> 2. SIGSEGV fault would happen due to "igt_output" did not
>store properly in "data->output". Main funciton already
>pass "igt_output" pointer into "run_test()" function.
>Use this pointer instead of "data->output" to get display mode.
>
> Fixes: a1772be7dede ("tests/kms_dp_dsc: Bug fix for DP on Pipe A")
>
Tested on ChromeOS on TGL (Delbin) and JSL (Drawlat)
Tested-by: Mark Yacoub 
> Signed-off-by: Lee Shawn C 
> ---
>  tests/kms_dp_dsc.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/tests/kms_dp_dsc.c b/tests/kms_dp_dsc.c
> index ea7c9f4f72ce..e434384da369 100644
> --- a/tests/kms_dp_dsc.c
> +++ b/tests/kms_dp_dsc.c
> @@ -224,11 +224,11 @@ static void update_display(data_t *data, enum 
> dsc_test_type test_type)
>  }
>
>  static void run_test(data_t *data, igt_output_t *output,
> -enum dsc_test_type test_type)
> +drmModeConnector *connector, enum dsc_test_type 
> test_type)
>  {
> enum pipe pipe;
>
> -   data->mode = igt_output_get_mode(data->output);
> +   data->mode = igt_output_get_mode(output);
> igt_create_pattern_fb(data->drm_fd, data->mode->hdisplay,
>   data->mode->vdisplay,
>   DRM_FORMAT_XRGB,
> @@ -239,7 +239,7 @@ static void run_test(data_t *data, igt_output_t *output,
> if (is_i915_device(data->drm_fd)) {
> uint32_t devid = intel_get_drm_devid(data->drm_fd);
>
> -   if (data->connector->connector_type == 
> DRM_MODE_CONNECTOR_DisplayPort &&
> +   if (connector->connector_type == 
> DRM_MODE_CONNECTOR_DisplayPort &&
> data->pipe == PIPE_A && IS_GEN11(devid)) {
> igt_debug("DSC not supported on Pipe A on 
> external DP in Gen11 platforms\n");
> continue;
> @@ -304,7 +304,7 @@ igt_main
> continue;
> }
> test_conn_cnt++;
> -   run_test(, output, 
> test_basic_dsc_enable);
> +   run_test(, output, connector, 
> test_basic_dsc_enable);
> }
> igt_skip_on(test_conn_cnt == 0);
> }
> --
> 2.17.1
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] tests/kms_dp_dsc: Avoid SIGSEGV when release DRM connector.

2021-06-04 Thread Mark Yacoub
On Mon, May 31, 2021 at 11:34 AM Lee Shawn C  wrote:
>
> Got SIGSEGV fault while running kms_dp_dsc test but did not
> connect DP DSC capable monitor on eDP/DP port. This test daemon
> should "SKIP" test without any problem. We found kms_dp_dsc
> can't get proper drmModeConnector and caused this SIGSEGV fault
> when release it. Make sure drmModeConnector is available before
> free it can avoid this issue.
>
Tested on ChromeOS on TGL (Delbin) and JSL (Drawlat).
Tested-by: Mark Yacoub 
> Signed-off-by: Lee Shawn C 
> ---
>  tests/kms_dp_dsc.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/tests/kms_dp_dsc.c b/tests/kms_dp_dsc.c
> index 2446fd82bba3..ea7c9f4f72ce 100644
> --- a/tests/kms_dp_dsc.c
> +++ b/tests/kms_dp_dsc.c
> @@ -262,7 +262,7 @@ igt_main
> data_t data = {};
> igt_output_t *output;
> drmModeRes *res;
> -   drmModeConnector *connector;
> +   drmModeConnector *connector = NULL;
> int i, test_conn_cnt, test_cnt;
> int tests[] = {DRM_MODE_CONNECTOR_eDP, 
> DRM_MODE_CONNECTOR_DisplayPort};
>
> @@ -311,7 +311,8 @@ igt_main
> }
>
> igt_fixture {
> -   drmModeFreeConnector(connector);
> +   if (connector)
> +   drmModeFreeConnector(connector);
> drmModeFreeResources(res);
> close(data.debugfs_fd);
> close(data.drm_fd);
> --
> 2.17.1
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH i-g-t] [RFC] tests/kms_big_fb: Wait for vblank before collecting CRC

2021-06-04 Thread Mark Yacoub
On Fri, May 28, 2021 at 12:36 AM Vidya Srinivas
 wrote:
>
> Without wait for vblank, CRC mismatch is seen
> between big and small CRC on few Gen11 systems.
>
Tested on ChromeOS on JSL (Drawlat).
Tested-by: Mark Yacoub 
> Signed-off-by: Vidya Srinivas 
> ---
>  tests/kms_big_fb.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/tests/kms_big_fb.c b/tests/kms_big_fb.c
> index b35727a09bd0..f90363c3beb2 100644
> --- a/tests/kms_big_fb.c
> +++ b/tests/kms_big_fb.c
> @@ -254,6 +254,7 @@ static void unset_lut(data_t *data)
>  static bool test_plane(data_t *data)
>  {
> igt_plane_t *plane = data->plane;
> +   igt_display_t *display = >display;
> struct igt_fb *small_fb = >small_fb;
> struct igt_fb *big_fb = >big_fb;
> int w = data->big_fb_width - small_fb->width;
> @@ -337,16 +338,17 @@ static bool test_plane(data_t *data)
> igt_display_commit2(>display, data->display.is_atomic ?
> COMMIT_ATOMIC : COMMIT_UNIVERSAL);
>
> -
> +   igt_wait_for_vblank(data->drm_fd, 
> display->pipes[data->pipe].crtc_offset);
> igt_pipe_crc_collect_crc(data->pipe_crc, _crc);
>
> igt_plane_set_fb(plane, big_fb);
> igt_fb_set_position(big_fb, plane, x, y);
> igt_fb_set_size(big_fb, plane, small_fb->width, 
> small_fb->height);
> +
> igt_plane_set_size(plane, data->width, data->height);
> igt_display_commit2(>display, data->display.is_atomic ?
> COMMIT_ATOMIC : COMMIT_UNIVERSAL);
> -
> +   igt_wait_for_vblank(data->drm_fd, 
> display->pipes[data->pipe].crtc_offset);
> igt_pipe_crc_collect_crc(data->pipe_crc, _crc);
>
> igt_plane_set_fb(plane, NULL);
> --
> 2.7.4
>
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [igt-dev] [PATCH i-g-t] [RFC] tests/kms_prime: Aligned pitch to 64 byte for Intel platforms

2021-06-04 Thread Mark Yacoub
On Mon, May 31, 2021 at 10:47 AM Srinivas, Vidya
 wrote:
>
> Hello Ville,
>
> Thank you very much.
> Before reaching our i915's i915_gem_dumb_create, it goes to 
> vgem_gem_dumb_create for kms_prime.
>
> The pitch gets calculated there and it is not 64 byte aligned. Due to this, 
> intel_framebuffer_init reports "pitch must be 64 byte aligned"
> and framebuffer creation fails. I tried submitting vgem patch where 64 byte 
> alignment can be done in vgem_gem_dumb_create and that also
> passes. But we did not get approval yet as few of them felt, vgem is generic 
> and other platforms might fail if we do 64 byte alignment there.
>
> Kindly suggest. Thanks a lot.
>
> Regards
> Vidya
>
> -Original Message-
> From: Ville Syrjälä 
> Sent: Monday, May 31, 2021 7:48 PM
> To: Srinivas, Vidya 
> Cc: intel-gfx@lists.freedesktop.org; igt-...@lists.freedesktop.org; Lin, 
> Charlton 
> Subject: Re: [igt-dev] [PATCH i-g-t] [RFC] tests/kms_prime: Aligned pitch to 
> 64 byte for Intel platforms
>
> On Fri, May 28, 2021 at 10:04:03AM +0530, Vidya Srinivas wrote:
> > For Intel platforms, pitch needs to be 64 byte aligned.
> > Kernel code vgem_gem_dumb_create which is platform generic code doesnt
> > do the alignment. This causes frame buffer creation to fail on Intel
> > platforms where the pitch is not 64 byte aligned.
> >
> > tests: test run on Intel platforms with panel resolution 1366x768
> >
Tested on ChromeOS on JSL (Drawlat).
Tested-by: Mark Yacoub 
> > Signed-off-by: Vidya Srinivas 
> > ---
> >  tests/kms_prime.c | 5 -
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/kms_prime.c b/tests/kms_prime.c index
> > 8cb2ca2a9dc3..fdc941fe8100 100644
> > --- a/tests/kms_prime.c
> > +++ b/tests/kms_prime.c
> > @@ -51,6 +51,8 @@ static struct {
> >   { .r = 1.0, .g = 0.0, .b = 0.0, .color = 0x },  };
> >
> > +bool check_platform;
I think we can do a more precise name to indicate which platform.
Something like is_intel_device or is_i915 would be more appropriate.
alternatively, we can drop the boolean and just do the check when needed.
So it would look something like
+ is_i915_device(fd) ? ALIGN(scratch->width, 64) : scratch->width,

> > +
> >  IGT_TEST_DESCRIPTION("Prime tests, focusing on KMS side");
> >
> >  static bool has_prime_import(int fd)
> > @@ -101,7 +103,7 @@ static void prepare_scratch(int exporter_fd, struct 
> > dumb_bo *scratch,
> >   scratch->bpp = 32;
> >
> >   scratch->handle = kmstest_dumb_create(exporter_fd,
> > - scratch->width,
> > + check_platform? ALIGN(scratch->width, 64): 
> > scratch->width,
>
> The dumb_create ioctl already does this for us.
>
> >   scratch->height,
> >   scratch->bpp,
> >   >pitch,
> > @@ -262,6 +264,7 @@ igt_main
> >
> >   /* ANY = anything that is not VGEM */
> >   first_fd = __drm_open_driver_another(0, DRIVER_ANY | 
> > DRIVER_VGEM);
> > + check_platform = is_i915_device(first_fd);
> >   igt_require(first_fd >= 0);
> >
> >   second_fd = __drm_open_driver_another(1, DRIVER_ANY | 
> > DRIVER_VGEM);
> > --
> > 2.7.4
> >
> > ___
> > igt-dev mailing list
> > igt-...@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/igt-dev
>
> --
> Ville Syrjälä
> Intel
> ___
> igt-dev mailing list
> igt-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/2] amd/amdgpu_dm: Verify Gamma and Degamma LUT sizes using DRM Core check

2021-10-13 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
drm_atomic_helper_check_crtc now verifies both legacy and non-legacy LUT
sizes. There is no need to check it within amdgpu_dm_atomic_check.

[How]
Remove the local call to verify LUT sizes and use DRM Core function
instead.

Tested on ChromeOS Zork.

v1:
Remove amdgpu_dm_verify_lut_sizes everywhere.

Signed-off-by: Mark Yacoub 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  8 ++---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 -
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 35 ---
 3 files changed, 4 insertions(+), 40 deletions(-)

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 f74663b6b046e..47f8de1cfc3a5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10244,6 +10244,10 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
}
}
 #endif
+   ret = drm_atomic_helper_check_crtcs(state);
+   if (ret)
+   return ret;
+
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 
@@ -10253,10 +10257,6 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
dm_old_crtc_state->dsc_force_changed == false)
continue;
 
-   ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
-   if (ret)
-   goto fail;
-
if (!new_crtc_state->enable)
continue;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index fcb9c4a629c32..22730e5542092 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -617,7 +617,6 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
 
 void amdgpu_dm_init_color_mod(void);
-int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
  struct dc_plane_state *dc_plane_state);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a022e5bb30a5c..319f8a8a89835 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -284,37 +284,6 @@ static int __set_input_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
-/**
- * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of
- * the expected size.
- * Returns 0 on success.
- */
-int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
-{
-   const struct drm_color_lut *lut = NULL;
-   uint32_t size = 0;
-
-   lut = __extract_blob_lut(crtc_state->degamma_lut, );
-   if (lut && size != MAX_COLOR_LUT_ENTRIES) {
-   DRM_DEBUG_DRIVER(
-   "Invalid Degamma LUT size. Should be %u but got %u.\n",
-   MAX_COLOR_LUT_ENTRIES, size);
-   return -EINVAL;
-   }
-
-   lut = __extract_blob_lut(crtc_state->gamma_lut, );
-   if (lut && size != MAX_COLOR_LUT_ENTRIES &&
-   size != MAX_COLOR_LEGACY_LUT_ENTRIES) {
-   DRM_DEBUG_DRIVER(
-   "Invalid Gamma LUT size. Should be %u (or %u for 
legacy) but got %u.\n",
-   MAX_COLOR_LUT_ENTRIES, MAX_COLOR_LEGACY_LUT_ENTRIES,
-   size);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 /**
  * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
  * @crtc: amdgpu_dm crtc state
@@ -348,10 +317,6 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
bool is_legacy;
int r;
 
-   r = amdgpu_dm_verify_lut_sizes(>base);
-   if (r)
-   return r;
-
degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, _size);
regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, _size);
 
-- 
2.33.0.882.g93a45727a2-goog



[Intel-gfx] [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-13 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
or Degamma props in the new CRTC state, allowing any invalid size to
be passed on.
2. Each driver has its own LUT size, which could also be different for
legacy users.

[How]
1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
assigned by the driver when it's initializing its color and CTM
management.
2. Create drm_atomic_helper_check_crtc which is called by
drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
they match the sizes in the new CRTC state.
3. Rename older lut checks that test for the color channels to indicate
it's a channel check. It's not included in drm_atomic_helper_check_crtc
as it's hardware specific and is to be called by the driver.
4. As the LUT size check now happens in drm_atomic_helper_check, remove
the lut check in intel_color.c

Fixes: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
Tested on Zork(amdgpu) and Jacuzzi(mediatek), volteer(TGL)

v1:
1. Fix typos
2. Remove the LUT size check from intel driver
3. Rename old LUT check to indicate it's a channel change

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_atomic_helper.c| 60 ++
 drivers/gpu/drm/drm_color_mgmt.c   | 14 ++---
 drivers/gpu/drm/i915/display/intel_color.c | 14 ++---
 include/drm/drm_atomic_helper.h|  1 +
 include/drm/drm_color_mgmt.h   |  7 +--
 include/drm/drm_crtc.h | 11 
 6 files changed, 89 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index bc3487964fb5e..5feb2ad0209c3 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -929,6 +929,62 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_helper_check_planes);
 
+/**
+ * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
+ * @state: the driver state object
+ *
+ * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the new
+ * state holds them.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->gamma_lut) {
+   uint64_t supported_lut_size = crtc->gamma_lut_size;
+   uint32_t supported_legacy_lut_size = crtc->gamma_size;
+   uint32_t new_state_lut_size =
+   drm_color_lut_size(new_crtc_state->gamma_lut);
+
+   if (new_state_lut_size != supported_lut_size &&
+   new_state_lut_size != supported_legacy_lut_size) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Gamma LUT size. Should be %u 
(or %u for legacy) but got %u.\n",
+   supported_lut_size,
+   supported_legacy_lut_size,
+   new_state_lut_size);
+   return -EINVAL;
+   }
+   }
+
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->degamma_lut) {
+   uint32_t new_state_lut_size =
+   drm_color_lut_size(new_crtc_state->degamma_lut);
+   uint64_t supported_lut_size = crtc->degamma_lut_size;
+
+   if (new_state_lut_size != supported_lut_size) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Degamma LUT size. Should be %u 
but got %u.\n",
+   supported_lut_size, new_state_lut_size);
+   return -EINVAL;
+   }
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_crtcs);
+
 /**
  * drm_atomic_helper_check - validate state object
  * @dev: DRM device
@@ -974,6 +1030,10 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
 
+   ret = drm_atomic_helper_check_crtcs(state);
+   if (ret)
+   return ret;
+
if (state->legacy_cursor_update)
state->async_update = !drm_atomic_helper_async_check(dev, 
state);
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index bb14f488c8f6c..e5b820ce823bf 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/

Re: [Intel-gfx] [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-26 Thread Mark Yacoub
On Tue, Oct 26, 2021 at 8:02 AM Paul Menzel  wrote:
>
> Dear Mark,
>
>
> Thank you for your patch.
>
> On 13.10.21 20:12, Mark Yacoub wrote:
> > From: Mark Yacoub 
> >
> > [Why]
> > 1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
> > or Degamma props in the new CRTC state, allowing any invalid size to
> > be passed on.
> > 2. Each driver has its own LUT size, which could also be different for
> > legacy users.
>
> How can the problem be reproduced?
It was caught using igt@kms_color@pipe-A-invalid-gamma-lut-sizes.
it validates that drivers will only LUTs of their expected size not
any random (smaller or larger) number.
>
> > [How]
> > 1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
> > assigned by the driver when it's initializing its color and CTM
> > management.
> > 2. Create drm_atomic_helper_check_crtc which is called by
> > drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
> > they match the sizes in the new CRTC state.
> > 3. Rename older lut checks that test for the color channels to indicate
> > it's a channel check. It's not included in drm_atomic_helper_check_crtc
> > as it's hardware specific and is to be called by the driver.
> > 4. As the LUT size check now happens in drm_atomic_helper_check, remove
> > the lut check in intel_color.c
> >
> > Fixes: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
>
> If I am not mistaken, the Fixes tag is used for commits I believe. Maybe
> use Resolves or something similar?
fixed!
>
> > Tested on Zork(amdgpu) and Jacuzzi(mediatek), volteer(TGL)
>
> Please add a space before the (.
>
> How did you test this?
smoke test on both MTK and TGL devices along with running
igt@kms_color on both devices.
>
> > v1:
> > 1. Fix typos
> > 2. Remove the LUT size check from intel driver
> > 3. Rename old LUT check to indicate it's a channel change
> >
> > Signed-off-by: Mark Yacoub 
> > ---
> >   drivers/gpu/drm/drm_atomic_helper.c| 60 ++
> >   drivers/gpu/drm/drm_color_mgmt.c   | 14 ++---
> >   drivers/gpu/drm/i915/display/intel_color.c | 14 ++---
> >   include/drm/drm_atomic_helper.h|  1 +
> >   include/drm/drm_color_mgmt.h   |  7 +--
> >   include/drm/drm_crtc.h | 11 
> >   6 files changed, 89 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index bc3487964fb5e..5feb2ad0209c3 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -929,6 +929,62 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
> >   }
> >   EXPORT_SYMBOL(drm_atomic_helper_check_planes);
> >
> > +/**
> > + * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
> > + * @state: the driver state object
> > + *
> > + * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the 
> > new
> > + * state holds them.
> > + *
> > + * RETURNS:
> > + * Zero for success or -errno
> > + */
> > +int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
> > +{
> > + struct drm_crtc *crtc;
> > + struct drm_crtc_state *new_crtc_state;
> > + int i;
> > +
> > + for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
> > + if (new_crtc_state->color_mgmt_changed &&
> > + new_crtc_state->gamma_lut) {
> > + uint64_t supported_lut_size = crtc->gamma_lut_size;
> > + uint32_t supported_legacy_lut_size = crtc->gamma_size;
> > + uint32_t new_state_lut_size =
> > + drm_color_lut_size(new_crtc_state->gamma_lut);
> > +
> > + if (new_state_lut_size != supported_lut_size &&
> > + new_state_lut_size != supported_legacy_lut_size) {
> > + drm_dbg_state(
> > + state->dev,
> > + "Invalid Gamma LUT size. Should be %u 
> > (or %u for legacy) but got %u.\n",
> > + supported_lut_size,
> > + supported_legacy_lut_size,
> > + new_state_lut_size);
> > + return -EINVAL;
> > + }
> > +   

Re: [Intel-gfx] [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-26 Thread Mark Yacoub
new patch: https://patchwork.freedesktop.org/series/96314/

On Tue, Oct 26, 2021 at 3:24 PM Mark Yacoub  wrote:
>
> On Tue, Oct 26, 2021 at 8:02 AM Paul Menzel  wrote:
> >
> > Dear Mark,
> >
> >
> > Thank you for your patch.
> >
> > On 13.10.21 20:12, Mark Yacoub wrote:
> > > From: Mark Yacoub 
> > >
> > > [Why]
> > > 1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
> > > or Degamma props in the new CRTC state, allowing any invalid size to
> > > be passed on.
> > > 2. Each driver has its own LUT size, which could also be different for
> > > legacy users.
> >
> > How can the problem be reproduced?
> It was caught using igt@kms_color@pipe-A-invalid-gamma-lut-sizes.
> it validates that drivers will only LUTs of their expected size not
> any random (smaller or larger) number.
> >
> > > [How]
> > > 1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
> > > assigned by the driver when it's initializing its color and CTM
> > > management.
> > > 2. Create drm_atomic_helper_check_crtc which is called by
> > > drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
> > > they match the sizes in the new CRTC state.
> > > 3. Rename older lut checks that test for the color channels to indicate
> > > it's a channel check. It's not included in drm_atomic_helper_check_crtc
> > > as it's hardware specific and is to be called by the driver.
> > > 4. As the LUT size check now happens in drm_atomic_helper_check, remove
> > > the lut check in intel_color.c
> > >
> > > Fixes: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
> >
> > If I am not mistaken, the Fixes tag is used for commits I believe. Maybe
> > use Resolves or something similar?
> fixed!
> >
> > > Tested on Zork(amdgpu) and Jacuzzi(mediatek), volteer(TGL)
> >
> > Please add a space before the (.
my apologies i missed this. I'll update it if another version is
needed or if the committer can do it for me when they apply it.
> >
> > How did you test this?
> smoke test on both MTK and TGL devices along with running
> igt@kms_color on both devices.
> >
> > > v1:
> > > 1. Fix typos
> > > 2. Remove the LUT size check from intel driver
> > > 3. Rename old LUT check to indicate it's a channel change
> > >
> > > Signed-off-by: Mark Yacoub 
> > > ---
> > >   drivers/gpu/drm/drm_atomic_helper.c| 60 ++
> > >   drivers/gpu/drm/drm_color_mgmt.c   | 14 ++---
> > >   drivers/gpu/drm/i915/display/intel_color.c | 14 ++---
> > >   include/drm/drm_atomic_helper.h|  1 +
> > >   include/drm/drm_color_mgmt.h   |  7 +--
> > >   include/drm/drm_crtc.h | 11 
> > >   6 files changed, 89 insertions(+), 18 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > > b/drivers/gpu/drm/drm_atomic_helper.c
> > > index bc3487964fb5e..5feb2ad0209c3 100644
> > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > @@ -929,6 +929,62 @@ drm_atomic_helper_check_planes(struct drm_device 
> > > *dev,
> > >   }
> > >   EXPORT_SYMBOL(drm_atomic_helper_check_planes);
> > >
> > > +/**
> > > + * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
> > > + * @state: the driver state object
> > > + *
> > > + * Check the CRTC state object such as the Gamma/Degamma LUT sizes if 
> > > the new
> > > + * state holds them.
> > > + *
> > > + * RETURNS:
> > > + * Zero for success or -errno
> > > + */
> > > +int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
> > > +{
> > > + struct drm_crtc *crtc;
> > > + struct drm_crtc_state *new_crtc_state;
> > > + int i;
> > > +
> > > + for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
> > > + if (new_crtc_state->color_mgmt_changed &&
> > > + new_crtc_state->gamma_lut) {
> > > + uint64_t supported_lut_size = crtc->gamma_lut_size;
> > > + uint32_t supported_legacy_lut_size = 
> > > crtc->gamma_size;
> > > + uint32_t new_state_lut_size =
> > > + 
> > > drm_color_lut_size(new_crtc_state->ga

[Intel-gfx] [PATCH v3 2/3] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-26 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
or Degamma props in the new CRTC state, allowing any invalid size to
be passed on.
2. Each driver has its own LUT size, which could also be different for
legacy users.

[How]
1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
assigned by the driver when it's initializing its color and CTM
management.
2. Create drm_atomic_helper_check_crtc which is called by
drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
they match the sizes in the new CRTC state.
3. As the LUT size check now happens in drm_atomic_helper_check, remove
the lut check in intel_color.c

Resolves: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
Tested on Zork(amdgpu) and Jacuzzi(mediatek), volteer(TGL)

v2:
1. Remove the rename to a parent commit.
2. Create a drm drm_check_lut_size instead of intel only function.

v1:
1. Fix typos
2. Remove the LUT size check from intel driver
3. Rename old LUT check to indicate it's a channel change

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_atomic_helper.c| 56 ++
 drivers/gpu/drm/drm_color_mgmt.c   |  2 +
 drivers/gpu/drm/i915/display/intel_color.c | 39 ---
 include/drm/drm_atomic_helper.h|  1 +
 include/drm/drm_color_mgmt.h   | 13 +
 include/drm/drm_crtc.h | 11 +
 6 files changed, 102 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index bc3487964fb5e..c565b3516cce9 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -929,6 +929,58 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_helper_check_planes);
 
+/**
+ * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
+ * @state: the driver state object
+ *
+ * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the new
+ * state holds them.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->gamma_lut) {
+   if (drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_lut_size) ||
+   drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Gamma LUT size. Should be %u 
(or %u for legacy) but got %u.\n",
+   crtc->gamma_lut_size, crtc->gamma_size,
+   drm_color_lut_size(
+   new_crtc_state->gamma_lut));
+   return -EINVAL;
+   }
+   }
+
+   if (new_crtc_state->color_mgmt_changed &&
+   new_crtc_state->degamma_lut) {
+   if (drm_check_lut_size(new_crtc_state->degamma_lut,
+  crtc->degamma_lut_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid DeGamma LUT size. Should be %u 
but got %u.\n",
+   crtc->degamma_lut_size,
+   drm_color_lut_size(
+   new_crtc_state->degamma_lut));
+   return -EINVAL;
+   }
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_crtcs);
+
 /**
  * drm_atomic_helper_check - validate state object
  * @dev: DRM device
@@ -974,6 +1026,10 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
 
+   ret = drm_atomic_helper_check_crtcs(state);
+   if (ret)
+   return ret;
+
if (state->legacy_cursor_update)
state->async_update = !drm_atomic_helper_async_check(dev, 
state);
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 6f4e04746d90f..6bb59645a75bc 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -166,6 +166,7 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
struct drm_mode_config *config = >mode_config;
 
if (degamma_lut_size) {
+  

[Intel-gfx] [PATCH v3 1/3] drm: Rename lut check functions to lut channel checks

2021-10-26 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
This function and enum do not do generic checking on the luts but they
test color channels in the LUTs.
Keeping the name explicit as more generic LUT checks will follow.

Tested on Eldrid ChromeOS (TGL).

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_color_mgmt.c   | 12 ++--
 drivers/gpu/drm/i915/display/intel_color.c | 10 +-
 include/drm/drm_color_mgmt.h   |  7 ---
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index bb14f488c8f6c..6f4e04746d90f 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -585,17 +585,17 @@ int drm_plane_create_color_properties(struct drm_plane 
*plane,
 EXPORT_SYMBOL(drm_plane_create_color_properties);
 
 /**
- * drm_color_lut_check - check validity of lookup table
+ * drm_color_lut_channels_check - check validity of the channels in the lookup 
table
  * @lut: property blob containing LUT to check
  * @tests: bitmask of tests to run
  *
- * Helper to check whether a userspace-provided lookup table is valid and
- * satisfies hardware requirements.  Drivers pass a bitmask indicating which of
- * the tests in _color_lut_tests should be performed.
+ * Helper to check whether each color channel of userspace-provided lookup 
table is valid and
+ * satisfies hardware requirements. Drivers pass a bitmask indicating which of 
in
+ * _color_lut_channels_tests should be performed.
  *
  * Returns 0 on success, -EINVAL on failure.
  */
-int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)
+int drm_color_lut_channels_check(const struct drm_property_blob *lut, u32 
tests)
 {
const struct drm_color_lut *entry;
int i;
@@ -625,4 +625,4 @@ int drm_color_lut_check(const struct drm_property_blob 
*lut, u32 tests)
 
return 0;
 }
-EXPORT_SYMBOL(drm_color_lut_check);
+EXPORT_SYMBOL(drm_color_lut_channels_check);
diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
b/drivers/gpu/drm/i915/display/intel_color.c
index dab892d2251ba..4bb1bc76c4de9 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -1285,7 +1285,7 @@ static int check_luts(const struct intel_crtc_state 
*crtc_state)
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
const struct drm_property_blob *degamma_lut = 
crtc_state->hw.degamma_lut;
int gamma_length, degamma_length;
-   u32 gamma_tests, degamma_tests;
+   u32 gamma_channels_tests, degamma_channels_tests;
 
/* Always allow legacy gamma LUT with no further checking. */
if (crtc_state_is_legacy_gamma(crtc_state))
@@ -1300,15 +1300,15 @@ static int check_luts(const struct intel_crtc_state 
*crtc_state)
 
degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
-   degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
-   gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
+   degamma_channels_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
+   gamma_channels_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
 
if (check_lut_size(degamma_lut, degamma_length) ||
check_lut_size(gamma_lut, gamma_length))
return -EINVAL;
 
-   if (drm_color_lut_check(degamma_lut, degamma_tests) ||
-   drm_color_lut_check(gamma_lut, gamma_tests))
+   if (drm_color_lut_channels_check(degamma_lut, degamma_channels_tests) ||
+   drm_color_lut_channels_check(gamma_lut, gamma_channels_tests))
return -EINVAL;
 
return 0;
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index 81c298488b0c8..cb1bf361ad3e3 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -94,12 +94,12 @@ int drm_plane_create_color_properties(struct drm_plane 
*plane,
  enum drm_color_range default_range);
 
 /**
- * enum drm_color_lut_tests - hw-specific LUT tests to perform
+ * enum drm_color_lut_channels_tests - hw-specific LUT tests to perform
  *
  * The drm_color_lut_check() function takes a bitmask of the values here to
  * determine which tests to apply to a userspace-provided LUT.
  */
-enum drm_color_lut_tests {
+enum drm_color_lut_channels_tests {
/**
 * @DRM_COLOR_LUT_EQUAL_CHANNELS:
 *
@@ -119,5 +119,6 @@ enum drm_color_lut_tests {
DRM_COLOR_LUT_NON_DECREASING = BIT(1),
 };
 
-int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests);
+int drm_color_lut_channels_check(const struct drm_property_blob *lut,
+u32 tests);
 #endif
-- 
2.33.0.1079.g6e70778dc9-goog



Re: [Intel-gfx] [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-10-26 Thread Mark Yacoub
On Mon, Oct 25, 2021 at 9:26 PM Sean Paul  wrote:
>
> On Wed, Oct 13, 2021 at 02:12:20PM -0400, Mark Yacoub wrote:
> > From: Mark Yacoub 
> >
> > [Why]
> > 1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
> > or Degamma props in the new CRTC state, allowing any invalid size to
> > be passed on.
> > 2. Each driver has its own LUT size, which could also be different for
> > legacy users.
> >
> > [How]
> > 1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
> > assigned by the driver when it's initializing its color and CTM
> > management.
> > 2. Create drm_atomic_helper_check_crtc which is called by
> > drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
> > they match the sizes in the new CRTC state.
> > 3. Rename older lut checks that test for the color channels to indicate
> > it's a channel check. It's not included in drm_atomic_helper_check_crtc
> > as it's hardware specific and is to be called by the driver.
> > 4. As the LUT size check now happens in drm_atomic_helper_check, remove
> > the lut check in intel_color.c
>
> I'd probably split the rename out from the crtc check since they're only
> tangentially related.
done.
>
> >
> > Fixes: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
> > Tested on Zork(amdgpu) and Jacuzzi(mediatek), volteer(TGL)
> >
> > v1:
> > 1. Fix typos
> > 2. Remove the LUT size check from intel driver
> > 3. Rename old LUT check to indicate it's a channel change
> >
> > Signed-off-by: Mark Yacoub 
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c| 60 ++
> >  drivers/gpu/drm/drm_color_mgmt.c   | 14 ++---
> >  drivers/gpu/drm/i915/display/intel_color.c | 14 ++---
> >  include/drm/drm_atomic_helper.h|  1 +
> >  include/drm/drm_color_mgmt.h   |  7 +--
> >  include/drm/drm_crtc.h | 11 
> >  6 files changed, 89 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index bc3487964fb5e..5feb2ad0209c3 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -929,6 +929,62 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_check_planes);
> >
> > +/**
> > + * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
> > + * @state: the driver state object
> > + *
> > + * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the 
> > new
> > + * state holds them.
> > + *
> > + * RETURNS:
> > + * Zero for success or -errno
> > + */
> > +int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
> > +{
> > + struct drm_crtc *crtc;
> > + struct drm_crtc_state *new_crtc_state;
> > + int i;
> > +
> > + for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
> > + if (new_crtc_state->color_mgmt_changed &&
> > + new_crtc_state->gamma_lut) {
> > + uint64_t supported_lut_size = crtc->gamma_lut_size;
> > + uint32_t supported_legacy_lut_size = crtc->gamma_size;
> > + uint32_t new_state_lut_size =
> > + drm_color_lut_size(new_crtc_state->gamma_lut);
> > +
> > + if (new_state_lut_size != supported_lut_size &&
> > + new_state_lut_size != supported_legacy_lut_size) {
> > + drm_dbg_state(
> > + state->dev,
> > + "Invalid Gamma LUT size. Should be %u 
> > (or %u for legacy) but got %u.\n",
> > + supported_lut_size,
> > + supported_legacy_lut_size,
> > + new_state_lut_size);
> > + return -EINVAL;
> > + }
> > + }
> > +
> > + if (new_crtc_state->color_mgmt_changed &&
> > + new_crtc_state->degamma_lut) {
> > + uint32_t new_state_lut_size =
> > + 
> > drm_color_lut_size(new_crtc_state->degamma_lut);
> > + uint64_t supported_lut_size = crtc->degamma_lut_size;
> > +
> > +

[Intel-gfx] [PATCH v5 2/3] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-11-04 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
or Degamma props in the new CRTC state, allowing any invalid size to
be passed on.
2. Each driver has its own LUT size, which could also be different for
legacy users.

[How]
1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
assigned by the driver when it's initializing its color and CTM
management.
2. Create drm_atomic_helper_check_crtc which is called by
drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
they match the sizes in the new CRTC state.
3. As the LUT size check now happens in drm_atomic_helper_check, remove
the lut check in intel_color.c

Resolves: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
Tested on Zork (amdgpu) and Jacuzzi (mediatek), volteer (TGL)

v3:
1. Check for lut pointer inside drm_check_lut_size.

v2:
1. Remove the rename to a parent commit.
2. Create a drm drm_check_lut_size instead of intel only function.

v1:
1. Fix typos
2. Remove the LUT size check from intel driver
3. Rename old LUT check to indicate it's a channel change

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_atomic_helper.c| 52 ++
 drivers/gpu/drm/drm_color_mgmt.c   | 19 
 drivers/gpu/drm/i915/display/intel_color.c | 32 ++---
 include/drm/drm_atomic_helper.h|  1 +
 include/drm/drm_color_mgmt.h   |  3 ++
 include/drm/drm_crtc.h | 11 +
 6 files changed, 99 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index bc3487964fb5e..548e5d8221fb4 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -929,6 +929,54 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_helper_check_planes);
 
+/**
+ * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
+ * @state: the driver state object
+ *
+ * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the new
+ * state holds them.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
+   if (!new_crtc_state->color_mgmt_changed)
+   continue;
+
+   if (drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_lut_size) ||
+   drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Gamma LUT size. Expected %u/%u, got 
%u.\n",
+   crtc->gamma_lut_size, crtc->gamma_size,
+   drm_color_lut_size(new_crtc_state->gamma_lut));
+   return -EINVAL;
+   }
+
+   if (drm_check_lut_size(new_crtc_state->degamma_lut,
+  crtc->degamma_lut_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Degamma LUT size. Expected %u, got 
%u.\n",
+   crtc->degamma_lut_size,
+   drm_color_lut_size(
+   new_crtc_state->degamma_lut));
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_crtcs);
+
 /**
  * drm_atomic_helper_check - validate state object
  * @dev: DRM device
@@ -974,6 +1022,10 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
 
+   ret = drm_atomic_helper_check_crtcs(state);
+   if (ret)
+   return ret;
+
if (state->legacy_cursor_update)
state->async_update = !drm_atomic_helper_async_check(dev, 
state);
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 16a07f84948f3..c85094223b535 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -166,6 +166,7 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
struct drm_mode_config *config = >mode_config;
 
if (degamma_lut_size) {
+   crtc->degamma_lut_size = degamma_lut_size;
drm_object_attach_property(>base,
   config->degamma_lut_property, 0);
drm_object_attach_property(>base,
@@ -178,6 +179,7 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
   config->

[Intel-gfx] [PATCH v5 1/3] drm: Move drm_color_lut_check implementation internal to intel_color

2021-11-04 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
The tests of LUT_EQUAL_CHANNELS and LUT_NON_DECREASING are currently
unique to i915 driver.
Freeing up the function name for the more generic LUT checks to folllow

Tested on Eldrid ChromeOS (TGL).

v2:
1. Convert the enum to #define.
2. Add INTEL_COLOR_ prefix.

v1:
Stuff the test function from DRM to intel driver.

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_color_mgmt.c   | 43 --
 drivers/gpu/drm/i915/display/intel_color.c | 43 +++---
 drivers/gpu/drm/i915/display/intel_color.h | 16 
 drivers/gpu/drm/i915/i915_pci.c| 28 --
 include/drm/drm_color_mgmt.h   | 27 --
 5 files changed, 71 insertions(+), 86 deletions(-)

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index bb14f488c8f6c..16a07f84948f3 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -583,46 +583,3 @@ int drm_plane_create_color_properties(struct drm_plane 
*plane,
return 0;
 }
 EXPORT_SYMBOL(drm_plane_create_color_properties);
-
-/**
- * drm_color_lut_check - check validity of lookup table
- * @lut: property blob containing LUT to check
- * @tests: bitmask of tests to run
- *
- * Helper to check whether a userspace-provided lookup table is valid and
- * satisfies hardware requirements.  Drivers pass a bitmask indicating which of
- * the tests in _color_lut_tests should be performed.
- *
- * Returns 0 on success, -EINVAL on failure.
- */
-int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)
-{
-   const struct drm_color_lut *entry;
-   int i;
-
-   if (!lut || !tests)
-   return 0;
-
-   entry = lut->data;
-   for (i = 0; i < drm_color_lut_size(lut); i++) {
-   if (tests & DRM_COLOR_LUT_EQUAL_CHANNELS) {
-   if (entry[i].red != entry[i].blue ||
-   entry[i].red != entry[i].green) {
-   DRM_DEBUG_KMS("All LUT entries must have equal 
r/g/b\n");
-   return -EINVAL;
-   }
-   }
-
-   if (i > 0 && tests & DRM_COLOR_LUT_NON_DECREASING) {
-   if (entry[i].red < entry[i - 1].red ||
-   entry[i].green < entry[i - 1].green ||
-   entry[i].blue < entry[i - 1].blue) {
-   DRM_DEBUG_KMS("LUT entries must never 
decrease.\n");
-   return -EINVAL;
-   }
-   }
-   }
-
-   return 0;
-}
-EXPORT_SYMBOL(drm_color_lut_check);
diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
b/drivers/gpu/drm/i915/display/intel_color.c
index dab892d2251ba..1469871d21ff9 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -1279,13 +1279,46 @@ static int check_lut_size(const struct 
drm_property_blob *lut, int expected)
return 0;
 }
 
+static int test_luts(const struct drm_property_blob *lut, u32 tests)
+{
+   const struct drm_color_lut *entry;
+   int i;
+
+   if (!lut || !tests)
+   return 0;
+
+   entry = lut->data;
+   for (i = 0; i < drm_color_lut_size(lut); i++) {
+   if (tests & INTEL_COLOR_LUT_EQUAL_CHANNELS) {
+   if (entry[i].red != entry[i].blue ||
+   entry[i].red != entry[i].green) {
+   DRM_DEBUG_KMS(
+   "All LUT entries must have equal 
r/g/b\n");
+   return -EINVAL;
+   }
+   }
+
+   if (i > 0 && tests & INTEL_COLOR_LUT_NON_DECREASING) {
+   if (entry[i].red < entry[i - 1].red ||
+   entry[i].green < entry[i - 1].green ||
+   entry[i].blue < entry[i - 1].blue) {
+   DRM_DEBUG_KMS(
+   "LUT entries must never decrease.\n");
+   return -EINVAL;
+   }
+   }
+   }
+
+   return 0;
+}
+
 static int check_luts(const struct intel_crtc_state *crtc_state)
 {
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
const struct drm_property_blob *degamma_lut = 
crtc_state->hw.degamma_lut;
int gamma_length, degamma_length;
-   u32 gamma_tests, degamma_tests;
+   u32 gamma_channels_tests, degamma_channels_tests;
 
/* Always allow legacy gamma LUT with no further checking. */
if (crtc_state_is_legacy_gamma(crtc_state))
@@ -1300,15 +1333,15 @@ static int check_

[Intel-gfx] [PATCH v4 1/3] drm: Move drm_color_lut_check implementation internal to intel_color

2021-11-04 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
The tests of LUT_EQUAL_CHANNELS and LUT_NON_DECREASING are currently
unique to i915 driver.
Freeing up the function name for the more generic LUT checks to folllow

Tested on Eldrid ChromeOS (TGL).

v1:
Stuff the test function from DRM to intel driver.

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_color_mgmt.c   | 43 --
 drivers/gpu/drm/i915/display/intel_color.c | 43 +++---
 drivers/gpu/drm/i915/display/intel_color.h | 27 ++
 drivers/gpu/drm/i915/i915_pci.c| 27 --
 include/drm/drm_color_mgmt.h   | 27 --
 5 files changed, 81 insertions(+), 86 deletions(-)

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index bb14f488c8f6c..16a07f84948f3 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -583,46 +583,3 @@ int drm_plane_create_color_properties(struct drm_plane 
*plane,
return 0;
 }
 EXPORT_SYMBOL(drm_plane_create_color_properties);
-
-/**
- * drm_color_lut_check - check validity of lookup table
- * @lut: property blob containing LUT to check
- * @tests: bitmask of tests to run
- *
- * Helper to check whether a userspace-provided lookup table is valid and
- * satisfies hardware requirements.  Drivers pass a bitmask indicating which of
- * the tests in _color_lut_tests should be performed.
- *
- * Returns 0 on success, -EINVAL on failure.
- */
-int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)
-{
-   const struct drm_color_lut *entry;
-   int i;
-
-   if (!lut || !tests)
-   return 0;
-
-   entry = lut->data;
-   for (i = 0; i < drm_color_lut_size(lut); i++) {
-   if (tests & DRM_COLOR_LUT_EQUAL_CHANNELS) {
-   if (entry[i].red != entry[i].blue ||
-   entry[i].red != entry[i].green) {
-   DRM_DEBUG_KMS("All LUT entries must have equal 
r/g/b\n");
-   return -EINVAL;
-   }
-   }
-
-   if (i > 0 && tests & DRM_COLOR_LUT_NON_DECREASING) {
-   if (entry[i].red < entry[i - 1].red ||
-   entry[i].green < entry[i - 1].green ||
-   entry[i].blue < entry[i - 1].blue) {
-   DRM_DEBUG_KMS("LUT entries must never 
decrease.\n");
-   return -EINVAL;
-   }
-   }
-   }
-
-   return 0;
-}
-EXPORT_SYMBOL(drm_color_lut_check);
diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
b/drivers/gpu/drm/i915/display/intel_color.c
index dab892d2251ba..bde98a155c9f3 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -1279,13 +1279,46 @@ static int check_lut_size(const struct 
drm_property_blob *lut, int expected)
return 0;
 }
 
+static int test_luts(const struct drm_property_blob *lut, u32 tests)
+{
+   const struct drm_color_lut *entry;
+   int i;
+
+   if (!lut || !tests)
+   return 0;
+
+   entry = lut->data;
+   for (i = 0; i < drm_color_lut_size(lut); i++) {
+   if (tests & LUT_EQUAL_CHANNELS) {
+   if (entry[i].red != entry[i].blue ||
+   entry[i].red != entry[i].green) {
+   DRM_DEBUG_KMS(
+   "All LUT entries must have equal 
r/g/b\n");
+   return -EINVAL;
+   }
+   }
+
+   if (i > 0 && tests & LUT_NON_DECREASING) {
+   if (entry[i].red < entry[i - 1].red ||
+   entry[i].green < entry[i - 1].green ||
+   entry[i].blue < entry[i - 1].blue) {
+   DRM_DEBUG_KMS(
+   "LUT entries must never decrease.\n");
+   return -EINVAL;
+   }
+   }
+   }
+
+   return 0;
+}
+
 static int check_luts(const struct intel_crtc_state *crtc_state)
 {
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
const struct drm_property_blob *degamma_lut = 
crtc_state->hw.degamma_lut;
int gamma_length, degamma_length;
-   u32 gamma_tests, degamma_tests;
+   u32 gamma_channels_tests, degamma_channels_tests;
 
/* Always allow legacy gamma LUT with no further checking. */
if (crtc_state_is_legacy_gamma(crtc_state))
@@ -1300,15 +1333,15 @@ static int check_luts(const struct intel_crtc_state 
*crtc_state)
 
degamma_

[Intel-gfx] [PATCH v4 2/3] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.

2021-11-04 Thread Mark Yacoub
From: Mark Yacoub 

[Why]
1. drm_atomic_helper_check doesn't check for the LUT sizes of either Gamma
or Degamma props in the new CRTC state, allowing any invalid size to
be passed on.
2. Each driver has its own LUT size, which could also be different for
legacy users.

[How]
1. Create |degamma_lut_size| and |gamma_lut_size| to save the LUT sizes
assigned by the driver when it's initializing its color and CTM
management.
2. Create drm_atomic_helper_check_crtc which is called by
drm_atomic_helper_check to check the LUT sizes saved in drm_crtc that
they match the sizes in the new CRTC state.
3. As the LUT size check now happens in drm_atomic_helper_check, remove
the lut check in intel_color.c

Resolves: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK
Tested on Zork (amdgpu) and Jacuzzi (mediatek), volteer (TGL)

v3:
1. Check for lut pointer inside drm_check_lut_size.

v2:
1. Remove the rename to a parent commit.
2. Create a drm drm_check_lut_size instead of intel only function.

v1:
1. Fix typos
2. Remove the LUT size check from intel driver
3. Rename old LUT check to indicate it's a channel change

Signed-off-by: Mark Yacoub 
---
 drivers/gpu/drm/drm_atomic_helper.c| 52 ++
 drivers/gpu/drm/drm_color_mgmt.c   | 19 
 drivers/gpu/drm/i915/display/intel_color.c | 32 ++---
 include/drm/drm_atomic_helper.h|  1 +
 include/drm/drm_color_mgmt.h   |  3 ++
 include/drm/drm_crtc.h | 11 +
 6 files changed, 99 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index bc3487964fb5e..548e5d8221fb4 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -929,6 +929,54 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_helper_check_planes);
 
+/**
+ * drm_atomic_helper_check_crtcs - validate state object for CRTC changes
+ * @state: the driver state object
+ *
+ * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the new
+ * state holds them.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
+   if (!new_crtc_state->color_mgmt_changed)
+   continue;
+
+   if (drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_lut_size) ||
+   drm_check_lut_size(new_crtc_state->gamma_lut,
+  crtc->gamma_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Gamma LUT size. Expected %u/%u, got 
%u.\n",
+   crtc->gamma_lut_size, crtc->gamma_size,
+   drm_color_lut_size(new_crtc_state->gamma_lut));
+   return -EINVAL;
+   }
+
+   if (drm_check_lut_size(new_crtc_state->degamma_lut,
+  crtc->degamma_lut_size)) {
+   drm_dbg_state(
+   state->dev,
+   "Invalid Degamma LUT size. Expected %u, got 
%u.\n",
+   crtc->degamma_lut_size,
+   drm_color_lut_size(
+   new_crtc_state->degamma_lut));
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_crtcs);
+
 /**
  * drm_atomic_helper_check - validate state object
  * @dev: DRM device
@@ -974,6 +1022,10 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
 
+   ret = drm_atomic_helper_check_crtcs(state);
+   if (ret)
+   return ret;
+
if (state->legacy_cursor_update)
state->async_update = !drm_atomic_helper_async_check(dev, 
state);
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 16a07f84948f3..c85094223b535 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -166,6 +166,7 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
struct drm_mode_config *config = >mode_config;
 
if (degamma_lut_size) {
+   crtc->degamma_lut_size = degamma_lut_size;
drm_object_attach_property(>base,
   config->degamma_lut_property, 0);
drm_object_attach_property(>base,
@@ -178,6 +179,7 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
   config->

Re: [Intel-gfx] [PATCH v3 1/3] drm: Rename lut check functions to lut channel checks

2021-10-28 Thread Mark Yacoub
On Thu, Oct 28, 2021 at 8:42 PM Sean Paul  wrote:
>
> On Tue, Oct 26, 2021 at 03:21:00PM -0400, Mark Yacoub wrote:
> > From: Mark Yacoub 
> >
> > [Why]
> > This function and enum do not do generic checking on the luts but they
> > test color channels in the LUTs.
>
> I'm not sure there's anything inherently specific to channels, it seems like
> one could add a new test to reflect a HW limitation and it would fit pretty 
> well
> in the lut check function. I wonder if it would be better to expose the types 
> of
> tests required by the crtc such that the atomic_check could also do the test?
>
So the tests of the color are pretty unique to intel devices, no other
device is using it so I didn't think it adds a lot of benefit adding
it to the lut check. However, it's still in DRM because technically it
can be supported by any driver. But once it is, the driver will have
to expose the tests it wants so we can check it in atomic_check. but
given that no one does expose any test but intel, i just left it only
used by them.

> Sean
>
> > Keeping the name explicit as more generic LUT checks will follow.
> >
> > Tested on Eldrid ChromeOS (TGL).
> >
> > Signed-off-by: Mark Yacoub 
> > ---
> >  drivers/gpu/drm/drm_color_mgmt.c   | 12 ++--
> >  drivers/gpu/drm/i915/display/intel_color.c | 10 +-
> >  include/drm/drm_color_mgmt.h   |  7 ---
> >  3 files changed, 15 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_color_mgmt.c 
> > b/drivers/gpu/drm/drm_color_mgmt.c
> > index bb14f488c8f6c..6f4e04746d90f 100644
> > --- a/drivers/gpu/drm/drm_color_mgmt.c
> > +++ b/drivers/gpu/drm/drm_color_mgmt.c
> > @@ -585,17 +585,17 @@ int drm_plane_create_color_properties(struct 
> > drm_plane *plane,
> >  EXPORT_SYMBOL(drm_plane_create_color_properties);
> >
> >  /**
> > - * drm_color_lut_check - check validity of lookup table
> > + * drm_color_lut_channels_check - check validity of the channels in the 
> > lookup table
> >   * @lut: property blob containing LUT to check
> >   * @tests: bitmask of tests to run
> >   *
> > - * Helper to check whether a userspace-provided lookup table is valid and
> > - * satisfies hardware requirements.  Drivers pass a bitmask indicating 
> > which of
> > - * the tests in _color_lut_tests should be performed.
> > + * Helper to check whether each color channel of userspace-provided lookup 
> > table is valid and
> > + * satisfies hardware requirements. Drivers pass a bitmask indicating 
> > which of in
> > + * _color_lut_channels_tests should be performed.
> >   *
> >   * Returns 0 on success, -EINVAL on failure.
> >   */
> > -int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests)
> > +int drm_color_lut_channels_check(const struct drm_property_blob *lut, u32 
> > tests)
> >  {
> >   const struct drm_color_lut *entry;
> >   int i;
> > @@ -625,4 +625,4 @@ int drm_color_lut_check(const struct drm_property_blob 
> > *lut, u32 tests)
> >
> >   return 0;
> >  }
> > -EXPORT_SYMBOL(drm_color_lut_check);
> > +EXPORT_SYMBOL(drm_color_lut_channels_check);
> > diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
> > b/drivers/gpu/drm/i915/display/intel_color.c
> > index dab892d2251ba..4bb1bc76c4de9 100644
> > --- a/drivers/gpu/drm/i915/display/intel_color.c
> > +++ b/drivers/gpu/drm/i915/display/intel_color.c
> > @@ -1285,7 +1285,7 @@ static int check_luts(const struct intel_crtc_state 
> > *crtc_state)
> >   const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
> >   const struct drm_property_blob *degamma_lut = 
> > crtc_state->hw.degamma_lut;
> >   int gamma_length, degamma_length;
> > - u32 gamma_tests, degamma_tests;
> > + u32 gamma_channels_tests, degamma_channels_tests;
> >
> >   /* Always allow legacy gamma LUT with no further checking. */
> >   if (crtc_state_is_legacy_gamma(crtc_state))
> > @@ -1300,15 +1300,15 @@ static int check_luts(const struct intel_crtc_state 
> > *crtc_state)
> >
> >   degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
> >   gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
> > - degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
> > - gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
> > + degamma_channels_tests = 
> > INTEL_INFO(dev_priv)->color.degamma_lut_tests;
> > + gamma_channels_tests = INTEL_INFO(dev_priv)->color.gamma_lut

[Intel-gfx] [PATCH v6 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch moves the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Abhinav Kumar 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-2-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-2-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-2-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-2-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-2-s...@poorly.run
 #v5

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in V6:
-Rebase: move helper from drm_hdcp.c to drm_hdcp_helper.c

---
 drivers/gpu/drm/display/drm_hdcp_helper.c   | 69 +
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 --
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/display/drm_hdcp_helper.h   |  3 +
 5 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index e78999c72bd7..7d910523b05f 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline void drm_hdcp_print_ksv(const u8 *ksv)
 {
@@ -419,3 +420,71 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs an update
+ *
+ * This function can be used by display drivers to perform an atomic check on 
the
+ * hdcp state elements. If hdcp state has changed, this function will set
+ * mode_changed on the crtc driving the connector so it can update its hardware
+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+   old_hdcp = old_conn_state->content_protection;
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state =
+   drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+   /*
+   * Fix the HDCP uapi content protection state in case of modeset.
+   * FIXME: As per HDCP content protection property uapi doc, an uevent()
+   * need to be sent if there is transition from ENABLED->DESIRED.
+   */
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display

[Intel-gfx] [PATCH v6 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

Instead of forcing a modeset in the hdcp atomic check, simply return
true if the content protection value is changing and let the driver
decide whether a modeset is required or not.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-3-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-3-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-3-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-3-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-3-s...@poorly.run
 #v5

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in V6:
-Rebase: modifications in drm_hdcp_helper.c instead of drm_hdcp.c

---
 drivers/gpu/drm/display/drm_hdcp_helper.c   | 33 +++--
 drivers/gpu/drm/i915/display/intel_atomic.c |  6 ++--
 include/drm/display/drm_hdcp_helper.h   |  2 +-
 3 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 7d910523b05f..a3896b0904b5 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -428,11 +428,14 @@ EXPORT_SYMBOL(drm_hdcp_update_content_protection);
  * @connector: drm_connector on which content protection state needs an update
  *
  * This function can be used by display drivers to perform an atomic check on 
the
- * hdcp state elements. If hdcp state has changed, this function will set
- * mode_changed on the crtc driving the connector so it can update its hardware
- * to match the hdcp state.
+ * hdcp state elements. If hdcp state has changed in a manner which requires 
the
+ * driver to enable or disable content protection, this function will return
+ * true.
+ *
+ * Returns:
+ * true if the driver must enable/disable hdcp, false otherwise
  */
-void drm_hdcp_atomic_check(struct drm_connector *connector,
+bool drm_hdcp_atomic_check(struct drm_connector *connector,
   struct drm_atomic_state *state)
 {
struct drm_connector_state *new_conn_state, *old_conn_state;
@@ -450,10 +453,12 @@ void drm_hdcp_atomic_check(struct drm_connector 
*connector,
 * If the connector is being disabled with CP enabled, mark it
 * desired so it's re-enabled when the connector is brought back
 */
-   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   return;
+   return true;
+   }
+   return false;
}
 
new_crtc_state =
@@ -465,9 +470,19 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
*/
if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
-new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Coming back from disable or changing CRTC with DESIRED state requires
+* that the driver try CP enable.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -482,9 +497,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 8a473199c4bf..a2067cbae2d5 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -123,8 +123,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hdcp_atomic_check(conn, state);
-
if (!new_state->crtc)
return 0;
 
@@ -140,8 +138,8 @@

[Intel-gfx] [PATCH v6 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2023-01-18 Thread Mark Yacoub
From: Mark Yacoub 

Hello,

I rebased this series which is authored by Sean Paul.

A major rebase conflict was that drm/drm_hdcp was split to drm/display/drm_hdcp 
& drm/display/drm_hdcp_helper.

Another major one was in msm dp where drm_connector was no longer tracked, but 
it's replaced by msm_dp_bridge to carry over its functionalities.

The first 4 patches modify DRM. They've been reviewed.
Patches 5-7 are intel-only. Only patch 7 hasn't been reviewed.
Patches 8-10 are msm-only. Only patch 9 hasn't been reviewed.

Thanks,
Mark

Sean Paul (10):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  dt-bindings: msm/dp: Add bindings for HDCP registers
  arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |8 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |8 +
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1202 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |8 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   11 +-
 .../drm/i915/display/intel_display_types.h|   60 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  348 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1028 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |   36 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  270 ++--
 drivers/gpu/drm/msm/Kconfig   |1 +
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/dp/dp_debug.c |   48 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |6 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   52 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |  108 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |   16 +-
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  456 +++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   29 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   20 +-
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   32 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   15 +
 include/drm/display/drm_hdcp.h|  168 ++-
 include/drm/display/drm_hdcp_helper.h |   33 +-
 28 files changed, 2667 insertions(+), 1354 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

-- 
2.39.0.246.g2a6d74b583-goog



[Intel-gfx] [PATCH v6 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-8-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-8-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-8-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-8-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-8-s...@poorly.run
 #v5

Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased.

---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  60 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 348 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 952 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |  31 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 270 ++---
 8 files changed, 445 insertions(+), 1270 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 69ecf2a3d6c6..a4397f066a3e 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -2909,6 +2910,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!intel_crtc_is_bigjoiner_slave(crtc_state))
@@ -2925,12 +2930,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 }
 
 static void intel_disable_ddi_dp(struct intel_atomic_state *state,
@@ -2976,7 +2979,14 @@ static void intel_disable_ddi(struct intel_atomic_state 
*state,
  const struct intel_crtc_state *old_crtc_state,
  const struct drm_connector_state *old_conn_state)
 {
-   intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
+   struct intel_connector *connector =
+   to_intel_connector(old_conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
@@ -3004,13 +3014,19 @@ void intel_ddi_update_pipe(struct intel_atomic_state 
*state,
   const struct intel_crtc_state *crtc_state,
   const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector

[Intel-gfx] [PATCH v6 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-7-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-7-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-7-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-7-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-7-s...@poorly.run
 #v5

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased

---
 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 7c7253a2541c..13a4153bb76e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -492,6 +492,7 @@ static void intel_panel_info(struct seq_file *m,
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -499,8 +500,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, _cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, _cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0a20bc41be55..61a862ae1f28 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -177,50 +177,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, );
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = >hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(_priv->display.hdcp.comp_mutex);
if (!dev_priv->display.hdcp.comp_added ||  
!dev_priv->display.hdcp.master) {
mutex_unlock(_priv->display.hdcp.comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(_priv->display.hdcp.comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, );
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2355,6 +2354,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = >hdcp;
unsigned long check_link_interval = DRM_HD

[Intel-gfx] [PATCH v6 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-6-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-6-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-6-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-6-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-6-s...@poorly.run
 #v5

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None

---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 396d2cef000a..0a20bc41be55 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2190,6 +2190,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = >hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2329,28 +2360,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(>mutex);
mutex_lock(_port->hdcp_mutex);
drm_WARN_ON(_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2378,6 +2395,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(_port->hdcp_mutex);
mutex_unlock(>mutex);
return ret;
-- 
2.39.0.246.g2a6d74b583-goog



[Intel-gfx] [PATCH v6 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch adds the bindings for the MSM DisplayPort HDCP registers
which are required to write the HDCP key into the display controller as
well as the registers to enable HDCP authentication/key
exchange/encryption.

We'll use a new compatible string for this since the fields are optional.

Cc: Rob Herring 
Cc: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-13-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-13-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-13-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-13-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/2025202153.117244-1-s...@poorly.run
 #v4.5
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-9-s...@poorly.run
 #v5

Changes in v2:
-Drop register range names (Stephen)
-Fix yaml errors (Rob)
Changes in v3:
-Add new compatible string for dp-hdcp
-Add descriptions to reg
-Add minItems/maxItems to reg
-Make reg depend on the new hdcp compatible string
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v4.5:
-Remove maxItems from reg (Rob)
-Remove leading zeros in example (Rob)
Changes in v5:
-None
Changes in v6:
-Rebased: modify minItems instead of adding it as new line.

---
 .../devicetree/bindings/display/msm/dp-controller.yaml| 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index f2515af8256f..17d741f9af86 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -24,13 +24,15 @@ properties:
   - qcom,sm8350-dp
 
   reg:
-minItems: 4
+minItems: 5
 items:
   - description: ahb register block
   - description: aux register block
   - description: link register block
   - description: p0 register block
   - description: p1 register block
+  - description: (Optional) Registers for HDCP device key injection
+  - description: (Optional) Registers for HDCP TrustZone interaction
 
   interrupts:
 maxItems: 1
@@ -154,7 +156,9 @@ examples:
   <0xae90200 0x200>,
   <0xae90400 0xc00>,
   <0xae91000 0x400>,
-  <0xae91400 0x400>;
+  <0xae91400 0x400>,
+  <0xaed1000 0x174>,
+  <0xaee1000 0x2c>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
2.39.0.246.g2a6d74b583-goog



[Intel-gfx] [PATCH v6 03/10] drm/hdcp: Update property value on content type and user changes

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch updates the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Abhinav Kumar 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-4-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-4-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-4-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-4-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-4-s...@poorly.run

Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased: modifications in drm_hdcp_helper.c instead of drm_hdcp.c

---
 drivers/gpu/drm/display/drm_hdcp_helper.c | 29 +++
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index a3896b0904b5..ce92f1cac251 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -485,21 +485,30 @@ bool drm_hdcp_atomic_check(struct drm_connector 
*connector,
return true;
 
/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
-*  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+* Content type changes require an HDCP disable/enable cycle.
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if (new_conn_state->hdcp_content_type !=
+   old_conn_state->hdcp_content_type) {
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
+*  - HDCP was activated since the last commit
+*  - Attempting to set to desired while already enabled
+*/
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}
 
-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
-- 
2.39.0.246.g2a6d74b583-goog



[Intel-gfx] [PATCH v6 04/10] drm/hdcp: Expand HDCP helper library for enable/disable/check

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch expands upon the HDCP helper library to manage HDCP
enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the shim vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Cc: Abhinav Kumar 
Acked-by: Jani Nikula 
Reviewed-by: Abhinav Kumar 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-5-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-5-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-5-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-5-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-5-s...@poorly.run
 #v5

Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Fixed typo in function descriptions
-Rebased: Moved the new code between drm_hdcp.h and drm_hdcp_helper.c/h
-Add missing headers. Reported-by: kernel test robot 

---
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1109 +
 include/drm/display/drm_hdcp.h|  168 +++-
 include/drm/display/drm_hdcp_helper.h |   30 +-
 3 files changed, 1305 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index ce92f1cac251..de8c006b9cda 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -6,13 +6,18 @@
  * Ramalingam C 
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
+#include 
 #include 
 #include 
 #include 
@@ -512,3 +517,1107 @@ bool drm_hdcp_atomic_check(struct drm_connector 
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
+
+struct drm_hdcp_helper_data {
+   struct mutex mutex;
+   struct mutex *driver_mutex;
+
+   struct drm_connector *connector;
+   const struct drm_hdcp_helper_funcs *funcs;
+
+   u64 value;
+   unsigned int enabled_type;
+
+   struct delayed_work check_work;
+   struct work_struct prop_work;
+
+   struct drm_dp_aux *aux;
+   const struct drm_hdcp_hdcp1_receiver_reg_lut *hdcp1_lut;
+};
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_ddc_lut = {
+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_dpcd_lut = {
+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4

[Intel-gfx] [PATCH v6 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch adds the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller. Now that these are supported, change the
compatible string to "dp-hdcp".

Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-14-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-14-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-10-s...@poorly.run
 #v5

Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Put the tz register offsets in trogdor dtsi (Rob C)
Changes in v6:
-Rebased: Removed modifications in sc7180.dtsi as it's already upstream

---
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 178efaaa89ec..6f6fe5cb6563 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -817,6 +817,14 @@ _dp {
pinctrl-names = "default";
pinctrl-0 = <_hot_plug_det>;
data-lanes = <0 1>;
+
+   reg = <0 0x0ae9 0 0x200>,
+ <0 0x0ae90200 0 0x200>,
+ <0 0x0ae90400 0 0xc00>,
+ <0 0x0ae91000 0 0x400>,
+ <0 0x0ae91400 0 0x400>,
+ <0 0x0aed1000 0 0x175>,
+ <0 0x0aee1000 0 0x2c>;
 };
 
 _adc {
-- 
2.39.0.246.g2a6d74b583-goog



[Intel-gfx] [PATCH v6 10/10] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2023-01-18 Thread Mark Yacoub
From: Sean Paul 

This patch adds HDCP 1.x support to msm DP connectors using the new HDCP
helpers.

Cc: Stephen Boyd 
Cc: Abhinav Kumar 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-15-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-15-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-11-s...@poorly.run
 #v5

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Change return check of drm_hdcp_helper_initialize_dp() (Stephen)
Changes in v6:
-Change the tracking of the state from connector state to bridge as
state as drm_connector_state is no longer tracked and the functionality
has moved to msm_dp_bridge

[1] 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run

---
 drivers/gpu/drm/msm/Kconfig |   1 +
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/dp/dp_debug.c   |  48 ++-
 drivers/gpu/drm/msm/dp/dp_debug.h   |   6 +-
 drivers/gpu/drm/msm/dp/dp_display.c |  52 +++-
 drivers/gpu/drm/msm/dp/dp_display.h |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c | 108 ++-
 drivers/gpu/drm/msm/dp/dp_drm.h |  16 +-
 drivers/gpu/drm/msm/dp/dp_hdcp.c| 456 
 drivers/gpu/drm/msm/dp/dp_hdcp.h|  29 ++
 drivers/gpu/drm/msm/dp/dp_parser.c  |  20 +-
 drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h |  32 +-
 drivers/gpu/drm/msm/msm_atomic.c|  15 +
 14 files changed, 772 insertions(+), 21 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 61ca0c0757bc..9d9a66d9156c 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -15,6 +15,7 @@ config DRM_MSM
select REGULATOR
select DRM_DP_AUX_BUS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7274c41228ed..a73e7b858af2 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -122,6 +122,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c 
b/drivers/gpu/drm/msm/dp/dp_debug.c
index 5e35033ba3e4..e97d27edbb13 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dp_parser.h"
 #include "dp_catalog.h"
@@ -15,6 +16,7 @@
 #include "dp_ctrl.h"
 #include "dp_debug.h"
 #include "dp_display.h"
+#include "dp_hdcp.h"
 
 #define DEBUG_NAME "msm_dp"
 
@@ -25,6 +27,7 @@ struct dp_debug_private {
struct dp_link *link;
struct dp_panel *panel;
struct drm_connector *connector;
+   struct dp_hdcp *hdcp;
struct device *dev;
struct drm_device *drm_dev;
 
@@ -196,6 +199,35 @@ static int dp_test_active_open(struct inode *inode,
inode->i_private);
 }
 
+static ssize_t dp_hdcp_key_write(struct file *file, const char __user *ubuf,
+size_t len, loff_t *offp)
+{
+   char *input_buffer;
+   int ret;
+   struct dp_debug_private *debug = file->private_data;
+
+   if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
+   return -EINVAL;
+
+   if (!debug->hdcp)
+   return -ENOENT;
+
+   input_buffer = memdup_user_nul(ubuf, len);
+   if (IS_ERR(input_buffer))
+   return PTR_ERR(i

[Intel-gfx] [PATCH v7 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
- None

 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 396d2cef000aa..0a20bc41be55d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2190,6 +2190,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = >hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2329,28 +2360,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(>mutex);
mutex_lock(_port->hdcp_mutex);
drm_WARN_ON(_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2378,6 +2395,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(_port->hdcp_mutex);
mutex_unlock(>mutex);
return ret;
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v7 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Add the bindings for the MSM DisplayPort HDCP registers
which are required to write the HDCP key into the display controller as
well as the registers to enable HDCP authentication/key
exchange/encryption.

Cc: Rob Herring 
Cc: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Drop register range names (Stephen)
-Fix yaml errors (Rob)
Changes in v3:
-Add new compatible string for dp-hdcp
-Add descriptions to reg
-Add minItems/maxItems to reg
-Make reg depend on the new hdcp compatible string
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v4.5:
-Remove maxItems from reg (Rob)
-Remove leading zeros in example (Rob)
Changes in v5:
-None
Changes in v6:
-Rebased: modify minItems instead of adding it as new line.
Changes in v7:
-Revert the change to minItems
-Added the maxItems to Reg

 .../devicetree/bindings/display/msm/dp-controller.yaml | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 774ccb5184b88..c47ade3a4ae17 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -31,6 +31,8 @@ properties:
   - description: link register block
   - description: p0 register block
   - description: p1 register block
+  - description: (Optional) Registers for HDCP device key injection
+  - description: (Optional) Registers for HDCP TrustZone interaction
 
   interrupts:
 maxItems: 1
@@ -158,6 +160,7 @@ allOf:
 aux-bus: false
 reg:
   minItems: 5
+  maxItems: 7
   required:
 - "#sound-dai-cells"
 
@@ -175,7 +178,9 @@ examples:
   <0xae90200 0x200>,
   <0xae90400 0xc00>,
   <0xae91000 0x400>,
-  <0xae91400 0x400>;
+  <0xae91400 0x400>,
+  <0xaed1000 0x174>,
+  <0xaee1000 0x2c>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v7 10/10] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Add HDCP 1.x support to msm DP bridges using the new HDCP
helpers.

Cc: Stephen Boyd 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Change return check of drm_hdcp_helper_initialize_dp() (Stephen)
Changes in v6:
-Change the tracking of the state from connector state to bridge as
state as drm_connector_state is no longer tracked and the functionality
has moved to msm_dp_bridge
Changes in v7:
-Use dp bridge to maintain the state with no use for connector

 drivers/gpu/drm/msm/Kconfig |   1 +
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/dp/dp_debug.c   |  48 ++-
 drivers/gpu/drm/msm/dp/dp_debug.h   |  17 +-
 drivers/gpu/drm/msm/dp/dp_display.c |  42 ++-
 drivers/gpu/drm/msm/dp/dp_display.h |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c |  39 ++-
 drivers/gpu/drm/msm/dp/dp_drm.h |  12 +-
 drivers/gpu/drm/msm/dp/dp_hdcp.c| 483 
 drivers/gpu/drm/msm/dp/dp_hdcp.h|  31 ++
 drivers/gpu/drm/msm/dp/dp_parser.c  |  19 ++
 drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h |  30 +-
 drivers/gpu/drm/msm/msm_atomic.c|  19 ++
 14 files changed, 732 insertions(+), 19 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 86f0e64cbda30..c3e4d6102a5fa 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -15,6 +15,7 @@ config DRM_MSM
select REGULATOR
select DRM_DP_AUX_BUS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7274c41228ed9..a73e7b858af27 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -122,6 +122,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c 
b/drivers/gpu/drm/msm/dp/dp_debug.c
index 5e35033ba3e43..e97d27edbb13b 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dp_parser.h"
 #include "dp_catalog.h"
@@ -15,6 +16,7 @@
 #include "dp_ctrl.h"
 #include "dp_debug.h"
 #include "dp_display.h"
+#include "dp_hdcp.h"
 
 #define DEBUG_NAME "msm_dp"
 
@@ -25,6 +27,7 @@ struct dp_debug_private {
struct dp_link *link;
struct dp_panel *panel;
struct drm_connector *connector;
+   struct dp_hdcp *hdcp;
struct device *dev;
struct drm_device *drm_dev;
 
@@ -196,6 +199,35 @@ static int dp_test_active_open(struct inode *inode,
inode->i_private);
 }
 
+static ssize_t dp_hdcp_key_write(struct file *file, const char __user *ubuf,
+size_t len, loff_t *offp)
+{
+   char *input_buffer;
+   int ret;
+   struct dp_debug_private *debug = file->private_data;
+
+   if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
+   return -EINVAL;
+
+   if (!debug->hdcp)
+   return -ENOENT;
+
+   input_buffer = memdup_user_nul(ubuf, len);
+   if (IS_ERR(input_buffer))
+   return PTR_ERR(input_buffer);
+
+   ret = dp_hdcp_ingest_key(debug->hdcp, input_buffer, len);
+
+   kfree(input_buffer);
+   if (ret < 0) {
+   DRM_ERROR("Could not ingest HDCP key, ret=%d\n", ret);
+   return ret;
+   }
+
+   *offp += len;
+   return len;
+}
+
 static const struct file_operations test_active_fops = {
.owner = THIS_MODULE,
.open = dp_test_active_open,
@@ -205,6 +237,12 @@ static const struct file_operations test_active_fops = {
.write = dp_test_active_wri

[Intel-gfx] [PATCH v7 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Add the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller.

Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Put the tz register offsets in trogdor dtsi (Rob C)
Changes in v6:
-Rebased: Removed modifications in sc7180.dtsi as it's already upstream
Changes in v7:
-Change registers offset

 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 47f39c547c41a..63183ac9c3c48 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -816,6 +816,14 @@ _dp {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_hot_plug_det>;
+
+   reg = <0 0x0ae9 0 0x200>,
+ <0 0x0ae90200 0 0x200>,
+ <0 0x0ae90400 0 0xc00>,
+ <0 0x0ae91000 0 0x400>,
+ <0 0x0ae91400 0 0x400>,
+ <0 0x0aed1000 0 0x174>,
+ <0 0x0aee1000 0 0x2c>;
 };
 
 _dp_out {
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v7 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Acked-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased.
Changes in v7:
-Added to drm_hdcp_helper_funcs new functions that are unique between DP
and HDMI
-Adjusted the function signatures to take "driver data"

 drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 368 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 960 --
 drivers/gpu/drm/i915/display/intel_hdcp.h |  37 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 276 ++---
 8 files changed, 484 insertions(+), 1262 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 0f1ec2a98cc87..550a99d1811b4 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -2941,6 +2942,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!intel_crtc_is_bigjoiner_slave(crtc_state))
@@ -2957,12 +2962,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 }
 
 static void intel_disable_ddi_dp(struct intel_atomic_state *state,
@@ -3008,7 +3011,14 @@ static void intel_disable_ddi(struct intel_atomic_state 
*state,
  const struct intel_crtc_state *old_crtc_state,
  const struct drm_connector_state *old_conn_state)
 {
-   intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
+   struct intel_connector *connector =
+   to_intel_connector(old_conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
@@ -3036,13 +3046,19 @@ void intel_ddi_update_pipe(struct intel_atomic_state 
*state,
   const struct intel_crtc_state *crtc_state,
   const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
!intel_encoder_is_mst(encoder))
intel_ddi_update_pipe_dp(state, encoder, crtc_state,
   

[Intel-gfx] [PATCH v7 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased
Changes in v7:
-None

 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 7bcd90384a46d..a14b86a07e545 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -494,6 +494,7 @@ static void intel_panel_info(struct seq_file *m,
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -501,8 +502,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, _cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, _cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0a20bc41be55d..61a862ae1f286 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -177,50 +177,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, );
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = >hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(_priv->display.hdcp.comp_mutex);
if (!dev_priv->display.hdcp.comp_added ||  
!dev_priv->display.hdcp.master) {
mutex_unlock(_priv->display.hdcp.comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(_priv->display.hdcp.comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, );
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2355,6 +2354,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = >hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
+   bool capable;
int ret = -EINVAL;
 
if (!hdcp->shim)
@@ -2373,21 +2373,27 @@ int intel_hdcp_enable(struct intel_connector *connector,
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
 */
-   if (intel_hdcp2_capable(connector)) {
+   ret = intel_hdcp2_capable(connector, );
+   if (capable) {

[Intel-gfx] [PATCH v7 04/10] drm/hdcp: Expand HDCP helper library for enable/disable/check

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Expand upon the HDCP helper library to manage HDCP enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the shim vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Fixed typo in function descriptions
-Rebased: Moved the new code between drm_hdcp.h and drm_hdcp_helper.c/h
-Add missing headers. Reported-by: kernel test robot 
Changes in v7:
- Add a |driver_data| field to some functions in drm_hdcp_helper_funcs
  that are called by the driver so drivers can pass anything they such
  as bridges
- Isolate all non-common code between HDMI and DP into separate
  functions instead of manually checking for datra->aux

 drivers/gpu/drm/display/drm_hdcp_helper.c | 1211 +
 include/drm/display/drm_hdcp.h|  287 +
 include/drm/display/drm_hdcp_helper.h |   51 +-
 3 files changed, 1548 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 3ee1a6ae26c53..40ea10869736c 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -6,13 +6,18 @@
  * Ramalingam C 
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
+#include 
 #include 
 #include 
 #include 
@@ -507,3 +512,1209 @@ bool drm_hdcp_has_changed(struct drm_connector 
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_ddc_lut = {
+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_dpcd_lut = {
+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+* definition by different names. In the HDMI spec, it's called BSTATUS,
+* but in DP it's called BINFO.
+*/
+   .bstatus = DP_AUX_HDCP_BINFO,
+};
+
+/*
+ * Read a DPCD register.
+ *
+ * @data: drm_hdcp_helper_data containing the DisplayPort AUX channel (SST or 
MST)
+ * @offset: address of the (first) register to read
+ * @value: buffer to store the register values
+ * @len: number of bytes in @value
+ * 
+ * Return: 0 on success or a negative error code on fail

[Intel-gfx] [PATCH v7 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Move the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: move helper from drm_hdcp.c to drm_hdcp_helper.c
Changes in v7:
-Removed links to patch from commit msg (Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 64 +
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 ---
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/display/drm_hdcp_helper.h   |  3 +
 5 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index e78999c72bd77..7ca390b3ea106 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline void drm_hdcp_print_ksv(const u8 *ksv)
 {
@@ -419,3 +420,66 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs an update
+ *
+ * This function can be used by display drivers to perform an atomic check on 
the
+ * hdcp state elements. If hdcp state has changed, this function will set
+ * mode_changed on the crtc driving the connector so it can update its hardware
+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+   old_hdcp = old_conn_state->content_protection;
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state =
+   drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 6621aa245caf4..934ca9dcecc54 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -39,7 +40,6 @@
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
 #include "intel_global_state.h"
-#include "intel_hdcp.h"
 #include "intel_psr.h"
 #include "skl_universal_plane.h"
 
@@ -123,7 +123,7 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,

[Intel-gfx] [PATCH v7 03/10] drm/hdcp: Update property value on content type and user changes

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Update the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Rebased as function name has changed.

 drivers/gpu/drm/display/drm_hdcp_helper.c | 29 +++
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 34baf2b97cd87..3ee1a6ae26c53 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -480,21 +480,30 @@ bool drm_hdcp_has_changed(struct drm_connector *connector,
return true;
 
/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
-*  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+* Content type changes require an HDCP disable/enable cycle.
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if (new_conn_state->hdcp_content_type !=
+   old_conn_state->hdcp_content_type) {
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
+*  - HDCP was activated since the last commit
+*  - Attempting to set to desired while already enabled
+*/
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}
 
-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v7 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Instead of forcing a modeset in the hdcp atomic check, rename to
drm_hdcp_has_changed and return true if the content protection value
is changing and let the driver decide whether a modeset is required or not.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Renamed the function from drm_hdcp_atomic_check to drm_hdcp_has_changed
(Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 39 ++---
 drivers/gpu/drm/i915/display/intel_atomic.c |  6 ++--
 include/drm/display/drm_hdcp_helper.h   |  2 +-
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 7ca390b3ea106..34baf2b97cd87 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -422,18 +422,21 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
 
 /**
- * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ * drm_hdcp_has_changed - Helper for drivers to call during 
connector->atomic_check
  *
  * @state: pointer to the atomic state being checked
  * @connector: drm_connector on which content protection state needs an update
  *
  * This function can be used by display drivers to perform an atomic check on 
the
- * hdcp state elements. If hdcp state has changed, this function will set
- * mode_changed on the crtc driving the connector so it can update its hardware
- * to match the hdcp state.
+ * hdcp state elements. If hdcp state has changed in a manner which requires 
the
+ * driver to enable or disable content protection, this function will return
+ * true.
+ *
+ * Returns:
+ * true if the driver must enable/disable hdcp, false otherwise
  */
-void drm_hdcp_atomic_check(struct drm_connector *connector,
-  struct drm_atomic_state *state)
+bool drm_hdcp_has_changed(struct drm_connector *connector,
+ struct drm_atomic_state *state)
 {
struct drm_connector_state *new_conn_state, *old_conn_state;
struct drm_crtc_state *new_crtc_state;
@@ -450,19 +453,31 @@ void drm_hdcp_atomic_check(struct drm_connector 
*connector,
 * If the connector is being disabled with CP enabled, mark it
 * desired so it's re-enabled when the connector is brought back
 */
-   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   return;
+   return true;
+   }
+   return false;
}
 
new_crtc_state =
drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
-new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Coming back from UNDESIRED state, CRTC change or re-enablement 
requires
+* the driver to try CP enable.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -477,9 +492,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
-EXPORT_SYMBOL(drm_hdcp_atomic_check);
+EXPORT_SYMBOL(drm_hdcp_has_changed);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 934ca9dcecc54..bce4aba752974 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -123,8 +123,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hdcp_ato

Re: [Intel-gfx] [PATCH v6 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-03-24 Thread Mark Yacoub
On Tue, Mar 14, 2023 at 1:54 AM Kandpal, Suraj  wrote:
>
> >
> > From: Sean Paul 
> >
> > Now that all of the HDCP 1.x logic has been migrated to the central HDCP
> > helpers, use it in the i915 driver.
> >
> > The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
> > however there are a few helper hooks which are connector-specific and
> > need to be partially or fully implemented in the intel_dp_hdcp.c or
> > intel_hdmi.c.
> >
> > We'll leave most of the HDCP 2.x code alone since we don't have another
> > implementation of HDCP 2.x to use as reference for what should and
> > should not live in the drm helpers. The helper will call the overly
> > general enable/disable/is_capable HDCP 2.x callbacks and leave the
> > interesting stuff for the driver. Once we have another HDCP 2.x
> > implementation, we should do a similar migration.
> >
> > Acked-by: Jani Nikula 
> > Signed-off-by: Sean Paul 
> > Signed-off-by: Mark Yacoub 
> > Link:
> > https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-8-
> > s...@poorly.run #v1
> > Link:
> > https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-8-
> > s...@poorly.run #v2
> > Link:
> > https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-8-
> > s...@poorly.run #v3
> > Link:
> > https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-
> > 8-s...@poorly.run #v4
> > Link:
> > https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-
> > 8-s...@poorly.run #v5
> >
> > Changes in v2:
> > -Fix mst helper function pointer reported by 0-day
> > Changes in v3:
> > -Add forward declaration for drm_atomic_state in intel_hdcp.h identified
> >  by 0-day
> > Changes in v4:
> > -None
> > Changes in v5:
> > -None
> > Changes in v6:
> > -Rebased.
> >
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
> >  .../drm/i915/display/intel_display_debugfs.c  |   6 +-
> >  .../drm/i915/display/intel_display_types.h|  60 +-
> >  drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 348 +++
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
> >  drivers/gpu/drm/i915/display/intel_hdcp.c | 952 +++---
> >  drivers/gpu/drm/i915/display/intel_hdcp.h |  31 +-
> >  drivers/gpu/drm/i915/display/intel_hdmi.c | 270 ++---
> >  8 files changed, 445 insertions(+), 1270 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 69ecf2a3d6c6..a4397f066a3e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -28,6 +28,7 @@
> >  #include 
> >
> >  #include 
> > +#include 
> >  #include 
> >
> >  #include "i915_drv.h"
> > @@ -2909,6 +2910,10 @@ static void intel_enable_ddi(struct
> > intel_atomic_state *state,
> >const struct intel_crtc_state *crtc_state,
> >const struct drm_connector_state *conn_state)
> >  {
> > + struct intel_connector *connector =
> > + to_intel_connector(conn_state->connector);
> > + struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
> > +
> >   drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
> >
> >   if (!intel_crtc_is_bigjoiner_slave(crtc_state))
> > @@ -2925,12 +2930,10 @@ static void intel_enable_ddi(struct
> > intel_atomic_state *state,
> >   else
> >   intel_enable_ddi_dp(state, encoder, crtc_state,
> > conn_state);
> >
> > - /* Enable hdcp if it's desired */
> > - if (conn_state->content_protection ==
> > - DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > - intel_hdcp_enable(to_intel_connector(conn_state-
> > >connector),
> > -   crtc_state,
> > -   (u8)conn_state->hdcp_content_type);
> > + if (connector->hdcp_helper_data)
> > + drm_hdcp_helper_atomic_commit(connector-
> > >hdcp_helper_data,
> > +   >base,
> > +   _port->hdcp_mutex);
> >  }
> >
> >  static void intel_disable_ddi_dp(struct intel_atomic_state *state,
> > @@ -2976,7 +2979,14 @@ static void intel_disable_ddi(struct
> > intel_atomic_state *state,
> > c

Re: [Intel-gfx] [PATCH v6 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-03-24 Thread Mark Yacoub
On Thu, Mar 23, 2023 at 3:18 AM Kandpal, Suraj  wrote:
>
>
>
> > -Original Message-
> > From: Kandpal, Suraj
> > Sent: Friday, March 10, 2023 1:55 PM
> > To: Mark Yacoub ; quic_khs...@quicinc.com;
> > linux-arm-...@vger.kernel.org; dri-de...@lists.freedesktop.org;
> > freedr...@lists.freedesktop.org; devicet...@vger.kernel.org; linux-
> > ker...@vger.kernel.org; intel-gfx@lists.freedesktop.org
> > Cc: quic_sbill...@quicinc.com; konrad.dyb...@somainline.org; Souza, Jose
> > ; bjorn.anders...@linaro.org;
> > krzysztof.kozlowski...@linaro.org; hbh...@gmail.com; Vasut, Marek
> > ; Dixit, Ashutosh ;
> > s...@poorly.run; abhin...@codeaurora.org; javi...@redhat.com; Murthy,
> > Arun R ; Lisovskiy, Stanislav
> > ; agr...@kernel.org;
> > quic_jessz...@quicinc.com; Nautiyal, Ankit K ;
> > Nikula, Jani ; De Marchi, Lucas
> > ; quic_abhin...@quicinc.com;
> > swb...@chromium.org; robh...@kernel.org;
> > christophe.jail...@wanadoo.fr; max...@cerno.tech; Vivi, Rodrigo
> > ; johan+lin...@kernel.org;
> > tvrtko.ursu...@linux.intel.com; anders...@kernel.org;
> > diand...@chromium.org; Sharma, Swati2 ;
> > Navare, Manasi D ; tzimmerm...@suse.de;
> > Modem, Bhanuprakash ;
> > dmitry.barysh...@linaro.org; seanp...@chromium.org
> > Subject: RE: [PATCH v6 06/10] drm/i915/hdcp: Retain hdcp_capable return
> > codes
> >
> > > Subject: [PATCH v6 06/10] drm/i915/hdcp: Retain hdcp_capable return
> > > codes
> > >
> > > From: Sean Paul 
> > >
> > > The shim functions return error codes, but they are discarded in
> > > intel_hdcp.c. This patch plumbs the return codes through so they are
> > > properly handled.
> > >
> > > Acked-by: Jani Nikula 
> > > Reviewed-by: Rodrigo Vivi 
> > > Signed-off-by: Sean Paul 
> > > Signed-off-by: Mark Yacoub 
> > > Link:
> > > https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-7-
> > > s...@poorly.run #v1
> > > Link:
> > > https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-7-
> > > s...@poorly.run #v2
> > > Link:
> > > https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-7-
> > > s...@poorly.run #v3
> > > Link:
> > >
> > https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-
> > > 7-s...@poorly.run #v4
> > > Link:
> > >
> > https://patchwork.freedesktop.org/patch/msgid/20220411204741.1074308-
> > > 7-s...@poorly.run #v5
> > >
> > > Changes in v2:
> > > -None
> > > Changes in v3:
> > > -None
> > > Changes in v4:
> > > -None
> > > Changes in v5:
> > > -None
> > > Changes in v6:
> > > -Rebased
> > >
> > > ---
> > >  .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
> > >  drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
> > >  drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
> > >  3 files changed, 37 insertions(+), 27 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > index 7c7253a2541c..13a4153bb76e 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > @@ -492,6 +492,7 @@ static void intel_panel_info(struct seq_file *m,
> > > static void intel_hdcp_info(struct seq_file *m,
> > > struct intel_connector *intel_connector)  {
> > > +   int ret;
> > > bool hdcp_cap, hdcp2_cap;
> > >
> > > if (!intel_connector->hdcp.shim) {
> > > @@ -499,8 +500,12 @@ static void intel_hdcp_info(struct seq_file *m,
> > > goto out;
> > > }
> > >
> > > -   hdcp_cap = intel_hdcp_capable(intel_connector);
> > > -   hdcp2_cap = intel_hdcp2_capable(intel_connector);
> > > +   ret = intel_hdcp_capable(intel_connector, _cap);
> > > +   if (ret)
> > > +   hdcp_cap = false;
> > > +   ret = intel_hdcp2_capable(intel_connector, _cap);
> > > +   if (ret)
> > > +   hdcp2_cap = false;
> > >
> >
> > This does not seem to be adding value here as this error which you referred
> > to as being ignored is used both in case of hdmi and dp is being to 
> > determine
> > if hdcp_cap or hdcp2 cap is true or false which you basically reiterate 
> 

[Intel-gfx] [PATCH v7 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Acked-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased.
Changes in v7:
-Added to drm_hdcp_helper_funcs new functions that are unique between DP
and HDMI
-Adjusted the function signatures to take "driver data"

 drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 368 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 960 --
 drivers/gpu/drm/i915/display/intel_hdcp.h |  37 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 276 ++---
 8 files changed, 484 insertions(+), 1262 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 0f1ec2a98cc87..550a99d1811b4 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -2941,6 +2942,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!intel_crtc_is_bigjoiner_slave(crtc_state))
@@ -2957,12 +2962,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 }
 
 static void intel_disable_ddi_dp(struct intel_atomic_state *state,
@@ -3008,7 +3011,14 @@ static void intel_disable_ddi(struct intel_atomic_state 
*state,
  const struct intel_crtc_state *old_crtc_state,
  const struct drm_connector_state *old_conn_state)
 {
-   intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
+   struct intel_connector *connector =
+   to_intel_connector(old_conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
@@ -3036,13 +3046,19 @@ void intel_ddi_update_pipe(struct intel_atomic_state 
*state,
   const struct intel_crtc_state *crtc_state,
   const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
!intel_encoder_is_mst(encoder))
intel_ddi_update_pipe_dp(state, encoder, crtc_state,
   

[Intel-gfx] [PATCH v7 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
- None

 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 396d2cef000aa..0a20bc41be55d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2190,6 +2190,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = >hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2329,28 +2360,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(>mutex);
mutex_lock(_port->hdcp_mutex);
drm_WARN_ON(_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2378,6 +2395,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(_port->hdcp_mutex);
mutex_unlock(>mutex);
return ret;
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v7 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased
Changes in v7:
-None

 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 7bcd90384a46d..a14b86a07e545 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -494,6 +494,7 @@ static void intel_panel_info(struct seq_file *m,
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -501,8 +502,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, _cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, _cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0a20bc41be55d..61a862ae1f286 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -177,50 +177,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, );
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = >hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(_priv->display.hdcp.comp_mutex);
if (!dev_priv->display.hdcp.comp_added ||  
!dev_priv->display.hdcp.master) {
mutex_unlock(_priv->display.hdcp.comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(_priv->display.hdcp.comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, );
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2355,6 +2354,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = >hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
+   bool capable;
int ret = -EINVAL;
 
if (!hdcp->shim)
@@ -2373,21 +2373,27 @@ int intel_hdcp_enable(struct intel_connector *connector,
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
 */
-   if (intel_hdcp2_capable(connector)) {
+   ret = intel_hdcp2_capable(connector, );
+   if (capable) {

[Intel-gfx] [PATCH v7 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Instead of forcing a modeset in the hdcp atomic check, rename to
drm_hdcp_has_changed and return true if the content protection value
is changing and let the driver decide whether a modeset is required or not.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Renamed the function from drm_hdcp_atomic_check to drm_hdcp_has_changed
(Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 39 ++---
 drivers/gpu/drm/i915/display/intel_atomic.c |  6 ++--
 include/drm/display/drm_hdcp_helper.h   |  2 +-
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 7ca390b3ea106..34baf2b97cd87 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -422,18 +422,21 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
 
 /**
- * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ * drm_hdcp_has_changed - Helper for drivers to call during 
connector->atomic_check
  *
  * @state: pointer to the atomic state being checked
  * @connector: drm_connector on which content protection state needs an update
  *
  * This function can be used by display drivers to perform an atomic check on 
the
- * hdcp state elements. If hdcp state has changed, this function will set
- * mode_changed on the crtc driving the connector so it can update its hardware
- * to match the hdcp state.
+ * hdcp state elements. If hdcp state has changed in a manner which requires 
the
+ * driver to enable or disable content protection, this function will return
+ * true.
+ *
+ * Returns:
+ * true if the driver must enable/disable hdcp, false otherwise
  */
-void drm_hdcp_atomic_check(struct drm_connector *connector,
-  struct drm_atomic_state *state)
+bool drm_hdcp_has_changed(struct drm_connector *connector,
+ struct drm_atomic_state *state)
 {
struct drm_connector_state *new_conn_state, *old_conn_state;
struct drm_crtc_state *new_crtc_state;
@@ -450,19 +453,31 @@ void drm_hdcp_atomic_check(struct drm_connector 
*connector,
 * If the connector is being disabled with CP enabled, mark it
 * desired so it's re-enabled when the connector is brought back
 */
-   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   return;
+   return true;
+   }
+   return false;
}
 
new_crtc_state =
drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
-new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Coming back from UNDESIRED state, CRTC change or re-enablement 
requires
+* the driver to try CP enable.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -477,9 +492,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
-EXPORT_SYMBOL(drm_hdcp_atomic_check);
+EXPORT_SYMBOL(drm_hdcp_has_changed);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 934ca9dcecc54..bce4aba752974 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -123,8 +123,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hdcp_ato

[Intel-gfx] [PATCH v7 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-03-24 Thread Mark Yacoub
From: Sean Paul 

Move the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: move helper from drm_hdcp.c to drm_hdcp_helper.c
Changes in v7:
-Removed links to patch from commit msg (Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 64 +
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 ---
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/display/drm_hdcp_helper.h   |  3 +
 5 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index e78999c72bd77..7ca390b3ea106 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline void drm_hdcp_print_ksv(const u8 *ksv)
 {
@@ -419,3 +420,66 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs an update
+ *
+ * This function can be used by display drivers to perform an atomic check on 
the
+ * hdcp state elements. If hdcp state has changed, this function will set
+ * mode_changed on the crtc driving the connector so it can update its hardware
+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+   old_hdcp = old_conn_state->content_protection;
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state =
+   drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index 6621aa245caf4..934ca9dcecc54 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -39,7 +40,6 @@
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
 #include "intel_global_state.h"
-#include "intel_hdcp.h"
 #include "intel_psr.h"
 #include "skl_universal_plane.h"
 
@@ -123,7 +123,7 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,

[Intel-gfx] [PATCH v7 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2023-03-24 Thread Mark Yacoub
From: Mark Yacoub 

Hi all,
This is v7 of the HDCP patches. The patches are authored by Sean Paul. 
I rebased and addressed the review comments in v6-v7.

Patches 1-4 focus on moving the common HDCP helpers to common DRM. 
This introduces a slight change in the original intel flow
as it splits the unique driver protocol from the generic implementation.

Patches 5-7 split the HDCP flow on i915 driver to make use the common DRM 
helpers.

Patches 8-10 implement HDCP on MSM driver.

(Note: I resent the patch to add missing cc's)

Thanks,
-Mark Yacoub

Sean Paul (10):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  dt-bindings: msm/dp: Add bindings for HDCP registers
  arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |7 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |8 +
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1299 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |8 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   11 +-
 .../drm/i915/display/intel_display_types.h|   51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  368 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1036 +++--
 drivers/gpu/drm/i915/display/intel_hdcp.h |   42 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  276 ++--
 drivers/gpu/drm/msm/Kconfig   |1 +
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/dp/dp_debug.c |   48 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |   17 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   42 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |   39 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |   12 +-
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  483 ++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   31 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   19 +
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   30 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   19 +
 include/drm/display/drm_hdcp.h|  287 
 include/drm/display/drm_hdcp_helper.h |   52 +
 28 files changed, 2903 insertions(+), 1341 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v10 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Add the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller.

Reviewed-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Put the tz register offsets in trogdor dtsi (Rob C)
Changes in v6:
-Rebased: Removed modifications in sc7180.dtsi as it's already upstream
Changes in v7:
-Change registers offset

 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 423630c4d02c7..89d913fa6e3eb 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -822,6 +822,14 @@ _dp {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_hot_plug_det>;
+
+   reg = <0 0x0ae9 0 0x200>,
+ <0 0x0ae90200 0 0x200>,
+ <0 0x0ae90400 0 0xc00>,
+ <0 0x0ae91000 0 0x400>,
+ <0 0x0ae91400 0 0x400>,
+ <0 0x0aed1000 0 0x174>,
+ <0 0x0aee1000 0 0x2c>;
 };
 
 _dp_out {
-- 
2.40.0.634.g4ca3ef3211-goog



[Intel-gfx] [PATCH v10 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
- None

 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 396d2cef000aa..0a20bc41be55d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2190,6 +2190,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = >hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2329,28 +2360,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(>mutex);
mutex_lock(_port->hdcp_mutex);
drm_WARN_ON(_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2378,6 +2395,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(_port->hdcp_mutex);
mutex_unlock(>mutex);
return ret;
-- 
2.40.0.634.g4ca3ef3211-goog



[Intel-gfx] [PATCH v10 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Acked-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased.
Changes in v7:
-Added to drm_hdcp_helper_funcs new functions that are unique between DP
and HDMI
-Adjusted the function signatures to take "driver data"
Changes in v8:
-None
Changes in v9:
-rename dev_priv to i915
-remove display type specific hdcp calls init from driver
Changes in v10:
-Make functions static (kernel bot warning)

 drivers/gpu/drm/display/drm_hdcp_helper.c |  12 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   7 +-
 .../drm/i915/display/intel_display_types.h|  51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 352 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 984 --
 drivers/gpu/drm/i915/display/intel_hdcp.h |  43 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 267 ++---
 9 files changed, 481 insertions(+), 1283 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 9b62e476d21b4..41f5619dfd258 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -672,8 +672,8 @@ static int drm_hdcp_read_valid_bksv(struct 
drm_hdcp_helper_data *data,
return 0;
 }
 
-int drm_hdcp_helper_hdcp1_capable_dp(struct drm_hdcp_helper_data *data,
-bool *capable)
+static int drm_hdcp_helper_hdcp1_capable_dp(struct drm_hdcp_helper_data *data,
+   bool *capable)
 {
int ret;
u8 bcaps;
@@ -1322,9 +1322,10 @@ static void drm_hdcp_helper_prop_work(struct work_struct 
*work)
 /*
  * Check the link registers for HDCP 1.x for DP.
  */
-int drm_hdcp_hdcp1_check_link_registers_dp(struct drm_device *dev,
-  struct drm_hdcp_helper_data *data,
-  bool *shoud_retry)
+static int
+drm_hdcp_hdcp1_check_link_registers_dp(struct drm_device *dev,
+  struct drm_hdcp_helper_data *data,
+  bool *shoud_retry)
 {
u8 bstatus;
int ret = drm_hdcp_remote_dpcd_read(data, DP_AUX_HDCP_BSTATUS, ,
@@ -1341,7 +1342,6 @@ int drm_hdcp_hdcp1_check_link_registers_dp(struct 
drm_device *dev,
 
return 0;
 }
-EXPORT_SYMBOL(drm_hdcp_hdcp1_check_link_registers_dp);
 
 static int
 drm_hdcp_hdcp1_check_link_registers_hdmi(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 254559abedfba..8a2f20c929e9c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -2956,6 +2957,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!intel_crtc_is_bigjoiner_slave(crtc_state))
@@ -2975,12 +2980,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+

[Intel-gfx] [PATCH v10 10/10] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Add HDCP 1.x support to msm DP bridges using the new HDCP
helpers.

Cc: Stephen Boyd 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Change return check of drm_hdcp_helper_initialize_dp() (Stephen)
Changes in v6:
-Change the tracking of the state from connector state to bridge as
state as drm_connector_state is no longer tracked and the functionality
has moved to msm_dp_bridge
Changes in v7:
-Use dp bridge to maintain the state with no use for connector
Changes in v8:
-Move the hdcp read/write to dp_catalog
Changes in v9:
-Remove display type specific helper funcs init from driver
Changes in v10:
-Fix #include to include directory (kernel test bot)

 drivers/gpu/drm/msm/Kconfig |   1 +
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/dp/dp_catalog.c | 156 +++
 drivers/gpu/drm/msm/dp/dp_catalog.h |  18 ++
 drivers/gpu/drm/msm/dp/dp_debug.c   |  46 +++-
 drivers/gpu/drm/msm/dp/dp_debug.h   |  11 +-
 drivers/gpu/drm/msm/dp/dp_display.c |  39 ++-
 drivers/gpu/drm/msm/dp/dp_display.h |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c |  39 ++-
 drivers/gpu/drm/msm/dp/dp_drm.h |   7 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c| 389 
 drivers/gpu/drm/msm/dp/dp_hdcp.h|  33 +++
 drivers/gpu/drm/msm/dp/dp_parser.c  |  14 +
 drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h |  30 ++-
 drivers/gpu/drm/msm/msm_atomic.c|  19 ++
 16 files changed, 800 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 4d8fddbdcd9e0..1c369ca2ea6e3 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -15,6 +15,7 @@ config DRM_MSM
select REGULATOR
select DRM_DP_AUX_BUS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7274c41228ed9..a73e7b858af27 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -122,6 +122,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 676279d0ca8d9..a1395e0c67d56 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -16,6 +16,8 @@
 #include "dp_catalog.h"
 #include "dp_reg.h"
 
+#include 
+
 #define POLLING_SLEEP_US   1000
 #define POLLING_TIMEOUT_US 1
 
@@ -47,6 +49,14 @@
 #define DP_INTERRUPT_STATUS2_MASK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
 
+#define DP_AN_READ_DELAY_US 1
+/* Key offsets based on hdcp_key mmio */
+#define DP_HDCP_KEY_BASE 0x30
+#define DP_HDCP_KEY_MSB(x) (DP_HDCP_KEY_BASE + (x * 8))
+#define DP_HDCP_KEY_LSB(x) (DP_HDCP_KEY_MSB(x) + 4)
+#define DP_HDCP_KEY_VALID 0x170
+#define DP_HDCP_SW_KEY_VALID BIT(0)
+
 struct dp_catalog_private {
struct device *dev;
struct drm_device *drm_dev;
@@ -133,6 +143,18 @@ static inline void dp_write_link(struct dp_catalog_private 
*catalog,
writel(data, catalog->io->dp_controller.link.base + offset);
 }
 
+static inline void dp_write_hdcp_key(struct dp_catalog_private *catalog,
+u32 offset, u32 val)
+{
+   writel(val, catalog->io->dp_controller.hdcp_key.base + offset);
+}
+
+static inline void dp_write_hdcp_tz(struct dp_catalog_private *catalog,
+   u32 offset, u32 val)
+{
+   writel(val, catalog->io->dp_controller.hdcp_tz.base + offset);
+}
+
 /* aux related catalog functions */
 u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog)
 {
@@ -1094,3 +1116,137 @@ void dp_catalog_au

[Intel-gfx] [PATCH v10 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Move the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: move helper from drm_hdcp.c to drm_hdcp_helper.c
Changes in v7:
-Removed links to patch from commit msg (Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 64 +
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 ---
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/display/drm_hdcp_helper.h   |  3 +
 5 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index e78999c72bd77..7ca390b3ea106 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline void drm_hdcp_print_ksv(const u8 *ksv)
 {
@@ -419,3 +420,66 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs an update
+ *
+ * This function can be used by display drivers to perform an atomic check on 
the
+ * hdcp state elements. If hdcp state has changed, this function will set
+ * mode_changed on the crtc driving the connector so it can update its hardware
+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+   old_hdcp = old_conn_state->content_protection;
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state =
+   drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index a9a3f3715279d..e9d00b6a63d39 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -39,7 +40,6 @@
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
 #include "intel_global_state.h"
-#include "intel_hdcp.h"
 #include "intel_psr.h"
 #include "intel_fb.h"
 #include "skl_universal_plane.h"
@@ -124,7 +124,7 @@ int intel_digital_connector_atomic_check(struct 
drm

[Intel-gfx] [PATCH v10 03/10] drm/hdcp: Update property value on content type and user changes

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Update the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Rebased as function name has changed.

 drivers/gpu/drm/display/drm_hdcp_helper.c | 29 +++
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 34baf2b97cd87..3ee1a6ae26c53 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -480,21 +480,30 @@ bool drm_hdcp_has_changed(struct drm_connector *connector,
return true;
 
/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
-*  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+* Content type changes require an HDCP disable/enable cycle.
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if (new_conn_state->hdcp_content_type !=
+   old_conn_state->hdcp_content_type) {
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
+*  - HDCP was activated since the last commit
+*  - Attempting to set to desired while already enabled
+*/
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}
 
-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
-- 
2.40.0.634.g4ca3ef3211-goog



[Intel-gfx] [PATCH v10 04/10] drm/hdcp: Expand HDCP helper library for enable/disable/check

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Expand upon the HDCP helper library to manage HDCP enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the shim vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Fixed typo in function descriptions
-Rebased: Moved the new code between drm_hdcp.h and drm_hdcp_helper.c/h
-Add missing headers. Reported-by: kernel test robot 
Changes in v7:
- Add a |driver_data| field to some functions in drm_hdcp_helper_funcs
  that are called by the driver so drivers can pass anything they such
  as bridges
- Isolate all non-common code between HDMI and DP into separate
  functions instead of manually checking for datra->aux
Changes in v8 (suraj):
-Try hdcp 1.x if hdcp2_capable returns an error instead of goto out.
-set the enabled type to either 1 or 0 depending on the prop as hdcp2
can support either.
Changes in v9:
-Replace the drm_err by drm_dbg_kms
-Assign data->enabled_type without if-statement
-Moved display type specific func init into the drm helper

 drivers/gpu/drm/display/drm_hdcp_helper.c | 1136 +
 include/drm/display/drm_hdcp.h|  296 ++
 include/drm/display/drm_hdcp_helper.h |   22 +-
 3 files changed, 1453 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 3ee1a6ae26c53..9b62e476d21b4 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -6,13 +6,18 @@
  * Ramalingam C 
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
+#include 
 #include 
 #include 
 #include 
@@ -507,3 +512,1134 @@ bool drm_hdcp_has_changed(struct drm_connector 
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_ddc_lut = {
+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_dpcd_lut = {
+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+* definition by different names. In the HDMI spec, it's called BSTATUS,
+* but in DP it's called BINFO.
+*/
+   .b

[Intel-gfx] [PATCH v10 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Add the bindings for the MSM DisplayPort HDCP registers
which are required to write the HDCP key into the display controller as
well as the registers to enable HDCP authentication/key
exchange/encryption.

Cc: Rob Herring 
Cc: Stephen Boyd 
Reviewed-by: Rob Herring 
Reviewed-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Drop register range names (Stephen)
-Fix yaml errors (Rob)
Changes in v3:
-Add new compatible string for dp-hdcp
-Add descriptions to reg
-Add minItems/maxItems to reg
-Make reg depend on the new hdcp compatible string
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v4.5:
-Remove maxItems from reg (Rob)
-Remove leading zeros in example (Rob)
Changes in v5:
-None
Changes in v6:
-Rebased: modify minItems instead of adding it as new line.
Changes in v7:
-Revert the change to minItems
-Added the maxItems to Reg

 .../devicetree/bindings/display/msm/dp-controller.yaml | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 0e8d8df686dc9..4763a2ff12fb7 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -34,6 +34,8 @@ properties:
   - description: link register block
   - description: p0 register block
   - description: p1 register block
+  - description: (Optional) Registers for HDCP device key injection
+  - description: (Optional) Registers for HDCP TrustZone interaction
 
   interrupts:
 maxItems: 1
@@ -159,6 +161,7 @@ allOf:
 aux-bus: false
 reg:
   minItems: 5
+  maxItems: 7
   required:
 - "#sound-dai-cells"
 
@@ -176,7 +179,9 @@ examples:
   <0xae90200 0x200>,
   <0xae90400 0xc00>,
   <0xae91000 0x400>,
-  <0xae91400 0x400>;
+  <0xae91400 0x400>,
+  <0xaed1000 0x174>,
+  <0xaee1000 0x2c>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
2.40.0.634.g4ca3ef3211-goog



[Intel-gfx] [PATCH v10 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

Instead of forcing a modeset in the hdcp atomic check, rename to
drm_hdcp_has_changed and return true if the content protection value
is changing and let the driver decide whether a modeset is required or not.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Renamed the function from drm_hdcp_atomic_check to drm_hdcp_has_changed
(Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 39 ++---
 drivers/gpu/drm/i915/display/intel_atomic.c |  6 ++--
 include/drm/display/drm_hdcp_helper.h   |  2 +-
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 7ca390b3ea106..34baf2b97cd87 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -422,18 +422,21 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
 
 /**
- * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ * drm_hdcp_has_changed - Helper for drivers to call during 
connector->atomic_check
  *
  * @state: pointer to the atomic state being checked
  * @connector: drm_connector on which content protection state needs an update
  *
  * This function can be used by display drivers to perform an atomic check on 
the
- * hdcp state elements. If hdcp state has changed, this function will set
- * mode_changed on the crtc driving the connector so it can update its hardware
- * to match the hdcp state.
+ * hdcp state elements. If hdcp state has changed in a manner which requires 
the
+ * driver to enable or disable content protection, this function will return
+ * true.
+ *
+ * Returns:
+ * true if the driver must enable/disable hdcp, false otherwise
  */
-void drm_hdcp_atomic_check(struct drm_connector *connector,
-  struct drm_atomic_state *state)
+bool drm_hdcp_has_changed(struct drm_connector *connector,
+ struct drm_atomic_state *state)
 {
struct drm_connector_state *new_conn_state, *old_conn_state;
struct drm_crtc_state *new_crtc_state;
@@ -450,19 +453,31 @@ void drm_hdcp_atomic_check(struct drm_connector 
*connector,
 * If the connector is being disabled with CP enabled, mark it
 * desired so it's re-enabled when the connector is brought back
 */
-   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   return;
+   return true;
+   }
+   return false;
}
 
new_crtc_state =
drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
-new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Coming back from UNDESIRED state, CRTC change or re-enablement 
requires
+* the driver to try CP enable.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -477,9 +492,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
-EXPORT_SYMBOL(drm_hdcp_atomic_check);
+EXPORT_SYMBOL(drm_hdcp_has_changed);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index e9d00b6a63d39..23a6ba315a22e 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -124,8 +124,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hdcp_ato

[Intel-gfx] [PATCH v10 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2023-04-19 Thread Mark Yacoub
Hi all,
This is v10 of the HDCP patches. The patches are authored by Sean Paul. 
I rebased and addressed the review comments in v6-v10.

Main change in v10 is handling the kernel test bot warnings.

Patches 1-4 focus on moving the common HDCP helpers to common DRM. 
This introduces a slight change in the original intel flow
as it splits the unique driver protocol from the generic implementation.

Patches 5-7 split the HDCP flow on the i915 driver to make use of the common 
DRM helpers.

Patches 8-10 implement HDCP on MSM driver.

Thanks,
-Mark Yacoub

Sean Paul (10):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  dt-bindings: msm/dp: Add bindings for HDCP registers
  arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |7 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |8 +
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1224 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |8 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   12 +-
 .../drm/i915/display/intel_display_types.h|   51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  352 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1060 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |   48 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  267 ++--
 drivers/gpu/drm/msm/Kconfig   |1 +
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/dp/dp_catalog.c   |  156 +++
 drivers/gpu/drm/msm/dp/dp_catalog.h   |   18 +
 drivers/gpu/drm/msm/dp/dp_debug.c |   46 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |   11 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   39 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |   39 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |7 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  389 ++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   33 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   14 +
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   30 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   19 +
 include/drm/display/drm_hdcp.h|  296 
 include/drm/display/drm_hdcp_helper.h |   23 +
 30 files changed, 2867 insertions(+), 1349 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

-- 
2.40.0.634.g4ca3ef3211-goog



[Intel-gfx] [PATCH v10 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-04-19 Thread Mark Yacoub
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Suraj Kandpal 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased
Changes in v7:
-None

 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 7bcd90384a46d..a14b86a07e545 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -494,6 +494,7 @@ static void intel_panel_info(struct seq_file *m,
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -501,8 +502,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, _cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, _cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0a20bc41be55d..61a862ae1f286 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -177,50 +177,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, );
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = >hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(_priv->display.hdcp.comp_mutex);
if (!dev_priv->display.hdcp.comp_added ||  
!dev_priv->display.hdcp.master) {
mutex_unlock(_priv->display.hdcp.comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(_priv->display.hdcp.comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, );
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2355,6 +2354,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = >hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
+   bool capable;
int ret = -EINVAL;
 
if (!hdcp->shim)
@@ -2373,21 +2373,27 @@ int intel_hdcp_enable(struct intel_connector *connector,
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
 */
-   if (intel_hdcp2_capable(connector)) {
+   ret = intel_hdcp2_capable(connector, );
+   

[Intel-gfx] [PATCH v8 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Move the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: move helper from drm_hdcp.c to drm_hdcp_helper.c
Changes in v7:
-Removed links to patch from commit msg (Dmitry Baryshkov)
Changes in v8:
-None

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 64 +
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 ---
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/display/drm_hdcp_helper.h   |  3 +
 5 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index e78999c72bd77..7ca390b3ea106 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline void drm_hdcp_print_ksv(const u8 *ksv)
 {
@@ -419,3 +420,66 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs an update
+ *
+ * This function can be used by display drivers to perform an atomic check on 
the
+ * hdcp state elements. If hdcp state has changed, this function will set
+ * mode_changed on the crtc driving the connector so it can update its hardware
+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+   old_hdcp = old_conn_state->content_protection;
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state =
+   drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index a9a3f3715279d..e9d00b6a63d39 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -39,7 +40,6 @@
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
 #include "intel_global_state.h"
-#include "intel_hdcp.h"
 #include "intel_psr.h"
 #include "intel_fb.h"
 #include "skl_universal_plane.h"
@@ -124,7 +124,7 @@ int intel_digital

[Intel-gfx] [PATCH v8 03/10] drm/hdcp: Update property value on content type and user changes

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Update the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Rebased as function name has changed.
Changes in v8:
-None

 drivers/gpu/drm/display/drm_hdcp_helper.c | 29 +++
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 34baf2b97cd87..3ee1a6ae26c53 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -480,21 +480,30 @@ bool drm_hdcp_has_changed(struct drm_connector *connector,
return true;
 
/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
-*  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+* Content type changes require an HDCP disable/enable cycle.
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if (new_conn_state->hdcp_content_type !=
+   old_conn_state->hdcp_content_type) {
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
+*  - HDCP was activated since the last commit
+*  - Attempting to set to desired while already enabled
+*/
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}
 
-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v8 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2023-03-31 Thread Mark Yacoub
Hi all,
This is v7 of the HDCP patches. The patches are authored by Sean Paul. 
I rebased and addressed the review comments in v6-v8.

Patches 1-4 focus on moving the common HDCP helpers to common DRM. 
This introduces a slight change in the original intel flow
as it splits the unique driver protocol from the generic implementation.

Patches 5-7 split the HDCP flow on the i915 driver to make use of the common 
DRM helpers.

Patches 8-10 implement HDCP on MSM driver.

Thanks,
-Mark Yacoub


Sean Paul (10):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  dt-bindings: msm/dp: Add bindings for HDCP registers
  arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |7 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |8 +
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1303 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |8 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   11 +-
 .../drm/i915/display/intel_display_types.h|   51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  368 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1036 +++--
 drivers/gpu/drm/i915/display/intel_hdcp.h |   42 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  276 ++--
 drivers/gpu/drm/msm/Kconfig   |1 +
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/dp/dp_catalog.c   |  156 ++
 drivers/gpu/drm/msm/dp/dp_catalog.h   |   18 +
 drivers/gpu/drm/msm/dp/dp_debug.c |   46 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |   11 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   39 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |   39 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |7 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  397 +
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   33 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   14 +
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   30 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   19 +
 include/drm/display/drm_hdcp.h|  287 
 include/drm/display/drm_hdcp_helper.h |   52 +
 30 files changed, 2983 insertions(+), 1334 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v8 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Acked-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased.
Changes in v7:
-Added to drm_hdcp_helper_funcs new functions that are unique between DP
and HDMI
-Adjusted the function signatures to take "driver data"
Changes in v8:
-None

 drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 368 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 960 --
 drivers/gpu/drm/i915/display/intel_hdcp.h |  37 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 276 ++---
 8 files changed, 484 insertions(+), 1262 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 254559abedfba..8a2f20c929e9c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -2956,6 +2957,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!intel_crtc_is_bigjoiner_slave(crtc_state))
@@ -2975,12 +2980,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 }
 
 static void intel_disable_ddi_dp(struct intel_atomic_state *state,
@@ -3026,7 +3029,14 @@ static void intel_disable_ddi(struct intel_atomic_state 
*state,
  const struct intel_crtc_state *old_crtc_state,
  const struct drm_connector_state *old_conn_state)
 {
-   intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
+   struct intel_connector *connector =
+   to_intel_connector(old_conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
@@ -3054,13 +3064,19 @@ void intel_ddi_update_pipe(struct intel_atomic_state 
*state,
   const struct intel_crtc_state *crtc_state,
   const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
!intel_encoder_is_mst(encoder))
intel_ddi_update_pipe_dp(

[Intel-gfx] [PATCH v8 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased
Changes in v7:
-None
Changes in v8:
-None

 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 7bcd90384a46d..a14b86a07e545 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -494,6 +494,7 @@ static void intel_panel_info(struct seq_file *m,
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -501,8 +502,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, _cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, _cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0a20bc41be55d..61a862ae1f286 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -177,50 +177,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, );
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = >hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(_priv->display.hdcp.comp_mutex);
if (!dev_priv->display.hdcp.comp_added ||  
!dev_priv->display.hdcp.master) {
mutex_unlock(_priv->display.hdcp.comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(_priv->display.hdcp.comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, );
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2355,6 +2354,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = >hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
+   bool capable;
int ret = -EINVAL;
 
if (!hdcp->shim)
@@ -2373,21 +2373,27 @@ int intel_hdcp_enable(struct intel_connector *connector,
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
 */
-   if (intel_hdcp2_capable(connector)) {
+   ret = intel_hdcp2_capable(connector, );
+   

[Intel-gfx] [PATCH v8 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Add the bindings for the MSM DisplayPort HDCP registers
which are required to write the HDCP key into the display controller as
well as the registers to enable HDCP authentication/key
exchange/encryption.

Cc: Rob Herring 
Cc: Stephen Boyd 
Reviewed-by: Rob Herring 
Reviewed-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Drop register range names (Stephen)
-Fix yaml errors (Rob)
Changes in v3:
-Add new compatible string for dp-hdcp
-Add descriptions to reg
-Add minItems/maxItems to reg
-Make reg depend on the new hdcp compatible string
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v4.5:
-Remove maxItems from reg (Rob)
-Remove leading zeros in example (Rob)
Changes in v5:
-None
Changes in v6:
-Rebased: modify minItems instead of adding it as new line.
Changes in v7:
-Revert the change to minItems
-Added the maxItems to Reg
Changes in v8:
-None

 .../devicetree/bindings/display/msm/dp-controller.yaml | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 0e8d8df686dc9..4763a2ff12fb7 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -34,6 +34,8 @@ properties:
   - description: link register block
   - description: p0 register block
   - description: p1 register block
+  - description: (Optional) Registers for HDCP device key injection
+  - description: (Optional) Registers for HDCP TrustZone interaction
 
   interrupts:
 maxItems: 1
@@ -159,6 +161,7 @@ allOf:
 aux-bus: false
 reg:
   minItems: 5
+  maxItems: 7
   required:
 - "#sound-dai-cells"
 
@@ -176,7 +179,9 @@ examples:
   <0xae90200 0x200>,
   <0xae90400 0xc00>,
   <0xae91000 0x400>,
-  <0xae91400 0x400>;
+  <0xae91400 0x400>,
+  <0xaed1000 0x174>,
+  <0xaee1000 0x2c>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v8 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Change-Id: Ib358a503fa4520d072e477f708f1705b19f1c4fc
Signed-off-by: Sean Paul 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
- None
Changes in v8:
-None

 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 396d2cef000aa..0a20bc41be55d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2190,6 +2190,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = >hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2329,28 +2360,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(>mutex);
mutex_lock(_port->hdcp_mutex);
drm_WARN_ON(_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2378,6 +2395,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(_port->hdcp_mutex);
mutex_unlock(>mutex);
return ret;
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v8 04/10] drm/hdcp: Expand HDCP helper library for enable/disable/check

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Expand upon the HDCP helper library to manage HDCP enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the shim vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Fixed typo in function descriptions
-Rebased: Moved the new code between drm_hdcp.h and drm_hdcp_helper.c/h
-Add missing headers. Reported-by: kernel test robot 
Changes in v7:
- Add a |driver_data| field to some functions in drm_hdcp_helper_funcs
  that are called by the driver so drivers can pass anything they such
  as bridges
- Isolate all non-common code between HDMI and DP into separate
  functions instead of manually checking for datra->aux
Changes in v8 (suraj):
-Try hdcp 1.x if hdcp2_capable returns an error instead of goto out.
-set the enabled type to either 1 or 0 depending on the prop as hdcp2
can support either.

 drivers/gpu/drm/display/drm_hdcp_helper.c | 1215 +
 include/drm/display/drm_hdcp.h|  287 +
 include/drm/display/drm_hdcp_helper.h |   51 +-
 3 files changed, 1552 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 3ee1a6ae26c53..3bc0308cc95d8 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -6,13 +6,18 @@
  * Ramalingam C 
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
+#include 
 #include 
 #include 
 #include 
@@ -507,3 +512,1213 @@ bool drm_hdcp_has_changed(struct drm_connector 
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_ddc_lut = {
+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_dpcd_lut = {
+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+* definition by different names. In the HDMI spec, it's called BSTATUS,
+* but in DP it's called BINFO.
+*/
+   .bstatus = DP_AUX_HDCP_BINFO,
+};
+
+/*
+ * Read a DPCD register.
+ *
+ * @data: drm_hdcp_helper_data containing the DisplayPort AUX channel (SST or 
MST)
+ * @offset: addr

[Intel-gfx] [PATCH v8 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Add the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller.

Reviewed-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Put the tz register offsets in trogdor dtsi (Rob C)
Changes in v6:
-Rebased: Removed modifications in sc7180.dtsi as it's already upstream
Changes in v7:
-Change registers offset
Changes in v8:
-None

 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 423630c4d02c7..89d913fa6e3eb 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -822,6 +822,14 @@ _dp {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_hot_plug_det>;
+
+   reg = <0 0x0ae9 0 0x200>,
+ <0 0x0ae90200 0 0x200>,
+ <0 0x0ae90400 0 0xc00>,
+ <0 0x0ae91000 0 0x400>,
+ <0 0x0ae91400 0 0x400>,
+ <0 0x0aed1000 0 0x174>,
+ <0 0x0aee1000 0 0x2c>;
 };
 
 _dp_out {
-- 
2.40.0.348.gf938b09366-goog



[Intel-gfx] [PATCH v8 10/10] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Add HDCP 1.x support to msm DP bridges using the new HDCP
helpers.

Cc: Stephen Boyd 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Change return check of drm_hdcp_helper_initialize_dp() (Stephen)
Changes in v6:
-Change the tracking of the state from connector state to bridge as
state as drm_connector_state is no longer tracked and the functionality
has moved to msm_dp_bridge
Changes in v7:
-Use dp bridge to maintain the state with no use for connector
Changes in v8:
-Move the hdcp read/write to dp_catalog

 drivers/gpu/drm/msm/Kconfig |   1 +
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/dp/dp_catalog.c | 156 +++
 drivers/gpu/drm/msm/dp/dp_catalog.h |  18 ++
 drivers/gpu/drm/msm/dp/dp_debug.c   |  46 +++-
 drivers/gpu/drm/msm/dp/dp_debug.h   |  11 +-
 drivers/gpu/drm/msm/dp/dp_display.c |  39 ++-
 drivers/gpu/drm/msm/dp/dp_display.h |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c |  39 ++-
 drivers/gpu/drm/msm/dp/dp_drm.h |   7 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c| 397 
 drivers/gpu/drm/msm/dp/dp_hdcp.h|  33 +++
 drivers/gpu/drm/msm/dp/dp_parser.c  |  14 +
 drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h |  30 ++-
 drivers/gpu/drm/msm/msm_atomic.c|  19 ++
 16 files changed, 808 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 4d8fddbdcd9e0..1c369ca2ea6e3 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -15,6 +15,7 @@ config DRM_MSM
select REGULATOR
select DRM_DP_AUX_BUS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7274c41228ed9..a73e7b858af27 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -122,6 +122,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 676279d0ca8d9..a1395e0c67d56 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -16,6 +16,8 @@
 #include "dp_catalog.h"
 #include "dp_reg.h"
 
+#include 
+
 #define POLLING_SLEEP_US   1000
 #define POLLING_TIMEOUT_US 1
 
@@ -47,6 +49,14 @@
 #define DP_INTERRUPT_STATUS2_MASK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
 
+#define DP_AN_READ_DELAY_US 1
+/* Key offsets based on hdcp_key mmio */
+#define DP_HDCP_KEY_BASE 0x30
+#define DP_HDCP_KEY_MSB(x) (DP_HDCP_KEY_BASE + (x * 8))
+#define DP_HDCP_KEY_LSB(x) (DP_HDCP_KEY_MSB(x) + 4)
+#define DP_HDCP_KEY_VALID 0x170
+#define DP_HDCP_SW_KEY_VALID BIT(0)
+
 struct dp_catalog_private {
struct device *dev;
struct drm_device *drm_dev;
@@ -133,6 +143,18 @@ static inline void dp_write_link(struct dp_catalog_private 
*catalog,
writel(data, catalog->io->dp_controller.link.base + offset);
 }
 
+static inline void dp_write_hdcp_key(struct dp_catalog_private *catalog,
+u32 offset, u32 val)
+{
+   writel(val, catalog->io->dp_controller.hdcp_key.base + offset);
+}
+
+static inline void dp_write_hdcp_tz(struct dp_catalog_private *catalog,
+   u32 offset, u32 val)
+{
+   writel(val, catalog->io->dp_controller.hdcp_tz.base + offset);
+}
+
 /* aux related catalog functions */
 u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog)
 {
@@ -1094,3 +1116,137 @@ void dp_catalog_audio_sfe_level(struct dp_catalog 
*dp_catalog)
 
dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
 }
+
+u32 dp_catalog_hdcp

[Intel-gfx] [PATCH v8 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-03-31 Thread Mark Yacoub
From: Sean Paul 

Instead of forcing a modeset in the hdcp atomic check, rename to
drm_hdcp_has_changed and return true if the content protection value
is changing and let the driver decide whether a modeset is required or not.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Renamed the function from drm_hdcp_atomic_check to drm_hdcp_has_changed
(Dmitry Baryshkov)
Changes in v8:
-None

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 39 ++---
 drivers/gpu/drm/i915/display/intel_atomic.c |  6 ++--
 include/drm/display/drm_hdcp_helper.h   |  2 +-
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 7ca390b3ea106..34baf2b97cd87 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -422,18 +422,21 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
 
 /**
- * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ * drm_hdcp_has_changed - Helper for drivers to call during 
connector->atomic_check
  *
  * @state: pointer to the atomic state being checked
  * @connector: drm_connector on which content protection state needs an update
  *
  * This function can be used by display drivers to perform an atomic check on 
the
- * hdcp state elements. If hdcp state has changed, this function will set
- * mode_changed on the crtc driving the connector so it can update its hardware
- * to match the hdcp state.
+ * hdcp state elements. If hdcp state has changed in a manner which requires 
the
+ * driver to enable or disable content protection, this function will return
+ * true.
+ *
+ * Returns:
+ * true if the driver must enable/disable hdcp, false otherwise
  */
-void drm_hdcp_atomic_check(struct drm_connector *connector,
-  struct drm_atomic_state *state)
+bool drm_hdcp_has_changed(struct drm_connector *connector,
+ struct drm_atomic_state *state)
 {
struct drm_connector_state *new_conn_state, *old_conn_state;
struct drm_crtc_state *new_crtc_state;
@@ -450,19 +453,31 @@ void drm_hdcp_atomic_check(struct drm_connector 
*connector,
 * If the connector is being disabled with CP enabled, mark it
 * desired so it's re-enabled when the connector is brought back
 */
-   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   return;
+   return true;
+   }
+   return false;
}
 
new_crtc_state =
drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
-new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Coming back from UNDESIRED state, CRTC change or re-enablement 
requires
+* the driver to try CP enable.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -477,9 +492,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
-EXPORT_SYMBOL(drm_hdcp_atomic_check);
+EXPORT_SYMBOL(drm_hdcp_has_changed);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index e9d00b6a63d39..23a6ba315a22e 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -124,8 +124,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hd

[Intel-gfx] [PATCH v9 01/10] drm/hdcp: Add drm_hdcp_atomic_check()

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Move the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: move helper from drm_hdcp.c to drm_hdcp_helper.c
Changes in v7:
-Removed links to patch from commit msg (Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 64 +
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 ---
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/display/drm_hdcp_helper.h   |  3 +
 5 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index e78999c72bd77..7ca390b3ea106 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline void drm_hdcp_print_ksv(const u8 *ksv)
 {
@@ -419,3 +420,66 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs an update
+ *
+ * This function can be used by display drivers to perform an atomic check on 
the
+ * hdcp state elements. If hdcp state has changed, this function will set
+ * mode_changed on the crtc driving the connector so it can update its hardware
+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+   old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+   old_hdcp = old_conn_state->content_protection;
+
+   new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state =
+   drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index a9a3f3715279d..e9d00b6a63d39 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -39,7 +40,6 @@
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
 #include "intel_global_state.h"
-#include "intel_hdcp.h"
 #include "intel_psr.h"
 #include "intel_fb.h"
 #include "skl_universal_plane.h"
@@ -124,7 +124,7 @@ int intel_digital_connector_atomic_check(struct 
drm

[Intel-gfx] [PATCH v9 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Instead of forcing a modeset in the hdcp atomic check, rename to
drm_hdcp_has_changed and return true if the content protection value
is changing and let the driver decide whether a modeset is required or not.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebase: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Renamed the function from drm_hdcp_atomic_check to drm_hdcp_has_changed
(Dmitry Baryshkov)

 drivers/gpu/drm/display/drm_hdcp_helper.c   | 39 ++---
 drivers/gpu/drm/i915/display/intel_atomic.c |  6 ++--
 include/drm/display/drm_hdcp_helper.h   |  2 +-
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 7ca390b3ea106..34baf2b97cd87 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -422,18 +422,21 @@ void drm_hdcp_update_content_protection(struct 
drm_connector *connector,
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
 
 /**
- * drm_hdcp_atomic_check - Helper for drivers to call during 
connector->atomic_check
+ * drm_hdcp_has_changed - Helper for drivers to call during 
connector->atomic_check
  *
  * @state: pointer to the atomic state being checked
  * @connector: drm_connector on which content protection state needs an update
  *
  * This function can be used by display drivers to perform an atomic check on 
the
- * hdcp state elements. If hdcp state has changed, this function will set
- * mode_changed on the crtc driving the connector so it can update its hardware
- * to match the hdcp state.
+ * hdcp state elements. If hdcp state has changed in a manner which requires 
the
+ * driver to enable or disable content protection, this function will return
+ * true.
+ *
+ * Returns:
+ * true if the driver must enable/disable hdcp, false otherwise
  */
-void drm_hdcp_atomic_check(struct drm_connector *connector,
-  struct drm_atomic_state *state)
+bool drm_hdcp_has_changed(struct drm_connector *connector,
+ struct drm_atomic_state *state)
 {
struct drm_connector_state *new_conn_state, *old_conn_state;
struct drm_crtc_state *new_crtc_state;
@@ -450,19 +453,31 @@ void drm_hdcp_atomic_check(struct drm_connector 
*connector,
 * If the connector is being disabled with CP enabled, mark it
 * desired so it's re-enabled when the connector is brought back
 */
-   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
-   return;
+   return true;
+   }
+   return false;
}
 
new_crtc_state =
drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
-new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)) {
new_conn_state->content_protection =
DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Coming back from UNDESIRED state, CRTC change or re-enablement 
requires
+* the driver to try CP enable.
+*/
+   if (new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   new_conn_state->crtc != old_conn_state->crtc)
+   return true;
 
/*
 * Nothing to do if content type is unchanged and one of:
@@ -477,9 +492,9 @@ void drm_hdcp_atomic_check(struct drm_connector *connector,
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
if (old_conn_state->hdcp_content_type ==
new_conn_state->hdcp_content_type)
-   return;
+   return false;
}
 
-   new_crtc_state->mode_changed = true;
+   return true;
 }
-EXPORT_SYMBOL(drm_hdcp_atomic_check);
+EXPORT_SYMBOL(drm_hdcp_has_changed);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index e9d00b6a63d39..23a6ba315a22e 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -124,8 +124,6 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
 
-   drm_hdcp_ato

[Intel-gfx] [PATCH v9 03/10] drm/hdcp: Update property value on content type and user changes

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Update the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased: modifications in drm_hdcp_helper.c instead of drm_hdcp.c
Changes in v7:
-Rebased as function name has changed.

 drivers/gpu/drm/display/drm_hdcp_helper.c | 29 +++
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 34baf2b97cd87..3ee1a6ae26c53 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -480,21 +480,30 @@ bool drm_hdcp_has_changed(struct drm_connector *connector,
return true;
 
/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
-*  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+* Content type changes require an HDCP disable/enable cycle.
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if (new_conn_state->hdcp_content_type !=
+   old_conn_state->hdcp_content_type) {
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
+*  - HDCP was activated since the last commit
+*  - Attempting to set to desired while already enabled
+*/
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}
 
-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
-- 
2.40.0.577.gac1e443424-goog



[Intel-gfx] [PATCH v9 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2023-04-11 Thread Mark Yacoub
Hi all,
This is v7 of the HDCP patches. The patches are authored by Sean Paul. 
I rebased and addressed the review comments in v6-v9.

Main change in v9 is renaming i915 priv data and moving the display type 
specific init to the drm helper instead of the driver.

Patches 1-4 focus on moving the common HDCP helpers to common DRM. 
This introduces a slight change in the original intel flow
as it splits the unique driver protocol from the generic implementation.

Patches 5-7 split the HDCP flow on the i915 driver to make use of the common 
DRM helpers.

Patches 8-10 implement HDCP on MSM driver.

Thanks,
-Mark Yacoub

Sean Paul (10):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  dt-bindings: msm/dp: Add bindings for HDCP registers
  arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |7 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |8 +
 drivers/gpu/drm/display/drm_hdcp_helper.c | 1224 +
 drivers/gpu/drm/i915/display/intel_atomic.c   |8 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   12 +-
 .../drm/i915/display/intel_display_types.h|   51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  352 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1060 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |   48 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  267 ++--
 drivers/gpu/drm/msm/Kconfig   |1 +
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/dp/dp_catalog.c   |  156 +++
 drivers/gpu/drm/msm/dp/dp_catalog.h   |   18 +
 drivers/gpu/drm/msm/dp/dp_debug.c |   46 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |   11 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   39 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |   39 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |7 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  389 ++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   33 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   14 +
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   30 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   19 +
 include/drm/display/drm_hdcp.h|  296 
 include/drm/display/drm_hdcp_helper.h |   23 +
 30 files changed, 2867 insertions(+), 1349 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

-- 
2.40.0.577.gac1e443424-goog



[Intel-gfx] [PATCH v9 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Add the bindings for the MSM DisplayPort HDCP registers
which are required to write the HDCP key into the display controller as
well as the registers to enable HDCP authentication/key
exchange/encryption.

Cc: Rob Herring 
Cc: Stephen Boyd 
Reviewed-by: Rob Herring 
Reviewed-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Drop register range names (Stephen)
-Fix yaml errors (Rob)
Changes in v3:
-Add new compatible string for dp-hdcp
-Add descriptions to reg
-Add minItems/maxItems to reg
-Make reg depend on the new hdcp compatible string
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v4.5:
-Remove maxItems from reg (Rob)
-Remove leading zeros in example (Rob)
Changes in v5:
-None
Changes in v6:
-Rebased: modify minItems instead of adding it as new line.
Changes in v7:
-Revert the change to minItems
-Added the maxItems to Reg

 .../devicetree/bindings/display/msm/dp-controller.yaml | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 0e8d8df686dc9..4763a2ff12fb7 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -34,6 +34,8 @@ properties:
   - description: link register block
   - description: p0 register block
   - description: p1 register block
+  - description: (Optional) Registers for HDCP device key injection
+  - description: (Optional) Registers for HDCP TrustZone interaction
 
   interrupts:
 maxItems: 1
@@ -159,6 +161,7 @@ allOf:
 aux-bus: false
 reg:
   minItems: 5
+  maxItems: 7
   required:
 - "#sound-dai-cells"
 
@@ -176,7 +179,9 @@ examples:
   <0xae90200 0x200>,
   <0xae90400 0xc00>,
   <0xae91000 0x400>,
-  <0xae91400 0x400>;
+  <0xae91400 0x400>,
+  <0xaed1000 0x174>,
+  <0xaee1000 0x2c>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,
-- 
2.40.0.577.gac1e443424-goog



[Intel-gfx] [PATCH v9 07/10] drm/i915/hdcp: Use HDCP helpers for i915

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Now that all of the HDCP 1.x logic has been migrated to the central HDCP
helpers, use it in the i915 driver.

The majority of the driver code for HDCP 1.x will live in intel_hdcp.c,
however there are a few helper hooks which are connector-specific and
need to be partially or fully implemented in the intel_dp_hdcp.c or
intel_hdmi.c.

We'll leave most of the HDCP 2.x code alone since we don't have another
implementation of HDCP 2.x to use as reference for what should and
should not live in the drm helpers. The helper will call the overly
general enable/disable/is_capable HDCP 2.x callbacks and leave the
interesting stuff for the driver. Once we have another HDCP 2.x
implementation, we should do a similar migration.

Acked-by: Jani Nikula 
Acked-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fix mst helper function pointer reported by 0-day
Changes in v3:
-Add forward declaration for drm_atomic_state in intel_hdcp.h identified
 by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased.
Changes in v7:
-Added to drm_hdcp_helper_funcs new functions that are unique between DP
and HDMI
-Adjusted the function signatures to take "driver data"
Changes in v8:
-None
Changes in v9:
-rename dev_priv to i915
-remove display type specific hdcp calls init from driver

 drivers/gpu/drm/i915/display/intel_ddi.c  |  32 +-
 .../drm/i915/display/intel_display_debugfs.c  |   7 +-
 .../drm/i915/display/intel_display_types.h|  51 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 352 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 984 --
 drivers/gpu/drm/i915/display/intel_hdcp.h |  43 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 267 ++---
 8 files changed, 475 insertions(+), 1277 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 254559abedfba..8a2f20c929e9c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "i915_drv.h"
@@ -2956,6 +2957,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
if (!intel_crtc_is_bigjoiner_slave(crtc_state))
@@ -2975,12 +2980,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
else
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
 
-   /* Enable hdcp if it's desired */
-   if (conn_state->content_protection ==
-   DRM_MODE_CONTENT_PROTECTION_DESIRED)
-   intel_hdcp_enable(to_intel_connector(conn_state->connector),
- crtc_state,
- (u8)conn_state->hdcp_content_type);
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 }
 
 static void intel_disable_ddi_dp(struct intel_atomic_state *state,
@@ -3026,7 +3029,14 @@ static void intel_disable_ddi(struct intel_atomic_state 
*state,
  const struct intel_crtc_state *old_crtc_state,
  const struct drm_connector_state *old_conn_state)
 {
-   intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
+   struct intel_connector *connector =
+   to_intel_connector(old_conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+   if (connector->hdcp_helper_data)
+   drm_hdcp_helper_atomic_commit(connector->hdcp_helper_data,
+ >base,
+ _port->hdcp_mutex);
 
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
@@ -3054,13 +3064,19 @@ void intel_ddi_update_pipe(struct intel_atomic_state 
*state,
   const struct intel_crtc_state *crtc_state,
   const struct drm_connector_state *conn_state)
 {
+   struct intel_connector *connector =
+   to_intel_connector(conn_state->connector);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
if (!intel_crtc_has_type(crtc

[Intel-gfx] [PATCH v9 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Add the register ranges required for HDCP key injection and
HDCP TrustZone interaction as described in the dt-bindings for the
sc7180 dp controller.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v3:
-Split off into a new patch containing just the dts change (Stephen)
-Add hdcp compatible string (Stephen)
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Put the tz register offsets in trogdor dtsi (Rob C)
Changes in v6:
-Rebased: Removed modifications in sc7180.dtsi as it's already upstream
Changes in v7:
-Change registers offset

 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 423630c4d02c7..89d913fa6e3eb 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -822,6 +822,14 @@ _dp {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_hot_plug_det>;
+
+   reg = <0 0x0ae9 0 0x200>,
+ <0 0x0ae90200 0 0x200>,
+ <0 0x0ae90400 0 0xc00>,
+ <0 0x0ae91000 0 0x400>,
+ <0 0x0ae91400 0 0x400>,
+ <0 0x0aed1000 0 0x174>,
+ <0 0x0aee1000 0 0x2c>;
 };
 
 _dp_out {
-- 
2.40.0.577.gac1e443424-goog



[Intel-gfx] [PATCH v9 10/10] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Add HDCP 1.x support to msm DP bridges using the new HDCP
helpers.

Cc: Stephen Boyd 
Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions
Changes in v4:
-Rebase on Bjorn's multi-dp patchset
Changes in v5:
-Change return check of drm_hdcp_helper_initialize_dp() (Stephen)
Changes in v6:
-Change the tracking of the state from connector state to bridge as
state as drm_connector_state is no longer tracked and the functionality
has moved to msm_dp_bridge
Changes in v7:
-Use dp bridge to maintain the state with no use for connector
Changes in v8:
-Move the hdcp read/write to dp_catalog
Changes in v9:
-Remove display type specific helper funcs init from driver

 drivers/gpu/drm/msm/Kconfig |   1 +
 drivers/gpu/drm/msm/Makefile|   1 +
 drivers/gpu/drm/msm/dp/dp_catalog.c | 156 +++
 drivers/gpu/drm/msm/dp/dp_catalog.h |  18 ++
 drivers/gpu/drm/msm/dp/dp_debug.c   |  46 +++-
 drivers/gpu/drm/msm/dp/dp_debug.h   |  11 +-
 drivers/gpu/drm/msm/dp/dp_display.c |  39 ++-
 drivers/gpu/drm/msm/dp/dp_display.h |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c |  39 ++-
 drivers/gpu/drm/msm/dp/dp_drm.h |   7 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c| 389 
 drivers/gpu/drm/msm/dp/dp_hdcp.h|  33 +++
 drivers/gpu/drm/msm/dp/dp_parser.c  |  14 +
 drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h |  30 ++-
 drivers/gpu/drm/msm/msm_atomic.c|  19 ++
 16 files changed, 800 insertions(+), 12 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 4d8fddbdcd9e0..1c369ca2ea6e3 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -15,6 +15,7 @@ config DRM_MSM
select REGULATOR
select DRM_DP_AUX_BUS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7274c41228ed9..a73e7b858af27 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -122,6 +122,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 676279d0ca8d9..a1395e0c67d56 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -16,6 +16,8 @@
 #include "dp_catalog.h"
 #include "dp_reg.h"
 
+#include 
+
 #define POLLING_SLEEP_US   1000
 #define POLLING_TIMEOUT_US 1
 
@@ -47,6 +49,14 @@
 #define DP_INTERRUPT_STATUS2_MASK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
 
+#define DP_AN_READ_DELAY_US 1
+/* Key offsets based on hdcp_key mmio */
+#define DP_HDCP_KEY_BASE 0x30
+#define DP_HDCP_KEY_MSB(x) (DP_HDCP_KEY_BASE + (x * 8))
+#define DP_HDCP_KEY_LSB(x) (DP_HDCP_KEY_MSB(x) + 4)
+#define DP_HDCP_KEY_VALID 0x170
+#define DP_HDCP_SW_KEY_VALID BIT(0)
+
 struct dp_catalog_private {
struct device *dev;
struct drm_device *drm_dev;
@@ -133,6 +143,18 @@ static inline void dp_write_link(struct dp_catalog_private 
*catalog,
writel(data, catalog->io->dp_controller.link.base + offset);
 }
 
+static inline void dp_write_hdcp_key(struct dp_catalog_private *catalog,
+u32 offset, u32 val)
+{
+   writel(val, catalog->io->dp_controller.hdcp_key.base + offset);
+}
+
+static inline void dp_write_hdcp_tz(struct dp_catalog_private *catalog,
+   u32 offset, u32 val)
+{
+   writel(val, catalog->io->dp_controller.hdcp_tz.base + offset);
+}
+
 /* aux related catalog functions */
 u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog)
 {
@@ -1094,3 +1116,137 @@ void dp_catalog_audio_sfe_level(struct dp_catalog 
*dp_catalog)
 
dp_write_link(cata

[Intel-gfx] [PATCH v9 04/10] drm/hdcp: Expand HDCP helper library for enable/disable/check

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Expand upon the HDCP helper library to manage HDCP enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the shim vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Fixed typo in function descriptions
-Rebased: Moved the new code between drm_hdcp.h and drm_hdcp_helper.c/h
-Add missing headers. Reported-by: kernel test robot 
Changes in v7:
- Add a |driver_data| field to some functions in drm_hdcp_helper_funcs
  that are called by the driver so drivers can pass anything they such
  as bridges
- Isolate all non-common code between HDMI and DP into separate
  functions instead of manually checking for datra->aux
Changes in v8 (suraj):
-Try hdcp 1.x if hdcp2_capable returns an error instead of goto out.
-set the enabled type to either 1 or 0 depending on the prop as hdcp2
can support either.
Changes in v9:
-Replace the drm_err by drm_dbg_kms
-Assign data->enabled_type without if-statement
-Moved display type specific func init into the drm helper

 drivers/gpu/drm/display/drm_hdcp_helper.c | 1136 +
 include/drm/display/drm_hdcp.h|  296 ++
 include/drm/display/drm_hdcp_helper.h |   22 +-
 3 files changed, 1453 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdcp_helper.c 
b/drivers/gpu/drm/display/drm_hdcp_helper.c
index 3ee1a6ae26c53..9b62e476d21b4 100644
--- a/drivers/gpu/drm/display/drm_hdcp_helper.c
+++ b/drivers/gpu/drm/display/drm_hdcp_helper.c
@@ -6,13 +6,18 @@
  * Ramalingam C 
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 
 
+#include 
 #include 
 #include 
 #include 
@@ -507,3 +512,1134 @@ bool drm_hdcp_has_changed(struct drm_connector 
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_has_changed);
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_ddc_lut = {
+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut drm_hdcp_hdcp1_dpcd_lut = {
+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+* definition by different names. In the HDMI spec, it's called BSTATUS,
+* but in DP it's called BINFO.
+*/
+   .b

[Intel-gfx] [PATCH v9 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

Stick all of the setup for HDCP into a dedicated function. No functional
change, but this will facilitate moving HDCP logic into helpers.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Signed-off-by: Sean Paul 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
- None

 drivers/gpu/drm/i915/display/intel_hdcp.c | 52 +++
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 396d2cef000aa..0a20bc41be55d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2190,6 +2190,37 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum 
transcoder cpu_transcoder)
}
 }
 
+static int
+_intel_hdcp_setup(struct intel_connector *connector,
+ const struct intel_crtc_state *pipe_config, u8 content_type)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct intel_hdcp *hdcp = >hdcp;
+   int ret = 0;
+
+   if (!connector->encoder) {
+   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
+   connector->base.name, connector->base.base.id);
+   return -ENODEV;
+   }
+
+   hdcp->content_type = content_type;
+
+   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
+   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
+   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
+   } else {
+   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
+   hdcp->stream_transcoder = INVALID_TRANSCODER;
+   }
+
+   if (DISPLAY_VER(dev_priv) >= 12)
+   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+
+   return ret;
+}
+
 static int initialize_hdcp_port_data(struct intel_connector *connector,
 struct intel_digital_port *dig_port,
 const struct intel_hdcp_shim *shim)
@@ -2329,28 +2360,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
if (!hdcp->shim)
return -ENOENT;
 
-   if (!connector->encoder) {
-   drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n",
-   connector->base.name, connector->base.base.id);
-   return -ENODEV;
-   }
-
mutex_lock(>mutex);
mutex_lock(_port->hdcp_mutex);
drm_WARN_ON(_priv->drm,
hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-   hdcp->content_type = content_type;
-
-   if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) {
-   hdcp->cpu_transcoder = pipe_config->mst_master_transcoder;
-   hdcp->stream_transcoder = pipe_config->cpu_transcoder;
-   } else {
-   hdcp->cpu_transcoder = pipe_config->cpu_transcoder;
-   hdcp->stream_transcoder = INVALID_TRANSCODER;
-   }
 
-   if (DISPLAY_VER(dev_priv) >= 12)
-   dig_port->hdcp_port_data.fw_tc = 
intel_get_mei_fw_tc(hdcp->cpu_transcoder);
+   ret = _intel_hdcp_setup(connector, pipe_config, content_type);
+   if (ret)
+   goto out;
 
/*
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
@@ -2378,6 +2395,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
true);
}
 
+out:
mutex_unlock(_port->hdcp_mutex);
mutex_unlock(>mutex);
return ret;
-- 
2.40.0.577.gac1e443424-goog



[Intel-gfx] [PATCH v9 06/10] drm/i915/hdcp: Retain hdcp_capable return codes

2023-04-11 Thread Mark Yacoub
From: Sean Paul 

The shim functions return error codes, but they are discarded in
intel_hdcp.c. This patch plumbs the return codes through so they are
properly handled.

Acked-by: Jani Nikula 
Reviewed-by: Rodrigo Vivi 
Reviewed-by: Suraj Kandpal 
Signed-off-by: Sean Paul 
Signed-off-by: Mark Yacoub 

---
Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-Rebased
Changes in v7:
-None

 .../drm/i915/display/intel_display_debugfs.c  |  9 +++-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 51 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.h |  4 +-
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 7bcd90384a46d..a14b86a07e545 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -494,6 +494,7 @@ static void intel_panel_info(struct seq_file *m,
 static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector)
 {
+   int ret;
bool hdcp_cap, hdcp2_cap;
 
if (!intel_connector->hdcp.shim) {
@@ -501,8 +502,12 @@ static void intel_hdcp_info(struct seq_file *m,
goto out;
}
 
-   hdcp_cap = intel_hdcp_capable(intel_connector);
-   hdcp2_cap = intel_hdcp2_capable(intel_connector);
+   ret = intel_hdcp_capable(intel_connector, _cap);
+   if (ret)
+   hdcp_cap = false;
+   ret = intel_hdcp2_capable(intel_connector, _cap);
+   if (ret)
+   hdcp2_cap = false;
 
if (hdcp_cap)
seq_puts(m, "HDCP1.4 ");
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0a20bc41be55d..61a862ae1f286 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -177,50 +177,49 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port 
*dig_port,
 }
 
 /* Is HDCP1.4 capable on Platform and Sink */
-bool intel_hdcp_capable(struct intel_connector *connector)
+int intel_hdcp_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
-   bool capable = false;
u8 bksv[5];
 
+   *capable = false;
+
if (!shim)
-   return capable;
+   return 0;
 
-   if (shim->hdcp_capable) {
-   shim->hdcp_capable(dig_port, );
-   } else {
-   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
-   capable = true;
-   }
+   if (shim->hdcp_capable)
+   return shim->hdcp_capable(dig_port, capable);
+
+   if (!intel_hdcp_read_valid_bksv(dig_port, shim, bksv))
+   *capable = true;
 
-   return capable;
+   return 0;
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-bool intel_hdcp2_capable(struct intel_connector *connector)
+int intel_hdcp2_capable(struct intel_connector *connector, bool *capable)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = >hdcp;
-   bool capable = false;
+
+   *capable = false;
 
/* I915 support for HDCP2.2 */
if (!hdcp->hdcp2_supported)
-   return false;
+   return 0;
 
/* MEI interface is solid */
mutex_lock(_priv->display.hdcp.comp_mutex);
if (!dev_priv->display.hdcp.comp_added ||  
!dev_priv->display.hdcp.master) {
mutex_unlock(_priv->display.hdcp.comp_mutex);
-   return false;
+   return 0;
}
mutex_unlock(_priv->display.hdcp.comp_mutex);
 
/* Sink's capability for HDCP2.2 */
-   hdcp->shim->hdcp_2_2_capable(dig_port, );
-
-   return capable;
+   return hdcp->shim->hdcp_2_2_capable(dig_port, capable);
 }
 
 static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
@@ -2355,6 +2354,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
struct intel_hdcp *hdcp = >hdcp;
unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
+   bool capable;
int ret = -EINVAL;
 
if (!hdcp->shim)
@@ -2373,21 +2373,27 @@ int intel_hdcp_enable(struct intel_connector *connector,
 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
 */
-   if (intel_hdcp2_capable(connector)) {
+   ret = intel_hdcp2_capable(connector, );
+