From: Sascha Hauer <s.hauer@pengutronix.de>
To: Andy Yan <andy.yan@rock-chips.com>
Cc: Andy Yan <andyshrk@163.com>,
heiko@sntech.de, hjc@rock-chips.com,
dri-devel@lists.freedesktop.org,
linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org,
krzysztof.kozlowski+dt@linaro.org, robh+dt@kernel.org,
devicetree@vger.kernel.org, sebastian.reichel@collabora.com,
kever.yang@rock-chips.com, chris.obbard@collabora.com
Subject: Re: [PATCH v2 11/12] drm/rockchip: vop2: Add debugfs support
Date: Wed, 29 Nov 2023 09:52:29 +0100 [thread overview]
Message-ID: <20231129085229.GC963049@pengutronix.de> (raw)
In-Reply-To: <ea24a638-d10f-4f58-9992-1c80bafdd6d4@rock-chips.com>
On Mon, Nov 27, 2023 at 06:56:34PM +0800, Andy Yan wrote:
> Hi Sascha:
>
> thanks for you review.
>
> On 11/27/23 18:13, Sascha Hauer wrote:
>
> On Wed, Nov 22, 2023 at 08:56:01PM +0800, Andy Yan wrote:
>
> From: Andy Yan [1]<andy.yan@rock-chips.com>
>
> /sys/kernel/debug/dri/vop2/summary: dump vop display state
> /sys/kernel/debug/dri/vop2/regs: dump whole vop registers
> /sys/kernel/debug/dri/vop2/active_regs: only dump the registers of
> activated modules
>
> Signed-off-by: Andy Yan [2]<andy.yan@rock-chips.com>
> ---
>
> (no changes since v1)
>
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 399 +++++++++++++++++++
> 1 file changed, 399 insertions(+)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index 9eecbe1f71f9..4a2342209c15 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -27,6 +27,7 @@
> #include <drm/drm_debugfs.h>
> #include <drm/drm_flip_work.h>
> #include <drm/drm_framebuffer.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> #include <drm/drm_probe_helper.h>
> #include <drm/drm_vblank.h>
>
> @@ -187,6 +188,7 @@ struct vop2 {
> */
> u32 registered_num_wins;
>
> + struct resource *res;
> void __iomem *regs;
> struct regmap *map;
>
> @@ -228,6 +230,44 @@ struct vop2 {
> #define vop2_output_if_is_lvds(x) (x == ROCKCHIP_VOP2_EP_LVDS0 || x == ROCKCHIP_VOP2_EP_LVDS1)
> #define vop2_output_if_is_dpi(x) (x == ROCKCHIP_VOP2_EP_RGB0)
>
> +struct vop2_regs_dump {
> + const char *name;
> + u32 base;
> + u32 en_reg;
> + u32 en_val;
> + u32 en_mask;
> +};
> +
> +/*
> + * bus-format types.
> + */
> +struct drm_bus_format_enum_list {
> + int type;
> + const char *name;
> +};
> +
> +static const struct drm_bus_format_enum_list drm_bus_format_enum_list[] = {
> + { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
> + { MEDIA_BUS_FMT_RGB565_1X16, "RGB565_1X16" },
> + { MEDIA_BUS_FMT_RGB666_1X18, "RGB666_1X18" },
> + { MEDIA_BUS_FMT_RGB666_1X24_CPADHI, "RGB666_1X24_CPADHI" },
> + { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, "RGB666_1X7X3_SPWG" },
> + { MEDIA_BUS_FMT_YUV8_1X24, "YUV8_1X24" },
> + { MEDIA_BUS_FMT_UYYVYY8_0_5X24, "UYYVYY8_0_5X24" },
> + { MEDIA_BUS_FMT_YUV10_1X30, "YUV10_1X30" },
> + { MEDIA_BUS_FMT_UYYVYY10_0_5X30, "UYYVYY10_0_5X30" },
> + { MEDIA_BUS_FMT_RGB888_3X8, "RGB888_3X8" },
> + { MEDIA_BUS_FMT_RGB888_1X24, "RGB888_1X24" },
> + { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, "RGB888_1X7X4_SPWG" },
> + { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, "RGB888_1X7X4_JEIDA" },
> + { MEDIA_BUS_FMT_UYVY8_2X8, "UYVY8_2X8" },
> + { MEDIA_BUS_FMT_YUYV8_1X16, "YUYV8_1X16" },
> + { MEDIA_BUS_FMT_UYVY8_1X16, "UYVY8_1X16" },
> + { MEDIA_BUS_FMT_RGB101010_1X30, "RGB101010_1X30" },
> + { MEDIA_BUS_FMT_YUYV10_1X20, "YUYV10_1X20" },
> +};
> +static DRM_ENUM_NAME_FN(drm_get_bus_format_name, drm_bus_format_enum_list)
> +
> static const struct regmap_config vop2_regmap_config;
>
> static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
> @@ -2487,6 +2527,363 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
> .atomic_disable = vop2_crtc_atomic_disable,
> };
>
> +static void vop2_dump_connector_on_crtc(struct drm_crtc *crtc, struct seq_file *s)
> +{
> + struct drm_connector_list_iter conn_iter;
> + struct drm_connector *connector;
> +
> + drm_connector_list_iter_begin(crtc->dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + if (crtc->state->connector_mask & drm_connector_mask(connector))
> + seq_printf(s, " Connector: %s\n", connector->name);
> +
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +}
> +
> +static int vop2_plane_state_dump(struct seq_file *s, struct drm_plane *plane)
> +{
> + struct vop2_win *win = to_vop2_win(plane);
> + struct drm_plane_state *pstate = plane->state;
> + struct drm_rect *src, *dst;
> + struct drm_framebuffer *fb;
> + struct drm_gem_object *obj;
> + struct rockchip_gem_object *rk_obj;
> + bool xmirror;
> + bool ymirror;
> + bool rotate_270;
> + bool rotate_90;
> + dma_addr_t fb_addr;
> + int i;
> +
> + seq_printf(s, " %s: %s\n", win->data->name, pstate->crtc ? "ACTIVE" : "DISABLED");
> + if (!pstate || !pstate->fb)
> + return 0;
> +
> + fb = pstate->fb;
> + src = &pstate->src;
> + dst = &pstate->dst;
> + xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
> + ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
> + rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
> + rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
> +
> + seq_printf(s, "\twin_id: %d\n", win->win_id);
> +
> + seq_printf(s, "\tformat: %p4cc%s glb_alpha[0x%x]\n",
> + &fb->format->format,
> + drm_is_afbc(fb->modifier) ? "[AFBC]" : "",
> + pstate->alpha >> 8);
> + seq_printf(s, "\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n",
> + xmirror, ymirror, rotate_90, rotate_270);
> + seq_printf(s, "\tzpos: %d\n", pstate->normalized_zpos);
> + seq_printf(s, "\tsrc: pos[%d, %d] rect[%d x %d]\n", src->x1 >> 16,
> + src->y1 >> 16, drm_rect_width(src) >> 16,
> + drm_rect_height(src) >> 16);
> + seq_printf(s, "\tdst: pos[%d, %d] rect[%d x %d]\n", dst->x1, dst->y1,
> + drm_rect_width(dst), drm_rect_height(dst));
> +
> + for (i = 0; i < fb->format->num_planes; i++) {
> + obj = fb->obj[0];
> + rk_obj = to_rockchip_obj(obj);
> + fb_addr = rk_obj->dma_addr + fb->offsets[0];
> +
> + seq_printf(s, "\tbuf[%d]: addr: %pad pitch: %d offset: %d\n",
> + i, &fb_addr, fb->pitches[i], fb->offsets[i]);
> + }
> +
> + return 0;
> +}
> +
> +static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
> +{
> + struct vop2_video_port *vp = to_vop2_video_port(crtc);
> + struct drm_crtc_state *cstate = crtc->state;
> + struct rockchip_crtc_state *vcstate;
> + struct drm_display_mode *mode;
> + struct drm_plane *plane;
> + bool interlaced;
> +
> + seq_printf(s, "Video Port%d: %s\n", vp->id, !cstate ?
> + "DISABLED" : cstate->active ? "ACTIVE" : "DISABLED");
> +
> + if (!cstate || !cstate->active)
> + return 0;
> +
> + mode = &crtc->state->adjusted_mode;
> + vcstate = to_rockchip_crtc_state(cstate);
> + interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
> +
> + vop2_dump_connector_on_crtc(crtc, s);
> + seq_printf(s, "\tbus_format[%x]: %s\n", vcstate->bus_format,
> + drm_get_bus_format_name(vcstate->bus_format));
> + seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
> + seq_printf(s, " color_space[%d]\n", vcstate->color_space);
> + seq_printf(s, " Display mode: %dx%d%s%d\n",
> + mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
> + drm_mode_vrefresh(mode));
> + seq_printf(s, "\tclk[%d] real_clk[%d] type[%x] flag[%x]\n",
> + mode->clock, mode->crtc_clock, mode->type, mode->flags);
> + seq_printf(s, "\tH: %d %d %d %d\n", mode->hdisplay, mode->hsync_start,
> + mode->hsync_end, mode->htotal);
> + seq_printf(s, "\tV: %d %d %d %d\n", mode->vdisplay, mode->vsync_start,
> + mode->vsync_end, mode->vtotal);
> +
> + drm_atomic_crtc_for_each_plane(plane, crtc) {
> + vop2_plane_state_dump(s, plane);
> + }
> +
> + return 0;
> +}
> +
> +static int vop2_summary_show(struct seq_file *s, void *data)
> +{
> + struct drm_info_node *node = s->private;
> + struct drm_minor *minor = node->minor;
> + struct drm_device *drm_dev = minor->dev;
> + struct drm_crtc *crtc;
> +
> + drm_modeset_lock_all(drm_dev);
> + drm_for_each_crtc(crtc, drm_dev) {
> + vop2_crtc_state_dump(crtc, s);
> + }
> + drm_modeset_unlock_all(drm_dev);
> +
> + return 0;
> +}
> +
> +static void vop2_regs_print(struct vop2 *vop2, struct seq_file *s, struct vop2_regs_dump *dump)
> +{
> + resource_size_t start;
> + const int reg_num = 0x110 / 4;
>
> If I'm not mistaken this prints a register space of 0x110 bytes.
> Shouldn't it be 0x100 bytes instead?
>
> Also, are all these register spaces really have the same size? Does it
> make sense to add the size to struct vop2_regs_dump?
>
> In fact, most used registers of the most blocks are not more than 100, but
> for Cluster windows,
>
> there is a CLUSTER_CTRL register sting at 0x100.
>
> I think i should add the size to struct vop2_regs_dump.
>
>
> + u32 val;
> + int i;
> +
> + if (dump->en_mask) {
> + val = vop2_readl(vop2, dump->base + dump->en_reg);
> + if ((val & dump->en_mask) != dump->en_val)
> + return;
> + }
> + seq_printf(s, "\n%s:\n", dump->name);
> +
> + start = vop2->res->start + dump->base;
> + for (i = 0; i < reg_num;) {
> + seq_printf(s, "%08x: %08x %08x %08x %08x\n", (u32)start + i * 4,
> + vop2_readl(vop2, dump->base + (4 * i)),
> + vop2_readl(vop2, dump->base + (4 * (i + 1))),
> + vop2_readl(vop2, dump->base + (4 * (i + 2))),
> + vop2_readl(vop2, dump->base + (4 * (i + 3))));
> + i += 4;
> + }
> +
> +}
> +
> +static int vop2_regs_show(struct seq_file *s, void *arg)
> +{
> + struct drm_info_node *node = s->private;
> + struct vop2 *vop2 = (struct vop2 *)node->info_ent->data;
> + struct drm_minor *minor = node->minor;
> + struct drm_device *drm_dev = minor->dev;
> +
> + struct vop2_regs_dump dump;
> +
> + drm_modeset_lock_all(drm_dev);
> +
> + if (vop2->enable_count) {
> + dump.en_mask = 0;
> +
> + dump.name = "SYS";
> + dump.base = RK3568_REG_CFG_DONE;
> + vop2_regs_print(vop2, s, &dump);
>
> Can you create a statically initialized array of struct vop2_regs_dump
> and iterate over it?
> You would need an additional present_in_soc_xy flag in struct
> vop2_regs_dump, but other than that I don't see a problem and the result
> might look better.
>
> For the windows it might also be an option to iterate over
> vop2->data->win instead. This array already contains the register base
> addresses and window names.
>
> In fact, we have a dump_regs arrar in vop2_data per soc in our bsp
> kernel[0],
>
> do you like something like that?
>
> [0]
> [3]https://github.com/armbian/linux-rockchip/blob/rk-5.10-rkr6/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c#L3684
This looks good from a first glance. I would suggest using C99
initializers though.
> Not sure if we really need an additional debugfs entry to print only the
> active entities, but if we do then we could avoid a bit of code
> duplication by adding creating a common register dump function called
> from vop2_regs_show() and vop2_active_regs_show() which takes an
> additional ignore_disabled argument.
>
> As the whole vop2 registers block is very large, so some times only dump
>
> active modules make we dig bugs easier.
>
> It seems that if we "initialized array of struct vop2_regs_dump" as you
> said befor, we can avoid
>
> some duplication code here?
Yes.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
next prev parent reply other threads:[~2023-11-29 8:52 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-22 12:53 [PATCH v2 00/12] Add VOP2 support on rk3588 Andy Yan
2023-11-22 12:53 ` [PATCH v2 01/12] drm/rockchip: move output interface related definition to rockchip_drm_drv.h Andy Yan
2023-11-27 14:03 ` Sascha Hauer
2023-11-22 12:54 ` [PATCH v2 02/12] Revert "drm/rockchip: vop2: Use regcache_sync() to fix suspend/resume" Andy Yan
2023-11-27 14:04 ` Sascha Hauer
2023-11-22 12:54 ` [PATCH v2 03/12] drm/rockchip: vop2: set half_block_en bit in all mode Andy Yan
2023-11-27 14:04 ` Sascha Hauer
2023-11-27 15:01 ` Heiko Stübner
2023-11-22 12:54 ` [PATCH v2 04/12] drm/rockchip: vop2: clear afbc en and transform bit for cluster window at linear mode Andy Yan
2023-11-27 14:04 ` Sascha Hauer
2023-11-27 15:02 ` Heiko Stübner
2023-11-28 8:03 ` Andy Yan
2023-11-28 8:30 ` Heiko Stübner
2023-11-28 9:44 ` Andy Yan
2023-11-22 12:54 ` [PATCH v2 05/12] drm/rockchip: vop2: Set YUV/RGB overlay mode Andy Yan
2023-11-27 14:16 ` Sascha Hauer
2023-11-29 6:52 ` Andy Yan
2023-11-22 12:54 ` [PATCH v2 06/12] drm/rockchip: vop2: rename grf to sys_grf Andy Yan
2023-11-27 14:17 ` Sascha Hauer
2023-11-22 12:55 ` [PATCH v2 07/12] dt-bindings: soc: rockchip: add rk3588 vop/vo syscon Andy Yan
2023-11-22 12:55 ` [PATCH v2 08/12] dt-bindings: display: vop2: Add rk3588 support Andy Yan
2023-11-22 19:07 ` Krzysztof Kozlowski
2023-11-30 12:32 ` Andy Yan
2023-11-22 12:55 ` [PATCH v2 09/12] dt-bindings: soc: vop2: Add more endpoint definition Andy Yan
2023-11-22 19:08 ` Krzysztof Kozlowski
2023-11-22 12:55 ` [PATCH v2 10/12] drm/rockchip: vop2: Add support for rk3588 Andy Yan
2023-11-27 11:19 ` Sascha Hauer
2023-11-29 8:28 ` Andy Yan
2023-11-27 15:29 ` Heiko Stübner
2023-11-28 9:32 ` Andy Yan
2023-11-28 9:44 ` Heiko Stübner
2023-11-28 10:11 ` Andy Yan
2023-11-22 12:56 ` [PATCH v2 11/12] drm/rockchip: vop2: Add debugfs support Andy Yan
2023-11-27 10:13 ` Sascha Hauer
[not found] ` <ea24a638-d10f-4f58-9992-1c80bafdd6d4@rock-chips.com>
2023-11-29 8:52 ` Sascha Hauer [this message]
2023-11-29 11:01 ` Andy Yan
2023-11-29 12:59 ` Sascha Hauer
2023-11-30 1:15 ` Andy Yan
2023-11-22 12:56 ` [PATCH v2 12/12] arm64: dts: rockchip: Add vop on rk3588 Andy Yan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231129085229.GC963049@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=andy.yan@rock-chips.com \
--cc=andyshrk@163.com \
--cc=chris.obbard@collabora.com \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=heiko@sntech.de \
--cc=hjc@rock-chips.com \
--cc=kever.yang@rock-chips.com \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=robh+dt@kernel.org \
--cc=sebastian.reichel@collabora.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).