Module Name: src
Committed By: bouyer
Date: Fri Jun 1 17:18:44 UTC 2018
Modified Files:
src/sys/arch/arm/sunxi: sunxi_debe.c sunxi_display.h sunxi_hdmi.c
sunxi_tcon.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/sunxi/sunxi_debe.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/sunxi/sunxi_display.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/sunxi/sunxi_hdmi.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/sunxi/sunxi_tcon.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_debe.c
diff -u src/sys/arch/arm/sunxi/sunxi_debe.c:1.8 src/sys/arch/arm/sunxi/sunxi_debe.c:1.9
--- src/sys/arch/arm/sunxi/sunxi_debe.c:1.8 Sat Apr 7 18:09:33 2018
+++ src/sys/arch/arm/sunxi/sunxi_debe.c Fri Jun 1 17:18:44 2018
@@ -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 <[email protected]>
@@ -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 sunxi_debe_softc {
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 @@ sunxi_debe_attach(device_t parent, devic
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 @@ sunxi_debe_attach(device_t parent, devic
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,20 +182,11 @@ sunxi_debe_attach(device_t parent, devic
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) {
- aprint_error(": couldn't enable clocks\n");
+ sc->sc_rst = fdtbus_reset_get_index(phandle, 0);
+ if (sc->sc_rst == NULL) {
+ aprint_error(": couldn't get reset\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;
@@ -218,16 +195,8 @@ sunxi_debe_attach(device_t parent, devic
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 @@ sunxi_debe_attach(device_t parent, devic
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 @@ sunxi_debe_pipeline(int phandle, bool ac
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 @@ sunxi_debe_pipeline(int phandle, bool ac
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) {
Index: src/sys/arch/arm/sunxi/sunxi_display.h
diff -u src/sys/arch/arm/sunxi/sunxi_display.h:1.2 src/sys/arch/arm/sunxi/sunxi_display.h:1.3
--- src/sys/arch/arm/sunxi/sunxi_display.h:1.2 Sat Apr 7 18:09:33 2018
+++ src/sys/arch/arm/sunxi/sunxi_display.h Fri Jun 1 17:18:44 2018
@@ -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 @@ int sunxi_debe_pipeline(int, bool);
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);
Index: src/sys/arch/arm/sunxi/sunxi_hdmi.c
diff -u src/sys/arch/arm/sunxi/sunxi_hdmi.c:1.3 src/sys/arch/arm/sunxi/sunxi_hdmi.c:1.4
--- src/sys/arch/arm/sunxi/sunxi_hdmi.c:1.3 Tue Apr 3 16:17:59 2018
+++ src/sys/arch/arm/sunxi/sunxi_hdmi.c Fri Jun 1 17:18:44 2018
@@ -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 <[email protected]>
@@ -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 @@ sunxi_hdmi_attach(device_t parent, devic
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 @@ sunxi_hdmi_attach(device_t parent, devic
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 @@ sunxi_hdmi_attach(device_t parent, devic
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");
+ return;
+ }
}
}
Index: src/sys/arch/arm/sunxi/sunxi_tcon.c
diff -u src/sys/arch/arm/sunxi/sunxi_tcon.c:1.6 src/sys/arch/arm/sunxi/sunxi_tcon.c:1.7
--- src/sys/arch/arm/sunxi/sunxi_tcon.c:1.6 Sat Apr 7 18:09:33 2018
+++ src/sys/arch/arm/sunxi/sunxi_tcon.c Fri Jun 1 17:18:44 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_tcon.c,v 1.6 2018/04/07 18:09:33 bouyer Exp $ */
+/* $NetBSD: sunxi_tcon.c,v 1.7 2018/06/01 17:18:44 bouyer Exp $ */
/*-
* Copyright (c) 2018 Manuel Bouyer <[email protected]>
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_tcon.c,v 1.6 2018/04/07 18:09:33 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_tcon.c,v 1.7 2018/06/01 17:18:44 bouyer Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -65,6 +65,7 @@ struct sunxi_tcon_softc {
struct clk *sc_clk_ahb;
struct clk *sc_clk_ch0;
struct clk *sc_clk_ch1;
+ struct fdtbus_reset *sc_rst, *sc_lvds_rst;
unsigned int sc_output_type;
#define OUTPUT_HDMI 0
#define OUTPUT_LVDS 1
@@ -120,8 +121,6 @@ sunxi_tcon_attach(device_t parent, devic
const int phandle = faa->faa_phandle;
bus_addr_t addr;
bus_size_t size;
- struct fdtbus_reset *rst, *lvds_rst;
-
sc->sc_dev = self;
sc->sc_phandle = phandle;
@@ -149,54 +148,13 @@ sunxi_tcon_attach(device_t parent, devic
return;
}
- rst = fdtbus_reset_get(phandle, "lcd");
- if (rst == NULL) {
+ sc->sc_rst = fdtbus_reset_get(phandle, "lcd");
+ if (sc->sc_rst == NULL) {
aprint_error(": couldn't get lcd reset\n");
return;
}
- lvds_rst = fdtbus_reset_get(phandle, "lvds");
-
- if (clk_disable(sc->sc_clk_ahb) != 0) {
- aprint_error(": couldn't disable ahb clock\n");
- return;
- }
- if (clk_disable(sc->sc_clk_ch0) != 0) {
- aprint_error(": couldn't disable ch0 clock\n");
- return;
- }
-
- if (clk_disable(sc->sc_clk_ch1) != 0) {
- aprint_error(": couldn't disable ch1 clock\n");
- return;
- }
-
- if (fdtbus_reset_assert(rst) != 0) {
- aprint_error(": couldn't assert lcd reset\n");
- return;
- }
- if (lvds_rst != NULL) {
- if (fdtbus_reset_assert(lvds_rst) != 0) {
- aprint_error(": couldn't assert lvds reset\n");
- return;
- }
- }
- delay(1);
- if (fdtbus_reset_deassert(rst) != 0) {
- aprint_error(": couldn't de-assert lcd reset\n");
- return;
- }
- if (lvds_rst != NULL) {
- if (fdtbus_reset_deassert(lvds_rst) != 0) {
- aprint_error(": couldn't de-assert lvds reset\n");
- return;
- }
- }
-
- if (clk_enable(sc->sc_clk_ahb) != 0) {
- aprint_error(": couldn't enable ahb clock\n");
- return;
- }
+ sc->sc_lvds_rst = fdtbus_reset_get(phandle, "lvds");
sc->sc_type = of_search_compatible(faa->faa_phandle, compat_data)->data;
@@ -209,24 +167,82 @@ sunxi_tcon_attach(device_t parent, devic
sc->sc_ports.dp_ep_activate = sunxi_tcon_ep_activate;
sc->sc_ports.dp_ep_enable = sunxi_tcon_ep_enable;
fdt_ports_register(&sc->sc_ports, self, phandle, EP_OTHER);
+}
- TCON_WRITE(sc, SUNXI_TCON_GINT0_REG, 0);
- TCON_WRITE(sc, SUNXI_TCON_GINT1_REG,
- __SHIFTIN(0x20, SUNXI_TCON_GINT1_TCON0_LINENO));
- TCON_WRITE(sc, SUNXI_TCON0_DCLK_REG, 0xf0000000);
- TCON_WRITE(sc, SUNXI_TCON0_LVDS_IF_REG, 0x0);
- TCON_WRITE(sc, SUNXI_TCON0_CTL_REG, 0);
- TCON_WRITE(sc, SUNXI_TCON0_IO_TRI_REG, 0xffffffff);
- TCON_WRITE(sc, SUNXI_TCON1_CTL_REG, 0);
- TCON_WRITE(sc, SUNXI_TCON1_IO_TRI_REG, 0xffffffff);
- TCON_WRITE(sc, SUNXI_TCON_GCTL_REG, 0);
+void
+sunxi_tcon_doreset(void)
+{
+ device_t dev;
+ struct sunxi_tcon_softc *sc;
+ for (int i = 0;;i++) {
+ dev = device_find_by_driver_unit("sunxitcon", i);
+ if (dev == NULL)
+ return;
+ sc = device_private(dev);
- /* clock needed for the mux in unit 0 */
- if (sc->sc_unit != 0) {
if (clk_disable(sc->sc_clk_ahb) != 0) {
- aprint_error(": couldn't disable ahb clock\n");
+ aprint_error_dev(dev, ": couldn't disable ahb clock\n");
+ return;
+ }
+ if (clk_disable(sc->sc_clk_ch0) != 0) {
+ aprint_error_dev(dev, ": couldn't disable ch0 clock\n");
+ return;
+ }
+
+ if (clk_disable(sc->sc_clk_ch1) != 0) {
+ aprint_error_dev(dev, ": couldn't disable ch1 clock\n");
+ return;
+ }
+
+ if (fdtbus_reset_assert(sc->sc_rst) != 0) {
+ aprint_error_dev(dev, ": couldn't assert lcd reset\n");
+ return;
+ }
+ if (sc->sc_lvds_rst != NULL) {
+ if (fdtbus_reset_assert(sc->sc_lvds_rst) != 0) {
+ aprint_error_dev(dev,
+ ": couldn't assert lvds reset\n");
+ return;
+ }
+ }
+ delay(1);
+ if (fdtbus_reset_deassert(sc->sc_rst) != 0) {
+ aprint_error_dev(dev,
+ ": couldn't de-assert lcd reset\n");
return;
}
+ if (sc->sc_lvds_rst != NULL) {
+ if (fdtbus_reset_deassert(sc->sc_lvds_rst) != 0) {
+ aprint_error_dev(dev,
+ ": couldn't de-assert lvds reset\n");
+ return;
+ }
+ }
+
+ if (clk_enable(sc->sc_clk_ahb) != 0) {
+ aprint_error_dev(dev, ": couldn't enable ahb clock\n");
+ return;
+ }
+
+ TCON_WRITE(sc, SUNXI_TCON_GINT0_REG, 0);
+ TCON_WRITE(sc, SUNXI_TCON_GINT1_REG,
+ __SHIFTIN(0x20, SUNXI_TCON_GINT1_TCON0_LINENO));
+ TCON_WRITE(sc, SUNXI_TCON0_DCLK_REG, 0xf0000000);
+ TCON_WRITE(sc, SUNXI_TCON0_LVDS_IF_REG, 0x0);
+ TCON_WRITE(sc, SUNXI_TCON0_CTL_REG, 0);
+ TCON_WRITE(sc, SUNXI_TCON0_IO_TRI_REG, 0xffffffff);
+ TCON_WRITE(sc, SUNXI_TCON1_CTL_REG, 0);
+ TCON_WRITE(sc, SUNXI_TCON1_IO_TRI_REG, 0xffffffff);
+ TCON_WRITE(sc, SUNXI_TCON_GCTL_REG, 0);
+
+ /* clock needed for the mux in unit 0 */
+ if (sc->sc_unit != 0) {
+ if (clk_disable(sc->sc_clk_ahb) != 0) {
+ aprint_error_dev(dev,
+ ": couldn't disable ahb clock\n");
+ return;
+ }
+ }
}
}