Merge branch 'tegra/cleanup' into next/soc
This is a dependency for the tegra/soc branch. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
3be1812ea3
|
@ -99,7 +99,7 @@
|
|||
};
|
||||
|
||||
pmc {
|
||||
compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc";
|
||||
compatible = "nvidia,tegra114-pmc";
|
||||
reg = <0x7000e400 0x400>;
|
||||
};
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@
|
|||
};
|
||||
|
||||
sdhci@c8000600 {
|
||||
cd-gpios = <&gpio 23 0>; /* gpio PC7 */
|
||||
cd-gpios = <&gpio 23 1>; /* gpio PC7 */
|
||||
};
|
||||
|
||||
sound {
|
||||
|
|
|
@ -437,7 +437,7 @@
|
|||
|
||||
sdhci@c8000200 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
|
||||
cd-gpios = <&gpio 69 1>; /* gpio PI5 */
|
||||
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
|
||||
power-gpios = <&gpio 155 0>; /* gpio PT3 */
|
||||
bus-width = <4>;
|
||||
|
@ -445,7 +445,7 @@
|
|||
|
||||
sdhci@c8000600 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 58 0>; /* gpio PH2 */
|
||||
cd-gpios = <&gpio 58 1>; /* gpio PH2 */
|
||||
wp-gpios = <&gpio 59 0>; /* gpio PH3 */
|
||||
power-gpios = <&gpio 70 0>; /* gpio PI6 */
|
||||
bus-width = <8>;
|
||||
|
|
|
@ -436,7 +436,7 @@
|
|||
|
||||
sdhci@c8000000 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 173 0>; /* gpio PV5 */
|
||||
cd-gpios = <&gpio 173 1>; /* gpio PV5 */
|
||||
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
|
||||
power-gpios = <&gpio 169 0>; /* gpio PV1 */
|
||||
bus-width = <4>;
|
||||
|
|
|
@ -584,7 +584,7 @@
|
|||
|
||||
sdhci@c8000400 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
|
||||
cd-gpios = <&gpio 69 1>; /* gpio PI5 */
|
||||
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
|
||||
power-gpios = <&gpio 70 0>; /* gpio PI6 */
|
||||
bus-width = <4>;
|
||||
|
|
|
@ -465,7 +465,7 @@
|
|||
};
|
||||
|
||||
sdhci@c8000600 {
|
||||
cd-gpios = <&gpio 58 0>; /* gpio PH2 */
|
||||
cd-gpios = <&gpio 58 1>; /* gpio PH2 */
|
||||
wp-gpios = <&gpio 59 0>; /* gpio PH3 */
|
||||
bus-width = <4>;
|
||||
status = "okay";
|
||||
|
|
|
@ -325,7 +325,7 @@
|
|||
|
||||
sdhci@c8000600 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 121 0>; /* gpio PP1 */
|
||||
cd-gpios = <&gpio 121 1>; /* gpio PP1 */
|
||||
wp-gpios = <&gpio 122 0>; /* gpio PP2 */
|
||||
bus-width = <4>;
|
||||
};
|
||||
|
|
|
@ -520,7 +520,7 @@
|
|||
|
||||
sdhci@c8000400 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
|
||||
cd-gpios = <&gpio 69 1>; /* gpio PI5 */
|
||||
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
|
||||
power-gpios = <&gpio 70 0>; /* gpio PI6 */
|
||||
bus-width = <4>;
|
||||
|
|
|
@ -510,6 +510,7 @@
|
|||
|
||||
sdhci@c8000400 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 69 1>; /* gpio PI5 */
|
||||
wp-gpios = <&gpio 173 0>; /* gpio PV5 */
|
||||
bus-width = <8>;
|
||||
};
|
||||
|
|
|
@ -145,6 +145,7 @@
|
|||
0 1 0x04
|
||||
0 41 0x04
|
||||
0 42 0x04>;
|
||||
clocks = <&tegra_car 5>;
|
||||
};
|
||||
|
||||
tegra_car: clock {
|
||||
|
@ -304,6 +305,7 @@
|
|||
compatible = "nvidia,tegra20-rtc";
|
||||
reg = <0x7000e000 0x100>;
|
||||
interrupts = <0 2 0x04>;
|
||||
clocks = <&tegra_car 4>;
|
||||
};
|
||||
|
||||
i2c@7000c000 {
|
||||
|
|
|
@ -257,7 +257,7 @@
|
|||
|
||||
sdhci@78000000 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
|
||||
cd-gpios = <&gpio 69 1>; /* gpio PI5 */
|
||||
wp-gpios = <&gpio 155 0>; /* gpio PT3 */
|
||||
power-gpios = <&gpio 31 0>; /* gpio PD7 */
|
||||
bus-width = <4>;
|
||||
|
|
|
@ -311,7 +311,7 @@
|
|||
|
||||
sdhci@78000000 {
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
|
||||
cd-gpios = <&gpio 69 1>; /* gpio PI5 */
|
||||
wp-gpios = <&gpio 155 0>; /* gpio PT3 */
|
||||
power-gpios = <&gpio 31 0>; /* gpio PD7 */
|
||||
bus-width = <4>;
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
0 42 0x04
|
||||
0 121 0x04
|
||||
0 122 0x04>;
|
||||
clocks = <&tegra_car 5>;
|
||||
};
|
||||
|
||||
tegra_car: clock {
|
||||
|
@ -291,6 +292,7 @@
|
|||
compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
|
||||
reg = <0x7000e000 0x100>;
|
||||
interrupts = <0 2 0x04>;
|
||||
clocks = <&tegra_car 4>;
|
||||
};
|
||||
|
||||
i2c@7000c000 {
|
||||
|
@ -423,7 +425,7 @@
|
|||
};
|
||||
|
||||
pmc {
|
||||
compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
|
||||
compatible = "nvidia,tegra30-pmc";
|
||||
reg = <0x7000e400 0x400>;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ obj-y += pm.o
|
|||
obj-y += reset.o
|
||||
obj-y += reset-handler.o
|
||||
obj-y += sleep.o
|
||||
obj-y += tegra.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
|
||||
|
@ -27,9 +28,6 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
|||
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
|
||||
obj-$(CONFIG_TEGRA_PCI) += pcie.o
|
||||
|
||||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
|
||||
endif
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* NVIDIA Tegra114 device tree board support
|
||||
*
|
||||
* Copyright (C) 2013 NVIDIA Corporation
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/clocksource.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
|
||||
static void __init tegra114_dt_init(void)
|
||||
{
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
static const char * const tegra114_dt_board_compat[] = {
|
||||
"nvidia,tegra114",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)")
|
||||
.smp = smp_ops(tegra_smp_ops),
|
||||
.map_io = tegra_map_common_io,
|
||||
.init_early = tegra114_init_early,
|
||||
.init_irq = tegra_dt_init_irq,
|
||||
.init_time = clocksource_of_init,
|
||||
.init_machine = tegra114_dt_init,
|
||||
.init_late = tegra_init_late,
|
||||
.restart = tegra_assert_system_reset,
|
||||
.dt_compat = tegra114_dt_board_compat,
|
||||
MACHINE_END
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* arch/arm/mach-tegra/board-dt-tegra30.c
|
||||
*
|
||||
* NVIDIA Tegra30 device tree board support
|
||||
*
|
||||
* Copyright (C) 2011 NVIDIA Corporation
|
||||
*
|
||||
* Derived from:
|
||||
*
|
||||
* arch/arm/mach-tegra/board-dt-tegra20.c
|
||||
*
|
||||
* Copyright (C) 2010 Secret Lab Technologies, Ltd.
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
#include "iomap.h"
|
||||
|
||||
static void __init tegra30_dt_init(void)
|
||||
{
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
static const char *tegra30_dt_board_compat[] = {
|
||||
"nvidia,tegra30",
|
||||
NULL
|
||||
};
|
||||
|
||||
DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
|
||||
.smp = smp_ops(tegra_smp_ops),
|
||||
.map_io = tegra_map_common_io,
|
||||
.init_early = tegra30_init_early,
|
||||
.init_irq = tegra_dt_init_irq,
|
||||
.init_time = clocksource_of_init,
|
||||
.init_machine = tegra30_dt_init,
|
||||
.init_late = tegra_init_late,
|
||||
.restart = tegra_assert_system_reset,
|
||||
.dt_compat = tegra30_dt_board_compat,
|
||||
MACHINE_END
|
|
@ -62,7 +62,11 @@ int __init harmony_pcie_init(void)
|
|||
goto err_reg;
|
||||
}
|
||||
|
||||
regulator_enable(regulator);
|
||||
err = regulator_enable(regulator);
|
||||
if (err) {
|
||||
pr_err("%s: regulator_enable failed: %d\n", __func__, err);
|
||||
goto err_en;
|
||||
}
|
||||
|
||||
err = tegra_pcie_init(true, true);
|
||||
if (err) {
|
||||
|
@ -74,6 +78,7 @@ int __init harmony_pcie_init(void)
|
|||
|
||||
err_pcie:
|
||||
regulator_disable(regulator);
|
||||
err_en:
|
||||
regulator_put(regulator);
|
||||
err_reg:
|
||||
gpio_free(en_vdd_1v05);
|
||||
|
|
|
@ -26,9 +26,7 @@
|
|||
|
||||
void tegra_assert_system_reset(char mode, const char *cmd);
|
||||
|
||||
void __init tegra20_init_early(void);
|
||||
void __init tegra30_init_early(void);
|
||||
void __init tegra114_init_early(void);
|
||||
void __init tegra_init_early(void);
|
||||
void __init tegra_map_common_io(void);
|
||||
void __init tegra_init_irq(void);
|
||||
void __init tegra_dt_init_irq(void);
|
||||
|
|
|
@ -94,7 +94,7 @@ static void __init tegra_init_cache(void)
|
|||
|
||||
}
|
||||
|
||||
static void __init tegra_init_early(void)
|
||||
void __init tegra_init_early(void)
|
||||
{
|
||||
tegra_cpu_reset_handler_init();
|
||||
tegra_apb_io_init();
|
||||
|
@ -102,31 +102,9 @@ static void __init tegra_init_early(void)
|
|||
tegra_init_cache();
|
||||
tegra_pmc_init();
|
||||
tegra_powergate_init();
|
||||
tegra_hotplug_init();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
void __init tegra20_init_early(void)
|
||||
{
|
||||
tegra_init_early();
|
||||
tegra20_hotplug_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
|
||||
void __init tegra30_init_early(void)
|
||||
{
|
||||
tegra_init_early();
|
||||
tegra30_hotplug_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_114_SOC
|
||||
void __init tegra114_init_early(void)
|
||||
{
|
||||
tegra_init_early();
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init tegra_init_late(void)
|
||||
{
|
||||
tegra_powergate_debugfs_init();
|
||||
|
|
|
@ -102,12 +102,8 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
|
|||
|
||||
smp_wmb();
|
||||
|
||||
save_cpu_arch_register();
|
||||
|
||||
cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
|
||||
|
||||
restore_cpu_arch_register();
|
||||
|
||||
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -7,8 +7,5 @@
|
|||
|
||||
ENTRY(tegra_secondary_startup)
|
||||
bl v7_invalidate_l1
|
||||
/* Enable coresight */
|
||||
mov32 r0, 0xC5ACCE55
|
||||
mcr p14, 0, r0, c7, c12, 6
|
||||
b secondary_startup
|
||||
ENDPROC(tegra_secondary_startup)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
* All Rights Reserved
|
||||
* Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -15,6 +14,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
#include "fuse.h"
|
||||
#include "sleep.h"
|
||||
|
||||
static void (*tegra_hotplug_shutdown)(void);
|
||||
|
@ -56,18 +56,13 @@ int tegra_cpu_disable(unsigned int cpu)
|
|||
return cpu == 0 ? -EPERM : 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
extern void tegra20_hotplug_shutdown(void);
|
||||
void __init tegra20_hotplug_init(void)
|
||||
void __init tegra_hotplug_init(void)
|
||||
{
|
||||
tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
|
||||
}
|
||||
#endif
|
||||
if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
|
||||
extern void tegra30_hotplug_shutdown(void);
|
||||
void __init tegra30_hotplug_init(void)
|
||||
{
|
||||
tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
|
||||
tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
|
||||
tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,22 +26,16 @@
|
|||
#include <asm/smp_scu.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
#include <mach/powergate.h>
|
||||
|
||||
#include "fuse.h"
|
||||
#include "flowctrl.h"
|
||||
#include "reset.h"
|
||||
#include "pmc.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "iomap.h"
|
||||
|
||||
extern void tegra_secondary_startup(void);
|
||||
|
||||
static cpumask_t tegra_cpu_init_mask;
|
||||
|
||||
#define EVP_CPU_RESET_VECTOR \
|
||||
(IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
|
||||
|
||||
static void __cpuinit tegra_secondary_init(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
|
@ -54,25 +48,43 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu)
|
|||
cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
|
||||
}
|
||||
|
||||
static int tegra20_power_up_cpu(unsigned int cpu)
|
||||
|
||||
static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
/* Enable the CPU clock. */
|
||||
cpu = cpu_logical_map(cpu);
|
||||
|
||||
/*
|
||||
* Force the CPU into reset. The CPU must remain in reset when
|
||||
* the flow controller state is cleared (which will cause the
|
||||
* flow controller to stop driving reset if the CPU has been
|
||||
* power-gated via the flow controller). This will have no
|
||||
* effect on first boot of the CPU since it should already be
|
||||
* in reset.
|
||||
*/
|
||||
tegra_put_cpu_in_reset(cpu);
|
||||
|
||||
/*
|
||||
* Unhalt the CPU. If the flow controller was used to
|
||||
* power-gate the CPU this will cause the flow controller to
|
||||
* stop driving reset. The CPU will remain in reset because the
|
||||
* clock and reset block is now driving reset.
|
||||
*/
|
||||
flowctrl_write_cpu_halt(cpu, 0);
|
||||
|
||||
tegra_enable_cpu_clock(cpu);
|
||||
|
||||
/* Clear flow controller CSR. */
|
||||
flowctrl_write_cpu_csr(cpu, 0);
|
||||
|
||||
flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
|
||||
tegra_cpu_out_of_reset(cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra30_power_up_cpu(unsigned int cpu)
|
||||
static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
int ret, pwrgateid;
|
||||
int ret;
|
||||
unsigned long timeout;
|
||||
|
||||
pwrgateid = tegra_cpu_powergate_id(cpu);
|
||||
if (pwrgateid < 0)
|
||||
return pwrgateid;
|
||||
cpu = cpu_logical_map(cpu);
|
||||
tegra_put_cpu_in_reset(cpu);
|
||||
flowctrl_write_cpu_halt(cpu, 0);
|
||||
|
||||
/*
|
||||
* The power up sequence of cold boot CPU and warm boot CPU
|
||||
|
@ -85,13 +97,13 @@ static int tegra30_power_up_cpu(unsigned int cpu)
|
|||
* the IO clamps.
|
||||
* For cold boot CPU, do not wait. After the cold boot CPU be
|
||||
* booted, it will run to tegra_secondary_init() and set
|
||||
* tegra_cpu_init_mask which influences what tegra30_power_up_cpu()
|
||||
* tegra_cpu_init_mask which influences what tegra30_boot_secondary()
|
||||
* next time around.
|
||||
*/
|
||||
if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
|
||||
timeout = jiffies + msecs_to_jiffies(50);
|
||||
do {
|
||||
if (!tegra_powergate_is_powered(pwrgateid))
|
||||
if (tegra_pmc_cpu_is_powered(cpu))
|
||||
goto remove_clamps;
|
||||
udelay(10);
|
||||
} while (time_before(jiffies, timeout));
|
||||
|
@ -103,14 +115,14 @@ static int tegra30_power_up_cpu(unsigned int cpu)
|
|||
* be un-gated by un-toggling the power gate register
|
||||
* manually.
|
||||
*/
|
||||
if (!tegra_powergate_is_powered(pwrgateid)) {
|
||||
ret = tegra_powergate_power_on(pwrgateid);
|
||||
if (!tegra_pmc_cpu_is_powered(cpu)) {
|
||||
ret = tegra_pmc_cpu_power_on(cpu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait for the power to come up. */
|
||||
timeout = jiffies + msecs_to_jiffies(100);
|
||||
while (tegra_powergate_is_powered(pwrgateid)) {
|
||||
while (tegra_pmc_cpu_is_powered(cpu)) {
|
||||
if (time_after(jiffies, timeout))
|
||||
return -ETIMEDOUT;
|
||||
udelay(10);
|
||||
|
@ -123,57 +135,26 @@ remove_clamps:
|
|||
udelay(10);
|
||||
|
||||
/* Remove I/O clamps. */
|
||||
ret = tegra_powergate_remove_clamping(pwrgateid);
|
||||
ret = tegra_pmc_cpu_remove_clamping(cpu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
udelay(10);
|
||||
|
||||
/* Clear flow controller CSR. */
|
||||
flowctrl_write_cpu_csr(cpu, 0);
|
||||
|
||||
flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
|
||||
tegra_cpu_out_of_reset(cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
static int __cpuinit tegra_boot_secondary(unsigned int cpu,
|
||||
struct task_struct *idle)
|
||||
{
|
||||
int status;
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
|
||||
return tegra20_boot_secondary(cpu, idle);
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
|
||||
return tegra30_boot_secondary(cpu, idle);
|
||||
|
||||
cpu = cpu_logical_map(cpu);
|
||||
|
||||
/*
|
||||
* Force the CPU into reset. The CPU must remain in reset when the
|
||||
* flow controller state is cleared (which will cause the flow
|
||||
* controller to stop driving reset if the CPU has been power-gated
|
||||
* via the flow controller). This will have no effect on first boot
|
||||
* of the CPU since it should already be in reset.
|
||||
*/
|
||||
tegra_put_cpu_in_reset(cpu);
|
||||
|
||||
/*
|
||||
* Unhalt the CPU. If the flow controller was used to power-gate the
|
||||
* CPU this will cause the flow controller to stop driving reset.
|
||||
* The CPU will remain in reset because the clock and reset block
|
||||
* is now driving reset.
|
||||
*/
|
||||
flowctrl_write_cpu_halt(cpu, 0);
|
||||
|
||||
switch (tegra_chip_id) {
|
||||
case TEGRA20:
|
||||
status = tegra20_power_up_cpu(cpu);
|
||||
break;
|
||||
case TEGRA30:
|
||||
status = tegra30_power_up_cpu(cpu);
|
||||
break;
|
||||
default:
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status)
|
||||
goto done;
|
||||
|
||||
/* Take the CPU out of reset. */
|
||||
tegra_cpu_out_of_reset(cpu);
|
||||
done:
|
||||
return status;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
|
|
@ -46,26 +46,11 @@
|
|||
#define PMC_CPUPWROFF_TIMER 0xcc
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static unsigned int g_diag_reg;
|
||||
static DEFINE_SPINLOCK(tegra_lp2_lock);
|
||||
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
|
||||
static struct clk *tegra_pclk;
|
||||
void (*tegra_tear_down_cpu)(void);
|
||||
|
||||
void save_cpu_arch_register(void)
|
||||
{
|
||||
/* read diagnostic register */
|
||||
asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
|
||||
return;
|
||||
}
|
||||
|
||||
void restore_cpu_arch_register(void)
|
||||
{
|
||||
/* write diagnostic register */
|
||||
asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
|
||||
return;
|
||||
}
|
||||
|
||||
static void set_power_timers(unsigned long us_on, unsigned long us_off)
|
||||
{
|
||||
unsigned long long ticks;
|
||||
|
@ -119,8 +104,6 @@ static void restore_cpu_complex(void)
|
|||
tegra_cpu_clock_resume();
|
||||
|
||||
flowctrl_cpu_suspend_exit(cpu);
|
||||
|
||||
restore_cpu_arch_register();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -145,8 +128,6 @@ static void suspend_cpu_complex(void)
|
|||
tegra_cpu_clock_suspend();
|
||||
|
||||
flowctrl_cpu_suspend_enter(cpu);
|
||||
|
||||
save_cpu_arch_register();
|
||||
}
|
||||
|
||||
void tegra_clear_cpu_in_lp2(int phy_cpu_id)
|
||||
|
@ -183,12 +164,7 @@ bool tegra_set_cpu_in_lp2(int phy_cpu_id)
|
|||
|
||||
static int tegra_sleep_cpu(unsigned long v2p)
|
||||
{
|
||||
/* Switch to the identity mapping. */
|
||||
cpu_switch_mm(idmap_pgd, &init_mm);
|
||||
|
||||
/* Flush the TLB. */
|
||||
local_flush_tlb_all();
|
||||
|
||||
setup_mm_for_reboot();
|
||||
tegra_sleep_cpu_finish(v2p);
|
||||
|
||||
/* should never here */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,57 +18,149 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "iomap.h"
|
||||
#define PMC_CTRL 0x0
|
||||
#define PMC_CTRL_INTR_LOW (1 << 17)
|
||||
#define PMC_PWRGATE_TOGGLE 0x30
|
||||
#define PMC_PWRGATE_TOGGLE_START (1 << 8)
|
||||
#define PMC_REMOVE_CLAMPING 0x34
|
||||
#define PMC_PWRGATE_STATUS 0x38
|
||||
|
||||
#define PMC_CTRL 0x0
|
||||
#define PMC_CTRL_INTR_LOW (1 << 17)
|
||||
#define TEGRA_POWERGATE_PCIE 3
|
||||
#define TEGRA_POWERGATE_VDEC 4
|
||||
#define TEGRA_POWERGATE_CPU1 9
|
||||
#define TEGRA_POWERGATE_CPU2 10
|
||||
#define TEGRA_POWERGATE_CPU3 11
|
||||
|
||||
static u8 tegra_cpu_domains[] = {
|
||||
0xFF, /* not available for CPU0 */
|
||||
TEGRA_POWERGATE_CPU1,
|
||||
TEGRA_POWERGATE_CPU2,
|
||||
TEGRA_POWERGATE_CPU3,
|
||||
};
|
||||
static DEFINE_SPINLOCK(tegra_powergate_lock);
|
||||
|
||||
static void __iomem *tegra_pmc_base;
|
||||
static bool tegra_pmc_invert_interrupt;
|
||||
|
||||
static inline u32 tegra_pmc_readl(u32 reg)
|
||||
{
|
||||
return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
|
||||
return readl(tegra_pmc_base + reg);
|
||||
}
|
||||
|
||||
static inline void tegra_pmc_writel(u32 val, u32 reg)
|
||||
{
|
||||
writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
|
||||
writel(val, tegra_pmc_base + reg);
|
||||
}
|
||||
|
||||
static int tegra_pmc_get_cpu_powerdomain_id(int cpuid)
|
||||
{
|
||||
if (cpuid <= 0 || cpuid >= num_possible_cpus())
|
||||
return -EINVAL;
|
||||
return tegra_cpu_domains[cpuid];
|
||||
}
|
||||
|
||||
static bool tegra_pmc_powergate_is_powered(int id)
|
||||
{
|
||||
return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1;
|
||||
}
|
||||
|
||||
static int tegra_pmc_powergate_set(int id, bool new_state)
|
||||
{
|
||||
bool old_state;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tegra_powergate_lock, flags);
|
||||
|
||||
old_state = tegra_pmc_powergate_is_powered(id);
|
||||
WARN_ON(old_state == new_state);
|
||||
|
||||
tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE);
|
||||
|
||||
spin_unlock_irqrestore(&tegra_powergate_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pmc_powergate_remove_clamping(int id)
|
||||
{
|
||||
u32 mask;
|
||||
|
||||
/*
|
||||
* Tegra has a bug where PCIE and VDE clamping masks are
|
||||
* swapped relatively to the partition ids.
|
||||
*/
|
||||
if (id == TEGRA_POWERGATE_VDEC)
|
||||
mask = (1 << TEGRA_POWERGATE_PCIE);
|
||||
else if (id == TEGRA_POWERGATE_PCIE)
|
||||
mask = (1 << TEGRA_POWERGATE_VDEC);
|
||||
else
|
||||
mask = (1 << id);
|
||||
|
||||
tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tegra_pmc_cpu_is_powered(int cpuid)
|
||||
{
|
||||
int id;
|
||||
|
||||
id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
|
||||
if (id < 0)
|
||||
return false;
|
||||
return tegra_pmc_powergate_is_powered(id);
|
||||
}
|
||||
|
||||
int tegra_pmc_cpu_power_on(int cpuid)
|
||||
{
|
||||
int id;
|
||||
|
||||
id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
|
||||
if (id < 0)
|
||||
return id;
|
||||
return tegra_pmc_powergate_set(id, true);
|
||||
}
|
||||
|
||||
int tegra_pmc_cpu_remove_clamping(int cpuid)
|
||||
{
|
||||
int id;
|
||||
|
||||
id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
|
||||
if (id < 0)
|
||||
return id;
|
||||
return tegra_pmc_powergate_remove_clamping(id);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id matches[] __initconst = {
|
||||
{ .compatible = "nvidia,tegra114-pmc" },
|
||||
{ .compatible = "nvidia,tegra30-pmc" },
|
||||
{ .compatible = "nvidia,tegra20-pmc" },
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
static void tegra_pmc_parse_dt(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_matching_node(NULL, matches);
|
||||
BUG_ON(!np);
|
||||
|
||||
tegra_pmc_base = of_iomap(np, 0);
|
||||
|
||||
tegra_pmc_invert_interrupt = of_property_read_bool(np,
|
||||
"nvidia,invert-interrupt");
|
||||
}
|
||||
|
||||
void __init tegra_pmc_init(void)
|
||||
{
|
||||
/*
|
||||
* For now, Harmony is the only board that uses the PMC, and it wants
|
||||
* the signal inverted. Seaboard would too if it used the PMC.
|
||||
* Hopefully by the time other boards want to use the PMC, everything
|
||||
* will be device-tree, or they also want it inverted.
|
||||
*/
|
||||
bool invert_interrupt = true;
|
||||
u32 val;
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
if (of_have_populated_dt()) {
|
||||
struct device_node *np;
|
||||
|
||||
invert_interrupt = false;
|
||||
|
||||
np = of_find_matching_node(NULL, matches);
|
||||
if (np) {
|
||||
if (of_find_property(np, "nvidia,invert-interrupt",
|
||||
NULL))
|
||||
invert_interrupt = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
tegra_pmc_parse_dt();
|
||||
|
||||
val = tegra_pmc_readl(PMC_CTRL);
|
||||
if (invert_interrupt)
|
||||
if (tegra_pmc_invert_interrupt)
|
||||
val |= PMC_CTRL_INTR_LOW;
|
||||
else
|
||||
val &= ~PMC_CTRL_INTR_LOW;
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#ifndef __MACH_TEGRA_PMC_H
|
||||
#define __MACH_TEGRA_PMC_H
|
||||
|
||||
bool tegra_pmc_cpu_is_powered(int cpuid);
|
||||
int tegra_pmc_cpu_power_on(int cpuid);
|
||||
int tegra_pmc_cpu_remove_clamping(int cpuid);
|
||||
|
||||
void tegra_pmc_init(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,9 +41,6 @@
|
|||
*/
|
||||
ENTRY(tegra_resume)
|
||||
bl v7_invalidate_l1
|
||||
/* Enable coresight */
|
||||
mov32 r0, 0xC5ACCE55
|
||||
mcr p14, 0, r0, c7, c12, 6
|
||||
|
||||
cpu_id r0
|
||||
cmp r0, #0 @ CPU0?
|
||||
|
@ -99,6 +96,8 @@ ENTRY(__tegra_cpu_reset_handler_start)
|
|||
*
|
||||
* Register usage within the reset handler:
|
||||
*
|
||||
* Others: scratch
|
||||
* R6 = SoC ID << 8
|
||||
* R7 = CPU present (to the OS) mask
|
||||
* R8 = CPU in LP1 state mask
|
||||
* R9 = CPU in LP2 state mask
|
||||
|
@ -114,6 +113,40 @@ ENTRY(__tegra_cpu_reset_handler_start)
|
|||
ENTRY(__tegra_cpu_reset_handler)
|
||||
|
||||
cpsid aif, 0x13 @ SVC mode, interrupts disabled
|
||||
|
||||
mov32 r6, TEGRA_APB_MISC_BASE
|
||||
ldr r6, [r6, #APB_MISC_GP_HIDREV]
|
||||
and r6, r6, #0xff00
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
t20_check:
|
||||
cmp r6, #(0x20 << 8)
|
||||
bne after_t20_check
|
||||
t20_errata:
|
||||
# Tegra20 is a Cortex-A9 r1p1
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read system control register
|
||||
orr r0, r0, #1 << 14 @ erratum 716044
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write system control register
|
||||
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
|
||||
orr r0, r0, #1 << 4 @ erratum 742230
|
||||
orr r0, r0, #1 << 11 @ erratum 751472
|
||||
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
|
||||
b after_errata
|
||||
after_t20_check:
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
|
||||
t30_check:
|
||||
cmp r6, #(0x30 << 8)
|
||||
bne after_t30_check
|
||||
t30_errata:
|
||||
# Tegra30 is a Cortex-A9 r2p9
|
||||
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
|
||||
orr r0, r0, #1 << 6 @ erratum 743622
|
||||
orr r0, r0, #1 << 11 @ erratum 751472
|
||||
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
|
||||
b after_errata
|
||||
after_t30_check:
|
||||
#endif
|
||||
after_errata:
|
||||
mrc p15, 0, r10, c0, c0, 5 @ MPIDR
|
||||
and r10, r10, #0x3 @ R10 = CPU number
|
||||
mov r11, #1
|
||||
|
@ -129,16 +162,13 @@ ENTRY(__tegra_cpu_reset_handler)
|
|||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
/* Are we on Tegra20? */
|
||||
mov32 r6, TEGRA_APB_MISC_BASE
|
||||
ldr r0, [r6, #APB_MISC_GP_HIDREV]
|
||||
and r0, r0, #0xff00
|
||||
cmp r0, #(0x20 << 8)
|
||||
cmp r6, #(0x20 << 8)
|
||||
bne 1f
|
||||
/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
|
||||
mov32 r6, TEGRA_PMC_BASE
|
||||
mov32 r5, TEGRA_PMC_BASE
|
||||
mov r0, #0
|
||||
cmp r10, #0
|
||||
strne r0, [r6, #PMC_SCRATCH41]
|
||||
strne r0, [r5, #PMC_SCRATCH41]
|
||||
1:
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -124,11 +124,11 @@ int tegra_sleep_cpu_finish(unsigned long);
|
|||
void tegra_disable_clean_inv_dcache(void);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
void tegra20_hotplug_init(void);
|
||||
void tegra30_hotplug_init(void);
|
||||
void tegra20_hotplug_shutdown(void);
|
||||
void tegra30_hotplug_shutdown(void);
|
||||
void tegra_hotplug_init(void);
|
||||
#else
|
||||
static inline void tegra20_hotplug_init(void) {}
|
||||
static inline void tegra30_hotplug_init(void) {}
|
||||
static inline void tegra_hotplug_init(void) {}
|
||||
#endif
|
||||
|
||||
void tegra20_cpu_shutdown(int cpu);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* nVidia Tegra device tree board support
|
||||
* NVIDIA Tegra SoC device tree board support
|
||||
*
|
||||
* Copyright (C) 2011, 2013, NVIDIA Corporation
|
||||
* Copyright (C) 2010 Secret Lab Technologies, Ltd.
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
*
|
||||
|
@ -111,7 +112,8 @@ static void __init harmony_init(void)
|
|||
|
||||
static void __init paz00_init(void)
|
||||
{
|
||||
tegra_paz00_wifikill_init();
|
||||
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
|
||||
tegra_paz00_wifikill_init();
|
||||
}
|
||||
|
||||
static struct {
|
||||
|
@ -137,19 +139,21 @@ static void __init tegra_dt_init_late(void)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *tegra20_dt_board_compat[] = {
|
||||
static const char * const tegra_dt_board_compat[] = {
|
||||
"nvidia,tegra114",
|
||||
"nvidia,tegra30",
|
||||
"nvidia,tegra20",
|
||||
NULL
|
||||
};
|
||||
|
||||
DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
|
||||
DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
|
||||
.map_io = tegra_map_common_io,
|
||||
.smp = smp_ops(tegra_smp_ops),
|
||||
.init_early = tegra20_init_early,
|
||||
.init_early = tegra_init_early,
|
||||
.init_irq = tegra_dt_init_irq,
|
||||
.init_time = clocksource_of_init,
|
||||
.init_machine = tegra_dt_init,
|
||||
.init_late = tegra_dt_init_late,
|
||||
.restart = tegra_assert_system_reset,
|
||||
.dt_compat = tegra20_dt_board_compat,
|
||||
.dt_compat = tegra_dt_board_compat,
|
||||
MACHINE_END
|
|
@ -711,8 +711,8 @@ static void tegra20_pll_init(void)
|
|||
}
|
||||
|
||||
static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
|
||||
"pll_p_cclk", "pll_p_out4_cclk",
|
||||
"pll_p_out3_cclk", "clk_d", "pll_x" };
|
||||
"pll_p", "pll_p_out4",
|
||||
"pll_p_out3", "clk_d", "pll_x" };
|
||||
static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
|
||||
"pll_p_out3", "pll_p_out2", "clk_d",
|
||||
"clk_32k", "pll_m_out1" };
|
||||
|
@ -721,38 +721,6 @@ static void tegra20_super_clk_init(void)
|
|||
{
|
||||
struct clk *clk;
|
||||
|
||||
/*
|
||||
* DIV_U71 dividers for CCLK, these dividers are used only
|
||||
* if parent clock is fixed rate.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Clock input to cclk divided from pll_p using
|
||||
* U71 divider of cclk.
|
||||
*/
|
||||
clk = tegra_clk_register_divider("pll_p_cclk", "pll_p",
|
||||
clk_base + SUPER_CCLK_DIVIDER, 0,
|
||||
TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
|
||||
clk_register_clkdev(clk, "pll_p_cclk", NULL);
|
||||
|
||||
/*
|
||||
* Clock input to cclk divided from pll_p_out3 using
|
||||
* U71 divider of cclk.
|
||||
*/
|
||||
clk = tegra_clk_register_divider("pll_p_out3_cclk", "pll_p_out3",
|
||||
clk_base + SUPER_CCLK_DIVIDER, 0,
|
||||
TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
|
||||
clk_register_clkdev(clk, "pll_p_out3_cclk", NULL);
|
||||
|
||||
/*
|
||||
* Clock input to cclk divided from pll_p_out4 using
|
||||
* U71 divider of cclk.
|
||||
*/
|
||||
clk = tegra_clk_register_divider("pll_p_out4_cclk", "pll_p_out4",
|
||||
clk_base + SUPER_CCLK_DIVIDER, 0,
|
||||
TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
|
||||
clk_register_clkdev(clk, "pll_p_out4_cclk", NULL);
|
||||
|
||||
/* CCLK */
|
||||
clk = tegra_clk_register_super_mux("cclk", cclk_parents,
|
||||
ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
|
||||
|
|
|
@ -189,7 +189,7 @@ static void __init tegra20_init_timer(void)
|
|||
BUG();
|
||||
}
|
||||
|
||||
clk = clk_get_sys("timer", NULL);
|
||||
clk = of_clk_get(np, 0);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
|
||||
rate = 12000000;
|
||||
|
@ -216,7 +216,7 @@ static void __init tegra20_init_timer(void)
|
|||
* rtc registers are used by read_persistent_clock, keep the rtc clock
|
||||
* enabled
|
||||
*/
|
||||
clk = clk_get_sys("rtc-tegra", NULL);
|
||||
clk = of_clk_get(np, 0);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("Unable to get rtc-tegra clock\n");
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue