Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/sunxi work in progress on porting graphics driv...



details:   https://anonhg.NetBSD.org/src/rev/3bd9873b34db
branches:  trunk
changeset: 831515:3bd9873b34db
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Tue Apr 03 12:52:16 2018 +0000

description:
work in progress on porting graphics drivers from arm/allwinner to fdt.
sunxidebe: display backend drivers
sunxitcon: lcd controller driver
sunxihdmi: hdmi controller driver
sunxidep: display engine pipeline driver. Its role is only to parse the
   fdt display-engine node, and activate de backend drivers based on the
   content of allwinner,pipelines

So far HDMI and lvds output works, in dual-framebuffer mode.
It has only been tested on A20. It should be OK on the A10 too, but
will likely need more work for other SoCs.
Console is not handled yet, and it conflicts with the simplefb driver if
it has been activated by u-boot.

diffstat:

 sys/arch/arm/sunxi/files.sunxi     |    24 +-
 sys/arch/arm/sunxi/sunxi_debe.c    |   937 +++++++++++++++++++++++++++
 sys/arch/arm/sunxi/sunxi_debereg.h |   138 ++++
 sys/arch/arm/sunxi/sunxi_dep.c     |   113 +++
 sys/arch/arm/sunxi/sunxi_display.h |    39 +
 sys/arch/arm/sunxi/sunxi_hdmi.c    |  1221 ++++++++++++++++++++++++++++++++++++
 sys/arch/arm/sunxi/sunxi_hdmireg.h |   299 ++++++++
 sys/arch/arm/sunxi/sunxi_tcon.c    |   817 ++++++++++++++++++++++++
 sys/arch/arm/sunxi/sunxi_tconreg.h |   125 +++
 9 files changed, 3712 insertions(+), 1 deletions(-)

diffs (truncated from 3759 to 300 lines):

diff -r 4411116f0e34 -r 3bd9873b34db sys/arch/arm/sunxi/files.sunxi
--- a/sys/arch/arm/sunxi/files.sunxi    Tue Apr 03 12:40:20 2018 +0000
+++ b/sys/arch/arm/sunxi/files.sunxi    Tue Apr 03 12:52:16 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.sunxi,v 1.47 2018/04/01 21:19:17 bouyer Exp $
+#      $NetBSD: files.sunxi,v 1.48 2018/04/03 12:52:16 bouyer Exp $
 #
 # Configuration info for Allwinner sunxi family SoCs
 #
@@ -189,6 +189,28 @@
 attach genfb at fdt with simplefb
 file   dev/fdt/simplefb.c                      simplefb
 
+# A10/A20 LCD/TV timing controller (TCON)
+device sunxitcon
+attach sunxitcon at fdt with sunxi_tcon
+file   arch/arm/sunxi/sunxi_tcon.c             sunxi_tcon needs-flag
+
+# A10/A20 Display engine backend (DE-BE)
+device sunxidebe { }
+attach sunxidebe at fdt with sunxi_debe
+file   arch/arm/sunxi/sunxi_debe.c             sunxi_debe needs-flag
+
+attach genfb at sunxidebe with sunxi_befb
+
+# A10/A20 HDMI
+device sunxihdmi: edid, videomode
+attach sunxihdmi at fdt with sunxi_hdmi
+file   arch/arm/sunxi/sunxi_hdmi.c             sunxi_hdmi needs-flag
+
+# A10/A20 display engine pipeline
+device sunxidep
+attach sunxidep at fdt with sunxi_dep
+file   arch/arm/sunxi/sunxi_dep.c              sunxi_dep
+
 # Touch Screen controller
 device sunxits: wsmousedev, tpcalib, sysmon_envsys
 attach sunxits at fdt with sunxi_ts
diff -r 4411116f0e34 -r 3bd9873b34db sys/arch/arm/sunxi/sunxi_debe.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/sunxi/sunxi_debe.c   Tue Apr 03 12:52:16 2018 +0000
@@ -0,0 +1,937 @@
+/* $NetBSD: sunxi_debe.c,v 1.3 2018/04/03 12:52:16 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2018 Manuel Bouyer <bouyer%antioche.eu.org@localhost>
+ * All rights reserved.
+ *
+ * Copyright (c) 2014 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 "genfb.h"
+
+#ifndef SUNXI_DEBE_VIDEOMEM
+#define SUNXI_DEBE_VIDEOMEM    (16 * 1024 * 1024)
+#endif
+
+#define SUNXI_DEBE_CURMAX      64
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c,v 1.3 2018/04/03 12:52:16 bouyer 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/mutex.h>
+#include <sys/condvar.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/fdt_port.h>
+
+#include <dev/videomode/videomode.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wsfb/genfbvar.h>
+
+#include <arm/sunxi/sunxi_debereg.h>
+#include <arm/sunxi/sunxi_display.h>
+
+enum sunxi_debe_type {
+       DEBE_A10 = 1,
+       DEBE_A20,
+};
+
+struct sunxi_debe_softc {
+       device_t sc_dev;
+       device_t sc_fbdev;
+       enum sunxi_debe_type sc_type;
+       bus_space_tag_t sc_bst;
+       bus_space_handle_t sc_bsh;
+       bus_dma_tag_t sc_dmat;
+
+       struct clk *sc_clk_ahb;
+       struct clk *sc_clk_mod;
+       struct clk *sc_clk_ram;
+
+       bus_dma_segment_t sc_dmasegs[1];
+       bus_size_t sc_dmasize;
+       bus_dmamap_t sc_dmamap;
+       void *sc_dmap;
+
+       bool sc_cursor_enable;
+       int sc_cursor_x, sc_cursor_y;
+       int sc_hot_x, sc_hot_y;
+       uint8_t sc_cursor_bitmap[8 * SUNXI_DEBE_CURMAX];
+       uint8_t sc_cursor_mask[8 * SUNXI_DEBE_CURMAX];
+
+       int     sc_phandle;
+       struct fdt_device_ports sc_ports;
+       struct fdt_endpoint *sc_out_ep;
+       int sc_unit; /* debe0 or debe1 */
+};
+
+#define DEBE_READ(sc, reg) \
+    bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define DEBE_WRITE(sc, reg, val) \
+    bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+static const struct of_compat_data compat_data[] = {
+       {"allwinner,sun4i-a10-display-backend", DEBE_A10},
+       {"allwinner,sun7i-a20-display-backend", DEBE_A20},
+       {NULL}
+};
+
+struct sunxifb_attach_args {
+       void *afb_fb;
+       uint32_t afb_width;
+       uint32_t afb_height;
+       bus_dma_tag_t afb_dmat;
+       bus_dma_segment_t *afb_dmasegs;
+       int afb_ndmasegs;
+};
+
+static void    sunxi_debe_ep_connect(device_t, struct fdt_endpoint *, bool);
+static int     sunxi_debe_ep_enable(device_t, struct fdt_endpoint *, bool);
+static int     sunxi_debe_match(device_t, cfdata_t, void *);
+static void    sunxi_debe_attach(device_t, device_t, void *);
+
+static int     sunxi_debe_alloc_videomem(struct sunxi_debe_softc *);
+static void    sunxi_debe_setup_fbdev(struct sunxi_debe_softc *,
+                                     const struct videomode *);
+
+static int     sunxi_debe_set_curpos(struct sunxi_debe_softc *, int, int);
+static int     sunxi_debe_set_cursor(struct sunxi_debe_softc *,
+                                    struct wsdisplay_cursor *);
+static int     sunxi_debe_ioctl(device_t, u_long, void *);
+static void    sunxi_befb_set_videomode(device_t, u_int, u_int);
+void sunxi_debe_dump_regs(int);
+
+CFATTACH_DECL_NEW(sunxi_debe, sizeof(struct sunxi_debe_softc),
+       sunxi_debe_match, sunxi_debe_attach, NULL, NULL);
+
+static int
+sunxi_debe_match(device_t parent, cfdata_t cf, void *aux)
+{
+       struct fdt_attach_args * const faa = aux;
+
+       return of_match_compat_data(faa->faa_phandle, compat_data);
+}
+
+static void
+sunxi_debe_attach(device_t parent, device_t self, void *aux)
+{
+       struct sunxi_debe_softc *sc = device_private(self);
+       struct fdt_attach_args * const faa = aux;
+       const int phandle = faa->faa_phandle;
+       bus_addr_t addr;
+       bus_size_t size;
+       struct fdtbus_reset *rst;
+#if NAWIN_MP > 0
+       device_t mpdev;
+#endif
+#ifdef AWIN_DEBE_FWINIT
+       struct videomode mode;
+#endif
+       int error;
+
+       sc->sc_dev = self;
+       sc->sc_phandle = phandle;
+       sc->sc_bst = faa->faa_bst;
+       sc->sc_dmat = faa->faa_dmat;
+       if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+               aprint_error(": couldn't get registers\n");
+       }
+       if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+               aprint_error(": couldn't map registers\n");
+               return;
+       }
+
+       sc->sc_clk_ahb = fdtbus_clock_get(phandle, "ahb");
+       sc->sc_clk_mod = fdtbus_clock_get(phandle, "mod");
+       sc->sc_clk_ram = fdtbus_clock_get(phandle, "ram");
+
+       rst = fdtbus_reset_get_index(phandle, 0);
+       if (rst == NULL) {
+               aprint_error(": couldn't get reset\n");
+               return;
+       }
+       if (fdtbus_reset_assert(rst) != 0) {
+               aprint_error(": couldn't assert reset\n");
+               return;
+       }
+       delay(1);
+       if (fdtbus_reset_deassert(rst) != 0) {
+               aprint_error(": couldn't de-assert reset\n");
+               return;
+       }
+
+       if (sc->sc_clk_ahb == NULL || sc->sc_clk_mod == NULL
+           || sc->sc_clk_ram == NULL) {
+               aprint_error(": couldn't get clocks\n");
+               aprint_debug_dev(self, "clk ahb %s mod %s ram %s\n",
+                   sc->sc_clk_ahb == NULL ? "missing" : "present",
+                   sc->sc_clk_mod == NULL ? "missing" : "present",
+                   sc->sc_clk_ram == NULL ? "missing" : "present");
+               return;
+       }
+
+       error = clk_set_rate(sc->sc_clk_mod, 300000000);
+       if (error) {
+               aprint_error("couln't set mod clock rate (%d)\n", error);
+               return;
+       }
+
+       if (clk_enable(sc->sc_clk_ahb) != 0 ||
+           clk_enable(sc->sc_clk_mod) != 0 ||
+           clk_enable(sc->sc_clk_ram) != 0) {
+               aprint_error(": couldn't enable clocks\n");
+               return;
+       }
+
+       sc->sc_type = of_search_compatible(faa->faa_phandle, compat_data)->data;
+
+       aprint_naive("\n");
+       aprint_normal(": Display Engine Backend (%s)\n",
+           fdtbus_get_string(phandle, "name"));
+
+
+#ifdef AWIN_DEBE_FWINIT
+       const uint32_t modctl = DEBE_READ(sc, SUNXI_DEBE_MODCTL_REG);
+       const uint32_t dissize = DEBE_READ(sc, SUNXI_DEBE_DISSIZE_REG);
+       if ((modctl & SUNXI_DEBE_MODCTL_EN) == 0) {
+               aprint_error_dev(sc->sc_dev, "disabled\n");
+               return;
+       }
+       if ((modctl & SUNXI_DEBE_MODCTL_START_CTL) == 0) {
+               aprint_error_dev(sc->sc_dev, "stopped\n");
+               return;
+       }
+       memset(&mode, 0, sizeof(mode));
+       mode.hdisplay = (dissize & 0xffff) + 1;
+       mode.vdisplay = ((dissize >> 16) & 0xffff) + 1;
+
+       if (mode.hdisplay == 1 || mode.vdisplay == 1) {
+               aprint_error_dev(sc->sc_dev,
+                   "couldn't determine video mode\n");
+               return;
+       }
+
+       aprint_verbose_dev(sc->sc_dev, "using %dx%d mode from firmware\n",
+           mode.hdisplay, mode.vdisplay);
+
+       sc->sc_dmasize = mode.hdisplay * mode.vdisplay * 4;
+#else
+       for (unsigned int reg = 0x800; reg < 0x1000; reg += 4) {
+               DEBE_WRITE(sc, reg, 0);
+       }
+
+       DEBE_WRITE(sc, SUNXI_DEBE_MODCTL_REG, SUNXI_DEBE_MODCTL_EN);
+
+       sc->sc_dmasize = SUNXI_DEBE_VIDEOMEM;
+#endif
+
+       DEBE_WRITE(sc, SUNXI_DEBE_HWC_PALETTE_TABLE, 0);
+
+       error = sunxi_debe_alloc_videomem(sc);



Home | Main Index | Thread Index | Old Index