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);