Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Add FUSE driver, use it to determine maximum CPU fr...



details:   https://anonhg.NetBSD.org/src/rev/c716bd56979d
branches:  trunk
changeset: 811900:c716bd56979d
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Nov 21 12:09:39 2015 +0000

description:
Add FUSE driver, use it to determine maximum CPU frequency for the board.
Retire CPUFREQ_BOOT option and always use highest available CPU frequency.

diffstat:

 sys/arch/arm/nvidia/files.tegra     |   10 +-
 sys/arch/arm/nvidia/soc_tegra124.c  |  117 ++++++++++++++++++++++++++++++++++-
 sys/arch/arm/nvidia/tegra_car.c     |   26 +++++++-
 sys/arch/arm/nvidia/tegra_cpufreq.c |    8 +-
 sys/arch/arm/nvidia/tegra_fuse.c    |  103 +++++++++++++++++++++++++++++++
 sys/arch/arm/nvidia/tegra_io.c      |    6 +-
 sys/arch/arm/nvidia/tegra_reg.h     |    4 +-
 sys/arch/arm/nvidia/tegra_var.h     |    6 +-
 sys/arch/evbarm/conf/JETSONTK1      |    6 +-
 sys/arch/evbarm/conf/NYAN-BIG       |    3 +-
 10 files changed, 264 insertions(+), 25 deletions(-)

diffs (truncated from 503 to 300 lines):

diff -r d0be1ef1ff0c -r c716bd56979d sys/arch/arm/nvidia/files.tegra
--- a/sys/arch/arm/nvidia/files.tegra   Sat Nov 21 11:15:31 2015 +0000
+++ b/sys/arch/arm/nvidia/files.tegra   Sat Nov 21 12:09:39 2015 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.tegra,v 1.22 2015/11/19 22:09:16 jmcneill Exp $
+#      $NetBSD: files.tegra,v 1.23 2015/11/21 12:09:39 jmcneill Exp $
 #
 # Configuration info for NVIDIA Tegra ARM Peripherals
 #
@@ -32,6 +32,11 @@
 attach tegrapmc at tegraio with tegra_pmc
 file   arch/arm/nvidia/tegra_pmc.c             tegra_pmc
 
+# eFUSE
+device tegrafuse
+attach tegrafuse at tegraio with tegra_fuse
+file   arch/arm/nvidia/tegra_fuse.c            tegra_fuse
+
 # Clock and Reset controller
 device tegracar
 attach tegracar at tegraio with tegra_car
@@ -135,9 +140,6 @@
 # Memory parameters
 defparam opt_tegra.h                   MEMSIZE
 
-# CPU parameters
-defparam opt_tegra.h                   CPUFREQ_BOOT
-
 # SOC parameters
 defflag        opt_tegra.h                     SOC_TEGRAK1
 defflag        opt_tegra.h                     SOC_TEGRA124: SOC_TEGRAK1
diff -r d0be1ef1ff0c -r c716bd56979d sys/arch/arm/nvidia/soc_tegra124.c
--- a/sys/arch/arm/nvidia/soc_tegra124.c        Sat Nov 21 11:15:31 2015 +0000
+++ b/sys/arch/arm/nvidia/soc_tegra124.c        Sat Nov 21 12:09:39 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: soc_tegra124.c,v 1.8 2015/11/12 10:31:29 jmcneill Exp $ */
+/* $NetBSD: soc_tegra124.c,v 1.9 2015/11/21 12:09:39 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: soc_tegra124.c,v 1.8 2015/11/12 10:31:29 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.9 2015/11/21 12:09:39 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -47,6 +47,22 @@
 
 #define EVP_RESET_VECTOR_0_REG 0x100
 
+#define FUSE_SKU_INFO_REG      0x110
+#define FUSE_CPU_SPEEDO_0_REG  0x114
+#define FUSE_CPU_IDDQ_REG      0x118
+#define FUSE_FT_REV_REG                0x128
+#define FUSE_CPU_SPEEDO_1_REG  0x12c
+#define FUSE_CPU_SPEEDO_2_REG  0x130
+#define FUSE_SOC_SPEEDO_0_REG  0x134
+#define FUSE_SOC_SPEEDO_1_REG  0x138
+#define FUSE_SOC_SPEEDO_2_REG  0x13c
+#define FUSE_SOC_IDDQ_REG      0x140
+#define FUSE_GPU_IDDQ_REG      0x228
+
+static void    tegra124_speedo_init(void);
+static int     tegra124_speedo_init_ids(uint32_t);
+static bool    tegra124_speedo_rate_ok(u_int);
+
 static u_int   tegra124_cpufreq_set_rate(u_int);
 static u_int   tegra124_cpufreq_get_rate(void);
 static size_t  tegra124_cpufreq_get_available(u_int *, size_t);
@@ -74,6 +90,23 @@
        { 696, 1, 58, 0 }
 };
 
+static const u_int tegra124_cpufreq_max[] = {
+       2014,
+       2320,
+       2116,
+       2524
+};
+
+static struct tegra124_speedo {
+       u_int cpu_speedo_id;
+       u_int soc_speedo_id;
+       u_int gpu_speedo_id;
+} tegra124_speedo = {
+       .cpu_speedo_id = 0,
+       .soc_speedo_id = 0,
+       .gpu_speedo_id = 0
+};
+
 void
 tegra124_cpuinit(void)
 {
@@ -85,15 +118,85 @@
        tegra_i2c_dvc_write(0x40, (sd0_vsel << 8) | 00, 2);
        delay(10000);
 
+       tegra124_speedo_init();
+
        tegra_cpufreq_register(&tegra124_cpufreq_func);
 }
 
+static void
+tegra124_speedo_init(void)
+{
+       uint32_t sku_id;
+
+       sku_id = tegra_fuse_read(FUSE_SKU_INFO_REG);
+       tegra124_speedo_init_ids(sku_id);
+}
+
+static int
+tegra124_speedo_init_ids(uint32_t sku_id)
+{
+       int threshold = 0;
+
+       switch (sku_id) {
+       case 0x00:
+       case 0x0f:
+       case 0x23:
+               break;  /* use default */
+       case 0x83:
+               tegra124_speedo.cpu_speedo_id = 2;
+               break;
+       case 0x1f:
+       case 0x87:
+       case 0x27:
+               tegra124_speedo.cpu_speedo_id = 2;
+               tegra124_speedo.soc_speedo_id = 0;
+               tegra124_speedo.gpu_speedo_id = 1;
+               break;
+       case 0x81:
+       case 0x21:
+       case 0x07:
+               tegra124_speedo.cpu_speedo_id = 1;
+               tegra124_speedo.soc_speedo_id = 1;
+               tegra124_speedo.gpu_speedo_id = 1;
+               threshold = 1;
+               break;
+       case 0x49:
+       case 0x4a:
+       case 0x48:
+               tegra124_speedo.cpu_speedo_id = 4;
+               tegra124_speedo.soc_speedo_id = 2;
+               tegra124_speedo.gpu_speedo_id = 3;
+               threshold = 1;
+               break;
+       default:
+               aprint_error("tegra124: unknown SKU ID %#x\n", sku_id);
+               break;  /* use default */
+       }
+
+       return threshold;
+}
+
+static bool
+tegra124_speedo_rate_ok(u_int rate)
+{
+       u_int tbl = 0;
+
+       if (tegra124_speedo.cpu_speedo_id < __arraycount(tegra124_cpufreq_max))
+               tbl = tegra124_speedo.cpu_speedo_id;
+
+       return rate <= tegra124_cpufreq_max[tbl];
+}
+
+
 static u_int
 tegra124_cpufreq_set_rate(u_int rate)
 {
        const u_int nrates = __arraycount(tegra124_cpufreq_rates);
        const struct tegra124_cpufreq_rate *r = NULL;
 
+       if (tegra124_speedo_rate_ok(rate) == false)
+               return EINVAL;
+
        for (int i = 0; i < nrates; i++) {
                if (tegra124_cpufreq_rates[i].rate == rate) {
                        r = &tegra124_cpufreq_rates[i];
@@ -118,15 +221,17 @@
 tegra124_cpufreq_get_available(u_int *pavail, size_t maxavail)
 {
        const u_int nrates = __arraycount(tegra124_cpufreq_rates);
-       u_int n;
+       u_int n, cnt;
 
        KASSERT(nrates <= maxavail);
 
-       for (n = 0; n < nrates; n++) {
-               pavail[n] = tegra124_cpufreq_rates[n].rate;
+       for (n = 0, cnt = 0; n < nrates; n++) {
+               if (tegra124_speedo_rate_ok(tegra124_cpufreq_rates[n].rate)) {
+                       pavail[cnt++] = tegra124_cpufreq_rates[n].rate;
+               }
        }
 
-       return nrates;
+       return cnt;
 }
 
 void
diff -r d0be1ef1ff0c -r c716bd56979d sys/arch/arm/nvidia/tegra_car.c
--- a/sys/arch/arm/nvidia/tegra_car.c   Sat Nov 21 11:15:31 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_car.c   Sat Nov 21 12:09:39 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_car.c,v 1.28 2015/11/19 22:26:48 jmcneill Exp $ */
+/* $NetBSD: tegra_car.c,v 1.29 2015/11/21 12:09:39 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.28 2015/11/19 22:26:48 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.29 2015/11/21 12:09:39 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -860,3 +860,25 @@
        /* Leave reset */
        bus_space_write_4(bst, bsh, CAR_RST_DEV_X_CLR_REG, CAR_DEV_X_GPU);
 }
+
+void
+tegra_car_fuse_enable(void)
+{
+       bus_space_tag_t bst;
+       bus_space_handle_t bsh;
+
+       tegra_car_get_bs(&bst, &bsh);
+
+       tegra_reg_set_clear(bst, bsh, CAR_CLK_ENB_H_SET_REG, CAR_DEV_H_FUSE, 0);
+}
+
+void
+tegra_car_fuse_disable(void)
+{
+       bus_space_tag_t bst;
+       bus_space_handle_t bsh;
+
+       tegra_car_get_bs(&bst, &bsh);
+
+       tegra_reg_set_clear(bst, bsh, CAR_CLK_ENB_H_SET_REG, 0, CAR_DEV_H_FUSE);
+}
diff -r d0be1ef1ff0c -r c716bd56979d sys/arch/arm/nvidia/tegra_cpufreq.c
--- a/sys/arch/arm/nvidia/tegra_cpufreq.c       Sat Nov 21 11:15:31 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_cpufreq.c       Sat Nov 21 12:09:39 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_cpufreq.c,v 1.1 2015/05/13 11:06:13 jmcneill Exp $ */
+/* $NetBSD: tegra_cpufreq.c,v 1.2 2015/11/21 12:09:39 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_cpufreq.c,v 1.1 2015/05/13 11:06:13 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_cpufreq.c,v 1.2 2015/11/21 12:09:39 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -128,10 +128,8 @@
                goto sysctl_failed;
        cpufreq_node_available = node->sysctl_num;
 
-#ifdef CPUFREQ_BOOT
-       cpufreq_set_rate(CPUFREQ_BOOT);
+       cpufreq_set_rate(availfreq[0]);
        tegra_cpufreq_post(NULL, NULL);
-#endif
 
        return;
 
diff -r d0be1ef1ff0c -r c716bd56979d sys/arch/arm/nvidia/tegra_fuse.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/nvidia/tegra_fuse.c  Sat Nov 21 12:09:39 2015 +0000
@@ -0,0 +1,103 @@
+/* $NetBSD: tegra_fuse.c,v 1.1 2015/11/21 12:09:39 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.



Home | Main Index | Thread Index | Old Index