diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-06-08 04:48:17 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-06-08 04:48:17 +0000 |
commit | 999f0686e0633f8b7bb9b76a14e47f5c20d2ea36 (patch) | |
tree | dbe3cb52b25db114fa92d119c4d7489e1632683b /sys/dev/fdt | |
parent | 8f362563d8e3edaf51e661f18685f44716781993 (diff) |
update drm to linux 5.7
adds kernel support for
amdgpu: vega20, raven2, renoir, navi10, navi14
inteldrm: icelake, tigerlake
Thanks to the OpenBSD Foundation for sponsoring this work, kettenis@ for
helping, patrick@ for helping adapt rockchip drm and many developers for
testing.
Diffstat (limited to 'sys/dev/fdt')
-rw-r--r-- | sys/dev/fdt/rkanxdp.c | 43 | ||||
-rw-r--r-- | sys/dev/fdt/rkdrm.c | 98 | ||||
-rw-r--r-- | sys/dev/fdt/rkdrm.h | 3 | ||||
-rw-r--r-- | sys/dev/fdt/rkdwhdmi.c | 44 | ||||
-rw-r--r-- | sys/dev/fdt/rkvop.c | 274 | ||||
-rw-r--r-- | sys/dev/fdt/simplepanel.c | 21 |
6 files changed, 176 insertions, 307 deletions
diff --git a/sys/dev/fdt/rkanxdp.c b/sys/dev/fdt/rkanxdp.c index 888abbee33d..1d87a2fccb1 100644 --- a/sys/dev/fdt/rkanxdp.c +++ b/sys/dev/fdt/rkanxdp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkanxdp.c,v 1.3 2020/03/16 21:51:25 kettenis Exp $ */ +/* $OpenBSD: rkanxdp.c,v 1.4 2020/06/08 04:47:58 jsg Exp $ */ /* $NetBSD: rk_anxdp.c,v 1.2 2020/01/04 12:08:32 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jonathan A. Kollasch <jakllsch@kollasch.net> @@ -40,7 +40,6 @@ #include <dev/ofw/ofw_pinctrl.h> #include <dev/ofw/fdt.h> -#include <drm/drmP.h> #include <drm/drm_crtc_helper.h> #include <dev/ic/anxdp.h> @@ -72,14 +71,7 @@ int rkanxdp_match(struct device *, void *, void *); void rkanxdp_attach(struct device *, struct device *, void *); void rkanxdp_select_input(struct rkanxdp_softc *, u_int); -bool rkanxdp_encoder_mode_fixup(struct drm_encoder *, - const struct drm_display_mode *, struct drm_display_mode *); -void rkanxdp_encoder_mode_set(struct drm_encoder *, - struct drm_display_mode *, struct drm_display_mode *); void rkanxdp_encoder_enable(struct drm_encoder *); -void rkanxdp_encoder_disable(struct drm_encoder *); -void rkanxdp_encoder_prepare(struct drm_encoder *); -void rkanxdp_encoder_commit(struct drm_encoder *); void rkanxdp_encoder_dpms(struct drm_encoder *, int); int rkanxdp_ep_activate(void *, struct endpoint *, void *); @@ -161,32 +153,9 @@ rkanxdp_select_input(struct rkanxdp_softc *sc, u_int crtc_index) regmap_write_4(sc->sc_grf, RK3399_GRF_SOC_CON20, write_mask | write_val); } -bool -rkanxdp_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) -{ - return true; -} - -void -rkanxdp_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, struct drm_display_mode *adjusted) -{ -} - void rkanxdp_encoder_enable(struct drm_encoder *encoder) { -} - -void -rkanxdp_encoder_disable(struct drm_encoder *encoder) -{ -} - -void -rkanxdp_encoder_prepare(struct drm_encoder *encoder) -{ struct rkanxdp_softc *sc = to_rkanxdp_encoder(encoder); u_int crtc_index = drm_crtc_index(encoder->crtc); @@ -194,11 +163,6 @@ rkanxdp_encoder_prepare(struct drm_encoder *encoder) } void -rkanxdp_encoder_commit(struct drm_encoder *encoder) -{ -} - -void rkanxdp_encoder_dpms(struct drm_encoder *encoder, int mode) { struct rkanxdp_softc *sc = to_rkanxdp_encoder(encoder); @@ -211,12 +175,7 @@ struct drm_encoder_funcs rkanxdp_encoder_funcs = { }; struct drm_encoder_helper_funcs rkanxdp_encoder_helper_funcs = { - .prepare = rkanxdp_encoder_prepare, - .mode_fixup = rkanxdp_encoder_mode_fixup, - .mode_set = rkanxdp_encoder_mode_set, .enable = rkanxdp_encoder_enable, - .disable = rkanxdp_encoder_disable, - .commit = rkanxdp_encoder_commit, .dpms = rkanxdp_encoder_dpms, }; diff --git a/sys/dev/fdt/rkdrm.c b/sys/dev/fdt/rkdrm.c index 8fb09f592e7..64b7911430b 100644 --- a/sys/dev/fdt/rkdrm.c +++ b/sys/dev/fdt/rkdrm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkdrm.c,v 1.9 2020/05/25 09:55:48 jsg Exp $ */ +/* $OpenBSD: rkdrm.c,v 1.10 2020/06/08 04:47:58 jsg Exp $ */ /* $NetBSD: rk_drm.c,v 1.3 2019/12/15 01:00:58 mrg Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> @@ -44,7 +44,10 @@ #include <uvm/uvm_object.h> #include <uvm/uvm_device.h> -#include <drm/drmP.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_drv.h> +#include <drm/drm_vblank.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> #include <drm/drm_gem.h> @@ -65,10 +68,6 @@ void rkdrm_attachhook(struct device *); vmem_t *rkdrm_alloc_cma_pool(struct drm_device *, size_t); #endif -uint32_t rkdrm_get_vblank_counter(struct drm_device *, unsigned int); -int rkdrm_enable_vblank(struct drm_device *, unsigned int); -void rkdrm_disable_vblank(struct drm_device *, unsigned int); - int rkdrm_load(struct drm_device *, unsigned long); int rkdrm_unload(struct drm_device *); @@ -76,14 +75,10 @@ int rkdrm_gem_fault(struct drm_gem_object *, struct uvm_faultinfo *, off_t, vaddr_t, vm_page_t *, int, int, vm_prot_t, int); struct drm_driver rkdrm_driver = { - .driver_features = DRIVER_MODESET | DRIVER_GEM, - - .get_vblank_counter = rkdrm_get_vblank_counter, - .enable_vblank = rkdrm_enable_vblank, - .disable_vblank = rkdrm_disable_vblank, + .driver_features = DRIVER_ATOMIC | DRIVER_MODESET | DRIVER_GEM, .dumb_create = drm_gem_cma_dumb_create, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, + .dumb_map_offset = drm_gem_dumb_map_offset, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_fault = drm_gem_cma_fault, @@ -117,7 +112,6 @@ rkdrm_attach(struct device *parent, struct device *self, void *aux) { struct rkdrm_softc *sc = (struct rkdrm_softc *)self; struct fdt_attach_args *faa = aux; - struct drm_attach_args arg; sc->sc_dmat = faa->fa_dmat; sc->sc_iot = faa->fa_iot; @@ -132,15 +126,8 @@ rkdrm_attach(struct device *parent, struct device *self, void *aux) if (OF_is_compatible(stdout_node, "simple-framebuffer")) stdout_node = sc->sc_node; - memset(&arg, 0, sizeof(arg)); - arg.driver = &rkdrm_driver; - arg.drm = &sc->sc_ddev; - arg.dmat = faa->fa_dmat; - arg.bst = faa->fa_iot; - arg.busid = sc->sc_dev.dv_xname; - arg.busid_len = strlen(sc->sc_dev.dv_xname) + 1; - config_found_sm(self, &arg, drmprint, drmsubmatch); - + drm_attach_platform(&rkdrm_driver, faa->fa_iot, faa->fa_dmat, self, + &sc->sc_ddev); config_mountroot(self, rkdrm_attachhook); } @@ -159,7 +146,7 @@ rkdrm_fb_destroy(struct drm_framebuffer *fb) struct rkdrm_framebuffer *sfb = to_rkdrm_framebuffer(fb); drm_framebuffer_cleanup(fb); - drm_gem_object_unreference_unlocked(&sfb->obj->base); + drm_gem_object_put_unlocked(&sfb->obj->base); free(sfb, M_DRM, sizeof(*sfb)); } @@ -197,13 +184,20 @@ rkdrm_fb_create(struct drm_device *ddev, struct drm_file *file, dealloc: drm_framebuffer_cleanup(&fb->base); free(fb, M_DRM, sizeof(*fb)); - drm_gem_object_unreference_unlocked(gem_obj); + drm_gem_object_put_unlocked(gem_obj); return NULL; } +struct drm_mode_config_helper_funcs rkdrm_mode_config_helper_funcs = +{ + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, +}; + struct drm_mode_config_funcs rkdrm_mode_config_funcs = { .fb_create = rkdrm_fb_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, }; int rkdrm_fb_probe(struct drm_fb_helper *, struct drm_fb_helper_surface_size *); @@ -212,50 +206,6 @@ struct drm_fb_helper_funcs rkdrm_fb_helper_funcs = { .fb_probe = rkdrm_fb_probe, }; -uint32_t -rkdrm_get_vblank_counter(struct drm_device *ddev, unsigned int crtc) -{ - struct rkdrm_softc *sc = rkdrm_private(ddev); - - if (crtc >= nitems(sc->sc_vbl)) - return 0; - - if (sc->sc_vbl[crtc].get_vblank_counter == NULL) - return 0; - - return sc->sc_vbl[crtc].get_vblank_counter(sc->sc_vbl[crtc].priv); -} - -int -rkdrm_enable_vblank(struct drm_device *ddev, unsigned int crtc) -{ - struct rkdrm_softc *sc = rkdrm_private(ddev); - - if (crtc >= nitems(sc->sc_vbl)) - return 0; - - if (sc->sc_vbl[crtc].enable_vblank == NULL) - return 0; - - sc->sc_vbl[crtc].enable_vblank(sc->sc_vbl[crtc].priv); - - return 0; -} - -void -rkdrm_disable_vblank(struct drm_device *ddev, unsigned int crtc) -{ - struct rkdrm_softc *sc = rkdrm_private(ddev); - - if (crtc >= nitems(sc->sc_vbl)) - return; - - if (sc->sc_vbl[crtc].disable_vblank == NULL) - return; - - sc->sc_vbl[crtc].disable_vblank(sc->sc_vbl[crtc].priv); -} - int rkdrm_unload(struct drm_device *ddev) { @@ -457,6 +407,8 @@ rkdrm_attachhook(struct device *dev) sc->sc_ddev.mode_config.max_width = RK_DRM_MAX_WIDTH; sc->sc_ddev.mode_config.max_height = RK_DRM_MAX_HEIGHT; sc->sc_ddev.mode_config.funcs = &rkdrm_mode_config_funcs; + sc->sc_ddev.mode_config.helper_private = + &rkdrm_mode_config_helper_funcs; nports = 0; ports = malloc(portslen, M_TEMP, M_WAITOK); @@ -475,8 +427,10 @@ rkdrm_attachhook(struct device *dev) return; } + drm_mode_config_reset(&sc->sc_ddev); + drm_fb_helper_prepare(&sc->sc_ddev, &sc->helper, &rkdrm_fb_helper_funcs); - if (drm_fb_helper_init(&sc->sc_ddev, &sc->helper, 1)) { + if (drm_fb_helper_init(&sc->sc_ddev, &sc->helper)) { printf("%s: can't initialize framebuffer helper\n", sc->sc_dev.dv_xname); drm_mode_config_cleanup(&sc->sc_ddev); @@ -486,14 +440,8 @@ rkdrm_attachhook(struct device *dev) sc->helper.fb = malloc(sizeof(struct rkdrm_framebuffer), M_DRM, M_WAITOK | M_ZERO); - drm_fb_helper_single_add_all_connectors(&sc->helper); - drm_helper_disable_unused_functions(&sc->sc_ddev); drm_fb_helper_initial_config(&sc->helper, 32); - /* XXX */ - sc->sc_ddev.irq_enabled = true; - drm_vblank_init(&sc->sc_ddev, 1); - task_set(&sc->switchtask, rkdrm_doswitch, ri); drm_fb_helper_restore_fbdev_mode_unlocked(&sc->helper); diff --git a/sys/dev/fdt/rkdrm.h b/sys/dev/fdt/rkdrm.h index a84216b5013..71fc7ca1ab0 100644 --- a/sys/dev/fdt/rkdrm.h +++ b/sys/dev/fdt/rkdrm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rkdrm.h,v 1.1 2020/02/21 15:44:54 patrick Exp $ */ +/* $OpenBSD: rkdrm.h,v 1.2 2020/06/08 04:47:58 jsg Exp $ */ /* $NetBSD: rk_drm.h,v 1.1 2019/11/09 23:30:14 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> @@ -34,6 +34,7 @@ #include <dev/rasops/rasops.h> #include <drm/drm_fb_helper.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_cma_helper.h> #define DRIVER_AUTHOR "Jared McNeill" diff --git a/sys/dev/fdt/rkdwhdmi.c b/sys/dev/fdt/rkdwhdmi.c index 871ba0ef8dd..a2326657950 100644 --- a/sys/dev/fdt/rkdwhdmi.c +++ b/sys/dev/fdt/rkdwhdmi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkdwhdmi.c,v 1.3 2020/03/16 21:51:25 kettenis Exp $ */ +/* $OpenBSD: rkdwhdmi.c,v 1.4 2020/06/08 04:47:58 jsg Exp $ */ /* $NetBSD: rk_dwhdmi.c,v 1.4 2019/12/17 18:26:36 jakllsch Exp $ */ /*- @@ -41,7 +41,6 @@ #include <dev/ofw/ofw_pinctrl.h> #include <dev/ofw/fdt.h> -#include <drm/drmP.h> #include <drm/drm_crtc_helper.h> #include <dev/ic/dwhdmi.h> @@ -90,15 +89,7 @@ int rkdwhdmi_match(struct device *, void *, void *); void rkdwhdmi_attach(struct device *, struct device *, void *); void rkdwhdmi_select_input(struct rkdwhdmi_softc *, u_int); -bool rkdwhdmi_encoder_mode_fixup(struct drm_encoder *, - const struct drm_display_mode *, struct drm_display_mode *); -void rkdwhdmi_encoder_mode_set(struct drm_encoder *, - struct drm_display_mode *, struct drm_display_mode *); void rkdwhdmi_encoder_enable(struct drm_encoder *); -void rkdwhdmi_encoder_disable(struct drm_encoder *); -void rkdwhdmi_encoder_prepare(struct drm_encoder *); -void rkdwhdmi_encoder_commit(struct drm_encoder *); -void rkdwhdmi_encoder_dpms(struct drm_encoder *, int); int rkdwhdmi_ep_activate(void *, struct endpoint *, void *); void *rkdwhdmi_ep_get_cookie(void *, struct endpoint *); @@ -212,54 +203,21 @@ rkdwhdmi_select_input(struct rkdwhdmi_softc *sc, u_int crtc_index) regmap_write_4(sc->sc_grf, RK3399_GRF_SOC_CON20, write_mask | write_val); } -bool -rkdwhdmi_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) -{ - return true; -} - -void -rkdwhdmi_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, struct drm_display_mode *adjusted) -{ -} - void rkdwhdmi_encoder_enable(struct drm_encoder *encoder) { -} - -void -rkdwhdmi_encoder_disable(struct drm_encoder *encoder) -{ -} - -void -rkdwhdmi_encoder_prepare(struct drm_encoder *encoder) -{ struct rkdwhdmi_softc * const sc = to_rkdwhdmi_encoder(encoder); const u_int crtc_index = drm_crtc_index(encoder->crtc); rkdwhdmi_select_input(sc, crtc_index); } -void -rkdwhdmi_encoder_commit(struct drm_encoder *encoder) -{ -} - struct drm_encoder_funcs rkdwhdmi_encoder_funcs = { .destroy = drm_encoder_cleanup, }; struct drm_encoder_helper_funcs rkdwhdmi_encoder_helper_funcs = { - .prepare = rkdwhdmi_encoder_prepare, - .mode_fixup = rkdwhdmi_encoder_mode_fixup, - .mode_set = rkdwhdmi_encoder_mode_set, .enable = rkdwhdmi_encoder_enable, - .disable = rkdwhdmi_encoder_disable, - .commit = rkdwhdmi_encoder_commit, }; int diff --git a/sys/dev/fdt/rkvop.c b/sys/dev/fdt/rkvop.c index 39397f4375c..eebdb6c2c08 100644 --- a/sys/dev/fdt/rkvop.c +++ b/sys/dev/fdt/rkvop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkvop.c,v 1.3 2020/04/07 15:23:42 kettenis Exp $ */ +/* $OpenBSD: rkvop.c,v 1.4 2020/06/08 04:47:58 jsg Exp $ */ /* $NetBSD: rk_vop.c,v 1.6 2020/01/05 12:14:35 mrg Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca> @@ -39,7 +39,9 @@ #include <dev/ofw/ofw_misc.h> #include <dev/ofw/fdt.h> -#include <drm/drmP.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_fourcc.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_plane_helper.h> @@ -137,6 +139,7 @@ struct rkvop_softc { struct rkvop_config *sc_conf; struct rkvop_crtc sc_crtc; + struct drm_plane sc_plane; struct device_ports sc_ports; }; @@ -158,20 +161,9 @@ struct rkvop_config { int rkvop_match(struct device *, void *, void *); void rkvop_attach(struct device *, struct device *, void *); -int rkvop_mode_do_set_base(struct drm_crtc *, struct drm_framebuffer *, - int, int, int); -void rkvop_destroy(struct drm_crtc *); void rkvop_dpms(struct drm_crtc *, int); bool rkvop_mode_fixup(struct drm_crtc *, const struct drm_display_mode *, struct drm_display_mode *); -int rkvop_mode_set(struct drm_crtc *, struct drm_display_mode *, - struct drm_display_mode *, int, int, struct drm_framebuffer *); -int rkvop_mode_set_base(struct drm_crtc *, int, int, struct drm_framebuffer *); -int rkvop_mode_set_base_atomic(struct drm_crtc *, struct drm_framebuffer *, - int, int, enum mode_set_atomic); -void rkvop_disable(struct drm_crtc *); -void rkvop_prepare(struct drm_crtc *); -void rkvop_commit(struct drm_crtc *); void rk3399_vop_init(struct rkvop_softc *); void rk3399_vop_set_polarity(struct rkvop_softc *, enum vop_ep_type, uint32_t); @@ -266,47 +258,101 @@ rkvop_attach(struct device *parent, struct device *self, void *aux) } int -rkvop_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, - int x, int y, int atomic) +rkvop_plane_check(struct drm_plane *plane, struct drm_plane_state *state) { - struct rkvop_crtc *mixer_crtc = to_rkvop_crtc(crtc); - struct rkvop_softc *sc = mixer_crtc->sc; - struct rkdrm_framebuffer *sfb = atomic? - to_rkdrm_framebuffer(fb) : - to_rkdrm_framebuffer(crtc->primary->fb); + struct drm_crtc_state *crtc_state; - uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr; + if (state->crtc == NULL) + return 0; - paddr += y * sfb->base.pitches[0]; - paddr += x * drm_format_plane_cpp(sfb->base.format->format, 0); + crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); - KASSERT((paddr & ~0xffffffff) == 0); + return drm_atomic_helper_check_plane_state(state, crtc_state, + DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, + false, true); +} + +void +rkvop_plane_update(struct drm_plane *plane, struct drm_plane_state *old_state) +{ + struct drm_plane_state *state = plane->state; + struct drm_crtc *crtc = state->crtc; + struct rkvop_crtc *rkcrtc = to_rkvop_crtc(crtc); + struct rkvop_softc *sc = rkcrtc->sc; + struct drm_framebuffer *fb = state->fb; + struct rkdrm_framebuffer *rkfb = to_rkdrm_framebuffer(fb); + struct drm_rect *src = &state->src; + struct drm_rect *dst = &state->dst; + u_int act_width = drm_rect_width(src) >> 16; + u_int act_height = drm_rect_height(src) >> 16; + u_int htotal = crtc->mode.htotal; + u_int vtotal = crtc->mode.vtotal; + u_int hsync_start = crtc->mode.hsync_start; + u_int vsync_start = crtc->mode.vsync_start; + uint64_t paddr; + u_int lb_mode; + uint32_t val; + + val = WIN0_ACT_WIDTH(act_width - 1) | + WIN0_ACT_HEIGHT(act_height - 1); + HWRITE4(sc, VOP_WIN0_ACT_INFO, val); + + val = WIN0_DSP_WIDTH(drm_rect_width(dst) - 1) | + WIN0_DSP_HEIGHT(drm_rect_height(dst) - 1); + HWRITE4(sc, VOP_WIN0_DSP_INFO, val); + + val = WIN0_DSP_XST(dst->x1 + htotal - hsync_start) | + WIN0_DSP_YST(dst->y1 + vtotal - vsync_start); + HWRITE4(sc, VOP_WIN0_DSP_ST, val); + + HWRITE4(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 = WIN0_LB_MODE(lb_mode) | + WIN0_DATA_FMT(WIN0_DATA_FMT_ARGB888) | + WIN0_EN; + HWRITE4(sc, VOP_WIN0_CTRL, val); - uint32_t vir = WIN0_VIR_STRIDE(sfb->base.pitches[0] / 4); - HWRITE4(sc, VOP_WIN0_VIR, vir); + val = WIN0_VIR_STRIDE(fb->pitches[0] / 4); + HWRITE4(sc, VOP_WIN0_VIR, val); /* Framebuffer start address */ + paddr = (uint64_t)rkfb->obj->dmamap->dm_segs[0].ds_addr; + paddr += (src->y1 >> 16) * fb->pitches[0]; + paddr += (src->x1 >> 16) * fb->format->cpp[0]; + KASSERT((paddr & ~0xffffffff) == 0); HWRITE4(sc, VOP_WIN0_YRGB_MST, (uint32_t)paddr); - - return 0; } -void -rkvop_destroy(struct drm_crtc *crtc) -{ - drm_crtc_cleanup(crtc); -} +struct drm_plane_helper_funcs rkvop_plane_helper_funcs = { + .atomic_check = rkvop_plane_check, + .atomic_update = rkvop_plane_update, +}; -struct drm_crtc_funcs rkvop_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, - .destroy = rkvop_destroy, +struct drm_plane_funcs rkvop_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, }; void rkvop_dpms(struct drm_crtc *crtc, int mode) { - struct rkvop_crtc *mixer_crtc = to_rkvop_crtc(crtc); - struct rkvop_softc *sc = mixer_crtc->sc; + struct rkvop_crtc *rkcrtc = to_rkvop_crtc(crtc); + struct rkvop_softc *sc = rkcrtc->sc; uint32_t val; val = HREAD4(sc, VOP_SYS_CTRL); @@ -336,14 +382,23 @@ rkvop_mode_fixup(struct drm_crtc *crtc, } int -rkvop_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) +rkvop_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { - struct rkvop_crtc *mixer_crtc = to_rkvop_crtc(crtc); - struct rkvop_softc *sc = mixer_crtc->sc; + 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); +} + +void +rkvop_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) +{ + struct rkvop_crtc *rkcrtc = to_rkvop_crtc(crtc); + struct rkvop_softc *sc = rkcrtc->sc; + struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; uint32_t val; - u_int lb_mode; u_int pol; int connector_type = 0; struct drm_connector *connector; @@ -361,36 +416,6 @@ rkvop_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, clock_set_frequency(sc->sc_node, "dclk_vop", adjusted_mode->clock * 1000); - val = WIN0_ACT_WIDTH(hactive - 1) | - WIN0_ACT_HEIGHT(vactive - 1); - HWRITE4(sc, VOP_WIN0_ACT_INFO, val); - - val = WIN0_DSP_WIDTH(hactive - 1) | - WIN0_DSP_HEIGHT(vactive - 1); - HWRITE4(sc, VOP_WIN0_DSP_INFO, val); - - val = WIN0_DSP_XST(hsync_len + hback_porch) | - WIN0_DSP_YST(vsync_len + vback_porch); - HWRITE4(sc, VOP_WIN0_DSP_ST, val); - - HWRITE4(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 = WIN0_LB_MODE(lb_mode) | - WIN0_DATA_FMT(WIN0_DATA_FMT_ARGB888) | - WIN0_EN; - HWRITE4(sc, VOP_WIN0_CTRL, val); - - rkvop_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; @@ -458,55 +483,13 @@ rkvop_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, val = DSP_VTOTAL(vsync_len) | DSP_VS_END(vsync_len + vback_porch + vactive + vfront_porch); HWRITE4(sc, VOP_DSP_VTOTAL_VS_END, val); - - return 0; -} - -int -rkvop_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct rkvop_crtc *mixer_crtc = to_rkvop_crtc(crtc); - struct rkvop_softc *sc = mixer_crtc->sc; - - rkvop_mode_do_set_base(crtc, old_fb, x, y, 0); - - /* Commit settings */ - HWRITE4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN); - - return 0; -} - -int -rkvop_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) -{ - struct rkvop_crtc *mixer_crtc = to_rkvop_crtc(crtc); - struct rkvop_softc *sc = mixer_crtc->sc; - - rkvop_mode_do_set_base(crtc, fb, x, y, 1); - - /* Commit settings */ - HWRITE4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN); - - return 0; -} - -void -rkvop_disable(struct drm_crtc *crtc) -{ } void -rkvop_prepare(struct drm_crtc *crtc) +rkvop_crtc_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { -} - -void -rkvop_commit(struct drm_crtc *crtc) -{ - struct rkvop_crtc *mixer_crtc = to_rkvop_crtc(crtc); - struct rkvop_softc *sc = mixer_crtc->sc; + struct rkvop_crtc *rkcrtc = to_rkvop_crtc(crtc); + struct rkvop_softc *sc = rkcrtc->sc; /* Commit settings */ HWRITE4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN); @@ -515,12 +498,18 @@ rkvop_commit(struct drm_crtc *crtc) struct drm_crtc_helper_funcs rkvop_crtc_helper_funcs = { .dpms = rkvop_dpms, .mode_fixup = rkvop_mode_fixup, - .mode_set = rkvop_mode_set, - .mode_set_base = rkvop_mode_set_base, - .mode_set_base_atomic = rkvop_mode_set_base_atomic, - .disable = rkvop_disable, - .prepare = rkvop_prepare, - .commit = rkvop_commit, + .atomic_check = rkvop_crtc_check, + .atomic_enable = rkvop_crtc_enable, + .atomic_flush = rkvop_crtc_flush, +}; + +struct drm_crtc_funcs rkvop_crtc_funcs = { + .reset = drm_atomic_helper_crtc_reset, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; int @@ -528,17 +517,30 @@ rkvop_ep_activate(void *cookie, struct endpoint *ep, void *arg) { struct rkvop_softc *sc = cookie; struct drm_device *ddev = arg; - - if (sc->sc_crtc.sc == NULL) { - sc->sc_crtc.sc = sc; - - drm_crtc_init(ddev, &sc->sc_crtc.base, &rkvop_crtc_funcs); - drm_crtc_helper_add(&sc->sc_crtc.base, &rkvop_crtc_helper_funcs); - - printf("%s: using CRTC %d for %s\n", sc->sc_dev.dv_xname, - drm_crtc_index(&sc->sc_crtc.base), sc->sc_conf->descr); - } - + struct drm_plane *plane = &sc->sc_plane; + struct drm_crtc *crtc = &sc->sc_crtc.base; + uint32_t formats[] = { DRM_FORMAT_ARGB8888 }; + int error; + + if (sc->sc_crtc.sc) + return 0; + + drm_plane_helper_add(plane, &rkvop_plane_helper_funcs); + error = drm_universal_plane_init(ddev, plane, 0, &rkvop_plane_funcs, + formats, nitems(formats), NULL, DRM_PLANE_TYPE_PRIMARY, NULL); + if (error) + return -error; + + drm_crtc_helper_add(&sc->sc_crtc.base, &rkvop_crtc_helper_funcs); + error = drm_crtc_init_with_planes(ddev, crtc, plane, NULL, + &rkvop_crtc_funcs, NULL); + if (error) + return -error; + + printf("%s: using CRTC %d for %s\n", sc->sc_dev.dv_xname, + drm_crtc_index(&sc->sc_crtc.base), sc->sc_conf->descr); + + sc->sc_crtc.sc = sc; return 0; } diff --git a/sys/dev/fdt/simplepanel.c b/sys/dev/fdt/simplepanel.c index 77a15e6af40..5718b53a43c 100644 --- a/sys/dev/fdt/simplepanel.c +++ b/sys/dev/fdt/simplepanel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: simplepanel.c,v 1.2 2020/03/17 15:49:38 kettenis Exp $ */ +/* $OpenBSD: simplepanel.c,v 1.3 2020/06/08 04:47:58 jsg Exp $ */ /* * Copyright (c) 2020 Patrick Wildt <patrick@blueri.se> * @@ -64,7 +64,7 @@ struct cfdriver simplepanel_cd = { }; void *simplepanel_ep_get_cookie(void *, struct endpoint *); -int simplepanel_get_modes(struct drm_panel *); +int simplepanel_get_modes(struct drm_panel *, struct drm_connector *); struct drm_panel_funcs simplepanel_funcs = { .get_modes = simplepanel_get_modes @@ -86,6 +86,7 @@ simplepanel_attach(struct device *parent, struct device *self, void *aux) struct fdt_attach_args *faa = aux; uint32_t power_supply; uint32_t *gpios; + int connector_type = DRM_MODE_CONNECTOR_Unknown; int len, err; pinctrl_byname(faa->fa_node, "default"); @@ -103,12 +104,13 @@ simplepanel_attach(struct device *parent, struct device *self, void *aux) free(gpios, M_TEMP, len); } - if (OF_is_compatible(faa->fa_node, "boe,nv140fhmn49")) - sc->sc_mode = &boe_nv140fhmn49_mode; + if (OF_is_compatible(faa->fa_node, "boe,nv140fhmn49")) { + sc->sc_mode = &boe_nv140fhmn49_mode; + connector_type = DRM_MODE_CONNECTOR_eDP; + } - drm_panel_init(&sc->sc_panel); - sc->sc_panel.dev = self; - sc->sc_panel.funcs = &simplepanel_funcs; + drm_panel_init(&sc->sc_panel, self, &simplepanel_funcs, + connector_type); err = drm_panel_add(&sc->sc_panel); if (err < 0) { printf(": can't register panel\n"); @@ -137,16 +139,15 @@ to_simplepanel(struct drm_panel *panel) } int -simplepanel_get_modes(struct drm_panel *panel) +simplepanel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { - struct drm_connector *connector = panel->connector; struct simplepanel_softc *sc = to_simplepanel(panel); struct drm_display_mode *mode; if (sc->sc_mode == NULL) return 0; - mode = drm_mode_duplicate(panel->drm, sc->sc_mode); + mode = drm_mode_duplicate(connector->dev, sc->sc_mode); if (mode == NULL) return 0; mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; |