Add support to the YUV formats bellow:
- NV12/NV16/NV24
- NV21/NV61/NV42
- YUV420/YUV422/YUV444
- YVU420/YVU422/YVU444
The conversion from yuv to rgb is done with fixed-point arithmetic, using
32.32 fixed-point numbers and the drm_fixed helpers.
To do the conversion, a specific matrix must be used for each color range
(DRM_COLOR_*_RANGE) and encoding (DRM_COLOR_*). This matrix is stored in
the `conversion_matrix` struct, along with the specific y_offset needed.
This matrix is queried only once, in `vkms_plane_atomic_update` and
stored in a `vkms_plane_state`. Those conversion matrices of each
encoding and range were obtained by rounding the values of the original
conversion matrices multiplied by 2^32. This is done to avoid the use of
floating point operations.
The same reading function is used for YUV and YVU formats. As the only
difference between those two category of formats is the order of field, a
simple swap in conversion matrix columns allows using the same function.
[Louis Chauvet:
- Adapted Arthur's work
- Implemented the read_line_t callbacks for yuv
- add struct conversion_matrix
- store the whole conversion_matrix in the plane state
- remove struct pixel_yuv_u8
- update the commit message
- Merge the modifications from Arthur]
Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250415-yuv-v18-2-f2918f71ec4b@bootlin.com
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
We can't trace dependencies from drm_sched_job_add_dependency
because when it's called the job's fence is not available yet.
So instead each dependency is traced individually when
drm_sched_entity_push_job is used.
Tracing the dependencies allows tools to analyze the dependencies
between the jobs (previously it was only possible for fences
traced by drm_sched_job_wait_dep).
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://lore.kernel.org/r/20250526125505.2360-6-pierre-eric.pelloux-prayer@amd.com
Since switching the scheduler from using kthreads to workqueues in
commit a6149f0393 ("drm/sched: Convert drm scheduler to use a work
queue rather than kthread") userspace applications cannot determine
the device from the PID of the threads sending the trace events
anymore.
Each queue had its own kthread which had a given PID for the whole
time. So, at least for amdgpu, it was possible to associate a PID
to the hardware queues of each GPU in the system. Then, when a
drm_run_job trace event was received by userspace, the source PID
allowed to associate it back to the correct GPU.
With workqueues this is not possible anymore, so the event needs to
contain the dev_name() to identify the device.
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://lore.kernel.org/r/20250526125505.2360-4-pierre-eric.pelloux-prayer@amd.com
This will be used in a later commit to trace the drm client_id in
some of the gpu_scheduler trace events.
This requires changing all the users of drm_sched_job_init to
add an extra parameter.
The newly added drm_client_id field in the drm_sched_fence is a bit
of a duplicate of the owner one. One suggestion I received was to
merge those 2 fields - this can't be done right now as amdgpu uses
some special values (AMDGPU_FENCE_OWNER_*) that can't really be
translated into a client id. Christian is working on getting rid of
those; when it's done we should be able to squash owner/drm_client_id
together.
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://lore.kernel.org/r/20250526125505.2360-3-pierre-eric.pelloux-prayer@amd.com
This is the new API for allocating DRM bridges.
This driver embeds an array of channels in the main struct, and each
channel embeds a drm_bridge. This prevents dynamic, refcount-based
deallocation of the bridges.
To make the new, dynamic bridge allocation possible:
* change the array of channels into an array of channel pointers
* allocate each channel using devm_drm_bridge_alloc()
* adapt the code wherever using the channels
* remove the is_available flag, now "ch != NULL" is equivalent
Reviewed-by: Liu Ying <victor.liu@nxp.com>
Link: https://lore.kernel.org/r/20250509-drm-bridge-convert-to-alloc-api-v3-18-b8bc1f16d7aa@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
When moving the Sitronix DRM drivers and renaming their Kconfig symbols,
the old symbols were kept, aiming to provide a seamless migration path
when running "make olddefconfig" or "make oldconfig".
However, the old compatibility symbols are not visible. Hence unless
they are selected by another symbol (which they are not), they can never
be enabled, and no backwards compatibility is provided.
Drop the broken mechanism and the old symbols.
Fixes: 9b8f32002c ("drm/sitronix: move tiny Sitronix drivers to their own subdir")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20395b14effe5e2e05a4f0856fdcda51c410329d.1747751592.git.geert+renesas@glider.be
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Replace vesadrm's code for programming the hardware gamma LUT with
DRM helpers. Either load a provided gamma ramp or program a default.
Set the individual entries with a callback.
Each gamma value is given as 3 individual 16-bit values for red,
green and blue. The driver reduces them to 8 bit to make them fit
into hardware registers.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250520094203.30545-6-tzimmermann@suse.de
Replace ofdrm's code for programming the hardware gamma LUT with
DRM helpers. Either load a provided gamma ramp or program a default.
Set the individual entries with a callback.
Each gamma value is given as 3 individual 16-bit values for red,
green and blue. The driver reduces them to 8 bit to make them fit
into hardware registers.
v2:
- fix coding style
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250520094203.30545-5-tzimmermann@suse.de
Replace mgag200's code for programming the hardware gamma LUT with
DRM helpers. Either load a provided gamma ramp or program a default.
Set the individual entries with a callback.
Each gamma value is given as 3 individual 16-bit values for red,
green and blue. The driver reduces them to 8 bit to make them fit
into hardware registers.
v2:
- fix coding style
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20250520094203.30545-4-tzimmermann@suse.de
Replace ast's code for programming the hardware gamma/palette LUT
with DRM helpers. Either load provided data or program a default.
Set the individual entries with a callback.
Each gamma/palette value is given as 3 individual 16-bit values
for red, green and blue. The driver reduces them to 8 bit to make
them fit into hardware registers.
v3:
- fix tags (Javier)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20250520094203.30545-3-tzimmermann@suse.de
Provide helpers that program hardware gamma LUTs. Tha gamma ramp is
either provided by the driver or generated by the helper.
The DRM driver exports the GAMMA_LUT property with a fixed number of
entries per color component, such as 256 on 8-bit-wide components. The
entries describe the gamma ramp of each individual component. The new
helper drm_crtc_load_gamma_888() loads such gamma ramp to hardware. The
hardware uses each displayed pixel's individial components as indices
into the hardware gamma table.
For color modes with less than 8 bits per color component, the helpers
drm_crtc_load_gamma_565_from() and drm_crtc_load_gamma_555_from_888()
interpolate the provided gamma ramp to reduce it to the correct number
of entries; 5/6/5 for RGB565-like formats and 5/5/5 for XRGB1555-like
formats.
If no gamma ramp has been provided, drivers can use the new helper
drm_crtc_fill_gamma_888() to load a default gamma ramp with 256 entries
per color component. For color modes with less bits, the new helpers
drm_crtc_fill_gamma_565() and drm_crtc_fill_gamma_555() are available.
The default gamma ramp uses a gamma factor of 1.
For color modes with palette, drm_crtc_load_palette_8() load an 8-bit
palette into the hardware. If no palette has been specified,
drm_crtc_fill_palette_8() load a system-specific default palette. This
is currently only a grey-scale palette with increasing luminance, but
later patches can change this. For PCs, a VGA default palette could
be used.
v2:
- drop comment on gamma factor of 2.2 (Michel, Pekka)
- fix typos in commit description (Javier)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250520094203.30545-2-tzimmermann@suse.de
devm_drm_bridge_alloc() is the new API to be used for allocating (and
partially initializing) a private driver struct embedding a struct
drm_bridge.
For many drivers having a simple code flow in the probe function, this
commit does a mass conversion automatically with the following semantic
patch. The changes have been reviewed manually for correctness as well as
to find any false positives.
The patch has been applied with the explicit exclusion of bridge/panel.c,
handled by a separate patch.
After applying the semantic patch, manually fixed these issues:
- 4 drivers need ERR_CAST() instead of PTR_ERR() as the function calling
devm_drm_bridge_alloc() returns a pointer
- re-added empty lines and comments that the script had removed but that
should stay
@@
type T;
identifier C;
identifier BR;
expression DEV;
expression FUNCS;
@@
-T *C;
+T *C;
...
(
-C = devm_kzalloc(DEV, ...);
-if (!C)
- return -ENOMEM;
+C = devm_drm_bridge_alloc(DEV, T, BR, FUNCS);
+if (IS_ERR(C))
+ return PTR_ERR(C);
|
-C = devm_kzalloc(DEV, ...);
-if (!C)
- return ERR_PTR(-ENOMEM);
+C = devm_drm_bridge_alloc(DEV, T, BR, FUNCS);
+if (IS_ERR(C))
+ return PTR_ERR(C);
)
...
-C->BR.funcs = FUNCS;
Reviewed-by: Manikandan Muralidharan <manikandan.m@microchip.com> # microchip-lvds.c
Reviewed-by: Douglas Anderson <dianders@chromium.org> # parade-ps8640
Tested-by: Douglas Anderson <dianders@chromium.org> # parade-ps8640
Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250509-drm-bridge-convert-to-alloc-api-v3-2-b8bc1f16d7aa@bootlin.com
[Luca: fixed trivial patch conflict in adv7511_drv.c while applying]
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
This is the new API for allocating DRM bridges.
The devm lifetime management of this driver is peculiar. The underlying
device for the panel_bridge is the panel, and the devm lifetime is tied the
panel device (panel->dev). However the panel_bridge allocation is not
performed by the panel driver, but rather by a separate entity (typically
the previous bridge in the encoder chain).
Thus when that separate entity is destroyed, the panel_bridge is not
removed automatically by devm, so it is rather done explicitly by calling
drm_panel_bridge_remove(). This is the function that does devm_kfree() the
panel_bridge in current code, so update it as well to put the bridge
reference instead.
This is a temporary solution until the panel lifetime is reworked, which
should make this workaround unnecessary, so add a comment to clarify that.
Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250509-drm-bridge-convert-to-alloc-api-v3-21-b8bc1f16d7aa@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Bridges obtained via devm_drm_bridge_alloc(dev, ...) will be put when the
requesting device (@dev) is removed.
However drivers which obtained them may need to put the obtained reference
explicitly. One such case is if they bind the devm removal action to a
different device than the one implemented by the driver itself and which
might be removed at a different time, such as bridge/panel.c.
Add devm_drm_put_bridge() to manually release a devm-obtained bridge in
such cases.
This function is considered only a temporary workaround until the panel
bridge is reworked and should be removed afterwards.
Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250509-drm-bridge-convert-to-alloc-api-v3-20-b8bc1f16d7aa@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
This is the new API for allocating DRM bridges.
This driver has a peculiar structure. zynqmp_dpsub.c is the actual driver,
which delegates to a submodule (zynqmp_dp.c) the allocation of a
sub-structure embedding the drm_bridge and its initialization, however it
does not delegate the drm_bridge_add(). Hence, following carefully the code
flow, it is correct to change the allocation function and .funcs assignment
in the submodule, while the drm_bridge_add() is not in that submodule.
Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250509-drm-bridge-convert-to-alloc-api-v3-17-b8bc1f16d7aa@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
This is the new API for allocating DRM bridges.
This driver allocates the DRM bridge separately from the main driver
private struct, which prevents using the new devm_drm_bridge_alloc()
API. Simplify the code by replacing the struct drm_bridge pointer with an
embedded struct drm_bridge inside the private struct, to make use of the
new API with the same code flow.
Acked-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250509-drm-bridge-convert-to-alloc-api-v3-16-b8bc1f16d7aa@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>