From 095f6375b12b0fb47b872d38c979a1c14ab8be5e Mon Sep 17 00:00:00 2001 From: jmcneill Date: Sat, 22 Apr 2017 23:53:24 +0000 Subject: [PATCH] Get rid of tegra_cpuinit after scanning fdt and attach the cpufreq support to the /cpus node. Use regulator API instead of poking directly at the I2C controller to set voltages. --- sys/arch/arm/nvidia/files.tegra | 16 +++-- sys/arch/arm/nvidia/soc_tegra124.c | 105 +++++++++++++++++----------- sys/arch/arm/nvidia/tegra_cpufreq.c | 15 ++-- sys/arch/arm/nvidia/tegra_fdt.c | 6 +- sys/arch/arm/nvidia/tegra_soc.c | 18 +---- sys/arch/arm/nvidia/tegra_var.h | 5 +- sys/arch/evbarm/conf/TEGRA | 5 +- 7 files changed, 89 insertions(+), 81 deletions(-) diff --git a/sys/arch/arm/nvidia/files.tegra b/sys/arch/arm/nvidia/files.tegra index 6fcdd94099eb..9d2e1e785ba3 100644 --- a/sys/arch/arm/nvidia/files.tegra +++ b/sys/arch/arm/nvidia/files.tegra @@ -1,4 +1,4 @@ -# $NetBSD: files.tegra,v 1.31 2017/04/21 23:35:29 jmcneill Exp $ +# $NetBSD: files.tegra,v 1.32 2017/04/22 23:53:24 jmcneill Exp $ # # Configuration info for NVIDIA Tegra ARM Peripherals # @@ -13,15 +13,19 @@ file arch/arm/arm32/irq_dispatch.S file arch/arm/arm32/armv7_generic_space.c file arch/arm/arm/bus_space_a4x.S -file arch/arm/nvidia/tegra_soc.c -file arch/arm/nvidia/tegra_cpufreq.c -file arch/arm/nvidia/soc_tegra124.c soc_tegra124 - -# On-board I/O +# Devicetree device tegrafdt : bus_space_generic, fdtbus attach tegrafdt at mainbus with tegra_fdt file arch/arm/nvidia/tegra_fdt.c tegra_fdt +file arch/arm/nvidia/tegra_soc.c +file arch/arm/nvidia/tegra_cpufreq.c + +# Tegra T124 (32-bit K1) support +device tegra124cpu +attach tegra124cpu at fdt with tegra124_cpu +file arch/arm/nvidia/soc_tegra124.c soc_tegra124 | tegra124_cpu + # Interrupt controller device tegralic attach tegralic at fdt with tegra_lic diff --git a/sys/arch/arm/nvidia/soc_tegra124.c b/sys/arch/arm/nvidia/soc_tegra124.c index a27c5ae594b2..98938c9a8321 100644 --- a/sys/arch/arm/nvidia/soc_tegra124.c +++ b/sys/arch/arm/nvidia/soc_tegra124.c @@ -1,4 +1,4 @@ -/* $NetBSD: soc_tegra124.c,v 1.15 2017/04/17 00:43:42 jmcneill Exp $ */ +/* $NetBSD: soc_tegra124.c,v 1.16 2017/04/22 23:53:24 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill @@ -30,7 +30,7 @@ #include "opt_multiprocessor.h" #include -__KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.15 2017/04/17 00:43:42 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.16 2017/04/22 23:53:24 jmcneill Exp $"); #include #include @@ -39,8 +39,6 @@ __KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.15 2017/04/17 00:43:42 jmcneill E #include -#include -#include #include #include @@ -71,6 +69,13 @@ 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); +static int tegra124_cpu_match(device_t, cfdata_t, void *); +static void tegra124_cpu_attach(device_t, device_t, void *); +static void tegra124_cpu_init_cpufreq(device_t); + +CFATTACH_DECL_NEW(tegra124_cpu, 0, tegra124_cpu_match, tegra124_cpu_attach, + NULL, NULL); + static const struct tegra_cpufreq_func tegra124_cpufreq_func = { .set_rate = tegra124_cpufreq_set_rate, .get_rate = tegra124_cpufreq_get_rate, @@ -82,16 +87,17 @@ static struct tegra124_cpufreq_rate { u_int divm; u_int divn; u_int divp; + u_int uvol; } tegra124_cpufreq_rates[] = { - { 2316, 1, 193, 0 }, - { 2100, 1, 175, 0 }, - { 1896, 1, 158, 0 }, - { 1692, 1, 141, 0 }, - { 1500, 1, 125, 0 }, - { 1296, 1, 108, 0 }, - { 1092, 1, 91, 0 }, - { 900, 1, 75, 0 }, - { 696, 1, 58, 0 } + { 2316, 1, 193, 0, 1400000 }, + { 2100, 1, 175, 0, 1400000 }, + { 1896, 1, 158, 0, 1400000 }, + { 1692, 1, 141, 0, 1400000 }, + { 1500, 1, 125, 0, 1400000 }, + { 1296, 1, 108, 0, 1400000 }, + { 1092, 1, 91, 0, 1400000 }, + { 900, 1, 75, 0, 1400000 }, + { 696, 1, 58, 0, 1400000 } }; static const u_int tegra124_cpufreq_max[] = { @@ -112,42 +118,46 @@ static struct tegra124_speedo { }; static struct clk *tegra124_clk_pllx = NULL; +static struct fdtbus_regulator *tegra124_reg_vddcpu = NULL; -void -tegra124_cpuinit(void) +static int +tegra124_cpu_match(device_t parent, cfdata_t cf, void *aux) { - int i2c_node = OF_finddevice("/i2c@7000d000"); - if (i2c_node == -1) - i2c_node = OF_finddevice("/i2c@0,7000d000"); /* old DTB */ - if (i2c_node == -1) { - aprint_error("cpufreq: ERROR: couldn't find i2c@7000d000\n"); - return; - } - i2c_tag_t ic = fdtbus_get_i2c_tag(i2c_node); + const char * const compatible[] = { "nvidia,tegra124", NULL }; + struct fdt_attach_args *faa = aux; - /* Set VDD_CPU voltage to 1.4V */ - const u_int target_mv = 1400; - const u_int sd0_vsel = (target_mv - 600) / 10; - uint8_t data[2] = { 0x00, sd0_vsel }; + if (OF_finddevice("/cpus") != faa->faa_phandle) + return 0; - iic_acquire_bus(ic, I2C_F_POLL); - const int error = iic_exec(ic, I2C_OP_WRITE_WITH_STOP, 0x40, - NULL, 0, data, sizeof(data), I2C_F_POLL); - iic_release_bus(ic, I2C_F_POLL); - if (error) { - aprint_error("cpufreq: ERROR: couldn't set VDD_CPU: %d\n", - error); - return; - } - delay(10000); + return of_match_compatible(OF_finddevice("/"), compatible); +} +static void +tegra124_cpu_attach(device_t parent, device_t self, void *aux) +{ + aprint_naive("\n"); + aprint_normal(": CPU complex\n"); + + config_defer(self, tegra124_cpu_init_cpufreq); +} + +static void +tegra124_cpu_init_cpufreq(device_t dev) +{ tegra124_speedo_init(); int cpu_node = OF_finddevice("/cpus/cpu@0"); - if (cpu_node != -1) + if (cpu_node != -1) { tegra124_clk_pllx = fdtbus_clock_get(cpu_node, "pll_x"); + tegra124_reg_vddcpu = fdtbus_regulator_acquire(cpu_node, + "vdd-cpu-supply"); + } if (tegra124_clk_pllx == NULL) { - aprint_error("cpufreq: ERROR: couldn't find pll_x\n"); + aprint_error_dev(dev, "couldn't find clock pll_x\n"); + return; + } + if (tegra124_reg_vddcpu == NULL) { + aprint_error_dev(dev, "couldn't find voltage regulator\n"); return; } @@ -226,6 +236,7 @@ tegra124_cpufreq_set_rate(u_int rate) const struct tegra124_cpufreq_rate *r = NULL; CPU_INFO_ITERATOR cii; struct cpu_info *ci; + u_int cur_uvol; int error; if (tegra124_speedo_rate_ok(rate) == false) @@ -240,6 +251,17 @@ tegra124_cpufreq_set_rate(u_int rate) if (r == NULL) return EINVAL; + error = fdtbus_regulator_get_voltage(tegra124_reg_vddcpu, &cur_uvol); + if (error != 0) + return error; + + if (cur_uvol < r->uvol) { + error = fdtbus_regulator_set_voltage(tegra124_reg_vddcpu, + r->uvol, r->uvol); + if (error != 0) + return error; + } + error = clk_set_rate(tegra124_clk_pllx, r->rate * 1000000); if (error == 0) { rate = tegra124_cpufreq_get_rate(); @@ -248,6 +270,11 @@ tegra124_cpufreq_set_rate(u_int rate) } } + if (cur_uvol > r->uvol) { + (void)fdtbus_regulator_set_voltage(tegra124_reg_vddcpu, + r->uvol, r->uvol); + } + return error; } diff --git a/sys/arch/arm/nvidia/tegra_cpufreq.c b/sys/arch/arm/nvidia/tegra_cpufreq.c index 66148917352e..e0fb78b91580 100644 --- a/sys/arch/arm/nvidia/tegra_cpufreq.c +++ b/sys/arch/arm/nvidia/tegra_cpufreq.c @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_cpufreq.c,v 1.4 2016/11/21 04:10:05 ozaki-r Exp $ */ +/* $NetBSD: tegra_cpufreq.c,v 1.5 2017/04/22 23:53:24 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill @@ -29,7 +29,7 @@ #include "locators.h" #include -__KERNEL_RCSID(0, "$NetBSD: tegra_cpufreq.c,v 1.4 2016/11/21 04:10:05 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_cpufreq.c,v 1.5 2017/04/22 23:53:24 jmcneill Exp $"); #include #include @@ -58,21 +58,14 @@ static char tegra_cpufreq_available[TEGRA_CPUFREQ_MAX * 5]; void tegra_cpufreq_register(const struct tegra_cpufreq_func *cf) -{ - KASSERT(cpufreq_func == NULL); - cpufreq_func = cf; -} - -void -tegra_cpufreq_init(void) { const struct sysctlnode *node, *cpunode, *freqnode; u_int availfreq[TEGRA_CPUFREQ_MAX]; size_t nfreq; int error; - if (cpufreq_func == NULL) - return; + KASSERT(cpufreq_func == NULL); + cpufreq_func = cf; nfreq = cpufreq_get_available(availfreq, TEGRA_CPUFREQ_MAX); if (nfreq == 0) diff --git a/sys/arch/arm/nvidia/tegra_fdt.c b/sys/arch/arm/nvidia/tegra_fdt.c index a71265884185..0ad5dd48c014 100644 --- a/sys/arch/arm/nvidia/tegra_fdt.c +++ b/sys/arch/arm/nvidia/tegra_fdt.c @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_fdt.c,v 1.4 2017/04/16 12:27:47 jmcneill Exp $ */ +/* $NetBSD: tegra_fdt.c,v 1.5 2017/04/22 23:53:24 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill @@ -29,7 +29,7 @@ #include "opt_tegra.h" #include -__KERNEL_RCSID(0, "$NetBSD: tegra_fdt.c,v 1.4 2017/04/16 12:27:47 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_fdt.c,v 1.5 2017/04/22 23:53:24 jmcneill Exp $"); #include #include @@ -77,6 +77,4 @@ tegrafdt_attach(device_t parent, device_t self, void *aux) .faa_phandle = OF_peer(0), }; config_found(self, &faa, NULL); - - tegra_cpuinit(); } diff --git a/sys/arch/arm/nvidia/tegra_soc.c b/sys/arch/arm/nvidia/tegra_soc.c index 6898120fbebb..53c8e65673ce 100644 --- a/sys/arch/arm/nvidia/tegra_soc.c +++ b/sys/arch/arm/nvidia/tegra_soc.c @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_soc.c,v 1.9 2016/03/26 09:07:31 skrll Exp $ */ +/* $NetBSD: tegra_soc.c,v 1.10 2017/04/22 23:53:24 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill @@ -30,7 +30,7 @@ #include "opt_multiprocessor.h" #include -__KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.9 2016/03/26 09:07:31 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra_soc.c,v 1.10 2017/04/22 23:53:24 jmcneill Exp $"); #define _ARM32_BUS_DMA_PRIVATE #include @@ -89,20 +89,6 @@ tegra_dma_bootstrap(psize_t psize) { } -void -tegra_cpuinit(void) -{ - switch (tegra_chip_id()) { -#ifdef SOC_TEGRA124 - case CHIP_ID_TEGRA124: - tegra124_cpuinit(); - break; -#endif - } - - tegra_cpufreq_init(); -} - static void tegra_mpinit(void) { diff --git a/sys/arch/arm/nvidia/tegra_var.h b/sys/arch/arm/nvidia/tegra_var.h index a6c5c15c7279..e55cde347a23 100644 --- a/sys/arch/arm/nvidia/tegra_var.h +++ b/sys/arch/arm/nvidia/tegra_var.h @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_var.h,v 1.32 2017/04/21 21:13:04 jmcneill Exp $ */ +/* $NetBSD: tegra_var.h,v 1.33 2017/04/22 23:53:24 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill @@ -51,7 +51,6 @@ u_int tegra_chip_id(void); const char *tegra_chip_name(void); void tegra_bootstrap(void); void tegra_dma_bootstrap(psize_t); -void tegra_cpuinit(void); struct tegra_gpio_pin; struct tegra_gpio_pin *tegra_gpio_acquire(const char *, u_int); @@ -103,10 +102,8 @@ struct tegra_cpufreq_func { size_t (*get_available)(u_int *, size_t); }; void tegra_cpufreq_register(const struct tegra_cpufreq_func *); -void tegra_cpufreq_init(void); #if defined(SOC_TEGRA124) -void tegra124_cpuinit(void); void tegra124_mpinit(void); #endif diff --git a/sys/arch/evbarm/conf/TEGRA b/sys/arch/evbarm/conf/TEGRA index bd20e1e33627..199b4057ae1b 100644 --- a/sys/arch/evbarm/conf/TEGRA +++ b/sys/arch/evbarm/conf/TEGRA @@ -1,5 +1,5 @@ # -# $NetBSD: TEGRA,v 1.16 2017/04/22 21:50:13 jmcneill Exp $ +# $NetBSD: TEGRA,v 1.17 2017/04/22 23:53:24 jmcneill Exp $ # # NVIDIA Tegra K1 (T124) # @@ -39,6 +39,9 @@ armgtmr0 at armperiph? # ARM Generic Timer tegrafdt0 at mainbus? fdt* at fdtbus? +# CPU frequency scaling +tegra124cpu* at fdt? + fclock* at fdt? fregulator* at fdt? gpiokeys* at fdt?