Module Name:    src
Committed By:   jmcneill
Date:           Wed Feb  6 03:07:08 UTC 2019

Modified Files:
        src/sys/arch/arm/sunxi: sunxi_drm.c sunxi_mixer.c

Log Message:
Add support for hardware cursors where we can.

As far as I can tell, alpha blending only works between overlay channels,
and not between layers on a channel. Unfortunately, RT-Mixer1 only has
a single UI channel, so this feature is limited to RT-Mixer0.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/sunxi/sunxi_drm.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/sunxi/sunxi_mixer.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/sunxi/sunxi_drm.c
diff -u src/sys/arch/arm/sunxi/sunxi_drm.c:1.6 src/sys/arch/arm/sunxi/sunxi_drm.c:1.7
--- src/sys/arch/arm/sunxi/sunxi_drm.c:1.6	Mon Feb  4 12:10:13 2019
+++ src/sys/arch/arm/sunxi/sunxi_drm.c	Wed Feb  6 03:07:08 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_drm.c,v 1.6 2019/02/04 12:10:13 jmcneill Exp $ */
+/* $NetBSD: sunxi_drm.c,v 1.7 2019/02/06 03:07:08 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_drm.c,v 1.6 2019/02/04 12:10:13 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_drm.c,v 1.7 2019/02/06 03:07:08 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -247,6 +247,7 @@ sunxi_drm_fb_create(struct drm_device *d
 
 	switch (fb->base.pixel_format) {
 	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
 		fb->base.depth = 32;
 		break;
 	default:

Index: src/sys/arch/arm/sunxi/sunxi_mixer.c
diff -u src/sys/arch/arm/sunxi/sunxi_mixer.c:1.5 src/sys/arch/arm/sunxi/sunxi_mixer.c:1.6
--- src/sys/arch/arm/sunxi/sunxi_mixer.c:1.5	Tue Feb  5 21:01:38 2019
+++ src/sys/arch/arm/sunxi/sunxi_mixer.c	Wed Feb  6 03:07:08 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_mixer.c,v 1.5 2019/02/05 21:01:38 jmcneill Exp $ */
+/* $NetBSD: sunxi_mixer.c,v 1.6 2019/02/06 03:07:08 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.c,v 1.5 2019/02/05 21:01:38 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.c,v 1.6 2019/02/06 03:07:08 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/conf.h>
+#include <sys/sysctl.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
@@ -47,13 +48,14 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.
 
 #include <arm/sunxi/sunxi_drm.h>
 
+#define	MIXER_CURSOR_MAXWIDTH	256
+#define	MIXER_CURSOR_MAXHEIGHT	256
+
 #define	SUNXI_MIXER_FREQ	432000000
 
 #define	GLB_BASE		0x00000
 #define	BLD_BASE		0x01000
 #define	OVL_BASE(n)		(0x02000 + (n) * 0x1000)
-#define	OVL_V_BASE		OVL_BASE(0)
-#define	OVL_UI_BASE		OVL_BASE(1)
 #define	VSU_BASE		0x20000
 #define	CSC_BASE(n)		((n) == 0 ? 0xaa050 : 0xa0000)
 
@@ -67,11 +69,20 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.
 
 /* BLD registers */
 #define	BLD_FILL_COLOR_CTL	0x000
+#define	 BLD_FILL_COLOR_CTL_P3_EN		__BIT(11)
+#define	 BLD_FILL_COLOR_CTL_P2_EN		__BIT(10)
 #define	 BLD_FILL_COLOR_CTL_P1_EN		__BIT(9)
 #define	 BLD_FILL_COLOR_CTL_P0_EN		__BIT(8)
+#define	 BLD_FILL_COLOR_CTL_P3_FCEN		__BIT(3)
+#define	 BLD_FILL_COLOR_CTL_P2_FCEN		__BIT(2)
+#define	 BLD_FILL_COLOR_CTL_P1_FCEN		__BIT(1)
+#define	 BLD_FILL_COLOR_CTL_P0_FCEN		__BIT(0)
+#define	BLD_FILL_COLOR(n)	(0x004 + (n) * 0x10)
 #define	BLD_CH_ISIZE(n)		(0x008 + (n) * 0x10)
 #define	BLD_CH_OFFSET(n)	(0x00c + (n) * 0x10)
 #define	BLD_CH_RTCTL		0x080
+#define	 BLD_CH_RTCTL_P3			__BITS(15,12)
+#define	 BLD_CH_RTCTL_P2			__BITS(11,8)
 #define	 BLD_CH_RTCTL_P1			__BITS(7,4)
 #define	 BLD_CH_RTCTL_P0			__BITS(3,0)
 #define	BLD_SIZE		0x08c
@@ -88,6 +99,7 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.
 #define	  OVL_V_ATTCTL_LAY_FBFMT_YUV422		0x06
 #define	  OVL_V_ATTCTL_LAY_FBFMT_YUV420		0x0a
 #define	  OVL_V_ATTCTL_LAY_FBFMT_YUV411		0x0e
+#define	  OVL_V_ATTCTL_LAY_FBFMT_ARGB_8888	0x00
 #define	  OVL_V_ATTCTL_LAY_FBFMT_XRGB_8888	0x04
 #define	 OVL_V_ATTCTL_LAY0_EN			__BIT(0)
 #define	OVL_V_MBSIZE(n)		(0x004 + (n) * 0x30)
@@ -112,13 +124,16 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.
 /* OVL_UI registers */
 #define	OVL_UI_ATTR_CTL(n)	(0x000 + (n) * 0x20)
 #define	 OVL_UI_ATTR_CTL_LAY_FBFMT		__BITS(12,8)
+#define	  OVL_UI_ATTR_CTL_LAY_FBFMT_ARGB_8888	0x00
 #define	  OVL_UI_ATTR_CTL_LAY_FBFMT_XRGB_8888	0x04
 #define	 OVL_UI_ATTR_CTL_LAY_EN			__BIT(0)
 #define	OVL_UI_MBSIZE(n)	(0x004 + (n) * 0x20)
 #define	OVL_UI_COOR(n)		(0x008 + (n) * 0x20)
 #define	OVL_UI_PITCH(n)		(0x00c + (n) * 0x20)
 #define	OVL_UI_TOP_LADD(n)	(0x010 + (n) * 0x20)
+#define	OVL_UI_FILL_COLOR(n)	(0x018 + (n) * 0x20)
 #define	OVL_UI_TOP_HADD		0x080
+#define	 OVL_UI_TOP_HADD_LAYER1	__BITS(15,8)
 #define	 OVL_UI_TOP_HADD_LAYER0	__BITS(7,0)
 #define	OVL_UI_SIZE		0x088
 
@@ -158,11 +173,11 @@ enum {
 	MIXER_PORT_OUTPUT = 1,
 };
 
-static const char * const compatible[] = {
-	"allwinner,sun8i-h3-de2-mixer-0",
-	"allwinner,sun50i-a64-de2-mixer-0",
-	"allwinner,sun50i-a64-de2-mixer-1",
-	NULL
+static const struct of_compat_data compat_data[] = {
+	{ "allwinner,sun8i-h3-de2-mixer-0",	3 },
+	{ "allwinner,sun50i-a64-de2-mixer-0",	3 },
+	{ "allwinner,sun50i-a64-de2-mixer-1",	1 },
+	{ NULL }
 };
 
 struct sunxi_mixer_softc;
@@ -172,7 +187,7 @@ struct sunxi_mixer_crtc {
 	struct sunxi_mixer_softc *sc;
 };
 
-struct sunxi_mixer_overlay {
+struct sunxi_mixer_plane {
 	struct drm_plane	base;
 	struct sunxi_mixer_softc *sc;
 };
@@ -183,8 +198,10 @@ struct sunxi_mixer_softc {
 	bus_space_handle_t	sc_bsh;
 	int			sc_phandle;
 
+	u_int			sc_ovl_ui_count;
+
 	struct sunxi_mixer_crtc	sc_crtc;
-	struct sunxi_mixer_overlay sc_overlay;
+	struct sunxi_mixer_plane sc_overlay;
 
 	struct fdt_device_ports	sc_ports;
 };
@@ -200,14 +217,14 @@ struct sunxi_mixer_softc {
 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, BLD_BASE + (reg), (val))
 
 #define	OVL_V_READ(sc, reg)				\
-	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, OVL_V_BASE + (reg))
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE(0) + (reg))
 #define	OVL_V_WRITE(sc, reg, val)			\
-	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, OVL_V_BASE + (reg), (val))
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE(0) + (reg), (val))
 
-#define	OVL_UI_READ(sc, reg)				\
-	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, OVL_UI_BASE + (reg))
-#define	OVL_UI_WRITE(sc, reg, val)			\
-	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, OVL_UI_BASE + (reg), (val))
+#define	OVL_UI_READ(sc, n, reg)				\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE((n) + 1) + (reg))
+#define	OVL_UI_WRITE(sc, n, reg, val)			\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, OVL_BASE((n) + 1) + (reg), (val))
 
 #define	VSU_READ(sc, reg)				\
 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, VSU_BASE + (reg))
@@ -220,7 +237,7 @@ struct sunxi_mixer_softc {
 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, CSC_BASE(n) + (reg), (val))
 
 #define	to_sunxi_mixer_crtc(x)		container_of(x, struct sunxi_mixer_crtc, base)
-#define	to_sunxi_mixer_overlay(x)	container_of(x, struct sunxi_mixer_overlay, base)
+#define	to_sunxi_mixer_plane(x)	container_of(x, struct sunxi_mixer_plane, base)
 
 static int
 sunxi_mixer_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb,
@@ -231,6 +248,7 @@ sunxi_mixer_mode_do_set_base(struct drm_
 	struct sunxi_drm_framebuffer *sfb = atomic?
 	    to_sunxi_drm_framebuffer(fb) :
 	    to_sunxi_drm_framebuffer(crtc->primary->fb);
+	uint32_t val;
 
 	uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr;
 
@@ -238,8 +256,11 @@ sunxi_mixer_mode_do_set_base(struct drm_
 	uint32_t laddr = paddr & 0xffffffff;
 
 	/* Framebuffer start address */
-	OVL_UI_WRITE(sc, OVL_UI_TOP_HADD, haddr);
-	OVL_UI_WRITE(sc, OVL_UI_TOP_LADD(0), laddr);
+	val = OVL_UI_READ(sc, 0, OVL_UI_TOP_HADD);
+	val &= ~OVL_UI_TOP_HADD_LAYER0;
+	val |= __SHIFTIN(haddr, OVL_UI_TOP_HADD_LAYER0);
+	OVL_UI_WRITE(sc, 0, OVL_UI_TOP_HADD, val);
+	OVL_UI_WRITE(sc, 0, OVL_UI_TOP_LADD(0), laddr);
 
 	return 0;
 }
@@ -274,10 +295,137 @@ sunxi_mixer_page_flip(struct drm_crtc *c
 	return 0;
 }
 
+static int
+sunxi_mixer_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+    uint32_t handle, uint32_t width, uint32_t height)
+{
+	struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc);
+	struct sunxi_mixer_softc * const sc = mixer_crtc->sc;
+	struct drm_gem_object *gem_obj = NULL;
+	struct drm_gem_cma_object *obj;
+	uint32_t val;
+	int error;
+
+	/* Only mixers with more than one UI layer can support hardware cursors */
+	if (sc->sc_ovl_ui_count <= 1)
+		return -EINVAL;
+
+	if (handle == 0) {
+		val = BLD_READ(sc, BLD_FILL_COLOR_CTL);
+		val &= ~BLD_FILL_COLOR_CTL_P2_EN;
+		val |= BLD_FILL_COLOR_CTL_P2_FCEN;
+		BLD_WRITE(sc, BLD_FILL_COLOR_CTL, val);
+
+		error = 0;
+		goto done;
+	}
+
+	/* Arbitrary limits, the hardware layer can do 8192x8192 */
+	if (width > MIXER_CURSOR_MAXWIDTH || height > MIXER_CURSOR_MAXHEIGHT) {
+		DRM_ERROR("Cursor dimension %ux%u not supported\n", width, height);
+		error = -EINVAL;
+		goto done;
+	}
+
+	gem_obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
+	if (gem_obj == NULL) {
+		DRM_ERROR("Cannot find cursor object %#x for crtc %d\n",
+		    handle, drm_crtc_index(crtc));
+		error = -ENOENT;
+		goto done;
+	}
+	obj = to_drm_gem_cma_obj(gem_obj);
+
+	if (obj->base.size < width * height * 4) {
+		DRM_ERROR("Cursor buffer is too small\n");
+		error = -ENOMEM;
+		goto done;
+	}
+
+	uint64_t paddr = (uint64_t)obj->dmamap->dm_segs[0].ds_addr;
+	uint32_t haddr = (paddr >> 32) & OVL_UI_TOP_HADD_LAYER0;
+	uint32_t laddr = paddr & 0xffffffff;
+
+	/* Framebuffer start address */
+	val = OVL_UI_READ(sc, 1, OVL_UI_TOP_HADD);
+	val &= ~OVL_UI_TOP_HADD_LAYER0;
+	val |= __SHIFTIN(haddr, OVL_UI_TOP_HADD_LAYER0);
+	OVL_UI_WRITE(sc, 1, OVL_UI_TOP_HADD, val);
+	OVL_UI_WRITE(sc, 1, OVL_UI_TOP_LADD(0), laddr);
+
+	const uint32_t size = ((height - 1) << 16) | (width - 1);
+	const uint32_t offset = (crtc->cursor_y << 16) | crtc->cursor_x;
+	const uint32_t crtc_size = ((crtc->primary->fb->height - 1) << 16) |
+	    (crtc->primary->fb->width - 1);
+
+	/* Enable cursor in ARGB8888 mode */
+	val = OVL_UI_ATTR_CTL_LAY_EN |
+	      __SHIFTIN(OVL_UI_ATTR_CTL_LAY_FBFMT_ARGB_8888, OVL_UI_ATTR_CTL_LAY_FBFMT);
+	OVL_UI_WRITE(sc, 1, OVL_UI_ATTR_CTL(0), val);
+	/* Set UI overlay layer size */
+	OVL_UI_WRITE(sc, 1, OVL_UI_MBSIZE(0), size);
+	/* Set UI overlay offset */
+	OVL_UI_WRITE(sc, 1, OVL_UI_COOR(0), offset);
+	/* Set UI overlay line size */
+	OVL_UI_WRITE(sc, 1, OVL_UI_PITCH(0), width * 4);
+	/* Set UI overlay window size */
+	OVL_UI_WRITE(sc, 1, OVL_UI_SIZE, crtc_size);
+
+	/* Set blender 2 input size */
+	BLD_WRITE(sc, BLD_CH_ISIZE(2), crtc_size);
+	/* Set blender 2 offset */
+	BLD_WRITE(sc, BLD_CH_OFFSET(2), 0);
+	/* Route channel 2 to pipe 2 */
+	val = BLD_READ(sc, BLD_CH_RTCTL);
+	val &= ~BLD_CH_RTCTL_P2;
+	val |= __SHIFTIN(2, BLD_CH_RTCTL_P2);
+	BLD_WRITE(sc, BLD_CH_RTCTL, val);
+
+	/* Enable pipe 2 */
+	val = BLD_READ(sc, BLD_FILL_COLOR_CTL);
+	val |= BLD_FILL_COLOR_CTL_P2_EN;
+	val &= ~BLD_FILL_COLOR_CTL_P2_FCEN;
+	BLD_WRITE(sc, BLD_FILL_COLOR_CTL, val);
+
+	error = 0;
+
+done:
+	if (error == 0) {
+		/* Commit settings */
+		GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY);
+	}
+
+	if (gem_obj != NULL)
+		drm_gem_object_unreference_unlocked(gem_obj);
+
+	return error;
+}
+
+static int
+sunxi_mixer_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc);
+	struct sunxi_mixer_softc * const sc = mixer_crtc->sc;
+
+	crtc->cursor_x = x & 0xffff;
+	crtc->cursor_y = y & 0xffff;
+
+	const uint32_t offset = (crtc->cursor_y << 16) | crtc->cursor_x;
+
+	OVL_UI_WRITE(sc, 1, OVL_UI_COOR(0), offset);
+
+	/* Commit settings */
+	GLB_WRITE(sc, GLB_DBUFFER, GLB_DBUFFER_DOUBLE_BUFFER_RDY);
+
+	return 0;
+}
+
 static const struct drm_crtc_funcs sunxi_mixer_crtc_funcs = {
 	.set_config = drm_crtc_helper_set_config,
-	.page_flip = sunxi_mixer_page_flip,
 	.destroy = sunxi_mixer_destroy,
+	.page_flip = sunxi_mixer_page_flip,
+	.cursor_set = sunxi_mixer_cursor_set,
+	.cursor_move = sunxi_mixer_cursor_move,
 };
 
 static void
@@ -300,6 +448,7 @@ sunxi_mixer_mode_set(struct drm_crtc *cr
 	struct sunxi_mixer_crtc *mixer_crtc = to_sunxi_mixer_crtc(crtc);
 	struct sunxi_mixer_softc * const sc = mixer_crtc->sc;
 	uint32_t val;
+	u_int fbfmt;
 
 	const uint32_t size = ((adjusted_mode->vdisplay - 1) << 16) |
 			      (adjusted_mode->hdisplay - 1);
@@ -325,18 +474,21 @@ sunxi_mixer_mode_set(struct drm_crtc *cr
 	/* Set blender output size */
 	BLD_WRITE(sc, BLD_SIZE, size);
 
-	/* Enable UI overlay in XRGB8888 mode */
-	val = OVL_UI_ATTR_CTL_LAY_EN |
-	      __SHIFTIN(OVL_UI_ATTR_CTL_LAY_FBFMT_XRGB_8888, OVL_UI_ATTR_CTL_LAY_FBFMT);
-	OVL_UI_WRITE(sc, OVL_UI_ATTR_CTL(0), val);
+	/* Enable UI overlay */
+	if (crtc->primary->fb->pixel_format == DRM_FORMAT_XRGB8888)
+		fbfmt = OVL_UI_ATTR_CTL_LAY_FBFMT_XRGB_8888;
+	else
+		fbfmt = OVL_UI_ATTR_CTL_LAY_FBFMT_ARGB_8888;
+	val = OVL_UI_ATTR_CTL_LAY_EN | __SHIFTIN(fbfmt, OVL_UI_ATTR_CTL_LAY_FBFMT);
+	OVL_UI_WRITE(sc, 0, OVL_UI_ATTR_CTL(0), val);
 	/* Set UI overlay layer size */
-	OVL_UI_WRITE(sc, OVL_UI_MBSIZE(0), size);
+	OVL_UI_WRITE(sc, 0, OVL_UI_MBSIZE(0), size);
 	/* Set UI overlay offset */
-	OVL_UI_WRITE(sc, OVL_UI_COOR(0), offset);
+	OVL_UI_WRITE(sc, 0, OVL_UI_COOR(0), offset);
 	/* Set UI overlay line size */
-	OVL_UI_WRITE(sc, OVL_UI_PITCH(0), adjusted_mode->hdisplay * 4);
+	OVL_UI_WRITE(sc, 0, OVL_UI_PITCH(0), adjusted_mode->hdisplay * 4);
 	/* Set UI overlay window size */
-	OVL_UI_WRITE(sc, OVL_UI_SIZE, size);
+	OVL_UI_WRITE(sc, 0, OVL_UI_SIZE, size);
 
 	sunxi_mixer_mode_do_set_base(crtc, old_fb, x, y, 0);
 
@@ -418,6 +570,7 @@ static bool
 sunxi_mixer_overlay_rgb(uint32_t drm_format)
 {
 	switch (drm_format) {
+	case DRM_FORMAT_ARGB8888:
 	case DRM_FORMAT_XRGB8888:
 		return true;
 	default:
@@ -429,6 +582,7 @@ static u_int
 sunxi_mixer_overlay_format(uint32_t drm_format)
 {
 	switch (drm_format) {
+	case DRM_FORMAT_ARGB8888:	return OVL_V_ATTCTL_LAY_FBFMT_ARGB_8888;
 	case DRM_FORMAT_XRGB8888:	return OVL_V_ATTCTL_LAY_FBFMT_XRGB_8888;
 	case DRM_FORMAT_VYUY:		return OVL_V_ATTCTL_LAY_FBFMT_VYUY;
 	case DRM_FORMAT_YVYU:		return OVL_V_ATTCTL_LAY_FBFMT_YVYU;
@@ -888,7 +1042,7 @@ sunxi_mixer_overlay_update_plane(struct 
     struct drm_framebuffer *fb, int crtc_x, int crtc_y, u_int crtc_w, u_int crtc_h,
     uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
 {
-	struct sunxi_mixer_overlay *overlay = to_sunxi_mixer_overlay(plane);
+	struct sunxi_mixer_plane *overlay = to_sunxi_mixer_plane(plane);
 	struct sunxi_mixer_softc * const sc = overlay->sc;
 	struct sunxi_drm_framebuffer *sfb = to_sunxi_drm_framebuffer(fb);
 	uint32_t val;
@@ -967,7 +1121,7 @@ sunxi_mixer_overlay_update_plane(struct 
 static int
 sunxi_mixer_overlay_disable_plane(struct drm_plane *plane)
 {
-	struct sunxi_mixer_overlay *overlay = to_sunxi_mixer_overlay(plane);
+	struct sunxi_mixer_plane *overlay = to_sunxi_mixer_plane(plane);
 	struct sunxi_mixer_softc * const sc = overlay->sc;
 	uint32_t val;
 
@@ -990,6 +1144,7 @@ static const struct drm_plane_funcs sunx
 };
 
 static uint32_t sunxi_mixer_overlay_formats[] = {
+	DRM_FORMAT_ARGB8888,
 	DRM_FORMAT_XRGB8888,
 #if notyet
 	DRM_FORMAT_VYUY,
@@ -1007,6 +1162,7 @@ sunxi_mixer_ep_activate(device_t dev, st
 {
 	struct sunxi_mixer_softc * const sc = device_private(dev);
 	struct drm_device *ddev;
+	bus_size_t reg;
 
 	if (!activate)
 		return EINVAL;
@@ -1020,6 +1176,14 @@ sunxi_mixer_ep_activate(device_t dev, st
 	sc->sc_crtc.sc = sc;
 	sc->sc_overlay.sc = sc;
 
+	/* Initialize registers */
+	for (reg = 0; reg < 0xc000; reg += 4)
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, 0);
+	BLD_WRITE(sc, BLD_CTL(0), 0x03010301);
+	BLD_WRITE(sc, BLD_CTL(1), 0x03010301);
+	BLD_WRITE(sc, BLD_CTL(2), 0x03010301);
+	BLD_WRITE(sc, BLD_CTL(3), 0x03010301);
+
 	drm_crtc_init(ddev, &sc->sc_crtc.base, &sunxi_mixer_crtc_funcs);
 	drm_crtc_helper_add(&sc->sc_crtc.base, &sunxi_mixer_crtc_helper_funcs);
 
@@ -1044,7 +1208,7 @@ sunxi_mixer_match(device_t parent, cfdat
 {
 	struct fdt_attach_args * const faa = aux;
 
-	return of_match_compatible(faa->faa_phandle, compatible);
+	return of_match_compat_data(faa->faa_phandle, compat_data);
 }
 
 static void
@@ -1091,6 +1255,7 @@ sunxi_mixer_attach(device_t parent, devi
 		return;
 	}
 	sc->sc_phandle = faa->faa_phandle;
+	sc->sc_ovl_ui_count = of_search_compatible(phandle, compat_data)->data;
 
 	aprint_naive("\n");
 	aprint_normal(": Display Engine Mixer\n");

Reply via email to