Module Name:    src
Committed By:   bouyer
Date:           Tue Apr  3 16:17:59 UTC 2018

Modified Files:
        src/sys/arch/arm/sunxi: sunxi_debe.c sunxi_hdmi.c sunxi_tcon.c

Log Message:
disable all clocks at end of attach function, and re-enable ahb and mod only
in activate function.
enable ram gate (in debe) and video plls (in tcon) only when the video output
is enabled. Saves about 20mw when both video outputs are off.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/sunxi/sunxi_debe.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/sunxi/sunxi_hdmi.c \
    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.4 src/sys/arch/arm/sunxi/sunxi_debe.c:1.5
--- src/sys/arch/arm/sunxi/sunxi_debe.c:1.4	Tue Apr  3 13:38:13 2018
+++ src/sys/arch/arm/sunxi/sunxi_debe.c	Tue Apr  3 16:17:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_debe.c,v 1.4 2018/04/03 13:38:13 bouyer Exp $ */
+/* $NetBSD: sunxi_debe.c,v 1.5 2018/04/03 16:17:59 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.4 2018/04/03 13:38:13 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c,v 1.5 2018/04/03 16:17:59 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -204,11 +204,13 @@ sunxi_debe_attach(device_t parent, devic
 	}
 
 	if (clk_enable(sc->sc_clk_ahb) != 0 ||
-	    clk_enable(sc->sc_clk_mod) != 0 ||
-	    clk_enable(sc->sc_clk_ram) != 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;
 
@@ -278,6 +280,12 @@ sunxi_debe_attach(device_t parent, devic
 #ifdef AWIN_DEBE_FWINIT
 	sunxi_debe_set_videomode(device_unit(self), &mode);
 	sunxi_debe_enable(device_unit(self), true);
+#else
+	if (clk_disable(sc->sc_clk_ahb) != 0 ||
+	    clk_disable(sc->sc_clk_mod) != 0) {
+		aprint_error(": couldn't disable clocks\n");
+		return;
+	}
 #endif
 }
 
@@ -520,6 +528,10 @@ sunxi_debe_ep_enable(device_t dev, struc
 	sc = device_private(dev);
 
 	if (enable) {
+		if (clk_enable(sc->sc_clk_ram) != 0) {
+			device_printf(dev,
+			    ": warning: failed to enable ram clock\n");
+		}
 		val = DEBE_READ(sc, SUNXI_DEBE_REGBUFFCTL_REG);
 		val |= SUNXI_DEBE_REGBUFFCTL_REGLOADCTL;
 		DEBE_WRITE(sc, SUNXI_DEBE_REGBUFFCTL_REG, val);
@@ -534,6 +546,10 @@ sunxi_debe_ep_enable(device_t dev, struc
 		val = DEBE_READ(sc, SUNXI_DEBE_MODCTL_REG);
 		val &= ~SUNXI_DEBE_MODCTL_START_CTL;
 		DEBE_WRITE(sc, SUNXI_DEBE_MODCTL_REG, val);
+		if (clk_disable(sc->sc_clk_ram) != 0) {
+			device_printf(dev,
+			    ": warning: failed to disable ram clock\n");
+		}
 	}
 #if 0
 	for (int i = 0; i < 0x1000; i += 4) {
@@ -860,6 +876,11 @@ sunxi_debe_pipeline(int phandle, bool ac
 			break;
 	}
 	aprint_normal("activate %s\n", device_xname(dev));
+	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 EIO;
+	}
 	/* connect debd0 to tcon0, debe1 to tcon1 */
 	ep = fdt_endpoint_get_from_index(&sc->sc_ports, SUNXI_PORT_OUTPUT,
 	    sc->sc_unit);

Index: src/sys/arch/arm/sunxi/sunxi_hdmi.c
diff -u src/sys/arch/arm/sunxi/sunxi_hdmi.c:1.2 src/sys/arch/arm/sunxi/sunxi_hdmi.c:1.3
--- src/sys/arch/arm/sunxi/sunxi_hdmi.c:1.2	Tue Apr  3 13:38:13 2018
+++ src/sys/arch/arm/sunxi/sunxi_hdmi.c	Tue Apr  3 16:17:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_hdmi.c,v 1.2 2018/04/03 13:38:13 bouyer Exp $ */
+/* $NetBSD: sunxi_hdmi.c,v 1.3 2018/04/03 16:17:59 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.2 2018/04/03 13:38:13 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_hdmi.c,v 1.3 2018/04/03 16:17:59 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -237,6 +237,10 @@ 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;
+	}
 }
 
 static void
@@ -580,6 +584,10 @@ sunxi_hdmi_do_enable(struct sunxi_hdmi_s
 	int error;
 	uint32_t dbg0_reg;
 
+	if (clk_enable(sc->sc_clk_ahb) != 0) {
+		aprint_error_dev(sc->sc_dev, "couldn't enable ahb clock\n");
+		return;
+	}
 	/* assume tcon0 uses pll3, tcon1 uses pll7 */
 	switch(fdt_endpoint_index(sc->sc_in_ep)) {
 	case 0:
@@ -805,6 +813,7 @@ sunxi_hdmi_video_enable(struct sunxi_hdm
 	uint32_t val;
 
 	fdt_endpoint_enable(sc->sc_out_ep, enable);
+
 	val = HDMI_READ(sc, SUNXI_HDMI_VID_CTRL_REG);
 	val &= ~SUNXI_HDMI_VID_CTRL_SRC_SEL;
 #ifdef SUNXI_HDMI_CBGEN
Index: src/sys/arch/arm/sunxi/sunxi_tcon.c
diff -u src/sys/arch/arm/sunxi/sunxi_tcon.c:1.2 src/sys/arch/arm/sunxi/sunxi_tcon.c:1.3
--- src/sys/arch/arm/sunxi/sunxi_tcon.c:1.2	Tue Apr  3 13:38:13 2018
+++ src/sys/arch/arm/sunxi/sunxi_tcon.c	Tue Apr  3 16:17:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_tcon.c,v 1.2 2018/04/03 13:38:13 bouyer Exp $ */
+/* $NetBSD: sunxi_tcon.c,v 1.3 2018/04/03 16:17:59 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.2 2018/04/03 13:38:13 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_tcon.c,v 1.3 2018/04/03 16:17:59 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -219,6 +219,10 @@ sunxi_tcon_attach(device_t parent, devic
 	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);
+	if (clk_disable(sc->sc_clk_ahb) != 0) {
+		aprint_error(": couldn't disable ahb clock\n");
+		return;
+	}
 }
 
 static void
@@ -304,6 +308,10 @@ sunxi_tcon_ep_activate(device_t dev, str
 	if (!activate)
 		return EOPNOTSUPP;
 
+	if (clk_enable(sc->sc_clk_ahb) != 0) {
+		aprint_error_dev(dev, "couldn't enable ahb clock\n");
+		return EIO;
+	}
 	sc->sc_in_ep = ep;
 	sc->sc_in_rep = fdt_endpoint_remote(ep);
 	/* check that our other input is not active */
@@ -565,6 +573,11 @@ sunxi_tcon0_enable(struct sunxi_tcon_sof
 		return error;
 	delay(20000);
 	if (enable) {
+		if ((error = clk_enable(sc->sc_clk_ch0)) != 0) {
+			device_printf(sc->sc_dev,
+			    ": couldn't enable ch0 clock\n");
+			return error;
+		}
 		val = TCON_READ(sc, SUNXI_TCON_GCTL_REG);
 		val |= SUNXI_TCON_GCTL_EN;
 		TCON_WRITE(sc, SUNXI_TCON_GCTL_REG, val);
@@ -586,6 +599,11 @@ sunxi_tcon0_enable(struct sunxi_tcon_sof
 		val = TCON_READ(sc, SUNXI_TCON_GCTL_REG);
 		val &= ~SUNXI_TCON_GCTL_EN;
 		TCON_WRITE(sc, SUNXI_TCON_GCTL_REG, val);
+		if ((error = clk_disable(sc->sc_clk_ch0)) != 0) {
+			device_printf(sc->sc_dev,
+			    ": couldn't disable ch0 clock\n");
+			return error;
+		}
 	}
 #ifdef SUNXI_TCON_DEBUG
 	sunxi_tcon_dump_regs(device_unit(sc->sc_dev));
@@ -597,6 +615,7 @@ static int
 sunxi_tcon1_enable(struct sunxi_tcon_softc *sc, bool enable)
 {
 	uint32_t val;
+	int error;
 
 	KASSERT((sc->sc_output_type == OUTPUT_HDMI) || 
 		    (sc->sc_output_type == OUTPUT_VGA));
@@ -604,6 +623,11 @@ sunxi_tcon1_enable(struct sunxi_tcon_sof
 	fdt_endpoint_enable(sc->sc_in_ep, enable);
 	delay(20000);
 	if (enable) {
+		if ((error = clk_enable(sc->sc_clk_ch1)) != 0) {
+			device_printf(sc->sc_dev,
+			    ": couldn't enable ch1 clock\n");
+			return error;
+		}
 		val = TCON_READ(sc, SUNXI_TCON_GCTL_REG);
 		val |= SUNXI_TCON_GCTL_EN;
 		TCON_WRITE(sc, SUNXI_TCON_GCTL_REG, val);
@@ -622,6 +646,11 @@ sunxi_tcon1_enable(struct sunxi_tcon_sof
 		val = TCON_READ(sc, SUNXI_TCON_GCTL_REG);
 		val &= ~SUNXI_TCON_GCTL_EN;
 		TCON_WRITE(sc, SUNXI_TCON_GCTL_REG, val);
+		if ((error = clk_disable(sc->sc_clk_ch1)) != 0) {
+			device_printf(sc->sc_dev,
+			    ": couldn't disable ch1 clock\n");
+			return error;
+		}
 	}
 
 	KASSERT(tcon_mux_inited);

Reply via email to