tegra: warmboot (suspend / resume) support
Subsystems (3)
cover tegra: warmboot (suspend / resume) support
This series adds support for warm boot, allowing the device to suspend and resume. U-Boot sets up some 'warm boot' code in a special area such that the SOC can find it on a resume. This code is responsible for setting up memory and clocked and then allowing the OS to continue where it left off.
Jimmy Zhang (4):
tegra: Add EMC support for optimal memory timings
tegra: Add PMU to manage power supplies
tegra: Set vdd_core and vdd_cpu to high
tegra: Add EMC settings for Seaboard, Harmony
Simon Glass (5):
tegra: Move ap20.h header into arch location
tegra: Add tegra_get_chip_type() to detect SKU
tegra: Set up PMU for Nvidia boards
tegra: Set up warmboot code on Nvidia boards
tegra: Enable LP0 on Seaboard
Yen Lin (5):
Add AES crypto library
tegra: Add crypto library for warmboot code
tegra: Add flow, gp_padctl, fuse, sdram headers
tegra: Add warmboot implementation
tegra: Setup PMC scratch info from ap20 setup
arch/arm/cpu/armv7/tegra2/Makefile | 8 +-
arch/arm/cpu/armv7/tegra2/ap20.c | 32 +-
arch/arm/cpu/armv7/tegra2/board.c | 4 +-
arch/arm/cpu/armv7/tegra2/crypto.c | 234 ++++++++
arch/arm/cpu/armv7/tegra2/crypto.h | 36 ++
arch/arm/cpu/armv7/tegra2/emc.c | 165 ++++++
arch/arm/cpu/armv7/tegra2/pmu.c | 355 ++++++++++++
arch/arm/cpu/armv7/tegra2/warmboot.c | 444 +++++++++++++++
arch/arm/cpu/armv7/tegra2/warmboot_avp.c | 312 ++++++++++
arch/arm/cpu/armv7/tegra2/warmboot_avp.h | 81 +++
.../tegra2 => include/asm/arch-tegra2}/ap20.h | 7 +
arch/arm/include/asm/arch-tegra2/emc.h | 107 ++++
arch/arm/include/asm/arch-tegra2/flow.h | 36 ++
arch/arm/include/asm/arch-tegra2/fuse.h | 39 ++
arch/arm/include/asm/arch-tegra2/gp_padctrl.h | 64 +++
arch/arm/include/asm/arch-tegra2/pmu.h | 63 ++
arch/arm/include/asm/arch-tegra2/sdram_param.h | 148 +++++
arch/arm/include/asm/arch-tegra2/tegra2.h | 26 +
arch/arm/include/asm/arch-tegra2/warmboot.h | 81 +++
board/nvidia/common/Makefile | 1 +
board/nvidia/common/board.c | 37 ++
board/nvidia/common/emc.c | 295 ++++++++++
board/nvidia/common/emc.h | 29 +
include/aes.h | 70 +++
include/configs/seaboard.h | 7 +
include/configs/tegra2-common.h | 17 +
lib/Makefile | 1 +
lib/aes.c | 599 ++++++++++++++++++++
28 files changed, 3294 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.c
create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.h
create mode 100644 arch/arm/cpu/armv7/tegra2/emc.c
create mode 100644 arch/arm/cpu/armv7/tegra2/pmu.c
create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot.c
create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot_avp.c
create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot_avp.h
rename arch/arm/{cpu/armv7/tegra2 => include/asm/arch-tegra2}/ap20.h (96%)
create mode 100644 arch/arm/include/asm/arch-tegra2/emc.h
create mode 100644 arch/arm/include/asm/arch-tegra2/flow.h
create mode 100644 arch/arm/include/asm/arch-tegra2/fuse.h
create mode 100644 arch/arm/include/asm/arch-tegra2/gp_padctrl.h
create mode 100644 arch/arm/include/asm/arch-tegra2/pmu.h
create mode 100644 arch/arm/include/asm/arch-tegra2/sdram_param.h
create mode 100644 arch/arm/include/asm/arch-tegra2/warmboot.h
create mode 100644 board/nvidia/common/emc.c
create mode 100644 board/nvidia/common/emc.h
create mode 100644 include/aes.h
create mode 100644 lib/aes.cSignature · 1 line
1.7.3.1
PATCH 1/14 Add AES crypto library
From: Yen Lin <[email protected]>
Add support for AES using an implementation form Karl Malbrain. This offers small code size (around 5KB on ARM) and supports 128-bit AES only.
--- include/aes.h | 70 +++++++ lib/Makefile | 1 + lib/aes.c | 599 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 670 insertions(+), 0 deletions(-) create mode 100644 include/aes.h create mode 100644 lib/aes.c
include/aes.h new file +70 -0
@@ -0,0 +1,70 @@ +/* +* Copyright (c) 2011 The Chromium OS Authors. +* (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* 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; either version 2 of +* the License, or (at your option) any later version. +* +* 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., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#ifndef _AES_REF_H_ +#define _AES_REF_H_ + +/* +* AES encryption library, with small code size, supporting only 128-bit AES +* +* AES is a stream cipher which works a block at a time, with each block +* in this case being AES_KEY_LENGTH bytes. +*/ + +enum { +AES_STATECOLS =4 ,/* columns in the state & expanded key */ +AES_KEYCOLS =4 ,/* columns in a key */ +AES_ROUNDS =10 ,/* rounds in encryption */ + +AES_KEY_LENGTH =128 /8 , +AES_EXPAND_KEY_LENGTH =4 *AES_STATECOLS * (AES_ROUNDS +1 ), +}; + +/** +* Expand a key into a key schedule, which is then used for the other +* operations. +* +* \param key Key, of length AES_KEY_LENGTH bytes +* \param expkey Buffer to place expanded key, AES_EXPAND_KEY_LENGTH +*/ +void aes_expand_key (u8 *key,u8 *expkey); + +/** +* Encrypt a single block of data +* +* in Input data +* expkey Expanded key to use for encryption (from aes_expand_key()) +* out Output data +*/ +void aes_encrypt (u8 *in,u8 *expkey,u8 *out); + +/** +* Decrypt a single block of data +* +* in Input data +* expkey Expanded key to use for decryption (from aes_expand_key()) +* out Output data +*/ +void aes_decrypt (u8 *in,u8 *expkey,u8 *out); + +#endif /* _AES_REF_H_ */
lib/Makefile +1 -0
@@ -27,6 +27,7 @@ LIB = $(obj)libgeneric.o ifndef CONFIG_SPL_BUILD COBJS-$(CONFIG_ADDR_MAP) += addr_map.o +COBJS-$(CONFIG_AES) += aes.o COBJS-$(CONFIG_BZIP2) += bzlib.o COBJS-$(CONFIG_BZIP2) += bzlib_crctable.o COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
lib/aes.c new file +599 -0
599 lines not on this page · raw message
Signature · 1 line
1.7.3.1
PATCH 1/14 Add AES crypto library
lib/aes.c line 299
Quoted 11 lines · On Monday 26 December 2011 14:32:54 Simon Glass wrote:
lib/aes.c new file +8
-0+static u8 sbox[256] = { +static u8 inv_sbox[256] = { +static u8 x2_sbox[256] = { +static u8 x3_sbox[256] = { +static u8 x_time_9[256] = { +static u8 x_time_b[256] = { +static u8 x_time_d[256] = { +static u8 x_time_e[256] = {
const
lib/aes.c line 439
Quoted 4 lines
lib/aes.c new file +3
-0+static void mix_sub_columns (u8 *state) +{ + x3_sbox[state[2 ]] ^ sbox[state[7 ]];
looks bad whitespace after that ^
Quoted 1 line
+static u8 rcon[11] = {
const
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120108/ea6a1bbb/attachment.pgp>
PATCH 1/14 Add AES crypto library
Quoted 22 lines · On Monday 26 December 2011 14:32:54 Simon Glass wrote:
lib/aes.c line 299
Quoted 11 lines
lib/aes.c new file +8
-0+static u8 sbox[256] = { +static u8 inv_sbox[256] = { +static u8 x2_sbox[256] = { +static u8 x3_sbox[256] = { +static u8 x_time_9[256] = { +static u8 x_time_b[256] = { +static u8 x_time_d[256] = { +static u8 x_time_e[256] = {const
lib/aes.c line 439
Quoted 4 lines
lib/aes.c new file +3
-0+static void mix_sub_columns (u8 *state) +{ + x3_sbox[state[2 ]] ^ sbox[state[7 ]];looks bad whitespace after that ^
Quoted 4 lines
Quoted 1 line
+static u8 rcon[11] = {
const
-mike
We already have checkpatch in tools ... run it on the series.
M
PATCH 1/14 Add AES crypto library
Quoted 22 lines · On Sunday 08 January 2012 03:57:47 Marek Vasut wrote:
Quoted 22 lines · On Monday 26 December 2011 14:32:54 Simon Glass wrote:
lib/aes.c line 299
Quoted 11 lines
lib/aes.c new file +8
-0+static u8 sbox[256] = { +static u8 inv_sbox[256] = { +static u8 x2_sbox[256] = { +static u8 x3_sbox[256] = { +static u8 x_time_9[256] = { +static u8 x_time_b[256] = { +static u8 x_time_d[256] = { +static u8 x_time_e[256] = {const
lib/aes.c line 439
Quoted 4 lines
lib/aes.c new file +3
-0+static void mix_sub_columns (u8 *state) +{ + x3_sbox[state[2 ]] ^ sbox[state[7 ]];looks bad whitespace after that ^
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
+static u8 rcon[11] = {
const
We already have checkpatch in tools ... run it on the series.
i don't think checkpatch catches const
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120108/3250cc48/attachment.pgp>
PATCH 1/14 Add AES crypto library
Quoted 23 lines · On Sunday 08 January 2012 03:57:47 Marek Vasut wrote:
Quoted 22 lines
Quoted 22 lines · On Monday 26 December 2011 14:32:54 Simon Glass wrote:
lib/aes.c line 299
Quoted 11 lines
lib/aes.c new file +8
-0+static u8 sbox[256] = { +static u8 inv_sbox[256] = { +static u8 x2_sbox[256] = { +static u8 x3_sbox[256] = { +static u8 x_time_9[256] = { +static u8 x_time_b[256] = { +static u8 x_time_d[256] = { +static u8 x_time_e[256] = {const
lib/aes.c line 439
Quoted 4 lines
lib/aes.c new file +3
-0+static void mix_sub_columns (u8 *state) +{ + x3_sbox[state[2 ]] ^ sbox[state[7 ]];looks bad whitespace after that ^
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
+static u8 rcon[11] = {
const
We already have checkpatch in tools ... run it on the series.
i don't think checkpatch catches const
-mike
No, but it catches whitespaces ... M
PATCH 1/14 Add AES crypto library
Hi Marek,
Quoted 23 lines · Marek Vasut
Quoted 23 lines · On Sunday 08 January 2012 03:57:47 Marek Vasut wrote:
Quoted 22 lines
Quoted 22 lines · On Monday 26 December 2011 14:32:54 Simon Glass wrote:
lib/aes.c line 299
Quoted 11 lines
lib/aes.c new file +8
-0+static u8 sbox[256] = { +static u8 inv_sbox[256] = { +static u8 x2_sbox[256] = { +static u8 x3_sbox[256] = { +static u8 x_time_9[256] = { +static u8 x_time_b[256] = { +static u8 x_time_d[256] = { +static u8 x_time_e[256] = {const
lib/aes.c
Quoted 4 lines
lib/aes.c new file +3
-0+static void mix_sub_columns (u8 *state) +{ + ? ? ? ? ? ? ? ?x3_sbox[state[2]] ^ ? ? ? sbox[state[7]];looks bad whitespace after that ^
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
+static u8 rcon[11] = {
const
We already have checkpatch in tools ... run it on the series.
This happened as part of my using patman to submit this series. I just checked it again and there are no warnings.
Quoted 2 lines
Quoted 2 lines
i don't think checkpatch catches const
Nope.
Quoted 3 lines
Quoted 1 line
-mike
No, but it catches whitespaces ... M
Not in this case, unfortunately. Sometimes we still need beady eyes :-)
I will fix these two.
Regards,
Simon
Quoted 4 lines
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH 2/14 tegra: Move ap20.h header into arch location
In reply to Simon GlassWe want to include this from board code, so move the header into an easily-accessible location.
---
arch/arm/cpu/armv7/tegra2/ap20.c | 2 +-
arch/arm/cpu/armv7/tegra2/board.c | 4 ++--
.../tegra2 => include/asm/arch-tegra2}/ap20.h | 0
3 files changed, 3 insertions(+), 3 deletions(-)
rename arch/arm/{cpu/armv7/tegra2 => include/asm/arch-tegra2}/ap20.h (100%)arch/arm/cpu/armv7/tegra2/ap20.c +1 -1
@@ -21,9 +21,9 @@* MA 02111-1307 USA */ -#include "ap20.h" #include <asm/io.h> #include <asm/arch/tegra2.h> +#include <asm/arch/ap20.h> #include <asm/arch/clk_rst.h> #include <asm/arch/clock.h> #include <asm/arch/pmc.h>
arch/arm/cpu/armv7/tegra2/board.c +2 -2
@@ -23,12 +23,12 @@#include <common.h> #include <asm/io.h> -#include "ap20.h" +#include <asm/arch/ap20.h> #include <asm/arch/clock.h> #include <asm/arch/funcmux.h> +#include <asm/arch/pmc.h> #include <asm/arch/sys_proto.h> #include <asm/arch/tegra2.h> -#include <asm/arch/pmc.h> DECLARE_GLOBAL_DATA_PTR ;
arch/arm/include/asm/arch-tegra2/ap20.h renamed from arch/arm/cpu/armv7/tegra2/ap20.h +0 -0
Signature · 1 line
1.7.3.1
PATCH 3/14 tegra: Add crypto library for warmboot code
In reply to Simon GlassFrom: Yen Lin <[email protected]>
Provides an interface to aes.c for the warmboot code.
--- arch/arm/cpu/armv7/tegra2/crypto.c | 234 ++++++++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/tegra2/crypto.h | 36 ++++++ 2 files changed, 270 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.c create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.h
arch/arm/cpu/armv7/tegra2/crypto.c new file +234 -0
@@ -0,0 +1,234 @@ +/* +* Copyright (c) 2011 The Chromium OS Authors. +* (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* 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; either version 2 of +* the License, or (at your option) any later version. +* +* 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., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#include <common.h> +#include <asm/errno.h> +#include "crypto.h" +#include "aes.h" + +static u8 zero_key[16 ]; + +#define AES_CMAC_CONST_RB 0x87/* from RFC 4493, Figure 2.2 */ + +enum security_op { +SECURITY_SIGN =1 <<0 ,/* Sign the data */ +SECURITY_ENCRYPT =1 <<1 ,/* Encrypt the data */ +}; + +#ifdef DEBUG +static void debug_print_vector (char *name,u32 num_bytes,u8 *data) +{ +u32 i; + +printf ("%s [%d] @0x%08x" , name, num_bytes, (u32 )data); +for (i =0 ; i < num_bytes; i++) { +if (i %16 ==0 ) +printf (" = " ); +printf ("%02x" , data[i]); +if ((i+1 ) %16 !=0 ) +printf (" " ); + } +printf ("\n" ); +} +#else +#define debug_print_vector (name, num_bytes, data) +#endif + +/** +* Apply chain data to the destination using EOR +* +* Each array is of length AES_AES_KEY_LENGTH. +* +* \param cbc_chain_data Chain data +* \param src Source data +* \param dst Destination data, which is modified here +*/ +static void apply_cbc_chain_data (u8 *cbc_chain_data,u8 *src,u8 *dst) +{ +int i; + +for (i =0 ; i <16 ; i++) + *dst++ = *src++ ^ *cbc_chain_data++; +} + +/** +* Encrypt some data with AES. +* +* \param key_schedule Expanded key to use +* \param src Source data to encrypt +* \param dst Destination buffer +* \param num_aes_blocks Number of AES blocks to encrypt +*/ +static void encrypt_object (u8 *key_schedule,u8 *src,u8 *dst, +u32 num_aes_blocks) +{ +u8 tmp_data[AES_KEY_LENGTH ]; +u8 *cbc_chain_data; +u32 i; + + cbc_chain_data = zero_key;/* Convenient array of 0's for IV */ + +for (i =0 ; i < num_aes_blocks; i++) { +debug ("encrypt_object: block %d of %d\n" , i, num_aes_blocks); +debug_print_vector ("AES Src" ,AES_KEY_LENGTH , src); + +/* Apply the chain data */ +apply_cbc_chain_data (cbc_chain_data, src, tmp_data); +debug_print_vector ("AES Xor" ,AES_KEY_LENGTH , tmp_data); + +/* encrypt the AES block */ +aes_encrypt (tmp_data, key_schedule, dst); +debug_print_vector ("AES Dst" ,AES_KEY_LENGTH , dst); + +/* Update pointers for next loop. */ + cbc_chain_data = dst; + src +=AES_KEY_LENGTH ; + dst +=AES_KEY_LENGTH ; + } +} + +/** +* Shift a vector left by one bit +* +* \param in Input vector +* \param out Output vector +* \param size Length of vector in bytes +*/ +static void left_shift_vector (u8 *in,u8 *out,int size) +{ +int carry =0 ; +int i; + +for (i = size -1 ; i >=0 ; i--) { + out[i] = (in[i] <<1 ) | carry; + carry = in[i] >>7 ;/* get most significant bit */ + } +} + +/** +* Sign a block of data, putting the result into dst. +* +* \param key Input AES key, length AES_KEY_LENGTH +* \param key_schedule Expanded key to use +* \param src Source data of length 'num_aes_blocks' blocks +* \param dst Destination buffer, length AES_KEY_LENGTH +* \param num_aes_blocks Number of AES blocks to encrypt +*/ +static void sign_object (u8 *key,u8 *key_schedule,u8 *src,u8 *dst, +u32 num_aes_blocks) +{ +u8 tmp_data[AES_KEY_LENGTH ]; +u8 left[AES_KEY_LENGTH ]; +u8 k1[AES_KEY_LENGTH ]; +u8 *cbc_chain_data; +unsigned i; + + cbc_chain_data = zero_key;/* Convenient array of 0's for IV */ + +/* compute K1 constant needed by AES-CMAC calculation */ +for (i =0 ; i <AES_KEY_LENGTH ; i++) + tmp_data[i] =0 ; + +encrypt_object (key_schedule, tmp_data, left,1 ); +debug_print_vector ("AES(key, nonce)" ,AES_KEY_LENGTH , left); + +left_shift_vector (left, k1,sizeof (left)); +debug_print_vector ("L" ,AES_KEY_LENGTH , left); + +if ((left[0 ] >>7 ) !=0 )/* get MSB of L */ + k1[AES_KEY_LENGTH -1 ] ^=AES_CMAC_CONST_RB ; +debug_print_vector ("K1" ,AES_KEY_LENGTH , k1); + +/* compute the AES-CMAC value */ +for (i =0 ; i < num_aes_blocks; i++) { +/* Apply the chain data */ +apply_cbc_chain_data (cbc_chain_data, src, tmp_data); + +/* for the final block, XOR K1 into the IV */ +if (i == num_aes_blocks -1 ) +apply_cbc_chain_data (tmp_data, k1, tmp_data); + +/* encrypt the AES block */ +aes_encrypt (tmp_data, key_schedule, dst); + +debug ("sign_obj: block %d of %d\n" , i, num_aes_blocks); +debug_print_vector ("AES-CMAC Src" ,AES_KEY_LENGTH , src); +debug_print_vector ("AES-CMAC Xor" ,AES_KEY_LENGTH , tmp_data); +debug_print_vector ("AES-CMAC Dst" ,AES_KEY_LENGTH , dst); + +/* Update pointers for next loop. */ + cbc_chain_data = dst; + src +=AES_KEY_LENGTH ; + } + +debug_print_vector ("AES-CMAC Hash" ,AES_KEY_LENGTH , dst); +} + +/** +* Encrypt and sign a block of data (depending on security mode). +* +* \param key Input AES key, length AES_KEY_LENGTH +* \param oper Security operations mask to perform (enum security_op) +* \param src Source data +* \param length Size of source data +* \param sig_dst Destination address for signature, AES_KEY_LENGTH bytes +*/ +static int encrypt_and_sign (u8 *key,enum security_op oper,u8 *src, +u32 length,u8 *sig_dst) +{ +u32 num_aes_blocks; +u8 key_schedule[AES_EXPAND_KEY_LENGTH ]; + +debug ("encrypt_and_sign: length = %d\n" , length); +debug_print_vector ("AES key" ,AES_KEY_LENGTH , key); + +/* +* The only need for a key is for signing/checksum purposes, so +* if not encrypting, expand a key of 0s. +*/ +aes_expand_key (oper &SECURITY_ENCRYPT ? key : zero_key, key_schedule); + + num_aes_blocks = (length +AES_KEY_LENGTH -1 ) /AES_KEY_LENGTH ; + +if (oper &SECURITY_ENCRYPT ) { +/* Perform this in place, resulting in src being encrypted. */ +debug ("encrypt_and_sign: begin encryption\n" ); +encrypt_object (key_schedule, src, src, num_aes_blocks); +debug ("encrypt_and_sign: end encryption\n" ); + } + +if (oper &SECURITY_SIGN ) { +/* encrypt the data, overwriting the result in signature. */ +debug ("encrypt_and_sign: begin signing\n" ); +sign_object (key, key_schedule, src, sig_dst, num_aes_blocks); +debug ("encrypt_and_sign: end signing\n" ); + } + +return 0 ; +} + +int sign_data_block (u8 *source,unsigned length,u8 *signature) +{ +return encrypt_and_sign (zero_key,SECURITY_SIGN , source, + length, signature); +}
arch/arm/cpu/armv7/tegra2/crypto.h new file +36 -0
@@ -0,0 +1,36 @@ +/* +* Copyright (c) 2011 The Chromium OS Authors. +* (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* 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; either version 2 of +* the License, or (at your option) any later version. +* +* 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., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + +/** +* Sign a block of data +* +* \param source Source data +* \param length Size of source data +* \param signature Destination address for signature, AES_KEY_LENGTH bytes +*/ +int sign_data_block (u8 *source,unsigned length,u8 *signature); + +#endif /* #ifndef _CRYPTO_H_ */
Signature · 1 line
1.7.3.1
PATCH 3/14 tegra: Add crypto library for warmboot code
Quoted 11 lines · On Monday 26 December 2011 14:32:56 Simon Glass wrote:
arch/arm/cpu/armv7/tegra2/crypto.c new file +8
-0+#ifdef DEBUG +static void debug_print_vector (char *name,u32 num_bytes,u8 *data) +{ +u32 i; + +printf ("%s [%d] @0x%08x" , name, num_bytes, (u32 )data); +for (i =0 ; i < num_bytes; i++) { +if (i %16 ==0 )
arch/arm/cpu/armv7/tegra2/crypto.c line 55
Quoted 10 lines
arch/arm/cpu/armv7/tegra2/crypto.c new file +10
-0+printf (" = " ); +printf ("%02x" , data[i]); +if ((i+1 ) %16 !=0 ) + printf(" "); + } +printf ("\n" ); +} +#else +#define debug_print_vector (name, num_bytes, data) +#endif
if you used debug() instead of printf(), wouldn't this get optimized without the #ifdef protection ?
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120108/022ecb01/attachment.pgp>
PATCH 3/14 tegra: Add crypto library for warmboot code
Hi Mike,
Quoted 17 lines · Mike Frysinger
Quoted 16 lines · On Monday 26 December 2011 14:32:56 Simon Glass wrote:
arch/arm/cpu/armv7/tegra2/crypto.c new file +13
-0+#ifdef DEBUG +static void debug_print_vector (char *name,u32 num_bytes,u8 *data) +{ + ? ? u32 i; + + ? ? printf("%s [%d] @0x%08x", name, num_bytes, (u32)data); + ? ? for (i = 0; i < num_bytes; i++) { + ? ? ? ? ? ? if (i % 16 == 0) + ? ? ? ? ? ? ? ? ? ? printf(" = "); + ? ? ? ? ? ? printf("%02x", data[i]); + ? ? ? ? ? ? if ((i+1) % 16 != 0) + ? ? ? ? ? ? ? ? ? ? printf(" "); + ? ? }
Quoted 8 lines
arch/arm/cpu/armv7/tegra2/crypto.c line 55
Quoted 5 lines
+ ? ?
printf("\n");arch/arm/cpu/armv7/tegra2/crypto.c new file +4
-0+} +#else +#define debug_print_vector (name, num_bytes, data) +#endif if you used
debug()instead ofprintf(), wouldn't this get optimized without the #ifdef protection ?
Yes it does, clever compiler. I will change it.
Regards
Simon
Quoted 1 line
-mike
PATCH 4/14 tegra: Add flow, gp_padctl, fuse, sdram headers
In reply to Simon GlassFrom: Yen Lin <[email protected]>
These headers provide access to additional Tegra features.
flow - start/stop CPUs
sdram - parameters for SDRAM
fuse - access to on-chip fuses / security settings gp_padctl - pad control and general purpose registers
--- arch/arm/include/asm/arch-tegra2/flow.h | 36 ++++++ arch/arm/include/asm/arch-tegra2/fuse.h | 39 ++++++ arch/arm/include/asm/arch-tegra2/gp_padctrl.h | 64 ++++++++++ arch/arm/include/asm/arch-tegra2/sdram_param.h | 148 ++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra2/tegra2.h | 1 + 5 files changed, 288 insertions(+), 0 deletions(-) create mode 100644 arch/arm/include/asm/arch-tegra2/flow.h create mode 100644 arch/arm/include/asm/arch-tegra2/fuse.h create mode 100644 arch/arm/include/asm/arch-tegra2/gp_padctrl.h create mode 100644 arch/arm/include/asm/arch-tegra2/sdram_param.h
arch/arm/include/asm/arch-tegra2/flow.h new file +36 -0
@@ -0,0 +1,36 @@ +/* +* (C) Copyright 2010, 2011 +* NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* 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; either version 2 of +* the License, or (at your option) any later version. +* +* 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., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#ifndef _FLOW_H_ +#define _FLOW_H_ + +struct flow_ctlr { +u32 halt_cpu_events; +u32 halt_cop_events; +u32 cpu_csr; +u32 cop_csr; +u32 halt_cpu1_events; +u32 cpu1_csr; +}; + +#endif
arch/arm/include/asm/arch-tegra2/fuse.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +* (C) Copyright 2010,2011 +* NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* 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; either version 2 of +* the License, or (at your option) any later version. +* +* 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., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#ifndef _FUSE_H_ +#define _FUSE_H_ + +/* FUSE registers */ +struct fuse_regs { +u32 reserved0[64 ];/* 0x00 - 0xFC: */ +u32 production_mode;/* 0x100: FUSE_PRODUCTION_MODE */ +u32 reserved1[3 ];/* 0x104 - 0x10c: */ +u32 sku_info;/* 0x110 */ +u32 reserved2[13 ];/* 0x114 - 0x144: */ +u32 fa;/* 0x148: FUSE_FA */ +u32 reserved3[21 ];/* 0x14C - 0x19C: */ +u32 security_mode;/* 0x1A0: FUSE_SECURITY_MODE */ +}; + +#endif /* ifndef _FUSE_H_ */
arch/arm/include/asm/arch-tegra2/gp_padctrl.h new file +64 -0
64 lines not on this page · raw message
arch/arm/include/asm/arch-tegra2/sdram_param.h new file +148 -0
148 lines not on this page · raw message
arch/arm/include/asm/arch-tegra2/tegra2.h +1 -0
@@ -44,6 +44,7 @@#define TEGRA2_I2C2_BASE (NV_PA_APB_MISC_BASE + 0xC400)#define TEGRA2_I2C3_BASE (NV_PA_APB_MISC_BASE + 0xC500)#define TEGRA2_DVC_BASE (NV_PA_APB_MISC_BASE + 0xD000) +#define TEGRA2_FUSE_BASE (NV_PA_APB_MISC_BASE + 0xF800)#define NV_PA_CSITE_BASE 0x70040000#define TEGRA_USB1_BASE 0xC5000000#define TEGRA_USB3_BASE 0xC5008000
Signature · 1 line
1.7.3.1
PATCH 5/14 tegra: Add tegra_get_chip_type() to detect SKU
In reply to Simon GlassWe want to know which type of chip we are running on - the Tegra family has several SKUs. This can be determined by reading a fuse register, so add this function to ap20.
--- arch/arm/cpu/armv7/tegra2/ap20.c | 24 ++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra2/ap20.h | 7 +++++++ arch/arm/include/asm/arch-tegra2/tegra2.h | 23 +++++++++++++++++++++++ 3 files changed, 54 insertions(+), 0 deletions(-)
arch/arm/cpu/armv7/tegra2/ap20.c +24 -0
@@ -26,11 +26,35 @@#include <asm/arch/ap20.h> #include <asm/arch/clk_rst.h> #include <asm/arch/clock.h> +#include <asm/arch/fuse.h> #include <asm/arch/pmc.h> #include <asm/arch/pinmux.h> #include <asm/arch/scu.h> #include <common.h> +int tegra_get_chip_type (void ) +{ +struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE ; +uint tegra_sku_id; + + tegra_sku_id =readl (&fuse->sku_info) &0xff ; + +switch (tegra_sku_id) { +case SKU_ID_T20 : +return TEGRA_SOC_T20 ; +case SKU_ID_T25SE : +case SKU_ID_AP25 : +case SKU_ID_T25 : +case SKU_ID_AP25E : +case SKU_ID_T25E : +return TEGRA_SOC_T25 ; + +default : +/* unknown sku id */ +return TEGRA_SOC_UNKNOWN ; + } +} +/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */ static int ap20_cpu_is_cortexa9 (void ) {
arch/arm/include/asm/arch-tegra2/ap20.h +7 -0
@@ -100,3 +100,10 @@ void tegra2_start(void);/* This is the main entry into U-Boot, used by the Cortex-A9 */ extern void _start (void ); + +/** +* Works out the SOC type used for clocks settings +* +* @return SOC type - see TEGRA_SOC... +*/ +int tegra_get_chip_type (void );
arch/arm/include/asm/arch-tegra2/tegra2.h +23 -0
@@ -59,6 +59,29 @@struct timerus {unsigned int cntr_1us; }; + +/* Address at which WB code runs, it must not overlap Bootrom's IRAM usage */ +#define AP20_WB_RUN_ADDRESS 0x40020000 + +/* These are the available SKUs (product types) for Tegra */ +enum { +SKU_ID_T20 =0x8 , +SKU_ID_T25SE =0x14 , +SKU_ID_AP25 =0x17 , +SKU_ID_T25 =0x18 , +SKU_ID_AP25E =0x1b , +SKU_ID_T25E =0x1c , +}; + +/* These are the SOC categories that affect clocking */ +enum { +TEGRA_SOC_T20 , +TEGRA_SOC_T25 , + +TEGRA_SOC_COUNT , +TEGRA_SOC_UNKNOWN =-1 , +}; +#else /* __ASSEMBLY__ */ #define PRM_RSTCTRL TEGRA2_PMC_BASE#endif
Signature · 1 line
1.7.3.1
PATCH 5/14 tegra: Add tegra_get_chip_type() to detect SKU
Quoted 3 lines · Simon Glass
We want to know which type of chip we are running on - the Tegra family has several SKUs. This can be determined by reading a fuse register, so add this function to ap20.
...
Quoted 1 line
arch/arm/cpu/armv7/tegra2/ap20.c +0
-0
...
arch/arm/cpu/armv7/tegra2/ap20.c line 42
Quoted 8 lines
arch/arm/cpu/armv7/tegra2/ap20.c +8
-0+int tegra_get_chip_type (void ) +{ +struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE ; +uint tegra_sku_id; + + tegra_sku_id =readl (&fuse->sku_info) &0xff ; + +switch (tegra_sku_id) {
I think this should read/validate/switch-on the SoC ID field too; I assume the SKU IDs can only be interpreted relative to some specific SoC ID.
Chip ID is bits 15:8 of the register APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for Tegra30.
Signature · 1 line
nvpublic
PATCH 5/14 tegra: Add tegra_get_chip_type() to detect SKU
Hi Stephen,
Quoted 19 lines · Stephen Warren
Quoted 3 lines · Simon Glass
We want to know which type of chip we are running on - the Tegra family has several SKUs. This can be determined by reading a fuse register, so add this function to ap20.
...
Quoted 1 line
arch/arm/cpu/armv7/tegra2/ap20.c +0
-0...
arch/arm/cpu/armv7/tegra2/ap20.c
Quoted 8 lines
arch/arm/cpu/armv7/tegra2/ap20.c +8
-0+int tegra_get_chip_type (void ) +{ + ? ? struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE; + ? ? uint tegra_sku_id; + + ? ? tegra_sku_id = readl(&fuse->sku_info) & 0xff; + + ? ? switch (tegra_sku_id) {I think this should read/validate/switch-on the SoC ID field too; I assume the SKU IDs can only be interpreted relative to some specific SoC ID.
Quoted 2 lines
Chip ID is bits 15:8 of the register
APB_MISC+0x804, and has value0x20for Tegra20,0x30for Tegra30.
My TRM doesn't mention those values. What version are you referring to? I have v06.
Regards,
Simon
Quoted 3 lines
--
nvpublic
PATCH 5/14 tegra: Add tegra_get_chip_type() to detect SKU
Simon Glass wrote at Thursday, January 12, 2012 12:36 PM:
Quoted 2 lines · Stephen Warren
Quoted 1 line · Simon Glass
...
Quoted 8 lines
Quoted 5 lines
I think this should read/validate/switch-on the SoC ID field too; I assume the SKU IDs can only be interpreted relative to some specific SoC ID.
Chip ID is bits 15:8 of the register
APB_MISC+0x804, and has value0x20for Tegra20,0x30for Tegra30.My TRM doesn't mention those values. What version are you referring to? I have v06.
In both v06 and v01p (the public version), the register is in section 11.1.6.8. I guess that doesn't actually define the values of the fields, sigh. But, I can say that Tegra20 is 0x20 and Tegra30 is 0x30.
For example, see:
function void tegra_get_tegraid_from_hw, and:
for definitions of TEGRA_CHIPID_*.
Signature · 1 line
nvpublic
PATCH 5/14 tegra: Add tegra_get_chip_type() to detect SKU
Hi Stephen,
Quoted 19 lines · Stephen Warren
Simon Glass wrote at Thursday, January 12, 2012 12:36 PM:
Quoted 2 lines · Stephen Warren
Quoted 1 line · Simon Glass
...
Quoted 8 lines
Quoted 5 lines
I think this should read/validate/switch-on the SoC ID field too; I assume the SKU IDs can only be interpreted relative to some specific SoC ID.
Chip ID is bits 15:8 of the register
APB_MISC+0x804, and has value0x20for Tegra20,0x30for Tegra30.My TRM doesn't mention those values. What version are you referring to? I have v06.
In both v06 and v01p (the public version), the register is in section 11.1.6.8. I guess that doesn't actually define the values of the fields, sigh. But, I can say that Tegra20 is
0x20and Tegra30 is0x30.For example, see:
Quoted 7 lines
function void
tegra_get_tegraid_from_hw, and:for definitions of TEGRA_CHIPID_*.
OK, I will put this in as you say with a suitable comment.
Regards,
Simon
Quoted 4 lines
--
nvpublic
PATCH 6/14 tegra: Add EMC support for optimal memory timings
In reply to Simon GlassFrom: Jimmy Zhang <[email protected]>
Add support for setting up the memory controller parameters. Boards can call tegra_set_emc() with a table containing the required parameters.
--- arch/arm/cpu/armv7/tegra2/Makefile | 1 + arch/arm/cpu/armv7/tegra2/emc.c | 165 +++++++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra2/emc.h | 107 +++++++++++++++++++ arch/arm/include/asm/arch-tegra2/tegra2.h | 1 + 4 files changed, 274 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/tegra2/emc.c create mode 100644 arch/arm/include/asm/arch-tegra2/emc.h
arch/arm/cpu/armv7/tegra2/Makefile +1 -0
@@ -34,6 +34,7 @@ LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o COBJS-y := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o +COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o COBJS := $(COBJS-y)
arch/arm/cpu/armv7/tegra2/emc.c new file +165 -0
165 lines not on this page · raw message
arch/arm/include/asm/arch-tegra2/emc.h new file +107 -0
107 lines not on this page · raw message
arch/arm/include/asm/arch-tegra2/tegra2.h +1 -0
@@ -44,6 +44,7 @@#define TEGRA2_I2C2_BASE (NV_PA_APB_MISC_BASE + 0xC400)#define TEGRA2_I2C3_BASE (NV_PA_APB_MISC_BASE + 0xC500)#define TEGRA2_DVC_BASE (NV_PA_APB_MISC_BASE + 0xD000) +#define TEGRA2_EMC_BASE (NV_PA_APB_MISC_BASE + 0xF400)#define TEGRA2_FUSE_BASE (NV_PA_APB_MISC_BASE + 0xF800)#define NV_PA_CSITE_BASE 0x70040000#define TEGRA_USB1_BASE 0xC5000000
Signature · 1 line
1.7.3.1
PATCH 6/14 tegra: Add EMC support for optimal memory timings
Quoted 5 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
Add support for setting up the memory controller parameters. Boards can call
tegra_set_emc()with a table containing the required parameters.
...
Quoted 1 line
arch/arm/cpu/armv7/tegra2/emc.c +0
-0
...
arch/arm/cpu/armv7/tegra2/emc.c line 31
Quoted 2 lines
arch/arm/cpu/armv7/tegra2/emc.c +2
-0+static const struct tegra_emc_table *tegra_emc_table; +static int tegra_emc_table_size;
This isn't "table_size", but "number_of_tables" or "num_tables" or "table_count". This sounds nit-picky, but it made me think about this change more than I needed to given its simplicity.
arch/arm/cpu/armv7/tegra2/emc.c line 49
Quoted 2 lines
arch/arm/cpu/armv7/tegra2/emc.c +2
-0+static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS ] = { +0x2c ,/* RC */
For reference, I validated that the order or registers here matches that in the DT binding that Olof published for the kernel, which is good.
Quoted 8 lines
arch/arm/cpu/armv7/tegra2/emc.c +8
-0+/* The EMC registers have shadow registers. When the EMC clock is updated +* in the clock controller, the shadow registers are copied to the active +* registers, allowing glitchless memory bus frequency changes. +* This function updates the shadow registers for a new clock frequency, +* and relies on the clock lock on the emc clock to avoid races between +* multiple frequency changes */ +#define EMC_SDRAM_RATE_T20 (333000 * 2 * 1000) +#define EMC_SDRAM_RATE_T25 (380000 * 2 * 1000)
...
Quoted 1 line
+int
tegra_set_emc(const struct tegra_emc_table *table, int table_size)
...
arch/arm/cpu/armv7/tegra2/emc.c line 160
Quoted 11 lines
arch/arm/cpu/armv7/tegra2/emc.c +11
-0+switch (tegra_get_chip_type ()) { +case TEGRA_SOC_T20 : + rate =EMC_SDRAM_RATE_T20 ; +break ; +case TEGRA_SOC_T25 : + rate =EMC_SDRAM_RATE_T25 ; +break ; +default : +/* unknown chip type, no clk change*/ +return -1 ; + }
I'm not convinced that limiting this to those two specific clocks is correct. I've certainly seen BCTs that appear to run the EMC clock at other frequencies. Specifically, for Seaboard, we appear to have BCTs for 190, 333, 380, and 400MHz internally. I think a board should be able to at least override the default rate selected by that switch statement.
In tegra_emc_set_rate(), it's unclear to me why clock_ll_set_source_divisor() is used to trigger use of the new EMC register content, rather than say clock_set_rate(). I guess that's just how the HW work?
Signature · 1 line
nvpublic
PATCH 6/14 tegra: Add EMC support for optimal memory timings
Hi Stephen,
Quoted 7 lines · Stephen Warren
Quoted 5 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
Add support for setting up the memory controller parameters. Boards can call
tegra_set_emc()with a table containing the required parameters....
Quoted 8 lines
Quoted 1 line
arch/arm/cpu/armv7/tegra2/emc.c +0
-0...
arch/arm/cpu/armv7/tegra2/emc.c line 31
Quoted 2 lines
arch/arm/cpu/armv7/tegra2/emc.c +2
-0+static const struct tegra_emc_table *tegra_emc_table; +static int tegra_emc_table_size;This isn't "
table_size", but "number_of_tables" or "num_tables" or "table_count". This sounds nit-picky, but it made me think about this change more than I needed to given its simplicity.
OK changed to num_emc_tables.
Quoted 8 lines
Quoted 3 lines
+static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
+ ? ? ?0x2c, ? /* RC */For reference, I validated that the order or registers here matches that in the DT binding that Olof published for the kernel, which is good.
Yes I would hope so :-) Thanks for checking. I can't see it committed, so will reply on that thread.
Quoted 24 lines
Quoted 9 lines
arch/arm/cpu/armv7/tegra2/emc.c +8
-0+/* The EMC registers have shadow registers. ?When the EMC clock is updated +* in the clock controller, the shadow registers are copied to the active +* registers, allowing glitchless memory bus frequency changes. +* This function updates the shadow registers for a new clock frequency, +* and relies on the clock lock on the emc clock to avoid races between +* multiple frequency changes */ +#define EMC_SDRAM_RATE_T20 ? ? (333000 * 2 * 1000) +#define EMC_SDRAM_RATE_T25 ? ? (380000 * 2 * 1000)...
Quoted 1 line
+int
tegra_set_emc(const struct tegra_emc_table *table, int table_size)...
Quoted 11 lines
+ ? ? ? switch (
tegra_get_chip_type()) {
+ ? ? ? caseTEGRA_SOC_T20:
+ ? ? ? ? ? ? ? rate ?=EMC_SDRAM_RATE_T20;
+ ? ? ? ? ? ? ? break;
+ ? ? ? caseTEGRA_SOC_T25:
+ ? ? ? ? ? ? ? rate ?=EMC_SDRAM_RATE_T25;
+ ? ? ? ? ? ? ? break;
+ ? ? ? default:
+ ? ? ? ? ? ? ? /* unknown chip type, no clk change*/
+ ? ? ? ? ? ? ? return -1;
+ ? ? ? }
Quoted 5 lines
I'm not convinced that limiting this to those two specific clocks is correct. I've certainly seen BCTs that appear to run the EMC clock at other frequencies. Specifically, for Seaboard, we appear to have BCTs for 190, 333, 380, and 400MHz internally. I think a board should be able to at least override the default rate selected by that switch statement.
OK. It might be time to move this to the fdt, I will take a look.
Quoted 5 lines
In
tegra_emc_set_rate(), it's unclear to me whyclock_ll_set_source_divisor()is used to trigger use of the new EMC register content, rather than sayclock_set_rate(). I guess that's just how the HW work?
It should be possible to do something like:
clock_adjust_periph_pll(PERIPH_ID_EMC, CLOCK_ID_MEMORY, 0, clock_get_rate(CLOCK_ID_MEMORY));
although it is a lot less efficient. I will try it.
Regards,
Simon
Quoted 3 lines
--
nvpublic
PATCH 6/14 tegra: Add EMC support for optimal memory timings
Hi Stephen,
Quoted 71 lines · Simon Glass
Hi Stephen,
Quoted 7 lines · Stephen Warren
Quoted 5 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
Add support for setting up the memory controller parameters. Boards can call
tegra_set_emc()with a table containing the required parameters....
Quoted 8 lines
Quoted 1 line
arch/arm/cpu/armv7/tegra2/emc.c +0
-0...
arch/arm/cpu/armv7/tegra2/emc.c line 31
Quoted 2 lines
arch/arm/cpu/armv7/tegra2/emc.c +2
-0+static const struct tegra_emc_table *tegra_emc_table; +static int tegra_emc_table_size;This isn't "
table_size", but "number_of_tables" or "num_tables" or "table_count". This sounds nit-picky, but it made me think about this change more than I needed to given its simplicity.OK changed to
num_emc_tables.Quoted 8 lines
Quoted 3 lines
+static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
+ ? ? ?0x2c, ? /* RC */For reference, I validated that the order or registers here matches that in the DT binding that Olof published for the kernel, which is good.
Yes I would hope so :-) Thanks for checking. I can't see it committed, so will reply on that thread.
Quoted 24 lines
Quoted 9 lines
arch/arm/cpu/armv7/tegra2/emc.c +8
-0+/* The EMC registers have shadow registers. ?When the EMC clock is updated +* in the clock controller, the shadow registers are copied to the active +* registers, allowing glitchless memory bus frequency changes. +* This function updates the shadow registers for a new clock frequency, +* and relies on the clock lock on the emc clock to avoid races between +* multiple frequency changes */ +#define EMC_SDRAM_RATE_T20 ? ? (333000 * 2 * 1000) +#define EMC_SDRAM_RATE_T25 ? ? (380000 * 2 * 1000)...
Quoted 1 line
+int
tegra_set_emc(const struct tegra_emc_table *table, int table_size)...
Quoted 11 lines
+ ? ? ? switch (
tegra_get_chip_type()) {
+ ? ? ? caseTEGRA_SOC_T20:
+ ? ? ? ? ? ? ? rate ?=EMC_SDRAM_RATE_T20;
+ ? ? ? ? ? ? ? break;
+ ? ? ? caseTEGRA_SOC_T25:
+ ? ? ? ? ? ? ? rate ?=EMC_SDRAM_RATE_T25;
+ ? ? ? ? ? ? ? break;
+ ? ? ? default:
+ ? ? ? ? ? ? ? /* unknown chip type, no clk change*/
+ ? ? ? ? ? ? ? return -1;
+ ? ? ? }Quoted 5 lines
I'm not convinced that limiting this to those two specific clocks is correct. I've certainly seen BCTs that appear to run the EMC clock at other frequencies. Specifically, for Seaboard, we appear to have BCTs for 190, 333, 380, and 400MHz internally. I think a board should be able to at least override the default rate selected by that switch statement.
OK. It might be time to move this to the fdt, I will take a look.
Quoted 5 lines
In
tegra_emc_set_rate(), it's unclear to me whyclock_ll_set_source_divisor()is used to trigger use of the new EMC register content, rather than sayclock_set_rate(). I guess that's just how the HW work?
Quoted 6 lines
It should be possible to do something like:
? ? ? ?clock_adjust_periph_pll(PERIPH_ID_EMC,
CLOCK_ID_MEMORY, 0, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?clock_get_rate(CLOCK_ID_MEMORY));although it is a lot less efficient. I will try it.
Yes that works. I want to reduce use of the xxx_ll() functions as much as possible so have changed this.
Regards,
Simon
Quoted 7 lines
Regards,
SimonQuoted 3 lines
--
nvpublic
PATCH 7/14 tegra: Add PMU to manage power supplies
In reply to Simon GlassFrom: Jimmy Zhang <[email protected]>
Power supplies must be adjusted in line with clock frequency. This code provides a simple routine to set the voltage to allow operation at maximum frequency.
--- arch/arm/cpu/armv7/tegra2/Makefile | 1 + arch/arm/cpu/armv7/tegra2/pmu.c | 355 ++++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra2/pmu.h | 63 ++++++ 3 files changed, 419 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/tegra2/pmu.c create mode 100644 arch/arm/include/asm/arch-tegra2/pmu.h
arch/arm/cpu/armv7/tegra2/Makefile +1 -0
@@ -35,6 +35,7 @@ LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o COBJS-y := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o +COBJS-$(CONFIG_TEGRA_PMU) += pmu.o COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o COBJS := $(COBJS-y)
arch/arm/cpu/armv7/tegra2/pmu.c new file +355 -0
355 lines not on this page · raw message
arch/arm/include/asm/arch-tegra2/pmu.h new file +63 -0
63 lines not on this page · raw message
Signature · 1 line
1.7.3.1
PATCH 7/14 tegra: Add PMU to manage power supplies
Quoted 6 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
Power supplies must be adjusted in line with clock frequency. This code provides a simple routine to set the voltage to allow operation at maximum frequency.
Quoted 8 lines
Signed-off-by Simon Glass <[email protected]>--- arch/arm/cpu/armv7/tegra2/Makefile | 1 + arch/arm/cpu/armv7/tegra2/pmu.c | 355 ++++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-tegra2/pmu.h | 63 ++++++ 3 files changed, 419 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/tegra2/pmu.c create mode 100644 arch/arm/include/asm/arch-tegra2/pmu.h
This driver appears to be for an I2C-based device, so I assume it'd for a particular PMIC not Tegra's PMC HW module. I imagine this is a driver for the TI TPS6586X, right?
As such, naming this "pmu" and putting it into the Tegra directory doesn't make sense. There should be a generic TPS6586X driver, and possibly a separate file and patch to implement the use of that chip in conjunction with Tegra.
Signature · 1 line
nvpublic
PATCH 7/14 tegra: Add PMU to manage power supplies
Hi Stephen,
Quoted 16 lines · Stephen Warren
Quoted 6 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
Power supplies must be adjusted in line with clock frequency. This code provides a simple routine to set the voltage to allow operation at maximum frequency.
Quoted 8 lines
Signed-off-by Simon Glass <[email protected]>---
?arch/arm/cpu/armv7/tegra2/Makefile ? ? | ? ?1 + ?arch/arm/cpu/armv7/tegra2/pmu.c ? ? ? ?| ?355 ++++++++++++++++++++++++++++++++ ?arch/arm/include/asm/arch-tegra2/pmu.h | ? 63 ++++++?3 files changed, 419 insertions(+), 0 deletions(-) ?create mode 100644
arch/arm/cpu/armv7/tegra2/pmu.c?create mode 100644arch/arm/include/asm/arch-tegra2/pmu.h
Quoted 8 lines
This driver appears to be for an I2C-based device, so I assume it'd for a particular PMIC not Tegra's PMC HW module. I imagine this is a driver for the TI TPS6586X, right?
As such, naming this "pmu" and putting it into the Tegra directory doesn't make sense. There should be a generic TPS6586X driver, and possibly a separate file and patch to implement the use of that chip in conjunction with Tegra.
Oh dear, but yes you are right. It is a TPS658621C according to my schematic. I will leap into this also.
Regards,
Simon
Quoted 3 lines
--
nvpublic
PATCH 7/14 tegra: Add PMU to manage power supplies
Simon Glass wrote at Thursday, January 12, 2012 4:17 PM:
Quoted 21 lines · Stephen Warren
Quoted 20 lines · Simon Glass
Quoted 6 lines
From: Jimmy Zhang <[email protected]>
Power supplies must be adjusted in line with clock frequency. This code provides a simple routine to set the voltage to allow operation at maximum frequency.
Quoted 8 lines
Signed-off-by Simon Glass <[email protected]>---
?arch/arm/cpu/armv7/tegra2/Makefile ? ? | ? ?1 + ?arch/arm/cpu/armv7/tegra2/pmu.c ? ? ? ?| ?355 ++++++++++++++++++++++++++++++++ ?arch/arm/include/asm/arch-tegra2/pmu.h | ? 63 ++++++?3 files changed, 419 insertions(+), 0 deletions(-) ?create mode 100644
arch/arm/cpu/armv7/tegra2/pmu.c?create mode 100644arch/arm/include/asm/arch-tegra2/pmu.hThis driver appears to be for an I2C-based device, so I assume it'd for a particular PMIC not Tegra's PMC HW module. I imagine this is a driver for the TI TPS6586X, right?
Quoted 7 lines
Quoted 4 lines
As such, naming this "pmu" and putting it into the Tegra directory doesn't make sense. There should be a generic TPS6586X driver, and possibly a separate file and patch to implement the use of that chip in conjunction with Tegra.
Oh dear, but yes you are right. It is a TPS658621C according to my schematic. I will leap into this also.
I believe some number of the devices are compatible, hence the kernel has a tps6586x driver rather than more individual drivers for each value of "x".
Signature · 1 line
nvpublic
PATCH 7/14 tegra: Add PMU to manage power supplies
Hi Stephen,
Quoted 27 lines · Stephen Warren
Simon Glass wrote at Thursday, January 12, 2012 4:17 PM:
Quoted 26 lines · Stephen Warren
Quoted 24 lines · Simon Glass
Quoted 6 lines
From: Jimmy Zhang <[email protected]>
Power supplies must be adjusted in line with clock frequency. This code provides a simple routine to set the voltage to allow operation at maximum frequency.
Quoted 8 lines
Signed-off-by Simon Glass <[email protected]>---
?arch/arm/cpu/armv7/tegra2/Makefile ? ? | ? ?1 + ?arch/arm/cpu/armv7/tegra2/pmu.c ? ? ? ?| ?355 ++++++++++++++++++++++++++++++++ ?arch/arm/include/asm/arch-tegra2/pmu.h | ? 63 ++++++?3 files changed, 419 insertions(+), 0 deletions(-) ?create mode 100644
arch/arm/cpu/armv7/tegra2/pmu.c?create mode 100644arch/arm/include/asm/arch-tegra2/pmu.hThis driver appears to be for an I2C-based device, so I assume it'd for a particular PMIC not Tegra's PMC HW module. I imagine this is a driver for the TI TPS6586X, right?
As such, naming this "pmu" and putting it into the Tegra directory doesn't make sense. There should be a generic TPS6586X driver, and possibly a separate file and patch to implement the use of that chip in conjunction with Tegra.
Quoted 6 lines
Quoted 2 lines
Oh dear, but yes you are right. It is a TPS658621C according to my schematic. I will leap into this also.
I believe some number of the devices are compatible, hence the kernel has a tps6586x driver rather than more individual drivers for each value of "x".
OK I will follow along with that.
Regards,
Simon
Quoted 4 lines
--
nvpublic
PATCH 8/14 tegra: Set up PMU for Nvidia boards
In reply to Simon GlassAdjust PMU to permit maximum frequency operation.
--- board/nvidia/common/board.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
board/nvidia/common/board.c +10 -0
@@ -31,6 +31,8 @@#include <asm/arch/clk_rst.h> #include <asm/arch/clock.h> #include <asm/arch/pinmux.h> +#include <asm/arch/pmc.h> +#include <asm/arch/pmu.h> #include <asm/arch/uart.h> #include <spi.h> #include <asm/arch/usb.h>
@@ -81,6 +83,14 @@ int board_init(void)board_usb_init (gd->fdt_blob);#endif +#ifdef CONFIG_TEGRA2_I2C +i2c_init_board (); + +#ifdef CONFIG_TEGRA_PMU +pmu_set_nominal (); +#endif +#endif +return 0 ; }
Signature · 1 line
1.7.3.1
PATCH 8/14 tegra: Set up PMU for Nvidia boards
Quoted 1 line · Simon Glass
Adjust PMU to permit maximum frequency operation.
...
Quoted 1 line
board/nvidia/common/board.c +0
-0
...
board/nvidia/common/board.c int board_init(void) · line 95
Quoted 10 lines
board/nvidia/common/board.c +8
-0+#ifdef CONFIG_TEGRA2_I2C +i2c_init_board (); + +#ifdef CONFIG_TEGRA_PMU +pmu_set_nominal (); +#endif +#endif +return 0 ; }
I think there's some patch confusion here; weren't the outer ifdef and call to i2c_init_board() added in the I2C patch series too?
Signature · 1 line
nvpublic
PATCH 8/14 tegra: Set up PMU for Nvidia boards
Hi Stephen,
Quoted 5 lines · Stephen Warren
Quoted 1 line · Simon Glass
Adjust PMU to permit maximum frequency operation.
...
Quoted 1 line
board/nvidia/common/board.c +0
-0...
Quoted 13 lines
Quoted 10 lines
board/nvidia/common/board.c +8
-0+#ifdef CONFIG_TEGRA2_I2C + ? ? i2c_init_board(); + +#ifdef CONFIG_TEGRA_PMU + ? ? pmu_set_nominal(); +#endif +#endif +? ? ? return 0;
?}I think there's some patch confusion here; weren't the outer ifdef and call to
i2c_init_board()added in the I2C patch series too?
Yes, I moved some code around and duplicated it. I will fix this.
Regards,
Simon
Quoted 3 lines
--
nvpublic
PATCH 9/14 tegra: Add warmboot implementation
In reply to Simon GlassFrom: Yen Lin <[email protected]>
Add code to set up the warm boot area in the Tegra CPU ready for a resume after suspend.
--- arch/arm/cpu/armv7/tegra2/Makefile | 6 +- arch/arm/cpu/armv7/tegra2/warmboot.c | 444 +++++++++++++++++++++++++++ arch/arm/cpu/armv7/tegra2/warmboot_avp.c | 312 +++++++++++++++++++ arch/arm/cpu/armv7/tegra2/warmboot_avp.h | 81 +++++ arch/arm/include/asm/arch-tegra2/tegra2.h | 1 + arch/arm/include/asm/arch-tegra2/warmboot.h | 81 +++++ 6 files changed, 924 insertions(+), 1 deletions(-) create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot.c create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot_avp.c create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot_avp.h create mode 100644 arch/arm/include/asm/arch-tegra2/warmboot.h
arch/arm/cpu/armv7/tegra2/Makefile +5 -1
@@ -27,17 +27,21 @@ # flags for any startup files it might use. CFLAGS_arch/arm/cpu/armv7/tegra2/ap20.o += -march=armv4t CFLAGS_arch/arm/cpu/armv7/tegra2/clock.o += -march=armv4t +CFLAGS_arch/arm/cpu/armv7/tegra2/warmboot_avp.o += -march=armv4t include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -SOBJS := lowlevel_init.o +SOBJS-y := lowlevel_init.o COBJS-y := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o + COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o COBJS-$(CONFIG_TEGRA_PMU) += pmu.o COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o +COBJS-$(CONFIG_TEGRA2_LP0) += crypto.o warmboot.o warmboot_avp.o +SOBJS := $(SOBJS-y) COBJS := $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
arch/arm/cpu/armv7/tegra2/warmboot.c new file +444 -0
444 lines not on this page · raw message
arch/arm/cpu/armv7/tegra2/warmboot_avp.c new file +312 -0
312 lines not on this page · raw message
arch/arm/cpu/armv7/tegra2/warmboot_avp.h new file +81 -0
81 lines not on this page · raw message
arch/arm/include/asm/arch-tegra2/tegra2.h +1 -0
@@ -33,6 +33,7 @@#define NV_PA_GPIO_BASE 0x6000D000#define NV_PA_EVP_BASE 0x6000F000#define NV_PA_APB_MISC_BASE 0x70000000 +#define TEGRA2_APB_MISC_GP_BASE (NV_PA_APB_MISC_BASE + 0x0800)#define NV_PA_APB_UARTA_BASE (NV_PA_APB_MISC_BASE + 0x6000)#define NV_PA_APB_UARTB_BASE (NV_PA_APB_MISC_BASE + 0x6040)#define NV_PA_APB_UARTC_BASE (NV_PA_APB_MISC_BASE + 0x6200)
arch/arm/include/asm/arch-tegra2/warmboot.h new file +81 -0
81 lines not on this page · raw message
Signature · 1 line
1.7.3.1
PATCH 9/14 tegra: Add warmboot implementation
Quoted 6 lines · Simon Glass
From: Yen Lin <[email protected]>
Add code to set up the warm boot area in the Tegra CPU ready for a resume after suspend.
Signed-off-by Simon Glass <[email protected]>
How come Yen's S-o-b line is missing here?
As a general comment on this patch, it contains a lot of structure definitions and defines that should really be part of the clock module's headers and similar; why not just included the clock headers and place all the definitions in those headers if they aren't already there?
There's also some amount of code duplication; e.g. wasn't get_major_version() part of another patch you recently posted that implements APIs to return SKU IDs etc? If not, it seems like it belongs there. Only warmboot_avp.c appears to run on the AVP, so I don't think needing ARMv4 compile flags is an argument for not putting this code in a more logical place.
Quoted 1 line
arch/arm/cpu/armv7/tegra2/Makefile +0
-0
...
Quoted 2 lines
arch/arm/cpu/armv7/tegra2/Makefile +1
-1-SOBJS := lowlevel_init.o +SOBJS-y := lowlevel_init.o
...
Quoted 1 line
+SOBJS := $(SOBJS-y)
That's really a separate patch, but I guess it's fine.
Quoted 1 line
arch/arm/cpu/armv7/tegra2/warmboot.c +0
-0
...
arch/arm/cpu/armv7/tegra2/warmboot.c line 41
Quoted 3 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +3
-0+#define BCT_OFFSET 0x100/* BCT starts at 0x100 */ +#define BCT_SDRAM_PARAMS_OFFSET (BCT_OFFSET + 0x88) +#define SDRAM_PARAMS_BASE (AP20_BASE_PA_SRAM + BCT_SDRAM_PARAMS_OFFSET)
BCT_OFFSET is where the BCT is stored within some warmboot-specific memory location. I think the comment should be explicit about this, because IIRC the BCT starts at offset 0 within the (cold) boot flash memory, so the comment is confusing until you trace through the code and find what SDRAM_PARAMS_BASE is used for.
arch/arm/cpu/armv7/tegra2/warmboot.c line 244
Quoted 10 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +10
-0+/* +* NOTE: If more than one of the following is enabled, only one of them will +* actually be used. RANDOM takes precedence over PATTERN and ZERO, and +* PATTERN takes precedence overy ZERO. +* +* RANDOM_AES_BLOCK_IS_PATTERN is to define a 32-bit PATTERN. +*/ +#define RANDOM_AES_BLOCK_IS_RANDOM /* to randomize the header */ +#undef RANDOM_AES_BLOCK_IS_PATTERN/* to patternize the header */ +#undef RANDOM_AES_BLOCK_IS_ZERO/* to clear the header */
Why not just used ifdefs to make sure that only (and exactly) one of these is defined?
arch/arm/cpu/armv7/tegra2/warmboot.c line 323
Quoted 5 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +5
-0+/* Currently, this routine returns a 32-bit all 0 seed. */ +static u32 query_random_seed (void ) +{ +return 0 ; +}
So the random option isn't really implemented at all. Perhaps just remove it completely; if someone wants it, they have to implement this function for it to be useful anyway, so adding the call to the function at the same time seems reasonable enough?
If not, at least make this print something at run-time so it's obvious it isn't really working.
Quoted 1 line
+int
warmboot_prepare_code(u32 seg_address, u32 seg_length)
...
arch/arm/cpu/armv7/tegra2/warmboot.c line 381
Quoted 9 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +9
-0+/* +* The region specified by seg_address must not be in IRAM and must be +* nonzero in length. +*/ +if ((seg_length ==0 ) || (seg_address ==0 ) || + (seg_address >=AP20_BASE_PA_SRAM )) { + err = -EFAULT ; + goto fail; + }
The IRAM check only validates that the address isn't at, within, or after the IRAM location, which doesn't exactly match the comment. If the restriction is "within" IRAM, the end address needs to be checked too. Isn't the real restriction that the address needs to be within SDRAM though? If so, it seems better to check that directly.
...
Quoted 8 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +8
-0+/* Populate the random_aes_block as requested. */ + { +u32 *aes_block = (u32 *)&(dst_header->random_aes_block); +u32 *end = (u32 *)(((u32 )aes_block) + +sizeof (dst_header->random_aes_block)); + + do { +#if defined(RANDOM_AES_BLOCK_IS_RANDOM)
arch/arm/cpu/armv7/tegra2/warmboot.c line 415
Quoted 10 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +10
-0+ *aes_block++ =query_random_seed (); +#elif defined(RANDOM_AES_BLOCK_IS_PATTERN ) + *aes_block++ =RANDOM_AES_BLOCK_IS_PATTERN ; +#elif defined(RANDOM_AES_BLOCK_IS_ZERO ) + *aes_block++ =0 ; +#else +printf ("None of RANDOM_AES_BLOCK_IS_XXX is defined; " ); +printf ("Default to pattern 0.\n" ); + *aes_block++ =0 ; +#endif
Why not issue a compile error so the person who configured U-Boot is immediately aware of the problem, instead of delaying the issue to run-time?
Quoted 4 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +2
-0+ }while (aes_block < end); + }arch/arm/cpu/armv7/tegra2/warmboot_avp.c +0
-0
...
Quoted 15 lines
arch/arm/cpu/armv7/tegra2/warmboot_avp.c +15
-0+void wb_start (void ) +{ +struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE ; +struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE ; +struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE ; +struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE ; +union osc_ctrl_reg osc_ctrl; +union pllx_base_reg pllx_base; +union pllx_misc_reg pllx_misc; +union scratch3_reg scratch3; +u32 reg; + +/* enable JTAG & TBE */ +writel (CONFIG_CTL_TBE |CONFIG_CTL_JTAG , &pmt->pmt_cfg_ctl);
arch/arm/cpu/armv7/tegra2/warmboot_avp.c line 124
Quoted 10 lines
arch/arm/cpu/armv7/tegra2/warmboot_avp.c +10
-0+ +/* Are we running where we're supposed to be? */ + asmvolatile ( +"adr %0, wb_start;" /* reg: wb_start address */ + :"=r" (reg)/* output */ +/* no input, no clobber list */ + ); + +if (reg !=AP20_WB_RUN_ADDRESS ) + goto do_reset;
Does that code actually work; for it to work, the code would need to be either explicitly compile PIC (position independent) or accidentally be synthesized to code that happens to be PIC (not sure that's possible/likely).
arch/arm/cpu/armv7/tegra2/warmboot_avp.c line 141
Quoted 5 lines
arch/arm/cpu/armv7/tegra2/warmboot_avp.c +5
-0+/* Set the drive strength */ + osc_ctrl.word =readl (&clkrst->crc_osc_ctrl); + osc_ctrl.xofs =4 ; + osc_ctrl.xoe =1 ; +writel (osc_ctrl.word, &clkrst->crc_osc_ctrl);
Isn't that board-specific?
Shouldn't the code save the old value during suspend, and restore it later or something like that, or be a board-specific #define?
A general question: How much does this all depend on specific interactions with the kernel? Does the kernel have to follow some specific protocol during suspend to make this all work? In mainline, there's no suspend support in Tegra, so I'm slightly worried that when it gets upstreamed, this code might need changes to address any review comments there?
Quoted 1 line
arch/arm/include/asm/arch-tegra2/warmboot.h +0
-0
...
arch/arm/include/asm/arch-tegra2/warmboot.h line 65
Quoted 11 lines
arch/arm/include/asm/arch-tegra2/warmboot.h +11
-0+/* +* Defines the code header information for the boot rom. +* +* The code immediately follows the code header. +* +* Note that the code header needs to be 16 bytes aligned to preserve +* the alignment of relevant data for hash and decryption computations without +* requiring extra copies to temporary memory areas. +*/ +struct wb_header { +u32 length_in_secure;/* length of the code header */
I assume s/in_secure/insecure/ ?
Quoted 8 lines
arch/arm/include/asm/arch-tegra2/warmboot.h +8
-0+u32 reserved[3 ]; +struct hash hash;/* hash of header+code, starts next field*/ +struct hash random_aes_block;/* a data block to aid security. */ +u32 length_secure;/* length of the code header */ +u32 destination;/* destination address to put the wb code */ +u32 entry_point;/* execution address of the wb code */ +u32 code_length;/* length of the code */ +};
Signature · 1 line
nvpublic
PATCH 9/14 tegra: Add warmboot implementation
Hi Stephen,
[Yen please can you read this also?]
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
From: Yen Lin <[email protected]>
Add code to set up the warm boot area in the Tegra CPU ready for a resume after suspend.
Quoted 8 lines
Quoted 1 line
Signed-off-by Simon Glass <[email protected]>How come Yen's S-o-b line is missing here?
As a general comment on this patch, it contains a lot of structure definitions and defines that should really be part of the clock module's headers and similar; why not just included the clock headers and place all the definitions in those headers if they aren't already there?
Yes this bit of it got a pretty light review at the time and I was reluctant to press on the bitfields when that side of things was still up in the air. No functions exist to access these things and using the clk_rst.h header adds a mountain of ugly reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT to the code. I am still uncomfortable with how this sort of thing is done in U-Boot.
Also the AVP code cannot call functions in clock.c (they are in SDRAM which isn't on yet), so we need the structures or some sort of access there anyway.
I will tidy up some low-hanging fruit in warmboot.c but don't know that I can do much with warmboot_avp.c. At least it isn't assembler anymore!
But there a few questions here. Firstly it seems that it saves some memory speed info to scratch2 but never restores it. Then it restores CPU speed from scratch3 but I can't see where it saves it. Does Yen have any comments on that? Apparently it works because we have been using it, but... If it is saving things that are never restored I could dump that and reduce the code size.
Quoted 8 lines
There's also some amount of code duplication; e.g. wasn't
get_major_version()part of another patch you recently posted that implements APIs to return SKU IDs etc? If not, it seems like it belongs there. Onlywarmboot_avp.cappears to run on the AVP, so I don't think needing ARMv4 compile flags is an argument for not putting this code in a more logical place.
Quoted 8 lines
Quoted 1 line
arch/arm/cpu/armv7/tegra2/Makefile +0
-0...
Quoted 2 lines
arch/arm/cpu/armv7/tegra2/Makefile +1
-1-SOBJS ?:= lowlevel_init.o +SOBJS-y ? ? ? ?:= lowlevel_init.o...
Quoted 1 line
+SOBJS ?:= $(SOBJS-y)
That's really a separate patch, but I guess it's fine.
I can remove it now that wamboot is in C.
Quoted 12 lines
Quoted 2 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +0
-0...
arch/arm/cpu/armv7/tegra2/warmboot.c
Quoted 3 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +3
-0+#define BCT_OFFSET ? ? ? ? ? ? 0x100 ? ? ? ? ?/* BCT starts at 0x100 */ +#define BCT_SDRAM_PARAMS_OFFSET ? ? ? ?(BCT_OFFSET + 0x88) +#define SDRAM_PARAMS_BASE ? ? ?(AP20_BASE_PA_SRAM + BCT_SDRAM_PARAMS_OFFSET)
BCT_OFFSETis where the BCT is stored within some warmboot-specific memory location. I think the comment should be explicit about this, because IIRC the BCT starts at offset 0 within the (cold) boot flash memory, so the comment is confusing until you trace through the code and find whatSDRAM_PARAMS_BASEis used for.
OK, I think I can just remove those first two defines.
Quoted 14 lines
arch/arm/cpu/armv7/tegra2/warmboot.c
Quoted 11 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +10
-0+/* +* NOTE: If more than one of the following is enabled, only one of them will +* ? ? ?actually be used. RANDOM takes precedence over PATTERN and ZERO, and +* ? ? ?PATTERN takes precedence overy ZERO. +* +* ? ? ?RANDOM_AES_BLOCK_IS_PATTERN is to define a 32-bit PATTERN. +*/ +#define RANDOM_AES_BLOCK_IS_RANDOM ? ?/* to randomize the header */ +#undef RANDOM_AES_BLOCK_IS_PATTERN ? ?/* to patternize the header */ +#undef RANDOM_AES_BLOCK_IS_ZERO ? ? ? ? ? ? ? ?/* to clear the header */ Why not just used ifdefs to make sure that only (and exactly) one of these is defined?
OK
Quoted 12 lines
arch/arm/cpu/armv7/tegra2/warmboot.c line 323
Quoted 6 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +5
-0+/* Currently, this routine returns a 32-bit all 0 seed. */ +static u32 query_random_seed (void ) +{ + ? ? ? return 0; +}So the random option isn't really implemented at all. Perhaps just remove it completely; if someone wants it, they have to implement this function for it to be useful anyway, so adding the call to the function at the same time seems reasonable enough?
Quoted 2 lines
If not, at least make this print something at run-time so it's obvious it isn't really working.
Well I think I'll just punt this stuff.
Quoted 13 lines
Quoted 2 lines
+int
warmboot_prepare_code(u32 seg_address, u32 seg_length)...
Quoted 9 lines
+ ? ? ? /*
+ ? ? ? ?* The region specified byseg_addressmust not be in IRAM and must be
+ ? ? ? ?* nonzero in length.
+ ? ? ? ?*/
+ ? ? ? if ((seg_length== 0) || (seg_address== 0) ||
+ ? ? ? ? ? (seg_address>=AP20_BASE_PA_SRAM)) {
+ ? ? ? ? ? ? ? err =-EFAULT;
+ ? ? ? ? ? ? ? goto fail;
+ ? ? ? }
Quoted 6 lines
The IRAM check only validates that the address isn't at, within, or after the IRAM location, which doesn't exactly match the comment. If the restriction is "within" IRAM, the end address needs to be checked too. Isn't the real restriction that the address needs to be within SDRAM though? If so, it seems better to check that directly.
Done
Quoted 14 lines
...
Quoted 13 lines
+ ? ? ? /* Populate the
random_aes_blockas requested. */
+ ? ? ? {
+ ? ? ? ? ? ? ? u32*aes_block= (u32 *)&(dst_header->random_aes_block);
+ ? ? ? ? ? ? ? u32 *end = (u32 *)(((u32)aes_block) +
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(dst_header->random_aes_block));arch/arm/cpu/armv7/tegra2/warmboot.c +8
-0+ + ? ? ? ? ? ? ? do { +#if defined(RANDOM_AES_BLOCK_IS_RANDOM) + ? ? ? ? ? ? ? ? ? ? ? *aes_block++ = query_random_seed(); +#elif defined(RANDOM_AES_BLOCK_IS_PATTERN) + ? ? ? ? ? ? ? ? ? ? ? *aes_block++ = RANDOM_AES_BLOCK_IS_PATTERN; +#elif defined(RANDOM_AES_BLOCK_IS_ZERO) + ? ? ? ? ? ? ? ? ? ? ? *aes_block++ = 0;
Quoted 8 lines
arch/arm/cpu/armv7/tegra2/warmboot.c
Quoted 5 lines
arch/arm/cpu/armv7/tegra2/warmboot.c +5
-0+#else + ? ? ? ? ? ? ? ? ? ? ? printf("None of RANDOM_AES_BLOCK_IS_XXX is defined; "); + ? ? ? ? ? ? ? ? ? ? ? printf("Default to pattern 0.\n"); + ? ? ? ? ? ? ? ? ? ? ? *aes_block++ = 0; +#endif Why not issue a compile error so the person who configured U-Boot is immediately aware of the problem, instead of delaying the issue to run-time?
Will punt this.
Quoted 28 lines
Quoted 5 lines
+ ? ? ? ? ? ? ? } while (
aes_block< end);
+ ? ? ? }arch/arm/cpu/armv7/tegra2/warmboot_avp.c +0
-0...
Quoted 22 lines
arch/arm/cpu/armv7/tegra2/warmboot_avp.c +22
-0+void wb_start (void ) +{ + ? ? ? struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + ? ? ? struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; + ? ? ? struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + ? ? ? struct clk_rst_ctlr *clkrst = + ? ? ? ? ? ? ? ? ? ? ? (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + ? ? ? union osc_ctrl_reg osc_ctrl; + ? ? ? union pllx_base_reg pllx_base; + ? ? ? union pllx_misc_reg pllx_misc; + ? ? ? union scratch3_reg scratch3; + ? ? ? u32 reg; + + ? ? ? /* enable JTAG & TBE */ + ? ? ? writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, &pmt->pmt_cfg_ctl); + + ? ? ? /* Are we running where we're supposed to be? */ + ? ? ? asm volatile ( + ? ? ? ? ? ? ? "adr ? ?%0, wb_start;" ?/* reg: wb_start address */ + ? ? ? ? ? ? ? : "=r"(reg) ? ? ? ? ? ? /* output */ + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* no input, no clobber list */ + ? ? ? );
Quoted 8 lines
Quoted 3 lines
+
+ ? ? ? if (reg !=AP20_WB_RUN_ADDRESS)
+ ? ? ? ? ? ? ? gotodo_reset;Does that code actually work; for it to work, the code would need to be either explicitly compile PIC (position independent) or accidentally be synthesized to code that happens to be PIC (not sure that's possible/likely).
ARM is normally PIC unless you try hard.
Quoted 8 lines
Quoted 6 lines
+ ? ? ? /* Set the drive strength */
+ ? ? ? osc_ctrl.word =readl(&clkrst->crc_osc_ctrl);
+ ? ? ? osc_ctrl.xofs = 4;
+ ? ? ? osc_ctrl.xoe = 1;
+ ? ? ?writel(osc_ctrl.word, &clkrst->crc_osc_ctrl);Isn't that board-specific?
If so it currently works on all boards.
Quoted 3 lines
Shouldn't the code save the old value during suspend, and restore it later or something like that, or be a board-specific #define?
Maybe, but I'm not aware of any differences. Perhaps something to look at later if it is needed? I will add a TODO.
Quoted 7 lines
A general question: How much does this all depend on specific interactions with the kernel? Does the kernel have to follow some specific protocol during suspend to make this all work? In mainline, there's no suspend support in Tegra, so I'm slightly worried that when it gets upstreamed, this code might need changes to address any review comments there?
My limited understanding is that U-Boot's bit has a clear and small responsibility to get the memory and CPU clocks running so that the A9 cores start up again, and it is up to Linux to take it from there.
Both the code to save the info and restore it are in U-Boot. There may be some gotchas when the kernel stuff goes upstream, not sure.
Quoted 16 lines
Quoted 2 lines
arch/arm/include/asm/arch-tegra2/warmboot.h +0
-0...
arch/arm/include/asm/arch-tegra2/warmboot.h
Quoted 11 lines
arch/arm/include/asm/arch-tegra2/warmboot.h +11
-0+/* +* Defines the code header information for the boot rom. +* +* The code immediately follows the code header. +* +* Note that the code header needs to be 16 bytes aligned to preserve +* the alignment of relevant data for hash and decryption computations without +* requiring extra copies to temporary memory areas. +*/ +struct wb_header { + ? ? ? u32 length_in_secure; ? /* length of the code header */I assume s/in_secure/insecure/ ?
Seems likely to me, will change it.
Quoted 10 lines
Quoted 9 lines
+ ? ? ? u32 reserved[3];
+ ? ? ? struct hash hash; ? ? ? /* hash of header+code, starts next field*/
+ ? ? ? struct hashrandom_aes_block; ? /* a data block to aid security. */
+ ? ? ? u32length_secure; ? ? ?/* length of the code header */
+ ? ? ? u32 destination; ? ? ? ?/* destination address to put the wb code */
+ ? ? ? u32entry_point; ? ? ? ?/* execution address of the wb code */
+ ? ? ? u32code_length; ? ? ? ?/* length of the code */
+};
Quoted 2 lines
--
nvpublic
Regards,
Simon
PATCH 9/14 tegra: Add warmboot implementation
Hi Simon,
Quoted 35 lines · Simon Glass
Hi Stephen,
[Yen please can you read this also?]
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
From: Yen Lin <[email protected]>
Add code to set up the warm boot area in the Tegra CPU ready for a resume after suspend.
Quoted 8 lines
Quoted 1 line
Signed-off-by Simon Glass <[email protected]>How come Yen's S-o-b line is missing here?
As a general comment on this patch, it contains a lot of structure definitions and defines that should really be part of the clock module's headers and similar; why not just included the clock headers and place all the definitions in those headers if they aren't already there?
Yes this bit of it got a pretty light review at the time and I was reluctant to press on the bitfields when that side of things was still up in the air. No functions exist to access these things and using the
clk_rst.hheader adds a mountain of ugly reg &OSC_FREQ_MASK) >>OSC_FREQ_SHIFTto the code. I am still uncomfortable with how this sort of thing is done in U-Boot.Also the AVP code cannot call functions in
clock.c(they are in SDRAM which isn't on yet), so we need the structures or some sort of access there anyway.I will tidy up some low-hanging fruit in
warmboot.cbut don't know that I can do much withwarmboot_avp.c. At least it isn't assembler anymore!
Quoted 7 lines
But there a few questions here. Firstly it seems that it saves some memory speed info to scratch2 but never restores it. Then it restores CPU speed from scratch3 but I can't see where it saves it. Does Yen have any comments on that? Apparently it works because we have been using it, but... If it is saving things that are never restored I could dump that and reduce the code size.
U-boot code saves sdram parameters to scratch2, scratch4, and scratch 24 registers, so when system resumes, bootrom can restore sdram parameters from these registers.
The scratch3 register content was saved by kernel before suspend, and is used by the warmboot code to restore PLLX settings.
Regards,
Yen
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
PATCH 9/14 tegra: Add warmboot implementation
Hi Yen,
Quoted 46 lines · Yen Lin
Hi Simon,
Quoted 35 lines · Simon Glass
Hi Stephen,
[Yen please can you read this also?]
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
From: Yen Lin <[email protected]>
Add code to set up the warm boot area in the Tegra CPU ready for a resume after suspend.
Quoted 8 lines
Quoted 1 line
Signed-off-by Simon Glass <[email protected]>How come Yen's S-o-b line is missing here?
As a general comment on this patch, it contains a lot of structure definitions and defines that should really be part of the clock module's headers and similar; why not just included the clock headers and place all the definitions in those headers if they aren't already there?
Yes this bit of it got a pretty light review at the time and I was reluctant to press on the bitfields when that side of things was still up in the air. No functions exist to access these things and using the
clk_rst.hheader adds a mountain of ugly reg &OSC_FREQ_MASK) >>OSC_FREQ_SHIFTto the code. I am still uncomfortable with how this sort of thing is done in U-Boot.Also the AVP code cannot call functions in
clock.c(they are in SDRAM which isn't on yet), so we need the structures or some sort of access there anyway.I will tidy up some low-hanging fruit in
warmboot.cbut don't know that I can do much withwarmboot_avp.c. At least it isn't assembler anymore!Quoted 7 lines
But there a few questions here. Firstly it seems that it saves some memory speed info to scratch2 but never restores it. Then it restores CPU speed from scratch3 but I can't see where it saves it. Does Yen have any comments on that? Apparently it works because we have been using it, but... If it is saving things that are never restored I could dump that and reduce the code size.
Quoted 6 lines
U-boot code saves sdram parameters to scratch2, scratch4, and scratch 24 registers, so when system resumes, bootrom can restore sdram parameters from these registers.
The scratch3 register content was saved by kernel before suspend, and is used by the warmboot code to restore PLLX settings.
Thanks for the info.
On resume I do not see it using scratch2, 4 or 24 within U-Boot. Are those used in the kernel?
I should add something to document this so the kernel people can match up when that side of it goes up stream.
Regards,
Simon
Quoted 13 lines
Regards,
Yen
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain confidential information. ?Any unauthorized review, use, disclosure or distribution is prohibited. ?If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
PATCH 9/14 tegra: Add warmboot implementation
Quoted 4 lines · Simon Glass
Quoted 3 lines · Yen Lin
Quoted 2 lines · Simon Glass
Quoted 1 line · Stephen Warren
On 12/26/2011 12:33 PM, Simon Glass wrote:
...
Quoted 12 lines
Quoted 12 lines
Quoted 7 lines
But there a few questions here. Firstly it seems that it saves some memory speed info to scratch2 but never restores it. Then it restores CPU speed from scratch3 but I can't see where it saves it. Does Yen have any comments on that? Apparently it works because we have been using it, but... If it is saving things that are never restored I could dump that and reduce the code size.
U-boot code saves sdram parameters to scratch2, scratch4, and scratch 24 registers, so when system resumes, bootrom can restore sdram parameters from these registers.
Quoted 7 lines
Quoted 2 lines
The scratch3 register content was saved by kernel before suspend, and is used by the warmboot code to restore PLLX settings.
Thanks for the info.
On resume I do not see it using scratch2, 4 or 24 within U-Boot. Are those used in the kernel?
The Tegra boot ROM (which contains the power-on code for the AVP) is what interprets these, according to Yen above.
One question for Yen: Why doesn't the boot ROM read the SDRAM parameters from the BCT like it does during a cold boot? Perhaps there's some interaction with clock settings, so the boot ROM needs to know the clock/voltage/... state the kernel was in when suspending, rather than just using the "usual" cold boot settings?
Quoted 2 lines
I should add something to document this so the kernel people can match up when that side of it goes up stream.
Signature · 1 line
nvpublic
PATCH 9/14 tegra: Add warmboot implementation
Quoted 26 lines · Stephen Warren
Quoted 4 lines · Simon Glass
Quoted 3 lines · Yen Lin
Quoted 2 lines · Simon Glass
Quoted 1 line · Stephen Warren
On 12/26/2011 12:33 PM, Simon Glass wrote:
...
Quoted 12 lines
Quoted 12 lines
Quoted 7 lines
But there a few questions here. Firstly it seems that it saves some memory speed info to scratch2 but never restores it. Then it restores CPU speed from scratch3 but I can't see where it saves it. Does Yen have any comments on that? Apparently it works because we have been using it, but... If it is saving things that are never restored I could dump that and reduce the code size.
U-boot code saves sdram parameters to scratch2, scratch4, and scratch 24 registers, so when system resumes, bootrom can restore sdram parameters from these registers.
Quoted 7 lines
Quoted 2 lines
The scratch3 register content was saved by kernel before suspend, and is used by the warmboot code to restore PLLX settings.
Thanks for the info.
On resume I do not see it using scratch2, 4 or 24 within U-Boot. Are those used in the kernel?
Quoted 9 lines
The Tegra boot ROM (which contains the power-on code for the AVP) is what interprets these, according to Yen above.
One question for Yen: Why doesn't the boot ROM read the SDRAM parameters from the BCT like it does during a cold boot? Perhaps there's some interaction with clock settings, so the boot ROM needs to know the clock/voltage/... state the kernel was in when suspending, rather than just using the "usual" cold boot settings?
This is to reduce latency. During resume, Bootrom will not read BCT (from SPI or EMMC) to set SDRAM parameters. Instead, it reads directly from those scratch registers to set SDRAM.
Quoted 3 lines
Quoted 2 lines
I should add something to document this so the kernel people can match up when that side of it goes up stream.
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
PATCH 10/14 tegra: Setup PMC scratch info from ap20 setup
In reply to Simon GlassFrom: Yen Lin <[email protected]>
Save SDRAM parameters into the warmboot scratch registers
--- arch/arm/cpu/armv7/tegra2/ap20.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
arch/arm/cpu/armv7/tegra2/ap20.c +6 -0
@@ -30,6 +30,7 @@#include <asm/arch/pmc.h> #include <asm/arch/pinmux.h> #include <asm/arch/scu.h> +#include <asm/arch/warmboot.h> #include <common.h> int tegra_get_chip_type (void )
@@ -310,6 +311,11 @@ void init_pmc_scratch(void)/* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ writel (CONFIG_SYS_BOARD_ODMDATA , &pmc->pmc_scratch20); + +#ifdef CONFIG_TEGRA2_LP0 +/* save Sdram params to PMC 2, 4, and 24 for WB0 */ +warmboot_save_sdram_params (); +#endif }void tegra2_start (void )
Signature · 1 line
1.7.3.1
PATCH 11/14 tegra: Set up warmboot code on Nvidia boards
In reply to Simon GlassCall the function to put warmboot boot in a suitable place for resume.
--- board/nvidia/common/board.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
board/nvidia/common/board.c +5 -0
@@ -34,6 +34,7 @@#include <asm/arch/pmc.h> #include <asm/arch/pmu.h> #include <asm/arch/uart.h> +#include <asm/arch/warmboot.h> #include <spi.h> #include <asm/arch/usb.h> #include <i2c.h>
@@ -83,6 +84,10 @@ int board_init(void)board_usb_init (gd->fdt_blob);#endif +#ifdef CONFIG_TEGRA2_LP0 +/* prepare the WB code to LP0 location */ +warmboot_prepare_code (TEGRA_LP0_ADDR ,TEGRA_LP0_SIZE ); +#endif #ifdef CONFIG_TEGRA2_I2C i2c_init_board ();
Signature · 1 line
1.7.3.1
PATCH 12/14 tegra: Set vdd_core and vdd_cpu to high
In reply to Simon GlassFrom: Jimmy Zhang <[email protected]>
At cold boot, the default voltage supplied by pmu is not high enough to support emc to run at its highest clock frequency. The code added here is to update the default vdd_core and vdd_cpu to higher values.
(Sorry if I have mangled this comment)
--- board/nvidia/common/board.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
board/nvidia/common/board.c +18 -0
@@ -30,6 +30,7 @@#include <asm/arch/board.h> #include <asm/arch/clk_rst.h> #include <asm/arch/clock.h> +#include <asm/arch/fuse.h> #include <asm/arch/pinmux.h> #include <asm/arch/pmc.h> #include <asm/arch/pmu.h>
@@ -56,6 +57,21 @@ int timer_init(void) }/* +* Routine: power_det_init +* Description: turn off power detects +*/ +static void power_det_init (void ) +{ +#if defined(CONFIG_TEGRA2 ) +struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE ; + +/* turn off power detects */ +writel (0 , &pmc->pmc_pwr_det_latch); +writel (0 , &pmc->pmc_pwr_det); +#endif +} + +/* * Routine: board_init * Description: Early hardware init. */
@@ -88,6 +104,8 @@ int board_init(void)/* prepare the WB code to LP0 location */ warmboot_prepare_code (TEGRA_LP0_ADDR ,TEGRA_LP0_SIZE );#endif + +power_det_init ();#ifdef CONFIG_TEGRA2_I2C i2c_init_board ();
Signature · 1 line
1.7.3.1
PATCH 12/14 tegra: Set vdd_core and vdd_cpu to high
Quoted 7 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
At cold boot, the default voltage supplied by pmu is not high enough to support emc to run at its highest clock frequency. The code added here is to update the default
vdd_coreandvdd_cputo higher values.(Sorry if I have mangled this comment)
?? Remove that last line?
I thought this issue only affected the T25 SKU when coupled with a particular voltage regulator that wasn't reprogrammed to explicitly support T25. Hence, shouldn't this code only be enabled for specific boards?
Quoted 1 line
board/nvidia/common/board.c +0
-0
...
Quoted 4 lines
/*
+ * Routine:power_det_init
+ * Description: turn off power detects
+ */
board/nvidia/common/board.c int timer_init(void) · line 72
Quoted 10 lines
board/nvidia/common/board.c +10
-0+static void power_det_init (void ) +{ +#if defined(CONFIG_TEGRA2 ) +struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE ; + +/* turn off power detects */ +writel (0 , &pmc->pmc_pwr_det_latch); +writel (0 , &pmc->pmc_pwr_det); +#endif +}
I can't tell how that code relates to the commit description.
Signature · 1 line
nvpublic
PATCH 12/14 tegra: Set vdd_core and vdd_cpu to high
Hi Stephen,
Quoted 10 lines · Stephen Warren
Quoted 7 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
At cold boot, the default voltage supplied by pmu is not high enough to support emc to run at its highest clock frequency. The code added here is to update the default
vdd_coreandvdd_cputo higher values.(Sorry if I have mangled this comment)
?? Remove that last line?
Actually that is the truth! Unfortunately this commit originally brought in the whole PMU and assorted other things in one big patch. I split those things out in this series, and I think this may actually relate to something else.
Quoted 7 lines
I thought this issue only affected the T25 SKU when coupled with a particular voltage regulator that wasn't reprogrammed to explicitly support T25. Hence, shouldn't this code only be enabled for specific boards?
Quoted 1 line
board/nvidia/common/board.c +0
-0...
Quoted 16 lines
Quoted 4 lines
?/*
+ * Routine:power_det_init
+ * Description: turn off power detects
+ */board/nvidia/common/board.c int timer_init(void) · line 72
Quoted 10 lines
board/nvidia/common/board.c +10
-0+static void power_det_init (void ) +{ +#if defined(CONFIG_TEGRA2 ) + ? ? struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; + + ? ? /* turn off power detects */ + ? ? writel(0, &pmc->pmc_pwr_det_latch); + ? ? writel(0, &pmc->pmc_pwr_det); +#endif +}I can't tell how that code relates to the commit description.
Neither could I, hence my comment. But I think I just made a mistake - I have been back through the commits and actually I think it should be:
Tegra core power rail has leakage voltage around 0.2V while system in suspend mode. The source of the leakage should be coming from PMC
power detect
logic for IO rails power detection.
That can be disabled by writing a '0' to PWR_DET_LATCH followed by
writing '0'
to PWR_DET (APBDEV_PMC_PWR_DET_0).
so I will change it.
Regards,
Simon
Quoted 3 lines
--
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
In reply to Simon GlassFrom: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
--- board/nvidia/common/Makefile | 1 + board/nvidia/common/board.c | 4 + board/nvidia/common/emc.c | 295 ++++++++++++++++++++++++++++++++++++++++++ board/nvidia/common/emc.h | 29 ++++ 4 files changed, 329 insertions(+), 0 deletions(-) create mode 100644 board/nvidia/common/emc.c create mode 100644 board/nvidia/common/emc.h
board/nvidia/common/Makefile +1 -0
@@ -27,6 +27,7 @@ LIB = $(obj)lib$(VENDOR).o COBJS-y += board.o COBJS-$(CONFIG_SPI_UART_SWITCH) += uart-spi-switch.o +COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o COBJS := $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
board/nvidia/common/board.c +4 -0
@@ -30,6 +30,7 @@#include <asm/arch/board.h> #include <asm/arch/clk_rst.h> #include <asm/arch/clock.h> +#include <asm/arch/emc.h> #include <asm/arch/fuse.h> #include <asm/arch/pinmux.h> #include <asm/arch/pmc.h>
@@ -40,6 +41,7 @@#include <asm/arch/usb.h> #include <i2c.h> #include "board.h" +#include "emc.h" DECLARE_GLOBAL_DATA_PTR ;
@@ -111,6 +113,8 @@ int board_init(void)#ifdef CONFIG_TEGRA_PMU pmu_set_nominal (); + +board_emc_init ();#endif #endif
board/nvidia/common/emc.c new file +295 -0
295 lines not on this page · raw message
board/nvidia/common/emc.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +* Copyright (c) 2011 The Chromium OS Authors. +* (C) Copyright 2010,2011 NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* 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; either version 2 of +* the License, or (at your option) any later version. +* +* 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., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#ifndef _NVIDIA_EMC_H_ +#define _NVIDIA_EMC_H_ + +int board_emc_init (void ); + +#endif
Signature · 1 line
1.7.3.1
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Quoted 8 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
Signed-off-by Simon Glass <[email protected]>board/nvidia/common/emc.c +0
-0
...
Quoted 1 line
+static const struct
tegra_emc_tableseaboard_emc_tables_hynix_333Mhz[] = {
...
Quoted 1 line
+static const struct
tegra_emc_tableseaboard_emc_tables_hynix_380Mhz[] = {
...
Quoted 1 line
+void
seaboard_emc_init(void)
...
board/nvidia/common/emc.c line 273
Quoted 10 lines
board/nvidia/common/emc.c +10
-0+static struct emc_init board_table[] = { + { + .id =MACH_TYPE_HARMONY , + .init =NULL , + }, + { + .id =MACH_TYPE_SEABOARD , + .init = seaboard_emc_init, + }, +};
Why not just put the Seaboard-specific code into Seaboard's board directory instead of a common location? Then you wouldn't need this table at all, and boards other than Seaboard wouldn't be required to carry the Seaboard EMC tables.
There don't appear to be any tables for Harmony, which is inconsistent with the commit description.
board/nvidia/common/emc.c line 284
Quoted 10 lines
board/nvidia/common/emc.c +10
-0+int board_emc_init (void ) +{ +int i; +DECLARE_GLOBAL_DATA_PTR ; + +#ifdef CONFIG_TEGRA_PMU +/* if voltage has not been set properly, return */ +if (!pmu_is_voltage_nominal ()) +return -1 ; +#endif
Why/when would the PMU voltage not be nominal?
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
Finally, I don't think there are EMC tables here for all the EMC frequencies that we have BCTs for. Perhaps that's not an issue, and perhaps I should ignore the other BCTs (e.g. 400MHZ EMC) since nobody actually uses them?
Signature · 1 line
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Hi Stephen,
Quoted 16 lines · Stephen Warren
Quoted 8 lines · Simon Glass
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
Signed-off-by Simon Glass <[email protected]>board/nvidia/common/emc.c +0
-0...
Quoted 1 line
+static const struct
tegra_emc_tableseaboard_emc_tables_hynix_333Mhz[] = {...
Quoted 1 line
+static const struct
tegra_emc_tableseaboard_emc_tables_hynix_380Mhz[] = {...
Quoted 1 line
+void
seaboard_emc_init(void)...
Quoted 15 lines
board/nvidia/common/emc.c
Quoted 10 lines
board/nvidia/common/emc.c +10
-0+static struct emc_init board_table[] = { + ? ? ? { + ? ? ? ? ? ? ? .id ? ? = MACH_TYPE_HARMONY, + ? ? ? ? ? ? ? .init ? = NULL, + ? ? ? }, + ? ? ? { + ? ? ? ? ? ? ? .id ? ? = MACH_TYPE_SEABOARD, + ? ? ? ? ? ? ? .init ? = seaboard_emc_init, + ? ? ? }, +};Why not just put the Seaboard-specific code into Seaboard's board directory instead of a common location? Then you wouldn't need this table at all, and boards other than Seaboard wouldn't be required to carry the Seaboard EMC tables.
I have moved this into the device tree.
Quoted 2 lines
There don't appear to be any tables for Harmony, which is inconsistent with the commit description.
Updated the commit description :-)
Quoted 13 lines
board/nvidia/common/emc.c line 284
Quoted 11 lines
board/nvidia/common/emc.c +10
-0+int board_emc_init (void ) +{ + ? ? ? int ? ? i; + ? ? ? DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_TEGRA_PMU + ? ? ? /* if voltage has not been set properly, return */ + ? ? ? if (!pmu_is_voltage_nominal()) + ? ? ? ? ? ? ? return -1; +#endif Why/when would the PMU voltage not be nominal?
On boot, it starts up lower and we raise it to nominal so we can run at full speed.
Quoted 4 lines
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
I don't think so, since we can't know in U-Boot what the start-up voltages are.
Quoted 4 lines
Finally, I don't think there are EMC tables here for all the EMC frequencies that we have BCTs for. Perhaps that's not an issue, and perhaps I should ignore the other BCTs (e.g. 400MHZ EMC) since nobody actually uses them?
Yes I think maximum speed is all anyone is probably interested in now.
Regards,
Simon
Quoted 3 lines
--
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Simon Glass wrote at Thursday, January 12, 2012 4:05 PM:
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
Quoted 4 lines
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
...
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
board/nvidia/common/emc.c new file +4
-0+int board_emc_init (void ) +{ + ? ? ? int ? ? i; + ? ? ? DECLARE_GLOBAL_DATA_PTR;Quoted 8 lines
board/nvidia/common/emc.c line 284
Quoted 6 lines
board/nvidia/common/emc.c new file +6
-0+ +#ifdef CONFIG_TEGRA_PMU + ? ? ? /* if voltage has not been set properly, return */ + ? ? ? if (!pmu_is_voltage_nominal()) + ? ? ? ? ? ? ? return -1; +#endif Why/when would the PMU voltage not be nominal?
Quoted 8 lines
On boot, it starts up lower and we raise it to nominal so we can run at full speed.
Quoted 3 lines
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
I don't think so, since we can't know in U-Boot what the start-up voltages are.
So how does the system get to the nominal state? And if board_emc_init() is called when the system isn't in the nominal state, does it somehow get called again later once it is, so that the EMC initialization doesn't fail the error-check quoted above?
In other words, presumably U-Boot explicitly programs the PMU into the nominal stage at some point. Shouldn't we defer calling board_emc_init() until after that time, thus making that error-check redundant?
Quoted 6 lines
Quoted 4 lines
Finally, I don't think there are EMC tables here for all the EMC frequencies that we have BCTs for. Perhaps that's not an issue, and perhaps I should ignore the other BCTs (e.g. 400MHZ EMC) since nobody actually uses them?
Yes I think maximum speed is all anyone is probably interested in now.
400MHz is faster than the entries in the table in this change, IIRC. But if the tables in this change are for the standard frequencies average people use (i.e. not those doing board/memory quals), it's probably fine.
Signature · 1 line
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Hi Stephen,
Quoted 28 lines · Stephen Warren
Simon Glass wrote at Thursday, January 12, 2012 4:05 PM:
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
Quoted 4 lines
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
...
Quoted 20 lines
Quoted 4 lines
Quoted 4 lines
board/nvidia/common/emc.c new file +4
-0+int board_emc_init (void ) +{ + ? ? ? int ? ? i; + ? ? ? DECLARE_GLOBAL_DATA_PTR;Quoted 8 lines
board/nvidia/common/emc.c line 284
Quoted 6 lines
board/nvidia/common/emc.c new file +6
-0+ +#ifdef CONFIG_TEGRA_PMU + ? ? ? /* if voltage has not been set properly, return */ + ? ? ? if (!pmu_is_voltage_nominal()) + ? ? ? ? ? ? ? return -1; +#endif Why/when would the PMU voltage not be nominal?
On boot, it starts up lower and we raise it to nominal so we can run at full speed.
Quoted 3 lines
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
Quoted 6 lines
Quoted 1 line
I don't think so, since we can't know in U-Boot what the start-up voltages are.
So how does the system get to the nominal state? And if
board_emc_init()is called when the system isn't in the nominal state, does it somehow get called again later once it is, so that the EMC initialization doesn't fail the error-check quoted above?
We call board_emc_init() after pmu_set_nominal().
Quoted 4 lines
In other words, presumably U-Boot explicitly programs the PMU into the nominal stage at some point. Shouldn't we defer calling
board_emc_init()until after that time, thus making that error-check redundant?
Yes, but if you look at the patch above, that's what we do:
#ifdef CONFIG_TEGRA_PMU
pmu_set_nominal();+
+ board_emc_init();
#endif
#endif
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Finally, I don't think there are EMC tables here for all the EMC frequencies that we have BCTs for. Perhaps that's not an issue, and perhaps I should ignore the other BCTs (e.g. 400MHZ EMC) since nobody actually uses them?
Quoted 5 lines
Quoted 1 line
Yes I think maximum speed is all anyone is probably interested in now.
400MHz is faster than the entries in the table in this change, IIRC. But if the tables in this change are for the standard frequencies average people use (i.e. not those doing board/memory quals), it's probably fine.
OK, perhaps I should have said maximum speed that actually works reliably :-)
Regards,
Simon
Quoted 4 lines
--
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Simon Glass wrote at Thursday, January 12, 2012 4:55 PM:
Quoted 47 lines · Stephen Warren
Quoted 28 lines
Simon Glass wrote at Thursday, January 12, 2012 4:05 PM:
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
Quoted 4 lines
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
...
Quoted 20 lines
Quoted 4 lines
Quoted 4 lines
board/nvidia/common/emc.c new file +4
-0+int board_emc_init (void ) +{ + ? ? ? int ? ? i; + ? ? ? DECLARE_GLOBAL_DATA_PTR;Quoted 8 lines
board/nvidia/common/emc.c line 284
Quoted 6 lines
board/nvidia/common/emc.c new file +6
-0+ +#ifdef CONFIG_TEGRA_PMU + ? ? ? /* if voltage has not been set properly, return */ + ? ? ? if (!pmu_is_voltage_nominal()) + ? ? ? ? ? ? ? return -1; +#endif Why/when would the PMU voltage not be nominal?
On boot, it starts up lower and we raise it to nominal so we can run at full speed.
Quoted 3 lines
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
Quoted 6 lines
Quoted 1 line
I don't think so, since we can't know in U-Boot what the start-up voltages are.
So how does the system get to the nominal state? And if
board_emc_init()is called when the system isn't in the nominal state, does it somehow get called again later once it is, so that the EMC initialization doesn't fail the error-check quoted above?We call
board_emc_init()afterpmu_set_nominal().Quoted 4 lines
In other words, presumably U-Boot explicitly programs the PMU into the nominal stage at some point. Shouldn't we defer calling
board_emc_init()until after that time, thus making that error-check redundant?Yes, but if you look at the patch above, that's what we do:
#ifdef CONFIG_TEGRA_PMU pmu_set_nominal();
board/nvidia/common/board.c int board_init(void) · line 119
Quoted 4 lines
board/nvidia/common/board.c +2
-0+ +board_emc_init ();#endif #endif
OK, so in practice,
/* if voltage has not been set properly, return */ if (!pmu_is_voltage_nominal())
... will never fire. My original point was that if so, why is that check needed? I suppose it's a reasonable safety net though - that's the reason?
Signature · 1 line
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Hi Stephen,
Quoted 53 lines · Stephen Warren
Simon Glass wrote at Thursday, January 12, 2012 4:55 PM:
Quoted 43 lines · Stephen Warren
Quoted 28 lines
Simon Glass wrote at Thursday, January 12, 2012 4:05 PM:
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
Quoted 4 lines
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
...
Quoted 20 lines
Quoted 4 lines
Quoted 4 lines
board/nvidia/common/emc.c new file +4
-0+int board_emc_init (void ) +{ + ? ? ? int ? ? i; + ? ? ? DECLARE_GLOBAL_DATA_PTR;Quoted 8 lines
board/nvidia/common/emc.c line 284
Quoted 6 lines
board/nvidia/common/emc.c new file +6
-0+ +#ifdef CONFIG_TEGRA_PMU + ? ? ? /* if voltage has not been set properly, return */ + ? ? ? if (!pmu_is_voltage_nominal()) + ? ? ? ? ? ? ? return -1; +#endif Why/when would the PMU voltage not be nominal?
On boot, it starts up lower and we raise it to nominal so we can run at full speed.
Quoted 3 lines
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
Quoted 6 lines
Quoted 1 line
I don't think so, since we can't know in U-Boot what the start-up voltages are.
So how does the system get to the nominal state? And if
board_emc_init()is called when the system isn't in the nominal state, does it somehow get called again later once it is, so that the EMC initialization doesn't fail the error-check quoted above?We call
board_emc_init()afterpmu_set_nominal().Quoted 4 lines
In other words, presumably U-Boot explicitly programs the PMU into the nominal stage at some point. Shouldn't we defer calling
board_emc_init()until after that time, thus making that error-check redundant?Quoted 8 lines
Yes, but if you look at the patch above, that's what we do:
?#ifdef
CONFIG_TEGRA_PMU
? ? ? ?pmu_set_nominal();
+
+ ? ? ?board_emc_init();
?#endif
?#endif
Quoted 8 lines
OK, so in practice,
/* if voltage has not been set properly, return */ if (!pmu_is_voltage_nominal())
... will never fire. My original point was that if so, why is that check needed? I suppose it's a reasonable safety net though - that's the reason?
OK I see. It certainly shouldn't - it is a check that everything is well since this code is in a different file and it is possible that someone may get this wrong. If they do then the system may continue but die later in interesting ways. Still, the user has other equally complex things to worry about.
I'm happy to remove this particularly as this might become example code for other boards - what do you think?
Regards,
Simon
Quoted 4 lines
--
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Simon Glass wrote at Thursday, January 12, 2012 5:06 PM:
Quoted 63 lines · Stephen Warren
Quoted 53 lines
Simon Glass wrote at Thursday, January 12, 2012 4:55 PM:
Quoted 43 lines · Stephen Warren
Quoted 28 lines
Simon Glass wrote at Thursday, January 12, 2012 4:05 PM:
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
Quoted 4 lines
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
...
Quoted 20 lines
Quoted 4 lines
Quoted 4 lines
(quoted diff) +4
-0+int board_emc_init(void) +{ + ? ? ? int ? ? i; + ? ? ? DECLARE_GLOBAL_DATA_PTR;Quoted 8 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ +#ifdef CONFIG_TEGRA_PMU + ? ? ? /* if voltage has not been set properly, return */ + ? ? ? if (!pmu_is_voltage_nominal()) + ? ? ? ? ? ? ? return -1; +#endifWhy/when would the PMU voltage not be nominal?
On boot, it starts up lower and we raise it to nominal so we can run at full speed.
Quoted 3 lines
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
Quoted 6 lines
Quoted 1 line
I don't think so, since we can't know in U-Boot what the start-up voltages are.
So how does the system get to the nominal state? And if
board_emc_init()is called when the system isn't in the nominal state, does it somehow get called again later once it is, so that the EMC initialization doesn't fail the error-check quoted above?We call
board_emc_init()afterpmu_set_nominal().Quoted 4 lines
In other words, presumably U-Boot explicitly programs the PMU into the nominal stage at some point. Shouldn't we defer calling
board_emc_init()until after that time, thus making that error-check redundant?Quoted 8 lines
Yes, but if you look at the patch above, that's what we do:
?#ifdef
CONFIG_TEGRA_PMU
? ? ? ?pmu_set_nominal();
+
+ ? ? ?board_emc_init();
?#endif
?#endifQuoted 8 lines
OK, so in practice,
/* if voltage has not been set properly, return */ if (!pmu_is_voltage_nominal())
... will never fire. My original point was that if so, why is that check needed? I suppose it's a reasonable safety net though - that's the reason?
Quoted 8 lines
OK I see. It certainly shouldn't - it is a check that everything is well since this code is in a different file and it is possible that someone may get this wrong. If they do then the system may continue but die later in interesting ways. Still, the user has other equally complex things to worry about.
I'm happy to remove this particularly as this might become example code for other boards - what do you think?
The check itself is probably fine for the reasons you state. However, I'd suggest adjusting the comment to something more like:
This code should only be called once the PMU is operating at nominal voltage. Hence, this test should never fail. However, this prevents unpredictable failures from occurring later if this pre-condition is not met.
Signature · 1 line
nvpublic
PATCH 13/14 tegra: Add EMC settings for Seaboard, Harmony
Hi Stephen,
Quoted 73 lines · Stephen Warren
Simon Glass wrote at Thursday, January 12, 2012 5:06 PM:
Quoted 63 lines · Stephen Warren
Quoted 53 lines
Simon Glass wrote at Thursday, January 12, 2012 4:55 PM:
Quoted 43 lines · Stephen Warren
Quoted 28 lines
Simon Glass wrote at Thursday, January 12, 2012 4:05 PM:
Quoted 6 lines · Stephen Warren
Quoted 5 lines · Simon Glass
Quoted 4 lines
From: Jimmy Zhang <[email protected]>
Set Seaboard and Harmony to optimal memory settings based on the SOC in use (T20 or T25).
...
Quoted 20 lines
Quoted 4 lines
Quoted 4 lines
(quoted diff) +4
-0+int board_emc_init(void) +{ + ? ? ? int ? ? i; + ? ? ? DECLARE_GLOBAL_DATA_PTR;Quoted 8 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ +#ifdef CONFIG_TEGRA_PMU + ? ? ? /* if voltage has not been set properly, return */ + ? ? ? if (!pmu_is_voltage_nominal()) + ? ? ? ? ? ? ? return -1; +#endifWhy/when would the PMU voltage not be nominal?
On boot, it starts up lower and we raise it to nominal so we can run at full speed.
Quoted 3 lines
Can't we error out the compile if the options that cause the PMU voltage to be initialized to nominal are not set, instead of detecting this at runtime?
Quoted 6 lines
Quoted 1 line
I don't think so, since we can't know in U-Boot what the start-up voltages are.
So how does the system get to the nominal state? And if
board_emc_init()is called when the system isn't in the nominal state, does it somehow get called again later once it is, so that the EMC initialization doesn't fail the error-check quoted above?We call
board_emc_init()afterpmu_set_nominal().Quoted 4 lines
In other words, presumably U-Boot explicitly programs the PMU into the nominal stage at some point. Shouldn't we defer calling
board_emc_init()until after that time, thus making that error-check redundant?Quoted 8 lines
Yes, but if you look at the patch above, that's what we do:
?#ifdef
CONFIG_TEGRA_PMU
? ? ? ?pmu_set_nominal();
+
+ ? ? ?board_emc_init();
?#endif
?#endifQuoted 8 lines
OK, so in practice,
/* if voltage has not been set properly, return */ if (!pmu_is_voltage_nominal())
... will never fire. My original point was that if so, why is that check needed? I suppose it's a reasonable safety net though - that's the reason?
Quoted 8 lines
OK I see. It certainly shouldn't - it is a check that everything is well since this code is in a different file and it is possible that someone may get this wrong. If they do then the system may continue but die later in interesting ways. Still, the user has other equally complex things to worry about.
I'm happy to remove this particularly as this might become example code for other boards - what do you think?
Quoted 7 lines
The check itself is probably fine for the reasons you state. However, I'd suggest adjusting the comment to something more like:
This code should only be called once the PMU is operating at nominal voltage. Hence, this test should never fail. However, this prevents unpredictable failures from occurring later if this pre-condition is not met.
OK, will do.
Regards,
Simon
Quoted 4 lines
--
nvpublic
PATCH 14/14 tegra: Enable LP0 on Seaboard
In reply to Simon GlassThis enables LP0 to support suspend / resume on Seaboard.
--- include/configs/seaboard.h | 7 +++++++ include/configs/tegra2-common.h | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 0 deletions(-)
include/configs/seaboard.h +7 -0
@@ -25,6 +25,13 @@#define __CONFIG_H#include <asm/sizes.h> + +/* LP0 suspend / resume */ +#define CONFIG_TEGRA2_LP0 +#define CONFIG_AES +#define CONFIG_TEGRA_PMU +#define CONFIG_TEGRA_CLOCK_SCALING +#include "tegra2-common.h" /* Enable fdt support for Seaboard. Flash the image in u-boot-dtb.bin */
include/configs/tegra2-common.h +17 -0
@@ -26,6 +26,14 @@#include <asm/sizes.h> /* +* QUOTE(m) will evaluate to a string version of the value of the macro m +* passed in. The extra level of indirection here is to first evaluate the +* macro m before applying the quoting operator. +*/ +#define QUOTE_ (m) #m +#define QUOTE (m) QUOTE_(m) + +/* * High Level Configuration Options */ #define CONFIG_ARMCORTEXA9 /* This is an ARM V7 CPU core */
@@ -50,6 +58,15 @@#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ #define CONFIG_OF_LIBFDT /* enable passing of devicetree */ +#ifdef CONFIG_TEGRA2_LP0 +#define TEGRA_LP0_ADDR 0x1C406000 +#define TEGRA_LP0_SIZE 0x2000 +#define TEGRA_LP0_VEC \ + "lp0_vec=" QUOTE(TEGRA_LP0_SIZE) "@" QUOTE(TEGRA_LP0_ADDR) " " +#else +#define TEGRA_LP0_VEC +#endif +/* Environment */ #define CONFIG_ENV_SIZE 0x2000/* Total Size Environment */
Signature · 1 line
1.7.3.1