From eb222d1d7de5946501ed15c49f9d23bc05fc5a87 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 27 Mar 2013 09:37:02 +0000 Subject: ARM: tegra: support T33 SKU of Tegra30 Make U-Boot aware of the T33 SKU of Tegra30, and treat it identically to any other Tegra30. An alternative would be to simply remove the SKU checking from tegra_get_chip_type(); most use of the value most likely simply wants to know the current chip, not the specific SKU. Or, the function could be split into separate tegra_get_chip() and tegra_get_sku() for the cases where differentiation really is required. I wonder whether tegra_get_chip_type() should printf() whenever any unkown chip/SKU is found, although perhaps the function is called so early that the printf() wouldn't actually make it to the UART anyway. Signed-off-by: Stephen Warren Signed-off-by: Tom Warren Acked-by: Simon Glass --- arch/arm/cpu/tegra-common/ap.c | 1 + arch/arm/include/asm/arch-tegra/tegra.h | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c index 236cda8..3f30805 100644 --- a/arch/arm/cpu/tegra-common/ap.c +++ b/arch/arm/cpu/tegra-common/ap.c @@ -65,6 +65,7 @@ int tegra_get_chip_type(void) break; case CHIPID_TEGRA30: switch (tegra_sku_id) { + case SKU_ID_T33: case SKU_ID_T30: return TEGRA_SOC_T30; } diff --git a/arch/arm/include/asm/arch-tegra/tegra.h b/arch/arm/include/asm/arch-tegra/tegra.h index bf7229d..3e642e9 100644 --- a/arch/arm/include/asm/arch-tegra/tegra.h +++ b/arch/arm/include/asm/arch-tegra/tegra.h @@ -78,6 +78,7 @@ enum { SKU_ID_T25 = 0x18, SKU_ID_AP25E = 0x1b, SKU_ID_T25E = 0x1c, + SKU_ID_T33 = 0x80, SKU_ID_T30 = 0x81, /* Cardhu value */ SKU_ID_T114_ENG = 0x00, /* Dalmore value, unfused */ }; -- cgit v1.1 From 3ebbbfe4c78089db47599fc7b57ad016e247dd52 Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Thu, 28 Mar 2013 10:03:22 -0700 Subject: Tegra: Restore cp15 VBAR _start vector write for ARMv7 A start vector fix was added by AneeshV for OMAP4 (commit 0d479b53), and caused the old monilithic Tegra builds to hang due to an undefined instruction trap. Previously, the code needed to run on both the AVP (ARM7TDI) and A9, and the AVP doesn't have a CP15 register. I corrected this in commit 6d6c0bae w/#ifndef CONFIG_TEGRA, but now that we use SPL, and boot the AVP w/o any ARMv7 code, I can revert my change, and make Aneesh's change apply to Tegra. Signed-off-by: Tom Warren --- arch/arm/cpu/armv7/start.S | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 5feae7a..e9e57e6 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -253,11 +253,9 @@ ENTRY(c_runtime_cpu_setup) /* * Move vector table */ -#if !defined(CONFIG_TEGRA) /* Set vector address in CP15 VBAR register */ ldr r0, =_start mcr p15, 0, r0, c12, c0, 0 @Set VBAR -#endif /* !Tegra */ bx lr -- cgit v1.1 From d0edce4fa394325a0ccfd38a5d668fb5ee1af34d Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Mon, 25 Mar 2013 16:22:26 -0700 Subject: Tegra: Configure L2 cache control reg properly. Without this change, kernel fails at calling function cache_clean_flush during kernel early boot. Aprocryphally, intended for T114 only, so I check for a T114 SoC. Works (i.e. dalmore 3.8 kernel now starts printing to console). Signed-off-by: Tom Warren --- arch/arm/cpu/tegra-common/Makefile | 2 +- arch/arm/cpu/tegra-common/ap.c | 9 ++----- arch/arm/cpu/tegra-common/cache.c | 48 ++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra/ap.h | 1 + 4 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 arch/arm/cpu/tegra-common/cache.c (limited to 'arch') diff --git a/arch/arm/cpu/tegra-common/Makefile b/arch/arm/cpu/tegra-common/Makefile index 8e95c7e..4e0301c 100644 --- a/arch/arm/cpu/tegra-common/Makefile +++ b/arch/arm/cpu/tegra-common/Makefile @@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)libcputegra-common.o SOBJS += lowlevel_init.o -COBJS-y += ap.o board.o sys_info.o timer.o clock.o +COBJS-y += ap.o board.o sys_info.o timer.o clock.o cache.o SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c index 3f30805..a739fe2 100644 --- a/arch/arm/cpu/tegra-common/ap.c +++ b/arch/arm/cpu/tegra-common/ap.c @@ -139,11 +139,6 @@ void s_init(void) enable_scu(); - /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */ - asm volatile( - "mrc p15, 0, r0, c1, c0, 1\n" - "orr r0, r0, #0x41\n" - "mcr p15, 0, r0, c1, c0, 1\n"); - - /* FIXME: should have SoC's L2 disabled too? */ + /* init the cache */ + config_cache(); } diff --git a/arch/arm/cpu/tegra-common/cache.c b/arch/arm/cpu/tegra-common/cache.c new file mode 100644 index 0000000..48e9319 --- /dev/null +++ b/arch/arm/cpu/tegra-common/cache.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +/* Tegra cache routines */ + +#include +#include +#include +#include + +void config_cache(void) +{ + struct apb_misc_gp_ctlr *gp = + (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; + u32 reg = 0; + + /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */ + asm volatile( + "mrc p15, 0, r0, c1, c0, 1\n" + "orr r0, r0, #0x41\n" + "mcr p15, 0, r0, c1, c0, 1\n"); + + /* Currently, only T114 needs this L2 cache change to boot Linux */ + reg = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK); + if (reg != (CHIPID_TEGRA114 << HIDREV_CHIPID_SHIFT)) + return; + /* + * Systems with an architectural L2 cache must not use the PL310. + * Config L2CTLR here for a data RAM latency of 3 cycles. + */ + asm("mrc p15, 1, %0, c9, c0, 2" : : "r" (reg)); + reg &= ~7; + reg |= 2; + asm("mcr p15, 1, %0, c9, c0, 2" : : "r" (reg)); +} diff --git a/arch/arm/include/asm/arch-tegra/ap.h b/arch/arm/include/asm/arch-tegra/ap.h index 73dfd39..5999f55 100644 --- a/arch/arm/include/asm/arch-tegra/ap.h +++ b/arch/arm/include/asm/arch-tegra/ap.h @@ -64,3 +64,4 @@ extern void _start(void); * @return SOC type - see TEGRA_SOC... */ int tegra_get_chip_type(void); +void config_cache(void); -- cgit v1.1 From b40f734af9fdc47a0993f1f94f32d40a86f30587 Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Mon, 1 Apr 2013 15:48:54 -0700 Subject: Tegra114: Initialize System Counter (TSC) with osc frequency T114 needs the SYSCTR0 counter initialized so the TSC can be read by the kernel. Do it in the bootloader since it's a write-once deal (secure/non-secure mode dependent). Signed-off-by: Tom Warren Reviewed-by: Stephen Warren --- arch/arm/cpu/tegra-common/clock.c | 3 +++ arch/arm/cpu/tegra114-common/clock.c | 22 ++++++++++++++++++ arch/arm/cpu/tegra20-common/clock.c | 4 ++++ arch/arm/cpu/tegra30-common/clock.c | 4 ++++ arch/arm/include/asm/arch-tegra/clock.h | 3 +++ arch/arm/include/asm/arch-tegra114/sysctr.h | 35 +++++++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra114/tegra.h | 1 + 7 files changed, 72 insertions(+) create mode 100644 arch/arm/include/asm/arch-tegra114/sysctr.h (limited to 'arch') diff --git a/arch/arm/cpu/tegra-common/clock.c b/arch/arm/cpu/tegra-common/clock.c index 49a0633..9156d00 100644 --- a/arch/arm/cpu/tegra-common/clock.c +++ b/arch/arm/cpu/tegra-common/clock.c @@ -557,4 +557,7 @@ void clock_init(void) debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]); debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]); + + /* Do any special system timer/TSC setup */ + arch_timer_init(); } diff --git a/arch/arm/cpu/tegra114-common/clock.c b/arch/arm/cpu/tegra114-common/clock.c index 9b29ce1..5c4305a 100644 --- a/arch/arm/cpu/tegra114-common/clock.c +++ b/arch/arm/cpu/tegra114-common/clock.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -653,3 +654,24 @@ void clock_early_init(void) writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); udelay(2); } + +void arch_timer_init(void) +{ + struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE; + u32 freq, val; + + freq = clock_get_rate(CLOCK_ID_OSC); + debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq); + + /* ARM CNTFRQ */ + asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq)); + + /* Only T114 has the System Counter regs */ + debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq); + writel(freq, &sysctr->cntfid0); + + val = readl(&sysctr->cntcr); + val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG; + writel(val, &sysctr->cntcr); + debug("%s: TSC CNTCR = 0x%08X\n", __func__, val); +} diff --git a/arch/arm/cpu/tegra20-common/clock.c b/arch/arm/cpu/tegra20-common/clock.c index ec93894..4afb205 100644 --- a/arch/arm/cpu/tegra20-common/clock.c +++ b/arch/arm/cpu/tegra20-common/clock.c @@ -559,3 +559,7 @@ void clock_early_init(void) break; } } + +void arch_timer_init(void) +{ +} diff --git a/arch/arm/cpu/tegra30-common/clock.c b/arch/arm/cpu/tegra30-common/clock.c index a93f2c9..74bd22b 100644 --- a/arch/arm/cpu/tegra30-common/clock.c +++ b/arch/arm/cpu/tegra30-common/clock.c @@ -616,3 +616,7 @@ void clock_early_init(void) break; } } + +void arch_timer_init(void) +{ +} diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h index c8677bd..c7a696c 100644 --- a/arch/arm/include/asm/arch-tegra/clock.h +++ b/arch/arm/include/asm/arch-tegra/clock.h @@ -317,4 +317,7 @@ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon); #define periphc_internal_id_isvalid(id) ((id) >= 0 && \ (id) < PERIPHC_COUNT) +/* SoC-specific TSC init */ +void arch_timer_init(void); + #endif /* _TEGRA_CLOCK_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/sysctr.h b/arch/arm/include/asm/arch-tegra114/sysctr.h new file mode 100644 index 0000000..c05e2c3 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra114/sysctr.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#ifndef _TEGRA114_SYSCTR_H_ +#define _TEGRA114_SYSCTR_H_ + +struct sysctr_ctlr { + u32 cntcr; /* 0x00: SYSCTR0_CNTCR Counter Control */ + u32 cntsr; /* 0x04: SYSCTR0_CNTSR Counter Status */ + u32 cntcv0; /* 0x08: SYSCTR0_CNTCV0 Counter Count 31:00 */ + u32 cntcv1; /* 0x0C: SYSCTR0_CNTCV1 Counter Count 63:32 */ + u32 reserved1[4]; /* 0x10 - 0x1C */ + u32 cntfid0; /* 0x20: SYSCTR0_CNTFID0 Freq Table Entry */ + u32 cntfid1; /* 0x24: SYSCTR0_CNTFID1 Freq Table End */ + u32 reserved2[1002]; /* 0x28 - 0xFCC */ + u32 counterid[12]; /* 0xFD0 - 0xFxx CounterID regs, RO */ +}; + +#define TSC_CNTCR_ENABLE (1 << 0) /* Enable */ +#define TSC_CNTCR_HDBG (1 << 1) /* Halt on debug */ + +#endif /* _TEGRA114_SYSCTR_H_ */ diff --git a/arch/arm/include/asm/arch-tegra114/tegra.h b/arch/arm/include/asm/arch-tegra114/tegra.h index a3d12d6..5d426b5 100644 --- a/arch/arm/include/asm/arch-tegra114/tegra.h +++ b/arch/arm/include/asm/arch-tegra114/tegra.h @@ -18,6 +18,7 @@ #define _TEGRA114_H_ #define NV_PA_SDRAM_BASE 0x80000000 /* 0x80000000 for real T114 */ +#define NV_PA_TSC_BASE 0x700F0000 /* System Counter TSC regs */ #include -- cgit v1.1 From d94c2dbd0a55d742ab6ed9bd0c51b27ceed4084e Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Wed, 3 Apr 2013 14:39:30 -0700 Subject: Tegra: Fix MSELECT clock divisors for T30/T114. A comparison of registers between our internal NV U-Boot and u-boot-tegra/next showed some discrepancies in the MSELECT clock divisor programming. T20 doesn't have a MSELECT clk src reg. Signed-off-by: Tom Warren Reviewed-by: Stephen Warren --- arch/arm/cpu/arm720t/tegra114/cpu.c | 10 ++++------ arch/arm/cpu/arm720t/tegra30/cpu.c | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/arm720t/tegra114/cpu.c b/arch/arm/cpu/arm720t/tegra114/cpu.c index 6a94179..51ecff7 100644 --- a/arch/arm/cpu/arm720t/tegra114/cpu.c +++ b/arch/arm/cpu/arm720t/tegra114/cpu.c @@ -170,15 +170,13 @@ void t114_init_clocks(void) clock_set_enable(PERIPH_ID_MC1, 1); clock_set_enable(PERIPH_ID_DVFS, 1); - /* Switch MSELECT clock to PLLP (00) */ - clock_ll_set_source(PERIPH_ID_MSELECT, 0); - /* - * Clock divider request for 102MHz would setup MSELECT clock as - * 102MHz for PLLP base 408MHz + * Set MSELECT clock source as PLLP (00), and ask for a clock + * divider that would set the MSELECT clock at 102MHz for a + * PLLP base of 408MHz. */ clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, - (NVBL_PLLP_KHZ/102000)); + CLK_DIVIDER(NVBL_PLLP_KHZ, 102000)); /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c index dedcdd9..e162357 100644 --- a/arch/arm/cpu/arm720t/tegra30/cpu.c +++ b/arch/arm/cpu/arm720t/tegra30/cpu.c @@ -110,8 +110,8 @@ void t30_init_clocks(void) reset_set_enable(PERIPH_ID_MSELECT, 1); clock_set_enable(PERIPH_ID_MSELECT, 1); - /* Switch MSELECT clock to PLLP (00) */ - clock_ll_set_source(PERIPH_ID_MSELECT, 0); + /* Switch MSELECT clock to PLLP (00) and use a divisor of 2 */ + clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, 2); /* * Our high-level clock routines are not available prior to -- cgit v1.1 From 49493cb7144f0c51a5aaecc75fcd1b3f157633ba Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Wed, 10 Apr 2013 10:32:32 -0700 Subject: Tegra: Split tegra_get_chip_type() into soc & sku funcs As suggested by Stephen Warren, use tegra_get_chip() to return the pure CHIPID for a Tegra SoC (i.e. 0x20 for Tegra20, 0x30 for Tegra30, etc.) and rename tegra_get_chip_type() to reflect its true function, i.e. tegra_get_chip_sku(), which returns an ID like TEGRA_SOC_T25, TEGRA_SOC_T33, etc. Signed-off-by: Tom Warren Reviewed-by: Stephen Warren --- arch/arm/cpu/arm720t/tegra-common/cpu.c | 48 +++++++++++++++++++-------------- arch/arm/cpu/arm720t/tegra-common/cpu.h | 4 ++- arch/arm/cpu/tegra-common/ap.c | 43 +++++++++++++++++++++-------- arch/arm/cpu/tegra20-common/pmu.c | 4 +-- arch/arm/include/asm/arch-tegra/ap.h | 20 ++++++++++++-- 5 files changed, 83 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.c b/arch/arm/cpu/arm720t/tegra-common/cpu.c index 119342e..9294611 100644 --- a/arch/arm/cpu/arm720t/tegra-common/cpu.c +++ b/arch/arm/cpu/arm720t/tegra-common/cpu.c @@ -143,26 +143,34 @@ void init_pllx(void) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX]; - int chip_type; + int soc_type, sku_info, chip_sku; enum clock_osc_freq osc; struct clk_pll_table *sel; debug("init_pllx entry\n"); - /* get chip type */ - chip_type = tegra_get_chip_type(); - debug(" init_pllx: chip_type = %d\n", chip_type); + /* get SOC (chip) type */ + soc_type = tegra_get_chip(); + debug(" init_pllx: SoC = 0x%02X\n", soc_type); + + /* get SKU info */ + sku_info = tegra_get_sku_info(); + debug(" init_pllx: SKU info byte = 0x%02X\n", sku_info); + + /* get chip SKU, combo of the above info */ + chip_sku = tegra_get_chip_sku(); + debug(" init_pllx: Chip SKU = %d\n", chip_sku); /* get osc freq */ osc = clock_get_osc_freq(); - debug(" init_pllx: osc = %d\n", osc); + debug(" init_pllx: osc = %d\n", osc); /* set pllx */ - sel = &tegra_pll_x_table[chip_type][osc]; + sel = &tegra_pll_x_table[chip_sku][osc]; pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon); - /* adjust PLLP_out1-4 on T30/T114 */ - if (chip_type == TEGRA_SOC_T30 || chip_type == TEGRA_SOC_T114) { + /* adjust PLLP_out1-4 on T3x/T114 */ + if (soc_type >= CHIPID_TEGRA30) { debug(" init_pllx: adjusting PLLP out freqs\n"); adjust_pllp_out_freqs(); } @@ -287,7 +295,7 @@ void reset_A9_cpu(int reset) void clock_enable_coresight(int enable) { u32 rst, src = 2; - int chip; + int soc_type; debug("clock_enable_coresight entry\n"); clock_set_enable(PERIPH_ID_CORESIGHT, enable); @@ -295,21 +303,21 @@ void clock_enable_coresight(int enable) if (enable) { /* - * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by - * 1.5, giving an effective frequency of 144MHz. - * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor - * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) - * - * Clock divider request for 204MHz would setup CSITE clock as - * 144MHz for PLLP base 216MHz and 204MHz for PLLP base 408MHz + * Put CoreSight on PLLP_OUT0 and divide it down as per + * PLLP base frequency based on SoC type (T20/T30/T114). + * Clock divider request would setup CSITE clock as 144MHz + * for PLLP base 216MHz and 204MHz for PLLP base 408MHz */ - chip = tegra_get_chip_type(); - if (chip == TEGRA_SOC_T30 || chip == TEGRA_SOC_T114) + + soc_type = tegra_get_chip(); + if (soc_type == CHIPID_TEGRA30 || soc_type == CHIPID_TEGRA114) src = CLK_DIVIDER(NVBL_PLLP_KHZ, 204000); - else if (chip == TEGRA_SOC_T20 || chip == TEGRA_SOC_T25) + else if (soc_type == CHIPID_TEGRA20) src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); else - printf("%s: Unknown chip type %X!\n", __func__, chip); + printf("%s: Unknown SoC type %X!\n", + __func__, soc_type); + clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); /* Unlock the CPU CoreSight interfaces */ diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.h b/arch/arm/cpu/arm720t/tegra-common/cpu.h index e8e05d7..f9bfb32 100644 --- a/arch/arm/cpu/arm720t/tegra-common/cpu.h +++ b/arch/arm/cpu/arm720t/tegra-common/cpu.h @@ -80,5 +80,7 @@ void init_pllx(void); void powerup_cpu(void); void reset_A9_cpu(int reset); void start_cpu(u32 reset_vector); -int tegra_get_chip_type(void); +int tegra_get_chip(void); +int tegra_get_sku_info(void); +int tegra_get_chip_sku(void); void adjust_pllp_out_freqs(void); diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c index a739fe2..9b77b2b 100644 --- a/arch/arm/cpu/tegra-common/ap.c +++ b/arch/arm/cpu/tegra-common/ap.c @@ -34,25 +34,44 @@ #include #include -int tegra_get_chip_type(void) +int tegra_get_chip(void) { - struct apb_misc_gp_ctlr *gp; - struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; - uint tegra_sku_id, rev; + int rev; + struct apb_misc_gp_ctlr *gp = + (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; /* * This is undocumented, Chip ID is bits 15:8 of the register * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for * Tegra30, and 0x35 for T114. */ - gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; + debug("%s: CHIPID is 0x%02X\n", __func__, rev); + + return rev; +} + +int tegra_get_sku_info(void) +{ + int sku_id; + struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; + + sku_id = readl(&fuse->sku_info) & 0xff; + debug("%s: SKU info byte is 0x%02X\n", __func__, sku_id); + + return sku_id; +} + +int tegra_get_chip_sku(void) +{ + uint sku_id, chip_id; - tegra_sku_id = readl(&fuse->sku_info) & 0xff; + chip_id = tegra_get_chip(); + sku_id = tegra_get_sku_info(); - switch (rev) { + switch (chip_id) { case CHIPID_TEGRA20: - switch (tegra_sku_id) { + switch (sku_id) { case SKU_ID_T20: return TEGRA_SOC_T20; case SKU_ID_T25SE: @@ -64,20 +83,22 @@ int tegra_get_chip_type(void) } break; case CHIPID_TEGRA30: - switch (tegra_sku_id) { + switch (sku_id) { case SKU_ID_T33: case SKU_ID_T30: return TEGRA_SOC_T30; } break; case CHIPID_TEGRA114: - switch (tegra_sku_id) { + switch (sku_id) { case SKU_ID_T114_ENG: return TEGRA_SOC_T114; } break; } - /* unknown sku id */ + /* unknown chip/sku id */ + printf("%s: ERROR: UNKNOWN CHIP/SKU ID COMBO (0x%02X/0x%02X)\n", + __func__, chip_id, sku_id); return TEGRA_SOC_UNKNOWN; } diff --git a/arch/arm/cpu/tegra20-common/pmu.c b/arch/arm/cpu/tegra20-common/pmu.c index 2282953..4c5a533 100644 --- a/arch/arm/cpu/tegra20-common/pmu.c +++ b/arch/arm/cpu/tegra20-common/pmu.c @@ -44,7 +44,7 @@ int pmu_set_nominal(void) int core, cpu, bus; /* by default, the table has been filled with T25 settings */ - switch (tegra_get_chip_type()) { + switch (tegra_get_chip_sku()) { case TEGRA_SOC_T20: core = VDD_CORE_NOMINAL_T20; cpu = VDD_CPU_NOMINAL_T20; @@ -54,7 +54,7 @@ int pmu_set_nominal(void) cpu = VDD_CPU_NOMINAL_T25; break; default: - debug("%s: Unknown chip type\n", __func__); + debug("%s: Unknown SKU id\n", __func__); return -1; } diff --git a/arch/arm/include/asm/arch-tegra/ap.h b/arch/arm/include/asm/arch-tegra/ap.h index 5999f55..f6d08c6 100644 --- a/arch/arm/include/asm/arch-tegra/ap.h +++ b/arch/arm/include/asm/arch-tegra/ap.h @@ -59,9 +59,25 @@ extern void _start(void); /** - * Works out the SOC type used for clocks settings + * Works out the SOC/SKU type used for clocks settings * * @return SOC type - see TEGRA_SOC... */ -int tegra_get_chip_type(void); +int tegra_get_chip_sku(void); + +/** + * Returns the pure SOC (chip ID) from the HIDREV register + * + * @return SOC ID - see CHIPID_TEGRAxx... + */ +int tegra_get_chip(void); + +/** + * Returns the SKU ID from the sku_info register + * + * @return SKU ID - see SKU_ID_Txx... + */ +int tegra_get_sku_info(void); + +/* Do any chip-specific cache config */ void config_cache(void); -- cgit v1.1 From dc47e2bc7d1c5307b18b9a43f3286969e36a974e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 13 Apr 2013 04:26:41 +0000 Subject: exynos: Correct use of 64-bit division The current code is causing errors like this on my toolchains: /usr/x86_64-pc-linux-gnu/armv7a-cros-linux-gnueabi/binutils-bin/2.22/ ld.bfd.real: failed to merge target specific data of file /usr/lib/gcc/ armv7a-cros-linux-gnueabi/4.7.x-google/libgcc.a(_divdi3.o) Use do_div() to avoid this. Signed-off-by: Simon Glass Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/s5p-common/timer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c index 6a0fa58..4adfaae 100644 --- a/arch/arm/cpu/armv7/s5p-common/timer.c +++ b/arch/arm/cpu/armv7/s5p-common/timer.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -76,6 +77,8 @@ int timer_init(void) */ unsigned long get_timer(unsigned long base) { + unsigned long long time_ms; + ulong now = timer_get_us_down(); /* @@ -87,7 +90,9 @@ unsigned long get_timer(unsigned long base) gd->arch.lastinc = now; /* Divide by 1000 to convert from us to ms */ - return gd->arch.timer_reset_value / 1000 - base; + time_ms = gd->arch.timer_reset_value; + do_div(time_ms, 1000); + return time_ms - base; } unsigned long timer_get_us(void) -- cgit v1.1