Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/ti Add AM335x DVFS support.



details:   https://anonhg.NetBSD.org/src/rev/0e4e95675084
branches:  trunk
changeset: 460617:0e4e95675084
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Oct 28 21:16:47 2019 +0000

description:
Add AM335x DVFS support.

diffstat:

 sys/arch/arm/ti/files.ti        |   18 ++-
 sys/arch/arm/ti/ti_cpufreq.c    |  113 +++++++++++++++++
 sys/arch/arm/ti/ti_div_clock.c  |  202 ++++++++++++++++++++++++++++++++
 sys/arch/arm/ti/ti_dpll_clock.c |  252 ++++++++++++++++++++++++++++++++++++++++
 sys/arch/arm/ti/ti_mux_clock.c  |  211 +++++++++++++++++++++++++++++++++
 5 files changed, 794 insertions(+), 2 deletions(-)

diffs (truncated from 832 to 300 lines):

diff -r 9369a063cad9 -r 0e4e95675084 sys/arch/arm/ti/files.ti
--- a/sys/arch/arm/ti/files.ti  Mon Oct 28 21:16:10 2019 +0000
+++ b/sys/arch/arm/ti/files.ti  Mon Oct 28 21:16:47 2019 +0000
@@ -1,7 +1,8 @@
-#      $NetBSD: files.ti,v 1.11 2019/10/27 19:11:07 jmcneill Exp $
+#      $NetBSD: files.ti,v 1.12 2019/10/28 21:16:47 jmcneill Exp $
 #
 
 file   arch/arm/ti/ti_platform.c       soc_ti
+file   arch/arm/ti/ti_cpufreq.c        soc_ti
 
 # Interrupt controller
 device omapintc: pic, pic_splfuncs
@@ -18,10 +19,23 @@
 file   arch/arm/ti/ti_prcm.c           ti_prcm
 
 # PRCM (AM3xxx)
-device am3prcm: ti_prcm
+device am3prcm { } : fdt, ti_prcm
 attach am3prcm at fdt with am3_prcm
 file   arch/arm/ti/am3_prcm.c          am3_prcm
 
+# Clocks
+device timuxclk
+attach timuxclk at fdt with ti_mux_clock
+file   arch/arm/ti/ti_mux_clock.c      ti_mux_clock
+
+device tidivclk
+attach tidivclk at fdt with ti_div_clock
+file   arch/arm/ti/ti_div_clock.c      ti_div_clock
+
+device tidpllclk
+attach tidpllclk at fdt with ti_dpll_clock
+file   arch/arm/ti/ti_dpll_clock.c     ti_dpll_clock
+
 # UART
 attach com at fdt with ti_com: ti_prcm
 file   arch/arm/ti/ti_com.c            ti_com needs-flag
diff -r 9369a063cad9 -r 0e4e95675084 sys/arch/arm/ti/ti_cpufreq.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/ti/ti_cpufreq.c      Mon Oct 28 21:16:47 2019 +0000
@@ -0,0 +1,113 @@
+/* $NetBSD: ti_cpufreq.c,v 1.1 2019/10/28 21:16:47 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 Jared 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 "opt_soc.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ti_cpufreq.c,v 1.1 2019/10/28 21:16:47 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kmem.h>
+#include <sys/bus.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
+
+static bool            ti_opp_probed = false;
+static bool            (*ti_opp_supportedfn)(const int, const int);
+static struct syscon   *ti_opp_syscon;
+
+#ifdef SOC_TI_AM335X
+
+#define        AM33XX_REV_OFFSET       0x0600
+#define        AM33XX_REV_MASK         0xf0000000
+#define        AM33XX_EFUSE_OFFSET     0x07fc
+#define        AM33XX_EFUSE_MASK       0x00001fff
+#define        AM33XX_EFUSE_DEFAULT    0x1e2f
+
+static const char * const am33xx_compatible[] = { "ti,am33xx", NULL };
+
+static bool
+am33xx_opp_supported(const int opp_table, const int opp_node)
+{
+       const u_int *supported_hw;
+       uint32_t efuse, rev;
+       int len;
+
+       syscon_lock(ti_opp_syscon);
+       rev = __SHIFTOUT(syscon_read_4(ti_opp_syscon, AM33XX_REV_OFFSET), AM33XX_REV_MASK);
+       efuse = __SHIFTOUT(syscon_read_4(ti_opp_syscon, AM33XX_EFUSE_OFFSET), AM33XX_EFUSE_MASK);
+       syscon_unlock(ti_opp_syscon);
+
+       if (efuse == 0)
+               efuse = AM33XX_EFUSE_DEFAULT;
+       efuse = ~efuse;
+
+       supported_hw = fdtbus_get_prop(opp_node, "opp-supported-hw", &len);
+       if (len != 8)
+               return false;
+
+       if ((rev & be32toh(supported_hw[0])) == 0)
+               return false;
+
+       if ((efuse & be32toh(supported_hw[1])) == 0)
+               return false;
+
+       return true;
+}
+#endif
+
+static void
+ti_opp_probe(const int opp_table)
+{
+       if (ti_opp_probed)
+               return;
+       ti_opp_probed = true;
+
+       ti_opp_syscon = fdtbus_syscon_acquire(opp_table, "syscon");
+
+#ifdef SOC_TI_AM335X
+       if (ti_opp_syscon && of_match_compatible(OF_finddevice("/"), am33xx_compatible))
+               ti_opp_supportedfn = am33xx_opp_supported;
+#endif
+}
+
+static bool
+ti_opp_supported(const int opp_table, const int opp_node)
+{
+       ti_opp_probe(opp_table);
+
+       if (!of_hasprop(opp_node, "opp-supported-hw"))
+               return true;
+
+       return ti_opp_supportedfn ? ti_opp_supportedfn(opp_table, opp_node) : false;
+}
+
+FDT_OPP(ti, "operating-points-v2-ti-cpu", ti_opp_supported);
diff -r 9369a063cad9 -r 0e4e95675084 sys/arch/arm/ti/ti_div_clock.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/ti/ti_div_clock.c    Mon Oct 28 21:16:47 2019 +0000
@@ -0,0 +1,202 @@
+/* $NetBSD: ti_div_clock.c,v 1.1 2019/10/28 21:16:47 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 Jared 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: ti_div_clock.c,v 1.1 2019/10/28 21:16:47 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kmem.h>
+#include <sys/bus.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <dev/fdt/fdtvar.h>
+
+static const char * const compatible[] = {
+       "ti,divider-clock",
+       NULL
+};
+
+static int     ti_div_clock_match(device_t, cfdata_t, void *);
+static void    ti_div_clock_attach(device_t, device_t, void *);
+
+static struct clk *ti_div_clock_decode(device_t, int, const void *, size_t);
+
+static const struct fdtbus_clock_controller_func ti_div_clock_fdt_funcs = {
+       .decode = ti_div_clock_decode
+};
+
+static struct clk *ti_div_clock_get(void *, const char *);
+static void    ti_div_clock_put(void *, struct clk *);
+static u_int   ti_div_clock_get_rate(void *, struct clk *);
+static struct clk *ti_div_clock_get_parent(void *, struct clk *);
+
+static const struct clk_funcs ti_div_clock_clk_funcs = {
+       .get = ti_div_clock_get,
+       .put = ti_div_clock_put,
+       .get_rate = ti_div_clock_get_rate,
+       .get_parent = ti_div_clock_get_parent,
+};
+
+struct ti_div_clock_softc {
+       device_t                sc_dev;
+       int                     sc_phandle;
+       bus_space_tag_t         sc_bst;
+       bus_space_handle_t      sc_bsh;
+
+       struct clk_domain       sc_clkdom;
+       struct clk              sc_clk;
+};
+
+#define        RD4(sc)                 \
+       bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, 0)
+#define        WR4(sc, val)            \
+       bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, 0, (val))
+
+CFATTACH_DECL_NEW(ti_div_clock, sizeof(struct ti_div_clock_softc),
+    ti_div_clock_match, ti_div_clock_attach, NULL, NULL);
+
+static int
+ti_div_clock_match(device_t parent, cfdata_t cf, void *aux)
+{
+       const struct fdt_attach_args *faa = aux;
+
+       return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+ti_div_clock_attach(device_t parent, device_t self, void *aux)
+{
+       struct ti_div_clock_softc * const sc = device_private(self);
+       const struct fdt_attach_args *faa = aux;
+       const int phandle = faa->faa_phandle;
+       bus_addr_t addr, base_addr;
+
+       const int prcm_phandle = OF_parent(OF_parent(phandle));
+       if (fdtbus_get_reg(phandle, 0, &addr, NULL) != 0 ||
+           fdtbus_get_reg(prcm_phandle, 0, &base_addr, NULL) != 0) {
+               aprint_error(": couldn't get registers\n");
+               return;
+       }
+
+       sc->sc_dev = self;
+       sc->sc_phandle = phandle;
+       sc->sc_bst = faa->faa_bst;
+       if (bus_space_map(sc->sc_bst, base_addr + addr, 4, 0, &sc->sc_bsh) != 0) {
+               aprint_error(": couldn't map registers\n");
+               return;
+       }
+
+       sc->sc_clkdom.name = device_xname(self);
+       sc->sc_clkdom.funcs = &ti_div_clock_clk_funcs;
+       sc->sc_clkdom.priv = sc;
+
+       sc->sc_clk.domain = &sc->sc_clkdom;
+       sc->sc_clk.name = kmem_asprintf("%s", faa->faa_name);
+       clk_attach(&sc->sc_clk);
+
+       aprint_naive("\n");
+       aprint_normal(": TI divider clock (%s)\n", sc->sc_clk.name);
+
+       fdtbus_register_clock_controller(self, phandle, &ti_div_clock_fdt_funcs);
+}
+
+static struct clk *
+ti_div_clock_decode(device_t dev, int cc_phandle, const void *data,
+                    size_t len)
+{
+       struct ti_div_clock_softc * const sc = device_private(dev);
+
+       return &sc->sc_clk;
+}
+
+static struct clk *
+ti_div_clock_get(void *priv, const char *name)



Home | Main Index | Thread Index | Old Index