817 Commits

Author SHA1 Message Date
Maxime Ripard
dccb4d74e0
drm/vc4: hdmi: Use full range helper in csc functions
The CSC callbacks takes a boolean as an argument to tell whether we're
using the full range or limited range RGB.

However, with the upcoming YUV support, the logic will be a bit more
complex. In order to address this, let's make the callbacks take the
entire mode, and call our new helper to tell whether the full or limited
range RGB should be used.

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20220120151625.594595-7-maxime@cerno.tech
2022-01-25 10:02:36 +01:00
Maxime Ripard
a649cc821a
drm/vc4: hdmi: Add full range RGB helper
We're going to need to tell whether we want to run with a full or
limited range RGB output in multiple places in the code, so let's create
a helper that will return whether we need with full range or not.

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20220120151625.594595-6-maxime@cerno.tech
2022-01-25 10:02:31 +01:00
Maxime Ripard
4a46e5d251
drm/edid: Rename drm_hdmi_avi_infoframe_colorspace to _colorimetry
The drm_hdmi_avi_infoframe_colorspace() function actually sets the
colorimetry and extended_colorimetry fields in the hdmi_avi_infoframe
structure with DRM_MODE_COLORIMETRY_* values.

To make things worse, the hdmi_avi_infoframe structure also has a
colorspace field used to signal whether an RGB or YUV output is being
used.

Let's remove the inconsistency and allow for the colorspace usage by
renaming the function.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20220120151625.594595-2-maxime@cerno.tech
2022-01-25 10:00:13 +01:00
Colin Ian King
7f0fec39c9
drm/vc4: remove redundant assignment of variable size
The variable 'size' is being assigned a value that is never read,
the assignment is redundant and can be removed. Cleans up clang-scan
warning:

drivers/gpu/drm/vc4/vc4_bo.c:358:2: warning: Value stored to 'size'
is never read [deadcode.DeadStores]
        size = roundup(size, PAGE_SIZE);

Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20220112232036.1182846-1-colin.i.king@gmail.com
2022-01-14 14:14:56 +01:00
Maxime Ripard
c406ad5e4a
drm/vc4: Notify the firmware when DRM is in charge
Once the call to drm_fb_helper_remove_conflicting_framebuffers() has
been made, simplefb has been unregistered and the KMS driver is entirely
in charge of the display.

Thus, we can notify the firmware it can free whatever resource it was
using to maintain simplefb functional.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20211215095117.176435-5-maxime@cerno.tech
2022-01-11 13:16:12 +01:00
Maxime Ripard
a7e6f3d8a4
drm/vc4: Remove conflicting framebuffers before callind bind_all
The bind hooks will modify their controller registers, so simplefb is
going to be unusable anyway. Let's avoid any transient state where it
could still be in the system but no longer functionnal.

Acked-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20211215095117.176435-4-maxime@cerno.tech
2022-01-11 13:16:11 +01:00
Maxime Ripard
d62b9bee52
drm/vc4: Support nomodeset
If we have nomodeset on the kernel command line we should have the
firmware framebuffer driver kept as is and not try to load the
full-blown KMS driver.

In this case, let's just register the v3d driver.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20211215095117.176435-3-maxime@cerno.tech
2022-01-11 13:16:11 +01:00
Thomas Zimmermann
9758ff2fa2 Merge drm/drm-next into drm-misc-next
Backmerging for v5.16-rc5. Resolves a conflict between drm-misc-next
and drm-misc-fixes in the vc4 driver.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
2021-12-16 14:48:27 +01:00
Dave Stevenson
d619f38c01
drm/vc4: plane: Add support for YUV color encodings and ranges
The BT601/BT709 color encoding and limited vs full
range properties were not being exposed, defaulting
always to BT601 limited range.

Expose the parameters and set the registers appropriately.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20211215091739.135042-4-maxime@cerno.tech
2021-12-16 11:23:23 +01:00
Dave Stevenson
145b42fbae
drm/vc4: plane: Add support for DRM_FORMAT_P030
The P030 format, used with the DRM_FORMAT_MOD_BROADCOM_SAND128 modifier,
is a format output by the video decoder on the BCM2711.

Add native support to the KMS planes for that format.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20211215091739.135042-3-maxime@cerno.tech
2021-12-16 11:23:22 +01:00
Maxime Ripard
244a36e50d drm/vc4: kms: Wait for the commit before increasing our clock rate
Several DRM/KMS atomic commits can run in parallel if they affect
different CRTC. These commits share the global HVS state, so we have
some code to make sure we run commits in sequence. This synchronization
code is one of the first thing that runs in vc4_atomic_commit_tail().

Another constraints we have is that we need to make sure the HVS clock
gets a boost during the commit. That code relies on clk_set_min_rate and
will remove the old minimum and set a new one. We also need another,
temporary, minimum for the duration of the commit.

The algorithm is thus to set a temporary minimum, drop the previous
one, do the commit, and finally set the minimum for the current mode.

However, the part that sets the temporary minimum and drops the older
one runs before the commit synchronization code.

Thus, under the proper conditions, we can end up mixing up the minimums
and ending up with the wrong one for our current step.

To avoid it, let's move the clock setup in the protected section.

Fixes: d7d96c00e585 ("drm/vc4: hvs: Boost the core clock during modeset")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Tested-by: Jian-Hong Pan <jhp@endlessos.org>
[danvet: re-apply this from 0c980a006d3f ("drm/vc4: kms: Wait for the
commit before increasing our clock rate") because I lost that part in
my merge resolution in 99b03ca651f1 ("Merge v5.16-rc5 into drm-next")]
Fixes: 99b03ca651f1 ("Merge v5.16-rc5 into drm-next")
Acked-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://lore.kernel.org/r/20211117094527.146275-2-maxime@cerno.tech
2021-12-15 12:10:50 +01:00
Daniel Vetter
99b03ca651 Linux 5.16-rc5
-----BEGIN PGP SIGNATURE-----
 
 iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAmG2fU0eHHRvcnZhbGRz
 QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGC7EH/3R7Rt+OD8Wn8Ss3
 w8V+dBxVwa2u2oMTyUHPxaeOXZ7bi38XlUdLFPOK/76bGwO0a5TmYZqsWdRbGyT0
 HfcYjHsQ0lbJXk/nh2oM47oJxJXVpThIHXJEk0FZ0Y5t+DYjIYlNHzqZymUyhLem
 St74zgWcyT+MXuqY34vB827FJDUnOxhhhi85tObeunaSPAomy9aiYidSC1ARREnz
 iz2VUntP/QnRnKVvL2nUZNzcz1xL5vfCRSKsRGRSv3qW1Y/1M71ylt6JVmSftWq+
 VmMdFxFhdrb1OK/1ct/930Un/UP2NG9EJsWxote2XYlnVSZHzDqH7lUhbqgdCcLz
 1m2tVNY=
 =7wRd
 -----END PGP SIGNATURE-----

Merge v5.16-rc5 into drm-next

Thomas Zimmermann requested a fixes backmerge, specifically also for
96c5f82ef0a1 ("drm/vc4: fix error code in vc4_create_object()")

Just a bunch of adjacent changes conflicts, even the big pile of them
in vc4.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2021-12-14 10:24:28 +01:00
Thomas Zimmermann
09717af7d1 drm: Remove CONFIG_DRM_KMS_CMA_HELPER option
Link drm_fb_cma_helper.o into drm_cma_helper.ko if CONFIG_DRM_KMS_HELPER
has been set. Remove CONFIG_DRM_KMS_CMA_HELPER config option. Selecting
KMS helpers and CMA will now automatically enable CMA KMS helpers.

Some drivers' Kconfig files did not correctly select KMS or CMA helpers.
Fix this as part of the change.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20211106193509.17472-3-tzimmermann@suse.de
2021-11-30 11:10:03 +01:00
Thomas Zimmermann
e580ea25c0 drm/cma-helper: Pass GEM CMA object in public interfaces
Change all GEM CMA object functions that receive a GEM object
of type struct drm_gem_object to expect an object of type
struct drm_gem_cma_object instead.

This change reduces the number of upcasts from struct drm_gem_object
by moving them into callers. The C compiler can now verify that the
GEM CMA functions are called with the correct type.

For consistency, the patch also renames drm_gem_cma_free_object to
drm_gem_cma_free. It further updates documentation for a number of
functions.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20211115120148.21766-4-tzimmermann@suse.de
2021-11-30 09:49:58 +01:00
Thomas Zimmermann
05b1de51df drm/cma-helper: Export dedicated wrappers for GEM object functions
Wrap GEM CMA functions for struct drm_gem_object_funcs and update
all callers. This will allow for an update of the public interfaces
of the GEM CMA helper library.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20211115120148.21766-3-tzimmermann@suse.de
2021-11-30 09:49:55 +01:00
Maxime Ripard
6052a3110b
drm/vc4: kms: Fix previous HVS commit wait
Our current code is supposed to serialise the commits by waiting for all
the drm_crtc_commits associated to the previous HVS state.

However, assuming we have two CRTCs running and being configured and we
configure each one alternately, we end up in a situation where we're
not waiting at all.

Indeed, starting with a state (state 0) where both CRTCs are running,
and doing a commit (state 1) on the first CRTC (CRTC 0), we'll associate
its commit to its assigned FIFO in vc4_hvs_state.

If we get a new commit (state 2), this time affecting the second CRTC
(CRTC 1), the DRM core will allow both commits to execute in parallel
(assuming they don't have any share resources).

Our code in vc4_atomic_commit_tail is supposed to make sure we only get
one commit at a time and serialised by order of submission. It does so
by using for_each_old_crtc_in_state, making sure that the CRTC has a
FIFO assigned, is used, and has a commit pending. If it does, then we'll
wait for the commit before going forward.

During the transition from state 0 to state 1, as our old CRTC state we
get the CRTC 0 state 0, its commit, we wait for it, everything works fine.

During the transition from state 1 to state 2 though, the use of
for_each_old_crtc_in_state is wrong. Indeed, while the code assumes it's
returning the state of the CRTC in the old state (so CRTC 0 state 1), it
actually returns the old state of the CRTC affected by the current
commit, so CRTC 0 state 0 since it wasn't part of state 1.

Due to this, if we alternate between the configuration of CRTC 0 and
CRTC 1, we never actually wait for anything since we should be waiting
on the other every time, but it never is affected by the previous
commit.

Change the logic to, at every commit, look at every FIFO in the previous
HVS state, and if it's in use and has a commit associated to it, wait
for that commit.

Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Tested-by: Jian-Hong Pan <jhp@endlessos.org>
Link: https://lore.kernel.org/r/20211117094527.146275-7-maxime@cerno.tech
2021-11-29 15:18:09 +01:00
Maxime Ripard
d354699e22
drm/vc4: kms: Don't duplicate pending commit
Our HVS global state, when duplicated, will also copy the pointer to the
drm_crtc_commit (and increase the reference count) for each FIFO if the
pointer is not NULL.

However, our atomic_setup function will overwrite that pointer without
putting the reference back leading to a memory leak.

Since the commit is only relevant during the atomic commit process, it
doesn't make sense to duplicate the reference to the commit anyway.
Let's remove it.

Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Tested-by: Jian-Hong Pan <jhp@endlessos.org>
Link: https://lore.kernel.org/r/20211117094527.146275-6-maxime@cerno.tech
2021-11-29 15:18:00 +01:00
Maxime Ripard
d134c5ff71
drm/vc4: kms: Clear the HVS FIFO commit pointer once done
Commit 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a
commit") introduced a wait on the previous commit done on a given HVS
FIFO.

However, we never cleared that pointer once done. Since
drm_crtc_commit_put can free the drm_crtc_commit structure directly if
we were the last user, this means that it can lead to a use-after free
if we were to duplicate the state, and that stale pointer would even be
copied to the new state.

Set the pointer to NULL once we're done with the wait so that we don't
carry over a pointer to a free'd structure.

Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Tested-by: Jian-Hong Pan <jhp@endlessos.org>
Link: https://lore.kernel.org/r/20211117094527.146275-5-maxime@cerno.tech
2021-11-29 15:17:57 +01:00
Maxime Ripard
049cfff8d5
drm/vc4: kms: Add missing drm_crtc_commit_put
Commit 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a
commit") introduced a global state for the HVS, with each FIFO storing
the current CRTC commit so that we can properly synchronize commits.

However, the refcounting was off and we thus ended up leaking the
drm_crtc_commit structure every commit. Add a drm_crtc_commit_put to
prevent the leakage.

Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Tested-by: Jian-Hong Pan <jhp@endlessos.org>
Link: https://lore.kernel.org/r/20211117094527.146275-4-maxime@cerno.tech
2021-11-29 15:17:54 +01:00
Maxime Ripard
f927767978
drm/vc4: kms: Fix return code check
The HVS global state functions return an error pointer, but in most
cases we check if it's NULL, possibly resulting in an invalid pointer
dereference.

Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Tested-by: Jian-Hong Pan <jhp@endlessos.org>
Link: https://lore.kernel.org/r/20211117094527.146275-3-maxime@cerno.tech
2021-11-29 15:17:51 +01:00
Maxime Ripard
0c980a006d
drm/vc4: kms: Wait for the commit before increasing our clock rate
Several DRM/KMS atomic commits can run in parallel if they affect
different CRTC. These commits share the global HVS state, so we have
some code to make sure we run commits in sequence. This synchronization
code is one of the first thing that runs in vc4_atomic_commit_tail().

Another constraints we have is that we need to make sure the HVS clock
gets a boost during the commit. That code relies on clk_set_min_rate and
will remove the old minimum and set a new one. We also need another,
temporary, minimum for the duration of the commit.

The algorithm is thus to set a temporary minimum, drop the previous
one, do the commit, and finally set the minimum for the current mode.

However, the part that sets the temporary minimum and drops the older
one runs before the commit synchronization code.

Thus, under the proper conditions, we can end up mixing up the minimums
and ending up with the wrong one for our current step.

To avoid it, let's move the clock setup in the protected section.

Fixes: d7d96c00e585 ("drm/vc4: hvs: Boost the core clock during modeset")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Tested-by: Jian-Hong Pan <jhp@endlessos.org>
Link: https://lore.kernel.org/r/20211117094527.146275-2-maxime@cerno.tech
2021-11-29 15:17:25 +01:00
Dan Carpenter
96c5f82ef0
drm/vc4: fix error code in vc4_create_object()
The ->gem_create_object() functions are supposed to return NULL if there
is an error.  None of the callers expect error pointers so returing one
will lead to an Oops.  See drm_gem_vram_create(), for example.

Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20211118111416.GC1147@kili
2021-11-19 11:59:15 +01:00
Thomas Zimmermann
a713ca234e Merge drm/drm-next into drm-misc-next
Backmerging from drm/drm-next for v5.16-rc1.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
2021-11-18 09:36:39 +01:00
Maxime Ripard
1998646129
drm/vc4: hdmi: Introduce a scdc_enabled flag
We currently rely on two functions, vc4_hdmi_supports_scrambling() and
vc4_hdmi_mode_needs_scrambling() to determine if we should enable and
disable the scrambler for any given mode.

Since we might need to disable the controller at boot, we also always
run vc4_hdmi_disable_scrambling() and thus call those functions without
a mode yet, which in turns need to make some special casing in order for
it to work.

Instead of duplicating the check for whether or not we need to take care
of the scrambler in both vc4_hdmi_enable_scrambling() and
vc4_hdmi_disable_scrambling(), we can do that check only when we enable
it and store whether or not it's been enabled in our private structure.

We also need to initialize that flag at true to make sure we disable the
scrambler at boot since we can't really know its state yet.

This allows to simplify a bit that part of the driver, and removes one
user of our copy of the CRTC adjusted mode outside of KMS (since
vc4_hdmi_disable_scrambling() might be called from the hotplug interrupt
handler).

It also removes our last user of the legacy encoder->crtc pointer.

Link: https://lore.kernel.org/r/20211025141113.702757-10-maxime@cerno.tech
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:30 +01:00
Maxime Ripard
ebae26d618
drm/vc4: hdmi: Introduce an output_enabled flag
We currently poke at encoder->crtc in the ALSA code path to determine
whether the HDMI output is enabled or not, and thus whether we should
allow the audio output.

However, that pointer is deprecated and shouldn't really be used by
atomic drivers anymore. Since we have the infrastructure in place now,
let's just create a flag that we toggle to report whether the controller
is currently enabled and use that instead of encoder->crtc in ALSA.

Link: https://lore.kernel.org/r/20211025141113.702757-9-maxime@cerno.tech
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:29 +01:00
Maxime Ripard
a64ff88cb5
drm/vc4: hdmi: Check the device state in prepare()
Even though we already check that the encoder->crtc pointer is there
during in startup(), which is part of the open() path in ASoC, nothing
guarantees that our encoder state won't change between the time when we
open the device and the time we prepare it.

Move the sanity checks we do in startup() to a helper and call it from
prepare().

Link: https://lore.kernel.org/r/20211025141113.702757-8-maxime@cerno.tech
Fixes: 91e99e113929 ("drm/vc4: hdmi: Register HDMI codec")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:28 +01:00
Maxime Ripard
633be8c3c0
drm/vc4: hdmi: Prevent access to crtc->state outside of KMS
Accessing the crtc->state pointer from outside the modesetting context
is not allowed. We thus need to copy whatever we need from the KMS state
to our structure in order to access it.

However, in the vc4 HDMI driver we do use that pointer in the ALSA code
path, and potentially in the hotplug interrupt handler path.

These paths both need access to the CRTC adjusted mode in order for the
proper dividers to be set for ALSA, and the scrambler state to be
reinstated properly for hotplug.

Let's copy this mode into our private encoder structure and reference it
from there when needed. Since that part is shared between KMS and other
paths, we need to protect it using our mutex.

Link: https://lore.kernel.org/all/YWgteNaNeaS9uWDe@phenom.ffwll.local/
Link: https://lore.kernel.org/r/20211025141113.702757-7-maxime@cerno.tech
Fixes: bb7d78568814 ("drm/vc4: Add HDMI audio support")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:27 +01:00
Maxime Ripard
82cb88af12
drm/vc4: hdmi: Use a mutex to prevent concurrent framework access
The vc4 HDMI controller registers into the KMS, CEC and ALSA
frameworks.

However, no particular care is done to prevent the concurrent execution
of different framework hooks from happening at the same time.

In order to protect against that scenario, let's introduce a mutex that
relevant ALSA and KMS hooks will need to take to prevent concurrent
execution.

CEC is left out at the moment though, since the .get_modes and .detect
KMS hooks, when running cec_s_phys_addr_from_edid, can end up calling
CEC's .adap_enable hook. This introduces some reentrancy that isn't easy
to deal with properly.

The CEC hooks also don't share much state with the rest of the driver:
the registers are entirely separate, we don't share any variable, the
only thing that can conflict is the CEC clock divider setup that can be
affected by a mode set.

However, after discussing it, it looks like CEC should be able to
recover from this if it was to happen.

Link: https://lore.kernel.org/r/20211025141113.702757-6-maxime@cerno.tech
Fixes: bb7d78568814 ("drm/vc4: Add HDMI audio support")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:25 +01:00
Maxime Ripard
81fb55e500
drm/vc4: hdmi: Add a spinlock to protect register access
The vc4 HDMI driver has multiple path shared between the CEC, ALSA and
KMS frameworks, plus two interrupt handlers (CEC and hotplug) that will
read and modify a number of registers.

Even though not bug has been reported so far, it's definitely unsafe, so
let's just add a spinlock to protect the register access of the HDMI
controller.

Link: https://lore.kernel.org/r/20211025141113.702757-5-maxime@cerno.tech
Fixes: c8b75bca92cb ("drm/vc4: Add KMS support for Raspberry Pi.")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:24 +01:00
Maxime Ripard
eeb6ab4639
drm/vc4: crtc: Copy assigned channel to the CRTC
Accessing the crtc->state pointer from outside the modesetting context
is not allowed. We thus need to copy whatever we need from the KMS state
to our structure in order to access it.

In VC4, a number of users of that pointers have crept in over the years,
and the previous commits removed them all but the HVS channel a CRTC has
been assigned.

Let's move this channel in struct vc4_crtc at atomic_begin() time, drop
it from our private state structure, and remove our use of crtc->state
from our vblank handler entirely.

Link: https://lore.kernel.org/all/YWgteNaNeaS9uWDe@phenom.ffwll.local/
Link: https://lore.kernel.org/r/20211025141113.702757-4-maxime@cerno.tech
Fixes: 87ebcd42fb7b ("drm/vc4: crtc: Assign output to channel automatically")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:22 +01:00
Maxime Ripard
0c250c150c
drm/vc4: Fix non-blocking commit getting stuck forever
In some situation, we can end up being stuck on a non-blocking that went
through properly.

The situation that seems to trigger it reliably is to first start a
non-blocking commit, and then right after, and before we had any vblank
interrupt), start a blocking commit.

This will lead to the first commit workqueue to be scheduled, setup the
display, while the second commit is waiting for the first one to be
completed.

The vblank interrupt will then be raised, vc4_crtc_handle_vblank() will
run and will compare the active dlist in the HVS channel to the one
associated with the crtc->state.

However, at that point, the second commit is waiting using
drm_atomic_helper_wait_for_dependencies that occurs after
drm_atomic_helper_swap_state has been called, so crtc->state points to
the second commit state. vc4_crtc_handle_vblank() will compare the two
dlist addresses and since they don't match will ignore the interrupt.

The vblank event will never be reported, and the first and second commit
will wait for the first commit completion until they timeout.

The underlying reason is that it was never safe to do so. Indeed,
accessing the ->state pointer access synchronization is based on
ownership guarantees that can only occur within the functions and hooks
defined as part of the KMS framework, and obviously the irq handler
isn't one of them. The rework to move to generic helpers only uncovered
the underlying issue.

However, since the code path between
drm_atomic_helper_wait_for_dependencies() and
drm_atomic_helper_wait_for_vblanks() is serialised and we can't get two
commits in that path at the same time, we can work around this issue by
setting a variable associated to struct drm_crtc to the dlist we expect,
and then using it from the vc4_crtc_handle_vblank() function.

Since that state is shared with the modesetting path, we also need to
introduce a spinlock to protect the code shared between the interrupt
handler and the modesetting path, protecting only our new variable for
now.

Link: https://lore.kernel.org/all/YWgteNaNeaS9uWDe@phenom.ffwll.local/
Link: https://lore.kernel.org/r/20211025141113.702757-3-maxime@cerno.tech
Fixes: 56d1fe0979dc ("drm/vc4: Make pageflip completion handling more robust.")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:21 +01:00
Maxime Ripard
a16c66401f
drm/vc4: crtc: Drop feed_txp from state
Accessing the crtc->state pointer from outside the modesetting context
is not allowed. We thus need to copy whatever we need from the KMS state
to our structure in order to access it.

In VC4, a number of users of that pointers have crept in over the years,
the first one being whether or not the downstream controller of the
pixelvalve is our writeback controller.

Fortunately for us, Since commit 39fcb2808376 ("drm/vc4: txp: Turn the
TXP into a CRTC of its own") this is no longer something that can change
from one commit to the other and is hardcoded.

Let's set this flag in struct vc4_crtc if we happen to be the TXP, and
drop the flag from our private state structure.

Link: https://lore.kernel.org/all/YWgteNaNeaS9uWDe@phenom.ffwll.local/
Link: https://lore.kernel.org/r/20211025141113.702757-2-maxime@cerno.tech
Fixes: 008095e065a8 ("drm/vc4: Add support for the transposer block")
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-11-05 12:53:16 +01:00
Maxime Ripard
16e101051f
drm/vc4: Increase the core clock based on HVS load
Depending on a given HVS output (HVS to PixelValves) and input (planes
attached to a channel) load, the HVS needs for the core clock to be
raised above its boot time default.

Failing to do so will result in a vblank timeout and a stalled display
pipeline.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-11-maxime@cerno.tech
2021-11-04 10:37:14 +01:00
Maxime Ripard
b7551457c5
drm/vc4: hdmi: Enable the scrambler on reconnection
If we have a state already and disconnect/reconnect the display, the
SCDC messages won't be sent again since we didn't go through a disable /
enable cycle.

In order to fix this, let's call the vc4_hdmi_enable_scrambling function
in the detect callback if there is a mode and it needs the scrambler to
be enabled.

Fixes: c85695a2016e ("drm/vc4: hdmi: Enable the scrambler")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-10-maxime@cerno.tech
2021-11-04 10:37:14 +01:00
Maxime Ripard
bd43e22bf2
drm/vc4: hdmi: Raise the maximum clock rate
Now that we have the infrastructure in place, we can raise the maximum
pixel rate we can reach for HDMI0 on the BCM2711.

HDMI1 is left untouched since its pixelvalve has a smaller FIFO and
would need a clock faster than what we can provide to support the same
modes.

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://lore.kernel.org/r/20211025152903.1088803-9-maxime@cerno.tech
2021-11-04 10:36:26 +01:00
Maxime Ripard
7f817159c3
drm/vc4: Leverage the load tracker on the BCM2711
The load tracker was initially designed to report and warn about a load
too high for the HVS. To do so, it computes for each plane the impact
it's going to have on the HVS, and will warn (if it's enabled) if we go
over what the hardware can process.

While the limits being used are a bit irrelevant to the BCM2711, the
algorithm to compute the HVS load will be one component used in order to
compute the core clock rate on the BCM2711.

Let's remove the hooks to prevent the load tracker to do its
computation, but since we don't have the same limits, don't check them
against them, and prevent the debugfs file to enable it from being
created.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-8-maxime@cerno.tech
2021-11-04 10:36:25 +01:00
Maxime Ripard
e1a7094b58
drm/vc4: crtc: Add some logging
The encoder retrieval code has been a source of bugs and glitches in the
past and the crtc <-> encoder association been wrong in a number of
different ways.

Add some logging to quickly spot issues if they occur.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-7-maxime@cerno.tech
2021-11-04 10:36:25 +01:00
Maxime Ripard
94c1adc4c1
drm/vc4: crtc: Rework the encoder retrieval code (again)
It turns out the encoder retrieval code, in addition to being
unnecessarily complicated, has a bug when only the planes and crtcs are
affected by a given atomic commit.

Indeed, in such a case, either drm_atomic_get_old_connector_state or
drm_atomic_get_new_connector_state will return NULL and thus our encoder
retrieval code will not match on anything.

We can however simplify the code by using drm_for_each_encoder_mask, the
drm_crtc_state storing the encoders a given CRTC is connected to
directly and without relying on any other state.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-6-maxime@cerno.tech
2021-11-04 10:36:25 +01:00
Maxime Ripard
d6faf94a68
drm/vc4: crtc: Add encoder to vc4_crtc_config_pv prototype
vc4_crtc_config_pv() retrieves the encoder again, even though its only
caller, vc4_crtc_atomic_enable(), already did.

Pass the encoder pointer as an argument instead of going through all the
connectors to retrieve it again.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-5-maxime@cerno.tech
2021-11-04 10:36:25 +01:00
Maxime Ripard
d0229c360a
drm/vc4: Make vc4_crtc_get_encoder public
We'll need that function in vc4_kms to compute the core clock rate
requirements.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-4-maxime@cerno.tech
2021-11-04 10:36:25 +01:00
Maxime Ripard
e32e572325
drm/vc4: hdmi: Fix HPD GPIO detection
Prior to commit 6800234ceee0 ("drm/vc4: hdmi: Convert to gpiod"), in the
detect hook, if we had an HPD GPIO we would only rely on it and return
whatever state it was in.

However, that commit changed that by mistake to only consider the case
where we have a GPIO and it returns a logical high, and would fall back
to the other methods otherwise.

Since we can read the EDIDs when the HPD signal is low on some displays,
we changed the detection status from disconnected to connected, and we
would ignore an HPD pulse.

Fixes: 6800234ceee0 ("drm/vc4: hdmi: Convert to gpiod")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-3-maxime@cerno.tech
2021-11-04 10:36:25 +01:00
Maxime Ripard
cc5f1cbbc1
drm/vc4: hdmi: Remove the DDC probing for status detection
Commit 9d44abbbb8d5 ("drm/vc4: Fall back to using an EDID probe in the
absence of a GPIO.") added some code to read the EDID through DDC in the
HDMI driver detect hook since the Pi3 had no HPD GPIO back then.
However, commit b1b8f45b3130 ("ARM: dts: bcm2837: Add missing GPIOs of
Expander") changed that a couple of years later.

This causes an issue though since some TV (like the LG 55C8) when it
comes out of standy will deassert the HPD line, but the EDID will
remain readable.

It causes an issues nn platforms without an HPD GPIO, like the Pi4,
where the DDC probing will be our primary mean to detect a display, and
thus we will never detect the HPD pulse. This was fine before since the
pulse was small enough that we would never detect it, and we also didn't
have anything (like the scrambler) that needed to be set up in the
display.

However, now that we have both, the display during the HPD pulse will
clear its scrambler status, and since we won't detect the
disconnect/reconnect cycle we will never enable the scrambler back.

As our main reason for that DDC probing is gone, let's just remove it.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20211025152903.1088803-2-maxime@cerno.tech
2021-11-04 10:35:32 +01:00
Dave Airlie
970eae1560 Linux 5.15-rc7
-----BEGIN PGP SIGNATURE-----
 
 iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAmF298ceHHRvcnZhbGRz
 QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGIJYH/1rsEFQQ6caeQdy1
 z9eFIe48DNM4l7bFk+qEj2UAbzPdahVJ299Mg5fW0n2CDemOc9/n0b9TxQ37YObi
 mOzu0xwJVupIxkyFMPQSSc2q8aLm67NSpJy08DsmaNses5hSvu8x15RPHLQTybjt
 SwtKns+jpCq79P1GWbrB5e5UkLb0VNoxNp4L1U4pMrYGcEkJUXbaxNY2V/JcXdM7
 Vtn+qN0T/J6V6QVftv0t8Ecj3bjEnmL3kZHaTaNg3dGeKRpCGyHc5lcBQ0cNFG6t
 vjZ9VbuhBzGI3TN2tHH5hpA1UXo7HPBBCwQqxF1jeGLGHULikYwZ3TAPWqL3QZqC
 9cxr9SY=
 =p75d
 -----END PGP SIGNATURE-----

BackMerge tag 'v5.15-rc7' into drm-next

The msm next tree is based on rc3, so let's just backmerge rc7 before pulling it in.

Signed-off-by: Dave Airlie <airlied@redhat.com>
2021-10-28 14:59:38 +10:00
Maxime Ripard
bca10db67b
drm/vc4: crtc: Make sure the HDMI controller is powered when disabling
Since commit 875a4d536842 ("drm/vc4: drv: Disable the CRTC at boot
time"), during the initial setup of the driver we call into the VC4 HDMI
controller hooks to make sure the controller is properly disabled.

However, we were never making sure that the device was properly powered
while doing so. This never resulted in any (reported) issue in practice,
but since the introduction of commit 4209f03fcb8e ("drm/vc4: hdmi: Warn
if we access the controller while disabled") we get a loud complaint
when we do that kind of access.

Let's make sure we have the HDMI controller properly powered while
disabling it.

Fixes: 875a4d536842 ("drm/vc4: drv: Disable the CRTC at boot time")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Tested-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210923185013.826679-1-maxime@cerno.tech
2021-10-25 15:33:41 +02:00
Maxime Ripard
14e193b956
drm/vc4: hdmi: Warn if we access the controller while disabled
We've had many silent hangs where the kernel would look like it just
stalled due to the access to one of the HDMI registers while the
controller was disabled.

Add a warning if we're about to do that so that it's at least not silent
anymore.

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-7-maxime@cerno.tech
2021-10-25 15:33:41 +02:00
Maxime Ripard
20b0dfa86b
drm/vc4: hdmi: Make sure the device is powered with CEC
Similarly to what we encountered with the detect hook with DRM, nothing
actually prevents any of the CEC callback from being run while the HDMI
output is disabled.

However, this is an issue since any register access to the controller
when it's powered down will result in a silent hang.

Let's make sure we run the runtime_pm hooks when the CEC adapter is
opened and closed by the userspace to avoid that issue.

Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support")
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-6-maxime@cerno.tech
2021-10-25 15:33:41 +02:00
Maxime Ripard
724fc856c0
drm/vc4: hdmi: Split the CEC disable / enable functions in two
In order to ease further additions to the CEC enable and disable, let's
split the function into two functions, one to enable and the other to
disable.

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-5-maxime@cerno.tech
2021-10-25 15:33:41 +02:00
Maxime Ripard
caa51a4c11
drm/vc4: hdmi: Rework the pre_crtc_configure error handling
Since our pre_crtc_configure hook returned void, we didn't implement a
goto-based error path handling, leading to errors like failing to put
back the device in pm_runtime in all the error paths, but also failing
to disable the pixel clock if clk_set_min_rate on the HSM clock fails.

Move to a goto-based implementation to have an easier consitency.

Fixes: 4f6e3d66ac52 ("drm/vc4: Add runtime PM support to the HDMI encoder driver")
Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-4-maxime@cerno.tech
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-10-25 15:33:40 +02:00
Maxime Ripard
9c6e4f6ed1
drm/vc4: hdmi: Make sure the controller is powered up during bind
In the bind hook, we actually need the device to have the HSM clock
running during the final part of the display initialisation where we
reset the controller and initialise the CEC component.

Failing to do so will result in a complete, silent, hang of the CPU.

Fixes: 411efa18e4b0 ("drm/vc4: hdmi: Move the HSM clock enable to runtime_pm")
Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-3-maxime@cerno.tech
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
2021-10-25 15:33:40 +02:00
Maxime Ripard
0f5251339e
drm/vc4: hdmi: Make sure the controller is powered in detect
If the HPD GPIO is not available and drm_probe_ddc fails, we end up
reading the HDMI_HOTPLUG register, but the controller might be powered
off resulting in a CPU hang. Make sure we have the power domain and the
HSM clock powered during the detect cycle to prevent the hang from
happening.

Fixes: 4f6e3d66ac52 ("drm/vc4: Add runtime PM support to the HDMI encoder driver")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Tested-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Tested-by: Michael Stapelberg <michael@stapelberg.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20210922125419.4125779-6-maxime@cerno.tech
2021-10-25 15:33:40 +02:00