public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support
@ 2012-04-02 23:18 Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 01/23] fdt: Add function to locate an array in the device tree Simon Glass
                   ` (23 more replies)
  0 siblings, 24 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

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.

Also included here is support for the EMC, which allows setting the memory
timings correctly in U-Boot for maximum speed operation.

Note: sign-offs are needed from Jimmy Zhang, Wei Ni and Yen Lin.

Changes in v2:
- Add check of undocumented values in hidrev register
- Add debug() output to EMC
- Add new fdtdec_locate_array() function
- Add patch to find DVC bus number
- Check error return from pmu_set_nominal() in debug mode
- Move EMC tables to device tree
- Move structs shared between A9 and AVP into warmboot.h header file
- New patch to add low-level clock functions
- Rely on compiler to optimise out debug_print_vector()
- Remove unused crypto code
- Remove unused crypto code from crypto.c
- Removed check for nominal voltage (not needed as it is done just before)
- Split PMU code into separate TPS6586X driver
- Tidy SDRAM range check in warmboot_prepare_code()
- Tidy whitespace problems
- Use const for sbox arrays
- Use low-level clock functions in warmboot code instead of register access

Changes in v3:
- Add apb_misc.h header file in new patch
- Add better error reporting when EMC setup fails
- Add new fdtdec_next_compatible_subnode() patch
- Add new patch to put abs() in common.h
- Fix CONFIG_TEGRA_I2C define
- Move abs() macro into common.h
- Support nvidia,use-ram-code binding option for EMC
- Try to return a useful error code when EMC config fails

Jimmy Zhang (3):
  tegra: Add EMC support for optimal memory timings
  tegra: Add PMU to manage power supplies
  tegra: Add EMC settings for Seaboard

Simon Glass (14):
  fdt: Add function to locate an array in the device tree
  fdt: Add function to return next compatible subnode
  Add abs() macro to return absolute value
  i2c: Add TPS6586X driver
  tegra: Move ap20.h header into arch location
  tegra: Add functions to access low-level Osc/PLL details
  tegra: Add tegra_get_chip_type() to detect SKU
  tegra: Add header file for APB_MISC register
  tegra: Set up PMU for Nvidia boards
  tegra: Set up warmboot code on Nvidia boards
  fdt: tegra: Add EMC node to device tree
  tegra: i2c: Add function to find DVC bus
  tegra: fdt: Add EMC data for Tegra2 Seaboard
  tegra: Enable LP0 on Seaboard

Wei Ni (1):
  tegra: Turn off power detect in board init

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                 |    4 +
 arch/arm/cpu/armv7/tegra2/ap20.c                   |   44 ++-
 arch/arm/cpu/armv7/tegra2/board.c                  |    4 +-
 arch/arm/cpu/armv7/tegra2/clock.c                  |   32 +
 arch/arm/cpu/armv7/tegra2/crypto.c                 |  230 ++++++++
 arch/arm/cpu/armv7/tegra2/crypto.h                 |   36 ++
 arch/arm/cpu/armv7/tegra2/emc.c                    |  286 ++++++++++
 arch/arm/cpu/armv7/tegra2/pmu.c                    |   70 +++
 arch/arm/cpu/armv7/tegra2/warmboot.c               |  382 +++++++++++++
 arch/arm/cpu/armv7/tegra2/warmboot_avp.c           |  250 ++++++++
 arch/arm/cpu/armv7/tegra2/warmboot_avp.h           |   81 +++
 arch/arm/dts/tegra20.dtsi                          |    7 +
 .../tegra2 => include/asm/arch-tegra2}/ap20.h      |    7 +
 arch/arm/include/asm/arch-tegra2/apb_misc.h        |   36 ++
 arch/arm/include/asm/arch-tegra2/clk_rst.h         |    3 +
 arch/arm/include/asm/arch-tegra2/clock.h           |   22 +
 arch/arm/include/asm/arch-tegra2/emc.h             |  113 ++++
 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      |   73 +++
 arch/arm/include/asm/arch-tegra2/pmu.h             |   30 +
 arch/arm/include/asm/arch-tegra2/sdram_param.h     |  148 +++++
 arch/arm/include/asm/arch-tegra2/tegra2.h          |   25 +
 arch/arm/include/asm/arch-tegra2/tegra_i2c.h       |    7 +
 arch/arm/include/asm/arch-tegra2/warmboot.h        |  150 +++++
 board/nvidia/common/Makefile                       |    1 +
 board/nvidia/common/board.c                        |   41 ++-
 board/nvidia/common/emc.c                          |   53 ++
 board/nvidia/common/emc.h                          |   29 +
 board/nvidia/dts/tegra2-seaboard.dts               |   72 +++
 drivers/i2c/tegra_i2c.c                            |   14 +
 drivers/power/Makefile                             |    1 +
 drivers/power/tps6586x.c                           |  280 +++++++++
 include/aes.h                                      |   70 +++
 include/common.h                                   |   13 +
 include/configs/seaboard.h                         |    8 +
 include/configs/tegra2-common.h                    |   17 +
 include/fdtdec.h                                   |   38 ++
 include/tps6586x.h                                 |   68 +++
 lib/Makefile                                       |    1 +
 lib/aes.c                                          |  598 ++++++++++++++++++++
 lib/fdtdec.c                                       |   28 +
 42 files changed, 3443 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/apb_misc.h
 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 drivers/power/tps6586x.c
 create mode 100644 include/aes.h
 create mode 100644 include/tps6586x.h
 create mode 100644 lib/aes.c

-- 
1.7.7.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 01/23] fdt: Add function to locate an array in the device tree
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 02/23] fdt: Add function to return next compatible subnode Simon Glass
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

fdtdec_locate_array() locates an integer array but does not copy it. This
saves the caller having to allocated wasted space.

Access to array elements should be through the fdt32_to_cpu() macro.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Add new fdtdec_locate_array() function

 include/fdtdec.h |   19 +++++++++++++++++++
 lib/fdtdec.c     |   11 +++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/include/fdtdec.h b/include/fdtdec.h
index 171c628..84f0768 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -272,6 +272,25 @@ int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
 		u32 *array, int count);
 
 /**
+ * Look up a property in a node and return a pointer to its contents as a
+ * unsigned int array of given length. The property must have at least enough
+ * data for the array ('count' cells). It may have more, but this will be
+ * ignored. The data is not copied.
+ *
+ * Note that you must access elements of the array with fdt32_to_cpu(),
+ * since the elements will be big endian even on a little endian machine.
+ *
+ * @param blob		FDT blob
+ * @param node		node to examine
+ * @param prop_name	name of property to find
+ * @param count		number of array elements
+ * @return pointer to array if found, or NULL if the property is not
+ *		found or there is not enough data
+ */
+const u32 *fdtdec_locate_array(const void *blob, int node,
+			       const char *prop_name, int count);
+
+/**
  * Look up a boolean property in a node and return it.
  *
  * A boolean properly is true if present in the device tree and false if not
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index bdec1a0..4a5ab71 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -363,6 +363,17 @@ int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
 	return err;
 }
 
+const u32 *fdtdec_locate_array(const void *blob, int node,
+			       const char *prop_name, int count)
+{
+	const u32 *cell;
+	int err;
+
+	cell = get_prop_check_min_len(blob, node, prop_name,
+				      sizeof(u32) * count, &err);
+	return err ? NULL : cell;
+}
+
 int fdtdec_get_bool(const void *blob, int node, const char *prop_name)
 {
 	const s32 *cell;
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 02/23] fdt: Add function to return next compatible subnode
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 01/23] fdt: Add function to locate an array in the device tree Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 03/23] Add abs() macro to return absolute value Simon Glass
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

We need to iterate through subnodes of a parent, looking only at
compatible nodes. Add a utility function to do this for us.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Add new fdtdec_next_compatible_subnode() patch

 include/fdtdec.h |   17 +++++++++++++++++
 lib/fdtdec.c     |   15 +++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/include/fdtdec.h b/include/fdtdec.h
index 84f0768..0351a25 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -117,6 +117,23 @@ int fdtdec_next_compatible(const void *blob, int node,
 		enum fdt_compat_id id);
 
 /**
+ * Find the next compatible subnode for a peripheral.
+ *
+ * Do the first call with node set to the parent and depth = 0. This
+ * function will return the offset of the next compatible node. Next time
+ * you call this function, pass the node value returned last time, with
+ * depth unchanged, and the next node will be provided.
+ *
+ * @param blob		FDT blob to use
+ * @param node		Start node for search
+ * @param id		Compatible ID to look for (enum fdt_compat_id)
+ * @param depthp	Current depth (set to 0 before first call)
+ * @return offset of next compatible node, or -FDT_ERR_NOTFOUND if no more
+ */
+int fdtdec_next_compatible_subnode(const void *blob, int node,
+		enum fdt_compat_id id, int *depthp);
+
+/**
  * Look up an address property in a node and return it as an address.
  * The property must hold either one address with no trailing data or
  * one address with a length. This is only tested on 32-bit machines.
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 4a5ab71..76d3808 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -133,6 +133,21 @@ int fdtdec_next_compatible(const void *blob, int node,
 	return fdt_node_offset_by_compatible(blob, node, compat_names[id]);
 }
 
+int fdtdec_next_compatible_subnode(const void *blob, int node,
+		enum fdt_compat_id id, int *depthp)
+{
+	do {
+		node = fdt_next_node(blob, node, depthp);
+	} while (*depthp > 1);
+
+	/* If this is a direct subnode, and compatible, return it */
+	if (*depthp == 1 && 0 == fdt_node_check_compatible(
+						blob, node, compat_names[id]))
+		return node;
+
+	return -FDT_ERR_NOTFOUND;
+}
+
 int fdtdec_next_alias(const void *blob, const char *name,
 		enum fdt_compat_id id, int *upto)
 {
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 03/23] Add abs() macro to return absolute value
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 01/23] fdt: Add function to locate an array in the device tree Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 02/23] fdt: Add function to return next compatible subnode Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver Simon Glass
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

This macro is generally useful to make it available in common.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Add new patch to put abs() in common.h

 include/common.h |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/include/common.h b/include/common.h
index 74d9704..92eac2c 100644
--- a/include/common.h
+++ b/include/common.h
@@ -229,6 +229,19 @@ ulong timer_get_boot_us(void);
 #define MIN(x, y)  min(x, y)
 #define MAX(x, y)  max(x, y)
 
+/*
+ * Return the absolute value of a number. This handles unsigned ints, shorts
+ * and chars and returns a signed long.
+ */
+#define abs(x) ({					\
+		long ret;				\
+		{					\
+			typeof((x)) __x = (x);		\
+			ret = (__x < 0) ? -__x : __x;	\
+		}					\
+		ret;					\
+	})
+
 #if defined(CONFIG_ENV_IS_EMBEDDED)
 #define TOTAL_MALLOC_LEN	CONFIG_SYS_MALLOC_LEN
 #elif ( ((CONFIG_ENV_ADDR+CONFIG_ENV_SIZE) < CONFIG_SYS_MONITOR_BASE) || \
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (2 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 03/23] Add abs() macro to return absolute value Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-09 21:01   ` Stephen Warren
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 05/23] Add AES crypto library Simon Glass
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

This power management chip supports battery charging and a large number
of power supplies. This initial driver only provides the ability to adjust
the two synchronous buck converters SM0 and SM1 in a stepwise manner.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Split PMU code into separate TPS6586X driver

Changes in v3:
- Move abs() macro into common.h

 drivers/power/Makefile   |    1 +
 drivers/power/tps6586x.c |  280 ++++++++++++++++++++++++++++++++++++++++++++++
 include/tps6586x.h       |   68 +++++++++++
 3 files changed, 349 insertions(+), 0 deletions(-)
 create mode 100644 drivers/power/tps6586x.c
 create mode 100644 include/tps6586x.h

diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index ead00f8..e327688 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB 	:= $(obj)libpower.o
 
 COBJS-$(CONFIG_FTPMU010_POWER)	+= ftpmu010.o
+COBJS-$(CONFIG_TPS6586X_POWER)	+= tps6586x.o
 COBJS-$(CONFIG_TWL4030_POWER)	+= twl4030.o
 COBJS-$(CONFIG_TWL6030_POWER)	+= twl6030.o
 
diff --git a/drivers/power/tps6586x.c b/drivers/power/tps6586x.c
new file mode 100644
index 0000000..f3f2ec6
--- /dev/null
+++ b/drivers/power/tps6586x.c
@@ -0,0 +1,280 @@
+/*
+ * 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 <tps6586x.h>
+#include <asm/io.h>
+#include <i2c.h>
+
+static int bus_num;		/* I2C bus we are on */
+#define I2C_ADDRESS		0x34	/* chip requires this address */
+static char inited;		/* 1 if we have been inited */
+
+enum {
+	/* Registers that we access */
+	SUPPLY_CONTROL1		= 0x20,
+	SUPPLY_CONTROL2,
+	SM1_VOLTAGE_V1		= 0x23,
+	SM1_VOLTAGE_V2,
+	SM0_VOLTAGE_V1		= 0x26,
+	SM0_VOLTAGE_V2,
+	PFM_MODE		= 0x47,
+
+	/* Bits in the supply control registers */
+	CTRL_SM1_RAMP		= 0x01,
+	CTRL_SM1_SUPPLY2	= 0x02,
+	CTRL_SM0_RAMP		= 0x04,
+	CTRL_SM0_SUPPLY2	= 0x08,
+};
+
+#define MAX_I2C_RETRY	3
+int tps6586x_read(int reg)
+{
+	int	i;
+	uchar	data;
+	int	retval = -1;
+	int	old_bus_num;
+
+	old_bus_num = i2c_get_bus_num();
+	i2c_set_bus_num(bus_num);
+
+	for (i = 0; i < MAX_I2C_RETRY; ++i) {
+		if (!i2c_read(I2C_ADDRESS, reg, 1, &data, 1)) {
+			retval = (int)data;
+			goto exit;
+		}
+
+		/* i2c access failed, retry */
+		udelay(100);
+	}
+
+exit:
+	i2c_set_bus_num(old_bus_num);
+	debug("pmu_read %x=%x\n", reg, retval);
+	if (retval < 0)
+		debug("%s: failed to read register %#x: %d\n", __func__, reg,
+		      retval);
+	return retval;
+}
+
+int tps6586x_write(int reg, uchar *data, uint len)
+{
+	int	i;
+	int	retval = -1;
+	int	old_bus_num;
+
+	old_bus_num = i2c_get_bus_num();
+	i2c_set_bus_num(bus_num);
+
+	for (i = 0; i < MAX_I2C_RETRY; ++i) {
+		if (!i2c_write(I2C_ADDRESS, reg, 1, data, len)) {
+			retval = 0;
+			goto exit;
+		}
+
+		/* i2c access failed, retry */
+		udelay(100);
+	}
+
+exit:
+	i2c_set_bus_num(old_bus_num);
+	debug("pmu_write %x=%x: ", reg, retval);
+	for (i = 0; i < len; i++)
+		debug("%x ", data[i]);
+	if (retval)
+		debug("%s: failed to write register %#x\n", __func__, reg);
+	return retval;
+}
+
+/*
+ * Get current voltage of SM0 and SM1
+ *
+ * @param sm0	Place to put SM0 voltage
+ * @param sm1	Place to put SM1 voltage
+ * @return 0 if ok, -1 on error
+ */
+static int read_voltages(int *sm0, int *sm1)
+{
+	int ctrl1, ctrl2;
+	int is_v2;
+
+	/*
+	 * Each vdd has two supply sources, ie, v1 and v2.
+	 * The supply control reg1 and reg2 determine the current selection.
+	 */
+	ctrl1 = tps6586x_read(SUPPLY_CONTROL1);
+	ctrl2 = tps6586x_read(SUPPLY_CONTROL2);
+	if (ctrl1 == -1 || ctrl2 == -1)
+		return -1;
+
+	/* Figure out whether V1 or V2 is selected */
+	is_v2 = (ctrl1 | ctrl2) & CTRL_SM0_SUPPLY2;
+	*sm0 = tps6586x_read(is_v2 ? SM0_VOLTAGE_V2 : SM0_VOLTAGE_V1);
+	*sm1 = tps6586x_read(is_v2 ? SM1_VOLTAGE_V2 : SM1_VOLTAGE_V1);
+	if (*sm0 == -1 || *sm1 == -1)
+		return -1;
+
+	return 0;
+}
+
+static int set_voltage(int reg, int data, int rate)
+{
+	uchar control_bit;
+	uchar buff[3];
+
+	control_bit = (reg == SM0_VOLTAGE_V1 ? CTRL_SM0_RAMP : CTRL_SM1_RAMP);
+
+	/*
+	 * Only one supply is needed in u-boot. set both v1 and v2 to
+	 * same value.
+	 *
+	 * When both v1 and v2 are set to same value, we just need to set
+	 * control1 reg to trigger the supply selection.
+	 */
+	buff[0] = buff[1] = (uchar)data;
+	buff[2] = rate;
+
+	/* write v1, v2 and rate, then trigger */
+	if (tps6586x_write(reg, buff, 3) ||
+	    tps6586x_write(SUPPLY_CONTROL1, &control_bit, 1))
+		return -1;
+
+	return 0;
+}
+
+static int calculate_next_voltage(int voltage, int target, int step)
+{
+	int diff = voltage < target ? step : -step;
+
+	if (abs(target - voltage) > step)
+		voltage += diff;
+	else
+		voltage = target;
+
+	return voltage;
+}
+
+int tps6586x_set_pwm_mode(int mask)
+{
+	uchar val;
+	int ret;
+
+	assert(inited);
+	ret = tps6586x_read(PFM_MODE);
+	if (ret != -1) {
+		val = (uchar)ret;
+		val |= mask;
+
+		ret = tps6586x_write(PFM_MODE, &val, 1);
+	}
+
+	if (ret == -1)
+		debug("%s: Failed to read/write PWM mode reg\n", __func__);
+
+	return ret;
+}
+
+int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
+			    int min_sm0_over_sm1)
+{
+	int sm0, sm1;
+	int bad;
+
+	assert(inited);
+
+	/* get current voltage settings */
+	if (read_voltages(&sm0, &sm1)) {
+		debug("%s: Cannot read voltage settings\n", __func__);
+		return -1;
+	}
+
+	/*
+	 * if vdd_core < vdd_cpu + rel
+	 *    skip
+	 *
+	 * This condition may happen when system reboots due to kernel crash.
+	 */
+	if (min_sm0_over_sm1 != -1 && sm0 < sm1 + min_sm0_over_sm1) {
+		debug("%s: SM0 is %d, SM1 is %d, but min_sm0_over_sm1 is %d\n",
+		      __func__, sm0, sm1, min_sm0_over_sm1);
+		return -1;
+	}
+
+	/*
+	 * Since vdd_core and vdd_cpu may both stand at either greater or less
+	 * than their nominal voltage, the adjustment may go either directions.
+	 *
+	 * Make sure vdd_core is always higher than vdd_cpu with certain margin.
+	 * So, find out which vdd to adjust first in each step.
+	 *
+	 * case 1: both sm0 and sm1 need to move up
+	 *              adjust sm0 before sm1
+	 *
+	 * case 2: both sm0 and sm1 need to move down
+	 *              adjust sm1 before sm0
+	 *
+	 * case 3: sm0 moves down and sm1 moves up
+	 *              adjusting either one first is fine.
+	 *
+	 * Adjust vdd_core and vdd_cpu one step@a time until they reach
+	 * their nominal values.
+	 */
+	bad = 0;
+	while (!bad && (sm0 != sm0_target || sm1 != sm1_target)) {
+		int adjust_sm0_late = 0; /* flag to adjust vdd_core later */
+
+		debug("%d-%d   %d-%d   ", sm0, sm0_target, sm1, sm1_target);
+
+		if (sm0 != sm0_target) {
+			/*
+			 * if case 1 and case 3, set new sm0 first.
+			 * otherwise, hold down until new sm1 is set.
+			 */
+			sm0 = calculate_next_voltage(sm0, sm0_target, step);
+			if (sm1 < sm1_target)
+				bad |= set_voltage(SM0_VOLTAGE_V1, sm0, rate);
+			else
+				adjust_sm0_late = 1;
+		}
+
+		if (sm1 != sm1_target) {
+			sm1 = calculate_next_voltage(sm1, sm1_target, step);
+			bad |= set_voltage(SM1_VOLTAGE_V1, sm1, rate);
+		}
+
+		if (adjust_sm0_late)
+			bad |= set_voltage(SM0_VOLTAGE_V1, sm0, rate);
+		debug("%d\n", adjust_sm0_late);
+	}
+	debug("%d-%d   %d-%d   done\n", sm0, sm0_target, sm1, sm1_target);
+
+	return bad ? -1 : 0;
+}
+
+int tps6586x_init(int bus)
+{
+	bus_num = bus;
+	inited = 1;
+
+	return 0;
+}
diff --git a/include/tps6586x.h b/include/tps6586x.h
new file mode 100644
index 0000000..ab88082
--- /dev/null
+++ b/include/tps6586x.h
@@ -0,0 +1,68 @@
+/*
+ *  (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 __H_
+#define _TPS6586X_H_
+
+enum {
+	/* SM0-2 PWM/PFM Mode Selection */
+	TPS6586X_PWM_SM0	= 1 << 0,
+	TPS6586X_PWM_SM1	= 1 << 1,
+	TPS6586X_PWM_SM2	= 1 << 2,
+};
+
+/**
+ * Enable PWM mode for selected SM0-2
+ *
+ * @param mask	Mask of synchronous converter to enable (TPS6586X_PWM_...)
+ * @return 0 if ok, -1 on error
+ */
+int tps6586x_set_pwm_mode(int mask);
+
+/**
+ * Adjust SM0 and SM1 voltages to the given targets in incremental steps.
+ *
+ * @param sm0_target	Target voltage for SM0 in 25mW units, 0=725mV, 31=1.5V
+ * @param sm1_target	Target voltage for SM1 in 25mW units, 0=725mV, 31=1.5V
+ * @param step		Amount to change voltage in each step, in 25mW units
+ * @param rate		Slew ratein mV/us: 0=instantly, 1=0.11, 2=0.22,
+ *			3=0.44, 4=0.88, 5=1.76, 6=3.52, 7=7.04
+ * @param min_sm0_over_sm1	Minimum amount by which sm0 must exceed sm1.
+ *			If this condition is not met, no adjustment will be
+ *			done and an error will be reported. Use -1 to skip
+ *			this check.
+ * @return 0 if ok, -1 on error
+ */
+int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
+			    int min_sm0_over_sm1);
+
+/**
+ * Set up the TPS6586X I2C bus number. This will be used for all operations
+ * on the device. This function must be called before using other functions.
+ *
+ * @param bus	I2C bus number containing the TPS6586X chip
+ * @return 0 (always succeeds)
+ */
+int tps6586x_init(int bus);
+
+#endif	/* _TPS6586X_H_ */
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 05/23] Add AES crypto library
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (3 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-03 18:46   ` Yen Lin
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location Simon Glass
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Yen Lin <yelin@nvidia.com>

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.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Tidy whitespace problems
- Use const for sbox arrays

 include/aes.h |   70 +++++++
 lib/Makefile  |    1 +
 lib/aes.c     |  598 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 669 insertions(+), 0 deletions(-)
 create mode 100644 include/aes.h
 create mode 100644 lib/aes.c

diff --git a/include/aes.h b/include/aes.h
new file mode 100644
index 0000000..41b0db2
--- /dev/null
+++ b/include/aes.h
@@ -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_ */
diff --git a/lib/Makefile b/lib/Makefile
index a0fec60..1e8478f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -28,6 +28,7 @@ LIB	= $(obj)libgeneric.o
 ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_ADDR_MAP) += addr_map.o
 COBJS-$(CONFIG_BCH) += bch.o
+COBJS-$(CONFIG_AES) += aes.o
 COBJS-$(CONFIG_BZIP2) += bzlib.o
 COBJS-$(CONFIG_BZIP2) += bzlib_crctable.o
 COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
diff --git a/lib/aes.c b/lib/aes.c
new file mode 100644
index 0000000..7da9edb
--- /dev/null
+++ b/lib/aes.c
@@ -0,0 +1,598 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 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
+ */
+
+/*
+ * advanced encryption standard
+ * author: karl malbrain, malbrain at yahoo.com
+ *
+ * This work, including the source code, documentation
+ * and related data, is placed into the public domain.
+ *
+ * The orginal author is Karl Malbrain.
+ *
+ * THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
+ * OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
+ * MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
+ * ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
+ * RESULTING FROM THE USE, MODIFICATION, OR
+ * REDISTRIBUTION OF THIS SOFTWARE.
+*/
+
+#include <common.h>
+#include "aes.h"
+
+/* forward s-box */
+static const u8 sbox[256] = {
+	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+/* inverse s-box */
+static const u8 inv_sbox[256] = {
+	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
+	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
+	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
+	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
+	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
+	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
+	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
+	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
+	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
+	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
+	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
+	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
+	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
+	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
+	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
+	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
+	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
+
+/* combined Xtimes2[Sbox[]] */
+static const u8 x2_sbox[256] = {
+	0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91,
+	0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
+	0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb,
+	0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
+	0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83,
+	0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
+	0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f,
+	0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
+	0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b,
+	0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
+	0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6,
+	0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
+	0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11,
+	0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
+	0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1,
+	0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
+	0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e,
+	0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
+	0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b,
+	0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
+	0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8,
+	0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
+	0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49,
+	0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
+	0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97,
+	0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
+	0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c,
+	0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
+	0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33,
+	0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
+	0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0,
+	0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
+};
+
+/* combined Xtimes3[Sbox[]] */
+static const u8 x3_sbox[256] = {
+	0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54,
+	0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
+	0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b,
+	0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
+	0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f,
+	0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
+	0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5,
+	0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
+	0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb,
+	0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
+	0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed,
+	0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
+	0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94,
+	0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
+	0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04,
+	0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
+	0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39,
+	0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
+	0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83,
+	0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
+	0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4,
+	0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
+	0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0,
+	0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
+	0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51,
+	0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
+	0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12,
+	0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
+	0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7,
+	0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
+	0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8,
+	0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
+};
+
+/*
+ * modular multiplication tables based on:
+ *
+ * Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
+ * Xtime3[x] = x^Xtime2[x];
+ */
+static const u8 x_time_9[256] = {
+	0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+	0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+	0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
+	0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
+	0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+	0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+	0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94,
+	0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
+	0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
+	0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
+	0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9,
+	0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
+	0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72,
+	0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
+	0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
+	0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
+	0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3,
+	0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
+	0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43,
+	0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
+	0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
+	0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
+	0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78,
+	0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
+	0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5,
+	0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
+	0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
+	0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
+	0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e,
+	0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
+	0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e,
+	0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
+};
+
+static const u8 x_time_b[256] = {
+	0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31,
+	0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
+	0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
+	0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
+	0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a,
+	0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
+	0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa,
+	0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
+	0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
+	0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
+	0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77,
+	0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
+	0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc,
+	0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
+	0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
+	0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
+	0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6,
+	0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
+	0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76,
+	0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
+	0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
+	0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
+	0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d,
+	0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
+	0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30,
+	0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
+	0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
+	0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
+	0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b,
+	0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
+	0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb,
+	0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
+};
+
+static const u8 x_time_d[256] = {
+	0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23,
+	0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
+	0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
+	0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
+	0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98,
+	0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
+	0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48,
+	0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
+	0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
+	0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
+	0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e,
+	0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
+	0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5,
+	0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
+	0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
+	0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
+	0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9,
+	0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
+	0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29,
+	0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
+	0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
+	0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
+	0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92,
+	0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
+	0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94,
+	0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
+	0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
+	0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
+	0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f,
+	0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
+	0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff,
+	0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
+};
+
+static const u8 x_time_e[256] = {
+	0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a,
+	0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
+	0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
+	0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
+	0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1,
+	0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
+	0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11,
+	0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
+	0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
+	0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
+	0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67,
+	0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
+	0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c,
+	0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
+	0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
+	0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
+	0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b,
+	0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
+	0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b,
+	0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
+	0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
+	0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
+	0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50,
+	0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
+	0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6,
+	0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
+	0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
+	0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
+	0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d,
+	0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
+	0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd,
+	0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
+};
+
+/*
+ * Exchanges columns in each of 4 rows
+ * row0 - unchanged, row1- shifted left 1,
+ * row2 - shifted left 2 and row3 - shifted left 3
+ */
+static void shift_rows(u8 *state)
+{
+	u8 tmp;
+
+	/* just substitute row 0 */
+	state[0] = sbox[state[0]];
+	state[4] = sbox[state[4]];
+	state[8] = sbox[state[8]];
+	state[12] = sbox[state[12]];
+
+	/* rotate row 1 */
+	tmp = sbox[state[1]];
+	state[1] = sbox[state[5]];
+	state[5] = sbox[state[9]];
+	state[9] = sbox[state[13]];
+	state[13] = tmp;
+
+	/* rotate row 2 */
+	tmp = sbox[state[2]];
+	state[2] = sbox[state[10]];
+	state[10] = tmp;
+	tmp = sbox[state[6]];
+	state[6] = sbox[state[14]];
+	state[14] = tmp;
+
+	/* rotate row 3 */
+	tmp = sbox[state[15]];
+	state[15] = sbox[state[11]];
+	state[11] = sbox[state[7]];
+	state[7] = sbox[state[3]];
+	state[3] = tmp;
+}
+
+/*
+ * restores columns in each of 4 rows
+ * row0 - unchanged, row1- shifted right 1,
+ * row2 - shifted right 2 and row3 - shifted right 3
+ */
+static void inv_shift_rows(u8 *state)
+{
+	u8 tmp;
+
+	/* restore row 0 */
+	state[0] = inv_sbox[state[0]];
+	state[4] = inv_sbox[state[4]];
+	state[8] = inv_sbox[state[8]];
+	state[12] = inv_sbox[state[12]];
+
+	/* restore row 1 */
+	tmp = inv_sbox[state[13]];
+	state[13] = inv_sbox[state[9]];
+	state[9] = inv_sbox[state[5]];
+	state[5] = inv_sbox[state[1]];
+	state[1] = tmp;
+
+	/* restore row 2 */
+	tmp = inv_sbox[state[2]];
+	state[2] = inv_sbox[state[10]];
+	state[10] = tmp;
+	tmp = inv_sbox[state[6]];
+	state[6] = inv_sbox[state[14]];
+	state[14] = tmp;
+
+	/* restore row 3 */
+	tmp = inv_sbox[state[3]];
+	state[3] = inv_sbox[state[7]];
+	state[7] = inv_sbox[state[11]];
+	state[11] = inv_sbox[state[15]];
+	state[15] = tmp;
+}
+
+/* recombine and mix each row in a column */
+static void mix_sub_columns(u8 *state)
+{
+	u8 tmp[4 * AES_STATECOLS];
+
+	/* mixing column 0 */
+	tmp[0] = x2_sbox[state[0]] ^ x3_sbox[state[5]] ^
+		 sbox[state[10]] ^ sbox[state[15]];
+	tmp[1] = sbox[state[0]] ^ x2_sbox[state[5]] ^
+		 x3_sbox[state[10]] ^ sbox[state[15]];
+	tmp[2] = sbox[state[0]] ^ sbox[state[5]] ^
+		 x2_sbox[state[10]] ^ x3_sbox[state[15]];
+	tmp[3] = x3_sbox[state[0]] ^ sbox[state[5]] ^
+		 sbox[state[10]] ^ x2_sbox[state[15]];
+
+	/* mixing column 1 */
+	tmp[4] = x2_sbox[state[4]] ^ x3_sbox[state[9]] ^
+		 sbox[state[14]] ^ sbox[state[3]];
+	tmp[5] = sbox[state[4]] ^ x2_sbox[state[9]] ^
+		 x3_sbox[state[14]] ^ sbox[state[3]];
+	tmp[6] = sbox[state[4]] ^ sbox[state[9]] ^
+		 x2_sbox[state[14]] ^ x3_sbox[state[3]];
+	tmp[7] = x3_sbox[state[4]] ^ sbox[state[9]] ^
+		 sbox[state[14]] ^ x2_sbox[state[3]];
+
+	/* mixing column 2 */
+	tmp[8] = x2_sbox[state[8]] ^ x3_sbox[state[13]] ^
+		 sbox[state[2]] ^ sbox[state[7]];
+	tmp[9] = sbox[state[8]] ^ x2_sbox[state[13]] ^
+		 x3_sbox[state[2]] ^ sbox[state[7]];
+	tmp[10] = sbox[state[8]] ^ sbox[state[13]] ^
+		  x2_sbox[state[2]] ^ x3_sbox[state[7]];
+	tmp[11] = x3_sbox[state[8]] ^ sbox[state[13]] ^
+		  sbox[state[2]] ^ x2_sbox[state[7]];
+
+	/* mixing column 3 */
+	tmp[12] = x2_sbox[state[12]] ^ x3_sbox[state[1]] ^
+		  sbox[state[6]] ^ sbox[state[11]];
+	tmp[13] = sbox[state[12]] ^ x2_sbox[state[1]] ^
+		  x3_sbox[state[6]] ^ sbox[state[11]];
+	tmp[14] = sbox[state[12]] ^ sbox[state[1]] ^
+		  x2_sbox[state[6]] ^ x3_sbox[state[11]];
+	tmp[15] = x3_sbox[state[12]] ^ sbox[state[1]] ^
+		  sbox[state[6]] ^ x2_sbox[state[11]];
+
+	memcpy(state, tmp, sizeof(tmp));
+}
+
+/* restore and un-mix each row in a column */
+static void inv_mix_sub_columns(u8 *state)
+{
+	u8 tmp[4 * AES_STATECOLS];
+	int  i;
+
+	/* restore column 0 */
+	tmp[0] = x_time_e[state[0]] ^ x_time_b[state[1]] ^
+		 x_time_d[state[2]] ^ x_time_9[state[3]];
+	tmp[5] = x_time_9[state[0]] ^ x_time_e[state[1]] ^
+		 x_time_b[state[2]] ^ x_time_d[state[3]];
+	tmp[10] = x_time_d[state[0]] ^ x_time_9[state[1]] ^
+		  x_time_e[state[2]] ^ x_time_b[state[3]];
+	tmp[15] = x_time_b[state[0]] ^ x_time_d[state[1]] ^
+		  x_time_9[state[2]] ^ x_time_e[state[3]];
+
+	/* restore column 1 */
+	tmp[4] = x_time_e[state[4]] ^ x_time_b[state[5]] ^
+		 x_time_d[state[6]] ^ x_time_9[state[7]];
+	tmp[9] = x_time_9[state[4]] ^ x_time_e[state[5]] ^
+		 x_time_b[state[6]] ^ x_time_d[state[7]];
+	tmp[14] = x_time_d[state[4]] ^ x_time_9[state[5]] ^
+		  x_time_e[state[6]] ^ x_time_b[state[7]];
+	tmp[3] = x_time_b[state[4]] ^ x_time_d[state[5]] ^
+		 x_time_9[state[6]] ^ x_time_e[state[7]];
+
+	/* restore column 2 */
+	tmp[8] = x_time_e[state[8]] ^ x_time_b[state[9]] ^
+		 x_time_d[state[10]] ^ x_time_9[state[11]];
+	tmp[13] = x_time_9[state[8]] ^ x_time_e[state[9]] ^
+		  x_time_b[state[10]] ^ x_time_d[state[11]];
+	tmp[2] = x_time_d[state[8]] ^ x_time_9[state[9]] ^
+		 x_time_e[state[10]] ^ x_time_b[state[11]];
+	tmp[7] = x_time_b[state[8]] ^ x_time_d[state[9]] ^
+		 x_time_9[state[10]] ^ x_time_e[state[11]];
+
+	/* restore column 3 */
+	tmp[12] = x_time_e[state[12]] ^ x_time_b[state[13]] ^
+		  x_time_d[state[14]] ^ x_time_9[state[15]];
+	tmp[1] = x_time_9[state[12]] ^ x_time_e[state[13]] ^
+		 x_time_b[state[14]] ^ x_time_d[state[15]];
+	tmp[6] = x_time_d[state[12]] ^ x_time_9[state[13]] ^
+		 x_time_e[state[14]] ^ x_time_b[state[15]];
+	tmp[11] = x_time_b[state[12]] ^ x_time_d[state[13]] ^
+		  x_time_9[state[14]] ^ x_time_e[state[15]];
+
+	for (i = 0; i < 4 * AES_STATECOLS; i++)
+		state[i] = inv_sbox[tmp[i]];
+}
+
+/*
+ * encrypt/decrypt columns of the key
+ * n.b. you can replace this with byte-wise xor if you wish.
+ */
+static void add_round_key(u32 *state, u32 *key)
+{
+	int idx;
+
+	for (idx = 0; idx < 4; idx++)
+		state[idx] ^= key[idx];
+}
+
+static u8 rcon[11] = {
+	0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
+};
+
+/* produce AES_STATECOLS bytes for each round */
+void aes_expand_key(u8 *key, u8 *expkey)
+{
+	u8 tmp0, tmp1, tmp2, tmp3, tmp4;
+	u32 idx;
+
+	memcpy(expkey, key, AES_KEYCOLS * 4);
+
+	for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
+		tmp0 = expkey[4*idx - 4];
+		tmp1 = expkey[4*idx - 3];
+		tmp2 = expkey[4*idx - 2];
+		tmp3 = expkey[4*idx - 1];
+		if (!(idx % AES_KEYCOLS)) {
+			tmp4 = tmp3;
+			tmp3 = sbox[tmp0];
+			tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
+			tmp1 = sbox[tmp2];
+			tmp2 = sbox[tmp4];
+		} else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
+			tmp0 = sbox[tmp0];
+			tmp1 = sbox[tmp1];
+			tmp2 = sbox[tmp2];
+			tmp3 = sbox[tmp3];
+		}
+
+		expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
+		expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
+		expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
+		expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
+	}
+}
+
+/* encrypt one 128 bit block */
+void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
+{
+	u8 state[AES_STATECOLS * 4];
+	u32 round;
+
+	memcpy(state, in, AES_STATECOLS * 4);
+	add_round_key((u32 *)state, (u32 *)expkey);
+
+	for (round = 1; round < AES_ROUNDS + 1; round++) {
+		if (round < AES_ROUNDS)
+			mix_sub_columns(state);
+		else
+			shift_rows(state);
+
+		add_round_key((u32 *)state,
+			      (u32 *)expkey + round * AES_STATECOLS);
+	}
+
+	memcpy(out, state, sizeof(state));
+}
+
+void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
+{
+	u8 state[AES_STATECOLS * 4];
+	int round;
+
+	memcpy(state, in, sizeof(state));
+
+	add_round_key((u32 *)state,
+		      (u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
+	inv_shift_rows(state);
+
+	for (round = AES_ROUNDS; round--; ) {
+		add_round_key((u32 *)state,
+			      (u32 *)expkey + round * AES_STATECOLS);
+		if (round)
+			inv_mix_sub_columns(state);
+	}
+
+	memcpy(out, state, sizeof(state));
+}
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (4 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 05/23] Add AES crypto library Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-09 21:03   ` Stephen Warren
  2012-04-09 21:06   ` Stephen Warren
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 07/23] tegra: Add functions to access low-level Osc/PLL details Simon Glass
                   ` (17 subsequent siblings)
  23 siblings, 2 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

We want to include this from board code, so move the header into
an easily-accessible location.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 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%)

diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
index b749821..a6dd3e4 100644
--- a/arch/arm/cpu/armv7/tegra2/ap20.c
+++ b/arch/arm/cpu/armv7/tegra2/ap20.c
@@ -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>
diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c
index a797e6f..a50b1b9 100644
--- a/arch/arm/cpu/armv7/tegra2/board.c
+++ b/arch/arm/cpu/armv7/tegra2/board.c
@@ -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;
 
diff --git a/arch/arm/cpu/armv7/tegra2/ap20.h b/arch/arm/include/asm/arch-tegra2/ap20.h
similarity index 100%
rename from arch/arm/cpu/armv7/tegra2/ap20.h
rename to arch/arm/include/asm/arch-tegra2/ap20.h
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 07/23] tegra: Add functions to access low-level Osc/PLL details
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (5 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 08/23] tegra: Add crypto library for warmboot code Simon Glass
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

Add clock_ll_read_pll() to read PLL parameters and clock_get_osc_bypass()
to find out if the Oscillator is bypassed. These are needed by warmboot.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- New patch to add low-level clock functions

 arch/arm/cpu/armv7/tegra2/clock.c          |   32 ++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/clk_rst.h |    3 ++
 arch/arm/include/asm/arch-tegra2/clock.h   |   22 +++++++++++++++++++
 3 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c
index 39376ab..b6b3210 100644
--- a/arch/arm/cpu/armv7/tegra2/clock.c
+++ b/arch/arm/cpu/armv7/tegra2/clock.c
@@ -410,6 +410,16 @@ enum clock_osc_freq clock_get_osc_freq(void)
 	return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
 }
 
+int clock_get_osc_bypass(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	reg = readl(&clkrst->crc_osc_ctrl);
+	return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT;
+}
+
 /* Returns a pointer to the registers of the given pll */
 static struct clk_pll *get_pll(enum clock_id clkid)
 {
@@ -420,6 +430,28 @@ static struct clk_pll *get_pll(enum clock_id clkid)
 	return &clkrst->crc_pll[clkid];
 }
 
+int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
+		u32 *divp, u32 *cpcon, u32 *lfcon)
+{
+	struct clk_pll *pll = get_pll(clkid);
+	u32 data;
+
+	assert(clkid != CLOCK_ID_USB);
+
+	/* Safety check, adds to code size but is small */
+	if (!clock_id_isvalid(clkid) || clkid == CLOCK_ID_USB)
+		return -1;
+	data = readl(&pll->pll_base);
+	*divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
+	*divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT;
+	*divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
+	data = readl(&pll->pll_misc);
+	*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT;
+	*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT;
+
+	return 0;
+}
+
 unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
 		u32 divp, u32 cpcon, u32 lfcon)
 {
diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h
index 415e420..8c3be91 100644
--- a/arch/arm/include/asm/arch-tegra2/clk_rst.h
+++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h
@@ -117,6 +117,7 @@ struct clk_rst_ctlr {
 #define PLL_CPCON_MASK		(15U << PLL_CPCON_SHIFT)
 
 #define PLL_LFCON_SHIFT		4
+#define PLL_LFCON_MASK		(15U << PLL_LFCON_SHIFT)
 
 #define PLLU_VCO_FREQ_SHIFT	20
 #define PLLU_VCO_FREQ_MASK	(1U << PLLU_VCO_FREQ_SHIFT)
@@ -124,6 +125,8 @@ struct clk_rst_ctlr {
 /* CLK_RST_CONTROLLER_OSC_CTRL_0 */
 #define OSC_FREQ_SHIFT		30
 #define OSC_FREQ_MASK		(3U << OSC_FREQ_SHIFT)
+#define OSC_XOBP_SHIFT		1
+#define OSC_XOBP_MASK		(1U << OSC_XOBP_SHIFT)
 
 /*
  * CLK_RST_CONTROLLER_CLK_SOURCE_x_OUT_0 - the mask here is normally 8 bits
diff --git a/arch/arm/include/asm/arch-tegra2/clock.h b/arch/arm/include/asm/arch-tegra2/clock.h
index 6b12c76..1d3ae38 100644
--- a/arch/arm/include/asm/arch-tegra2/clock.h
+++ b/arch/arm/include/asm/arch-tegra2/clock.h
@@ -210,6 +210,21 @@ enum clock_osc_freq clock_get_osc_freq(void);
 unsigned long clock_start_pll(enum clock_id id, u32 divm, u32 divn,
 		u32 divp, u32 cpcon, u32 lfcon);
 
+/**
+ * Read low-level parameters of a PLL.
+ *
+ * @param id	clock id to read (note: USB is not supported)
+ * @param divm	returns input divider
+ * @param divn	returns feedback divider
+ * @param divp	returns post divider 2^n
+ * @param cpcon	returns charge pump setup control
+ * @param lfcon	returns loop filter setup control
+ *
+ * @returns 0 if ok, -1 on error (invalid clock id)
+ */
+int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
+		      u32 *divp, u32 *cpcon, u32 *lfcon);
+
 /*
  * Enable a clock
  *
@@ -368,6 +383,13 @@ void clock_ll_start_uart(enum periph_id periph_id);
  */
 enum periph_id clock_decode_periph_id(const void *blob, int node);
 
+/**
+ * Checks if the oscillator bypass is enabled (XOBP bit)
+ *
+ * @return 1 if bypass is enabled, 0 if not
+ */
+int clock_get_osc_bypass(void);
+
 /*
  * Checks that clocks are valid and prints a warning if not
  *
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 08/23] tegra: Add crypto library for warmboot code
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (6 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 07/23] tegra: Add functions to access low-level Osc/PLL details Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-03 18:47   ` Yen Lin
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 09/23] tegra: Add flow, gp_padctl, fuse, sdram headers Simon Glass
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Yen Lin <yelin@nvidia.com>

Provides an interface to aes.c for the warmboot code.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Rely on compiler to optimise out debug_print_vector()
- Remove unused crypto code from crypto.c

 arch/arm/cpu/armv7/tegra2/crypto.c |  230 ++++++++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/tegra2/crypto.h |   36 ++++++
 2 files changed, 266 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.c
 create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.h

diff --git a/arch/arm/cpu/armv7/tegra2/crypto.c b/arch/arm/cpu/armv7/tegra2/crypto.c
new file mode 100644
index 0000000..5f0b240
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/crypto.c
@@ -0,0 +1,230 @@
+/*
+ * 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 */
+};
+
+static void debug_print_vector(char *name, u32 num_bytes, u8 *data)
+{
+	u32 i;
+
+	debug("%s [%d] @0x%08x", name, num_bytes, (u32)data);
+	for (i = 0; i < num_bytes; i++) {
+		if (i % 16 == 0)
+			debug(" = ");
+		debug("%02x", data[i]);
+		if ((i+1) % 16 != 0)
+			debug(" ");
+	}
+	debug("\n");
+}
+
+/**
+ * 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);
+}
diff --git a/arch/arm/cpu/armv7/tegra2/crypto.h b/arch/arm/cpu/armv7/tegra2/crypto.h
new file mode 100644
index 0000000..aff67e7
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/crypto.h
@@ -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_ */
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 09/23] tegra: Add flow, gp_padctl, fuse, sdram headers
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (7 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 08/23] tegra: Add crypto library for warmboot code Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-03 18:52   ` Yen Lin
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 10/23] tegra: Add tegra_get_chip_type() to detect SKU Simon Glass
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Yen Lin <yelin@nvidia.com>

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

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 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

diff --git a/arch/arm/include/asm/arch-tegra2/flow.h b/arch/arm/include/asm/arch-tegra2/flow.h
new file mode 100644
index 0000000..cce6cbf
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/flow.h
@@ -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
diff --git a/arch/arm/include/asm/arch-tegra2/fuse.h b/arch/arm/include/asm/arch-tegra2/fuse.h
new file mode 100644
index 0000000..b7e3808
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/fuse.h
@@ -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_ */
diff --git a/arch/arm/include/asm/arch-tegra2/gp_padctrl.h b/arch/arm/include/asm/arch-tegra2/gp_padctrl.h
new file mode 100644
index 0000000..25bb46d
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/gp_padctrl.h
@@ -0,0 +1,64 @@
+/*
+ *  (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 _GP_PADCTRL_H_
+#define _GP_PADCTRL_H_
+
+/* APB_MISC_GP and padctrl registers */
+struct apb_misc_gp_ctlr {
+	u32	modereg;	/* 0x00: APB_MISC_GP_MODEREG */
+	u32	hidrev;		/* 0x04: APB_MISC_GP_HIDREV */
+	u32	reserved0[22];	/* 0x08 - 0x5C: */
+	u32	emu_revid;	/* 0x60: APB_MISC_GP_EMU_REVID */
+	u32	xactor_scratch;	/* 0x64: APB_MISC_GP_XACTOR_SCRATCH */
+	u32	aocfg1;		/* 0x68: APB_MISC_GP_AOCFG1PADCTRL */
+	u32	aocfg2;		/* 0x6c: APB_MISC_GP_AOCFG2PADCTRL */
+	u32	atcfg1;		/* 0x70: APB_MISC_GP_ATCFG1PADCTRL */
+	u32	atcfg2;		/* 0x74: APB_MISC_GP_ATCFG2PADCTRL */
+	u32	cdevcfg1;	/* 0x78: APB_MISC_GP_CDEV1CFGPADCTRL */
+	u32	cdevcfg2;	/* 0x7C: APB_MISC_GP_CDEV2CFGPADCTRL */
+	u32	csuscfg;	/* 0x80: APB_MISC_GP_CSUSCFGPADCTRL */
+	u32	dap1cfg;	/* 0x84: APB_MISC_GP_DAP1CFGPADCTRL */
+	u32	dap2cfg;	/* 0x88: APB_MISC_GP_DAP2CFGPADCTRL */
+	u32	dap3cfg;	/* 0x8C: APB_MISC_GP_DAP3CFGPADCTRL */
+	u32	dap4cfg;	/* 0x90: APB_MISC_GP_DAP4CFGPADCTRL */
+	u32	dbgcfg;		/* 0x94: APB_MISC_GP_DBGCFGPADCTRL */
+	u32	lcdcfg1;	/* 0x98: APB_MISC_GP_LCDCFG1PADCTRL */
+	u32	lcdcfg2;	/* 0x9C: APB_MISC_GP_LCDCFG2PADCTRL */
+	u32	sdmmc2_cfg;	/* 0xA0: APB_MISC_GP_SDMMC2CFGPADCTRL */
+	u32	sdmmc3_cfg;	/* 0xA4: APB_MISC_GP_SDMMC3CFGPADCTRL */
+	u32	spicfg;		/* 0xA8: APB_MISC_GP_SPICFGPADCTRL */
+	u32	uaacfg;		/* 0xAC: APB_MISC_GP_UAACFGPADCTRL */
+	u32	uabcfg;		/* 0xB0: APB_MISC_GP_UABCFGPADCTRL */
+	u32	uart2cfg;	/* 0xB4: APB_MISC_GP_UART2CFGPADCTRL */
+	u32	uart3cfg;	/* 0xB8: APB_MISC_GP_UART3CFGPADCTRL */
+	u32	vicfg1;		/* 0xBC: APB_MISC_GP_VICFG1PADCTRL */
+	u32	vicfg2;		/* 0xC0: APB_MISC_GP_VICFG2PADCTRL */
+	u32	xm2cfga;	/* 0xC4: APB_MISC_GP_XM2CFGAPADCTRL */
+	u32	xm2cfgc;	/* 0xC8: APB_MISC_GP_XM2CFGCPADCTRL */
+	u32	xm2cfgd;	/* 0xCC: APB_MISC_GP_XM2CFGDPADCTRL */
+	u32	xm2clkcfg;	/* 0xD0: APB_MISC_GP_XM2CLKCFGPADCTRL */
+	u32	memcomp;	/* 0xD4: APB_MISC_GP_MEMCOMPPADCTRL */
+};
+
+#endif
diff --git a/arch/arm/include/asm/arch-tegra2/sdram_param.h b/arch/arm/include/asm/arch-tegra2/sdram_param.h
new file mode 100644
index 0000000..6c427d0
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/sdram_param.h
@@ -0,0 +1,148 @@
+/*
+ *  (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 _SDRAM_PARAM_H_
+#define _SDRAM_PARAM_H_
+
+/*
+ * Defines the number of 32-bit words provided in each set of SDRAM parameters
+ * for arbitration configuration data.
+ */
+#define BCT_SDRAM_ARB_CONFIG_WORDS 27
+
+enum memory_type {
+	MEMORY_TYPE_NONE = 0,
+	MEMORY_TYPE_DDR,
+	MEMORY_TYPE_LPDDR,
+	MEMORY_TYPE_DDR2,
+	MEMORY_TYPE_LPDDR2,
+	MEMORY_TYPE_NUM,
+	MEMORY_TYPE_FORCE32 = 0x7FFFFFFF
+};
+
+/* Defines the SDRAM parameter structure */
+struct sdram_params {
+	enum memory_type memory_type;
+	u32 pllm_charge_pump_setup_control;
+	u32 pllm_loop_filter_setup_control;
+	u32 pllm_input_divider;
+	u32 pllm_feedback_divider;
+	u32 pllm_post_divider;
+	u32 pllm_stable_time;
+	u32 emc_clock_divider;
+	u32 emc_auto_cal_interval;
+	u32 emc_auto_cal_config;
+	u32 emc_auto_cal_wait;
+	u32 emc_pin_program_wait;
+	u32 emc_rc;
+	u32 emc_rfc;
+	u32 emc_ras;
+	u32 emc_rp;
+	u32 emc_r2w;
+	u32 emc_w2r;
+	u32 emc_r2p;
+	u32 emc_w2p;
+	u32 emc_rd_rcd;
+	u32 emc_wr_rcd;
+	u32 emc_rrd;
+	u32 emc_rext;
+	u32 emc_wdv;
+	u32 emc_quse;
+	u32 emc_qrst;
+	u32 emc_qsafe;
+	u32 emc_rdv;
+	u32 emc_refresh;
+	u32 emc_burst_refresh_num;
+	u32 emc_pdex2wr;
+	u32 emc_pdex2rd;
+	u32 emc_pchg2pden;
+	u32 emc_act2pden;
+	u32 emc_ar2pden;
+	u32 emc_rw2pden;
+	u32 emc_txsr;
+	u32 emc_tcke;
+	u32 emc_tfaw;
+	u32 emc_trpab;
+	u32 emc_tclkstable;
+	u32 emc_tclkstop;
+	u32 emc_trefbw;
+	u32 emc_quseextra;
+	u32 emc_fbioc_fg1;
+	u32 emc_fbio_dqsib_dly;
+	u32 emc_fbio_dqsib_dly_msb;
+	u32 emc_fbio_quse_dly;
+	u32 emc_fbio_quse_dly_msb;
+	u32 emc_fbio_cfg5;
+	u32 emc_fbio_cfg6;
+	u32 emc_fbio_spare;
+	u32 emc_mrs;
+	u32 emc_emrs;
+	u32 emc_mrw1;
+	u32 emc_mrw2;
+	u32 emc_mrw3;
+	u32 emc_mrw_reset_command;
+	u32 emc_mrw_reset_init_wait;
+	u32 emc_adr_cfg;
+	u32 emc_adr_cfg1;
+	u32 emc_emem_cfg;
+	u32 emc_low_latency_config;
+	u32 emc_cfg;
+	u32 emc_cfg2;
+	u32 emc_dbg;
+	u32 ahb_arbitration_xbar_ctrl;
+	u32 emc_cfg_dig_dll;
+	u32 emc_dll_xform_dqs;
+	u32 emc_dll_xform_quse;
+	u32 warm_boot_wait;
+	u32 emc_ctt_term_ctrl;
+	u32 emc_odt_write;
+	u32 emc_odt_read;
+	u32 emc_zcal_ref_cnt;
+	u32 emc_zcal_wait_cnt;
+	u32 emc_zcal_mrw_cmd;
+	u32 emc_mrs_reset_dll;
+	u32 emc_mrw_zq_init_dev0;
+	u32 emc_mrw_zq_init_dev1;
+	u32 emc_mrw_zq_init_wait;
+	u32 emc_mrs_reset_dll_wait;
+	u32 emc_emrs_emr2;
+	u32 emc_emrs_emr3;
+	u32 emc_emrs_ddr2_dll_enable;
+	u32 emc_mrs_ddr2_dll_reset;
+	u32 emc_emrs_ddr2_ocd_calib;
+	u32 emc_edr2_wait;
+	u32 emc_cfg_clktrim0;
+	u32 emc_cfg_clktrim1;
+	u32 emc_cfg_clktrim2;
+	u32 pmc_ddr_pwr;
+	u32 apb_misc_gp_xm2cfga_padctrl;
+	u32 apb_misc_gp_xm2cfgc_padctrl;
+	u32 apb_misc_gp_xm2cfgc_padctrl2;
+	u32 apb_misc_gp_xm2cfgd_padctrl;
+	u32 apb_misc_gp_xm2cfgd_padctrl2;
+	u32 apb_misc_gp_xm2clkcfg_padctrl;
+	u32 apb_misc_gp_xm2comp_padctrl;
+	u32 apb_misc_gp_xm2vttgen_padctrl;
+	u32 arbitration_config[BCT_SDRAM_ARB_CONFIG_WORDS];
+};
+#endif
diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h b/arch/arm/include/asm/arch-tegra2/tegra2.h
index ca1881e..2e152fd 100644
--- a/arch/arm/include/asm/arch-tegra2/tegra2.h
+++ b/arch/arm/include/asm/arch-tegra2/tegra2.h
@@ -40,6 +40,7 @@
 #define NV_PA_APB_UARTE_BASE	(NV_PA_APB_MISC_BASE + 0x6400)
 #define TEGRA2_SPI_BASE		(NV_PA_APB_MISC_BASE + 0xC380)
 #define TEGRA2_PMC_BASE		(NV_PA_APB_MISC_BASE + 0xE400)
+#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
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 10/23] tegra: Add tegra_get_chip_type() to detect SKU
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (8 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 09/23] tegra: Add flow, gp_padctl, fuse, sdram headers Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-09 21:09   ` Stephen Warren
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 11/23] tegra: Add header file for APB_MISC register Simon Glass
                   ` (13 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

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.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Stephen Warren <swarren@nvidia.com>
---
Changes in v2:
- Add check of undocumented values in hidrev register

 arch/arm/cpu/armv7/tegra2/ap20.c              |   36 +++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/ap20.h       |    7 +++++
 arch/arm/include/asm/arch-tegra2/gp_padctrl.h |    9 ++++++
 arch/arm/include/asm/arch-tegra2/tegra2.h     |   24 ++++++++++++++++
 4 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
index a6dd3e4..150fbfd 100644
--- a/arch/arm/cpu/armv7/tegra2/ap20.c
+++ b/arch/arm/cpu/armv7/tegra2/ap20.c
@@ -26,11 +26,47 @@
 #include <asm/arch/ap20.h>
 #include <asm/arch/clk_rst.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/fuse.h>
+#include <asm/arch/gp_padctrl.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 apb_misc_gp_ctlr *gp;
+	struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
+	uint tegra_sku_id, rev;
+
+	/*
+	 * This is undocumented, Chip ID is bits 15:8 of the register
+	 * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
+	 * Tegra30
+	 */
+	gp = (struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+	rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
+
+	tegra_sku_id = readl(&fuse->sku_info) & 0xff;
+
+	switch (rev) {
+	case CHIPID_TEGRA2:
+		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;
+		}
+		break;
+	}
+	/* 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)
 {
diff --git a/arch/arm/include/asm/arch-tegra2/ap20.h b/arch/arm/include/asm/arch-tegra2/ap20.h
index a4b4d73..d222c44 100644
--- a/arch/arm/include/asm/arch-tegra2/ap20.h
+++ b/arch/arm/include/asm/arch-tegra2/ap20.h
@@ -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);
diff --git a/arch/arm/include/asm/arch-tegra2/gp_padctrl.h b/arch/arm/include/asm/arch-tegra2/gp_padctrl.h
index 25bb46d..1755ab2 100644
--- a/arch/arm/include/asm/arch-tegra2/gp_padctrl.h
+++ b/arch/arm/include/asm/arch-tegra2/gp_padctrl.h
@@ -61,4 +61,13 @@ struct apb_misc_gp_ctlr {
 	u32	memcomp;	/* 0xD4: APB_MISC_GP_MEMCOMPPADCTRL */
 };
 
+/* bit fields definitions for APB_MISC_GP_HIDREV register */
+#define HIDREV_CHIPID_SHIFT		8
+#define HIDREV_CHIPID_MASK		(0xff << HIDREV_CHIPID_SHIFT)
+#define HIDREV_MAJORPREV_SHIFT		4
+#define HIDREV_MAJORPREV_MASK		(0xf << HIDREV_MAJORPREV_SHIFT)
+
+/* CHIPID field returned from APB_MISC_GP_HIDREV register */
+#define CHIPID_TEGRA2				0x20
+
 #endif
diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h b/arch/arm/include/asm/arch-tegra2/tegra2.h
index 2e152fd..d4ada10 100644
--- a/arch/arm/include/asm/arch-tegra2/tegra2.h
+++ b/arch/arm/include/asm/arch-tegra2/tegra2.h
@@ -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)
@@ -55,6 +56,29 @@
 struct timerus {
 	unsigned int cntr_1us;
 };
+
+/* Address@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
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 11/23] tegra: Add header file for APB_MISC register
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (9 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 10/23] tegra: Add tegra_get_chip_type() to detect SKU Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 12/23] tegra: Add EMC support for optimal memory timings Simon Glass
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

Add a basic header file for this register, to be filled in as needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Add apb_misc.h header file in new patch

 arch/arm/include/asm/arch-tegra2/apb_misc.h |   36 +++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-tegra2/apb_misc.h

diff --git a/arch/arm/include/asm/arch-tegra2/apb_misc.h b/arch/arm/include/asm/arch-tegra2/apb_misc.h
new file mode 100644
index 0000000..eb69d18
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/apb_misc.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * 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 _GP_PADCTRL_H_
+#define _GP_PADCTRL_H_
+
+/* APB_MISC_PP registers */
+struct apb_misc_pp_ctlr {
+	u32	reserved0[2];
+	u32	strapping_opt_a;/* 0x08: APB_MISC_PP_STRAPPING_OPT_A */
+};
+
+/* bit fields definitions for APB_MISC_PP_STRAPPING_OPT_A register */
+#define RAM_CODE_SHIFT		4
+#define RAM_CODE_MASK		(0xf << RAM_CODE_SHIFT)
+
+#endif
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 12/23] tegra: Add EMC support for optimal memory timings
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (10 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 11/23] tegra: Add header file for APB_MISC register Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-09 23:52   ` jimmzhang
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 13/23] tegra: Add PMU to manage power supplies Simon Glass
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Jimmy Zhang <jimmzhang@nvidia.com>

Add support for setting up the memory controller parameters. Boards
can set up an appropriate table in the device tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Add debug() output to EMC
- Move EMC tables to device tree

Changes in v3:
- Support nvidia,use-ram-code binding option for EMC
- Try to return a useful error code when EMC config fails

 arch/arm/cpu/armv7/tegra2/Makefile     |    1 +
 arch/arm/cpu/armv7/tegra2/emc.c        |  286 ++++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/emc.h |  113 +++++++++++++
 include/fdtdec.h                       |    2 +
 lib/fdtdec.c                           |    2 +
 5 files changed, 404 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/emc.c
 create mode 100644 arch/arm/include/asm/arch-tegra2/emc.h

diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile
index e9ac6c9..dcd6329 100644
--- a/arch/arm/cpu/armv7/tegra2/Makefile
+++ b/arch/arm/cpu/armv7/tegra2/Makefile
@@ -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)
diff --git a/arch/arm/cpu/armv7/tegra2/emc.c b/arch/arm/cpu/armv7/tegra2/emc.c
new file mode 100644
index 0000000..c0e5c56
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/emc.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * 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 <fdtdec.h>
+#include <asm/io.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/apb_misc.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/emc.h>
+#include <asm/arch/tegra2.h>
+
+/*
+ * 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
+ */
+
+/*
+ * This table defines the ordering of the registers provided to
+ * tegra_set_mmc()
+ * TODO: Convert to fdt version once available
+ */
+static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
+	0x2c,	/* RC */
+	0x30,	/* RFC */
+	0x34,	/* RAS */
+	0x38,	/* RP */
+	0x3c,	/* R2W */
+	0x40,	/* W2R */
+	0x44,	/* R2P */
+	0x48,	/* W2P */
+	0x4c,	/* RD_RCD */
+	0x50,	/* WR_RCD */
+	0x54,	/* RRD */
+	0x58,	/* REXT */
+	0x5c,	/* WDV */
+	0x60,	/* QUSE */
+	0x64,	/* QRST */
+	0x68,	/* QSAFE */
+	0x6c,	/* RDV */
+	0x70,	/* REFRESH */
+	0x74,	/* BURST_REFRESH_NUM */
+	0x78,	/* PDEX2WR */
+	0x7c,	/* PDEX2RD */
+	0x80,	/* PCHG2PDEN */
+	0x84,	/* ACT2PDEN */
+	0x88,	/* AR2PDEN */
+	0x8c,	/* RW2PDEN */
+	0x90,	/* TXSR */
+	0x94,	/* TCKE */
+	0x98,	/* TFAW */
+	0x9c,	/* TRPAB */
+	0xa0,	/* TCLKSTABLE */
+	0xa4,	/* TCLKSTOP */
+	0xa8,	/* TREFBW */
+	0xac,	/* QUSE_EXTRA */
+	0x114,	/* FBIO_CFG6 */
+	0xb0,	/* ODT_WRITE */
+	0xb4,	/* ODT_READ */
+	0x104,	/* FBIO_CFG5 */
+	0x2bc,	/* CFG_DIG_DLL */
+	0x2c0,	/* DLL_XFORM_DQS */
+	0x2c4,	/* DLL_XFORM_QUSE */
+	0x2e0,	/* ZCAL_REF_CNT */
+	0x2e4,	/* ZCAL_WAIT_CNT */
+	0x2a8,	/* AUTO_CAL_INTERVAL */
+	0x2d0,	/* CFG_CLKTRIM_0 */
+	0x2d4,	/* CFG_CLKTRIM_1 */
+	0x2d8,	/* CFG_CLKTRIM_2 */
+};
+
+struct emc_ctlr *emc_get_controller(const void *blob)
+{
+	fdt_addr_t addr;
+	int node;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC);
+	if (node > 0) {
+		addr = fdtdec_get_addr(blob, node, "reg");
+		if (addr != FDT_ADDR_T_NONE)
+			return (struct emc_ctlr *)addr;
+	}
+	return NULL;
+}
+
+/* Error codes we use */
+enum {
+	ERR_NO_EMC_NODE = -10,
+	ERR_NO_EMC_REG,
+	ERR_NO_FREQ,
+	ERR_FREQ_NOT_FOUND,
+	ERR_BAD_REGS,
+	ERR_NO_RAM_CODE,
+	ERR_RAM_CODE_NOT_FOUND,
+};
+
+/**
+ * Find EMC tables for the given ram code.
+ *
+ * The tegra EMC binding has two options, one using the ram code and one not.
+ * We detect which is in use by looking for the nvidia,use-ram-code property.
+ * If this is not present, then the EMC tables are directly below 'node',
+ * otherwise we select the correct emc-tables subnode based on the 'ram_code'
+ * value.
+ *
+ * @param blob		Device tree blob
+ * @param node		EMC node (nvidia,tegra20-emc compatible string)
+ * @param ram_code	RAM code to select (0-3, or -1 if unknown)
+ * @return 0 if ok, otherwise a -ve ERR_ code (see enum above)
+ */
+static int find_emc_tables(const void *blob, int node, int ram_code)
+{
+	int need_ram_code;
+	int depth;
+	int offset;
+
+	/* If we are using RAM codes, scan through the tables for our code */
+	need_ram_code = fdtdec_get_bool(blob, node, "nvidia,use-ram-code");
+	if (!need_ram_code)
+		return node;
+	if (ram_code == -1) {
+		debug("%s: RAM code required but not supplied\n", __func__);
+		return ERR_NO_RAM_CODE;
+	}
+
+	offset = node;
+	depth = 0;
+	do {
+		/*
+		 * Sadly there is no compatible string so we cannot use
+		 * fdtdec_next_compatible_subnode().
+		 */
+		offset = fdt_next_node(blob, offset, &depth);
+		if (depth <= 0)
+			break;
+
+		/* Make sure this is a direct subnode */
+		if (depth != 1)
+			continue;
+		if (strcmp("emc-tables", fdt_get_name(blob, offset, NULL)))
+			continue;
+
+		if (fdtdec_get_int(blob, offset, "nvidia,ram-code", -1)
+				== ram_code)
+			return offset;
+	} while (1);
+
+	debug("%s: Could not find tables for RAM code %d\n", __func__,
+	      ram_code);
+	return ERR_RAM_CODE_NOT_FOUND;
+}
+
+/**
+ * Decode the EMC node of the device tree, returning a pointer to the emc
+ * controller and the table to be used for the given rate.
+ *
+ * @param blob	Device tree blob
+ * @param rate	Clock speed of memory controller in Hz (=2x memory bus rate)
+ * @param emcp	Returns address of EMC controller registers
+ * @param tablep Returns pointer to table to program into EMC. There are
+ *		TEGRA_EMC_NUM_REGS entries, destined for offsets as per the
+ *		emc_reg_addr array.
+ * @return 0 if ok, otherwise a -ve error code which will allow someone to
+ * figure out roughly what went wrong by looking@this code.
+ */
+static int decode_emc(const void *blob, unsigned rate, struct emc_ctlr **emcp,
+		      const u32 **tablep)
+{
+	struct apb_misc_pp_ctlr *pp =
+		(struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE;
+	int ram_code;
+	int depth;
+	int node;
+
+	ram_code = (readl(&pp->strapping_opt_a) & RAM_CODE_MASK)
+			>> RAM_CODE_SHIFT;
+	/*
+	 * The EMC clock rate is twice the bus rate, and the bus rate is
+	 * measured in kHz
+	 */
+	rate = rate / 2 / 1000;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC);
+	if (node < 0) {
+		debug("%s: No EMC node found in FDT\n", __func__);
+		return ERR_NO_EMC_NODE;
+	}
+	*emcp = (struct emc_ctlr *)fdtdec_get_addr(blob, node, "reg");
+	if (*emcp == (struct emc_ctlr *)FDT_ADDR_T_NONE) {
+		debug("%s: No EMC node reg property\n", __func__);
+		return ERR_NO_EMC_REG;
+	}
+
+	/* Work out the parent node which contains our EMC tables */
+	node = find_emc_tables(blob, node, ram_code & 3);
+	if (node < 0)
+		return node;
+
+	depth = 0;
+	for (;;) {
+		int node_rate;
+
+		node = fdtdec_next_compatible_subnode(blob, node,
+				COMPAT_NVIDIA_TEGRA20_EMC_TABLE, &depth);
+		if (node < 0)
+			break;
+		node_rate = fdtdec_get_int(blob, node, "clock-frequency", -1);
+		if (node_rate == -1) {
+			debug("%s: Missing clock-frequency\n", __func__);
+			return ERR_NO_FREQ; /* we expect this property */
+		}
+
+		if (node_rate == rate)
+			break;
+	}
+	if (node < 0) {
+		debug("%s: No node found for clock frequency %d\n", __func__,
+		      rate);
+		return ERR_FREQ_NOT_FOUND;
+	}
+
+	*tablep = fdtdec_locate_array(blob, node, "nvidia,emc-registers",
+				      TEGRA_EMC_NUM_REGS);
+	if (!*tablep) {
+		debug("%s: node '%s' array missing / wrong size\n", __func__,
+		      fdt_get_name(blob, node, NULL));
+		return ERR_BAD_REGS;
+	}
+
+	/* All seems well */
+	return 0;
+}
+
+int tegra_set_emc(const void *blob, unsigned rate)
+{
+	struct emc_ctlr *emc;
+	const u32 *table;
+	int err, i;
+
+	err = decode_emc(blob, rate, &emc, &table);
+	if (err) {
+		debug("Warning: no valid EMC (%d), memory timings unset\n",
+		       err);
+		return err;
+	}
+
+	debug("%s: Table found, setting EMC values as follows:\n", __func__);
+	for (i = 0; i < TEGRA_EMC_NUM_REGS; i++) {
+		u32 value = fdt32_to_cpu(table[i]);
+		u32 addr = (uintptr_t)emc + emc_reg_addr[i];
+
+		debug("   %#x: %#x\n", addr, value);
+		writel(value, addr);
+	}
+
+	/* trigger emc with new settings */
+	clock_adjust_periph_pll_div(PERIPH_ID_EMC, CLOCK_ID_MEMORY,
+				clock_get_rate(CLOCK_ID_MEMORY), NULL);
+	debug("EMC clock set to %lu\n",
+	      clock_get_periph_rate(PERIPH_ID_EMC, CLOCK_ID_MEMORY));
+
+	return 0;
+}
diff --git a/arch/arm/include/asm/arch-tegra2/emc.h b/arch/arm/include/asm/arch-tegra2/emc.h
new file mode 100644
index 0000000..deb3d36
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/emc.h
@@ -0,0 +1,113 @@
+/*
+ * 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 _ARCH_EMC_H_
+#define _ARCH_EMC_H_
+
+#include <asm/types.h>
+
+#define TEGRA_EMC_NUM_REGS	46
+
+/* EMC Registers */
+struct emc_ctlr {
+	u32 cfg;		/* 0x00: EMC_CFG */
+	u32 reserved0[3];	/* 0x04 ~ 0x0C */
+	u32 adr_cfg;		/* 0x10: EMC_ADR_CFG */
+	u32 adr_cfg1;		/* 0x14: EMC_ADR_CFG_1 */
+	u32 reserved1[2];	/* 0x18 ~ 0x18 */
+	u32 refresh_ctrl;	/* 0x20: EMC_REFCTRL */
+	u32 pin;		/* 0x24: EMC_PIN */
+	u32 timing_ctrl;	/* 0x28: EMC_TIMING_CONTROL */
+	u32 rc;			/* 0x2C: EMC_RC */
+	u32 rfc;		/* 0x30: EMC_RFC */
+	u32 ras;		/* 0x34: EMC_RAS */
+	u32 rp;			/* 0x38: EMC_RP */
+	u32 r2w;		/* 0x3C: EMC_R2W */
+	u32 w2r;		/* 0x40: EMC_W2R */
+	u32 r2p;		/* 0x44: EMC_R2P */
+	u32 w2p;		/* 0x48: EMC_W2P */
+	u32 rd_rcd;		/* 0x4C: EMC_RD_RCD */
+	u32 wd_rcd;		/* 0x50: EMC_WD_RCD */
+	u32 rrd;		/* 0x54: EMC_RRD */
+	u32 rext;		/* 0x58: EMC_REXT */
+	u32 wdv;		/* 0x5C: EMC_WDV */
+	u32 quse;		/* 0x60: EMC_QUSE */
+	u32 qrst;		/* 0x64: EMC_QRST */
+	u32 qsafe;		/* 0x68: EMC_QSAFE */
+	u32 rdv;		/* 0x6C: EMC_RDV */
+	u32 refresh;		/* 0x70: EMC_REFRESH */
+	u32 burst_refresh_num;	/* 0x74: EMC_BURST_REFRESH_NUM */
+	u32 pdex2wr;		/* 0x78: EMC_PDEX2WR */
+	u32 pdex2rd;		/* 0x7c: EMC_PDEX2RD */
+	u32 pchg2pden;		/* 0x80: EMC_PCHG2PDEN */
+	u32 act2pden;		/* 0x84: EMC_ACT2PDEN */
+	u32 ar2pden;		/* 0x88: EMC_AR2PDEN */
+	u32 rw2pden;		/* 0x8C: EMC_RW2PDEN */
+	u32 txsr;		/* 0x90: EMC_TXSR */
+	u32 tcke;		/* 0x94: EMC_TCKE */
+	u32 tfaw;		/* 0x98: EMC_TFAW */
+	u32 trpab;		/* 0x9C: EMC_TRPAB */
+	u32 tclkstable;		/* 0xA0: EMC_TCLKSTABLE */
+	u32 tclkstop;		/* 0xA4: EMC_TCLKSTOP */
+	u32 trefbw;		/* 0xA8: EMC_TREFBW */
+	u32 quse_extra;		/* 0xAC: EMC_QUSE_EXTRA */
+	u32 odt_write;		/* 0xB0: EMC_ODT_WRITE */
+	u32 odt_read;		/* 0xB4: EMC_ODT_READ */
+	u32 reserved2[5];	/* 0xB8 ~ 0xC8 */
+	u32 mrs;		/* 0xCC: EMC_MRS */
+	u32 emrs;		/* 0xD0: EMC_EMRS */
+	u32 ref;		/* 0xD4: EMC_REF */
+	u32 pre;		/* 0xD8: EMC_PRE */
+	u32 nop;		/* 0xDC: EMC_NOP */
+	u32 self_ref;		/* 0xE0: EMC_SELF_REF */
+	u32 dpd;		/* 0xE4: EMC_DPD */
+	u32 mrw;		/* 0xE8: EMC_MRW */
+	u32 mrr;		/* 0xEC: EMC_MRR */
+	u32 reserved3;		/* 0xF0: */
+	u32 fbio_cfg1;		/* 0xF4: EMC_FBIO_CFG1 */
+	u32 fbio_dqsib_dly;	/* 0xF8: EMC_FBIO_DQSIB_DLY */
+	u32 fbio_dqsib_dly_msb;	/* 0xFC: EMC_FBIO_DQSIB_DLY_MSG */
+	u32 fbio_spare;		/* 0x100: SBIO_SPARE */
+				/* There are more registers ... */
+};
+
+/**
+ * Set up the EMC for the given rate. The timing parameters are retrieved
+ * from the device tree "nvidia,tegra20-emc" node and its
+ * "nvidia,tegra20-emc-table" sub-nodes.
+ *
+ * @param blob	Device tree blob
+ * @param rate	Clock speed of memory controller in Hz (=2x memory bus rate)
+ * @return 0 if ok, else -ve error code (look in emc.c to decode it)
+ */
+int tegra_set_emc(const void *blob, unsigned rate);
+
+/**
+ * Get a pointer to the EMC controller from the device tree.
+ *
+ * @param blob	Device tree blob
+ * @return pointer to EMC controller
+ */
+struct emc_ctlr *emc_get_controller(const void *blob);
+
+#endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 0351a25..49251d5 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -60,6 +60,8 @@ enum fdt_compat_id {
 	COMPAT_NVIDIA_TEGRA20_USB,	/* Tegra2 USB port */
 	COMPAT_NVIDIA_TEGRA20_I2C,	/* Tegra2 i2c */
 	COMPAT_NVIDIA_TEGRA20_DVC,	/* Tegra2 dvc (really just i2c) */
+	COMPAT_NVIDIA_TEGRA20_EMC,	/* Tegra2 memory controller */
+	COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra2 memory timing table */
 
 	COMPAT_COUNT,
 };
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 76d3808..42c3e89 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -40,6 +40,8 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"),
 	COMPAT(NVIDIA_TEGRA20_I2C, "nvidia,tegra20-i2c"),
 	COMPAT(NVIDIA_TEGRA20_DVC, "nvidia,tegra20-i2c-dvc"),
+	COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"),
+	COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 13/23] tegra: Add PMU to manage power supplies
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (11 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 12/23] tegra: Add EMC support for optimal memory timings Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-09 23:47   ` jimmzhang
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 14/23] tegra: Set up PMU for Nvidia boards Simon Glass
                   ` (10 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Jimmy Zhang <jimmzhang@nvidia.com>

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.

- Split PMU code into separate TPS6586X driver

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/arm/cpu/armv7/tegra2/Makefile     |    1 +
 arch/arm/cpu/armv7/tegra2/pmu.c        |   70 ++++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/pmu.h |   30 ++++++++++++++
 3 files changed, 101 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/pmu.c
 create mode 100644 arch/arm/include/asm/arch-tegra2/pmu.h

diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile
index dcd6329..dba684d 100644
--- a/arch/arm/cpu/armv7/tegra2/Makefile
+++ b/arch/arm/cpu/armv7/tegra2/Makefile
@@ -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)
diff --git a/arch/arm/cpu/armv7/tegra2/pmu.c b/arch/arm/cpu/armv7/tegra2/pmu.c
new file mode 100644
index 0000000..4673802
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/pmu.c
@@ -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
+ */
+
+#include <common.h>
+#include <tps6586x.h>
+#include <asm/io.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/tegra_i2c.h>
+#include <asm/arch/sys_proto.h>
+
+#define VDD_CORE_NOMINAL_T25	0x17	/* 1.3v */
+#define VDD_CPU_NOMINAL_T25	0x10	/* 1.125v */
+
+#define VDD_CORE_NOMINAL_T20	0x16	/* 1.275v */
+#define VDD_CPU_NOMINAL_T20	0x0f	/* 1.1v */
+
+#define VDD_RELATION		0x02	/*  50mv */
+#define VDD_TRANSITION_STEP	0x06	/* 150mv */
+#define VDD_TRANSITION_RATE	0x06	/* 3.52mv/us */
+
+int pmu_set_nominal(void)
+{
+	int core, cpu, bus;
+
+	/* by default, the table has been filled with T25 settings */
+	switch (tegra_get_chip_type()) {
+	case TEGRA_SOC_T20:
+		core = VDD_CORE_NOMINAL_T20;
+		cpu = VDD_CPU_NOMINAL_T20;
+		break;
+	case TEGRA_SOC_T25:
+		core = VDD_CORE_NOMINAL_T25;
+		cpu = VDD_CPU_NOMINAL_T25;
+		break;
+	default:
+		debug("%s: Unknown chip type\n", __func__);
+		return -1;
+	}
+
+	bus = tegra_i2c_get_dvc_bus_num();
+	if (bus == -1) {
+		debug("%s: Cannot find DVC I2C bus\n", __func__);
+		return -1;
+	}
+	tps6586x_init(bus);
+	tps6586x_set_pwm_mode(TPS6586X_PWM_SM1);
+	return tps6586x_adjust_sm0_sm1(core, cpu, VDD_TRANSITION_STEP,
+				VDD_TRANSITION_RATE, VDD_RELATION);
+}
diff --git a/arch/arm/include/asm/arch-tegra2/pmu.h b/arch/arm/include/asm/arch-tegra2/pmu.h
new file mode 100644
index 0000000..390815f
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/pmu.h
@@ -0,0 +1,30 @@
+/*
+ *  (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 _ARCH_PMU_H_
+#define _ARCH_PMU_H_
+
+/* Set core and CPU voltages to nominal levels */
+int pmu_set_nominal(void);
+
+#endif	/* _ARCH_PMU_H_ */
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 14/23] tegra: Set up PMU for Nvidia boards
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (12 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 13/23] tegra: Add PMU to manage power supplies Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation Simon Glass
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

Adjust PMU to permit maximum frequency operation.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Check error return from pmu_set_nominal() in debug mode

 board/nvidia/common/board.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 85dd359..640b9c4 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -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,10 @@ int board_init(void)
 #error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
 #endif
 	i2c_init_board();
+# ifdef CONFIG_TEGRA_PMU
+	if (pmu_set_nominal())
+		debug("Failed to select nominal voltages\n");
+# endif
 #endif
 
 #ifdef CONFIG_USB_EHCI_TEGRA
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (13 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 14/23] tegra: Set up PMU for Nvidia boards Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-03 18:56   ` Yen Lin
  2012-04-09 21:36   ` Stephen Warren
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 16/23] tegra: Setup PMC scratch info from ap20 setup Simon Glass
                   ` (8 subsequent siblings)
  23 siblings, 2 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Yen Lin <yelin@nvidia.com>

Add code to set up the warm boot area in the Tegra CPU ready for a
resume after suspend.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Stephen Warren <swarren@nvidia.com>
---
Changes in v2:
- Move structs shared between A9 and AVP into warmboot.h header file
- Remove unused crypto code
- Tidy SDRAM range check in warmboot_prepare_code()
- Use low-level clock functions in warmboot code instead of register access

 arch/arm/cpu/armv7/tegra2/Makefile          |    2 +
 arch/arm/cpu/armv7/tegra2/warmboot.c        |  382 +++++++++++++++++++++++++++
 arch/arm/cpu/armv7/tegra2/warmboot_avp.c    |  250 +++++++++++++++++
 arch/arm/cpu/armv7/tegra2/warmboot_avp.h    |   81 ++++++
 arch/arm/include/asm/arch-tegra2/warmboot.h |  150 +++++++++++
 5 files changed, 865 insertions(+), 0 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

diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile
index dba684d..08c4137 100644
--- a/arch/arm/cpu/armv7/tegra2/Makefile
+++ b/arch/arm/cpu/armv7/tegra2/Makefile
@@ -27,6 +27,7 @@
 # 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
 
@@ -37,6 +38,7 @@ 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
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/cpu/armv7/tegra2/warmboot.c b/arch/arm/cpu/armv7/tegra2/warmboot.c
new file mode 100644
index 0000000..fdfcf2e
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/warmboot.c
@@ -0,0 +1,382 @@
+/*
+ * (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/io.h>
+#include <asm/errno.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/pmc.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/fuse.h>
+#include <asm/arch/emc.h>
+#include <asm/arch/gp_padctrl.h>
+#include <asm/arch/warmboot.h>
+#include <asm/arch/sdram_param.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This is the place in SRAM where the SDRAM parameters are stored. There
+ * are 4 blocks, one for each RAM code
+ */
+#define SDRAM_PARAMS_BASE	(AP20_BASE_PA_SRAM + 0x188)
+
+/* TODO: If we later add support for the Misc GP controller, refactor this */
+union xm2cfga_reg {
+	struct {
+		u32 reserved0:2;
+		u32 hsm_en:1;
+		u32 reserved1:2;
+		u32 preemp_en:1;
+		u32 vref_en:1;
+		u32 reserved2:5;
+		u32 cal_drvdn:5;
+		u32 reserved3:3;
+		u32 cal_drvup:5;
+		u32 reserved4:3;
+		u32 cal_drvdn_slwr:2;
+		u32 cal_drvup_slwf:2;
+	};
+	u32 word;
+};
+
+union xm2cfgd_reg {
+	struct {
+		u32 reserved0:2;
+		u32 hsm_en:1;
+		u32 schmt_en:1;
+		u32 lpmd:2;
+		u32 vref_en:1;
+		u32 reserved1:5;
+		u32 cal_drvdn:5;
+		u32 reserved2:3;
+		u32 cal_drvup:5;
+		u32 reserved3:3;
+		u32 cal_drvdn_slwr:2;
+		u32 cal_drvup_slwf:2;
+	};
+	u32 word;
+};
+
+/*
+ * TODO: This register is not documented in the TRM yet. We could move this
+ * into the EMC and give it a proper interface, but not while it is
+ * undocumented.
+ */
+union fbio_spare_reg {
+	struct {
+		u32 reserved:24;
+		u32 cfg_wb0:8;
+	};
+	u32 word;
+};
+
+/* We pack the resume information into these unions for later */
+union scratch2_reg {
+	struct {
+		u32 pllm_base_divm:5;
+		u32 pllm_base_divn:10;
+		u32 pllm_base_divp:3;
+		u32 pllm_misc_lfcon:4;
+		u32 pllm_misc_cpcon:4;
+		u32 gp_xm2cfga_padctrl_preemp:1;
+		u32 gp_xm2cfgd_padctrl_schmt:1;
+		u32 osc_ctrl_xobp:1;
+		u32 memory_type:3;
+	};
+	u32 word;
+};
+
+union scratch4_reg {
+	struct {
+		u32 emc_clock_divider:8;
+		u32 pllm_stable_time:8;
+		u32 pllx_stable_time:8;
+		u32 emc_fbio_spare_cfg_wb0:8;
+	};
+	u32 word;
+};
+
+union scratch24_reg {
+	struct {
+		u32 emc_auto_cal_wait:8;
+		u32 emc_pin_program_wait:8;
+		u32 warmboot_wait:8;
+		u32 reserved:8;
+	};
+	u32 word;
+};
+
+int warmboot_save_sdram_params(void)
+{
+	u32 ram_code;
+	struct sdram_params sdram;
+	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 apb_misc_gp_ctlr *gp =
+			(struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+	struct emc_ctlr *emc = emc_get_controller(gd->fdt_blob);
+	union scratch2_reg scratch2;
+	union scratch4_reg scratch4;
+	union scratch24_reg scratch24;
+	union xm2cfga_reg xm2cfga;
+	union xm2cfgd_reg xm2cfgd;
+	union fbio_spare_reg fbio_spare;
+
+	/* get ram code that is used as index to array sdram_params in BCT */
+	ram_code = (readl(&pmt->pmt_strap_opt_a) >>
+			STRAP_OPT_A_RAM_CODE_SHIFT) & 3;
+	memcpy(&sdram,
+	       (char *)((struct sdram_params *)SDRAM_PARAMS_BASE + ram_code),
+	       sizeof(sdram));
+
+	xm2cfga.word = readl(&gp->xm2cfga);
+	xm2cfgd.word = readl(&gp->xm2cfgd);
+
+	scratch2.word = 0;
+	scratch2.osc_ctrl_xobp = clock_get_osc_bypass();
+
+	/* Get the memory PLL settings */
+	{
+		u32 divm, divn, divp, cpcon, lfcon;
+
+		if (clock_ll_read_pll(CLOCK_ID_MEMORY, &divm, &divn, &divp,
+					&cpcon, &lfcon))
+			return -1;
+		scratch2.pllm_base_divm = divm;
+		scratch2.pllm_base_divn = divn;
+		scratch2.pllm_base_divp = divp;
+		scratch2.pllm_misc_cpcon = cpcon;
+		scratch2.pllm_misc_lfcon = lfcon;
+	}
+
+	scratch2.gp_xm2cfga_padctrl_preemp = xm2cfga.preemp_en;
+	scratch2.gp_xm2cfgd_padctrl_schmt = xm2cfgd.schmt_en;
+	scratch2.memory_type = sdram.memory_type;
+	writel(scratch2.word, &pmc->pmc_scratch2);
+
+	/* collect data from various sources for pmc_scratch4 */
+	fbio_spare.word = readl(&emc->fbio_spare);
+	scratch4.word = 0;
+	scratch4.emc_fbio_spare_cfg_wb0 = fbio_spare.cfg_wb0;
+	scratch4.emc_clock_divider = sdram.emc_clock_divider;
+	scratch4.pllm_stable_time = -1;
+	scratch4.pllx_stable_time = -1;
+	writel(scratch4.word, &pmc->pmc_scratch4);
+
+	/* collect various data from sdram for pmc_scratch24 */
+	scratch24.word = 0;
+	scratch24.emc_pin_program_wait = sdram.emc_pin_program_wait;
+	scratch24.emc_auto_cal_wait = sdram.emc_auto_cal_wait;
+	scratch24.warmboot_wait = sdram.warm_boot_wait;
+	writel(scratch24.word, &pmc->pmc_scratch24);
+
+	return 0;
+}
+
+static u32 get_major_version(void)
+{
+	u32 major_id;
+	struct apb_misc_gp_ctlr *gp =
+		(struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+
+	major_id = (readl(&gp->hidrev) & HIDREV_MAJORPREV_MASK) >>
+			HIDREV_MAJORPREV_SHIFT;
+	return major_id;
+}
+
+static int is_production_mode_fuse_set(struct fuse_regs *fuse)
+{
+	return readl(&fuse->production_mode);
+}
+
+static int is_odm_production_mode_fuse_set(struct fuse_regs *fuse)
+{
+	return readl(&fuse->security_mode);
+}
+
+static int is_failure_analysis_mode(struct fuse_regs *fuse)
+{
+	return readl(&fuse->fa);
+}
+
+static int ap20_is_odm_production_mode(void)
+{
+	struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
+
+	if (!is_failure_analysis_mode(fuse) &&
+	    is_odm_production_mode_fuse_set(fuse))
+		return 1;
+	else
+		return 0;
+}
+
+static int ap20_is_production_mode(void)
+{
+	struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
+
+	if (get_major_version() == 0)
+		return 1;
+
+	if (!is_failure_analysis_mode(fuse) &&
+	    is_production_mode_fuse_set(fuse) &&
+	    !is_odm_production_mode_fuse_set(fuse))
+		return 1;
+	else
+		return 0;
+}
+
+static enum fuse_operating_mode fuse_get_operation_mode(void)
+{
+	u32 chip_id;
+	struct apb_misc_gp_ctlr *gp =
+		(struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+
+	chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >>
+			HIDREV_CHIPID_SHIFT;
+	if (chip_id == CHIPID_TEGRA2) {
+		if (ap20_is_odm_production_mode()) {
+			printf("!! odm_production_mode is not supported !!\n");
+			return MODE_UNDEFINED;
+		} else
+			if (ap20_is_production_mode())
+				return MODE_PRODUCTION;
+			else
+				return MODE_UNDEFINED;
+	}
+	return MODE_UNDEFINED;
+}
+
+static void determine_crypto_options(int *is_encrypted, int *is_signed,
+				     int *use_zero_key)
+{
+	switch (fuse_get_operation_mode()) {
+	case MODE_PRODUCTION:
+		*is_encrypted = 0;
+		*is_signed = 1;
+		*use_zero_key = 1;
+		break;
+	case MODE_UNDEFINED:
+	default:
+		*is_encrypted = 0;
+		*is_signed = 0;
+		*use_zero_key  = 0;
+		break;
+	}
+}
+
+static int sign_wb_code(u32 start, u32 length, int use_zero_key)
+{
+	int err;
+	u8 *source;		/* Pointer to source */
+	u8 *hash;
+
+	/* Calculate AES block parameters. */
+	source = (u8 *)(start + offsetof(struct wb_header, random_aes_block));
+	length -= offsetof(struct wb_header, random_aes_block);
+	hash = (u8 *)(start + offsetof(struct wb_header, hash));
+	err = sign_data_block(source, length, hash);
+
+	return err;
+}
+
+int warmboot_prepare_code(u32 seg_address, u32 seg_length)
+{
+	int err = 0;
+	u32 length;			/* length of the signed/encrypt code */
+	struct wb_header *dst_header;	/* Pointer to dest WB header */
+	int is_encrypted;		/* Segment is encrypted */
+	int is_signed;			/* Segment is signed */
+	int use_zero_key;		/* Use key of all zeros */
+
+	/* Determine crypto options. */
+	determine_crypto_options(&is_encrypted, &is_signed, &use_zero_key);
+
+	/* Get the actual code limits. */
+	length = roundup(((u32)wb_end - (u32)wb_start), 16);
+
+	/*
+	 * The region specified by seg_address must be in SDRAM and must be
+	 * nonzero in length.
+	 */
+	if (seg_length == 0 || seg_address < NV_PA_SDRAM_BASE ||
+		seg_address + seg_length >= NV_PA_SDRAM_BASE + gd->ram_size) {
+		err = -EFAULT;
+		goto fail;
+	}
+
+	/* Things must be 16-byte aligned. */
+	if ((seg_length & 0xF) || (seg_address & 0xF)) {
+		err = -EINVAL;
+		goto fail;
+	}
+
+	/* Will the code fit? (destination includes wb_header + wb code) */
+	if (seg_length < (length + sizeof(struct wb_header))) {
+		err = -EINVAL;
+		goto fail;
+	}
+
+	dst_header = (struct wb_header *)seg_address;
+	memset((char *)dst_header, 0, sizeof(struct wb_header));
+
+	/* 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 {
+			*aes_block++ = 0;
+		} while (aes_block < end);
+	}
+
+	/* Populate the header. */
+	dst_header->length_insecure = length + sizeof(struct wb_header);
+	dst_header->length_secure = length + sizeof(struct wb_header);
+	dst_header->destination = AP20_WB_RUN_ADDRESS;
+	dst_header->entry_point = AP20_WB_RUN_ADDRESS;
+	dst_header->code_length = length;
+
+	if (is_encrypted) {
+		printf("!!!! Encryption is not supported !!!!\n");
+		dst_header->length_insecure = 0;
+		err = -EACCES;
+		goto fail;
+	} else
+		/* copy the wb code directly following dst_header. */
+		memcpy((char *)(dst_header+1), (char *)wb_start, length);
+
+	if (is_signed)
+		err = sign_wb_code(seg_address, dst_header->length_insecure,
+				   use_zero_key);
+
+fail:
+	if (err)
+		printf("Warning: warmboot code copy failed (error=%d)\n", err);
+
+	return err;
+}
diff --git a/arch/arm/cpu/armv7/tegra2/warmboot_avp.c b/arch/arm/cpu/armv7/tegra2/warmboot_avp.c
new file mode 100644
index 0000000..70bcd8e
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/warmboot_avp.c
@@ -0,0 +1,250 @@
+/*
+ * (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/io.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/flow.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/pmc.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/warmboot.h>
+#include "warmboot_avp.h"
+
+#define DEBUG_RESET_CORESIGHT
+
+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 */
+	);
+
+	if (reg != AP20_WB_RUN_ADDRESS)
+		goto do_reset;
+
+	/* Are we running with AVP? */
+	if (readl(NV_PA_PG_UP_BASE + PG_UP_TAG_0) != PG_UP_TAG_AVP)
+		goto do_reset;
+
+#ifdef DEBUG_RESET_CORESIGHT
+	/* Assert CoreSight reset */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]);
+	reg |= SWR_CSITE_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]);
+#endif
+
+	/* TODO: Set the drive strength - maybe make this a board parameter? */
+	osc_ctrl.word = readl(&clkrst->crc_osc_ctrl);
+	osc_ctrl.xofs = 4;
+	osc_ctrl.xoe = 1;
+	writel(osc_ctrl.word, &clkrst->crc_osc_ctrl);
+
+	/* Power up the CPU complex if necessary */
+	if (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) {
+		reg = PWRGATE_TOGGLE_PARTID_CPU | PWRGATE_TOGGLE_START;
+		writel(reg, &pmc->pmc_pwrgate_toggle);
+		while (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU))
+			;
+	}
+
+	/* Remove the I/O clamps from the CPU power partition. */
+	reg = readl(&pmc->pmc_remove_clamping);
+	reg |= CPU_CLMP;
+	writel(reg, &pmc->pmc_remove_clamping);
+
+	reg = EVENT_ZERO_VAL_20 | EVENT_MSEC | EVENT_MODE_STOP;
+	writel(reg, &flow->halt_cop_events);
+
+	/* Assert CPU complex reset */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]);
+	reg |= CPU_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
+
+	/* Hold both CPUs in reset */
+	reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_CPURESET1 | CPU_CMPLX_DERESET0 |
+	      CPU_CMPLX_DERESET1 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DBGRESET1;
+	writel(reg, &clkrst->crc_cpu_cmplx_set);
+
+	/* Halt CPU1 at the flow controller for uni-processor configurations */
+	writel(EVENT_MODE_STOP, &flow->halt_cpu1_events);
+
+	/*
+	 * Set the CPU reset vector. SCRATCH41 contains the physical
+	 * address of the CPU-side restoration code.
+	 */
+	reg = readl(&pmc->pmc_scratch41);
+	writel(reg, EXCEP_VECTOR_CPU_RESET_VECTOR);
+
+	/* Select CPU complex clock source */
+	writel(CCLK_PLLP_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
+
+	/* Start the CPU0 clock and stop the CPU1 clock */
+	reg = CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 | CPU_CMPLX_CPU0_CLK_STP_RUN |
+	      CPU_CMPLX_CPU1_CLK_STP_STOP;
+	writel(reg, &clkrst->crc_clk_cpu_cmplx);
+
+	/* Enable the CPU complex clock */
+	reg = readl(&clkrst->crc_clk_out_enb[TEGRA_DEV_L]);
+	reg |= CLK_ENB_CPU;
+	writel(reg, &clkrst->crc_clk_out_enb[TEGRA_DEV_L]);
+
+	/* Make sure the resets were held for at least 2 microseconds */
+	reg = readl(TIMER_USEC_CNTR);
+	while (readl(TIMER_USEC_CNTR) <= (reg + 2))
+		;
+
+#ifdef DEBUG_RESET_CORESIGHT
+	/*
+	 * De-assert CoreSight reset.
+	 * NOTE: We're leaving the CoreSight clock on the oscillator for
+	 *	now. It will be restored to its original clock source
+	 *	when the CPU-side restoration code runs.
+	 */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]);
+	reg &= ~SWR_CSITE_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]);
+#endif
+
+	/* Unlock the CPU CoreSight interfaces */
+	reg = 0xC5ACCE55;
+	writel(reg, CSITE_CPU_DBG0_LAR);
+	writel(reg, CSITE_CPU_DBG1_LAR);
+
+	/*
+	 * Sample the microsecond timestamp again. This is the time we must
+	 * use when returning from LP0 for PLL stabilization delays.
+	 */
+	reg = readl(TIMER_USEC_CNTR);
+	writel(reg, &pmc->pmc_scratch1);
+
+	pllx_base.word = 0;
+	pllx_misc.word = 0;
+	scratch3.word = readl(&pmc->pmc_scratch3);
+
+	/* Get the OSC. For 19.2 MHz, use 19 to make the calculations easier */
+	reg = (readl(TIMER_USEC_CFG) & USEC_CFG_DIVISOR_MASK) + 1;
+
+	/*
+	 * According to the TRM, for 19.2MHz OSC, the USEC_DIVISOR is 0x5f, and
+	 * USEC_DIVIDEND is 0x04. So, if USEC_DIVISOR > 26, OSC is 19.2 MHz.
+	 *
+	 * reg is used to calculate the pllx freq, which is used to determine if
+	 * to set dccon or not.
+	 */
+	if (reg > 26)
+		reg = 19;
+
+	/* PLLX_BASE.PLLX_DIVM */
+	if (scratch3.pllx_base_divm == reg)
+		reg = 0;
+	else
+		reg = 1;
+
+	/* PLLX_BASE.PLLX_DIVN */
+	pllx_base.divn = scratch3.pllx_base_divn;
+	reg = scratch3.pllx_base_divn << reg;
+
+	/* PLLX_BASE.PLLX_DIVP */
+	pllx_base.divp = scratch3.pllx_base_divp;
+	reg = reg >> scratch3.pllx_base_divp;
+
+	pllx_base.bypass = 1;
+
+	/* PLLX_MISC_DCCON must be set for pllx frequency > 600 MHz. */
+	if (reg > 600)
+		pllx_misc.dccon = 1;
+
+	/* PLLX_MISC_LFCON */
+	pllx_misc.lfcon = scratch3.pllx_misc_lfcon;
+
+	/* PLLX_MISC_CPCON */
+	pllx_misc.cpcon = scratch3.pllx_misc_cpcon;
+
+	writel(pllx_misc.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_misc);
+	writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+
+	pllx_base.enable = 1;
+	writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+	pllx_base.bypass = 0;
+	writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+
+	writel(0, flow->halt_cpu_events);
+
+	reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DERESET0;
+	writel(reg, &clkrst->crc_cpu_cmplx_clr);
+
+	reg = PLLM_OUT1_RSTN_RESET_DISABLE | PLLM_OUT1_CLKEN_ENABLE |
+	      PLLM_OUT1_RATIO_VAL_8;
+	writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out);
+
+	reg = SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 | SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 |
+	      SCLK_SWAKE_RUN_SRC_PLLM_OUT1 | SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 |
+	      SCLK_SYS_STATE_IDLE;
+	writel(reg, &clkrst->crc_sclk_brst_pol);
+
+	/* avp_resume: no return after the write */
+	reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]);
+	reg &= ~CPU_RST;
+	writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
+
+	/* avp_halt: */
+avp_halt:
+	reg = EVENT_MODE_STOP | EVENT_JTAG;
+	writel(reg, flow->halt_cop_events);
+	goto avp_halt;
+
+do_reset:
+	/*
+	 * Execution comes here if something goes wrong. The chip is reset and
+	 * a cold boot is performed.
+	 */
+	writel(SWR_TRIG_SYS_RST, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
+	goto do_reset;
+}
+
+/*
+ * wb_end() is a dummy function, and must be directly following wb_start(),
+ * and is used to calculate the size of wb_start().
+ */
+void wb_end(void)
+{
+}
diff --git a/arch/arm/cpu/armv7/tegra2/warmboot_avp.h b/arch/arm/cpu/armv7/tegra2/warmboot_avp.h
new file mode 100644
index 0000000..4b71c07
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/warmboot_avp.h
@@ -0,0 +1,81 @@
+/*
+ * (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 _WARMBOOT_AVP_H_
+#define _WARMBOOT_AVP_H_
+
+#define TEGRA_DEV_L			0
+#define TEGRA_DEV_H			1
+#define TEGRA_DEV_U			2
+
+#define SIMPLE_PLLX			(CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE)
+#define SIMPLE_PLLE			(CLOCK_ID_EPCI - CLOCK_ID_FIRST_SIMPLE)
+
+#define TIMER_USEC_CNTR			(NV_PA_TMRUS_BASE + 0)
+#define TIMER_USEC_CFG			(NV_PA_TMRUS_BASE + 4)
+
+#define USEC_CFG_DIVISOR_MASK		0xffff
+
+#define CONFIG_CTL_TBE			(1 << 7)
+#define CONFIG_CTL_JTAG			(1 << 6)
+
+#define CPU_RST				(1 << 0)
+#define CLK_ENB_CPU			(1 << 0)
+#define SWR_TRIG_SYS_RST		(1 << 2)
+#define SWR_CSITE_RST			(1 << 9)
+
+#define PWRGATE_STATUS_CPU		(1 << 0)
+#define PWRGATE_TOGGLE_PARTID_CPU	(0 << 0)
+#define PWRGATE_TOGGLE_START		(1 << 8)
+
+#define CPU_CMPLX_CPU_BRIDGE_CLKDIV_4	(3 << 0)
+#define CPU_CMPLX_CPU0_CLK_STP_STOP	(1 << 8)
+#define CPU_CMPLX_CPU0_CLK_STP_RUN	(0 << 8)
+#define CPU_CMPLX_CPU1_CLK_STP_STOP	(1 << 9)
+#define CPU_CMPLX_CPU1_CLK_STP_RUN	(0 << 9)
+
+#define CPU_CMPLX_CPURESET0		(1 << 0)
+#define CPU_CMPLX_CPURESET1		(1 << 1)
+#define CPU_CMPLX_DERESET0		(1 << 4)
+#define CPU_CMPLX_DERESET1		(1 << 5)
+#define CPU_CMPLX_DBGRESET0		(1 << 12)
+#define CPU_CMPLX_DBGRESET1		(1 << 13)
+
+#define PLLM_OUT1_RSTN_RESET_DISABLE	(1 << 0)
+#define PLLM_OUT1_CLKEN_ENABLE		(1 << 1)
+#define PLLM_OUT1_RATIO_VAL_8		(8 << 8)
+
+#define SCLK_SYS_STATE_IDLE		(1 << 28)
+#define SCLK_SWAKE_FIQ_SRC_PLLM_OUT1	(7 << 12)
+#define SCLK_SWAKE_IRQ_SRC_PLLM_OUT1	(7 << 8)
+#define SCLK_SWAKE_RUN_SRC_PLLM_OUT1	(7 << 4)
+#define SCLK_SWAKE_IDLE_SRC_PLLM_OUT1	(7 << 0)
+
+#define EVENT_ZERO_VAL_20		(20 << 0)
+#define EVENT_MSEC			(1 << 24)
+#define EVENT_JTAG			(1 << 28)
+#define EVENT_MODE_STOP			(2 << 29)
+
+#define CCLK_PLLP_BURST_POLICY		0x20004444
+
+#endif
diff --git a/arch/arm/include/asm/arch-tegra2/warmboot.h b/arch/arm/include/asm/arch-tegra2/warmboot.h
new file mode 100644
index 0000000..99ac2e7
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/warmboot.h
@@ -0,0 +1,150 @@
+/*
+ * (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 _WARM_BOOT_H_
+#define _WARM_BOOT_H_
+
+#define STRAP_OPT_A_RAM_CODE_SHIFT	4
+#define STRAP_OPT_A_RAM_CODE_MASK	(0xf << STRAP_OPT_A_RAM_CODE_SHIFT)
+
+/* Defines the supported operating modes */
+enum fuse_operating_mode {
+	MODE_PRODUCTION = 3,
+	MODE_UNDEFINED,
+};
+
+/* Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) */
+enum {
+	HASH_LENGTH = 4
+};
+
+/* Defines the storage for a hash value (128 bits) */
+struct hash {
+	u32 hash[HASH_LENGTH];
+};
+
+/*
+ * 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_insecure;	/* length of the code header */
+	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 */
+};
+
+/*
+ * The warm boot code needs direct access to these registers since it runs in
+ * SRAM and cannot call other U-Boot code.
+ */
+union osc_ctrl_reg {
+	struct {
+		u32 xoe:1;
+		u32 xobp:1;
+		u32 reserved0:2;
+		u32 xofs:6;
+		u32 reserved1:2;
+		u32 xods:5;
+		u32 reserved2:3;
+		u32 oscfi_spare:8;
+		u32 pll_ref_div:2;
+		u32 osc_freq:2;
+	};
+	u32 word;
+};
+
+union pllx_base_reg {
+	struct {
+		u32 divm:5;
+		u32 reserved0:3;
+		u32 divn:10;
+		u32 reserved1:2;
+		u32 divp:3;
+		u32 reserved2:4;
+		u32 lock:1;
+		u32 reserved3:1;
+		u32 ref_dis:1;
+		u32 enable:1;
+		u32 bypass:1;
+	};
+	u32 word;
+};
+
+union pllx_misc_reg {
+	struct {
+		u32 vcocon:4;
+		u32 lfcon:4;
+		u32 cpcon:4;
+		u32 lock_sel:6;
+		u32 reserved0:1;
+		u32 lock_enable:1;
+		u32 reserved1:1;
+		u32 dccon:1;
+		u32 pts:2;
+		u32 reserved2:6;
+		u32 out1_div_byp:1;
+		u32 out1_inv_clk:1;
+	};
+	u32 word;
+};
+
+/*
+ * TODO: This register is not documented in the TRM yet. We could move this
+ * into the EMC and give it a proper interface, but not while it is
+ * undocumented.
+ */
+union scratch3_reg {
+	struct {
+		u32 pllx_base_divm:5;
+		u32 pllx_base_divn:10;
+		u32 pllx_base_divp:3;
+		u32 pllx_misc_lfcon:4;
+		u32 pllx_misc_cpcon:4;
+	};
+	u32 word;
+};
+
+
+/**
+ * Save warmboot memory settings for a later resume
+ *
+ * @return 0 if ok, -1 on error
+ */
+int warmboot_save_sdram_params(void);
+
+int warmboot_prepare_code(u32 seg_address, u32 seg_length);
+int sign_data_block(u8 *source, u32 length, u8 *signature);
+void wb_start(void);	/* Start of WB assembly code */
+void wb_end(void);	/* End of WB assembly code */
+
+#endif
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 16/23] tegra: Setup PMC scratch info from ap20 setup
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (14 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-03 18:57   ` Yen Lin
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 17/23] tegra: Set up warmboot code on Nvidia boards Simon Glass
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Yen Lin <yelin@nvidia.com>

Save SDRAM parameters into the warmboot scratch registers

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/arm/cpu/armv7/tegra2/ap20.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
index 150fbfd..698bfd0 100644
--- a/arch/arm/cpu/armv7/tegra2/ap20.c
+++ b/arch/arm/cpu/armv7/tegra2/ap20.c
@@ -31,6 +31,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)
@@ -322,6 +323,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)
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 17/23] tegra: Set up warmboot code on Nvidia boards
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (15 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 16/23] tegra: Setup PMC scratch info from ap20 setup Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 18/23] tegra: Turn off power detect in board init Simon Glass
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

Call the function to put warmboot boot in a suitable place for resume.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 board/nvidia/common/board.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 640b9c4..b82e61a 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -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>
@@ -94,6 +95,11 @@ 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
+
 	return 0;
 }
 
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 18/23] tegra: Turn off power detect in board init
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (16 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 17/23] tegra: Set up warmboot code on Nvidia boards Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-10  6:02   ` Wei Ni
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 19/23] tegra: Add EMC settings for Seaboard Simon Glass
                   ` (5 subsequent siblings)
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Wei Ni <wni@nvidia.com>

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).

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Fix CONFIG_TEGRA_I2C define

 board/nvidia/common/board.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index b82e61a..1d6b002 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -62,6 +62,21 @@ void __pin_mux_usb(void)
 void pin_mux_usb(void) __attribute__((weak, alias("__pin_mux_usb")));
 
 /*
+ * 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.
  */
@@ -79,6 +94,9 @@ int board_init(void)
 #endif
 	/* boot param addr */
 	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
+
+	power_det_init();
+
 #ifdef CONFIG_TEGRA_I2C
 #ifndef CONFIG_SYS_I2C_INIT_BOARD
 #error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 19/23] tegra: Add EMC settings for Seaboard
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (17 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 18/23] tegra: Turn off power detect in board init Simon Glass
@ 2012-04-02 23:18 ` Simon Glass
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 20/23] fdt: tegra: Add EMC node to device tree Simon Glass
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:18 UTC (permalink / raw)
  To: u-boot

From: Jimmy Zhang <jimmzhang@nvidia.com>

Set Seaboard to optimal memory settings based on the SOC in use (T20 or T25).

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Move EMC tables to device tree
- Removed check for nominal voltage (not needed as it is done just before)

Changes in v3:
- Add better error reporting when EMC setup fails

 board/nvidia/common/Makefile |    1 +
 board/nvidia/common/board.c  |   13 ++++++++-
 board/nvidia/common/emc.c    |   53 ++++++++++++++++++++++++++++++++++++++++++
 board/nvidia/common/emc.h    |   29 +++++++++++++++++++++++
 4 files changed, 94 insertions(+), 2 deletions(-)
 create mode 100644 board/nvidia/common/emc.c
 create mode 100644 board/nvidia/common/emc.h

diff --git a/board/nvidia/common/Makefile b/board/nvidia/common/Makefile
index 3e748fd..a93d458 100644
--- a/board/nvidia/common/Makefile
+++ b/board/nvidia/common/Makefile
@@ -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)
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 1d6b002..e2cdb6e 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -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/pinmux.h>
 #include <asm/arch/pmc.h>
 #include <asm/arch/pmu.h>
@@ -39,6 +40,7 @@
 #include <asm/arch/usb.h>
 #include <i2c.h>
 #include "board.h"
+#include "emc.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -82,6 +84,8 @@ static void power_det_init(void)
  */
 int board_init(void)
 {
+	int err;
+
 	/* Do clocks and UART first so that printf() works */
 	clock_init();
 	clock_verify();
@@ -105,8 +109,13 @@ int board_init(void)
 # ifdef CONFIG_TEGRA_PMU
 	if (pmu_set_nominal())
 		debug("Failed to select nominal voltages\n");
-# endif
-#endif
+#  ifdef CONFIG_TEGRA_CLOCK_SCALING
+	err = board_emc_init();
+	if (err)
+		debug("Memory controller init failed: %d\n", err);
+#  endif
+# endif /* CONFIG_TEGRA_PMU */
+#endif /* CONFIG_TEGRA_I2C */
 
 #ifdef CONFIG_USB_EHCI_TEGRA
 	pin_mux_usb();
diff --git a/board/nvidia/common/emc.c b/board/nvidia/common/emc.c
new file mode 100644
index 0000000..8e4290c
--- /dev/null
+++ b/board/nvidia/common/emc.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * 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/io.h>
+#include <asm/arch/ap20.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/emc.h>
+#include <asm/arch/pmu.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/tegra2.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* These rates are hard-coded for now, until fdt provides them */
+#define EMC_SDRAM_RATE_T20	(333000 * 2 * 1000)
+#define EMC_SDRAM_RATE_T25	(380000 * 2 * 1000)
+
+int board_emc_init(void)
+{
+	unsigned rate;
+
+	switch (tegra_get_chip_type()) {
+	default:
+	case TEGRA_SOC_T20:
+		rate  = EMC_SDRAM_RATE_T20;
+		break;
+	case TEGRA_SOC_T25:
+		rate  = EMC_SDRAM_RATE_T25;
+		break;
+	}
+	return tegra_set_emc(gd->fdt_blob, rate);
+}
diff --git a/board/nvidia/common/emc.h b/board/nvidia/common/emc.h
new file mode 100644
index 0000000..ec1b115
--- /dev/null
+++ b/board/nvidia/common/emc.h
@@ -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
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 20/23] fdt: tegra: Add EMC node to device tree
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (18 preceding siblings ...)
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 19/23] tegra: Add EMC settings for Seaboard Simon Glass
@ 2012-04-02 23:19 ` Simon Glass
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 21/23] tegra: i2c: Add function to find DVC bus Simon Glass
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:19 UTC (permalink / raw)
  To: u-boot

Add a definition of the memory controller node according to the bindings
here:

http://patchwork.ozlabs.org/patch/132928/

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/arm/dts/tegra20.dtsi |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index d5ca02c..bc64f42 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -193,4 +193,11 @@
 		clocks = <&tegra_car 59>;	/* PERIPH_ID_USB3 */
 	};
 
+	emc at 7000f400 {
+		#address-cells = < 1 >;
+		#size-cells = < 0 >;
+		compatible = "nvidia,tegra20-emc";
+		reg = <0x7000f400 0x200>;
+	};
+
 };
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 21/23] tegra: i2c: Add function to find DVC bus
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (19 preceding siblings ...)
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 20/23] fdt: tegra: Add EMC node to device tree Simon Glass
@ 2012-04-02 23:19 ` Simon Glass
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard Simon Glass
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:19 UTC (permalink / raw)
  To: u-boot

Add tegra_i2c_get_dvc_bus_num() to obtain the I2C bus number of DVC bus.
This allows us to talk to the PMU.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Add patch to find DVC bus number

 arch/arm/include/asm/arch-tegra2/tegra_i2c.h |    7 +++++++
 drivers/i2c/tegra_i2c.c                      |   14 ++++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/arch-tegra2/tegra_i2c.h b/arch/arm/include/asm/arch-tegra2/tegra_i2c.h
index 0a7d99c..cfb136c 100644
--- a/arch/arm/include/asm/arch-tegra2/tegra_i2c.h
+++ b/arch/arm/include/asm/arch-tegra2/tegra_i2c.h
@@ -154,4 +154,11 @@ struct i2c_ctlr {
 #define I2C_INT_ARBITRATION_LOST_SHIFT	2
 #define I2C_INT_ARBITRATION_LOST_MASK	(1 << I2C_INT_ARBITRATION_LOST_SHIFT)
 
+/**
+ * Returns the bus number of the DVC controller
+ *
+ * @return number of bus, or -1 if there is no DVC active
+ */
+int tegra_i2c_get_dvc_bus_num(void);
+
 #endif
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 21f6897..5b6ea0e 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -567,3 +567,17 @@ int i2c_set_bus_num(unsigned int bus)
 	return 0;
 }
 #endif
+
+int tegra_i2c_get_dvc_bus_num(void)
+{
+	int i;
+
+	for (i = 0; i < CONFIG_SYS_MAX_I2C_BUS; i++) {
+		struct i2c_bus *bus = &i2c_controllers[i];
+
+		if (bus->inited && bus->is_dvc)
+			return i;
+	}
+
+	return -1;
+}
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (20 preceding siblings ...)
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 21/23] tegra: i2c: Add function to find DVC bus Simon Glass
@ 2012-04-02 23:19 ` Simon Glass
  2012-04-03  5:22   ` Olof Johansson
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 23/23] tegra: Enable LP0 on Seaboard Simon Glass
  2012-04-09 21:54 ` [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Stephen Warren
  23 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:19 UTC (permalink / raw)
  To: u-boot

This adds timings for T20 and T25 Seaboards, using the bindings found here:

http://patchwork.ozlabs.org/patch/132928/

We supply both full speed options for normal running, and half speed options
for testing / development.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 board/nvidia/dts/tegra2-seaboard.dts |   72 ++++++++++++++++++++++++++++++++++
 1 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/board/nvidia/dts/tegra2-seaboard.dts b/board/nvidia/dts/tegra2-seaboard.dts
index 6ba3ec4..31e0f9d 100644
--- a/board/nvidia/dts/tegra2-seaboard.dts
+++ b/board/nvidia/dts/tegra2-seaboard.dts
@@ -89,4 +89,76 @@
 	i2c at 7000c500 {
 		clock-frequency = <100000>;
 	};
+
+	emc at 7000f400 {
+		emc-table at 166500 {
+			reg = <166500>;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 166500 >;
+			nvidia,emc-registers = < 0x0000000a 0x00000021
+				0x00000008 0x00000003 0x00000004 0x00000004
+				0x00000002 0x0000000c 0x00000003 0x00000003
+				0x00000002 0x00000001 0x00000004 0x00000005
+				0x00000004 0x00000009 0x0000000d 0x000004df
+				0x00000000 0x00000003 0x00000003 0x00000003
+				0x00000003 0x00000001 0x0000000a 0x000000c8
+				0x00000003 0x00000006 0x00000004 0x0000000f
+				0x00000002 0x00000000 0x00000000 0x00000002
+				0x00000000 0x00000000 0x00000083 0xa04004ae
+				0x007fd010 0x00000000 0x00000000 0x00000000
+				0x00000000 0x00000000 0x00000000 0x00000000 >;
+		};
+		emc-table at 333000 {
+			reg = <333000>;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 333000 >;
+			nvidia,emc-registers = < 0x00000014 0x00000041
+				0x0000000f 0x00000005 0x00000004 0x00000005
+				0x00000003 0x0000000c 0x00000005 0x00000005
+				0x00000003 0x00000001 0x00000004 0x00000005
+				0x00000004 0x00000009 0x0000000d 0x000009ff
+				0x00000000 0x00000003 0x00000003 0x00000005
+				0x00000005 0x00000001 0x0000000f 0x000000c8
+				0x00000003 0x0000000c 0x00000006 0x0000000f
+				0x00000002 0x00000000 0x00000000 0x00000002
+				0x00000000 0x00000000 0x00000083 0xe034048b
+				0x007e8010 0x00000000 0x00000000 0x00000000
+				0x00000000 0x00000000 0x00000000 0x00000000 >;
+		};
+
+		emc-table at 190000 {
+			reg = < 190000 >;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 190000 >;
+			nvidia,emc-registers = < 0x0000000c 0x00000026
+				0x00000009 0x00000003 0x00000004 0x00000004
+				0x00000002 0x0000000c 0x00000003 0x00000003
+				0x00000002 0x00000001 0x00000004 0x00000005
+				0x00000004 0x00000009 0x0000000d 0x0000059f
+				0x00000000 0x00000003 0x00000003 0x00000003
+				0x00000003 0x00000001 0x0000000b 0x000000c8
+				0x00000003 0x00000007 0x00000004 0x0000000f
+				0x00000002 0x00000000 0x00000000 0x00000002
+				0x00000000 0x00000000 0x00000083 0xa06204ae
+				0x007dc010 0x00000000 0x00000000 0x00000000
+				0x00000000 0x00000000 0x00000000 0x00000000 >;
+		};
+		emc-table at 380000 {
+			reg = < 380000 >;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 380000 >;
+			nvidia,emc-registers = < 0x00000017 0x0000004b
+				0x00000012 0x00000006 0x00000004 0x00000005
+				0x00000003 0x0000000c 0x00000006 0x00000006
+				0x00000003 0x00000001 0x00000004 0x00000005
+				0x00000004 0x00000009 0x0000000d 0x00000b5f
+				0x00000000 0x00000003 0x00000003 0x00000006
+				0x00000006 0x00000001 0x00000011 0x000000c8
+				0x00000003 0x0000000e 0x00000007 0x0000000f
+				0x00000002 0x00000000 0x00000000 0x00000002
+				0x00000000 0x00000000 0x00000083 0xe044048b
+				0x007d8010 0x00000000 0x00000000 0x00000000
+				0x00000000 0x00000000 0x00000000 0x00000000 >;
+		};
+	};
 };
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 23/23] tegra: Enable LP0 on Seaboard
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (21 preceding siblings ...)
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard Simon Glass
@ 2012-04-02 23:19 ` Simon Glass
  2012-04-09 21:54 ` [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Stephen Warren
  23 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-02 23:19 UTC (permalink / raw)
  To: u-boot

This enables LP0 to support suspend / resume on Seaboard.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/configs/seaboard.h      |    8 ++++++++
 include/configs/tegra2-common.h |   17 +++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h
index ea7e4f0..5d33dc5 100644
--- a/include/configs/seaboard.h
+++ b/include/configs/seaboard.h
@@ -25,6 +25,14 @@
 #define __CONFIG_H
 
 #include <asm/sizes.h>
+
+/* LP0 suspend / resume */
+#define CONFIG_TEGRA2_LP0
+#define CONFIG_AES
+#define CONFIG_TEGRA_PMU
+#define CONFIG_TPS6586X_POWER
+#define CONFIG_TEGRA_CLOCK_SCALING
+
 #include "tegra2-common.h"
 
 #define CONFIG_SYS_DCACHE_OFF
diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 837f859..c5870dd 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -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 */
 
-- 
1.7.7.3

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard Simon Glass
@ 2012-04-03  5:22   ` Olof Johansson
  2012-04-04  0:47     ` Simon Glass
  0 siblings, 1 reply; 54+ messages in thread
From: Olof Johansson @ 2012-04-03  5:22 UTC (permalink / raw)
  To: u-boot

On Mon, Apr 2, 2012 at 4:19 PM, Simon Glass <sjg@chromium.org> wrote:
> This adds timings for T20 and T25 Seaboards, using the bindings found here:
>
> http://patchwork.ozlabs.org/patch/132928/
>
> We supply both full speed options for normal running, and half speed options
> for testing / development.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>

This seems incorrect to me. You provide both T20 and T25 EMC tables in
the same device tree with no way to determine which one to use.

Unfortunately nvidia didn't use the boot straps to tell if they were
on a t20 or t25 seaboard, so you'll just have to know. At the kernel
side we chose to just ditch T20 since most boards still in use are
T25.



-Olof

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 05/23] Add AES crypto library
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 05/23] Add AES crypto library Simon Glass
@ 2012-04-03 18:46   ` Yen Lin
  2012-04-05 21:38     ` Simon Glass
  0 siblings, 1 reply; 54+ messages in thread
From: Yen Lin @ 2012-04-03 18:46 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> From: Yen Lin <yelin@nvidia.com>
> 
> 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.
> 

Could you fix "form" to "from"?

Signed-off-by: Yen Lin <yelin@nvidia.com>

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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 08/23] tegra: Add crypto library for warmboot code
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 08/23] tegra: Add crypto library for warmboot code Simon Glass
@ 2012-04-03 18:47   ` Yen Lin
  0 siblings, 0 replies; 54+ messages in thread
From: Yen Lin @ 2012-04-03 18:47 UTC (permalink / raw)
  To: u-boot

On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> From: Yen Lin <yelin@nvidia.com>
> 
> Provides an interface to aes.c for the warmboot code.
> 

Signed-off-by: Yen Lin <yelin@nvidia.com>

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in v2:
> - Rely on compiler to optimise out debug_print_vector()
> - Remove unused crypto code from crypto.c



-----------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 09/23] tegra: Add flow, gp_padctl, fuse, sdram headers
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 09/23] tegra: Add flow, gp_padctl, fuse, sdram headers Simon Glass
@ 2012-04-03 18:52   ` Yen Lin
  0 siblings, 0 replies; 54+ messages in thread
From: Yen Lin @ 2012-04-03 18:52 UTC (permalink / raw)
  To: u-boot

On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> From: Yen Lin <yelin@nvidia.com>
> 
> 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
> 

Signed-off-by: Yen Lin <yelin@nvidia.com>

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---



-----------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation Simon Glass
@ 2012-04-03 18:56   ` Yen Lin
  2012-04-09 21:36   ` Stephen Warren
  1 sibling, 0 replies; 54+ messages in thread
From: Yen Lin @ 2012-04-03 18:56 UTC (permalink / raw)
  To: u-boot

On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> From: Yen Lin <yelin@nvidia.com>
> 
> Add code to set up the warm boot area in the Tegra CPU ready for a
> resume after suspend.
> 

Signed-off-by: Yen Lin <yelin@nvidia.com>

> Signed-off-by: Simon Glass <sjg@chromium.org>
> Acked-by: Stephen Warren <swarren@nvidia.com>
> ---
> Changes in v2:
> - Move structs shared between A9 and AVP into warmboot.h header file
> - Remove unused crypto code
> - Tidy SDRAM range check in warmboot_prepare_code()
> - Use low-level clock functions in warmboot code instead of register access



-----------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 16/23] tegra: Setup PMC scratch info from ap20 setup
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 16/23] tegra: Setup PMC scratch info from ap20 setup Simon Glass
@ 2012-04-03 18:57   ` Yen Lin
  0 siblings, 0 replies; 54+ messages in thread
From: Yen Lin @ 2012-04-03 18:57 UTC (permalink / raw)
  To: u-boot

On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> From: Yen Lin <yelin@nvidia.com>
> 
> Save SDRAM parameters into the warmboot scratch registers
> 

Signed-off-by: Yen Lin <yelin@nvidia.com>

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 



-----------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard
  2012-04-03  5:22   ` Olof Johansson
@ 2012-04-04  0:47     ` Simon Glass
  2012-04-05 21:58       ` Simon Glass
  0 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-04  0:47 UTC (permalink / raw)
  To: u-boot

Hi Olof,

On Mon, Apr 2, 2012 at 10:22 PM, Olof Johansson <olof@lixom.net> wrote:
> On Mon, Apr 2, 2012 at 4:19 PM, Simon Glass <sjg@chromium.org> wrote:
>> This adds timings for T20 and T25 Seaboards, using the bindings found here:
>>
>> http://patchwork.ozlabs.org/patch/132928/
>>
>> We supply both full speed options for normal running, and half speed options
>> for testing / development.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> This seems incorrect to me. You provide both T20 and T25 EMC tables in
> the same device tree with no way to determine which one to use.
>
> Unfortunately nvidia didn't use the boot straps to tell if they were
> on a t20 or t25 seaboard, so you'll just have to know. At the kernel
> side we chose to just ditch T20 since most boards still in use are
> T25.

The selection of memory speed is down to the board. There is a later
patch in this series (just cc'd to you) which looks at the SOC ID to
determine whether it is T20 or T25, and selects the speed accordingly.
This speed is used to look up the correct table in the device tree

>
>
>
> -Olof

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 05/23] Add AES crypto library
  2012-04-03 18:46   ` Yen Lin
@ 2012-04-05 21:38     ` Simon Glass
  0 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-05 21:38 UTC (permalink / raw)
  To: u-boot

Hi Yen,

On Tue, Apr 3, 2012 at 11:46 AM, Yen Lin <yelin@nvidia.com> wrote:
> Hi Simon,
>
> On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
>> From: Yen Lin <yelin@nvidia.com>
>>
>> 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.
>>
>
> Could you fix "form" to "from"?

done - I will update this patch.

>
> Signed-off-by: Yen Lin <yelin@nvidia.com>
>
> 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.
> -----------------------------------------------------------------------------------

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard
  2012-04-04  0:47     ` Simon Glass
@ 2012-04-05 21:58       ` Simon Glass
  0 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-05 21:58 UTC (permalink / raw)
  To: u-boot

Hi,

On Tue, Apr 3, 2012 at 5:47 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Olof,
>
> On Mon, Apr 2, 2012 at 10:22 PM, Olof Johansson <olof@lixom.net> wrote:
>> On Mon, Apr 2, 2012 at 4:19 PM, Simon Glass <sjg@chromium.org> wrote:
>>> This adds timings for T20 and T25 Seaboards, using the bindings found here:
>>>
>>> http://patchwork.ozlabs.org/patch/132928/
>>>
>>> We supply both full speed options for normal running, and half speed options
>>> for testing / development.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> This seems incorrect to me. You provide both T20 and T25 EMC tables in
>> the same device tree with no way to determine which one to use.
>>
>> Unfortunately nvidia didn't use the boot straps to tell if they were
>> on a t20 or t25 seaboard, so you'll just have to know. At the kernel
>> side we chose to just ditch T20 since most boards still in use are
>> T25.
>
> The selection of memory speed is down to the board. There is a later
> patch in this series (just cc'd to you) which looks at the SOC ID to
> determine whether it is T20 or T25, and selects the speed accordingly.
> This speed is used to look up the correct table in the device tree

Well if we really want to do this properly we should have a separate
device tree file for the T20 Seaboard. Since the kernel has dropped
T20 support, we should do the same. I have updated this patch.

Regards,
Simon

>
>>
>>
>>
>> -Olof
>
> Regards,
> Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver Simon Glass
@ 2012-04-09 21:01   ` Stephen Warren
  2012-04-09 21:25     ` Simon Glass
  0 siblings, 1 reply; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:01 UTC (permalink / raw)
  To: u-boot

On 04/02/2012 05:18 PM, Simon Glass wrote:
> This power management chip supports battery charging and a large number
> of power supplies. This initial driver only provides the ability to adjust
> the two synchronous buck converters SM0 and SM1 in a stepwise manner.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

> +#define MAX_I2C_RETRY	3
> +int tps6586x_read(int reg)
...
> +	for (i = 0; i < MAX_I2C_RETRY; ++i) {
> +		if (!i2c_read(I2C_ADDRESS, reg, 1, &data, 1)) {
> +			retval = (int)data;
> +			goto exit;
> +		}
> +
> +		/* i2c access failed, retry */
> +		udelay(100);
> +	}

Why do we need this retry logic; the kernel driver doesn't appear to
have this.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location Simon Glass
@ 2012-04-09 21:03   ` Stephen Warren
  2012-04-09 21:06   ` Stephen Warren
  1 sibling, 0 replies; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:03 UTC (permalink / raw)
  To: u-boot

On 04/02/2012 05:18 PM, Simon Glass wrote:
> We want to include this from board code, so move the header into
> an easily-accessible location.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

> diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c

> +#include <asm/arch/pmc.h>

That seems unrelated.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location Simon Glass
  2012-04-09 21:03   ` Stephen Warren
@ 2012-04-09 21:06   ` Stephen Warren
  2012-04-09 21:24     ` Simon Glass
  1 sibling, 1 reply; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:06 UTC (permalink / raw)
  To: u-boot

On 04/02/2012 05:18 PM, Simon Glass wrote:
> We want to include this from board code, so move the header into
> an easily-accessible location.

> diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c

> -#include "ap20.h"
>  #include <asm/io.h>
>  #include <asm/arch/tegra2.h>
> +#include <asm/arch/ap20.h>

BTW, why do we have separate tegra2.h and ap20.h?

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 10/23] tegra: Add tegra_get_chip_type() to detect SKU
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 10/23] tegra: Add tegra_get_chip_type() to detect SKU Simon Glass
@ 2012-04-09 21:09   ` Stephen Warren
  2012-04-09 21:50     ` Simon Glass
  0 siblings, 1 reply; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:09 UTC (permalink / raw)
  To: u-boot

On 04/02/2012 05:18 PM, Simon Glass wrote:
> 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.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Acked-by: Stephen Warren <swarren@nvidia.com>
> ---
> Changes in v2:
> - Add check of undocumented values in hidrev register

> diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c

> +int tegra_get_chip_type(void)
> +{
> +	struct apb_misc_gp_ctlr *gp;
> +	struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
> +	uint tegra_sku_id, rev;
> +
> +	/*
> +	 * This is undocumented, Chip ID is bits 15:8 of the register
> +	 * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
> +	 * Tegra30
> +	 */
> +	gp = (struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
> +	rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;

That's not entirely true; the register and its fields are documented in
the TRM. The values of the CHIPID field itself are indeed not documented.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location
  2012-04-09 21:06   ` Stephen Warren
@ 2012-04-09 21:24     ` Simon Glass
  2012-04-09 21:50       ` Tom Warren
  2012-04-09 21:55       ` Stephen Warren
  0 siblings, 2 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-09 21:24 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Mon, Apr 9, 2012 at 2:06 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/02/2012 05:18 PM, Simon Glass wrote:
>> We want to include this from board code, so move the header into
>> an easily-accessible location.
>
>> diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
>
>> -#include "ap20.h"
>> ?#include <asm/io.h>
>> ?#include <asm/arch/tegra2.h>
>> +#include <asm/arch/ap20.h>
>
> BTW, why do we have separate tegra2.h and ap20.h?

I'm not sure - was ap20 the old name? Tom do you know? For now we use
ap20 as the interface to the AVP side, and where we start up the A9.

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver
  2012-04-09 21:01   ` Stephen Warren
@ 2012-04-09 21:25     ` Simon Glass
  2012-04-09 21:57       ` Stephen Warren
  0 siblings, 1 reply; 54+ messages in thread
From: Simon Glass @ 2012-04-09 21:25 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Mon, Apr 9, 2012 at 2:01 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/02/2012 05:18 PM, Simon Glass wrote:
>> This power management chip supports battery charging and a large number
>> of power supplies. This initial driver only provides the ability to adjust
>> the two synchronous buck converters SM0 and SM1 in a stepwise manner.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
>> +#define MAX_I2C_RETRY ? ? ? ?3
>> +int tps6586x_read(int reg)
> ...
>> + ? ? for (i = 0; i < MAX_I2C_RETRY; ++i) {
>> + ? ? ? ? ? ? if (!i2c_read(I2C_ADDRESS, reg, 1, &data, 1)) {
>> + ? ? ? ? ? ? ? ? ? ? retval = (int)data;
>> + ? ? ? ? ? ? ? ? ? ? goto exit;
>> + ? ? ? ? ? ? }
>> +
>> + ? ? ? ? ? ? /* i2c access failed, retry */
>> + ? ? ? ? ? ? udelay(100);
>> + ? ? }
>
> Why do we need this retry logic; the kernel driver doesn't appear to
> have this.

We apparently have found the device to be flaky on i2c sometimes,
which is why this is here.

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation Simon Glass
  2012-04-03 18:56   ` Yen Lin
@ 2012-04-09 21:36   ` Stephen Warren
  2012-04-10 15:13     ` Simon Glass
  1 sibling, 1 reply; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:36 UTC (permalink / raw)
  To: u-boot

On 04/02/2012 05:18 PM, Simon Glass wrote:
> From: Yen Lin <yelin@nvidia.com>
> 
> Add code to set up the warm boot area in the Tegra CPU ready for a
> resume after suspend.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Acked-by: Stephen Warren <swarren@nvidia.com>

> +static enum fuse_operating_mode fuse_get_operation_mode(void)
> +{
> +	u32 chip_id;
> +	struct apb_misc_gp_ctlr *gp =
> +		(struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
> +
> +	chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >>
> +			HIDREV_CHIPID_SHIFT;

This duplicates code from the SKU retrieval function added in an earlier
patch. Not a big deal; it could be unified in a followon patch.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location
  2012-04-09 21:24     ` Simon Glass
@ 2012-04-09 21:50       ` Tom Warren
  2012-04-09 21:52         ` Simon Glass
  2012-04-09 21:55       ` Stephen Warren
  1 sibling, 1 reply; 54+ messages in thread
From: Tom Warren @ 2012-04-09 21:50 UTC (permalink / raw)
  To: u-boot

Simon/Stephen,

> -----Original Message-----
> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
> Sent: Monday, April 09, 2012 2:24 PM
> To: Stephen Warren
> Cc: U-Boot Mailing List; Tom Warren
> Subject: Re: [PATCH v3 06/23] tegra: Move ap20.h header into arch location
> 
> Hi Stephen,
> 
> On Mon, Apr 9, 2012 at 2:06 PM, Stephen Warren <swarren@wwwdotorg.org>
> wrote:
> > On 04/02/2012 05:18 PM, Simon Glass wrote:
> >> We want to include this from board code, so move the header into an
> >> easily-accessible location.
> >
> >> diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c
> >> b/arch/arm/cpu/armv7/tegra2/ap20.c
> >
> >> -#include "ap20.h"
> >> ?#include <asm/io.h>
> >> ?#include <asm/arch/tegra2.h>
> >> +#include <asm/arch/ap20.h>
> >
> > BTW, why do we have separate tegra2.h and ap20.h?
> 
> I'm not sure - was ap20 the old name? Tom do you know? For now we use
> ap20 as the interface to the AVP side, and where we start up the A9.
AP20 is the name of one classification/sku/bin/type of Tegra20 chip - Application Processor, IIRC. Usually AP20 and T20 are used interchangeably. The history of ap20.h is messy - it came from our Embedded group originally and was ported to U-Boot by stripping out all the NV-proprietary-API cruft, changing CamelCase var/func names, to U-Boot-compliant code, etc.  At this point, it might be able to be merged w/tegra2.h, but tegra2.h is more general to the entire chip and its periphs, and ap20.h is more specific to the CPU(s) and AVP/CPU init.  But I won't object to a merger.

Tom
> 
> Regards,
> Simon
-- 
nvpublic

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 10/23] tegra: Add tegra_get_chip_type() to detect SKU
  2012-04-09 21:09   ` Stephen Warren
@ 2012-04-09 21:50     ` Simon Glass
  0 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-09 21:50 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Mon, Apr 9, 2012 at 2:09 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/02/2012 05:18 PM, Simon Glass wrote:
>> 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.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Acked-by: Stephen Warren <swarren@nvidia.com>
>> ---
>> Changes in v2:
>> - Add check of undocumented values in hidrev register
>
>> diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
>
>> +int tegra_get_chip_type(void)
>> +{
>> + ? ? struct apb_misc_gp_ctlr *gp;
>> + ? ? struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
>> + ? ? uint tegra_sku_id, rev;
>> +
>> + ? ? /*
>> + ? ? ?* This is undocumented, Chip ID is bits 15:8 of the register
>> + ? ? ?* APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
>> + ? ? ?* Tegra30
>> + ? ? ?*/
>> + ? ? gp = (struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
>> + ? ? rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
>
> That's not entirely true; the register and its fields are documented in
> the TRM. The values of the CHIPID field itself are indeed not documented.

OK I have updated this. It is confusing because there is another
register at TEGRA2_APB_MISC_PP_BASE which has a space in those fields.

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location
  2012-04-09 21:50       ` Tom Warren
@ 2012-04-09 21:52         ` Simon Glass
  0 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-09 21:52 UTC (permalink / raw)
  To: u-boot

Hi Tom,

On Mon, Apr 9, 2012 at 2:50 PM, Tom Warren <TWarren@nvidia.com> wrote:
> Simon/Stephen,
>
>> -----Original Message-----
>> From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
>> Sent: Monday, April 09, 2012 2:24 PM
>> To: Stephen Warren
>> Cc: U-Boot Mailing List; Tom Warren
>> Subject: Re: [PATCH v3 06/23] tegra: Move ap20.h header into arch location
>>
>> Hi Stephen,
>>
>> On Mon, Apr 9, 2012 at 2:06 PM, Stephen Warren <swarren@wwwdotorg.org>
>> wrote:
>> > On 04/02/2012 05:18 PM, Simon Glass wrote:
>> >> We want to include this from board code, so move the header into an
>> >> easily-accessible location.
>> >
>> >> diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c
>> >> b/arch/arm/cpu/armv7/tegra2/ap20.c
>> >
>> >> -#include "ap20.h"
>> >> ?#include <asm/io.h>
>> >> ?#include <asm/arch/tegra2.h>
>> >> +#include <asm/arch/ap20.h>
>> >
>> > BTW, why do we have separate tegra2.h and ap20.h?
>>
>> I'm not sure - was ap20 the old name? Tom do you know? For now we use
>> ap20 as the interface to the AVP side, and where we start up the A9.
> AP20 is the name of one classification/sku/bin/type of Tegra20 chip - Application Processor, IIRC. Usually AP20 and T20 are used interchangeably. The history of ap20.h is messy - it came from our Embedded group originally and was ported to U-Boot by stripping out all the NV-proprietary-API cruft, changing CamelCase var/func names, to U-Boot-compliant code, etc. ?At this point, it might be able to be merged w/tegra2.h, but tegra2.h is more general to the entire chip and its periphs, and ap20.h is more specific to the CPU(s) and AVP/CPU init. ?But I won't object to a merger.

Thanks for that. Perhaps we should rename it to avp or cpu_init.
Something to think about.

>
> Tom
>>
>> Regards,
>> Simon
> --
> nvpublic

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support
  2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
                   ` (22 preceding siblings ...)
  2012-04-02 23:19 ` [U-Boot] [PATCH v3 23/23] tegra: Enable LP0 on Seaboard Simon Glass
@ 2012-04-09 21:54 ` Stephen Warren
  2012-04-09 22:05   ` Tom Warren
  23 siblings, 1 reply; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:54 UTC (permalink / raw)
  To: u-boot

On 04/02/2012 05:18 PM, Simon Glass wrote:
> 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.
> 
> Also included here is support for the EMC, which allows setting the memory
> timings correctly in U-Boot for maximum speed operation.

The series partially:

Tested-by: Stephen Warren <swarren@wwwdotorg.org>

I tested that on both Harmony and Seaboard, this series didn't seem to
impact existing operation (boot to a command-prompt, load files from an
SD card, produce serial output). I didn't actually test LP0.

Note:

Neither board appears to be able to actually boot a kernel any more,
failing with the following error:

=============
Starting kernel ...

Uncompressing Linux... done, booting the kernel.
Warning: Neither atags nor dtb found
=============

However, this problem is present in u-boot-tegra/master before any
changes in this series.

Tom, do you want me to file an internal bug for this?

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location
  2012-04-09 21:24     ` Simon Glass
  2012-04-09 21:50       ` Tom Warren
@ 2012-04-09 21:55       ` Stephen Warren
  1 sibling, 0 replies; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:55 UTC (permalink / raw)
  To: u-boot

On 04/09/2012 03:24 PM, Simon Glass wrote:
> Hi Stephen,
> 
> On Mon, Apr 9, 2012 at 2:06 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 04/02/2012 05:18 PM, Simon Glass wrote:
>>> We want to include this from board code, so move the header into
>>> an easily-accessible location.
>>
>>> diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
>>
>>> -#include "ap20.h"
>>>  #include <asm/io.h>
>>>  #include <asm/arch/tegra2.h>
>>> +#include <asm/arch/ap20.h>
>>
>> BTW, why do we have separate tegra2.h and ap20.h?
> 
> I'm not sure - was ap20 the old name? Tom do you know? For now we use
> ap20 as the interface to the AVP side, and where we start up the A9.

AP20 and T20 are different SKUs of Tegra 2/Tegra20.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver
  2012-04-09 21:25     ` Simon Glass
@ 2012-04-09 21:57       ` Stephen Warren
  2012-04-09 23:02         ` Simon Glass
  0 siblings, 1 reply; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 21:57 UTC (permalink / raw)
  To: u-boot

On 04/09/2012 03:25 PM, Simon Glass wrote:
> Hi Stephen,
> 
> On Mon, Apr 9, 2012 at 2:01 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 04/02/2012 05:18 PM, Simon Glass wrote:
>>> This power management chip supports battery charging and a large number
>>> of power supplies. This initial driver only provides the ability to adjust
>>> the two synchronous buck converters SM0 and SM1 in a stepwise manner.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>>> +#define MAX_I2C_RETRY        3
>>> +int tps6586x_read(int reg)
>> ...
>>> +     for (i = 0; i < MAX_I2C_RETRY; ++i) {
>>> +             if (!i2c_read(I2C_ADDRESS, reg, 1, &data, 1)) {
>>> +                     retval = (int)data;
>>> +                     goto exit;
>>> +             }
>>> +
>>> +             /* i2c access failed, retry */
>>> +             udelay(100);
>>> +     }
>>
>> Why do we need this retry logic; the kernel driver doesn't appear to
>> have this.
> 
> We apparently have found the device to be flaky on i2c sometimes,
> which is why this is here.

Is it the device itself, or bad board layout/...? Do we need something
similar in the kernel?

In general though, if we're having problems communicating with the PMIC,
we're pretty screwed; how do we know whether failed transactions simply
fail (e.g. no ACK), or send bogus data to the PMIC (e.g. set some random
register so that something gets programmed to be over-voltage)? A better
solution might be a full system reset when you fail to communicate with
the PMIC.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support
  2012-04-09 21:54 ` [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Stephen Warren
@ 2012-04-09 22:05   ` Tom Warren
  2012-04-09 22:10     ` Stephen Warren
  0 siblings, 1 reply; 54+ messages in thread
From: Tom Warren @ 2012-04-09 22:05 UTC (permalink / raw)
  To: u-boot

Stephen,

> -----Original Message-----
> From: Stephen Warren [mailto:swarren at wwwdotorg.org]
> Sent: Monday, April 09, 2012 2:54 PM
> To: Simon Glass; Tom Warren
> Cc: U-Boot Mailing List
> Subject: Re: [PATCH v3 0/23] tegra: warmboot (suspend / resume) support
> 
> On 04/02/2012 05:18 PM, Simon Glass wrote:
> > 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.
> >
> > Also included here is support for the EMC, which allows setting the
> > memory timings correctly in U-Boot for maximum speed operation.
> 
> The series partially:
> 
> Tested-by: Stephen Warren <swarren@wwwdotorg.org>
> 
> I tested that on both Harmony and Seaboard, this series didn't seem to
> impact existing operation (boot to a command-prompt, load files from an SD
> card, produce serial output). I didn't actually test LP0.
> 
> Note:
> 
> Neither board appears to be able to actually boot a kernel any more, failing
> with the following error:
> 
> =============
> Starting kernel ...
> 
> Uncompressing Linux... done, booting the kernel.
> Warning: Neither atags nor dtb found
> =============
> 
> However, this problem is present in u-boot-tegra/master before any changes
> in this series.
> 
> Tom, do you want me to file an internal bug for this?
Has the upstream Seaboard (or Harmony) build ever been able to boot a kernel? I've never tried it, as I thought it was too incomplete for that yet (i.e. needs more drivers/periphs init'd first).

You can file a bug if you wish as a placeholder. I'm not sure what's missing (if it's not a regression) - bootargs for a kernel? _ATAG config items? If they were there & were taken out in a particular patch series, I'd like to see the person responsible for that be tasked w/replacing them (edited, if need be, for current state such as WB/LP0 vec, usb/mmc boot, etc.).

Tom

-- 
nvpublic

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support
  2012-04-09 22:05   ` Tom Warren
@ 2012-04-09 22:10     ` Stephen Warren
  0 siblings, 0 replies; 54+ messages in thread
From: Stephen Warren @ 2012-04-09 22:10 UTC (permalink / raw)
  To: u-boot

On 04/09/2012 04:05 PM, Tom Warren wrote:
> From: Stephen Warren wrote at Monday, April 09, 2012 2:54 PM:
...
>> Note:
>>
>> Neither board appears to be able to actually boot a kernel any more, failing
>> with the following error:
>>
>> =============
>> Starting kernel ...
>>
>> Uncompressing Linux... done, booting the kernel.
>> Warning: Neither atags nor dtb found
>> =============
>>
>> However, this problem is present in u-boot-tegra/master before any changes
>> in this series.
>>
>> Tom, do you want me to file an internal bug for this?
>
> Has the upstream Seaboard (or Harmony) build ever been able to boot a kernel? I've never tried it, as I thought it was too incomplete for that yet (i.e. needs more drivers/periphs init'd first).

Yes, this (used to) work just fine, on both boards, booting with either
ATAGs or device tree. Same for Ventana and Paz00.

For reference, I use commit 9a420986cccc9bd2c37affd931d627b3c3e72952
plus a few patches that have since been upstreamed, plus a local change
to the default environment. I believe I tested a much later commmit than
that while testing other patches of Simon's as well (an earlier version
of the DT/USB/I2C patchset), but didn't update all my systems since I
didn't need that functionality.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver
  2012-04-09 21:57       ` Stephen Warren
@ 2012-04-09 23:02         ` Simon Glass
  0 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-09 23:02 UTC (permalink / raw)
  To: u-boot

+Jimmy, who wrote the original pmu code

Hi Stephen,

On Mon, Apr 9, 2012 at 2:57 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/09/2012 03:25 PM, Simon Glass wrote:
>> Hi Stephen,
>>
>> On Mon, Apr 9, 2012 at 2:01 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>> On 04/02/2012 05:18 PM, Simon Glass wrote:
>>>> This power management chip supports battery charging and a large number
>>>> of power supplies. This initial driver only provides the ability to adjust
>>>> the two synchronous buck converters SM0 and SM1 in a stepwise manner.
>>>>
>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>
>>>> +#define MAX_I2C_RETRY ? ? ? ?3
>>>> +int tps6586x_read(int reg)
>>> ...
>>>> + ? ? for (i = 0; i < MAX_I2C_RETRY; ++i) {
>>>> + ? ? ? ? ? ? if (!i2c_read(I2C_ADDRESS, reg, 1, &data, 1)) {
>>>> + ? ? ? ? ? ? ? ? ? ? retval = (int)data;
>>>> + ? ? ? ? ? ? ? ? ? ? goto exit;
>>>> + ? ? ? ? ? ? }
>>>> +
>>>> + ? ? ? ? ? ? /* i2c access failed, retry */
>>>> + ? ? ? ? ? ? udelay(100);
>>>> + ? ? }
>>>
>>> Why do we need this retry logic; the kernel driver doesn't appear to
>>> have this.
>>
>> We apparently have found the device to be flaky on i2c sometimes,
>> which is why this is here.
>
> Is it the device itself, or bad board layout/...? Do we need something
> similar in the kernel?

I am not sure - Jimmy do you know?

>
> In general though, if we're having problems communicating with the PMIC,
> we're pretty screwed; how do we know whether failed transactions simply
> fail (e.g. no ACK), or send bogus data to the PMIC (e.g. set some random
> register so that something gets programmed to be over-voltage)? A better
> solution might be a full system reset when you fail to communicate with
> the PMIC.

I believe the problem is that there is no ACK - it would be pretty bad
if it ACKed but didn't work :-)

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 13/23] tegra: Add PMU to manage power supplies
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 13/23] tegra: Add PMU to manage power supplies Simon Glass
@ 2012-04-09 23:47   ` jimmzhang
  0 siblings, 0 replies; 54+ messages in thread
From: jimmzhang @ 2012-04-09 23:47 UTC (permalink / raw)
  To: u-boot

On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> From: Jimmy Zhang <jimmzhang@nvidia.com>
> 
> 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.
> 
> - Split PMU code into separate TPS6586X driver
> 

Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 



-----------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 12/23] tegra: Add EMC support for optimal memory timings
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 12/23] tegra: Add EMC support for optimal memory timings Simon Glass
@ 2012-04-09 23:52   ` jimmzhang
  2012-10-06 16:54     ` Albert ARIBAUD
  0 siblings, 1 reply; 54+ messages in thread
From: jimmzhang @ 2012-04-09 23:52 UTC (permalink / raw)
  To: u-boot

On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> From: Jimmy Zhang <jimmzhang@nvidia.com>
> 
> Add support for setting up the memory controller parameters. Boards
> can set up an appropriate table in the device tree.
> 

Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---



-----------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 18/23] tegra: Turn off power detect in board init
  2012-04-02 23:18 ` [U-Boot] [PATCH v3 18/23] tegra: Turn off power detect in board init Simon Glass
@ 2012-04-10  6:02   ` Wei Ni
  0 siblings, 0 replies; 54+ messages in thread
From: Wei Ni @ 2012-04-10  6:02 UTC (permalink / raw)
  To: u-boot



>-----Original Message-----
>From: Simon Glass [mailto:sjg at chromium.org]
>Sent: Tuesday, April 03, 2012 7:19 AM
>To: U-Boot Mailing List
>Cc: Tom Warren; Stephen Warren; Wei Ni; Simon Glass; Stephen Warren
>Subject: [PATCH v3 18/23] tegra: Turn off power detect in board init
>
>From: Wei Ni <wni@nvidia.com>
>
>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).

Signe-off-by: Wei Ni <wni@nvidia.com>

>
>Signed-off-by: Simon Glass <sjg@chromium.org>
>---
>Changes in v3:
>- Fix CONFIG_TEGRA_I2C define
-----------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation
  2012-04-09 21:36   ` Stephen Warren
@ 2012-04-10 15:13     ` Simon Glass
  0 siblings, 0 replies; 54+ messages in thread
From: Simon Glass @ 2012-04-10 15:13 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Mon, Apr 9, 2012 at 2:36 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/02/2012 05:18 PM, Simon Glass wrote:
>> From: Yen Lin <yelin@nvidia.com>
>>
>> Add code to set up the warm boot area in the Tegra CPU ready for a
>> resume after suspend.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Acked-by: Stephen Warren <swarren@nvidia.com>
>
>> +static enum fuse_operating_mode fuse_get_operation_mode(void)
>> +{
>> + ? ? u32 chip_id;
>> + ? ? struct apb_misc_gp_ctlr *gp =
>> + ? ? ? ? ? ? (struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
>> +
>> + ? ? chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >>
>> + ? ? ? ? ? ? ? ? ? ? HIDREV_CHIPID_SHIFT;
>
> This duplicates code from the SKU retrieval function added in an earlier
> patch. Not a big deal; it could be unified in a followon patch.

Yes, I didn't notice that - yes we can tidy it up later.

Regards,
Simon

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [U-Boot] [PATCH v3 12/23] tegra: Add EMC support for optimal memory timings
  2012-04-09 23:52   ` jimmzhang
@ 2012-10-06 16:54     ` Albert ARIBAUD
  0 siblings, 0 replies; 54+ messages in thread
From: Albert ARIBAUD @ 2012-10-06 16:54 UTC (permalink / raw)
  To: u-boot

Hi Jimmy,

On Mon, 09 Apr 2012 16:52:56 -0700, jimmzhang <jimmzhang@nvidia.com>
wrote:

> On Mon, 2012-04-02 at 16:18 -0700, Simon Glass wrote:
> > From: Jimmy Zhang <jimmzhang@nvidia.com>
> > 
> > Add support for setting up the memory controller parameters. Boards
> > can set up an appropriate table in the device tree.
> > 
> 
> Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
> 
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---

This patch causes a warning with building with the debian cross tool
chain:

emc.c: In function 'tegra_set_emc':
emc.c:272:15: warning: 'table' may be used uninitialized in this
function [-Wmaybe-uninitialized] emc.c: In function 'tegra_set_emc':
emc.c:272:15: warning: 'table' may be used uninitialized in this
function [-Wmaybe-uninitialized]

Could you provide a patch to fix this?

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2012-10-06 16:54 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-02 23:18 [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 01/23] fdt: Add function to locate an array in the device tree Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 02/23] fdt: Add function to return next compatible subnode Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 03/23] Add abs() macro to return absolute value Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 04/23] i2c: Add TPS6586X driver Simon Glass
2012-04-09 21:01   ` Stephen Warren
2012-04-09 21:25     ` Simon Glass
2012-04-09 21:57       ` Stephen Warren
2012-04-09 23:02         ` Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 05/23] Add AES crypto library Simon Glass
2012-04-03 18:46   ` Yen Lin
2012-04-05 21:38     ` Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 06/23] tegra: Move ap20.h header into arch location Simon Glass
2012-04-09 21:03   ` Stephen Warren
2012-04-09 21:06   ` Stephen Warren
2012-04-09 21:24     ` Simon Glass
2012-04-09 21:50       ` Tom Warren
2012-04-09 21:52         ` Simon Glass
2012-04-09 21:55       ` Stephen Warren
2012-04-02 23:18 ` [U-Boot] [PATCH v3 07/23] tegra: Add functions to access low-level Osc/PLL details Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 08/23] tegra: Add crypto library for warmboot code Simon Glass
2012-04-03 18:47   ` Yen Lin
2012-04-02 23:18 ` [U-Boot] [PATCH v3 09/23] tegra: Add flow, gp_padctl, fuse, sdram headers Simon Glass
2012-04-03 18:52   ` Yen Lin
2012-04-02 23:18 ` [U-Boot] [PATCH v3 10/23] tegra: Add tegra_get_chip_type() to detect SKU Simon Glass
2012-04-09 21:09   ` Stephen Warren
2012-04-09 21:50     ` Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 11/23] tegra: Add header file for APB_MISC register Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 12/23] tegra: Add EMC support for optimal memory timings Simon Glass
2012-04-09 23:52   ` jimmzhang
2012-10-06 16:54     ` Albert ARIBAUD
2012-04-02 23:18 ` [U-Boot] [PATCH v3 13/23] tegra: Add PMU to manage power supplies Simon Glass
2012-04-09 23:47   ` jimmzhang
2012-04-02 23:18 ` [U-Boot] [PATCH v3 14/23] tegra: Set up PMU for Nvidia boards Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 15/23] tegra: Add warmboot implementation Simon Glass
2012-04-03 18:56   ` Yen Lin
2012-04-09 21:36   ` Stephen Warren
2012-04-10 15:13     ` Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 16/23] tegra: Setup PMC scratch info from ap20 setup Simon Glass
2012-04-03 18:57   ` Yen Lin
2012-04-02 23:18 ` [U-Boot] [PATCH v3 17/23] tegra: Set up warmboot code on Nvidia boards Simon Glass
2012-04-02 23:18 ` [U-Boot] [PATCH v3 18/23] tegra: Turn off power detect in board init Simon Glass
2012-04-10  6:02   ` Wei Ni
2012-04-02 23:18 ` [U-Boot] [PATCH v3 19/23] tegra: Add EMC settings for Seaboard Simon Glass
2012-04-02 23:19 ` [U-Boot] [PATCH v3 20/23] fdt: tegra: Add EMC node to device tree Simon Glass
2012-04-02 23:19 ` [U-Boot] [PATCH v3 21/23] tegra: i2c: Add function to find DVC bus Simon Glass
2012-04-02 23:19 ` [U-Boot] [PATCH v3 22/23] tegra: fdt: Add EMC data for Tegra2 Seaboard Simon Glass
2012-04-03  5:22   ` Olof Johansson
2012-04-04  0:47     ` Simon Glass
2012-04-05 21:58       ` Simon Glass
2012-04-02 23:19 ` [U-Boot] [PATCH v3 23/23] tegra: Enable LP0 on Seaboard Simon Glass
2012-04-09 21:54 ` [U-Boot] [PATCH v3 0/23] tegra: warmboot (suspend / resume) support Stephen Warren
2012-04-09 22:05   ` Tom Warren
2012-04-09 22:10     ` Stephen Warren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox