Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Add a basic driver for the Clock and Reset controll...



details:   https://anonhg.NetBSD.org/src/rev/23202362dc97
branches:  trunk
changeset: 337798:23202362dc97
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Tue Apr 28 11:15:55 2015 +0000

description:
Add a basic driver for the Clock and Reset controller, use it to determine
CPU frequency.

diffstat:

 sys/arch/arm/nvidia/files.tegra    |    7 +-
 sys/arch/arm/nvidia/tegra_car.c    |  123 +++++++++++++++++++++++++++++++++++++
 sys/arch/arm/nvidia/tegra_carreg.h |   44 +++++++++++++
 sys/arch/arm/nvidia/tegra_io.c     |   11 ++-
 sys/arch/arm/nvidia/tegra_reg.h    |    4 +-
 sys/arch/arm/nvidia/tegra_soc.c    |    6 +-
 sys/arch/arm/nvidia/tegra_var.h    |    5 +-
 sys/arch/evbarm/conf/JETSONTK1     |    5 +-
 8 files changed, 196 insertions(+), 9 deletions(-)

diffs (truncated from 319 to 300 lines):

diff -r df4fbcedb660 -r 23202362dc97 sys/arch/arm/nvidia/files.tegra
--- a/sys/arch/arm/nvidia/files.tegra   Tue Apr 28 09:48:30 2015 +0000
+++ b/sys/arch/arm/nvidia/files.tegra   Tue Apr 28 11:15:55 2015 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.tegra,v 1.2 2015/03/29 22:27:04 jmcneill Exp $
+#      $NetBSD: files.tegra,v 1.3 2015/04/28 11:15:55 jmcneill Exp $
 #
 # Configuration info for NVIDIA Tegra ARM Peripherals
 #
@@ -31,6 +31,11 @@
 attach tegrapmc at tegraio with tegra_pmc
 file   arch/arm/nvidia/tegra_pmc.c             tegra_pmc
 
+# Clock and Reset controller
+device tegracar
+attach tegracar at tegraio with tegra_car
+file   arch/arm/nvidia/tegra_car.c             tegra_car
+
 # UART
 attach com at tegraio with tegra_com
 file   arch/arm/nvidia/tegra_com.c             tegra_com needs-flag
diff -r df4fbcedb660 -r 23202362dc97 sys/arch/arm/nvidia/tegra_car.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/nvidia/tegra_car.c   Tue Apr 28 11:15:55 2015 +0000
@@ -0,0 +1,123 @@
+/* $NetBSD: tegra_car.c,v 1.1 2015/04/28 11:15:55 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 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 "locators.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.1 2015/04/28 11:15:55 jmcneill 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 <arm/nvidia/tegra_reg.h>
+#include <arm/nvidia/tegra_carreg.h>
+#include <arm/nvidia/tegra_var.h>
+
+static int     tegra_car_match(device_t, cfdata_t, void *);
+static void    tegra_car_attach(device_t, device_t, void *);
+
+struct tegra_car_softc {
+       device_t                sc_dev;
+       bus_space_tag_t         sc_bst;
+       bus_space_handle_t      sc_bsh;
+};
+
+static struct tegra_car_softc *pmc_softc = NULL;
+
+CFATTACH_DECL_NEW(tegra_car, sizeof(struct tegra_car_softc),
+       tegra_car_match, tegra_car_attach, NULL, NULL);
+
+static int
+tegra_car_match(device_t parent, cfdata_t cf, void *aux)
+{
+       return 1;
+}
+
+static void
+tegra_car_attach(device_t parent, device_t self, void *aux)
+{
+       struct tegra_car_softc * const sc = device_private(self);
+       struct tegraio_attach_args * const tio = aux;
+       const struct tegra_locators * const loc = &tio->tio_loc;
+
+       sc->sc_dev = self;
+       sc->sc_bst = tio->tio_bst;
+       bus_space_subregion(tio->tio_bst, tio->tio_bsh,
+           loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+
+       KASSERT(pmc_softc == NULL);
+       pmc_softc = sc;
+
+       aprint_naive("\n");
+       aprint_normal(": CAR\n");
+
+       aprint_verbose_dev(self, "PLLX = %u Hz\n", tegra_car_pllx_rate());
+}
+
+static void
+tegra_car_get_bs(bus_space_tag_t *pbst, bus_space_handle_t *pbsh)
+{
+       if (pmc_softc) {
+               *pbst = pmc_softc->sc_bst;
+               *pbsh = pmc_softc->sc_bsh;
+       } else {
+               *pbst = &armv7_generic_bs_tag;
+               bus_space_subregion(*pbst, tegra_ppsb_bsh,
+                   TEGRA_CAR_OFFSET, TEGRA_CAR_SIZE, pbsh);
+       }
+}
+
+u_int
+tegra_car_osc_rate(void)
+{
+       return TEGRA_REF_FREQ;
+}
+
+u_int
+tegra_car_pllx_rate(void)
+{
+       bus_space_tag_t bst;
+       bus_space_handle_t bsh;
+       uint64_t rate;
+
+       tegra_car_get_bs(&bst, &bsh);
+
+       rate = tegra_car_osc_rate();    
+       const uint32_t base = bus_space_read_4(bst, bsh, CAR_PLLX_BASE_REG);
+       const u_int divm = __SHIFTOUT(base, CAR_PLLX_BASE_DIVM);
+       const u_int divn = __SHIFTOUT(base, CAR_PLLX_BASE_DIVN);
+       const u_int divp = __SHIFTOUT(base, CAR_PLLX_BASE_DIVP);
+
+       rate = tegra_car_osc_rate() * divn;
+
+       return rate / (divm << divp);
+}
diff -r df4fbcedb660 -r 23202362dc97 sys/arch/arm/nvidia/tegra_carreg.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/nvidia/tegra_carreg.h        Tue Apr 28 11:15:55 2015 +0000
@@ -0,0 +1,44 @@
+/* $NetBSD: tegra_carreg.h,v 1.1 2015/04/28 11:15:55 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 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.
+ */
+
+#ifndef _ARM_TEGRA_CARREG_H
+#define _ARM_TEGRA_CARREG_H
+
+#define CAR_PLLX_BASE_REG      0xe0
+#define CAR_PLLX_BASE_ENABLE           __BIT(31)
+#define CAR_PLLX_BASE_LOCK_OVERRIDE    __BIT(30)
+#define CAR_PLLX_BASE_REF              __BIT(29)
+#define CAR_PLLX_BASE_LOCK             __BIT(27)
+#define CAR_PLLX_BASE_DIVP             __BITS(23,20)
+#define CAR_PLLX_BASE_DIVN             __BITS(15,8)
+#define CAR_PLLX_BASE_DIVM             __BITS(7,0)
+
+#define CAR_PLLX_MISC_REG      0xe8
+
+
+#endif /* _ARM_TEGRA_CARREG_H */
diff -r df4fbcedb660 -r 23202362dc97 sys/arch/arm/nvidia/tegra_io.c
--- a/sys/arch/arm/nvidia/tegra_io.c    Tue Apr 28 09:48:30 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_io.c    Tue Apr 28 11:15:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_io.c,v 1.2 2015/03/29 22:27:04 jmcneill Exp $ */
+/* $NetBSD: tegra_io.c,v 1.3 2015/04/28 11:15:55 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "opt_tegra.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.2 2015/03/29 22:27:04 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.3 2015/04/28 11:15:55 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -61,6 +61,11 @@
 #define NOPORT TEGRAIOCF_PORT_DEFAULT
 #define NOINTR TEGRAIO_INTR_DEFAULT
 
+static const struct tegra_locators tegra_ppsb_locators[] = {
+  { "tegracar",
+    TEGRA_CAR_OFFSET, TEGRA_CAR_SIZE, NOPORT, NOINTR },
+};
+
 static const struct tegra_locators tegra_apb_locators[] = {
   { "tegramc",
     TEGRA_MC_OFFSET, TEGRA_MC_SIZE, NOPORT, NOINTR },
@@ -113,6 +118,8 @@
        aprint_naive("\n");
        aprint_normal(": %s\n", tegra_chip_name());
 
+       tegraio_scan(self, tegra_ppsb_bsh,
+           tegra_ppsb_locators, __arraycount(tegra_ppsb_locators));
        tegraio_scan(self, tegra_apb_bsh,
            tegra_apb_locators, __arraycount(tegra_apb_locators));
        tegraio_scan(self, tegra_ahb_a2_bsh,
diff -r df4fbcedb660 -r 23202362dc97 sys/arch/arm/nvidia/tegra_reg.h
--- a/sys/arch/arm/nvidia/tegra_reg.h   Tue Apr 28 09:48:30 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_reg.h   Tue Apr 28 11:15:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_reg.h,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */
+/* $NetBSD: tegra_reg.h,v 1.4 2015/04/28 11:15:55 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -87,6 +87,8 @@
 #define TEGRA_XUSB_DEV_SIZE    0xa000
 
 /* PPSB */
+#define TEGRA_CAR_OFFSET       0x00006000
+#define TEGRA_CAR_SIZE         0x1000
 #define TEGRA_EVP_OFFSET       0x0000f000
 #define TEGRA_EVP_SIZE         0x1000
 
diff -r df4fbcedb660 -r 23202362dc97 sys/arch/arm/nvidia/tegra_soc.c
--- a/sys/arch/arm/nvidia/tegra_soc.c   Tue Apr 28 09:48:30 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_soc.c   Tue Apr 28 11:15:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_soc.c,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */
+/* $NetBSD: tegra_soc.c,v 1.4 2015/04/28 11:15:55 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -30,7 +30,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.3 2015/04/26 22:04:28 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.4 2015/04/28 11:15:55 jmcneill Exp $");
 
 #define        _ARM32_BUS_DMA_PRIVATE
 #include <sys/param.h>
@@ -81,7 +81,7 @@
            &tegra_ahb_a2_bsh) != 0)
                panic("couldn't map AHB A2");
 
-       curcpu()->ci_data.cpu_cc_freq = 696000000; /* XXX */
+       curcpu()->ci_data.cpu_cc_freq = tegra_car_pllx_rate();
 
        tegra_mpinit();
 }
diff -r df4fbcedb660 -r 23202362dc97 sys/arch/arm/nvidia/tegra_var.h
--- a/sys/arch/arm/nvidia/tegra_var.h   Tue Apr 28 09:48:30 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_var.h   Tue Apr 28 11:15:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_var.h,v 1.3 2015/04/26 22:04:28 jmcneill Exp $ */
+/* $NetBSD: tegra_var.h,v 1.4 2015/04/28 11:15:55 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -69,6 +69,9 @@
 const char *tegra_chip_name(void);
 void   tegra_bootstrap(void);
 
+u_int  tegra_car_osc_rate(void);
+u_int  tegra_car_pllx_rate(void);
+
 void   tegra_pmc_reset(void);
 void   tegra_pmc_power(u_int, bool);
 
diff -r df4fbcedb660 -r 23202362dc97 sys/arch/evbarm/conf/JETSONTK1



Home | Main Index | Thread Index | Old Index