U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
April 2013
- 204 participants
- 570 discussions

23 Apr '13
This patch set enables and initialises DWMMC for Exynos5250 on SMDK5250.
Adds driver changes required for DWMMC.
Adds FDT support for DWMMC.
Adds EMMC boot support for SMDK5250.
This patch set is based on:
"EXYNOS: mmc: support DesignWare Controller for Samsung-SoC", which
is merged in u-boot-mmc.
"Exynos: clock: support get_mmc_clk for exynos".
"Add DT based ethernet driver for SMDK5250".
"SMDK5250: Add FDT support" present at the following link
http://comments.gmane.org/gmane.comp.boot-loaders.u-boot/149991
Changes since V1:
1)Corrected in response to review comments.
2)Created separate board files for FDT and non-FDT versions.
3)Added binding file for DWMMC device node.
4)Removed the propname 'index' from device node.
5)Prefixed the vendor name 'samsung' before propname in device node.
6)Ensured to have same signature for the function exynos_dwmci_init()
for both FDT and non-FDT versions.
7)EMMC clock setting has been moved from spl_boot.c to clock_init.c.
Changes since V2:
1)Updation of commit message and resubmition of proper patch set.
Changes since V3:
1)Updated to use the macro DWMCI_CTRL_SEND_AS_CCSD instead of the
hard coded value (1 << 10).
2)In the file exynos_dw_mmc.c, replaced the new function
exynos5_mmc_set_clk_div() with the existing function set_mmc_clk().
set_mmc_clk() will do the purpose.
3)In the file exynos_dw_mmc.c, computation of FSYS block clock
divisor (pre-ratio) value is added.
4)Removed the new function exynos5_mmc_set_clk_div() from clock.c.
Changes since V4:
1)Updated the function dwmci_send_cmd() to use get_timer() instead
of using mdelay(1).
2)Replaced the function call 'exynos_dwmmc_init(0, 8);' with the
function exynos_dwmmc_add_port() in smdk5250.c.
3)The function get_irom_func(int index) has been added to avoid
type casting at many places.
4)Used the generic function "mmc_boot_part_access()" instead of two
functions "mmc_boot_open()" and "mmc_boot_close()". By doing so user
can specify which boot partition to be accessed (opened / closed).
Changes since V5:
1)Added the 'removable' flag to mmc device node.
2)Changed the mmc clock value from 50MHz to 52MHz in the function
exynos_dwmci_add_port() present in file drivers/mmc/exynos_dw_mmc.c.
3)Enabled CONFIG_LCD only for non-FDT operation.
4)Removed the function call i2c_init() present inside the
function board_i2c_init().
Changes since V6:
1)Re-based to the patch "SMDK5250: Add PMIC voltage settings".
Changes since V7:
1)Re-based to the patch
"Exynos: pwm: Remove dead code of function exynos5_get_pwm_clk".
2)In file dw_mmc.c, updated the function dwmci_setup_bus() to
return 0 if (freq == 0).This is to avoid the run time exception
"raise:Signal # 8 caught".
3)In the files drivers/mmc/mmc.c and common/cmd_mmc.c, the piece
of code involved in EMMC open/close and resize of EMMC boot
partition has been made conditional and is enabled only if the
macro CONFIG_SUPPORT_EMMC_BOOT is defined.
4)The macros FSYS1_MMC0_DIV_MASK and FSYS1_MMC0_DIV_VAL are made
local to file clock_init.c.
Amar (9):
FDT: Add compatible string for DWMMC
EXYNOS5: FDT: Add DWMMC device node data
DWMMC: Initialise dwmci and resolve EMMC read write issues
EXYNOS5: DWMMC: Added FDT support for DWMMC
EXYNOS5: DWMMC: Initialise the local variable to avoid unwanted
results.
SMDK5250: Initialise and Enable DWMMC, support FDT and non-FDT
MMC: APIs to support resize of EMMC boot partition
SMDK5250: Enable EMMC booting
COMMON: MMC: Command to support EMMC booting and to resize EMMC boot
partition
arch/arm/cpu/armv7/exynos/clock.c | 4 +-
arch/arm/dts/exynos5250.dtsi | 33 +++
arch/arm/include/asm/arch-exynos/dwmmc.h | 11 +-
board/samsung/dts/exynos5250-smdk5250.dts | 24 ++
board/samsung/smdk5250/Makefile | 4 +
board/samsung/smdk5250/clock_init.c | 18 ++
board/samsung/smdk5250/clock_init.h | 5 +
board/samsung/smdk5250/exynos5-dt.c | 423 ++++++++++++++++++++++++++++++
board/samsung/smdk5250/smdk5250.c | 223 ++++------------
board/samsung/smdk5250/spl_boot.c | 52 +++-
common/cmd_mmc.c | 110 +++++++-
doc/device-tree-bindings/exynos/dwmmc.txt | 54 ++++
drivers/mmc/dw_mmc.c | 28 +-
drivers/mmc/exynos_dw_mmc.c | 127 ++++++++-
drivers/mmc/mmc.c | 134 ++++++++++
drivers/video/exynos_fb.c | 4 +-
include/configs/exynos5250-dt.h | 8 +
include/dwmmc.h | 3 +
include/fdtdec.h | 1 +
include/mmc.h | 26 ++
lib/fdtdec.c | 1 +
21 files changed, 1087 insertions(+), 206 deletions(-)
create mode 100644 board/samsung/smdk5250/exynos5-dt.c
create mode 100644 doc/device-tree-bindings/exynos/dwmmc.txt
--
1.8.0
4
22
From: Naveen Krishna Chatradhi <ch.naveen(a)samsung.com>
Adding NACK logic for i2c write.
Verified by reading and writing to device with address 9 on i2c-0.
Signed-off-by: Naveen Krishna Chatradhi <ch.naveen(a)samsung.com>
Signed-off-by: Akshay Saraswat <akshay.s(a)samsung.com>
---
drivers/i2c/s3c24x0_i2c.c | 111 +++++++++++++++++++++++-----------------------
1 file changed, 56 insertions(+), 55 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index 769a2ba..d2b4eb0 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -201,6 +201,35 @@ unsigned int i2c_get_bus_num(void)
}
#endif
+/*
+ * Verify the whether I2C ACK was received or not
+ *
+ * @param i2c pointer to I2C register base
+ * @param buf array of data
+ * @param len length of data
+ * return I2C_OK when transmission done
+ * I2C_NACK otherwise
+ */
+static int i2c_send_verify(struct s3c24x0_i2c *i2c, unsigned char buf[],
+ unsigned char len)
+{
+ int i, result = I2C_OK;
+
+ if (IsACK(i2c)) {
+ for (i = 0; (i < len) && (result == I2C_OK); i++) {
+ writel(buf[i], &i2c->iicds);
+ ReadWriteByte(i2c);
+ result = WaitForXfer(i2c);
+ if (!IsACK(i2c))
+ result = I2C_NACK;
+ }
+ } else {
+ result = I2C_NACK;
+ }
+
+ return result;
+}
+
void i2c_init(int speed, int slaveadd)
{
struct s3c24x0_i2c *i2c;
@@ -302,41 +331,30 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c,
return I2C_NOK_TOUT;
writel(readl(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon);
- result = I2C_OK;
+
+ if (addr && addr_len) {
+ writel(chip, &i2c->iicds);
+ /* send START */
+ writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
+ &i2c->iicstat);
+ if (WaitForXfer(i2c) == I2C_OK)
+ result = i2c_send_verify(i2c, addr, addr_len);
+ else
+ result = I2C_NACK;
+ } else
+ result = I2C_NACK;
switch (cmd_type) {
case I2C_WRITE:
- if (addr && addr_len) {
- writel(chip, &i2c->iicds);
- /* send START */
- writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
- &i2c->iicstat);
- i = 0;
- while ((i < addr_len) && (result == I2C_OK)) {
- result = WaitForXfer(i2c);
- writel(addr[i], &i2c->iicds);
- ReadWriteByte(i2c);
- i++;
- }
- i = 0;
- while ((i < data_len) && (result == I2C_OK)) {
- result = WaitForXfer(i2c);
- writel(data[i], &i2c->iicds);
- ReadWriteByte(i2c);
- i++;
- }
- } else {
+ if (result == I2C_OK)
+ result = i2c_send_verify(i2c, data, data_len);
+ else {
writel(chip, &i2c->iicds);
/* send START */
writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
- &i2c->iicstat);
- i = 0;
- while ((i < data_len) && (result = I2C_OK)) {
- result = WaitForXfer(i2c);
- writel(data[i], &i2c->iicds);
- ReadWriteByte(i2c);
- i++;
- }
+ &i2c->iicstat);
+ if (WaitForXfer(i2c) == I2C_OK)
+ result = i2c_send_verify(i2c, data, data_len);
}
if (result == I2C_OK)
@@ -348,42 +366,25 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c,
break;
case I2C_READ:
- if (addr && addr_len) {
- writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
+ if (result == I2C_OK) {
+ writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
writel(chip, &i2c->iicds);
/* send START */
writel(readl(&i2c->iicstat) | I2C_START_STOP,
&i2c->iicstat);
- result = WaitForXfer(i2c);
- if (IsACK(i2c)) {
- i = 0;
- while ((i < addr_len) && (result == I2C_OK)) {
- writel(addr[i], &i2c->iicds);
- ReadWriteByte(i2c);
- result = WaitForXfer(i2c);
- i++;
- }
-
- writel(chip, &i2c->iicds);
- /* resend START */
- writel(I2C_MODE_MR | I2C_TXRX_ENA |
- I2C_START_STOP, &i2c->iicstat);
ReadWriteByte(i2c);
result = WaitForXfer(i2c);
- i = 0;
- while ((i < data_len) && (result == I2C_OK)) {
- /* disable ACK for final READ */
- if (i == data_len - 1)
- writel(readl(&i2c->iiccon)
+ i = 0;
+ while ((i < data_len) && (result == I2C_OK)) {
+ /* disable ACK for final READ */
+ if (i == data_len - 1)
+ writel(readl(&i2c->iiccon)
& ~I2CCON_ACKGEN,
&i2c->iiccon);
ReadWriteByte(i2c);
result = WaitForXfer(i2c);
- data[i] = readl(&i2c->iicds);
- i++;
- }
- } else {
- result = I2C_NACK;
+ data[i] = readl(&i2c->iicds);
+ i++;
}
} else {
--
1.8.0
2
1

23 Apr '13
From: Mathias Leblanc <mathias.leblanc(a)st.com>
* STMicroelectronics version 1.2.0, Copyright (C) 2013
* This is free software, and you are welcome to redistribute it
* under certain conditions.
This is the driver for TPM chip from ST Microelectronics.
If you have a TPM security chip from STMicroelectronics working with
an I2C, read the README file and add the correct defines regarding
the tpm in the configuration file of your board.
This file is located in include/configs/your_board.h
The driver will be accessible from within uboot terminal.
Signed-off-by: Mathias Leblanc <mathias.leblanc(a)st.com>
---
Makefile | 2 +-
README | 14 +-
common/cmd_tpm.c | 170 +++++++++++-
drivers/tpm/Makefile | 1 +
drivers/tpm/compatibility.h | 52 ++++
drivers/tpm/tis_i2c.c | 248 +++++++++++++++++
drivers/tpm/tpm.c | 477 ++++++++++++++++++++++++++++++++
drivers/tpm/tpm.h | 170 +++++++++++
drivers/tpm/tpm_i2c_st.c | 599 ++++++++++++++++++++++++++++++++++++++++
include/configs/coreboot.h | 4 +-
include/configs/omap3_beagle.h | 8 +
include/tpm.h | 17 ++
12 files changed, 1757 insertions(+), 5 deletions(-)
create mode 100644 drivers/tpm/compatibility.h
create mode 100644 drivers/tpm/tis_i2c.c
create mode 100644 drivers/tpm/tpm.c
create mode 100644 drivers/tpm/tpm.h
create mode 100644 drivers/tpm/tpm_i2c_st.c
diff --git a/Makefile b/Makefile
index 12763ce..ef954a4 100644
--- a/Makefile
+++ b/Makefile
@@ -314,7 +314,7 @@ endif
LIBS-y += drivers/rtc/librtc.o
LIBS-y += drivers/serial/libserial.o
LIBS-y += drivers/sound/libsound.o
-LIBS-$(CONFIG_GENERIC_LPC_TPM) += drivers/tpm/libtpm.o
+LIBS-$(CONFIG_TPM) += drivers/tpm/libtpm.o
LIBS-y += drivers/twserial/libtws.o
LIBS-y += drivers/usb/eth/libusb_eth.o
LIBS-y += drivers/usb/gadget/libusb_gadget.o
diff --git a/README b/README
index 7f2506a..3b1b633 100644
--- a/README
+++ b/README
@@ -1201,7 +1201,7 @@ The following options need to be configured:
If this option is set, the driver enables cache flush.
- TPM Support:
- CONFIG_GENERIC_LPC_TPM
+ CONFIG_TPM
Support for generic parallel port TPM devices. Only one device
per system is supported at this time.
@@ -1210,6 +1210,18 @@ The following options need to be configured:
to. Contemporary x86 systems usually map it at
0xfed40000.
+ CONFIG_ST_TPM_I2C
+ Define to compile the ST TPM I2C DRIVER.
+
+ CONFIG_TPM_I2C_BUS
+ Define the bus number of the board.
+
+ CONFIG_TPM_I2C_ADDR
+ Define the address of the TPM.
+
+ CONFIG_CMD_TPM
+ Define to use some TPM u-boot commands.
+
- USB Support:
At the moment only the UHCI host controller is
supported (PIP405, MIP405, MPC5200); define
diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c
index 0970a6f..2b7bf35 100644
--- a/common/cmd_tpm.c
+++ b/common/cmd_tpm.c
@@ -145,10 +145,177 @@ static int do_tpm_many(cmd_tbl_t *cmdtp, int flag,
return rv;
}
+static int do_tpm_hash(cmd_tbl_t *cmdtp, int flag, int argc,
+char * const argv[])
+{
+ u8 tpm_buffer[MAX_TRANSACTION_SIZE];
+ u32 write_size, read_size;
+ char *p;
+ int rv = -1;
+ argc -= 1;
+ argv += 1;
+ u8 response[MAX_TRANSACTION_SIZE];
+ u32 rlength = MAX_TRANSACTION_SIZE;
+
+ u8 startup[] = {
+ 0x00, 0xc1,
+ 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x99,
+ 0x00, 0x01
+ };
+
+ u8 selftestfull[] = {
+ 0x00, 0xc1,
+ 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x50
+ };
+
+ u8 readpcr17[] = {
+ 0x00, 0xc1,
+ 0x00, 0x00, 0x00, 0x0e,
+ 0x00, 0x00, 0x00, 0x15,
+ 0x00, 0x00, 0x00, 0x11
+ };
+
+ for (write_size = 0; write_size < argc; write_size++) {
+ u32 datum = simple_strtoul(argv[write_size], &p, 0);
+ if (*p || (datum > 0xff)) {
+ printf("\n%s: bad data value\n\n", argv[write_size]);
+ cmd_usage(cmdtp);
+ return rv;
+ }
+ tpm_buffer[write_size] = (u8)datum;
+ }
+
+ if (tis_init()) {
+ puts("tis_init() failed!\n");
+ return -1;
+ }
+
+ if (tis_open()) {
+ puts("tis_open() failed!\n");
+ return -1;
+ }
+
+ rv = tis_sendrecv(startup, sizeof(startup), &response, &rlength);
+ if (rv) {
+ printf("tpm test startup failed\n");
+ CHECK(tis_close());
+ }
+
+ rv = tis_sendrecv(selftestfull, sizeof(selftestfull), &response,
+ &rlength);
+ if (rv) {
+ printf("tpm test selftestfull failed\n");
+ CHECK(tis_close());
+ }
+
+ if (!
+ tis_sendrecv(readpcr17, sizeof(readpcr17), &response, &read_size)) {
+ int i;
+ puts("TPM Read PCR 17:\n");
+ for (i = 10; i < read_size; i++)
+ printf(" %2.2x", response[i]);
+ puts("\n");
+ rv = 0;
+ } else {
+ printf("tpm test readpcr17 failed\n");
+ CHECK(tis_close());
+ }
+
+ read_size = sizeof(tpm_buffer);
+ if (!
+ tis_sendrecv_hash(tpm_buffer, write_size, tpm_buffer, &read_size)) {
+ int i;
+ puts("Got TPM Hash response:\n");
+ for (i = 0; i < read_size; i++)
+ printf(" %2.2x", tpm_buffer[i]);
+ puts("\n");
+ rv = 0;
+ } else {
+ puts("tpm hash command failed\n");
+ }
+
+ if (!
+ tis_sendrecv(readpcr17, sizeof(readpcr17), &response, &read_size)) {
+ int i;
+ puts("TPM Read PCR 17 after hash:\n");
+ for (i = 10; i < read_size; i++)
+ printf(" %2.2x", response[i]);
+ puts("\n");
+ rv = 0;
+ } else {
+ printf("tpm test readpcr17 failed\n");
+ CHECK(tis_close());
+ }
+
+ if (tis_close()) {
+ puts("tis_close() failed!\n");
+ rv = -1;
+ }
+
+ return rv;
+}
+
+static int do_tpm_get_flag(void)
+{
+ int rv = 0;
+ u8 response[MAX_TRANSACTION_SIZE];
+ u32 rlength = MAX_TRANSACTION_SIZE;
+
+ u8 startup[] = {
+ 0x00, 0xc1,
+ 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x99,
+ 0x00, 0x01
+ };
+ u8 selftestfull[] = {
+ 0x00, 0xc1,
+ 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0x50
+ };
+ u8 getpermflags[] = {
+ 0x00, 0xc1,
+ 0x00, 0x00, 0x00, 0x16,
+ 0x00, 0x00, 0x00, 0x65,
+ 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x01, 0x08
+ };
+
+
+ CHECK(tis_init());
+
+
+ CHECK(tis_open());
+ rv = tis_sendrecv(startup, sizeof(startup), response, &rlength);
+ if (rv) {
+ printf("tpm test startup failed\n");
+ CHECK(tis_close());
+ }
+ rv = tis_sendrecv(selftestfull, sizeof(selftestfull), response,
+ &rlength);
+ if (rv) {
+ printf("tpm test selftestfull failed\n");
+ CHECK(tis_close());
+ }
+ rv = tis_sendrecv(getpermflags, sizeof(getpermflags), response,
+ &rlength);
+ if (rv) {
+ printf("tpm test getpermflags failed\n");
+ CHECK(tis_close());
+ }
+ CHECK(tis_close());
+ return rv;
+}
static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- return do_tpm_many(cmdtp, flag, argc, argv, 0);
+ if (strcmp(argv[1], "hash"))
+ return do_tpm_hash(cmdtp, flag, argc, argv);
+ else if (strcmp(argv[1], "get_flag"))
+ return do_tpm_get_flag();
+ else
+ return do_tpm_many(cmdtp, flag, argc, argv, 0);
}
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index be11c8b..802b54e 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -24,6 +24,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libtpm.o
COBJS-$(CONFIG_GENERIC_LPC_TPM) = generic_lpc_tpm.o
+COBJS-$(CONFIG_ST_TPM_I2C) = tis_i2c.o tpm.o tpm_i2c_st.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/tpm/compatibility.h b/drivers/tpm/compatibility.h
new file mode 100644
index 0000000..c68a855
--- /dev/null
+++ b/drivers/tpm/compatibility.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external(a)infineon.com>
+ *
+ * Version: 2.1.1
+ *
+ * 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 _COMPATIBILITY_H_
+#define _COMPATIBILITY_H_
+
+/* all includes from U-Boot */
+#include <linux/types.h>
+#include <linux/unaligned/be_byteshift.h>
+#include <asm-generic/errno.h>
+#include <compiler.h>
+#include <common.h>
+
+/* extended error numbers from linux (see errno.h) */
+#define ECANCELED 125 /* Operation Canceled */
+
+#define msleep(t) udelay((t)*1000)
+
+/* Timer frequency. Corresponds to msec timer resolution*/
+#define HZ 1000
+
+
+#define dev_dbg(dev, format, arg...) debug(format, ##arg)
+#define dev_err(dev, format, arg...) printf(format, ##arg)
+#define dev_info(dev, format, arg...) debug(format, ##arg)
+#define dbg_printf debug
+
+#endif
diff --git a/drivers/tpm/tis_i2c.c b/drivers/tpm/tis_i2c.c
new file mode 100644
index 0000000..3b3740f
--- /dev/null
+++ b/drivers/tpm/tis_i2c.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external(a)infineon.com>
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
+ * Infineon I2C Protocol Stack Specification v0.20.
+ *
+ * It is based on the Linux kernel driver tpm.c from Leendert van
+ * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
+ *
+ * Version: 2.1.1
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *Date: Monday April 13
+ *
+ * [backport from https://github.com/theopolis/u-boot-sboot/
+ * blob/master/drivers/tpm/tis_i2c.c]
+ */
+
+#include <config.h>
+#include <common.h>
+#include <i2c.h>
+#include "tpm.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Define in board config */
+#ifndef CONFIG_TPM_I2C_BUS
+ #define CONFIG_TPM_I2C_BUS 0
+ #define CONFIG_TPM_I2C_ADDR 0
+#endif
+
+/* TPM configuration */
+struct tpm {
+ int i2c_bus;
+ int slave_addr;
+ char inited;
+ int old_bus;
+} tpm;
+
+
+static int tpm_select(void)
+{
+ int ret;
+
+ tpm.old_bus = i2c_get_bus_num();
+ if (tpm.old_bus != tpm.i2c_bus) {
+ ret = i2c_set_bus_num(tpm.i2c_bus);
+ if (ret) {
+ debug("%s: Fail to set i2c bus %d\n", __func__,
+ tpm.i2c_bus);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int tpm_deselect(void)
+{
+ int ret;
+
+ if (tpm.old_bus != i2c_get_bus_num()) {
+ ret = i2c_set_bus_num(tpm.old_bus);
+ if (ret) {
+ debug("%s: Fail to restore i2c bus %d\n",
+ __func__, tpm.old_bus);
+ return -1;
+ }
+ }
+ tpm.old_bus = -1;
+ return 0;
+}
+
+/**
+ * Decode TPM configuration.
+ *
+ * @param dev Returns a configuration of TPM device
+ * @return 0 if ok, -1 on error
+ */
+static int tpm_decode_config(struct tpm *dev)
+{
+#ifdef CONFIG_OF_CONTROL
+ const void *blob = gd->fdt_blob;
+ int node, parent;
+ int i2c_bus;
+
+ node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
+ if (node < 0) {
+ debug("%s: Node not found\n", __func__);
+ return -1;
+ }
+ parent = fdt_parent_offset(blob, node);
+ if (parent < 0) {
+ debug("%s: Cannot find node parent\n", __func__);
+ return -1;
+ }
+ i2c_bus = i2c_get_bus_num_fdt(blob, parent);
+ if (i2c_bus < 0)
+ return -1;
+ dev->i2c_bus = i2c_bus;
+ dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
+#else
+ dev->i2c_bus = CONFIG_TPM_I2C_BUS;
+ dev->slave_addr = CONFIG_TPM_I2C_ADDR;
+#endif
+ return 0;
+}
+
+/* Methods used by cmd_tpm */
+int tis_init(void)
+{
+ if (tpm.inited)
+ return 0;
+ if (tpm_decode_config(&tpm))
+ return -1;
+ if (tpm_select())
+ return -1;
+ /*
+ * Probe TPM twice; the first probing might fail because TPM is asleep,
+ * and the probing can wake up TPM.
+ */
+ if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
+ debug(
+ "%s: fail to probe i2c addr 0x%x\n", __func__, tpm.slave_addr);
+ return -1;
+ }
+ tpm_deselect();
+ tpm.inited = 1;
+ return 0;
+}
+
+int tis_open(void)
+{
+ int rc;
+ if (!tpm.inited)
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ rc = tpm_open(tpm.slave_addr);
+ tpm_deselect();
+
+ return rc;
+}
+
+int tis_close(void)
+{
+ if (!tpm.inited)
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ tpm_close();
+
+ tpm_deselect();
+
+ return 0;
+}
+
+int tis_sendrecv_hash(const uint8_t *sendbuf, size_t sbuf_size,
+ uint8_t *recvbuf, size_t *rbuf_len)
+{
+ int len;
+ uint8_t buf[TPM_BUFSIZE];
+
+ if (!tpm.inited)
+ return -1;
+
+ if (sizeof(buf) < sbuf_size)
+ return -1;
+
+ memcpy(buf, sendbuf, sbuf_size);
+
+ if (tpm_select())
+ return -1;
+
+ len = tpm_transmit_hash(buf, sbuf_size);
+
+ tpm_deselect();
+
+ if (len < 10) {
+ *rbuf_len = 0;
+ return -1;
+ }
+
+ memcpy(recvbuf, buf, len);
+ *rbuf_len = len;
+
+ return 0;
+}
+
+int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
+ uint8_t *recvbuf, size_t *rbuf_len)
+{
+ int len;
+ uint8_t buf[TPM_BUFSIZE];
+
+ if (!tpm.inited)
+ return -1;
+
+ if (sizeof(buf) < sbuf_size)
+ return -1;
+
+ memcpy(buf, sendbuf, sbuf_size);
+
+ if (tpm_select())
+ return -1;
+
+ len = tpm_transmit(buf, sbuf_size);
+
+ tpm_deselect();
+
+ if (len < 10) {
+ *rbuf_len = 0;
+ return -1;
+ }
+
+ memcpy(recvbuf, buf, len);
+ *rbuf_len = len;
+
+ return 0;
+}
diff --git a/drivers/tpm/tpm.c b/drivers/tpm/tpm.c
new file mode 100644
index 0000000..25d6157
--- /dev/null
+++ b/drivers/tpm/tpm.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external(a)infineon.com>
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * It is based on the Linux kernel driver tpm.c from Leendert van
+ * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
+ *
+ * Version: 2.1.1
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *Date: Monday April 13
+ *
+ * [backport from https://github.com/theopolis/u-boot-sboot/
+ * blob/master/drivers/tpm/tpm.c]
+ */
+
+#include <malloc.h>
+#include "tpm.h"
+
+/* global structure for tpm chip data */
+struct tpm_chip g_chip;
+
+enum tpm_duration {
+ TPM_SHORT = 0,
+ TPM_MEDIUM = 1,
+ TPM_LONG = 2,
+ TPM_UNDEFINED,
+};
+
+#define TPM_MAX_ORDINAL 243
+#define TPM_MAX_PROTECTED_ORDINAL 12
+#define TPM_PROTECTED_ORDINAL_MASK 0xFF
+
+/*
+ * Array with one entry per ordinal defining the maximum amount
+ * of time the chip could take to return the result. The ordinal
+ * designation of short, medium or long is defined in a table in
+ * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
+ * values of the SHORT, MEDIUM, and LONG durations are retrieved
+ * from the chip during initialization with a call to tpm_get_timeouts.
+ */
+static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
+ TPM_UNDEFINED, /* 0 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 5 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 10 */
+ TPM_SHORT,
+};
+
+static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
+ TPM_UNDEFINED, /* 0 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 5 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 10 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_LONG,
+ TPM_MEDIUM, /* 15 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_SHORT, /* 20 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT, /* 25 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 30 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 35 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 40 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 45 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_LONG,
+ TPM_MEDIUM, /* 50 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 55 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 60 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 65 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 70 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 75 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 80 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 85 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 90 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 95 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 100 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 105 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 110 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 115 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 120 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 125 */
+ TPM_SHORT,
+ TPM_LONG,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 130 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_UNDEFINED, /* 135 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 140 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 145 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 150 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 155 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 160 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 165 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 170 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 175 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 180 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM, /* 185 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 190 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 195 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 200 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 205 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 210 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_UNDEFINED, /* 215 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 220 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 225 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 230 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 235 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 240 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+};
+
+/*
+ * Returns max number of milliseconds to wait
+ */
+unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
+{
+ int duration_idx = TPM_UNDEFINED;
+ int duration = 0;
+
+ if (ordinal < TPM_MAX_ORDINAL)
+ duration_idx = tpm_ordinal_duration[ordinal];
+ else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
+ TPM_MAX_PROTECTED_ORDINAL)
+ duration_idx =
+ tpm_protected_ordinal_duration[ordinal &
+ TPM_PROTECTED_ORDINAL_MASK];
+
+ if (duration_idx != TPM_UNDEFINED)
+ duration = chip->vendor.duration[duration_idx];
+ if (duration <= 0)
+ return 2 * 60 * HZ; /*two minutes timeout*/
+ else
+ return duration;
+}
+
+ssize_t tpm_transmit_hash(const unsigned char *buf, size_t bufsiz)
+{
+ ssize_t rc;
+ u32 count, ordinal;
+ unsigned long start, stop;
+
+ struct tpm_chip *chip = &g_chip;
+
+ rc = chip->vendor.send_hash(chip, (u8 *)buf, bufsiz);
+ if (rc < 0) {
+ dev_err(chip->dev, "tpm_transmit: tpm_send: error %zd\n", rc);
+ goto out;
+ }
+
+out_recv:
+
+ dbg_printf("out_recv: reading response...\n");
+ rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
+ if (rc < 0)
+ dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc);
+out:
+ return rc;
+}
+
+ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
+{
+ ssize_t rc;
+ u32 count, ordinal;
+ unsigned long start, stop;
+
+ struct tpm_chip *chip = &g_chip;
+
+ /* switch endianess: big->little */
+ count = get_unaligned_be32(buf + TPM_CMD_SIZE_BYTE);
+ ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
+
+ if (count == 0) {
+ dev_err(chip->dev, "no data\n");
+ return -ENODATA;
+ }
+ if (count > bufsiz) {
+ dev_err(chip->dev,
+ "invalid count value %x %zx\n", count, bufsiz);
+ return -E2BIG;
+ }
+
+ rc = chip->vendor.send(chip, (u8 *)buf, count);
+ if (rc < 0) {
+ dev_err(chip->dev, "tpm_transmit: tpm_send: error %zd\n", rc);
+ goto out;
+ }
+
+ if (chip->vendor.irq)
+ goto out_recv;
+
+ start = get_timer(0);
+ stop = tpm_calc_ordinal_duration(chip, ordinal);
+ do {
+ dbg_printf("waiting for status...\n");
+ u8 status = chip->vendor.status(chip);
+ if ((status & chip->vendor.req_complete_mask) ==
+ chip->vendor.req_complete_val) {
+ dbg_printf("...got it;\n");
+ goto out_recv;
+ }
+
+ if ((status == chip->vendor.req_canceled)) {
+ dev_err(chip->dev, "Operation Canceled\n");
+ rc = -ECANCELED;
+ goto out;
+ }
+ msleep(TPM_TIMEOUT);
+ } while (get_timer(start) < stop);
+
+ chip->vendor.cancel(chip);
+ dev_err(chip->dev, "Operation Timed out\n");
+ rc = -ETIME;
+ goto out;
+
+out_recv:
+
+ dbg_printf("out_recv: reading response...\n");
+ rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
+ if (rc < 0)
+ dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc);
+out:
+ return rc;
+}
+
+enum tpm_capabilities {
+ TPM_CAP_PROP = cpu_to_be32(5),
+};
+
+enum tpm_sub_capabilities {
+ TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
+ TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
+};
+
+struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
+{
+ struct tpm_chip *chip;
+
+ /* Driver specific per-device data */
+ chip = &g_chip;
+ memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
+ chip->is_open = 1;
+
+ return chip;
+}
+
+int tpm_open(uint32_t dev_addr)
+{
+ int rc;
+ if (g_chip.is_open)
+ return -EBUSY;
+ rc = tpm_vendor_init(dev_addr);
+ if (rc < 0)
+ g_chip.is_open = 0;
+ return rc;
+}
+
+void tpm_close(void)
+{
+ if (g_chip.is_open) {
+ tpm_vendor_cleanup(&g_chip);
+ g_chip.is_open = 0;
+ }
+}
diff --git a/drivers/tpm/tpm.h b/drivers/tpm/tpm.h
new file mode 100644
index 0000000..e5ce16e
--- /dev/null
+++ b/drivers/tpm/tpm.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2011 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <huewe.external(a)infineon.com>
+ *
+ * Version: 2.1.1
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * It is based on the Linux kernel driver tpm.c from Leendert van
+ * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
+ *
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *Date: Monday April 13
+ *
+ * [backport from https://github.com/theopolis/u-boot-sboot/
+ * blob/master/drivers/tpm/tpm.h]
+ */
+
+#ifndef _TPM_H_
+#define _TPM_H_
+
+#include "compatibility.h"
+
+enum tpm_timeout {
+ TPM_TIMEOUT = 5, /* msecs */
+};
+
+/* Size of external transmit buffer (used in tpm_transmit)*/
+#define TPM_BUFSIZE 4096
+#define TPM_ERROR_SIZE 10
+#define TPM_HEADER_SIZE 10
+
+/* Index of fields in TPM command buffer */
+#define TPM_CMD_SIZE_BYTE 2
+#define TPM_CMD_ORDINAL_BYTE 6
+
+/* Index of Count field in TPM response buffer */
+#define TPM_RSP_SIZE_BYTE 2
+#define TPM_RSP_RC_BYTE 6
+
+struct tpm_chip;
+
+struct tpm_vendor_specific {
+ const u8 req_complete_mask;
+ const u8 req_complete_val;
+ const u8 req_canceled;
+ int irq;
+ int (*recv) (struct tpm_chip *, u8 *, size_t);
+ int (*send) (struct tpm_chip *, u8 *, size_t);
+ int (*send_hash) (struct tpm_chip *, u8 *, size_t);
+ void (*cancel) (struct tpm_chip *);
+ u8 (*status) (struct tpm_chip *);
+ int locality;
+ unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
+ unsigned long duration[3]; /* msec */
+};
+
+struct tpm_chip {
+ int is_open;
+ struct tpm_vendor_specific vendor;
+ /* testing */
+ u8 dev;
+};
+
+struct tpm_input_header {
+ __be16 tag;
+ __be32 length;
+ __be32 ordinal;
+} __packed;
+
+struct tpm_output_header {
+ __be16 tag;
+ __be32 length;
+ __be32 return_code;
+} __packed;
+
+struct timeout_t {
+ __be32 a;
+ __be32 b;
+ __be32 c;
+ __be32 d;
+} __packed;
+
+struct duration_t {
+ __be32 tpm_short;
+ __be32 tpm_medium;
+ __be32 tpm_long;
+} __packed;
+
+struct cap_t {
+ struct timeout_t timeout;
+ struct duration_t duration;
+} __packed;
+
+struct tpm_getcap_params_in {
+ __be32 cap;
+ __be32 subcap_size;
+ __be32 subcap;
+} __packed;
+
+struct tpm_getcap_params_out {
+ __be32 cap_size;
+ struct cap_t cap;
+} __packed;
+
+struct tpm_cmd_header {
+ struct tpm_input_header in;
+ struct tpm_output_header out;
+} __packed;
+
+struct tpm_cmd_params {
+ struct tpm_getcap_params_out getcap_out;
+ struct tpm_getcap_params_in getcap_in;
+} __packed;
+
+struct tpm_cmd_t {
+ struct tpm_cmd_header header;
+ struct tpm_cmd_params params;
+} __packed;
+
+
+/* ---------- Interface for TPM vendor ------------ */
+
+extern struct tpm_chip *tpm_register_hardware(
+ const struct tpm_vendor_specific *);
+
+extern int tpm_vendor_init(uint32_t dev_addr);
+
+extern void tpm_vendor_cleanup(struct tpm_chip *chip);
+
+/* ---------- Interface for TDDL ------------------- */
+
+/*
+ * if dev_addr != 0 - redefines TPM device address
+ * Returns < 0 on error, 0 on success.
+ */
+extern int tpm_open(uint32_t dev_addr);
+
+extern void tpm_close(void);
+
+/*
+ * Transmit bufsiz bytes out of buf to TPM and get results back in buf, too.
+ * Returns < 0 on error, 0 on success.
+ */
+extern ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz);
+
+#endif
diff --git a/drivers/tpm/tpm_i2c_st.c b/drivers/tpm/tpm_i2c_st.c
new file mode 100644
index 0000000..f630dbd
--- /dev/null
+++ b/drivers/tpm/tpm_i2c_st.c
@@ -0,0 +1,599 @@
+/*
+ * STMicroelectronics TPM I2C UBOOT Linux driver for TPM ST33ZP24
+ * Copyright (C) 2013 STMicroelectronics
+ *
+ * (c) Copyright 2013 Mathias Leblanc <mathias.leblanc(a)st.com>
+ * This file is released under the terms of GPL v2 and any later version
+ * See the file COPYING in the root directory of the source tree for details
+ *
+ * Description:
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
+ * STMicroelectronics I2C Protocol Stack Specification version 1.2.0.
+ *
+ * It is based on the Linux I2C TPM driver from Peter Huewe, modified
+ * from the original tpm
+ * device drivers from Leendert van Dorn, Dave Safford, Reiner Sailer
+ * and Kyleen Hall.
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * @Author: Mathias Leblanc tpmsupport(a)st.com
+ *
+ * @File: tpm_i2c_st.c
+ *
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <linux/types.h>
+
+#include "compatibility.h"
+#include "tpm.h"
+
+/* max. buffer size supported by our tpm */
+#ifdef TPM_BUFSIZE
+#undef TPM_BUFSIZE
+#endif
+
+#define MINOR_NUM_I2C 224
+
+#define TPM_ACCESS (0x0)
+#define TPM_STS (0x18)
+#define TPM_HASH_END (0x20)
+#define TPM_DATA_FIFO (0x24)
+#define TPM_HASH_DATA (0x24)
+#define TPM_HASH_START (0x28)
+#define TPM_INTF_CAPABILITY (0x14)
+#define TPM_INT_STATUS (0x10)
+#define TPM_INT_ENABLE (0x08)
+
+#define TPM_DUMMY_BYTE 0xAA
+#define TPM_WRITE_DIRECTION 0x80
+#define TPM_HEADER_SIZE 10
+#define TPM_BUFSIZE 2048
+
+#define LOCALITY0 0
+#define LOCALITY4 4
+
+struct st_tpm_hash {
+ int size;
+ u8 *data;
+};
+
+enum stm33zp24_access {
+ TPM_ACCESS_VALID = 0x80,
+ TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
+ TPM_ACCESS_REQUEST_PENDING = 0x04,
+ TPM_ACCESS_REQUEST_USE = 0x02,
+};
+
+enum stm33zp24_status {
+ TPM_STS_VALID = 0x80,
+ TPM_STS_COMMAND_READY = 0x40,
+ TPM_STS_GO = 0x20,
+ TPM_STS_DATA_AVAIL = 0x10,
+ TPM_STS_DATA_EXPECT = 0x08,
+};
+
+enum stm33zp24_int_flags {
+ TPM_GLOBAL_INT_ENABLE = 0x80,
+ TPM_INTF_CMD_READY_INT = 0x080,
+ TPM_INTF_FIFO_AVALAIBLE_INT = 0x040,
+ TPM_INTF_WAKE_UP_READY_INT = 0x020,
+ TPM_INTF_LOC4SOFTRELEASE_INT = 0x008,
+ TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
+ TPM_INTF_STS_VALID_INT = 0x002,
+ TPM_INTF_DATA_AVAIL_INT = 0x001,
+};
+
+enum tis_defaults {
+ TIS_SHORT_TIMEOUT = 750, /* ms */
+ TIS_LONG_TIMEOUT = 2000, /* 2 sec */
+};
+
+struct tpm_i2c_ST_dev {
+ uint addr;
+ u8 buf[TPM_BUFSIZE];
+};
+
+static struct tpm_i2c_ST_dev tpm_dev = {
+ /* Note: replace with defined addr from board configuration */
+ .addr = CONFIG_TPM_I2C_ADDR
+};
+
+/*
+ * write8_reg
+ * Send byte to the TIS register according to the ST33ZP24 I2C protocol.
+ * @param: tpm_register, the tpm tis register where the data should be written
+ * @param: tpm_data, the tpm_data to write inside the tpm_register
+ * @param: tpm_size, The length of the data
+ * @return: Returns zero in case of success else the negative error code.
+ */
+static int write8_reg(u8 addr, u8 tpm_register,
+ u8 *tpm_data, u16 tpm_size)
+{
+ u8 data;
+ data = tpm_register;
+ memcpy(&(tpm_dev.buf[0]), &data, sizeof(data));
+ memcpy(&(tpm_dev.buf[0])+1, tpm_data, tpm_size);
+
+ return i2c_write(addr, 0, 0, &tpm_dev.buf[0],
+ tpm_size + 1);
+
+} /* write8_reg() */
+
+/*
+* read8_reg
+* Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
+* @param: tpm_register, the tpm tis register where the data should be read
+* @param: tpm_data, the TPM response
+* @param: tpm_size, tpm TPM response size to read.
+* @return: Returns zero in case of success else the negative error code.
+*/
+static int read8_reg(u8 addr, u8 tpm_register,
+u8 *tpm_data, int tpm_size)
+{
+ u8 status = 0;
+ u8 data;
+ data = TPM_DUMMY_BYTE;
+ status = write8_reg(addr, tpm_register, &data, 1);
+ if (status == 0)
+ status = i2c_read(addr, 0, 0, tpm_data, tpm_size);
+return status;
+} /* read8_reg() */
+
+/*
+ * I2C_WRITE_DATA
+ * Send byte to the TIS register according to the ST33ZP24 I2C protocol.
+ * @param: client, the chip description
+ * @param: tpm_register, the tpm tis register where the data should be written
+ * @param: tpm_data, the tpm_data to write inside the tpm_register
+ * @param: tpm_size, The length of the data
+ * @return: Returns zero in case of success else the negative error code.
+ */
+#define I2C_WRITE_DATA(client, tpm_register, tpm_data, tpm_size)\
+ (write8_reg(client, tpm_register | \
+ TPM_WRITE_DIRECTION, tpm_data, tpm_size))
+
+/*
+ * I2C_READ_DATA
+ * Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
+ * @param: tpm, the chip description
+ * @param: tpm_register, the tpm tis register where the data should be read
+ * @param: tpm_data, the TPM response
+ * @param: tpm_size, tpm TPM response size to read.
+ * @return: Returns zero in case of success else the negative error code.
+ */
+#define I2C_READ_DATA(client, tpm_register, tpm_data, tpm_size)\
+ (read8_reg(client, tpm_register, tpm_data, tpm_size))
+
+/*
+ * release_locality release the active locality
+ * @param: chip, the tpm chip description.
+ */
+static void release_locality(struct tpm_chip *chip)
+{
+ u8 data = TPM_ACCESS_ACTIVE_LOCALITY;
+
+ I2C_WRITE_DATA(tpm_dev.addr, TPM_ACCESS, &data, 1);
+}
+
+/*
+ * clear_interruption
+ * clear the TPM interrupt register.
+ * @param: tpm, the chip description
+ */
+static void clear_interruption(u8 addr)
+{
+ u8 interrupt;
+ I2C_READ_DATA(tpm_dev.addr, TPM_INT_STATUS, &interrupt, 1);
+ I2C_WRITE_DATA(tpm_dev.addr, TPM_INT_STATUS, &interrupt, 1);
+ I2C_READ_DATA(tpm_dev.addr, TPM_INT_STATUS, &interrupt, 1);
+} /* clear_interruption() */
+
+int wait_for_serirq_timeout(struct tpm_chip *chip, int condition,
+ unsigned long timeout)
+{
+ int status = 2;
+
+ clear_interruption(tpm_dev.addr);
+ if (condition)
+ status = 1;
+
+ return status;
+}
+
+/*
+ * check_locality if the locality is active
+ * @param: chip, the tpm chip description
+ * @return: the active locality or -EACCESS.
+ */
+static int check_locality(struct tpm_chip *chip)
+{
+ u8 data;
+ u8 status;
+ status = I2C_READ_DATA(tpm_dev.addr, TPM_ACCESS, &data, 1);
+
+ if ((status == 0) && (data &
+ (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
+ return chip->vendor.locality;
+
+ return -EACCES;
+
+} /* check_locality() */
+
+/*
+ * request_locality request the TPM locality
+ * @param: chip, the chip description
+ * @return: the active locality or EACCESS.
+ */
+static int request_locality(struct tpm_chip *chip)
+{
+ unsigned long start, stop;
+ long rc;
+ u8 data;
+ if (check_locality(chip) == chip->vendor.locality)
+ return chip->vendor.locality;
+
+ data = TPM_ACCESS_REQUEST_USE;
+ rc = I2C_WRITE_DATA(tpm_dev.addr, TPM_ACCESS, &data, 1);
+ if (rc < 0)
+ goto end;
+
+ if (chip->vendor.irq) {
+ rc = wait_for_serirq_timeout(chip, (check_locality
+ (chip) >= 0),
+ chip->vendor.timeout_a);
+ if (rc > 0)
+ return chip->vendor.locality;
+ } else{
+ /* wait for locality activated */
+ start = get_timer(0);
+ stop = chip->vendor.timeout_a;
+ do {
+ if (check_locality(chip) >= 0)
+ return chip->vendor.locality;
+
+ msleep(TPM_TIMEOUT);
+ } while (get_timer(start) < stop);
+ }
+ rc = -EACCES;
+end:
+ return rc;
+} /* request_locality() */
+
+/*
+ * tpm_stm_i2c_cancel, cancel is not implemented.
+ * @param: chip, tpm_chip description.
+ */
+static void tpm_stm_i2c_cancel(struct tpm_chip *chip)
+{
+ u8 data;
+
+ data = TPM_STS_COMMAND_READY;
+ I2C_WRITE_DATA(tpm_dev.addr, TPM_STS, &data, 1);
+ if (chip->vendor.irq)
+ wait_for_serirq_timeout(chip, 1, chip->vendor.timeout_a);
+} /* tpm_stm_i2c_cancel() */
+
+/*
+ * tpm_stm_spi_status return the TPM_STS register
+ * @param: chip, the tpm chip description
+ * @return: the TPM_STS register value.
+ */
+static u8 tpm_stm_i2c_status(struct tpm_chip *chip)
+{
+ u8 data;
+ I2C_READ_DATA(tpm_dev.addr, TPM_STS, &data, 1);
+ return data;
+} /* tpm_stm_i2c_status() */
+
+/*
+ * get_burstcount return the burstcount address 0x19 0x1A
+ * @param: chip, the chip description
+ * return: the burstcount.
+ */
+static int get_burstcount(struct tpm_chip *chip)
+{
+ unsigned long start, stop;
+ int burstcnt, status;
+ u8 tpm_reg, temp;
+
+ /* wait for burstcount */
+ /* which timeout value, spec has 2 answers (c & d) */
+ start = get_timer(0);
+ stop = chip->vendor.timeout_d;
+ do {
+ tpm_reg = TPM_STS + 1;
+ status = I2C_READ_DATA(tpm_dev.addr, tpm_reg, &temp, 1);
+ if (status < 0)
+ goto end;
+
+ tpm_reg = tpm_reg + 1;
+ burstcnt = temp;
+ status = I2C_READ_DATA(tpm_dev.addr, tpm_reg, &temp, 1);
+ if (status < 0)
+ goto end;
+
+ burstcnt |= temp << 8;
+ if (burstcnt)
+ return burstcnt;
+
+ msleep(TPM_TIMEOUT);
+ } while (get_timer(start) < stop);
+
+end:
+ return -EBUSY;
+} /* get_burstcount() */
+
+
+/*
+ * recv_data receive data
+ * @param: chip, the tpm chip description
+ * @param: buf, the buffer where the data are received
+ * @param: count, the number of data to receive
+ * @return: the number of bytes read from TPM FIFO.
+ */
+static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ int size = 0, burstcnt, len;
+
+ while (size < count) {
+ burstcnt = get_burstcount(chip);
+ len = count - size;
+ if ((len) > burstcnt)
+ len = burstcnt;
+ if (
+ I2C_READ_DATA(tpm_dev.addr, TPM_DATA_FIFO, buf + size, len) == 0)
+ size += len;
+ else
+ break;
+ }
+ return size;
+} /* recv_data() */
+
+/*
+ * tpm_stm_i2c_recv received TPM response through the I2C bus.
+ * @param: chip, tpm_chip description.
+ * @param: buf, the buffer to store datas.
+ * @param: count, the number of bytes to send.
+ * @return: Returns zero in case of success else the negative error code.
+ */
+static int tpm_stm_i2c_recv(struct tpm_chip *chip, unsigned char *buf,
+ size_t count)
+{
+ int size = 0;
+ int expected;
+
+ if (chip == NULL)
+ return -EBUSY;
+
+ if (count < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
+
+ size = recv_data(chip, buf, TPM_HEADER_SIZE);
+ if (size < TPM_HEADER_SIZE) {
+ dev_err(chip->dev, "Unable to read header\n");
+ goto out;
+ }
+
+
+ expected = get_unaligned_be32(buf + TPM_RSP_SIZE_BYTE);
+ if (expected > count) {
+ size = -EIO;
+ goto out;
+ }
+
+ size += recv_data(chip, &buf[TPM_HEADER_SIZE],
+ expected - TPM_HEADER_SIZE);
+ if (size < expected) {
+ dev_err(chip->dev, "Unable to read remainder of result\n");
+ size = -ETIME;
+ goto out;
+ }
+
+out:
+ chip->vendor.cancel(chip);
+ release_locality(chip);
+ return size;
+} /* tpm_stm_i2c_recv() */
+
+/*
+ * tpm_stm_i2c_send send TPM commands through the I2C bus.
+ *
+ * @param: chip, tpm_chip description.
+ * @param: buf, the buffer to send.
+ * @param: len, the number of bytes to send.
+ * @return: Returns zero in case of success else the negative error code.
+ */
+static int tpm_stm_i2c_send(struct tpm_chip *chip, u8 *buf,
+ size_t len)
+{
+ u32 ret = 0,
+ status,
+ burstcnt = 0, i, size;
+ u8 data;
+
+ if (chip == NULL)
+ return -EBUSY;
+ if (len < TPM_HEADER_SIZE)
+ return -EBUSY;
+
+ ret = request_locality(chip);
+ if (ret < 0)
+ return ret;
+
+ status = tpm_stm_i2c_status(chip);
+ if ((status & TPM_STS_COMMAND_READY) == 0)
+ tpm_stm_i2c_cancel(chip);
+
+ for (i = 0; i < len - 1;) {
+ burstcnt = get_burstcount(chip);
+ size = len - i - 1;
+ if ((size) > burstcnt)
+ size = burstcnt;
+ ret = I2C_WRITE_DATA(tpm_dev.addr, TPM_DATA_FIFO, buf, size);
+ if (ret < 0)
+ goto out_err;
+
+ i += size;
+ }
+
+ status = tpm_stm_i2c_status(chip);
+ if ((status & TPM_STS_DATA_EXPECT) == 0) {
+ ret = -EIO;
+ goto out_err;
+ }
+
+ ret = I2C_WRITE_DATA(tpm_dev.addr, TPM_DATA_FIFO, buf + len - 1, 1);
+ if (ret < 0)
+ goto out_err;
+
+ status = tpm_stm_i2c_status(chip);
+ if ((status & TPM_STS_DATA_EXPECT) != 0) {
+ ret = -EIO;
+ goto out_err;
+ }
+
+ data = TPM_STS_GO;
+ I2C_WRITE_DATA(tpm_dev.addr, TPM_STS, &data, 1);
+
+ return len;
+out_err:
+ tpm_stm_i2c_cancel(chip);
+ release_locality(chip);
+ return ret;
+} /* tpm_stm_i2c_send() */
+
+/*
+ * tpm_stm_i2c_send_hash send TPM locality 4 hash datas through the I2C bus
+ * to update the PCR[17].
+ * @param: chip, the tpm_chip description.
+ * @param: buf, the data buffer to send.
+ * @param: len, the number of bytes to send.
+ * @return: Returns zero in case of success else the negative error code.
+ */
+static int tpm_stm_i2c_send_hash(struct tpm_chip *chip, unsigned char *buf,
+ size_t len)
+{
+ u32 ret = 0;
+ u8 data;
+
+ if (chip == NULL)
+ return -EBUSY;
+
+ release_locality(chip);
+
+ tpm_dev.addr = 0x1B;
+ chip->vendor.locality = LOCALITY4;
+
+ data = TPM_DUMMY_BYTE;
+ ret = I2C_WRITE_DATA(tpm_dev.addr, TPM_HASH_START, &data, 1);
+ if (ret < 0)
+ goto end;
+ ret = I2C_WRITE_DATA(tpm_dev.addr, TPM_DATA_FIFO, buf, len);
+ if (ret < 0)
+ goto end;
+
+end:
+ I2C_WRITE_DATA(tpm_dev.addr, TPM_HASH_END, &data, 1);
+ release_locality(chip);
+ chip->vendor.locality = LOCALITY0;
+ tpm_dev.addr = 0x13;
+ ret = request_locality(chip);
+ return ret;
+} /* tpm_stm_i2c_send_hash */
+
+static struct tpm_vendor_specific st_i2c_tpm = {
+ .send = tpm_stm_i2c_send,
+ .send_hash = tpm_stm_i2c_send_hash,
+ .recv = tpm_stm_i2c_recv,
+ .cancel = tpm_stm_i2c_cancel,
+ .status = tpm_stm_i2c_status,
+ .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_canceled = TPM_STS_COMMAND_READY,
+};
+
+/*
+ * tpm_vendor_init initialize the TPM device
+ * @param: dev_addr, the i2c address of the tpm.
+ * @return: 0 in case of success.
+ * -1 in other case.
+ */
+int tpm_vendor_init(uint32_t dev_addr)
+{
+ u32 vendor;
+ uint old_addr;
+ int rc = 0;
+ struct tpm_chip *chip;
+
+ old_addr = tpm_dev.addr;
+ if (dev_addr != 0)
+ tpm_dev.addr = dev_addr;
+
+ chip = tpm_register_hardware(&st_i2c_tpm);
+
+ if (chip < 0) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ /* Default timeouts */
+ chip->vendor.timeout_a = TIS_SHORT_TIMEOUT;
+ chip->vendor.timeout_b = TIS_LONG_TIMEOUT;
+ chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
+ chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
+
+ chip->vendor.locality = LOCALITY0;
+
+ if (request_locality(chip) != 0) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ vendor = be32_to_cpu(vendor);
+
+
+ dev_info(dev, "1.2 TPM STMicroelectronics");
+ /*
+ * A timeout query to TPM can be placed here.
+ * Standard timeout values are used so far
+ */
+
+ return 0;
+
+out_err:
+ tpm_dev.addr = old_addr;
+ return rc;
+} /* tpm_vendor_init() */
+
+
+
+void tpm_vendor_cleanup(struct tpm_chip *chip)
+{
+ release_locality(chip);
+} /* tpm_vendor_cleanup() */
diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h
index 87daf62..fda6512 100644
--- a/include/configs/coreboot.h
+++ b/include/configs/coreboot.h
@@ -76,8 +76,8 @@
CONFIG_SYS_SCSI_MAX_LUN)
#endif
-/* Generic TPM interfaced through LPC bus */
-#define CONFIG_GENERIC_LPC_TPM
+/* Generic TPM interfaced through LPC / I2C bus */
+#define CONFIG_TPM
#define CONFIG_TPM_TIS_BASE_ADDRESS 0xfed40000
/*-----------------------------------------------------------------------
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index 48ce4c0..ef381f8 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -111,6 +111,14 @@
#define STATUS_LED_BOOT STATUS_LED_BIT
#define STATUS_LED_GREEN STATUS_LED_BIT1
+/* TPM */
+#define CONFIG_CMD_TPM
+#define CONFIG_TPM
+#define CONFIG_ST_TPM_DEBUG
+#define CONFIG_ST_TPM_I2C
+#define CONFIG_TPM_I2C_BUS 1
+#define CONFIG_TPM_I2C_ADDR 0x13
+
/* Enable Multi Bus support for I2C */
#define CONFIG_I2C_MULTI_BUS 1
diff --git a/include/tpm.h b/include/tpm.h
index 6b21e9c..77a1514 100644
--- a/include/tpm.h
+++ b/include/tpm.h
@@ -68,4 +68,21 @@ int tis_close(void);
int tis_sendrecv(const uint8_t *sendbuf, size_t send_size, uint8_t *recvbuf,
size_t *recv_len);
+/*
+ * tis_sendrecv_hash()
+ *
+ * Send the requested data to the TPM for hash in LOC 4
+ * and then try to get its response
+ *
+ * @sendbuf - buffer of the data to hash
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at recv_len)
+ * or -1 on failure.
+ */
+int tis_sendrecv_hash(const uint8_t *sendbuf, size_t send_size,
+ uint8_t *recvbuf,
+ size_t *recv_len);
+
#endif /* _INCLUDE_TPM_H_ */
--
1.7.1
3
2
Hi Marek,
Another U-Boot engineer and I are looking at running up driver model.
It seems to work in sandbox quite nicely. I had half a mind to try to
get some core patches together for this merge window, but have
questions.
For 'struct instance' it seems to be an attempt to keep the constant
data separate from the dynamic data to reduce early RAM usage. But
when I look at struct driver_instance, it seems to have a 'struct
instance' within it (not a pointer). So doesn't this defeat that
benefit? You presumably can't put struct driver_instance in read-only
memory because you need it updates its flags.
I still have trouble keeping track of some of the naming - e.g. and
instance feels to me like it should be called a device, and the naming
of 'core' seems odd although I do understand the concept. Also
bind/unbind seems like register/unregister to me - but maybe there is
a difference.
There is:
struct driver_info
struct instance
struct core_instance
struct driver_instance
struct u_boot_driver
struct u_boot_core
Anyway I'll leave that alone for now.
There seems to be a lot of boilerplate code about. For example the
bind/unbind methods just call a core_...() function and it seems that
the core library could do this itself. It seems to me that some of the
methods could be NULL for most drivers, and that would reduce the
porting effort.
If we do this I would like to build in device tree from the start so
that on boards that use CONFIG_OF_CONTROL there is no need for static
data.
I think the existing 'demo' driver is a really good idea since it
gives people something to copy.
Regards,
Simon
2
3
This series adjusts the image code to work with sandbox and prepares it for
verified boot to come later.
The primary goal here is to get image loading to work on sandbox, which is
mostly a set of fairly minor changes such as using map_sysmem() instead of
just a cast when converting from a U-Boot address to a pointer. Since
common/image.c runs to over 3000 lines and half of it is FIT-related code
behind an #ifdef, this code is moved into a new image-fit.c file.
This series depends on the sandbox generic board series:
sandbox: Generic board support and other improvements
Changes in v3:
- Update notes to note that generic board support has now landed
- Split out image improvements into a separate series
Changes in v2:
- Change hash_block() to use an unsigned int len
- Clarify use of output_size parameter to hash_block()
- Fix line continuation problem
- Fix checkpatch checks about parenthesis alignment
- Rebase on previous patches
- Rebase on previous patches
- Rebase on previous patches
- Add IMAGE_ENABLE_IGNORE to avoid #ifdef around ignore property handling
- Rename commit message to say "function" instead of "function"
- Rebase on previous patches
- Put err_msgp strings on a single line
- Rebase on previous patches
- Put params before description in fit_conf_get_prop_node() comment
- Rebase on previous patches
- Rebase on previous patches
- Fix checkpatch checks about parenthesis alignment
Simon Glass (19):
env: Fix minor comment typos in cmd_nvedit
Add minor updates to README.fdt-control
hash: Add a way to calculate a hash for any algortihm
bootstage: Don't build for HOSTCC
mkimage: Move ARRAY_SIZE to header file
libfdt: Add fdt_next_subnode() to permit easy subnode iteration
image: Move timestamp #ifdefs to header file
image: Export fit_check_ramdisk()
image: Split FIT code into new image-fit.c
image: Move HOSTCC image code to tools/
image: Split hash node processing into its own function
image: Convert fit_image_hash_set_value() to static, and rename
image: Rename fit_image_check_hashes() to fit_image_verify()
image: Move hash checking into its own function
image: Move error! string to common place
image: Export fit_conf_get_prop_node()
image: Rename fit_add_hashes() to fit_add_verification_data()
image: Rename hash printing to fit_image_print_verification_data()
sandbox: image: Add support for booting images in sandbox
common/Makefile | 1 +
common/cmd_bootm.c | 25 +-
common/cmd_fpga.c | 2 +-
common/cmd_nvedit.c | 4 +-
common/cmd_source.c | 2 +-
common/cmd_ximg.c | 2 +-
common/hash.c | 23 +
common/image-fit.c | 1497 ++++++++++++++++++++++++++++++++++++++++++
common/image.c | 1679 ++----------------------------------------------
common/update.c | 2 +-
doc/README.fdt-control | 9 +-
include/bootstage.h | 5 +-
include/hash.h | 22 +
include/image.h | 55 +-
include/libfdt.h | 17 +
lib/libfdt/fdt.c | 12 +
tools/Makefile | 4 +
tools/aisimage.c | 1 -
tools/fit_image.c | 2 +-
tools/image-host.c | 213 ++++++
tools/mkimage.h | 2 +
21 files changed, 1903 insertions(+), 1676 deletions(-)
create mode 100644 common/image-fit.c
create mode 100644 tools/image-host.c
--
1.8.2.1
2
20

22 Apr '13
As per doc/feature-removal-schedule.txt, remove CONFIG_CMD_MEMTEST from
default list of commands.
Signed-off-by: Tom Rini <trini(a)ti.com>
---
doc/feature-removal-schedule.txt | 17 -----------------
include/config_cmd_default.h | 1 -
2 files changed, 18 deletions(-)
diff --git a/doc/feature-removal-schedule.txt b/doc/feature-removal-schedule.txt
index ce72861..b4899c4 100644
--- a/doc/feature-removal-schedule.txt
+++ b/doc/feature-removal-schedule.txt
@@ -7,23 +7,6 @@ file.
---------------------------
-What: Remove CONFIG_CMD_MEMTEST from default list
-When: Release v2013.07
-
-Why: The "mtest" command is of little practical use (if any), and
- experience has shown that a large number of board configu-
- rations define useless or even dangerous start and end
- addresses. If not even the board maintainers are able to
- figure out which memory range can be reliably tested, how can
- we expect such from the end users? As this problem comes up
- repeatedly, we rather do not enable this command by default,
- so only people who know what they are doing will be confronted
- with it.
-
-Who: Wolfgang Denk <wd(a)denx.de>
-
----------------------------
-
What: Remove CONFIG_SYS_ENABLE_PADS_ALL and CONFIG_SYS_CLOCKS_ENABLE_ALL
When: Release v2013.07
diff --git a/include/config_cmd_default.h b/include/config_cmd_default.h
index a521103..73c9544 100644
--- a/include/config_cmd_default.h
+++ b/include/config_cmd_default.h
@@ -31,7 +31,6 @@
#define CONFIG_CMD_LOADB /* loadb */
#define CONFIG_CMD_LOADS /* loads */
#define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop */
-#define CONFIG_CMD_MEMTEST /* mtest */
#define CONFIG_CMD_MISC /* Misc functions like sleep etc*/
#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */
#define CONFIG_CMD_NFS /* NFS support */
--
1.7.9.5
1
2
Hi Tom,
please pull the following patch:
The following changes since commit d10f68ae47b67acab8b110b5c605dde4197a1820:
Prepare v2013.04 (2013-04-19 10:25:43 -0400)
are available in the git repository at:
git://www.denx.de/git/u-boot-cfi-flash.git master
for you to fetch changes up to 352ef3f1b613cb711c51ec962d2cc1eafff1bf95:
flash: Add optional verify-after-write feature (2013-04-22 10:56:38 +0200)
----------------------------------------------------------------
Stefan Roese (1):
flash: Add optional verify-after-write feature
README | 9 +++++++++
common/flash.c | 11 +++++++++++
2 files changed, 20 insertions(+)
2
1
Hi Tom!
Please pull the following pending patches:
The following changes since commit d10f68ae47b67acab8b110b5c605dde4197a1820:
Prepare v2013.04 (2013-04-19 10:25:43 -0400)
are available in the git repository at:
git://www.denx.de/git/u-boot-ppc4xx.git master
for you to fetch changes up to f47b048b3a283dca63cfdce46840dd477e591336:
ppc4xx: Add lcd4_lwmon5 support (2013-04-22 09:53:53 +0200)
----------------------------------------------------------------
Stefan Roese (3):
ppc4xx: Add SPL support
Makefile: Add target for combined u-boot.img & spl/u-boot.bin
ppc4xx: Add lcd4_lwmon5 support
Makefile | 12 ++++++
arch/powerpc/cpu/ppc4xx/Makefile | 4 ++
arch/powerpc/cpu/ppc4xx/spl_boot.c | 72 ++++++++++++++++++++++++++++++++
arch/powerpc/cpu/ppc4xx/start.S | 37 +++++++++++++++--
arch/powerpc/cpu/ppc4xx/u-boot-spl.lds | 74 +++++++++++++++++++++++++++++++++
arch/powerpc/cpu/ppc4xx/u-boot.lds | 2 +
board/lwmon5/lwmon5.c | 75 +++++++++++++++++++++++++++++++++-
board/lwmon5/sdram.c | 4 +-
boards.cfg | 1 +
config.mk | 4 ++
include/configs/lwmon5.h | 68 ++++++++++++++++++++++++++++--
11 files changed, 343 insertions(+), 10 deletions(-)
create mode 100644 arch/powerpc/cpu/ppc4xx/spl_boot.c
create mode 100644 arch/powerpc/cpu/ppc4xx/u-boot-spl.lds
2
1
From: Michal Simek <monstr(a)monstr.eu>
Remove CONFIG_SYS_RESET_ADDRESS macro.
It was there from historical point of view
when soft reset was just jump to u-boot text start
(not used right now).
Signed-off-by: Michal Simek <monstr(a)monstr.eu>
Signed-off-by: Michal Simek <michal.simek(a)xilinx.com>
---
board/xilinx/microblaze-generic/microblaze-generic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c
index 70f94c1..8ba99f9 100644
--- a/board/xilinx/microblaze-generic/microblaze-generic.c
+++ b/board/xilinx/microblaze-generic/microblaze-generic.c
@@ -38,10 +38,10 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) =
++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)));
#endif
-#ifdef CONFIG_SYS_RESET_ADDRESS
+
puts ("Reseting board\n");
asm ("bra r0");
-#endif
+
return 0;
}
--
1.8.2.1
2
4
NanoBone Specification:
-----------------------
Memory:
256MB DDR3
64MB NOR flash
256MB NAND flash
128KB FRAM
Ethernet:
2 x 10/100 connected to SMSC LAN8710 PHY
USB:
1 x USB2.0 Type A
I2C:
2Kbit EEPROM (Microchip 24AA02)
RTC (Maxim DS1338)
GPIO Expander (Microchip MCP23017)
Expansion connector:
6 x UART
1 x MMC/SD
1 x USB2.0
Signed-off-by: Mark Jackson <mpfj(a)newflow.co.uk>
---
MAINTAINERS | 4 +
board/newflow/nanobone/Makefile | 46 ++++++
board/newflow/nanobone/board.c | 337 +++++++++++++++++++++++++++++++++++++++
board/newflow/nanobone/board.h | 24 +++
board/newflow/nanobone/mux.c | 203 +++++++++++++++++++++++
boards.cfg | 1 +
include/configs/nanobone.h | 291 +++++++++++++++++++++++++++++++++
7 files changed, 906 insertions(+)
create mode 100644 board/newflow/nanobone/Makefile
create mode 100644 board/newflow/nanobone/board.c
create mode 100644 board/newflow/nanobone/board.h
create mode 100644 board/newflow/nanobone/mux.c
create mode 100644 include/configs/nanobone.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 1614b91..7778883 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -710,6 +710,10 @@ Ilko Iliev <iliev(a)ronetix.at>
PM9263 AT91SAM9263
PM9G45 ARM926EJS (AT91SAM9G45 SoC)
+Mark Jackson <mpfj(a)newflow.co.uk>
+
+ NANOBONE ARM ARMV7 (AM33xx Soc)
+
Michael Jones <michael.jones(a)matrix-vision.de>
omap3_mvblx ARM ARMV7 (OMAP3xx SoC)
diff --git a/board/newflow/nanobone/Makefile b/board/newflow/nanobone/Makefile
new file mode 100644
index 0000000..67a87a1
--- /dev/null
+++ b/board/newflow/nanobone/Makefile
@@ -0,0 +1,46 @@
+#
+# Makefile
+#
+# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+#
+# 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 "as is" WITHOUT ANY WARRANTY of any
+# kind, whether express or implied; without even the implied warranty
+# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).o
+
+ifdef CONFIG_SPL_BUILD
+COBJS := mux.o
+endif
+
+COBJS += board.o
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/newflow/nanobone/board.c b/board/newflow/nanobone/board.c
new file mode 100644
index 0000000..e8f7e00
--- /dev/null
+++ b/board/newflow/nanobone/board.c
@@ -0,0 +1,337 @@
+/*
+ * board.c
+ *
+ * Board functions for Newflow NanoBone board
+ *
+ * Copyright (C) 2013, Newflow Ltd - http://www.newflow.co.uk/
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/omap.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <cpsw.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <spl.h>
+#include "board.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* FRAM config */
+#define FRAM_CS 1
+#define FRAM_BASE 0x1c000000
+#define FRAM_SIZE GPMC_SIZE_16M
+static u32 gpmc_fram_config[GPMC_MAX_REG] = {
+ 0x00001200,
+ 0x00101000,
+ 0x00020201,
+ 0x0f030f03,
+ 0x010d1010,
+ 0x000301c0,
+ 0
+};
+
+/* NOR Flash config */
+#define NOR_CS 3
+#define NOR_BASE 0x18000000
+#define NOR_SIZE GPMC_SIZE_64M
+static u32 gpmc_nor_config[GPMC_MAX_REG] = {
+ 0x00001200,
+ 0x00101004,
+ 0x00020201,
+ 0x10041004,
+ 0x010f1010,
+ 0x000601c0,
+ 0
+};
+
+static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+#ifdef CONFIG_SPL_BUILD
+static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
+#endif
+
+/* MII mode defines */
+#define PORT1_MII_MODE_ENABLE 0x0
+#define PORT2_MII_MODE_ENABLE 0x0
+
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+/* UART Defines */
+#ifdef CONFIG_SPL_BUILD
+#define UART_RESET (0x1 << 1)
+#define UART_CLK_RUNNING_MASK 0x1
+#define UART_SMART_IDLE_EN (0x1 << 0x3)
+
+static void rtc32k_enable(void)
+{
+ struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
+
+ /*
+ * Unlock the RTC's registers. For more details please see the
+ * RTC_SS section of the TRM. In order to unlock we need to
+ * write these specific values (keys) in this order.
+ */
+ writel(0x83e70b13, &rtc->kick0r);
+ writel(0x95a4f1e0, &rtc->kick1r);
+
+ /* Enable the RTC 32K OSC by setting bits 3 and 6. */
+ writel((1 << 3) | (1 << 6), &rtc->osc);
+}
+
+static const struct ddr_data ddr3_data = {
+ .datardsratio0 = MT41J128MJT125_RD_DQS,
+ .datawdsratio0 = MT41J128MJT125_WR_DQS,
+ .datafwsratio0 = MT41J128MJT125_PHY_FIFO_WE,
+ .datawrsratio0 = MT41J128MJT125_PHY_WR_DATA,
+ .datadldiff0 = PHY_DLL_LOCK_DIFF,
+};
+
+static const struct cmd_control ddr3_cmd_ctrl_data = {
+ .cmd0csratio = MT41J128MJT125_RATIO,
+ .cmd0dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
+ .cmd0iclkout = MT41J128MJT125_INVERT_CLKOUT,
+
+ .cmd1csratio = MT41J128MJT125_RATIO,
+ .cmd1dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
+ .cmd1iclkout = MT41J128MJT125_INVERT_CLKOUT,
+
+ .cmd2csratio = MT41J128MJT125_RATIO,
+ .cmd2dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
+ .cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT,
+};
+
+static struct emif_regs ddr3_emif_reg_data = {
+ .sdram_config = MT41J128MJT125_EMIF_SDCFG,
+ .ref_ctrl = MT41J128MJT125_EMIF_SDREF,
+ .sdram_tim1 = MT41J128MJT125_EMIF_TIM1,
+ .sdram_tim2 = MT41J128MJT125_EMIF_TIM2,
+ .sdram_tim3 = MT41J128MJT125_EMIF_TIM3,
+ .zq_config = MT41J128MJT125_ZQ_CFG,
+ .emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY,
+};
+#endif /* CONFIG_SPL_BUILD */
+
+#if defined(CONFIG_NAND_OMAP_GPMC) & !defined(CONFIG_SPL_BUILD)
+/******************************************************************************
+ * OMAP3 specific command to switch between NAND HW and SW ecc
+ *****************************************************************************/
+static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+ if (argc < 2)
+ goto usage;
+ if (strncmp(argv[1], "hw", 2) == 0)
+ {
+ int type = 1;
+ if (argc == 3)
+ type = simple_strtoul(argv[2], NULL, 10);
+ omap_nand_switch_ecc(type);
+ }
+ else if (strncmp(argv[1], "sw", 2) == 0)
+ omap_nand_switch_ecc(0);
+ else
+ goto usage;
+
+ return 0;
+
+usage:
+ printf ("Usage: nandecc %s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(
+ nandecc, 3, 1, do_switch_ecc,
+ "switch OMAP3 NAND ECC calculation algorithm",
+ "[hw 1/hw 2/sw] - Switch between NAND ecc algorithm\n"
+ " hw 1 = kernel/FS layout\n"
+ " hw 2 = xloader/uboot layout\n"
+ " sw = 1-bit software"
+);
+
+#endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */
+
+/*
+ * early system init of muxing and clocks.
+ */
+void s_init(void)
+{
+ /* WDT1 is already running when the bootloader gets control
+ * Disable it to avoid "random" resets
+ */
+ writel(0xAAAA, &wdtimer->wdtwspr);
+ while (readl(&wdtimer->wdtwwps) != 0x0)
+ ;
+ writel(0x5555, &wdtimer->wdtwspr);
+ while (readl(&wdtimer->wdtwwps) != 0x0)
+ ;
+
+#ifdef CONFIG_SPL_BUILD
+ /* Setup the PLLs and the clocks for the peripherals */
+ pll_init();
+
+ /* Enable RTC32K clock */
+ rtc32k_enable();
+
+ /* UART softreset */
+ u32 regVal;
+ regVal = readl(&uart_base->uartsyscfg);
+ regVal |= UART_RESET;
+ writel(regVal, &uart_base->uartsyscfg);
+ while ((readl(&uart_base->uartsyssts) &
+ UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK)
+ ;
+
+ /* Disable smart idle */
+ regVal = readl(&uart_base->uartsyscfg);
+ regVal |= UART_SMART_IDLE_EN;
+ writel(regVal, &uart_base->uartsyscfg);
+
+ config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
+ &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
+
+ gd = &gdata;
+
+ enable_board_pin_mux();
+
+ preloader_console_init();
+
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif /* CONFIG_SPL_BUILD */
+}
+
+/*
+ * Basic board specific setup. Pinmux has been handled already.
+ */
+int board_init(void)
+{
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+ gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
+
+ gpmc_init();
+
+ /* enable FRAM chip select */
+ enable_gpmc_cs_config(gpmc_fram_config, &gpmc_cfg->cs[FRAM_CS],
+ FRAM_BASE, FRAM_SIZE);
+ /* enable NOR flash chip select */
+ enable_gpmc_cs_config(gpmc_nor_config, &gpmc_cfg->cs[NOR_CS],
+ NOR_BASE, NOR_SIZE);
+
+ return 0;
+}
+
+int board_late_init(void)
+{
+ setenv("board_name", "nanobone");
+ setenv("board_rev", "0001");
+
+ return 0;
+}
+
+static void cpsw_control(int enabled)
+{
+ /* VTP can be added here */
+
+ return;
+}
+
+static struct cpsw_slave_data cpsw_slaves[] = {
+ {
+ .slave_reg_ofs = 0x208,
+ .sliver_reg_ofs = 0xd80,
+ .phy_id = 0,
+ },
+ {
+ .slave_reg_ofs = 0x308,
+ .sliver_reg_ofs = 0xdc0,
+ .phy_id = 1,
+ },
+};
+
+static struct cpsw_platform_data cpsw_data = {
+ .mdio_base = CPSW_MDIO_BASE,
+ .cpsw_base = CPSW_BASE,
+ .mdio_div = 0xff,
+ .channels = 8,
+ .cpdma_reg_ofs = 0x800,
+ .slaves = 2,
+ .slave_data = cpsw_slaves,
+ .ale_reg_ofs = 0xd00,
+ .ale_entries = 1024,
+ .host_port_reg_ofs = 0x108,
+ .hw_stats_reg_ofs = 0x900,
+ .mac_control = (1 << 5),
+ .control = cpsw_control,
+ .host_port_num = 0,
+ .version = CPSW_CTRL_VERSION_2,
+};
+
+int board_eth_init(bd_t *bis)
+{
+ int rv, n = 0;
+ uint8_t mac_addr[6];
+ uint32_t mac_hi, mac_lo;
+
+ if (!getenv("ethaddr")) {
+ printf("<ethaddr> not set. Reading from E-fuse\n");
+ /* try reading mac address from efuse */
+ mac_lo = readl(&cdev->macid0l);
+ mac_hi = readl(&cdev->macid0h);
+ mac_addr[0] = mac_hi & 0xff;
+ mac_addr[1] = (mac_hi & 0xff00) >> 8;
+ mac_addr[2] = (mac_hi & 0xff0000) >> 16;
+ mac_addr[3] = (mac_hi & 0xff000000) >> 24;
+ mac_addr[4] = mac_lo & 0xff;
+ mac_addr[5] = (mac_lo & 0xff00) >> 8;
+
+ if (is_valid_ether_addr(mac_addr))
+ eth_setenv_enetaddr("ethaddr", mac_addr);
+ }
+
+ if (!getenv("eth1addr")) {
+ printf("<eth1addr> not set. Reading from E-fuse\n");
+ /* try reading mac address from efuse */
+ mac_lo = readl(&cdev->macid1l);
+ mac_hi = readl(&cdev->macid1h);
+ mac_addr[0] = mac_hi & 0xff;
+ mac_addr[1] = (mac_hi & 0xff00) >> 8;
+ mac_addr[2] = (mac_hi & 0xff0000) >> 16;
+ mac_addr[3] = (mac_hi & 0xff000000) >> 24;
+ mac_addr[4] = mac_lo & 0xff;
+ mac_addr[5] = (mac_lo & 0xff00) >> 8;
+
+ if (is_valid_ether_addr(mac_addr))
+ eth_setenv_enetaddr("eth1addr", mac_addr);
+ }
+
+ writel(PORT1_MII_MODE_ENABLE | PORT2_MII_MODE_ENABLE, &cdev->miisel);
+ cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_MII;
+
+ rv = cpsw_register(&cpsw_data);
+ if (rv < 0)
+ printf("Error %d registering CPSW switch\n", rv);
+ else
+ n += rv;
+
+ return n;
+}
diff --git a/board/newflow/nanobone/board.h b/board/newflow/nanobone/board.h
new file mode 100644
index 0000000..9f5075b
--- /dev/null
+++ b/board/newflow/nanobone/board.h
@@ -0,0 +1,24 @@
+/*
+ * board.h
+ *
+ * TI AM335x boards information header
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * 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.
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+void enable_board_pin_mux(void);
+
+#endif
diff --git a/board/newflow/nanobone/mux.c b/board/newflow/nanobone/mux.c
new file mode 100644
index 0000000..bf9c999
--- /dev/null
+++ b/board/newflow/nanobone/mux.c
@@ -0,0 +1,203 @@
+/*
+ * mux.c
+ *
+ * Copyright (C) 2013, Newflow Ltd - http://www.newflow.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/io.h>
+#include <i2c.h>
+#include "board.h"
+
+static struct module_pin_mux gpmc_pin_mux[] = {
+ {OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD0 */
+ {OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD1 */
+ {OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD2 */
+ {OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD3 */
+ {OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD4 */
+ {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD5 */
+ {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD6 */
+ {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD7 */
+ {OFFSET(gpmc_ad8), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD8 */
+ {OFFSET(gpmc_ad9), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD9 */
+ {OFFSET(gpmc_ad10), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD10 */
+ {OFFSET(gpmc_ad11), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD11 */
+ {OFFSET(gpmc_ad12), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD12 */
+ {OFFSET(gpmc_ad13), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD13 */
+ {OFFSET(gpmc_ad14), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD14 */
+ {OFFSET(gpmc_ad15), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* GPMC AD15 */
+ {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* GPMC_CSN0 */
+ {OFFSET(gpmc_csn1), (MODE(0) | PULLUDEN)}, /* GPMC_CSN1 */
+ {OFFSET(gpmc_csn2), (MODE(0) | PULLUDEN)}, /* GPMC_CSN2 */
+ {OFFSET(gpmc_csn3), (MODE(0) | PULLUDEN)}, /* GPMC_CSN3 */
+ {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* GPMC_ADV_ALE */
+ {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* GPMC_OE */
+ {OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* GPMC_WEN */
+ {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* GPMC_BE_CLE */
+ {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE)}, /* NAND WAIT */
+ {OFFSET(lcd_data1), (MODE(1) | PULLUDDIS)}, /* GPMC A17 */
+ {OFFSET(lcd_data2), (MODE(1) | PULLUDDIS)}, /* GPMC A18 */
+ {OFFSET(lcd_data3), (MODE(1) | PULLUDDIS)}, /* GPMC A19 */
+ {OFFSET(lcd_data4), (MODE(1) | PULLUDDIS)}, /* GPMC A20 */
+ {OFFSET(lcd_data5), (MODE(1) | PULLUDDIS)}, /* GPMC A21 */
+ {OFFSET(lcd_data6), (MODE(1) | PULLUDDIS)}, /* GPMC A22 */
+ {OFFSET(lcd_data7), (MODE(1) | PULLUDDIS)}, /* GPMC A23 */
+ {OFFSET(lcd_data8), (MODE(1) | PULLUDDIS)}, /* GPMC A24 */
+ {OFFSET(lcd_data9), (MODE(1) | PULLUDDIS)}, /* GPMC A25 */
+ {OFFSET(lcd_data10), (MODE(1) | PULLUDDIS)}, /* GPMC A26 */
+ {-1},
+};
+
+static struct module_pin_mux i2c0_pin_mux[] = {
+ {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
+ PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
+ {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE |
+ PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
+ {-1},
+};
+
+static struct module_pin_mux mii1_pin_mux[] = {
+ {OFFSET(mii1_col), MODE(0) | RXACTIVE}, /* MII1_COL */
+ {OFFSET(mii1_crs), MODE(0) | RXACTIVE}, /* MII1_CRS */
+ {OFFSET(mii1_rxerr), MODE(0) | RXACTIVE}, /* MII1_RXERR */
+ {OFFSET(mii1_txen), MODE(0)}, /* MII1_TXEN */
+ {OFFSET(mii1_rxdv), MODE(0) | RXACTIVE}, /* MII1_RXDV */
+ {OFFSET(mii1_txd3), MODE(0)}, /* MII1_TXD3 */
+ {OFFSET(mii1_txd2), MODE(0)}, /* MII1_TXD2 */
+ {OFFSET(mii1_txd1), MODE(0)}, /* MII1_TXD1 */
+ {OFFSET(mii1_txd0), MODE(0)}, /* MII1_TXD0 */
+ {OFFSET(mii1_txclk), MODE(0) | RXACTIVE}, /* MII1_TXCLK */
+ {OFFSET(mii1_rxclk), MODE(0) | RXACTIVE}, /* MII1_RXCLK */
+ {OFFSET(mii1_rxd3), MODE(0) | RXACTIVE}, /* MII1_RXD3 */
+ {OFFSET(mii1_rxd2), MODE(0) | RXACTIVE}, /* MII1_RXD2 */
+ {OFFSET(mii1_rxd1), MODE(0) | RXACTIVE}, /* MII1_RXD1 */
+ {OFFSET(mii1_rxd0), MODE(0) | RXACTIVE}, /* MII1_RXD0 */
+ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
+ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
+ {-1},
+};
+
+static struct module_pin_mux mii2_pin_mux[] = {
+ {OFFSET(gpmc_a0), MODE(1)}, /* MII2_TXEN */
+ {OFFSET(gpmc_a1), MODE(1) | RXACTIVE}, /* MII2_RXDV */
+ {OFFSET(gpmc_a2), MODE(1)}, /* MII2_TXD3 */
+ {OFFSET(gpmc_a3), MODE(1)}, /* MII2_TXD2 */
+ {OFFSET(gpmc_a4), MODE(1)}, /* MII2_TXD1 */
+ {OFFSET(gpmc_a5), MODE(1)}, /* MII2_TXD0 */
+ {OFFSET(gpmc_a6), MODE(1) | RXACTIVE}, /* MII2_TXCLK */
+ {OFFSET(gpmc_a7), MODE(1) | RXACTIVE}, /* MII2_RXCLK */
+ {OFFSET(gpmc_a8), MODE(1) | RXACTIVE}, /* MII2_RXD3 */
+ {OFFSET(gpmc_a9), MODE(1) | RXACTIVE}, /* MII2_RXD2 */
+ {OFFSET(gpmc_a10), MODE(1) | RXACTIVE}, /* MII2_RXD1 */
+ {OFFSET(gpmc_a11), MODE(1) | RXACTIVE}, /* MII2_RXD0 */
+ {OFFSET(gpmc_wpn), MODE(1) | RXACTIVE}, /* MII2_RXERR */
+ {OFFSET(gpmc_be1n), MODE(1) | RXACTIVE}, /* MII2_COL */
+ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
+ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
+ {-1},
+};
+
+static struct module_pin_mux mmc0_no_cd_pin_mux[] = {
+ {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */
+ {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */
+ {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */
+ {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */
+ {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */
+ {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */
+ {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)}, /* MMC0_WP */
+ {OFFSET(emu1), (MODE(7) | RXACTIVE)}, /* MMC0_CD */
+ {-1},
+};
+
+static struct module_pin_mux uart0_pin_mux[] = {
+ {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART0_RXD */
+ {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, /* UART0_TXD */
+ {-1},
+};
+
+static struct module_pin_mux uart1_pin_mux[] = {
+ {OFFSET(uart1_ctsn), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART1_CTSN */
+ {OFFSET(uart1_rtsn), (MODE(0) | PULLUDEN)}, /* UART1_RTSN */
+ {OFFSET(uart1_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART1_RXD */
+ {OFFSET(uart1_txd), (MODE(0) | PULLUDEN)}, /* UART1_TXD */
+ {-1},
+};
+
+static struct module_pin_mux uart2_pin_mux[] = {
+ {OFFSET(lcd_data8), (MODE(6) | PULLUP_EN | RXACTIVE)}, /* UART2_CTSN */
+ {OFFSET(lcd_data9), (MODE(6) | PULLUDEN)}, /* UART2_RTSN */
+ {OFFSET(spi0_sclk), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART2_RXD */
+ {OFFSET(spi0_d0), (MODE(1) | PULLUDEN)}, /* UART2_TXD */
+ {-1},
+};
+
+static struct module_pin_mux uart3_pin_mux[] = {
+ {OFFSET(lcd_data10), (MODE(6) | PULLUP_EN | RXACTIVE)}, /* UART3_CTSN */
+ {OFFSET(lcd_data11), (MODE(6) | PULLUDEN)}, /* UART3_RTSN */
+ {OFFSET(spi0_cs1), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART3_RXD */
+ {OFFSET(ecap0_in_pwm0_out), (MODE(1) | PULLUDEN)}, /* UART3_TXD */
+ {-1},
+};
+
+static struct module_pin_mux uart4_pin_mux[] = {
+ {OFFSET(lcd_data12), (MODE(6) | PULLUP_EN | RXACTIVE)}, /* UART4_CTSN */
+ {OFFSET(lcd_data13), (MODE(6) | PULLUDEN)}, /* UART4_RTSN */
+ {OFFSET(uart0_ctsn), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART4_RXD */
+ {OFFSET(uart0_rtsn), (MODE(1) | PULLUDEN)}, /* UART4_TXD */
+ {-1},
+};
+
+static struct module_pin_mux uart5_pin_mux[] = {
+ {OFFSET(lcd_data14), (MODE(4) | PULLUP_EN | RXACTIVE)}, /* UART5_RXD */
+ {OFFSET(rmii1_refclk), (MODE(3) | PULLUDEN)}, /* UART5_TXD */
+ {-1},
+};
+
+static struct module_pin_mux usb0_pin_mux[] = {
+ {OFFSET(usb0_dm), (MODE(0) | RXACTIVE)}, /* USB0_DM */
+ {OFFSET(usb0_dp), (MODE(0) | RXACTIVE)}, /* USB0_DP */
+ {OFFSET(usb0_ce), (MODE(0) | RXACTIVE)}, /* USB0_CE */
+ {OFFSET(usb0_id), (MODE(0) | RXACTIVE)}, /* USB0_ID */
+ {OFFSET(usb0_vbus), (MODE(0) | RXACTIVE)}, /* USB0_VBUS */
+ {OFFSET(usb0_drvvbus), (MODE(0) | PULLUDEN)}, /* USB0_DRVVBUS */
+ {-1},
+};
+
+static struct module_pin_mux usb1_pin_mux[] = {
+ {OFFSET(usb1_dm), (MODE(0) | RXACTIVE)}, /* USB1_DM */
+ {OFFSET(usb1_dp), (MODE(0) | RXACTIVE)}, /* USB1_DP */
+ {OFFSET(usb1_ce), (MODE(0) | RXACTIVE)}, /* USB1_CE */
+ {OFFSET(usb1_id), (MODE(0) | RXACTIVE)}, /* USB1_ID */
+ {OFFSET(usb1_vbus), (MODE(0) | RXACTIVE)}, /* USB1_VBUS */
+ {OFFSET(usb1_drvvbus), (MODE(0) | PULLUDEN)}, /* USB1_DRVVBUS */
+ {-1},
+};
+
+void enable_board_pin_mux()
+{
+ configure_module_pin_mux(gpmc_pin_mux);
+ configure_module_pin_mux(i2c0_pin_mux);
+ configure_module_pin_mux(mii1_pin_mux);
+ configure_module_pin_mux(mii2_pin_mux);
+ configure_module_pin_mux(mmc0_no_cd_pin_mux);
+ configure_module_pin_mux(uart0_pin_mux);
+ configure_module_pin_mux(uart1_pin_mux);
+ configure_module_pin_mux(uart2_pin_mux);
+ configure_module_pin_mux(uart3_pin_mux);
+ configure_module_pin_mux(uart4_pin_mux);
+ configure_module_pin_mux(uart5_pin_mux);
+ configure_module_pin_mux(usb0_pin_mux);
+ configure_module_pin_mux(usb1_pin_mux);
+}
diff --git a/boards.cfg b/boards.cfg
index 5fc70be..b2f68e9 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -241,6 +241,7 @@ am335x_evm_uart3 arm armv7 am335x ti
am335x_evm_uart4 arm armv7 am335x ti am33xx am335x_evm:SERIAL5,CONS_INDEX=5
am335x_evm_uart5 arm armv7 am335x ti am33xx am335x_evm:SERIAL6,CONS_INDEX=6
am335x_evm_usbspl arm armv7 am335x ti am33xx am335x_evm:SERIAL1,CONS_INDEX=1,SPL_USBETH_SUPPORT
+nanobone arm armv7 nanobone newflow am33xx
ti814x_evm arm armv7 ti814x ti am33xx
pcm051 arm armv7 pcm051 phytec am33xx pcm051
highbank arm armv7 highbank - highbank
diff --git a/include/configs/nanobone.h b/include/configs/nanobone.h
new file mode 100644
index 0000000..184f06a
--- /dev/null
+++ b/include/configs/nanobone.h
@@ -0,0 +1,291 @@
+/*
+ * nanobone.h
+ *
+ * Copyright (C) 2013 Newflow Ltd - http://www.newflow.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __CONFIG_NANOBONE_H
+#define __CONFIG_NANOBONE_H
+
+#define CONFIG_AM33XX
+
+#include <asm/arch/omap.h>
+
+#define CONFIG_DMA_COHERENT
+#define CONFIG_DMA_COHERENT_SIZE (1 << 20)
+
+#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */
+#define CONFIG_SYS_MALLOC_LEN (1024 << 10)
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT "U-Boot# "
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_SYS_NO_FLASH
+#define MACH_TYPE_NANOBONE 4483
+#define CONFIG_MACH_TYPE MACH_TYPE_NANOBONE
+
+#define CONFIG_OF_LIBFDT
+#define CONFIG_CMD_BOOTZ
+#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+/* commands to include */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_VERSION_VARIABLE
+
+/* set to negative value for no autoboot */
+#define CONFIG_BOOTDELAY 0
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_ENV_VARS_UBOOT_CONFIG
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "loadaddr=0x80200000\0" \
+ "fdtaddr=0x80f80000\0" \
+ "fdt_high=0xffffffff\0" \
+ "console=ttyO0,115200n8\0" \
+
+#endif /* CONFIG_SPL_BUILD */
+
+#define CONFIG_BOOTCOMMAND "mtdparts default; " \
+ "nand read $loadaddr kernel; bootm"
+#define CONFIG_BOOTARGS "console=ttyO0,115200n8 noinitrd ip=off " \
+ "mem=256M rootwait=1 ubi.mtd=4,2048 " \
+ "rootfstype=ubifs root=ubi0:rootfs " \
+ "ignore_loglevel"
+
+/* Clock Defines */
+#define V_OSCK 26000000 /* Clock output from T2 */
+#define V_SCLK (V_OSCK)
+#define CONFIG_SYS_MPUCLK 720
+
+#define CONFIG_CMD_ECHO
+
+/* max number of command args */
+#define CONFIG_SYS_MAXARGS 16
+
+/* Console I/O Buffer Size */
+#define CONFIG_SYS_CBSIZE 512
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \
+ + sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+/*
+ * memtest works on 8 MB in DRAM after skipping 32MB from
+ * start addr of ram disk
+ */
+#define CONFIG_SYS_MEMTEST_START (PHYS_DRAM_1 + (64 * 1024 * 1024))
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START \
+ + (8 * 1024 * 1024))
+
+#define CONFIG_SYS_LOAD_ADDR 0x81000000 /* Default load address */
+#define CONFIG_SYS_HZ 1000 /* 1ms clock */
+
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_OMAP_HSMMC
+#define CONFIG_CMD_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EXT4
+#define CONFIG_CMD_FS_GENERIC
+
+ /* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
+#define PHYS_DRAM_1 0x80000000 /* DRAM Bank #1 */
+#define CONFIG_MAX_RAM_BANK_SIZE (1024 << 20) /* 1GB */
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_DRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR (NON_SECURE_SRAM_END - \
+ GENERATED_GBL_DATA_SIZE)
+ /* Platform/Board specific defs */
+#define CONFIG_SYS_TIMERBASE 0x48040000 /* Use Timer2 */
+#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
+#define CONFIG_SYS_HZ 1000
+
+/* NS16550 Configuration */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SERIAL_MULTI
+#define CONFIG_SYS_NS16550_REG_SIZE (-4)
+#define CONFIG_SYS_NS16550_CLK (48000000)
+#define CONFIG_SYS_NS16550_COM1 0x44e09000 /* UART0 */
+#define CONFIG_SYS_NS16550_COM2 0x48022000 /* UART1 */
+#define CONFIG_SYS_NS16550_COM3 0x48024000 /* UART2 */
+#define CONFIG_SYS_NS16550_COM4 0x481a6000 /* UART3 */
+#define CONFIG_SYS_NS16550_COM5 0x481a8000 /* UART4 */
+#define CONFIG_SYS_NS16550_COM6 0x481aa000 /* UART5 */
+#define CONFIG_CONS_INDEX 1
+
+/* I2C Configuration */
+#define CONFIG_I2C
+#define CONFIG_CMD_I2C
+#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_SYS_I2C_SLAVE 1
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_DRIVER_OMAP24XX_I2C
+#define CONFIG_CMD_EEPROM
+#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* Main EEPROM */
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
+#define CONFIG_SYS_I2C_MULTI_EEPROMS
+
+#define CONFIG_OMAP_GPIO
+
+#define CONFIG_BAUDRATE 115200
+
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/* Defines for SPL */
+#define CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_TEXT_BASE 0x402F0400
+#define CONFIG_SPL_MAX_SIZE (101 * 1024)
+#define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR
+
+#define CONFIG_SPL_BSS_START_ADDR 0x80000000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KB */
+
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */
+#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION 1
+#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img"
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_FAT_SUPPORT
+#define CONFIG_SPL_I2C_SUPPORT
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_YMODEM_SUPPORT
+#define CONFIG_SPL_NET_SUPPORT
+#define CONFIG_SPL_NET_VCI_STRING "AM335x U-Boot SPL"
+#define CONFIG_SPL_ETH_SUPPORT
+#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
+
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_NAND_AM33XX_BCH
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \
+ CONFIG_SYS_NAND_PAGE_SIZE)
+#define CONFIG_SYS_NAND_PAGE_SIZE 2048
+#define CONFIG_SYS_NAND_OOBSIZE 64
+#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS
+#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \
+ 10, 11, 12, 13, 14, 15, 16, 17, \
+ 18, 19, 20, 21, 22, 23, 24, 25, \
+ 26, 27, 28, 29, 30, 31, 32, 33, \
+ 34, 35, 36, 37, 38, 39, 40, 41, \
+ 42, 43, 44, 45, 46, 47, 48, 49, \
+ 50, 51, 52, 53, 54, 55, 56, 57, }
+
+#define CONFIG_SYS_NAND_ECCSIZE 512
+#define CONFIG_SYS_NAND_ECCBYTES 14
+
+#define CONFIG_SYS_NAND_ECCSTEPS 4
+#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
+ CONFIG_SYS_NAND_ECCSTEPS)
+
+#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x20000
+
+/*
+ * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
+ * 64 bytes before this address should be set aside for u-boot.img's
+ * header. That is 0x800FFFC0--0x80100000 should not be used for any
+ * other needs.
+ */
+#define CONFIG_SYS_TEXT_BASE 0x80800000
+#define CONFIG_SYS_SPL_MALLOC_START 0x80208000
+#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000
+
+/* Since SPL did pll and ddr initialization for us,
+ * we don't need to do it twice.
+ */
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif /* CONFIG_SPL_BUILD */
+
+/* Unsupported features */
+#undef CONFIG_USE_IRQ
+
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PING
+#define CONFIG_DRIVER_TI_CPSW
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_NET_RETRY_COUNT 10
+#define CONFIG_NET_MULTI
+#define CONFIG_PHY_GIGE
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_ADDR 0
+#define CONFIG_PHY_SMSC
+
+
+/* UBIFS support */
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+
+/* NAND support */
+#define CONFIG_NAND
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NAND_TRIMFFS
+
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_CMD_MTDPARTS
+#define MTDIDS_DEFAULT "nand0=nand"
+#define MTDPARTS_DEFAULT "mtdparts=nand:" \
+ "128k(spl)," \
+ "1792k(boot)," \
+ "128k(env)," \
+ "4m(kernel)," \
+ "64m(rootfs)," \
+ "-(data)"
+
+#define CONFIG_NAND_OMAP_GPMC
+#define GPMC_NAND_ECC_LP_x8_LAYOUT 1
+#define CONFIG_SYS_NAND_BASE (0x08000000) /* physical address */
+ /* to access nand at */
+ /* CS0 */
+#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND
+ devices */
+#undef CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET 0x1e0000 /* environment starts here */
+#define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) /* 128 KiB */
+
+#endif /* ! __CONFIG_NANOBONE_H */
--
1.7.9.5
4
14