[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <DE7IXK6SWV7J.3B9AOCCGWT4EH@cknow-tech.com>
Date: Thu, 13 Nov 2025 12:18:17 +0100
From: "Diederik de Haas" <diederik@...ow-tech.com>
To: "Dang Huynh" <dang.huynh@...nlining.org>, "Andy Yan" <andyshrk@....com>
Cc: <heiko@...ech.de>, <hjc@...k-chips.com>, <diederik@...ow-tech.com>,
<dri-devel@...ts.freedesktop.org>, <linux-arm-kernel@...ts.infradead.org>,
<linux-kernel@...r.kernel.org>, <linux-rockchip@...ts.infradead.org>, "Andy
Yan" <andy.yan@...k-chips.com>
Subject: Re: [PATCH] drm/rockchip: vop2: Use OVL_LAYER_SEL configuration
instead of use win_mask calculate used layers
On Thu Nov 13, 2025 at 9:11 AM CET, Dang Huynh wrote:
> Hi Andy,
>
> This fix works on my device. No more black box around the cursor.
>
> Tested-by: Dang Huynh <dang.huynh@...nlining.org>
Thanks for testing and your Tested-by tag :-D
FYI: Apparently something went wrong with delivery it as it only arrived
at LKML, but not dri-devel, linux-arm-kernel or linux-rockchip MLs.
No idea if that's problematic (for b4 f.e.) though.
'lore' has it here:
https://lore.kernel.org/all/hrg6geclph37olvqr3o5v4d4mifvl25kaemh7f2z3hwega7h2b@muf2gkfqzvvz/
Cheers,
Diederik
> On Wed, Nov 12, 2025 at 04:50:23PM +0800, Andy Yan wrote:
>> From: Andy Yan <andy.yan@...k-chips.com>
>>
>> When there are multiple Video Ports, and only one of them is working
>> (for example, VP1 is working while VP0 is not), in this case, the
>> win_mask of VP0 is 0. However, we have already set the port mux for VP0
>> according to vp0->nlayers, and at the same time, in the OVL_LAYER_SEL
>> register, there are windows will also be assigned to layers which will
>> map to the inactive VPs. In this situation, vp0->win_mask is zero as it
>> now working, it is more reliable to calculate the used layers based on
>> the configuration of the OVL_LAYER_SEL register.
>>
>> Note: as the configuration of OVL_LAYER_SEL is take effect when the
>> vsync is come, so we use the value backup in vop2->old_layer_sel instead
>> of read OVL_LAYER_SEL directly.
>>
>> Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568")
>> Reported-by: Diederik de Haas <diederik@...ow-tech.com>
>> Closes: https://bugs.kde.org/show_bug.cgi?id=511274
>> Signed-off-by: Andy Yan <andy.yan@...k-chips.com>
>> ---
>>
>> drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 49 +++++++++++++++++---
>> 1 file changed, 42 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> index d22ce11a4235..f3950e8476a7 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> @@ -1369,6 +1369,25 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
>> },
>> };
>>
>> +/*
>> + * phys_id is used to identify a main window(Cluster Win/Smart Win, not
>> + * include the sub win of a cluster or the multi area) that can do overlay
>> + * in main overlay stage.
>> + */
>> +static struct vop2_win *vop2_find_win_by_phys_id(struct vop2 *vop2, uint8_t phys_id)
>> +{
>> + struct vop2_win *win;
>> + int i;
>> +
>> + for (i = 0; i < vop2->data->win_size; i++) {
>> + win = &vop2->win[i];
>> + if (win->data->phys_id == phys_id)
>> + return win;
>> + }
>> +
>> + return NULL;
>> +}
>> +
>> static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
>> {
>> struct vop2 *vop2 = vp->vop2;
>> @@ -1842,15 +1861,31 @@ static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
>> alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
>> }
>>
>> -static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
>> +static int vop2_find_start_mixer_id_for_vp(struct vop2_video_port *vp)
>> {
>> - struct vop2_video_port *vp;
>> - int used_layer = 0;
>> + struct vop2 *vop2 = vp->vop2;
>> + struct vop2_win *win;
>> + u32 layer_sel = vop2->old_layer_sel;
>> + u32 used_layer = 0;
>> + unsigned long win_mask = vp->win_mask;
>> + unsigned long phys_id;
>> + bool match;
>> int i;
>>
>> - for (i = 0; i < port_id; i++) {
>> - vp = &vop2->vps[i];
>> - used_layer += hweight32(vp->win_mask);
>> + for (i = 0; i < 31; i += 4) {
>> + match = false;
>> + for_each_set_bit(phys_id, &win_mask, ROCKCHIP_VOP2_ESMART3) {
>> + win = vop2_find_win_by_phys_id(vop2, phys_id);
>> + if (win->data->layer_sel_id[vp->id] == ((layer_sel >> i) & 0xf)) {
>> + match = true;
>> + break;
>> + }
>> + }
>> +
>> + if (!match)
>> + used_layer += 1;
>> + else
>> + break;
>> }
>>
>> return used_layer;
>> @@ -1935,7 +1970,7 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
>> u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
>>
>> if (vop2->version <= VOP_VERSION_RK3588)
>> - mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
>> + mixer_id = vop2_find_start_mixer_id_for_vp(vp);
>> else
>> mixer_id = 0;
>>
>> --
>> 2.43.0
>>
>> base-commit: ded94ec6167e84195507237100f6278941e36fdd
>> branch: drm-misc-next-2025-1016
>>
>>
>> _______________________________________________
>> Linux-rockchip mailing list
>> Linux-rockchip@...ts.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-rockchip
Powered by blists - more mailing lists