NV12 framebuffers produced by the VPU shows distorted on RK3288
after win has been disabled when scaling is active.
This issue can be reproduced using a 1080p modeset by:
- Scale a 1280x720 NV12 framebuffer to 1920x1080 on win0
- Disable win0
- Display a 1920x1080 NV12 framebuffer without scaling on win0
- Output will now show the framebuffer distorted
And by:
- Scale a 1280x720 NV12 framebuffer to 1920x1080
- Change to a 720p modeset (win gets disabled and scaling reset to none)
- Output will now show the framebuffer distorted
Fix this by setting scale mode to none when win is disabled.
Fixes: 4c156c21c7 ("drm/rockchip: vop: support plane scale")
Cc: stable@vger.kernel.org
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/AM3PR03MB0966DE3E19BACE07328CD637AC7D0@AM3PR03MB0966.eurprd03.prod.outlook.com
Before assigning window data, we should check if the yuv2yuv vop-data
is set at all, because it looks like it can otherwise reference something
wrong, as I saw on my rk3188 today which ended up in a null pointer
dereference in vop_plane_atomic_update when accessing the yuv2yuv data.
Fixes: 1c21aa8f2b ("drm/rockchip: Fix YUV buffers color rendering")
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/2556882.Heuq80WCVD@phil
Add the KMS plane rotation property to the DRM rockchip driver,
for SoCs RK3328, RK3368 and RK3399.
RK3288 only supports rotation at the display level (i.e. CRTC),
but for now we are only interested in plane rotation.
This commit only adds support for the value of reflect-y
and reflect-x (i.e. mirroring).
Note that y-mirroring is not compatible with YUV.
The following modetest commands would test this feature,
where 30 is the plane ID, and 49 = rotate_0 + relect_y + reflect_x.
X mirror:
modetest -s 43@33:1920x1080@XR24 -w 30:rotation:17
Y mirror:
modetest -s 43@33:1920x1080@XR24 -w 30:rotation:33
XY mirror:
modetest -s 43@33:1920x1080@XR24 -w 30:rotation:49
Signed-off-by: Daniele Castagna <dcastagna@chromium.org>
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20190109185639.5093-4-ezequiel@collabora.com
Currently, YUV hardware overlays are converted to RGB using
a color space conversion different than BT.601.
The result is that colors of e.g. NV12 buffers don't match
colors of YUV hardware overlays.
In order to fix this, enable YUV2YUV and set appropriate coefficients
for formats such as NV12 to be displayed correctly.
This commit was tested using modetest, gstreamer and chromeos (hardware
accelerated video playback). Before the commit, tests rendering
with NV12 format resulted in colors not displayed correctly.
Test examples (Tested on RK3399 and RK3288 boards
connected to HDMI monitor):
$ modetest 39@32:1920x1080@NV12
$ gst-launch-1.0 videotestrc ! video/x-raw,format=NV12 ! kmssink
Signed-off-by: Daniele Castagna <dcastagna@chromium.org>
[ezequiel: rebase on linux-next and massage commit log]
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20190108214659.28794-1-ezequiel@collabora.com
Add the Rockchip-sepcific dual-dsi setup and hook it into the VOP as well.
As described in the general dual-dsi devicetree binding, the panel should
define two input ports and point each of them to one of the used dsi-
controllers, as well as declare one of them as clock-master.
This is used to determine the dual-dsi state and get access to both
controller instances.
v6:
handle master+slave component in dsi-attach
v5:
use driver-internal mechanism to find dual dsi slave
v4:
add component directly in probe when adding empty dsi slave controller
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181001123845.11818-8-heiko@sntech.de
Some Rockchip CRTCs, like rv1108 and px30, can directly output parallel
and serial RGB data to panel or conversion chip.
So add a feature-bit for vops to mark the ability for these direct
outputs and add an internal encoder in that case, that can attach to
bridge chipsor panels.
Changes in v7:
1. forget to delete rockchip_rgb_driver and delete it.
Changes in v6:
1. Update according to Heiko Stuebner' implemention, rgb output is
part of vop's feature, should not register as a independent
driver.
Changes in v5:
1. add SPDX-License-Identifier tag
Changes in v4:
1. add support px30;
Changes in v3:
1. update for rgb-mode move to panel node.
Changes in v2:
1. add error log when probe failed;
2. update name_to_output_mode() according to sean's suggest;
3. Fix uninitialized use of ret.
Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20180830211207.10480-3-heiko@sntech.de
One of the more common cases of allocation size calculations is finding
the size of a structure that has a zero-sized array at the end, along
with memory for some number of elements for that array. For example:
struct foo {
int stuff;
void *entry[];
};
instance = devm_kzalloc(dev, sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL);
or, like in this particular case:
size = sizeof(struct foo) + sizeof(void *) * count;
instance = devm_kzalloc(dev, size, GFP_KERNEL);
Instead of leaving these open-coded and prone to type mistakes, we can
now use the new struct_size() helper:
instance = devm_kzalloc(dev, struct_size(instance, entry, count),
GFP_KERNEL);
This issue was detected with the help of Coccinelle.
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20180826184712.GA9330@embeddedor.com
The vop irq is shared between vop and iommu and irq probing in the
iommu driver moved to the probe function recently. This can in some
cases lead to a stall if the irq is triggered while the vop driver
still has it disabled, but the vop irq handler gets called.
But there is no real need to disable the irq, as the vop can simply
also track its enabled state and ignore irqs in that case.
For this we can simply check the power-domain state of the vop,
similar to how the iommu driver does it.
So remove the enable/disable handling and add appropriate condition
to the irq handler.
changes in v2:
- move to just check the power-domain state
- add clock handling
changes in v3:
- clarify comment to speak of runtime-pm not power-domain
changes in v4:
- address Marc's comments (clk-enable WARN_ON and style improvement)
Fixes: d0b912bd4c ("iommu/rockchip: Request irqs in rk_iommu_probe()")
Cc: stable@vger.kernel.org
Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Ezequiel Garcia <ezequiel@collabora.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180612132028.27490-3-heiko@sntech.de
We have seen a case of a bad reference count for vblanks with the
Rockchip VOP:
------------[ cut here ]------------
WARNING: CPU: 1 PID: 383 at drivers/gpu/drm/drm_irq.c:1198 drm_vblank_put+0x40/0xcc
Modules linked in: brcmfmac brcmutil
CPU: 1 PID: 383 Comm: kworker/u8:2 Not tainted 4.9.75-rt60 #1
Hardware name: Rockchip (Device Tree)
Workqueue: events_unbound flip_worker
Backtrace:
[<c010b7b0>] (dump_backtrace) from [<c010ba4c>] (show_stack+0x18/0x1c)
r7:c0b1b13c r6:600b0013 r5:00000000 r4:c0b1b13c
[<c010ba34>] (show_stack) from [<c032d248>] (dump_stack+0x78/0x94)
[<c032d1d0>] (dump_stack) from [<c011e6e8>] (__warn+0xe4/0x104)
r7:00000009 r6:c03cf26c r5:00000000 r4:00000000
[<c011e604>] (__warn) from [<c011e7c0>] (warn_slowpath_null+0x28/0x30)
r9:eeb443a0 r8:eeb443c8 r7:ee8a5ec0 r6:ee8a5ec0 r5:edb47f00 r4:ee096200
[<c011e798>] (warn_slowpath_null) from [<c03cf26c>] (drm_vblank_put+0x40/0xcc)
[<c03cf22c>] (drm_vblank_put) from [<c03cf310>] (drm_crtc_vblank_put+0x18/0x1c)
r5:edb47f00 r4:ee3c8a80
[<c03cf2f8>] (drm_crtc_vblank_put) from [<c03ef9b4>] (vop_fb_unref_worker+0x18/0x24)
[<c03ef99c>] (vop_fb_unref_worker) from [<c03df194>] (flip_worker+0x98/0xb4)
r5:edb47f00 r4:eeb443a8
[<c03df0fc>] (flip_worker) from [<c0134808>] (process_one_work+0x1a8/0x2fc)
r9:00000000 r8:ee807d00 r7:00000000 r6:ee809c00 r5:eeb443a8 r4:edfe5f80
[<c0134660>] (process_one_work) from [<c01358ec>] (worker_thread+0x2ac/0x458)
r10:00000088 r9:edfe5f98 r8:ee809c2c r7:c0b04100 r6:ee809c00 r5:ee809c00
r4:edfe5f80
[<c0135640>] (worker_thread) from [<c013a0bc>] (kthread+0xfc/0x10c)
r10:00000000 r9:00000000 r8:c0135640 r7:edfe5f80 r6:00000000 r5:edf0e240
r4:ee8a4000 r3:ed194e00
[<c0139fc0>] (kthread) from [<c0107cb8>] (ret_from_fork+0x14/0x3c)
r8:00000000 r7:00000000 r6:00000000 r5:c0139fc0 r4:edf0e240
---[ end trace 0000000000000002 ]---
It seems that this is caused by unfortunate timing between
vop_crtc_atomic_flush() and vop_handle_vblank() given the following
ordering:
atomic_flush handle_vblank
------------ -------------
drm_flip_work_queue
set_bit
if (test_and_clear_bit(...))
drm_flip_work_commit
drm_vblank_get
This results in vop_fb_unref_worker (called as flip work) decrementing
the vblank refcount before it has been incremented.
Signed-off-by: John Keeping <john@metanate.com>
Reviewed-by: Sandy huang <hjc@rock-chips.com>
Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180328160351.23763-1-john@metanate.com
The rockchip DRM driver is quite careful to disable interrupts
when taking a lock that is also taken in interrupt context,
which is a good thing.
What is a bit over the top is to use spin_lock_irqsave when
already in interrupt context, as you cannot take another
interrupt again, and disabling interrupt is just pure
overhead.
Switching to the non _irqsave version in interrupt context is
more logical, and less heavy handed.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20180220130120.5254-4-marc.zyngier@arm.com
Calling request_irq() followed by disable_irq() is usually a bad idea,
specially if the interrupt can be pending, and you're not yet in a
position to handle it.
This is exactly what happens on my kevin system when rebooting in a
second kernel using kexec: Some interrupt is left pending from
the previous kernel, and we take it too early, before disable_irq()
could do anything.
Let's clear the pending interrupts as we initialize the HW, and move
the interrupt request after that point. This ensures that we're in
a sane state when the interrupt is requested.
Cc: stable@vger.kernel.org
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
[adapted to recent rockchip-drm changes]
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20180220130120.5254-2-marc.zyngier@arm.com
drm_plane_helper_check_state() is supposed to do things the atomic way,
so it should not be inspecting crtc->enabled. Rather we should be
looking at crtc_state->enable.
We have a slight complication due to drm_plane_helper_check_update()
reusing drm_plane_helper_check_state() for non-atomic drivers. Thus
we'll have to pass the crtc_state in manally and construct a fake
crtc_state in drm_plane_helper_check_update().
v2: Fix the WARNs about plane_state->crtc matching crtc_state->crtc
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171101201558.6059-1-ville.syrjala@linux.intel.com
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This patch replace instances of dev_info/err/debug with
DRM_DEV_INFO/ERROR/WARN respectively inorder to use a drm-formatted
specific log messages. Issue corrected with the help of the following
Coccinelle script:
@r@
@@
(
-dev_info
+DRM_DEV_INFO
|
-dev_err
+DRM_DEV_ERROR
|
-dev_dbg
+DRM_DEV_DEBUG
)
Signed-off-by: Haneen Mohammed <hamohammed.sa@gmail.com>
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170915083603.GA18992@Haneen
Use drm_*_get() and drm_*_put() helpers instead of drm_*_reference()
and drm_*_unreference() helpers.
drm_*_reference() and drm_*_unreference() functions are just
compatibility alias for drm_*_get() and drm_*_put() and should not be
used by new code. So convert all users of compatibility functions to
use the new APIs.
Generated by: scripts/coccinelle/api/drm-get-put.cocci
Signed-off-by: Cihangir Akturk <cakturk@gmail.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/1502454794-28558-21-git-send-email-cakturk@gmail.com
Iommu would get page fault with following path:
vop_disable:
1, disable all windows and set vop config done
2, vop enter to standy, all windows not works, but their registers
are not clean, when you read window's enable bit, may found the
window is enable.
vop_enable:
1, memcpy(vop->regsbak, vop->regs, len)
save current vop registers to vop->regsbak, then you can found
window is enable on regsbak.
2, VOP_WIN_SET(vop, win, gate, 1);
force enable window gate, but gate and enable are on same
hardware register, then window enable bit rewrite to vop hardware.
3, vop power on, and vop might try to scan destroyed buffer,
then iommu get page fault.
Move windows disable after vop regsbak restore, then vop regsbak mechanism
would keep tracing the modify, everything would be safe.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Reviewed-by: Sandy huang <sandy.huang@rock-chips.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1501494582-6934-1-git-send-email-mark.yao@rock-chips.com
This is the plumbing for supporting fb modifiers on planes. Modifiers
have already been introduced to some extent, but this series will extend
this to allow querying modifiers per plane. Based on this, the client to
enable optimal modifications for framebuffers.
This patch simply allows the DRM drivers to initialize their list of
supported modifiers upon initializing the plane.
v2: A minor addition from Daniel
v3:
* Updated commit message
* s/INVALID/DRM_FORMAT_MOD_INVALID (Liviu)
* Remove some excess newlines (Liviu)
* Update comment for > 64 modifiers (Liviu)
v4: Minor comment adjustments (Liviu)
v5: Some new platforms added due to rebase
v6: Add some missed plane inits (or maybe they're new - who knows at
this point) (Daniel)
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Daniel Stone <daniels@collabora.com> (v2)
Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Stone <daniels@collabora.com>