From nobody Mon Apr 13 05:44:37 2026 Received: from cstnet.cn (smtp81.cstnet.cn [159.226.251.81]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AFCF234EEED for ; Mon, 9 Mar 2026 08:53:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.81 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773046424; cv=none; b=CT2quOgyYQSm0UyNgS5wn8jrOI2NOiQ6PYUKWEHKUlnplqxkL07dnyDreYRfo/4icAL/6RtWtviS5XnkzwupLF0TairwVMIgYsARPTSXBLXx44enkXh3SqdQfpwjthmAb40N+0s8k8R5FvGv8NAgpDvvR6AgySKkbZsHh0J4Zps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773046424; c=relaxed/simple; bh=MqGpAvCKeOOJg4jpUyN6dojXkdjIUjblICqp/8LozpQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oVFTj5kBEM1qEUE1rLYDhq8kjeEVX/vebx/i8g/4PpcgrQHQgjT9/1lCr4XpxW5pks1BM+lxlgca0erPNa7ldjxqYXbJBnkZLxQOXAAHigrM4bk+tWO/QynFPkoQwvbU7B3ynrQuPQmz83c9WLjHjNxxGwuO/l0nDBRc9hYrwrw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn; spf=pass smtp.mailfrom=iscas.ac.cn; arc=none smtp.client-ip=159.226.251.81 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iscas.ac.cn Received: from edelgard.fodlan.icenowy.me (unknown [112.94.103.14]) by APP-03 (Coremail) with SMTP id rQCowADX+N9_iq5pkiwjCg--.65307S3; Mon, 09 Mar 2026 16:53:26 +0800 (CST) From: Icenowy Zheng To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Icenowy Zheng , Han Gao , Icenowy Zheng Subject: [PATCH -next 1/2] drm: verisilicon: add max cursor size to HWDB Date: Mon, 9 Mar 2026 16:53:01 +0800 Message-ID: <20260309085302.3132732-2-zhengxingda@iscas.ac.cn> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260309085302.3132732-1-zhengxingda@iscas.ac.cn> References: <20260309085302.3132732-1-zhengxingda@iscas.ac.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: rQCowADX+N9_iq5pkiwjCg--.65307S3 X-Coremail-Antispam: 1UD129KBjvJXoW7AFWrAFW5GFWxCF4ftF18Krg_yoW8ZrWUpF 42yryDWa95Ja13twn7JrW2gryayas5JayIgryrt3sa9rs0ga4UXa43CayYkFZ5tr1xArya qFs29rW3Cr4IyF7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmj14x267AKxVW5JVWrJwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r1I6r4UM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UM2 8EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2AI xVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20x vE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xv r2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI8v6xkF7I0E8cxan2IY04 v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j 6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7 AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE 2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcV C2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2Kfnx nUUI43ZEXa7VUbn2-7UUUUU== X-CM-SenderInfo: x2kh0wp0lqwv3d6l2u1dvotugofq/ Content-Type: text/plain; charset="utf-8" Different display controller variants support different maximum cursor size. All known DC8200 variants support both 32x32 and 64x64, but some DC8000 variants support either only 32x32 or up to 256x256. The minimum size is fixed at 32 and only PoT square sizes are supported. Add the max cursor size field to HWDB and fill all entries with 64. Signed-off-by: Icenowy Zheng --- drivers/gpu/drm/verisilicon/vs_hwdb.c | 4 ++++ drivers/gpu/drm/verisilicon/vs_hwdb.h | 1 + 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/verisilicon/vs_hwdb.c b/drivers/gpu/drm/verisi= licon/vs_hwdb.c index 09336af0900ae..2a0f7c59afa3a 100644 --- a/drivers/gpu/drm/verisilicon/vs_hwdb.c +++ b/drivers/gpu/drm/verisilicon/vs_hwdb.c @@ -95,6 +95,7 @@ static struct vs_chip_identity vs_chip_identities[] =3D { .customer_id =3D ~0U, =20 .display_count =3D 2, + .max_cursor_size =3D 64, .formats =3D &vs_formats_no_yuv444, }, { @@ -103,6 +104,7 @@ static struct vs_chip_identity vs_chip_identities[] =3D= { .customer_id =3D 0x30B, =20 .display_count =3D 2, + .max_cursor_size =3D 64, .formats =3D &vs_formats_no_yuv444, }, { @@ -111,6 +113,7 @@ static struct vs_chip_identity vs_chip_identities[] =3D= { .customer_id =3D 0x310, =20 .display_count =3D 2, + .max_cursor_size =3D 64, .formats =3D &vs_formats_with_yuv444, }, { @@ -119,6 +122,7 @@ static struct vs_chip_identity vs_chip_identities[] =3D= { .customer_id =3D 0x311, =20 .display_count =3D 2, + .max_cursor_size =3D 64, .formats =3D &vs_formats_no_yuv444, }, }; diff --git a/drivers/gpu/drm/verisilicon/vs_hwdb.h b/drivers/gpu/drm/verisi= licon/vs_hwdb.h index 92192e4fa0862..c54c9326c1681 100644 --- a/drivers/gpu/drm/verisilicon/vs_hwdb.h +++ b/drivers/gpu/drm/verisilicon/vs_hwdb.h @@ -20,6 +20,7 @@ struct vs_chip_identity { u32 customer_id; =20 u32 display_count; + int32_t max_cursor_size; const struct vs_formats *formats; }; =20 --=20 2.52.0 From nobody Mon Apr 13 05:44:37 2026 Received: from cstnet.cn (smtp81.cstnet.cn [159.226.251.81]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E0A152DC76A for ; Mon, 9 Mar 2026 08:53:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.81 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773046421; cv=none; b=rqUq0uUnRArKU13XPPCpiO+FRxtlr4E30NDn28DWcmUhlnu5BqxpTxoUuooGUbiMQqTh/e6bBz4/tmHscDJVA2+uGS191yxDDXyYx9C7eDpXopnAMd44FBh5v+1zyEv92ZArBPJg0Usuxcw3AaoADNQ7IEx5oo6ggxWE4AZ1RKA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773046421; c=relaxed/simple; bh=TdR8zbrP/OzG/7fz3ESvuHcJXmNVImqpgOzhHXdwOaU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=thfsST7T2NrU0ltqbqMeqlrEbVT4mF+Z/D9utV/eGvkAtO/Wi9yxsAPrLXo0tjqC3t6O3OKshCKk2AHkpYeCroh4azAwVc5phagWyiWoK3k9BTxn9B9b6ARa4VXR3kFIMSR2ampGzePwFCMhB5p39uFWr2GNXUp3EuYitzno6d8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn; spf=pass smtp.mailfrom=iscas.ac.cn; arc=none smtp.client-ip=159.226.251.81 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iscas.ac.cn Received: from edelgard.fodlan.icenowy.me (unknown [112.94.103.14]) by APP-03 (Coremail) with SMTP id rQCowADX+N9_iq5pkiwjCg--.65307S4; Mon, 09 Mar 2026 16:53:29 +0800 (CST) From: Icenowy Zheng To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Icenowy Zheng , Han Gao , Icenowy Zheng Subject: [PATCH -next 2/2] drm: verisilicon: add support for cursor planes Date: Mon, 9 Mar 2026 16:53:02 +0800 Message-ID: <20260309085302.3132732-3-zhengxingda@iscas.ac.cn> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260309085302.3132732-1-zhengxingda@iscas.ac.cn> References: <20260309085302.3132732-1-zhengxingda@iscas.ac.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: rQCowADX+N9_iq5pkiwjCg--.65307S4 X-Coremail-Antispam: 1UD129KBjvAXoW3tF48AFy3Aw17Gr4fCF45ZFb_yoW8Gw15to WxXa13Gw4kt3Z7KrZ0yw48tw1rZFs7Wrs0k3y0gFW8Za4DJwn0vFW7WryY9FWxtr1Fyr4D uw4vy3ZFqF1UCan3n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO77AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r15M28IrcIa0x kI8VCY1x0267AKxVW8JVW5JwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAS 0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2 IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0 Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWU JVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0x vEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVj vjDU0xZFpf9x0JUczV8UUUUU= X-CM-SenderInfo: x2kh0wp0lqwv3d6l2u1dvotugofq/ Content-Type: text/plain; charset="utf-8" Verisilicon display controllers support hardware cursors per output port. Add support for them as cursor planes. Signed-off-by: Icenowy Zheng --- drivers/gpu/drm/verisilicon/Makefile | 3 +- drivers/gpu/drm/verisilicon/vs_crtc.c | 11 +- drivers/gpu/drm/verisilicon/vs_cursor_plane.c | 273 ++++++++++++++++++ .../drm/verisilicon/vs_cursor_plane_regs.h | 44 +++ drivers/gpu/drm/verisilicon/vs_plane.h | 1 + .../drm/verisilicon/vs_primary_plane_regs.h | 5 +- 6 files changed, 333 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/verisilicon/vs_cursor_plane.c create mode 100644 drivers/gpu/drm/verisilicon/vs_cursor_plane_regs.h diff --git a/drivers/gpu/drm/verisilicon/Makefile b/drivers/gpu/drm/verisil= icon/Makefile index fd8d805fbcde1..426f4bcaa834d 100644 --- a/drivers/gpu/drm/verisilicon/Makefile +++ b/drivers/gpu/drm/verisilicon/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only =20 -verisilicon-dc-objs :=3D vs_bridge.o vs_crtc.o vs_dc.o vs_drm.o vs_hwdb.o = vs_plane.o vs_primary_plane.o +verisilicon-dc-objs :=3D vs_bridge.o vs_crtc.o vs_dc.o vs_drm.o vs_hwdb.o \ + vs_plane.o vs_primary_plane.o vs_cursor_plane.o =20 obj-$(CONFIG_DRM_VERISILICON_DC) +=3D verisilicon-dc.o diff --git a/drivers/gpu/drm/verisilicon/vs_crtc.c b/drivers/gpu/drm/verisi= licon/vs_crtc.c index f494017130006..5c9714a3e69a7 100644 --- a/drivers/gpu/drm/verisilicon/vs_crtc.c +++ b/drivers/gpu/drm/verisilicon/vs_crtc.c @@ -159,7 +159,7 @@ struct vs_crtc *vs_crtc_init(struct drm_device *drm_dev= , struct vs_dc *dc, unsigned int output) { struct vs_crtc *vcrtc; - struct drm_plane *primary; + struct drm_plane *primary, *cursor; int ret; =20 vcrtc =3D drmm_kzalloc(drm_dev, sizeof(*vcrtc), GFP_KERNEL); @@ -175,9 +175,16 @@ struct vs_crtc *vs_crtc_init(struct drm_device *drm_de= v, struct vs_dc *dc, return ERR_PTR(PTR_ERR(primary)); } =20 + /* Create our cursor plane */ + cursor =3D vs_cursor_plane_init(drm_dev, dc); + if (IS_ERR(cursor)) { + drm_err(drm_dev, "Couldn't create the cursor plane\n"); + return ERR_CAST(cursor); + } + ret =3D drmm_crtc_init_with_planes(drm_dev, &vcrtc->base, primary, - NULL, + cursor, &vs_crtc_funcs, NULL); if (ret) { diff --git a/drivers/gpu/drm/verisilicon/vs_cursor_plane.c b/drivers/gpu/dr= m/verisilicon/vs_cursor_plane.c new file mode 100644 index 0000000000000..4c86519458077 --- /dev/null +++ b/drivers/gpu/drm/verisilicon/vs_cursor_plane.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Institute of Software, Chinese Academy of Sciences (= ISCAS) + * + * Authors: + * Icenowy Zheng + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vs_crtc.h" +#include "vs_plane.h" +#include "vs_dc.h" +#include "vs_hwdb.h" +#include "vs_cursor_plane_regs.h" + +#define VSDC_CURSOR_LOCATION_MAX_POSITIVE BIT_MASK(15) +#define VSDC_CURSOR_LOCATION_MAX_NEGATIVE BIT_MASK(5) + +static bool vs_cursor_plane_check_coord(int32_t coord) +{ + if (coord >=3D 0) + return coord <=3D VSDC_CURSOR_LOCATION_MAX_POSITIVE; + else + return (-coord) <=3D VSDC_CURSOR_LOCATION_MAX_NEGATIVE; +} + +static int vs_cursor_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_plane_state =3D drm_atomic_get_new_plane_stat= e(state, + plane); + struct drm_crtc *crtc =3D new_plane_state->crtc; + struct drm_framebuffer *fb =3D new_plane_state->fb; + struct drm_crtc_state *crtc_state =3D NULL; + struct vs_crtc *vcrtc; + struct vs_dc *dc; + int ret; + + if (crtc) + crtc_state =3D drm_atomic_get_new_crtc_state(state, crtc); + + ret =3D drm_atomic_helper_check_plane_state(new_plane_state, + crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + true, true); + if (ret) + return ret; + + if (!crtc) + return 0; /* Skip validity check */ + + vcrtc =3D drm_crtc_to_vs_crtc(crtc); + dc =3D vcrtc->dc; + + /* Only certain square sizes is supported */ + switch (new_plane_state->crtc_w) { + case 32: + case 64: + case 128: + case 256: + break; + default: + return -EINVAL; + } + + if (new_plane_state->crtc_w > dc->identity.max_cursor_size) + return -EINVAL; + + if (new_plane_state->crtc_w !=3D new_plane_state->crtc_h) + return -EINVAL; + + /* Check if the cursor is inside the register fields' range */ + if (!vs_cursor_plane_check_coord(new_plane_state->crtc_x) || + !vs_cursor_plane_check_coord(new_plane_state->crtc_y)) + return -EINVAL; + + if (fb) { + /* Only ARGB8888 is supported */ + if (drm_WARN_ON_ONCE(plane->dev, + fb->format->format !=3D DRM_FORMAT_ARGB8888)) + return -EINVAL; + + /* Extra line padding isn't supported */ + if (fb->pitches[0] !=3D + drm_format_info_min_pitch(fb->format, 0, + new_plane_state->crtc_w)) + return -EINVAL; + } + + return 0; +} + +static void vs_cursor_plane_commit(struct vs_dc *dc, unsigned int output) +{ + regmap_set_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_COMMIT | + VSDC_CURSOR_CONFIG_IMG_UPDATE); +} + +static void vs_cursor_plane_atomic_enable(struct drm_plane *plane, + struct drm_atomic_state *atomic_state) +{ + struct drm_plane_state *state =3D drm_atomic_get_new_plane_state(atomic_s= tate, + plane); + struct drm_crtc *crtc =3D state->crtc; + struct vs_crtc *vcrtc =3D drm_crtc_to_vs_crtc(crtc); + unsigned int output =3D vcrtc->id; + struct vs_dc *dc =3D vcrtc->dc; + + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_FMT_MASK, + VSDC_CURSOR_CONFIG_FMT_ARGB8888); + + vs_cursor_plane_commit(dc, output); +} + +static void vs_cursor_plane_atomic_disable(struct drm_plane *plane, + struct drm_atomic_state *atomic_state) +{ + struct drm_plane_state *state =3D drm_atomic_get_old_plane_state(atomic_s= tate, + plane); + struct drm_crtc *crtc =3D state->crtc; + struct vs_crtc *vcrtc =3D drm_crtc_to_vs_crtc(crtc); + unsigned int output =3D vcrtc->id; + struct vs_dc *dc =3D vcrtc->dc; + + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_FMT_MASK, + VSDC_CURSOR_CONFIG_FMT_OFF); + + vs_cursor_plane_commit(dc, output); +} + +static void vs_cursor_plane_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *atomic_state) +{ + struct drm_plane_state *state =3D drm_atomic_get_new_plane_state(atomic_s= tate, + plane); + struct drm_framebuffer *fb =3D state->fb; + struct drm_crtc *crtc =3D state->crtc; + struct vs_dc *dc; + struct vs_crtc *vcrtc; + unsigned int output; + dma_addr_t dma_addr; + + if (!state->visible) { + vs_cursor_plane_atomic_disable(plane, atomic_state); + return; + } + + vcrtc =3D drm_crtc_to_vs_crtc(crtc); + output =3D vcrtc->id; + dc =3D vcrtc->dc; + + switch (state->crtc_w) { + case 32: + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_SIZE_MASK, + VSDC_CURSOR_CONFIG_SIZE_32); + break; + case 64: + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_SIZE_MASK, + VSDC_CURSOR_CONFIG_SIZE_64); + break; + case 128: + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_SIZE_MASK, + VSDC_CURSOR_CONFIG_SIZE_128); + break; + case 256: + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_SIZE_MASK, + VSDC_CURSOR_CONFIG_SIZE_256); + break; + } + + dma_addr =3D vs_fb_get_dma_addr(fb, &state->src); + + regmap_write(dc->regs, VSDC_CURSOR_ADDRESS(output), + lower_32_bits(dma_addr)); + + /* + * The X_OFF and Y_OFF fields define which point does the LOCATION + * register represent in the cursor image, and LOCATION register + * values are unsigned. To for positive left-top coordinates the + * offset is set to 0 and the location is set to the coordinate, for + * negative coordinates the location is set to 0 and the offset + * is set to the opposite number of the coordinate to offset the + * cursor image partly off-screen. + */ + if (state->crtc_x >=3D 0) { + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_X_OFF_MASK, 0); + regmap_update_bits(dc->regs, VSDC_CURSOR_LOCATION(output), + VSDC_CURSOR_LOCATION_X_MASK, + VSDC_CURSOR_LOCATION_X(state->crtc_x)); + } else { + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_X_OFF_MASK, + -state->crtc_x); + regmap_update_bits(dc->regs, VSDC_CURSOR_LOCATION(output), + VSDC_CURSOR_LOCATION_X_MASK, 0); + } + + if (state->crtc_y >=3D 0) { + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_Y_OFF_MASK, 0); + regmap_update_bits(dc->regs, VSDC_CURSOR_LOCATION(output), + VSDC_CURSOR_LOCATION_Y_MASK, + VSDC_CURSOR_LOCATION_Y(state->crtc_y)); + } else { + regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output), + VSDC_CURSOR_CONFIG_Y_OFF_MASK, + -state->crtc_y); + regmap_update_bits(dc->regs, VSDC_CURSOR_LOCATION(output), + VSDC_CURSOR_LOCATION_Y_MASK, 0); + } + + vs_cursor_plane_commit(dc, output); +} + +static const struct drm_plane_helper_funcs vs_cursor_plane_helper_funcs = =3D { + .atomic_check =3D vs_cursor_plane_atomic_check, + .atomic_update =3D vs_cursor_plane_atomic_update, + .atomic_enable =3D vs_cursor_plane_atomic_enable, + .atomic_disable =3D vs_cursor_plane_atomic_disable, +}; + +static const struct drm_plane_funcs vs_cursor_plane_funcs =3D { + .atomic_destroy_state =3D drm_atomic_helper_plane_destroy_state, + .atomic_duplicate_state =3D drm_atomic_helper_plane_duplicate_state, + .disable_plane =3D drm_atomic_helper_disable_plane, + .reset =3D drm_atomic_helper_plane_reset, + .update_plane =3D drm_atomic_helper_update_plane, +}; + +static const u32 vs_cursor_plane_formats[] =3D { + DRM_FORMAT_ARGB8888, +}; + +struct drm_plane *vs_cursor_plane_init(struct drm_device *drm_dev, + struct vs_dc *dc) +{ + struct drm_plane *plane; + + plane =3D drmm_universal_plane_alloc(drm_dev, struct drm_plane, dev, 0, + &vs_cursor_plane_funcs, + vs_cursor_plane_formats, + ARRAY_SIZE(vs_cursor_plane_formats), + NULL, + DRM_PLANE_TYPE_CURSOR, + NULL); + + if (IS_ERR(plane)) + return plane; + + drm_plane_helper_add(plane, &vs_cursor_plane_helper_funcs); + + return plane; +} diff --git a/drivers/gpu/drm/verisilicon/vs_cursor_plane_regs.h b/drivers/g= pu/drm/verisilicon/vs_cursor_plane_regs.h new file mode 100644 index 0000000000000..99693f2c95b94 --- /dev/null +++ b/drivers/gpu/drm/verisilicon/vs_cursor_plane_regs.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2025 Icenowy Zheng + * + * Based on vs_dc_hw.h, which is: + * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. + */ + +#ifndef _VS_CURSOR_PLANE_REGS_H_ +#define _VS_CURSOR_PLANE_REGS_H_ + +#include + +#define VSDC_CURSOR_CONFIG(n) (0x1468 + 0x1080 * (n)) +#define VSDC_CURSOR_CONFIG_FMT_MASK GENMASK(1, 0) +#define VSDC_CURSOR_CONFIG_FMT_ARGB8888 (0x2 << 0) +#define VSDC_CURSOR_CONFIG_FMT_OFF (0x0 << 0) +#define VSDC_CURSOR_CONFIG_IMG_UPDATE BIT(2) +#define VSDC_CURSOR_CONFIG_COMMIT BIT(3) +#define VSDC_CURSOR_CONFIG_SIZE_MASK GENMASK(7, 5) +#define VSDC_CURSOR_CONFIG_SIZE_32 (0x0 << 5) +#define VSDC_CURSOR_CONFIG_SIZE_64 (0x1 << 5) +#define VSDC_CURSOR_CONFIG_SIZE_128 (0x2 << 5) +#define VSDC_CURSOR_CONFIG_SIZE_256 (0x3 << 5) +#define VSDC_CURSOR_CONFIG_Y_OFF_MASK GENMASK(12, 8) +#define VSDC_CURSOR_CONFIG_Y_OFF(v) ((v) << 8) +#define VSDC_CURSOR_CONFIG_X_OFF_MASK GENMASK(20, 16) +#define VSDC_CURSOR_CONFIG_X_OFF(v) ((v) << 16) + +#define VSDC_CURSOR_ADDRESS(n) (0x146C + 0x1080 * (n)) + +#define VSDC_CURSOR_LOCATION(n) (0x1470 + 0x1080 * (n)) +#define VSDC_CURSOR_LOCATION_X_MASK GENMASK(14, 0) +#define VSDC_CURSOR_LOCATION_X(v) ((v) << 0) +#define VSDC_CURSOR_LOCATION_Y_MASK GENMASK(30, 16) +#define VSDC_CURSOR_LOCATION_Y(v) ((v) << 16) + +#define VSDC_CURSOR_BACKGROUND(n) (0x1474 + 0x1080 * (n)) +#define VSDC_CURSOR_BACKGRUOND_DEFAULT 0x00FFFFFF + +#define VSDC_CURSOR_FOREGROUND(n) (0x1478 + 0x1080 * (n)) +#define VSDC_CURSOR_FOREGRUOND_DEFAULT 0x00AAAAAA + +#endif /* _VS_CURSOR_PLANE_REGS_H_ */ diff --git a/drivers/gpu/drm/verisilicon/vs_plane.h b/drivers/gpu/drm/veris= ilicon/vs_plane.h index 41875ea3d66a5..60b5b3a1bc22a 100644 --- a/drivers/gpu/drm/verisilicon/vs_plane.h +++ b/drivers/gpu/drm/verisilicon/vs_plane.h @@ -68,5 +68,6 @@ dma_addr_t vs_fb_get_dma_addr(struct drm_framebuffer *fb, const struct drm_rect *src_rect); =20 struct drm_plane *vs_primary_plane_init(struct drm_device *dev, struct vs_= dc *dc); +struct drm_plane *vs_cursor_plane_init(struct drm_device *dev, struct vs_d= c *dc); =20 #endif /* _VS_PLANE_H_ */ diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h b/drivers/= gpu/drm/verisilicon/vs_primary_plane_regs.h index cbb125c46b390..61a48c2faa1b2 100644 --- a/drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h +++ b/drivers/gpu/drm/verisilicon/vs_primary_plane_regs.h @@ -1,9 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2025 Icenowy Zheng + * Copyright (C) 2026 Institute of Software, Chinese Academy of Sciences (= ISCAS) * * Based on vs_dc_hw.h, which is: * Copyright (C) 2023 VeriSilicon Holdings Co., Ltd. + * + * Authors: + * Icenowy Zheng */ =20 #ifndef _VS_PRIMARY_PLANE_REGS_H_ --=20 2.52.0