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 Defer display hardware reset to pipeline ...



details:   https://anonhg.NetBSD.org/src/rev/0ad9e0e8cb26
branches:  trunk
changeset: 323134:0ad9e0e8cb26
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Fri Jun 01 17:18:44 2018 +0000

description:
Defer display hardware reset to pipeline activation. This way, if we have a
pipeline setup which we can't manage, the simple framebuffer will keep working.

diffstat:

 sys/arch/arm/sunxi/sunxi_debe.c    |  111 ++++++++++++++++++-----------
 sys/arch/arm/sunxi/sunxi_display.h |    5 +-
 sys/arch/arm/sunxi/sunxi_hdmi.c    |   62 ++++++++++------
 sys/arch/arm/sunxi/sunxi_tcon.c    |  140 ++++++++++++++++++++----------------
 4 files changed, 189 insertions(+), 129 deletions(-)

diffs (truncated from 495 to 300 lines):

diff -r 0d9af7d85004 -r 0ad9e0e8cb26 sys/arch/arm/sunxi/sunxi_debe.c
--- a/sys/arch/arm/sunxi/sunxi_debe.c   Fri Jun 01 16:13:08 2018 +0000
+++ b/sys/arch/arm/sunxi/sunxi_debe.c   Fri Jun 01 17:18:44 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_debe.c,v 1.8 2018/04/07 18:09:33 bouyer Exp $ */
+/* $NetBSD: sunxi_debe.c,v 1.9 2018/06/01 17:18:44 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2018 Manuel Bouyer <bouyer%antioche.eu.org@localhost>
@@ -38,7 +38,7 @@
 #define SUNXI_DEBE_CURMAX      64
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c,v 1.8 2018/04/07 18:09:33 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c,v 1.9 2018/06/01 17:18:44 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -77,6 +77,8 @@
        struct clk *sc_clk_mod;
        struct clk *sc_clk_ram;
 
+       struct fdtbus_reset *sc_rst;
+
        bus_dma_segment_t sc_dmasegs[1];
        bus_size_t sc_dmasize;
        bus_dmamap_t sc_dmamap;
@@ -152,7 +154,6 @@
        const int phandle = faa->faa_phandle;
        bus_addr_t addr;
        bus_size_t size;
-       struct fdtbus_reset *rst;
        int error;
 
        sc->sc_dev = self;
@@ -171,21 +172,6 @@
        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");
@@ -196,21 +182,12 @@
                return;
        }
 
-       error = clk_set_rate(sc->sc_clk_mod, 300000000);
-       if (error) {
-               aprint_error("couln't set mod clock rate (%d)\n", error);
+       sc->sc_rst = fdtbus_reset_get_index(phandle, 0);
+       if (sc->sc_rst == NULL) {
+               aprint_error(": couldn't get reset\n");
                return;
        }
 
-       if (clk_enable(sc->sc_clk_ahb) != 0 ||
-           clk_enable(sc->sc_clk_mod) != 0) {
-               aprint_error(": couldn't enable clocks\n");
-               return;
-       }
-       if (clk_disable(sc->sc_clk_ram) != 0) {
-               aprint_error(": couldn't disable ram clock\n");
-       }
-
        sc->sc_type = of_search_compatible(faa->faa_phandle, compat_data)->data;
 
        aprint_naive("\n");
@@ -218,16 +195,8 @@
            fdtbus_get_string(phandle, "name"));
 
 
-       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;
 
-       DEBE_WRITE(sc, SUNXI_DEBE_HWC_PALETTE_TABLE, 0);
-
        error = sunxi_debe_alloc_videomem(sc);
        if (error) {
                aprint_error_dev(sc->sc_dev,
@@ -239,11 +208,61 @@
        sc->sc_ports.dp_ep_connect = sunxi_debe_ep_connect;
        sc->sc_ports.dp_ep_enable = sunxi_debe_ep_enable;
        fdt_ports_register(&sc->sc_ports, self, phandle, EP_OTHER);
+}
 
-       if (clk_disable(sc->sc_clk_ahb) != 0 ||
-           clk_disable(sc->sc_clk_mod) != 0) {
-               aprint_error(": couldn't disable clocks\n");
-               return;
+static void
+sunxi_debe_doreset(void)
+{
+       device_t dev;
+       struct sunxi_debe_softc *sc;
+       int error;
+
+       for (int i = 0;;i++) {
+               dev = device_find_by_driver_unit("sunxidebe", i);
+               if (dev == NULL)
+                       return;
+               sc = device_private(dev);
+
+               if (fdtbus_reset_assert(sc->sc_rst) != 0) {
+                       aprint_error_dev(dev, ": couldn't assert reset\n");
+                       return;
+               }
+               delay(1);
+               if (fdtbus_reset_deassert(sc->sc_rst) != 0) {
+                       aprint_error_dev(dev, ": couldn't de-assert reset\n");
+                       return;
+               }
+
+
+               error = clk_set_rate(sc->sc_clk_mod, 300000000);
+               if (error) {
+                       aprint_error_dev(dev,
+                           "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) {
+                       aprint_error_dev(dev, ": couldn't enable clocks\n");
+                       return;
+               }
+               if (clk_disable(sc->sc_clk_ram) != 0) {
+                       aprint_error_dev(dev, ": couldn't disable ram clock\n");
+               }
+
+               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);
+
+               DEBE_WRITE(sc, SUNXI_DEBE_HWC_PALETTE_TABLE, 0);
+
+               if (clk_disable(sc->sc_clk_ahb) != 0 ||
+                   clk_disable(sc->sc_clk_mod) != 0) {
+                       aprint_error_dev(sc->sc_dev,
+                           ": couldn't disable clocks\n");
+               }
        }
 }
 
@@ -841,6 +860,7 @@
        struct sunxi_debe_softc *sc;
        struct fdt_endpoint *ep;
        int i, error;
+       static bool reset_done = false;
 
        if (!active)
                return EOPNOTSUPP;
@@ -853,6 +873,13 @@
                if (sc->sc_phandle == phandle)
                        break;
        }
+       if (!reset_done) {
+               sunxi_debe_doreset();
+               sunxi_tcon_doreset();
+               sunxi_hdmi_doreset();
+               reset_done = true;
+       }
+
        aprint_normal("activate %s\n", device_xname(dev));
        if (clk_enable(sc->sc_clk_ahb) != 0 ||
            clk_enable(sc->sc_clk_mod) != 0) {
diff -r 0d9af7d85004 -r 0ad9e0e8cb26 sys/arch/arm/sunxi/sunxi_display.h
--- a/sys/arch/arm/sunxi/sunxi_display.h        Fri Jun 01 16:13:08 2018 +0000
+++ b/sys/arch/arm/sunxi/sunxi_display.h        Fri Jun 01 17:18:44 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sunxi_display.h,v 1.2 2018/04/07 18:09:33 bouyer Exp $ */
+/*     $NetBSD: sunxi_display.h,v 1.3 2018/06/01 17:18:44 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -38,3 +38,6 @@
 void sunxi_tcon1_set_videomode(device_t, const struct videomode *);
 void sunxi_debe_set_videomode(device_t, const struct videomode *);
 bool sunxi_tcon_is_console(device_t, const char *);
+
+void sunxi_tcon_doreset(void);
+void sunxi_hdmi_doreset(void);
diff -r 0d9af7d85004 -r 0ad9e0e8cb26 sys/arch/arm/sunxi/sunxi_hdmi.c
--- a/sys/arch/arm/sunxi/sunxi_hdmi.c   Fri Jun 01 16:13:08 2018 +0000
+++ b/sys/arch/arm/sunxi/sunxi_hdmi.c   Fri Jun 01 17:18:44 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_hdmi.c,v 1.3 2018/04/03 16:17:59 bouyer Exp $ */
+/* $NetBSD: sunxi_hdmi.c,v 1.4 2018/06/01 17:18:44 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_hdmi.c,v 1.3 2018/04/03 16:17:59 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_hdmi.c,v 1.4 2018/06/01 17:18:44 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -165,7 +165,6 @@
        bus_addr_t addr;
        bus_size_t size;
        uint32_t ver;
-       int error;
 
        sc->sc_dev = self;
        sc->sc_phandle = phandle;
@@ -197,28 +196,10 @@
                return;
        }
 
-       error = clk_disable(sc->sc_clk_mod);
-       if (error) {
-               aprint_error(": couldn't disable mod clock\n");
-               return;
-       }
-
        if (clk_enable(sc->sc_clk_ahb) != 0) {
                aprint_error(": couldn't enable ahb clock\n");
                return;
        }
-#if defined(SUNXI_HDMI_DEBUG)
-       sunxi_hdmi_dump_regs();
-#endif
-
-       /*
-        * reset device, in case it has been setup by firmware in an
-        * incompatible way
-        */
-       for (int i = 0; i <= 0x500; i += 4) {
-               HDMI_WRITE(sc, i, 0);
-       }
-
        ver = HDMI_READ(sc, SUNXI_HDMI_VERSION_ID_REG);
 
        const int vmaj = __SHIFTOUT(ver, SUNXI_HDMI_VERSION_ID_H);
@@ -236,10 +217,43 @@
 
        mutex_init(&sc->sc_pwr_lock, MUTEX_DEFAULT, IPL_NONE);
        sunxi_hdmi_i2c_init(sc);
+}
 
-       if (clk_disable(sc->sc_clk_ahb) != 0) {
-               aprint_error(": couldn't disable ahb clock\n");
-               return;
+void
+sunxi_hdmi_doreset(void)
+{
+       device_t dev;
+       struct sunxi_hdmi_softc *sc;
+       int error;
+
+       for (int i = 0;;i++) {
+               dev = device_find_by_driver_unit("sunxihdmi", i);
+               if (dev == NULL)
+                       return;
+               sc = device_private(dev);
+       
+               error = clk_disable(sc->sc_clk_mod);
+               if (error) {
+                       aprint_error_dev(dev, ": couldn't disable mod clock\n");
+                       return;
+               }
+
+#if defined(SUNXI_HDMI_DEBUG)
+               sunxi_hdmi_dump_regs();
+#endif
+
+               /*
+                * reset device, in case it has been setup by firmware in an
+                * incompatible way
+                */
+               for (int j = 0; j <= 0x500; j += 4) {
+                       HDMI_WRITE(sc, j, 0);
+               }
+
+               if (clk_disable(sc->sc_clk_ahb) != 0) {
+                       aprint_error_dev(dev, ": couldn't disable ahb clock\n");



Home | Main Index | Thread Index | Old Index