Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/rockchip WIP display driver for Rockchip RK3399
details: https://anonhg.NetBSD.org/src/rev/e0aa6c2eac6c
branches: trunk
changeset: 1004685:e0aa6c2eac6c
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Nov 09 23:30:14 2019 +0000
description:
WIP display driver for Rockchip RK3399
diffstat:
sys/arch/arm/rockchip/files.rockchip | 22 +-
sys/arch/arm/rockchip/rk_drm.c | 514 +++++++++++++++++++++++++++
sys/arch/arm/rockchip/rk_drm.h | 99 +++++
sys/arch/arm/rockchip/rk_dwhdmi.c | 293 +++++++++++++++
sys/arch/arm/rockchip/rk_fb.c | 160 ++++++++
sys/arch/arm/rockchip/rk_vop.c | 659 +++++++++++++++++++++++++++++++++++
6 files changed, 1746 insertions(+), 1 deletions(-)
diffs (truncated from 1781 to 300 lines):
diff -r d47e67e16ddc -r e0aa6c2eac6c sys/arch/arm/rockchip/files.rockchip
--- a/sys/arch/arm/rockchip/files.rockchip Sat Nov 09 23:29:48 2019 +0000
+++ b/sys/arch/arm/rockchip/files.rockchip Sat Nov 09 23:30:14 2019 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.rockchip,v 1.20 2019/08/05 15:22:59 tnn Exp $
+# $NetBSD: files.rockchip,v 1.21 2019/11/09 23:30:14 jmcneill Exp $
#
# Configuration info for Rockchip family SoCs
#
@@ -83,6 +83,26 @@
attach rkpwm at fdt with rk_pwm
file arch/arm/rockchip/rk_pwm.c rk_pwm
+# DRM master
+define rkfbbus { }
+device rkdrm: drmkms, ddc_read_edid, rkfbbus
+attach rkdrm at fdt with rk_drm
+file arch/arm/rockchip/rk_drm.c rk_drm
+
+# DRM framebuffer console
+device rkfb: rkfbbus, drmfb, wsemuldisplaydev
+attach rkfb at rkfbbus with rk_fb
+file arch/arm/rockchip/rk_fb.c rk_fb
+
+# Visual Output Processor
+device rkvop: drmkms
+attach rkvop at fdt with rk_vop
+file arch/arm/rockchip/rk_vop.c rk_vop
+
+# HDMI TX (Designware based)
+attach dwhdmi at fdt with rk_dwhdmi
+file arch/arm/rockchip/rk_dwhdmi.c rk_dwhdmi
+
# SOC parameters
defflag opt_soc.h SOC_ROCKCHIP
defflag opt_soc.h SOC_RK3328: SOC_ROCKCHIP
diff -r d47e67e16ddc -r e0aa6c2eac6c sys/arch/arm/rockchip/rk_drm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/rockchip/rk_drm.c Sat Nov 09 23:30:14 2019 +0000
@@ -0,0 +1,514 @@
+/* $NetBSD: rk_drm.c,v 1.1 2019/11/09 23:30:14 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rk_drm.c,v 1.1 2019/11/09 23:30:14 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+
+#include <uvm/uvm_extern.h>
+#include <uvm/uvm_object.h>
+#include <uvm/uvm_device.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/fdt_port.h>
+
+#include <arm/rockchip/rk_drm.h>
+
+#define RK_DRM_MAX_WIDTH 3840
+#define RK_DRM_MAX_HEIGHT 2160
+
+static TAILQ_HEAD(, rk_drm_ports) rk_drm_ports =
+ TAILQ_HEAD_INITIALIZER(rk_drm_ports);
+
+static const char * const compatible[] = {
+ "rockchip,display-subsystem",
+ NULL
+};
+
+static const char * fb_compatible[] = {
+ "simple-framebuffer",
+ NULL
+};
+
+static int rk_drm_match(device_t, cfdata_t, void *);
+static void rk_drm_attach(device_t, device_t, void *);
+
+static void rk_drm_init(device_t);
+static vmem_t *rk_drm_alloc_cma_pool(struct drm_device *, size_t);
+
+static int rk_drm_set_busid(struct drm_device *, struct drm_master *);
+
+static uint32_t rk_drm_get_vblank_counter(struct drm_device *, unsigned int);
+static int rk_drm_enable_vblank(struct drm_device *, unsigned int);
+static void rk_drm_disable_vblank(struct drm_device *, unsigned int);
+
+static int rk_drm_load(struct drm_device *, unsigned long);
+static int rk_drm_unload(struct drm_device *);
+
+static struct drm_driver rk_drm_driver = {
+ .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+ .dev_priv_size = 0,
+ .load = rk_drm_load,
+ .unload = rk_drm_unload,
+
+ .gem_free_object = drm_gem_cma_free_object,
+ .mmap_object = drm_gem_or_legacy_mmap_object,
+ .gem_uvm_ops = &drm_gem_cma_uvm_ops,
+
+ .dumb_create = drm_gem_cma_dumb_create,
+ .dumb_map_offset = drm_gem_cma_dumb_map_offset,
+ .dumb_destroy = drm_gem_dumb_destroy,
+
+ .get_vblank_counter = rk_drm_get_vblank_counter,
+ .enable_vblank = rk_drm_enable_vblank,
+ .disable_vblank = rk_drm_disable_vblank,
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+
+ .set_busid = rk_drm_set_busid,
+};
+
+CFATTACH_DECL_NEW(rk_drm, sizeof(struct rk_drm_softc),
+ rk_drm_match, rk_drm_attach, NULL, NULL);
+
+static int
+rk_drm_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+rk_drm_attach(device_t parent, device_t self, void *aux)
+{
+ struct rk_drm_softc * const sc = device_private(self);
+ struct fdt_attach_args * const faa = aux;
+ struct drm_driver * const driver = &rk_drm_driver;
+ prop_dictionary_t dict = device_properties(self);
+ bool is_disabled;
+
+ sc->sc_dev = self;
+ sc->sc_dmat = faa->faa_dmat;
+ sc->sc_bst = faa->faa_bst;
+ sc->sc_phandle = faa->faa_phandle;
+
+ drm_debug = 0xff;
+
+ aprint_naive("\n");
+
+ if (prop_dictionary_get_bool(dict, "disabled", &is_disabled) && is_disabled) {
+ aprint_normal(": (disabled)\n");
+ return;
+ }
+
+ aprint_normal("\n");
+
+ sc->sc_ddev = drm_dev_alloc(driver, sc->sc_dev);
+ if (sc->sc_ddev == NULL) {
+ aprint_error_dev(self, "couldn't allocate DRM device\n");
+ return;
+ }
+ sc->sc_ddev->dev_private = sc;
+ sc->sc_ddev->bst = sc->sc_bst;
+ sc->sc_ddev->bus_dmat = sc->sc_dmat;
+ sc->sc_ddev->dmat = sc->sc_ddev->bus_dmat;
+ sc->sc_ddev->dmat_subregion_p = false;
+
+ fdt_remove_bycompat(fb_compatible);
+
+ config_defer(self, rk_drm_init);
+}
+
+static void
+rk_drm_init(device_t dev)
+{
+ struct rk_drm_softc * const sc = device_private(dev);
+ struct drm_driver * const driver = &rk_drm_driver;
+ int error;
+
+ error = -drm_dev_register(sc->sc_ddev, 0);
+ if (error) {
+ drm_dev_unref(sc->sc_ddev);
+ aprint_error_dev(dev, "couldn't register DRM device: %d\n",
+ error);
+ return;
+ }
+
+ aprint_normal_dev(dev, "initialized %s %d.%d.%d %s on minor %d\n",
+ driver->name, driver->major, driver->minor, driver->patchlevel,
+ driver->date, sc->sc_ddev->primary->index);
+}
+
+static vmem_t *
+rk_drm_alloc_cma_pool(struct drm_device *ddev, size_t cma_size)
+{
+ struct rk_drm_softc * const sc = rk_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("rkdrm", segs[0].ds_addr, segs[0].ds_len,
+ PAGE_SIZE, NULL, NULL, NULL, 0, VM_SLEEP, IPL_NONE);
+}
+
+static int
+rk_drm_set_busid(struct drm_device *ddev, struct drm_master *master)
+{
+ struct rk_drm_softc * const sc = rk_drm_private(ddev);
+ char id[32];
+
+ snprintf(id, sizeof(id), "platform:rk:%u", device_unit(sc->sc_dev));
+
+ master->unique = kzalloc(strlen(id) + 1, GFP_KERNEL);
+ if (master->unique == NULL)
+ return -ENOMEM;
+ strcpy(master->unique, id);
+ master->unique_len = strlen(master->unique);
+
+ return 0;
+}
+
+static int
+rk_drm_fb_create_handle(struct drm_framebuffer *fb,
+ struct drm_file *file, unsigned int *handle)
+{
+ struct rk_drm_framebuffer *sfb = to_rk_drm_framebuffer(fb);
+
+ return drm_gem_handle_create(file, &sfb->obj->base, handle);
+}
+
+static void
+rk_drm_fb_destroy(struct drm_framebuffer *fb)
+{
+ struct rk_drm_framebuffer *sfb = to_rk_drm_framebuffer(fb);
+
+ drm_framebuffer_cleanup(fb);
+ drm_gem_object_unreference_unlocked(&sfb->obj->base);
+ kmem_free(sfb, sizeof(*sfb));
+}
+
+static const struct drm_framebuffer_funcs rk_drm_framebuffer_funcs = {
+ .create_handle = rk_drm_fb_create_handle,
+ .destroy = rk_drm_fb_destroy,
+};
+
+static struct drm_framebuffer *
+rk_drm_fb_create(struct drm_device *ddev, struct drm_file *file,
+ struct drm_mode_fb_cmd2 *cmd)
+{
+ struct rk_drm_framebuffer *fb;
+ struct drm_gem_object *gem_obj;
+ int error;
+
+ if (cmd->flags)
+ return NULL;
+
+ gem_obj = drm_gem_object_lookup(ddev, file, cmd->handles[0]);
+ if (gem_obj == NULL)
+ return NULL;
+
+ fb = kmem_zalloc(sizeof(*fb), KM_SLEEP);
+ fb->obj = to_drm_gem_cma_obj(gem_obj);
Home |
Main Index |
Thread Index |
Old Index