diff mbox

[U-Boot,U-Boot:RESEND,[PATCH,6/7] k2hk: add support for k2hk SOC and EVM

Message ID 1391815393-19536-7-git-send-email-m-karicheri2@ti.com
State Superseded
Delegated to: Tom Rini
Headers show

Commit Message

Murali Karicheri Feb. 7, 2014, 11:23 p.m. UTC
k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
refer the ti/k2hk_evm/README for details on the board, build and other
information.

This patch add support for keystone architecture and k2hk evm.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
---
 - Resend with some more in cc
 Makefile                                           |   19 +
 arch/arm/cpu/armv7/keystone/Makefile               |   18 +
 arch/arm/cpu/armv7/keystone/aemif.c                |   79 +++++
 arch/arm/cpu/armv7/keystone/clock-k2hk.c           |  106 ++++++
 arch/arm/cpu/armv7/keystone/clock.c                |  200 +++++++++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c            |  139 ++++++++
 arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 +++++++
 arch/arm/cpu/armv7/keystone/config.mk              |   14 +
 arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 ++++
 arch/arm/cpu/armv7/keystone/init.c                 |   49 +++
 arch/arm/cpu/armv7/keystone/lowlevel_init.S        |   13 +
 arch/arm/cpu/armv7/keystone/msmc.c                 |   69 ++++
 arch/arm/cpu/armv7/keystone/psc.c                  |  240 +++++++++++++
 arch/arm/cpu/armv7/keystone/spl.c                  |   45 +++
 arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 ++++++
 arch/arm/include/asm/arch-keystone/clock.h         |   17 +
 arch/arm/include/asm/arch-keystone/clock_defs.h    |   97 +++++
 arch/arm/include/asm/arch-keystone/emif_defs.h     |   75 ++++
 arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  143 ++++++++
 arch/arm/include/asm/arch-keystone/hardware.h      |  174 +++++++++
 arch/arm/include/asm/arch-keystone/i2c_defs.h      |   86 +++++
 arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 ++
 arch/arm/include/asm/arch-keystone/psc_defs.h      |   91 +++++
 arch/arm/include/asm/arch-keystone/spl.h           |   12 +
 board/ti/k2hk_evm/Makefile                         |    9 +
 board/ti/k2hk_evm/README                           |   56 +++
 board/ti/k2hk_evm/board.c                          |  246 +++++++++++++
 board/ti/k2hk_evm/ddr3.c                           |  269 ++++++++++++++
 boards.cfg                                         |    1 +
 drivers/i2c/Makefile                               |    1 +
 drivers/i2c/keystone_i2c.c                         |  372 ++++++++++++++++++++
 drivers/serial/ns16550.c                           |    8 +
 include/configs/k2hk_evm.h                         |  221 ++++++++++++
 33 files changed, 3203 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
 create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock-k2hk.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
 create mode 100644 arch/arm/cpu/armv7/keystone/config.mk
 create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
 create mode 100644 arch/arm/cpu/armv7/keystone/init.c
 create mode 100644 arch/arm/cpu/armv7/keystone/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
 create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
 create mode 100644 board/ti/k2hk_evm/Makefile
 create mode 100644 board/ti/k2hk_evm/README
 create mode 100644 board/ti/k2hk_evm/board.c
 create mode 100644 board/ti/k2hk_evm/ddr3.c
 create mode 100644 drivers/i2c/keystone_i2c.c
 create mode 100644 include/configs/k2hk_evm.h

Comments

Tom Rini Feb. 10, 2014, 9:25 p.m. UTC | #1
On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:

> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
> refer the ti/k2hk_evm/README for details on the board, build and other
> information.
> 
> This patch add support for keystone architecture and k2hk evm.

Globally, only use
/*
 * Multiline comments like this
 */

> +++ b/arch/arm/cpu/armv7/keystone/Makefile
> @@ -0,0 +1,18 @@
> +#
> +# (C) Copyright 2012-2014
> +#     Texas Instruments Incorporated, <www.ti.com>
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y	+= aemif.o
> +obj-y   += init.o
> +obj-y   += psc.o
> +obj-y   += clock.o
> +obj-y   += cmd_clock.o
> +obj-y   += cmd_mon.o
> +obj-y   += msmc.o
> +obj-y   += lowlevel_init.o
> +obj-$(CONFIG_SPL_BUILD) += spl.o
> +obj-y	+= ddr3.o

Mix of space and tab, just tab it all out to line up please.

> +++ b/arch/arm/cpu/armv7/keystone/aemif.c
> @@ -0,0 +1,79 @@
> +/*
> + * Keystone2: Asynchronous EMIF Configuration
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +
> +#ifdef CONFIG_SOC_K2HK
> +#define ASYNC_EMIF_BASE			K2HK_ASYNC_EMIF_CNTRL_BASE
> +#endif

So, does Keystone 1 have this in a different location?

> +#define ASYNC_EMIF_CONFIG(cs)		(ASYNC_EMIF_BASE+0x10+(cs)*4)
> +#define ASYNC_EMIF_ONENAND_CONTROL	(ASYNC_EMIF_BASE+0x5c)
> +#define ASYNC_EMIF_NAND_CONTROL		(ASYNC_EMIF_BASE+0x60)
> +#define ASYNC_EMIF_WAITCYCLE_CONFIG	(ASYNC_EMIF_BASE+0x4)

Register access is done over structs not define of base + offset, please
rework.

> +#define CONFIG_SELECT_STROBE(v)		((v) ? 1 << 31 : 0)
> +#define CONFIG_EXTEND_WAIT(v)		((v) ? 1 << 30 : 0)
> +#define CONFIG_WR_SETUP(v)		(((v) & 0x0f) << 26)
> +#define CONFIG_WR_STROBE(v)		(((v) & 0x3f) << 20)
> +#define CONFIG_WR_HOLD(v)		(((v) & 0x07) << 17)
> +#define CONFIG_RD_SETUP(v)		(((v) & 0x0f) << 13)
> +#define CONFIG_RD_STROBE(v)		(((v) & 0x3f) << 7)
> +#define CONFIG_RD_HOLD(v)		(((v) & 0x07) << 4)
> +#define CONFIG_TURN_AROUND(v)		(((v) & 0x03) << 2)
> +#define CONFIG_WIDTH(v)			(((v) & 0x03) << 0)

To avoid confusion please do AEMIF_CONFIG_... or AEMIF_CFG_... or maybe
just CFG_...

> +++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
[snip]
> +			prediv = (tmp & 0x3f) + 1;
> +			mult = (((tmp & 0x7f000) >> 6) | (pllctl_reg_read(pll,
> +							mult) & 0x3f)) + 1;
> +			output_div = ((pllctl_reg_read(pll, secctl) >> 19) &
> +				      0xf) + 1;

Please define magic numbers, check globally.

> +	return ret;
> +}
> +
> +
> +
> +
> +unsigned long clk_get_rate(unsigned int clk)

Extra empty lines.

> +++ b/arch/arm/cpu/armv7/keystone/clock.c
[snip]
> +static void pll_delay(unsigned int loop_count)
> +{
> +	while (loop_count--)
> +		asm("   NOP");
> +}

If we cannot use udelay yet use sdelay.

> +#include "clock-k2hk.c"

Please use function prototypes, header files and then build the right
SoC clock file itself.

> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c

We just added a generic

> @@ -0,0 +1,139 @@
> +/*
> + * keystone2: commands for clocks
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <asm/arch/hardware.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/psc_defs.h>
> +
> +static u32 atoui(char *pstr)
> +{
> +	u32 res = 0;
> +
> +	for (; *pstr != 0; pstr++) {
> +		if (*pstr < '0' || *pstr > '9')
> +			break;
> +
> +		res = (res * 10) + (*pstr - '0');
> +	}
> +
> +	return res;
> +}
> +
> +struct pll_init_data cmd_pll_data = {
> +	.pll			= MAIN_PLL,
> +	.pll_m			= 16,
> +	.pll_d			= 1,
> +	.pll_od			= 2,
> +};
> +
> +int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	if (argc != 5)
> +		goto pll_cmd_usage;
> +
> +	if (strncmp(argv[1], "pa", 2) == 0)
> +		cmd_pll_data.pll = PASS_PLL;
> +	else if (strncmp(argv[1], "arm", 3) == 0)
> +		cmd_pll_data.pll = TETRIS_PLL;
> +	else if (strncmp(argv[1], "ddr3a", 5) == 0)
> +		cmd_pll_data.pll = DDR3A_PLL;
> +	else if (strncmp(argv[1], "ddr3b", 5) == 0)
> +		cmd_pll_data.pll = DDR3B_PLL;
> +	else
> +		goto pll_cmd_usage;
> +
> +	cmd_pll_data.pll_m   = atoui(argv[2]);
> +	cmd_pll_data.pll_d   = atoui(argv[3]);
> +	cmd_pll_data.pll_od  = atoui(argv[4]);

Why not simple_strtoul(argv[n], NULL, 10) ?

> +
> +	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
> +	       cmd_pll_data.pll, cmd_pll_data.pll_m,
> +	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
> +	init_pll(&cmd_pll_data);
> +
> +	return 0;
> +
> +pll_cmd_usage:
> +	return cmd_usage(cmdtp);
> +}
> +
> +U_BOOT_CMD(
> +	pllset,	5,	0,	do_pll_cmd,
> +	"set pll multiplier and pre divider",
> +	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
> +);

Wolfgang, if we add another command that takes decimal not hexidecimal
inputs, you're going to hit me with a ruler, aren't you?  Even for a
clock command?

> +U_BOOT_CMD(
> +	getclk,	2,	0,	do_getclk_cmd,
> +	"get clock rate",
> +	"<clk index>\n"
> +	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
> +);

This would fit with the generic clk command and 'dump' which we just
added.

> +++ b/arch/arm/cpu/armv7/keystone/config.mk
> @@ -0,0 +1,14 @@
> +# (C) Copyright 2012-2014
> +#     Texas Instruments Incorporated, <www.ti.com>
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
> +
> +# =========================================================================
> +#
> +# Supply options according to compiler version
> +#
> +# =========================================================================
> +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
> +		    $(call cc-option,-malignment-traps,))

You need to do this as:
PF_CPPFLAGS_SLB := ...
PLATFORM_RELFALGS += $(PF_CPPFLAGS_SLB)

The way you have it causes an evaluation per file and the above is a one
time evaluation.

> diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
> new file mode 100644
> index 0000000..4875db7
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/ddr3.c

Part of me wonders just how close/far this is from the omap-common
EMIF/DDR code.  Some parts look pretty familiar (and makes me wonder if
you don't have some corner-case bugs around not setting shadow registers
and initially setting some of the values to max, then setting them
optimally due to which bits cause a refresh cycle).

> +++ b/arch/arm/cpu/armv7/keystone/lowlevel_init.S

Is there a reason you don't use arch/arm/cpu/armv7/lowlevel_init.S and
the s_init calling sequence?

> +++ b/board/ti/k2hk_evm/board.c
[snip]
> +/* Byte swap the 32-bit data if the device is BE */
> +int cpu_to_bus(u32 *ptr, u32 length)
> +{
> +	u32 i;
> +
> +	if (device_big_endian)
> +		for (i = 0; i < length; i++, ptr++)
> +			*ptr = __swab32(*ptr);
> +
> +	return 0;
> +}

cpu_to_be32() ?

> +int board_init(void)
> +{
> +	gd->bd->bi_arch_number = -1;

Just don't set it?

> +void enable_caches(void)
> +{
> +#ifndef CONFIG_SYS_DCACHE_OFF
> +	/* Enable D-cache. I-cache is already enabled in start.S */
> +	dcache_enable();
> +#endif
> +}

This belongs in one of the arch/arm/cpu/armv7/keystone/ files

> +++ b/drivers/i2c/keystone_i2c.c
> @@ -0,0 +1,372 @@
> +/*
> + * TI Keystone i2c driver
> + * Based on TI DaVinci (TMS320DM644x) I2C driver.

And how different is it really?  Can we not reuse the davinci driver?
Vitaly Andrianov Feb. 11, 2014, 1:44 a.m. UTC | #2
On 02/10/2014 04:25 PM, Tom Rini wrote:
> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
>
>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
>> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
>> refer the ti/k2hk_evm/README for details on the board, build and other
>> information.
>>
>> This patch add support for keystone architecture and k2hk evm.
> Globally, only use
> /*
>   * Multiline comments like this
>   */
I'll fix this.
>> +++ b/arch/arm/cpu/armv7/keystone/Makefile
>> @@ -0,0 +1,18 @@
>> +#
>> +# (C) Copyright 2012-2014
>> +#     Texas Instruments Incorporated, <www.ti.com>
>> +#
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +obj-y	+= aemif.o
>> +obj-y   += init.o
>> +obj-y   += psc.o
>> +obj-y   += clock.o
>> +obj-y   += cmd_clock.o
>> +obj-y   += cmd_mon.o
>> +obj-y   += msmc.o
>> +obj-y   += lowlevel_init.o
>> +obj-$(CONFIG_SPL_BUILD) += spl.o
>> +obj-y	+= ddr3.o
> Mix of space and tab, just tab it all out to line up please.
Will fix.

>> +++ b/arch/arm/cpu/armv7/keystone/aemif.c
>> @@ -0,0 +1,79 @@
>> +/*
>> + * Keystone2: Asynchronous EMIF Configuration
>> + *
>> + * (C) Copyright 2012-2014
>> + *     Texas Instruments Incorporated, <www.ti.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <asm/io.h>
>> +#include <asm/arch/clock.h>
>> +
>> +#ifdef CONFIG_SOC_K2HK
>> +#define ASYNC_EMIF_BASE			K2HK_ASYNC_EMIF_CNTRL_BASE
>> +#endif
> So, does Keystone 1 have this in a different location?
That is not for Keystone1. K2HK is for Hawking and Kepler SoC.
The ASYNC_EMIF_BASE may be different for other SOC of the Keystone2 family.
>> +#define ASYNC_EMIF_CONFIG(cs)		(ASYNC_EMIF_BASE+0x10+(cs)*4)
>> +#define ASYNC_EMIF_ONENAND_CONTROL	(ASYNC_EMIF_BASE+0x5c)
>> +#define ASYNC_EMIF_NAND_CONTROL		(ASYNC_EMIF_BASE+0x60)
>> +#define ASYNC_EMIF_WAITCYCLE_CONFIG	(ASYNC_EMIF_BASE+0x4)
> Register access is done over structs not define of base + offset, please
> rework.
This style was taken form Davinci code. Shall we rework it?
>> +#define CONFIG_SELECT_STROBE(v)		((v) ? 1 << 31 : 0)
>> +#define CONFIG_EXTEND_WAIT(v)		((v) ? 1 << 30 : 0)
>> +#define CONFIG_WR_SETUP(v)		(((v) & 0x0f) << 26)
>> +#define CONFIG_WR_STROBE(v)		(((v) & 0x3f) << 20)
>> +#define CONFIG_WR_HOLD(v)		(((v) & 0x07) << 17)
>> +#define CONFIG_RD_SETUP(v)		(((v) & 0x0f) << 13)
>> +#define CONFIG_RD_STROBE(v)		(((v) & 0x3f) << 7)
>> +#define CONFIG_RD_HOLD(v)		(((v) & 0x07) << 4)
>> +#define CONFIG_TURN_AROUND(v)		(((v) & 0x03) << 2)
>> +#define CONFIG_WIDTH(v)			(((v) & 0x03) << 0)
> To avoid confusion please do AEMIF_CONFIG_... or AEMIF_CFG_... or maybe
> just CFG_...
Agree and will change.

>> +++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
> [snip]
>> +			prediv = (tmp & 0x3f) + 1;
>> +			mult = (((tmp & 0x7f000) >> 6) | (pllctl_reg_read(pll,
>> +							mult) & 0x3f)) + 1;
>> +			output_div = ((pllctl_reg_read(pll, secctl) >> 19) &
>> +				      0xf) + 1;
> Please define magic numbers, check globally.
OK
>
>> +	return ret;
>> +}
>> +
>> +
>> +
>> +
>> +unsigned long clk_get_rate(unsigned int clk)
> Extra empty lines.
Will remove.

>> +++ b/arch/arm/cpu/armv7/keystone/clock.c
> [snip]
>> +static void pll_delay(unsigned int loop_count)
>> +{
>> +	while (loop_count--)
>> +		asm("   NOP");
>> +}
> If we cannot use udelay yet use sdelay.
>
>> +#include "clock-k2hk.c"
> Please use function prototypes, header files and then build the right
> SoC clock file itself.
The idea was to have common clock.h for all Keystone2 family and include 
in to
it a specific for each SoC include file. Are you asking to remove that 
specific include
from the clock.h?

>> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> We just added a generic
I'll check it out.

>> @@ -0,0 +1,139 @@
>> +/*
>> + * keystone2: commands for clocks
>> + *
>> + * (C) Copyright 2012-2014
>> + *     Texas Instruments Incorporated, <www.ti.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <command.h>
>> +#include <asm/arch/hardware.h>
>> +#include <asm/arch/clock.h>
>> +#include <asm/arch/psc_defs.h>
>> +
>> +static u32 atoui(char *pstr)
>> +{
>> +	u32 res = 0;
>> +
>> +	for (; *pstr != 0; pstr++) {
>> +		if (*pstr < '0' || *pstr > '9')
>> +			break;
>> +
>> +		res = (res * 10) + (*pstr - '0');
>> +	}
>> +
>> +	return res;
>> +}
>> +
>> +struct pll_init_data cmd_pll_data = {
>> +	.pll			= MAIN_PLL,
>> +	.pll_m			= 16,
>> +	.pll_d			= 1,
>> +	.pll_od			= 2,
>> +};
>> +
>> +int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> +{
>> +	if (argc != 5)
>> +		goto pll_cmd_usage;
>> +
>> +	if (strncmp(argv[1], "pa", 2) == 0)
>> +		cmd_pll_data.pll = PASS_PLL;
>> +	else if (strncmp(argv[1], "arm", 3) == 0)
>> +		cmd_pll_data.pll = TETRIS_PLL;
>> +	else if (strncmp(argv[1], "ddr3a", 5) == 0)
>> +		cmd_pll_data.pll = DDR3A_PLL;
>> +	else if (strncmp(argv[1], "ddr3b", 5) == 0)
>> +		cmd_pll_data.pll = DDR3B_PLL;
>> +	else
>> +		goto pll_cmd_usage;
>> +
>> +	cmd_pll_data.pll_m   = atoui(argv[2]);
>> +	cmd_pll_data.pll_d   = atoui(argv[3]);
>> +	cmd_pll_data.pll_od  = atoui(argv[4]);
> Why not simple_strtoul(argv[n], NULL, 10) ?
>
>> +
>> +	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
>> +	       cmd_pll_data.pll, cmd_pll_data.pll_m,
>> +	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
>> +	init_pll(&cmd_pll_data);
>> +
>> +	return 0;
>> +
>> +pll_cmd_usage:
>> +	return cmd_usage(cmdtp);
>> +}
>> +
>> +U_BOOT_CMD(
>> +	pllset,	5,	0,	do_pll_cmd,
>> +	"set pll multiplier and pre divider",
>> +	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
>> +);
> Wolfgang, if we add another command that takes decimal not hexidecimal
> inputs, you're going to hit me with a ruler, aren't you?  Even for a
> clock command?
>
>> +U_BOOT_CMD(
>> +	getclk,	2,	0,	do_getclk_cmd,
>> +	"get clock rate",
>> +	"<clk index>\n"
>> +	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
>> +);
> This would fit with the generic clk command and 'dump' which we just
> added.
>
>> +++ b/arch/arm/cpu/armv7/keystone/config.mk
>> @@ -0,0 +1,14 @@
>> +# (C) Copyright 2012-2014
>> +#     Texas Instruments Incorporated, <www.ti.com>
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
>> +
>> +# =========================================================================
>> +#
>> +# Supply options according to compiler version
>> +#
>> +# =========================================================================
>> +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
>> +		    $(call cc-option,-malignment-traps,))
> You need to do this as:
> PF_CPPFLAGS_SLB := ...
> PLATFORM_RELFALGS += $(PF_CPPFLAGS_SLB)
>
> The way you have it causes an evaluation per file and the above is a one
> time evaluation.
>
>> diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
>> new file mode 100644
>> index 0000000..4875db7
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv7/keystone/ddr3.c
> Part of me wonders just how close/far this is from the omap-common
> EMIF/DDR code.  Some parts look pretty familiar (and makes me wonder if
> you don't have some corner-case bugs around not setting shadow registers
> and initially setting some of the values to max, then setting them
> optimally due to which bits cause a refresh cycle).
This code is based on AVV test code and is very specific to SOC DDR3 
controller,
which as I know is different from OMAP.

>> +++ b/arch/arm/cpu/armv7/keystone/lowlevel_init.S
> Is there a reason you don't use arch/arm/cpu/armv7/lowlevel_init.S and
> the s_init calling sequence?
>
>> +++ b/board/ti/k2hk_evm/board.c
> [snip]
>> +/* Byte swap the 32-bit data if the device is BE */
>> +int cpu_to_bus(u32 *ptr, u32 length)
>> +{
>> +	u32 i;
>> +
>> +	if (device_big_endian)
>> +		for (i = 0; i < length; i++, ptr++)
>> +			*ptr = __swab32(*ptr);
>> +
>> +	return 0;
>> +}
> cpu_to_be32() ?
>
>> +int board_init(void)
>> +{
>> +	gd->bd->bi_arch_number = -1;
> Just don't set it?
>
>> +void enable_caches(void)
>> +{
>> +#ifndef CONFIG_SYS_DCACHE_OFF
>> +	/* Enable D-cache. I-cache is already enabled in start.S */
>> +	dcache_enable();
>> +#endif
>> +}
> This belongs in one of the arch/arm/cpu/armv7/keystone/ files
>
>> +++ b/drivers/i2c/keystone_i2c.c
>> @@ -0,0 +1,372 @@
>> +/*
>> + * TI Keystone i2c driver
>> + * Based on TI DaVinci (TMS320DM644x) I2C driver.
> And how different is it really?  Can we not reuse the davinci driver?
>
It is reworked a little bit and also supports multiple ports, while 
davinci driver
supports only one.

I'll check out other comment as well.

Thanks,
Vitaly
Tom Rini Feb. 12, 2014, 12:53 p.m. UTC | #3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/10/2014 08:44 PM, Vitaly Andrianov wrote:
> On 02/10/2014 04:25 PM, Tom Rini wrote:
>> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
>>
>>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
>>> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
>>> refer the ti/k2hk_evm/README for details on the board, build and other
>>> information.
[snip]
>>> +#ifdef CONFIG_SOC_K2HK
>>> +#define ASYNC_EMIF_BASE            K2HK_ASYNC_EMIF_CNTRL_BASE
>>> +#endif
>> So, does Keystone 1 have this in a different location?
> That is not for Keystone1. K2HK is for Hawking and Kepler SoC.
> The ASYNC_EMIF_BASE may be different for other SOC of the Keystone2 family.

That seems pretty unlikely, unless you've seen actual plans to the
contrary, so lets assume the base won't change for this family at least.

>>> +#define ASYNC_EMIF_CONFIG(cs)        (ASYNC_EMIF_BASE+0x10+(cs)*4)
>>> +#define ASYNC_EMIF_ONENAND_CONTROL    (ASYNC_EMIF_BASE+0x5c)
>>> +#define ASYNC_EMIF_NAND_CONTROL        (ASYNC_EMIF_BASE+0x60)
>>> +#define ASYNC_EMIF_WAITCYCLE_CONFIG    (ASYNC_EMIF_BASE+0x4)
>> Register access is done over structs not define of base + offset, please
>> rework.
> This style was taken form Davinci code. Shall we rework it?

Yes.

[snip]
>>> +++ b/arch/arm/cpu/armv7/keystone/clock.c
>> [snip]
>>> +static void pll_delay(unsigned int loop_count)
>>> +{
>>> +    while (loop_count--)
>>> +        asm("   NOP");
>>> +}
>> If we cannot use udelay yet use sdelay.
>>
>>> +#include "clock-k2hk.c"
>> Please use function prototypes, header files and then build the right
>> SoC clock file itself.
> The idea was to have common clock.h for all Keystone2 family and include
> in to
> it a specific for each SoC include file. Are you asking to remove that
> specific include
> from the clock.h?

I'm saying we can't include a c file from another c file.  See
arch/arm/cpu/armv7/am33xx/ (and asm/arch-am33xx/) for how we support
different clocks in similar-but-different families.

[snip]
>>> diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c
>>> b/arch/arm/cpu/armv7/keystone/ddr3.c
>>> new file mode 100644
>>> index 0000000..4875db7
>>> --- /dev/null
>>> +++ b/arch/arm/cpu/armv7/keystone/ddr3.c
>> Part of me wonders just how close/far this is from the omap-common
>> EMIF/DDR code.  Some parts look pretty familiar (and makes me wonder if
>> you don't have some corner-case bugs around not setting shadow registers
>> and initially setting some of the values to max, then setting them
>> optimally due to which bits cause a refresh cycle).
> This code is based on AVV test code and is very specific to SOC DDR3
> controller,
> which as I know is different from OMAP.

I'm not going to push this too hard since I don't have all the low level
knowledge (nor contacts) about just how the block was re-used, but it's
not 100% different from the rest of the EMIF parts TI uses.  We should
revisit this later (and once I've got the right docs for keystone parts
around).

[snip]
>>> +++ b/drivers/i2c/keystone_i2c.c
>>> @@ -0,0 +1,372 @@
>>> +/*
>>> + * TI Keystone i2c driver
>>> + * Based on TI DaVinci (TMS320DM644x) I2C driver.
>> And how different is it really?  Can we not reuse the davinci driver?
>>
> It is reworked a little bit and also supports multiple ports, while
> davinci driver supports only one.

Right, so lets enhance the existing driver.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJS+27JAAoJENk4IS6UOR1W/FAP/iUgQQf7q1NiGMwF4HfJqeZe
PsrO3ElN3TPPrnFQ5PgqXk3t8RSAFy7EVIetLjs8ZSh+JZvH48/YH9RCVm0err/I
LQVeQbklHNiV5kNtxMWQlwGmG/ySG3S7DiZ9wS2GyTbrJV0v4Zl9P6qjdxyc5vAl
O6aWDHv7IvqG5GXY8tSsptb8oN6H71foniufSLref5qQWeDxJtXpS31f0g0R9h4e
r76o7eQ4iNpUoCu5eKz4XzOUEV9ve1zQP1Iv5d2JGxV0FXkSyZ32STAkkdf6zglP
vnrK+dzk7B67hc1EQb2V0y3oY3yEmY+Z3aXkf3ws+5BY7R7SfZ8WfLxg1i7NJBZs
CFwFPVV91A05Tq4yRMnniCs6mOCpG08IwyxEz5SmEoG52H/onNHd1HnYhBEiuwRI
ENKm7IxdYFuWBVSd+FLaU6IQQdL8WnzL9YVkBuYdA+hPEAbcPVEWGFTVGo9fJP9r
SoWXzI8ue+fUiJxvVJdcwJ8AJrq7Ci4FBFjMDtxe+8e9wgUp0ZVeFPOW6kEml7I2
O8HkgtMB0MdMDdESB9m/neFs0E3Va7EX3tlVPAcfqlQjjkFS0v9OmlGZG23bs9HP
emejngR267JKcmJjuimf12IhIRWc62QtJBPXx+8WmEUy53CjkFhUfD7EKEzHT/52
CKaOAhmNc1EZAZkZcaBv
=anbB
-----END PGP SIGNATURE-----
Vitaly Andrianov Feb. 17, 2014, 9:19 p.m. UTC | #4
> -----Original Message-----
> From: Tom Rini [mailto:tom.rini@gmail.com] On Behalf Of Rini, Tom
> Sent: Monday, February 10, 2014 4:26 PM
> To: Karicheri, Muralidharan
> Cc: u-boot@lists.denx.de; Sandeep@theia.denx.de; Kwok, WingMan; Nair,
> Sandeep; Andrianov, Vitaly
> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for
> k2hk SOC and EVM
> 
> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
> 
> > k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC.
> > Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
> the
> > ti/k2hk_evm/README for details on the board, build and other
> > information.
> >
> > This patch add support for keystone architecture and k2hk evm.

[snip]
 
> 
> > +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> 
> We just added a generic
> 

Tom,
Where can I see this generic implementation?

Thanks,
Vitaly
Tom Rini Feb. 17, 2014, 9:57 p.m. UTC | #5
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/17/2014 04:19 PM, Andrianov, Vitaly wrote:
>> -----Original Message-----
>> From: Tom Rini [mailto:tom.rini@gmail.com] On Behalf Of Rini, Tom
>> Sent: Monday, February 10, 2014 4:26 PM
>> To: Karicheri, Muralidharan
>> Cc: u-boot@lists.denx.de; Sandeep@theia.denx.de; Kwok, WingMan; Nair,
>> Sandeep; Andrianov, Vitaly
>> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for
>> k2hk SOC and EVM
>>
>> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
>>
>>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC.
>>> Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
>> the
>>> ti/k2hk_evm/README for details on the board, build and other
>>> information.
>>>
>>> This patch add support for keystone architecture and k2hk evm.
> 
> [snip]
>  
>>
>>> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
>>
>> We just added a generic
>>
> 
> Tom,
> Where can I see this generic implementation?

Start poking at common/cmd_clk.c

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTAoXUAAoJENk4IS6UOR1WbQIQALPc/cIk4WTGLjV4lZQ+j2XH
0LzIel0Crx4TT3XPSfepxfQM0GqDseO92ujrGM5uqG043UIji8F/KmcJR2ILLgji
/07XiGG6fM9HSf/rnCgLFil7kY9DSoru5JLfnSkZISnowkK7/JgwRwrbXsG17rXD
vgyuGbS/Fpi6kt4AfjF1FtmDs/l9e28nh5ds9MUjQKBiWEVeSZdBDid6mq2kyY7e
6asozG0qIbaNS+o2F7HSbaQs8Ar78CLkM36Bsu3cjpHO+JZLtqaOvvlm6U8kbj5a
DK77Of6zQ9ToGOVtFFxVvMFinf/BRgZ+M9cyntKWlZ12uClPGXgOW3EyDrrW2VE8
3cXRqOlfBfUoJevtg6SQu837EeLrVOYKP8bs6A6IQ3etNGc+OhsXZnNhkmfHjtuw
2n7sOqOdC4Hpw0rjWfY1UaWPEPHoq+HPSqJHN6VaVkopKzPX5bWqDBxT+MtMxp5q
o196auSdfyW+z3A4MIpSWpEhB5Q7afr6v/VPs9wqkehuj/QdcFm8N2nD3s6Pg5NS
reuqTEZZbbQ5RORgjFDBqhnpgUaHx3OGM+HsCr5Msz/QRjtiljFYI9DtLdkn0XZw
jTbvUkEob8hVGaoptdppwUj90Cw6sJ5r15TGTHohJLkxzQfBkXeTK0fUXYSfPCMJ
Iyf9nPf1+D1AMKzIM14q
=Bk7g
-----END PGP SIGNATURE-----
Vitaly Andrianov Feb. 20, 2014, 5:27 p.m. UTC | #6
> -----Original Message-----
> From: Rini, Tom
> Sent: Monday, February 17, 2014 4:58 PM
> To: Andrianov, Vitaly
> Cc: Karicheri, Muralidharan; u-boot@lists.denx.de;
> Sandeep@theia.denx.de; Kwok, WingMan; Nair, Sandeep
> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for
> k2hk SOC and EVM
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> On 02/17/2014 04:19 PM, Andrianov, Vitaly wrote:
> >> -----Original Message-----
> >> From: Tom Rini [mailto:tom.rini@gmail.com] On Behalf Of Rini, Tom
> >> Sent: Monday, February 10, 2014 4:26 PM
> >> To: Karicheri, Muralidharan
> >> Cc: u-boot@lists.denx.de; Sandeep@theia.denx.de; Kwok, WingMan;
> Nair,
> >> Sandeep; Andrianov, Vitaly
> >> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support
> >> for k2hk SOC and EVM
> >>
> >> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
> >>
> >>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
> SoC.
> >>> Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
> >> the
> >>> ti/k2hk_evm/README for details on the board, build and other
> >>> information.
> >>>
> >>> This patch add support for keystone architecture and k2hk evm.
> >
> > [snip]
> >
> >>
> >>> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> >>
> >> We just added a generic
> >>
> >
> > Tom,
> > Where can I see this generic implementation?
> 
> Start poking at common/cmd_clk.c
> 

The command in that file just dump all clocks. We need to have a command
to display one particular clock. So, for now we will continue to use
the keystone2 specific implementation and change it later when the
generic will support one clock only.

> - --
> Tom
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.11 (GNU/Linux)
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
> 
> iQIcBAEBAgAGBQJTAoXUAAoJENk4IS6UOR1WbQIQALPc/cIk4WTGLjV4lZQ+j2XH
> 0LzIel0Crx4TT3XPSfepxfQM0GqDseO92ujrGM5uqG043UIji8F/KmcJR2ILLgji
> /07XiGG6fM9HSf/rnCgLFil7kY9DSoru5JLfnSkZISnowkK7/JgwRwrbXsG17rXD
> vgyuGbS/Fpi6kt4AfjF1FtmDs/l9e28nh5ds9MUjQKBiWEVeSZdBDid6mq2kyY7e
> 6asozG0qIbaNS+o2F7HSbaQs8Ar78CLkM36Bsu3cjpHO+JZLtqaOvvlm6U8kbj5a
> DK77Of6zQ9ToGOVtFFxVvMFinf/BRgZ+M9cyntKWlZ12uClPGXgOW3EyDrrW2VE8
> 3cXRqOlfBfUoJevtg6SQu837EeLrVOYKP8bs6A6IQ3etNGc+OhsXZnNhkmfHjtuw
> 2n7sOqOdC4Hpw0rjWfY1UaWPEPHoq+HPSqJHN6VaVkopKzPX5bWqDBxT+MtMxp5q
> o196auSdfyW+z3A4MIpSWpEhB5Q7afr6v/VPs9wqkehuj/QdcFm8N2nD3s6Pg5NS
> reuqTEZZbbQ5RORgjFDBqhnpgUaHx3OGM+HsCr5Msz/QRjtiljFYI9DtLdkn0XZw
> jTbvUkEob8hVGaoptdppwUj90Cw6sJ5r15TGTHohJLkxzQfBkXeTK0fUXYSfPCMJ
> Iyf9nPf1+D1AMKzIM14q
> =Bk7g
> -----END PGP SIGNATURE-----

Thanks,
Vitaly
diff mbox

Patch

diff --git a/Makefile b/Makefile
index 47a03e3..ea2a387 100644
--- a/Makefile
+++ b/Makefile
@@ -491,6 +491,23 @@  $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
 			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@
 		cat $(obj)u-boot.img >> $@
 
+$(obj)u-boot-spi.gph:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
+			-n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
+		$(OBJCOPY) ${OBJCFLAGS} -I binary \
+			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
+			$(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
+		cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
+
+$(obj)u-boot-nand.gph:	$(obj)u-boot.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
+			-n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
+		@dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
+		@cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
+		@rm $(obj)zero.bin
+
 ifneq ($(CONFIG_TEGRA),)
 $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
 		$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
@@ -841,12 +858,14 @@  clobber:	tidy
 	@rm -f $(obj)u-boot.dtb
 	@rm -f $(obj)u-boot.sb
 	@rm -f $(obj)u-boot.spr
+	@rm -f $(obj)u-boot-*.gph
 	@rm -f $(obj)nand_spl/{u-boot.{lds,lst},System.map}
 	@rm -f $(obj)nand_spl/{u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map}
 	@rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.map}
 	@rm -f $(obj)spl/u-boot-spl.lds
 	@rm -f $(obj)tpl/{u-boot-tpl,u-boot-tpl.bin,u-boot-tpl.map}
 	@rm -f $(obj)tpl/u-boot-spl.lds
+	@rm -f $(obj)spl/{u-boot-spl.gph,u-boot-spl-pad.gph}
 	@rm -f $(obj)MLO MLO.byteswap
 	@rm -f $(obj)SPL
 	@rm -f $(obj)tools/xway-swap-bytes
diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile
new file mode 100644
index 0000000..0fd4189
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/Makefile
@@ -0,0 +1,18 @@ 
+#
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= aemif.o
+obj-y   += init.o
+obj-y   += psc.o
+obj-y   += clock.o
+obj-y   += cmd_clock.o
+obj-y   += cmd_mon.o
+obj-y   += msmc.o
+obj-y   += lowlevel_init.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
+obj-y	+= ddr3.o
+
diff --git a/arch/arm/cpu/armv7/keystone/aemif.c b/arch/arm/cpu/armv7/keystone/aemif.c
new file mode 100644
index 0000000..1063858
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/aemif.c
@@ -0,0 +1,79 @@ 
+/*
+ * Keystone2: Asynchronous EMIF Configuration
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+#ifdef CONFIG_SOC_K2HK
+#define ASYNC_EMIF_BASE			K2HK_ASYNC_EMIF_CNTRL_BASE
+#endif
+
+#define ASYNC_EMIF_CONFIG(cs)		(ASYNC_EMIF_BASE+0x10+(cs)*4)
+#define ASYNC_EMIF_ONENAND_CONTROL	(ASYNC_EMIF_BASE+0x5c)
+#define ASYNC_EMIF_NAND_CONTROL		(ASYNC_EMIF_BASE+0x60)
+#define ASYNC_EMIF_WAITCYCLE_CONFIG	(ASYNC_EMIF_BASE+0x4)
+
+#define CONFIG_SELECT_STROBE(v)		((v) ? 1 << 31 : 0)
+#define CONFIG_EXTEND_WAIT(v)		((v) ? 1 << 30 : 0)
+#define CONFIG_WR_SETUP(v)		(((v) & 0x0f) << 26)
+#define CONFIG_WR_STROBE(v)		(((v) & 0x3f) << 20)
+#define CONFIG_WR_HOLD(v)		(((v) & 0x07) << 17)
+#define CONFIG_RD_SETUP(v)		(((v) & 0x0f) << 13)
+#define CONFIG_RD_STROBE(v)		(((v) & 0x3f) << 7)
+#define CONFIG_RD_HOLD(v)		(((v) & 0x07) << 4)
+#define CONFIG_TURN_AROUND(v)		(((v) & 0x03) << 2)
+#define CONFIG_WIDTH(v)			(((v) & 0x03) << 0)
+
+#define set_config_field(reg, field, val)			\
+	do {							\
+		if (val != -1) {				\
+			reg &= ~CONFIG_##field(0xffffffff);	\
+			reg |=	CONFIG_##field(val);		\
+		}						\
+	} while (0)
+
+void configure_async_emif(int cs, struct async_emif_config *cfg)
+{
+	unsigned long tmp;
+
+	if (cfg->mode == ASYNC_EMIF_MODE_NAND) {
+		tmp = __raw_readl(ASYNC_EMIF_NAND_CONTROL);
+		tmp |= (1 << cs);
+		__raw_writel(tmp, ASYNC_EMIF_NAND_CONTROL);
+
+	} else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) {
+		tmp = __raw_readl(ASYNC_EMIF_ONENAND_CONTROL);
+		tmp |= (1 << cs);
+		__raw_writel(tmp, ASYNC_EMIF_ONENAND_CONTROL);
+	}
+
+	tmp = __raw_readl(ASYNC_EMIF_CONFIG(cs));
+
+	set_config_field(tmp, SELECT_STROBE,	cfg->select_strobe);
+	set_config_field(tmp, EXTEND_WAIT,	cfg->extend_wait);
+	set_config_field(tmp, WR_SETUP,		cfg->wr_setup);
+	set_config_field(tmp, WR_STROBE,	cfg->wr_strobe);
+	set_config_field(tmp, WR_HOLD,		cfg->wr_hold);
+	set_config_field(tmp, RD_SETUP,		cfg->rd_setup);
+	set_config_field(tmp, RD_STROBE,	cfg->rd_strobe);
+	set_config_field(tmp, RD_HOLD,		cfg->rd_hold);
+	set_config_field(tmp, TURN_AROUND,	cfg->turn_around);
+	set_config_field(tmp, WIDTH,		cfg->width);
+
+	__raw_writel(tmp, ASYNC_EMIF_CONFIG(cs));
+}
+
+void init_async_emif(int num_cs, struct async_emif_config *config)
+{
+	int cs;
+
+	for (cs = 0; cs < num_cs; cs++)
+		configure_async_emif(cs, config + cs);
+}
diff --git a/arch/arm/cpu/armv7/keystone/clock-k2hk.c b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
new file mode 100644
index 0000000..5e404dd
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
@@ -0,0 +1,106 @@ 
+/*
+ * K2HK: pll clock utilities
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+static const struct pll_regs pll_regs[] = {
+	[CORE_PLL]	= { K2HK_MAINPLLCTL0, K2HK_MAINPLLCTL1},
+	[PASS_PLL]	= { K2HK_PASSPLLCTL0, K2HK_PASSPLLCTL1},
+	[TETRIS_PLL]	= { K2HK_ARMPLLCTL0,  K2HK_ARMPLLCTL1},
+	[DDR3A_PLL]	= { K2HK_DDR3APLLCTL0, K2HK_DDR3APLLCTL1},
+	[DDR3B_PLL]	= { K2HK_DDR3BPLLCTL0, K2HK_DDR3BPLLCTL1},
+};
+
+/* Fout = Fref * NF(mult) / NR(prediv) / OD */
+static unsigned long pll_freq_get(int pll)
+{
+	unsigned long mult = 1, prediv = 1, output_div = 2;
+	unsigned long ret;
+	u32 tmp, reg;
+
+	if (pll == CORE_PLL) {
+		ret = external_clk[sys_clk];
+		if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) {
+			/* PLL mode */
+			tmp = __raw_readl(K2HK_MAINPLLCTL0);
+			prediv = (tmp & 0x3f) + 1;
+			mult = (((tmp & 0x7f000) >> 6) | (pllctl_reg_read(pll,
+							mult) & 0x3f)) + 1;
+			output_div = ((pllctl_reg_read(pll, secctl) >> 19) &
+				      0xf) + 1;
+
+			ret = ret / prediv / output_div * mult;
+		}
+	} else {
+		switch (pll) {
+		case PASS_PLL:
+			ret = external_clk[pa_clk];
+			reg = K2HK_PASSPLLCTL0;
+			break;
+		case TETRIS_PLL:
+			ret = external_clk[tetris_clk];
+			reg = K2HK_ARMPLLCTL0;
+			break;
+		case DDR3A_PLL:
+			ret = external_clk[ddr3a_clk];
+			reg = K2HK_DDR3APLLCTL0;
+			break;
+		case DDR3B_PLL:
+			ret = external_clk[ddr3b_clk];
+			reg = K2HK_DDR3BPLLCTL0;
+			break;
+		default:
+			return 0;
+		}
+
+		tmp = __raw_readl(reg);
+
+		if (!(tmp & 0x00800000)) {
+			/* Bypass disabled */
+			prediv = (tmp & 0x3f) + 1;
+			mult = ((tmp >> 6) & 0x1fff) + 1;
+			output_div = ((tmp >> 19) & 0xf) + 1;
+			ret = ((ret / prediv) * mult) / output_div;
+		}
+	}
+
+	return ret;
+}
+
+
+
+
+unsigned long clk_get_rate(unsigned int clk)
+{
+	switch (clk) {
+	case core_pll_clk:	return pll_freq_get(CORE_PLL);
+	case pass_pll_clk:	return pll_freq_get(PASS_PLL);
+	case tetris_pll_clk:	return pll_freq_get(TETRIS_PLL);
+	case ddr3a_pll_clk:	return pll_freq_get(DDR3A_PLL);
+	case ddr3b_pll_clk:	return pll_freq_get(DDR3B_PLL);
+	case sys_clk0_1_clk:
+	case sys_clk0_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(1);
+	case sys_clk1_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(2);
+	case sys_clk2_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(3);
+	case sys_clk3_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(4);
+	case sys_clk0_2_clk:	return clk_get_rate(sys_clk0_clk) / 2;
+	case sys_clk0_3_clk:	return clk_get_rate(sys_clk0_clk) / 3;
+	case sys_clk0_4_clk:	return clk_get_rate(sys_clk0_clk) / 4;
+	case sys_clk0_6_clk:	return clk_get_rate(sys_clk0_clk) / 6;
+	case sys_clk0_8_clk:	return clk_get_rate(sys_clk0_clk) / 8;
+	case sys_clk0_12_clk:	return clk_get_rate(sys_clk0_clk) / 12;
+	case sys_clk0_24_clk:	return clk_get_rate(sys_clk0_clk) / 24;
+	case sys_clk1_3_clk:	return clk_get_rate(sys_clk1_clk) / 3;
+	case sys_clk1_4_clk:	return clk_get_rate(sys_clk1_clk) / 4;
+	case sys_clk1_6_clk:	return clk_get_rate(sys_clk1_clk) / 6;
+	case sys_clk1_12_clk:	return clk_get_rate(sys_clk1_clk) / 12;
+	default:
+		break;
+	}
+	return 0;
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c
new file mode 100644
index 0000000..70f88ce
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock.c
@@ -0,0 +1,200 @@ 
+/*
+ * Keystone2: pll initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clock_defs.h>
+
+static void pll_delay(unsigned int loop_count)
+{
+	while (loop_count--)
+		asm("   NOP");
+}
+
+static void wait_for_completion(const struct pll_init_data *data)
+{
+	int i;
+	for (i = 0; i < 100; i++) {
+		pll_delay(300);
+		if ((pllctl_reg_read(data->pll, stat) & 0x00000001) == 0)
+			break;
+	}
+}
+
+struct pll_regs {
+	u32	reg0, reg1;
+};
+
+
+#include "clock-k2hk.c"
+
+void init_pll(const struct pll_init_data *data)
+{
+	u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj;
+
+	pllm = data->pll_m - 1;
+	plld = (data->pll_d - 1) & 0x3f;
+	pllod = (data->pll_od - 1) & 0xf;
+
+	if (data->pll == MAIN_PLL) {
+		pll_delay(140000);
+
+		tmp = pllctl_reg_read(data->pll, secctl);
+
+		if (tmp & (PLLCTL_BYPASS)) {
+			reg_setbits(pll_regs[data->pll].reg1,
+				    BIT(MAIN_ENSAT_OFFSET));
+
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
+					   PLLCTL_PLLENSRC);
+			pll_delay(225);
+
+			pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS);
+			pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+			pll_delay(14000);
+
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+		} else {
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
+					   PLLCTL_PLLENSRC);
+			pll_delay(225);
+		}
+
+		pllctl_reg_write(data->pll, mult, pllm & 0x3f);
+
+		reg_rmw(pll_regs[data->pll].reg0, 0x0007F000, (pllm << 6));
+
+		/* Set the BWADJ     (12 bit field)  */
+		tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */
+		reg_rmw(pll_regs[data->pll].reg0, 0xFF000000, (tmp_ctl << 24));
+		reg_rmw(pll_regs[data->pll].reg1, 0x0000000F, (tmp_ctl >> 8));
+
+		/* Set the pll divider (6 bit field)   *
+		 * PLLD[5:0] is located in MAINPLLCTL0 */
+		reg_rmw(pll_regs[data->pll].reg0, 0x0000003F, plld);
+
+		/* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */
+		pllctl_reg_rmw(data->pll, secctl, 0x00780000, (pllod << 19));
+		wait_for_completion(data);
+
+		pllctl_reg_write(data->pll, div1, 0x00008000);
+		pllctl_reg_write(data->pll, div2, 0x00008000);
+		pllctl_reg_write(data->pll, div3, 0x00008001);
+		pllctl_reg_write(data->pll, div4, 0x00008004);
+		pllctl_reg_write(data->pll, div5, 0x000080017);
+
+		pllctl_reg_setbits(data->pll, alnctl, 0x1f);
+
+		/* Set GOSET bit in PLLCMD to initiate the GO operation
+		 * to change the divide */
+		pllctl_reg_setbits(data->pll, cmd, 0x1);
+		pll_delay(1000); /* wait for the phase adj */
+		wait_for_completion(data);
+
+		/* Reset PLL */
+		pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
+		pll_delay(14000);	/* Wait for a minimum of 7 us*/
+		pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
+		pll_delay(70000);	/* Wait for PLL Lock time (min 50 us) */
+
+		pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS);
+
+		tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN);
+
+	} else if (data->pll == TETRIS_PLL) {
+		bwadj = pllm >> 1;
+		/* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */
+		reg_setbits(pll_regs[data->pll].reg0,  0x00800000);
+		/* Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass)
+		 * only applicable for Kepler */
+		reg_clrbits(0x02620c7c, (1<<13));
+		/* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */
+		reg_setbits(pll_regs[data->pll].reg1 , (1<<14) | (1 << 6));
+
+		/* 3 Program PLLM and PLLD in PLLCTL0 register
+		 * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in
+		 * PLLCTL1 register. BWADJ value must be set
+		 * to ((PLLM + 1) >> 1) – 1) */
+		tmp = ((bwadj & 0xff) << 24) | (pllm << 6) |
+			(plld & 0x3f) | (pllod<<19) | 0x00800000;
+		__raw_writel(tmp, pll_regs[data->pll].reg0);
+
+		/* Set BWADJ[11:8] bits */
+		tmp = __raw_readl(pll_regs[data->pll].reg1);
+		tmp &= ~(0xf);
+		tmp |= ((bwadj>>8) & 0xf);
+		__raw_writel(tmp, pll_regs[data->pll].reg1);
+		/* 5 Wait for at least 5 us based on the reference
+		 * clock (PLL reset time) */
+		pll_delay(14000);	/* Wait for a minimum of 7 us*/
+
+		/* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */
+		reg_clrbits(pll_regs[data->pll].reg1 , (1<<14));
+		/* 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1)
+		 * (PLL lock time) */
+		pll_delay(70000);
+		/* 8 disable bypass */
+		reg_clrbits(pll_regs[data->pll].reg0, 0x00800000);
+		/* 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass)
+		 * only applicable for Kepler */
+		reg_setbits(0x02620c7c, (1<<13));
+	} else {
+		reg_setbits(pll_regs[data->pll].reg1, 0x00000040);
+		/* process keeps state of Bypass bit while programming
+		 * all other DDR PLL settings */
+		tmp = __raw_readl(pll_regs[data->pll].reg0);
+		tmp &= 0x00800000;	/* clear everything except Bypass */
+
+		/* Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0,
+		 * bypass disabled */
+		bwadj = pllm >> 1;
+		tmp |= ((bwadj & 0xff) << 24) | (pllm << 6) |
+			(plld & 0x3f) | (pllod<<19);
+		__raw_writel(tmp, pll_regs[data->pll].reg0);
+
+		/* Set BWADJ[11:8] bits */
+		tmp = __raw_readl(pll_regs[data->pll].reg1);
+		tmp &= ~(0xf);
+		tmp |= ((bwadj>>8) & 0xf);
+
+		/* set PLL Select (bit 13) for PASS PLL */
+		if (data->pll == PASS_PLL)
+			tmp |= 0x00002000;
+
+		__raw_writel(tmp, pll_regs[data->pll].reg1);
+
+		/* Reset bit: bit 14 for both DDR3 & PASS PLL */
+		tmp = 0x00004000;
+		/* Set RESET bit = 1 */
+		reg_setbits(pll_regs[data->pll].reg1, tmp);
+		/* Wait for a minimum of 7 us*/
+		pll_delay(14000);
+		/* Clear RESET bit */
+		reg_clrbits(pll_regs[data->pll].reg1, tmp);
+		pll_delay(70000);
+
+		/* clear BYPASS (Enable PLL Mode) */
+		reg_clrbits(pll_regs[data->pll].reg0, 0x00800000);
+		pll_delay(14000);	/* Wait for a minimum of 7 us*/
+	}
+
+	pll_delay(140000);
+}
+
+void init_plls(int num_pll, struct pll_init_data *config)
+{
+	int i;
+
+	for (i = 0; i < num_pll; i++)
+		init_pll(&config[i]);
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c b/arch/arm/cpu/armv7/keystone/cmd_clock.c
new file mode 100644
index 0000000..a18e31b
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
@@ -0,0 +1,139 @@ 
+/*
+ * keystone2: commands for clocks
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/psc_defs.h>
+
+static u32 atoui(char *pstr)
+{
+	u32 res = 0;
+
+	for (; *pstr != 0; pstr++) {
+		if (*pstr < '0' || *pstr > '9')
+			break;
+
+		res = (res * 10) + (*pstr - '0');
+	}
+
+	return res;
+}
+
+struct pll_init_data cmd_pll_data = {
+	.pll			= MAIN_PLL,
+	.pll_m			= 16,
+	.pll_d			= 1,
+	.pll_od			= 2,
+};
+
+int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc != 5)
+		goto pll_cmd_usage;
+
+	if (strncmp(argv[1], "pa", 2) == 0)
+		cmd_pll_data.pll = PASS_PLL;
+	else if (strncmp(argv[1], "arm", 3) == 0)
+		cmd_pll_data.pll = TETRIS_PLL;
+	else if (strncmp(argv[1], "ddr3a", 5) == 0)
+		cmd_pll_data.pll = DDR3A_PLL;
+	else if (strncmp(argv[1], "ddr3b", 5) == 0)
+		cmd_pll_data.pll = DDR3B_PLL;
+	else
+		goto pll_cmd_usage;
+
+	cmd_pll_data.pll_m   = atoui(argv[2]);
+	cmd_pll_data.pll_d   = atoui(argv[3]);
+	cmd_pll_data.pll_od  = atoui(argv[4]);
+
+	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
+	       cmd_pll_data.pll, cmd_pll_data.pll_m,
+	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
+	init_pll(&cmd_pll_data);
+
+	return 0;
+
+pll_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	pllset,	5,	0,	do_pll_cmd,
+	"set pll multiplier and pre divider",
+	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
+);
+
+int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned int clk;
+	unsigned int freq;
+
+	if (argc != 2)
+		goto getclk_cmd_usage;
+
+	clk = atoui(argv[1]);
+
+	freq = clk_get_rate(clk);
+	printf("clock index [%d] - frequency %u\n", clk, freq);
+	return 0;
+
+getclk_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	getclk,	2,	0,	do_getclk_cmd,
+	"get clock rate",
+	"<clk index>\n"
+	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
+);
+
+int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int	psc_module;
+	int	res;
+
+	if (argc != 3)
+		goto psc_cmd_usage;
+
+	psc_module = atoui(argv[1]);
+	if (strcmp(argv[2], "en") == 0) {
+		res = psc_enable_module(psc_module);
+		printf("psc_enable_module(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+	if (strcmp(argv[2], "di") == 0) {
+		res = psc_disable_module(psc_module);
+		printf("psc_disable_module(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+	if (strcmp(argv[2], "domain") == 0) {
+		res = psc_disable_domain(psc_module);
+		printf("psc_disable_domain(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+psc_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	psc,	3,	0,	do_psc_cmd,
+	"<enable/disable psc module os disable domain>",
+	"<mod/domain index> <en|di|domain>\n"
+	"See the hardware.h for Power and Sleep Controller (PSC) Domains\n"
+);
+
diff --git a/arch/arm/cpu/armv7/keystone/cmd_mon.c b/arch/arm/cpu/armv7/keystone/cmd_mon.c
new file mode 100644
index 0000000..f9f58a3
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/cmd_mon.c
@@ -0,0 +1,131 @@ 
+/*
+ * K2HK: secure kernel command file
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+asm(".arch_extension sec\n\t");
+
+static int mon_install(u32 addr, u32 dpsc, u32 freq)
+{
+	int result;
+
+	__asm__ __volatile__ (
+		"stmfd r13!, {lr}\n"
+		"mov r0, %1\n"
+		"mov r1, %2\n"
+		"mov r2, %3\n"
+		"blx r0\n"
+		"ldmfd r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (addr), "r" (dpsc), "r" (freq)
+		: "cc", "r0", "r1", "r2", "memory");
+	return result;
+}
+
+static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
+{
+	u32 addr, dpsc_base = 0x1E80000, freq;
+	int     rcode = 0;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	freq = clk_get_rate(sys_clk0_6_clk);
+
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	rcode = mon_install(addr, dpsc_base, freq);
+	printf("## installed monitor, freq [%d], status %d\n",
+	       freq, rcode);
+
+	return 0;
+}
+
+U_BOOT_CMD(mon_install, 2, 0, do_mon_install,
+	   "Install boot kernel at 'addr'",
+	   ""
+);
+
+static void core_spin(void)
+{
+	while (1)
+		; /* forever */;
+}
+
+int mon_power_on(int core_id, void *ep)
+{
+	int result;
+
+	asm volatile (
+		"stmfd  r13!, {lr}\n"
+		"mov r1, %1\n"
+		"mov r2, %2\n"
+		"mov r0, #0\n"
+		"smc	#0\n"
+		"ldmfd  r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (core_id), "r" (ep)
+		: "cc", "r0", "r1", "r2", "memory");
+	return  result;
+}
+
+int mon_power_off(int core_id)
+{
+	int result;
+
+	asm volatile (
+		"stmfd  r13!, {lr}\n"
+		"mov r1, %1\n"
+		"mov r0, #1\n"
+		"smc	#1\n"
+		"ldmfd  r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (core_id)
+		: "cc", "r0", "r1", "memory");
+	return  result;
+}
+
+int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc,
+			char * const argv[])
+{
+	int     rcode = 0, core_id, on;
+	void (*fn)(void);
+
+	fn = core_spin;
+
+	if (argc < 3)
+		return CMD_RET_USAGE;
+
+	core_id = simple_strtoul(argv[1], NULL, 16);
+	on = simple_strtoul(argv[2], NULL, 16);
+
+	if (on)
+		rcode = mon_power_on(core_id, fn);
+	else
+		rcode = mon_power_off(core_id);
+
+	if (on) {
+		if (!rcode)
+			printf("core %d powered on successfully\n", core_id);
+		else
+			printf("core %d power on failure\n", core_id);
+	} else {
+		printf("core %d powered off successfully\n", core_id);
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(mon_power, 3, 0, do_mon_power,
+	   "Power On/Off secondary core",
+	   "mon_power <coreid> <oper>\n"
+	   "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n"
+	   ""
+);
diff --git a/arch/arm/cpu/armv7/keystone/config.mk b/arch/arm/cpu/armv7/keystone/config.mk
new file mode 100644
index 0000000..18385f4
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/config.mk
@@ -0,0 +1,14 @@ 
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
+
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
+		    $(call cc-option,-malignment-traps,))
diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
new file mode 100644
index 0000000..4875db7
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/ddr3.c
@@ -0,0 +1,69 @@ 
+/*
+ * Keystone2: DDR3 initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg)
+{
+	unsigned int tmp;
+
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET)
+		 & 0x00000001) != 0x00000001)
+		;
+
+	__raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET);
+
+	tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET);
+	tmp &= ~(phy_cfg->pgcr1_mask);
+	tmp |= phy_cfg->pgcr1_val;
+	__raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET);
+
+	__raw_writel(phy_cfg->ptr0,   base + KS2_DDRPHY_PTR0_OFFSET);
+	__raw_writel(phy_cfg->ptr1,   base + KS2_DDRPHY_PTR1_OFFSET);
+	__raw_writel(phy_cfg->ptr3,  base + KS2_DDRPHY_PTR3_OFFSET);
+	__raw_writel(phy_cfg->ptr4,  base + KS2_DDRPHY_PTR4_OFFSET);
+
+	tmp =  __raw_readl(base + KS2_DDRPHY_DCR_OFFSET);
+	tmp &= ~(phy_cfg->dcr_mask);
+	tmp |= phy_cfg->dcr_val;
+	__raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET);
+
+	__raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET);
+	__raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET);
+	__raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET);
+	__raw_writel(phy_cfg->mr0,   base + KS2_DDRPHY_MR0_OFFSET);
+	__raw_writel(phy_cfg->mr1,   base + KS2_DDRPHY_MR1_OFFSET);
+	__raw_writel(phy_cfg->mr2,   base + KS2_DDRPHY_MR2_OFFSET);
+	__raw_writel(phy_cfg->dtcr,  base + KS2_DDRPHY_DTCR_OFFSET);
+	__raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET);
+
+	__raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET);
+	__raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET);
+	__raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET);
+
+	__raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET);
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
+		;
+
+	__raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET);
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
+		;
+}
+
+void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg)
+{
+	__raw_writel(emif_cfg->sdcfg,  base + KS2_DDR3_SDCFG_OFFSET);
+	__raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET);
+	__raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET);
+	__raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET);
+	__raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET);
+	__raw_writel(emif_cfg->zqcfg,  base + KS2_DDR3_ZQCFG_OFFSET);
+	__raw_writel(emif_cfg->sdrfc,  base + KS2_DDR3_SDRFC_OFFSET);
+}
diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c
new file mode 100644
index 0000000..6d5512e
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/init.c
@@ -0,0 +1,49 @@ 
+/*
+ * Keystone2: Architecture initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+
+void chip_configuration_unlock(void)
+{
+	__raw_writel(KEYSTONE_KICK0_MAGIC, KEYSTONE_KICK0);
+	__raw_writel(KEYSTONE_KICK1_MAGIC, KEYSTONE_KICK1);
+}
+
+int arch_cpu_init(void)
+{
+	chip_configuration_unlock();
+	icache_enable();
+
+#ifdef CONFIG_SOC_K2HK
+	share_all_segments(8);
+	share_all_segments(9);
+	share_all_segments(10); /* QM PDSP */
+	share_all_segments(11); /* PCIE */
+#endif
+
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	volatile u32 *rstctrl = (volatile u32 *)(CLOCK_BASE + 0xe8);
+	u32 tmp;
+
+	tmp = *rstctrl & 0xffff0000;
+	*rstctrl = tmp | 0x5a69;
+
+	*rstctrl &= 0xfffe0000;
+
+	for (;;)
+		;
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/lowlevel_init.S b/arch/arm/cpu/armv7/keystone/lowlevel_init.S
new file mode 100644
index 0000000..ac98472
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/lowlevel_init.S
@@ -0,0 +1,13 @@ 
+/*
+ * Keystone2: Low-level pre-relocation initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+.globl lowlevel_init
+lowlevel_init:
+	/* nothing for now, maybe needed for more exotic boot modes */
+	mov	pc, lr
diff --git a/arch/arm/cpu/armv7/keystone/msmc.c b/arch/arm/cpu/armv7/keystone/msmc.c
new file mode 100644
index 0000000..8f2f324
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/msmc.c
@@ -0,0 +1,69 @@ 
+/*
+ * MSMC controller utilities
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+
+struct mpax {
+	u32	mpaxl;
+	u32	mpaxh;
+};
+
+struct msms_regs {
+	u32	pid;
+	u32	_res_04;
+	u32	smcerrar;
+	u32	smcerrxr;
+	u32	smedcc;
+	u32	smcea;
+	u32	smsecc;
+	u32	smpfar;
+	u32	smpfxr;
+	u32	smpfr;
+	u32	smpfcr;
+	u32	_res_2c;
+	u32	sbndc[8];
+	u32	sbndm;
+	u32	sbnde;
+	u32	_res_58;
+	u32	cfglck;
+	u32	cfgulck;
+	u32	cfglckstat;
+	u32	sms_mpax_lck;
+	u32	sms_mpax_ulck;
+	u32	sms_mpax_lckstat;
+	u32	ses_mpax_lck;
+	u32	ses_mpax_ulck;
+	u32	ses_mpax_lckstat;
+	u32	smestat;
+	u32	smirstat;
+	u32	smirc;
+	u32	smiestat;
+	u32	smiec;
+	u32	_res_94_c0[12];
+	u32	smncerrar;
+	u32	smncerrxr;
+	u32	smncea;
+	u32	_res_d0_1fc[76];
+	struct mpax sms[16][8];
+	struct mpax ses[16][8];
+};
+
+
+void share_all_segments(int priv_id)
+{
+	struct msms_regs *msmc = (struct msms_regs *)K2HK_MSMC_CTRL_BASE;
+	int j;
+
+	for (j = 0; j < 8; j++) {
+		msmc->sms[priv_id][j].mpaxh &= 0xffffff7ful;
+		msmc->ses[priv_id][j].mpaxh &= 0xffffff7ful;
+	}
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/psc.c b/arch/arm/cpu/armv7/keystone/psc.c
new file mode 100644
index 0000000..9697da6
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/psc.c
@@ -0,0 +1,240 @@ 
+/*
+ * Keystone: PSC configuration module
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+/*****************************************************************************
+ * FILE PURPOSE: Driver for the PSC module
+ *****************************************************************************
+ * FILE NAME: psc.c
+ *
+ * DESCRIPTION: The boot loader PSC driver
+ *
+ *****************************************************************************/
+#include <common.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/psc_defs.h>
+
+#define DEVICE_REG32_R(addr)			__raw_readl((u32 *)(addr))
+#define DEVICE_REG32_W(addr, val)		__raw_writel(val, (u32 *)(addr))
+
+#ifdef CONFIG_SOC_K2HK
+#define DEVICE_PSC_BASE				K2HK_PSC_BASE
+#endif
+
+int psc_delay(void)
+{
+	udelay(10);
+	return 10;
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Wait for end of transitional state
+ ******************************************************************************
+ * DESCRIPTION: Polls pstat for the selected domain and waits for transitions
+ *              to be complete.
+ *
+ *              Since this is boot loader code it is *ASSUMED* that interrupts
+ *              are disabled and no other core is mucking around with the psc
+ *              at the same time.
+ *
+ *              Returns 0 when the domain is free. Returns -1 if a timeout
+ *              occurred waiting for the completion.
+ *****************************************************************************/
+int psc_wait(u32 domain_num)
+{
+	u32 retry;
+	u32 ptstat;
+
+	/* Do nothing if the power domain is in transition. This should never
+	 * happen since the boot code is the only software accesses psc.
+	 * It's still remotely possible that the hardware state machines
+	 * initiate transitions.
+	 * Don't trap if the domain (or a module in this domain) is
+	 * stuck in transition.  */
+	retry = 0;
+
+	do {
+		ptstat = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PSTAT);
+		ptstat = ptstat & (1 << domain_num);
+	} while ((ptstat != 0) && ((retry += psc_delay()) <
+		 PSC_PTSTAT_TIMEOUT_LIMIT));
+
+	if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
+		return -1;
+
+	return 0;
+}
+
+u32 psc_get_domain_num(u32 mod_num)
+{
+	u32 domain_num;
+
+	/* Get the power domain associated with the module number */
+	domain_num = DEVICE_REG32_R(DEVICE_PSC_BASE +
+				    PSC_REG_MDCFG(mod_num));
+	domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
+
+	return domain_num;
+}
+
+/*****************************************************************************
+ * FUNCTION PURPOSE: Power up/down a module
+ *****************************************************************************
+ * DESCRIPTION: Powers up/down the requested module and the associated power
+ *		domain if required. No action is taken it the module is
+ *		already powered up/down.
+ *
+ *              This only controls modules. The domain in which the module
+ *              resides will be left in the power on state. Multiple modules
+ *              can exist in a power domain, so powering down the domain based
+ *              on a single module is not done.
+ *
+ *              Returns 0 on success, -1 if the module can't be powered up, or
+ *              if there is a timeout waiting for the transition.
+ *****************************************************************************/
+int psc_set_state(u32 mod_num, u32 state)
+{
+	u32 domain_num;
+	u32 pdctl;
+	u32 mdctl;
+	u32 ptcmd;
+	u32 reset_iso;
+	u32 v;
+
+	/* Get the power domain associated with the module number, and reset
+	 * isolation functionality */
+	v = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCFG(mod_num));
+	domain_num = PSC_REG_MDCFG_GET_PD(v);
+	reset_iso  = PSC_REG_MDCFG_GET_RESET_ISO(v);
+
+	/* Wait for the status of the domain/module to be non-transitional */
+	if (psc_wait(domain_num) != 0)
+		return -1;
+
+	/* Perform configuration even if the current status matches the
+	 * existing state */
+
+	/* Set the next state of the power domain to on. It's OK if the domain
+	 * is always on. This code will not ever power down a domain, so no
+	 * change is made if the new state is power down. */
+	if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
+		pdctl = DEVICE_REG32_R(DEVICE_PSC_BASE +
+				       PSC_REG_PDCTL(domain_num));
+		pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
+					       PSC_REG_VAL_PDCTL_NEXT_ON);
+		DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num),
+			       pdctl);
+	}
+
+	/* Set the next state for the module to enabled/disabled */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
+	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	/* Trigger the enable */
+	ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD);
+	ptcmd |= (u32)(1<<domain_num);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd);
+
+	/* Wait on the complete */
+	return psc_wait(domain_num);
+}
+
+/*****************************************************************************
+ * FUNCTION PURPOSE: Power up a module
+ *****************************************************************************
+ * DESCRIPTION: Powers up the requested module and the associated power domain
+ *              if required. No action is taken it the module is already
+ *              powered up.
+ *
+ *              Returns 0 on success, -1 if the module can't be powered up, or
+ *              if there is a timeout waiting for the transition.
+ *****************************************************************************/
+int psc_enable_module(u32 mod_num)
+{
+	u32 mdctl;
+
+	/* Set the bit to apply reset */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
+		return 0;
+
+	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Power down a module
+ ******************************************************************************
+ * DESCRIPTION: Powers down the requested module.
+ *
+ *              Returns 0 on success, -1 on failure or timeout.
+ ******************************************************************************/
+int psc_disable_module(u32 mod_num)
+{
+	u32 mdctl;
+
+	/* Set the bit to apply reset */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	if ((mdctl & 0x3f) == 0)
+		return 0;
+	mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Set the reset isolation bit in mdctl
+ ******************************************************************************
+ * DESCRIPTION: The reset isolation enable bit is set. The state of the module
+ *              is not changed. Returns 0 if the module config showed that
+ *              reset isolation is supported. Returns 1 otherwise. This is not
+ *              an error, but setting the bit in mdctl has no effect.
+ ******************************************************************************/
+int psc_set_reset_iso(u32 mod_num)
+{
+	u32 v;
+	u32 mdctl;
+
+	/* Set the reset isolation bit */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	v = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCFG(mod_num));
+	if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
+		return 0;
+
+	return 1;
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Disable a power domain
+ ******************************************************************************
+ * DESCRIPTION: The power domain is disabled
+ ******************************************************************************/
+int psc_disable_domain(u32 domain_num)
+{
+	u32 pdctl;
+	u32 ptcmd;
+
+	pdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num));
+	pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
+	pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num), pdctl);
+
+	ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD);
+	ptcmd |= (u32)(1 << domain_num);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd);
+
+	return psc_wait(domain_num);
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/spl.c b/arch/arm/cpu/armv7/keystone/spl.c
new file mode 100644
index 0000000..e07b64d
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/spl.c
@@ -0,0 +1,45 @@ 
+/*
+ * common spl init code
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <config.h>
+#include <ns16550.h>
+#include <malloc.h>
+#include <spl.h>
+#include <spi_flash.h>
+
+#include <asm/u-boot.h>
+#include <asm/utils.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct pll_init_data spl_pll_config[] = {
+	CORE_PLL_799,
+	TETRIS_PLL_500,
+};
+
+void spl_init_keystone_plls(void)
+{
+	init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
+}
+
+void spl_board_init(void)
+{
+	spl_init_keystone_plls();
+	preloader_console_init();
+}
+
+u32 spl_boot_device(void)
+{
+#if defined(CONFIG_SPL_SPI_LOAD)
+	return BOOT_DEVICE_SPI;
+#else
+	puts("Unknown boot device\n");
+	hang();
+#endif
+}
diff --git a/arch/arm/include/asm/arch-keystone/clock-k2hk.h b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
new file mode 100644
index 0000000..6721939
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
@@ -0,0 +1,109 @@ 
+/*
+ * K2HK: Clock management APIs
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_K2HK_H
+#define __ASM_ARCH_CLOCK_K2HK_H
+
+#include <asm/arch/hardware.h>
+
+#ifndef __ASSEMBLY__
+
+enum ext_clk_e {
+	sys_clk,
+	alt_core_clk,
+	pa_clk,
+	tetris_clk,
+	ddr3a_clk,
+	ddr3b_clk,
+	mcm_clk,
+	pcie_clk,
+	sgmii_srio_clk,
+	xgmii_clk,
+	usb_clk,
+	rp1_clk,
+	ext_clk_count /* number of external clocks */
+};
+
+extern unsigned int external_clk[ext_clk_count];
+
+enum clk_e {
+	core_pll_clk,
+	pass_pll_clk,
+	tetris_pll_clk,
+	ddr3a_pll_clk,
+	ddr3b_pll_clk,
+	sys_clk0_clk,
+	sys_clk0_1_clk,
+	sys_clk0_2_clk,
+	sys_clk0_3_clk,
+	sys_clk0_4_clk,
+	sys_clk0_6_clk,
+	sys_clk0_8_clk,
+	sys_clk0_12_clk,
+	sys_clk0_24_clk,
+	sys_clk1_clk,
+	sys_clk1_3_clk,
+	sys_clk1_4_clk,
+	sys_clk1_6_clk,
+	sys_clk1_12_clk,
+	sys_clk2_clk,
+	sys_clk3_clk
+};
+
+#define K2HK_CLK1_6	sys_clk0_6_clk
+
+/* PLL identifiers */
+enum pll_type_e {
+	CORE_PLL,
+	PASS_PLL,
+	TETRIS_PLL,
+	DDR3A_PLL,
+	DDR3B_PLL,
+};
+#define MAIN_PLL CORE_PLL
+
+/* PLL configuration data */
+struct pll_init_data {
+	int pll;
+	int pll_m;		/* PLL Multiplier */
+	int pll_d;		/* PLL divider */
+	int pll_od;		/* PLL output divider    */
+};
+
+#define CORE_PLL_799	{CORE_PLL,	13,	1,	2}
+#define CORE_PLL_983	{CORE_PLL,	16,	1,	2}
+#define CORE_PLL_1167	{CORE_PLL,	19,	1,	2}
+#define CORE_PLL_1228	{CORE_PLL,	20,	1,	2}
+#define PASS_PLL_1228	{PASS_PLL,	20,	1,	2}
+#define PASS_PLL_983	{PASS_PLL,	16,	1,	2}
+#define PASS_PLL_1050	{PASS_PLL,	205,    12,	2}
+#define TETRIS_PLL_500  {TETRIS_PLL,	8,	1,	2}
+#define TETRIS_PLL_750  {TETRIS_PLL,	12,	1,	2}
+#define TETRIS_PLL_687  {TETRIS_PLL,	11,	1,	2}
+#define TETRIS_PLL_625  {TETRIS_PLL,	10,	1,	2}
+#define TETRIS_PLL_812  {TETRIS_PLL,	13,	1,	2}
+#define TETRIS_PLL_875  {TETRIS_PLL,	14,	1,	2}
+#define TETRIS_PLL_1188 {TETRIS_PLL,	19,	2,	1}
+#define TETRIS_PLL_1200 {TETRIS_PLL,	48,	5,	1}
+#define TETRIS_PLL_1375 {TETRIS_PLL,	22,	2,	1}
+#define TETRIS_PLL_1400 {TETRIS_PLL,	56,	5,	1}
+#define DDR3_PLL_200(x)	{DDR3##x##_PLL,	4,	1,	2}
+#define DDR3_PLL_400(x)	{DDR3##x##_PLL,	16,	1,	4}
+#define DDR3_PLL_800(x)	{DDR3##x##_PLL,	16,	1,	2}
+#define DDR3_PLL_333(x)	{DDR3##x##_PLL,	20,	1,	6}
+
+void init_plls(int num_pll, struct pll_init_data *config);
+void init_pll(const struct pll_init_data *data);
+unsigned long clk_get_rate(unsigned int clk);
+unsigned long clk_round_rate(unsigned int clk, unsigned long hz);
+int clk_set_rate(unsigned int clk, unsigned long hz);
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock.h b/arch/arm/include/asm/arch-keystone/clock.h
new file mode 100644
index 0000000..324501b
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock.h
@@ -0,0 +1,17 @@ 
+/*
+ * keystone2: common clock header file
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H
+
+#ifdef CONFIG_SOC_K2HK
+#include <asm/arch/clock-k2hk.h>
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock_defs.h b/arch/arm/include/asm/arch-keystone/clock_defs.h
new file mode 100644
index 0000000..00e3dfb
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock_defs.h
@@ -0,0 +1,97 @@ 
+/*
+ * keystone2: common pll clock definitions
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _CLOCK_DEFS_H_
+#define _CLOCK_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+#define BIT(x)			(1 << (x))
+
+/* PLL Control Registers */
+struct pllctl_regs {
+	u32	ctl;		/* 00 */
+	u32	ocsel;		/* 04 */
+	u32	secctl;		/* 08 */
+	u32	__pad0;
+	u32	mult;		/* 10 */
+	u32	prediv;		/* 14 */
+	u32	div1;		/* 18 */
+	u32	div2;		/* 1c */
+	u32	div3;		/* 20 */
+	u32	oscdiv1;	/* 24 */
+	u32	__pad1;		/* 28 */
+	u32	bpdiv;		/* 2c */
+	u32	wakeup;		/* 30 */
+	u32	__pad2;
+	u32	cmd;		/* 38 */
+	u32	stat;		/* 3c */
+	u32	alnctl;		/* 40 */
+	u32	dchange;	/* 44 */
+	u32	cken;		/* 48 */
+	u32	ckstat;		/* 4c */
+	u32	systat;		/* 50 */
+	u32	ckctl;		/* 54 */
+	u32	__pad3[2];
+	u32	div4;		/* 60 */
+	u32	div5;		/* 64 */
+	u32	div6;		/* 68 */
+	u32	div7;		/* 6c */
+	u32	div8;		/* 70 */
+	u32	div9;		/* 74 */
+	u32	div10;		/* 78 */
+	u32	div11;		/* 7c */
+	u32	div12;		/* 80 */
+};
+
+static struct pllctl_regs *pllctl_regs[] = {
+	(struct pllctl_regs *)(CLOCK_BASE + 0x100)
+};
+
+#define pllctl_reg(pll, reg)		(&(pllctl_regs[pll]->reg))
+#define pllctl_reg_read(pll, reg)	__raw_readl(pllctl_reg(pll, reg))
+#define pllctl_reg_write(pll, reg, val)	__raw_writel(val, pllctl_reg(pll, reg))
+
+#define pllctl_reg_rmw(pll, reg, mask, val)			\
+	pllctl_reg_write(pll, reg,				\
+		(pllctl_reg_read(pll, reg) & ~(mask)) | val)
+
+#define pllctl_reg_setbits(pll, reg, mask)			\
+	pllctl_reg_rmw(pll, reg, 0, mask)
+
+#define pllctl_reg_clrbits(pll, reg, mask)			\
+	pllctl_reg_rmw(pll, reg, mask, 0)
+
+#define reg_rmw(reg, mask, val) \
+	__raw_writel((__raw_readl((reg)) & ~(mask)) | ((val) & (mask)) , \
+		     (reg));
+
+#define reg_setbits(reg, bits)	\
+	__raw_writel((__raw_readl(reg) | (bits)) , (reg));
+
+#define reg_clrbits(reg, bits)	\
+	__raw_writel((__raw_readl(reg) & ~(bits)) , (reg));
+
+#define pll0div_read(N) ((pllctl_reg_read(CORE_PLL, div##N) & 0xff) + 1)
+
+/* PLLCTL Bits */
+#define PLLCTL_BYPASS		BIT(23)
+#define PLLCTL_CLKMODE		BIT(8)
+#define PLLCTL_PLLSELB		BIT(7)
+#define PLLCTL_PLLENSRC		BIT(5)
+#define PLLCTL_PLLDIS		BIT(4)
+#define PLLCTL_PLLRST		BIT(3)
+#define PLLCTL_PLLPWRDN		BIT(1)
+#define PLLCTL_PLLEN		BIT(0)
+
+#define MAIN_ENSAT_OFFSET	6
+
+#define PLLDIV_ENABLE		BIT(15)
+
+
+#endif  /* _CLOCK_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-keystone/emif_defs.h b/arch/arm/include/asm/arch-keystone/emif_defs.h
new file mode 100644
index 0000000..fa93321
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/emif_defs.h
@@ -0,0 +1,75 @@ 
+/*
+ * emif definitions to re-use davinci emif driver on Keystone2
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _EMIF_DEFS_H_
+#define _EMIF_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+struct davinci_emif_regs {
+	u_int32_t	ercsr;
+	u_int32_t	awccr;
+	u_int32_t	sdbcr;
+	u_int32_t	sdrcr;
+	u_int32_t	ab1cr;
+	u_int32_t	ab2cr;
+	u_int32_t	ab3cr;
+	u_int32_t	ab4cr;
+	u_int32_t	sdtimr;
+	u_int32_t	ddrsr;
+	u_int32_t	ddrphycr;
+	u_int32_t	ddrphysr;
+	u_int32_t	totar;
+	u_int32_t	totactr;
+	u_int32_t	ddrphyid_rev;
+	u_int32_t	sdsretr;
+	u_int32_t	eirr;
+	u_int32_t	eimr;
+	u_int32_t	eimsr;
+	u_int32_t	eimcr;
+	u_int32_t	ioctrlr;
+	u_int32_t	iostatr;
+	u_int8_t	rsvd0[8];
+	u_int32_t	nandfcr;
+	u_int32_t	nandfsr;
+	u_int8_t	rsvd1[8];
+	u_int32_t	nandfecc[4];
+	u_int8_t	rsvd2[60];
+	u_int32_t	nand4biteccload;
+	u_int32_t	nand4bitecc[4];
+	u_int32_t	nanderradd1;
+	u_int32_t	nanderradd2;
+	u_int32_t	nanderrval1;
+	u_int32_t	nanderrval2;
+};
+
+#define davinci_emif_regs \
+	((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE)
+
+#define DAVINCI_NANDFCR_NAND_ENABLE(n)			(1 << ((n) - 2))
+#define DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK		(3 << 4)
+#define DAVINCI_NANDFCR_4BIT_ECC_SEL(n)			(((n) - 2) << 4)
+#define DAVINCI_NANDFCR_1BIT_ECC_START(n)		(1 << (8 + ((n) - 2)))
+#define DAVINCI_NANDFCR_4BIT_ECC_START			(1 << 12)
+#define DAVINCI_NANDFCR_4BIT_CALC_START			(1 << 13)
+
+/* Chip Select setup */
+#define DAVINCI_ABCR_STROBE_SELECT			(1 << 31)
+#define DAVINCI_ABCR_EXT_WAIT				(1 << 30)
+#define DAVINCI_ABCR_WSETUP(n)				((n) << 26)
+#define DAVINCI_ABCR_WSTROBE(n)				((n) << 20)
+#define DAVINCI_ABCR_WHOLD(n)				((n) << 17)
+#define DAVINCI_ABCR_RSETUP(n)				((n) << 13)
+#define DAVINCI_ABCR_RSTROBE(n)				((n) << 7)
+#define DAVINCI_ABCR_RHOLD(n)				((n) << 4)
+#define DAVINCI_ABCR_TA(n)				((n) << 2)
+#define DAVINCI_ABCR_ASIZE_16BIT			1
+#define DAVINCI_ABCR_ASIZE_8BIT				0
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
new file mode 100644
index 0000000..929dc90
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
@@ -0,0 +1,143 @@ 
+/*
+ * K2HK: SoC definitions
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __ASM_ARCH_HARDWARE_K2HK_H
+#define __ASM_ARCH_HARDWARE_K2HK_H
+
+#define K2HK_ASYNC_EMIF_CNTRL_BASE	0x21000a00
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE	K2HK_ASYNC_EMIF_CNTRL_BASE
+#define K2HK_ASYNC_EMIF_DATA_CE0_BASE	0x30000000
+#define K2HK_ASYNC_EMIF_DATA_CE1_BASE	0x34000000
+#define K2HK_ASYNC_EMIF_DATA_CE2_BASE	0x38000000
+#define K2HK_ASYNC_EMIF_DATA_CE3_BASE	0x3c000000
+
+#define K2HK_PLL_CNTRL_BASE		0x02310000
+#define CLOCK_BASE			K2HK_PLL_CNTRL_BASE
+#define K2HK_PSC_BASE			0x02350000
+#define KS2_DEVICE_STATE_CTRL_BASE	0x02620000
+#define JTAG_ID_REG			(KS2_DEVICE_STATE_CTRL_BASE + 0x18)
+#define K2HK_DEVSTAT			(KS2_DEVICE_STATE_CTRL_BASE + 0x20)
+
+#define K2HK_SPI0_BASE			0x21000400
+#define K2HK_SPI1_BASE			0x21000600
+#define K2HK_SPI2_BASE			0x21000800
+#define K2HK_SPI_BASE			K2HK_SPI0_BASE
+
+/* Chip configuration unlock codes and registers */
+#define KEYSTONE_KICK0			(KS2_DEVICE_STATE_CTRL_BASE+0x38)
+#define KEYSTONE_KICK1			(KS2_DEVICE_STATE_CTRL_BASE+0x3c)
+#define KEYSTONE_KICK0_MAGIC		0x83e70b13
+#define KEYSTONE_KICK1_MAGIC		0x95a4f1e0
+
+/* PA SS Registers */
+#define KS2_PASS_BASE			0x02000000
+
+/* PLL control registers */
+#define K2HK_MAINPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x350)
+#define K2HK_MAINPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x354)
+#define K2HK_PASSPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x358)
+#define K2HK_PASSPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x35C)
+#define K2HK_DDR3APLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x360)
+#define K2HK_DDR3APLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x364)
+#define K2HK_DDR3BPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x368)
+#define K2HK_DDR3BPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x36C)
+#define K2HK_ARMPLLCTL0			(KS2_DEVICE_STATE_CTRL_BASE+0x370)
+#define K2HK_ARMPLLCTL1			(KS2_DEVICE_STATE_CTRL_BASE+0x374)
+
+/******************************************************************************/
+/* Power and Sleep Controller (PSC) Domains */
+#define K2HK_LPSC_MOD			0
+#define K2HK_LPSC_DUMMY1		1
+#define K2HK_LPSC_USB			2
+#define K2HK_LPSC_EMIF25_SPI		3
+#define K2HK_LPSC_TSIP			4
+#define K2HK_LPSC_DEBUGSS_TRC		5
+#define K2HK_LPSC_TETB_TRC		6
+#define K2HK_LPSC_PKTPROC		7
+#define KS2_LPSC_PA			K2HK_LPSC_PKTPROC
+#define K2HK_LPSC_SGMII			8
+#define KS2_LPSC_CPGMAC			K2HK_LPSC_SGMII
+#define K2HK_LPSC_CRYPTO		9
+#define K2HK_LPSC_PCIE			10
+#define K2HK_LPSC_SRIO			11
+#define K2HK_LPSC_VUSR0			12
+#define K2HK_LPSC_CHIP_SRSS		13
+#define K2HK_LPSC_MSMC			14
+#define K2HK_LPSC_GEM_0			15
+#define K2HK_LPSC_GEM_1			16
+#define K2HK_LPSC_GEM_2			17
+#define K2HK_LPSC_GEM_3			18
+#define K2HK_LPSC_GEM_4			19
+#define K2HK_LPSC_GEM_5			20
+#define K2HK_LPSC_GEM_6			21
+#define K2HK_LPSC_GEM_7			22
+#define K2HK_LPSC_EMIF4F_DDR3A		23
+#define K2HK_LPSC_EMIF4F_DDR3B		24
+#define K2HK_LPSC_TAC			25
+#define K2HK_LPSC_RAC			26
+#define K2HK_LPSC_RAC_1			27
+#define K2HK_LPSC_FFTC_A		28
+#define K2HK_LPSC_FFTC_B		29
+#define K2HK_LPSC_FFTC_C		30
+#define K2HK_LPSC_FFTC_D		31
+#define K2HK_LPSC_FFTC_E		32
+#define K2HK_LPSC_FFTC_F		33
+#define K2HK_LPSC_AI2			34
+#define K2HK_LPSC_TCP3D_0		35
+#define K2HK_LPSC_TCP3D_1		36
+#define K2HK_LPSC_TCP3D_2		37
+#define K2HK_LPSC_TCP3D_3		38
+#define K2HK_LPSC_VCP2X4_A		39
+#define K2HK_LPSC_CP2X4_B		40
+#define K2HK_LPSC_VCP2X4_C		41
+#define K2HK_LPSC_VCP2X4_D		42
+#define K2HK_LPSC_VCP2X4_E		43
+#define K2HK_LPSC_VCP2X4_F		44
+#define K2HK_LPSC_VCP2X4_G		45
+#define K2HK_LPSC_VCP2X4_H		46
+#define K2HK_LPSC_BCP			47
+#define K2HK_LPSC_DXB			48
+#define K2HK_LPSC_VUSR1			49
+#define K2HK_LPSC_XGE			50
+#define K2HK_LPSC_ARM_SREFLEX		51
+#define K2HK_LPSC_TETRIS		52
+
+
+#define K2HK_UART0_BASE			0x02530c00
+
+/* DDR3A definitions */
+#define K2HK_DDR3A_EMIF_CTRL_BASE	0x21010000
+#define K2HK_DDR3A_EMIF_DATA_BASE	0x80000000
+#define K2HK_DDR3A_DDRPHYC		0x02329000
+/* DDR3B definitions */
+#define K2HK_DDR3B_EMIF_CTRL_BASE	0x21020000
+#define K2HK_DDR3B_EMIF_DATA_BASE	0x60000000
+#define K2HK_DDR3B_DDRPHYC		0x02328000
+
+/* Queue manager */
+#define DEVICE_QM_MANAGER_BASE		0x02a02000
+#define DEVICE_QM_DESC_SETUP_BASE	0x02a03000
+#define DEVICE_QM_MANAGER_QUEUES_BASE	0x02a80000
+#define DEVICE_QM_MANAGER_Q_PROXY_BASE	0x02ac0000
+#define DEVICE_QM_QUEUE_STATUS_BASE	0x02a40000
+#define DEVICE_QM_NUM_LINKRAMS		2
+#define DEVICE_QM_NUM_MEMREGIONS	20
+
+#define DEVICE_PA_CDMA_GLOBAL_CFG_BASE	0x02004000
+#define DEVICE_PA_CDMA_TX_CHAN_CFG_BASE	0x02004400
+#define DEVICE_PA_CDMA_RX_CHAN_CFG_BASE	0x02004800
+#define DEVICE_PA_CDMA_RX_FLOW_CFG_BASE	0x02005000
+
+#define DEVICE_PA_CDMA_RX_NUM_CHANNELS	24
+#define DEVICE_PA_CDMA_RX_NUM_FLOWS	32
+#define DEVICE_PA_CDMA_TX_NUM_CHANNELS	9
+
+/* MSMC control */
+#define K2HK_MSMC_CTRL_BASE		0x0bc00000
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/hardware.h b/arch/arm/include/asm/arch-keystone/hardware.h
new file mode 100644
index 0000000..8d3f97d
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware.h
@@ -0,0 +1,174 @@ 
+/*
+ * Keystone2: Common SoC definitions, structures etc.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <config.h>
+
+#ifndef __ASSEMBLY__
+
+#include <asm/sizes.h>
+#include <asm/io.h>
+
+#define	REG(addr)	(*(volatile unsigned int *)(addr))
+#define REG_P(addr)	((volatile unsigned int *)(addr))
+
+typedef volatile unsigned int	dv_reg;
+typedef volatile unsigned int	*dv_reg_p;
+
+#define ASYNC_EMIF_NUM_CS		4
+#define ASYNC_EMIF_MODE_NOR		0
+#define ASYNC_EMIF_MODE_NAND		1
+#define ASYNC_EMIF_MODE_ONENAND		2
+#define ASYNC_EMIF_PRESERVE		-1
+
+struct async_emif_config {
+	unsigned mode;
+	unsigned select_strobe;
+	unsigned extend_wait;
+	unsigned wr_setup;
+	unsigned wr_strobe;
+	unsigned wr_hold;
+	unsigned rd_setup;
+	unsigned rd_strobe;
+	unsigned rd_hold;
+	unsigned turn_around;
+	enum {
+		ASYNC_EMIF_8	= 0,
+		ASYNC_EMIF_16	= 1,
+		ASYNC_EMIF_32	= 2,
+	} width;
+};
+
+void init_async_emif(int num_cs, struct async_emif_config *config);
+
+struct ddr3_phy_config {
+	unsigned int pllcr;
+	unsigned int pgcr1_mask;
+	unsigned int pgcr1_val;
+	unsigned int ptr0;
+	unsigned int ptr1;
+	unsigned int ptr2;
+	unsigned int ptr3;
+	unsigned int ptr4;
+	unsigned int dcr_mask;
+	unsigned int dcr_val;
+	unsigned int dtpr0;
+	unsigned int dtpr1;
+	unsigned int dtpr2;
+	unsigned int mr0;
+	unsigned int mr1;
+	unsigned int mr2;
+	unsigned int dtcr;
+	unsigned int pgcr2;
+	unsigned int zq0cr1;
+	unsigned int zq1cr1;
+	unsigned int zq2cr1;
+	unsigned int pir_v1;
+	unsigned int pir_v2;
+};
+
+struct ddr3_emif_config {
+	unsigned int sdcfg;
+	unsigned int sdtim1;
+	unsigned int sdtim2;
+	unsigned int sdtim3;
+	unsigned int sdtim4;
+	unsigned int zqcfg;
+	unsigned int sdrfc;
+};
+
+#endif
+
+#define		BIT(x)	(1 << (x))
+
+#define KS2_DDRPHY_PIR_OFFSET		0x04
+#define KS2_DDRPHY_PGCR0_OFFSET		0x08
+#define KS2_DDRPHY_PGCR1_OFFSET		0x0C
+#define KS2_DDRPHY_PGSR0_OFFSET		0x10
+#define KS2_DDRPHY_PGSR1_OFFSET		0x14
+#define KS2_DDRPHY_PLLCR_OFFSET		0x18
+#define KS2_DDRPHY_PTR0_OFFSET		0x1C
+#define KS2_DDRPHY_PTR1_OFFSET		0x20
+#define KS2_DDRPHY_PTR2_OFFSET		0x24
+#define KS2_DDRPHY_PTR3_OFFSET		0x28
+#define KS2_DDRPHY_PTR4_OFFSET		0x2C
+#define KS2_DDRPHY_DCR_OFFSET		0x44
+
+#define KS2_DDRPHY_DTPR0_OFFSET		0x48
+#define KS2_DDRPHY_DTPR1_OFFSET		0x4C
+#define KS2_DDRPHY_DTPR2_OFFSET		0x50
+
+#define KS2_DDRPHY_MR0_OFFSET		0x54
+#define KS2_DDRPHY_MR1_OFFSET		0x58
+#define KS2_DDRPHY_MR2_OFFSET		0x5C
+#define KS2_DDRPHY_DTCR_OFFSET		0x68
+#define KS2_DDRPHY_PGCR2_OFFSET		0x8C
+
+#define KS2_DDRPHY_ZQ0CR1_OFFSET	0x184
+#define KS2_DDRPHY_ZQ1CR1_OFFSET	0x194
+#define KS2_DDRPHY_ZQ2CR1_OFFSET	0x1A4
+#define KS2_DDRPHY_ZQ3CR1_OFFSET	0x1B4
+
+#define KS2_DDRPHY_DATX8_8_OFFSET	0x3C0
+
+#define IODDRM_MASK			0x00000180
+#define ZCKSEL_MASK			0x01800000
+#define CL_MASK				0x00000072
+#define WR_MASK				0x00000E00
+#define BL_MASK				0x00000003
+#define RRMODE_MASK			0x00040000
+#define UDIMM_MASK			0x20000000
+#define BYTEMASK_MASK			0x0003FC00
+#define MPRDQ_MASK			0x00000080
+#define PDQ_MASK			0x00000070
+#define NOSRA_MASK			0x08000000
+#define ECC_MASK			0x00000001
+
+#define KS2_DDR3_MIDR_OFFSET		0x00
+#define KS2_DDR3_STATUS_OFFSET		0x04
+#define KS2_DDR3_SDCFG_OFFSET		0x08
+#define KS2_DDR3_SDRFC_OFFSET		0x10
+#define KS2_DDR3_SDTIM1_OFFSET		0x18
+#define KS2_DDR3_SDTIM2_OFFSET		0x1C
+#define KS2_DDR3_SDTIM3_OFFSET		0x20
+#define KS2_DDR3_SDTIM4_OFFSET		0x28
+#define KS2_DDR3_PMCTL_OFFSET		0x38
+#define KS2_DDR3_ZQCFG_OFFSET		0xC8
+
+#ifdef CONFIG_SOC_K2HK
+#include <asm/arch/hardware-k2hk.h>
+#endif
+
+#ifndef __ASSEMBLY__
+static inline int cpu_is_k2hk(void)
+{
+	unsigned int jtag_id	= __raw_readl(JTAG_ID_REG);
+	unsigned int part_no	= (jtag_id >> 12) & 0xffff;
+
+	return ((part_no == 0xb981) ? 1 : 0);
+}
+
+static inline int cpu_revision(void)
+{
+	unsigned int jtag_id	= __raw_readl(JTAG_ID_REG);
+	unsigned int rev	= (jtag_id >> 28) & 0xf;
+
+	return rev;
+}
+
+void share_all_segments(int priv_id);
+int cpu_to_bus(u32 *ptr, u32 length);
+void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg);
+void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg);
+void init_ddr3(void);
+
+#endif
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/i2c_defs.h b/arch/arm/include/asm/arch-keystone/i2c_defs.h
new file mode 100644
index 0000000..bf28626
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/i2c_defs.h
@@ -0,0 +1,86 @@ 
+/*
+ * keystone: i2c driver definitions
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _KEYSTONE_I2C_H_
+#define _KEYSTONE_I2C_H_
+
+#define I2C_WRITE		0
+#define I2C_READ		1
+
+#define I2C0_BASE		0x02530000
+#define I2C1_BASE		0x02530400
+#define I2C2_BASE		0x02530800
+#define I2C_BASE		I2C0_BASE
+
+struct i2c_regs {
+	u32	i2c_oa;
+	u32	i2c_ie;
+	u32	i2c_stat;
+	u32	i2c_scll;
+	u32	i2c_sclh;
+	u32	i2c_cnt;
+	u32	i2c_drr;
+	u32	i2c_sa;
+	u32	i2c_dxr;
+	u32	i2c_con;
+	u32	i2c_iv;
+	u32	res_2c;
+	u32	i2c_psc;
+};
+
+/* I2C masks */
+
+/* I2C Interrupt Enable Register (I2C_IE): */
+#define I2C_IE_SCD_IE	(1 << 5)	/* Stop condition */
+#define I2C_IE_XRDY_IE	(1 << 4)	/* Transmit data ready */
+#define I2C_IE_RRDY_IE	(1 << 3)	/* Receive data ready */
+#define I2C_IE_ARDY_IE	(1 << 2)	/* Register access ready */
+#define I2C_IE_NACK_IE	(1 << 1)	/* No acknowledgment */
+#define I2C_IE_AL_IE	(1 << 0)	/* Arbitration lost */
+
+/* I2C Status Register (I2C_STAT): */
+
+#define I2C_STAT_BB	(1 << 12)	/* Bus busy */
+#define I2C_STAT_ROVR	(1 << 11)	/* Receive overrun */
+#define I2C_STAT_XUDF	(1 << 10)	/* Transmit underflow */
+#define I2C_STAT_AAS	(1 << 9)	/* Address as slave */
+#define I2C_STAT_SCD	(1 << 5)	/* Stop condition detect */
+#define I2C_STAT_XRDY	(1 << 4)	/* Transmit data ready */
+#define I2C_STAT_RRDY	(1 << 3)	/* Receive data ready */
+#define I2C_STAT_ARDY	(1 << 2)	/* Register access ready */
+#define I2C_STAT_NACK	(1 << 1)	/* No acknowledgment */
+#define I2C_STAT_AL	(1 << 0)	/* Arbitration lost */
+
+/* I2C Interrupt Code Register (I2C_INTCODE): */
+
+#define I2C_INTCODE_MASK	7
+#define I2C_INTCODE_NONE	0
+#define I2C_INTCODE_AL		1	/* Arbitration lost */
+#define I2C_INTCODE_NAK		2	/* No acknowledgement/general call */
+#define I2C_INTCODE_ARDY	3	/* Register access ready */
+#define I2C_INTCODE_RRDY	4	/* Rcv data ready */
+#define I2C_INTCODE_XRDY	5	/* Xmit data ready */
+#define I2C_INTCODE_SCD		6	/* Stop condition detect */
+
+
+/* I2C Configuration Register (I2C_CON): */
+
+#define I2C_CON_EN	(1 << 5)	/* I2C module enable */
+#define I2C_CON_STB	(1 << 4)	/* Start byte mode (master mode only) */
+#define I2C_CON_MST	(1 << 10)	/* Master/slave mode */
+#define I2C_CON_TRX	(1 << 9)	/* Transmitter/receiver mode
+					   (master mode only) */
+#define I2C_CON_XA	(1 << 8)	/* Expand address */
+#define I2C_CON_STP	(1 << 11)	/* Stop condition (master mode only) */
+#define I2C_CON_STT	(1 << 13)	/* Start condition (master mode only) */
+#define I2C_CON_FREE	(1 << 14)	/* Free run on emulation */
+
+#define I2C_TIMEOUT	0xffff0000	/* Timeout mask for poll_i2c_irq() */
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/nand_defs.h b/arch/arm/include/asm/arch-keystone/nand_defs.h
new file mode 100644
index 0000000..6d6f846
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/nand_defs.h
@@ -0,0 +1,25 @@ 
+/*
+ * nand driver definitions to re-use davinci nand driver on Keystone2
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _NAND_DEFS_H_
+#define _NAND_DEFS_H_
+
+#include <asm/arch/hardware.h>
+#include <linux/mtd/nand.h>
+
+#define	MASK_CLE	0x4000
+#define	MASK_ALE	0x2000
+
+#define NAND_READ_START		0x00
+#define NAND_READ_END		0x30
+#define NAND_STATUS		0x70
+
+extern void davinci_nand_init(struct nand_chip *nand);
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/psc_defs.h b/arch/arm/include/asm/arch-keystone/psc_defs.h
new file mode 100644
index 0000000..edba256
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/psc_defs.h
@@ -0,0 +1,91 @@ 
+/*
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _PSC_DEFS_H_
+#define _PSC_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+/******************************************************************************
+ * FILE PURPOSE: Local Power Sleep Controller definitions
+ ******************************************************************************
+ * FILE NAME: psc_defs.h
+ *
+ * DESCRIPTION: Provides local definitions for the power saver controller
+ *
+ *****************************************************************************/
+
+/* Register offsets */
+#define PSC_REG_PTCMD		0x120
+#define PSC_REG_PSTAT	        0x128
+#define PSC_REG_PDSTAT(x)	(0x200 + (4*(x)))
+#define PSC_REG_PDCTL(x)	(0x300 + (4*(x)))
+#define PSC_REG_MDCFG(x)	(0x600 + (4*(x)))
+#define PSC_REG_MDSTAT(x)	(0x800 + (4*(x)))
+#define PSC_REG_MDCTL(x)	(0xa00 + (4*(x)))
+
+#define BOOTBITMASK(x, y)	((((((u32)1 << (((u32)x)-((u32)y)+(u32)1)) - \
+				  (u32)1)) << ((u32)y)))
+
+#define BOOT_READ_BITFIELD(z, x, y)	(((u32)z) & BOOTBITMASK(x, y)) >> (y)
+#define BOOT_SET_BITFIELD(z, f, x, y)	(((u32)z) & ~BOOTBITMASK(x, y)) | \
+					 ((((u32)f) << (y)) & BOOTBITMASK(x, y))
+
+/* Macros to access register fields */
+/* PDCTL */
+#define PSC_REG_PDCTL_SET_NEXT(x, y)	BOOT_SET_BITFIELD((x), (y), 0, 0)
+#define PSC_REG_PDCTL_SET_PDMODE(x, y)	BOOT_SET_BITFIELD((x), (y), 15, 12)
+
+/* PDSTAT */
+#define PSC_REG_PDSTAT_GET_STATE(x)	BOOT_READ_BITFIELD((x), 4, 0)
+
+/* MDCFG */
+#define PSC_REG_MDCFG_GET_PD(x)		BOOT_READ_BITFIELD((x), 20, 16)
+#define PSC_REG_MDCFG_GET_RESET_ISO(x)	BOOT_READ_BITFIELD((x), 14, 14)
+
+/* MDCTL */
+#define PSC_REG_MDCTL_SET_NEXT(x, y)	BOOT_SET_BITFIELD((x), (y), 4, 0)
+#define PSC_REG_MDCTL_SET_LRSTZ(x, y)	BOOT_SET_BITFIELD((x), (y), 8, 8)
+#define PSC_REG_MDCTL_GET_LRSTZ(x)	BOOT_READ_BITFIELD((x), 8, 8)
+#define PSC_REG_MDCTL_SET_RESET_ISO(x, y)	BOOT_SET_BITFIELD((x), (y), \
+								  12, 12)
+
+/* MDSTAT */
+#define PSC_REG_MDSTAT_GET_STATUS(x)	BOOT_READ_BITFIELD((x), 5, 0)
+#define PSC_REG_MDSTAT_GET_LRSTZ(x)	BOOT_READ_BITFIELD((x), 8, 8)
+#define PSC_REG_MDSTAT_GET_LRSTDONE(x)	BOOT_READ_BITFIELD((x), 9, 9)
+
+/* PDCTL states */
+#define PSC_REG_VAL_PDCTL_NEXT_ON		1
+#define PSC_REG_VAL_PDCTL_NEXT_OFF		0
+
+#define PSC_REG_VAL_PDCTL_PDMODE_SLEEP		0
+
+/* MDCTL states */
+#define PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE	0
+#define PSC_REG_VAL_MDCTL_NEXT_OFF		2
+#define PSC_REG_VAL_MDCTL_NEXT_ON		3
+
+
+/* MDSTAT states */
+#define PSC_REG_VAL_MDSTAT_STATE_ON		3
+#define PSC_REG_VAL_MDSTAT_STATE_ENABLE_IN_PROG	0x24
+#define PSC_REG_VAL_MDSTAT_STATE_OFF		2
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG1	0x20
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG2	0x21
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG3	0x22
+
+
+/* Timeout limit on checking PTSTAT. This is the number of times the
+ * wait function will be called before giving up. */
+#define PSC_PTSTAT_TIMEOUT_LIMIT    100
+
+u32 psc_get_domain_num(u32 mod_num);
+int psc_enable_module(u32 mod_num);
+int psc_disable_module(u32 mod_num);
+int psc_disable_domain(u32 domain_num);
+
+#endif /* _PSC_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-keystone/spl.h b/arch/arm/include/asm/arch-keystone/spl.h
new file mode 100644
index 0000000..eb0b3ed
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/spl.h
@@ -0,0 +1,12 @@ 
+/*
+ * (C) Copyright 2012-2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef	_ASM_ARCH_SPL_H_
+#define	_ASM_SPL_H_
+
+#define BOOT_DEVICE_SPI		2
+
+#endif
diff --git a/board/ti/k2hk_evm/Makefile b/board/ti/k2hk_evm/Makefile
new file mode 100644
index 0000000..3645f2f
--- /dev/null
+++ b/board/ti/k2hk_evm/Makefile
@@ -0,0 +1,9 @@ 
+#
+# K2HK-EVM: board Makefile
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= board.o
+obj-y	+= ddr3.o
diff --git a/board/ti/k2hk_evm/README b/board/ti/k2hk_evm/README
new file mode 100644
index 0000000..6ab660b
--- /dev/null
+++ b/board/ti/k2hk_evm/README
@@ -0,0 +1,56 @@ 
+U-Boot port for Texas Instruments XTCIEVMK2X
+============================================
+
+Author: Murali Karicheri <m-karicheri2@ti.com>
+
+This README has information on the u-boot port for XTCIEVMK2X EVM board.
+Documentation for this board can be found at
+  http://www.advantech.com/Support/TI-EVM/EVMK2HX_sd.aspx
+
+The board is based on Texas Instruments Keystone2 family of SoCs : K2H, K2K.
+More details on these SoCs are available at company websites
+ K2K: http://www.ti.com/product/tci6638k2k
+ K2H: http://www.ti.com/product/tci6638k2h
+
+Board configuration:
+====================
+
+Some of the peripherals that are configured by u-boot are:-
+
+1. 2GB DDR3 (can support 8GB SO DIMM as well)
+2. 512M NAND (over ti emif16 bus)
+3. 6MB MSM SRAM (part of the SoC)
+4. two 1GBit Ethernet ports (SoC supports upto 4)
+5. two UART ports
+6. three i2c interfaces
+7. three spi interfaces (only 1 interface supported in driver)
+
+There are seperate PLLs to drive clocks to Tetris ARM and Peripherals.
+To bring up SMP Linux on this board, there is a boot monitor
+code that will be installed in MSMC SRAM. There is command available
+to install this image from u-boot.
+
+The port related files can be found at following folders
+ keystone2 SoC related files: arch/arm/cpu/armv7/keystone/
+ K2HK evm board files: board/ti/k2hk_evm/
+
+board configuration file: include/configs/k2hk_evm.h
+
+Supported boot modes:
+ - SPI NOR boot
+
+Supported image formats:-
+ - u-boot.bin: for loading and running u-boot.bin through Texas instruments
+               code composure studio (CCS)
+ - u-boot-spi.gph: gpimage for programming SPI NOR flash for SPI NOR boot
+
+Build instructions:
+===================
+
+To build u-boot.bin
+  >make k2hk_evm_config
+  >make u-boot-spi.gph
+
+To build u-boot-spi.gph
+  >make k2hk_evm_config
+  >make u-boot-spi.gph
diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c
new file mode 100644
index 0000000..0ab3aef
--- /dev/null
+++ b/board/ti/k2hk_evm/board.c
@@ -0,0 +1,246 @@ 
+/*
+ * K2HK EVM : Board initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <exports.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/arch/nand_defs.h>
+#include <asm/arch/psc_defs.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 device_big_endian;
+
+unsigned int external_clk[ext_clk_count] = {
+	[sys_clk]	=	122880000,
+	[alt_core_clk]	=	125000000,
+	[pa_clk]	=	122880000,
+	[tetris_clk]	=	125000000,
+	[ddr3a_clk]	=	100000000,
+	[ddr3b_clk]	=	100000000,
+	[mcm_clk]	=	312500000,
+	[pcie_clk]	=	100000000,
+	[sgmii_srio_clk] =	156250000,
+	[xgmii_clk]	=	156250000,
+	[usb_clk]	=	100000000,
+	[rp1_clk]	=	123456789    /* TODO: cannot find
+						what is that */
+};
+
+static struct async_emif_config async_emif_config[ASYNC_EMIF_NUM_CS] = {
+	{			/* CS0 */
+		.mode		= ASYNC_EMIF_MODE_NAND,
+		.wr_setup	= 0xf,
+		.wr_strobe	= 0x3f,
+		.wr_hold	= 7,
+		.rd_setup	= 0xf,
+		.rd_strobe	= 0x3f,
+		.rd_hold	= 7,
+		.turn_around	= 3,
+		.width		= ASYNC_EMIF_8,
+	},
+
+};
+
+static struct pll_init_data pll_config[] = {
+	CORE_PLL_1228,
+	PASS_PLL_983,
+	TETRIS_PLL_1200,
+};
+
+int dram_init(void)
+{
+	init_ddr3();
+
+	gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
+				    CONFIG_MAX_RAM_BANK_SIZE);
+	init_async_emif(ARRAY_SIZE(async_emif_config), async_emif_config);
+	return 0;
+}
+
+/* Byte swap the 32-bit data if the device is BE */
+int cpu_to_bus(u32 *ptr, u32 length)
+{
+	u32 i;
+
+	if (device_big_endian)
+		for (i = 0; i < length; i++, ptr++)
+			*ptr = __swab32(*ptr);
+
+	return 0;
+}
+
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+int board_early_init_f(void)
+{
+	init_plls(ARRAY_SIZE(pll_config), pll_config);
+	return 0;
+}
+#endif
+
+int board_init(void)
+{
+	gd->bd->bi_arch_number = -1;
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	return 0;
+}
+
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+#endif
+}
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+#define K2_DDR3_START_ADDR 0x80000000
+void ft_board_setup(void *blob, bd_t *bd)
+{
+	u64 start[2];
+	u64 size[2];
+	char name[32], *env, *endp;
+	int lpae, nodeoffset;
+	u32 ddr3a_size;
+	int nbanks;
+
+	env = getenv("mem_lpae");
+	lpae = env && simple_strtol(env, NULL, 0);
+
+	ddr3a_size = 0;
+	if (lpae) {
+		env = getenv("ddr3a_size");
+		if (env)
+			ddr3a_size = simple_strtol(env, NULL, 10);
+		if ((ddr3a_size != 8) && (ddr3a_size != 4))
+			ddr3a_size = 0;
+	}
+
+	nbanks = 1;
+	start[0] = bd->bi_dram[0].start;
+	size[0]  = bd->bi_dram[0].size;
+
+	/* adjust memory start address for LPAE */
+	if (lpae) {
+		start[0] -= K2_DDR3_START_ADDR;
+		start[0] += CONFIG_SYS_LPAE_SDRAM_BASE;
+	}
+
+	if ((size[0] == 0x80000000) && (ddr3a_size != 0)) {
+		size[1] = ((u64)ddr3a_size - 2) << 30;
+		start[1] = 0x880000000;
+		nbanks++;
+	}
+
+	/* reserve memory at start of bank */
+	sprintf(name, "mem_reserve_head");
+	env = getenv(name);
+	if (env) {
+		start[0] += ustrtoul(env, &endp, 0);
+		size[0] -= ustrtoul(env, &endp, 0);
+	}
+
+	sprintf(name, "mem_reserve");
+	env = getenv(name);
+	if (env)
+		size[0] -= ustrtoul(env, &endp, 0);
+
+	fdt_fixup_memory_banks(blob, start, size, nbanks);
+
+	/* Fix up the initrd */
+	if (lpae) {
+		u64 initrd_start, initrd_end;
+		u32 *prop1, *prop2;
+		int err;
+		nodeoffset = fdt_path_offset(blob, "/chosen");
+		if (nodeoffset >= 0) {
+			prop1 = (u32 *)fdt_getprop(blob, nodeoffset,
+					    "linux,initrd-start", NULL);
+			prop2 = (u32 *)fdt_getprop(blob, nodeoffset,
+					    "linux,initrd-end", NULL);
+			if (prop1 && prop2) {
+				initrd_start = __be32_to_cpu(*prop1);
+				initrd_start -= K2_DDR3_START_ADDR;
+				initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE;
+				initrd_start = __cpu_to_be64(initrd_start);
+				initrd_end = __be32_to_cpu(*prop2);
+				initrd_end -= K2_DDR3_START_ADDR;
+				initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE;
+				initrd_end = __cpu_to_be64(initrd_end);
+
+				err = fdt_delprop(blob, nodeoffset,
+						  "linux,initrd-start");
+				if (err < 0)
+					printf("error deleting linux,initrd-start\n");
+
+				err = fdt_delprop(blob, nodeoffset,
+						  "linux,initrd-end");
+				if (err < 0)
+					printf("error deleting linux,initrd-end\n");
+
+				err = fdt_setprop(blob, nodeoffset,
+						  "linux,initrd-start",
+						  &initrd_start,
+						  sizeof(initrd_start));
+				if (err < 0)
+					printf("error adding linux,initrd-start\n");
+
+				err = fdt_setprop(blob, nodeoffset,
+						  "linux,initrd-end",
+						  &initrd_end,
+						  sizeof(initrd_end));
+				if (err < 0)
+					printf("error adding linux,initrd-end\n");
+			}
+		}
+	}
+}
+
+void ft_board_setup_ex(void *blob, bd_t *bd)
+{
+	int	lpae;
+	char	*env;
+	u64	*reserve_start, size;
+
+	env = getenv("mem_lpae");
+	lpae = env && simple_strtol(env, NULL, 0);
+
+	if (lpae) {
+		/*
+		 * the initrd and other reserved memory areas are
+		 * embedded in in the DTB itslef. fix up these addresses
+		 * to 36 bit format
+		 */
+		reserve_start = (u64 *)((char *)blob +
+				       fdt_off_mem_rsvmap(blob));
+		while (1) {
+			*reserve_start = __cpu_to_be64(*reserve_start);
+			size = __cpu_to_be64(*(reserve_start + 1));
+			if (size) {
+				*reserve_start -= K2_DDR3_START_ADDR;
+				*reserve_start +=
+					CONFIG_SYS_LPAE_SDRAM_BASE;
+				*reserve_start =
+					__cpu_to_be64(*reserve_start);
+			} else {
+				break;
+			}
+			reserve_start += 2;
+		}
+	}
+}
+#endif
diff --git a/board/ti/k2hk_evm/ddr3.c b/board/ti/k2hk_evm/ddr3.c
new file mode 100644
index 0000000..973c35d
--- /dev/null
+++ b/board/ti/k2hk_evm/ddr3.c
@@ -0,0 +1,269 @@ 
+/*
+ * Keystone2: DDR3 initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <i2c.h>
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1600_64A = {
+	.pllcr		= 0x0001C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0D861A80ul,
+	.ptr4		= 0x0C827100ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0xA19DBB66ul,
+	.dtpr1		= 0x12868300ul,
+	.dtpr2		= 0x50035200ul,
+	.mr0		= 0x00001C70ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000018ul,
+	.dtcr		= 0x730035C7ul,
+	.pgcr2		= 0x00F07A12ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1600_64 = {
+	.sdcfg		= 0x6200CE6aul,
+	.sdtim1		= 0x16709C55ul,
+	.sdtim2		= 0x00001D4Aul,
+	.sdtim3		= 0x435DFF54ul,
+	.sdtim4		= 0x553F0CFFul,
+	.zqcfg		= 0xF0073200ul,
+	.sdrfc		= 0x00001869ul,
+};
+
+static struct ddr3_phy_config ddr3phy_1600_32 = {
+	.pllcr		= 0x0001C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0D861A80ul,
+	.ptr4		= 0x0C827100ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0xA19DBB66ul,
+	.dtpr1		= 0x12868300ul,
+	.dtpr2		= 0x50035200ul,
+	.mr0		= 0x00001C70ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000018ul,
+	.dtcr		= 0x730035C7ul,
+	.pgcr2		= 0x00F07A12ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1600_32 = {
+	.sdcfg		= 0x6200DE6aul,
+	.sdtim1		= 0x16709C55ul,
+	.sdtim2		= 0x00001D4Aul,
+	.sdtim3		= 0x435DFF54ul,
+	.sdtim4		= 0x553F0CFFul,
+	.zqcfg		= 0x70073200ul,
+	.sdrfc		= 0x00001869ul,
+};
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1333_64A = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK |
+			   NOSRA_MASK | UDIMM_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27) | (1 << 29)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1333_64 = {
+	.sdcfg		= 0x62008C62ul,
+	.sdtim1		= 0x125C8044ul,
+	.sdtim2		= 0x00001D29ul,
+	.sdtim3		= 0x32CDFF43ul,
+	.sdtim4		= 0x543F0ADFul,
+	.zqcfg		= 0xF0073200ul,
+	.sdrfc		= 0x00001457ul,
+};
+
+static struct ddr3_phy_config ddr3phy_1333_32 = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK |
+			   NOSRA_MASK | UDIMM_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27) | (1 << 29)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1333_32 = {
+	.sdcfg		= 0x62009C62ul,
+	.sdtim1		= 0x125C8044ul,
+	.sdtim2		= 0x00001D29ul,
+	.sdtim3		= 0x32CDFF43ul,
+	.sdtim4		= 0x543F0ADFul,
+	.zqcfg		= 0xf0073200ul,
+	.sdrfc		= 0x00001457ul,
+};
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1333_64 = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+/******************************************************/
+int get_dimm_params(char *dimm_name)
+{
+	u8 spd_params[256];
+	int ret;
+	int old_bus;
+
+	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	old_bus = i2c_get_bus_num();
+	i2c_set_bus_num(1);
+
+	ret = i2c_read(0x53, 0, 1, spd_params, 256);
+
+	i2c_set_bus_num(old_bus);
+
+	dimm_name[0] = '\0';
+
+	if (ret) {
+		puts("Cannot read DIMM params\n");
+		return 1;
+	}
+
+	/*
+	 * We need to convert spd data to dimm parameters
+	 * and to DDR3 EMIF and PHY regirsters values.
+	 * For now we just return DIMM type string value.
+	 * Caller may use this value to choose appropriate
+	 * a pre-set DDR3 configuration
+	 */
+
+	strncpy(dimm_name, (char *)&spd_params[0x80], 18);
+	dimm_name[18] = '\0';
+
+	return 0;
+}
+
+struct pll_init_data ddr3a_333 = DDR3_PLL_333(A);
+struct pll_init_data ddr3b_333 = DDR3_PLL_333(B);
+struct pll_init_data ddr3a_400 = DDR3_PLL_400(A);
+struct pll_init_data ddr3b_400 = DDR3_PLL_400(B);
+
+void init_ddr3(void)
+{
+	char dimm_name[32];
+
+	get_dimm_params(dimm_name);
+
+	printf("Detected SO-DIMM [%s]\n", dimm_name);
+
+	if (!strcmp(dimm_name, "18KSF1G72HZ-1G6E2 ")) {
+		init_pll(&ddr3a_400);
+		if (cpu_revision() > 0) {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_64A);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_64);
+			printf("DRAM:  Capacity 8 GiB (includes reported below)\n");
+		} else {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_32);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_32);
+			printf("DRAM:  Capacity 4 GiB (includes reported below)\n");
+		}
+	} else if (!strcmp(dimm_name, "SQR-SD3T-2G1333SED")) {
+		init_pll(&ddr3a_333);
+		if (cpu_revision() > 0) {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_64A);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_64);
+		} else {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_32);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_32);
+		}
+	} else {
+		printf("Unknown SO-DIMM. Cannot configure DDR3\n");
+		while (1)
+			;
+	}
+
+	init_pll(&ddr3b_333);
+	init_ddrphy(K2HK_DDR3B_DDRPHYC, &ddr3phy_1333_64);
+	init_ddremif(K2HK_DDR3B_EMIF_CTRL_BASE, &ddr3_1333_64);
+}
+
diff --git a/boards.cfg b/boards.cfg
index a8336cc..1690315 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -362,6 +362,7 @@  Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_microzed			-
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm010			zynq_zc770:ZC770_XM010                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm012			zynq_zc770:ZC770_XM012                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm013			zynq_zc770:ZC770_XM013                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
+Active  arm         armv7          keystone    ti              k2hk_evm            k2hk_evm                             -                                                                                                                                 Vitaly Andrianov <vitalya@ti.com>
 Active  arm         armv7:arm720t  tegra114    nvidia          dalmore             dalmore                              -                                                                                                                                 Tom Warren <twarren@nvidia.com>
 Active  arm         armv7:arm720t  tegra20     avionic-design  medcom-wide         medcom-wide                          -                                                                                                                                 Alban Bedel <alban.bedel@avionic-design.de>
 Active  arm         armv7:arm720t  tegra20     avionic-design  plutux              plutux                               -                                                                                                                                 Alban Bedel <alban.bedel@avionic-design.de>
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index fa3a875..996a8f2 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -7,6 +7,7 @@ 
 
 obj-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 obj-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
+obj-$(CONFIG_DRIVER_KEYSTONE_I2C) += keystone_i2c.o
 obj-$(CONFIG_DW_I2C) += designware_i2c.o
 obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 obj-$(CONFIG_I2C_MV) += mv_i2c.o
diff --git a/drivers/i2c/keystone_i2c.c b/drivers/i2c/keystone_i2c.c
new file mode 100644
index 0000000..e2093c1
--- /dev/null
+++ b/drivers/i2c/keystone_i2c.c
@@ -0,0 +1,372 @@ 
+/*
+ * TI Keystone i2c driver
+ * Based on TI DaVinci (TMS320DM644x) I2C driver.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/i2c_defs.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
+						(struct i2c_regs *)I2C_BASE;
+
+static unsigned int __attribute__((section(".data")))
+		bus_initialized[I2C_BUS_MAX] = { [0 ... (I2C_BUS_MAX-1)] = 0 };
+static unsigned int __attribute__((section(".data"))) current_bus;
+
+#define CHECK_NACK() \
+	do {\
+		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
+			REG(&(i2c_base->i2c_con)) = 0;\
+			return 1;\
+		} \
+	} while (0)
+
+static int wait_for_bus(void)
+{
+	int	stat, timeout;
+
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		stat = REG(&(i2c_base->i2c_stat));
+		if (!((stat) & I2C_STAT_BB)) {
+			REG(&(i2c_base->i2c_stat)) = 0xffff;
+			return 0;
+		}
+
+		REG(&(i2c_base->i2c_stat)) = stat;
+		udelay(50000);
+	}
+
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return 1;
+}
+
+
+static int poll_i2c_irq(int mask)
+{
+	int	stat, timeout;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		udelay(1000);
+		stat = REG(&(i2c_base->i2c_stat));
+		if (stat & mask)
+			return stat;
+	}
+
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return stat | I2C_TIMEOUT;
+}
+
+
+void flush_rx(void)
+{
+	while (1) {
+		if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
+			break;
+
+		REG(&(i2c_base->i2c_drr));
+		REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
+		udelay(1000);
+	}
+}
+
+
+void i2c_init(int speed, int slaveadd)
+{
+	u_int32_t	div, psc;
+
+	if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		udelay(50000);
+	}
+
+	psc = 2;
+	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
+	REG(&(i2c_base->i2c_psc)) = psc;
+	REG(&(i2c_base->i2c_scll)) = (div * 50) / 100;
+	REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
+
+	REG(&(i2c_base->i2c_oa)) = slaveadd;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+
+	/* Interrupts must be enabled or I2C module won't work */
+	REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
+
+	/* Now enable I2C controller (get it out of reset) */
+	REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
+
+	udelay(1000);
+
+	if (gd->flags & GD_FLG_RELOC)
+		bus_initialized[current_bus] = 1;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
+	return 0;
+}
+
+int i2c_probe(u_int8_t chip)
+{
+	int	rc = 1;
+
+	if (chip == REG(&(i2c_base->i2c_oa)))
+		return rc;
+
+	REG(&(i2c_base->i2c_con)) = 0;
+	if (wait_for_bus())
+		return 1;
+
+	/* try to read one byte from current (or only) address */
+	REG(&(i2c_base->i2c_cnt)) = 1;
+	REG(&(i2c_base->i2c_sa))  = chip;
+	REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+				     I2C_CON_STP);
+	udelay(50000);
+
+	if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
+		rc = 0;
+		flush_rx();
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
+	} else {
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
+		REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
+		udelay(20000);
+		if (wait_for_bus())
+			return 1;
+	}
+
+	flush_rx();
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	return rc;
+}
+
+
+int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
+	}
+
+	if (wait_for_bus())
+		return 1;
+
+	if (alen != 0) {
+		/* Start address phase */
+		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
+		REG(&(i2c_base->i2c_cnt)) = alen;
+		REG(&(i2c_base->i2c_sa)) = chip;
+		REG(&(i2c_base->i2c_con)) = tmp;
+
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		switch (alen) {
+		case 2:
+			/* Send address MSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+			/* No break, fall through */
+		case 1:
+			/* Send address LSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK |
+					   I2C_STAT_ARDY);
+
+			CHECK_NACK();
+
+			if (!(tmp & I2C_STAT_ARDY)) {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+		}
+	}
+
+	/* Address phase is over, now read 'len' bytes and stop */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
+	REG(&(i2c_base->i2c_cnt)) = len & 0xffff;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK |
+				   I2C_STAT_ROVR);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_RRDY) {
+			buf[i] = REG(&(i2c_base->i2c_drr));
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
+	}
+
+	flush_rx();
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
+
+	return 0;
+}
+
+
+int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
+	}
+	if (len < 0) {
+		printf("%s(): bogus length %x\n", __func__, len);
+		return 1;
+	}
+
+	if (wait_for_bus())
+		return 1;
+
+	/* Start address phase */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+		I2C_CON_TRX | I2C_CON_STP;
+	REG(&(i2c_base->i2c_cnt)) = (alen == 0) ?
+		len & 0xffff : (len & 0xffff) + alen;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
+
+	switch (alen) {
+	case 2:
+		/* Send address MSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+		/* No break, fall through */
+	case 1:
+		/* Send address LSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+	}
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY)
+			REG(&(i2c_base->i2c_dxr)) = buf[i];
+		else
+			return 1;
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
+	}
+
+	flush_rx();
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
+
+	return 0;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= I2C_BUS_MAX)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	switch (bus) {
+#if I2C_BUS_MAX == 3
+	case 2:
+		i2c_base = (struct i2c_regs *)I2C2_BASE;
+		break;
+#endif
+#if I2C_BUS_MAX >= 2
+	case 1:
+		i2c_base = (struct i2c_regs *)I2C1_BASE;
+		break;
+#endif
+	default:
+		i2c_base = (struct i2c_regs *)I2C0_BASE;
+		bus = 0;
+	}
+
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return (int) current_bus;
+}
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index fbc37b2..8a13454 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -30,6 +30,11 @@ 
 #define serial_in(y)		readb(y)
 #endif
 
+#if defined(CONFIG_K2HK_EVM)
+#define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE   0
+#define UART_REG_VAL_PWREMU_MGMT_UART_ENABLE ((1 << 14) | (1 << 13) | (1 << 0))
+#endif
+
 #ifndef CONFIG_SYS_NS16550_IER
 #define CONFIG_SYS_NS16550_IER  0x00
 #endif /* CONFIG_SYS_NS16550_IER */
@@ -77,6 +82,9 @@  void NS16550_init(NS16550_t com_port, int baud_divisor)
 	/* /16 is proper to hit 115200 with 48MHz */
 	serial_out(0, &com_port->mdr1);
 #endif /* CONFIG_OMAP */
+#if defined(CONFIG_K2HK_EVM)
+	serial_out(UART_REG_VAL_PWREMU_MGMT_UART_ENABLE, &com_port->regC);
+#endif
 }
 
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
new file mode 100644
index 0000000..a43318a
--- /dev/null
+++ b/include/configs/k2hk_evm.h
@@ -0,0 +1,221 @@ 
+/*
+ * Configuration header file for TI's k2hk-evm
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* Platform type */
+#define CONFIG_SOC_K2HK
+#define CONFIG_K2HK_EVM
+
+/* U-Boot Build Configuration */
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is a 2nd stage loader */
+#define CONFIG_SYS_NO_FLASH		/* that is, no *NOR* flash */
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_SYS_THUMB_BUILD
+
+/* SoC Configuration */
+#define CONFIG_ARMV7
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ			1000
+#define CONFIG_SYS_TEXT_BASE		0x0c001000
+#define CONFIG_OF_LIBFDT		1
+#define CONFIG_OF_BOARD_SETUP
+#define CONFIG_SYS_DCACHE_OFF
+
+/* Memory Configuration */
+#define CONFIG_NR_DRAM_BANKS		2
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_LPAE_SDRAM_BASE	0x800000000
+#define CONFIG_MAX_RAM_BANK_SIZE	(2 << 30)	/* 2GB */
+#define CONFIG_STACKSIZE		(512 << 10)	/* 512 KiB */
+#define CONFIG_SYS_MALLOC_LEN		(1024 << 10)	/* 1 MiB */
+#define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_SDRAM_BASE + 32 << 20)
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE -	\
+					 GENERATED_GBL_DATA_SIZE)
+
+/* SPL SPI Loader Configuration */
+#define CONFIG_SPL_TEXT_BASE		0x0c200000
+#define CONFIG_SPL_PAD_TO		65536
+#define CONFIG_SPL_MAX_SIZE		(CONFIG_SPL_PAD_TO - 8)
+#define CONFIG_SPL_BSS_START_ADDR	(CONFIG_SPL_TEXT_BASE +		\
+					 CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SPL_BSS_MAX_SIZE		(32 * 1024)
+#define CONFIG_SYS_SPL_MALLOC_START	(CONFIG_SPL_BSS_START_ADDR +	\
+					 CONFIG_SPL_BSS_MAX_SIZE)
+#define CONFIG_SYS_SPL_MALLOC_SIZE	(32 * 1024)
+#define CONFIG_SPL_STACK_SIZE		(8 * 1024)
+#define CONFIG_SPL_STACK		(CONFIG_SYS_SPL_MALLOC_START +	\
+					 CONFIG_SYS_SPL_MALLOC_SIZE +	\
+					 CONFIG_SPL_STACK_SIZE - 4)
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_SPI_LOAD
+#define CONFIG_SPL_SPI_BUS		0
+#define CONFIG_SPL_SPI_CS		0
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	CONFIG_SPL_PAD_TO
+#define CONFIG_SPL_FRAMEWORK
+
+/* UART Configuration */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_REG_SIZE	-4
+#define CONFIG_SYS_NS16550_COM1		K2HK_UART0_BASE
+#define CONFIG_SYS_NS16550_CLK		clk_get_rate(K2HK_CLK1_6)
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_CONS_INDEX		1
+#define CONFIG_BAUDRATE			115200
+
+/* SPI Configuration */
+#define CONFIG_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_DAVINCI_SPI
+#define CONFIG_SYS_SPI_BASE		K2HK_SPI_BASE
+#define CONFIG_SYS_SPI_CLK		clk_get_rate(K2HK_LPSC_EMIF25_SPI)
+#define CONFIG_SF_DEFAULT_SPEED		30000000
+#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
+
+/* I2C Configuration */
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_KEYSTONE_I2C
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0x10	/* SMBus host address */
+#define CONFIG_I2C_MULTI_BUS		1
+#define I2C_BUS_MAX			3
+
+/* EEPROM definitions */
+#define CONFIG_SYS_I2C_MULTI_EEPROMS
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         2
+#define CONFIG_SYS_I2C_EEPROM_ADDR             0x50
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      6
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  20
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+
+/* NAND Configuration */
+#define CONFIG_NAND_DAVINCI
+#define CONFIG_SYS_NAND_CS		2
+#define CONFIG_SYS_NAND_USE_FLASH_BBT
+#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
+#define CONFIG_SYS_NAND_PAGE_2K
+
+#define CONFIG_SYS_NAND_LARGEPAGE
+#define CONFIG_SYS_NAND_BASE_LIST	{ 0x30000000, }
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_MAX_CHIPS	1
+#define CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+#define CONFIG_ENV_SIZE			(256 << 10)	/* 256 KiB */
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET		0x100000
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_MTD_DEVICE
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define MTDIDS_DEFAULT			"nand0=davinci_nand.0"
+#define PART_BOOT			"1024k(bootloader)ro,"
+#define PART_PARAMS			"512k(params)ro,"
+#define PART_UBI			"-(ubifs)"
+#define MTDPARTS_DEFAULT		"mtdparts=davinci_nand.0:"	\
+					PART_BOOT PART_PARAMS PART_UBI
+
+/* U-Boot command configuration */
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_EEPROM
+
+/* U-Boot general configuration */
+#define CONFIG_SYS_PROMPT		"K2HK EVM # "
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SYS_PBSIZE		2048
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_TIMESTAMP
+
+#define CONFIG_BOOTDELAY		3
+#define CONFIG_BOOTFILE			"uImage"
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	"boot=ramfs\0"							\
+	"tftp_root=/\0"							\
+	"nfs_root=/export\0"						\
+	"mem_lpae=1\0"							\
+	"mem_reserve=512M\0"						\
+	"addr_fdt=0x87000000\0"						\
+	"addr_kern=0x88000000\0"					\
+	"addr_mon=0x0c5f0000\0"						\
+	"addr_uboot=0x87000000\0"					\
+	"addr_fs=0x82000000\0"						\
+	"addr_ubi=0x82000000\0"						\
+	"fdt_high=0xffffffff\0"						\
+	"run_mon=mon_install ${addr_mon}\0"				\
+	"run_kern=bootm ${addr_kern} - ${addr_fdt}\0"			\
+	"init_ubi=run args_all args_ubi; "				\
+		"ubi part ubifs; ubifsmount boot\0"			\
+	"get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0"		\
+	"get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0"		\
+	"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0"		\
+	"burn_uboot=sf probe; sf erase 0 0x100000; "			\
+		"sf write ${addr_uboot} 0 ${filesize}\0"		\
+	"args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0"	\
+	"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs "	\
+		"root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0"	\
+	"burn_ubi=nand erase.part ubifs; "				\
+		"nand write ${addr_ubi} ubifs ${filesize}\0"		\
+	"init_ramfs=run args_all args_ramfs get_fs_ramfs\0"		\
+	"args_ramfs=setenv bootargs ${bootargs} earlyprintk "		\
+		"rdinit=/sbin/init rw root=/dev/ram0 "			\
+		"initrd=0x802000000,9M\0"				\
+	"mtdparts=mtdparts=davinci_nand.0:"				\
+		"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
+#define CONFIG_BOOTCOMMAND						\
+	"run init_${boot} get_fdt_${boot} get_mon_${boot} "		\
+		"get_kern_${boot} run_mon run_kern"
+#define CONFIG_BOOTARGS							\
+
+/* Linux interfacing */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_SYS_BARGSIZE		1024
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x08000000)
+#define LINUX_BOOT_PARAM_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x100)
+
+#define CONFIG_SUPPORT_RAW_INITRD
+
+/* we may include files below only after all above definitions */
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#define CONFIG_SYS_HZ_CLOCK		clk_get_rate(K2HK_CLK1_6)
+
+#endif /* __CONFIG_H */