Module Name:    src
Committed By:   martin
Date:           Wed Nov  6 09:48:32 UTC 2019

Modified Files:
        src/sys/arch/arm/sunxi [netbsd-9]: sunxi_drm.c
        src/sys/external/bsd/drm2/dist/include/drm [netbsd-9]: drmP.h
            drm_gem_cma_helper.h
        src/sys/external/bsd/drm2/drm [netbsd-9]: drm_gem_cma_helper.c
        src/sys/external/bsd/drm2/include/drm [netbsd-9]: bus_dma_hacks.h
            drm_os_netbsd.h

Log Message:
Pull up following revision(s) (requested by jmcneill in ticket #400):

        sys/arch/arm/sunxi/sunxi_drm.c: revision 1.8
        sys/external/bsd/drm2/dist/include/drm/drm_gem_cma_helper.h: revision 
1.6
        sys/external/bsd/drm2/dist/include/drm/drmP.h: revision 1.36
        sys/external/bsd/drm2/include/drm/bus_dma_hacks.h: revision 1.18
        sys/external/bsd/drm2/drm/drm_gem_cma_helper.c: revision 1.9
        sys/external/bsd/drm2/include/drm/drm_os_netbsd.h: revision 1.15

Arm DMA tags with _nranges=0 require no address translation. Handle this
in PHYS_TO_BUS_MEM and BUS_TO_PHYS_MEM instead of panicing.

Add support for DRM GEM/CMA helpers using a driver provided vmem arena.

Reserve enough memory at boot to support the drmfb buffer plus a 4K buffer
for Xorg.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.7.6.1 src/sys/arch/arm/sunxi/sunxi_drm.c
cvs rdiff -u -r1.35 -r1.35.4.1 \
    src/sys/external/bsd/drm2/dist/include/drm/drmP.h
cvs rdiff -u -r1.5 -r1.5.4.1 \
    src/sys/external/bsd/drm2/dist/include/drm/drm_gem_cma_helper.h
cvs rdiff -u -r1.7.4.1 -r1.7.4.2 \
    src/sys/external/bsd/drm2/drm/drm_gem_cma_helper.c
cvs rdiff -u -r1.17 -r1.17.4.1 \
    src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h
cvs rdiff -u -r1.14 -r1.14.4.1 \
    src/sys/external/bsd/drm2/include/drm/drm_os_netbsd.h

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.7 src/sys/arch/arm/sunxi/sunxi_drm.c:1.7.6.1
--- src/sys/arch/arm/sunxi/sunxi_drm.c:1.7	Wed Feb  6 03:07:08 2019
+++ src/sys/arch/arm/sunxi/sunxi_drm.c	Wed Nov  6 09:48:31 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_drm.c,v 1.7 2019/02/06 03:07:08 jmcneill Exp $ */
+/* $NetBSD: sunxi_drm.c,v 1.7.6.1 2019/11/06 09:48:31 martin 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.7 2019/02/06 03:07:08 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_drm.c,v 1.7.6.1 2019/11/06 09:48:31 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -50,6 +50,9 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_drm.c,
 
 #include <arm/sunxi/sunxi_drm.h>
 
+#define	SUNXI_DRM_MAX_WIDTH	3840
+#define	SUNXI_DRM_MAX_HEIGHT	2160
+
 static TAILQ_HEAD(, sunxi_drm_endpoint) sunxi_drm_endpoints =
     TAILQ_HEAD_INITIALIZER(sunxi_drm_endpoints);
 
@@ -68,6 +71,7 @@ static int	sunxi_drm_match(device_t, cfd
 static void	sunxi_drm_attach(device_t, device_t, void *);
 
 static void	sunxi_drm_init(device_t);
+static vmem_t	*sunxi_drm_alloc_cma_pool(struct drm_device *, size_t);
 
 static int	sunxi_drm_set_busid(struct drm_device *, struct drm_master *);
 
@@ -176,6 +180,25 @@ sunxi_drm_init(device_t dev)
 	    driver->date, sc->sc_ddev->primary->index);
 }
 
+static vmem_t *
+sunxi_drm_alloc_cma_pool(struct drm_device *ddev, size_t cma_size)
+{
+	struct sunxi_drm_softc * const sc = sunxi_drm_private(ddev);
+	bus_dma_segment_t segs[1];
+	int nsegs;
+	int error;
+
+	error = bus_dmamem_alloc(sc->sc_dmat, cma_size, PAGE_SIZE, 0,
+	    segs, 1, &nsegs, BUS_DMA_NOWAIT);
+	if (error) {
+		aprint_error_dev(sc->sc_dev, "couldn't allocate CMA pool\n");
+		return NULL;
+	}
+
+	return vmem_create("sunxidrm", segs[0].ds_addr, segs[0].ds_len,
+	    PAGE_SIZE, NULL, NULL, NULL, 0, VM_SLEEP, IPL_NONE);
+}
+
 static int
 sunxi_drm_set_busid(struct drm_device *ddev, struct drm_master *master)
 {
@@ -280,6 +303,7 @@ sunxi_drm_fb_probe(struct drm_fb_helper 
 	struct sunxi_drm_framebuffer *sfb = to_sunxi_drm_framebuffer(helper->fb);
 	struct drm_framebuffer *fb = helper->fb;
 	struct sunxi_drmfb_attach_args sfa;
+	size_t cma_size;
 	int error;
 
 	const u_int width = sizes->surface_width;
@@ -288,6 +312,15 @@ sunxi_drm_fb_probe(struct drm_fb_helper 
 
 	const size_t size = roundup(height * pitch, PAGE_SIZE);
 
+	/* Reserve enough memory for the FB console plus a 4K plane, rounded to 1MB */
+	cma_size = size;
+	cma_size += (SUNXI_DRM_MAX_WIDTH * SUNXI_DRM_MAX_HEIGHT * 4);
+	cma_size = roundup(cma_size, 1024 * 1024);
+	sc->sc_ddev->cma_pool = sunxi_drm_alloc_cma_pool(sc->sc_ddev, cma_size);
+	if (sc->sc_ddev->cma_pool != NULL)
+		aprint_normal_dev(sc->sc_dev, "reserved %u MB DRAM for CMA\n",
+		    (u_int)(cma_size / (1024 * 1024)));
+
 	sfb->obj = drm_gem_cma_create(ddev, size);
 	if (sfb->obj == NULL) {
 		DRM_ERROR("failed to allocate memory for framebuffer\n");
@@ -340,8 +373,8 @@ sunxi_drm_load(struct drm_device *ddev, 
 	drm_mode_config_init(ddev);
 	ddev->mode_config.min_width = 0;
 	ddev->mode_config.min_height = 0;
-	ddev->mode_config.max_width = 3840;
-	ddev->mode_config.max_height = 2160;
+	ddev->mode_config.max_width = SUNXI_DRM_MAX_WIDTH;
+	ddev->mode_config.max_height = SUNXI_DRM_MAX_HEIGHT;
 	ddev->mode_config.funcs = &sunxi_drm_mode_config_funcs;
 
 	num_crtc = 0;

Index: src/sys/external/bsd/drm2/dist/include/drm/drmP.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.35 src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.35.4.1
--- src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.35	Fri Dec 21 07:51:18 2018
+++ src/sys/external/bsd/drm2/dist/include/drm/drmP.h	Wed Nov  6 09:48:31 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: drmP.h,v 1.35 2018/12/21 07:51:18 maya Exp $	*/
+/*	$NetBSD: drmP.h,v 1.35.4.1 2019/11/06 09:48:31 martin Exp $	*/
 
 /*
  * Internal Header for the Direct Rendering Manager
@@ -931,6 +931,7 @@ struct drm_device {
 	bool dmat_subregion_p;
 	bus_addr_t dmat_subregion_min;
 	bus_addr_t dmat_subregion_max;
+	vmem_t *cma_pool;
 #endif
 
 	struct drm_sg_mem *sg;	/**< Scatter gather memory */

Index: src/sys/external/bsd/drm2/dist/include/drm/drm_gem_cma_helper.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/drm_gem_cma_helper.h:1.5 src/sys/external/bsd/drm2/dist/include/drm/drm_gem_cma_helper.h:1.5.4.1
--- src/sys/external/bsd/drm2/dist/include/drm/drm_gem_cma_helper.h:1.5	Mon Aug 27 15:26:15 2018
+++ src/sys/external/bsd/drm2/dist/include/drm/drm_gem_cma_helper.h	Wed Nov  6 09:48:31 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_gem_cma_helper.h,v 1.5 2018/08/27 15:26:15 riastradh Exp $	*/
+/*	$NetBSD: drm_gem_cma_helper.h,v 1.5.4.1 2019/11/06 09:48:31 martin Exp $	*/
 
 #ifndef __DRM_GEM_CMA_HELPER_H__
 #define __DRM_GEM_CMA_HELPER_H__
@@ -20,6 +20,8 @@ struct drm_gem_cma_object {
 	bus_dma_segment_t dmasegs[1];
 	bus_size_t dmasize;
 	bus_dmamap_t dmamap;
+	vmem_t *vmem_pool;
+	vmem_addr_t vmem_addr;
 #else
 	dma_addr_t paddr;
 #endif

Index: src/sys/external/bsd/drm2/drm/drm_gem_cma_helper.c
diff -u src/sys/external/bsd/drm2/drm/drm_gem_cma_helper.c:1.7.4.1 src/sys/external/bsd/drm2/drm/drm_gem_cma_helper.c:1.7.4.2
--- src/sys/external/bsd/drm2/drm/drm_gem_cma_helper.c:1.7.4.1	Wed Nov  6 09:43:20 2019
+++ src/sys/external/bsd/drm2/drm/drm_gem_cma_helper.c	Wed Nov  6 09:48:32 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_gem_cma_helper.c,v 1.7.4.1 2019/11/06 09:43:20 martin Exp $ */
+/* $NetBSD: drm_gem_cma_helper.c,v 1.7.4.2 2019/11/06 09:48:32 martin Exp $ */
 
 /*-
  * Copyright (c) 2015-2017 Jared McNeill <jmcne...@invisible.ca>
@@ -27,10 +27,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_gem_cma_helper.c,v 1.7.4.1 2019/11/06 09:43:20 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_gem_cma_helper.c,v 1.7.4.2 2019/11/06 09:48:32 martin Exp $");
 
 #include <drm/drmP.h>
 #include <drm/drm_gem_cma_helper.h>
+#include <drm/bus_dma_hacks.h>
 
 #include <uvm/uvm.h>
 
@@ -49,8 +50,24 @@ drm_gem_cma_create_internal(struct drm_d
 		error = -drm_prime_sg_to_bus_dmamem(obj->dmat, obj->dmasegs, 1,
 		    &nsegs, sgt);
 	} else {
-		error = bus_dmamem_alloc(obj->dmat, obj->dmasize, PAGE_SIZE, 0,
-		    obj->dmasegs, 1, &nsegs, BUS_DMA_WAITOK);
+		if (ddev->cma_pool != NULL) {
+			error = vmem_xalloc(ddev->cma_pool, obj->dmasize,
+			    PAGE_SIZE, 0, 0, VMEM_ADDR_MIN, VMEM_ADDR_MAX,
+			    VM_BESTFIT | VM_NOSLEEP, &obj->vmem_addr);
+			if (!error) {
+				obj->vmem_pool = ddev->cma_pool;
+				obj->dmasegs[0].ds_addr =
+				    PHYS_TO_BUS_MEM(obj->dmat, obj->vmem_addr);
+				obj->dmasegs[0].ds_len =
+				    roundup(obj->dmasize, PAGE_SIZE);
+				nsegs = 1;
+			}
+		}
+		if (obj->vmem_pool == NULL) {
+			error = bus_dmamem_alloc(obj->dmat, obj->dmasize,
+			    PAGE_SIZE, 0, obj->dmasegs, 1, &nsegs,
+			    BUS_DMA_WAITOK);
+		}
 	}
 	if (error)
 		goto failed;
@@ -80,7 +97,12 @@ destroy:
 unmap:
 	bus_dmamem_unmap(obj->dmat, obj->vaddr, obj->dmasize);
 free:
-	bus_dmamem_free(obj->dmat, obj->dmasegs, nsegs);
+	if (obj->sgt)
+		drm_prime_sg_free(obj->sgt);
+	else if (obj->vmem_pool)
+		vmem_xfree(obj->vmem_pool, obj->vmem_addr, obj->dmasize);
+	else
+		bus_dmamem_free(obj->dmat, obj->dmasegs, nsegs);
 failed:
 	kmem_free(obj, sizeof(*obj));
 
@@ -103,6 +125,8 @@ drm_gem_cma_obj_free(struct drm_gem_cma_
 	bus_dmamem_unmap(obj->dmat, obj->vaddr, obj->dmasize);
 	if (obj->sgt)
 		drm_prime_sg_free(obj->sgt);
+	else if (obj->vmem_pool)
+		vmem_xfree(obj->vmem_pool, obj->vmem_addr, obj->dmasize);
 	else
 		bus_dmamem_free(obj->dmat, obj->dmasegs, 1);
 	kmem_free(obj, sizeof(*obj));

Index: src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h
diff -u src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.17 src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.17.4.1
--- src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.17	Mon Aug 27 15:32:39 2018
+++ src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h	Wed Nov  6 09:48:32 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: bus_dma_hacks.h,v 1.17 2018/08/27 15:32:39 riastradh Exp $	*/
+/*	$NetBSD: bus_dma_hacks.h,v 1.17.4.1 2019/11/06 09:48:32 martin Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -51,6 +51,9 @@ PHYS_TO_BUS_MEM(bus_dma_tag_t dmat, padd
 {
 	unsigned i;
 
+	if (dmat->_nranges == 0)
+		return (bus_addr_t)pa;
+
 	for (i = 0; i < dmat->_nranges; i++) {
 		const struct arm32_dma_range *dr = &dmat->_ranges[i];
 
@@ -64,6 +67,9 @@ BUS_MEM_TO_PHYS(bus_dma_tag_t dmat, bus_
 {
 	unsigned i;
 
+	if (dmat->_nranges == 0)
+		return (paddr_t)ba;
+
 	for (i = 0; i < dmat->_nranges; i++) {
 		const struct arm32_dma_range *dr = &dmat->_ranges[i];
 

Index: src/sys/external/bsd/drm2/include/drm/drm_os_netbsd.h
diff -u src/sys/external/bsd/drm2/include/drm/drm_os_netbsd.h:1.14 src/sys/external/bsd/drm2/include/drm/drm_os_netbsd.h:1.14.4.1
--- src/sys/external/bsd/drm2/include/drm/drm_os_netbsd.h:1.14	Sun Apr  7 20:28:41 2019
+++ src/sys/external/bsd/drm2/include/drm/drm_os_netbsd.h	Wed Nov  6 09:48:32 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_os_netbsd.h,v 1.14 2019/04/07 20:28:41 maya Exp $	*/
+/*	$NetBSD: drm_os_netbsd.h,v 1.14.4.1 2019/11/06 09:48:32 martin Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -72,4 +72,6 @@
 #include <drm/drm_irq_netbsd.h>
 #include <drm/drm_wait_netbsd.h>
 
+#include <sys/vmem.h>
+
 #endif  /* _DRM_DRM_OS_NETBSD_H_ */

Reply via email to