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.
This commit is contained in:
parent
cd139f033f
commit
095f6375b1
|
@ -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
|
# 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/arm32/armv7_generic_space.c
|
||||||
file arch/arm/arm/bus_space_a4x.S
|
file arch/arm/arm/bus_space_a4x.S
|
||||||
|
|
||||||
file arch/arm/nvidia/tegra_soc.c
|
# Devicetree
|
||||||
file arch/arm/nvidia/tegra_cpufreq.c
|
|
||||||
file arch/arm/nvidia/soc_tegra124.c soc_tegra124
|
|
||||||
|
|
||||||
# On-board I/O
|
|
||||||
device tegrafdt : bus_space_generic, fdtbus
|
device tegrafdt : bus_space_generic, fdtbus
|
||||||
attach tegrafdt at mainbus with tegra_fdt
|
attach tegrafdt at mainbus with tegra_fdt
|
||||||
file arch/arm/nvidia/tegra_fdt.c 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
|
# Interrupt controller
|
||||||
device tegralic
|
device tegralic
|
||||||
attach tegralic at fdt with tegra_lic
|
attach tegralic at fdt with tegra_lic
|
||||||
|
|
|
@ -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 <jmcneill@invisible.ca>
|
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
#include "opt_multiprocessor.h"
|
#include "opt_multiprocessor.h"
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__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 <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
|
@ -39,8 +39,6 @@ __KERNEL_RCSID(0, "$NetBSD: soc_tegra124.c,v 1.15 2017/04/17 00:43:42 jmcneill E
|
||||||
|
|
||||||
#include <uvm/uvm_extern.h>
|
#include <uvm/uvm_extern.h>
|
||||||
|
|
||||||
#include <dev/clk/clk.h>
|
|
||||||
#include <dev/i2c/i2cvar.h>
|
|
||||||
#include <dev/fdt/fdtvar.h>
|
#include <dev/fdt/fdtvar.h>
|
||||||
|
|
||||||
#include <arm/cpufunc.h>
|
#include <arm/cpufunc.h>
|
||||||
|
@ -71,6 +69,13 @@ static u_int tegra124_cpufreq_set_rate(u_int);
|
||||||
static u_int tegra124_cpufreq_get_rate(void);
|
static u_int tegra124_cpufreq_get_rate(void);
|
||||||
static size_t tegra124_cpufreq_get_available(u_int *, size_t);
|
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 = {
|
static const struct tegra_cpufreq_func tegra124_cpufreq_func = {
|
||||||
.set_rate = tegra124_cpufreq_set_rate,
|
.set_rate = tegra124_cpufreq_set_rate,
|
||||||
.get_rate = tegra124_cpufreq_get_rate,
|
.get_rate = tegra124_cpufreq_get_rate,
|
||||||
|
@ -82,16 +87,17 @@ static struct tegra124_cpufreq_rate {
|
||||||
u_int divm;
|
u_int divm;
|
||||||
u_int divn;
|
u_int divn;
|
||||||
u_int divp;
|
u_int divp;
|
||||||
|
u_int uvol;
|
||||||
} tegra124_cpufreq_rates[] = {
|
} tegra124_cpufreq_rates[] = {
|
||||||
{ 2316, 1, 193, 0 },
|
{ 2316, 1, 193, 0, 1400000 },
|
||||||
{ 2100, 1, 175, 0 },
|
{ 2100, 1, 175, 0, 1400000 },
|
||||||
{ 1896, 1, 158, 0 },
|
{ 1896, 1, 158, 0, 1400000 },
|
||||||
{ 1692, 1, 141, 0 },
|
{ 1692, 1, 141, 0, 1400000 },
|
||||||
{ 1500, 1, 125, 0 },
|
{ 1500, 1, 125, 0, 1400000 },
|
||||||
{ 1296, 1, 108, 0 },
|
{ 1296, 1, 108, 0, 1400000 },
|
||||||
{ 1092, 1, 91, 0 },
|
{ 1092, 1, 91, 0, 1400000 },
|
||||||
{ 900, 1, 75, 0 },
|
{ 900, 1, 75, 0, 1400000 },
|
||||||
{ 696, 1, 58, 0 }
|
{ 696, 1, 58, 0, 1400000 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u_int tegra124_cpufreq_max[] = {
|
static const u_int tegra124_cpufreq_max[] = {
|
||||||
|
@ -112,42 +118,46 @@ static struct tegra124_speedo {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk *tegra124_clk_pllx = NULL;
|
static struct clk *tegra124_clk_pllx = NULL;
|
||||||
|
static struct fdtbus_regulator *tegra124_reg_vddcpu = NULL;
|
||||||
|
|
||||||
void
|
static int
|
||||||
tegra124_cpuinit(void)
|
tegra124_cpu_match(device_t parent, cfdata_t cf, void *aux)
|
||||||
{
|
{
|
||||||
int i2c_node = OF_finddevice("/i2c@7000d000");
|
const char * const compatible[] = { "nvidia,tegra124", NULL };
|
||||||
if (i2c_node == -1)
|
struct fdt_attach_args *faa = aux;
|
||||||
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);
|
|
||||||
|
|
||||||
/* Set VDD_CPU voltage to 1.4V */
|
if (OF_finddevice("/cpus") != faa->faa_phandle)
|
||||||
const u_int target_mv = 1400;
|
return 0;
|
||||||
const u_int sd0_vsel = (target_mv - 600) / 10;
|
|
||||||
uint8_t data[2] = { 0x00, sd0_vsel };
|
|
||||||
|
|
||||||
iic_acquire_bus(ic, I2C_F_POLL);
|
return of_match_compatible(OF_finddevice("/"), compatible);
|
||||||
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);
|
|
||||||
|
|
||||||
|
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();
|
tegra124_speedo_init();
|
||||||
|
|
||||||
int cpu_node = OF_finddevice("/cpus/cpu@0");
|
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_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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +236,7 @@ tegra124_cpufreq_set_rate(u_int rate)
|
||||||
const struct tegra124_cpufreq_rate *r = NULL;
|
const struct tegra124_cpufreq_rate *r = NULL;
|
||||||
CPU_INFO_ITERATOR cii;
|
CPU_INFO_ITERATOR cii;
|
||||||
struct cpu_info *ci;
|
struct cpu_info *ci;
|
||||||
|
u_int cur_uvol;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (tegra124_speedo_rate_ok(rate) == false)
|
if (tegra124_speedo_rate_ok(rate) == false)
|
||||||
|
@ -240,6 +251,17 @@ tegra124_cpufreq_set_rate(u_int rate)
|
||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
return EINVAL;
|
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);
|
error = clk_set_rate(tegra124_clk_pllx, r->rate * 1000000);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
rate = tegra124_cpufreq_get_rate();
|
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;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 <jmcneill@invisible.ca>
|
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
#include "locators.h"
|
#include "locators.h"
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__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 <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
|
@ -58,21 +58,14 @@ static char tegra_cpufreq_available[TEGRA_CPUFREQ_MAX * 5];
|
||||||
|
|
||||||
void
|
void
|
||||||
tegra_cpufreq_register(const struct tegra_cpufreq_func *cf)
|
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;
|
const struct sysctlnode *node, *cpunode, *freqnode;
|
||||||
u_int availfreq[TEGRA_CPUFREQ_MAX];
|
u_int availfreq[TEGRA_CPUFREQ_MAX];
|
||||||
size_t nfreq;
|
size_t nfreq;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (cpufreq_func == NULL)
|
KASSERT(cpufreq_func == NULL);
|
||||||
return;
|
cpufreq_func = cf;
|
||||||
|
|
||||||
nfreq = cpufreq_get_available(availfreq, TEGRA_CPUFREQ_MAX);
|
nfreq = cpufreq_get_available(availfreq, TEGRA_CPUFREQ_MAX);
|
||||||
if (nfreq == 0)
|
if (nfreq == 0)
|
||||||
|
|
|
@ -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 <jmcneill@invisible.ca>
|
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
#include "opt_tegra.h"
|
#include "opt_tegra.h"
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__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 <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -77,6 +77,4 @@ tegrafdt_attach(device_t parent, device_t self, void *aux)
|
||||||
.faa_phandle = OF_peer(0),
|
.faa_phandle = OF_peer(0),
|
||||||
};
|
};
|
||||||
config_found(self, &faa, NULL);
|
config_found(self, &faa, NULL);
|
||||||
|
|
||||||
tegra_cpuinit();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <jmcneill@invisible.ca>
|
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
#include "opt_multiprocessor.h"
|
#include "opt_multiprocessor.h"
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__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
|
#define _ARM32_BUS_DMA_PRIVATE
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -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
|
static void
|
||||||
tegra_mpinit(void)
|
tegra_mpinit(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 <jmcneill@invisible.ca>
|
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||||
|
@ -51,7 +51,6 @@ u_int tegra_chip_id(void);
|
||||||
const char *tegra_chip_name(void);
|
const char *tegra_chip_name(void);
|
||||||
void tegra_bootstrap(void);
|
void tegra_bootstrap(void);
|
||||||
void tegra_dma_bootstrap(psize_t);
|
void tegra_dma_bootstrap(psize_t);
|
||||||
void tegra_cpuinit(void);
|
|
||||||
|
|
||||||
struct tegra_gpio_pin;
|
struct tegra_gpio_pin;
|
||||||
struct tegra_gpio_pin *tegra_gpio_acquire(const char *, u_int);
|
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);
|
size_t (*get_available)(u_int *, size_t);
|
||||||
};
|
};
|
||||||
void tegra_cpufreq_register(const struct tegra_cpufreq_func *);
|
void tegra_cpufreq_register(const struct tegra_cpufreq_func *);
|
||||||
void tegra_cpufreq_init(void);
|
|
||||||
|
|
||||||
#if defined(SOC_TEGRA124)
|
#if defined(SOC_TEGRA124)
|
||||||
void tegra124_cpuinit(void);
|
|
||||||
void tegra124_mpinit(void);
|
void tegra124_mpinit(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -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)
|
# NVIDIA Tegra K1 (T124)
|
||||||
#
|
#
|
||||||
|
@ -39,6 +39,9 @@ armgtmr0 at armperiph? # ARM Generic Timer
|
||||||
tegrafdt0 at mainbus?
|
tegrafdt0 at mainbus?
|
||||||
fdt* at fdtbus?
|
fdt* at fdtbus?
|
||||||
|
|
||||||
|
# CPU frequency scaling
|
||||||
|
tegra124cpu* at fdt?
|
||||||
|
|
||||||
fclock* at fdt?
|
fclock* at fdt?
|
||||||
fregulator* at fdt?
|
fregulator* at fdt?
|
||||||
gpiokeys* at fdt?
|
gpiokeys* at fdt?
|
||||||
|
|
Loading…
Reference in New Issue