Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev
On Thu, Jul 13, 2023 at 9:04 AM Uwe Kleine-König wrote: > > hello Sean, > > On Wed, Jul 12, 2023 at 02:31:02PM -0400, Sean Paul wrote: > > I'd really prefer this patch (series or single) is not accepted. This > > will cause problems for everyone cherry-picking patches to a > > downstream kernel (LTS or distro tree). I usually wouldn't expect > > sympathy here, but the questionable benefit does not outweigh the cost > > IM[biased]O. > > I agree that for backports this isn't so nice. However with the split > approach (that was argumented against here) it's not soo bad. Patch #1 > (and similar changes for the other affected structures) could be > trivially backported and with that it doesn't matter if you write dev or > drm (or whatever name is chosen in the end); both work in the same way. Patch #1 avoids the need to backport the entire set, however every change occuring after the rename patches will cause conflicts on future cherry-picks. Downstream kernels will have to backport the whole set. Backporting the entire set will create an epoch in downstream kernels where cherry-picking patches preceding this set will need to undergo conflict resolution as well. As mentioned in my previous email, I don't expect sympathy here, it's part of maintaining a downstream kernel, but there is a real cost to kernel consumers. > > But even with the one-patch-per-rename approach I'd consider the > renaming a net win, because ease of understanding code has a big value. > It's value is not so easy measurable as "conflicts when backporting", > but it also matters in say two years from now, while backporting > shouldn't be an issue then any more. You've rightly identified the conjecture in your statement. I've been on both sides of the argument, having written/maintained drm code upstream and cherry-picked changes to a downstream kernel. Perhaps it's because drm's definition of dev is ingrained in my muscle memory, or maybe it's because I don't do a lot of upstream development these days, but I just have a hard time seeing the benefit here. I appreciate your engagement on the topic, thank you! Sean > > Thanks for your input, best regards > Uwe > > -- > Pengutronix e.K. | Uwe Kleine-König| > Industrial Linux Solutions | https://www.pengutronix.de/ |
Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev
On Wed, Jul 12, 2023 at 10:52 AM Jani Nikula wrote: > > On Wed, 12 Jul 2023, Uwe Kleine-König wrote: > > Hello, > > > > while I debugged an issue in the imx-lcdc driver I was constantly > > irritated about struct drm_device pointer variables being named "dev" > > because with that name I usually expect a struct device pointer. > > > > I think there is a big benefit when these are all renamed to "drm_dev". > > I have no strong preference here though, so "drmdev" or "drm" are fine > > for me, too. Let the bikesheding begin! > > > > Some statistics: > > > > $ git grep -ohE 'struct drm_device *\* *[^ (),;]*' v6.5-rc1 | sort | uniq > > -c | sort -n > > 1 struct drm_device *adev_to_drm > > 1 struct drm_device *drm_ > > 1 struct drm_device *drm_dev > > 1 struct drm_device*drm_dev > > 1 struct drm_device *pdev > > 1 struct drm_device *rdev > > 1 struct drm_device *vdev > > 2 struct drm_device *dcss_drv_dev_to_drm > > 2 struct drm_device **ddev > > 2 struct drm_device *drm_dev_alloc > > 2 struct drm_device *mock > > 2 struct drm_device *p_ddev > > 5 struct drm_device *device > > 9 struct drm_device * dev > > 25 struct drm_device *d > > 95 struct drm_device * > > 216 struct drm_device *ddev > > 234 struct drm_device *drm_dev > > 611 struct drm_device *drm > >4190 struct drm_device *dev > > > > This series starts with renaming struct drm_crtc::dev to drm_dev. If > > it's not only me and others like the result of this effort it should be > > followed up by adapting the other structs and the individual usages in > > the different drivers. > > I think this is an unnecessary change. In drm, a dev is usually a drm > device, i.e. struct drm_device *. As shown by the numbers above. > I'd really prefer this patch (series or single) is not accepted. This will cause problems for everyone cherry-picking patches to a downstream kernel (LTS or distro tree). I usually wouldn't expect sympathy here, but the questionable benefit does not outweigh the cost IM[biased]O. Sean > If folks insist on following through with this anyway, I'm firmly in the > camp the name should be "drm" and nothing else. > > > BR, > Jani. > > > -- > Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH] Documentation: vkms: clarify devres managed refernce cleanup
On Thu, Apr 27, 2023 at 12:02:18PM +0200, Daniel Vetter wrote: > On Tue, Apr 25, 2023 at 08:02:40AM +, Brandon Pollack wrote: > > added documentation to drm_dev_unregister clarifying that devres managed > > devices allocated with devm_drm_dev_alloc do not require calls to > > drm_dev_put. > > > > Signed-off-by: Brandon Pollack > > > > --- > > > > This is my first patch to any tree. I've tried my best to read as many > > kernel docs etc as possible (wip). This took me a moment to realize so I > > figured it was as good a candidate as any for a first patch (at the very > > least to make sure I have the whole patching process figured out). I > > hope to make more janitorial changes as I continue to learn leading up > > to the work I hope to do. > > > > We're hoping to add multiple display hotplug output support to VKMS for > > testing purposes. Some work has been done already, but we'll be taking > > over moving forward. Our intent is to remain involved and assist in > > maintaining these changes. > > > > Looking forward to your comments/advice (now and henceforth!) > > Looking good! > > Reviewed-by: Daniel Vetter > > Since you're @chromium.org I'm assuming that one of the cros committers > will push this to drm-misc-next. If not please holler. Applied to drm-misc-next, thank you for the review. Sean > -Daniel > > > --- > > drivers/gpu/drm/drm_drv.c | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > > index cee0cc522ed9..12687dd9e1ac 100644 > > --- a/drivers/gpu/drm/drm_drv.c > > +++ b/drivers/gpu/drm/drm_drv.c > > @@ -969,7 +969,9 @@ EXPORT_SYMBOL(drm_dev_register); > > * > > * Unregister the DRM device from the system. This does the reverse of > > * drm_dev_register() but does not deallocate the device. The caller must > > call > > - * drm_dev_put() to drop their final reference. > > + * drm_dev_put() to drop their final reference, unless it is managed with > > devres > > + * (as devices allocated with devm_drm_dev_alloc() are), in which case > > there is > > + * already an unwind action registered. > > * > > * A special form of unregistering for hotpluggable devices is > > drm_dev_unplug(), > > * which can be called while there are still open users of @dev. > > -- > > 2.40.0.634.g4ca3ef3211-goog > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 1/2] drm/atomic: Allow vblank-enabled + self-refresh "disable"
On Mon, Jan 09, 2023 at 05:18:16PM -0800, Brian Norris wrote: > The self-refresh helper framework overloads "disable" to sometimes mean > "go into self-refresh mode," and this mode activates automatically > (e.g., after some period of unchanging display output). In such cases, > the display pipe is still considered "on", and user-space is not aware > that we went into self-refresh mode. Thus, users may expect that > vblank-related features (such as DRM_IOCTL_WAIT_VBLANK) still work > properly. > > However, we trigger the WARN_ONCE() here if a CRTC driver tries to leave > vblank enabled. > > Add a different expectation: that CRTCs *should* leave vblank enabled > when going into self-refresh. > > This patch is preparation for another patch -- "drm/rockchip: vop: Leave > vblank enabled in self-refresh" -- which resolves conflicts between the > above self-refresh behavior and the API tests in IGT's kms_vblank test > module. > > == Some alternatives discussed: == > > It's likely that on many display controllers, vblank interrupts will > turn off when the CRTC is disabled, and so in some cases, self-refresh > may not support vblank. To support such cases, we might consider > additions to the generic helpers such that we fire vblank events based > on a timer. > > However, there is currently only one driver using the common > self-refresh helpers (i.e., rockchip), and at least as of commit > bed030a49f3e ("drm/rockchip: Don't fully disable vop on self refresh"), > the CRTC hardware is powered enough to continue to generate vblank > interrupts. > > So we chose the simpler option of leaving vblank interrupts enabled. We > can reevaluate this decision and perhaps augment the helpers if/when we > gain a second driver that has different requirements. > > v3: > * include discussion summary > > v2: > * add 'ret != 0' warning case for self-refresh > * describe failing test case and relation to drm/rockchip patch better > > Cc: # dependency for "drm/rockchip: vop: Leave > # vblank enabled in self-refresh" > Signed-off-by: Brian Norris Pushed both patches to drm-misc-next, thanks Brian > --- > drivers/gpu/drm/drm_atomic_helper.c | 11 ++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > b/drivers/gpu/drm/drm_atomic_helper.c > index d579fd8f7cb8..a22485e3e924 100644 > --- a/drivers/gpu/drm/drm_atomic_helper.c > +++ b/drivers/gpu/drm/drm_atomic_helper.c > @@ -1209,7 +1209,16 @@ disable_outputs(struct drm_device *dev, struct > drm_atomic_state *old_state) > continue; > > ret = drm_crtc_vblank_get(crtc); > - WARN_ONCE(ret != -EINVAL, "driver forgot to call > drm_crtc_vblank_off()\n"); > + /* > + * Self-refresh is not a true "disable"; ensure vblank remains > + * enabled. > + */ > + if (new_crtc_state->self_refresh_active) > + WARN_ONCE(ret != 0, > + "driver disabled vblank in self-refresh\n"); > + else > + WARN_ONCE(ret != -EINVAL, > + "driver forgot to call > drm_crtc_vblank_off()\n"); > if (ret == 0) > drm_crtc_vblank_put(crtc); > } > -- > 2.39.0.314.g84b9a713c41-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v2 1/3] drm: Create support for Write-Only property blob
On Thu, Apr 27, 2023 at 5:59 AM Daniel Vetter wrote: > > On Fri, Apr 21, 2023 at 12:27:47PM -0400, Mark Yacoub wrote: > > From: Mark Yacoub > > > > [Why] > > User space might need to inject data into the kernel without allowing it > > to be read again by any user space. > > An example of where this is particularly useful is secret keys fetched > > by user space and injected into the kernel to enable content protection. > > > > [How] > > Create a DRM_MODE_CREATE_BLOB_WRITE_ONLY flag used by user space to > > create a blob and mark the blob as write only. > > On reading back the blob, data will be not be copied if it's a write > > only blob > > This makes no sense at all, why would you want to disallow reading? > Userspace already knows the key, there's not much point in hiding it from > userspace? There are varying levels of trust amongst userspace applications. For example, in CrOS we trust portions of Chrome to handle the key securely, but would like to avoid access from other portions, or users from exposing the key via modetest output. We could play whack-a-mole and try to patch up all untrusted userspace, but that doesn't seem like a scalable solution. Sean > > Also for new uapi we need the igt patches and userspace, please link > those. > -Daniel > > > > > Signed-off-by: Mark Yacoub > > --- > > drivers/gpu/drm/drm_property.c | 3 ++- > > include/drm/drm_property.h | 2 ++ > > include/uapi/drm/drm_mode.h| 6 ++ > > 3 files changed, 10 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c > > index dfec479830e49..afedf7109d002 100644 > > --- a/drivers/gpu/drm/drm_property.c > > +++ b/drivers/gpu/drm/drm_property.c > > @@ -765,7 +765,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev, > > if (!blob) > > return -ENOENT; > > > > - if (out_resp->length == blob->length) { > > + if (out_resp->length == blob->length && !blob->is_write_only) { > > if (copy_to_user(u64_to_user_ptr(out_resp->data), > >blob->data, > >blob->length)) { > > @@ -800,6 +800,7 @@ int drm_mode_createblob_ioctl(struct drm_device *dev, > > ret = -EFAULT; > > goto out_blob; > > } > > + blob->is_write_only = out_resp->flags & > > DRM_MODE_CREATE_BLOB_WRITE_ONLY; > > > > /* Dropping the lock between create_blob and our access here is safe > >* as only the same file_priv can remove the blob; at this point, it > > is > > diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h > > index 65bc9710a4702..700782f021b99 100644 > > --- a/include/drm/drm_property.h > > +++ b/include/drm/drm_property.h > > @@ -205,6 +205,7 @@ struct drm_property { > > * &drm_mode_config.property_blob_list. > > * @head_file: entry on the per-file blob list in &drm_file.blobs list. > > * @length: size of the blob in bytes, invariant over the lifetime of the > > object > > + * @is_write_only: user space can't read the blob data. > > * @data: actual data, embedded at the end of this structure > > * > > * Blobs are used to store bigger values than what fits directly into the > > 64 > > @@ -219,6 +220,7 @@ struct drm_property_blob { > > struct list_head head_global; > > struct list_head head_file; > > size_t length; > > + bool is_write_only; > > void *data; > > }; > > > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h > > index 46becedf5b2fc..10403c9a73082 100644 > > --- a/include/uapi/drm/drm_mode.h > > +++ b/include/uapi/drm/drm_mode.h > > @@ -1168,6 +1168,9 @@ struct drm_format_modifier { > > __u64 modifier; > > }; > > > > +#define DRM_MODE_CREATE_BLOB_WRITE_ONLY > > \ > > + (1 << 0) /* data of the blob can't be read by user space */ > > + > > /** > > * struct drm_mode_create_blob - Create New blob property > > * > > @@ -1181,6 +1184,9 @@ struct drm_mode_create_blob { > > __u32 length; > > /** @blob_id: Return: new property ID. */ > > __u32 blob_id; > > + /** Flags for special handling. */ > > + __u32 flags; > > + __u32 pad; > > }; > > > > /** > > -- > > 2.40.0.634.g4ca3ef3211-goog > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch
Re: [PATCH v6 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
On Thu, Jan 19, 2023 at 11:35:32AM +0100, Krzysztof Kozlowski wrote: > On 18/01/2023 20:30, Mark Yacoub wrote: > > From: Sean Paul > > > > This patch adds the register ranges required for HDCP key injection and > > Do not use "This commit/patch". > https://elixir.bootlin.com/linux/v5.17.1/source/Documentation/process/submitting-patches.rst#L95 > > This applies to all your patches. Fix it everywhere. My goodness, this is peak bikeshedding. Surely we have better things to do with our time? > > > 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". > > What does it mean? Where do you do it? > > > > > 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 > > Drop the links. Why? I've always done this, it seems helpful to me? > > > > > 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 > > > > --- > > Changelog after --- . It's common practice in drm subsystem to include this in the commit message. Sean > > > arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 > > 1 file changed, 8 insertions(+) > > > > Best regards, > Krzysztof > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v6 01/10] drm/hdcp: Add drm_hdcp_atomic_check()
On Thu, Jan 19, 2023 at 11:37:52AM +0100, Krzysztof Kozlowski wrote: > On 18/01/2023 20:30, Mark Yacoub wrote: > > 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 > > It seems all your previous versions were sent not to correct people and > lists. Therefore we see it for the first time even though it is v6! Hi Krzysztof, Thanks for your review comments. Here are the addresses the last version was sent to, who is missing? To: dri-devel@lists.freedesktop.org, jani.nik...@intel.com, intel-...@lists.freedesktop.org, freedr...@lists.freedesktop.org, rodrigo.v...@intel.com Cc: bjorn.anders...@linaro.org, swb...@chromium.org, abhin...@codeaurora.org, markyac...@chromium.org, Sean Paul , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Jani Nikula , Joonas Lahtinen , Tvrtko Ursulin > It's > not the first such weird CC list in chromium, so maybe your > organisational process could be improved? Not only for you but for > colleagues as well, so you all start using get_maintainers.pl on newest > kernel (not something ancient)? I can't really speak for others, but I use MAINTAINERS from drm-tip. The previous patch sets were sent before 24df12013853 ("MAINTAINERS: Add Dmitry as MSM DRM driver co-maintainer"), which might explain why you think there are absences? Thanks again, Sean > > Best regards, > Krzysztof > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] drm/docs: Explicitly document default CRTC background behavior
On Tue, Jan 03, 2023 at 06:32:58PM +, Simon Ser wrote: > Nice! > > Reviewed-by: Simon Ser Thanks for the review, Simon! Applied to drm-misc-next. -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH] drm/docs: Explicitly document default CRTC background behavior
From: Sean Paul Add a paragraph explaining that the default behavior for areas which are not covered by planes or where planes are blending with the CRTC background, is black. This is alluded to in the "pixel blend mode" property docs, but not called out explicitly. Signed-off-by: Sean Paul --- drivers/gpu/drm/drm_plane.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 33357629a7f5..24e7998d1731 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -46,6 +46,11 @@ * properties that specify how the pixels are positioned and blended, like * rotation or Z-position. All these properties are stored in &drm_plane_state. * + * Unless explicitly specified (via CRTC property or otherwise), the active area + * of a CRTC will be black by default. This means portions of the active area + * which are not covered by a plane will be black, and alpha blending of any + * planes with the CRTC background will blend with black at the lowest zpos. + * * To create a plane, a KMS drivers allocates and zeroes an instances of * &struct drm_plane (possibly as part of a larger structure) and registers it * with a call to drm_universal_plane_init(). -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v7 3/3] drm/bridge: it6505: handle HDCP request
o avoid races. Sean [1] - https://lore.kernel.org/all/20220411204741.1074308-1-s...@poorly.run/ > + > + return 0; > +} > + > +static int it6505_bridge_atomic_check(struct drm_bridge *bridge, > + struct drm_bridge_state *bridge_state, > + struct drm_crtc_state *crtc_state, > + struct drm_connector_state *conn_state) > +{ > + struct it6505 *it6505 = bridge_to_it6505(bridge); > + > + return it6505_connector_atomic_check(it6505, conn_state); > +} > + > static const struct drm_bridge_funcs it6505_bridge_funcs = { > .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, > .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, > @@ -3035,6 +3087,7 @@ static const struct drm_bridge_funcs > it6505_bridge_funcs = { > .attach = it6505_bridge_attach, > .detach = it6505_bridge_detach, > .mode_valid = it6505_bridge_mode_valid, > + .atomic_check = it6505_bridge_atomic_check, > .atomic_enable = it6505_bridge_atomic_enable, > .atomic_disable = it6505_bridge_atomic_disable, > .atomic_pre_enable = it6505_bridge_atomic_pre_enable, > @@ -3354,6 +3407,7 @@ static int it6505_i2c_probe(struct i2c_client *client, > it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; > it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | >DRM_BRIDGE_OP_HPD; > + it6505->bridge.support_hdcp = true; > drm_bridge_add(&it6505->bridge); > > return 0; > -- > 2.38.1.584.g0f3c55d4c2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 2/2] drm/bridge: anx7625: register content protect property
On Wed, Nov 02, 2022 at 07:11:47PM +0800, Hsin-Yi Wang wrote: > Set support_hdcp so the connector can register content protect proterty > when it's initializing. > Reviewed-by: Sean Paul > Signed-off-by: Hsin-Yi Wang > --- > drivers/gpu/drm/bridge/analogix/anx7625.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > b/drivers/gpu/drm/bridge/analogix/anx7625.c > index b0ff1ecb80a50..0636ac59c7399 100644 > --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > @@ -2680,6 +2680,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, > platform->bridge.type = platform->pdata.panel_bridge ? > DRM_MODE_CONNECTOR_eDP : > DRM_MODE_CONNECTOR_DisplayPort; > + platform->bridge.support_hdcp = true; > > drm_bridge_add(&platform->bridge); > > -- > 2.38.0.135.g90850a2211-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 1/2] drm_bridge: register content protect property
On Wed, Nov 02, 2022 at 07:11:46PM +0800, Hsin-Yi Wang wrote: > Some bridges are able to update HDCP status from userspace request if > they support HDCP. > > HDCP property is the same as other connector properties that needs to be > created after the connecter is initialized and before the connector is > registered. > > If there exists a bridge that supports HDCP, add the property to the > bridge connector. > Reviewed-by: Sean Paul > Signed-off-by: Hsin-Yi Wang > --- > v2->v3: > Only register the property when there exists any bridge that supports > hdcp. > --- > drivers/gpu/drm/drm_bridge_connector.c | 8 > include/drm/drm_bridge.h | 4 > 2 files changed, 12 insertions(+) > > diff --git a/drivers/gpu/drm/drm_bridge_connector.c > b/drivers/gpu/drm/drm_bridge_connector.c > index 1c7d936523df5..b4fb5da0b963f 100644 > --- a/drivers/gpu/drm/drm_bridge_connector.c > +++ b/drivers/gpu/drm/drm_bridge_connector.c > @@ -7,6 +7,7 @@ > #include > #include > > +#include > #include > #include > #include > @@ -333,6 +334,7 @@ struct drm_connector *drm_bridge_connector_init(struct > drm_device *drm, > struct i2c_adapter *ddc = NULL; > struct drm_bridge *bridge, *panel_bridge = NULL; > int connector_type; > + bool support_hdcp = false; > > bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL); > if (!bridge_connector) > @@ -376,6 +378,9 @@ struct drm_connector *drm_bridge_connector_init(struct > drm_device *drm, > > if (drm_bridge_is_panel(bridge)) > panel_bridge = bridge; > + > + if (bridge->support_hdcp) > + support_hdcp = true; > } > > if (connector_type == DRM_MODE_CONNECTOR_Unknown) { > @@ -398,6 +403,9 @@ struct drm_connector *drm_bridge_connector_init(struct > drm_device *drm, > if (panel_bridge) > drm_panel_bridge_set_orientation(connector, panel_bridge); > > + if (support_hdcp && IS_ENABLED(CONFIG_DRM_DISPLAY_HDCP_HELPER)) > + drm_connector_attach_content_protection_property(connector, > true); > + > return connector; > } > EXPORT_SYMBOL_GPL(drm_bridge_connector_init); > diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h > index 6b65b0dfb4fb4..1d2ab70f3436a 100644 > --- a/include/drm/drm_bridge.h > +++ b/include/drm/drm_bridge.h > @@ -768,6 +768,10 @@ struct drm_bridge { >* modes. >*/ > bool interlace_allowed; > + /** > + * @support_hdcp: Indicate that the bridge supports HDCP. > + */ > + bool support_hdcp; > /** >* @ddc: Associated I2C adapter for DDC access, if any. >*/ > -- > 2.38.0.135.g90850a2211-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v2] drm/mediatek: make eDP panel as the first connected connector
On Thu, Nov 10, 2022 at 1:49 PM Gil Dekel wrote: > > [Why] > Some userspaces assume that the first connected connector is the "main" > display, which supposed to display, for example, the login screen. > For laptops, this should be the internal connector. > > [How] > This patch calls drm_helper_move_panel_connectors_to_head() right before > crtc creation to ensure internal connectors are at the top of the > connector list. > > Tested by ensuring the internal panels are at the top of the connector > list via modetest -c. > > This patch does to mediatek what the following patch > https://www.spinics.net/lists/stable/msg590605.html > did for qualcomm. > Reviewed-by: Sean Paul > Signed-off-by: Gil Dekel > Tested-by: Gil Dekel > --- > v2: Fix copy-paste errors in commit message so it's relevant for this > patch and the mediatek driver. > --- > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > index 91f58db5915f..76daaf6a0945 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c > @@ -386,6 +386,12 @@ static int mtk_drm_kms_init(struct drm_device *drm) > if (ret) > goto put_mutex_dev; > > + /* > +* Ensure internal panels are at the top of the connector list before > +* crtc creation. > +*/ > + drm_helper_move_panel_connectors_to_head(drm); > + > /* > * We currently support two fixed data streams, each optional, > * and each statically assigned to a crtc: > -- > Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics
Re: [PATCH v2] drm_bridge: register content protect property
On Mon, Oct 17, 2022 at 9:49 AM Hsin-Yi Wang wrote: > > On Wed, Oct 12, 2022 at 12:20 PM Hsin-Yi Wang wrote: > > > > Some bridges are able to update HDCP status from userspace request if > > they support HDCP. > > > > HDCP property is the same as other connector properties that need to be > > created after the connecter is initialized and before the connector is > > registered. > > > anx7625 is a user for this. I feel like we should not unconditionally attach this property for bridges, this should be done in the driver which supports it IMO. Sean > > > > Signed-off-by: Hsin-Yi Wang > > Reported-by: kernel test robot > > --- > > v2: Fix compile error when config is not set. > > --- > > drivers/gpu/drm/drm_bridge_connector.c | 3 +++ > > include/drm/display/drm_hdcp_helper.h | 8 > > 2 files changed, 11 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_bridge_connector.c > > b/drivers/gpu/drm/drm_bridge_connector.c > > index 1c7d936523df5..a3b9ef8dc3f0b 100644 > > --- a/drivers/gpu/drm/drm_bridge_connector.c > > +++ b/drivers/gpu/drm/drm_bridge_connector.c > > @@ -7,6 +7,7 @@ > > #include > > #include > > > > +#include > > #include > > #include > > #include > > @@ -398,6 +399,8 @@ struct drm_connector *drm_bridge_connector_init(struct > > drm_device *drm, > > if (panel_bridge) > > drm_panel_bridge_set_orientation(connector, panel_bridge); > > > > + drm_connector_attach_content_protection_property(connector, true); > > + > > return connector; > > } > > EXPORT_SYMBOL_GPL(drm_bridge_connector_init); > > diff --git a/include/drm/display/drm_hdcp_helper.h > > b/include/drm/display/drm_hdcp_helper.h > > index 8aaf87bf27351..c65d9f06a2532 100644 > > --- a/include/drm/display/drm_hdcp_helper.h > > +++ b/include/drm/display/drm_hdcp_helper.h > > @@ -15,8 +15,16 @@ struct drm_device; > > struct drm_connector; > > > > int drm_hdcp_check_ksvs_revoked(struct drm_device *dev, u8 *ksvs, u32 > > ksv_count); > > +#if defined(CONFIG_DRM_DISPLAY_HDCP_HELPER) > > int drm_connector_attach_content_protection_property(struct drm_connector > > *connector, > > bool > > hdcp_content_type); > > +#else > > +static inline int drm_connector_attach_content_protection_property(struct > > drm_connector *connector, > > + bool > > hdcp_content_type) > > +{ > > + return 0; > > +} > > +#endif > > void drm_hdcp_update_content_protection(struct drm_connector *connector, > > u64 val); > > > > #endif > > -- > > 2.38.0.rc1.362.ged0d419d3c-goog > >
Re: [PATCH 5/5] drm/vkms: Support registering configfs devices
ne_entry->plane) > + break; > + > + if (is_object_linked( > + &plane_entry->config_plane->possible_crtcs, > + config_crtc->crtc_config_idx)) { > + plane_entry->plane->base.possible_crtcs |= > + drm_crtc_mask(&vkms_crtc->base); > + } > + } > + > + for (int j = 0; j < output->num_encoders; j++) { > + struct encoder_map *encoder_entry = &encoder_map[j]; > + > + if (is_object_linked(&encoder_entry->config_encoder > + ->possible_crtcs, > + config_crtc->crtc_config_idx)) { > + encoder_entry->encoder->possible_crtcs |= > + drm_crtc_mask(&vkms_crtc->base); > + } > + } > + > + if (card->vkms_device->config.writeback) { > + ret = vkms_enable_writeback_connector(card, vkms_crtc); > + if (ret) > + DRM_WARN( > + "Failed to init writeback connector for > config crtc: %s", > + item->ci_name); Nit: drm_dbg and please print the error message. > + } > } > > - memset(output, 0, sizeof(struct vkms_output)); > + drm_mode_config_reset(dev); > + > + return 0; > > +cleanup_output: > + vkms_output_clear(card); > + resume_device_irqs(); // REMOVE REMOVE? > return ret; > } > > -int vkms_output_init(struct vkms_card *card, int index) > +void vkms_output_clear(struct vkms_card *card) > { > - return -ENOTSUPP; > + struct vkms_output *output = &card->output; > + > + for (int i = 0; i < output->num_crtcs; i++) { > + drm_crtc_cleanup(&output->crtcs[i].base); > + } > + for (int i = 0; i < output->num_encoders; i++) { > + drm_encoder_cleanup(&output->encoders[i]); > + } > + for (int i = 0; i < output->num_connectors; i++) { > + drm_connector_cleanup(&output->connectors[i]); > + } > + for (int i = 0; i < output->num_planes; i++) { > + drm_plane_cleanup(&output->planes[i].base); > + } Nit: braces for all of these > + > + memset(output, 0, sizeof(*output)); Same concerns about memset as before. > } > -- > 2.37.1.359.gd136c6c3e2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 4/5] drm/vkms: Add ConfigFS scaffolding to VKMS
t vkms_card *vkms_card_init(const char *name, bool > is_default) > card->platform = pdev; > card->drm.unique = card->name_buf; > card->vkms_device = &vkms_device; > - card->is_default = is_default; > + card->configfs = configfs; > + card->is_default = configfs == NULL; IMO we should get rid of is_default and just check !configfs if they're equivalent. > card->is_registered = false; > card->resource_group_id = grp; > > @@ -235,7 +239,10 @@ struct vkms_card *vkms_card_init(const char *name, bool > is_default) > > devres_close_group(&pdev->dev, grp); > list_add_tail(&card->node, &vkms_device.cards); > - > + > + if (configfs) > + configfs->card = card; > + > return card; > > out_release_group: > @@ -260,16 +267,24 @@ void vkms_card_destroy(struct vkms_card *card) > static int __init vkms_init(void) > { > struct vkms_card *card; > + int ret; > > vkms_device.config.cursor = enable_cursor; > vkms_device.config.writeback = enable_writeback; > vkms_device.config.overlay = enable_overlay; > INIT_LIST_HEAD(&vkms_device.cards); > + > + ret = vkms_init_configfs(); > + if (ret) { > + DRM_ERROR("Unable to initialize configfs\n"); > + return ret; > + } > > card = vkms_card_init("default", /* configfs */ NULL); > if (IS_ERR(card)) { > - DRM_ERROR("Unable to init default card"); > + DRM_ERROR("Unable to init default card\n"); Does this belong in an earlier change? > vkms_device_destroy(); > + vkms_unregister_configfs(); vkms_unregister_configfs() always directly follows vkms_device_destroy(), seems like it could just be called from destroy? > return PTR_ERR(card); > } > > @@ -279,6 +294,7 @@ static int __init vkms_init(void) > static void __exit vkms_exit(void) > { > vkms_device_destroy(); > + vkms_unregister_configfs(); > } > > module_init(vkms_init); > diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h > index 30ae06d7af71..f43e4c563863 100644 > --- a/drivers/gpu/drm/vkms/vkms_drv.h > +++ b/drivers/gpu/drm/vkms/vkms_drv.h > @@ -3,6 +3,7 @@ > #ifndef _VKMS_DRV_H_ > #define _VKMS_DRV_H_ > > +#include > #include > #include > > @@ -10,6 +11,7 @@ > #include > #include > #include > +#include > #include > > #define XRES_MIN20 > @@ -116,11 +118,59 @@ struct vkms_config { > bool overlay; > }; > > +struct vkms_config_links { > + struct config_group group; > + unsigned long linked_object_bitmap; > +}; > + > +struct vkms_config_connector { > + struct config_group config_group; > + struct vkms_config_links possible_encoders; > +}; > + > +struct vkms_config_crtc { > + struct config_group config_group; > + unsigned long crtc_config_idx; > +}; > + > +struct vkms_config_encoder { > + struct config_group config_group; > + struct vkms_config_links possible_crtcs; > + unsigned long encoder_config_idx; > +}; > + > +struct vkms_config_plane { > + struct config_group config_group; > + struct vkms_config_links possible_crtcs; > + enum drm_plane_type type; > +}; > + > +struct vkms_card; > + > +struct vkms_configfs { > + /* Directory group containing connector configs, e.g. > /config/vkms/card/ */ > + struct config_group card_group; > + /* Directory group containing connector configs, e.g. > /config/vkms/card/connectors/ */ > + struct config_group connectors_group; > + /* Directory group containing CRTC configs, e.g. > /config/vkms/card/crtcs/ */ > + struct config_group crtcs_group; > + /* Directory group containing encoder configs, e.g. > /config/vkms/card/encoders/ */ > + struct config_group encoders_group; > + /* Directory group containing plane configs, e.g. > /config/vkms/card/planes/ */ > + struct config_group planes_group; > + > + unsigned long allocated_crtcs; > + unsigned long allocated_encoders; For bitmasks you probably want to explicitly specify their length by using u32/u64 types. This probably applies elsewhere too. > + > + struct vkms_card *card; > +}; > + > struct vkms_card { > struct platform_device *platform; > struct drm_device drm; > struct list_head node; > struct vkms_output output; > + struct vkms_configfs *configfs; > struct vkms_device *vkms_device; > /* storage for the value of drm->unique, giving this dev a unique busid > */ > char name_buf[64]; > @@ -149,8 +199,27 @@ struct vkms_device { > #define to_vkms_plane_state(target)\ > container_of(target, struct vkms_plane_state, base.base) > > +#define item_to_configfs(item)\ > + container_of(to_config_group(item), struct vkms_configfs, card_group) > + > +#define item_to_config_connector(item)\ > + container_of(to_config_group(item), struct vkms_config_connector, > config_group) > + > +#define item_to_config_crtc(item) \ > + container_of(to_config_group(item), struct vkms_config_crtc, > config_group) > + > +#define item_to_config_encoder(item) \ > + container_of(to_config_group(item), struct vkms_config_encoder, > config_group) > + > +#define item_to_config_plane(item) \ > + container_of(to_config_group(item), struct vkms_config_plane, > config_group) > + > +#define item_to_config_links(item) \ > + container_of(to_config_group(item), struct vkms_config_links, group) > + > /* Cards */ > -struct vkms_card *vkms_card_init(const char *name, bool is_default); > +struct vkms_card *vkms_card_init(const char *name, > + struct vkms_configfs *configfs); > void vkms_card_destroy(struct vkms_card *card); > > /* CRTC */ > @@ -176,4 +245,8 @@ void vkms_set_composer(struct vkms_crtc *vkms_crtc, bool > enabled); > /* Writeback */ > int vkms_enable_writeback_connector(struct vkms_card *card, struct vkms_crtc > *vkms_crtc); > > +/* ConfigFS Support */ > +int vkms_init_configfs(void); > +void vkms_unregister_configfs(void); > + > #endif /* _VKMS_DRV_H_ */ > diff --git a/drivers/gpu/drm/vkms/vkms_output.c > b/drivers/gpu/drm/vkms/vkms_output.c > index 2b72d8e763a8..e343a9c1f311 100644 > --- a/drivers/gpu/drm/vkms/vkms_output.c > +++ b/drivers/gpu/drm/vkms/vkms_output.c > @@ -1,10 +1,14 @@ > // SPDX-License-Identifier: GPL-2.0+ > > -#include "vkms_drv.h" > +#include > +#include > + > #include > #include > #include > > +#include "vkms_drv.h" > + > static void vkms_connector_destroy(struct drm_connector *connector) > { > drm_connector_cleanup(connector); > @@ -171,3 +175,8 @@ int vkms_output_init_default(struct vkms_card *card, int > index) > > return ret; > } > + > +int vkms_output_init(struct vkms_card *card, int index) > +{ > + return -ENOTSUPP; > +} I think you can drop this from the patch and introduce it when it's useful. > -- > 2.37.1.359.gd136c6c3e2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 3/5] drm/vkms: Support multiple objects (crtcs, etc.) per card
drv.h" > @@ -65,6 +66,19 @@ static void vkms_plane_destroy_state(struct drm_plane > *plane, > kfree(vkms_state); > } > > +static void vkms_plane_destroy(struct drm_plane *plane) I think this could be replaced by drm_plane_helper_destroy() instead of rolling your own destroy function. > +{ > + struct vkms_plane *vkms_plane = > + container_of(plane, struct vkms_plane, base); > + > + if (plane->state) { > + vkms_plane_destroy_state(plane, plane->state); > + plane->state = NULL; > + } > + > + memset(vkms_plane, 0, sizeof(struct vkms_plane)); > +} > + > static void vkms_plane_reset(struct drm_plane *plane) > { > struct vkms_plane_state *vkms_state; > @@ -86,8 +100,9 @@ static void vkms_plane_reset(struct drm_plane *plane) > static const struct drm_plane_funcs vkms_plane_funcs = { > .update_plane = drm_atomic_helper_update_plane, > .disable_plane = drm_atomic_helper_disable_plane, > - .reset = vkms_plane_reset, > - .atomic_duplicate_state = vkms_plane_duplicate_state, > + .destroy= vkms_plane_destroy, > + .reset = vkms_plane_reset, Nit: Remove space before tab after .destroy and .reset. I think they're also not properly aligned. > + .atomic_duplicate_state = vkms_plane_duplicate_state, > .atomic_destroy_state = vkms_plane_destroy_state, > }; > > @@ -159,13 +174,20 @@ static const struct drm_plane_helper_funcs > vkms_primary_helper_funcs = { > }; > > struct vkms_plane *vkms_plane_init(struct vkms_card *card, > -enum drm_plane_type type, int index) > +enum drm_plane_type type) > { > struct drm_device *dev = &card->drm; > + struct vkms_output *output = &card->output; > const struct drm_plane_helper_funcs *funcs; > struct vkms_plane *plane; > const u32 *formats; > int nformats; > + int ret; > + > + if (output->num_planes >= VKMS_MAX_OUTPUT_OBJECTS) > + return ERR_PTR(ENOMEM); > + > + plane = &output->planes[output->num_planes++]; Hmm, I'm guessing this is why the destroy() hook is being hand rolled? Perhaps changing the output arrays to arrays of pointers would allow you to leverage the helpers and drmm_* > > switch (type) { > case DRM_PLANE_TYPE_PRIMARY: > @@ -186,12 +208,11 @@ struct vkms_plane *vkms_plane_init(struct vkms_card > *card, > break; > } > > - plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 1 << > index, > -&vkms_plane_funcs, > -formats, nformats, > -NULL, type, NULL); > - if (IS_ERR(plane)) > - return plane; > + ret = drm_universal_plane_init(dev, &plane->base, 0, > +&vkms_plane_funcs, formats, nformats, > +NULL, type, NULL); > + if (ret) > + return ERR_PTR(ret); > > drm_plane_helper_add(&plane->base, funcs); > > diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c > b/drivers/gpu/drm/vkms/vkms_writeback.c > index 681e7267d688..68c7a77ab93f 100644 > --- a/drivers/gpu/drm/vkms/vkms_writeback.c > +++ b/drivers/gpu/drm/vkms/vkms_writeback.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0+ > > #include > +#include Same kernel.h nit as before. > > #include > #include > @@ -94,15 +95,14 @@ static void vkms_wb_cleanup_job(struct > drm_writeback_connector *connector, > struct drm_writeback_job *job) > { > struct vkms_writeback_job *vkmsjob = job->priv; > - struct vkms_card *card; > + struct vkms_crtc *vkms_crtc = container_of(connector, struct vkms_crtc, > wb_connector); > > if (!job->fb) > return; > > drm_gem_fb_vunmap(job->fb, vkmsjob->map); > > - card = drm_device_to_vkms_card(job->fb->dev); > - vkms_set_composer(&card->output, false); > + vkms_set_composer(vkms_crtc, false); > kfree(vkmsjob); > } > > @@ -111,21 +111,20 @@ static void vkms_wb_atomic_commit(struct drm_connector > *conn, > { > struct drm_connector_state *connector_state = > drm_atomic_get_new_connector_state(state, > > conn); > - struct vkms_card *card = drm_device_to_vkms_card(conn->dev); > - struct vkms_output *output = &card->output; > - struct drm_writeback_connector *wb_conn = &output->wb_connector; > + struct vkms_crtc *vkms_crtc = > drm_crtc_to_vkms_crtc(connector_state->crtc); > + struct drm_writeback_connector *wb_conn = &vkms_crtc->wb_connector; > struct drm_connector_state *conn_state = wb_conn->base.state; > - struct vkms_crtc_state *crtc_state = output->composer_state; > + struct vkms_crtc_state *crtc_state = vkms_crtc->composer_state; > > if (!conn_state) > return; > > - vkms_set_composer(&card->output, true); > + vkms_set_composer(vkms_crtc, true); > > - spin_lock_irq(&output->composer_lock); > + spin_lock_irq(&vkms_crtc->composer_lock); > crtc_state->active_writeback = conn_state->writeback_job->priv; > crtc_state->wb_pending = true; > - spin_unlock_irq(&output->composer_lock); > + spin_unlock_irq(&vkms_crtc->composer_lock); > drm_writeback_queue_job(wb_conn, connector_state); > } > > @@ -136,11 +135,11 @@ static const struct drm_connector_helper_funcs > vkms_wb_conn_helper_funcs = { > .atomic_commit = vkms_wb_atomic_commit, > }; > > -int vkms_enable_writeback_connector(struct vkms_card *card) > +int vkms_enable_writeback_connector(struct vkms_card *card, struct vkms_crtc > *vkms_crtc) > { > - struct drm_writeback_connector *wb = &card->output.wb_connector; > + struct drm_writeback_connector *wb = &vkms_crtc->wb_connector; > > - card->output.wb_connector.encoder.possible_crtcs = 1; > + vkms_crtc->wb_connector.encoder.possible_crtcs = 1; > drm_connector_helper_add(&wb->base, &vkms_wb_conn_helper_funcs); > > return drm_writeback_connector_init(&card->drm, wb, > -- > 2.37.1.359.gd136c6c3e2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 2/5] drm/vkms: VKMS now supports more than one "card"
ry = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY, index); > + primary = vkms_plane_init(card, DRM_PLANE_TYPE_PRIMARY, index); > if (IS_ERR(primary)) > return PTR_ERR(primary); > > - if (vkmsdev->config.overlay) { > + if (config->overlay) { > for (n = 0; n < NUM_OVERLAY_PLANES; n++) { > - ret = vkms_add_overlay_plane(vkmsdev, index, crtc); > + ret = vkms_add_overlay_plane(card, index, crtc); > if (ret) > return ret; > } > } > > - if (vkmsdev->config.cursor) { > - cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR, index); > + if (config->cursor) { > + cursor = vkms_plane_init(card, DRM_PLANE_TYPE_CURSOR, index); > if (IS_ERR(cursor)) > return PTR_ERR(cursor); > } > @@ -103,8 +104,8 @@ int vkms_output_init(struct vkms_device *vkmsdev, int > index) > goto err_attach; > } > > - if (vkmsdev->config.writeback) { > - writeback = vkms_enable_writeback_connector(vkmsdev); > + if (config->writeback) { > + writeback = vkms_enable_writeback_connector(card); > if (writeback) > DRM_ERROR("Failed to init writeback connector\n"); > } > diff --git a/drivers/gpu/drm/vkms/vkms_plane.c > b/drivers/gpu/drm/vkms/vkms_plane.c > index d8eb674b49a6..28abd61a0bb9 100644 > --- a/drivers/gpu/drm/vkms/vkms_plane.c > +++ b/drivers/gpu/drm/vkms/vkms_plane.c > @@ -158,10 +158,10 @@ static const struct drm_plane_helper_funcs > vkms_primary_helper_funcs = { > DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, > }; > > -struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, > +struct vkms_plane *vkms_plane_init(struct vkms_card *card, > enum drm_plane_type type, int index) > { > - struct drm_device *dev = &vkmsdev->drm; > + struct drm_device *dev = &card->drm; > const struct drm_plane_helper_funcs *funcs; > struct vkms_plane *plane; > const u32 *formats; > diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c > b/drivers/gpu/drm/vkms/vkms_writeback.c > index af1604dfbbaf..681e7267d688 100644 > --- a/drivers/gpu/drm/vkms/vkms_writeback.c > +++ b/drivers/gpu/drm/vkms/vkms_writeback.c > @@ -94,15 +94,15 @@ static void vkms_wb_cleanup_job(struct > drm_writeback_connector *connector, > struct drm_writeback_job *job) > { > struct vkms_writeback_job *vkmsjob = job->priv; > - struct vkms_device *vkmsdev; > + struct vkms_card *card; > > if (!job->fb) > return; > > drm_gem_fb_vunmap(job->fb, vkmsjob->map); > > - vkmsdev = drm_device_to_vkms_device(job->fb->dev); > - vkms_set_composer(&vkmsdev->output, false); > + card = drm_device_to_vkms_card(job->fb->dev); > + vkms_set_composer(&card->output, false); > kfree(vkmsjob); > } > > @@ -111,8 +111,8 @@ static void vkms_wb_atomic_commit(struct drm_connector > *conn, > { > struct drm_connector_state *connector_state = > drm_atomic_get_new_connector_state(state, > > conn); > - struct vkms_device *vkmsdev = drm_device_to_vkms_device(conn->dev); > - struct vkms_output *output = &vkmsdev->output; > + struct vkms_card *card = drm_device_to_vkms_card(conn->dev); > + struct vkms_output *output = &card->output; > struct drm_writeback_connector *wb_conn = &output->wb_connector; > struct drm_connector_state *conn_state = wb_conn->base.state; > struct vkms_crtc_state *crtc_state = output->composer_state; > @@ -120,7 +120,7 @@ static void vkms_wb_atomic_commit(struct drm_connector > *conn, > if (!conn_state) > return; > > - vkms_set_composer(&vkmsdev->output, true); > + vkms_set_composer(&card->output, true); > > spin_lock_irq(&output->composer_lock); > crtc_state->active_writeback = conn_state->writeback_job->priv; > @@ -136,14 +136,14 @@ static const struct drm_connector_helper_funcs > vkms_wb_conn_helper_funcs = { > .atomic_commit = vkms_wb_atomic_commit, > }; > > -int vkms_enable_writeback_connector(struct vkms_device *vkmsdev) > +int vkms_enable_writeback_connector(struct vkms_card *card) > { > - struct drm_writeback_connector *wb = &vkmsdev->output.wb_connector; > + struct drm_writeback_connector *wb = &card->output.wb_connector; > > - vkmsdev->output.wb_connector.encoder.possible_crtcs = 1; > + card->output.wb_connector.encoder.possible_crtcs = 1; > drm_connector_helper_add(&wb->base, &vkms_wb_conn_helper_funcs); > > - return drm_writeback_connector_init(&vkmsdev->drm, wb, > + return drm_writeback_connector_init(&card->drm, wb, > &vkms_wb_connector_funcs, > &vkms_wb_encoder_helper_funcs, > vkms_wb_formats, > -- > 2.37.1.359.gd136c6c3e2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 3/5] drm/vkms: Support multiple objects (crtcs, etc.) per card
On Fri, Aug 05, 2022 at 06:27:08PM +, Sean Paul wrote: > On Fri, Jul 22, 2022 at 05:32:10PM -0400, Jim Shargo wrote: > > This is a small refactor to make ConfigFS support easier. > > > > We now store the vkms_device statically, and maintain a list of > > "cards", each representing a different virtual DRM driver. > > > > We also make it clear when a card is "default", that is created at > > initialization, and not. This is because, due to limitations on what we > > can do with the configfs API, the default card won't be reflected in > > configfs and is initialized in a unique way. > > > > Since we're only managing a single card, this should be a no-op. > > > > Signed-off-by: Jim Shargo /snip What a mess, I replied to the wrong patch. The review here is targeting PATCH 2/5 despite the title and reply-to.
Re: [PATCH 3/5] drm/vkms: Support multiple objects (crtcs, etc.) per card
return PTR_ERR(primary); > > - if (vkmsdev->config.overlay) { > + if (config->overlay) { > for (n = 0; n < NUM_OVERLAY_PLANES; n++) { > - ret = vkms_add_overlay_plane(vkmsdev, index, crtc); > + ret = vkms_add_overlay_plane(card, index, crtc); > if (ret) > return ret; > } > } > > - if (vkmsdev->config.cursor) { > - cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR, index); > + if (config->cursor) { > + cursor = vkms_plane_init(card, DRM_PLANE_TYPE_CURSOR, index); > if (IS_ERR(cursor)) > return PTR_ERR(cursor); > } > @@ -103,8 +104,8 @@ int vkms_output_init(struct vkms_device *vkmsdev, int > index) > goto err_attach; > } > > - if (vkmsdev->config.writeback) { > - writeback = vkms_enable_writeback_connector(vkmsdev); > + if (config->writeback) { > + writeback = vkms_enable_writeback_connector(card); > if (writeback) > DRM_ERROR("Failed to init writeback connector\n"); > } > diff --git a/drivers/gpu/drm/vkms/vkms_plane.c > b/drivers/gpu/drm/vkms/vkms_plane.c > index d8eb674b49a6..28abd61a0bb9 100644 > --- a/drivers/gpu/drm/vkms/vkms_plane.c > +++ b/drivers/gpu/drm/vkms/vkms_plane.c > @@ -158,10 +158,10 @@ static const struct drm_plane_helper_funcs > vkms_primary_helper_funcs = { > DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, > }; > > -struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, > +struct vkms_plane *vkms_plane_init(struct vkms_card *card, > enum drm_plane_type type, int index) > { > - struct drm_device *dev = &vkmsdev->drm; > + struct drm_device *dev = &card->drm; > const struct drm_plane_helper_funcs *funcs; > struct vkms_plane *plane; > const u32 *formats; > diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c > b/drivers/gpu/drm/vkms/vkms_writeback.c > index af1604dfbbaf..681e7267d688 100644 > --- a/drivers/gpu/drm/vkms/vkms_writeback.c > +++ b/drivers/gpu/drm/vkms/vkms_writeback.c > @@ -94,15 +94,15 @@ static void vkms_wb_cleanup_job(struct > drm_writeback_connector *connector, > struct drm_writeback_job *job) > { > struct vkms_writeback_job *vkmsjob = job->priv; > - struct vkms_device *vkmsdev; > + struct vkms_card *card; > > if (!job->fb) > return; > > drm_gem_fb_vunmap(job->fb, vkmsjob->map); > > - vkmsdev = drm_device_to_vkms_device(job->fb->dev); > - vkms_set_composer(&vkmsdev->output, false); > + card = drm_device_to_vkms_card(job->fb->dev); > + vkms_set_composer(&card->output, false); > kfree(vkmsjob); > } > > @@ -111,8 +111,8 @@ static void vkms_wb_atomic_commit(struct drm_connector > *conn, > { > struct drm_connector_state *connector_state = > drm_atomic_get_new_connector_state(state, > > conn); > - struct vkms_device *vkmsdev = drm_device_to_vkms_device(conn->dev); > - struct vkms_output *output = &vkmsdev->output; > + struct vkms_card *card = drm_device_to_vkms_card(conn->dev); > + struct vkms_output *output = &card->output; > struct drm_writeback_connector *wb_conn = &output->wb_connector; > struct drm_connector_state *conn_state = wb_conn->base.state; > struct vkms_crtc_state *crtc_state = output->composer_state; > @@ -120,7 +120,7 @@ static void vkms_wb_atomic_commit(struct drm_connector > *conn, > if (!conn_state) > return; > > - vkms_set_composer(&vkmsdev->output, true); > + vkms_set_composer(&card->output, true); > > spin_lock_irq(&output->composer_lock); > crtc_state->active_writeback = conn_state->writeback_job->priv; > @@ -136,14 +136,14 @@ static const struct drm_connector_helper_funcs > vkms_wb_conn_helper_funcs = { > .atomic_commit = vkms_wb_atomic_commit, > }; > > -int vkms_enable_writeback_connector(struct vkms_device *vkmsdev) > +int vkms_enable_writeback_connector(struct vkms_card *card) > { > - struct drm_writeback_connector *wb = &vkmsdev->output.wb_connector; > + struct drm_writeback_connector *wb = &card->output.wb_connector; > > - vkmsdev->output.wb_connector.encoder.possible_crtcs = 1; > + card->output.wb_connector.encoder.possible_crtcs = 1; > drm_connector_helper_add(&wb->base, &vkms_wb_conn_helper_funcs); > > - return drm_writeback_connector_init(&vkmsdev->drm, wb, > + return drm_writeback_connector_init(&card->drm, wb, > &vkms_wb_connector_funcs, > &vkms_wb_encoder_helper_funcs, > vkms_wb_formats, > -- > 2.37.1.359.gd136c6c3e2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 1/5] drm/vkms: Merge default_config and device
(&vkms_device->drm); > + drm_atomic_helper_shutdown(&vkms_device->drm); > devres_release_group(&pdev->dev, NULL); > platform_device_unregister(pdev); > - > - config->dev = NULL; > -} > - > -static void __exit vkms_exit(void) > -{ > - if (default_config->dev) > - vkms_destroy(default_config); > - > - kfree(default_config); > } > > module_init(vkms_init); > diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h > index 91e63b12f60f..c7ebc4ee6b14 100644 > --- a/drivers/gpu/drm/vkms/vkms_drv.h > +++ b/drivers/gpu/drm/vkms/vkms_drv.h > @@ -99,15 +99,14 @@ struct vkms_config { > bool writeback; > bool cursor; > bool overlay; > - /* only set when instantiated */ > - struct vkms_device *dev; > }; > > struct vkms_device { > struct drm_device drm; > struct platform_device *platform; > struct vkms_output output; > - const struct vkms_config *config; > + struct vkms_config config; > + bool initialized; > }; > > #define drm_crtc_to_vkms_output(target) \ > diff --git a/drivers/gpu/drm/vkms/vkms_output.c > b/drivers/gpu/drm/vkms/vkms_output.c > index ba0e82ae549a..d0061c82003a 100644 > --- a/drivers/gpu/drm/vkms/vkms_output.c > +++ b/drivers/gpu/drm/vkms/vkms_output.c > @@ -63,7 +63,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) > if (IS_ERR(primary)) > return PTR_ERR(primary); > > - if (vkmsdev->config->overlay) { > + if (vkmsdev->config.overlay) { > for (n = 0; n < NUM_OVERLAY_PLANES; n++) { > ret = vkms_add_overlay_plane(vkmsdev, index, crtc); > if (ret) > @@ -71,7 +71,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) > } > } > > - if (vkmsdev->config->cursor) { > + if (vkmsdev->config.cursor) { > cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR, index); > if (IS_ERR(cursor)) > return PTR_ERR(cursor); > @@ -103,7 +103,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int > index) > goto err_attach; > } > > - if (vkmsdev->config->writeback) { > + if (vkmsdev->config.writeback) { > writeback = vkms_enable_writeback_connector(vkmsdev); > if (writeback) > DRM_ERROR("Failed to init writeback connector\n"); > -- > 2.37.1.359.gd136c6c3e2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] drm/rockchip: vop: Don't crash for invalid duplicate_state()
On Fri, Jun 17, 2022 at 05:26:52PM -0700, Brian Norris wrote: > It's possible for users to try to duplicate the CRTC state even when the > state doesn't exist. drm_atomic_helper_crtc_duplicate_state() (and other > users of __drm_atomic_helper_crtc_duplicate_state()) already guard this > with a WARN_ON() instead of crashing, so let's do that here too. > > Signed-off-by: Brian Norris Thanks for this patch! Reviewed-by: Sean Paul > --- > > drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > index 74562d40f639..daf192881353 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > @@ -1570,6 +1570,9 @@ static struct drm_crtc_state > *vop_crtc_duplicate_state(struct drm_crtc *crtc) > { > struct rockchip_crtc_state *rockchip_state; > > + if (WARN_ON(!crtc->state)) > + return NULL; > + > rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL); > if (!rockchip_state) > return NULL; > -- > 2.36.1.476.g0c4daa206d-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v2 0/2] drm/bridge: analogix_dp: Self-refresh state machine fixes
On Mon, May 23, 2022 at 5:51 PM Brian Norris wrote: > > On Thu, Mar 10, 2022 at 3:50 PM Brian Norris wrote: > > On Mon, Feb 28, 2022 at 12:25 PM Brian Norris > > wrote: > > > Ping for review? Sean, perhaps? (You already reviewed this on the > > Chromium tracker.) > > Ping Apologies for the delay. Please in future ping on irc/chat if you're waiting for review from me, my inbox is often neglected. The set still looks good to me, Reviewed-by: Sean Paul Sean
Re: [Freedreno] [PATCH v4] drm/probe-helper: Default to 640x480 if no EDID on DP
On Wed, Jun 1, 2022 at 2:23 PM Douglas Anderson wrote: > > If we're unable to read the EDID for a display because it's corrupt / > bogus / invalid then we'll add a set of standard modes for the > display. Since we have no true information about the connected > display, these modes are essentially guesses but better than nothing. > At the moment, none of the modes returned is marked as preferred, but > the modes are sorted such that the higher resolution modes are listed > first. > > When userspace sees these modes presented by the kernel it needs to > figure out which one to pick. At least one userspace, ChromeOS [1] > seems to use the rules (which seem pretty reasonable): > 1. Try to pick the first mode marked as preferred. > 2. Try to pick the mode which matches the first detailed timing >descriptor in the EDID. > 3. If no modes were marked as preferred then pick the first mode. > > Unfortunately, userspace's rules combined with what the kernel is > doing causes us to fail section 4.2.2.6 (EDID Corruption Detection) of > the DP 1.4a Link CTS. That test case says that, while it's OK to allow > some implementation-specific fall-back modes if the EDID is bad that > userspace should _default_ to 640x480. > > Let's fix this by marking 640x480 as default for DP in the no-EDID > case. > > NOTES: > - In the discussion around v3 of this patch [2] there was talk about > solving this in userspace and I even implemented a patch that would > have solved this for ChromeOS, but then the discussion turned back > to solving this in the kernel. > - Also in the discussion of v3 [2] it was requested to limit this > 83;40900;0c change to just DP since folks were worried that it would break > some > subtle corner case on VGA or HDMI. > > [1] > https://source.chromium.org/chromium/chromium/src/+/a051f741d0a15caff2251301efe081c30e0f4a96:ui/ozone/platform/drm/common/drm_util.cc;l=488 > [2] > https://lore.kernel.org/r/20220513130533.v3.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid > > Signed-off-by: Douglas Anderson > Reviewed-by: Abhinav Kumar Reviewed-by: Sean Paul > > --- > I put Abhinav's Reviewed-by tag from v2 here since this is nearly the > same as v2. Hope this is OK. > > Changes in v4: > - Code is back to v2, but limit to just DP. > - Beefed up the commit message. > > Changes in v3: > - Don't set preferred, just disable the sort. > > Changes in v2: > - Don't modify drm_add_modes_noedid() 'cause that'll break others > - Set 640x480 as preferred in drm_helper_probe_single_connector_modes() > > drivers/gpu/drm/drm_probe_helper.c | 11 ++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_probe_helper.c > b/drivers/gpu/drm/drm_probe_helper.c > index 425f56280d51..75a71649b64d 100644 > --- a/drivers/gpu/drm/drm_probe_helper.c > +++ b/drivers/gpu/drm/drm_probe_helper.c > @@ -569,8 +569,17 @@ int drm_helper_probe_single_connector_modes(struct > drm_connector *connector, > count = drm_add_override_edid_modes(connector); > > if (count == 0 && (connector->status == connector_status_connected || > - connector->status == connector_status_unknown)) > + connector->status == connector_status_unknown)) { > count = drm_add_modes_noedid(connector, 1024, 768); > + > + /* > +* Section 4.2.2.6 (EDID Corruption Detection) of the DP 1.4a > +* Link CTS specifies that 640x480 (the official "failsafe" > +* mode) needs to be the default if there's no EDID. > +*/ > + if (connector->connector_type == > DRM_MODE_CONNECTOR_DisplayPort) > + drm_set_preferred_mode(connector, 640, 480); > + } > count += drm_helper_probe_add_cmdline_mode(connector); > if (count != 0) { > ret = __drm_helper_update_and_validate(connector, maxX, maxY, > &ctx); > -- > 2.36.1.255.ge46751e96f-goog >
Re: [PATCH v3] drm/probe-helper: Make 640x480 first if no EDID
On Wed, May 25, 2022 at 9:26 AM Daniel Vetter wrote: > > On Mon, May 23, 2022 at 05:59:02PM -0700, Doug Anderson wrote: > > Hi, > > > > On Fri, May 20, 2022 at 5:01 PM Doug Anderson wrote: > > > > > > Hi, > > > > > > On Mon, May 16, 2022 at 3:28 AM Thomas Zimmermann > > > wrote: > > > > > > > > Hi Douglas, > > > > > > > > I understand that you're trying to tell userspace that the modelist has > > > > been made up, but it's not something that should be done via fragile > > > > heuristics IMHO. > > > > > > > > I looked at the Chromium source code that you linked, but I cannot say > > > > whether it's doing the correct thing. It all depends on what your > > > > program needs. > > > > > > > > In that function, you could also search for 'DRM_MODE_TYPE_USERDEF'. > > > > It's the mode that the user specified on the kernel command line. If > > > > Chromium's automatic mode selection fails, you'd give your users direct > > > > control over it. > > > > > > That doesn't really work for Chrome OS. Certainly a kernel hacker > > > could do this, but it's not something I could imagine us exposing to > > > an average user of a Chromebook. > > > > > > > > > > When there's no flagged mode or if > > > > /sys/class/drm/card<...>/status contains "unconnected", you can assume > > > > that the modelist is artificial and try the modes in an appropriate > > > > order. > > > > > > So "no flagged" means that nothing is marked as preferred, correct? > > > > > > ...so I guess what you're suggesting is that the order that the kernel > > > is presenting the modes to userspace is not ABI. If there are no > > > preferred modes then userspace shouldn't necessarily assume that the > > > first mode returned is the best mode. Instead it should assume that if > > > there is no preferred mode then the mode list is made up and it should > > > make its own decisions about the best mode to start with. If this is > > > the ABI from the kernel then plausibly I could convince people to > > > change userspace to pick 640x480 first in this case. > > > > > > > If we really want the kernel to give additional guarantees, we should > > > > have a broader discussion about this topic IMHO. > > > > > > Sure. I've added Stéphane Marchesin to this thread in case he wants to > > > chime in about anything. > > > > > > Overall, my take on the matter: > > > > > > * Mostly I got involved because, apparently, a DP compliance test was > > > failing. The compliance test was upset that when it presented us with > > > no EDID that we didn't default to 640x480. There was a push to make a > > > fix for this in the Qualcomm specific driver but that didn't sit right > > > with me. > > > > > > * On all devices I'm currently working with (laptops), the DP is a > > > secondary display. If a user was trying to plug in a display with a > > > bad EDID and the max mode (1024x768) didn't work, they could just use > > > the primary display to choose a different resolution. It seems > > > unlikely a user would truly be upset and would probably be happy they > > > could get their broken display to work at all. Even if this is a > > > primary display, I believe there are documented key combos to change > > > the resolution of the primary display even if you can't see anything. > > > > > > * That all being said, defaulting to 640x480 when there's no EDID made > > > sense to me, especially since it's actually defined in the DP spec. So > > > I'm trying to do the right thing and solve this corner case. That > > > being said, if it's truly controversial I can just drop it. > > > > > > > > > So I guess my plan will be to give Stéphane a little while in case he > > > wants to chime in. If not then I guess I'll try a Chrome patch... > > > ...and if that doesn't work, I'll just drop it. > > > > OK, this userspace code seems to work: > > > > https://crrev.com/c/3662501 - ozone/drm: Try 640x480 before picking > > the first mode if no EDID > > > > ...so we'll see how review of that goes. :-) Mirroring some of my comments on that review here :-) IMO, this should be addressed in the kernel, or not at all. The kernel ensures other aspects of DisplayPort implementation are compliant, so I don't think this would be any exception. Further, the kernel is the one creating the "safe" mode list, so it seems odd that userspace would override that. Finally, relying on every userspace to do the right thing is asking for trouble (we have 3 places which would need this logic in CrOS). > > Yeah it sucks a bit but I'm mildly afraid that if we muck around with the > absolute fallback mode list in upstream we get whacked by a regression > report :-/ Yeah, this seems likely (unfortunately). > > There's the additional fun that on modern displays probably 720p (or maybe > 720i) is a lot more likely to work than anything else really, so best we > can do here maybe is to make it an uapi guarantee that if there's no > preferred mode, then most likely the kernel invent random noise out of > thin air, and userspac
Re: [PATCH v5 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers
On Tue, Apr 12, 2022 at 09:41:35AM -0400, Rodrigo Vivi wrote: > On Mon, Apr 11, 2022 at 08:47:29PM +0000, Sean Paul wrote: > > From: Sean Paul > > > > Rebased set from November. Fixed a nit from Stephen in the msm patch and > > moved hdcp registers into the trogdor dtsi file to avoid differences > > with sc7180-based windows devices. The set is 4 patches lighter since > > some of the changes were accepted into msm. > > > > I'm still waiting for Intel review of the first 7 patches. Rodrigo/Jani, > > would you please provide your input so we can move forward with this > > set? > > I'm a bit concerned with patches 4 and 7. It is hard to map the removals > and additions and there are some changes that looks like changing behaviors, > but end up not being clear in the big patch. Also with big patch it is prune > to the rebasing and backport conflicts. I had the same concerns when I was writing this. I originally had it split up, but it seemed really cluttered with 2 sets of helpers (intel-internal + drm) that worked slightly differently. I'll try again now that some time has passed, perhaps a fresh look will help. Sean > > Would be possible to split some work in moving individual functions from i915 > to drm little by little with smaller patches? > > But thank you for this great work. It is also good to align our drm drivers. > > Thanks, > Rodrigo. > > > > > Thanks, > > > > Sean > > > > Link: https://patchwork.freedesktop.org/series/94623/ #v1 > > Link: https://patchwork.freedesktop.org/series/94713/ #v2 > > Link: https://patchwork.freedesktop.org/series/94712/ #v3 > > Link: https://patchwork.freedesktop.org/series/94712/ #v4 > > > > 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 + > > arch/arm64/boot/dts/qcom/sc7180.dtsi |6 +- > > drivers/gpu/drm/drm_hdcp.c| 1197 - > > drivers/gpu/drm/i915/display/intel_atomic.c |7 +- > > drivers/gpu/drm/i915/display/intel_ddi.c | 29 +- > > .../drm/i915/display/intel_display_debugfs.c | 11 +- > > .../drm/i915/display/intel_display_types.h| 58 +- > > drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 345 ++--- > > drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +- > > drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++--- > > drivers/gpu/drm/i915/display/intel_hdcp.h | 36 +- > > drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++-- > > drivers/gpu/drm/msm/Makefile |1 + > > drivers/gpu/drm/msm/dp/dp_debug.c | 46 +- > > drivers/gpu/drm/msm/dp/dp_debug.h |6 +- > > drivers/gpu/drm/msm/dp/dp_display.c | 46 +- > > drivers/gpu/drm/msm/dp/dp_display.h |5 + > > drivers/gpu/drm/msm/dp/dp_drm.c | 68 +- > > drivers/gpu/drm/msm/dp/dp_drm.h |5 + > > drivers/gpu/drm/msm/dp/dp_hdcp.c | 453 +++ > > drivers/gpu/drm/msm/dp/dp_hdcp.h | 27 + > > 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/drm_hdcp.h| 194 +++ > > 27 files changed, 2582 insertions(+), 1328 deletions(-) > > create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c > > create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h > > > > -- > > Sean Paul, Software Engineer, Google / Chromium OS > > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v5 03/10] drm/hdcp: Update property value on content type and user changes
On Tue, Apr 12, 2022 at 09:25:59AM -0400, Rodrigo Vivi wrote: > On Mon, Apr 11, 2022 at 08:47:32PM +0000, Sean Paul wrote: > > 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: Abhinav Kumar > > Signed-off-by: Sean Paul > > 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 > > > > Changes in v2: > > -None > > Changes in v3: > > -Fixed indentation issue identified by 0-day > > Changes in v4: > > -None > > Changes in v5: > > -None > > --- > > drivers/gpu/drm/drm_hdcp.c | 26 +- > > 1 file changed, 17 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c > > index dd8fa91c51d6..8c851d40cd45 100644 > > --- a/drivers/gpu/drm/drm_hdcp.c > > +++ b/drivers/gpu/drm/drm_hdcp.c > > @@ -487,21 +487,29 @@ 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 > > +* Content type changes require an HDCP disable/enable cycle. > > +*/ > > + if (new_conn_state->hdcp_content_type != > > old_conn_state->hdcp_content_type) { > > shouldn't we add some && ( old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) { > here? Thanks for your reviews Rodrigo. I don't think so since the content type is changing the current state of old content protection is immaterial (ie: if we need to enable HDCP 2.x, the state of HDCP 1.x doesn't really matter), we need to re-evaluate whether the current level of HDCP is sufficient. Hopefully that makes sense, but I could be missing something :-) Sean > > > + 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 > > +* - Attempting to set to desired while already enabled > > */ > > - if (old_hdcp == new_hdcp || > > - (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED && > > + 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); > > -- > > Sean Paul, Software Engineer, Google / Chromium OS > > -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v5 10/10] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers
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 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 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) [1] https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run --- drivers/gpu/drm/msm/Makefile| 1 + drivers/gpu/drm/msm/dp/dp_debug.c | 46 ++- drivers/gpu/drm/msm/dp/dp_debug.h | 6 +- drivers/gpu/drm/msm/dp/dp_display.c | 46 ++- drivers/gpu/drm/msm/dp/dp_display.h | 5 + drivers/gpu/drm/msm/dp/dp_drm.c | 68 - drivers/gpu/drm/msm/dp/dp_drm.h | 5 + drivers/gpu/drm/msm/dp/dp_hdcp.c| 453 drivers/gpu/drm/msm/dp/dp_hdcp.h| 27 ++ 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 + 13 files changed, 720 insertions(+), 8 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/Makefile b/drivers/gpu/drm/msm/Makefile index e9cc7d8ac301..e7b0e860c1f0 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -106,6 +106,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 2f9c943f12d5..12e65294258f 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; @@ -198,6 +201,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, @@ -207,6 +239,12 @@ static const struct file_operations test_active_fops = { .write = dp_test_active_write }; +static const struct file_operations dp_hdcp_key_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = dp_hdcp_key_write, +}; + static void dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor)
[PATCH v5 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
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 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 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) --- arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 arch/arm64/boot/dts/qcom/sc7180.dtsi | 6 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi index 732e1181af48..c3559253aefc 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -815,6 +815,14 @@ &mdss_dp { data-lanes = <0 1>; vdda-1p2-supply = <&vdda_usb_ss_dp_1p2>; vdda-0p9-supply = <&vdda_usb_ss_dp_core>; + + 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>; }; &pm6150_adc { diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index e1c46b80f14a..3c3eef7a7d52 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -3089,7 +3089,11 @@ mdss_dp: displayport-controller@ae9 { compatible = "qcom,sc7180-dp"; status = "disabled"; - reg = <0 0x0ae9 0 0x1400>; + reg = <0 0x0ae9 0 0x200>, + <0 0x0ae90200 0 0x200>, + <0 0x0ae90400 0 0xc00>, + <0 0x0ae91000 0 0x400>, + <0 0x0ae91400 0 0x400>; interrupt-parent = <&mdss>; interrupts = <12>; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v5 08/10] dt-bindings: msm/dp: Add bindings for HDCP registers
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 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 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 --- .../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 cd05cfd76536..671d50f1f458 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -24,12 +24,15 @@ properties: - qcom,sm8350-dp reg: +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 @@ -113,7 +116,9 @@ examples: <0xae90200 0x200>, <0xae90400 0xc00>, <0xae91000 0x400>, - <0xae91400 0x400>; + <0xae91400 0x400>, + <0xaed1000 0x174>, + <0xaee1000 0x2c>; interrupt-parent = <&mdss>; interrupts = <12>; clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v5 07/10] drm/i915/hdcp: Use HDCP helpers for i915
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 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 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 --- drivers/gpu/drm/i915/display/intel_ddi.c | 29 +- .../drm/i915/display/intel_display_debugfs.c | 6 +- .../drm/i915/display/intel_display_types.h| 58 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 345 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 935 +++--- drivers/gpu/drm/i915/display/intel_hdcp.h | 31 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++--- 8 files changed, 418 insertions(+), 1259 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index cec578efc4bd..a320c2b178e5 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -29,6 +29,7 @@ #include #include +#include #include "i915_drv.h" #include "intel_audio.h" @@ -2921,6 +2922,9 @@ 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)) @@ -2937,12 +2941,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, + &state->base, + &dig_port->hdcp_mutex); } static void intel_disable_ddi_dp(struct intel_atomic_state *state, @@ -2988,7 +2990,13 @@ 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, + &state->base, + &dig_port->hdcp_mutex); if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) intel_disable_ddi_hdmi(state, encoder, old_crtc_state, @@ -3016,13 +3024,18 @@ 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);
[PATCH v5 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 Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -None Changes in v4: -None Changes in v5: -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 452d773fd4e3..f18b4bec4dd4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -489,6 +489,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) { @@ -496,8 +497,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, &hdcp_cap); + if (ret) + hdcp_cap = false; + ret = intel_hdcp2_capable(intel_connector, &hdcp2_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 6bb5a3971ed9..771e94fa8dff 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -154,50 +154,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, &capable); - } 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 = &connector->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(&dev_priv->hdcp_comp_mutex); if (!dev_priv->hdcp_comp_added || !dev_priv->hdcp_master) { mutex_unlock(&dev_priv->hdcp_comp_mutex); - return false; + return 0; } mutex_unlock(&dev_priv->hdcp_comp_mutex); /* Sink's capability for HDCP2.2 */ - hdcp->shim->hdcp_2_2_capable(dig_port, &capable); - - return capable; + return hdcp->shim->hdcp_2_2_capable(dig_port, capable); } static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv, @@ -2332,6 +2331,7 @@ int intel_hdcp_enable(struct intel_connector *connector, struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; + bool capable; int ret = -EINVAL; if (!hdcp->shim) @@ -2350,21 +2350,27 @@ int intel
[PATCH v5 05/10] drm/i915/hdcp: Consolidate HDCP setup/state cache
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 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 Changes in v2: -None Changes in v3: -None Changes in v4: -None Changes in v5: -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 861c550b5bd6..6bb5a3971ed9 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2167,6 +2167,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 = &connector->hdcp; + int ret = 0; + + if (!connector->encoder) { + drm_err(&dev_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) @@ -2306,28 +2337,14 @@ int intel_hdcp_enable(struct intel_connector *connector, if (!hdcp->shim) return -ENOENT; - if (!connector->encoder) { - drm_err(&dev_priv->drm, "[%s:%d] encoder is not initialized\n", - connector->base.name, connector->base.base.id); - return -ENODEV; - } - mutex_lock(&hdcp->mutex); mutex_lock(&dig_port->hdcp_mutex); drm_WARN_ON(&dev_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 @@ -2355,6 +2372,7 @@ int intel_hdcp_enable(struct intel_connector *connector, true); } +out: mutex_unlock(&dig_port->hdcp_mutex); mutex_unlock(&hdcp->mutex); return ret; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v5 04/10] drm/hdcp: Expand HDCP helper library for enable/disable/check
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 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 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 --- drivers/gpu/drm/drm_hdcp.c | 1103 include/drm/drm_hdcp.h | 191 +++ 2 files changed, 1294 insertions(+) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index 8c851d40cd45..3e550c892751 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -6,15 +6,20 @@ * Ramalingam C */ +#include #include #include #include +#include +#include #include #include #include +#include #include #include +#include #include #include #include @@ -513,3 +518,1101 @@ 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) }, + .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, +}; + +static int drm_hdcp_remote_ddc_read(str
[PATCH v5 03/10] drm/hdcp: Update property value on content type and user changes
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: Abhinav Kumar Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -Fixed indentation issue identified by 0-day Changes in v4: -None Changes in v5: -None --- drivers/gpu/drm/drm_hdcp.c | 26 +- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index dd8fa91c51d6..8c851d40cd45 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -487,21 +487,29 @@ 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 +* Content type changes require an HDCP disable/enable cycle. +*/ + 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 +* - Attempting to set to desired while already enabled */ - if (old_hdcp == new_hdcp || - (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED && + 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); -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v5 02/10] drm/hdcp: Avoid changing crtc state in hdcp atomic check
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 Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -None Changes in v4: -None Changes in v5: -None --- drivers/gpu/drm/drm_hdcp.c | 33 +++-- drivers/gpu/drm/i915/display/intel_atomic.c | 5 ++-- include/drm/drm_hdcp.h | 2 +- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index 522326b03e66..dd8fa91c51d6 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -430,11 +430,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; @@ -452,10 +455,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 = drm_atomic_get_new_crtc_state(state, @@ -467,9 +472,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: @@ -484,9 +499,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 b301a4d1017e..6d24b3450399 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_atomic_check(conn, state); - if (!new_state->crtc) return 0; @@ -142,7 +140,8 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn, new_conn_state->base.content_type != old_conn_state->base.content_type || new_conn_state->base.scaling_mode != old_conn_state->base.scaling
[PATCH v5 01/10] drm/hdcp: Add drm_hdcp_atomic_check()
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: Abhinav Kumar Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -None Changes in v4: -None Changes in v5: -None --- drivers/gpu/drm/drm_hdcp.c | 71 - 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/drm_hdcp.h | 3 + 5 files changed, 75 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index ca9b8f697202..522326b03e66 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -13,13 +13,14 @@ #include #include +#include +#include #include #include #include #include #include #include -#include #include "drm_internal.h" @@ -421,3 +422,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_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 40da7910f845..b301a4d1017e 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drive
[PATCH v5 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers
From: Sean Paul Rebased set from November. Fixed a nit from Stephen in the msm patch and moved hdcp registers into the trogdor dtsi file to avoid differences with sc7180-based windows devices. The set is 4 patches lighter since some of the changes were accepted into msm. I'm still waiting for Intel review of the first 7 patches. Rodrigo/Jani, would you please provide your input so we can move forward with this set? Thanks, Sean Link: https://patchwork.freedesktop.org/series/94623/ #v1 Link: https://patchwork.freedesktop.org/series/94713/ #v2 Link: https://patchwork.freedesktop.org/series/94712/ #v3 Link: https://patchwork.freedesktop.org/series/94712/ #v4 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 + arch/arm64/boot/dts/qcom/sc7180.dtsi |6 +- drivers/gpu/drm/drm_hdcp.c| 1197 - drivers/gpu/drm/i915/display/intel_atomic.c |7 +- drivers/gpu/drm/i915/display/intel_ddi.c | 29 +- .../drm/i915/display/intel_display_debugfs.c | 11 +- .../drm/i915/display/intel_display_types.h| 58 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 345 ++--- drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++--- drivers/gpu/drm/i915/display/intel_hdcp.h | 36 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++-- drivers/gpu/drm/msm/Makefile |1 + drivers/gpu/drm/msm/dp/dp_debug.c | 46 +- drivers/gpu/drm/msm/dp/dp_debug.h |6 +- drivers/gpu/drm/msm/dp/dp_display.c | 46 +- drivers/gpu/drm/msm/dp/dp_display.h |5 + drivers/gpu/drm/msm/dp/dp_drm.c | 68 +- drivers/gpu/drm/msm/dp/dp_drm.h |5 + drivers/gpu/drm/msm/dp/dp_hdcp.c | 453 +++ drivers/gpu/drm/msm/dp/dp_hdcp.h | 27 + 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/drm_hdcp.h| 194 +++ 27 files changed, 2582 insertions(+), 1328 deletions(-) create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH] drm/amd: Re-classify some log messages in commit path
From: Sean Paul ATOMIC and DRIVER log categories do not typically contain per-frame log messages. This patch re-classifies some messages in amd to chattier categories to keep ATOMIC/DRIVER quiet. Signed-off-by: Sean Paul --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 5 +++-- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index fae5c1debfad..1fcbab2fd3c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -113,8 +113,9 @@ static void amdgpu_display_flip_work_func(struct work_struct *__work) spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_SUBMITTED, work: %p,\n", -amdgpu_crtc->crtc_id, amdgpu_crtc, work); + drm_dbg_vbl(adev_to_drm(adev), + "crtc:%d[%p], pflip_stat:AMDGPU_FLIP_SUBMITTED, work: %p,\n", + amdgpu_crtc->crtc_id, amdgpu_crtc, work); } 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 b30656959fd8..45d130f86114 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9248,7 +9248,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, &bundle->flip_addrs[planes_count].address, afb->tmz_surface, false); - DRM_DEBUG_ATOMIC("plane: id=%d dcc_en=%d\n", + drm_dbg_state(state->dev, "plane: id=%d dcc_en=%d\n", new_plane_state->plane->index, bundle->plane_infos[planes_count].dcc.enable); @@ -9282,7 +9282,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, dc_plane, bundle->flip_addrs[planes_count].flip_timestamp_in_us); - DRM_DEBUG_ATOMIC("%s Flipping to hi: 0x%x, low: 0x%x\n", + drm_dbg_state(state->dev, "%s Flipping to hi: 0x%x, low: 0x%x\n", __func__, bundle->flip_addrs[planes_count].address.grph.addr.high_part, bundle->flip_addrs[planes_count].address.grph.addr.low_part); @@ -9624,7 +9624,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); - DRM_DEBUG_ATOMIC( + drm_dbg_state(state->dev, "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " "planes_changed:%d, mode_changed:%d,active_changed:%d," "connectors_changed:%d\n", @@ -10328,7 +10328,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) goto skip_modeset; - DRM_DEBUG_ATOMIC( + drm_dbg_state(state->dev, "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " "planes_changed:%d, mode_changed:%d,active_changed:%d," "connectors_changed:%d\n", -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v2] drm/amdgpu: Add support for drm_privacy_screen
From: Sean Paul This patch adds the necessary hooks to make amdgpu aware of privacy screens. On devices with privacy screen drivers (such as thinkpad-acpi), the amdgpu driver will defer probe until it's ready and then sync the sw and hw state on each commit the connector is involved and enabled. Changes in v2: -Tweaked the drm_privacy_screen_get() error check to avoid logging errors when privacy screen is absent (Hans) Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/477640/ #v1 --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 9 + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c| 3 +++ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 16 +++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 2ab675123ae3..e2cfae56c020 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include "amdgpu_drv.h" @@ -1988,6 +1989,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, { struct drm_device *ddev; struct amdgpu_device *adev; + struct drm_privacy_screen *privacy_screen; unsigned long flags = ent->driver_data; int ret, retry = 0, i; bool supports_atomic = false; @@ -2063,6 +2065,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, size = pci_resource_len(pdev, 0); is_fw_fb = amdgpu_is_fw_framebuffer(base, size); + /* If the LCD panel has a privacy screen, defer probe until its ready */ + privacy_screen = drm_privacy_screen_get(&pdev->dev, NULL); + if (IS_ERR(privacy_screen) && PTR_ERR(privacy_screen) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + drm_privacy_screen_put(privacy_screen); + /* Get rid of things like offb */ ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver); if (ret) 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 e1d3db3fe8de..9e2bb6523add 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9781,6 +9781,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) if (acrtc) { new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); + + /* Sync the privacy screen state between hw and sw */ + drm_connector_update_privacy_screen(new_con_state); } /* Skip any modesets/resets */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 740435ae3997..594a8002975a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "dm_services.h" #include "amdgpu.h" #include "amdgpu_dm.h" @@ -506,6 +507,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, struct amdgpu_dm_connector *aconnector, int link_index) { + struct drm_device *dev = dm->ddev; struct dc_link_settings max_link_enc_cap = {0}; aconnector->dm_dp_aux.aux.name = @@ -519,8 +521,20 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, drm_dp_cec_register_connector(&aconnector->dm_dp_aux.aux, &aconnector->base); - if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) + if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { + struct drm_privacy_screen *privacy_screen; + + /* Reference given up in drm_connector_cleanup() */ + privacy_screen = drm_privacy_screen_get(dev->dev, NULL); + if (!IS_ERR(privacy_screen)) { + drm_connector_attach_privacy_screen_provider(&aconnector->base, + privacy_screen); + } else if (PTR_ERR(privacy_screen) != -ENODEV) { + drm_err(dev, "Error getting privacy screen, ret=%d\n", + PTR_ERR(privacy_screen)); + } return; + } dc_link_dp_get_max_link_enc_cap(aconnector->dc_link, &max_link_enc_cap); aconnector->mst_mgr.cbs = &dm_mst_cbs; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH] drm/amdgpu: Add support for drm_privacy_screen
From: Sean Paul This patch adds the necessary hooks to make amdgpu aware of privacy screens. On devices with privacy screen drivers (such as thinkpad-acpi), the amdgpu driver will defer probe until it's ready and then sync the sw and hw state on each commit the connector is involved and enabled. Signed-off-by: Sean Paul --- I tested this locally, but am not super confident everything is in the correct place. Hopefully the intent of the patch is clear and we can tweak positioning if needed. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 9 + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c| 3 +++ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 16 +++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 2ab675123ae3..e2cfae56c020 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include "amdgpu_drv.h" @@ -1988,6 +1989,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, { struct drm_device *ddev; struct amdgpu_device *adev; + struct drm_privacy_screen *privacy_screen; unsigned long flags = ent->driver_data; int ret, retry = 0, i; bool supports_atomic = false; @@ -2063,6 +2065,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, size = pci_resource_len(pdev, 0); is_fw_fb = amdgpu_is_fw_framebuffer(base, size); + /* If the LCD panel has a privacy screen, defer probe until its ready */ + privacy_screen = drm_privacy_screen_get(&pdev->dev, NULL); + if (IS_ERR(privacy_screen) && PTR_ERR(privacy_screen) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + drm_privacy_screen_put(privacy_screen); + /* Get rid of things like offb */ ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver); if (ret) 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 e1d3db3fe8de..9e2bb6523add 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9781,6 +9781,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) if (acrtc) { new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); + + /* Sync the privacy screen state between hw and sw */ + drm_connector_update_privacy_screen(new_con_state); } /* Skip any modesets/resets */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 740435ae3997..e369fc95585e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "dm_services.h" #include "amdgpu.h" #include "amdgpu_dm.h" @@ -506,6 +507,7 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, struct amdgpu_dm_connector *aconnector, int link_index) { + struct drm_device *dev = dm->ddev; struct dc_link_settings max_link_enc_cap = {0}; aconnector->dm_dp_aux.aux.name = @@ -519,8 +521,20 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, drm_dp_cec_register_connector(&aconnector->dm_dp_aux.aux, &aconnector->base); - if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) + if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { + struct drm_privacy_screen *privacy_screen; + + /* Reference given up in drm_connector_cleanup() */ + privacy_screen = drm_privacy_screen_get(dev->dev, NULL); + if (!IS_ERR(privacy_screen)) { + drm_connector_attach_privacy_screen_provider(&aconnector->base, + privacy_screen); + } else { + drm_err(dev, "Error getting privacy screen, ret=%d\n", + PTR_ERR(privacy_screen)); + } return; + } dc_link_dp_get_max_link_enc_cap(aconnector->dc_link, &max_link_enc_cap); aconnector->mst_mgr.cbs = &dm_mst_cbs; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4.5 12/14] dt-bindings: msm/dp: Add bindings for HDCP registers
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 Signed-off-by: Sean Paul 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 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) --- .../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 b36d74c1da7c..aff7d45ba6ed 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -21,12 +21,15 @@ properties: - qcom,sc8180x-edp reg: +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 @@ -111,7 +114,9 @@ examples: <0xae90200 0x200>, <0xae90400 0xc00>, <0xae91000 0x400>, - <0xae91400 0x400>; + <0xae91400 0x400>, + <0xaed1000 0x174>, + <0xaee1000 0x2c>; interrupt-parent = <&mdss>; interrupts = <12>; clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 14/14] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers
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 Signed-off-by: Sean Paul 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 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 [1] https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run --- drivers/gpu/drm/msm/Makefile| 1 + drivers/gpu/drm/msm/dp/dp_debug.c | 46 ++- drivers/gpu/drm/msm/dp/dp_debug.h | 6 +- drivers/gpu/drm/msm/dp/dp_display.c | 46 ++- drivers/gpu/drm/msm/dp/dp_display.h | 5 + drivers/gpu/drm/msm/dp/dp_drm.c | 68 +++- drivers/gpu/drm/msm/dp/dp_drm.h | 5 + drivers/gpu/drm/msm/dp/dp_hdcp.c| 462 drivers/gpu/drm/msm/dp/dp_hdcp.h| 27 ++ 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 + 13 files changed, 729 insertions(+), 8 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/Makefile b/drivers/gpu/drm/msm/Makefile index 40577f8856d8..fb3411a74e61 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -108,6 +108,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 da4323556ef3..c16fce17d096 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; @@ -198,6 +201,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, @@ -207,6 +239,12 @@ static const struct file_operations test_active_fops = { .write = dp_test_active_write }; +static const struct file_operations dp_hdcp_key_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = dp_hdcp_key_write, +}; + static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) { int rc = 0; @@ -228,6 +266,10 @@ static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) minor->debugfs_root, debug, &a
[PATCH v4 13/14] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
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 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 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 --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index c8921e2d6480..838270f70b62 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -3088,7 +3088,13 @@ mdss_dp: displayport-controller@ae9 { compatible = "qcom,sc7180-dp"; status = "disabled"; - reg = <0 0x0ae9 0 0x1400>; + 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>; interrupt-parent = <&mdss>; interrupts = <12>; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 12/14] dt-bindings: msm/dp: Add bindings for HDCP registers
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 Signed-off-by: Sean Paul 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 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 --- .../devicetree/bindings/display/msm/dp-controller.yaml| 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index b36d74c1da7c..f6e4b102373a 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -21,12 +21,16 @@ properties: - qcom,sc8180x-edp reg: +minItems: 5 +maxItems: 7 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 @@ -111,7 +115,9 @@ examples: <0xae90200 0x200>, <0xae90400 0xc00>, <0xae91000 0x400>, - <0xae91400 0x400>; + <0xae91400 0x400>, + <0x0aed1000 0x174>, + <0x0aee1000 0x2c>; interrupt-parent = <&mdss>; interrupts = <12>; clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 11/14] drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules
From: Sean Paul Audio is initialized last, it should be de-initialized first to match the order in dp_init_sub_modules(). Reviewed-by: Abhinav Kumar Reviewed-by: Stephen Boyd Reviewed-by: Dmitry Baryshkov Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-12-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-12-s...@poorly.run #v2 Link: https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-12-s...@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -None --- drivers/gpu/drm/msm/dp/dp_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index aba8aa47ed76..79412a8fbaff 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -707,9 +707,9 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) static void dp_display_deinit_sub_modules(struct dp_display_private *dp) { dp_debug_put(dp->debug); + dp_audio_put(dp->audio); dp_panel_put(dp->panel); dp_aux_put(dp->aux); - dp_audio_put(dp->audio); } static int dp_init_sub_modules(struct dp_display_private *dp) -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 10/14] drm/msm/dpu: Remove encoder->enable() hack
From: Sean Paul encoder->commit() was being misused because there were some global resources which needed to be tweaked in encoder->enable() which were not accessible in dpu_encoder.c. That is no longer true and the redirect serves no purpose any longer. So remove the indirection. Tested-by: Stephen Boyd Reviewed-by: Stephen Boyd Reviewed-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-11-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-11-s...@poorly.run #v2 Link: https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-11-s...@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -None --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 22 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 4 4 files changed, 1 insertion(+), 32 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index cc57c615be67..c83bfda6a1ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2116,11 +2116,8 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { .mode_set = dpu_encoder_virt_mode_set, .disable = dpu_encoder_virt_disable, - .enable = dpu_kms_encoder_enable, + .enable = dpu_encoder_virt_enable, .atomic_check = dpu_encoder_virt_atomic_check, - - /* This is called by dpu_kms_encoder_enable */ - .commit = dpu_encoder_virt_enable, }; static const struct drm_encoder_funcs dpu_encoder_funcs = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 66b7df7daa6a..891faf8d6e21 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -384,28 +384,6 @@ static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask) } } -/* - * Override the encoder enable since we need to setup the inline rotator and do - * some crtc magic before enabling any bridge that might be present. - */ -void dpu_kms_encoder_enable(struct drm_encoder *encoder) -{ - const struct drm_encoder_helper_funcs *funcs = encoder->helper_private; - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc; - - /* Forward this enable call to the commit hook */ - if (funcs && funcs->commit) - funcs->commit(encoder); - - drm_for_each_crtc(crtc, dev) { - if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder))) - continue; - - trace_dpu_kms_enc_enable(DRMID(crtc)); - } -} - static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned crtc_mask) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 775bcbda860f..0707b2cb43c8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -235,8 +235,6 @@ void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms); int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); -void dpu_kms_encoder_enable(struct drm_encoder *encoder); - /** * dpu_kms_get_clk_rate() - get the clock rate * @dpu_kms: pointer to dpu_kms structure diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index 37bba57675a8..54d74341e690 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -266,10 +266,6 @@ DEFINE_EVENT(dpu_drm_obj_template, dpu_crtc_complete_commit, TP_PROTO(uint32_t drm_id), TP_ARGS(drm_id) ); -DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_enc_enable, - TP_PROTO(uint32_t drm_id), - TP_ARGS(drm_id) -); DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_commit, TP_PROTO(uint32_t drm_id), TP_ARGS(drm_id) -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 09/14] drm/msm/dpu: Remove useless checks in dpu_encoder
From: Sean Paul A couple more useless checks to remove in dpu_encoder. Reviewed-by: Stephen Boyd Reviewed-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-10-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-10-s...@poorly.run #v2 Link: https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-10-s...@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -None --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 1 file changed, 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index e7ee4cfb8461..cc57c615be67 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1148,10 +1148,6 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) struct msm_drm_private *priv; struct drm_display_mode *cur_mode = NULL; - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } dpu_enc = to_dpu_encoder_virt(drm_enc); mutex_lock(&dpu_enc->enc_lock); @@ -1197,14 +1193,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) struct msm_drm_private *priv; int i = 0; - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } else if (!drm_enc->dev) { - DPU_ERROR("invalid dev\n"); - return; - } - dpu_enc = to_dpu_encoder_virt(drm_enc); DPU_DEBUG_ENC(dpu_enc, "\n"); -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 08/14] drm/msm/dpu_kms: Re-order dpu includes
From: Sean Paul Make includes alphabetical in dpu_kms.c Reviewed-by: Abhinav Kumar Reviewed-by: Stephen Boyd Reviewed-by: Dmitry Baryshkov Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-9-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-9-s...@poorly.run #v2 Link: https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-9-s...@poorly.run #v3 Changes in v2: -None Changes in v3: -None Changes in v4: -None --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index a15b26428280..66b7df7daa6a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -21,14 +21,14 @@ #include "msm_gem.h" #include "disp/msm_disp_snapshot.h" -#include "dpu_kms.h" #include "dpu_core_irq.h" +#include "dpu_crtc.h" +#include "dpu_encoder.h" #include "dpu_formats.h" #include "dpu_hw_vbif.h" -#include "dpu_vbif.h" -#include "dpu_encoder.h" +#include "dpu_kms.h" #include "dpu_plane.h" -#include "dpu_crtc.h" +#include "dpu_vbif.h" #define CREATE_TRACE_POINTS #include "dpu_trace.h" -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 07/14] drm/i915/hdcp: Use HDCP helpers for i915
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 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 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 --- drivers/gpu/drm/i915/display/intel_ddi.c | 29 +- .../drm/i915/display/intel_display_debugfs.c | 6 +- .../drm/i915/display/intel_display_types.h| 58 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 345 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 935 +++--- drivers/gpu/drm/i915/display/intel_hdcp.h | 31 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++--- 8 files changed, 418 insertions(+), 1259 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 145d51ac43a3..bfdf586207d2 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -26,6 +26,7 @@ */ #include +#include #include "i915_drv.h" #include "intel_audio.h" @@ -3016,6 +3017,9 @@ 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 (!crtc_state->bigjoiner_slave) @@ -3032,12 +3036,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, + &state->base, + &dig_port->hdcp_mutex); } static void intel_disable_ddi_dp(struct intel_atomic_state *state, @@ -3088,7 +3090,13 @@ 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, + &state->base, + &dig_port->hdcp_mutex); if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) intel_disable_ddi_hdmi(state, encoder, old_crtc_state, @@ -3118,13 +3126,18 @@ 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,
[PATCH v4 06/14] 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 Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -None Changes in v4: -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 d7d6dde518a3..ef3039fb1e0c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -643,6 +643,7 @@ static void intel_panel_info(struct seq_file *m, struct intel_panel *panel) 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) { @@ -650,8 +651,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, &hdcp_cap); + if (ret) + hdcp_cap = false; + ret = intel_hdcp2_capable(intel_connector, &hdcp2_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 8fc830e38311..ac05d2c6d3e7 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -153,50 +153,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, &capable); - } 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 = &connector->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(&dev_priv->hdcp_comp_mutex); if (!dev_priv->hdcp_comp_added || !dev_priv->hdcp_master) { mutex_unlock(&dev_priv->hdcp_comp_mutex); - return false; + return 0; } mutex_unlock(&dev_priv->hdcp_comp_mutex); /* Sink's capability for HDCP2.2 */ - hdcp->shim->hdcp_2_2_capable(dig_port, &capable); - - return capable; + return hdcp->shim->hdcp_2_2_capable(dig_port, capable); } static bool intel_hdcp_in_use(struct drm_i915_private *dev_priv, @@ -2332,6 +2331,7 @@ int intel_hdcp_enable(struct intel_connector *connector, struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct intel_hdcp *hdcp = &connector->hdcp; unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS; + bool capable; int ret = -EINVAL; if (!hdcp->shim) @@ -2350,21 +2350,27 @@ int intel_hdcp_enable(struct intel_connector *connector, * Considering that HDC
[PATCH v4 05/14] drm/i915/hdcp: Consolidate HDCP setup/state cache
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 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 Changes in v2: -None Changes in v3: -None Changes in v4: -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 f12790697e2d..8fc830e38311 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2167,6 +2167,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 = &connector->hdcp; + int ret = 0; + + if (!connector->encoder) { + drm_err(&dev_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) @@ -2306,28 +2337,14 @@ int intel_hdcp_enable(struct intel_connector *connector, if (!hdcp->shim) return -ENOENT; - if (!connector->encoder) { - drm_err(&dev_priv->drm, "[%s:%d] encoder is not initialized\n", - connector->base.name, connector->base.base.id); - return -ENODEV; - } - mutex_lock(&hdcp->mutex); mutex_lock(&dig_port->hdcp_mutex); drm_WARN_ON(&dev_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 @@ -2355,6 +2372,7 @@ int intel_hdcp_enable(struct intel_connector *connector, true); } +out: mutex_unlock(&dig_port->hdcp_mutex); mutex_unlock(&hdcp->mutex); return ret; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 04/14] drm/hdcp: Expand HDCP helper library for enable/disable/check
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 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 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 --- drivers/gpu/drm/drm_hdcp.c | 1103 include/drm/drm_hdcp.h | 191 +++ 2 files changed, 1294 insertions(+) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index 8c851d40cd45..2bfa07fc3fbc 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -6,15 +6,20 @@ * Ramalingam C */ +#include #include #include #include +#include +#include #include #include #include +#include #include #include +#include #include #include #include @@ -513,3 +518,1101 @@ 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) }, + .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, +}; + +static int drm_hdcp_remote_ddc_read(struct i2c_adapter *i2c, + unsigned int offset, u8 *value, size_t len) +{ + int r
[PATCH v4 03/14] drm/hdcp: Update property value on content type and user changes
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: Abhinav Kumar Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -Fixed indentation issue identified by 0-day Changes in v4: -None --- drivers/gpu/drm/drm_hdcp.c | 26 +- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index dd8fa91c51d6..8c851d40cd45 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -487,21 +487,29 @@ 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 +* Content type changes require an HDCP disable/enable cycle. +*/ + 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 +* - Attempting to set to desired while already enabled */ - if (old_hdcp == new_hdcp || - (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED && + 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); -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v4 02/14] drm/hdcp: Avoid changing crtc state in hdcp atomic check
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 Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -None Changes in v4: -None --- drivers/gpu/drm/drm_hdcp.c | 33 +++-- drivers/gpu/drm/i915/display/intel_atomic.c | 5 ++-- include/drm/drm_hdcp.h | 2 +- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index 522326b03e66..dd8fa91c51d6 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -430,11 +430,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; @@ -452,10 +455,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 = drm_atomic_get_new_crtc_state(state, @@ -467,9 +472,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: @@ -484,9 +499,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 1e306e8427ec..c7b5470c40aa 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -122,8 +122,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; @@ -139,7 +137,8 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn, new_conn_state->base.picture_aspect_ratio != old_conn_state->base.picture_aspect_ratio || new_conn_state->base.content_type != old_conn_state->base.content_type || new_conn_state->base.scaling_mode != old_conn_state->base.scaling_mode || -
[PATCH v4 01/14] drm/hdcp: Add drm_hdcp_atomic_check()
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: Abhinav Kumar Signed-off-by: Sean Paul 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 Changes in v2: -None Changes in v3: -None Changes in v4: -None --- drivers/gpu/drm/drm_hdcp.c | 71 - 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/drm_hdcp.h | 3 + 5 files changed, 75 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c index ca9b8f697202..522326b03e66 100644 --- a/drivers/gpu/drm/drm_hdcp.c +++ b/drivers/gpu/drm/drm_hdcp.c @@ -13,13 +13,14 @@ #include #include +#include +#include #include #include #include #include #include #include -#include #include "drm_internal.h" @@ -421,3 +422,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_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index b4e7ac51aa31..1e306e8427ec 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -32,13 +32,13 @@ #include #include #include +#include #include #includ
[PATCH v4 00/14] drm/hdcp: Pull HDCP auth/exchange/check into helpers
From: Sean Paul Just me with another revision of HDCP support for msm. This v4 patch series is mostly a retread of v3 with the following changes: - rebased on Bjorn's displayport-controller register refactor - another change to the dt bindings to remove the compatible string added in v3 - updated review tags I'm missing reviews on the core, i915 patches, and the final patch. It would be fantastic to get some feedback on these before the set once again drifts too far from -tip and I need a painful rebase :-) Thank you to the reviewers for their feedback thus far! Please take a look, Sean Link: https://patchwork.freedesktop.org/series/94623/ #v1 Link: https://patchwork.freedesktop.org/series/94713/ #v2 Link: https://patchwork.freedesktop.org/series/94712/ #v3 Sean Paul (14): 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 drm/msm/dpu_kms: Re-order dpu includes drm/msm/dpu: Remove useless checks in dpu_encoder drm/msm/dpu: Remove encoder->enable() hack drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules 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.dtsi |8 +- drivers/gpu/drm/drm_hdcp.c| 1197 - drivers/gpu/drm/i915/display/intel_atomic.c |7 +- drivers/gpu/drm/i915/display/intel_ddi.c | 29 +- .../drm/i915/display/intel_display_debugfs.c | 11 +- .../drm/i915/display/intel_display_types.h| 58 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 345 ++--- drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++--- drivers/gpu/drm/i915/display/intel_hdcp.h | 36 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++-- drivers/gpu/drm/msm/Makefile |1 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 17 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 30 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |2 - drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |4 - drivers/gpu/drm/msm/dp/dp_debug.c | 46 +- drivers/gpu/drm/msm/dp/dp_debug.h |6 +- drivers/gpu/drm/msm/dp/dp_display.c | 48 +- drivers/gpu/drm/msm/dp/dp_display.h |5 + drivers/gpu/drm/msm/dp/dp_drm.c | 68 +- drivers/gpu/drm/msm/dp/dp_drm.h |5 + drivers/gpu/drm/msm/dp/dp_hdcp.c | 462 +++ drivers/gpu/drm/msm/dp/dp_hdcp.h | 27 + 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/drm_hdcp.h| 194 +++ 30 files changed, 2592 insertions(+), 1377 deletions(-) create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v2] drm/bridge: analogix_dp: Make PSR-exit block less
On Fri, Oct 29, 2021 at 04:50:55PM -0700, Brian Norris wrote: > Prior to commit 6c836d965bad ("drm/rockchip: Use the helpers for PSR"), > "PSR exit" used non-blocking analogix_dp_send_psr_spd(). The refactor > started using the blocking variant, for a variety of reasons -- quoting > Sean Paul's potentially-faulty memory: > > """ > - To avoid racing a subsequent PSR entry (if exit takes a long time) > - To avoid racing disable/modeset > - We're not displaying new content while exiting PSR anyways, so there >is minimal utility in allowing frames to be submitted > - We're lying to userspace telling them frames are on the screen when >we're just dropping them on the floor > """ > > However, I'm finding that this blocking transition is causing upwards of > 60+ ms of unneeded latency on PSR-exit, to the point that initial cursor > movements when leaving PSR are unbearably jumpy. > > It turns out that we need to meet in the middle somewhere: Sean is right > that we were "lying to userspace" with a non-blocking PSR-exit, but the > new blocking behavior is also waiting too long: > > According to the eDP specification, the sink device must support PSR > entry transitions from both state 4 (ACTIVE_RESYNC) and state 0 > (INACTIVE). It also states that in ACTIVE_RESYNC, "the Sink device must > display the incoming active frames from the Source device with no > visible glitches and/or artifacts." > > Thus, for our purposes, we only need to wait for ACTIVE_RESYNC before > moving on; we are ready to display video, and subsequent PSR-entry is > safe. > > Tested on a Samsung Chromebook Plus (i.e., Rockchip RK3399 Gru Kevin), > where this saves about 60ms of latency, for PSR-exit that used to > take about 80ms. > > Fixes: 6c836d965bad ("drm/rockchip: Use the helpers for PSR") > Cc: > Cc: Zain Wang > Cc: Tomasz Figa > Cc: Heiko Stuebner > Cc: Sean Paul Thank you for revising this! Reviewed-by: Sean Paul > Signed-off-by: Brian Norris > --- > CC list is partially constructed from the commit message of the Fixed > commit > > Changes in v2: > - retitled subject (previous: "drm/bridge: analogix_dp: Make >PSR-disable non-blocking") > - instead of completely non-blocking, make this "less"-blocking > - more background (thanks Sean!) > - more specification details > > drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 14 -- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c > b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c > index cab6c8b92efd..f8e119e84ae2 100644 > --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c > +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c > @@ -998,11 +998,21 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device > *dp, > if (!blocking) > return 0; > > + /* > + * db[1]==0: entering PSR, wait for fully active remote frame buffer. > + * db[1]!=0: exiting PSR, wait for either > + * (a) ACTIVE_RESYNC - the sink "must display the > + * incoming active frames from the Source device with no visible > + * glitches and/or artifacts", even though timings may still be > + * re-synchronizing; or > + * (b) INACTIVE - the transition is fully complete. > + */ > ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status, > psr_status >= 0 && > ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) || > - (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500, > - DP_TIMEOUT_PSR_LOOP_MS * 1000); > + (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC || > + psr_status == DP_PSR_SINK_INACTIVE))), > + 1500, DP_TIMEOUT_PSR_LOOP_MS * 1000); > if (ret) { > dev_warn(dp->dev, "Failed to apply PSR %d\n", ret); > return ret; > -- > 2.33.1.1089.g2158813163f-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v3 12/14] dt-bindings: msm/dp: Add bindings for HDCP registers
On Mon, Oct 04, 2021 at 02:58:41PM -0500, Bjorn Andersson wrote: > On Fri 01 Oct 10:11 CDT 2021, Sean Paul wrote: > > > 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. > > > > I don't think you need a new compatible, in particular since I presume > we should use the hdcp compatible in all platforms? Or is there a reason > for not picking that one? > > Instead I suggest that you simply do minItems: 1, maxItems: 3 and detect > which of the two cases you have in the driver. Thanks for your review, Bjorn! I had done this in v2 (see [1] & [2]), but it was suggested that a new compatible would be better. I'll change it back to this method rebased on top of your changes. Sean [1]- https://patchwork.freedesktop.org/patch/454066/?series=94712&rev=1 [2]- https://patchwork.freedesktop.org/patch/454068/?series=94712&rev=1 > > PS. I hope to get > https://lore.kernel.org/linux-arm-msm/20211001174400.981707-1-bjorn.anders...@linaro.org/ > landed before we add these new optional regions... > > Regards, > Bjorn > > > Cc: Rob Herring > > Cc: Stephen Boyd > > Signed-off-by: Sean Paul > > 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 > > > > 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 > > --- > > > > Disclaimer: I really don't know if this is the right way to approach > > this. I tried using examples from other bindings, but feedback would be > > very much welcome on how I could add the optional register ranges. > > > > > > .../bindings/display/msm/dp-controller.yaml | 34 --- > > 1 file changed, 30 insertions(+), 4 deletions(-) > > > > diff --git > > a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml > > b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml > > index 64d8d9e5e47a..a176f97b2f4c 100644 > > --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml > > +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml > > @@ -17,9 +17,10 @@ properties: > >compatible: > > enum: > >- qcom,sc7180-dp > > + - qcom,sc7180-dp-hdcp > > > > - reg: > > -maxItems: 1 > > + # See compatible-specific constraints below. > > + reg: true > > > >interrupts: > > maxItems: 1 > > @@ -89,6 +90,29 @@ required: > >- power-domains > >- ports > > > > +allOf: > > + - if: > > + properties: > > +compatible: > > + contains: > > +const: qcom,sc7180-dp-hdcp > > +then: > > + properties: > > +reg: > > + minItems: 3 > > + maxItems: 3 > > + items: > > +- description: Registers for base DP functionality > > +- description: (Optional) Registers for HDCP device key > > injection > > +- description: (Optional) Registers for HDCP TrustZone > > interaction > > +else: > > + properties: > > +reg: > > + minItems: 1 > > + maxItems: 1 > > + items: > > +- description: Registers for base DP functionality > > + > > additionalProperties: false > > > > examples: > > @@ -99,8 +123,10 @@ examples: > > #include > > > > displayport-controller@ae9 { > > -compatible = "qcom,sc7180-dp"; > > -reg = <0xae9 0x1400>; > > +compatible = "qcom,sc7180-dp-hdcp"; > > +reg = <0 0x0ae9 0 0x1400>, > > + <0 0x0aed1000 0 0x174>, > > + <0 0x0aee1000 0 0x2c>; > > interrupt-parent = <&mdss>; > > interrupts = <12>; > > clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, > > -- > > Sean Paul, Software Engineer, Google / Chromium OS > > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [Intel-gfx] [PATCH v3 1/3] drm: Rename lut check functions to lut channel checks
On Thu, Oct 28, 2021 at 11:03:54PM -0400, Mark Yacoub wrote: > 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. > Yeah, understood. Regardless of that, the spirit of the function is not specific to the color channels in the LUT, so renaming as channels_check is probably not the correct fix. I'd probably lean towards stuffing this in i915 as a driver-specific check instead of renaming it. Sean > > 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 &drm_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 > > > + * &drm_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; > > > - u
Re: [Intel-gfx] [PATCH v3 2/3] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.
rm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h > index 4045e2507e11c..a22d32a7a8719 100644 > --- a/include/drm/drm_atomic_helper.h > +++ b/include/drm/drm_atomic_helper.h > @@ -38,6 +38,7 @@ struct drm_atomic_state; > struct drm_private_obj; > struct drm_private_state; > > +int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state); > int drm_atomic_helper_check_modeset(struct drm_device *dev, > struct drm_atomic_state *state); > int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, > diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h > index cb1bf361ad3e3..c214812d1b7a5 100644 > --- a/include/drm/drm_color_mgmt.h > +++ b/include/drm/drm_color_mgmt.h > @@ -74,6 +74,19 @@ static inline int drm_color_lut_size(const struct > drm_property_blob *blob) > return blob->length / sizeof(struct drm_color_lut); > } > > +/** > + * drm_check_lut_size - Checks if LUT size matches the driver expected size. > + * @lut: blob containing the LUT > + * @expected_size: driver expected LUT size > + * > + * Returns -EINVAL on mismatch, 0 on match. > + */ > +static inline int drm_check_lut_size(const struct drm_property_blob *lut, > + uint64_t expected_size) > +{ If you add back in the check for !lut which existed in the intel version, you can remove all the NULL checks which precede this call above and this function will be less of a toy. I'd probably just lift the intel function into drm_color_mgmt.c with the improved docbook and export it. > + return drm_color_lut_size(lut) != expected_size ? -EINVAL : 0; > +} > + > enum drm_color_encoding { > DRM_COLOR_YCBCR_BT601, > DRM_COLOR_YCBCR_BT709, > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 2deb15d7e1610..cabd3ef1a6e32 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -1072,6 +1072,17 @@ struct drm_crtc { > /** @funcs: CRTC control functions */ > const struct drm_crtc_funcs *funcs; > > + /** > + * @degamma_lut_size: Size of degamma LUT. > + */ > + uint32_t degamma_lut_size; > + > + /** > + * @gamma_lut_size: Size of Gamma LUT. Not used by legacy userspace > such as > + * X, which doesn't support large lut sizes. > + */ > + uint32_t gamma_lut_size; > + > /** >* @gamma_size: Size of legacy gamma ramp reported to userspace. Set up >* by calling drm_mode_crtc_set_gamma_size(). > -- > 2.33.0.1079.g6e70778dc9-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [Intel-gfx] [PATCH v3 1/3] drm: Rename lut check functions to lut channel checks
t; > /** > - * 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 > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] drm/mediatek: Set Rotation default value to 1.
On Mon, Oct 25, 2021 at 09:11:54PM -0400, Sean Paul wrote: > On Fri, Oct 22, 2021 at 12:54:02PM -0400, Mark Yacoub wrote: > > From: Mark Yacoub > > > > [Why] > > The Rotation prob is a bitmask value. It must always have a valid value. > > nit: s/prob/prop/ > > > A default NO rotation is equal to 1 not 0. > > > > [How] > > 1. At the reset hook, call __drm_atomic_helper_plane_reset which is > > called at the initialization of the plane and sets the default value of > > all planes to DRM_MODE_ROTATE_0 which is equal to 1. > > 2. At the ovl layer check, do no overwrite the state->rotation value 0 > > if DRM_MODE_ROTATE_0 is set. We should not change the value that the > > userspace has set, especially if it's an unsupported value. > > nit: I would probably split these into 2 patches since they're related but > different Did you decide not to remove the default value from the plane rotation value? I still think we should do that. Sean > > Sean > > > > > Tested on Jacuzzi(MTK). > > Fixes IGT@kms_properties@plane-properties-{legacy,atomic} and > > IGT@kms_properties@get_properties-sanity-{atomic,non-atomic} > > > > Signed-off-by: Mark Yacoub > > --- > > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 2 +- > > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 20 +++- > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 5 ++--- > > drivers/gpu/drm/mediatek/mtk_drm_plane.c| 3 ++- > > 4 files changed, 12 insertions(+), 18 deletions(-) > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > index 86c3068894b11..2fc566964f68e 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > @@ -64,7 +64,7 @@ void mtk_ovl_config(struct device *dev, unsigned int w, > > unsigned int h, unsigned int vrefresh, > > unsigned int bpc, struct cmdq_pkt *cmdq_pkt); > > int mtk_ovl_layer_check(struct device *dev, unsigned int idx, > > - struct mtk_plane_state *mtk_state); > > + const struct mtk_plane_state *mtk_state); > > void mtk_ovl_layer_config(struct device *dev, unsigned int idx, > > struct mtk_plane_state *state, > > struct cmdq_pkt *cmdq_pkt); > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > index ea5760f856ec6..13999564304bc 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c > > @@ -190,19 +190,15 @@ unsigned int mtk_ovl_supported_rotations(struct > > device *dev) > > } > > > > int mtk_ovl_layer_check(struct device *dev, unsigned int idx, > > - struct mtk_plane_state *mtk_state) > > + const struct mtk_plane_state *mtk_state) > > { > > - struct drm_plane_state *state = &mtk_state->base; > > - unsigned int rotation = 0; > > + const struct drm_plane_state *state = &mtk_state->base; > > + unsigned int rotation = drm_rotation_simplify( > > + state->rotation, > > + DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y); > > > > - rotation = drm_rotation_simplify(state->rotation, > > -DRM_MODE_ROTATE_0 | > > -DRM_MODE_REFLECT_X | > > -DRM_MODE_REFLECT_Y); > > - rotation &= ~DRM_MODE_ROTATE_0; > > - > > - /* We can only do reflection, not rotation */ > > - if ((rotation & DRM_MODE_ROTATE_MASK) != 0) > > + /* We can only do reflection, not non-zero rotation */ > > + if (((rotation & ~DRM_MODE_ROTATE_0) & DRM_MODE_ROTATE_MASK) != 0) > > return -EINVAL; > > > > /* > > @@ -212,8 +208,6 @@ int mtk_ovl_layer_check(struct device *dev, unsigned > > int idx, > > if (state->fb->format->is_yuv && rotation != 0) > > return -EINVAL; > > > > - state->rotation = rotation; > > - > > return 0; > > } > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h > > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h > > index 1b582262b682b..530bdd031933f 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h > > @@ -53,9 +53,8 @@ struct mtk_ddp_comp_funcs { > >
Re: [Intel-gfx] [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.
ls_tests) || > + drm_color_lut_channels_check(gamma_lut, gamma_channels_tests)) > return -EINVAL; > > return 0; > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h > index 4045e2507e11c..a22d32a7a8719 100644 > --- a/include/drm/drm_atomic_helper.h > +++ b/include/drm/drm_atomic_helper.h > @@ -38,6 +38,7 @@ struct drm_atomic_state; > struct drm_private_obj; > struct drm_private_state; > > +int drm_atomic_helper_check_crtcs(struct drm_atomic_state *state); > int drm_atomic_helper_check_modeset(struct drm_device *dev, > struct drm_atomic_state *state); > int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, > 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 > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 2deb15d7e1610..cabd3ef1a6e32 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -1072,6 +1072,17 @@ struct drm_crtc { > /** @funcs: CRTC control functions */ > const struct drm_crtc_funcs *funcs; > > + /** > + * @degamma_lut_size: Size of degamma LUT. > + */ > + uint32_t degamma_lut_size; > + > + /** > + * @gamma_lut_size: Size of Gamma LUT. Not used by legacy userspace > such as > + * X, which doesn't support large lut sizes. > + */ > + uint32_t gamma_lut_size; > + > /** >* @gamma_size: Size of legacy gamma ramp reported to userspace. Set up >* by calling drm_mode_crtc_set_gamma_size(). > -- > 2.33.0.882.g93a45727a2-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] mediatek: Set default value for Panel Orientation connector prop.
On Fri, Oct 22, 2021 at 01:24:03PM -0400, Mark Yacoub wrote: > From: Mark Yacoub > > [Why] > Creating the prop uses UNKNOWN as the initial value, which is not a > supported value if the props is to be supported. > > [How] > Set the panel orientation default value to NORMAL right after creating > the prop. Reviewed-by: Sean Paul > > Tested on Jacuzzi(MTK) > Fixes IGT@kms_properties@get_properties-sanity-{atomic,non-atomic} > > Signed-off-by: Mark Yacoub > --- > drivers/gpu/drm/mediatek/mtk_dsi.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c > b/drivers/gpu/drm/mediatek/mtk_dsi.c > index 0ad7157660afa..b7c2528a8f41c 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c > @@ -1039,6 +1039,8 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, > struct mtk_dsi *dsi) > DRM_ERROR("Unable to init panel orientation\n"); > goto err_cleanup_encoder; > } > + drm_connector_set_panel_orientation(dsi->connector, > + DRM_MODE_PANEL_ORIENTATION_NORMAL); > > drm_connector_attach_encoder(dsi->connector, &dsi->encoder); > > -- > 2.33.0.1079.g6e70778dc9-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] drm/mediatek: Set Rotation default value to 1.
struct cmdq_pkt *cmdq_pkt); > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c > b/drivers/gpu/drm/mediatek/mtk_drm_plane.c > index e6dcb34d30522..accd26481b9fb 100644 > --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c > +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c > @@ -44,9 +44,10 @@ static void mtk_plane_reset(struct drm_plane *plane) > state = kzalloc(sizeof(*state), GFP_KERNEL); > if (!state) > return; > - plane->state = &state->base; > } > > + __drm_atomic_helper_plane_reset(plane, &state->base); > + > state->base.plane = plane; > state->pending.format = DRM_FORMAT_RGB565; > } > -- > 2.33.0.1079.g6e70778dc9-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] drm/bridge: analogix_dp: Make PSR-disable non-blocking
On Wed, Oct 20, 2021 at 04:17:28PM -0700, Brian Norris wrote: > Prior to commit 6c836d965bad ("drm/rockchip: Use the helpers for PSR"), > "PSR disable" used non-blocking analogix_dp_send_psr_spd(). The refactor > accidentally (?) set blocking=true. IIRC this wasn't accidental. The reason it became synchronous was: - To avoid racing a subsequent PSR entry (if exit takes a long time) - To avoid racing disable/modeset - We're not displaying new content while exiting PSR anyways, so there is minimal utility in allowing frames to be submitted - We're lying to userspace telling them frames are on the screen when we're just dropping them on the floor The actual latency gains from doing this synchronously are minimal since the panel will display new content as soon as it can regardless of whether the kernel is blocking. There is likely a perceptual difference, but that's only because kernel is lying to userspace and skipping frames without consent. Going back to the first line, it's entirely possible my memory is failing and this was accidental! Sean > > This can cause upwards of 60-100ms of unneeded latency when exiting > self-refresh, which can cause very noticeable lag when, say, moving a > cursor. > > Presumbaly it's OK to let the display finish exiting refresh in parallel > with clocking out the next video frames, so we shouldn't hold up the > atomic_enable() step. This also brings behavior in line with the > downstream ("mainline-derived") variant of the driver currently deployed > to Chrome OS Rockchip systems. > > Tested on a Samsung Chromebook Plus (i.e., Rockchip RK3399 Gru Kevin). > > Fixes: 6c836d965bad ("drm/rockchip: Use the helpers for PSR") > Cc: > Cc: Zain Wang > Cc: Tomasz Figa > Cc: Heiko Stuebner > Cc: Sean Paul > Signed-off-by: Brian Norris > --- > CC list is partially constructed from the commit message of the Fixed > commit > > drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > index b7d2e4449cfa..fbe6eb9df310 100644 > --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > @@ -1055,7 +1055,7 @@ static int analogix_dp_disable_psr(struct > analogix_dp_device *dp) > psr_vsc.db[0] = 0; > psr_vsc.db[1] = 0; > > - return analogix_dp_send_psr_spd(dp, &psr_vsc, true); > + return analogix_dp_send_psr_spd(dp, &psr_vsc, false); > } > > /* > -- > 2.33.0.1079.g6e70778dc9-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] MAINTAINERS: Fixup drm-misc website link
On Tue, Oct 19, 2021 at 9:00 PM Brian Norris wrote: > > https://drm.pages.freedesktop.org/maintainer-tools/drm-misc.html gives > HTTP 404, and https://drm.pages.freedesktop.org/maintainer-tools/ > redirects to freedesktop.org now. > > Let's save people the pain of figuring that out. > Nice catch! Reviewed-by: Sean Paul (fwiw) > Signed-off-by: Brian Norris > --- > > MAINTAINERS | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 100d7f93a15b..811d8d3e35fb 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6158,7 +6158,7 @@ M:Maarten Lankhorst > > M: Maxime Ripard > M: Thomas Zimmermann > S: Maintained > -W: https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html > +W: https://drm.pages.freedesktop.org/maintainer-tools/drm-misc.html > T: git git://anongit.freedesktop.org/drm/drm-misc > F: Documentation/gpu/ > F: drivers/gpu/drm/* > -- > 2.33.0.1079.g6e70778dc9-goog >
Re: [PATCH 2/2] amd/amdgpu_dm: Verify Gamma and Degamma LUT sizes using DRM Core check
On Wed, Oct 13, 2021 at 2:12 PM Mark Yacoub wrote: > > 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. > Reviewed-by: Sean Paul > 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, &size); > - 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, &size); > - 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(&crtc->base); > - if (r) > - return r; > - > degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, > °amma_size); > regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, ®amma_size); > > -- > 2.33.0.882.g93a45727a2-goog >
Re: [PATCH 15/16] Revert "drm/i915: cleanup: drm_modeset_lock_all_ctx() --> DRM_MODESET_LOCK_ALL_BEGIN()"
On Mon, Oct 04, 2021 at 12:41:00PM +0300, Ville Syrjälä wrote: > On Sat, Oct 02, 2021 at 11:45:41AM -0400, Sean Paul wrote: > > From: Sean Paul > > > > This reverts commit 399190e70816886e2bca1f3f3bc3d9c544af88e7. > > > > This patchset breaks on intel platforms and was previously NACK'd by > > Ville. > > > > Cc: Ville Syrjälä > > Cc: Fernando Ramos > > Signed-off-by: Sean Paul > > Yeah, best to try again from the start I think. Pushed the revert set (and left the TODO item out for now). Thanks for raising the issue. @Fernando, hopefully you can revise and post again. Thank you for your patches and your effort! Sean > > For the series > Acked-by: Ville Syrjälä > > > --- > > drivers/gpu/drm/i915/display/intel_display.c | 18 +- > > 1 file changed, 13 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c > > b/drivers/gpu/drm/i915/display/intel_display.c > > index 2bf01416d656..134a6acbd8fb 100644 > > --- a/drivers/gpu/drm/i915/display/intel_display.c > > +++ b/drivers/gpu/drm/i915/display/intel_display.c > > @@ -43,7 +43,6 @@ > > #include > > #include > > #include > > -#include > > > > #include "display/intel_audio.h" > > #include "display/intel_crt.h" > > @@ -13477,13 +13476,22 @@ void intel_display_resume(struct drm_device *dev) > > if (state) > > state->acquire_ctx = &ctx; > > > > - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); > > + drm_modeset_acquire_init(&ctx, 0); > > > > - ret = __intel_display_resume(dev, state, &ctx); > > + while (1) { > > + ret = drm_modeset_lock_all_ctx(dev, &ctx); > > + if (ret != -EDEADLK) > > + break; > > > > - intel_enable_ipc(dev_priv); > > + drm_modeset_backoff(&ctx); > > + } > > + > > + if (!ret) > > + ret = __intel_display_resume(dev, state, &ctx); > > > > - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); > > + intel_enable_ipc(dev_priv); > > + drm_modeset_drop_locks(&ctx); > > + drm_modeset_acquire_fini(&ctx); > > > > if (ret) > > drm_err(&dev_priv->drm, > > -- > > Sean Paul, Software Engineer, Google / Chromium OS > > -- > Ville Syrjälä > Intel -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 16/16] Revert "drm: cleanup: drm_modeset_lock_all_ctx() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 21dde40902d2636f70766b3154931de57e1215e9. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/drm_client_modeset.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 5f5184f071ed..ced09c7c06f9 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -574,7 +574,6 @@ static bool drm_client_firmware_config(struct drm_client_dev *client, int num_connectors_detected = 0; int num_tiled_conns = 0; struct drm_modeset_acquire_ctx ctx; - int err; if (!drm_drv_uses_atomic_modeset(dev)) return false; @@ -586,7 +585,10 @@ static bool drm_client_firmware_config(struct drm_client_dev *client, if (!save_enabled) return false; - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err); + drm_modeset_acquire_init(&ctx, 0); + + while (drm_modeset_lock_all_ctx(dev, &ctx) != 0) + drm_modeset_backoff(&ctx); memcpy(save_enabled, enabled, count); mask = GENMASK(count - 1, 0); @@ -741,7 +743,8 @@ static bool drm_client_firmware_config(struct drm_client_dev *client, ret = false; } - DRM_MODESET_LOCK_ALL_END(dev, ctx, err); + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); kfree(save_enabled); return ret; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 15/16] Revert "drm/i915: cleanup: drm_modeset_lock_all_ctx() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 399190e70816886e2bca1f3f3bc3d9c544af88e7. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/i915/display/intel_display.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2bf01416d656..134a6acbd8fb 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -43,7 +43,6 @@ #include #include #include -#include #include "display/intel_audio.h" #include "display/intel_crt.h" @@ -13477,13 +13476,22 @@ void intel_display_resume(struct drm_device *dev) if (state) state->acquire_ctx = &ctx; - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_acquire_init(&ctx, 0); - ret = __intel_display_resume(dev, state, &ctx); + while (1) { + ret = drm_modeset_lock_all_ctx(dev, &ctx); + if (ret != -EDEADLK) + break; - intel_enable_ipc(dev_priv); + drm_modeset_backoff(&ctx); + } + + if (!ret) + ret = __intel_display_resume(dev, state, &ctx); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + intel_enable_ipc(dev_priv); + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); if (ret) drm_err(&dev_priv->drm, -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 13/16] Revert "drm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 7c5f2eecc21f44fba1b1f13ce09c2533db9d781a. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/drm_client_modeset.c | 5 ++--- drivers/gpu/drm/drm_crtc_helper.c| 18 ++ drivers/gpu/drm/drm_fb_helper.c | 10 -- drivers/gpu/drm/drm_framebuffer.c| 6 ++ 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 43f772543d2a..5f5184f071ed 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -1062,10 +1062,9 @@ static int drm_client_modeset_commit_legacy(struct drm_client_dev *client) struct drm_device *dev = client->dev; struct drm_mode_set *mode_set; struct drm_plane *plane; - struct drm_modeset_acquire_ctx ctx; int ret = 0; - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); drm_for_each_plane(plane, dev) { if (plane->type != DRM_PLANE_TYPE_PRIMARY) drm_plane_force_disable(plane); @@ -1094,7 +1093,7 @@ static int drm_client_modeset_commit_legacy(struct drm_client_dev *client) goto out; } out: - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); return ret; } diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f3ce073dff79..bff917531f33 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -218,14 +218,11 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev) */ void drm_helper_disable_unused_functions(struct drm_device *dev) { - struct drm_modeset_acquire_ctx ctx; - int ret; - WARN_ON(drm_drv_uses_atomic_modeset(dev)); - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); __drm_helper_disable_unused_functions(dev); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); } EXPORT_SYMBOL(drm_helper_disable_unused_functions); @@ -945,14 +942,12 @@ void drm_helper_resume_force_mode(struct drm_device *dev) struct drm_crtc *crtc; struct drm_encoder *encoder; const struct drm_crtc_helper_funcs *crtc_funcs; - struct drm_modeset_acquire_ctx ctx; int encoder_dpms; bool ret; - int err; WARN_ON(drm_drv_uses_atomic_modeset(dev)); - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err); + drm_modeset_lock_all(dev); drm_for_each_crtc(crtc, dev) { if (!crtc->enabled) @@ -987,7 +982,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev) /* disable the unused connectors while restoring the modesetting */ __drm_helper_disable_unused_functions(dev); - DRM_MODESET_LOCK_ALL_END(dev, ctx, err); + drm_modeset_unlock_all(dev); } EXPORT_SYMBOL(drm_helper_resume_force_mode); @@ -1007,10 +1002,9 @@ EXPORT_SYMBOL(drm_helper_resume_force_mode); int drm_helper_force_disable_all(struct drm_device *dev) { struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; int ret = 0; - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); drm_for_each_crtc(crtc, dev) if (crtc->enabled) { struct drm_mode_set set = { @@ -1022,7 +1016,7 @@ int drm_helper_force_disable_all(struct drm_device *dev) goto out; } out: - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); return ret; } EXPORT_SYMBOL(drm_helper_force_disable_all); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 6860223f0068..3ab078321045 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -940,11 +940,10 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info) struct drm_fb_helper *fb_helper = info->par; struct drm_mode_set *modeset; struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; u16 *r, *g, *b; int ret = 0; - DRM_MODESET_LOCK_ALL_BEGIN(fb_helper->dev, ctx, 0, ret); + drm_modeset_lock_all(fb_helper->dev); drm_client_for_each_modeset(modeset, &fb_helper->client) { crtc = modeset->crtc; if (!crtc->funcs->gamma_set || !crtc->gamma_size) { @@ -971,7 +970,7 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info) goto out; } out: - DRM_MODESET_LOCK_ALL_END(fb_helper->dev, ctx, ret); + drm_modeset_unlock_all(fb_helper->dev);
[PATCH 14/16] Revert "drm/msm: cleanup: drm_modeset_lock_all_ctx() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 4c048437ef7adb2d81fe4ddc5c04179126eefcf2. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c index abda52f09b09..cabe15190ec1 100644 --- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c +++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c @@ -5,8 +5,6 @@ #define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__ -#include - #include "msm_disp_snapshot.h" static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *base_addr) @@ -101,18 +99,20 @@ static void msm_disp_capture_atomic_state(struct msm_disp_state *disp_state) { struct drm_device *ddev; struct drm_modeset_acquire_ctx ctx; - int ret; disp_state->timestamp = ktime_get(); ddev = disp_state->drm_dev; - DRM_MODESET_LOCK_ALL_BEGIN(ddev, ctx, 0, ret); + drm_modeset_acquire_init(&ctx, 0); + + while (drm_modeset_lock_all_ctx(ddev, &ctx) != 0) + drm_modeset_backoff(&ctx); disp_state->atomic_state = drm_atomic_helper_duplicate_state(ddev, &ctx); - - DRM_MODESET_LOCK_ALL_END(ddev, ctx, ret); + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } void msm_disp_snapshot_capture_state(struct msm_disp_state *disp_state) -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 12/16] Revert "drm/vmwgfx: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 6b92e77156c5adf6606c8ad825c71404417d88af. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 11 --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 12 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 7df35c6f1458..28af34ab6ed6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -28,7 +28,6 @@ #include "vmwgfx_drv.h" #include "vmwgfx_devcaps.h" #include -#include #include "vmwgfx_kms.h" int vmw_getparam_ioctl(struct drm_device *dev, void *data, @@ -173,7 +172,6 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, struct drm_vmw_rect __user *clips_ptr; struct drm_vmw_rect *clips = NULL; struct drm_framebuffer *fb; - struct drm_modeset_acquire_ctx ctx; struct vmw_framebuffer *vfb; struct vmw_resource *res; uint32_t num_clips; @@ -205,7 +203,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, goto out_no_copy; } - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); if (!fb) { @@ -233,7 +231,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, out_no_surface: drm_framebuffer_put(fb); out_no_fb: - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); out_no_copy: kfree(clips); out_clips: @@ -252,7 +250,6 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, struct drm_vmw_rect __user *clips_ptr; struct drm_vmw_rect *clips = NULL; struct drm_framebuffer *fb; - struct drm_modeset_acquire_ctx ctx; struct vmw_framebuffer *vfb; uint32_t num_clips; int ret; @@ -283,7 +280,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, goto out_no_copy; } - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); if (!fb) { @@ -306,7 +303,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, out_no_ttm_lock: drm_framebuffer_put(fb); out_no_fb: - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); out_no_copy: kfree(clips); out_clips: diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 268095cb8c84..74fa41909213 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "vmwgfx_kms.h" @@ -244,17 +243,15 @@ void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv) struct drm_device *dev = &dev_priv->drm; struct vmw_display_unit *du; struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; - int ret; - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); drm_for_each_crtc(crtc, dev) { du = vmw_crtc_to_du(crtc); du->hotspot_x = 0; du->hotspot_y = 0; } - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); } void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv) @@ -1015,10 +1012,9 @@ static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer, struct vmw_framebuffer_bo *vfbd = vmw_framebuffer_to_vfbd(framebuffer); struct drm_clip_rect norect; - struct drm_modeset_acquire_ctx ctx; int ret, increment = 1; - DRM_MODESET_LOCK_ALL_BEGIN((&dev_priv->drm), ctx, 0, ret); + drm_modeset_lock_all(&dev_priv->drm); if (!num_clips) { num_clips = 1; @@ -1044,7 +1040,7 @@ static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer, vmw_cmd_flush(dev_priv, false); - DRM_MODESET_LOCK_ALL_END((&dev_priv->drm), ctx, ret); + drm_modeset_unlock_all(&dev_priv->drm); return ret; } -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 11/16] Revert "drm/tegra: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit a2cd9947d99b54c959fce20dc19d81af53f4674e. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/tegra/dsi.c | 6 ++ drivers/gpu/drm/tegra/hdmi.c | 6 ++ drivers/gpu/drm/tegra/sor.c | 11 --- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 28050c188c1c..f46d377f0c30 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "dc.h" #include "drm.h" @@ -203,11 +202,10 @@ static int tegra_dsi_show_regs(struct seq_file *s, void *data) struct tegra_dsi *dsi = node->info_ent->data; struct drm_crtc *crtc = dsi->output.encoder.crtc; struct drm_device *drm = node->minor->dev; - struct drm_modeset_acquire_ctx ctx; unsigned int i; int err = 0; - DRM_MODESET_LOCK_ALL_BEGIN(drm, ctx, 0, err); + drm_modeset_lock_all(drm); if (!crtc || !crtc->state->active) { err = -EBUSY; @@ -222,7 +220,7 @@ static int tegra_dsi_show_regs(struct seq_file *s, void *data) } unlock: - DRM_MODESET_LOCK_ALL_END(drm, ctx, err); + drm_modeset_unlock_all(drm); return err; } diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index a62de7f92414..e5d2a4026028 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "hda.h" #include "hdmi.h" @@ -1032,11 +1031,10 @@ static int tegra_hdmi_show_regs(struct seq_file *s, void *data) struct tegra_hdmi *hdmi = node->info_ent->data; struct drm_crtc *crtc = hdmi->output.encoder.crtc; struct drm_device *drm = node->minor->dev; - struct drm_modeset_acquire_ctx ctx; unsigned int i; int err = 0; - DRM_MODESET_LOCK_ALL_BEGIN(drm, ctx, 0, err); + drm_modeset_lock_all(drm); if (!crtc || !crtc->state->active) { err = -EBUSY; @@ -1051,7 +1049,7 @@ static int tegra_hdmi_show_regs(struct seq_file *s, void *data) } unlock: - DRM_MODESET_LOCK_ALL_END(drm, ctx, err); + drm_modeset_unlock_all(drm); return err; } diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 3d1c8b3d1358..0ea320c1092b 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "dc.h" #include "dp.h" @@ -1491,11 +1490,10 @@ static int tegra_sor_show_crc(struct seq_file *s, void *data) struct tegra_sor *sor = node->info_ent->data; struct drm_crtc *crtc = sor->output.encoder.crtc; struct drm_device *drm = node->minor->dev; - struct drm_modeset_acquire_ctx ctx; int err = 0; u32 value; - DRM_MODESET_LOCK_ALL_BEGIN(drm, ctx, 0, err); + drm_modeset_lock_all(drm); if (!crtc || !crtc->state->active) { err = -EBUSY; @@ -1524,7 +1522,7 @@ static int tegra_sor_show_crc(struct seq_file *s, void *data) seq_printf(s, "%08x\n", value); unlock: - DRM_MODESET_LOCK_ALL_END(drm, ctx, err); + drm_modeset_unlock_all(drm); return err; } @@ -1654,11 +1652,10 @@ static int tegra_sor_show_regs(struct seq_file *s, void *data) struct tegra_sor *sor = node->info_ent->data; struct drm_crtc *crtc = sor->output.encoder.crtc; struct drm_device *drm = node->minor->dev; - struct drm_modeset_acquire_ctx ctx; unsigned int i; int err = 0; - DRM_MODESET_LOCK_ALL_BEGIN(drm, ctx, 0, err); + drm_modeset_lock_all(drm); if (!crtc || !crtc->state->active) { err = -EBUSY; @@ -1673,7 +1670,7 @@ static int tegra_sor_show_regs(struct seq_file *s, void *data) } unlock: - DRM_MODESET_LOCK_ALL_END(drm, ctx, err); + drm_modeset_unlock_all(drm); return err; } -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 10/16] Revert "drm/shmobile: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 9b8c437ef1a5f34686fc96b391c201a80f1a2ea0. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index 8ee215ab614e..7db01904d18d 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -156,12 +156,10 @@ static int shmob_drm_pm_suspend(struct device *dev) static int shmob_drm_pm_resume(struct device *dev) { struct shmob_drm_device *sdev = dev_get_drvdata(dev); - struct drm_modeset_acquire_ctx ctx; - int ret; - DRM_MODESET_LOCK_ALL_BEGIN(sdev->ddev, ctx, 0, ret); + drm_modeset_lock_all(sdev->ddev); shmob_drm_crtc_resume(&sdev->crtc); - DRM_MODESET_LOCK_ALL_END(sdev->ddev, ctx, ret); + drm_modeset_unlock_all(sdev->ddev); drm_kms_helper_poll_enable(sdev->ddev); return 0; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 09/16] Revert "drm/radeon: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 26723c3d6b930775f9a85521d09655c533a839e6. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/radeon/radeon_device.c | 21 ++--- drivers/gpu/drm/radeon/radeon_dp_mst.c | 10 -- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 7e31e5ce7f61..4f0fbf667431 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -1560,8 +1559,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, struct pci_dev *pdev; struct drm_crtc *crtc; struct drm_connector *connector; - struct drm_modeset_acquire_ctx ctx; - int i, r, ret; + int i, r; if (dev == NULL || dev->dev_private == NULL) { return -ENODEV; @@ -1575,15 +1573,12 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, drm_kms_helper_poll_disable(dev); - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); /* turn off display hw */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); } - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); - - if (ret) - return ret; + drm_modeset_unlock_all(dev); /* unpin the front buffers and cursors */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -1668,8 +1663,7 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) struct radeon_device *rdev = dev->dev_private; struct pci_dev *pdev = to_pci_dev(dev->dev); struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; - int r, ret; + int r; if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; @@ -1747,14 +1741,11 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) if (fbcon) { drm_helper_resume_force_mode(dev); /* turn on display hw */ - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); } - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); - - if (ret) - return ret; + drm_modeset_unlock_all(dev); } drm_kms_helper_poll_enable(dev); diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 3f83ee75b100..ec867fa880a4 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "atom.h" #include "ni_reg.h" @@ -738,12 +737,11 @@ static int radeon_debugfs_mst_info_show(struct seq_file *m, void *unused) struct radeon_device *rdev = (struct radeon_device *)m->private; struct drm_device *dev = rdev->ddev; struct drm_connector *connector; - struct drm_modeset_acquire_ctx ctx; struct radeon_connector *radeon_connector; struct radeon_connector_atom_dig *dig_connector; - int i, ret; + int i; - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) continue; @@ -761,8 +759,8 @@ static int radeon_debugfs_mst_info_show(struct seq_file *m, void *unused) radeon_connector->cur_stream_attribs[i].fe, radeon_connector->cur_stream_attribs[i].slots); } - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); - return ret; + drm_modeset_unlock_all(dev); + return 0; } DEFINE_SHOW_ATTRIBUTE(radeon_debugfs_mst_info); -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 08/16] Revert "drm/omapdrm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 6067fddc1a4fdf155787ab6182c192e4b360b73c. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/omapdrm/omap_fb.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index fa7636c13c19..190afc564914 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "omap_dmm_tiler.h" #include "omap_drv.h" @@ -63,17 +62,15 @@ static int omap_framebuffer_dirty(struct drm_framebuffer *fb, unsigned num_clips) { struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; - int ret; - DRM_MODESET_LOCK_ALL_BEGIN(fb->dev, ctx, 0, ret); + drm_modeset_lock_all(fb->dev); drm_for_each_crtc(crtc, fb->dev) omap_crtc_flush(crtc); - DRM_MODESET_LOCK_ALL_END(fb->dev, ctx, ret); + drm_modeset_unlock_all(fb->dev); - return ret; + return 0; } static const struct drm_framebuffer_funcs omap_framebuffer_funcs = { -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 07/16] Revert "drm/nouveau: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 6aa2daae589b63e8b39fe6f7f2b59fb3063efa05. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 86e18a844953..d7b9f7f8c9e3 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -42,7 +42,6 @@ #include #include #include -#include #include @@ -668,18 +667,16 @@ nv50_audio_component_bind(struct device *kdev, struct device *hda_kdev, struct drm_device *drm_dev = dev_get_drvdata(kdev); struct nouveau_drm *drm = nouveau_drm(drm_dev); struct drm_audio_component *acomp = data; - struct drm_modeset_acquire_ctx ctx; - int ret; if (WARN_ON(!device_link_add(hda_kdev, kdev, DL_FLAG_STATELESS))) return -ENOMEM; - DRM_MODESET_LOCK_ALL_BEGIN(drm_dev, ctx, 0, ret); + drm_modeset_lock_all(drm_dev); acomp->ops = &nv50_audio_component_ops; acomp->dev = kdev; drm->audio.component = acomp; - DRM_MODESET_LOCK_ALL_END(drm_dev, ctx, ret); - return ret; + drm_modeset_unlock_all(drm_dev); + return 0; } static void @@ -689,14 +686,12 @@ nv50_audio_component_unbind(struct device *kdev, struct device *hda_kdev, struct drm_device *drm_dev = dev_get_drvdata(kdev); struct nouveau_drm *drm = nouveau_drm(drm_dev); struct drm_audio_component *acomp = data; - struct drm_modeset_acquire_ctx ctx; - int ret; - DRM_MODESET_LOCK_ALL_BEGIN(drm_dev, ctx, 0, ret); + drm_modeset_lock_all(drm_dev); drm->audio.component = NULL; acomp->ops = NULL; acomp->dev = NULL; - DRM_MODESET_LOCK_ALL_END(drm_dev, ctx, ret); + drm_modeset_unlock_all(drm_dev); } static const struct component_ops nv50_audio_component_bind_ops = { -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 06/16] Revert "drm/msm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit fd49ef52e2db015ce69ad02bab0702489d141a41. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b89687074890..768012243b44 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "dpu_kms.h" #include "dpu_hw_lm.h" @@ -1173,15 +1172,14 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) struct drm_display_mode *mode; struct drm_framebuffer *fb; struct drm_plane_state *state; - struct drm_modeset_acquire_ctx ctx; struct dpu_crtc_state *cstate; - int i, out_width, ret; + int i, out_width; dpu_crtc = s->private; crtc = &dpu_crtc->base; - DRM_MODESET_LOCK_ALL_BEGIN(crtc->dev, ctx, 0, ret); + drm_modeset_lock_all(crtc->dev); cstate = to_dpu_crtc_state(crtc->state); mode = &crtc->state->adjusted_mode; @@ -1265,9 +1263,9 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) dpu_crtc->vblank_cb_time = ktime_set(0, 0); } - DRM_MODESET_LOCK_ALL_END(crtc->dev, ctx, ret); + drm_modeset_unlock_all(crtc->dev); - return ret; + return 0; } DEFINE_SHOW_ATTRIBUTE(_dpu_debugfs_status); -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 05/16] Revert "drm/i915: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 746826bcf8fdf682668ff1c415d6b91dbf5858be. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/i915/display/intel_audio.c| 16 +++ drivers/gpu/drm/i915/display/intel_display.c | 5 +- .../drm/i915/display/intel_display_debugfs.c | 46 +++ drivers/gpu/drm/i915/display/intel_overlay.c | 6 +-- drivers/gpu/drm/i915/display/intel_pipe_crc.c | 7 +-- drivers/gpu/drm/i915/i915_drv.c | 13 ++ 6 files changed, 32 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index c64f738cc062..532237588511 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -26,7 +26,6 @@ #include #include -#include #include "i915_drv.h" #include "intel_atomic.h" @@ -1215,8 +1214,7 @@ static int i915_audio_component_bind(struct device *i915_kdev, { struct i915_audio_component *acomp = data; struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev); - struct drm_modeset_acquire_ctx ctx; - int i, ret; + int i; if (drm_WARN_ON(&dev_priv->drm, acomp->base.ops || acomp->base.dev)) return -EEXIST; @@ -1226,16 +1224,16 @@ static int i915_audio_component_bind(struct device *i915_kdev, DL_FLAG_STATELESS))) return -ENOMEM; - DRM_MODESET_LOCK_ALL_BEGIN((&dev_priv->drm), ctx, 0, ret); + drm_modeset_lock_all(&dev_priv->drm); acomp->base.ops = &i915_audio_component_ops; acomp->base.dev = i915_kdev; BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS); for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++) acomp->aud_sample_rate[i] = 0; dev_priv->audio_component = acomp; - DRM_MODESET_LOCK_ALL_END((&dev_priv->drm), ctx, ret); + drm_modeset_unlock_all(&dev_priv->drm); - return ret; + return 0; } static void i915_audio_component_unbind(struct device *i915_kdev, @@ -1243,14 +1241,12 @@ static void i915_audio_component_unbind(struct device *i915_kdev, { struct i915_audio_component *acomp = data; struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev); - struct drm_modeset_acquire_ctx ctx; - int ret; - DRM_MODESET_LOCK_ALL_BEGIN((&dev_priv->drm), ctx, 0, ret); + drm_modeset_lock_all(&dev_priv->drm); acomp->base.ops = NULL; acomp->base.dev = NULL; dev_priv->audio_component = NULL; - DRM_MODESET_LOCK_ALL_END((&dev_priv->drm), ctx, ret); + drm_modeset_unlock_all(&dev_priv->drm); device_link_remove(hda_kdev, i915_kdev); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 297359411c5f..2bf01416d656 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -12512,7 +12512,6 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) int intel_modeset_init_nogem(struct drm_i915_private *i915) { struct drm_device *dev = &i915->drm; - struct drm_modeset_acquire_ctx ctx; enum pipe pipe; struct intel_crtc *crtc; int ret; @@ -12564,9 +12563,9 @@ int intel_modeset_init_nogem(struct drm_i915_private *i915) intel_vga_disable(i915); intel_setup_outputs(i915); - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); intel_modeset_setup_hw_state(dev, dev->mode_config.acquire_ctx); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); for_each_intel_crtc(dev, crtc) { struct intel_initial_plane_config plane_config = {}; diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index e0a6837996e7..8fdacb252bb1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -5,7 +5,6 @@ #include #include -#include #include "i915_debugfs.h" #include "intel_display_debugfs.h" @@ -1058,13 +1057,11 @@ static int i915_display_info(struct seq_file *m, void *unused) struct intel_crtc *crtc; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - struct drm_modeset_acquire_ctx ctx; intel_wakeref_t wakeref; - int ret; wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); seq_printf(m, "CRTC info\n&
[PATCH 04/16] Revert "drm/i915: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN() part 2"
From: Sean Paul This reverts commit 984c9949f1c4cf36c35aa2de5ee2b65c39379fd9. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/i915/display/intel_overlay.c | 40 ++-- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index c623738c59c8..c0ee135e5499 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -1105,7 +1105,6 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, struct drm_crtc *drmmode_crtc; struct intel_crtc *crtc; struct drm_i915_gem_object *new_bo; - struct drm_modeset_acquire_ctx ctx; int ret; overlay = dev_priv->overlay; @@ -1114,24 +1113,24 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, return -ENODEV; } - if (params->flags & I915_OVERLAY_ENABLE) { - - drmmode_crtc = drm_crtc_find(dev, file_priv, params->crtc_id); - if (!drmmode_crtc) - return -ENOENT; - crtc = to_intel_crtc(drmmode_crtc); + if (!(params->flags & I915_OVERLAY_ENABLE)) { + drm_modeset_lock_all(dev); + ret = intel_overlay_switch_off(overlay); + drm_modeset_unlock_all(dev); - new_bo = i915_gem_object_lookup(file_priv, params->bo_handle); - if (!new_bo) - return -ENOENT; + return ret; } - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drmmode_crtc = drm_crtc_find(dev, file_priv, params->crtc_id); + if (!drmmode_crtc) + return -ENOENT; + crtc = to_intel_crtc(drmmode_crtc); - if (!(params->flags & I915_OVERLAY_ENABLE)) { - ret = intel_overlay_switch_off(overlay); - goto out_unlock; - } + new_bo = i915_gem_object_lookup(file_priv, params->bo_handle); + if (!new_bo) + return -ENOENT; + + drm_modeset_lock_all(dev); if (i915_gem_object_is_tiled(new_bo)) { drm_dbg_kms(&dev_priv->drm, @@ -1196,11 +1195,14 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, if (ret != 0) goto out_unlock; -out_unlock: - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); + i915_gem_object_put(new_bo); + + return 0; - if (params->flags & I915_OVERLAY_ENABLE) - i915_gem_object_put(new_bo); +out_unlock: + drm_modeset_unlock_all(dev); + i915_gem_object_put(new_bo); return ret; } -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 03/16] Revert "drm/gma500: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 4f9e860e6ad65ff4ea8ce165a1407d96ff1b2211. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/gma500/psb_device.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c index 021a7238508f..3030f18ba022 100644 --- a/drivers/gpu/drm/gma500/psb_device.c +++ b/drivers/gpu/drm/gma500/psb_device.c @@ -8,7 +8,6 @@ #include #include -#include #include "gma_device.h" #include "intel_bios.h" @@ -170,10 +169,8 @@ static int psb_save_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; struct gma_connector *connector; struct psb_state *regs = &dev_priv->regs.psb; - int ret; /* Display arbitration control + watermarks */ regs->saveDSPARB = PSB_RVDC32(DSPARB); @@ -186,7 +183,7 @@ static int psb_save_display_registers(struct drm_device *dev) regs->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); /* Save crtc and output state */ - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (drm_helper_crtc_in_use(crtc)) dev_priv->ops->save_crtc(crtc); @@ -196,9 +193,8 @@ static int psb_save_display_registers(struct drm_device *dev) if (connector->save) connector->save(&connector->base); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); - - return ret; + drm_modeset_unlock_all(dev); + return 0; } /** @@ -211,10 +207,8 @@ static int psb_restore_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; struct gma_connector *connector; struct psb_state *regs = &dev_priv->regs.psb; - int ret; /* Display arbitration + watermarks */ PSB_WVDC32(regs->saveDSPARB, DSPARB); @@ -229,7 +223,7 @@ static int psb_restore_display_registers(struct drm_device *dev) /*make sure VGA plane is off. it initializes to on after reset!*/ PSB_WVDC32(0x8000, VGACNTRL); - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) if (drm_helper_crtc_in_use(crtc)) dev_priv->ops->restore_crtc(crtc); @@ -238,8 +232,8 @@ static int psb_restore_display_registers(struct drm_device *dev) if (connector->restore) connector->restore(&connector->base); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); - return ret; + drm_modeset_unlock_all(dev); + return 0; } static int psb_power_down(struct drm_device *dev) -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH 02/16] Revert "drm/amd: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN()"
From: Sean Paul This reverts commit 299f040e855b69c29522cde446777902381a07f5. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 21 +++- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 50 +-- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 25 -- 3 files changed, 43 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index b07e845a2600..7a7316731911 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -40,7 +40,6 @@ #include #include #include -#include static void amdgpu_display_flip_callback(struct dma_fence *f, struct dma_fence_cb *cb) @@ -1544,21 +1543,16 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev) struct drm_crtc *crtc; struct drm_connector *connector; struct drm_connector_list_iter iter; - struct drm_modeset_acquire_ctx ctx; - int r, ret; + int r; /* turn off display hw */ - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); drm_connector_list_iter_begin(dev, &iter); drm_for_each_connector_iter(connector, &iter) drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); drm_connector_list_iter_end(&iter); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); - - if (ret) - return ret; - + drm_modeset_unlock_all(dev); /* unpin the front buffers and cursors */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); @@ -1596,8 +1590,7 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev) struct drm_connector *connector; struct drm_connector_list_iter iter; struct drm_crtc *crtc; - struct drm_modeset_acquire_ctx ctx; - int r, ret; + int r; /* pin cursors */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -1619,7 +1612,7 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev) drm_helper_resume_force_mode(dev); /* turn on display hw */ - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + drm_modeset_lock_all(dev); drm_connector_list_iter_begin(dev, &iter); drm_for_each_connector_iter(connector, &iter) @@ -1627,8 +1620,8 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev) DRM_MODE_DPMS_ON); drm_connector_list_iter_end(&iter); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + drm_modeset_unlock_all(dev); - return ret; + return 0; } 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 5196c1d26f87..9b1fc54555ee 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -80,7 +80,6 @@ #include #include #include -#include #if defined(CONFIG_DRM_AMD_DC_DCN) #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" @@ -2622,9 +2621,6 @@ static void handle_hpd_irq(void *param) #ifdef CONFIG_DRM_AMD_DC_HDCP struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state); #endif - struct drm_modeset_acquire_ctx ctx; - int ret; - if (adev->dm.disable_hpd_irq) return; @@ -2650,6 +2646,14 @@ static void handle_hpd_irq(void *param) if (aconnector->base.force && new_connection_type == dc_connection_none) { emulated_link_detect(aconnector->dc_link); + + drm_modeset_lock_all(dev); + dm_restore_drm_connector_state(dev, connector); + drm_modeset_unlock_all(dev); + + if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) + drm_kms_helper_hotplug_event(dev); + } else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) { if (new_connection_type == dc_connection_none && aconnector->dc_link->type == dc_connection_none) @@ -2657,18 +2661,13 @@ static void handle_hpd_irq(void *param) amdgpu_dm_update_connector_after_detect(aconnector); - } else { - goto out; - } - - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); - dm_restore_drm_connector_state(dev, connector); - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); - - if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) - drm_kms_helper_hotplug_event(dev); +
[PATCH 01/16] Revert "drm: cleanup: remove drm_modeset_(un)lock_all()"
From: Sean Paul This reverts commit 8d813d1a535c8c7503a5f4061654a73026be8c5e. This patchset breaks on intel platforms and was previously NACK'd by Ville. Cc: Ville Syrjälä Cc: Fernando Ramos Signed-off-by: Sean Paul --- drivers/gpu/drm/drm_modeset_lock.c | 94 +- include/drm/drm_modeset_lock.h | 2 + 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index afd1351749a5..fcfe1a03c4a1 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -77,6 +77,93 @@ static DEFINE_WW_CLASS(crtc_ww_class); +/** + * drm_modeset_lock_all - take all modeset locks + * @dev: DRM device + * + * This function takes all modeset locks, suitable where a more fine-grained + * scheme isn't (yet) implemented. Locks must be dropped by calling the + * drm_modeset_unlock_all() function. + * + * This function is deprecated. It allocates a lock acquisition context and + * stores it in &drm_device.mode_config. This facilitate conversion of + * existing code because it removes the need to manually deal with the + * acquisition context, but it is also brittle because the context is global + * and care must be taken not to nest calls. New code should use the + * drm_modeset_lock_all_ctx() function and pass in the context explicitly. + */ +void drm_modeset_lock_all(struct drm_device *dev) +{ + struct drm_mode_config *config = &dev->mode_config; + struct drm_modeset_acquire_ctx *ctx; + int ret; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL); + if (WARN_ON(!ctx)) + return; + + mutex_lock(&config->mutex); + + drm_modeset_acquire_init(ctx, 0); + +retry: + ret = drm_modeset_lock_all_ctx(dev, ctx); + if (ret < 0) { + if (ret == -EDEADLK) { + drm_modeset_backoff(ctx); + goto retry; + } + + drm_modeset_acquire_fini(ctx); + kfree(ctx); + return; + } + ww_acquire_done(&ctx->ww_ctx); + + WARN_ON(config->acquire_ctx); + + /* +* We hold the locks now, so it is safe to stash the acquisition +* context for drm_modeset_unlock_all(). +*/ + config->acquire_ctx = ctx; + + drm_warn_on_modeset_not_all_locked(dev); +} +EXPORT_SYMBOL(drm_modeset_lock_all); + +/** + * drm_modeset_unlock_all - drop all modeset locks + * @dev: DRM device + * + * This function drops all modeset locks taken by a previous call to the + * drm_modeset_lock_all() function. + * + * This function is deprecated. It uses the lock acquisition context stored + * in &drm_device.mode_config. This facilitates conversion of existing + * code because it removes the need to manually deal with the acquisition + * context, but it is also brittle because the context is global and care must + * be taken not to nest calls. New code should pass the acquisition context + * directly to the drm_modeset_drop_locks() function. + */ +void drm_modeset_unlock_all(struct drm_device *dev) +{ + struct drm_mode_config *config = &dev->mode_config; + struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx; + + if (WARN_ON(!ctx)) + return; + + config->acquire_ctx = NULL; + drm_modeset_drop_locks(ctx); + drm_modeset_acquire_fini(ctx); + + kfree(ctx); + + mutex_unlock(&dev->mode_config.mutex); +} +EXPORT_SYMBOL(drm_modeset_unlock_all); + /** * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked * @dev: device @@ -293,9 +380,10 @@ EXPORT_SYMBOL(drm_modeset_unlock); * This function takes all modeset locks, suitable where a more fine-grained * scheme isn't (yet) implemented. * - * It doesn't take the &drm_mode_config.mutex since that lock isn't required for - * modeset state changes. Callers which need to grab that lock too need to do so - * outside of the acquire context @ctx. + * Unlike drm_modeset_lock_all(), it doesn't take the &drm_mode_config.mutex + * since that lock isn't required for modeset state changes. Callers which + * need to grab that lock too need to do so outside of the acquire context + * @ctx. * * Locks acquired with this function should be released by calling the * drm_modeset_drop_locks() function on @ctx. diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index 865e64bcc4cb..aafd07388eb7 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -132,6 +132,8 @@ struct drm_device; struct drm_crtc; struct drm_plane; +void drm_modeset_lock_all(struct drm_device *dev); +void drm_modeset_unlock_all(struct drm_device *dev); void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); int drm_modeset_lock_all_ctx(struct drm_device *dev, -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.
On Fri, Oct 01, 2021 at 04:34:34PM -0400, Sean Paul wrote: > On Wed, Sep 29, 2021 at 03:39:25PM -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. > > > > Did you consider extending drm_color_lut_check() with the size checks? > > > Fixes: igt@kms_color@pipe-A-invalid-gamma-lut-sizes on MTK > > Tested on Zork(amdgpu) and Jacuzzi(mediatek) > > > > Signed-off-by: Mark Yacoub > > nit: missing a space between name and email > > > > --- > > drivers/gpu/drm/drm_atomic_helper.c | 56 + > > drivers/gpu/drm/drm_color_mgmt.c| 2 ++ > > include/drm/drm_atomic_helper.h | 1 + > > include/drm/drm_crtc.h | 11 ++ > > 4 files changed, 70 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c > > b/drivers/gpu/drm/drm_atomic_helper.c > > index 2c0c6ec928200..265b9747250d1 100644 > > --- a/drivers/gpu/drm/drm_atomic_helper.c > > +++ b/drivers/gpu/drm/drm_atomic_helper.c > > @@ -930,6 +930,58 @@ drm_atomic_helper_check_planes(struct drm_device *dev, > > } > > EXPORT_SYMBOL(drm_atomic_helper_check_planes); > > > > +/** > > + * drm_atomic_helper_check_planes - validate state object for CRTC changes > > Ctrl+c/Ctrl+v error here > > > + * @state: the driver state object > > + * > > + * Check the CRTC state object such as the Gamma/Degamma LUT sizes if the > > new > > Are there missing words between "object" and "such"? > > > + * state holds them. > > + * > > + * RETURNS: > > + * Zero for success or -errno > > + */ > > +int drm_atomic_helper_check_crtc(struct drm_atomic_state *state) > > drm_atomic_helper_check_crtcs to be consistent with > drm_atomic_helper_check_planes > > > +{ > > + 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) { > > no space before ( Ignore this, parsing error on my behalf. > > > + if (new_crtc_state->gamma_lut) { > > Perhaps gate these with a check of state->color_mgmt_changed first? > > > + 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); > > nit: new_state_lut_size and supported_lut_size can be pulled out to top level > scope > to avoid re-instantiation on each iteration > > > + > > + if (new_state_lut_size != supported_lut_size && > > + new_state_lut_size != supported_legacy_lut_size) { > > According to the docbook, "If drivers support multiple LUT sizes then they > should publish the largest size, and sub-sample smaller sized LUTs". So > should this check be > instead of != ? > > > + DRM_DEBUG_DRIVER( > > drm_dbg_state() is probably more appropriate > > > + "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->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) { >
Re: [PATCH v2 00/17] drm: cleanup: Use DRM_MODESET_LOCK_ALL_* helpers where possible
On Fri, Oct 01, 2021 at 10:00:50PM +0300, Ville Syrjälä wrote: > On Fri, Oct 01, 2021 at 02:36:55PM -0400, Sean Paul wrote: > > On Fri, Sep 24, 2021 at 08:43:07AM +0200, Fernando Ramos wrote: > > > Hi all, > > > > > > One of the things in the DRM TODO list ("Documentation/gpu/todo.rst") was > > > to > > > "use DRM_MODESET_LOCAL_ALL_* helpers instead of boilerplate". That's what > > > this > > > patch series is about. > > > > > > You will find two types of changes here: > > > > > > - Replacing "drm_modeset_lock_all_ctx()" (and surrounding boilerplate) > > > with > > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()" in the remaining places (as it > > > has > > > already been done in previous commits such as b7ea04d2) > > > > > > - Replacing "drm_modeset_lock_all()" with > > > "DRM_MODESET_LOCK_ALL_BEGIN()/END()" > > > in the remaining places (as it has already been done in previous > > > commits > > > such as 57037094) > > > > > > Most of the changes are straight forward, except for a few cases in the > > > "amd" > > > and "i915" drivers where some extra dancing was needed to overcome the > > > limitation that the DRM_MODESET_LOCK_ALL_BEGIN()/END() macros can only be > > > used > > > once inside the same function (the reason being that the macro expansion > > > includes *labels*, and you can not have two labels named the same inside > > > one > > > function) > > > > > > Notice that, even after this patch series, some places remain where > > > "drm_modeset_lock_all()" and "drm_modeset_lock_all_ctx()" are still > > > present, > > > all inside drm core (which makes sense), except for two (in "amd" and > > > "i915") > > > which cannot be replaced due to the way they are being used. > > > > > > Changes in v2: > > > > > > - Fix commit message typo > > > - Use the value returned by DRM_MODESET_LOCK_ALL_END when possible > > > - Split drm/i915 patch into two simpler ones > > > - Remove drm_modeset_(un)lock_all() > > > - Fix build problems in non-x86 platforms > > > > > > Fernando Ramos (17): > > > drm: cleanup: drm_modeset_lock_all_ctx() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/i915: cleanup: drm_modeset_lock_all_ctx() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/msm: cleanup: drm_modeset_lock_all_ctx() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm: cleanup: drm_modeset_lock_all() --> DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/vmwgfx: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/tegra: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/shmobile: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/radeon: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/omapdrm: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/nouveau: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/msm: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/i915: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/i915: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() part 2 > > > drm/gma500: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm/amd: cleanup: drm_modeset_lock_all() --> > > > DRM_MODESET_LOCK_ALL_BEGIN() > > > drm: cleanup: remove drm_modeset_(un)lock_all() > > > doc: drm: remove TODO entry regarding DRM_MODSET_LOCK_ALL cleanup > > > > > > > Thank you for revising, Fernando! I've pushed the set to drm-misc-next > > (along > > with the necessary drm-tip conflict resolutions). > > Ugh. Did anyone actually review the locking changes this does? > I shot the previous i915 stuff down because the commit messages > did not address any of it. I reviewed the set on 9/17, I didn't see your feedback on that thread. Sean > > -- > Ville Syrjälä > Intel -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH] drm/brdige: analogix_dp: Grab runtime PM reference for DP-AUX
On Wed, Sep 29, 2021 at 02:41:03PM -0700, Brian Norris wrote: > If the display is not enable()d, then we aren't holding a runtime PM > reference here. Thus, it's easy to accidentally cause a hang, if user > space is poking around at /dev/drm_dp_aux0 at the "wrong" time. > > Let's get the panel and PM state right before trying to talk AUX. > > Fixes: 0d97ad03f422 ("drm/bridge: analogix_dp: Remove duplicated code") > Cc: > Cc: Tomeu Vizoso > Signed-off-by: Brian Norris > --- > > .../gpu/drm/bridge/analogix/analogix_dp_core.c | 17 - > 1 file changed, 16 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > index b7d2e4449cfa..a1b553904b85 100644 > --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c > @@ -1632,8 +1632,23 @@ static ssize_t analogix_dpaux_transfer(struct > drm_dp_aux *aux, > struct drm_dp_aux_msg *msg) > { > struct analogix_dp_device *dp = to_dp(aux); > + int ret, ret2; > > - return analogix_dp_transfer(dp, msg); > + ret = analogix_dp_prepare_panel(dp, true, false); > + if (ret) { > + DRM_DEV_ERROR(dp->dev, "Failed to prepare panel (%d)\n", ret); s/DRM_DEV_ERROR/drm_err/ > + return ret; > + } > + > + pm_runtime_get_sync(dp->dev); > + ret = analogix_dp_transfer(dp, msg); > + pm_runtime_put(dp->dev); > + > + ret2 = analogix_dp_prepare_panel(dp, false, false); > + if (ret2) > + DRM_DEV_ERROR(dp->dev, "Failed to unprepare panel (%d)\n", > ret2); What's the reasoning for not propagating unprepare failures? I feel like that should be fair game. > + > + return ret; > } > > struct analogix_dp_device * > -- > 2.33.0.685.g46640cef36-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 1/2] drm: Add Gamma and Degamma LUT sizes props to drm_crtc to validate.
if (ret) > return ret; > > + ret = drm_atomic_helper_check_crtc(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..72a1b628e7cdd 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 = &dev->mode_config; > > if (degamma_lut_size) { > + crtc->degamma_lut_size = degamma_lut_size; > drm_object_attach_property(&crtc->base, > config->degamma_lut_property, 0); > drm_object_attach_property(&crtc->base, > @@ -178,6 +179,7 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, > config->ctm_property, 0); > > if (gamma_lut_size) { > + crtc->gamma_lut_size = gamma_lut_size; > drm_object_attach_property(&crtc->base, > config->gamma_lut_property, 0); > drm_object_attach_property(&crtc->base, > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h > index 4045e2507e11c..3eda13622ca1e 100644 > --- a/include/drm/drm_atomic_helper.h > +++ b/include/drm/drm_atomic_helper.h > @@ -38,6 +38,7 @@ struct drm_atomic_state; > struct drm_private_obj; > struct drm_private_state; > > +int drm_atomic_helper_check_crtc(struct drm_atomic_state *state); > int drm_atomic_helper_check_modeset(struct drm_device *dev, > struct drm_atomic_state *state); > int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 13eeba2a750af..c602be2cafca9 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -1072,6 +1072,17 @@ struct drm_crtc { > /** @funcs: CRTC control functions */ > const struct drm_crtc_funcs *funcs; > > + /** > + * @degamma_lut_size: Size of degamma LUT. > + */ > + uint32_t degamma_lut_size; > + > + /** > + * @gamma_lut_size: Size of Gamma LUT. Not used by legacy userspace > such as > + * X, which doesn't support large lut sizes. > + */ > + uint32_t gamma_lut_size; > + Above, you're checking if (new_state_lut_size != gamma_size && new_state_lut_size != gamma_lut_size) fail; doesn't that imply that gamma_size and gamma_lut_size must always be equal? If so, perhaps turf this new state and rename degamma_lut_size to degamma_size to be consistent. De-duping this and initializing crtc->gamma_size in the initialization would mean the if (crtc->gamma_size) check in drm_crtc_supports_legacy_check() is no longer useful (and possibly other similar checks), so some care will need to be taken to avoid regression. I think the effort is worthwhile to avoid introducing new state. > /** >* @gamma_size: Size of legacy gamma ramp reported to userspace. Set up >* by calling drm_mode_crtc_set_gamma_size(). > -- > 2.33.0.685.g46640cef36-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH 2/2] amd/amdgpu_dm: Verify Gamma and Degamma LUT sizes using DRM Core check
On Wed, Sep 29, 2021 at 03:39:26PM -0400, Mark Yacoub wrote: > 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. > > Signed-off-by: Mark Yacoub > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 > 1 file changed, 4 insertions(+), 4 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 07adac1a8c42b..96a1d006b777e 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -10683,6 +10683,10 @@ static int amdgpu_dm_atomic_check(struct drm_device > *dev, > } > } > #endif > + ret = drm_atomic_helper_check_crtc(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); > > @@ -10692,10 +10696,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); >From a quick glance, I think you can now delete this function. It's called from amdgpu_dm_update_crtc_color_mgmt() which is part of the commit, so the lut sizes should have already been checked. If the call from amdgpu_dm_update_crtc_color_mgmt() is not possible to remove, you could replace it with a call to the new helper function. And if _that_ is not possible, please make amdgpu_dm_verify_lut_sizes() static :-) Sean > - if (ret) > - goto fail; > - > if (!new_crtc_state->enable) > continue; > > -- > 2.33.0.685.g46640cef36-goog > -- Sean Paul, Software Engineer, Google / Chromium OS
Re: [PATCH v2 00/17] drm: cleanup: Use DRM_MODESET_LOCK_ALL_* helpers where possible
0 +- > drivers/gpu/drm/shmobile/shmob_drm_drv.c | 6 +- > drivers/gpu/drm/tegra/dsi.c | 6 +- > drivers/gpu/drm/tegra/hdmi.c | 6 +- > drivers/gpu/drm/tegra/sor.c | 11 ++- > drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 11 ++- > drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 12 ++- > include/drm/drm_modeset_lock.h| 2 - > 30 files changed, 265 insertions(+), 292 deletions(-) > > > base-commit: 6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f > -- > 2.33.0 > -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v3 14/14] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers
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 Signed-off-by: Sean Paul 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 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 [1] https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run --- drivers/gpu/drm/msm/Makefile| 1 + drivers/gpu/drm/msm/dp/dp_debug.c | 46 ++- drivers/gpu/drm/msm/dp/dp_debug.h | 6 +- drivers/gpu/drm/msm/dp/dp_display.c | 47 ++- drivers/gpu/drm/msm/dp/dp_display.h | 5 + drivers/gpu/drm/msm/dp/dp_drm.c | 68 - drivers/gpu/drm/msm/dp/dp_drm.h | 5 + drivers/gpu/drm/msm/dp/dp_hdcp.c| 445 drivers/gpu/drm/msm/dp/dp_hdcp.h| 27 ++ drivers/gpu/drm/msm/dp/dp_parser.c | 23 +- drivers/gpu/drm/msm/dp/dp_parser.h | 4 + drivers/gpu/drm/msm/dp/dp_reg.h | 44 ++- drivers/gpu/drm/msm/msm_atomic.c| 15 + 13 files changed, 717 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/Makefile b/drivers/gpu/drm/msm/Makefile index 904535eda0c4..98731fd262d6 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -109,6 +109,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 2f6247e80e9d..25dc55b5f083 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" @@ -24,6 +26,7 @@ struct dp_debug_private { struct dp_usbpd *usbpd; struct dp_link *link; struct dp_panel *panel; + struct dp_hdcp *hdcp; struct drm_connector **connector; struct device *dev; struct drm_device *drm_dev; @@ -349,6 +352,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 dp_debug_fops = { .open = simple_open, .read = dp_debug_read_info, @@ -363,6 +395,12 @@ static const struct file_operations test_active_fops = { .write = dp_test_active_write }; +static const struct file_operations dp_hdcp_key_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = dp_hdcp_key_write, +}; + static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) { int rc = 0; @@ -384,6 +422,10 @@ static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) minor->debugfs_root, debug, &dp_test_type_fops); + debugfs_create_file("msm_dp_hdcp_key", 0222, + minor->debugfs_root,
[PATCH v3 13/14] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
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 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 Changes in v3: -Split off into a new patch containing just the dts change (Stephen) -Add hdcp compatible string (Stephen) --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index c8921e2d6480..f2d7f3c95c1f 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -3085,10 +3085,12 @@ dsi_phy: dsi-phy@ae94400 { }; mdss_dp: displayport-controller@ae9 { - compatible = "qcom,sc7180-dp"; + compatible = "qcom,sc7180-dp-hdcp"; status = "disabled"; - reg = <0 0x0ae9 0 0x1400>; + reg = <0 0x0ae9 0 0x1400>, + <0 0x0aed1000 0 0x174>, + <0 0x0aee1000 0 0x2c>; interrupt-parent = <&mdss>; interrupts = <12>; -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v3 12/14] dt-bindings: msm/dp: Add bindings for HDCP registers
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 Signed-off-by: Sean Paul 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 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 --- Disclaimer: I really don't know if this is the right way to approach this. I tried using examples from other bindings, but feedback would be very much welcome on how I could add the optional register ranges. .../bindings/display/msm/dp-controller.yaml | 34 --- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index 64d8d9e5e47a..a176f97b2f4c 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -17,9 +17,10 @@ properties: compatible: enum: - qcom,sc7180-dp + - qcom,sc7180-dp-hdcp - reg: -maxItems: 1 + # See compatible-specific constraints below. + reg: true interrupts: maxItems: 1 @@ -89,6 +90,29 @@ required: - power-domains - ports +allOf: + - if: + properties: +compatible: + contains: +const: qcom,sc7180-dp-hdcp +then: + properties: +reg: + minItems: 3 + maxItems: 3 + items: +- description: Registers for base DP functionality +- description: (Optional) Registers for HDCP device key injection +- description: (Optional) Registers for HDCP TrustZone interaction +else: + properties: +reg: + minItems: 1 + maxItems: 1 + items: +- description: Registers for base DP functionality + additionalProperties: false examples: @@ -99,8 +123,10 @@ examples: #include displayport-controller@ae9 { -compatible = "qcom,sc7180-dp"; -reg = <0xae9 0x1400>; +compatible = "qcom,sc7180-dp-hdcp"; +reg = <0 0x0ae9 0 0x1400>, + <0 0x0aed1000 0 0x174>, + <0 0x0aee1000 0 0x2c>; interrupt-parent = <&mdss>; interrupts = <12>; clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v3 11/14] drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules
From: Sean Paul Audio is initialized last, it should be de-initialized first to match the order in dp_init_sub_modules(). Reviewed-by: Abhinav Kumar Reviewed-by: Stephen Boyd Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-12-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-12-s...@poorly.run #v2 Changes in v2: -None --- drivers/gpu/drm/msm/dp/dp_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index fbe4c2cd52a3..19946024e235 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -714,9 +714,9 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) static void dp_display_deinit_sub_modules(struct dp_display_private *dp) { dp_debug_put(dp->debug); + dp_audio_put(dp->audio); dp_panel_put(dp->panel); dp_aux_put(dp->aux); - dp_audio_put(dp->audio); } static int dp_init_sub_modules(struct dp_display_private *dp) -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v3 10/14] drm/msm/dpu: Remove encoder->enable() hack
From: Sean Paul encoder->commit() was being misused because there were some global resources which needed to be tweaked in encoder->enable() which were not accessible in dpu_encoder.c. That is no longer true and the redirect serves no purpose any longer. So remove the indirection. Reviewed-by: Stephen Boyd Tested-by: Stephen Boyd Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-11-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-11-s...@poorly.run #v2 Changes in v2: -None Changes in v3: -None --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 22 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 4 4 files changed, 1 insertion(+), 32 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 984f8a59cb73..ddc542a0d41f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2122,11 +2122,8 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { .mode_set = dpu_encoder_virt_mode_set, .disable = dpu_encoder_virt_disable, - .enable = dpu_kms_encoder_enable, + .enable = dpu_encoder_virt_enable, .atomic_check = dpu_encoder_virt_atomic_check, - - /* This is called by dpu_kms_encoder_enable */ - .commit = dpu_encoder_virt_enable, }; static const struct drm_encoder_funcs dpu_encoder_funcs = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index fb0d9f781c66..4a0b55d145ad 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -381,28 +381,6 @@ static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask) } } -/* - * Override the encoder enable since we need to setup the inline rotator and do - * some crtc magic before enabling any bridge that might be present. - */ -void dpu_kms_encoder_enable(struct drm_encoder *encoder) -{ - const struct drm_encoder_helper_funcs *funcs = encoder->helper_private; - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc; - - /* Forward this enable call to the commit hook */ - if (funcs && funcs->commit) - funcs->commit(encoder); - - drm_for_each_crtc(crtc, dev) { - if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder))) - continue; - - trace_dpu_kms_enc_enable(DRMID(crtc)); - } -} - static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned crtc_mask) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 323a6bce9e64..f1ebb60dacab 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -248,8 +248,6 @@ void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms); int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); -void dpu_kms_encoder_enable(struct drm_encoder *encoder); - /** * dpu_kms_get_clk_rate() - get the clock rate * @dpu_kms: pointer to dpu_kms structure diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index 37bba57675a8..54d74341e690 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -266,10 +266,6 @@ DEFINE_EVENT(dpu_drm_obj_template, dpu_crtc_complete_commit, TP_PROTO(uint32_t drm_id), TP_ARGS(drm_id) ); -DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_enc_enable, - TP_PROTO(uint32_t drm_id), - TP_ARGS(drm_id) -); DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_commit, TP_PROTO(uint32_t drm_id), TP_ARGS(drm_id) -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v3 09/14] drm/msm/dpu: Remove useless checks in dpu_encoder
From: Sean Paul A couple more useless checks to remove in dpu_encoder. Reviewed-by: Stephen Boyd Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-10-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-10-s...@poorly.run #v2 Changes in v2: -None Changes in v3: -None --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 1 file changed, 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 0e9d3fa1544b..984f8a59cb73 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1153,10 +1153,6 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) struct msm_drm_private *priv; struct drm_display_mode *cur_mode = NULL; - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } dpu_enc = to_dpu_encoder_virt(drm_enc); mutex_lock(&dpu_enc->enc_lock); @@ -1203,14 +1199,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) struct msm_drm_private *priv; int i = 0; - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } else if (!drm_enc->dev) { - DPU_ERROR("invalid dev\n"); - return; - } - dpu_enc = to_dpu_encoder_virt(drm_enc); DPU_DEBUG_ENC(dpu_enc, "\n"); -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v3 08/14] drm/msm/dpu_kms: Re-order dpu includes
From: Sean Paul Make includes alphabetical in dpu_kms.c Reviewed-by: Abhinav Kumar Reviewed-by: Stephen Boyd Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-9-s...@poorly.run #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-9-s...@poorly.run #v2 Changes in v2: -None Changes in v3: -None --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index ae48f41821cf..fb0d9f781c66 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -21,14 +21,14 @@ #include "msm_gem.h" #include "disp/msm_disp_snapshot.h" -#include "dpu_kms.h" #include "dpu_core_irq.h" +#include "dpu_crtc.h" +#include "dpu_encoder.h" #include "dpu_formats.h" #include "dpu_hw_vbif.h" -#include "dpu_vbif.h" -#include "dpu_encoder.h" +#include "dpu_kms.h" #include "dpu_plane.h" -#include "dpu_crtc.h" +#include "dpu_vbif.h" #define CREATE_TRACE_POINTS #include "dpu_trace.h" -- Sean Paul, Software Engineer, Google / Chromium OS
[PATCH v3 07/14] drm/i915/hdcp: Use HDCP helpers for i915
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 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 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 --- drivers/gpu/drm/i915/display/intel_ddi.c | 29 +- .../drm/i915/display/intel_display_debugfs.c | 6 +- .../drm/i915/display/intel_display_types.h| 58 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 345 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 935 +++--- drivers/gpu/drm/i915/display/intel_hdcp.h | 31 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++--- 8 files changed, 418 insertions(+), 1259 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 51cd0420e00e..446544c75aa8 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -26,6 +26,7 @@ */ #include +#include #include "i915_drv.h" #include "intel_audio.h" @@ -3143,6 +3144,9 @@ 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 (!crtc_state->bigjoiner_slave) @@ -3159,12 +3163,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, + &state->base, + &dig_port->hdcp_mutex); } static void intel_disable_ddi_dp(struct intel_atomic_state *state, @@ -3224,7 +3226,13 @@ 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, + &state->base, + &dig_port->hdcp_mutex); if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) intel_disable_ddi_hdmi(state, encoder, old_crtc_state, @@ -3254,13 +3262,18 @@ 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, conn_state); - intel_hdcp_update_pipe(state, encoder