Module Name:    src
Committed By:   riastradh
Date:           Sun Dec 19 12:43:37 UTC 2021

Modified Files:
        src/sys/arch/arm/rockchip: rk_anxdp.c rk_drm.c rk_vop.c
        src/sys/dev/ic: anx_dp.c anx_dp.h
        src/sys/external/bsd/drm2/drm: drm_module.c

Log Message:
rkdrm: Convert to atomic modesetting, as needed for bridges.

Author: Jared McNeill <jmcne...@invisible.ca>
Committer: Taylor R Campbell <riastr...@netbsd.org>


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/rockchip/rk_anxdp.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/arm/rockchip/rk_drm.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/arm/rockchip/rk_vop.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/ic/anx_dp.c src/sys/dev/ic/anx_dp.h
cvs rdiff -u -r1.27 -r1.28 src/sys/external/bsd/drm2/drm/drm_module.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/rockchip/rk_anxdp.c
diff -u src/sys/arch/arm/rockchip/rk_anxdp.c:1.5 src/sys/arch/arm/rockchip/rk_anxdp.c:1.6
--- src/sys/arch/arm/rockchip/rk_anxdp.c:1.5	Sun Dec 19 11:00:46 2021
+++ src/sys/arch/arm/rockchip/rk_anxdp.c	Sun Dec 19 12:43:37 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_anxdp.c,v 1.5 2021/12/19 11:00:46 riastradh Exp $ */
+/* $NetBSD: rk_anxdp.c,v 1.6 2021/12/19 12:43:37 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2019 Jonathan A. Kollasch <jakll...@kollasch.net>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_anxdp.c,v 1.5 2021/12/19 11:00:46 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_anxdp.c,v 1.6 2021/12/19 12:43:37 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -117,19 +117,6 @@ rk_anxdp_encoder_prepare(struct drm_enco
 	rk_anxdp_select_input(sc, crtc_index);
 }
 
-static void
-rk_anxdp_encoder_commit(struct drm_encoder *encoder)
-{
-}
-
-static void
-rk_anxdp_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct rk_anxdp_softc * const sc = to_rk_anxdp_encoder(encoder);
-
-	anxdp_dpms(&sc->sc_base, mode);
-}
-
 static const struct drm_encoder_funcs rk_anxdp_encoder_funcs = {
 	.destroy = drm_encoder_cleanup,
 };
@@ -140,8 +127,6 @@ static const struct drm_encoder_helper_f
 	.mode_set = rk_anxdp_encoder_mode_set,
 	.enable = rk_anxdp_encoder_enable,
 	.disable = rk_anxdp_encoder_disable,
-	.commit = rk_anxdp_encoder_commit,
-	.dpms = rk_anxdp_encoder_dpms,
 };
 
 static int

Index: src/sys/arch/arm/rockchip/rk_drm.c
diff -u src/sys/arch/arm/rockchip/rk_drm.c:1.15 src/sys/arch/arm/rockchip/rk_drm.c:1.16
--- src/sys/arch/arm/rockchip/rk_drm.c:1.15	Sun Dec 19 12:43:29 2021
+++ src/sys/arch/arm/rockchip/rk_drm.c	Sun Dec 19 12:43:37 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_drm.c,v 1.15 2021/12/19 12:43:29 riastradh Exp $ */
+/* $NetBSD: rk_drm.c,v 1.16 2021/12/19 12:43:37 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_drm.c,v 1.15 2021/12/19 12:43:29 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_drm.c,v 1.16 2021/12/19 12:43:37 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -46,8 +46,10 @@ __KERNEL_RCSID(0, "$NetBSD: rk_drm.c,v 1
 
 #include <arm/rockchip/rk_drm.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_auth.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/drm_damage_helper.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_fourcc.h>
@@ -85,7 +87,7 @@ static void	rk_drm_unload(struct drm_dev
 static void	rk_drm_task_work(struct work *, void *);
 
 static struct drm_driver rk_drm_driver = {
-	.driver_features = DRIVER_MODESET | DRIVER_GEM,
+	.driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM,
 	.dev_priv_size = 0,
 	.load = rk_drm_load,
 	.unload = rk_drm_unload,
@@ -252,6 +254,7 @@ rk_drm_fb_destroy(struct drm_framebuffer
 static const struct drm_framebuffer_funcs rk_drm_framebuffer_funcs = {
 	.create_handle = rk_drm_fb_create_handle,
 	.destroy = rk_drm_fb_destroy,
+	.dirty = drm_atomic_helper_dirtyfb,
 };
 
 static struct drm_framebuffer *
@@ -289,6 +292,12 @@ dealloc:
 
 static struct drm_mode_config_funcs rk_drm_mode_config_funcs = {
 	.fb_create = rk_drm_fb_create,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+};
+
+static struct drm_mode_config_helper_funcs rk_drm_mode_config_helper_funcs = {
+	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
 static int
@@ -328,7 +337,6 @@ rk_drm_fb_probe(struct drm_fb_helper *he
 	fb->offsets[0] = 0;
 	fb->width = width;
 	fb->height = height;
-	fb->dev = ddev;
 	fb->modifier = 0;
 	fb->flags = 0;
 #ifdef __ARM_BIG_ENDIAN
@@ -336,6 +344,7 @@ rk_drm_fb_probe(struct drm_fb_helper *he
 #else
 	fb->format = drm_format_info(DRM_FORMAT_XRGB8888);
 #endif
+	fb->dev = ddev;
 
 	error = drm_framebuffer_init(ddev, fb, &rk_drm_framebuffer_funcs);
 	if (error != 0) {
@@ -381,6 +390,7 @@ rk_drm_load(struct drm_device *ddev, uns
 	ddev->mode_config.max_width = RK_DRM_MAX_WIDTH;
 	ddev->mode_config.max_height = RK_DRM_MAX_HEIGHT;
 	ddev->mode_config.funcs = &rk_drm_mode_config_funcs;
+	ddev->mode_config.helper_private = &rk_drm_mode_config_helper_funcs;
 
 	num_crtc = 0;
 	data = fdtbus_get_prop(sc->sc_phandle, "ports", &datalen);
@@ -424,8 +434,6 @@ rk_drm_load(struct drm_device *ddev, uns
 
 	drm_fb_helper_single_add_all_connectors(&fbdev->helper);
 
-	drm_helper_disable_unused_functions(ddev);
-
 	drm_fb_helper_initial_config(&fbdev->helper, 32);
 
 	/* XXX */

Index: src/sys/arch/arm/rockchip/rk_vop.c
diff -u src/sys/arch/arm/rockchip/rk_vop.c:1.12 src/sys/arch/arm/rockchip/rk_vop.c:1.13
--- src/sys/arch/arm/rockchip/rk_vop.c:1.12	Sun Dec 19 11:01:10 2021
+++ src/sys/arch/arm/rockchip/rk_vop.c	Sun Dec 19 12:43:37 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_vop.c,v 1.12 2021/12/19 11:01:10 riastradh Exp $ */
+/* $NetBSD: rk_vop.c,v 1.13 2021/12/19 12:43:37 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_vop.c,v 1.12 2021/12/19 11:01:10 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_vop.c,v 1.13 2021/12/19 12:43:37 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -43,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: rk_vop.c,v 1
 
 #include <arm/rockchip/rk_drm.h>
 
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_drv.h>
@@ -129,6 +131,11 @@ struct rk_vop_crtc {
 	struct rk_vop_softc	*sc;
 };
 
+struct rk_vop_plane {
+	struct drm_plane	base;
+	struct rk_vop_softc	*sc;
+};
+
 struct rk_vop_softc {
 	device_t		sc_dev;
 	bus_space_tag_t		sc_bst;
@@ -137,6 +144,7 @@ struct rk_vop_softc {
 
 	struct clk		*sc_dclk;
 
+	struct rk_vop_plane	sc_plane;
 	struct rk_vop_crtc	sc_crtc;
 
 	struct fdt_device_ports	sc_ports;
@@ -145,6 +153,7 @@ struct rk_vop_softc {
 };
 
 #define	to_rk_vop_crtc(x)	container_of(x, struct rk_vop_crtc, base)
+#define	to_rk_vop_plane(x)	container_of(x, struct rk_vop_plane, base)
 
 #define	RD4(sc, reg)				\
 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
@@ -159,6 +168,16 @@ struct rk_vop_config {
 						enum vop_ep_type, uint32_t);
 };
 
+static const uint32_t rk_vop_layer_formats[] = {
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XRGB8888,
+};
+
+static const uint64_t rk_vop_layer_modifiers[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID
+};
+
 #define	RK3399_VOP_MIPI_POL	__BITS(31,28)
 #define	RK3399_VOP_EDP_POL	__BITS(27,24)
 #define	RK3399_VOP_HDMI_POL	__BITS(23,20)
@@ -229,42 +248,132 @@ static const struct device_compatible_en
 };
 
 static int
-rk_vop_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb,
-    int x, int y, int atomic)
+rk_vop_plane_atomic_check(struct drm_plane *plane,
+    struct drm_plane_state *state)
 {
-	struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
-	struct rk_vop_softc * const sc = mixer_crtc->sc;
-	struct rk_drm_framebuffer *sfb = atomic?
-	    to_rk_drm_framebuffer(fb) :
-	    to_rk_drm_framebuffer(crtc->primary->fb);
+	struct drm_crtc_state *crtc_state;
+
+	if (state->crtc == NULL)
+		return 0;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	return drm_atomic_helper_check_plane_state(state, crtc_state,
+	    DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING,
+	    false, true);
+}
+
+static void
+rk_vop_plane_atomic_update(struct drm_plane *plane,
+    struct drm_plane_state *old_state)
+{
+	struct rk_vop_plane *vop_plane = to_rk_vop_plane(plane);
+	struct rk_vop_softc * const sc = vop_plane->sc;
+	struct rk_drm_framebuffer *sfb =
+	    to_rk_drm_framebuffer(plane->state->fb);
+	struct drm_display_mode *mode = &plane->state->crtc->mode;
+	struct drm_rect *src = &plane->state->src;
+	struct drm_rect *dst = &plane->state->dst;
+	uint32_t act_width, act_height, dsp_width, dsp_height;
+	uint32_t htotal, hsync_start;
+	uint32_t vtotal, vsync_start;
+	uint32_t lb_mode;
+	uint32_t block_h, block_w, x, y, block_start_y, num_hblocks;
+	uint64_t paddr;
+	uint32_t val;
+
+	act_width = drm_rect_width(src) >> 16;
+	act_height = drm_rect_height(src) >> 16;
+	val = __SHIFTIN(act_width - 1, WIN0_ACT_WIDTH) |
+	      __SHIFTIN(act_height - 1, WIN0_ACT_HEIGHT);
+	WR4(sc, VOP_WIN0_ACT_INFO, val);
+
+	dsp_width = drm_rect_width(dst);
+	dsp_height = drm_rect_height(dst);
+	val = __SHIFTIN(dsp_width - 1, WIN0_DSP_WIDTH) |
+	      __SHIFTIN(dsp_height - 1, WIN0_DSP_HEIGHT);
+	WR4(sc, VOP_WIN0_DSP_INFO, val);
+
+	htotal = mode->htotal;
+	hsync_start = mode->hsync_start;
+	vtotal = mode->vtotal;
+	vsync_start = mode->vsync_start;
+	val = __SHIFTIN(dst->x1 + htotal - hsync_start, WIN0_DSP_XST) |
+	      __SHIFTIN(dst->y1 + vtotal - vsync_start, WIN0_DSP_YST);
+	WR4(sc, VOP_WIN0_DSP_ST, val);
+
+	WR4(sc, VOP_WIN0_COLOR_KEY, 0);
+
+	if (act_width > 2560)
+		lb_mode = WIN0_LB_MODE_RGB_3840X2;
+	else if (act_width > 1920)
+		lb_mode = WIN0_LB_MODE_RGB_2560X4;
+	else if (act_width > 1280)
+		lb_mode = WIN0_LB_MODE_RGB_1920X5;
+	else
+		lb_mode = WIN0_LB_MODE_RGB_1280X8;
+	val = __SHIFTIN(lb_mode, WIN0_LB_MODE) |
+	      __SHIFTIN(WIN0_DATA_FMT_ARGB888, WIN0_DATA_FMT) |
+	      WIN0_EN;
+	WR4(sc, VOP_WIN0_CTRL, val);
 
-	uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr;
+	paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr;
+	paddr += sfb->base.offsets[0];
 
+	block_h = drm_format_info_block_height(sfb->base.format, 0);
+	block_w = drm_format_info_block_width(sfb->base.format, 0);
+	x = plane->state->src_x >> 16;
+	y = plane->state->src_y >> 16;
+	block_start_y = (y / block_h) * block_h;
+	num_hblocks = x / block_w;
 
-	paddr += y * sfb->base.pitches[0];
-	paddr += x * sfb->base.format->cpp[0];
+	paddr += block_start_y * sfb->base.pitches[0];
+	paddr += sfb->base.format->char_per_block[0] * num_hblocks;
+
+	DRM_DEBUG_KMS("[PLANE:%s] fb=%p paddr=0x%lx\n", plane->name, sfb, paddr);
 
 	KASSERT((paddr & ~0xffffffff) == 0);
 
-	const uint32_t vir = __SHIFTIN(sfb->base.pitches[0] / 4,
-	    WIN0_VIR_STRIDE);
-	WR4(sc, VOP_WIN0_VIR, vir);
+	val = __SHIFTIN(sfb->base.pitches[0] / 4, WIN0_VIR_STRIDE);
+	WR4(sc, VOP_WIN0_VIR, val);
 
 	/* Framebuffer start address */
 	WR4(sc, VOP_WIN0_YRGB_MST, (uint32_t)paddr);
-
-	return 0;
 }
 
 static void
-rk_vop_destroy(struct drm_crtc *crtc)
+rk_vop_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *state)
 {
-	drm_crtc_cleanup(crtc);
+	DRM_DEBUG_KMS("[PLANE:%s] disable TODO\n", plane->name);
 }
 
-static const struct drm_crtc_funcs rk_vop_crtc_funcs = {
-	.set_config = drm_crtc_helper_set_config,
-	.destroy = rk_vop_destroy,
+static const struct drm_plane_helper_funcs rk_vop_plane_helper_funcs = {
+	.atomic_check = rk_vop_plane_atomic_check,
+	.atomic_update = rk_vop_plane_atomic_update,
+	.atomic_disable = rk_vop_plane_atomic_disable,
+#if 0
+	.prepare_fb = drm_gem_vram_plane_helper_prepare_fb,
+	.cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb,
+#endif
+};
+
+static bool
+rk_vop_format_mod_supported(struct drm_plane *plane, uint32_t format,
+    uint64_t modifier)
+{
+	return modifier == DRM_FORMAT_MOD_LINEAR;
+}
+
+static const struct drm_plane_funcs rk_vop_plane_funcs = {
+	.update_plane = drm_atomic_helper_update_plane,
+	.disable_plane = drm_atomic_helper_disable_plane,
+	.destroy = drm_plane_cleanup,
+	.reset = drm_atomic_helper_plane_reset,
+	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+	.format_mod_supported = rk_vop_format_mod_supported,
 };
 
 static void
@@ -293,27 +402,29 @@ rk_vop_dpms(struct drm_crtc *crtc, int m
 	WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
 }
 
-static bool
-rk_vop_mode_fixup(struct drm_crtc *crtc,
-    const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
+static int
+rk_vop_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
 {
-	return true;
+	bool enabled = state->plane_mask & drm_plane_mask(crtc->primary);
+
+	if (enabled != state->enable)
+		return -EINVAL;
+
+	return drm_atomic_add_affected_planes(state->state, crtc);
 }
 
-static int
-rk_vop_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
-    struct drm_display_mode *adjusted_mode, int x, int y,
-    struct drm_framebuffer *old_fb)
+static void
+rk_vop_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *state)
 {
 	struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
 	struct rk_vop_softc * const sc = mixer_crtc->sc;
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
 	uint32_t val;
-	u_int lb_mode;
-	int error;
 	u_int pol;
 	int connector_type = 0;
 	struct drm_connector *connector;
 	struct drm_connector_list_iter conn_iter;
+	int error;
 
 	const u_int hactive = adjusted_mode->hdisplay;
 	const u_int hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
@@ -326,39 +437,9 @@ rk_vop_mode_set(struct drm_crtc *crtc, s
 	const u_int vfront_porch = adjusted_mode->vsync_start - adjusted_mode->vdisplay;
 
 	error = clk_set_rate(sc->sc_dclk, adjusted_mode->clock * 1000);
-	if (error != 0)
+	if (error)
 		DRM_ERROR("couldn't set pixel clock: %d\n", error);
 
-	val = __SHIFTIN(hactive - 1, WIN0_ACT_WIDTH) |
-	      __SHIFTIN(vactive - 1, WIN0_ACT_HEIGHT);
-	WR4(sc, VOP_WIN0_ACT_INFO, val);
-
-	val = __SHIFTIN(hactive - 1, WIN0_DSP_WIDTH) |
-	      __SHIFTIN(vactive - 1, WIN0_DSP_HEIGHT);
-	WR4(sc, VOP_WIN0_DSP_INFO, val);
-
-	val = __SHIFTIN(hsync_len + hback_porch, WIN0_DSP_XST) |
-	      __SHIFTIN(vsync_len + vback_porch, WIN0_DSP_YST);
-	WR4(sc, VOP_WIN0_DSP_ST, val);
-
-	WR4(sc, VOP_WIN0_COLOR_KEY, 0);
-
-	if (adjusted_mode->hdisplay > 2560)
-		lb_mode = WIN0_LB_MODE_RGB_3840X2;
-	else if (adjusted_mode->hdisplay > 1920)
-		lb_mode = WIN0_LB_MODE_RGB_2560X4;
-	else if (adjusted_mode->hdisplay > 1280)
-		lb_mode = WIN0_LB_MODE_RGB_1920X5;
-	else
-		lb_mode = WIN0_LB_MODE_RGB_1280X8;
-
-	val = __SHIFTIN(lb_mode, WIN0_LB_MODE) |
-	      __SHIFTIN(WIN0_DATA_FMT_ARGB888, WIN0_DATA_FMT) |
-	      WIN0_EN;
-	WR4(sc, VOP_WIN0_CTRL, val);
-
-	rk_vop_mode_do_set_base(crtc, old_fb, x, y, 0);
-
 	pol = DSP_DCLK_POL;
 	if ((adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) != 0)
 		pol |= DSP_HSYNC_POL;
@@ -427,52 +508,10 @@ rk_vop_mode_set(struct drm_crtc *crtc, s
 	val = __SHIFTIN(vsync_len, DSP_VTOTAL) |
 	      __SHIFTIN(vsync_len + vback_porch + vactive + vfront_porch, DSP_VS_END);
 	WR4(sc, VOP_DSP_VTOTAL_VS_END, val);
-
-	return 0;
-}
-
-static int
-rk_vop_mode_set_base(struct drm_crtc *crtc, int x, int y,
-    struct drm_framebuffer *old_fb)
-{
-	struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
-	struct rk_vop_softc * const sc = mixer_crtc->sc;
-
-	rk_vop_mode_do_set_base(crtc, old_fb, x, y, 0);
-
-	/* Commit settings */
-	WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
-
-	return 0;
-}
-
-static int
-rk_vop_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
-    int x, int y, enum mode_set_atomic state)
-{
-	struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
-	struct rk_vop_softc * const sc = mixer_crtc->sc;
-
-	rk_vop_mode_do_set_base(crtc, fb, x, y, 1);
-
-	/* Commit settings */
-	WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
-
-	return 0;
 }
 
 static void
-rk_vop_disable(struct drm_crtc *crtc)
-{
-}
-
-static void
-rk_vop_prepare(struct drm_crtc *crtc)
-{
-}
-
-static void
-rk_vop_commit(struct drm_crtc *crtc)
+rk_vop_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *state)
 {
 	struct rk_vop_crtc *mixer_crtc = to_rk_vop_crtc(crtc);
 	struct rk_vop_softc * const sc = mixer_crtc->sc;
@@ -483,13 +522,18 @@ rk_vop_commit(struct drm_crtc *crtc)
 
 static const struct drm_crtc_helper_funcs rk_vop_crtc_helper_funcs = {
 	.dpms = rk_vop_dpms,
-	.mode_fixup = rk_vop_mode_fixup,
-	.mode_set = rk_vop_mode_set,
-	.mode_set_base = rk_vop_mode_set_base,
-	.mode_set_base_atomic = rk_vop_mode_set_base_atomic,
-	.disable = rk_vop_disable,
-	.prepare = rk_vop_prepare,
-	.commit = rk_vop_commit,
+	.atomic_check = rk_vop_atomic_check,
+	.atomic_enable = rk_vop_atomic_enable,
+	.atomic_flush = rk_vop_atomic_flush,
+};
+
+static const struct drm_crtc_funcs rk_vop_crtc_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.destroy = drm_crtc_cleanup,
+	.page_flip = drm_atomic_helper_page_flip,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
 static int
@@ -497,6 +541,7 @@ rk_vop_ep_activate(device_t dev, struct 
 {
 	struct rk_vop_softc * const sc = device_private(dev);
 	struct drm_device *ddev;
+	int error;
 
 	if (!activate)
 		return EINVAL;
@@ -507,10 +552,27 @@ rk_vop_ep_activate(device_t dev, struct 
 		return ENXIO;
 	}
 
+	if (sc->sc_plane.sc == NULL) {
+		sc->sc_plane.sc = sc;
+
+		error = drm_universal_plane_init(ddev, &sc->sc_plane.base, 0x3,
+		    &rk_vop_plane_funcs,
+		    rk_vop_layer_formats, __arraycount(rk_vop_layer_formats),
+		    rk_vop_layer_modifiers,
+		    DRM_PLANE_TYPE_PRIMARY,
+		    NULL);
+		if (error) {
+			DRM_ERROR("couldn't initialize plane: %d\n", error);
+			return ENXIO;
+		}
+		drm_plane_helper_add(&sc->sc_plane.base, &rk_vop_plane_helper_funcs);
+	}
+
 	if (sc->sc_crtc.sc == NULL) {
 		sc->sc_crtc.sc = sc;
 
-		drm_crtc_init(ddev, &sc->sc_crtc.base, &rk_vop_crtc_funcs);
+		drm_crtc_init_with_planes(ddev, &sc->sc_crtc.base,
+		    &sc->sc_plane.base, NULL, &rk_vop_crtc_funcs, NULL);
 		drm_crtc_helper_add(&sc->sc_crtc.base, &rk_vop_crtc_helper_funcs);
 
 		aprint_debug_dev(dev, "using CRTC %d for %s\n",

Index: src/sys/dev/ic/anx_dp.c
diff -u src/sys/dev/ic/anx_dp.c:1.4 src/sys/dev/ic/anx_dp.c:1.5
--- src/sys/dev/ic/anx_dp.c:1.4	Sun Dec 19 11:01:11 2021
+++ src/sys/dev/ic/anx_dp.c	Sun Dec 19 12:43:37 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: anx_dp.c,v 1.4 2021/12/19 11:01:11 riastradh Exp $ */
+/* $NetBSD: anx_dp.c,v 1.5 2021/12/19 12:43:37 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2019 Jonathan A. Kollasch <jakll...@kollasch.net>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: anx_dp.c,v 1.4 2021/12/19 11:01:11 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: anx_dp.c,v 1.5 2021/12/19 12:43:37 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: anx_dp.c,v 1
 #include <dev/audio/audio_dai.h>
 #endif
 
+#include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_dp_helper.h>
@@ -252,6 +253,9 @@ static const struct drm_connector_funcs 
 	.detect = anxdp_connector_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = anxdp_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static void
@@ -308,7 +312,7 @@ anxdp_init_aux(struct anxdp_softc * cons
 
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_DP_INT_STA,
 	    RPLY_RECEIV | AUX_ERR);
-	
+
 	pd = bus_space_read_4(sc->sc_bst, sc->sc_bsh, pd_reg);
 	pd |= pd_mask;
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, pd_reg, pd);
@@ -367,8 +371,17 @@ anxdp_connector_get_modes(struct drm_con
 	return error;
 }
 
+static struct drm_encoder *
+anxdp_connector_best_encoder(struct drm_connector *connector)
+{
+	struct anxdp_connector *anxdp_connector = to_anxdp_connector(connector);
+
+	return anxdp_connector->encoder;
+}
+
 static const struct drm_connector_helper_funcs anxdp_connector_helper_funcs = {
 	.get_modes = anxdp_connector_get_modes,
+	.best_encoder = anxdp_connector_best_encoder,
 };
 
 static int
@@ -391,7 +404,7 @@ anxdp_bridge_attach(struct drm_bridge *b
 	drm_connector_helper_add(connector, &anxdp_connector_helper_funcs);
 
 	error = drm_connector_attach_encoder(connector, bridge->encoder);
-	if (error != 0)
+	if (error)
 		return error;
 
 	return drm_connector_register(connector);
@@ -416,17 +429,21 @@ anxdp_link_start(struct anxdp_softc * co
 	uint8_t training[4];
 	uint8_t bw[2];
 	uint32_t val;
+	int ret;
 
-	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_LINK_BW_SET, drm_dp_link_rate_to_bw_code(link->rate));
-	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_LANE_COUNT_SET, link->num_lanes);
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_LINK_BW_SET,
+	    drm_dp_link_rate_to_bw_code(link->rate));
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_LANE_COUNT_SET,
+	    link->num_lanes);
 
 	bw[0] = drm_dp_link_rate_to_bw_code(link->rate);
 	bw[1] = link->num_lanes;
 	if (link->enhanced_framing)
 		bw[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
-	if (drm_dp_dpcd_write(&sc->sc_dpaux, DP_LINK_BW_SET, bw, sizeof(bw)) < 0)
+	ret = drm_dp_dpcd_write(&sc->sc_dpaux, DP_LINK_BW_SET, bw, sizeof(bw));
+	if (ret < 0)
 		return;
-	
+
 	for (u_int i = 0; i < link->num_lanes; i++) {
 		val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
 		    ANXDP_LNx_LINK_TRAINING_CTL(i));
@@ -545,10 +562,13 @@ anxdp_train_link(struct anxdp_softc * co
 {
 	struct anxdp_link link;
 	uint8_t values[3], power;
+	int ret;
 
 	anxdp_macro_reset(sc);
 
-	if (drm_dp_dpcd_read(&sc->sc_dpaux, DP_DPCD_REV, values, sizeof(values)) < 0) {
+	ret = drm_dp_dpcd_read(&sc->sc_dpaux, DP_DPCD_REV, values,
+	    sizeof(values));
+	if (ret < 0) {
 		device_printf(sc->sc_dev, "link probe failed\n");
 		return;
 	}
@@ -638,20 +658,20 @@ anxdp_bringup(struct anxdp_softc * const
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PLL_FILTER_CTL_1,
 	    PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | TX_CUR1_2X | TX_CUR_16_MA);
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_TX_AMP_TUNING_CTL, 0);
-	
+
 	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_1);
 	val &= ~SW_FUNC_EN_N;
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_1, val);
 
 	anxdp_analog_power_up_all(sc);
-	
+
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_COMMON_INT_STA_1,
 	    PLL_LOCK_CHG);
-	
+
 	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_DEBUG_CTL);
 	val &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_DEBUG_CTL, val);
-	
+
 	if (anxdp_await_pll_lock(sc) != 0) {
 		device_printf(sc->sc_dev, "PLL lock timeout\n");
 	}
@@ -727,7 +747,8 @@ anxdp_bridge_post_disable(struct drm_bri
 
 static void
 anxdp_bridge_mode_set(struct drm_bridge *bridge,
-    const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode)
+    const struct drm_display_mode *mode,
+    const struct drm_display_mode *adjusted_mode)
 {
 	struct anxdp_softc * const sc = bridge->driver_private;
 
@@ -917,7 +938,7 @@ anxdp_dp_aux_transfer(struct drm_dp_aux 
 	    AUX_ADDR_15_8(dpmsg->address));
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_ADDR_19_16,
 	    AUX_ADDR_19_16(dpmsg->address));
-	
+
 	if (!(dpmsg->request & DP_AUX_I2C_READ)) {
 		for (i = 0; i < dpmsg->size; i++) {
 			bus_space_write_4(sc->sc_bst, sc->sc_bsh,
@@ -965,13 +986,13 @@ anxdp_dp_aux_transfer(struct drm_dp_aux 
 		ret = -EREMOTEIO;
 		goto out;
 	}
-		
+
 	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_CH_STA);
 	if (AUX_STATUS(val) != 0) {
 		ret = -EREMOTEIO;
 		goto out;
 	}
-	
+
 	if ((dpmsg->request & DP_AUX_I2C_READ)) {
 		for (i = 0; i < dpmsg->size; i++) {
 			val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
@@ -980,7 +1001,7 @@ anxdp_dp_aux_transfer(struct drm_dp_aux 
 			ret++;
 		}
 	}
-	
+
 	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_RX_COMM);
 	if (val == AUX_RX_COMM_AUX_DEFER)
 		dpmsg->reply = DP_AUX_NATIVE_REPLY_DEFER;
@@ -1000,21 +1021,6 @@ out:
 	return ret;
 }
 
-void
-anxdp_dpms(struct anxdp_softc *sc, int mode)
-{
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		pmf_event_inject(NULL, PMFE_DISPLAY_ON);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		pmf_event_inject(NULL, PMFE_DISPLAY_OFF);
-		break;
-	}
-}
-
 int
 anxdp_attach(struct anxdp_softc *sc)
 {
@@ -1048,15 +1054,18 @@ anxdp_bind(struct anxdp_softc *sc, struc
 {
 	int error;
 
+	sc->sc_connector.encoder = encoder;
+
 	sc->sc_bridge.driver_private = sc;
 	sc->sc_bridge.funcs = &anxdp_bridge_funcs;
-	sc->sc_bridge.encoder = encoder;
 
 	error = drm_bridge_attach(encoder, &sc->sc_bridge, NULL);
-	if (error != 0)
+	if (error)
 		return EIO;
 
-	if (sc->sc_panel != NULL && sc->sc_panel->funcs != NULL &&  sc->sc_panel->funcs->prepare != NULL)
+	if (sc->sc_panel != NULL &&
+	    sc->sc_panel->funcs != NULL &&
+	    sc->sc_panel->funcs->prepare != NULL)
 		sc->sc_panel->funcs->prepare(sc->sc_panel);
 
 	return 0;
Index: src/sys/dev/ic/anx_dp.h
diff -u src/sys/dev/ic/anx_dp.h:1.4 src/sys/dev/ic/anx_dp.h:1.5
--- src/sys/dev/ic/anx_dp.h:1.4	Sun Dec 19 11:01:11 2021
+++ src/sys/dev/ic/anx_dp.h	Sun Dec 19 12:43:37 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: anx_dp.h,v 1.4 2021/12/19 11:01:11 riastradh Exp $ */
+/* $NetBSD: anx_dp.h,v 1.5 2021/12/19 12:43:37 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2019 Jonathan A. Kollasch <jakll...@kollasch.net>
@@ -45,6 +45,7 @@ struct anxdp_softc;
 struct anxdp_connector {
 	struct drm_connector	base;
 	struct anxdp_softc	*sc;
+	struct drm_encoder	*encoder;
 #if ANXDP_AUDIO
 
 	bool			monitor_audio;
@@ -66,7 +67,7 @@ struct anxdp_softc {
 	struct anxdp_connector	sc_connector;
 	struct drm_bridge	sc_bridge;
 	struct drm_dp_aux       sc_dpaux;
-	struct drm_panel *	sc_panel;
+	struct drm_panel	*sc_panel;
 	uint8_t			sc_dpcd[DP_RECEIVER_CAP_SIZE];
 
 	struct drm_display_mode	sc_curmode;

Index: src/sys/external/bsd/drm2/drm/drm_module.c
diff -u src/sys/external/bsd/drm2/drm/drm_module.c:1.27 src/sys/external/bsd/drm2/drm/drm_module.c:1.28
--- src/sys/external/bsd/drm2/drm/drm_module.c:1.27	Sun Dec 19 11:49:11 2021
+++ src/sys/external/bsd/drm2/drm/drm_module.c	Sun Dec 19 12:43:37 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_module.c,v 1.27 2021/12/19 11:49:11 riastradh Exp $	*/
+/*	$NetBSD: drm_module.c,v 1.28 2021/12/19 12:43:37 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_module.c,v 1.27 2021/12/19 11:49:11 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_module.c,v 1.28 2021/12/19 12:43:37 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/condvar.h>
@@ -124,7 +124,7 @@ drm_init(void)
 #endif
 
 	if (ISSET(boothowto, AB_DEBUG))
-		__drm_debug = DRM_UT_CORE | DRM_UT_DRIVER | DRM_UT_KMS;
+		__drm_debug = DRM_UT_CORE | DRM_UT_DRIVER | DRM_UT_KMS | DRM_UT_ATOMIC;
 
 	spin_lock_init(&drm_minor_lock);
 	idr_init(&drm_minors_idr);

Reply via email to