Tegra124: Add support for the ARM architectural timer.
The kernel knows how to use the ARM architectural timer in a generic way, but some setup is needed which is specific to the implementation. The tegra code in the kernel doesn't configure those parts so we need to, or the kernel behaves poorly. BUG=None TEST=Before this change, the kernel would hang, the watch dog timer would go off and kill the machine, and/or there would be random seeming crashes and instability. After this change those problems were essentially gone. BRANCH=None Change-Id: Ibe0dccc964771b0a4a2376be9940192a4dfa6c43 Signed-off-by: Gabe Black <gabeblack@google.com> Reviewed-on: https://chromium-review.googlesource.com/174835 Reviewed-by: Gabe Black <gabeblack@chromium.org> Commit-Queue: Gabe Black <gabeblack@chromium.org> Tested-by: Gabe Black <gabeblack@chromium.org>
This commit is contained in:
parent
9513e608f3
commit
25a91fcf7e
4 changed files with 73 additions and 1 deletions
|
|
@ -22,6 +22,7 @@
|
|||
#include "cpug.h"
|
||||
#include "flow.h"
|
||||
#include "pmc.h"
|
||||
#include "sysctr.h"
|
||||
|
||||
/* Warning: Some devices just use different bits for the same sources for no
|
||||
* apparent reason. *Always* double-check the TRM before trusting this macro. */
|
||||
|
|
@ -32,7 +33,8 @@
|
|||
|
||||
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
||||
static struct flow_ctlr *flow = (void *)TEGRA_FLOW_BASE;
|
||||
static struct tegra_pmc_regs *pmc = (void*)TEGRA_PMC_BASE;
|
||||
static struct tegra_pmc_regs *pmc = (void *)TEGRA_PMC_BASE;
|
||||
static struct sysctr_regs *sysctr = (void *)TEGRA_SYSCTR0_BASE;
|
||||
|
||||
struct pll_dividers {
|
||||
u32 n : 10;
|
||||
|
|
@ -164,6 +166,20 @@ int clock_get_osc_khz(void)
|
|||
return osc_table[clock_get_osc_bits()].khz;
|
||||
}
|
||||
|
||||
void clock_init_arm_generic_timer(void)
|
||||
{
|
||||
uint32_t freq = clock_get_osc_khz() * 1000;
|
||||
// Set the cntfrq register.
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c14, c0, 0\n" :: "r"(freq));
|
||||
|
||||
// Record the system timer frequency.
|
||||
write32(freq, &sysctr->cntfid0);
|
||||
// Enable the system counter.
|
||||
uint32_t cntcr = read32(&sysctr->cntcr);
|
||||
cntcr |= SYSCTR_CNTCR_EN | SYSCTR_CNTCR_HDBG;
|
||||
write32(cntcr, &sysctr->cntcr);
|
||||
}
|
||||
|
||||
static void adjust_pllp_out_freqs(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ enum {
|
|||
TEGRA_EMC_BASE = TEGRA_APB_MISC_BASE + 0xF400,
|
||||
TEGRA_FUSE_BASE = TEGRA_APB_MISC_BASE + 0xF800,
|
||||
TEGRA_CSITE_BASE = 0x70040000,
|
||||
TEGRA_SYSCTR0_BASE = 0x700F0000,
|
||||
TEGRA_USB_ADDR_MASK = 0xFFFFC000,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -180,4 +180,5 @@ void clock_early_uart(void);
|
|||
void clock_cpu0_config_and_reset(void * entry);
|
||||
void clock_config(void);
|
||||
void clock_init(void);
|
||||
void clock_init_arm_generic_timer(void);
|
||||
#endif /* __SOC_NVIDIA_TEGRA124_CLOCK_H__ */
|
||||
|
|
|
|||
54
src/soc/nvidia/tegra124/sysctr.h
Normal file
54
src/soc/nvidia/tegra124/sysctr.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __SOC_NVIDIA_TEGRA124_SYSCTR_H__
|
||||
#define __SOC_NVIDIA_TEGRA124_SYSCTR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
SYSCTR_CNTCR_EN = 1 << 0,
|
||||
SYSCTR_CNTCR_HDBG = 1 << 1,
|
||||
SYSCTR_CNTCR_FCREQ = 1 << 8
|
||||
};
|
||||
|
||||
struct sysctr_regs {
|
||||
uint32_t cntcr;
|
||||
uint32_t cntsr;
|
||||
uint32_t cntcv0;
|
||||
uint32_t cntcv1;
|
||||
uint8_t _rsv0[0x10];
|
||||
uint32_t cntfid0;
|
||||
uint32_t cntfid1;
|
||||
uint8_t _rsv1[0xfa8];
|
||||
uint32_t counterid4;
|
||||
uint32_t counterid5;
|
||||
uint32_t counterid6;
|
||||
uint32_t counterid7;
|
||||
uint32_t counterid0;
|
||||
uint32_t counterid1;
|
||||
uint32_t counterid2;
|
||||
uint32_t counterid3;
|
||||
uint32_t counterid8;
|
||||
uint32_t counterid9;
|
||||
uint32_t counterid10;
|
||||
uint32_t counterid11;
|
||||
};
|
||||
|
||||
#endif /* __SOC_NVIDIA_TEGRA124_SYSCTR_H__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue