Discussion:
[U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
John Schmoller
2009-07-28 16:34:00 UTC
Permalink
Hello all,

I've been working on writing a User's Manual generation tool, and before
I get too far I'd like to see if this is something the U-Boot community
would be interested in.

The thought was that everyone needs to develop User's Manuals for their
customers, and there's no reason for us all to reinvent the wheel for
each product we create. I've written a Perl script, uboot-doc, which is
very loosely based on the kernel-doc documentation creator in Linux.
(Take it easy on my Perl, this is my first script.) The specific syntax
is described in uboot-doc, but the parser takes formatted comments with
@'s and converts the information into DocBook XML. The DocBook XML can be
used to generate HTML, XHTML, PDFs, and text, and can be extended to change
formatting and appearance. The static portions of the manual are taken
from .tmpl files in the doc/manual/ directory, which have basic
precompiler support (#ifdef, #else, #endif) and support for accessing
system environment variables (${TOPDIR}, for example) and any value
found in autoconf.mk, (@CONFIG_BAUDRATE, for example). All template
files in doc/manual/ can be over-ridden by a board specific file in
board/$BOARDDIR/manual. For example, doc/manual/manual.tmpl would be
over-ridden by board/$BOARDDIR/manual/manual.tmpl.

General Control Flow:
C pre-processor -> doc_stream.pl : pre-processed code gets everything but
comments with an @ stripped away
doc_stream.pl -> autoconf_doc.txt : "interesting" comments get sent to this
file
autoconf_doc.txt -> uboot-doc : file is parsed and comments are turned to XML
*.tmpl -> uboot-doc : template files are processed into XML
*.xml -> xsltproc : XML is converted into desired output format
*.fo -> fop : (PDFs only) fo files are translated to PDF

Steps to compile your very own manual (using Ubuntu package names):
1) Install xsltproc. I'm using version
1.1.24-2ubuntu2. If you've got no desire to make text, html, xhtml, or
pdf you don't need this tool.

2) Install docbook-xsl. I'm using version
1.73.2.dfsg.1-5. If you've got no desire to make text, html, xhtml, or
pdf you don't need this tool.

3) FOP needs to be installed with hyphenation support, which is not
available from Synaptic or apt-get. Use the instructions from
http://www.linuxfromscratch.org/blfs/view/svn/pst/fop.html to install
your version of FOP (yes, you do need OFFO and JAI). You will need to
install ant if you don't already have it (1.7.1-0ubuntu2).
If you've got no desire to make a PDF, you don't need this tool.

4) If you follow the steps above, the default values of DOCBOOK_XSL_DIR,
XSLT_PROCESSOR, and FO_PROCESSOR should be correct. If you decided to
try to go it your own, set them accordingly. DOCBOOK_XSL_DIR points to
your Docbook stylesheet directory, XSLT_PROCESSOR points to the default
program which compiles XML into it's various forms, and FO_PROCESSOR
points the the default program for turning FO images into PDFs.

5) Once you have the tools installed, you should be able to compile a
manual. This documentation feature was tested on the X-ES's XPedite5370.
make XPEDITE5370_config
make {xml/html/xhtml/pdf/text}
Note: text doesn't work yet as I believe there is an issue with the
docbook style sheets (or possibly how I'm using them). It's being looked
into. Something about varlistentries not belonging in varlists? I dunno.

The doc/manual directory also includes a PDF style sheet (uboot_manual.xsl).
By creating your own book_info.tmpl, you can add a company logo
and an address to the cover page. By default these two are left out. It is also
possible to create a completely new style sheet to customize your manual look.
Similarly, HTML output can be customized using CSS. The results of this output
as well as the HTML output can be found on the X-ES website:
www.xes-inc.com/sources/u-boot/index.html
www.xes-inc.com/sources/u-boot/xpedite5370.pdf
Note that I've defined a "mediaobject" and "address" in my custom
board/xes/xpedite5370/book_info.tmpl to place the address and company logo
on the cover page.

I see several advantages to adopting this scheme.
- Documentation should be easier to keep in sync with code
- DocBook XML output can be used to generate webpages, PDFs, text, etc,
which are all extensible
- People don't have to reinvent the wheel when writing documentation
- Source code ends up being thouroughly commented

These patches are just meant to be an example of how in-code documentation
could be used. You'll also notice there are many warnings regarding variables
the manual is referencing which aren't defined yet. I wanted to get some
feedback before diving in too far. What do others think? Is this worth
pursuing?

Thanks,
John

John Schmoller (3):
uboot-doc: Initial support of user documentation generator
uboot-doc: Add example support for uboot-doc
xpedite5370: Add uboot-doc support

Makefile | 2 +
board/xes/xpedite5370/manual/book_info.tmpl | 52 ++
board/xes/xpedite5370/manual/booting_linux.tmpl | 179 ++++
board/xes/xpedite5370/manual/booting_vxworks.tmpl | 166 ++++
board/xes/xpedite5370/manual/manual.tmpl | 30 +
board/xes/xpedite5370/manual/redundant_images.tmpl | 50 ++
board/xes/xpedite5370/manual/scripting.tmpl | 168 ++++
common/cmd_i2c.c | 71 ++-
common/cmd_mem.c | 45 +-
common/cmd_net.c | 30 +-
common/env_common.c | 35 +
config.mk | 1 +
doc/manual/85xx_program_flow.tmpl | 74 ++
doc/manual/book_info.tmpl | 35 +
doc/manual/booting_linux.tmpl | 249 ++++++
doc/manual/config.mk | 74 ++
doc/manual/doc-stream.pl | 34 +
doc/manual/introduction.tmpl | 136 +++
doc/manual/manual.tmpl | 26 +
doc/manual/scripting.tmpl | 154 ++++
doc/manual/setup.tmpl | 294 +++++++
doc/manual/uboot-doc | 866 ++++++++++++++++++++
doc/manual/uboot_manual.xsl | 286 +++++++
include/configs/XPEDITE5370.h | 47 ++
post/tests.c | 16 +
rules.mk | 7 +
26 files changed, 3122 insertions(+), 5 deletions(-)
create mode 100644 board/xes/xpedite5370/manual/book_info.tmpl
create mode 100644 board/xes/xpedite5370/manual/booting_linux.tmpl
create mode 100644 board/xes/xpedite5370/manual/booting_vxworks.tmpl
create mode 100644 board/xes/xpedite5370/manual/manual.tmpl
create mode 100644 board/xes/xpedite5370/manual/redundant_images.tmpl
create mode 100644 board/xes/xpedite5370/manual/scripting.tmpl
create mode 100644 doc/manual/85xx_program_flow.tmpl
create mode 100644 doc/manual/book_info.tmpl
create mode 100644 doc/manual/booting_linux.tmpl
create mode 100644 doc/manual/config.mk
create mode 100644 doc/manual/doc-stream.pl
create mode 100644 doc/manual/introduction.tmpl
create mode 100644 doc/manual/manual.tmpl
create mode 100644 doc/manual/scripting.tmpl
create mode 100644 doc/manual/setup.tmpl
create mode 100644 doc/manual/uboot-doc
create mode 100644 doc/manual/uboot_manual.xsl
John Schmoller
2009-07-28 16:34:02 UTC
Permalink
Add support to a small subset of commands, environment
variables, and POSTs. These are meant to show the
syntax and capabilities of the uboot-doc parser.

Signed-off-by: John Schmoller <jschmoller at xes-inc.com>
---
common/cmd_i2c.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
common/cmd_mem.c | 45 +++++++++++++++++++++++++++++++-
common/cmd_net.c | 30 ++++++++++++++++++++-
common/env_common.c | 35 +++++++++++++++++++++++++
post/tests.c | 16 +++++++++++
5 files changed, 192 insertions(+), 5 deletions(-)

diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 8f0fc9e..14d394c 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -1297,7 +1297,70 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
}

/***************************************************/
-
+/**
+ * @cmd: i2c speed
+ * @sect: I2C
+ * @param[or]: speed - target I2C bus speed
+ * @desc: Show or set I2C bus speed
+ */
+/**
+ * @cmd: i2c dev
+ * @sect: I2C
+ * @param[or]: dev - I2C device to make current
+ * @desc: Show or set current I2C bus
+ */
+/**
+ * @cmd: i2c md
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param[or]: # of objects - Numer of bytes to read
+ * @desc: Read from I2C device
+ */
+/**
+ * @cmd: i2c mm
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @desc: Write to I2C device (auto-incrementing)
+ */
+/**
+ * @cmd: i2c mw
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param: value - Value to write to I2C address
+ * @param[or]: count - Number of bytes to write
+ * @desc: Write to I2C device (fill)
+ */
+/**
+ * @cmd: i2c nm
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @desc: Write to I2C device (constant address)
+ */
+/**
+ * @cmd: i2c crc32
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param: count - Number of bytes to CRC
+ * @desc: Computes the CRC32 checksum of an address range
+ */
+/**
+ * @cmd: i2c probe
+ * @sect: I2C
+ * @desc: Shows all the devices on the I2C bus
+ */
+/**
+ * @cmd: i2c loop
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param: # of objects - Number of bytes to loop over
+ * @desc: Looping read of device. Never returns.
+ */
U_BOOT_CMD(
i2c, 6, 1, do_i2c,
"I2C sub-system",
@@ -1317,6 +1380,12 @@ U_BOOT_CMD(
"i2c reset - re-init the I2C Controller\n"
"i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device"
#if defined(CONFIG_CMD_SDRAM)
+/**
+ * @cmd: isdram
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @desc: Prints SDRAM configuration information
+ */
"\n"
"i2c sdram chip - print SDRAM configuration information"
#endif
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index cdf8c79..2276a1a 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -1169,20 +1169,61 @@ int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])


/**************************************************/
+/**
+ * @cmd: md
+ * @sect: Memory
+ * @param[or]: address - memory location to display
+ * @param[or]: objs - Number of objects to display
+ * @desc: The md command displays memory contents both as hexadecimal and
+ * ASCII data. The last displayed memory address and the value of the
+ * count argument are remembered, so when you enter md again without
+ * arguments it will automatically continue at the next address, and use
+ * the same count again.
+ *
+ * If invoked as md or md.l, data is displayed as 32-bit long words. If
+ * invoked as md.w or md.b instead, 16-bit words or 8-bit bytes are used,
+ * respectively.
+ */
U_BOOT_CMD(
md, 3, 1, do_mem_md,
"memory display",
"[.b, .w, .l] address [# of objects]"
);

-
+/**
+ * @cmd: mm
+ * @sect: Memory
+ * @param[or]: address - memory location to modify
+ * @desc: The mm command is a method to interactively modify memory contents.
+ * It will display the address and current contents and then prompt for
+ * user input. If you enter a legal hexadecimal number, this new value
+ * will be written to the address. Then, the next address will be
+ * prompted. If you don't enter any value and just press ENTER, then the
+ * contents of this address will remain unchanged. The command stops as
+ * soon as you enter any data that is not a hex number.
+ *
+ * If invoked as mm or mm.l, data is displayed as 32-bit long words. If
+ * invoked as mm.w or mm.b instead, 16-bit words or 8-bit bytes are used,
+ * respectively.
+ */
U_BOOT_CMD(
mm, 2, 1, do_mem_mm,
"memory modify (auto-incrementing address)",
"[.b, .w, .l] address"
);

-
+/**
+ * @cmd: nm
+ * @sect: Memory
+ * @param[or]: address - memory location to modify
+ * @desc: The nm command (non-incrementing memory modify) can be used to
+ * interactively write different data several times to the same address.
+ * This can be useful, for instance, to access and modify device registers.
+ *
+ * If invoked as nm or nm.l, data is modified as a 32-bit long word. If
+ * invoked as nm.w or nm.b instead, 16-bit words or 8-bit bytes are used,
+ * respectively.
+ */
U_BOOT_CMD(
nm, 2, 1, do_mem_nm,
"memory modify (constant address)",
diff --git a/common/cmd_net.c b/common/cmd_net.c
index 88f4e5b..7760230 100644
--- a/common/cmd_net.c
+++ b/common/cmd_net.c
@@ -47,7 +47,24 @@ int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
return netboot_common (TFTP, cmdtp, argc, argv);
}
-
+/**
+ * @cmd: tftpboot
+ * @sect: Networking
+ * @param[r]: loadAddress - address to store downloaded file
+ * @param[or]: [hostIPaddr:]bootfilename - file to download from specified IP
+ * @desc: The tftpboot command downloads a file from the
+ * network using the TFTP protocol. @eipaddr, @eserverip,
+ * @egatewayip, and @enetmask must be set prior to
+ * calling tftpboot.
+ * If loadAddress is specified, the file will be
+ * downloaded to this address. If not specified, the
+ * file will be downloaded to the address specified by the
+ * @eloadaddr environment varaible. A load file can
+ * either be specified by the bootfilename or by the
+ * @efileaddr. A host IP address can be specified when
+ * a bootfilename is specified by prepending it to
+ * bootfilename (ie XX.XX.XX.XX:file).
+ */
U_BOOT_CMD(
tftpboot, 3, 1, do_tftpb,
"boot image via network using TFTP protocol",
@@ -265,7 +282,16 @@ int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

return 0;
}
-
+/**
+ * @cmd: ping
+ * @sect: Networking
+ * @param[r]: addr - IP address to send Echo Request packet
+ * @desc: The ping command checks to see if a specific
+ * IP address is alive by sending an ICMP Echo
+ * Request packet. If the device specified by
+ * addr responds before a timeout occurs, ping
+ * reports that the board is alive.
+ */
U_BOOT_CMD(
ping, 2, 1, do_ping,
"send ICMP ECHO_REQUEST to network host",
diff --git a/common/env_common.c b/common/env_common.c
index 6be3bb0..e55ebce 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -97,9 +97,23 @@ uchar default_environment[] = {
#ifdef CONFIG_ETH5ADDR
"eth5addr=" MK_STR(CONFIG_ETH5ADDR) "\0"
#endif
+#ifdef CONFIG_CMD_NET
+ /**
+ * @env: ipaddr
+ * @sect: Networking
+ * @desc: IP address of this board
+ */
+#endif
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
#endif
+#ifdef CONFIG_CMD_NET
+ /**
+ * @env: serverip
+ * @sect: Networking
+ * @desc: IP address of the server
+ */
+#endif
#ifdef CONFIG_SERVERIP
"serverip=" MK_STR(CONFIG_SERVERIP) "\0"
#endif
@@ -112,9 +126,23 @@ uchar default_environment[] = {
#ifdef CONFIG_ROOTPATH
"rootpath=" MK_STR(CONFIG_ROOTPATH) "\0"
#endif
+#ifdef CONFIG_CMD_NET
+ /**
+ * @env: gatewayip
+ * @sect: Networking
+ * @desc: IP address of the next hop gateway
+ */
+#endif
#ifdef CONFIG_GATEWAYIP
"gatewayip=" MK_STR(CONFIG_GATEWAYIP) "\0"
#endif
+#ifdef CONFIG_CMD_NET
+ /**
+ * @env: netmask
+ * @sect: Networking
+ * @desc: Network mask to reach gateway
+ */
+#endif
#ifdef CONFIG_NETMASK
"netmask=" MK_STR(CONFIG_NETMASK) "\0"
#endif
@@ -124,6 +152,13 @@ uchar default_environment[] = {
#ifdef CONFIG_BOOTFILE
"bootfile=" MK_STR(CONFIG_BOOTFILE) "\0"
#endif
+#ifdef CONFIG_CMD_NET
+ /**
+ * @env: loadaddr
+ * @sect: Networking
+ * @desc: Address in memory to store downloaded files
+ */
+#endif
#ifdef CONFIG_LOADADDR
"loadaddr=" MK_STR(CONFIG_LOADADDR) "\0"
#endif
diff --git a/post/tests.c b/post/tests.c
index 3224f00..1bee185 100644
--- a/post/tests.c
+++ b/post/tests.c
@@ -102,6 +102,14 @@ struct post_test post_list[] =
#endif
#endif
#if CONFIG_POST & CONFIG_SYS_POST_I2C
+ /**
+ * @post: I2C Post
+ * @desc: The I2C POST verifies that a pre-assembled list of devices and
+ * only those devices respond to an I2C bus scan. This list is assembled
+ * in the board-specific config file as the board is developed. If a
+ * device doesn't respond, or a device which is not in the list responds,
+ * the POST will fail.
+ */
{
"I2C test",
"i2c",
@@ -126,6 +134,14 @@ struct post_test post_list[] =
},
#endif
#if CONFIG_POST & CONFIG_SYS_POST_MEMORY
+ /**
+ * @post: Memory Post
+ * @desc:The Memory POST verifies RAM by performing the following tests:
+ * pattern(zeros, ones, 0x5 checkerboard, 0xa checkerboard), bit-flip
+ * pattern, address pattern (offset), and address pattern (~offset).
+ * The POST verifies only small 4Kb regions of RAM around each 1Mb
+ * boundary.
+ */
{
"Memory test",
"memory",
--
1.6.0.4
Wolfgang Denk
2009-07-28 17:52:37 UTC
Permalink
Dear John Schmoller,

In message <310e8398479f23a6bfaceccf6cc86631b7bff4dc.1248798202.git.jschmoller at xes-inc.com> you wrote:
> Add support to a small subset of commands, environment
> variables, and POSTs. These are meant to show the
> syntax and capabilities of the uboot-doc parser.
>
> Signed-off-by: John Schmoller <jschmoller at xes-inc.com>
> ---
> common/cmd_i2c.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> common/cmd_mem.c | 45 +++++++++++++++++++++++++++++++-
> common/cmd_net.c | 30 ++++++++++++++++++++-
> common/env_common.c | 35 +++++++++++++++++++++++++
> post/tests.c | 16 +++++++++++
> 5 files changed, 192 insertions(+), 5 deletions(-)
>
> diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
> index 8f0fc9e..14d394c 100644
> --- a/common/cmd_i2c.c
> +++ b/common/cmd_i2c.c
> @@ -1297,7 +1297,70 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
> }
>
> /***************************************************/
> -
> +/**
> + * @cmd: i2c speed
> + * @sect: I2C
> + * @param[or]: speed - target I2C bus speed
> + * @desc: Show or set I2C bus speed
> + */
> +/**
> + * @cmd: i2c dev
> + * @sect: I2C
> + * @param[or]: dev - I2C device to make current
> + * @desc: Show or set current I2C bus
> + */
> +/**
> + * @cmd: i2c md
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param[or]: # of objects - Numer of bytes to read
> + * @desc: Read from I2C device
> + */
> +/**
> + * @cmd: i2c mm
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @desc: Write to I2C device (auto-incrementing)
> + */
> +/**
> + * @cmd: i2c mw
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param: value - Value to write to I2C address
> + * @param[or]: count - Number of bytes to write
> + * @desc: Write to I2C device (fill)
> + */
> +/**
> + * @cmd: i2c nm
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @desc: Write to I2C device (constant address)
> + */
> +/**
> + * @cmd: i2c crc32
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param: count - Number of bytes to CRC
> + * @desc: Computes the CRC32 checksum of an address range
> + */
> +/**
> + * @cmd: i2c probe
> + * @sect: I2C
> + * @desc: Shows all the devices on the I2C bus
> + */
> +/**
> + * @cmd: i2c loop
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param: # of objects - Number of bytes to loop over
> + * @desc: Looping read of device. Never returns.
> + */

Hm... isn't this basicly duplicating the information you get when
running the "help" command? Then why don't you simply include that
output here, like we do in the DULG?

To me this seems to be a mix of API documentation (which would be
useful, but you do it for the wrong set of functions) and User's
Manual (where it mostly seems to be a duplication of information, and
maintaining redundant information has never been a good idea).

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
It's certainly convenient the way the crime (or condition) of
stupidity carries with it its own punishment, automatically
admisistered without remorse, pity, or prejudice. :-)
-- Tom Christiansen in <559seq$ag1$1 at csnews.cs.colorado.edu>
jschmoller
2009-07-28 20:42:29 UTC
Permalink
On Tue, 2009-07-28 at 19:52 +0200, Wolfgang Denk wrote:
> Dear John Schmoller,
>
> In message <310e8398479f23a6bfaceccf6cc86631b7bff4dc.1248798202.git.jschmoller at xes-inc.com> you wrote:
> > Add support to a small subset of commands, environment
> > variables, and POSTs. These are meant to show the
> > syntax and capabilities of the uboot-doc parser.
> >
> > Signed-off-by: John Schmoller <jschmoller at xes-inc.com>
> > ---
> > common/cmd_i2c.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> > common/cmd_mem.c | 45 +++++++++++++++++++++++++++++++-
> > common/cmd_net.c | 30 ++++++++++++++++++++-
> > common/env_common.c | 35 +++++++++++++++++++++++++
> > post/tests.c | 16 +++++++++++
> > 5 files changed, 192 insertions(+), 5 deletions(-)
> >
> > diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
> > index 8f0fc9e..14d394c 100644
> > --- a/common/cmd_i2c.c
> > +++ b/common/cmd_i2c.c
> > @@ -1297,7 +1297,70 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
> > }
> >
> > /***************************************************/
> > -
> > +/**
> > + * @cmd: i2c speed
> > + * @sect: I2C
> > + * @param[or]: speed - target I2C bus speed
> > + * @desc: Show or set I2C bus speed
> > + */
> > +/**
> > + * @cmd: i2c dev
> > + * @sect: I2C
> > + * @param[or]: dev - I2C device to make current
> > + * @desc: Show or set current I2C bus
> > + */
> > +/**
> > + * @cmd: i2c md
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param[or]: # of objects - Numer of bytes to read
> > + * @desc: Read from I2C device
> > + */
> > +/**
> > + * @cmd: i2c mm
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @desc: Write to I2C device (auto-incrementing)
> > + */
> > +/**
> > + * @cmd: i2c mw
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param: value - Value to write to I2C address
> > + * @param[or]: count - Number of bytes to write
> > + * @desc: Write to I2C device (fill)
> > + */
> > +/**
> > + * @cmd: i2c nm
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @desc: Write to I2C device (constant address)
> > + */
> > +/**
> > + * @cmd: i2c crc32
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param: count - Number of bytes to CRC
> > + * @desc: Computes the CRC32 checksum of an address range
> > + */
> > +/**
> > + * @cmd: i2c probe
> > + * @sect: I2C
> > + * @desc: Shows all the devices on the I2C bus
> > + */
> > +/**
> > + * @cmd: i2c loop
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param: # of objects - Number of bytes to loop over
> > + * @desc: Looping read of device. Never returns.
> > + */
>
> Hm... isn't this basicly duplicating the information you get when
> running the "help" command? Then why don't you simply include that
> output here, like we do in the DULG?
>
> To me this seems to be a mix of API documentation (which would be
> useful, but you do it for the wrong set of functions) and User's
> Manual (where it mostly seems to be a duplication of information, and
> maintaining redundant information has never been a good idea).
>

It's true, I was a little lax on commenting the I2C commands. If I were
to move forward with this documentation tool, I would comment these
commands more thoroughly like I did with the Memory commands.

Thanks,
John
Wolfgang Denk
2009-07-28 21:37:18 UTC
Permalink
Dear John,

in message <1248813749.3915.104.camel at johns> you wrote:
>
> It's true, I was a little lax on commenting the I2C commands. If I were
> to move forward with this documentation tool, I would comment these
> commands more thoroughly like I did with the Memory commands.

Hm... of course I'm biased. Everybody thinks his own solution is the
best of all. On the other hand, the DUTS/DULG setup has been under
continuous development for more than 6 years (8 years if you nclude
the old DocBook based approach). We have used it both for quality
assurance and for documentation purposes with a number of customers.
On our web server you can find board-specific versions for close to 40
different boards (OK, some of these are not maintained any more
[because the respective board vendors don't care]), so you can be
pretty sure that a lot of experience went into this to make this easy
and efficient to handle and to make sure it scales well.

Maybe you find the time to try to get DUTS running for one of your
boards; for the beginning, a manually controlled setup would be
sufficient - running in fully automatic mode like we do in our virtual
lab not needed for such a first test. If you send us a tarball with
the generated log files, we can put these on our web server, so you
can test yourself with minimal effort what such a version of the
documentation looks like.

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Forty two.
John Schmoller
2009-07-28 16:34:03 UTC
Permalink
Add uboot-doc support to the XPedite5370. Incorporates
templates to override the defaults and includes memory
maps.

Signed-off-by: John Schmoller <jschmoller at xes-inc.com>
---
board/xes/xpedite5370/manual/book_info.tmpl | 52 ++++++
board/xes/xpedite5370/manual/booting_linux.tmpl | 179 ++++++++++++++++++++
board/xes/xpedite5370/manual/booting_vxworks.tmpl | 166 ++++++++++++++++++
board/xes/xpedite5370/manual/manual.tmpl | 30 ++++
board/xes/xpedite5370/manual/redundant_images.tmpl | 50 ++++++
board/xes/xpedite5370/manual/scripting.tmpl | 168 ++++++++++++++++++
include/configs/XPEDITE5370.h | 47 +++++
7 files changed, 692 insertions(+), 0 deletions(-)
create mode 100644 board/xes/xpedite5370/manual/book_info.tmpl
create mode 100644 board/xes/xpedite5370/manual/booting_linux.tmpl
create mode 100644 board/xes/xpedite5370/manual/booting_vxworks.tmpl
create mode 100644 board/xes/xpedite5370/manual/manual.tmpl
create mode 100644 board/xes/xpedite5370/manual/redundant_images.tmpl
create mode 100644 board/xes/xpedite5370/manual/scripting.tmpl

diff --git a/board/xes/xpedite5370/manual/book_info.tmpl b/board/xes/xpedite5370/manual/book_info.tmpl
new file mode 100644
index 0000000..3e6ec85
--- /dev/null
+++ b/board/xes/xpedite5370/manual/book_info.tmpl
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<info>
+ <title>${BOARD} U-Boot Manual</title>
+ <subtitle>U-Boot User&apos;s Manual</subtitle>
+ <releaseinfo>U-Boot version: ${VERSION}</releaseinfo>
+ <titleabbrev>${BOARD}</titleabbrev>
+ <pubdate>${DATE}</pubdate>
+ <address>
+ <personname>Extreme Engineering Solutions, Inc.</personname>
+ <street>3225 Demming Way, Suite 120</street>
+ <city>Middleton, </city>
+ <state>WI </state>
+ <postcode>53562-1408 </postcode>
+ <country>USA</country>
+ <phone>Phone: (608) 833-1155</phone>
+ <fax>Fax: (608) 827-6171</fax>
+ <uri>Web: http://xes-inc.com</uri>
+ <email>E-mail: sales at xes-inc.com</email>
+ </address>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="/home/jschmoller/trunk/share/src/images/xes_logo_with_name_left.svg"/>
+ </imageobject>
+ </mediaobject>
+ <legalnotice>
+ <para>
+ U-Boot is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+ </para>
+
+ <para>
+ U-Boot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ </para>
+
+ <para>
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ <orgname>Free Software Foundation, Inc.</orgname>,
+ <address><street>59 Temple Place, Suite 330</street>
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+ <country>USA</country>
+ </address>
+ </para>
+ </legalnotice>
+</info>
+
diff --git a/board/xes/xpedite5370/manual/booting_linux.tmpl b/board/xes/xpedite5370/manual/booting_linux.tmpl
new file mode 100644
index 0000000..d026d1b
--- /dev/null
+++ b/board/xes/xpedite5370/manual/booting_linux.tmpl
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_booting_linux_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Booting Linux</title>
+
+
+ <sect1 xml:id="uboot_booting_linux">
+ <title>Booting Linux with U-Boot</title>
+ <sect2 xml:id="uboot_booting_linux_intro">
+ <title>Booting Linux</title>
+ <para>The following is intended to be a Quick Start guide for booting a
+ Linux kernel. More information can be found in your Linux Manual.
+ </para>
+
+ <para>Your Linux kernel can be booted from either RAM or from Flash.
+ Images booted from RAM will need to be downloaded from the network
+ using <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+ on every reset. Images booted from Flash will be copied from Flash to
+ RAM automatically.
+ </para>
+
+ <sect3 xml:id="uboot_booting_linux_ram">
+ <title>Booting from RAM</title>
+ <para>To boot an image from RAM, you will need to have your Linux
+ kernel and Flat Device Tree image on a TFTP server. See
+ <link linkend="uboot_setup_network">
+ <literal>Networking</literal></link> for more information about
+ TFTP and TFTP servers. Next, you will need to set up your
+ <link linkend="uboot_env_sect_networking">
+ <literal>network environment variables</literal></link> to point to
+ your TFTP server.
+#ifdef CONFIG_CMD_DHCP
+ You can use a DHCP server to accomplish this if
+ your network has one set up using the
+ <link linkend="uboot_cmd_dhcp"><literal>dhcp</literal></link> command.
+#endif
+ Set <link linkend="uboot_env_osfile"><literal>osfile</literal></link>
+ to the path to your Linux kernel on your TFTP server and set
+ <link linkend="uboot_env_fdtfile"><literal>fdtfile</literal></link>
+ to the path to your Flat Device Tree image on your TFTP server.
+ Finally,
+ type <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ <link linkend="uboot_env_bootcmd_net">
+ <literal>bootcmd_net</literal></link> to download and boot your
+ Linux kernel. This option assumes you are booting an NFS file system.
+ </para>
+
+ <para>Your console input/output should look something like this.
+ <screen>
+=> run bootcmd_net
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/jschmoller/uImage-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0x1000000
+Loading: *###############################################################
+ #################################################################
+ #################################################################
+ #################################################################
+ ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/jschmoller/xpedite5370.dtb-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0xc00000
+Loading: *##
+done
+Bytes transferred = 16384 (4000 hex)
+## Booting kernel from Legacy Image at 01000000 ...
+ Image Name: Linux-2.6.23.17-fsl_r1
+ Created: 2008-08-06 16:46:04 UTC
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 3901211 Bytes = 3.7 MB
+ Load Address: 00000000
+ Entry Point: 00000000
+ Verifying Checksum ... OK
+ Uncompressing Kernel Image ... OK
+ </screen>
+ </para>
+ </sect3>
+
+ <sect3 xml:id="uboot_booting_linux_flash">
+ <title>Booting from Flash</title>
+ <para>To boot an image from Flash, you will need to follow a similar
+ procedure to load the Kernel and FDT for the first time. Make sure
+ you have your Kernel and FDT on your TFTP server. Set your
+ <link linkend="uboot_env_sect_networking">
+ <literal>network environment variables</literal></link> to point to
+ your TFTP server. Set
+ <link linkend="uboot_env_osfile"><literal>osfile</literal></link> to
+ the path to your Linux kernel on your TFTP server and set
+ <link linkend="uboot_env_fdtfile"><literal>fdtfile</literal></link>
+ to the path to your Flat Device Tree image on your TFTP server. Then,
+ type <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ <link linkend="uboot_env_prog_os1"><literal>prog_os1</literal></link>
+ to load the Primary OS, or type <link linkend="uboot_cmd_run">
+ <literal>run</literal></link> <link linkend="uboot_env_prog_os2">
+ <literal>prog_os2</literal></link> to load the Secondary OS. Next,
+ you&apos;ll need to load the FDT by running either
+ <link linkend="uboot_env_prog_fdt1">
+ <literal>prog_fdt1</literal></link> or <link linkend="env_prog_fdt2">
+ <literal>prog_fdt2</literal></link>. Once the image and FDT are
+ loaded into Flash, you can boot the Primary Image by typing
+ <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ <link linkend="uboot_env_bootcmd_flash1">
+ <literal>bootcmd_flash1</literal></link> at the prompt or you can
+ boot the Secondary Image by typing <link linkend="uboot_cmd_run">
+ <literal>run</literal></link>
+ <link linkend="uboot_env_bootcmd_flash2">
+ <literal>bootcmd_flash2</literal></link> at the prompt.
+ </para>
+
+ <para>Your console input/output should look something like this.
+ <screen>
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.255.0
+=> setenv ipaddr 10.52.250.134
+=> setenv serverip 10.52.0.33
+=> setenv osfile /home/jschmoller/uImage-XPedite5370-S2.6.23.17-fsl_r1
+=> setenv fdtfile /home/jschmoller/xpedite5370.dtb-XPedite5370-S2.6.23.17-fsl_r1
+=> run prog_os1
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.254.15
+Filename &apos;/home/jschmoller/uImage-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0x1000000
+Loading: #################################################################
+ #################################################################
+ #################################################################
+ #################################################################
+ ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+
+.............................. done
+Erased 30 sectors
+Copy to Flash... done
+Total of 3901275 bytes were the same
+OS PROGRAM SUCCEEDED
+
+=> run prog_fdt1
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134
+Filename &apos;/home/jschmoller/xpedite5370.dtb-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0xc00000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+
+. done
+Erased 1 sectors
+Copy to Flash... done
+Total of 16384 bytes were the same
+FDT PROGRAM SUCCEEDED
+=> run bootcmd_flash1
+## Booting kernel from Legacy Image at fef00000 ...
+ Image Name: Linux-2.6.23.17-fsl_r1
+ Created: 2008-08-06 16:46:04 UTC
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 3901211 Bytes = 3.7 MB
+ Load Address: 00000000
+ Entry Point: 00000000
+ Verifying Checksum ... OK
+ Uncompressing Kernel Image ... OK
+ </screen>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/board/xes/xpedite5370/manual/booting_vxworks.tmpl b/board/xes/xpedite5370/manual/booting_vxworks.tmpl
new file mode 100644
index 0000000..c10ba6f
--- /dev/null
+++ b/board/xes/xpedite5370/manual/booting_vxworks.tmpl
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_booting_vxworks_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Booting VxWorks</title>
+
+ <sect1 xml:id="uboot_booting_vxworks">
+ <title>Booting VxWorks with U-Boot</title>
+ <sect2 os="vxworks" xml:id="uboot_booting_vxworks_intro">
+ <title>VxWorks</title>
+
+ <para>The following is intended to be a Quick Start guide for booting a
+ VxWorks image. More information can be found in your VxWorks Manual.
+ </para>
+
+ <para>VxWorks images can be booted from either RAM or Flash. VxWorks
+ images also come in a uImage format and an ELF format. The boot
+ command for an ELF image is <link linkend="uboot_cmd_bootvx">
+ <literal>bootvx</literal></link> and the boot command for a uImage is
+ <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>.
+ </para>
+
+ <sect3 xml:id="uboot_booting_vxworks_ram">
+ <title>Booting from RAM</title>
+ <para>VxWorks requires a string of arguments to be passed to it in
+ order to function properly. To boot from RAM, begin by setting the
+ <link linkend="uboot_env_root_args">
+ <literal>root_args</literal></link> string to something like the
+ following: <literal>motetsec(0,0)host:&lt;Path to VxWorks image&gt;
+ h=&lt;Host IP&gt; e=&lt;Board IP&gt;:&lt;Netmask&gt; u=drives
+ pw=drives</literal> and the <link linkend="uboot_env_misc_args">
+ <literal>misc_args</literal></link> to <literal>f=0x0</literal>.
+ Replace the items in &lt;&gt;&apos;s with the appropriate values.
+ Next, configure your <link linkend="uboot_env_sect_networking">
+ <literal>network environment variables</literal></link> to point to
+ your TFTP server. Download the VxWorks image by typing
+ <link linkend="uboot_cmd_tftpboot"><literal>tftpboot</literal></link>
+ <literal>0x1000000 &lt;Path to VxWorks image&gt;</literal>. Finally,
+ use the boot command specified above and type
+ <literal>&lt;Boot Command&gt; 0x1000000</literal> at the prompt to
+ finish booting your VxWorks image.
+ </para>
+
+ <para>Your console input/output should look something like this.
+ <screen>
+=> setenv root_args motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives
+=> setenv misc_args f=0x0
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.255.0
+=> setenv ipaddr 10.52.250.134
+=> setenv serverip 10.52.0.33
+=> tftp 1000000 /home/mstarzewski/xes8572-vxWorks.st
+Enet starting in 1000BT/FD
+
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/mstarzewski/xes8572-vxWorks.st&apos;.
+Load address: 0x1000000
+Loading: #################################################################
+ ######################################################
+done
+Bytes transferred = 1740761 (1a8fd9 hex)
+=> bootvx 1000000
+## Ethernet MAC address not copied to NV RAM
+Loading .text @ 0x00100000 (1263808 bytes)
+Loading .sdata2 @ 0x002348c0 (432 bytes)
+Loading .data @ 0x00234a70 (128320 bytes)
+Loading .sdata @ 0x00253fb0 (2752 bytes)
+Clearing .sbss @ 0x00254a70 (2144 bytes)
+Clearing .bss @ 0x002552d0 (252128 bytes)
+## Using bootline (@ 0x4200): motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives f=0x0
+## Starting vxWorks at 0x00100000 ...
+Target Name: vxTarget
+...
+ </screen>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Booting from Flash</title>
+ <para>VxWorks requires a string of arguments to be passed to it in
+ order to function properly. To boot from Flash, begin by setting the
+ <link linkend="uboot_env_root_args">
+ <literal>root_args</literal></link> string to something like the
+ following: <literal>motetsec(0,0)host:
+ &lt;Path to VxWorks image&gt; h=&lt;Host IP&gt; e=&lt;Board IP&gt;:
+ &lt;Netmask&gt; u=drives pw=drives</literal> and the
+ <link linkend="uboot_env_misc_args">
+ <literal>misc_args</literal></link> to <literal>f=0x0</literal>.
+ Replace the items in &lt;&gt;&apos;s with the appropriate values.
+ Next, configure your <link linkend="uboot_env_sect_networking">
+ <literal>network environment variables</literal></link> to point to
+ your TFTP server. Download the VxWorks image by typing
+ <link linkend="uboot_cmd_tftpboot"><literal>tftpboot</literal></link>
+ <literal>1000000 &lt;Path to VxWorks image&gt;</literal>. To program
+ the image to Flash, start by clearing space for it. For the Primary
+ image, type <link linkend="uboot_cmd_erase"><literal>erase</literal>
+ </link> <literal>fef00000 +&amp;</literal>
+ <link linkend="uboot_env_filesize"><literal>filesize</literal></link>
+ and for the Secondary image, type <link linkend="uboot_cmd_erase">
+ <literal>erase</literal></link> <literal>f6f00000</literal>
+ <link linkend="uboot_env_filesize">
+ <literal>+$filesize</literal></link>. Next, copy the image from RAM
+ to Flash. Type <link linkend="uboot_cmd_cp">
+ <literal>cp.b</literal></link>
+ <literal>1000000 fef00000 $filesize</literal> for the Primary image
+ and <link linkend="uboot_cmd_cp"><literal>cp.b</literal></link>
+ <literal>1000000 f6f00000 $filesize</literal> for the Secondary image.
+ Finally, use the boot command specified above and type
+ <literal>&lt;Boot Command&gt; fef00000</literal> or
+ <literal>&lt;Boot Command&gt; f6f00000</literal> at the prompt to
+ finish booting your VxWorks image.
+ </para>
+
+ <para>Your console input/output should look something like this.
+ <screen>
+=> setenv root_args motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives
+=> setenv misc_args f=0x0
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.255.0
+=> setenv ipaddr 10.52.250.134
+=> setenv serverip 10.52.0.33
+=> tftp 1000000 /home/mstarzewski/xes8572-vxWorks.st
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/mstarzewski/xes8572-vxWorks.st&apos;.
+Load address: 0x1000000
+Loading: #################################################################
+ ######################################################
+done
+Bytes transferred = 1740761 (1a8fd9 hex)
+=> erase fef00000 +$filesize
+
+.............. done
+Erased 14 sectors
+=> cp.b 1000000 fef00000 $filesize
+
+Copy to Flash... done
+=> bootvx fef00000
+## Ethernet MAC address not copied to NV RAM
+Loading .text @ 0x00100000 (1296720 bytes)
+Loading .sdata2 @ 0x0023c950 (192 bytes)
+Loading .data @ 0x0023ca20 (136656 bytes)
+Loading .sdata @ 0x0025dff0 (2384 bytes)
+Clearing .sbss @ 0x0025e940 (2240 bytes)
+Clearing .bss @ 0x0025f200 (251184 bytes)
+## Using bootline (@ 0x4200): motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives f=0x0
+## Starting vxWorks at 0x00100000 ...
+Target Name: vxTarget
+...
+ </screen>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
+
+
diff --git a/board/xes/xpedite5370/manual/manual.tmpl b/board/xes/xpedite5370/manual/manual.tmpl
new file mode 100644
index 0000000..dfac2e6
--- /dev/null
+++ b/board/xes/xpedite5370/manual/manual.tmpl
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<book xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ version="5.0"
+ xml:id="uboot_manual">
+
+ <xi:include href="${TOPDIR}/doc/manual/book_info.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/introduction.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/setup.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/booting_linux.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/booting_vxworks.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/memory_resources.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/redundant_images.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/posts.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/environment_variables.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/commands.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/scripting.xml"/>
+
+</book>
diff --git a/board/xes/xpedite5370/manual/redundant_images.tmpl b/board/xes/xpedite5370/manual/redundant_images.tmpl
new file mode 100644
index 0000000..af6000c
--- /dev/null
+++ b/board/xes/xpedite5370/manual/redundant_images.tmpl
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_redundant_images_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Redundant Images</title>
+
+ <sect1 xml:id="uboot_redundant_images">
+ <title>Using Redundant Images with U-Boot</title>
+ <para>The ${BOARD} has two Flash banks, which can be used to hold dual or
+ redundant images. The board is configured with dual U-Boot images (see
+ <link linkend="uboot_memmap_recommended_flash_memory_map">
+ <literal>U-Boot Recommended Memory Regions</literal></link>). It can
+ also be configured with dual or redundant OS images. Sometimes it is
+ advantageous to store two different kernels in the primary and secondary
+ partitions. For example, the most recent version of the user&apos;s kernel
+ image could be stored in one partition, while a previous stable version
+ is kept in the other.
+ </para>
+
+ <para>Or, one kernel could be compiled with debug enabled
+ and the other without. Or the two OS partitions can also be used for
+ redundancy. The U-Boot uImage file has support for checksumming and can
+ be used to verify the integrity of an image. If the checksum fails on one
+ partition, U-Boot can be configured to boot the other partition&apos;s
+ image. This fallback image could be a carbon copy of the first, or could
+ send out notification of the first image&apos;s failure. Fallback is
+ easily configured; the fallback image does not necessarily need to be
+ from the same boot device.
+ </para>
+
+ <para>For example, if the checksum fails on an
+ image in flash, the fallback image could be downloaded over Ethernet.
+ For example, a simple script for booting one uImage and failing over to
+ the second could be written as
+ <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+ <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+ <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+ <literal>0xfef00000\;</literal>
+ <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+ <literal>0xf6f00000</literal>. In this example, U-Boot will attempt to
+ boot the Primary OS and will not return if the checksum is valid so
+ Secondary OS will not be called. If the Primary OS is corrupt, U-Boot
+ will return to a prompt where the Secondary OS will be executed.
+ </para>
+ </sect1>
+</chapter>
+
+
+
diff --git a/board/xes/xpedite5370/manual/scripting.tmpl b/board/xes/xpedite5370/manual/scripting.tmpl
new file mode 100644
index 0000000..f5e8a43
--- /dev/null
+++ b/board/xes/xpedite5370/manual/scripting.tmpl
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_scripting_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Scripting</title>
+
+ <sect1 xml:id="uboot_scripting">
+ <title>Scripting in U-Boot</title>
+ <sect2 xml:id="uboot_scripting_dollar_sign">
+ <title>Variable Expansion with $</title>
+ <para>Variable substitution can be done with the $ character. For
+ instance, <link linkend="uboot_cmd_printenv">
+ <literal>printenv</literal></link> <link linkend="uboot_env_bootargs">
+ <literal>bootargs</literal></link> could also be executed with
+ <link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+ <link linkend="uboot_env_bootargs"><literal>$bootargs</literal></link>.
+ More powerfully, this variable substitution can be used in scripting.
+ See the example in the next section.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_scripting_conditionals">
+ <title>Conditionals</title>
+ <para>U-Boot has a scripting language which can be used to customize
+ command execution. It contains if..then..else..fi, for..do..done,
+ while..do..done and until..do..done control flow operations.
+ </para>
+
+ <para>As an example, take the X-ES environment variable
+ <link linkend="uboot_env_bootcmd_net">
+ <literal>bootcmd_net</literal></link>.
+ <screen>
+bootcmd_net=run set_bootargs; $download_cmd $osaddr $osfile; if test $? -eq 0;
+then if test -n $fdtaddr; then $download_cmd $fdtaddr $fdtfile;
+if test $? -eq 0; then bootm $osaddr - $fdtaddr; else; echo FDT DOWNLOAD FAILED;
+fi; else; bootm $osaddr; fi; else; echo OS DOWNLOAD FAILED; fi;
+ </screen>
+ To walk through the script, we start with
+ <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ <link linkend="uboot_env_set_bootargs">
+ <literal>set_bootargs</literal></link>, which executes the commands
+ stored in <link linkend="uboot_env_set_bootargs">
+ <literal>set_bootargs</literal></link>. Next, we execute the command
+ stored in <link linkend="uboot_env_download_cmd">
+ <literal>download_cmd</literal></link> which in most cases is
+ <link linkend="uboot_cmd_dhcp"><literal>dhcp</literal></link> or
+ <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link> and
+ download the file stored in <link linkend="uboot_env_osfile">
+ <literal>osfile</literal></link> to the address stored in
+ <link linkend="uboot_env_osaddr"><literal>osaddr</literal></link>. The
+ next step is interesting. We start an <literal>if</literal> conditional,
+ and use the <link linkend="uboot_cmd_test">
+ <literal>test</literal></link> command to check to see if the return
+ value (<literal>$?</literal>) of the
+ <link linkend="uboot_env_download_cmd">
+ <literal>download_cmd</literal></link> is <literal>0</literal>. If it
+ isn&apos;t, meaning the download failed, we find the matching
+ <literal>then</literal> and see that we echo
+ <literal>DOWNLOAD FAILED</literal>. If it is <literal>0</literal>
+ meaning the download completed successfully, we start a new
+ <literal>if</literal> conditional and test to see if
+ <link linkend="uboot_env_fdtaddr"><literal>fdtaddr</literal></link> is
+ defined. If it is, use <link linkend="uboot_env_download_cmd">
+ <literal>download_cmd</literal></link> to download the file stored in
+ <link linkend="uboot_env_fdtfile"><literal>fdtfile</literal></link> to
+ the address stored in <link linkend="uboot_env_fdtaddr">
+ <literal>fdtaddr</literal></link>. Again, we verify that the download
+ completed successfully. If everything has worked up until now, we
+ complete the script with
+ <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+ <link linkend="uboot_env_osaddr"><literal>osaddr</literal></link>
+ <literal>-</literal> <link linkend="uboot_env_fdtaddr">
+ <literal>fdtaddr</literal></link> and boot the image we just downloaded.
+ If <link linkend="uboot_env_fdtaddr"><literal>fdtaddr</literal></link>
+ had been undefined, we would have executed
+ <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+ <link linkend="uboot_env_osaddr"><literal>osaddr</literal></link>
+ instead.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_scripting_and_or">
+ <title>&amp;&amp; and ||</title>
+ <para>Another feature of the U-Boot scripting language are the
+ <literal>&amp;&amp;</literal> and <literal>||</literal> functions. The
+ <literal>&amp;&amp;</literal> is an if and only if command. For
+ instance, the command
+ <link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+ <literal>$do_stuff &amp;&amp;</literal>
+ <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ <literal>$do_stuff</literal> would run <literal>do_stuff</literal>
+ only if the <link linkend="uboot_cmd_echo">
+ <literal>echo</literal></link> command returned successfully, meaning
+ that <literal>do_stuff</literal> is defined. If
+ <literal>do_stuff</literal> was not defined, the
+ <link linkend="uboot_cmd_run"><literal>run</literal></link> command
+ would not be executed. Similarly, the <literal>||</literal> command will
+ execute the second command only if the first command fails. For
+ instance, if <literal>bank1</literal> stored the location of the OS in
+ flash bank 1 and <literal>bank2</literal> stored the location of the
+ OS in flash bank 2, the following command would try to boot the image
+ in bank 1. If unsuccessful it would boot the image in bank 2. If that
+ failed, it would attempt to download the file over the network, and if
+ that succeeded, it would boot the image.
+ <screen>
+<literal>bootm $bank1 || bootm $bank2 || tftp $osaddr $osfile &amp;&amp; bootm</literal>
+ </screen>
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_scripting_quotes_and_ticks">
+ <title>Quotes and tick marks</title>
+ <para>Quotation marks and tick marks also have a special meaning in
+ U-Boot scripting. Let&apos;s say you wanted to create an environment
+ variable called <literal>do_stuff</literal> and this variable was going
+ to run <link linkend="uboot_env_set_bootargs">
+ <literal>set_bootargs</literal></link> then run
+ <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>.
+ Depending on how you format the command, it&apos;s execution will
+ change. You could save the command as
+ <screen>
+setenv do_stuff &quot;run $set_bootargs; run $bootcmd&quot;
+ </screen>
+ When you <link linkend="uboot_cmd_printenv">
+ <literal>printenv</literal></link> <literal>do_stuff</literal> you
+ should see something like
+ <screen>
+do_stuff=run setenv bootargs ${console_args} ${root_args} ${misc_args}; run run bootcmd_flash1
+ </screen>
+ Notice how the variables specified with the $ were expanded. Now, if
+ you do the same thing, replacing the quotation marks with tick marks,
+ <screen>
+setenv do_stuff &apos;run $set_bootargs; run $bootcmd&apos;
+ </screen>
+ you will see different behavior.
+ <screen>
+do_stuff=run $set_bootargs; run $bootcmd
+ </screen>
+ Notice how the variables specified with the $ were not expanded. In
+ most cases, this would be the desired behavior as these variables
+ would be expanded when they are executed. Then, any changes made to
+ <link linkend="uboot_env_set_bootargs">
+ <literal>set_bootargs</literal></link> and
+ <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+ between the time that <literal>do_stuff</literal> was set and it was
+ run would change the functionality of <literal>do_stuff</literal>.
+ For example,
+ <screen>
+setenv printscript print
+setenv do_stuff &quot;$printscript&quot;
+setenv printscript echo do nothing
+run do_stuff
+ </screen>
+ would result in printing all the environment variables, rather than
+ printing &quot;do nothing&quot;, whereas
+ <screen>
+setenv printscript print
+setenv do_stuff &apos;$printscript&apos;
+setenv printscript echo do nothing
+run do_stuff
+ </screen>
+ would result in printing &quot;do nothing&quot;.
+ </para>
+ </sect2>
+ </sect1>
+</chapter>
+
diff --git a/include/configs/XPEDITE5370.h b/include/configs/XPEDITE5370.h
index acb62ad..9322789 100644
--- a/include/configs/XPEDITE5370.h
+++ b/include/configs/XPEDITE5370.h
@@ -70,6 +70,15 @@
#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE
#define CONFIG_VERY_BIG_RAM

+/**
+ * @memmap: EEPROM Memory Map
+ * @entry: 0x2000: 0x3fff: Unused/Customer Available
+ * @entry: 0x1000: 0x1fff: Backup U-Boot Environment
+ * @entry: 0x0200: 0x0fff: Board Specific Information (SPD, etc.)
+ * @entry: 0x0100: 0x01ff: VxWorks Bootline (Optional)
+ * @entry: 0x0000: 0x00ff: Reset Configuration Data (Optional)
+ */
+
#ifndef __ASSEMBLY__
extern unsigned long get_board_sys_clk(unsigned long dummy);
extern unsigned long get_board_ddr_clk(unsigned long dummy);
@@ -117,6 +126,24 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
* 0xf800_0000 0xffff_ffff NOR Flash 1 128M non-cacheable
*/

+/**
+ * @memmap: System Memory Map
+ * @entry: 0xf800_0000: 0xffff_ffff: NOR Flash 1
+ * @entry: 0xf000_0000: 0xf7ff_ffff: NOR Flash 2
+ * @entry: 0xef90_0000: 0xefff_ffff: Reserved
+ * @entry: 0xef80_0000: 0xef8f_ffff: NAND Flash
+ * @entry: 0xef10_0000: 0xef7f_ffff: Reserved
+ * @entry: 0xef00_0000: 0xef0f_ffff: CCSR/IMMR
+ * @entry: 0xe900_0000: 0xeeff_ffff: Reserved
+ * @entry: 0xe880_0000: 0xe8ff_ffff: PCI Express 2 I/O
+ * @entry: 0xe800_0000: 0xe87f_ffff: PCI Express 1 I/O
+ * @entry: 0xe000_0000: 0xe7ff_ffff: SRAM/SSRAM/L1 Cache
+ * @entry: 0xd000_0000: 0xdfff_ffff: Reserved
+ * @entry: 0xc000_0000: 0xcfff_ffff: PCI Express 2 Memory
+ * @entry: 0x8000_0000: 0xbfff_ffff: PCI Express 1 Memory
+ * @entry: 0x0000_0000: 0x7fff_ffff: DDR2 SDRAM
+ */
+
#define CONFIG_SYS_LBC_LCRR (LCRR_CLKDIV_4 | LCRR_EADC_3)

/*
@@ -147,6 +174,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
#define CONFIG_SYS_FLASH_AUTOPROTECT_LIST { {0xfff40000, 0xc0000}, \
{0xf7f40000, 0xc0000} }
#define CONFIG_SYS_MONITOR_BASE TEXT_BASE /* start of monitor */
+#define CONFIG_REDUNDANT_MONITORS

/*
* Chip select configuration
@@ -435,6 +463,10 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128k (one sector) for env */
#define CONFIG_ENV_SIZE 0x8000
#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - (256 * 1024))
+#define CONFIG_IPADDR 0.0.0.0
+#define CONFIG_SERVERIP 0.0.0.0
+#define CONFIG_GATEWAYIP 0.0.0.0
+#define CONFIG_NETMASK 255.255.0.0

/*
* Flash memory map:
@@ -450,6 +482,21 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
* f6f00000 - f7efffff Sec OS image (16MB)
* f0000000 - f6efffff Sec OS Use/Filesystem (111MB)
*/
+
+/**
+ * @memmap: Recommended Flash Memory Map
+ * @entry: 0xfff8_0000: 0xffff_ffff: Primary U-Boot Image
+ * @entry: 0xfff4_0000: 0xfff7_ffff: Primary U-Boot Environment
+ * @entry: 0xfff0_0000: 0xfff3_ffff: Primary Flat-Device Tree
+ * @entry: 0xfef0_0000: 0xffef_ffff: Primary Operating System Image
+ * @entry: 0xf800_0000: 0xfeef_ffff: Primary Operating System Use/Filesystem
+ * @entry: 0xf7f8_0000: 0xf7ff_ffff: Secondary U-Boot Image
+ * @entry: 0xf7f4_0000: 0xf7f7_ffff: Secondary U-Boot Environment
+ * @entry: 0xf7f0_0000: 0xf7f3_ffff: Secondary Flat-Device Tree
+ * @entry: 0xf6f0_0000: 0xf7ef_ffff: Secondary Operating System Image
+ * @entry: 0xf000_0000: 0xf6ef_ffff: Secondary Operating System Use/Filesystem
+ */
+
#define CONFIG_UBOOT1_ENV_ADDR MK_STR(0xfff80000)
#define CONFIG_UBOOT2_ENV_ADDR MK_STR(0xf7f80000)
#define CONFIG_FDT1_ENV_ADDR MK_STR(0xfff00000)
--
1.6.0.4
John Schmoller
2009-07-28 16:34:01 UTC
Permalink
Initial support of U-Boot User's Manual documentation generator.
It makes use of the C pre-processor to gather context, and then
the doc-stream.pl program parses out interesting comments for
consideration by uboot-doc, which creates DocBook style XML from
autogenerated files as well as the template files. Template
files are pseudo-XML with precompiler directives. Also includes
a stylesheet wrapper for manual customization.

Signed-off-by: John Schmoller <jschmoller at xes-inc.com>
---
Makefile | 2 +
config.mk | 1 +
doc/manual/85xx_program_flow.tmpl | 74 ++++
doc/manual/book_info.tmpl | 35 ++
doc/manual/booting_linux.tmpl | 249 +++++++++++
doc/manual/config.mk | 74 ++++
doc/manual/doc-stream.pl | 34 ++
doc/manual/introduction.tmpl | 136 ++++++
doc/manual/manual.tmpl | 26 ++
doc/manual/scripting.tmpl | 154 +++++++
doc/manual/setup.tmpl | 294 +++++++++++++
doc/manual/uboot-doc | 866 +++++++++++++++++++++++++++++++++++++
doc/manual/uboot_manual.xsl | 286 ++++++++++++
rules.mk | 7 +
14 files changed, 2238 insertions(+), 0 deletions(-)
create mode 100644 doc/manual/85xx_program_flow.tmpl
create mode 100644 doc/manual/book_info.tmpl
create mode 100644 doc/manual/booting_linux.tmpl
create mode 100644 doc/manual/config.mk
create mode 100644 doc/manual/doc-stream.pl
create mode 100644 doc/manual/introduction.tmpl
create mode 100644 doc/manual/manual.tmpl
create mode 100644 doc/manual/scripting.tmpl
create mode 100644 doc/manual/setup.tmpl
create mode 100644 doc/manual/uboot-doc
create mode 100644 doc/manual/uboot_manual.xsl

diff --git a/Makefile b/Makefile
index ef535ed..ff4f242 100644
--- a/Makefile
+++ b/Makefile
@@ -153,6 +153,7 @@ ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
+sinclude $(obj)doc/manual/config.mk

# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
@@ -3646,6 +3647,7 @@ clean:
@rm -f $(obj)include/bmp_logo.h
@rm -f $(obj)nand_spl/{u-boot-spl,u-boot-spl.map,System.map}
@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map}
+ @rm -f $(obj)doc/manual/{*.xml,*.html,*.fo,*.pdf,params.xsl}
@rm -f $(TIMESTAMP_FILE) $(VERSION_FILE)
@find $(OBJTREE) -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' \
diff --git a/config.mk b/config.mk
index fd56621..fb8bed0 100644
--- a/config.mk
+++ b/config.mk
@@ -96,6 +96,7 @@ BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif
+export BOARDDIR
ifdef BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif
diff --git a/doc/manual/85xx_program_flow.tmpl b/doc/manual/85xx_program_flow.tmpl
new file mode 100644
index 0000000..1010780
--- /dev/null
+++ b/doc/manual/85xx_program_flow.tmpl
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <sect2 xmlns="http://docbook.org/ns/docbook"
+ xml:id="uboot_setup_prog_flow">
+ <title>U-Boot Program Flow</title>
+ <para>U-Boot follows the following program flow.</para>
+ <orderedlist>
+ <listitem>
+ <para>Reset</para>
+ </listitem>
+ <listitem>
+ <para>Initialize Processor</para>
+ </listitem>
+ <listitem>
+ <para>Set up data cache as stack</para>
+ </listitem>
+ <listitem>
+ <para>Set up TLBs and LAWs</para>
+ </listitem>
+ <listitem>
+ <para>Initialize U-Boot environment</para>
+ </listitem>
+ <listitem>
+ <para>Initialize serial port</para>
+ </listitem>
+ <listitem>
+ <para>Initialize I2C</para>
+ </listitem>
+ <listitem>
+ <para>Initialize DRAM</para>
+ </listitem>
+ <listitem>
+ <para>Relocate from Flash to RAM</para>
+ </listitem>
+ <listitem>
+ <para>Set up data cache</para>
+ </listitem>
+ <listitem>
+ <para>Initialize Flash Structure</para>
+ </listitem>
+ <listitem>
+ <para>Initialize malloc area</para>
+ </listitem>
+ <listitem>
+ <para>Initialize NAND device</para>
+ </listitem>
+ <listitem>
+ <para>Initialize PCI</para>
+ </listitem>
+ <listitem>
+ <para>Initialize Vector Table</para>
+ </listitem>
+ <listitem>
+ <para>Initialize Ethernet</para>
+ </listitem>
+#ifdef CONFIG_PREBOOT
+ <listitem>
+ <para>Exectue <link linkend="env_preboot"><literal>preboot</literal>
+ </link> environment variable
+ </para>
+ </listitem>
+#endif
+ <listitem>
+ <para>Wait <link linkend="env_bootdelay"><literal>bootdelay</literal>
+ </link> seconds to stop autoboot
+ </para>
+ </listitem>
+ <listitem>
+ <para>If not canceled, execute <link linkend="env_bootcmd">
+ <literal>bootcmd</literal></link> or enter main loop.
+ </para>
+ </listitem>
+ </orderedlist>
+ </sect2>
diff --git a/doc/manual/book_info.tmpl b/doc/manual/book_info.tmpl
new file mode 100644
index 0000000..a4cec17
--- /dev/null
+++ b/doc/manual/book_info.tmpl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<info>
+ <title>${BOARD} U-Boot Manual</title>
+ <subtitle>U-Boot User's Manual</subtitle>
+ <releaseinfo>U-Boot version: ${VERSION}</releaseinfo>
+ <titleabbrev>${BOARD}</titleabbrev>
+ <pubdate>${DATE}</pubdate>
+ <legalnotice>
+ <para>
+ U-Boot is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+ </para>
+
+ <para>
+ U-Boot is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ </para>
+
+ <para>
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ <orgname>Free Software Foundation, Inc.</orgname>,
+ <address><street>59 Temple Place, Suite 330</street>
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+ <country>USA</country>
+ </address>
+ </para>
+ </legalnotice>
+</info>
+
diff --git a/doc/manual/booting_linux.tmpl b/doc/manual/booting_linux.tmpl
new file mode 100644
index 0000000..e0ab37c
--- /dev/null
+++ b/doc/manual/booting_linux.tmpl
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_booting_linux_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Booting Linux</title>
+
+
+ <sect1 xml:id="uboot_booting_linux">
+ <title>Booting Linux with U-Boot</title>
+ <sect2 xml:id="uboot_booting_linux_intro">
+ <title>Booting Linux</title>
+ <para>The following is intended to be a Quick Start guide for booting a
+ Linux kernel. More information can be found in your Linux Manual.
+ </para>
+
+ <para>Your Linux kernel can be booted from either RAM or from Flash.
+ Images booted from RAM will need to be downloaded from the network
+ using <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+ on every reset. Images booted from Flash will be copied from Flash to
+ RAM automatically.
+ </para>
+
+ <sect3 xml:id="uboot_booting_linux_ram">
+ <title>Booting from RAM</title>
+ <para>To boot an image from RAM, you will need to have your Linux
+ kernel
+#ifdef CONFIG_OF_LIBFDT
+ and Flat Device Tree image
+#endif
+ on a TFTP server. See
+ <link linkend="uboot_setup_network">
+ <literal>Networking</literal></link> for more information about
+ TFTP and TFTP servers. Next, you will need to set up your
+ <link linkend="uboot_env_sect_networking">
+ <literal>network environment variables</literal></link> to point to
+ your TFTP server.
+#ifdef CONFIG_CMD_DHCP
+ You can use a DHCP server to accomplish this if
+ your network has one set up using the
+ <link linkend="uboot_cmd_dhcp"><literal>dhcp</literal></link> command.
+#endif
+ Download the Linux kernel using the
+ <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+ command.
+ <screen>
+tftp 10000000 &lt;Path to Linux Kernel&gt;
+ </screen>
+#ifdef CONFIG_OF_LIBFDT
+ Download the Flat Device Tree image using the
+ <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+ command.
+ <screen>
+tftp c000000 &lt;Path to Flat Device Tree image&gt;
+ </screen>
+#endif
+ Adjust the download address based on the size of your kernel image.
+ Consult your Linux manual for the recommended
+ <link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>.
+ Set the <link linkend="uboot_env_bootargs">
+ <literal>bootargs</literal></link> using the
+ <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+ command. Finally, boot your kernel image.
+ <screen>
+#ifdef CONFIG_OF_LIBFDT
+bootm 10000000 - c000000
+#else
+bootm 10000000
+#endif
+ </screen>
+ Since we didn't disguss downloading a file system, this option
+ assumes you are booting an NFS file system.
+ </para>
+
+ <para>Your console input/output should look something like this.
+ <screen>
+=> setenv serverip 10.52.0.33
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.0.0
+=> setenv ipaddr 10.52.4.240
+=> tftp 10000000 /home/jschmoller/uImage
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/uImage'.
+Load address: 0x10000000
+Loading: #################################################################
+ #################################################################
+ #################################################################
+ #################################################################
+ ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+#ifdef CONFIG_OF_LIBFDT
+=> tftp c000000 /home/jschmoller/dtb
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/dtb'.
+Load address: 0xc000000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+#endif
+=> setenv bootargs console=ttyS0,115200 root=/dev/nfs rw ip=on
+#ifdef CONFIG_OF_LIBFDT
+=> bootm 10000000 - c000000
+#else
+=> bootm 10000000
+#endif
+## Booting kernel from Legacy Image at 10000000 ...
+ Image Name: Linux-2.6.23.17-fsl_r1
+ Created: 2008-08-06 16:46:04 UTC
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 3901211 Bytes = 3.7 MB
+ Load Address: 00000000
+ Entry Point: 00000000
+ Verifying Checksum ... OK
+ Uncompressing Kernel Image ... OK
+ </screen>
+ </para>
+ </sect3>
+
+ <sect3 xml:id="uboot_booting_linux_flash">
+ <title>Booting from Flash</title>
+ <para>To boot an image from Flash, you will need to follow a similar
+ procedure to load the Kernel
+#ifdef CONFIG_OF_LIBFDT
+ and FDT
+#endif
+ for the first time. Make sure you have your Kernel
+#ifdef CONFIG_OF_LIBFDT
+ and FDT
+#endif
+ on your TFTP server. Set your
+ <link linkend="uboot_env_sect_networking">
+ <literal>network environment variables</literal></link> to point to
+ your TFTP server. Download the Linux kernel using the
+ <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+ command and then erase Flash and copy it using the
+ <link linkend="uboot_cmd_erase"><literal>erase</literal></link> and
+ <link linkend="uboot_cmd_cp"><literal>cp</literal></link> commands.
+ <screen>
+tftp 10000000 &lt;Path to Linux Kernel&gt;
+erase &lt;Flash start + 1000000&gt; +$filesize
+cp.b 10000000 &lt;Flash start + 1000000&gt; $filesize
+ </screen>
+#ifdef CONFIG_OF_LIBFDT
+ Download the Flat Device Tree image using the
+ <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+ command.
+ <screen>
+tftp c000000 &lt;Path to Flat Device Tree image&gt;
+erase &lt;Flash start&gt; +$filesize
+cp.b c000000 &lt;Flash start&gt; $filesize
+ </screen>
+#endif
+ Consult your Linux manual for the recommended
+ <link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>.
+ Set the <link linkend="uboot_env_bootargs">
+ <literal>bootargs</literal></link> using the
+ <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+ command and then save them using <link linkend="uboot_cmd_saveenv">
+ <literal>saveenv</literal></link>. Set up your
+ <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+ environment variable to automatically boot the Linux kernel.
+ <screen>
+#ifdef CONFIG_OF_LIBFDT
+setenv bootcmd bootm &lt;Flash start + 1000000&gt; - &lt;Flash start&gt;
+#else
+setenv bootcmd bootm &lt;Flash start + 1000000&gt;
+#endif
+ </screen>
+ Finally, boot your kernel image by resetting the board.
+ Since we didn't disguss downloading a file system, this option
+ assumes you are booting an NFS file system.
+ </para>
+
+ <para>Your console input/output should look something like this.
+ <screen>
+=> setenv serverip 10.52.0.33
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.0.0
+=> setenv ipaddr 10.52.4.240
+=> tftp 10000000 /home/jschmoller/uImage
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/uImage'.
+Load address: 0x10000000
+Loading: #################################################################
+ #################################################################
+ #################################################################
+ #################################################################
+ ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+=> erase f9000000 +$filesize
+
+.............................. done
+Erased 30 sectors
+=> cp.b 10000000 f9000000 $filesize
+Copy to Flash... done
+#ifdef CONFIG_OF_LIBFDT
+=> tftp c000000 /home/jschmoller/dtb
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/dtb'.
+Load address: 0xc000000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+=> erase f8000000 +$filesize
+
+. done
+Erased 1 sectors
+=> cp.b c000000 f8000000 $filesize
+Copy to Flash... done
+#endif
+=> setenv bootargs console=ttyS0,115200 root=/dev/nfs rw ip=on
+#ifdef CONFIG_OF_LIBFDT
+=> setenv bootcmd bootm f9000000 - f8000000
+#else
+=> setenv bootcmd bootm f9000000
+#endif
+=> saveenv
+=> reset
+&lt;Board resets&gt;
+Hit any key to stop autoboot: 0
+## Booting kernel from Legacy Image at f9000000 ...
+ Image Name: Linux-2.6.23.17-fsl_r1
+ Created: 2008-08-06 16:46:04 UTC
+ Image Type: PowerPC Linux Kernel Image (gzip compressed)
+ Data Size: 3901211 Bytes = 3.7 MB
+ Load Address: 00000000
+ Entry Point: 00000000
+ Verifying Checksum ... OK
+ Uncompressing Kernel Image ... OK
+ </screen>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/doc/manual/config.mk b/doc/manual/config.mk
new file mode 100644
index 0000000..59bebb7
--- /dev/null
+++ b/doc/manual/config.mk
@@ -0,0 +1,74 @@
+#
+# (C) Copyright 2009 Extreme Engineering Solutions
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#########################################################################
+
+ifndef DOCBOOK_XSL_DIR
+DOCBOOK_XSL_DIR = /usr/share/xml/docbook/stylesheet/nwalsh
+endif
+export DOCBOOK_XSL_DIR
+
+ifndef XSLT_PROCESSOR
+XSLT_PROCESSOR = xsltproc
+endif
+
+ifndef FO_PROCESSOR
+FO_PROCESSOR = fop
+endif
+
+.PHONY = $(obj)man_parse $(obj)xml
+
+$(obj)man_parse: $(obj)include/autoconf.mk $(TIMESTAMP_FILE) \
+ $(VERSION_FILE)
+ @for f in $(dir $(LIBS)); do \
+ echo $$f; \
+ $(MAKE) -C $$f _man_parse; \
+ done
+
+$(obj)xml: $(obj)man_parse
+ perl $(TOPDIR)/doc/manual/uboot-doc \
+ $(TOPDIR)/doc/manual/autoconf-doc.txt
+ rm $(TOPDIR)/doc/manual/autoconf-doc.txt
+
+$(obj)text: $(obj)xml
+ $(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+ --stringparam pages.template \
+ $(DOCBOOK_XSL_DIR)/roundtrip/template.xml \
+ $(DOCBOOK_XSL_DIR)/roundtrip/dbk2wordml.xsl \
+ $(TOPDIR)/doc/manual/manual.xml
+
+$(obj)html: $(obj)xml
+ $(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+ $(DOCBOOK_XSL_DIR)/html/chunk.xsl \
+ $(TOPDIR)/doc/manual/manual.xml
+
+$(obj)xhtml: $(obj)xml
+ $(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+ $(DOCBOOK_XSL_DIR)/xhtml/chunk.xsl \
+ $(TOPDIR)/doc/manual/manual.xml
+
+$(obj)pdf: $(obj)xml
+ $(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/$(BOARD).fo \
+ --stringparam docbook_path ${DOCBOOK_XSL_DIR} --xinclude \
+ $(TOPDIR)/doc/manual/uboot_manual.xsl \
+ $(TOPDIR)/doc/manual/manual.xml
+ $(FO_PROCESSOR) -fo $(TOPDIR)/doc/manual/$(BOARD).fo -pdf \
+ $(TOPDIR)/doc/manual/$(BOARD).pdf
diff --git a/doc/manual/doc-stream.pl b/doc/manual/doc-stream.pl
new file mode 100644
index 0000000..71b7d02
--- /dev/null
+++ b/doc/manual/doc-stream.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $comment = "";
+my $in_comment = 0;
+
+# This file takes the output of the C pre-processor and scans it for
+# "interesting" comments (those that contain an @) and prints the comment.
+# Those comments are then dumped into a file that can be processed by
+# uboot-doc. Without this script, the output of the C pre-processor is
+# unnecesarily large (~36MB).
+while (<STDIN>) {
+ if (/^\s*\/\*\*\s*$/) {
+ $comment .= $_;
+ $in_comment = 1;
+ } elsif (/\*\//) {
+ if ($in_comment) {
+ $comment .= $_;
+
+ if ($comment =~ /.*[\s\*]+ at .*/) {
+ print $comment;
+ }
+ }
+ $in_comment = 0;
+ $comment = "";
+ } elsif (/\s*\*\s*/) {
+ if ($in_comment) {
+ $comment .= $_;
+ }
+ }
+}
+
+
diff --git a/doc/manual/introduction.tmpl b/doc/manual/introduction.tmpl
new file mode 100644
index 0000000..063a6b8
--- /dev/null
+++ b/doc/manual/introduction.tmpl
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_introduction_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Das U-Boot</title>
+
+ <sect1 xml:id="uboot_introduction">
+ <title>Introduction to U-Boot</title>
+ <para>The ${BOARD} utilizes the U-Boot bootloader. U-Boot
+ is an open-source bootloader which provides low-level hardware
+ initialization, power on self tests (POSTs), access to onboard peripherals
+ (Ethernet, flash, EEPROMs, sensors, etc.), and contains a powerful
+ set of commands that allow booting a variety of
+ operation systems and applications. Additional U-Boot information
+ can be found at <link ns1:href="http://www.denx.de/wiki/U-Boot/WebHome"
+ xmlns:ns1="http://www.w3.org/1999/xlink"
+ >http://www.denx.de/wiki/U-Boot/WebHome</link>.</para>
+ </sect1>
+
+ <sect1 xml:id="uboot_introduction_terminology">
+ <title>Terminology and Conventions</title>
+ <para>Below is a glossary of terminology that is relevant to U-Boot</para>
+ <table xml:id="uboot_introduction_term_table">
+ <title>Terminology</title>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="c1"/>
+ <colspec colnum="2" colname="c2"/>
+ <thead>
+ <row>
+ <entry>Settings</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row xml:id="uboot_term_target">
+ <entry>
+ <literal>Target</literal>
+ </entry>
+ <entry>The single-board computer being used, e.g.: ${BOARD}</entry>
+ </row>
+#ifdef CONFIG_CMD_DHCP
+ <row xml:id="uboot_term_bootp">
+ <entry>
+ <literal>BOOTP</literal>
+ </entry>
+ <entry>Bootstrap Protocol. BOOTP can be used to configure the
+ target&apos;s network settings based on information provided
+ by a BOOTP server.</entry>
+ </row>
+ <row xml:id="uboot_term_dhcp">
+ <entry>
+ <literal>DHCP</literal>
+ </entry>
+ <entry>Dynamic Host Configuration Protocol. DHCP can be used to
+ configure the target&apos;s network settings based on information
+ provided by a DHCP server. DHCP is very similar to BOOTP. It
+ is newer and provides some advanced features which BOOTP lacks.
+ Most DHCP servers also provide support for BOOTP.</entry>
+ </row>
+#endif
+#ifdef CONFIG_CMD_SNTP
+ <row xml:id="uboot_term_ntp">
+ <entry>
+ <literal>NTP</literal>
+ </entry>
+ <entry>Network Time Protocol. NTP is used to synchronize the
+ target&apos;s date and time with an NTP server</entry>
+ </row>
+#endif
+ <row xml:id="uboot_term_os">
+ <entry>
+ <literal>OS</literal>
+ </entry>
+ <entry>Operating System. e.g.: Linux, VxWorks, QNX, INTEGRITY.</entry>
+ </row>
+ <row xml:id="uboot_term_uimage">
+ <entry>
+ <literal>uImage</literal>
+ </entry>
+ <entry>An image format which contains a payload (OS image,
+ application image, filesystem, script, etc) as well as metadata
+ describing the payload. The metadata includes such information
+ as a checksum, payload name, timestamp, load address, etc.
+ </entry>
+ </row>
+#ifdef CONFIG_OF_LIBFDT
+ <row xml:id="uboot_term_device_tree">
+ <entry>
+ <literal>Device Tree</literal>
+ </entry>
+ <entry>A device tree is a text file which contains information in
+ a tree structure based on the Open Firmware specification. The
+ most common use of a device tree is to specify board-specific
+ information such as baud rate, CPU speed, number of flashes, etc
+ which U-Boot can manipulate and pass to an operating system such
+ as Linux.</entry>
+ </row>
+ <row xml:id="uboot_term_dtb">
+ <entry>
+ <literal>DTB</literal>
+ </entry>
+ <entry>Device Tree Blob. A commonly used acronym for a flattened
+ device tree blob. DTB can be used interchangeably with FDT.
+ </entry>
+ </row>
+ <row xml:id="uboot_term_fdt">
+ <entry>
+ <literal>FDT</literal>
+ </entry>
+ <entry>Flattened device tree. A FDT blob is a device tree which
+ has been converted into a binary form (a &quot;blob&quot;).
+ </entry>
+ </row>
+#endif
+ <row xml:id="uboot_term_primary_flash">
+ <entry>
+ <literal>Primary Flash</literal>
+ </entry>
+ <entry>The primary NOR flash device on the target. Also referred
+ to as Flash 1.
+ </entry>
+ </row>
+ <row xml:id="uboot_term_secondary_flash">
+ <entry>
+ <literal>Secondary Flash</literal>
+ </entry>
+ <entry>The secondary NOR flash device on the target. Also referred
+ to as Flash 2.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+</chapter>
diff --git a/doc/manual/manual.tmpl b/doc/manual/manual.tmpl
new file mode 100644
index 0000000..37eb85d
--- /dev/null
+++ b/doc/manual/manual.tmpl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<book xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ version="5.0"
+ xml:id="uboot_manual">
+
+ <xi:include href="${TOPDIR}/doc/manual/book_info.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/introduction.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/setup.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/booting_linux.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/memory_resources.xml"/>
+#ifdef CONFIG_POST
+ <xi:include href="${TOPDIR}/doc/manual/posts.xml"/>
+#endif
+ <xi:include href="${TOPDIR}/doc/manual/environment_variables.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/commands.xml"/>
+
+ <xi:include href="${TOPDIR}/doc/manual/scripting.xml"/>
+
+</book>
diff --git a/doc/manual/scripting.tmpl b/doc/manual/scripting.tmpl
new file mode 100644
index 0000000..21a7918
--- /dev/null
+++ b/doc/manual/scripting.tmpl
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_scripting_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Scripting</title>
+
+ <sect1 xml:id="uboot_scripting">
+ <title>Scripting in U-Boot</title>
+ <sect2 xml:id="uboot_scripting_dollar_sign">
+ <title>Variable Expansion with $</title>
+ <para>Variable substitution can be done with the $ character. For
+ instance, <link linkend="uboot_cmd_printenv">
+ <literal>printenv</literal></link> <link linkend="uboot_env_bootargs">
+ <literal>bootargs</literal></link> could also be executed with
+ <link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+ <link linkend="uboot_env_bootargs"><literal>$bootargs</literal></link>.
+ More powerfully, this variable substitution can be used in scripting.
+ See the example in the next section.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_scripting_conditionals">
+ <title>Conditionals</title>
+ <para>U-Boot has a scripting language which can be used to customize
+ command execution. It contains if..then..else..fi, for..do..done,
+ while..do..done and until..do..done control flow operations.
+ </para>
+
+ <para>As an example, take the environment variable bootcmd_net.
+ <screen>
+bootcmd_net=run set_bootargs; $download_cmd $osaddr $osfile; if test $? -eq 0;
+then if test -n $fdtaddr; then $download_cmd $fdtaddr $fdtfile;
+if test $? -eq 0; then bootm $osaddr - $fdtaddr; else; echo FDT DOWNLOAD FAILED;
+fi; else; bootm $osaddr; fi; else; echo OS DOWNLOAD FAILED; fi;
+ </screen>
+ To walk through the script, we start with
+ <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ <literal>set_bootargs</literal>, which executes the commands stored
+ in <literal>set_bootargs</literal>. Next, we execute the command stored
+ in <literal>download_cmd</literal> which we&apos;ll assume is set to
+ <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link> and
+ download the file from the path stored in <literal>osfile</literal> to
+ the address stored in <literal>osaddr</literal>. The next step is
+ interesting. We start an <literal>if</literal> conditional, and use the
+ <link linkend="uboot_cmd_test"><literal>test</literal></link> command
+ to check to see if the return value (<literal>$?</literal>) of the
+ <literal>download_cmd</literal> is <literal>0</literal>. If it
+ isn&apos;t, meaning the download failed, we find the matching
+ <literal>then</literal> and see that we echo
+ <literal>DOWNLOAD FAILED</literal>. If it is <literal>0</literal>
+ meaning the download completed successfully, we start a new
+ <literal>if</literal> conditional and test to see if
+ <literal>fdtaddr</literal> is defined. If it is, use
+ <literal>download_cmd</literal> to download the file
+ stored in <literal>fdtfile</literal> to the address stored in
+ <literal>fdtaddr</literal>. Again, we verify that the download
+ completed successfully. If everything has worked up until now, we
+ complete the script with
+ <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+ <literal>osaddr - fdtaddr</literal> and boot the image we just
+ downloaded. If <literal>fdtaddr</literal> had been undefined, we would
+ have executed
+ <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+ <literal>osaddr</literal> instead.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_scripting_and_or">
+ <title>&amp;&amp; and ||</title>
+ <para>Another feature of the U-Boot scripting language are the
+ <literal>&amp;&amp;</literal> and <literal>||</literal> functions. The
+ <literal>&amp;&amp;</literal> is an if and only if command. For
+ instance, the command
+ <link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+ <literal>$do_stuff &amp;&amp;</literal>
+ <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ <literal>$do_stuff</literal> would run <literal>do_stuff</literal>
+ only if the <link linkend="uboot_cmd_echo">
+ <literal>echo</literal></link> command returned successfully, meaning
+ that <literal>do_stuff</literal> is defined. If
+ <literal>do_stuff</literal> was not defined, the
+ <link linkend="uboot_cmd_run"><literal>run</literal></link> command
+ would not be executed. Similarly, the <literal>||</literal> command will
+ execute the second command only if the first command fails. For
+ instance, if <literal>bank1</literal> stored the location of the OS in
+ flash bank 1 and <literal>bank2</literal> stored the location of the
+ OS in flash bank 2, the following command would try to boot the image
+ in bank 1. If unsuccessful it would boot the image in bank 2. If that
+ failed, it would attempt to download the file over the network, and if
+ that succeeded, it would boot the image.
+ <screen>
+<literal>bootm $bank1 || bootm $bank2 || tftp $osaddr $osfile &amp;&amp; bootm</literal>
+ </screen>
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_scripting_quotes_and_ticks">
+ <title>Quotes and tick marks</title>
+ <para>Quotation marks and tick marks also have a special meaning in
+ U-Boot scripting. Let&apos;s say you wanted to create an environment
+ variable called <literal>do_stuff</literal> and this variable was going
+ to run <link linkend="uboot_cmd_printenv">
+ <literal>printenv</literal></link>
+ <link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>
+ then run
+ <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>.
+ Depending on how you format the command, it&apos;s execution will
+ change. You could save the command as
+ <screen>
+setenv do_stuff &quot;print bootargs; run $bootcmd&quot;
+ </screen>
+ When you <link linkend="uboot_cmd_printenv">
+ <literal>printenv</literal></link> <literal>do_stuff</literal> you
+ should see something like
+ <screen>
+do_stuff=print bootargs; run bootm f8000000
+ </screen>
+ Notice how the variable specified with the $ was expanded. Now, if
+ you do the same thing, replacing the quotation marks with tick marks,
+ <screen>
+setenv do_stuff &apos;printenv bootargs; run $bootcmd&apos;
+ </screen>
+ you will see different behavior.
+ <screen>
+do_stuff=printenv bootargs; run $bootcmd
+ </screen>
+ Notice how the variables specified with the $ were not expanded. In
+ most cases, this would be the desired behavior as these variables
+ would be expanded when they are executed. Then, any changes made to
+ <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+ between the time that <literal>do_stuff</literal> was set and it was
+ run would change the functionality of <literal>do_stuff</literal>.
+ For example,
+ <screen>
+setenv printscript print
+setenv do_stuff &quot;$printscript&quot;
+setenv printscript echo do nothing
+run do_stuff
+ </screen>
+ would result in printing all the environment variables, rather than
+ printing &quot;do nothing&quot;, whereas
+ <screen>
+setenv printscript print
+setenv do_stuff &apos;$printscript&apos;
+setenv printscript echo do nothing
+run do_stuff
+ </screen>
+ would result in printing &quot;do nothing&quot.
+ </para>
+ </sect2>
+ </sect1>
+</chapter>
+
diff --git a/doc/manual/setup.tmpl b/doc/manual/setup.tmpl
new file mode 100644
index 0000000..2d43a72
--- /dev/null
+++ b/doc/manual/setup.tmpl
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_setup_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>U-Boot Setup</title>
+
+ <sect1 xml:id="uboot_setup">
+ <title>Getting Started</title>
+#ifdef CONFIG_BAUDRATE
+ <sect2 xml:id="uboot_setup_serial">
+ <title>Serial</title>
+
+ <para>The U-Boot console can be accessed by a standard PC using terminal
+ software such as HyperTerminal or TeraTerm in Windows or minicom in
+ Linux.
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>Plug the serial adapter cable into the ${BOARD}&apos;s serial
+ connector.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Connect the other end of the serial adapter cable to the male
+ DB9 to one of your host PC&apos;s COM ports; a DB9 extension cable
+ may be required. A USB-to-Serial adapter may also be used if the
+ host PC being used does not have a male DB9 port available.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Start up your host PC terminal emulator (eg: HyperTerminal,
+ TeraTerm, minicom) using the following parameters:
+ </para>
+
+ <table xml:id="setup_default_serial">
+ <title>Default serial port settings</title>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="c1"/>
+ <colspec colnum="2" colname="c2"/>
+ <thead>
+ <row>
+ <entry>Settings</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>Baud Rate</literal>
+ </entry>
+ <entry>@CONFIG_BAUDRATE</entry>
+ </row>
+ <row>
+ <entry>
+ <literal>Data Bits</literal>
+ </entry>
+ <entry>8</entry>
+ </row>
+ <row>
+ <entry>
+ <literal>Parity</literal>
+ </entry>
+ <entry>None</entry>
+ </row>
+ <row>
+ <entry>
+ <literal>Stop Bits</literal>
+ </entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>
+ <literal>Flow Control</literal>
+ </entry>
+ <entry>None</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </listitem>
+ </orderedlist>
+
+ <para>After configuring the serial terminal, you should be able to
+ interact with the target. When the target is powered on, the user should
+ be presented with output similar to the following:
+ <screen>
+U-Boot 1.3.4-xes_r3 (Jan 06 2009 - 11:42:40)
+
+CPU0: 8572E, Version: 1.0, (0x80e80010)
+Core: E500, Version: 3.0, (0x80210030)
+Clock Configuration:
+ CPU:1500 MHz, CCB:600 MHz,
+ DDR:300 MHz (600 MT/s data rate) (Synchronous), LBC:75 MHz
+L1: D-cache 32 kB enabled
+ I-cache 32 kB enabled
+Board: X-ES XPedite5370 3U VPX SBC
+ Rev SA, Serial# 26081001, Cfg 90030065-1
+I2C: ready
+DTT1: 45 C
+DTT2: 35 C
+DRAM: 2 GB (bank interleaving, ECC enabled)
+FLASH: Executed from FLASH1
+FLASH: 256 MB
+L2: 1024 KB enabled
+
+ PCIE1 connected as Root Complex (x4)
+ Scanning PCI bus 01
+ 02 01 10b5 8518 0604 00
+ 02 02 10b5 8518 0604 00
+ 02 03 10b5 8518 0604 00
+ 01 00 10b5 8518 0604 00
+ PCIE1 on bus 00 - 05
+
+ PCIE2 connected as End Point (x4)
+ PCIE2 on bus 06 - 06
+In: serial
+Out: serial
+Err: serial
+Net: eTSEC1, eTSEC2
+Hit any key to stop autoboot: 0
+=>
+ </screen>
+ </para>
+
+ <para>If you don't see console output:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Verify the serial cable is firmly connected to both the board
+ and your PC.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Verify that your serial port has the settings listed above.
+ If it does, your board may have been changed to a different
+ baudrate. Try setting your terminal to 9600 baud and reset the
+ board.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Verify that your jumper settings are logical.</para>
+ </listitem>
+ <listitem>
+ <para>Check to see if a reset LED is lit and stays lit. If it does,
+ your board is being held in reset. Make sure the board has adequate
+ power and that the shelf manager isn't powering it down.
+ </para>
+ </listitem>
+#ifdef CONFIG_REDUNDANT_MONITORS
+ <listitem>
+ <para>U-Boot has many valid baudrate options. Rather than try all
+ options, try booting from the other bank of flash, and thusly, the
+ other set of environment variables. Power down the board and move
+ the boot device select jumper to select the other bank.
+ </para>
+ </listitem>
+#endif
+ <listitem>
+ <para>Power on the board and wait for about a minute. If the board is
+ working but the serial port is not, you should autoboot into an OS
+ which may start a heartbeat LED. If you see an LED pulsing on and
+ off after some time, your board is booting but your serial
+ connection is bad. Try a different cable.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Contact Tech Support</para>
+ </listitem>
+ </orderedlist>
+ </sect2>
+#endif CONFIG_BAUDRATE
+
+#ifdef CONFIG_MPC85xx
+ <xi:include href="${TOPDIR}/doc/manual/85xx_program_flow.xml"/>
+#endif CONFIG MPC85xx
+
+ <sect2 xml:id="uboot_setup_autoboot">
+ <title>Autoboot</title>
+ <para>Your ${BOARD} may be set up to autoboot into an Operating System.
+ In order to stop autoboot and drop down to the U-Boot prompt, press
+ any key when the autoboot count down starts. To disable autobooting, use
+ the <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+ command to set the <link linkend="uboot_env_bootdelay">
+ <literal>bootdelay</literal></link> environment variable to
+ <literal>-1</literal>. You must use the
+ <link linkend="uboot_cmd_saveenv"><literal>saveenv</literal></link>
+ command to save this change.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_setup_shell">
+ <title>U-Boot Shell</title>
+ <para>U-Boot is designed to set up your ${BOARD} and turn execution over
+ to an OS. In order to transfer control, U-Boot provides many commands
+ to help customize the hardware.
+ </para>
+ <para>One way to customize your version of U-Boot is through the use of
+ <link linkend="uboot_env_vars">environment variables</link>. Variables
+ can be modified with the
+ <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+ command. These variables will return to defaults after a reset unless a
+ <link linkend="uboot_cmd_saveenv"><literal>saveenv</literal></link>
+ command is executed. You can create any number of environment variables
+ to store instruction sequences. These variables can then be executed
+ with the <link linkend="uboot_cmd_run"><literal>run</literal></link>
+ command. By modifying the
+ <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link> and
+ <link linkend="uboot_env_preboot"><literal>preboot</literal></link>
+ environment varaibles, you can automate the use of your customized
+ variables. In order to save a string of commands to your environment
+ variable, you must insert a semicolon between every command. You will
+ either need to escape your semicolon (\;) or put the entire variable in
+ quotation marks (&quot;&quot;). See the <link linkend="uboot_scripting">
+ <literal>Scripting in U-Boot</literal></link> section for more
+ information on quotation marks.
+ </para>
+ <para>To see a list of the commands available to you, type
+ <link linkend="uboot_cmd_help"><literal>help</literal></link> at the
+ command prompt.
+ </para>
+ <para>After entering a command, you can re-execute it simply by pressing
+ the ENTER or RETURN key. Some commands, such as memory display
+ (<link linkend="uboot_cmd_md"><literal>md</literal></link>),
+ auto-increment to the next address on each subsequent auto-repeat.
+ </para>
+ </sect2>
+
+
+ <sect2 xml:id="uboot_setup_network">
+ <title>Network</title>
+ <para>If network operations will be performed on the target, connect any
+ applicable Ethernet interfaces. The ${BOARD} supports IP, TCP, ARP,
+ DHCP, TFTP, UDP, and ICMP transactions. Please also reference the
+ <link linkend="uboot_env_sect_networking">
+ <literal>Network Environment Variables</literal></link> and
+ <link linkend="uboot_cmd_sect_networking">
+ <literal>Network Commands</literal></link> for information
+ on using the ${BOARD}&apos;s Ethernet ports.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="uboot_setup_firmware_update">
+ <title>Firmware Update Procedure</title>
+ <para>In the even that you receive a firmware update or one of your
+ U-Boot images becomes corrupt, use the following procedure.
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>Place a good U-Boot image on a TFTP server.</para>
+ </listitem>
+ <listitem>
+ <para>Set your <link linkend="uboot_env_sect_networking">
+ <literal>network environment variables</literal></link> to reflect
+ the location of your TFTP server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Download the new U-Boot image using the
+ <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+ command.
+ <screen>
+tftp $loadaddr &lt;path to U-Boot image&gt;
+ </screen>
+ </para>
+ </listitem>
+ <listitem>
+ <para>Erase the old U-Boot image, beginning at ${TEXT_BASE} using
+ the <link linkend="uboot_cmd_erase"><literal>erase</literal></link>
+ command.
+ <screen>
+erase ${TEXT_BASE} +800000
+ </screen>
+ </para>
+ </listitem>
+ <listitem>
+ <para>Copy the downloaded image to flash using the
+ <link linkend="uboot_cmd_cp"><literal>cp</literal></link> command.
+ <screen>
+cp.b $loadaddr ${TEXT_BASE} $filesize
+ </screen>
+ </para>
+ </listitem>
+ <listitem>
+ <para>Reset the board to load the new image using the
+ <link linkend="uboot_cmd_reset"><literal>reset</literal></link>
+ command.
+ </para>
+ </listitem>
+ </orderedlist>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/doc/manual/uboot-doc b/doc/manual/uboot-doc
new file mode 100644
index 0000000..c2939bc
--- /dev/null
+++ b/doc/manual/uboot-doc
@@ -0,0 +1,866 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+## Copyright (C) 2009 Extreme Engineering Solutions
+##
+## Author: John Schmoller <jschmoller at xes-inc.com>
+##
+## This software falls under the GNU General Public License.
+## Please read the COPYING file for more information
+##
+## This file is loosly based on kernel-doc originally created by
+## Michael Zucchi from the Linux distribution.
+
+#
+# This will read a 'c' file and scan for embedded comments in the
+# style of gnome comments (+minor extensions - see below).
+#
+
+# usage:
+# uboot-doc inputfile ...
+#
+# inputfile ... - a list of files which will be searched for comment
+# blocks to convert to XML.
+#
+# All errors go to stderr.
+
+#
+# format of comments.
+# In the following table, (...)? signifies optional structure.
+# (...)* signifies 0 or more structure elements
+# /**
+# * @cmd: cmd_name
+# (* @sect: sect_name)?
+# (* a blank line)?
+# (* @param([(o)?(r)?])?: param_name - description)*
+# * @desc: Description of function
+# (* Function description extends through comment end.)*
+# (*)?*/
+#
+# The @sect is optional, and specifies which command sub-section
+# to place the common. Any string is a valid @sect descriptor (e.g. "Memory",
+# "Networking", "Environment Modifying". If not
+# specified, the command will be placed in the "Other" section.
+#
+# There are two optional suffixes to the @param specifier. o states whether
+# the parameter is optional, r states whether the parameter is replaceable.
+# Non-replaceable parameters are entered litterally, like i2c *probe*.
+# Replaceable parameters are substituted before the command is valid, like
+# md *addr* to md *100000*. Valid options are [or], [ro], [o], [r], [], and
+# nothing. [] means not optional and non-replaceable. Nothing defaults to
+# not optional and replaceable.
+#
+# The @desc and @entry fields can have links to other points in the document.
+# To specify a link to a command, use @ccommand_name, and for environment
+# variables, @eenv_name. For example, @cprintenv or @ebootdelay.
+#
+# So .. the trivial example would be:
+#
+# /**
+# * @cmd: my_command
+# */
+#
+# Or more compicated:
+# /**
+# * @cmd: my_function
+# * @sect: Memory
+# * @param: my_arg - its mine
+# * @desc: Does my stuff explained.
+# */
+# etc.
+#
+# Besides functions you can also write documentation for environment varaibles,
+# POSTs, and memory maps. Instead of @cmd name you must write the name
+# of the declaration; @env, @post, or @memmap must always precede
+# the name. Nesting of declarations is not supported.
+# e.g.
+# /**
+# * @env: env_name
+# (* @sect: sect_name)?
+# * @desc: Environment variable description.
+# (* Additional description.)*
+# (*)?*/
+#
+# /**
+# * @post: post_name
+# * @desc: POST description.
+# (* Additional description.)*
+# (*)?*/
+#
+# /**
+# * @memmap: Memory Map Name
+# (* @entry: start_addr: end_addr: Entry description)*
+# (*)?*/
+#
+# All @desc can be multiline.
+#
+
+my $manual_dir = "doc/manual";
+
+sub usage {
+ print "Usage: $0 outputfile\n";
+ exit 1;
+}
+
+# read arguments
+if ( $#ARGV == -1 ) {
+ usage();
+}
+
+# states
+# 0 - normal code
+# 1 - looking for command, env var, post, or memmap
+# 2 - parsing params and the first line of desc
+# 3 - finish parsing desc's, parse memmap entries
+my $state;
+
+# Regular expressions for matching section types
+my $doc_special = '@';
+my $doc_system_env = '\$';
+my $doc_cmd_link = $doc_special . 'c';
+my $doc_env_link = $doc_special . 'e';
+my $doc_start = '^\s*/\*\*\s*$'; # Allow whitespace at end of comment start.
+my $doc_end = '\*/';
+my $doc_com = '\s*\*\s*';
+my $doc_sect = $doc_special . 'sect:';
+my $doc_cmd = $doc_special . 'cmd:\s*';
+my $doc_param = $doc_special . 'param\s*\[?[or]*\]?:\s*';
+my $doc_env = $doc_special . 'env:\s*';
+my $doc_desc = $doc_special . 'desc:\s*';
+my $doc_post = $doc_special . 'post:\s*';
+my $doc_memmap = $doc_special . 'memmap:\s*';
+my $doc_memmap_entry = $doc_special . 'entry:\s*';
+
+# Hashes and arrays for storing output to files
+my @valuetype;
+my @valuename;
+my @valuedesc;
+my %cmdhash;
+my %envhash;
+my %posthash;
+my %definehash;
+my %memmaphash;
+my @definecontext = (1);
+
+reset_state();
+
+# Open up commands.xml to write and add the XML header
+if ( !open( CMDOUT, ">$manual_dir/commands.xml" ) ) {
+ print STDERR "Error: Cannot open file commamds.xml\n";
+ return;
+}
+print CMDOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print CMDOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print CMDOUT "<chapter version=\"5.0\" xml:id=\"uboot_commands\"\n";
+print CMDOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print CMDOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print CMDOUT " <title>U-Boot Commands</title>\n\n";
+
+# Open up environment_variables.xml to write and add the XML header
+if ( !open( ENVOUT, ">$manual_dir/environment_variables.xml" ) ) {
+ print STDERR "Error: Cannot open file environment_variables.xml\n";
+ return;
+}
+print ENVOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print ENVOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print ENVOUT "<chapter version=\"5.0\" xml:id=\"uboot_env_vars\"\n";
+print ENVOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print ENVOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print ENVOUT " <title>U-Boot Environment Variables</title>\n\n";
+
+# Open up posts.xml to write and add XML header
+if ( !open( POSTOUT, ">$manual_dir/posts.xml" ) ) {
+ print STDERR "Error: Cannot open file posts.xml\n";
+ return;
+}
+print POSTOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print POSTOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print POSTOUT "<chapter version=\"5.0\" xml:id=\"uboot_posts\"\n";
+print POSTOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print POSTOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print POSTOUT " <title>U-Boot POST Descriptions</title>\n\n";
+
+# Open up memory_resources.xml to write and add XML header
+if ( !open( MEMOUT, ">$manual_dir/memory_resources.xml" ) ) {
+ print STDERR "Error: Cannot open file memory_resources.xml\n";
+ return;
+}
+print MEMOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print MEMOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print MEMOUT "<chapter version=\"5.0\" xml:id=\"uboot_mem_resources\"\n";
+print MEMOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print MEMOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print MEMOUT " <title>U-Boot Memory Resources</title>\n\n";
+
+# Parse autoconf.mk for #defines
+if ( open( AUTOCONF, "<include/autoconf.mk" ) ) {
+ while (<AUTOCONF>) {
+ my $key = $_;
+ my $value = $_;
+ $key =~ s/=.*\s*$//;
+ $value =~ s/^.*?=//;
+ $value =~ s/\s*$//;
+ $definehash{$key} = $value;
+ }
+} else {
+ print STDERR "Error: Cannot open file autoconf.mk\n";
+}
+
+# Get date from timestamp_autogenerated.h
+my $DATE = "Jan 1, 2000";
+if ( open( TIMESTAMP, "<include/timestamp_autogenerated.h" ) ) {
+ while (<TIMESTAMP>) {
+ if (/U_BOOT_DATE\s*\"([\w\s]*)\"\s*$/) {
+ $DATE = $1;
+ }
+ }
+}
+
+# Get version from version_autogenerated.h
+my $VERSION = "U-Boot $DATE";
+if ( open( VERSION, "<include/version_autogenerated.h" ) ) {
+ while (<VERSION>) {
+ if (/U_BOOT_VERSION\s*\"U-Boot\s*(.*?)\"\s*$/) {
+ $VERSION = $1;
+ }
+ }
+}
+
+sub process_file($);
+
+foreach (@ARGV) {
+ chomp;
+ process_file($_);
+}
+
+# Finish off the commands.xml file
+foreach my $HoHkey ( sort ( keys(%cmdhash) ) ) {
+ my $tag_key = lc($HoHkey);
+ while ( $tag_key =~ / / ) {
+ $tag_key =~ s/ /_/;
+ }
+ print CMDOUT " <sect1 xml:id=\"uboot_cmd_sect_$tag_key\">\n";
+ print CMDOUT " <title>$HoHkey Commands</title>\n";
+ foreach my $key ( sort ( keys %{ $cmdhash{$HoHkey} } ) ) {
+ print CMDOUT $cmdhash{$HoHkey}{$key};
+ }
+ print CMDOUT " </sect1>\n";
+}
+print CMDOUT "</chapter>";
+
+# Finish off the environment_variables.xml file
+foreach my $HoHkey ( sort ( keys(%envhash) ) ) {
+ my $tag_key = lc($HoHkey);
+ while ( $tag_key =~ / / ) {
+ $tag_key =~ s/ /_/;
+ }
+ print ENVOUT " <sect1 xml:id=\"uboot_env_sect_$tag_key\">\n";
+ print ENVOUT " <title>$HoHkey Environment Variables</title>\n";
+ print ENVOUT " <table xml:id=\"uboot_env_sect_" . $tag_key . "_table\">\n";
+ print ENVOUT " <title>$HoHkey Environment Variables</title>\n";
+ print ENVOUT " <tgroup cols=\"2\">\n";
+ print ENVOUT " <colspec colname=\"c1\" colnum=\"1\"/>\n";
+ print ENVOUT " <colspec colname=\"c2\" colnum=\"2\"/>\n";
+ print ENVOUT " <thead>\n";
+ print ENVOUT " <row>\n";
+ print ENVOUT " <entry>Variable</entry>\n";
+ print ENVOUT " <entry>Description</entry>\n";
+ print ENVOUT " </row>\n";
+ print ENVOUT " </thead>\n";
+ print ENVOUT " <tbody>\n";
+
+ foreach my $key ( sort ( keys %{ $envhash{$HoHkey} } ) ) {
+ print ENVOUT $envhash{$HoHkey}{$key};
+ }
+ print ENVOUT " </tbody>\n";
+ print ENVOUT " </tgroup>\n";
+ print ENVOUT " </table>\n";
+ print ENVOUT " </sect1>\n";
+}
+print ENVOUT "</chapter>";
+
+# Finish off the posts.xml file
+foreach my $key ( sort ( keys(%posthash) ) ) {
+ print POSTOUT $posthash{$key};
+}
+print POSTOUT "</chapter>";
+
+# Finish off the memory_resources.xml file
+# Set System Memory Map first, all others alphabetically
+foreach my $key ( sort ( keys(%memmaphash) ) ) {
+ my $tag_key = lc($key);
+ while ( $tag_key =~ / / ) {
+ $tag_key =~ s/ /_/;
+ }
+
+ print MEMOUT " <sect1 xml:id=\"uboot_memmap_$tag_key\">\n";
+ print MEMOUT " <title>$key</title>\n";
+ print MEMOUT " <table xml:id=\"uboot_memmap_" . $tag_key . "_table\">\n";
+ print MEMOUT " <title>$key</title>\n";
+ print MEMOUT " <tgroup cols=\"3\">\n";
+ print MEMOUT " <colspec colname=\"c1\" colnum=\"1\"/>\n";
+ print MEMOUT " <colspec colname=\"c2\" colnum=\"2\"/>\n";
+ print MEMOUT " <colspec colname=\"c3\" colnum=\"3\"/>\n";
+ print MEMOUT " <thead>\n";
+ print MEMOUT " <row>\n";
+ print MEMOUT " <entry>Start</entry>\n";
+ print MEMOUT " <entry>End</entry>\n";
+ print MEMOUT " <entry>Description</entry>\n";
+ print MEMOUT " </row>\n";
+ print MEMOUT " </thead>\n";
+ print MEMOUT " <tbody>\n";
+ print MEMOUT $memmaphash{$key};
+ print MEMOUT " </tbody>\n";
+ print MEMOUT " </tgroup>\n";
+ print MEMOUT " </table>\n";
+ print MEMOUT " </sect1>\n";
+}
+print MEMOUT "</chapter>";
+
+# Start processing the template files. Look first in $manual_dir/
+# then in board/$BOARDDIR/manual. Overwrite any duplicate
+# files found in $manual_dir/ with the ones found in board/.
+my %files;
+opendir( MANDIR, $ENV{'TOPDIR'} . "/$manual_dir" ) or die "$!";
+my @manfiles = grep { /.*\.tmpl/ } readdir MANDIR;
+close MANDIR;
+foreach my $file (@manfiles) {
+ $files{$file} = $ENV{'TOPDIR'} . "/$manual_dir/$file";
+}
+if ( opendir( BOARDDIR, $ENV{'TOPDIR'} . "/board/" .
+ $ENV{'BOARDDIR'} . "/manual" ) )
+{
+ my @boardfiles = grep { /.*\.tmpl/ } readdir BOARDDIR;
+ close BOARDDIR;
+ foreach my $file (@boardfiles) {
+ $files{$file} =
+ $ENV{'TOPDIR'} . "/board/" . $ENV{'BOARDDIR'} . "/manual/$file";
+ }
+}
+
+foreach my $file ( keys(%files) ) {
+ @definecontext = ();
+ push( @definecontext, 1 );
+ my $define;
+ my $outfile = $file;
+ $outfile =~ s/\.tmpl//;
+ $outfile .= ".xml";
+ open( FH, "$files{$file}" ) or die "Cannot open file $files{$file}: $!";
+ open( OUT, ">$manual_dir/$outfile" ) or die "$!";
+
+ while (<FH>) {
+
+ # #else processing
+ if (/^#else/) {
+
+ if ( $definecontext[$#definecontext] ) {
+ $definecontext[$#definecontext] = 0;
+ } else {
+ $definecontext[$#definecontext] = 1;
+ }
+
+ # #endif processing
+ } elsif (/^#endif/) {
+ pop(@definecontext);
+
+ # #ifdef processing
+ } elsif (/^#ifdef\s*(\w*)\s*$/) {
+
+ if ( !$definecontext[$#definecontext] ) {
+ push( @definecontext, 0 );
+ } elsif ( exists( $definehash{$1} ) ) {
+ push( @definecontext, 1 );
+ } else {
+ push( @definecontext, 0 );
+ }
+
+ # ignore everything else until context changes
+ } elsif ( !$definecontext[$#definecontext] ) {
+ next;
+
+ # System environment and #define processing
+ } elsif (/[$doc_special$doc_system_env]/) {
+ my @words = split(/\s+/);
+ foreach my $word (@words) {
+ while ( $word =~ /^.*?$doc_special(\w*).*?$/ ) {
+ $define = $1;
+
+ if ( exists( $definehash{$define} ) ) {
+ s/$doc_special\w*/$definehash{$define}/;
+ } else {
+ s/$doc_special/ at /;
+ }
+ $word =~ s/$doc_special/ at /;
+ }
+ while ( $word =~ /$doc_system_env\{(\w*)\}+/ ) {
+ $define = $1;
+
+ # Check for the special $VERSION and $DATE defines
+ if ( $define eq "VERSION" ) {
+ s/$doc_system_env\{\w*\}/$VERSION/;
+ } elsif ( $define eq "DATE" ) {
+ s/$doc_system_env\{\w*\}/$DATE/;
+ } elsif ( exists $ENV{"$define"} ) {
+ s/$doc_system_env\{\w*\}/$ENV{"$define"}/;
+ } else {
+ s/$doc_system_env\{(\w*)\}/\$$1/;
+ }
+ $word =~ s/$doc_system_env/ /;
+ }
+ }
+ print OUT $_;
+ } elsif ( $definecontext[$#definecontext] ) {
+ print OUT $_;
+ }
+ }
+ close(FH);
+}
+
+# Output the DOCBOOK_XSL_DIR variable so it's readable by the stylesheets
+if ( !open( PARAMS, ">$manual_dir/params.xsl" ) ) {
+ print STDERR "Error: Cannot open file params.xsl\n";
+ return;
+}
+print PARAMS "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print PARAMS "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print PARAMS "<xsl:stylesheet xmlns:xsl=";
+print PARAMS "\"http://www.w3.org/1999/XSL/Transform\"\n";
+print PARAMS " xmlns:d=\"http://docbook.org/ns/docbook\"\n";
+print PARAMS " xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"\n";
+print PARAMS " exclude-result-prefixes=\"d\"\n";
+print PARAMS " version='1.0'>\n\n";
+print PARAMS " <xsl:import href=\"" . $ENV{"DOCBOOK_XSL_DIR"} .
+ "/fo/docbook.xsl\"/>\n\n";
+print PARAMS "</xsl:stylesheet>\n";
+close(PARAMS);
+
+# Function to parse descriptive text to find possible XML links
+sub output_link($) {
+ my @words;
+ my $retstr = "";
+ $_ = $_[0];
+
+ @words = split(/\s+/);
+ foreach (@words) {
+ if (/^$doc_env_link(\w*)/) { #link to environment element in doc
+ $retstr .= "<link linkend=\"uboot_env_$1\">";
+ $retstr .= "<literal>$1</literal></link> ";
+ } elsif (/^$doc_cmd_link(\w*)/) { #link to command element in doc
+ $retstr .= "<link linkend=\"uboot_cmd_$1\">";
+ $retstr .= "<literal>$1</literal></link> ";
+ } else {
+ $retstr .= "$_ ";
+ }
+ }
+ return $retstr;
+}
+
+# Writes XML for a command to the command hash
+sub output_command {
+ my $i = 0;
+ my $conditional_prints = 1;
+ my $hashvalue = "";
+ my $hashkey;
+ my $tag_key;
+ my $hashofhasheskey;
+
+ # Make sure we're not re-processing a command
+ if ( exists( $cmdhash{ $valuedesc[0] }{ $valuename[0] } ) ) {
+ return;
+ }
+
+ # Cycle through all the elements to the command
+ foreach (@valuetype) {
+
+ # The @cmd and @sect lines
+ if (/$doc_cmd/) {
+ $hashkey = $valuename[$i];
+ $tag_key = lc( $valuename[$i] );
+ while ( $tag_key =~ / / ) {
+ $tag_key =~ s/ /_/;
+ }
+ $hashvalue .= " <sect2 xml:id=\"uboot_cmd_$tag_key\">\n";
+ $hashvalue .= " <title>$valuename[$i]</title>\n";
+ $hashvalue .= " <cmdsynopsis>\n";
+ $hashvalue .= " <command>$valuename[$i]</command>\n";
+ $hashofhasheskey = $valuedesc[$i];
+
+ if ( $hashofhasheskey eq '0' ) {
+ $hashofhasheskey = "Other";
+ }
+
+ if ( !exists( $cmdhash{$hashofhasheskey} ) ) {
+ $cmdhash{$hashofhasheskey} = {};
+ }
+ } elsif (/$doc_param/) { # The @param line
+ if (/\[[or]*\]/) { #arg options specified
+ if (/\[\w?o\w?\]/) { #arg optional
+ $hashvalue .= " <arg choice=\"opt\">\n";
+ } else { #arg required
+ $hashvalue .= " <arg choice=\"req\">\n";
+ }
+
+ if (/\[\w?r\w?\]/) { #arg replaceable
+ $hashvalue .= " <replaceable>$valuename[$i]";
+ $hashvalue .= "</replaceable>\n";
+ } else { #arg literal
+ $hashvalue .= " $valuename[$i]\n";
+ }
+ $hashvalue .= " </arg>\n";
+ } else { #assume [r]
+ $hashvalue .= " <arg choice=\"req\">\n";
+ $hashvalue .= " <replaceable>$valuename[$i]";
+ $hashvalue .= "</replaceable>\n";
+ $hashvalue .= " </arg>\n";
+ }
+ } elsif (/$doc_desc/) { # The @desc line
+ my @words;
+ if ($conditional_prints) { #finish up the synopsis
+ $hashvalue .= " </cmdsynopsis>\n";
+ $hashvalue .= " <para>";
+ $conditional_prints = 0;
+ } else {
+ $hashvalue .= " ";
+ }
+
+ if ( $valuedesc[$i] eq "\n" ) {
+ $hashvalue .= "</para>\n";
+ if ( $i != $#valuetype ) {
+ $hashvalue .= " <para>";
+ }
+ $i++;
+ next;
+ }
+
+ $hashvalue .= output_link( $valuedesc[$i] );
+
+ if ( ($i) == $#valuetype ) {
+ $hashvalue .= "</para>";
+ }
+
+ $hashvalue .= "\n";
+ }
+ $i++;
+ }
+
+ # Make a second run through the command to get the XML formatted correctly
+ $conditional_prints = 1;
+ $i = 0;
+ my $param_present = 0;
+ foreach (@valuetype) {
+ if (/$doc_param/) {
+ if ($conditional_prints) {
+ $hashvalue .= " <variablelist>\n";
+ $hashvalue .= " <title>Arguments</title>\n";
+ $conditional_prints = 0;
+ $param_present = 1;
+ }
+
+ $hashvalue .= " <varlistentry>\n";
+ $hashvalue .= " <term>\n";
+
+ if (/\[\w?r\w?\]/) { #replaceable arg option specified
+ $hashvalue .= " <replaceable>$valuename[$i]";
+ $hashvalue .= "</replaceable>\n";
+ } elsif (/\[\w*\]/) { #replaceable arg not specified
+ $hashvalue .= " $valuename[$i]\n";
+ } else { #no args specified, default to replaceable
+ $hashvalue .= " <replaceable>$valuename[$i]";
+ $hashvalue .= "</replaceable>\n";
+ }
+
+ $hashvalue .= " </term>\n";
+ $hashvalue .= " <listitem>\n";
+ $hashvalue .= " <para>$valuedesc[$i]</para>\n";
+ $hashvalue .= " </listitem>\n";
+ $hashvalue .= " </varlistentry>\n";
+ }
+
+ if ( $i == $#valuetype ) {
+ if ($param_present) {
+ $hashvalue .= " </variablelist>\n";
+ }
+ $hashvalue .= " </sect2>\n";
+
+ }
+ $i++;
+ }
+
+ $cmdhash{$hashofhasheskey}{$hashkey} = $hashvalue;
+}
+
+# Function writes XML for an environment variable to the env hash
+sub output_env {
+ my @words;
+ my $conditional_prints = 1;
+ my $i = 0;
+ my $hashvalue = "";
+ my $hashkey;
+ my $hashofhasheskey;
+
+ # Make sure we're not re-processing an environment variable
+ if ( exists( $envhash{ $valuedesc[0] }{ $valuename[0] } ) ) {
+ return;
+ }
+
+ $hashkey = $valuename[0];
+ $hashvalue .= " <row xml:id=\"uboot_env_$valuename[0]\">\n";
+ $hashvalue .= " <entry>\n";
+ $hashvalue .= " <literal>$valuename[0]</literal>\n";
+ $hashvalue .= " </entry>\n";
+ $hashvalue .= " <entry>\n";
+ $hashvalue .= " <para>";
+ $hashofhasheskey = $valuedesc[0];
+
+ if ( $hashofhasheskey eq '0' ) {
+ $hashofhasheskey = "Other";
+ }
+
+ if ( !exists( $envhash{$hashofhasheskey} ) ) {
+ $envhash{$hashofhasheskey} = {};
+ }
+
+ # For each description element, add to the env var description
+ foreach (@valuetype) {
+ if (/$doc_desc/) {
+ if ( $i != 0 ) {
+ $hashvalue .= " ";
+ }
+
+ if ( $valuedesc[$i] eq "\n" ) {
+ $hashvalue .= "</para>\n";
+ if ( $i != $#valuetype ) {
+ $hashvalue .= " <para>";
+ }
+ } else {
+
+ $hashvalue .= output_link( $valuedesc[$i] );
+
+ if ( ($i) == $#valuetype ) {
+ $hashvalue .= "</para>";
+ }
+
+ $hashvalue .= "\n";
+ }
+ }
+ $i++;
+ }
+
+ $hashvalue .= " </entry>\n";
+ $hashvalue .= " </row>\n";
+
+ $envhash{$hashofhasheskey}{$hashkey} = $hashvalue;
+}
+
+sub output_post {
+ my $hashvalue = "";
+ my $i = 0;
+
+ if ( exists( $posthash{ $valuename[0] } ) ) {
+ return;
+ }
+
+ my $hashkey = $valuename[0];
+ my $tag_key = $hashkey;
+ while ( $tag_key =~ / / ) {
+ $tag_key =~ s/ /_/;
+ }
+
+ foreach (@valuetype) {
+ if (/$doc_post/) {
+ $hashvalue .= " <sect1 xml:id=\"uboot_post_$tag_key\">\n";
+ $hashvalue .= " <title>$hashkey</title>\n";
+ $hashvalue .= " <para>\n";
+ } elsif (/$doc_desc/) {
+ if ( $valuedesc[$i] eq "\n" ) {
+ $hashvalue .= "</para>\n";
+ if ( $i != $#valuetype ) {
+ $hashvalue .= " <para>";
+ }
+ } else {
+ $hashvalue .= " ";
+ $hashvalue .= output_link( $valuedesc[$i] );
+ }
+ }
+ $i++;
+ }
+
+ $hashvalue .= " </para>\n";
+ $hashvalue .= " </sect1>\n";
+
+ $posthash{$hashkey} = $hashvalue;
+}
+
+# Function writes XML for a memory map to the memmap hash
+sub output_memmap {
+ my @words;
+ my $conditional_prints = 1;
+ my $i = 0;
+ my $hashvalue = "";
+ my $hashkey;
+
+ # Make sure we're not re-processing a memory map
+ if ( exists( $memmaphash{ $valuedesc[0] } ) ) {
+ return;
+ }
+
+ # Make a valid XML tag name out of memmap description
+ $hashkey = $valuedesc[0];
+ my $tag_key = lc($hashkey);
+ while ( $tag_key =~ / / ) {
+ $tag_key =~ s/ /_/;
+ }
+
+ # Cycle through all the memmap entries
+ foreach (@valuetype) {
+ my @words;
+ if (/$doc_memmap_entry/) {
+
+ $hashvalue .= " <row>\n";
+
+ # Split up start and end and drop them in the table
+ @words = split( /\s*:\s*/, $valuedesc[$i] );
+ foreach my $word (@words) {
+ $hashvalue .= " <entry>\n";
+ $hashvalue .= " <literal>$word</literal>\n";
+ $hashvalue .= " </entry>\n";
+ }
+
+ $hashvalue .= " <entry>\n";
+ $hashvalue .= " <para>";
+ $hashvalue .= output_link( $valuename[$i] );
+ $hashvalue .= "</para>\n";
+ $hashvalue .= " </entry>\n";
+ $hashvalue .= " </row>\n";
+
+ }
+ $i++;
+ }
+
+ $memmaphash{$hashkey} = $hashvalue;
+}
+
+# Call the appropriate output function
+sub output_section {
+ if ( $valuetype[0] =~ /$doc_cmd/io ) {
+ output_command();
+ } elsif ( $valuetype[0] =~ /$doc_env/io ) {
+ output_env();
+ } elsif ( $valuetype[0] =~ /$doc_post/io ) {
+ output_post();
+ } elsif ( $valuetype[0] =~ /$doc_memmap/io ) {
+ output_memmap();
+ }
+}
+
+# After each comment block, reset all our variables
+sub reset_state {
+
+ @valuetype = ();
+ @valuename = ();
+ @valuedesc = ();
+
+ $state = 0;
+}
+
+# Main processing loop
+sub process_file($) {
+ my $file;
+ my $identifier;
+ my $func;
+ my $descr;
+ my @links;
+
+ $file = "@_";
+
+ if ( !open( IN, "<$file" ) ) {
+ print STDERR "Error: Cannot open file $file\n";
+ return;
+ }
+
+ while (<IN>) {
+ if ( $state == 0 ) { # Normal code
+ if (/$doc_start/io) {
+ $state = 1;
+ }
+ } elsif ( $state == 1 )
+ { # We got the start of a potential comment block
+ if (/^$doc_com$/io) { # Got an empty line
+ next;
+
+ } elsif (/$doc_cmd\s*([\w\s-]*\w)\s*$/io) { # Found a function
+ push @valuetype, $doc_cmd;
+ push @valuename, $1;
+ push @valuedesc, '0';
+
+ $state = 2;
+ } elsif (/$doc_env\s*([\w\s-]*\w)\s*$/io) { # Found an env var
+ push @valuetype, $doc_env;
+ push @valuename, $1;
+ push @valuedesc, '0';
+
+ $state = 2;
+ } elsif (/$doc_post\s*([\w\s-]*\w)\s*$/io) { # Found POST descriptor
+ push @valuetype, $doc_post;
+ push @valuename, $1;
+ push @valuedesc, '0';
+
+ $state = 2;
+ } elsif (/$doc_memmap\s*([\w\s-]*\w)\s*$/io) { # Found a memory map
+ push @valuetype, $doc_memmap;
+ push @valuename, '0';
+ push @valuedesc, $1;
+
+ $state = 3;
+ } elsif (/$doc_end/io) { # Musta been a normal comment
+ $state = 0;
+ }
+ } elsif ( $state == 2 ) { # Found a valid comment declaration
+ if (/^$doc_com$/io) { # Got an empty line
+ next;
+ } elsif (/($doc_param)\s*([^-]*[^\s])\s*-\s*(.*)\s*$/io) { # Param
+ push @valuetype, $1;
+ push @valuename, $2;
+ push @valuedesc, $3;
+ } elsif (/$doc_desc(.*\s*$)/io) { # Got a description
+ push @valuetype, $doc_desc;
+ push @valuename, $doc_desc;
+ push @valuedesc, $1;
+
+ $state = 3;
+ } elsif (/$doc_sect\s*(.*[^\s])\s*$/io) { # Got a sub-section decl
+ $valuedesc[$#valuedesc] = $1;
+ } else { # Something undefined happened
+ print STDERR "Warning(${file}:$.): bad line: $_";
+ reset_state();
+ }
+ } elsif ( $state == 3 ) { # Process descriptions and memmap entries
+ if (/$doc_end/) { # End of comment block
+ # Write comment to proper hash
+ output_section();
+
+ # Reset hash variables and state
+ reset_state();
+ } elsif (/^$doc_com$/) { # Empty line, push a newline
+ push @valuetype, $doc_desc;
+ push @valuename, $doc_desc;
+ push @valuedesc, "\n";
+
+ # Got memmap entry
+ } elsif (/$doc_memmap_entry\s*(\w*\s*:\s*\w*)\s*:\s*(.*)$/io) {
+ push @valuetype, $doc_memmap_entry;
+ push @valuename, $2;
+ push @valuedesc, $1;
+ } else { # No tag, keep pushing description
+ $descr = $_;
+ $descr =~ s/^$doc_com//io;
+
+ push @valuetype, $doc_desc;
+ push @valuename, $doc_desc;
+ push @valuedesc, $descr;
+ }
+ }
+ }
+}
+
diff --git a/doc/manual/uboot_manual.xsl b/doc/manual/uboot_manual.xsl
new file mode 100644
index 0000000..bc40b46
--- /dev/null
+++ b/doc/manual/uboot_manual.xsl
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- **********************************************************************
+ U-Boot manual FO stylesheet
+
+ This stylesheet (DocBook customization layer) transforms U-Boot
+ manual XML documents into FO.
+
+ Since the DocBook stylesheets are currently in XSLT 1.0, this
+ stylesheet has to be XSLT 1.0.
+ ********************************************************************** -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:d="http://docbook.org/ns/docbook"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ exclude-result-prefixes="d"
+ version='1.0'>
+
+<!-- ======================================================================
+ Base DocBook stylesheet
+ ====================================================================== -->
+
+ <xsl:include href="params.xsl"/>
+
+<!-- ======================================================================
+ General customizations
+ ====================================================================== -->
+
+ <!-- General document settings. -->
+ <xsl:param name="draft.mode" select="'no'"/>
+ <xsl:param name="paper.type" select="'USletter'"/>
+ <xsl:param name="body.font.family" select="'sans-serif'"/>
+ <xsl:param name="body.font.master" select="10"/>
+
+<!-- ======================================================================
+ Section customizations
+ ====================================================================== -->
+
+ <!-- Add section numbering. -->
+ <xsl:param name="section.autolabel" select="1"/>
+ <xsl:param name="section.label.includes.component.label" select="1"/>
+
+ <!-- Section title properties. Only the 'space-before.*' attributes were
+ customized from their default values here. -->
+ <xsl:attribute-set name="section.title.properties">
+ <xsl:attribute name="font-family"><xsl:value-of select="$title.font.family"/></xsl:attribute>
+ <xsl:attribute name="font-weight">bold</xsl:attribute>
+ <!-- font size is calculated dynamically by section.heading template -->
+ <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+ <xsl:attribute name="space-before.minimum">2.8em</xsl:attribute>
+ <xsl:attribute name="space-before.optimum">3em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">3.2em</xsl:attribute>
+ <xsl:attribute name="text-align">left</xsl:attribute>
+ <xsl:attribute name="start-indent"><xsl:value-of select="$title.margin.left"/></xsl:attribute>
+ </xsl:attribute-set>
+
+<!-- ======================================================================
+ Front matter customizations
+ ====================================================================== -->
+
+ <!-- Title page template. Customized from fo/titlepage.templates.xsl. -->
+ <xsl:template name="book.titlepage.recto">
+ <fo:block font-family="Book Antiqua" text-align="left" hyphenate="false">
+ <fo:block font-size="45pt">
+ <!-- EDIT: CUSTOMIZE PRODUCT NAME HERE -->
+ <fo:inline>
+ <xsl:value-of select="ancestor-or-self::book/info/titleabbrev"/>
+ </fo:inline>
+ <!-- CUSTOMIZE PRODUCT NAME HERE -->
+ </fo:block>
+ <fo:block font-size="20pt" font-weight="bold"
+ space-before="2in">U-Boot User's Manual</fo:block>
+ <fo:block-container absolute-position="absolute" height="100%"
+ display-align="after" break-after="page"
+ left="10pt" bottom="10pt">
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-column column-number="1"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-column column-number="2"
+ column-width="proportional-column-width(1)"/>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>
+ <fo:external-graphic height="1.2in"
+ content-height="scale-to-fit">
+ <xsl:attribute name="src">
+ <xsl:text>url('</xsl:text>
+ <xsl:apply-templates select="ancestor-or-self::book/info/mediaobject/imageobject/imagedata/@fileref"/>
+ <xsl:text>')</xsl:text>
+ </xsl:attribute>
+ </fo:external-graphic>
+ </fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <fo:block font-size="10pt" text-align="right">
+ <fo:block>
+ <xsl:value-of select="ancestor-or-self::book/info/address/personname"/>
+ </fo:block>
+ <fo:block>
+ <xsl:value-of select="ancestor-or-self::book/info/address/street"/>
+ </fo:block>
+ <fo:block>
+ <xsl:value-of select="ancestor-or-self::book/info/address/city"/> <xsl:value-of select="ancestor-or-self::book/info/address/state"/> <xsl:value-of select="ancestor-or-self::book/info/address/postcode"/> <xsl:value-of select="ancestor-or-self::book/info/address/country"/>
+ </fo:block>
+ <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/phone"/></fo:block>
+ <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/fax"/></fo:block>
+ <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/uri"/></fo:block>
+ <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/email"/></fo:block>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:block font-size="10pt" font-weight="bold" text-align="center"
+ border-top="0.5pt solid black" padding-top="0.05in">
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </xsl:template>
+
+ <!-- Second page (legal/revhistory) template. Customized from
+ fo/titlepage.templates.xsl.
+
+ This template needs to be rewritten as well (see the comment for the
+ template above).
+ -->
+ <xsl:template name="book.titlepage.verso">
+ <fo:block font-family="sans-serif" font-size="18pt" font-weight="bold"><xsl:value-of select="ancestor-or-self::book/info/title"/></fo:block>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/releaseinfo"/>
+ <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/legalnotice"/>
+
+ </xsl:template>
+
+ <xsl:template match="legalnotice//emphasis">
+ <xsl:call-template name="inline.boldseq"/>
+ </xsl:template>
+
+<!-- ======================================================================
+ Header/footer customizations
+ ====================================================================== -->
+
+ <!-- Customized from fo/pagesetup.xsl. -->
+ <xsl:template name="header.content">
+ <xsl:param name="pageclass" select="''"/>
+ <xsl:param name="sequence" select="''"/>
+ <xsl:param name="position" select="''"/>
+ <xsl:param name="gentext-key" select="''"/>
+
+ <fo:block>
+ <xsl:choose>
+ <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'left'">
+ <xsl:value-of select="ancestor-or-self::d:book/d:info/d:author/d:orgname"/>
+ </xsl:when>
+ <xsl:when test="$pageclass = 'body' and $position = 'right'">
+ <xsl:apply-templates select="." mode="title.markup"/>
+ </xsl:when>
+ <xsl:otherwise/>
+ </xsl:choose>
+ </fo:block>
+ </xsl:template>
+
+ <!-- Customized from fo/pagesetup.xsl. -->
+ <xsl:template name="footer.content">
+ <xsl:param name="pageclass" select="''"/>
+ <xsl:param name="sequence" select="''"/>
+ <xsl:param name="position" select="''"/>
+ <xsl:param name="gentext-key" select="''"/>
+
+ <fo:block>
+ <xsl:choose>
+ <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'left'">
+ <xsl:value-of select="ancestor-or-self::d:book/d:info/d:title"/>
+ </xsl:when>
+ <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'right'">
+ <fo:page-number/>
+ </xsl:when>
+ <xsl:otherwise/>
+ </xsl:choose>
+ </fo:block>
+ </xsl:template>
+
+<!-- ======================================================================
+ Table customizations
+ ====================================================================== -->
+
+ <!-- Table customization. -->
+ <xsl:param name="default.table.frame" select="'none'"/>
+ <xsl:attribute-set name="table.properties" use-attribute-sets="formal.object.properties">
+ <xsl:attribute name="keep-together.within-column">always</xsl:attribute>
+ </xsl:attribute-set>
+
+<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
+ <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+ <xsl:attribute name="font-weight">bold</xsl:attribute>
+ <xsl:attribute name="font-size">
+ <xsl:value-of select="$body.font.master * 1.2"></xsl:value-of>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="hyphenate">false</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
+ <xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
+</xsl:attribute-set>
+
+
+ <!-- Customized from fo/table.xsl. -->
+ <xsl:template name="table.row.properties">
+ <xsl:variable name="rownum">
+ <xsl:number from="d:tgroup" count="d:row"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="ancestor::d:thead">
+ <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+ <xsl:attribute name="border-bottom">1.5pt solid black</xsl:attribute>
+ <xsl:attribute name="text-align">left</xsl:attribute>
+ <xsl:if test="ancestor::d:table/@role = 'wide'">
+ <xsl:attribute name="font-size">75%</xsl:attribute>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="text-align">left</xsl:attribute>
+ <xsl:if test="ancestor::d:table/@role = 'wide'">
+ <xsl:attribute name="font-size">60%</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="$rownum mod 2 = 0">
+ <xsl:attribute name="background-color">#e6e6fb</xsl:attribute>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="d:tbody/d:row/d:entry/d:emphasis">
+ <xsl:call-template name="inline.boldseq"/>
+ </xsl:template>
+
+ <xsl:param name="table.footnote.number.symbols" select="'*&#x2020;&#x2021;&#x25CA;&#x2720;'"/>
+
+ <xsl:attribute-set name="table.footnote.properties">
+ <xsl:attribute name="font-family"><xsl:value-of select="$body.fontset"></xsl:value-of></xsl:attribute>
+ <xsl:attribute name="font-size"><xsl:value-of select="$footnote.font.size"></xsl:value-of></xsl:attribute>
+ <xsl:attribute name="font-weight">normal</xsl:attribute>
+ <xsl:attribute name="font-style">normal</xsl:attribute>
+ <xsl:attribute name="space-before">4pt</xsl:attribute>
+ <xsl:attribute name="text-align"><xsl:value-of select="$alignment"></xsl:value-of></xsl:attribute>
+ </xsl:attribute-set>
+
+<!-- ======================================================================
+ List customizations
+ ====================================================================== -->
+
+ <xsl:attribute-set name="list.block.spacing">
+ <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+ <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+ <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
+ <xsl:attribute name="margin-left">0.25in</xsl:attribute>
+ </xsl:attribute-set>
+
+<!-- ======================================================================
+ Shell command and software install instructions customizations
+ ====================================================================== -->
+
+ <xsl:param name="shade.verbatim" select="1"></xsl:param>
+ <xsl:attribute-set name="verbatim.properties">
+ <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+ <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
+ <xsl:attribute name="hyphenate">false</xsl:attribute>
+ <xsl:attribute name="wrap-option">no-wrap</xsl:attribute>
+ <xsl:attribute name="white-space-collapse">false</xsl:attribute>
+ <xsl:attribute name="white-space-treatment">preserve</xsl:attribute>
+ <xsl:attribute name="linefeed-treatment">preserve</xsl:attribute>
+ <xsl:attribute name="text-align">start</xsl:attribute>
+ <xsl:attribute name="font-size">75%</xsl:attribute>
+ </xsl:attribute-set>
+
+</xsl:stylesheet>
diff --git a/rules.mk b/rules.mk
index 6f999dd..383bf6b 100644
--- a/rules.mk
+++ b/rules.mk
@@ -24,6 +24,7 @@
#########################################################################

_depend: $(obj).depend
+_man_parse: $(obj).man_parse

$(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS)
@rm -f $@
@@ -32,4 +33,10 @@ $(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS)
$(CC) -M $(HOSTCFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \
done

+$(obj).man_parse: $(src)Makefile $(TOPDIR)/config.mk $(SRCS)
+ @for f in $(SRCS); do \
+ $(CPP) $(CPPFLAGS) -C $$f | \
+ perl $(TOPDIR)/doc/manual/doc-stream.pl >> \
+ $(TOPDIR)/doc/manual/autoconf-doc.txt; \
+ done
#########################################################################
--
1.6.0.4
Wolfgang Denk
2009-07-28 17:49:23 UTC
Permalink
Dear John Schmoller,

In message <cover.1248798202.git.jschmoller at xes-inc.com> you wrote:
>
> I've been working on writing a User's Manual generation tool, and before
> I get too far I'd like to see if this is something the U-Boot community
> would be interested in.

Anything wrong with the User's Manual generation tool we already have
in use (DUTS) for example to generate the DULG?

> General Control Flow:
> C pre-processor -> doc_stream.pl : pre-processed code gets everything but
> comments with an @ stripped away
> doc_stream.pl -> autoconf_doc.txt : "interesting" comments get sent to this
> file
> autoconf_doc.txt -> uboot-doc : file is parsed and comments are turned to XML
> *.tmpl -> uboot-doc : template files are processed into XML
> *.xml -> xsltproc : XML is converted into desired output format
> *.fo -> fop : (PDFs only) fo files are translated to PDF

What you describe does not sound like a user's manual to me, but more
like some API documentation - whioch is a completely different thing
(and something we really don't have yet).

Your approach may be suitable for standard documents, but in many
years of working with U-Boot (and Linux) we found that it does not
work so well with the specific needs we have for a User's Manual. One
issue is that you have to support many different boards (well, maybe
not you as a user, but we as a community). And you have to include
examples. And examples must really fit the board. If you for example
provide a manual entry for the "erase" command you better make sure
that your example does not erase a range of flash that on some board
happens to hold the U-Boot image. etc.

That's how we came to the DULG we have today. I'm still convinced that
this is a really well-working approach.

It seems you don;t address this issue yet.


> I see several advantages to adopting this scheme.
> - Documentation should be easier to keep in sync with code

Better than what we have with the DULG? I doubt it.

> - DocBook XML output can be used to generate webpages, PDFs, text, etc,
> which are all extensible

We do the same with the DULG.

> - People don't have to reinvent the wheel when writing documentation

Well, you just did that, it seems ;-)

> - Source code ends up being thouroughly commented
>
> These patches are just meant to be an example of how in-code documentation
> could be used. You'll also notice there are many warnings regarding variables
> the manual is referencing which aren't defined yet. I wanted to get some
> feedback before diving in too far. What do others think? Is this worth
> pursuing?

Hm... we cannot look at your patches, you just posted the patch
statistics, but no content.

The documentation itself seems to duplicate a lot of content we have
in the DULG. I have to admit that I'd prefer to see the effort
invested in improving the existing manual, than to come up with
something different (and, as it seems, less flexible).

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Reader, suppose you were an idiot. And suppose you were a member of
Congress. But I repeat myself. - Mark Twain
jschmoller
2009-07-28 20:40:31 UTC
Permalink
On Tue, 2009-07-28 at 19:49 +0200, Wolfgang Denk wrote:
> Dear John Schmoller,
>
> In message <cover.1248798202.git.jschmoller at xes-inc.com> you wrote:
> >
> > I've been working on writing a User's Manual generation tool, and before
> > I get too far I'd like to see if this is something the U-Boot community
> > would be interested in.
>
> Anything wrong with the User's Manual generation tool we already have
> in use (DUTS) for example to generate the DULG?

I have to admit, I'm not very familiar with DUTS, so read up a little on
it before responding. So please correct me if I've misinterpreted
something.

It seems to me that DUTS is designed to test U-Boot and also automates
the running of commands whose output can be put online in the DULG. I
didn't notice any documented procedure on how to turn the DULG into XML,
extensible PDFs, etc. It also seems as if the DULG is a combination of
hand-edited wiki pages as well as the DUTS output? I was hoping to
develop a system that's completely automated. I also noticed in a quick
probe around that a few items in the DULG seem to be out of sync (imd
vs. i2c md, source vs. autoscr, etc.) and DHCP seems to be out of date
as well. Is the process for updating the DULG automatic? If so, how is
it done?

>
> > General Control Flow:
> > C pre-processor -> doc_stream.pl : pre-processed code gets everything but
> > comments with an @ stripped away
> > doc_stream.pl -> autoconf_doc.txt : "interesting" comments get sent to this
> > file
> > autoconf_doc.txt -> uboot-doc : file is parsed and comments are turned to XML
> > *.tmpl -> uboot-doc : template files are processed into XML
> > *.xml -> xsltproc : XML is converted into desired output format
> > *.fo -> fop : (PDFs only) fo files are translated to PDF
>
> What you describe does not sound like a user's manual to me, but more
> like some API documentation - whioch is a completely different thing
> (and something we really don't have yet).

As I mentioned, I borrowed this idea from the kernel-doc script in
Linux, which does do API documentation. But my hope for the uboot-doc
tool would be to create user documentation, or a manual we'd provide to
a customer when they purchased a product that would describe available
commands, environment variables, common operations, etc.

>
> Your approach may be suitable for standard documents, but in many
> years of working with U-Boot (and Linux) we found that it does not
> work so well with the specific needs we have for a User's Manual. One
> issue is that you have to support many different boards (well, maybe
> not you as a user, but we as a community). And you have to include
> examples. And examples must really fit the board. If you for example
> provide a manual entry for the "erase" command you better make sure
> that your example does not erase a range of flash that on some board
> happens to hold the U-Boot image. etc.

It's my hope that the documentation system I proposed can be made
flexible enough to support things such as this without too much
headache. That's the hope at least :)

> That's how we came to the DULG we have today. I'm still convinced that
> this is a really well-working approach.
>
> It seems you don;t address this issue yet.
>

That's correct, I wanted to get feedback before spending too much time
digging into the details.

>
> > I see several advantages to adopting this scheme.
> > - Documentation should be easier to keep in sync with code
>
> Better than what we have with the DULG? I doubt it.
>
> > - DocBook XML output can be used to generate webpages, PDFs, text, etc,
> > which are all extensible
>
> We do the same with the DULG.
>

This would make DUTS/DULG more appealing. What is the process of
generating DocBook XML from DUTS/DULG?

> > - People don't have to reinvent the wheel when writing documentation
>
> Well, you just did that, it seems ;-)
>

It's true, I may have. :) On the other hand, it seems that there are
still a lot of people who are in the same boat. Most manuals I have
seen from other embedded companies (Freescale, Analog Devices, etc.)
seem to provide their own format/content. Additionally, most companies
will prefer to have their content formatted to match the rest of their
manuals, which is easily done from DocBook XML. Again, if you can do
that with DUTS/DULG, then that's great and probably eliminates the need
for this tool.

> > - Source code ends up being thouroughly commented
> >
> > These patches are just meant to be an example of how in-code documentation
> > could be used. You'll also notice there are many warnings regarding variables
> > the manual is referencing which aren't defined yet. I wanted to get some
> > feedback before diving in too far. What do others think? Is this worth
> > pursuing?
>
> Hm... we cannot look at your patches, you just posted the patch
> statistics, but no content.

This is just the patch series introduction, the actual content appears
in 1-3.

> The documentation itself seems to duplicate a lot of content we have
> in the DULG. I have to admit that I'd prefer to see the effort
> invested in improving the existing manual, than to come up with
> something different (and, as it seems, less flexible).

As I mentioned, I'm not all that familiar with the abilities of
DUTS/DULG, but I got the impression that there was still a fair amount
of manual labor involved for each manual. Thus most people (that I'm
familiar with) provide their own documentation and "reinvent the wheel".
I was hoping that creating documentation from comments in the source
would be easier to maintain and providing DocBook output would allow
others to more easily reuse the U-Boot manual contents.

Thanks for your time,
John
Wolfgang Denk
2009-07-28 21:27:55 UTC
Permalink
Dear John,

in message <1248813631.3915.102.camel at johns> you wrote:
>
> It seems to me that DUTS is designed to test U-Boot and also automates
> the running of commands whose output can be put online in the DULG. I

Correct. And the DULG itself is a wiki (TWiki at the moment, to be
converted to Foswiki ASAP) based framework which holds the "static"
parts of the documentation.

> didn't notice any documented procedure on how to turn the DULG into XML,
> extensible PDFs, etc. It also seems as if the DULG is a combination of
> hand-edited wiki pages as well as the DUTS output? I was hoping to

You probably can export the DULG into XML, too - but what would that
be good for? At the moment we export it into PDF, PostScript, HTML and
plain text.

> develop a system that's completely automated. I also noticed in a quick

Hm... "completely automated" is a nice buzzword, but you still have to
write the documentation in the first place.

The nice thing of the wiki based approach is that you can have a
(even random) collection of pages which can be "linearized" and
brought into arbitrary sets of linear doucumentation - this is what
the WebOrder pages are good for - see
http://www.denx.de/wiki/DULG/WebOrder

So you can use the same set of wiki pages an genreate for example the
full fledged manual, a short version including only the most
significant topics and an extended version including other stuff that
is normally not part of the manual - all from the same envrionment.

> probe around that a few items in the DULG seem to be out of sync (imd
> vs. i2c md, source vs. autoscr, etc.) and DHCP seems to be out of date
> as well. Is the process for updating the DULG automatic? If so, how is
> it done?

Soemone still has to write the documentation - and this is not always
done in sync with the code. Your approach of including the
documentation with the source code makes it more likely that one
remebers to update the docs as well, but just remember how many
places there are where code and comments don't agree - it's no
guarantee either.

If you find such areas in the DULG that are out of sync or missing
please feel free to add them - everybody can contribute and modify the
pages or add new content. And everyboidy can modify and extend the
DUTS test cases, too.

> As I mentioned, I borrowed this idea from the kernel-doc script in
> Linux, which does do API documentation. But my hope for the uboot-doc
> tool would be to create user documentation, or a manual we'd provide to
> a customer when they purchased a product that would describe available
> commands, environment variables, common operations, etc.

That's what the DULG does, so you are truely duplicating efforts.

> > Your approach may be suitable for standard documents, but in many
> > years of working with U-Boot (and Linux) we found that it does not
> > work so well with the specific needs we have for a User's Manual. One
> > issue is that you have to support many different boards (well, maybe
> > not you as a user, but we as a community). And you have to include
> > examples. And examples must really fit the board. If you for example
> > provide a manual entry for the "erase" command you better make sure
> > that your example does not erase a range of flash that on some board
> > happens to hold the U-Boot image. etc.
>
> It's my hope that the documentation system I proposed can be made
> flexible enough to support things such as this without too much
> headache. That's the hope at least :)

Heh. Look at the DULG implementation... it's simple for the first 3 or
4 boards, especially when these are similar. But try supporting ARM
and PowerPC and MIPS boards from N different vendors, with different
kernel versions etc.

> This would make DUTS/DULG more appealing. What is the process of
> generating DocBook XML from DUTS/DULG?

What would you need DocBook XML for?

> It's true, I may have. :) On the other hand, it seems that there are
> still a lot of people who are in the same boat. Most manuals I have
> seen from other embedded companies (Freescale, Analog Devices, etc.)
> seem to provide their own format/content. Additionally, most companies
> will prefer to have their content formatted to match the rest of their
> manuals, which is easily done from DocBook XML. Again, if you can do
> that with DUTS/DULG, then that's great and probably eliminates the need
> for this tool.

Ah, I see.

Well, we use htmldoc to generate .pdf and .ps files from HTML; you
could for example use Tidy to convert HTML to DocBook (and I'm sure
there are lots of other tools that can do that).

> > Hm... we cannot look at your patches, you just posted the patch
> > statistics, but no content.
>
> This is just the patch series introduction, the actual content appears
> in 1-3.

Yes, I know. Sorry, patches arrived shortly after I started replying,
and I didn;t notice.

> As I mentioned, I'm not all that familiar with the abilities of
> DUTS/DULG, but I got the impression that there was still a fair amount
> of manual labor involved for each manual. Thus most people (that I'm

Indeed there is a lot of manual labor involved in preparing and
updating the documentation (the framework, that is; once a board has
been configured and added to DUTS, generating the needed include
files is mostly an automatic procedure - just the upload of the files
to the web server has to be triggered manually, but even this is
scripted).

But you have to spend at least the same amount of writing and updating
the documentation, don't you?

> I was hoping that creating documentation from comments in the source
> would be easier to maintain and providing DocBook output would allow
> others to more easily reuse the U-Boot manual contents.

A very, very old version of the DULG was set up like this, using a set
of Perl scripts and generating DokBoot output. We switched to the wiki
based approach some 6 years ago, and I never had the slightest wish to
switch back.

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I had the rare misfortune of being one of the first people to try and
implement a PL/1 compiler. -- T. Cheatham
Robin Getz
2009-07-28 22:16:20 UTC
Permalink
On Tue 28 Jul 2009 17:27, Wolfgang Denk pondered:
> Dear John,
>
> in message <1248813631.3915.102.camel at johns> you wrote:
> >
> > It seems to me that DUTS is designed to test U-Boot and also automates
> > the running of commands whose output can be put online in the DULG. I
>
> Correct. And the DULG itself is a wiki (TWiki at the moment, to be
> converted to Foswiki ASAP) based framework which holds the "static"
> parts of the documentation.

While we are on the topics of wikis, and U-Boot docs, can we discuss the
license?

http://www.denx.de/wiki/view/DULG/Introduction#Section_2.1.

Since it is "is not permitted to sell this document or the derivative work or
to include it into any package or distribution that is not freely available
to everybody."

Not meaning to interpret licensing, but to me that means I can't copy/paste
sections into end product documentation, and ship the product for a fee...

Was that the intent?
Detlev Zundel
2009-07-30 09:59:07 UTC
Permalink
Hi Robin,

> On Tue 28 Jul 2009 17:27, Wolfgang Denk pondered:
>> Dear John,
>>
>> in message <1248813631.3915.102.camel at johns> you wrote:
>> >
>> > It seems to me that DUTS is designed to test U-Boot and also automates
>> > the running of commands whose output can be put online in the DULG. I
>>
>> Correct. And the DULG itself is a wiki (TWiki at the moment, to be
>> converted to Foswiki ASAP) based framework which holds the "static"
>> parts of the documentation.
>
> While we are on the topics of wikis, and U-Boot docs, can we discuss the
> license?
>
> http://www.denx.de/wiki/view/DULG/Introduction#Section_2.1.
>
> Since it is "is not permitted to sell this document or the derivative work or
> to include it into any package or distribution that is not freely available
> to everybody."
>
> Not meaning to interpret licensing, but to me that means I can't copy/paste
> sections into end product documentation, and ship the product for a fee...

That's how it is currently, yes.

> Was that the intent?

Not really - but I'll better let Wolfgang answer that question as he
came up with the original licence text.

It is on my priority list however to assemble a list of all contributors
and ask them if they agree to relicence their contributions under the
FDL.

Cheers
Detlev

--
Each language has its purpose, however humble. Each language expresses
the Yin and Yang of software. Each language has its place within the Tao.

But do not program in COBOL if you can avoid it.
-- The Tao of Programming
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu at denx.de
Wolfgang Denk
2009-07-30 18:45:29 UTC
Permalink
Hi,

In message <m2eiryebkk.fsf at ohwell.denx.de> Detlev Zundel wrote:
...
> > Not meaning to interpret licensing, but to me that means I can't copy/paste
> > sections into end product documentation, and ship the product for a fee...
>
> That's how it is currently, yes.
>
> > Was that the intent?
>
> Not really - but I'll better let Wolfgang answer that question as he
> came up with the original licence text.

Originally this actualy has been my intent. But that was a long, long
time ago, back when I was writing all these documentation only by
myself.

> It is on my priority list however to assemble a list of all contributors
> and ask them if they agree to relicence their contributions under the
> FDL.

Consider my permission as granted :-)

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Celestial navigation is based on the premise that the Earth is the
center of the universe. The premise is wrong, but the navigation
works. An incorrect model can be a useful tool. - Kelvin Throop III
Robin Getz
2009-07-30 19:50:40 UTC
Permalink
On Thu 30 Jul 2009 14:45, Wolfgang DenkVersion 1.3 pondered:
> Hi,
>
> In message <m2eiryebkk.fsf at ohwell.denx.de> Detlev Zundel wrote:
> ...
> > > Not meaning to interpret licensing, but to me that means I
> > > can't copy/paste sections into end product documentation, and ship
> > > the product for a fee...
> >
> > That's how it is currently, yes.
> >
> > > Was that the intent?
> >
> > Not really - but I'll better let Wolfgang answer that question as he
> > came up with the original licence text.
>
> Originally this actualy has been my intent. But that was a long, long
> time ago, back when I was writing all these documentation only by
> myself.
>
> > It is on my priority list however to assemble a list of all contributors
> > and ask them if they agree to relicence their contributions under the
> > FDL.
>
> Consider my permission as granted :-)

I assume - no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts? or did you desire something else?

Since Front-Cover Text is limited to 5 words, and Back-Cover Text is limited
to 25 words - how about (as Back-Cover Text) "This manual includes sections
from the Das U-Boot documentation, which can be found at
http://www.denx.de/wiki/U-Boot and is copyright it's authors. Included under
the Free Documentation License (v1.3)"

?
Wolfgang Denk
2009-07-30 19:55:49 UTC
Permalink
Dear Robin Getz,

In message <200907301550.40651.rgetz at blackfin.uclinux.org> you wrote:
>
> I assume - no Invariant Sections, no Front-Cover Texts, and no Back-Cover
> Texts? or did you desire something else?

We don't have such detailed plans yet. I see no need for Invariant
Sections.

> Since Front-Cover Text is limited to 5 words, and Back-Cover Text is limited
> to 25 words - how about (as Back-Cover Text) "This manual includes sections
> from the Das U-Boot documentation, which can be found at
> http://www.denx.de/wiki/U-Boot and is copyright it's authors. Included under
> the Free Documentation License (v1.3)"
>
> ?

Maybe something like that. Thanks for the proposal :-)

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Einstein argued that there must be simplified explanations of nature,
because God is not capricious or arbitrary. No such faith comforts
the software engineer. - Fred Brooks, Jr.
Robin Getz
2009-07-31 01:49:02 UTC
Permalink
On Thu 30 Jul 2009 15:55, Wolfgang Denk pondered:
> Dear Robin Getz,
>
> In message <200907301550.40651.rgetz at blackfin.uclinux.org> you wrote:
> >
> > I assume - no Invariant Sections, no Front-Cover Texts, and no Back-Cover
> > Texts? or did you desire something else?
>
> We don't have such detailed plans yet.

Depending on the exact final plans, Analog Devices would be happy to donate
anything from the U-Boot documentation we have created over the past few
years....

https://docs.blackfin.uclinux.org/doku.php?id=bootloaders:u-boot

While the examples are Blackfin specific, most should be generic enough to
ensure that the reader should understand what to do on their architecture. We
see maintaining something separate a duplication of effort, and wasted
resources spent on documentation creation (which is a task most developers
don't like anyways)...


I think Mike brought this up awhile ago -
http://www.mail-archive.com/u-boot-users at lists.sourceforge.net/msg04491.html

Which gets back to the original question...

On Thu, 17 Apr 2008 11:02:18 -0700 Mike Frysinger pondered:
> On Thursday 17 April 2008, Detlev Zundel wrote:
> > Hi Mike,
> >
> > > On Monday 14 April 2008, Detlev Zundel wrote:
> > >> > we maintain a Blackfin-specific u-boot wiki that goes into quite a
> > >> > bit of detail, some of which is duplicated with the main u-boot
> > >> > wiki. how do people feel about extending the u-boot wiki to allow
> > >> > for arch-specific details ?
> > >>
> > >> What exactly do you have in mind? I surely don't see any principal
> > >> problem here.
> > >>
> > >> It would certainly be valuable to get all U-Boot related info
> > >> collected in a central place and have pointers wherever that make
> > >> sense...
> > >
> > > from my reading of the wiki, it's more of a technical/command reference
> > > than a guide. the wiki we maintain is geared to be more of a guide. i
> > > think the two can be merged, i just dont want to convert things only to
> > > find out people dont want to take it that direction.
> >
> > Just to be clear, we are discussing the DULG wiki, right?
>
> is there any other worth talking about :)
>
> > I agree that in the current state the documentation is more a reference
> > but IIRC that wasn't really a conscious design decision. It simply
> > turned out this way in the end.
> >
> > So I do not see any general problem in adding "guide style" sections in
> > there. Maybe then most of the current documentation can then be shifted
> > to a "commands reference" section.
>
> OK
>
> > One problem I see though is how to correctly adapt such sections to the
> > board specific nature of the DULG. Hopefully we can get away with
> > mostly generic text passages and only a few ifdefs. It would be very
> > helpful to know more concrete plans (outline!) to think further about
> > these implications.

Are there any thoughts about this?
Mike Frysinger
2009-08-13 07:32:20 UTC
Permalink
On Thursday 30 July 2009 05:59:07 Detlev Zundel wrote:
> It is on my priority list however to assemble a list of all contributors
> and ask them if they agree to relicence their contributions under the
> FDL.

why not CC-BY-SA ? the wikipedia page has a bunch of references to FDL being
a bad idea, and even the Debian guys declare it a non-free license.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20090813/46e096a6/attachment.pgp
jschmoller
2009-07-29 14:48:15 UTC
Permalink
On Tue, 2009-07-28 at 23:27 +0200, Wolfgang Denk wrote:
> Dear John,
>
> in message <1248813631.3915.102.camel at johns> you wrote:
> >
> > It seems to me that DUTS is designed to test U-Boot and also automates
> > the running of commands whose output can be put online in the DULG. I
>
> Correct. And the DULG itself is a wiki (TWiki at the moment, to be
> converted to Foswiki ASAP) based framework which holds the "static"
> parts of the documentation.
>
> > didn't notice any documented procedure on how to turn the DULG into XML,
> > extensible PDFs, etc. It also seems as if the DULG is a combination of
> > hand-edited wiki pages as well as the DUTS output? I was hoping to
>
> You probably can export the DULG into XML, too - but what would that
> be good for? At the moment we export it into PDF, PostScript, HTML and
> plain text.

Exporting to XML (and specifically DocBook XML, which is widely
supported and accepted as a standard (at least that's what the tech
writer next to me says :) ) is, I feel, a key to this whole process.
Since XML doesn't specify a style, but rather what the content *means*,
style sheets can be designed to turn the DocBook XML into anything, in
any format, rearranged in any way, and with any style (fonts, colors,
graphics). Again, I'm not familiar with the process you use to export
HTML to PFD, PS, etc. but I'm guessing that the formatting and style end
up being very similar.

> > develop a system that's completely automated. I also noticed in a quick
>
> Hm... "completely automated" is a nice buzzword, but you still have to
> write the documentation in the first place.

You're in luck, I've already volunteered to write it in the first
place :) and much of it is already done. Take a look at the manual
posted on the X-ES website and see for yourself.
http://www.xes-inc.com/sources/u-boot/xpedite5370.pdf This manual was
completely generated with my tool.

> The nice thing of the wiki based approach is that you can have a
> (even random) collection of pages which can be "linearized" and
> brought into arbitrary sets of linear doucumentation - this is what
> the WebOrder pages are good for - see
> http://www.denx.de/wiki/DULG/WebOrder
>
> So you can use the same set of wiki pages an genreate for example the
> full fledged manual, a short version including only the most
> significant topics and an extended version including other stuff that
> is normally not part of the manual - all from the same envrionment.

This is definitely possible with DocBook XML. For those who care, I'm
thinking the @role attribute available in standard DocBook, though there
may be a better way. I'll talk this through with our tech writers.

> > probe around that a few items in the DULG seem to be out of sync (imd
> > vs. i2c md, source vs. autoscr, etc.) and DHCP seems to be out of date
> > as well. Is the process for updating the DULG automatic? If so, how is
> > it done?
>
> Soemone still has to write the documentation - and this is not always
> done in sync with the code. Your approach of including the
> documentation with the source code makes it more likely that one
> remebers to update the docs as well, but just remember how many
> places there are where code and comments don't agree - it's no
> guarantee either.

I would guess someone is several dozen times more likely to update a
documentation snippet in the source over modifying a Wiki page.

> If you find such areas in the DULG that are out of sync or missing
> please feel free to add them - everybody can contribute and modify the
> pages or add new content. And everyboidy can modify and extend the
> DUTS test cases, too.
>
> > As I mentioned, I borrowed this idea from the kernel-doc script in
> > Linux, which does do API documentation. But my hope for the uboot-doc
> > tool would be to create user documentation, or a manual we'd provide to
> > a customer when they purchased a product that would describe available
> > commands, environment variables, common operations, etc.
>
> That's what the DULG does, so you are truely duplicating efforts.

As I mentioned earlier, it seems to me that most vendors are creating
their own manuals. That either means knowledge of the existence of DULG
is limited, or the tool isn't meeting people's needs. In order to use
it, you need to download a completely separate package (DUTS), learn to
use it, then hand edit the output into a Wiki page. The advantage with
a documentation engine distributed with the sources is that there is no
learning curve. "make pdf" creates a perfectly suitable PDF manual, and
with a little work (first time only) they can make it look like anything
and chug out manuals for all their boards in minutes.

> > > Your approach may be suitable for standard documents, but in many
> > > years of working with U-Boot (and Linux) we found that it does not
> > > work so well with the specific needs we have for a User's Manual. One
> > > issue is that you have to support many different boards (well, maybe
> > > not you as a user, but we as a community). And you have to include
> > > examples. And examples must really fit the board. If you for example
> > > provide a manual entry for the "erase" command you better make sure
> > > that your example does not erase a range of flash that on some board
> > > happens to hold the U-Boot image. etc.
> >
> > It's my hope that the documentation system I proposed can be made
> > flexible enough to support things such as this without too much
> > headache. That's the hope at least :)
>
> Heh. Look at the DULG implementation... it's simple for the first 3 or
> 4 boards, especially when these are similar. But try supporting ARM
> and PowerPC and MIPS boards from N different vendors, with different
> kernel versions etc.

That, I believe, is one of the strengths of the tool I created. First,
it uses the C pre-compiler to conditionally include comments from
source. Secondly, the common XML templates support pre-compiler
directives, so you can #ifdef in a section only when such-and-such is
defined. And finally, if your manual requirements are dramatically
different than others, a whole template can be overridden (or a whole
new template added or deleted) in the board/${BOARDDIR}/manual
directory. In my opinion, that's pretty flexible.

> > This would make DUTS/DULG more appealing. What is the process of
> > generating DocBook XML from DUTS/DULG?
>
> What would you need DocBook XML for?

As I mentioned above, I think the presence of DocBook XML is crucial to
gain wide acceptance. When people see that this tool can generate
manuals that look just like the manuals they offer now, I think that
will make the sale.

> > It's true, I may have. :) On the other hand, it seems that there are
> > still a lot of people who are in the same boat. Most manuals I have
> > seen from other embedded companies (Freescale, Analog Devices, etc.)
> > seem to provide their own format/content. Additionally, most companies
> > will prefer to have their content formatted to match the rest of their
> > manuals, which is easily done from DocBook XML. Again, if you can do
> > that with DUTS/DULG, then that's great and probably eliminates the need
> > for this tool.
>
> Ah, I see.
>
> Well, we use htmldoc to generate .pdf and .ps files from HTML; you
> could for example use Tidy to convert HTML to DocBook (and I'm sure
> there are lots of other tools that can do that).

XML specifies what the data means. HTML specifies what the data should
look like. In my head, it's intuitive to say titles should be big and
bold, but it's not intuitive to say big and bold should be a title. The
conversion is imperfect. DocBook has a page on doing just that, and
it's 5 steps which would probably several hours to get right for each
manual.
http://wiki.docbook.org/topic/Html2DocBook

> > > Hm... we cannot look at your patches, you just posted the patch
> > > statistics, but no content.
> >
> > This is just the patch series introduction, the actual content appears
> > in 1-3.
>
> Yes, I know. Sorry, patches arrived shortly after I started replying,
> and I didn;t notice.
>
> > As I mentioned, I'm not all that familiar with the abilities of
> > DUTS/DULG, but I got the impression that there was still a fair amount
> > of manual labor involved for each manual. Thus most people (that I'm
>
> Indeed there is a lot of manual labor involved in preparing and
> updating the documentation (the framework, that is; once a board has
> been configured and added to DUTS, generating the needed include
> files is mostly an automatic procedure - just the upload of the files
> to the web server has to be triggered manually, but even this is
> scripted).
>
> But you have to spend at least the same amount of writing and updating
> the documentation, don't you?

At least the way I see it, with your tool there's a fair amount of
manual labor for every manual. With my tool, it's a similar amount of
manual labor once for everyone in the whole community. Say we add a new
command, it's extra work to comment it properly, but then everyone in
the community reaps the benefits. Or more complexly, we add an entirely
new interface of some sort, and a whole new manual section needs to be
written. Someone writes it once and everyone in the community can reuse
that section. And sure, you could do that with the DULG, but that's
copy-and-paste-and-edit manual labor. For this tool, it would either be
just run "make pdf" again, or possibly add a #define to your config file
and then run "make pdf".

> > I was hoping that creating documentation from comments in the source
> > would be easier to maintain and providing DocBook output would allow
> > others to more easily reuse the U-Boot manual contents.
>
> A very, very old version of the DULG was set up like this, using a set
> of Perl scripts and generating DokBoot output. We switched to the wiki
> based approach some 6 years ago, and I never had the slightest wish to
> switch back.

I do see the benefit of using a wiki, but I feel that it doesn't fit the
needs of many U-Boot developers who need to generate documentation in a
variety of styles and formats. I have to assume the vast majority of
current U-Boot developers are rolling their own documentation as most
boards are not supported by DULG. My hope is that if we generated
U-Boot User's manuals in a different, easier manner with a more flexible
output many more people could use it, thereby saving time which they can
put to improving U-Boot itself :)

Thanks,
John
Simon Guinot
2011-05-02 21:01:37 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

This patch series adds support for Network Space v2 board and parents.

Changes since v1:
- netconsole: restore NetOurIP check
- add entries to MAINTAINERS file
- move boards from root Makefile to boards.cfg
- move MACH_TYPE definition into netspace_v2.h
- remove CONFIG_SYS_HZ redefinition
- turn PHY initialization message into debug()

Changes since v2:
- drop patch for Macronix MX25L4005A
- rewrite patch "sf: disable write protection for Macronix flash",
using the common spi flash code
- fix "Definitions" typo in mv-common.h
- netconsole: add a "/* Fall through */" comment before the NETCONS
case label

Changes since v3:
- sf macronix: use spi_flash_cmd_write_enable()
- enhance commit message for patch "Add support for Network Space v2"

Simon Guinot (5):
sf: disable write protection for Macronix flash
Kirkwood: allow to override CONFIG_SYS_TCLK
mv-common.h: fix DRAM banks configuration
netconsole: remove `serverip' check
Add support for Network Space v2

MAINTAINERS | 6 +
arch/arm/include/asm/arch-kirkwood/kw88f6281.h | 8 +-
board/LaCie/netspace_v2/Makefile | 49 +++++++
board/LaCie/netspace_v2/kwbimage.cfg | 162 ++++++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.c | 144 +++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.h | 39 ++++++
boards.cfg | 3 +
drivers/mtd/spi/macronix.c | 42 ++++++
include/configs/mv-common.h | 8 +-
include/configs/netspace_v2.h | 149 ++++++++++++++++++++++
net/net.c | 3 +-
11 files changed, 605 insertions(+), 8 deletions(-)
create mode 100644 board/LaCie/netspace_v2/Makefile
create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
create mode 100644 include/configs/netspace_v2.h
Wolfgang Denk
2011-05-02 21:29:35 UTC
Permalink
Dear Simon Guinot,

In message <1304370102-5978-1-git-send-email-simon.guinot at sequanux.org> you wrote:
> From: Simon Guinot <sguinot at lacie.com>
>
> This patch series adds support for Network Space v2 board and parents.
>
> Changes since v1:
...

Please read
http://www.denx.de/wiki/view/U-Boot/Patches#Sending_updated_patch_versions

You are supposed to provide such a changelog not (only) in a header
message, but in each patch of the series.

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
If it happens once, it's a bug.
If it happens twice, it's a feature.
If it happens more than twice, it's a design philosophy.
Simon Guinot
2011-05-02 22:46:39 UTC
Permalink
Hi Wolfgang,

On Mon, May 02, 2011 at 11:29:35PM +0200, Wolfgang Denk wrote:
> Dear Simon Guinot,
>
> In message <1304370102-5978-1-git-send-email-simon.guinot at sequanux.org> you wrote:
> > From: Simon Guinot <sguinot at lacie.com>
> >
> > This patch series adds support for Network Space v2 board and parents.
> >
> > Changes since v1:
> ...
>
> Please read
> http://www.denx.de/wiki/view/U-Boot/Patches#Sending_updated_patch_versions
>
> You are supposed to provide such a changelog not (only) in a header
> message, but in each patch of the series.

Added to v5.

Thanks,

Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110502/99fc84d1/attachment.pgp
Simon Guinot
2011-05-02 21:01:40 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

The asm/arch/config.h header define CONFIG_NR_DRAM_BANKS_MAX, which is
needed to configure DRAM banks.

This patch move the asm/arch/config.h header inclusion above the DRAM
banks configuration.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---
include/configs/mv-common.h | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index a8937dd..0a39257 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -113,6 +113,9 @@
#define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */
#define CONFIG_SYS_MAXARGS 16 /* max number of command args */

+/* ====> Include platform Common Definitions */
+#include <asm/arch/config.h>
+
/*
* DRAM Banks configuration, Custom config can be done in <board>.h
*/
@@ -124,10 +127,7 @@
#endif
#endif /* CONFIG_NR_DRAM_BANKS */

-/* ====> Include platform Common Definations */
-#include <asm/arch/config.h>
-
-/* ====> Include driver Common Definations */
+/* ====> Include driver Common Definitions */
/*
* Common NAND configuration
*/
--
1.6.3.1
Simon Guinot
2011-05-02 21:01:38 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---
drivers/mtd/spi/macronix.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index 96fd5f0..dacbc28 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -117,6 +117,45 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
},
};

+static int macronix_write_status(struct spi_flash *flash, u8 sr)
+{
+ u8 cmd;
+ int ret;
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret < 0) {
+ debug("SF: enabling write failed\n");
+ return ret;
+ }
+
+ cmd = CMD_MX25XX_WRSR;
+ ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &sr, 1);
+ if (ret) {
+ debug("SF: fail to write status register\n");
+ return ret;
+ }
+
+ ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+ if (ret < 0) {
+ debug("SF: write status register timed out\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int macronix_unlock(struct spi_flash *flash)
+{
+ int ret;
+
+ /* Enable status register writing and clear BP# bits */
+ ret = macronix_write_status(flash, 0);
+ if (ret)
+ debug("SF: fail to disable write protection\n");
+
+ return ret;
+}
+
static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len);
@@ -157,5 +196,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
* params->sectors_per_block;
flash->size = flash->sector_size * params->nr_blocks;

+ /* Clear BP# bits for read-only flash */
+ macronix_unlock(flash);
+
return flash;
}
--
1.6.3.1
Mike Frysinger
2011-05-02 21:07:02 UTC
Permalink
thanks, ive added this to my sf branch
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110502/6fbac8c9/attachment.pgp
Simon Guinot
2011-05-02 21:01:41 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

Netconsole use the environment variable `ncip' to configure the
destination IP. `serverip' don't need to be defined.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---
net/net.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/net.c b/net/net.c
index e50bdf1..19ac019 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1718,7 +1718,6 @@ static int net_check_prereq (proto_t protocol)
#if defined(CONFIG_CMD_NFS)
case NFS:
#endif
- case NETCONS:
case TFTP:
if (NetServerIP == 0) {
puts ("*** ERROR: `serverip' not set\n");
@@ -1728,7 +1727,9 @@ static int net_check_prereq (proto_t protocol)
defined(CONFIG_CMD_DNS)
common:
#endif
+ /* Fall through */

+ case NETCONS:
if (NetOurIP == 0) {
puts ("*** ERROR: `ipaddr' not set\n");
return (1);
--
1.6.3.1
Simon Guinot
2011-05-02 21:01:39 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

This patch allow to override CONFIG_SYS_TCLK from board configuration
files. This is needed for the Network Space v2 which use a non standard
core clock frequency (166MHz instead of 200MHz for a 6281 SoC).

As a possible enhancement for 6281 and 6282 devices, TCLK could be
dynamically detected by checking the Sample at Reset register bit 21.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
Acked-by: Prafulla Wadaskar <Prafulla at marvell.com>
---
arch/arm/include/asm/arch-kirkwood/kw88f6281.h | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
index 80723ea..22d10f1 100644
--- a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
+++ b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
@@ -27,11 +27,13 @@
#ifndef _ASM_ARCH_KW88F6281_H
#define _ASM_ARCH_KW88F6281_H

-/* SOC specific definations */
+/* SOC specific definitions */
#define KW88F6281_REGS_PHYS_BASE 0xf1000000
#define KW_REGS_PHY_BASE KW88F6281_REGS_PHYS_BASE

-/* TCLK Core Clock defination*/
-#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
+/* TCLK Core Clock definition */
+#ifndef CONFIG_SYS_TCLK
+#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
+#endif

#endif /* _ASM_ARCH_KW88F6281_H */
--
1.6.3.1
Simon Guinot
2011-05-02 21:01:42 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

This patch add support for the Network Space v2 board and parents, based
on the Marvell Kirkwood SoC. This include Network Space (Max) v2 and
Internet Space v2.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---
MAINTAINERS | 6 +
board/LaCie/netspace_v2/Makefile | 49 ++++++++++
board/LaCie/netspace_v2/kwbimage.cfg | 162 +++++++++++++++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.c | 144 +++++++++++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.h | 39 ++++++++
boards.cfg | 3 +
include/configs/netspace_v2.h | 149 ++++++++++++++++++++++++++++++
7 files changed, 552 insertions(+), 0 deletions(-)
create mode 100644 board/LaCie/netspace_v2/Makefile
create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
create mode 100644 include/configs/netspace_v2.h

diff --git a/MAINTAINERS b/MAINTAINERS
index e2a4ba9..f905a48 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -652,6 +652,12 @@ Sedji Gaouaou<sedji.gaouaou at atmel.com>
at91sam9g10ek ARM926EJS (AT91SAM9G10 SoC)
at91sam9m10g45ek ARM926EJS (AT91SAM9G45 SoC)

+Simon Guinot <simon.guinot at sequanux.org>
+
+ inetspace_v2 ARM926EJS (Kirkwood SoC)
+ netspace_v2 ARM926EJS (Kirkwood SoC)
+ netspace_max_v2 ARM926EJS (Kirkwood SoC)
+
Marius Gr?ger <mag at sysgo.de>

impa7 ARM720T (EP7211)
diff --git a/board/LaCie/netspace_v2/Makefile b/board/LaCie/netspace_v2/Makefile
new file mode 100644
index 0000000..a245f2c
--- /dev/null
+++ b/board/LaCie/netspace_v2/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := netspace_v2.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/LaCie/netspace_v2/kwbimage.cfg b/board/LaCie/netspace_v2/kwbimage.cfg
new file mode 100644
index 0000000..361feeb
--- /dev/null
+++ b/board/LaCie/netspace_v2/kwbimage.cfg
@@ -0,0 +1,162 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# Refer docs/README.kwimage for more details about how-to configure
+# and create kirkwood boot image
+#
+
+# Boot Media configurations
+BOOT_FROM spi # Boot from SPI flash
+
+# SOC registers configuration using bootrom header extension
+# Maximum KWBIMAGE_MAX_CONFIG configurations allowed
+
+# Configure RGMII-0 interface pad voltage to 1.8V
+DATA 0xFFD100e0 0x1B1B1B9B
+
+#Dram initalization for SINGLE x16 CL=5 @ 400MHz
+DATA 0xFFD01400 0x43000618 # DDR Configuration register
+# bit13-0: 0xa00 (2560 DDR2 clks refresh rate)
+# bit23-14: zero
+# bit24: 1= enable exit self refresh mode on DDR access
+# bit25: 1 required
+# bit29-26: zero
+# bit31-30: 01
+
+DATA 0xFFD01404 0x35143000 # DDR Controller Control Low
+# bit 4: 0=addr/cmd in smame cycle
+# bit 5: 0=clk is driven during self refresh, we don't care for APX
+# bit 6: 0=use recommended falling edge of clk for addr/cmd
+# bit14: 0=input buffer always powered up
+# bit18: 1=cpu lock transaction enabled
+# bit23-20: 5=recommended value for CL=5 and STARTBURST_DEL disabled bit31=0
+# bit27-24: 8= CL+3, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
+# bit30-28: 3 required
+# bit31: 0=no additional STARTBURST delay
+
+DATA 0xFFD01408 0x11012228 # DDR Timing (Low) (active cycles value +1)
+# bit7-4: TRCD
+# bit11- 8: TRP
+# bit15-12: TWR
+# bit19-16: TWTR
+# bit20: TRAS msb
+# bit23-21: 0x0
+# bit27-24: TRRD
+# bit31-28: TRTP
+
+DATA 0xFFD0140C 0x00000A19 # DDR Timing (High)
+# bit6-0: TRFC
+# bit8-7: TR2R
+# bit10-9: TR2W
+# bit12-11: TW2W
+# bit31-13: zero required
+
+DATA 0xFFD01410 0x0000CCCC # DDR Address Control
+# bit1-0: 01, Cs0width=x16
+# bit3-2: 11, Cs0size=1Gb
+# bit5-4: 00, Cs2width=nonexistent
+# bit7-6: 00, Cs1size =nonexistent
+# bit9-8: 00, Cs2width=nonexistent
+# bit11-10: 00, Cs2size =nonexistent
+# bit13-12: 00, Cs3width=nonexistent
+# bit15-14: 00, Cs3size =nonexistent
+# bit16: 0, Cs0AddrSel
+# bit17: 0, Cs1AddrSel
+# bit18: 0, Cs2AddrSel
+# bit19: 0, Cs3AddrSel
+# bit31-20: 0 required
+
+DATA 0xFFD01414 0x00000000 # DDR Open Pages Control
+# bit0: 0, OpenPage enabled
+# bit31-1: 0 required
+
+DATA 0xFFD01418 0x00000000 # DDR Operation
+# bit3-0: 0x0, DDR cmd
+# bit31-4: 0 required
+
+DATA 0xFFD0141C 0x00000632 # DDR Mode
+# bit2-0: 2, BurstLen=2 required
+# bit3: 0, BurstType=0 required
+# bit6-4: 4, CL=5
+# bit7: 0, TestMode=0 normal
+# bit8: 0, DLL reset=0 normal
+# bit11-9: 6, auto-precharge write recovery ????????????
+# bit12: 0, PD must be zero
+# bit31-13: 0 required
+
+DATA 0xFFD01420 0x00000004 # DDR Extended Mode
+# bit0: 0, DDR DLL enabled
+# bit1: 1, DDR drive strenght reduced
+# bit2: 1, DDR ODT control lsd enabled
+# bit5-3: 000, required
+# bit6: 1, DDR ODT control msb, enabled
+# bit9-7: 000, required
+# bit10: 0, differential DQS enabled
+# bit11: 0, required
+# bit12: 0, DDR output buffer enabled
+# bit31-13: 0 required
+
+DATA 0xFFD01424 0x0000F07F # DDR Controller Control High
+# bit2-0: 111, required
+# bit3 : 1 , MBUS Burst Chop disabled
+# bit6-4: 111, required
+# bit7 : 1 , D2P Latency enabled
+# bit8 : 1 , add writepath sample stage, must be 1 for DDR freq >= 300MHz
+# bit9 : 0 , no half clock cycle addition to dataout
+# bit10 : 0 , 1/4 clock cycle skew enabled for addr/ctl signals
+# bit11 : 0 , 1/4 clock cycle skew disabled for write mesh
+# bit15-12: 1111 required
+# bit31-16: 0 required
+
+DATA 0xFFD01428 0x00085520 # DDR2 ODT Read Timing (default values)
+DATA 0xFFD0147C 0x00008552 # DDR2 ODT Write Timing (default values)
+
+DATA 0xFFD01500 0x00000000 # CS[0]n Base address to 0x0
+DATA 0xFFD01504 0x0FFFFFF1 # CS[0]n Size
+# bit0: 1, Window enabled
+# bit1: 0, Write Protect disabled
+# bit3-2: 00, CS0 hit selected
+# bit23-4: ones, required
+# bit31-24: 0x07, Size (i.e. 128MB)
+
+DATA 0xFFD0150C 0x00000000 # CS[1]n Size, window disabled
+DATA 0xFFD01514 0x00000000 # CS[2]n Size, window disabled
+DATA 0xFFD0151C 0x00000000 # CS[3]n Size, window disabled
+
+DATA 0xFFD01494 0x00010000 # DDR ODT Control (Low)
+# bit3-0: 1, ODT0Rd, MODT[0] asserted during read from DRAM CS0
+# bit19-16:1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
+
+DATA 0xFFD01498 0x00000000 # DDR ODT Control (High)
+# bit1-0: 00, ODT0 controlled by ODT Control (low) register above
+# bit3-2: 01, ODT1 active NEVER!
+# bit31-4: zero, required
+
+DATA 0xFFD0149C 0x0000E40F # CPU ODT Control
+# bit3-0: 1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
+# bit7-4: 1, ODT0Wr, Internal ODT asserted during write to DRAM bank0
+# bit11-10:1, DQ_ODTSel. ODT select turned on
+
+DATA 0xFFD01480 0x00000001 # DDR Initialization Control
+#bit0=1, enable DDR init upon this register write
+
+# End of Header extension
+DATA 0x0 0x0
diff --git a/board/LaCie/netspace_v2/netspace_v2.c b/board/LaCie/netspace_v2/netspace_v2.c
new file mode 100644
index 0000000..9bc9940
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <command.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/arch/mpp.h>
+#include <asm/arch/gpio.h>
+#include "netspace_v2.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_early_init_f(void)
+{
+ /* Gpio configuration */
+ kw_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
+ NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
+
+ /* Multi-Purpose Pins Functionality configuration */
+ u32 kwmpp_config[] = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP4_NF_IO6,
+ MPP5_NF_IO7,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Fan speed (bit 1) */
+ MPP8_TW_SDA,
+ MPP9_TW_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_GPO, /* Red led */
+ MPP14_GPIO, /* USB fuse */
+ MPP16_GPIO, /* SATA 0 power */
+ MPP17_GPIO, /* SATA 1 power */
+ MPP18_NF_IO0,
+ MPP19_NF_IO1,
+ MPP20_SATA1_ACTn,
+ MPP21_SATA0_ACTn,
+ MPP22_GPIO, /* Fan speed (bit 0) */
+ MPP23_GPIO, /* Fan power */
+ MPP24_GPIO, /* USB mode select */
+ MPP25_GPIO, /* Fan rotation fail */
+ MPP26_GPIO, /* USB vbus-in detection */
+ MPP28_GPIO, /* USB enable vbus-out */
+ MPP29_GPIO, /* Blue led (slow register) */
+ MPP30_GPIO, /* Blue led (command register) */
+ MPP31_GPIO, /* Board power off */
+ MPP32_GPIO, /* Button (0 = Released, 1 = Pushed) */
+ MPP33_GPIO, /* Fan speed (bit 2) */
+ 0
+ };
+ kirkwood_mpp_conf(kwmpp_config);
+
+ return 0;
+}
+
+int board_init(void)
+{
+ /* Machine number */
+ gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
+
+ /* Boot parameters address */
+ gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+
+ return 0;
+}
+
+void mv_phy_88e1116_init(char *name)
+{
+ u16 reg;
+ u16 devadr;
+
+ if (miiphy_set_current_dev(name))
+ return;
+
+ /* command to read PHY dev address */
+ if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
+ printf("Err..(%s) could not read PHY dev address\n", __func__);
+ return;
+ }
+
+ /*
+ * Enable RGMII delay on Tx and Rx for CPU port
+ * Ref: sec 4.7.2 of chip datasheet
+ */
+ miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
+ miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
+ reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
+ miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
+ miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+
+ /* reset the phy */
+ if (miiphy_read(name, devadr, MII_BMCR, &reg) != 0) {
+ printf("Err..(%s) PHY status read failed\n", __func__);
+ return;
+ }
+ if (miiphy_write(name, devadr, MII_BMCR, reg | 0x8000) != 0) {
+ printf("Err..(%s) PHY reset failed\n", __func__);
+ return;
+ }
+
+ debug("88E1116 Initialized on %s\n", name);
+}
+
+/* Configure and initialize PHY */
+void reset_phy(void)
+{
+ mv_phy_88e1116_init("egiga0");
+}
+
+#define NETSPACE_V2_GPIO_BUTTON 32
+
+/* Return GPIO button status */
+static int
+do_read_button(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ return kw_gpio_get_value(NETSPACE_V2_GPIO_BUTTON);
+}
+
+U_BOOT_CMD(button, 1, 1, do_read_button,
+ "Return GPIO button status 0=off 1=on", "");
diff --git a/board/LaCie/netspace_v2/netspace_v2.h b/board/LaCie/netspace_v2/netspace_v2.h
new file mode 100644
index 0000000..c26a6e0
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef NETSPACE_V2_H
+#define NETSPACE_V2_H
+
+#define NETSPACE_V2_OE_LOW 0x06004000
+#define NETSPACE_V2_OE_HIGH 0x00000031
+#define NETSPACE_V2_OE_VAL_LOW 0x10030000
+#define NETSPACE_V2_OE_VAL_HIGH 0x00000000
+
+/* PHY related */
+#define MV88E1116_LED_FCTRL_REG 10
+#define MV88E1116_CPRSP_CR3_REG 21
+#define MV88E1116_MAC_CTRL_REG 21
+#define MV88E1116_PGADR_REG 22
+#define MV88E1116_RGMII_TXTM_CTRL (1 << 4)
+#define MV88E1116_RGMII_RXTM_CTRL (1 << 5)
+
+#endif /* NETSPACE_V2_H */
diff --git a/boards.cfg b/boards.cfg
index 2b0900a..459dee4 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -106,6 +106,9 @@ davinci_sonata arm arm926ejs sonata davinci
suen3 arm arm926ejs km_arm keymile kirkwood
suen8 arm arm926ejs km_arm keymile kirkwood
mgcoge2un arm arm926ejs km_arm keymile kirkwood
+inetspace_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:INETSPACE_V2
+netspace_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:NETSPACE_V2
+netspace_max_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:NETSPACE_MAX_V2
guruplug arm arm926ejs - Marvell kirkwood
mv88f6281gtw_ge arm arm926ejs - Marvell kirkwood
openrd_base arm arm926ejs - Marvell kirkwood
diff --git a/include/configs/netspace_v2.h b/include/configs/netspace_v2.h
new file mode 100644
index 0000000..ca4db53
--- /dev/null
+++ b/include/configs/netspace_v2.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CONFIG_NETSPACE_V2_H
+#define _CONFIG_NETSPACE_V2_H
+
+/*
+ * Machine number definition
+ */
+#if defined(CONFIG_INETSPACE_V2)
+#define CONFIG_MACH_TYPE MACH_TYPE_INETSPACE_V2
+#define CONFIG_IDENT_STRING " LaCie Internet Space v2"
+#elif defined(CONFIG_NETSPACE_V2)
+#define CONFIG_MACH_TYPE MACH_TYPE_NETSPACE_V2
+#define CONFIG_IDENT_STRING " LaCie Network Space v2"
+#elif defined(CONFIG_NETSPACE_MAX_V2)
+#define CONFIG_MACH_TYPE MACH_TYPE_NETSPACE_MAX_V2
+#define CONFIG_IDENT_STRING " LaCie Network Space Max v2"
+#endif
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_FEROCEON_88FR131 1 /* CPU Core subversion */
+#define CONFIG_KIRKWOOD 1 /* SOC Family Name */
+#define CONFIG_KW88F6281 1 /* SOC Name */
+#define CONFIG_MACH_NETSPACE_V2 1 /* Machine type */
+#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */
+
+/*
+ * Commands configuration
+ */
+#define CONFIG_SYS_NO_FLASH /* Declare no flash (NOR/SPI) */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IDE
+#define CONFIG_CMD_USB
+
+/*
+ * Core clock definition.
+ */
+#define CONFIG_SYS_TCLK 166000000 /* 166MHz */
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#define CONFIG_NR_DRAM_BANKS 2
+#include "mv-common.h"
+
+/* Remove or override few declarations from mv-common.h */
+#undef CONFIG_RBTREE
+#undef CONFIG_ENV_SPI_MAX_HZ
+#undef CONFIG_SYS_IDE_MAXBUS
+#undef CONFIG_SYS_IDE_MAXDEVICE
+#undef CONFIG_SYS_PROMPT
+#define CONFIG_ENV_SPI_MAX_HZ 20000000 /* 20Mhz */
+#define CONFIG_SYS_IDE_MAXBUS 1
+#define CONFIG_SYS_IDE_MAXDEVICE 1
+#define CONFIG_SYS_PROMPT "ns2> "
+
+/*
+ * Ethernet Driver configuration
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_MVGBE_PORTS {1, 0} /* enable port 0 only */
+#define CONFIG_NETCONSOLE
+#endif
+
+/*
+ * SATA Driver configuration
+ */
+#ifdef CONFIG_MVSATA_IDE
+#define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET
+/* Network Space Max v2 use 2 SATA ports */
+#ifdef CONFIG_NETSPACE_MAX_V2
+#define CONFIG_SYS_ATA_IDE1_OFFSET MV_SATA_PORT1_OFFSET
+#endif
+#endif
+
+/*
+ * Enable GPI0 support
+ */
+#define CONFIG_KIRKWOOD_GPIO
+
+/*
+ * File systems support
+ */
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+
+/*
+ * Use the HUSH parser
+ */
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+
+/*
+ * Console configuration
+ */
+#define CONFIG_CONSOLE_MUX 1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
+
+/*
+ * Environment variables configurations
+ */
+#define CONFIG_ENV_IS_IN_SPI_FLASH 1
+#define CONFIG_ENV_SECT_SIZE 0x10000 /* 64KB */
+#define CONFIG_ENV_SIZE 0x1000 /* 4KB */
+#define CONFIG_ENV_ADDR 0x70000
+#define CONFIG_ENV_OFFSET 0x70000 /* env starts here */
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_BOOTARGS "console=ttyS0,115200"
+
+#define CONFIG_BOOTCOMMAND \
+ "if run usbload || run diskload; then bootm 0x800000; fi"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "stdin=serial,nc\0" \
+ "stdout=serial,nc\0" \
+ "stderr=serial,nc\0" \
+ "ipaddr=192.168.1.111\0" \
+ "diskload=ide reset && " \
+ "ext2load ide 0:1 0x800000 /boot/uImage\0" \
+ "usbload=usb start && " \
+ "fatload usb 0:1 0x800000 /boot/uImage\0"
+
+#endif /* _CONFIG_NETSPACE_V2_H */
--
1.6.3.1
Simon Guinot
2011-05-02 22:42:23 UTC
Permalink
This patch series adds support for Network Space v2 board and parents.

Changes for v2:
- netconsole: restore NetOurIP check
- add entries to MAINTAINERS file
- move boards from root Makefile to boards.cfg
- move MACH_TYPE definition into netspace_v2.h
- remove CONFIG_SYS_HZ redefinition
- turn PHY initialization message into debug()

Changes for v3:
- drop patch for Macronix MX25L4005A
- rewrite patch "sf: disable write protection for Macronix flash",
using the common spi flash code
- fix "Definitions" typo in mv-common.h
- netconsole: add a "/* Fall through */" comment before the NETCONS
case label

Changes for v4:
- sf macronix: use spi_flash_cmd_write_enable()
- enhance commit message for patch "Add support for Network Space v2"

Changes for v5:
- add a changelog per patch

Simon Guinot (5):
sf: disable write protection for Macronix flash
Kirkwood: allow to override CONFIG_SYS_TCLK
mv-common.h: fix DRAM banks configuration
netconsole: remove `serverip' check
Add support for Network Space v2

MAINTAINERS | 6 +
arch/arm/include/asm/arch-kirkwood/kw88f6281.h | 8 +-
board/LaCie/netspace_v2/Makefile | 49 +++++++
board/LaCie/netspace_v2/kwbimage.cfg | 162 ++++++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.c | 144 +++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.h | 39 ++++++
boards.cfg | 3 +
drivers/mtd/spi/macronix.c | 42 ++++++
include/configs/mv-common.h | 8 +-
include/configs/netspace_v2.h | 149 ++++++++++++++++++++++
net/net.c | 3 +-
11 files changed, 605 insertions(+), 8 deletions(-)
create mode 100644 board/LaCie/netspace_v2/Makefile
create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
create mode 100644 include/configs/netspace_v2.h
Simon Guinot
2011-05-02 22:42:26 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

The asm/arch/config.h header define CONFIG_NR_DRAM_BANKS_MAX, which is
needed to configure DRAM banks.

This patch move the asm/arch/config.h header inclusion above the DRAM
banks configuration.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---
Changes for v2: none

Changes for v3:
- fix "Definitions" typo in mv-common.h

Changes for v4,5: none

include/configs/mv-common.h | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index a8937dd..0a39257 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -113,6 +113,9 @@
#define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */
#define CONFIG_SYS_MAXARGS 16 /* max number of command args */

+/* ====> Include platform Common Definitions */
+#include <asm/arch/config.h>
+
/*
* DRAM Banks configuration, Custom config can be done in <board>.h
*/
@@ -124,10 +127,7 @@
#endif
#endif /* CONFIG_NR_DRAM_BANKS */

-/* ====> Include platform Common Definations */
-#include <asm/arch/config.h>
-
-/* ====> Include driver Common Definations */
+/* ====> Include driver Common Definitions */
/*
* Common NAND configuration
*/
--
1.6.3.1
Simon Guinot
2011-05-02 22:42:24 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---

Changes for v2: none

Changes for v3:
- rewrite patch using the common spi flash code

Changes for v4:
- use spi_flash_cmd_write_enable()

Changes for v5: none

drivers/mtd/spi/macronix.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index 96fd5f0..dacbc28 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -117,6 +117,45 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
},
};

+static int macronix_write_status(struct spi_flash *flash, u8 sr)
+{
+ u8 cmd;
+ int ret;
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret < 0) {
+ debug("SF: enabling write failed\n");
+ return ret;
+ }
+
+ cmd = CMD_MX25XX_WRSR;
+ ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &sr, 1);
+ if (ret) {
+ debug("SF: fail to write status register\n");
+ return ret;
+ }
+
+ ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+ if (ret < 0) {
+ debug("SF: write status register timed out\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int macronix_unlock(struct spi_flash *flash)
+{
+ int ret;
+
+ /* Enable status register writing and clear BP# bits */
+ ret = macronix_write_status(flash, 0);
+ if (ret)
+ debug("SF: fail to disable write protection\n");
+
+ return ret;
+}
+
static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len);
@@ -157,5 +196,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
* params->sectors_per_block;
flash->size = flash->sector_size * params->nr_blocks;

+ /* Clear BP# bits for read-only flash */
+ macronix_unlock(flash);
+
return flash;
}
--
1.6.3.1
Mike Frysinger
2011-07-08 20:32:49 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

Signed-off-by: Simon Guinot <sguinot at lacie.com>
Signed-off-by: Mike Frysinger <vapier at gentoo.org>
---
v6
- tweak summary

drivers/mtd/spi/macronix.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index 96fd5f0..dacbc28 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -117,6 +117,45 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
},
};

+static int macronix_write_status(struct spi_flash *flash, u8 sr)
+{
+ u8 cmd;
+ int ret;
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret < 0) {
+ debug("SF: enabling write failed\n");
+ return ret;
+ }
+
+ cmd = CMD_MX25XX_WRSR;
+ ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &sr, 1);
+ if (ret) {
+ debug("SF: fail to write status register\n");
+ return ret;
+ }
+
+ ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+ if (ret < 0) {
+ debug("SF: write status register timed out\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int macronix_unlock(struct spi_flash *flash)
+{
+ int ret;
+
+ /* Enable status register writing and clear BP# bits */
+ ret = macronix_write_status(flash, 0);
+ if (ret)
+ debug("SF: fail to disable write protection\n");
+
+ return ret;
+}
+
static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len);
@@ -157,5 +196,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
* params->sectors_per_block;
flash->size = flash->sector_size * params->nr_blocks;

+ /* Clear BP# bits for read-only flash */
+ macronix_unlock(flash);
+
return flash;
}
--
1.7.6
Wolfgang Denk
2011-08-02 20:02:57 UTC
Permalink
Dear Mike Frysinger,

In message <1310157169-27623-1-git-send-email-vapier at gentoo.org> you wrote:
> From: Simon Guinot <sguinot at lacie.com>
>
> Signed-off-by: Simon Guinot <sguinot at lacie.com>
> Signed-off-by: Mike Frysinger <vapier at gentoo.org>
> ---
> v6
> - tweak summary
>
> drivers/mtd/spi/macronix.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 42 insertions(+), 0 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Q: How many DEC repairman does it take to fix a flat?
A: Five; four to hold the car up and one to swap tires.
Q: How long does it take?
A: It's indeterminate. It will depend upon how many flats they've
brought with them.
Q: What happens if you've got TWO flats?
A: They replace your generator.
Simon Guinot
2011-05-02 22:42:25 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

This patch allow to override CONFIG_SYS_TCLK from board configuration
files. This is needed for the Network Space v2 which use a non standard
core clock frequency (166MHz instead of 200MHz for a 6281 SoC).

As a possible enhancement for 6281 and 6282 devices, TCLK could be
dynamically detected by checking the Sample at Reset register bit 21.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
Acked-by: Prafulla Wadaskar <Prafulla at marvell.com>
---
Changes for v[1-5]: none

arch/arm/include/asm/arch-kirkwood/kw88f6281.h | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
index 80723ea..22d10f1 100644
--- a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
+++ b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
@@ -27,11 +27,13 @@
#ifndef _ASM_ARCH_KW88F6281_H
#define _ASM_ARCH_KW88F6281_H

-/* SOC specific definations */
+/* SOC specific definitions */
#define KW88F6281_REGS_PHYS_BASE 0xf1000000
#define KW_REGS_PHY_BASE KW88F6281_REGS_PHYS_BASE

-/* TCLK Core Clock defination*/
-#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
+/* TCLK Core Clock definition */
+#ifndef CONFIG_SYS_TCLK
+#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
+#endif

#endif /* _ASM_ARCH_KW88F6281_H */
--
1.6.3.1
Simon Guinot
2011-05-02 22:42:27 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

Netconsole use the environment variable `ncip' to configure the
destination IP. `serverip' don't need to be defined.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---
Changes for v2:
- restore NetOurIP check

Changes for v3:
- add a "/* Fall through */" comment before the NETCONS case label

Changes for v4,5: none

net/net.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/net.c b/net/net.c
index e50bdf1..19ac019 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1718,7 +1718,6 @@ static int net_check_prereq (proto_t protocol)
#if defined(CONFIG_CMD_NFS)
case NFS:
#endif
- case NETCONS:
case TFTP:
if (NetServerIP == 0) {
puts ("*** ERROR: `serverip' not set\n");
@@ -1728,7 +1727,9 @@ static int net_check_prereq (proto_t protocol)
defined(CONFIG_CMD_DNS)
common:
#endif
+ /* Fall through */

+ case NETCONS:
if (NetOurIP == 0) {
puts ("*** ERROR: `ipaddr' not set\n");
return (1);
--
1.6.3.1
Simon Guinot
2011-05-02 22:42:28 UTC
Permalink
From: Simon Guinot <sguinot at lacie.com>

This patch add support for the Network Space v2 board and parents, based
on the Marvell Kirkwood SoC. This include Network Space (Max) v2 and
Internet Space v2.

Signed-off-by: Simon Guinot <sguinot at lacie.com>
---
Changes for v2:
- add entries to MAINTAINERS file
- move boards from root Makefile to boards.cfg
- move MACH_TYPE definition into netspace_v2.h
- remove CONFIG_SYS_HZ redefinition
- turn PHY initialization message into debug()

Changes for v3: none

Changes for v4:
- enhance commit message: add SoC information

Changes for v5: none

MAINTAINERS | 6 +
board/LaCie/netspace_v2/Makefile | 49 ++++++++++
board/LaCie/netspace_v2/kwbimage.cfg | 162 +++++++++++++++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.c | 144 +++++++++++++++++++++++++++++
board/LaCie/netspace_v2/netspace_v2.h | 39 ++++++++
boards.cfg | 3 +
include/configs/netspace_v2.h | 149 ++++++++++++++++++++++++++++++
7 files changed, 552 insertions(+), 0 deletions(-)
create mode 100644 board/LaCie/netspace_v2/Makefile
create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
create mode 100644 include/configs/netspace_v2.h

diff --git a/MAINTAINERS b/MAINTAINERS
index e2a4ba9..f905a48 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -652,6 +652,12 @@ Sedji Gaouaou<sedji.gaouaou at atmel.com>
at91sam9g10ek ARM926EJS (AT91SAM9G10 SoC)
at91sam9m10g45ek ARM926EJS (AT91SAM9G45 SoC)

+Simon Guinot <simon.guinot at sequanux.org>
+
+ inetspace_v2 ARM926EJS (Kirkwood SoC)
+ netspace_v2 ARM926EJS (Kirkwood SoC)
+ netspace_max_v2 ARM926EJS (Kirkwood SoC)
+
Marius Gr?ger <mag at sysgo.de>

impa7 ARM720T (EP7211)
diff --git a/board/LaCie/netspace_v2/Makefile b/board/LaCie/netspace_v2/Makefile
new file mode 100644
index 0000000..a245f2c
--- /dev/null
+++ b/board/LaCie/netspace_v2/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := netspace_v2.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/LaCie/netspace_v2/kwbimage.cfg b/board/LaCie/netspace_v2/kwbimage.cfg
new file mode 100644
index 0000000..361feeb
--- /dev/null
+++ b/board/LaCie/netspace_v2/kwbimage.cfg
@@ -0,0 +1,162 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# Refer docs/README.kwimage for more details about how-to configure
+# and create kirkwood boot image
+#
+
+# Boot Media configurations
+BOOT_FROM spi # Boot from SPI flash
+
+# SOC registers configuration using bootrom header extension
+# Maximum KWBIMAGE_MAX_CONFIG configurations allowed
+
+# Configure RGMII-0 interface pad voltage to 1.8V
+DATA 0xFFD100e0 0x1B1B1B9B
+
+#Dram initalization for SINGLE x16 CL=5 @ 400MHz
+DATA 0xFFD01400 0x43000618 # DDR Configuration register
+# bit13-0: 0xa00 (2560 DDR2 clks refresh rate)
+# bit23-14: zero
+# bit24: 1= enable exit self refresh mode on DDR access
+# bit25: 1 required
+# bit29-26: zero
+# bit31-30: 01
+
+DATA 0xFFD01404 0x35143000 # DDR Controller Control Low
+# bit 4: 0=addr/cmd in smame cycle
+# bit 5: 0=clk is driven during self refresh, we don't care for APX
+# bit 6: 0=use recommended falling edge of clk for addr/cmd
+# bit14: 0=input buffer always powered up
+# bit18: 1=cpu lock transaction enabled
+# bit23-20: 5=recommended value for CL=5 and STARTBURST_DEL disabled bit31=0
+# bit27-24: 8= CL+3, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
+# bit30-28: 3 required
+# bit31: 0=no additional STARTBURST delay
+
+DATA 0xFFD01408 0x11012228 # DDR Timing (Low) (active cycles value +1)
+# bit7-4: TRCD
+# bit11- 8: TRP
+# bit15-12: TWR
+# bit19-16: TWTR
+# bit20: TRAS msb
+# bit23-21: 0x0
+# bit27-24: TRRD
+# bit31-28: TRTP
+
+DATA 0xFFD0140C 0x00000A19 # DDR Timing (High)
+# bit6-0: TRFC
+# bit8-7: TR2R
+# bit10-9: TR2W
+# bit12-11: TW2W
+# bit31-13: zero required
+
+DATA 0xFFD01410 0x0000CCCC # DDR Address Control
+# bit1-0: 01, Cs0width=x16
+# bit3-2: 11, Cs0size=1Gb
+# bit5-4: 00, Cs2width=nonexistent
+# bit7-6: 00, Cs1size =nonexistent
+# bit9-8: 00, Cs2width=nonexistent
+# bit11-10: 00, Cs2size =nonexistent
+# bit13-12: 00, Cs3width=nonexistent
+# bit15-14: 00, Cs3size =nonexistent
+# bit16: 0, Cs0AddrSel
+# bit17: 0, Cs1AddrSel
+# bit18: 0, Cs2AddrSel
+# bit19: 0, Cs3AddrSel
+# bit31-20: 0 required
+
+DATA 0xFFD01414 0x00000000 # DDR Open Pages Control
+# bit0: 0, OpenPage enabled
+# bit31-1: 0 required
+
+DATA 0xFFD01418 0x00000000 # DDR Operation
+# bit3-0: 0x0, DDR cmd
+# bit31-4: 0 required
+
+DATA 0xFFD0141C 0x00000632 # DDR Mode
+# bit2-0: 2, BurstLen=2 required
+# bit3: 0, BurstType=0 required
+# bit6-4: 4, CL=5
+# bit7: 0, TestMode=0 normal
+# bit8: 0, DLL reset=0 normal
+# bit11-9: 6, auto-precharge write recovery ????????????
+# bit12: 0, PD must be zero
+# bit31-13: 0 required
+
+DATA 0xFFD01420 0x00000004 # DDR Extended Mode
+# bit0: 0, DDR DLL enabled
+# bit1: 1, DDR drive strenght reduced
+# bit2: 1, DDR ODT control lsd enabled
+# bit5-3: 000, required
+# bit6: 1, DDR ODT control msb, enabled
+# bit9-7: 000, required
+# bit10: 0, differential DQS enabled
+# bit11: 0, required
+# bit12: 0, DDR output buffer enabled
+# bit31-13: 0 required
+
+DATA 0xFFD01424 0x0000F07F # DDR Controller Control High
+# bit2-0: 111, required
+# bit3 : 1 , MBUS Burst Chop disabled
+# bit6-4: 111, required
+# bit7 : 1 , D2P Latency enabled
+# bit8 : 1 , add writepath sample stage, must be 1 for DDR freq >= 300MHz
+# bit9 : 0 , no half clock cycle addition to dataout
+# bit10 : 0 , 1/4 clock cycle skew enabled for addr/ctl signals
+# bit11 : 0 , 1/4 clock cycle skew disabled for write mesh
+# bit15-12: 1111 required
+# bit31-16: 0 required
+
+DATA 0xFFD01428 0x00085520 # DDR2 ODT Read Timing (default values)
+DATA 0xFFD0147C 0x00008552 # DDR2 ODT Write Timing (default values)
+
+DATA 0xFFD01500 0x00000000 # CS[0]n Base address to 0x0
+DATA 0xFFD01504 0x0FFFFFF1 # CS[0]n Size
+# bit0: 1, Window enabled
+# bit1: 0, Write Protect disabled
+# bit3-2: 00, CS0 hit selected
+# bit23-4: ones, required
+# bit31-24: 0x07, Size (i.e. 128MB)
+
+DATA 0xFFD0150C 0x00000000 # CS[1]n Size, window disabled
+DATA 0xFFD01514 0x00000000 # CS[2]n Size, window disabled
+DATA 0xFFD0151C 0x00000000 # CS[3]n Size, window disabled
+
+DATA 0xFFD01494 0x00010000 # DDR ODT Control (Low)
+# bit3-0: 1, ODT0Rd, MODT[0] asserted during read from DRAM CS0
+# bit19-16:1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
+
+DATA 0xFFD01498 0x00000000 # DDR ODT Control (High)
+# bit1-0: 00, ODT0 controlled by ODT Control (low) register above
+# bit3-2: 01, ODT1 active NEVER!
+# bit31-4: zero, required
+
+DATA 0xFFD0149C 0x0000E40F # CPU ODT Control
+# bit3-0: 1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
+# bit7-4: 1, ODT0Wr, Internal ODT asserted during write to DRAM bank0
+# bit11-10:1, DQ_ODTSel. ODT select turned on
+
+DATA 0xFFD01480 0x00000001 # DDR Initialization Control
+#bit0=1, enable DDR init upon this register write
+
+# End of Header extension
+DATA 0x0 0x0
diff --git a/board/LaCie/netspace_v2/netspace_v2.c b/board/LaCie/netspace_v2/netspace_v2.c
new file mode 100644
index 0000000..9bc9940
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <command.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/arch/mpp.h>
+#include <asm/arch/gpio.h>
+#include "netspace_v2.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_early_init_f(void)
+{
+ /* Gpio configuration */
+ kw_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
+ NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
+
+ /* Multi-Purpose Pins Functionality configuration */
+ u32 kwmpp_config[] = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP4_NF_IO6,
+ MPP5_NF_IO7,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Fan speed (bit 1) */
+ MPP8_TW_SDA,
+ MPP9_TW_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_GPO, /* Red led */
+ MPP14_GPIO, /* USB fuse */
+ MPP16_GPIO, /* SATA 0 power */
+ MPP17_GPIO, /* SATA 1 power */
+ MPP18_NF_IO0,
+ MPP19_NF_IO1,
+ MPP20_SATA1_ACTn,
+ MPP21_SATA0_ACTn,
+ MPP22_GPIO, /* Fan speed (bit 0) */
+ MPP23_GPIO, /* Fan power */
+ MPP24_GPIO, /* USB mode select */
+ MPP25_GPIO, /* Fan rotation fail */
+ MPP26_GPIO, /* USB vbus-in detection */
+ MPP28_GPIO, /* USB enable vbus-out */
+ MPP29_GPIO, /* Blue led (slow register) */
+ MPP30_GPIO, /* Blue led (command register) */
+ MPP31_GPIO, /* Board power off */
+ MPP32_GPIO, /* Button (0 = Released, 1 = Pushed) */
+ MPP33_GPIO, /* Fan speed (bit 2) */
+ 0
+ };
+ kirkwood_mpp_conf(kwmpp_config);
+
+ return 0;
+}
+
+int board_init(void)
+{
+ /* Machine number */
+ gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
+
+ /* Boot parameters address */
+ gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+
+ return 0;
+}
+
+void mv_phy_88e1116_init(char *name)
+{
+ u16 reg;
+ u16 devadr;
+
+ if (miiphy_set_current_dev(name))
+ return;
+
+ /* command to read PHY dev address */
+ if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
+ printf("Err..(%s) could not read PHY dev address\n", __func__);
+ return;
+ }
+
+ /*
+ * Enable RGMII delay on Tx and Rx for CPU port
+ * Ref: sec 4.7.2 of chip datasheet
+ */
+ miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
+ miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
+ reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
+ miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
+ miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+
+ /* reset the phy */
+ if (miiphy_read(name, devadr, MII_BMCR, &reg) != 0) {
+ printf("Err..(%s) PHY status read failed\n", __func__);
+ return;
+ }
+ if (miiphy_write(name, devadr, MII_BMCR, reg | 0x8000) != 0) {
+ printf("Err..(%s) PHY reset failed\n", __func__);
+ return;
+ }
+
+ debug("88E1116 Initialized on %s\n", name);
+}
+
+/* Configure and initialize PHY */
+void reset_phy(void)
+{
+ mv_phy_88e1116_init("egiga0");
+}
+
+#define NETSPACE_V2_GPIO_BUTTON 32
+
+/* Return GPIO button status */
+static int
+do_read_button(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ return kw_gpio_get_value(NETSPACE_V2_GPIO_BUTTON);
+}
+
+U_BOOT_CMD(button, 1, 1, do_read_button,
+ "Return GPIO button status 0=off 1=on", "");
diff --git a/board/LaCie/netspace_v2/netspace_v2.h b/board/LaCie/netspace_v2/netspace_v2.h
new file mode 100644
index 0000000..c26a6e0
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef NETSPACE_V2_H
+#define NETSPACE_V2_H
+
+#define NETSPACE_V2_OE_LOW 0x06004000
+#define NETSPACE_V2_OE_HIGH 0x00000031
+#define NETSPACE_V2_OE_VAL_LOW 0x10030000
+#define NETSPACE_V2_OE_VAL_HIGH 0x00000000
+
+/* PHY related */
+#define MV88E1116_LED_FCTRL_REG 10
+#define MV88E1116_CPRSP_CR3_REG 21
+#define MV88E1116_MAC_CTRL_REG 21
+#define MV88E1116_PGADR_REG 22
+#define MV88E1116_RGMII_TXTM_CTRL (1 << 4)
+#define MV88E1116_RGMII_RXTM_CTRL (1 << 5)
+
+#endif /* NETSPACE_V2_H */
diff --git a/boards.cfg b/boards.cfg
index 2b0900a..459dee4 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -106,6 +106,9 @@ davinci_sonata arm arm926ejs sonata davinci
suen3 arm arm926ejs km_arm keymile kirkwood
suen8 arm arm926ejs km_arm keymile kirkwood
mgcoge2un arm arm926ejs km_arm keymile kirkwood
+inetspace_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:INETSPACE_V2
+netspace_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:NETSPACE_V2
+netspace_max_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:NETSPACE_MAX_V2
guruplug arm arm926ejs - Marvell kirkwood
mv88f6281gtw_ge arm arm926ejs - Marvell kirkwood
openrd_base arm arm926ejs - Marvell kirkwood
diff --git a/include/configs/netspace_v2.h b/include/configs/netspace_v2.h
new file mode 100644
index 0000000..ca4db53
--- /dev/null
+++ b/include/configs/netspace_v2.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CONFIG_NETSPACE_V2_H
+#define _CONFIG_NETSPACE_V2_H
+
+/*
+ * Machine number definition
+ */
+#if defined(CONFIG_INETSPACE_V2)
+#define CONFIG_MACH_TYPE MACH_TYPE_INETSPACE_V2
+#define CONFIG_IDENT_STRING " LaCie Internet Space v2"
+#elif defined(CONFIG_NETSPACE_V2)
+#define CONFIG_MACH_TYPE MACH_TYPE_NETSPACE_V2
+#define CONFIG_IDENT_STRING " LaCie Network Space v2"
+#elif defined(CONFIG_NETSPACE_MAX_V2)
+#define CONFIG_MACH_TYPE MACH_TYPE_NETSPACE_MAX_V2
+#define CONFIG_IDENT_STRING " LaCie Network Space Max v2"
+#endif
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_FEROCEON_88FR131 1 /* CPU Core subversion */
+#define CONFIG_KIRKWOOD 1 /* SOC Family Name */
+#define CONFIG_KW88F6281 1 /* SOC Name */
+#define CONFIG_MACH_NETSPACE_V2 1 /* Machine type */
+#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */
+
+/*
+ * Commands configuration
+ */
+#define CONFIG_SYS_NO_FLASH /* Declare no flash (NOR/SPI) */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IDE
+#define CONFIG_CMD_USB
+
+/*
+ * Core clock definition.
+ */
+#define CONFIG_SYS_TCLK 166000000 /* 166MHz */
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#define CONFIG_NR_DRAM_BANKS 2
+#include "mv-common.h"
+
+/* Remove or override few declarations from mv-common.h */
+#undef CONFIG_RBTREE
+#undef CONFIG_ENV_SPI_MAX_HZ
+#undef CONFIG_SYS_IDE_MAXBUS
+#undef CONFIG_SYS_IDE_MAXDEVICE
+#undef CONFIG_SYS_PROMPT
+#define CONFIG_ENV_SPI_MAX_HZ 20000000 /* 20Mhz */
+#define CONFIG_SYS_IDE_MAXBUS 1
+#define CONFIG_SYS_IDE_MAXDEVICE 1
+#define CONFIG_SYS_PROMPT "ns2> "
+
+/*
+ * Ethernet Driver configuration
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_MVGBE_PORTS {1, 0} /* enable port 0 only */
+#define CONFIG_NETCONSOLE
+#endif
+
+/*
+ * SATA Driver configuration
+ */
+#ifdef CONFIG_MVSATA_IDE
+#define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET
+/* Network Space Max v2 use 2 SATA ports */
+#ifdef CONFIG_NETSPACE_MAX_V2
+#define CONFIG_SYS_ATA_IDE1_OFFSET MV_SATA_PORT1_OFFSET
+#endif
+#endif
+
+/*
+ * Enable GPI0 support
+ */
+#define CONFIG_KIRKWOOD_GPIO
+
+/*
+ * File systems support
+ */
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+
+/*
+ * Use the HUSH parser
+ */
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+
+/*
+ * Console configuration
+ */
+#define CONFIG_CONSOLE_MUX 1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
+
+/*
+ * Environment variables configurations
+ */
+#define CONFIG_ENV_IS_IN_SPI_FLASH 1
+#define CONFIG_ENV_SECT_SIZE 0x10000 /* 64KB */
+#define CONFIG_ENV_SIZE 0x1000 /* 4KB */
+#define CONFIG_ENV_ADDR 0x70000
+#define CONFIG_ENV_OFFSET 0x70000 /* env starts here */
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_BOOTARGS "console=ttyS0,115200"
+
+#define CONFIG_BOOTCOMMAND \
+ "if run usbload || run diskload; then bootm 0x800000; fi"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "stdin=serial,nc\0" \
+ "stdout=serial,nc\0" \
+ "stderr=serial,nc\0" \
+ "ipaddr=192.168.1.111\0" \
+ "diskload=ide reset && " \
+ "ext2load ide 0:1 0x800000 /boot/uImage\0" \
+ "usbload=usb start && " \
+ "fatload usb 0:1 0x800000 /boot/uImage\0"
+
+#endif /* _CONFIG_NETSPACE_V2_H */
--
1.6.3.1
Simon Guinot
2011-05-03 13:19:42 UTC
Permalink
Hi Wolfgang,

I have failed to find an entry for this patch in the U-Boot patchwork
(and any previous version except the very first).

Have I missed something and/or done something wrong ?

Regards,

Simon

On Tue, May 03, 2011 at 12:42:28AM +0200, Simon Guinot wrote:
> From: Simon Guinot <sguinot at lacie.com>
>
> This patch add support for the Network Space v2 board and parents, based
> on the Marvell Kirkwood SoC. This include Network Space (Max) v2 and
> Internet Space v2.
>
> Signed-off-by: Simon Guinot <sguinot at lacie.com>
> ---
> Changes for v2:
> - add entries to MAINTAINERS file
> - move boards from root Makefile to boards.cfg
> - move MACH_TYPE definition into netspace_v2.h
> - remove CONFIG_SYS_HZ redefinition
> - turn PHY initialization message into debug()
>
> Changes for v3: none
>
> Changes for v4:
> - enhance commit message: add SoC information
>
> Changes for v5: none
>
> MAINTAINERS | 6 +
> board/LaCie/netspace_v2/Makefile | 49 ++++++++++
> board/LaCie/netspace_v2/kwbimage.cfg | 162 +++++++++++++++++++++++++++++++++
> board/LaCie/netspace_v2/netspace_v2.c | 144 +++++++++++++++++++++++++++++
> board/LaCie/netspace_v2/netspace_v2.h | 39 ++++++++
> boards.cfg | 3 +
> include/configs/netspace_v2.h | 149 ++++++++++++++++++++++++++++++
> 7 files changed, 552 insertions(+), 0 deletions(-)
> create mode 100644 board/LaCie/netspace_v2/Makefile
> create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
> create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
> create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
> create mode 100644 include/configs/netspace_v2.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e2a4ba9..f905a48 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -652,6 +652,12 @@ Sedji Gaouaou<sedji.gaouaou at atmel.com>
> at91sam9g10ek ARM926EJS (AT91SAM9G10 SoC)
> at91sam9m10g45ek ARM926EJS (AT91SAM9G45 SoC)
>
> +Simon Guinot <simon.guinot at sequanux.org>
> +
> + inetspace_v2 ARM926EJS (Kirkwood SoC)
> + netspace_v2 ARM926EJS (Kirkwood SoC)
> + netspace_max_v2 ARM926EJS (Kirkwood SoC)
> +
> Marius Gr?ger <mag at sysgo.de>
>
> impa7 ARM720T (EP7211)
> diff --git a/board/LaCie/netspace_v2/Makefile b/board/LaCie/netspace_v2/Makefile
> new file mode 100644
> index 0000000..a245f2c
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/Makefile
> @@ -0,0 +1,49 @@
> +#
> +# Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
> +#
> +# Based on Kirkwood support:
> +# (C) Copyright 2009
> +# Marvell Semiconductor <www.marvell.com>
> +# Written-by: Prafulla Wadaskar <prafulla at marvell.com>
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB = $(obj)lib$(BOARD).o
> +
> +COBJS := netspace_v2.o
> +
> +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
> +OBJS := $(addprefix $(obj),$(COBJS))
> +SOBJS := $(addprefix $(obj),$(SOBJS))
> +
> +$(LIB): $(obj).depend $(OBJS) $(SOBJS)
> + $(call cmd_link_o_target, $(OBJS) $(SOBJS))
> +
> +clean:
> + rm -f $(SOBJS) $(OBJS)
> +
> +distclean: clean
> + rm -f $(LIB) core *.bak .depend
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/board/LaCie/netspace_v2/kwbimage.cfg b/board/LaCie/netspace_v2/kwbimage.cfg
> new file mode 100644
> index 0000000..361feeb
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/kwbimage.cfg
> @@ -0,0 +1,162 @@
> +#
> +# Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
> +#
> +# Based on Kirkwood support:
> +# (C) Copyright 2009
> +# Marvell Semiconductor <www.marvell.com>
> +# Written-by: Prafulla Wadaskar <prafulla at marvell.com>
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# Refer docs/README.kwimage for more details about how-to configure
> +# and create kirkwood boot image
> +#
> +
> +# Boot Media configurations
> +BOOT_FROM spi # Boot from SPI flash
> +
> +# SOC registers configuration using bootrom header extension
> +# Maximum KWBIMAGE_MAX_CONFIG configurations allowed
> +
> +# Configure RGMII-0 interface pad voltage to 1.8V
> +DATA 0xFFD100e0 0x1B1B1B9B
> +
> +#Dram initalization for SINGLE x16 CL=5 @ 400MHz
> +DATA 0xFFD01400 0x43000618 # DDR Configuration register
> +# bit13-0: 0xa00 (2560 DDR2 clks refresh rate)
> +# bit23-14: zero
> +# bit24: 1= enable exit self refresh mode on DDR access
> +# bit25: 1 required
> +# bit29-26: zero
> +# bit31-30: 01
> +
> +DATA 0xFFD01404 0x35143000 # DDR Controller Control Low
> +# bit 4: 0=addr/cmd in smame cycle
> +# bit 5: 0=clk is driven during self refresh, we don't care for APX
> +# bit 6: 0=use recommended falling edge of clk for addr/cmd
> +# bit14: 0=input buffer always powered up
> +# bit18: 1=cpu lock transaction enabled
> +# bit23-20: 5=recommended value for CL=5 and STARTBURST_DEL disabled bit31=0
> +# bit27-24: 8= CL+3, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
> +# bit30-28: 3 required
> +# bit31: 0=no additional STARTBURST delay
> +
> +DATA 0xFFD01408 0x11012228 # DDR Timing (Low) (active cycles value +1)
> +# bit7-4: TRCD
> +# bit11- 8: TRP
> +# bit15-12: TWR
> +# bit19-16: TWTR
> +# bit20: TRAS msb
> +# bit23-21: 0x0
> +# bit27-24: TRRD
> +# bit31-28: TRTP
> +
> +DATA 0xFFD0140C 0x00000A19 # DDR Timing (High)
> +# bit6-0: TRFC
> +# bit8-7: TR2R
> +# bit10-9: TR2W
> +# bit12-11: TW2W
> +# bit31-13: zero required
> +
> +DATA 0xFFD01410 0x0000CCCC # DDR Address Control
> +# bit1-0: 01, Cs0width=x16
> +# bit3-2: 11, Cs0size=1Gb
> +# bit5-4: 00, Cs2width=nonexistent
> +# bit7-6: 00, Cs1size =nonexistent
> +# bit9-8: 00, Cs2width=nonexistent
> +# bit11-10: 00, Cs2size =nonexistent
> +# bit13-12: 00, Cs3width=nonexistent
> +# bit15-14: 00, Cs3size =nonexistent
> +# bit16: 0, Cs0AddrSel
> +# bit17: 0, Cs1AddrSel
> +# bit18: 0, Cs2AddrSel
> +# bit19: 0, Cs3AddrSel
> +# bit31-20: 0 required
> +
> +DATA 0xFFD01414 0x00000000 # DDR Open Pages Control
> +# bit0: 0, OpenPage enabled
> +# bit31-1: 0 required
> +
> +DATA 0xFFD01418 0x00000000 # DDR Operation
> +# bit3-0: 0x0, DDR cmd
> +# bit31-4: 0 required
> +
> +DATA 0xFFD0141C 0x00000632 # DDR Mode
> +# bit2-0: 2, BurstLen=2 required
> +# bit3: 0, BurstType=0 required
> +# bit6-4: 4, CL=5
> +# bit7: 0, TestMode=0 normal
> +# bit8: 0, DLL reset=0 normal
> +# bit11-9: 6, auto-precharge write recovery ????????????
> +# bit12: 0, PD must be zero
> +# bit31-13: 0 required
> +
> +DATA 0xFFD01420 0x00000004 # DDR Extended Mode
> +# bit0: 0, DDR DLL enabled
> +# bit1: 1, DDR drive strenght reduced
> +# bit2: 1, DDR ODT control lsd enabled
> +# bit5-3: 000, required
> +# bit6: 1, DDR ODT control msb, enabled
> +# bit9-7: 000, required
> +# bit10: 0, differential DQS enabled
> +# bit11: 0, required
> +# bit12: 0, DDR output buffer enabled
> +# bit31-13: 0 required
> +
> +DATA 0xFFD01424 0x0000F07F # DDR Controller Control High
> +# bit2-0: 111, required
> +# bit3 : 1 , MBUS Burst Chop disabled
> +# bit6-4: 111, required
> +# bit7 : 1 , D2P Latency enabled
> +# bit8 : 1 , add writepath sample stage, must be 1 for DDR freq >= 300MHz
> +# bit9 : 0 , no half clock cycle addition to dataout
> +# bit10 : 0 , 1/4 clock cycle skew enabled for addr/ctl signals
> +# bit11 : 0 , 1/4 clock cycle skew disabled for write mesh
> +# bit15-12: 1111 required
> +# bit31-16: 0 required
> +
> +DATA 0xFFD01428 0x00085520 # DDR2 ODT Read Timing (default values)
> +DATA 0xFFD0147C 0x00008552 # DDR2 ODT Write Timing (default values)
> +
> +DATA 0xFFD01500 0x00000000 # CS[0]n Base address to 0x0
> +DATA 0xFFD01504 0x0FFFFFF1 # CS[0]n Size
> +# bit0: 1, Window enabled
> +# bit1: 0, Write Protect disabled
> +# bit3-2: 00, CS0 hit selected
> +# bit23-4: ones, required
> +# bit31-24: 0x07, Size (i.e. 128MB)
> +
> +DATA 0xFFD0150C 0x00000000 # CS[1]n Size, window disabled
> +DATA 0xFFD01514 0x00000000 # CS[2]n Size, window disabled
> +DATA 0xFFD0151C 0x00000000 # CS[3]n Size, window disabled
> +
> +DATA 0xFFD01494 0x00010000 # DDR ODT Control (Low)
> +# bit3-0: 1, ODT0Rd, MODT[0] asserted during read from DRAM CS0
> +# bit19-16:1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
> +
> +DATA 0xFFD01498 0x00000000 # DDR ODT Control (High)
> +# bit1-0: 00, ODT0 controlled by ODT Control (low) register above
> +# bit3-2: 01, ODT1 active NEVER!
> +# bit31-4: zero, required
> +
> +DATA 0xFFD0149C 0x0000E40F # CPU ODT Control
> +# bit3-0: 1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
> +# bit7-4: 1, ODT0Wr, Internal ODT asserted during write to DRAM bank0
> +# bit11-10:1, DQ_ODTSel. ODT select turned on
> +
> +DATA 0xFFD01480 0x00000001 # DDR Initialization Control
> +#bit0=1, enable DDR init upon this register write
> +
> +# End of Header extension
> +DATA 0x0 0x0
> diff --git a/board/LaCie/netspace_v2/netspace_v2.c b/board/LaCie/netspace_v2/netspace_v2.c
> new file mode 100644
> index 0000000..9bc9940
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/netspace_v2.c
> @@ -0,0 +1,144 @@
> +/*
> + * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
> + *
> + * Based on Kirkwood support:
> + * (C) Copyright 2009
> + * Marvell Semiconductor <www.marvell.com>
> + * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <common.h>
> +#include <miiphy.h>
> +#include <netdev.h>
> +#include <command.h>
> +#include <asm/arch/kirkwood.h>
> +#include <asm/arch/mpp.h>
> +#include <asm/arch/gpio.h>
> +#include "netspace_v2.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int board_early_init_f(void)
> +{
> + /* Gpio configuration */
> + kw_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
> + NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
> +
> + /* Multi-Purpose Pins Functionality configuration */
> + u32 kwmpp_config[] = {
> + MPP0_SPI_SCn,
> + MPP1_SPI_MOSI,
> + MPP2_SPI_SCK,
> + MPP3_SPI_MISO,
> + MPP4_NF_IO6,
> + MPP5_NF_IO7,
> + MPP6_SYSRST_OUTn,
> + MPP7_GPO, /* Fan speed (bit 1) */
> + MPP8_TW_SDA,
> + MPP9_TW_SCK,
> + MPP10_UART0_TXD,
> + MPP11_UART0_RXD,
> + MPP12_GPO, /* Red led */
> + MPP14_GPIO, /* USB fuse */
> + MPP16_GPIO, /* SATA 0 power */
> + MPP17_GPIO, /* SATA 1 power */
> + MPP18_NF_IO0,
> + MPP19_NF_IO1,
> + MPP20_SATA1_ACTn,
> + MPP21_SATA0_ACTn,
> + MPP22_GPIO, /* Fan speed (bit 0) */
> + MPP23_GPIO, /* Fan power */
> + MPP24_GPIO, /* USB mode select */
> + MPP25_GPIO, /* Fan rotation fail */
> + MPP26_GPIO, /* USB vbus-in detection */
> + MPP28_GPIO, /* USB enable vbus-out */
> + MPP29_GPIO, /* Blue led (slow register) */
> + MPP30_GPIO, /* Blue led (command register) */
> + MPP31_GPIO, /* Board power off */
> + MPP32_GPIO, /* Button (0 = Released, 1 = Pushed) */
> + MPP33_GPIO, /* Fan speed (bit 2) */
> + 0
> + };
> + kirkwood_mpp_conf(kwmpp_config);
> +
> + return 0;
> +}
> +
> +int board_init(void)
> +{
> + /* Machine number */
> + gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
> +
> + /* Boot parameters address */
> + gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
> +
> + return 0;
> +}
> +
> +void mv_phy_88e1116_init(char *name)
> +{
> + u16 reg;
> + u16 devadr;
> +
> + if (miiphy_set_current_dev(name))
> + return;
> +
> + /* command to read PHY dev address */
> + if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
> + printf("Err..(%s) could not read PHY dev address\n", __func__);
> + return;
> + }
> +
> + /*
> + * Enable RGMII delay on Tx and Rx for CPU port
> + * Ref: sec 4.7.2 of chip datasheet
> + */
> + miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
> + miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
> + reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
> + miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
> + miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
> +
> + /* reset the phy */
> + if (miiphy_read(name, devadr, MII_BMCR, &reg) != 0) {
> + printf("Err..(%s) PHY status read failed\n", __func__);
> + return;
> + }
> + if (miiphy_write(name, devadr, MII_BMCR, reg | 0x8000) != 0) {
> + printf("Err..(%s) PHY reset failed\n", __func__);
> + return;
> + }
> +
> + debug("88E1116 Initialized on %s\n", name);
> +}
> +
> +/* Configure and initialize PHY */
> +void reset_phy(void)
> +{
> + mv_phy_88e1116_init("egiga0");
> +}
> +
> +#define NETSPACE_V2_GPIO_BUTTON 32
> +
> +/* Return GPIO button status */
> +static int
> +do_read_button(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> + return kw_gpio_get_value(NETSPACE_V2_GPIO_BUTTON);
> +}
> +
> +U_BOOT_CMD(button, 1, 1, do_read_button,
> + "Return GPIO button status 0=off 1=on", "");
> diff --git a/board/LaCie/netspace_v2/netspace_v2.h b/board/LaCie/netspace_v2/netspace_v2.h
> new file mode 100644
> index 0000000..c26a6e0
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/netspace_v2.h
> @@ -0,0 +1,39 @@
> +/*
> + * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
> + *
> + * Based on Kirkwood support:
> + * (C) Copyright 2009
> + * Marvell Semiconductor <www.marvell.com>
> + * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef NETSPACE_V2_H
> +#define NETSPACE_V2_H
> +
> +#define NETSPACE_V2_OE_LOW 0x06004000
> +#define NETSPACE_V2_OE_HIGH 0x00000031
> +#define NETSPACE_V2_OE_VAL_LOW 0x10030000
> +#define NETSPACE_V2_OE_VAL_HIGH 0x00000000
> +
> +/* PHY related */
> +#define MV88E1116_LED_FCTRL_REG 10
> +#define MV88E1116_CPRSP_CR3_REG 21
> +#define MV88E1116_MAC_CTRL_REG 21
> +#define MV88E1116_PGADR_REG 22
> +#define MV88E1116_RGMII_TXTM_CTRL (1 << 4)
> +#define MV88E1116_RGMII_RXTM_CTRL (1 << 5)
> +
> +#endif /* NETSPACE_V2_H */
> diff --git a/boards.cfg b/boards.cfg
> index 2b0900a..459dee4 100644
> --- a/boards.cfg
> +++ b/boards.cfg
> @@ -106,6 +106,9 @@ davinci_sonata arm arm926ejs sonata davinci
> suen3 arm arm926ejs km_arm keymile kirkwood
> suen8 arm arm926ejs km_arm keymile kirkwood
> mgcoge2un arm arm926ejs km_arm keymile kirkwood
> +inetspace_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:INETSPACE_V2
> +netspace_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:NETSPACE_V2
> +netspace_max_v2 arm arm926ejs netspace_v2 LaCie kirkwood netspace_v2:NETSPACE_MAX_V2
> guruplug arm arm926ejs - Marvell kirkwood
> mv88f6281gtw_ge arm arm926ejs - Marvell kirkwood
> openrd_base arm arm926ejs - Marvell kirkwood
> diff --git a/include/configs/netspace_v2.h b/include/configs/netspace_v2.h
> new file mode 100644
> index 0000000..ca4db53
> --- /dev/null
> +++ b/include/configs/netspace_v2.h
> @@ -0,0 +1,149 @@
> +/*
> + * Copyright (C) 2011 Simon Guinot <sguinot at lacie.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef _CONFIG_NETSPACE_V2_H
> +#define _CONFIG_NETSPACE_V2_H
> +
> +/*
> + * Machine number definition
> + */
> +#if defined(CONFIG_INETSPACE_V2)
> +#define CONFIG_MACH_TYPE MACH_TYPE_INETSPACE_V2
> +#define CONFIG_IDENT_STRING " LaCie Internet Space v2"
> +#elif defined(CONFIG_NETSPACE_V2)
> +#define CONFIG_MACH_TYPE MACH_TYPE_NETSPACE_V2
> +#define CONFIG_IDENT_STRING " LaCie Network Space v2"
> +#elif defined(CONFIG_NETSPACE_MAX_V2)
> +#define CONFIG_MACH_TYPE MACH_TYPE_NETSPACE_MAX_V2
> +#define CONFIG_IDENT_STRING " LaCie Network Space Max v2"
> +#endif
> +
> +/*
> + * High Level Configuration Options (easy to change)
> + */
> +#define CONFIG_FEROCEON_88FR131 1 /* CPU Core subversion */
> +#define CONFIG_KIRKWOOD 1 /* SOC Family Name */
> +#define CONFIG_KW88F6281 1 /* SOC Name */
> +#define CONFIG_MACH_NETSPACE_V2 1 /* Machine type */
> +#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */
> +
> +/*
> + * Commands configuration
> + */
> +#define CONFIG_SYS_NO_FLASH /* Declare no flash (NOR/SPI) */
> +#include <config_cmd_default.h>
> +#define CONFIG_CMD_ENV
> +#define CONFIG_CMD_DHCP
> +#define CONFIG_CMD_PING
> +#define CONFIG_CMD_SF
> +#define CONFIG_CMD_I2C
> +#define CONFIG_CMD_IDE
> +#define CONFIG_CMD_USB
> +
> +/*
> + * Core clock definition.
> + */
> +#define CONFIG_SYS_TCLK 166000000 /* 166MHz */
> +
> +/*
> + * mv-common.h should be defined after CMD configs since it used them
> + * to enable certain macros
> + */
> +#define CONFIG_NR_DRAM_BANKS 2
> +#include "mv-common.h"
> +
> +/* Remove or override few declarations from mv-common.h */
> +#undef CONFIG_RBTREE
> +#undef CONFIG_ENV_SPI_MAX_HZ
> +#undef CONFIG_SYS_IDE_MAXBUS
> +#undef CONFIG_SYS_IDE_MAXDEVICE
> +#undef CONFIG_SYS_PROMPT
> +#define CONFIG_ENV_SPI_MAX_HZ 20000000 /* 20Mhz */
> +#define CONFIG_SYS_IDE_MAXBUS 1
> +#define CONFIG_SYS_IDE_MAXDEVICE 1
> +#define CONFIG_SYS_PROMPT "ns2> "
> +
> +/*
> + * Ethernet Driver configuration
> + */
> +#ifdef CONFIG_CMD_NET
> +#define CONFIG_MVGBE_PORTS {1, 0} /* enable port 0 only */
> +#define CONFIG_NETCONSOLE
> +#endif
> +
> +/*
> + * SATA Driver configuration
> + */
> +#ifdef CONFIG_MVSATA_IDE
> +#define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET
> +/* Network Space Max v2 use 2 SATA ports */
> +#ifdef CONFIG_NETSPACE_MAX_V2
> +#define CONFIG_SYS_ATA_IDE1_OFFSET MV_SATA_PORT1_OFFSET
> +#endif
> +#endif
> +
> +/*
> + * Enable GPI0 support
> + */
> +#define CONFIG_KIRKWOOD_GPIO
> +
> +/*
> + * File systems support
> + */
> +#define CONFIG_CMD_EXT2
> +#define CONFIG_CMD_FAT
> +
> +/*
> + * Use the HUSH parser
> + */
> +#define CONFIG_SYS_HUSH_PARSER
> +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
> +
> +/*
> + * Console configuration
> + */
> +#define CONFIG_CONSOLE_MUX 1
> +#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
> +
> +/*
> + * Environment variables configurations
> + */
> +#define CONFIG_ENV_IS_IN_SPI_FLASH 1
> +#define CONFIG_ENV_SECT_SIZE 0x10000 /* 64KB */
> +#define CONFIG_ENV_SIZE 0x1000 /* 4KB */
> +#define CONFIG_ENV_ADDR 0x70000
> +#define CONFIG_ENV_OFFSET 0x70000 /* env starts here */
> +
> +/*
> + * Default environment variables
> + */
> +#define CONFIG_BOOTARGS "console=ttyS0,115200"
> +
> +#define CONFIG_BOOTCOMMAND \
> + "if run usbload || run diskload; then bootm 0x800000; fi"
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> + "stdin=serial,nc\0" \
> + "stdout=serial,nc\0" \
> + "stderr=serial,nc\0" \
> + "ipaddr=192.168.1.111\0" \
> + "diskload=ide reset && " \
> + "ext2load ide 0:1 0x800000 /boot/uImage\0" \
> + "usbload=usb start && " \
> + "fatload usb 0:1 0x800000 /boot/uImage\0"
> +
> +#endif /* _CONFIG_NETSPACE_V2_H */
> --
> 1.6.3.1
>

> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110503/9fab2f64/attachment.pgp
Wolfgang Denk
2011-05-12 17:24:25 UTC
Permalink
Dear Simon Guinot,

In message <20110503131942.GU19806 at kw.sim.vm.gnt> you wrote:
>
> I have failed to find an entry for this patch in the U-Boot patchwork
> (and any previous version except the very first).

I don't see it either.

> Have I missed something and/or done something wrong ?

Unlikely. Can you please ask Jeremy Kerr on the patchwork mailing
list?

Best regards,

Wolfgang Denk

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
God may be subtle, but He isn't plain mean. - Albert Einstein
Prafulla Wadaskar
2011-05-03 09:59:53 UTC
Permalink
> -----Original Message-----
> From: Simon Guinot [mailto:simon.guinot at sequanux.org]
> Sent: Tuesday, May 03, 2011 4:12 AM
> To: Prafulla Wadaskar; Albert ARIBAUD; Wolfgang Denk; Mike Frysinger
> Cc: u-boot at lists.denx.de; Simon Guinot
> Subject: [PATCH v5 0/5] Add support for LaCie NAS Network Space v2
>
> This patch series adds support for Network Space v2 board and parents.
>
> Changes for v2:
> - netconsole: restore NetOurIP check
> - add entries to MAINTAINERS file
> - move boards from root Makefile to boards.cfg
> - move MACH_TYPE definition into netspace_v2.h
> - remove CONFIG_SYS_HZ redefinition
> - turn PHY initialization message into debug()
>
> Changes for v3:
> - drop patch for Macronix MX25L4005A
> - rewrite patch "sf: disable write protection for Macronix flash",
> using the common spi flash code
> - fix "Definitions" typo in mv-common.h
> - netconsole: add a "/* Fall through */" comment before the NETCONS
> case label
>
> Changes for v4:
> - sf macronix: use spi_flash_cmd_write_enable()
> - enhance commit message for patch "Add support for Network Space v2"
>
> Changes for v5:
> - add a changelog per patch
>

> Simon Guinot (5):
> sf: disable write protection for Macronix flash

> Kirkwood: allow to override CONFIG_SYS_TCLK
> mv-common.h: fix DRAM banks configuration

Hi Simon
Prafulla Wadaskar
2011-05-03 12:09:33 UTC
Permalink
> -----Original Message-----
> From: Simon Guinot [mailto:simon.guinot at sequanux.org]
> Sent: Tuesday, May 03, 2011 4:12 AM
> To: Prafulla Wadaskar; Albert ARIBAUD; Wolfgang Denk; Mike Frysinger
> Cc: u-boot at lists.denx.de; Simon Guinot
> Subject: [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration
>
> From: Simon Guinot <sguinot at lacie.com>
>
> The asm/arch/config.h header define CONFIG_NR_DRAM_BANKS_MAX, which is
> needed to configure DRAM banks.
>
> This patch move the asm/arch/config.h header inclusion above the DRAM
> banks configuration.
>
> Additionally this patch fix a typo.
>
> Signed-off-by: Simon Guinot <sguinot at lacie.com>
> ---
> Changes for v2: none
>
> Changes for v3:
> - fix "Definitions" typo in mv-common.h
>
> Changes for v4,5: none
>
> include/configs/mv-common.h | 8 ++++----
> 1 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
> index a8937dd..0a39257 100644
> --- a/include/configs/mv-common.h
> +++ b/include/configs/mv-common.h
> @@ -113,6 +113,9 @@
> #define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */
> #define CONFIG_SYS_MAXARGS 16 /* max number of command args */
>
> +/* ====> Include platform Common Definitions */
> +#include <asm/arch/config.h>
> +
> /*
> * DRAM Banks configuration, Custom config can be done in <board>.h
> */
> @@ -124,10 +127,7 @@
> #endif
> #endif /* CONFIG_NR_DRAM_BANKS */
>
> -/* ====> Include platform Common Definations */
> -#include <asm/arch/config.h>
> -
> -/* ====> Include driver Common Definations */
> +/* ====> Include driver Common Definitions */
> /*
> * Common NAND configuration
> */
> --
> 1.6.3.1

Applied to u-boot-marvell.git master branch

Regards..
Prafulla . .
Prafulla Wadaskar
2011-05-03 12:09:59 UTC
Permalink
> -----Original Message-----
> From: Simon Guinot [mailto:simon.guinot at sequanux.org]
> Sent: Tuesday, May 03, 2011 4:12 AM
> To: Prafulla Wadaskar; Albert ARIBAUD; Wolfgang Denk; Mike Frysinger
> Cc: u-boot at lists.denx.de; Simon Guinot
> Subject: [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK
>
> From: Simon Guinot <sguinot at lacie.com>
>
> This patch allow to override CONFIG_SYS_TCLK from board configuration
> files. This is needed for the Network Space v2 which use a non standard
> core clock frequency (166MHz instead of 200MHz for a 6281 SoC).
>
> As a possible enhancement for 6281 and 6282 devices, TCLK could be
> dynamically detected by checking the Sample at Reset register bit 21.
>
> Additionally this patch fix a typo.
>
> Signed-off-by: Simon Guinot <sguinot at lacie.com>
> Acked-by: Prafulla Wadaskar <Prafulla at marvell.com>
> ---
> Changes for v[1-5]: none
>
> arch/arm/include/asm/arch-kirkwood/kw88f6281.h | 8 +++++---
> 1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> index 80723ea..22d10f1 100644
> --- a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> +++ b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> @@ -27,11 +27,13 @@
> #ifndef _ASM_ARCH_KW88F6281_H
> #define _ASM_ARCH_KW88F6281_H
>
> -/* SOC specific definations */
> +/* SOC specific definitions */
> #define KW88F6281_REGS_PHYS_BASE 0xf1000000
> #define KW_REGS_PHY_BASE KW88F6281_REGS_PHYS_BASE
>
> -/* TCLK Core Clock defination*/
> -#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
> +/* TCLK Core Clock definition */
> +#ifndef CONFIG_SYS_TCLK
> +#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
> +#endif
>
> #endif /* _ASM_ARCH_KW88F6281_H */
> --
> 1.6.3.1

Applied to u-boot-marvell.git master branch

Regards..
Prafulla . .
mohamed.haneef
2012-02-16 02:59:22 UTC
Permalink
From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>

*Support for msm7x30 mmc read and writes

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---
arch/arm/include/asm/arch-msm7630/mmc.h | 399 +++++++++++++++++++++
drivers/mmc/Makefile | 1 +
drivers/mmc/qc_mmc.c | 584 +++++++++++++++++++++++++++++++
3 files changed, 984 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
create mode 100644 drivers/mmc/qc_mmc.c

diff --git a/arch/arm/include/asm/arch-msm7630/mmc.h b/arch/arm/include/asm/arch-msm7630/mmc.h
new file mode 100644
index 0000000..949e43c
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/mmc.h
@@ -0,0 +1,399 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MMC_H__
+#define __MMC_H__
+
+#ifndef MMC_SLOT
+#define MMC_SLOT 0
+#endif
+
+#include <common.h>
+#include <part.h>
+#include <mmc.h>
+
+/*
+ * Define Macros for SDCC Registers
+ */
+/* 8 bit */
+#define MMC_BOOT_MCI_POWER 0x000
+
+/* MCICMD output control - 6th bit */
+#ifdef PLATFORM_MSM7X30
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x01
+#define MMC_BOOT_MCI_PWR_ON 0x01
+#else
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x02
+#define MMC_BOOT_MCI_PWR_ON 0x03
+#endif
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CLK 0x004
+/* Enable MCI bus clock - 0: clock disabled 1: enabled */
+#define MMC_BOOT_MCI_CLK_ENABLE (1 << 8)
+/* Disable clk o/p when bus idle- 0:always enabled 1:enabled when bus active */
+#define MMC_BOOT_MCI_CLK_PWRSAVE (1 << 9)
+/* Enable Widebus mode - 00: 1 bit mode 10:4 bit mode 01/11: 8 bit mode */
+#define MMC_BOOT_MCI_CLK_WIDEBUS_MODE (3 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT 0
+#define MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT (2 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT (1 << 10)
+/* Enable flow control- 0: disable 1: enable */
+#define MMC_BOOT_MCI_CLK_ENA_FLOW (1 << 12)
+/* Set/clear to select rising/falling edge for data/cmd output */
+#define MMC_BOOT_MCI_CLK_INVERT_OUT (1 << 13)
+/* Select to lach data/cmd coming in falling/rising/feedbk/loopbk of MCIclk */
+#define MMC_BOOT_MCI_CLK_IN_FALLING 0x0
+#define MMC_BOOT_MCI_CLK_IN_RISING (1 << 14)
+#define MMC_BOOT_MCI_CLK_IN_FEEDBACK (2 << 14)
+#define MMC_BOOT_MCI_CLK_IN_LOOPBACK (3 << 14)
+
+/* Bus Width */
+#define MMC_BOOT_BUS_WIDTH_1_BIT 0
+#define MMC_BOOT_BUS_WIDTH_4_BIT 2
+#define MMC_BOOT_BUS_WIDTH_8_BIT 3
+
+/* 32 bits */
+#define MMC_BOOT_MCI_ARGUMENT 0x008
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CMD 0x00C
+/* Command Index: 0 -5 */
+/* Waits for response if set */
+#define MMC_BOOT_MCI_CMD_RESPONSE (1 << 6)
+/* Receives a 136-bit long response if set */
+#define MMC_BOOT_MCI_CMD_LONGRSP (1 << 7)
+/* If set, CPSM disables command timer and waits for interrupt */
+#define MMC_BOOT_MCI_CMD_INTERRUPT (1 << 8)
+/* If set waits for CmdPend before starting to send a command */
+#define MMC_BOOT_MCI_CMD_PENDING (1 << 9)
+/* CPSM is enabled if set */
+#define MMC_BOOT_MCI_CMD_ENABLE (1 << 10)
+/* If set PROG_DONE status bit asserted when busy is de-asserted */
+#define MMC_BOOT_MCI_CMD_PROG_ENA (1 << 11)
+/* To indicate that this is a Command with Data (for SDIO interrupts) */
+#define MMC_BOOT_MCI_CMD_DAT_CMD (1 << 12)
+/* Signals the next command to be an abort (stop) command. Always read 0 */
+#define MMC_BOOT_MCI_CMD_MCIABORT (1 << 13)
+/* Waits for Command Completion Signal if set */
+#define MMC_BOOT_MCI_CMD_CCS_ENABLE (1 << 14)
+/* If set sends CCS disable sequence */
+#define MMC_BOOT_MCI_CMD_CCS_DISABLE (1 << 15)
+
+#define MMC_BOOT_MCI_RESP_CMD 0x010
+
+#define MMC_BOOT_MCI_RESP_0 0x014
+#define MMC_BOOT_MCI_RESP_1 0x018
+#define MMC_BOOT_MCI_RESP_2 0x01C
+#define MMC_BOOT_MCI_RESP_3 0x020
+
+#define MMC_BOOT_MCI_DATA_TIMER 0x024
+#define MMC_BOOT_MCI_DATA_LENGTH 0x028
+/* 16 bits */
+#define MMC_BOOT_MCI_DATA_CTL 0x02C
+/* Data transfer enabled */
+#define MMC_BOOT_MCI_DATA_ENABLE (1 << 0)
+/* Data transfer direction - 0: controller to card 1:card to controller */
+#define MMC_BOOT_MCI_DATA_DIR (1 << 1)
+/* Data transfer mode - 0: block data transfer 1: stream data transfer */
+#define MMC_BOOT_MCI_DATA_MODE (1 << 2)
+/* Enable DM interface - 0: DM disabled 1: DM enabled */
+#define MMC_BOOT_MCI_DATA_DM_ENABLE (1 << 3)
+/* Data block length in bytes (1-4096) */
+#define MMC_BOOT_MCI_BLKSIZE_POS 4
+#define MMC_BOOT_MCI_DATA_COUNT 0x030
+#define MMC_BOOT_MCI_STATUS 0x034
+/* Command response received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_CMD_CRC_FAIL (1 << 0)
+/* Data block sent/received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_DATA_CRC_FAIL (1 << 1)
+/* Command resonse timeout */
+#define MMC_BOOT_MCI_STAT_CMD_TIMEOUT (1 << 2)
+/* Data timeout */
+#define MMC_BOOT_MCI_STAT_DATA_TIMEOUT (1 << 3)
+/* Transmit FIFO underrun error */
+#define MMC_BOOT_MCI_STAT_TX_UNDRUN (1 << 4)
+/* Receive FIFO overrun error */
+#define MMC_BOOT_MCI_STAT_RX_OVRRUN (1 << 5)
+/* Command response received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_CMD_RESP_END (1 << 6)
+/* Command sent - no response required */
+#define MMC_BOOT_MCI_STAT_CMD_SENT (1 << 7)
+/* Data end - data counter zero */
+#define MMC_BOOT_MCI_STAT_DATA_END (1 << 8)
+/* Start bit not detected on all data signals in wide bus mode */
+#define MMC_BOOT_MCI_STAT_START_BIT_ERR (1 << 9)
+/* Data block sent/received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_DATA_BLK_END (1 << 10)
+/* Command transfer in progress */
+#define MMC_BOOT_MCI_STAT_CMD_ACTIVE (1 << 11)
+/* Data transmit in progress */
+#define MMC_BOOT_MCI_STAT_TX_ACTIVE (1 << 12)
+/* Data receive in progress */
+#define MMC_BOOT_MCI_STAT_RX_ACTIVE (1 << 13)
+/* Transmit FIFO half full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_HFULL (1 << 14)
+/* Receive FIFO half full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_HFULL (1 << 15)
+/* Transmit FIFO full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_FULL (1 << 16)
+/* Receive FIFO full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_FULL (1 << 17)
+/* Transmit FIFO empty */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY (1 << 18)
+/* Receive FIFO empty */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_EMPTY (1 << 19)
+/* Data available in transmit FIFO */
+#define MMC_BOOT_MCI_STAT_TX_DATA_AVLBL (1 << 20)
+/* Data available in receive FIFO */
+#define MMC_BOOT_MCI_STAT_RX_DATA_AVLBL (1 << 21)
+/* SDIO interrupt indicator for wake-up */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR (1 << 22)
+/* Programming done */
+#define MMC_BOOT_MCI_STAT_PROG_DONE (1 << 23)
+/* CE-ATA command completion signal detected */
+#define MMC_BOOT_MCI_STAT_ATA_CMD_CMPL (1 << 24)
+/* SDIO interrupt indicator for normal operation */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR_OP (1 << 25)
+/* Commpand completion signal timeout */
+#define MMC_BOOT_MCI_STAT_CCS_TIMEOUT (1 << 26)
+
+#define MMC_BOOT_MCI_STATIC_STATUS (MMC_BOOT_MCI_STAT_CMD_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_DATA_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_CMD_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_TX_UNDRUN| \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN| \
+ MMC_BOOT_MCI_STAT_CMD_RESP_END| \
+ MMC_BOOT_MCI_STAT_CMD_SENT| \
+ MMC_BOOT_MCI_STAT_DATA_END| \
+ MMC_BOOT_MCI_STAT_START_BIT_ERR| \
+ MMC_BOOT_MCI_STAT_DATA_BLK_END| \
+ MMC_BOOT_MCI_SDIO_INTR_CLR| \
+ MMC_BOOT_MCI_STAT_PROG_DONE| \
+ MMC_BOOT_MCI_STAT_ATA_CMD_CMPL |\
+ MMC_BOOT_MCI_STAT_CCS_TIMEOUT)
+
+#define MMC_BOOT_MCI_CLEAR 0x038
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_CLR (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_CLR (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_CLR (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_CLR (1 << 3)
+#define MMC_BOOT_MCI_TX_UNDERRUN_CLR (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_CLR (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_CLR (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_CLR (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_CLR (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_CLR (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_CLR (1 << 10)
+#define MMC_BOOT_MCI_SDIO_INTR_CLR (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_CLR (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPLR_CLR (1 << 24)
+#define MMC_BOOT_MCI_CCS_TIMEOUT_CLR (1 << 25)
+
+#define MMC_BOOT_MCI_INT_MASK0 0x03C
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_MASK (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_MASK (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_MASK (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_MASK (1 << 3)
+#define MMC_BOOT_MCI_TX_OVERRUN_MASK (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_MASK (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_MASK (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_MASK (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_MASK (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_MASK (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_MASK (1 << 10)
+#define MMC_BOOT_MCI_CMD_ACTIVE_MASK (1 << 11)
+#define MMC_BOOT_MCI_TX_ACTIVE_MASK (1 << 12)
+#define MMC_BOOT_MCI_RX_ACTIVE_MASK (1 << 13)
+#define MMC_BOOT_MCI_TX_FIFO_HFULL_MASK (1 << 14)
+#define MMC_BOOT_MCI_RX_FIFO_HFULL_MASK (1 << 15)
+#define MMC_BOOT_MCI_TX_FIFO_FULL_MASK (1 << 16)
+#define MMC_BOOT_MCI_RX_FIFO_FULL_MASK (1 << 17)
+#define MMC_BOOT_MCI_TX_FIFO_EMPTY_MASK (1 << 18)
+#define MMC_BOOT_MCI_RX_FIFO_EMPTY_MASK (1 << 19)
+#define MMC_BOOT_MCI_TX_DATA_AVLBL_MASK (1 << 20)
+#define MMC_BOOT_MCI_RX_DATA_AVLBL_MASK (1 << 21)
+#define MMC_BOOT_MCI_SDIO_INT_MASK (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_MASK (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPL_MASK (1 << 24)
+#define MMC_BOOT_MCI_SDIO_INT_OPER_MASK (1 << 25)
+#define MMC_BOOT_MCI_CCS_TIME_OUT_MASK (1 << 26)
+
+#define MMC_BOOT_MCI_INT_MASK1 0x040
+
+#define MMC_BOOT_MCI_FIFO_COUNT 0x044
+
+#define MMC_BOOT_MCI_CCS_TIMER 0x0058
+
+#define MMC_BOOT_MCI_FIFO 0x080
+
+/* OCR Register */
+#define MMC_BOOT_OCR_17_19 (1 << 7)
+#define MMC_BOOT_OCR_27_36 (0x1FF << 15)
+#define MMC_BOOT_OCR_SEC_MODE (2 << 29)
+#define MMC_BOOT_OCR_BUSY (1 << 31)
+
+/* Commands type */
+#define MMC_BOOT_CMD_BCAST (1 << 0)
+#define MMC_BOOT_CMD_BCAST_W_RESP (1 << 1)
+#define MMC_BOOT_CMD_ADDRESS (1 << 2)
+#define MMC_BOOT_CMD_ADDR_DATA_XFER (1 << 3)
+
+/* Card Status bits (R1 register) */
+#define MMC_BOOT_R1_AKE_SEQ_ERROR (1 << 3)
+#define MMC_BOOT_R1_APP_CMD (1 << 5)
+#define MMC_BOOT_R1_RDY_FOR_DATA (1 << 6)
+#define MMC_BOOT_R1_CURR_STATE_IDLE (0 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RDY (1 << 9)
+#define MMC_BOOT_R1_CURR_STATE_IDENT (2 << 9)
+#define MMC_BOOT_R1_CURR_STATE_STBY (3 << 9)
+#define MMC_BOOT_R1_CURR_STATE_TRAN (4 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DATA (5 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RCV (6 << 9)
+#define MMC_BOOT_R1_CURR_STATE_PRG (7 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DIS (8 << 9)
+#define MMC_BOOT_R1_ERASE_RESET (1 << 13)
+#define MMC_BOOT_R1_CARD_ECC_DISABLED (1 << 14)
+#define MMC_BOOT_R1_WP_ERASE_SKIP (1 << 15)
+#define MMC_BOOT_R1_ERROR (1 << 19)
+#define MMC_BOOT_R1_CC_ERROR (1 << 20)
+#define MMC_BOOT_R1_CARD_ECC_FAILED (1 << 21)
+#define MMC_BOOT_R1_ILLEGAL_CMD (1 << 22)
+#define MMC_BOOT_R1_COM_CRC_ERR (1 << 23)
+#define MMC_BOOT_R1_LOCK_UNLOCK_FAIL (1 << 24)
+#define MMC_BOOT_R1_CARD_IS_LOCKED (1 << 25)
+#define MMC_BOOT_R1_WP_VIOLATION (1 << 26)
+#define MMC_BOOT_R1_ERASE_PARAM (1 << 27)
+#define MMC_BOOT_R1_ERASE_SEQ_ERR (1 << 28)
+#define MMC_BOOT_R1_BLOCK_LEN_ERR (1 << 29)
+#define MMC_BOOT_R1_ADDR_ERR (1 << 30)
+#define MMC_BOOT_R1_OUT_OF_RANGE (1 << 31)
+
+/* Macros for Common Errors */
+#define MMC_BOOT_E_SUCCESS 0
+#define MMC_BOOT_E_FAILURE 1
+/* Not used..use instead TIMEOUT in include/mmc.h */
+#define MMC_BOOT_E_TIMEOUT 2
+#define MMC_BOOT_E_INVAL 3
+#define MMC_BOOT_E_CRC_FAIL 4
+#define MMC_BOOT_E_INIT_FAIL 5
+#define MMC_BOOT_E_CMD_INDX_MISMATCH 6
+#define MMC_BOOT_E_RESP_VERIFY_FAIL 7
+#define MMC_BOOT_E_NOT_SUPPORTED 8
+#define MMC_BOOT_E_CARD_BUSY 9
+#define MMC_BOOT_E_MEM_ALLOC_FAIL 10
+#define MMC_BOOT_E_CLK_ENABLE_FAIL 11
+#define MMC_BOOT_E_CMMC_DECODE_FAIL 12
+#define MMC_BOOT_E_CID_DECODE_FAIL 13
+#define MMC_BOOT_E_BLOCKLEN_ERR 14
+#define MMC_BOOT_E_ADDRESS_ERR 15
+#define MMC_BOOT_E_DATA_CRC_FAIL 16
+#define MMC_BOOT_E_DATA_TIMEOUT 17
+#define MMC_BOOT_E_RX_OVRRUN 18
+#define MMC_BOOT_E_VREG_SET_FAILED 19
+#define MMC_BOOT_E_GPIO_CFG_FAIL 20
+#define MMC_BOOT_E_DATA_ADM_ERR 21
+
+/* EXT_CSD */
+#define MMC_BOOT_ACCESS_WRITE 0x3
+#define MMC_BOOT_EXT_CMMC_HS_TIMING 185
+#define MMC_BOOT_EXT_CMMC_BUS_WIDTH 183
+
+#define MMC_BOOT_EXT_USER_WP 171
+#define MMC_BOOT_EXT_ERASE_GROUP_DEF 175
+#define MMC_BOOT_EXT_HC_WP_GRP_SIZE 221
+#define MMC_BOOT_EXT_HC_ERASE_GRP_SIZE 224
+
+#define MMC_BOOT_US_PERM_WP_EN 2
+#define MMC_BOOT_US_PWR_WP_DIS 3
+
+#define MMC_BOOT_US_PERM_WP_DIS (1<<4)
+#define MMC_BOOT_US_PWR_WP_EN 1
+
+/* For SD */
+#define MMC_BOOT_SD_HC_VOLT_SUPPLIED 0x000001AA
+#define MMC_BOOT_SD_NEG_OCR 0x00FF8000
+#define MMC_BOOT_SD_HC_HCS 0x40000000
+#define MMC_BOOT_SD_DEV_READY 0x80000000
+#define MMC_BOOT_SD_SWITCH_HS 0x80FFFFF1
+
+/* Data structure definitions */
+
+#define MMC_BOOT_XFER_MODE_BLOCK 0
+#define MMC_BOOT_XFER_MODE_STREAM 1
+#define MMC_BOOT_PROGRAM_ENABLED 2
+
+
+#define MMC_RCA 2
+
+#define MMC_BOOT_MAX_COMMAND_RETRY 1000
+#define MMC_BOOT_RD_BLOCK_LEN 512
+#define MMC_BOOT_WR_BLOCK_LEN 512
+
+/* We have 16 32-bits FIFO registers */
+#define MMC_BOOT_MCI_FIFO_DEPTH 16
+#define MMC_BOOT_MCI_HFIFO_COUNT (MMC_BOOT_MCI_FIFO_DEPTH / 2)
+#define MMC_BOOT_MCI_FIFO_SIZE (MMC_BOOT_MCI_FIFO_DEPTH * 4)
+
+#define MAX_PARTITIONS 64
+
+#define MMC_BOOT_CHECK_PATTERN 0xAA /* 10101010b */
+
+#define MMC_CLK_400KHZ 400000
+#define MMC_CLK_144KHZ 144000
+#define MMC_CLK_20MHZ 20000000
+#define MMC_CLK_24MHZ 24000000
+#define MMC_CLK_25MHZ 25000000
+#define MMC_CLK_26MHZ 26000000
+#define MMC_CLK_48MHZ 48000000
+#define MMC_CLK_50MHZ 49152000
+#define MMC_CLK_52MHZ 52000000
+
+#define MMC_CLK_ENABLE 1
+#define MMC_CLK_DISABLE 0
+
+#if 0
+#define MSM_SDC1_BASE 0x12400000
+#define MSM_SDC2_BASE 0x12140000
+#define MSM_SDC3_BASE 0x12180000
+#define MSM_SDC4_BASE 0x121C0000
+#endif
+struct mmc_priv {
+ unsigned int instance;
+ unsigned int base;
+ unsigned int rd_timeout_ns; /* for read timeout */
+};
+
+void mmc_boot_set_ios(struct mmc *mmc);
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data);
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset);
+unsigned int mmc_boot_main(struct mmc *mmc);
+
+extern void clock_config_mmc(uint32_t interface, uint32_t freq);
+extern void clock_init_mmc(uint32_t interface);
+#endif
+
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 506f1d6..2d926ec 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
COBJS-$(CONFIG_SDHCI) += sdhci.o
COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
COBJS-$(CONFIG_TEGRA2_MMC) += tegra2_mmc.o
+COBJS-$(CONFIG_QC_MMC) += qc_mmc.o

COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
new file mode 100644
index 0000000..7b7a1ed
--- /dev/null
+++ b/drivers/mmc/qc_mmc.c
@@ -0,0 +1,584 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/iomap.h>
+#include <common.h>
+
+#if MMC_BOOT_ADM
+#include "adm.h"
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define MMC_BOOT_DATA_READ 0
+#define MMC_BOOT_DATA_WRITE 1
+/*
+ * Calculates the address of registers according to the base address
+ */
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
+{
+ return base + offset;
+}
+
+
+/*
+ * Sets a timeout for read operation.
+ */
+static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
+{
+ if (mmc == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* todo: Add a check for HC, only if HC do this.
+ * If not, taac and nsac must be taken into account
+ */
+ ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
+ debug(" Read timeout set: %d ns\n",
+ ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Check to ensure that there is no alignment or data length errors
+ */
+static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
+{
+
+ if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
+ return MMC_BOOT_E_BLOCKLEN_ERR;
+
+ /* Misaligned address not matching block length */
+ if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
+ return MMC_BOOT_E_ADDRESS_ERR;
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Decode type of error caused during read and write
+ */
+static unsigned int mmc_boot_status_error(unsigned mmc_status)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* If DATA_CRC_FAIL bit is set to 1 then CRC error
+ * was detected by card/device during the data transfer
+ */
+ if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
+ mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
+ /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
+ * exceeded the data timeout period without completing the
+ * transfer
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
+ mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
+ /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
+ * receive data from the card before empty storage for new
+ * received data was available.
+ * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
+ * the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so no need to verify for now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+ /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
+ * data to the card before new data for sending was available.
+ * Verify that bit FLOW_ENA in MCI_CLK
+ * is set to 1 during the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so skipping it now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+
+ return mmc_ret;
+}
+
+/*
+ * Read data to SDC FIFO.
+ */
+static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
+ unsigned int data_len,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_count = 0;
+ unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN;
+ unsigned int i;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg_status, reg_fifo;
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
+
+ /* Read the data from the MCI_FIFO register as long as
+ * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
+ * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
+ * register are cleared to 0.
+ * Continue the reads until the whole transfer data is received
+ */
+
+ do {
+ mmc_ret = MMC_BOOT_E_SUCCESS;
+ mmc_status = readl(reg_status);
+
+ if (mmc_status & read_error) {
+ mmc_ret = mmc_boot_status_error(mmc_status);
+ break;
+ }
+
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
+ unsigned read_count = 1;
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
+ read_count = MMC_BOOT_MCI_HFIFO_COUNT;
+
+ for (i = 0; i < read_count; i++) {
+ /* FIFO contains 16 32-bit data buffer
+ * on 16 sequential addresses
+ */
+ *mmc_ptr = readl(reg_fifo +
+ (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+ mmc_ptr++;
+ /* increase mmc_count by word size */
+ mmc_count += sizeof(unsigned int);
+ }
+ /* quit if we have read enough of data */
+ if (mmc_count == data_len)
+ break;
+ } else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_END)
+ break;
+ } while (1);
+ return mmc_ret;
+}
+
+static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+ unsigned int data_len,
+ unsigned char direction,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ if (direction == MMC_BOOT_DATA_READ)
+ mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc);
+
+ return mmc_ret;
+}
+
+/*
+ * Sends specified command to a card and waits for a response.
+ */
+static unsigned int mmc_boot_send_command(struct mmc_cmd *cmd,
+ struct mmc *mmc)
+{
+ unsigned int mmc_cmd = 0;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_resp = 0;
+ unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
+ unsigned int cmd_index = 0;
+ int i = 0;
+ unsigned long reg, reg_status, reg_resp_cmd, reg_resp_0;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+
+ /* basic check */
+ if (cmd == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_ARGUMENT);
+ writel(cmd->cmdarg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
+ /* 2a. Write command index in CMD_INDEX field */
+ cmd_index = cmd->cmdidx;
+ mmc_cmd |= cmd->cmdidx;
+ /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */
+ if (cmd_index != MMC_CMD_GO_IDLE_STATE)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
+
+ /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
+ if (cmd->resp_type & MMC_RSP_136)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
+
+ /* 2d. Set INTERRUPT bit to 1 to disable command timeout */
+
+ /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
+ * mode data transfer
+ */
+ if (cmd->flags & MMC_BOOT_XFER_MODE_STREAM)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
+
+ /* 2f. Set ENABLE bit to 1 */
+ mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;
+
+ /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of
+ * write data transfer
+ */
+ if ((cmd_index == MMC_CMD_STOP_TRANSMISSION ||
+ cmd_index == MMC_CMD_SEND_STATUS) &&
+ (cmd->flags & MMC_BOOT_PROGRAM_ENABLED))
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
+
+
+ /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
+ /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
+ * of CE-ATA device is enabled
+ */
+
+ /* 2j. clear all static status bits */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLEAR);
+ writel(MMC_BOOT_MCI_STATIC_STATUS, reg);
+
+ /* 2k. Write to MMC_BOOT_MCI_CMD register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CMD);
+ writel(mmc_cmd, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_resp_cmd = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_CMD);
+ reg_resp_0 = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_0);
+
+ /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
+ * register
+ */
+ do {
+ /* 3a. Read MCI_STATUS register */
+ mmc_status = readl(reg_status);
+ while (mmc_status & MMC_BOOT_MCI_STAT_CMD_ACTIVE)
+ mmc_status = readl(reg_status);
+
+ /* 3b. CMD_SENT bit supposed to be set to 1 only
+ * after CMD0 is sent -no response required.
+ */
+ if ((cmd->resp_type == MMC_RSP_NONE) &&
+ (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT))
+ break;
+
+ /* 3c. If CMD_TIMEOUT bit is set then no response
+ * was received */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT) {
+ mmc_return = TIMEOUT;
+ break;
+ }
+ /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's
+ * response was received and CRC check passed
+ * Spcial case for ACMD41: it seems to always fail CRC even if
+ * the response is valid
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END) ||
+ (cmd_index == MMC_CMD_SEND_OP_COND)
+ || (cmd_index == SD_CMD_SEND_IF_COND)) {
+ /* 3i. Read MCI_RESP_CMD register to verify that
+ * response index is equal to command index
+ */
+ mmc_resp = readl(reg_resp_cmd) & 0x3F;
+
+ /* However, long response does not contain the
+ * command index field.
+ * In that case, response index field must be set to
+ * 111111b (0x3F)
+ */
+ if ((mmc_resp == cmd_index) ||
+ (cmd->resp_type == MMC_RSP_R2 ||
+ cmd->resp_type == MMC_RSP_R3 ||
+ cmd->resp_type == MMC_RSP_R6 ||
+ cmd->resp_type == MMC_RSP_R7)){
+ /* 3j. If resp index is equal to cmd index,
+ * read command resp from MCI_RESPn registers
+ * - MCI_RESP0/1/2/3 for CMD2/9/10
+ * - MCI_RESP0 for all other registers
+ */
+ if (cmd->resp_type & MMC_RSP_136) {
+ for (i = 0; i < 4; i++)
+ cmd->response[3-i] =
+ readl(reg_resp_0 + \
+ (i * 4));
+ } else
+ cmd->response[0] = readl(reg_resp_0);
+ } else
+ /* command index mis-match */
+ mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
+
+ break;
+ }
+
+ /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response
+ * was recvd, but CRC check failed.
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL)) {
+ if (cmd_index == SD_CMD_APP_SEND_OP_COND)
+ cmd->response[0] = readl(reg_resp_0);
+ else
+ mmc_return = MMC_BOOT_E_CRC_FAIL;
+ break;
+ }
+
+ } while (1);
+
+ return mmc_return;
+}
+
+static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ uint32_t data_ctrl, mmc_reg, data_len;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg;
+
+ /* Write data timeout period to MCI_DATA_TIMER register. */
+ /* Data timeout period should be in card bus clock periods */
+ mmc_reg = (unsigned long)(((struct mmc_priv *)
+ (mmc->priv))->rd_timeout_ns /
+ 1000000) * (mmc->clock / 1000);
+ /* add some extra clock cycles to be safe */
+ mmc_reg += 1000;
+ mmc_reg = mmc_reg/2;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
+ writel(mmc_reg, reg);
+
+ /* Write the total size of the transfer data to MCI_DATA_LENGTH
+ * register. For block xfer it must be multiple of the block
+ * size.
+ */
+
+ data_len = data->blocks*data->blocksize;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
+ writel(data_len, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
+ (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
+
+
+ if (data->flags == MMC_DATA_READ)
+ data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
+ writel(data_ctrl, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+}
+
+/*
+ * Function to map mmc send command to board send command
+ */
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* todo: do we need to fill in command type ?? */
+
+ if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
+ /* u-boot doesn't fill in the correct argument value */
+ cmd->cmdarg = mmc->rca << 16;
+ /* this is to explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+
+ } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
+ /* explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+ /* set the XFER mode */
+ cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
+ }
+
+
+ /* For Data cmd's */
+ if (data != NULL)
+ mmc_boot_init_data(mmc, cmd, data);
+
+ /* send command */
+ mmc_ret = mmc_boot_send_command(cmd, mmc);
+
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ debug("Return Error = %d\n", mmc_ret);
+ return mmc_ret;
+ }
+
+ if (data != NULL) {
+ mmc_ret = mmc_boot_check_read_data(cmd);
+ if (mmc_ret)
+ return mmc_ret;
+ mmc_boot_fifo_data_transfer((unsigned int *) data->dest,
+ data->blocks * data->blocksize,
+ MMC_BOOT_DATA_READ,
+ mmc);
+ }
+
+ if (cmd->cmdidx == MMC_CMD_SEND_CSD) {
+ /* Set read timeout once csd is received */
+ mmc_ret = mmc_boot_set_read_timeout(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("Error No.%d: Failure setting \
+ write Timeout value!\n",
+ mmc_ret);
+ return mmc_ret;
+ }
+ } else if ((cmd->cmdidx == SD_CMD_SWITCH_FUNC) && (data != NULL)) {
+ /* cmd6 needs at least 8 clocks after the
+ * End Data of Status.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(20);
+ }
+
+ return mmc_ret;
+}
+
+/*
+ * Initialize host structure, set and enable clock-rate and power mode.
+ */
+unsigned int mmc_boot_init(struct mmc *mmc)
+{
+ unsigned int mmc_pwr = 0;
+ struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;
+ int mmc_slot = priv->instance;
+ unsigned long reg;
+
+ /* Initialize any clocks needed for SDC controller */
+ clock_init_mmc(mmc_slot);
+
+ /* Setup initial freq to 400KHz */
+ clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);
+
+ /* set power mode*/
+ mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_POWER);
+ writel(mmc_pwr, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+static unsigned int mmc_boot_set_bus_width(unsigned int width,
+ struct mmc *mmc)
+{
+ unsigned int mmc_reg;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg;
+
+ /* set MCI_CLK accordingly */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLK);
+ mmc_reg = readl(reg);
+ mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+ if (width == 1)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
+ else if (width == 4)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
+ else if (width == 8)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
+ else
+ return MMC_BOOT_E_INVAL;
+
+ writel(mmc_reg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ debug("Setting bus width to %d\n", width);
+ return MMC_BOOT_E_SUCCESS;
+}
+
+void mmc_boot_set_ios(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ int mmc_slot = priv->instance;
+
+ /* clock frequency should be less than 400KHz in identification mode */
+ clock_config_mmc(mmc_slot, mmc->clock);
+ /*
+ * give atleast 2 MCLK cycles delay for clocks
+ * and SDCC core to stabilize.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(5);
+ mmc_ret = mmc_boot_set_bus_width(mmc->bus_width, mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS)
+ printf("Set bus width error %d\n", mmc_ret);
+}
+
+/*
+ * Board specific initializations
+ */
+unsigned int mmc_boot_main(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* Initialize necessary data structure and enable/set clock and power */
+ debug(" Initializing MMC host data structure and clock!\n");
+ mmc_ret = mmc_boot_init(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("MMC Boot: Error Initializing MMC Card!!!\n");
+ return MMC_BOOT_E_FAILURE;
+ }
+
+ return MMC_BOOT_E_SUCCESS;
+}
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Albert ARIBAUD
2012-02-29 00:03:07 UTC
Permalink
Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :
> From: Mohamed Haneef<mohamed.haneef at lntinfotech.com>
>
> *Support for msm7x30 mmc read and writes

The patch title is misleading. MMC reads and writes are already
supported in U-Boot; what you add is support for the qc_mc MMC controller.

Amicalement,
--
Albert.
Mohamed Haneef
2012-03-05 14:40:41 UTC
Permalink
* Support for qc_mmc MMC Controller

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---
change for v2:
- changed the patch title to "support for qc_mmc MMC Controller"


arch/arm/include/asm/arch-msm7630/mmc.h | 399 +++++++++++++++++++++
drivers/mmc/Makefile | 1 +
drivers/mmc/qc_mmc.c | 584 +++++++++++++++++++++++++++++++
3 files changed, 984 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
create mode 100644 drivers/mmc/qc_mmc.c

diff --git a/arch/arm/include/asm/arch-msm7630/mmc.h b/arch/arm/include/asm/arch-msm7630/mmc.h
new file mode 100644
index 0000000..949e43c
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/mmc.h
@@ -0,0 +1,399 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MMC_H__
+#define __MMC_H__
+
+#ifndef MMC_SLOT
+#define MMC_SLOT 0
+#endif
+
+#include <common.h>
+#include <part.h>
+#include <mmc.h>
+
+/*
+ * Define Macros for SDCC Registers
+ */
+/* 8 bit */
+#define MMC_BOOT_MCI_POWER 0x000
+
+/* MCICMD output control - 6th bit */
+#ifdef PLATFORM_MSM7X30
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x01
+#define MMC_BOOT_MCI_PWR_ON 0x01
+#else
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x02
+#define MMC_BOOT_MCI_PWR_ON 0x03
+#endif
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CLK 0x004
+/* Enable MCI bus clock - 0: clock disabled 1: enabled */
+#define MMC_BOOT_MCI_CLK_ENABLE (1 << 8)
+/* Disable clk o/p when bus idle- 0:always enabled 1:enabled when bus active */
+#define MMC_BOOT_MCI_CLK_PWRSAVE (1 << 9)
+/* Enable Widebus mode - 00: 1 bit mode 10:4 bit mode 01/11: 8 bit mode */
+#define MMC_BOOT_MCI_CLK_WIDEBUS_MODE (3 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT 0
+#define MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT (2 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT (1 << 10)
+/* Enable flow control- 0: disable 1: enable */
+#define MMC_BOOT_MCI_CLK_ENA_FLOW (1 << 12)
+/* Set/clear to select rising/falling edge for data/cmd output */
+#define MMC_BOOT_MCI_CLK_INVERT_OUT (1 << 13)
+/* Select to lach data/cmd coming in falling/rising/feedbk/loopbk of MCIclk */
+#define MMC_BOOT_MCI_CLK_IN_FALLING 0x0
+#define MMC_BOOT_MCI_CLK_IN_RISING (1 << 14)
+#define MMC_BOOT_MCI_CLK_IN_FEEDBACK (2 << 14)
+#define MMC_BOOT_MCI_CLK_IN_LOOPBACK (3 << 14)
+
+/* Bus Width */
+#define MMC_BOOT_BUS_WIDTH_1_BIT 0
+#define MMC_BOOT_BUS_WIDTH_4_BIT 2
+#define MMC_BOOT_BUS_WIDTH_8_BIT 3
+
+/* 32 bits */
+#define MMC_BOOT_MCI_ARGUMENT 0x008
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CMD 0x00C
+/* Command Index: 0 -5 */
+/* Waits for response if set */
+#define MMC_BOOT_MCI_CMD_RESPONSE (1 << 6)
+/* Receives a 136-bit long response if set */
+#define MMC_BOOT_MCI_CMD_LONGRSP (1 << 7)
+/* If set, CPSM disables command timer and waits for interrupt */
+#define MMC_BOOT_MCI_CMD_INTERRUPT (1 << 8)
+/* If set waits for CmdPend before starting to send a command */
+#define MMC_BOOT_MCI_CMD_PENDING (1 << 9)
+/* CPSM is enabled if set */
+#define MMC_BOOT_MCI_CMD_ENABLE (1 << 10)
+/* If set PROG_DONE status bit asserted when busy is de-asserted */
+#define MMC_BOOT_MCI_CMD_PROG_ENA (1 << 11)
+/* To indicate that this is a Command with Data (for SDIO interrupts) */
+#define MMC_BOOT_MCI_CMD_DAT_CMD (1 << 12)
+/* Signals the next command to be an abort (stop) command. Always read 0 */
+#define MMC_BOOT_MCI_CMD_MCIABORT (1 << 13)
+/* Waits for Command Completion Signal if set */
+#define MMC_BOOT_MCI_CMD_CCS_ENABLE (1 << 14)
+/* If set sends CCS disable sequence */
+#define MMC_BOOT_MCI_CMD_CCS_DISABLE (1 << 15)
+
+#define MMC_BOOT_MCI_RESP_CMD 0x010
+
+#define MMC_BOOT_MCI_RESP_0 0x014
+#define MMC_BOOT_MCI_RESP_1 0x018
+#define MMC_BOOT_MCI_RESP_2 0x01C
+#define MMC_BOOT_MCI_RESP_3 0x020
+
+#define MMC_BOOT_MCI_DATA_TIMER 0x024
+#define MMC_BOOT_MCI_DATA_LENGTH 0x028
+/* 16 bits */
+#define MMC_BOOT_MCI_DATA_CTL 0x02C
+/* Data transfer enabled */
+#define MMC_BOOT_MCI_DATA_ENABLE (1 << 0)
+/* Data transfer direction - 0: controller to card 1:card to controller */
+#define MMC_BOOT_MCI_DATA_DIR (1 << 1)
+/* Data transfer mode - 0: block data transfer 1: stream data transfer */
+#define MMC_BOOT_MCI_DATA_MODE (1 << 2)
+/* Enable DM interface - 0: DM disabled 1: DM enabled */
+#define MMC_BOOT_MCI_DATA_DM_ENABLE (1 << 3)
+/* Data block length in bytes (1-4096) */
+#define MMC_BOOT_MCI_BLKSIZE_POS 4
+#define MMC_BOOT_MCI_DATA_COUNT 0x030
+#define MMC_BOOT_MCI_STATUS 0x034
+/* Command response received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_CMD_CRC_FAIL (1 << 0)
+/* Data block sent/received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_DATA_CRC_FAIL (1 << 1)
+/* Command resonse timeout */
+#define MMC_BOOT_MCI_STAT_CMD_TIMEOUT (1 << 2)
+/* Data timeout */
+#define MMC_BOOT_MCI_STAT_DATA_TIMEOUT (1 << 3)
+/* Transmit FIFO underrun error */
+#define MMC_BOOT_MCI_STAT_TX_UNDRUN (1 << 4)
+/* Receive FIFO overrun error */
+#define MMC_BOOT_MCI_STAT_RX_OVRRUN (1 << 5)
+/* Command response received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_CMD_RESP_END (1 << 6)
+/* Command sent - no response required */
+#define MMC_BOOT_MCI_STAT_CMD_SENT (1 << 7)
+/* Data end - data counter zero */
+#define MMC_BOOT_MCI_STAT_DATA_END (1 << 8)
+/* Start bit not detected on all data signals in wide bus mode */
+#define MMC_BOOT_MCI_STAT_START_BIT_ERR (1 << 9)
+/* Data block sent/received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_DATA_BLK_END (1 << 10)
+/* Command transfer in progress */
+#define MMC_BOOT_MCI_STAT_CMD_ACTIVE (1 << 11)
+/* Data transmit in progress */
+#define MMC_BOOT_MCI_STAT_TX_ACTIVE (1 << 12)
+/* Data receive in progress */
+#define MMC_BOOT_MCI_STAT_RX_ACTIVE (1 << 13)
+/* Transmit FIFO half full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_HFULL (1 << 14)
+/* Receive FIFO half full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_HFULL (1 << 15)
+/* Transmit FIFO full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_FULL (1 << 16)
+/* Receive FIFO full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_FULL (1 << 17)
+/* Transmit FIFO empty */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY (1 << 18)
+/* Receive FIFO empty */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_EMPTY (1 << 19)
+/* Data available in transmit FIFO */
+#define MMC_BOOT_MCI_STAT_TX_DATA_AVLBL (1 << 20)
+/* Data available in receive FIFO */
+#define MMC_BOOT_MCI_STAT_RX_DATA_AVLBL (1 << 21)
+/* SDIO interrupt indicator for wake-up */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR (1 << 22)
+/* Programming done */
+#define MMC_BOOT_MCI_STAT_PROG_DONE (1 << 23)
+/* CE-ATA command completion signal detected */
+#define MMC_BOOT_MCI_STAT_ATA_CMD_CMPL (1 << 24)
+/* SDIO interrupt indicator for normal operation */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR_OP (1 << 25)
+/* Commpand completion signal timeout */
+#define MMC_BOOT_MCI_STAT_CCS_TIMEOUT (1 << 26)
+
+#define MMC_BOOT_MCI_STATIC_STATUS (MMC_BOOT_MCI_STAT_CMD_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_DATA_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_CMD_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_TX_UNDRUN| \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN| \
+ MMC_BOOT_MCI_STAT_CMD_RESP_END| \
+ MMC_BOOT_MCI_STAT_CMD_SENT| \
+ MMC_BOOT_MCI_STAT_DATA_END| \
+ MMC_BOOT_MCI_STAT_START_BIT_ERR| \
+ MMC_BOOT_MCI_STAT_DATA_BLK_END| \
+ MMC_BOOT_MCI_SDIO_INTR_CLR| \
+ MMC_BOOT_MCI_STAT_PROG_DONE| \
+ MMC_BOOT_MCI_STAT_ATA_CMD_CMPL |\
+ MMC_BOOT_MCI_STAT_CCS_TIMEOUT)
+
+#define MMC_BOOT_MCI_CLEAR 0x038
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_CLR (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_CLR (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_CLR (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_CLR (1 << 3)
+#define MMC_BOOT_MCI_TX_UNDERRUN_CLR (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_CLR (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_CLR (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_CLR (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_CLR (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_CLR (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_CLR (1 << 10)
+#define MMC_BOOT_MCI_SDIO_INTR_CLR (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_CLR (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPLR_CLR (1 << 24)
+#define MMC_BOOT_MCI_CCS_TIMEOUT_CLR (1 << 25)
+
+#define MMC_BOOT_MCI_INT_MASK0 0x03C
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_MASK (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_MASK (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_MASK (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_MASK (1 << 3)
+#define MMC_BOOT_MCI_TX_OVERRUN_MASK (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_MASK (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_MASK (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_MASK (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_MASK (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_MASK (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_MASK (1 << 10)
+#define MMC_BOOT_MCI_CMD_ACTIVE_MASK (1 << 11)
+#define MMC_BOOT_MCI_TX_ACTIVE_MASK (1 << 12)
+#define MMC_BOOT_MCI_RX_ACTIVE_MASK (1 << 13)
+#define MMC_BOOT_MCI_TX_FIFO_HFULL_MASK (1 << 14)
+#define MMC_BOOT_MCI_RX_FIFO_HFULL_MASK (1 << 15)
+#define MMC_BOOT_MCI_TX_FIFO_FULL_MASK (1 << 16)
+#define MMC_BOOT_MCI_RX_FIFO_FULL_MASK (1 << 17)
+#define MMC_BOOT_MCI_TX_FIFO_EMPTY_MASK (1 << 18)
+#define MMC_BOOT_MCI_RX_FIFO_EMPTY_MASK (1 << 19)
+#define MMC_BOOT_MCI_TX_DATA_AVLBL_MASK (1 << 20)
+#define MMC_BOOT_MCI_RX_DATA_AVLBL_MASK (1 << 21)
+#define MMC_BOOT_MCI_SDIO_INT_MASK (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_MASK (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPL_MASK (1 << 24)
+#define MMC_BOOT_MCI_SDIO_INT_OPER_MASK (1 << 25)
+#define MMC_BOOT_MCI_CCS_TIME_OUT_MASK (1 << 26)
+
+#define MMC_BOOT_MCI_INT_MASK1 0x040
+
+#define MMC_BOOT_MCI_FIFO_COUNT 0x044
+
+#define MMC_BOOT_MCI_CCS_TIMER 0x0058
+
+#define MMC_BOOT_MCI_FIFO 0x080
+
+/* OCR Register */
+#define MMC_BOOT_OCR_17_19 (1 << 7)
+#define MMC_BOOT_OCR_27_36 (0x1FF << 15)
+#define MMC_BOOT_OCR_SEC_MODE (2 << 29)
+#define MMC_BOOT_OCR_BUSY (1 << 31)
+
+/* Commands type */
+#define MMC_BOOT_CMD_BCAST (1 << 0)
+#define MMC_BOOT_CMD_BCAST_W_RESP (1 << 1)
+#define MMC_BOOT_CMD_ADDRESS (1 << 2)
+#define MMC_BOOT_CMD_ADDR_DATA_XFER (1 << 3)
+
+/* Card Status bits (R1 register) */
+#define MMC_BOOT_R1_AKE_SEQ_ERROR (1 << 3)
+#define MMC_BOOT_R1_APP_CMD (1 << 5)
+#define MMC_BOOT_R1_RDY_FOR_DATA (1 << 6)
+#define MMC_BOOT_R1_CURR_STATE_IDLE (0 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RDY (1 << 9)
+#define MMC_BOOT_R1_CURR_STATE_IDENT (2 << 9)
+#define MMC_BOOT_R1_CURR_STATE_STBY (3 << 9)
+#define MMC_BOOT_R1_CURR_STATE_TRAN (4 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DATA (5 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RCV (6 << 9)
+#define MMC_BOOT_R1_CURR_STATE_PRG (7 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DIS (8 << 9)
+#define MMC_BOOT_R1_ERASE_RESET (1 << 13)
+#define MMC_BOOT_R1_CARD_ECC_DISABLED (1 << 14)
+#define MMC_BOOT_R1_WP_ERASE_SKIP (1 << 15)
+#define MMC_BOOT_R1_ERROR (1 << 19)
+#define MMC_BOOT_R1_CC_ERROR (1 << 20)
+#define MMC_BOOT_R1_CARD_ECC_FAILED (1 << 21)
+#define MMC_BOOT_R1_ILLEGAL_CMD (1 << 22)
+#define MMC_BOOT_R1_COM_CRC_ERR (1 << 23)
+#define MMC_BOOT_R1_LOCK_UNLOCK_FAIL (1 << 24)
+#define MMC_BOOT_R1_CARD_IS_LOCKED (1 << 25)
+#define MMC_BOOT_R1_WP_VIOLATION (1 << 26)
+#define MMC_BOOT_R1_ERASE_PARAM (1 << 27)
+#define MMC_BOOT_R1_ERASE_SEQ_ERR (1 << 28)
+#define MMC_BOOT_R1_BLOCK_LEN_ERR (1 << 29)
+#define MMC_BOOT_R1_ADDR_ERR (1 << 30)
+#define MMC_BOOT_R1_OUT_OF_RANGE (1 << 31)
+
+/* Macros for Common Errors */
+#define MMC_BOOT_E_SUCCESS 0
+#define MMC_BOOT_E_FAILURE 1
+/* Not used..use instead TIMEOUT in include/mmc.h */
+#define MMC_BOOT_E_TIMEOUT 2
+#define MMC_BOOT_E_INVAL 3
+#define MMC_BOOT_E_CRC_FAIL 4
+#define MMC_BOOT_E_INIT_FAIL 5
+#define MMC_BOOT_E_CMD_INDX_MISMATCH 6
+#define MMC_BOOT_E_RESP_VERIFY_FAIL 7
+#define MMC_BOOT_E_NOT_SUPPORTED 8
+#define MMC_BOOT_E_CARD_BUSY 9
+#define MMC_BOOT_E_MEM_ALLOC_FAIL 10
+#define MMC_BOOT_E_CLK_ENABLE_FAIL 11
+#define MMC_BOOT_E_CMMC_DECODE_FAIL 12
+#define MMC_BOOT_E_CID_DECODE_FAIL 13
+#define MMC_BOOT_E_BLOCKLEN_ERR 14
+#define MMC_BOOT_E_ADDRESS_ERR 15
+#define MMC_BOOT_E_DATA_CRC_FAIL 16
+#define MMC_BOOT_E_DATA_TIMEOUT 17
+#define MMC_BOOT_E_RX_OVRRUN 18
+#define MMC_BOOT_E_VREG_SET_FAILED 19
+#define MMC_BOOT_E_GPIO_CFG_FAIL 20
+#define MMC_BOOT_E_DATA_ADM_ERR 21
+
+/* EXT_CSD */
+#define MMC_BOOT_ACCESS_WRITE 0x3
+#define MMC_BOOT_EXT_CMMC_HS_TIMING 185
+#define MMC_BOOT_EXT_CMMC_BUS_WIDTH 183
+
+#define MMC_BOOT_EXT_USER_WP 171
+#define MMC_BOOT_EXT_ERASE_GROUP_DEF 175
+#define MMC_BOOT_EXT_HC_WP_GRP_SIZE 221
+#define MMC_BOOT_EXT_HC_ERASE_GRP_SIZE 224
+
+#define MMC_BOOT_US_PERM_WP_EN 2
+#define MMC_BOOT_US_PWR_WP_DIS 3
+
+#define MMC_BOOT_US_PERM_WP_DIS (1<<4)
+#define MMC_BOOT_US_PWR_WP_EN 1
+
+/* For SD */
+#define MMC_BOOT_SD_HC_VOLT_SUPPLIED 0x000001AA
+#define MMC_BOOT_SD_NEG_OCR 0x00FF8000
+#define MMC_BOOT_SD_HC_HCS 0x40000000
+#define MMC_BOOT_SD_DEV_READY 0x80000000
+#define MMC_BOOT_SD_SWITCH_HS 0x80FFFFF1
+
+/* Data structure definitions */
+
+#define MMC_BOOT_XFER_MODE_BLOCK 0
+#define MMC_BOOT_XFER_MODE_STREAM 1
+#define MMC_BOOT_PROGRAM_ENABLED 2
+
+
+#define MMC_RCA 2
+
+#define MMC_BOOT_MAX_COMMAND_RETRY 1000
+#define MMC_BOOT_RD_BLOCK_LEN 512
+#define MMC_BOOT_WR_BLOCK_LEN 512
+
+/* We have 16 32-bits FIFO registers */
+#define MMC_BOOT_MCI_FIFO_DEPTH 16
+#define MMC_BOOT_MCI_HFIFO_COUNT (MMC_BOOT_MCI_FIFO_DEPTH / 2)
+#define MMC_BOOT_MCI_FIFO_SIZE (MMC_BOOT_MCI_FIFO_DEPTH * 4)
+
+#define MAX_PARTITIONS 64
+
+#define MMC_BOOT_CHECK_PATTERN 0xAA /* 10101010b */
+
+#define MMC_CLK_400KHZ 400000
+#define MMC_CLK_144KHZ 144000
+#define MMC_CLK_20MHZ 20000000
+#define MMC_CLK_24MHZ 24000000
+#define MMC_CLK_25MHZ 25000000
+#define MMC_CLK_26MHZ 26000000
+#define MMC_CLK_48MHZ 48000000
+#define MMC_CLK_50MHZ 49152000
+#define MMC_CLK_52MHZ 52000000
+
+#define MMC_CLK_ENABLE 1
+#define MMC_CLK_DISABLE 0
+
+#if 0
+#define MSM_SDC1_BASE 0x12400000
+#define MSM_SDC2_BASE 0x12140000
+#define MSM_SDC3_BASE 0x12180000
+#define MSM_SDC4_BASE 0x121C0000
+#endif
+struct mmc_priv {
+ unsigned int instance;
+ unsigned int base;
+ unsigned int rd_timeout_ns; /* for read timeout */
+};
+
+void mmc_boot_set_ios(struct mmc *mmc);
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data);
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset);
+unsigned int mmc_boot_main(struct mmc *mmc);
+
+extern void clock_config_mmc(uint32_t interface, uint32_t freq);
+extern void clock_init_mmc(uint32_t interface);
+#endif
+
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 506f1d6..2d926ec 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
COBJS-$(CONFIG_SDHCI) += sdhci.o
COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
COBJS-$(CONFIG_TEGRA2_MMC) += tegra2_mmc.o
+COBJS-$(CONFIG_QC_MMC) += qc_mmc.o

COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
new file mode 100644
index 0000000..7b7a1ed
--- /dev/null
+++ b/drivers/mmc/qc_mmc.c
@@ -0,0 +1,584 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/iomap.h>
+#include <common.h>
+
+#if MMC_BOOT_ADM
+#include "adm.h"
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define MMC_BOOT_DATA_READ 0
+#define MMC_BOOT_DATA_WRITE 1
+/*
+ * Calculates the address of registers according to the base address
+ */
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
+{
+ return base + offset;
+}
+
+
+/*
+ * Sets a timeout for read operation.
+ */
+static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
+{
+ if (mmc == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* todo: Add a check for HC, only if HC do this.
+ * If not, taac and nsac must be taken into account
+ */
+ ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
+ debug(" Read timeout set: %d ns\n",
+ ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Check to ensure that there is no alignment or data length errors
+ */
+static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
+{
+
+ if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
+ return MMC_BOOT_E_BLOCKLEN_ERR;
+
+ /* Misaligned address not matching block length */
+ if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
+ return MMC_BOOT_E_ADDRESS_ERR;
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Decode type of error caused during read and write
+ */
+static unsigned int mmc_boot_status_error(unsigned mmc_status)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* If DATA_CRC_FAIL bit is set to 1 then CRC error
+ * was detected by card/device during the data transfer
+ */
+ if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
+ mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
+ /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
+ * exceeded the data timeout period without completing the
+ * transfer
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
+ mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
+ /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
+ * receive data from the card before empty storage for new
+ * received data was available.
+ * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
+ * the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so no need to verify for now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+ /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
+ * data to the card before new data for sending was available.
+ * Verify that bit FLOW_ENA in MCI_CLK
+ * is set to 1 during the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so skipping it now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+
+ return mmc_ret;
+}
+
+/*
+ * Read data to SDC FIFO.
+ */
+static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
+ unsigned int data_len,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_count = 0;
+ unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN;
+ unsigned int i;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg_status, reg_fifo;
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
+
+ /* Read the data from the MCI_FIFO register as long as
+ * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
+ * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
+ * register are cleared to 0.
+ * Continue the reads until the whole transfer data is received
+ */
+
+ do {
+ mmc_ret = MMC_BOOT_E_SUCCESS;
+ mmc_status = readl(reg_status);
+
+ if (mmc_status & read_error) {
+ mmc_ret = mmc_boot_status_error(mmc_status);
+ break;
+ }
+
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
+ unsigned read_count = 1;
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
+ read_count = MMC_BOOT_MCI_HFIFO_COUNT;
+
+ for (i = 0; i < read_count; i++) {
+ /* FIFO contains 16 32-bit data buffer
+ * on 16 sequential addresses
+ */
+ *mmc_ptr = readl(reg_fifo +
+ (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+ mmc_ptr++;
+ /* increase mmc_count by word size */
+ mmc_count += sizeof(unsigned int);
+ }
+ /* quit if we have read enough of data */
+ if (mmc_count == data_len)
+ break;
+ } else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_END)
+ break;
+ } while (1);
+ return mmc_ret;
+}
+
+static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+ unsigned int data_len,
+ unsigned char direction,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ if (direction == MMC_BOOT_DATA_READ)
+ mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc);
+
+ return mmc_ret;
+}
+
+/*
+ * Sends specified command to a card and waits for a response.
+ */
+static unsigned int mmc_boot_send_command(struct mmc_cmd *cmd,
+ struct mmc *mmc)
+{
+ unsigned int mmc_cmd = 0;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_resp = 0;
+ unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
+ unsigned int cmd_index = 0;
+ int i = 0;
+ unsigned long reg, reg_status, reg_resp_cmd, reg_resp_0;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+
+ /* basic check */
+ if (cmd == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_ARGUMENT);
+ writel(cmd->cmdarg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
+ /* 2a. Write command index in CMD_INDEX field */
+ cmd_index = cmd->cmdidx;
+ mmc_cmd |= cmd->cmdidx;
+ /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */
+ if (cmd_index != MMC_CMD_GO_IDLE_STATE)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
+
+ /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
+ if (cmd->resp_type & MMC_RSP_136)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
+
+ /* 2d. Set INTERRUPT bit to 1 to disable command timeout */
+
+ /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
+ * mode data transfer
+ */
+ if (cmd->flags & MMC_BOOT_XFER_MODE_STREAM)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
+
+ /* 2f. Set ENABLE bit to 1 */
+ mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;
+
+ /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of
+ * write data transfer
+ */
+ if ((cmd_index == MMC_CMD_STOP_TRANSMISSION ||
+ cmd_index == MMC_CMD_SEND_STATUS) &&
+ (cmd->flags & MMC_BOOT_PROGRAM_ENABLED))
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
+
+
+ /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
+ /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
+ * of CE-ATA device is enabled
+ */
+
+ /* 2j. clear all static status bits */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLEAR);
+ writel(MMC_BOOT_MCI_STATIC_STATUS, reg);
+
+ /* 2k. Write to MMC_BOOT_MCI_CMD register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CMD);
+ writel(mmc_cmd, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_resp_cmd = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_CMD);
+ reg_resp_0 = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_0);
+
+ /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
+ * register
+ */
+ do {
+ /* 3a. Read MCI_STATUS register */
+ mmc_status = readl(reg_status);
+ while (mmc_status & MMC_BOOT_MCI_STAT_CMD_ACTIVE)
+ mmc_status = readl(reg_status);
+
+ /* 3b. CMD_SENT bit supposed to be set to 1 only
+ * after CMD0 is sent -no response required.
+ */
+ if ((cmd->resp_type == MMC_RSP_NONE) &&
+ (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT))
+ break;
+
+ /* 3c. If CMD_TIMEOUT bit is set then no response
+ * was received */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT) {
+ mmc_return = TIMEOUT;
+ break;
+ }
+ /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's
+ * response was received and CRC check passed
+ * Spcial case for ACMD41: it seems to always fail CRC even if
+ * the response is valid
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END) ||
+ (cmd_index == MMC_CMD_SEND_OP_COND)
+ || (cmd_index == SD_CMD_SEND_IF_COND)) {
+ /* 3i. Read MCI_RESP_CMD register to verify that
+ * response index is equal to command index
+ */
+ mmc_resp = readl(reg_resp_cmd) & 0x3F;
+
+ /* However, long response does not contain the
+ * command index field.
+ * In that case, response index field must be set to
+ * 111111b (0x3F)
+ */
+ if ((mmc_resp == cmd_index) ||
+ (cmd->resp_type == MMC_RSP_R2 ||
+ cmd->resp_type == MMC_RSP_R3 ||
+ cmd->resp_type == MMC_RSP_R6 ||
+ cmd->resp_type == MMC_RSP_R7)){
+ /* 3j. If resp index is equal to cmd index,
+ * read command resp from MCI_RESPn registers
+ * - MCI_RESP0/1/2/3 for CMD2/9/10
+ * - MCI_RESP0 for all other registers
+ */
+ if (cmd->resp_type & MMC_RSP_136) {
+ for (i = 0; i < 4; i++)
+ cmd->response[3-i] =
+ readl(reg_resp_0 + \
+ (i * 4));
+ } else
+ cmd->response[0] = readl(reg_resp_0);
+ } else
+ /* command index mis-match */
+ mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
+
+ break;
+ }
+
+ /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response
+ * was recvd, but CRC check failed.
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL)) {
+ if (cmd_index == SD_CMD_APP_SEND_OP_COND)
+ cmd->response[0] = readl(reg_resp_0);
+ else
+ mmc_return = MMC_BOOT_E_CRC_FAIL;
+ break;
+ }
+
+ } while (1);
+
+ return mmc_return;
+}
+
+static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ uint32_t data_ctrl, mmc_reg, data_len;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg;
+
+ /* Write data timeout period to MCI_DATA_TIMER register. */
+ /* Data timeout period should be in card bus clock periods */
+ mmc_reg = (unsigned long)(((struct mmc_priv *)
+ (mmc->priv))->rd_timeout_ns /
+ 1000000) * (mmc->clock / 1000);
+ /* add some extra clock cycles to be safe */
+ mmc_reg += 1000;
+ mmc_reg = mmc_reg/2;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
+ writel(mmc_reg, reg);
+
+ /* Write the total size of the transfer data to MCI_DATA_LENGTH
+ * register. For block xfer it must be multiple of the block
+ * size.
+ */
+
+ data_len = data->blocks*data->blocksize;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
+ writel(data_len, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
+ (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
+
+
+ if (data->flags == MMC_DATA_READ)
+ data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
+ writel(data_ctrl, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+}
+
+/*
+ * Function to map mmc send command to board send command
+ */
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* todo: do we need to fill in command type ?? */
+
+ if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
+ /* u-boot doesn't fill in the correct argument value */
+ cmd->cmdarg = mmc->rca << 16;
+ /* this is to explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+
+ } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
+ /* explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+ /* set the XFER mode */
+ cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
+ }
+
+
+ /* For Data cmd's */
+ if (data != NULL)
+ mmc_boot_init_data(mmc, cmd, data);
+
+ /* send command */
+ mmc_ret = mmc_boot_send_command(cmd, mmc);
+
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ debug("Return Error = %d\n", mmc_ret);
+ return mmc_ret;
+ }
+
+ if (data != NULL) {
+ mmc_ret = mmc_boot_check_read_data(cmd);
+ if (mmc_ret)
+ return mmc_ret;
+ mmc_boot_fifo_data_transfer((unsigned int *) data->dest,
+ data->blocks * data->blocksize,
+ MMC_BOOT_DATA_READ,
+ mmc);
+ }
+
+ if (cmd->cmdidx == MMC_CMD_SEND_CSD) {
+ /* Set read timeout once csd is received */
+ mmc_ret = mmc_boot_set_read_timeout(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("Error No.%d: Failure setting \
+ write Timeout value!\n",
+ mmc_ret);
+ return mmc_ret;
+ }
+ } else if ((cmd->cmdidx == SD_CMD_SWITCH_FUNC) && (data != NULL)) {
+ /* cmd6 needs at least 8 clocks after the
+ * End Data of Status.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(20);
+ }
+
+ return mmc_ret;
+}
+
+/*
+ * Initialize host structure, set and enable clock-rate and power mode.
+ */
+unsigned int mmc_boot_init(struct mmc *mmc)
+{
+ unsigned int mmc_pwr = 0;
+ struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;
+ int mmc_slot = priv->instance;
+ unsigned long reg;
+
+ /* Initialize any clocks needed for SDC controller */
+ clock_init_mmc(mmc_slot);
+
+ /* Setup initial freq to 400KHz */
+ clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);
+
+ /* set power mode*/
+ mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_POWER);
+ writel(mmc_pwr, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+static unsigned int mmc_boot_set_bus_width(unsigned int width,
+ struct mmc *mmc)
+{
+ unsigned int mmc_reg;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg;
+
+ /* set MCI_CLK accordingly */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLK);
+ mmc_reg = readl(reg);
+ mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+ if (width == 1)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
+ else if (width == 4)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
+ else if (width == 8)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
+ else
+ return MMC_BOOT_E_INVAL;
+
+ writel(mmc_reg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ debug("Setting bus width to %d\n", width);
+ return MMC_BOOT_E_SUCCESS;
+}
+
+void mmc_boot_set_ios(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ int mmc_slot = priv->instance;
+
+ /* clock frequency should be less than 400KHz in identification mode */
+ clock_config_mmc(mmc_slot, mmc->clock);
+ /*
+ * give atleast 2 MCLK cycles delay for clocks
+ * and SDCC core to stabilize.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(5);
+ mmc_ret = mmc_boot_set_bus_width(mmc->bus_width, mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS)
+ printf("Set bus width error %d\n", mmc_ret);
+}
+
+/*
+ * Board specific initializations
+ */
+unsigned int mmc_boot_main(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* Initialize necessary data structure and enable/set clock and power */
+ debug(" Initializing MMC host data structure and clock!\n");
+ mmc_ret = mmc_boot_init(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("MMC Boot: Error Initializing MMC Card!!!\n");
+ return MMC_BOOT_E_FAILURE;
+ }
+
+ return MMC_BOOT_E_SUCCESS;
+}
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Andy Fleming
2012-05-03 22:05:18 UTC
Permalink
NAK, allow me to explain below:

On Mon, Mar 5, 2012 at 8:40 AM, Mohamed Haneef
<mohamed.haneef at lntinfotech.com> wrote:
> ? ? ? ?* Support for qc_mmc MMC Controller
>
> Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
> ---
> +#ifndef __MMC_H__
> +#define __MMC_H__
> +
> +#ifndef MMC_SLOT
> +#define MMC_SLOT ? ? ? ? ? ?0
> +#endif


This sort of thing should probably be passed in by the board code.




> +
> +#if 0
> +#define MSM_SDC1_BASE ? ? ? 0x12400000
> +#define MSM_SDC2_BASE ? ? ? 0x12140000
> +#define MSM_SDC3_BASE ? ? ? 0x12180000
> +#define MSM_SDC4_BASE ? ? ? 0x121C0000
> +#endif


Why's this still here?



> diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
> new file mode 100644
> index 0000000..7b7a1ed
> --- /dev/null
> +++ b/drivers/mmc/qc_mmc.c
> @@ -0,0 +1,584 @@

> +#if MMC_BOOT_ADM
> +#include "adm.h"
> +#endif
> +
> +#ifndef NULL
> +#define NULL ? ? ? ?0
> +#endif


?? Is NULL ever undefined in C?


> +
> +#define MMC_BOOT_DATA_READ ? ? 0
> +#define MMC_BOOT_DATA_WRITE ? ?1
> +/*
> + * Calculates the address of registers according to the base address
> + */
> +unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
> +{
> + ? ? ? return base + offset;
> +}
> +
> +
> +/*
> + * Sets a timeout for read operation.
> + */
> +static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
> +{
> + ? ? ? if (mmc == NULL)
> + ? ? ? ? ? ? ? return MMC_BOOT_E_INVAL;
> +
> + ? ? ? /* todo: Add a check for HC, only if HC do this.
> + ? ? ? ?* If not, taac and nsac must be taken into account
> + ? ? ? ?*/
> + ? ? ? ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
> + ? ? ? debug(" Read timeout set: %d ns\n",
> + ? ? ? ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);


I think it's preferable to do:

struct mmc_priv *priv = mmc->priv;

priv->rd_timeout_ns = 100000000;


> +
> + ? ? ? return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Check to ensure that there is no alignment or data length errors
> + */
> +static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
> +{
> +
> + ? ? ? if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
> + ? ? ? ? ? ? ? return MMC_BOOT_E_BLOCKLEN_ERR;
> +
> + ? ? ? /* Misaligned address not matching block length */
> + ? ? ? if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
> + ? ? ? ? ? ? ? return MMC_BOOT_E_ADDRESS_ERR;
> +
> + ? ? ? return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Decode type of error caused during read and write
> + */
> +static unsigned int mmc_boot_status_error(unsigned mmc_status)
> +{
> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + ? ? ? ? ? ? ? /* If DATA_CRC_FAIL bit is set to 1 then CRC error
> + ? ? ? ? ? ? ? ?* was detected by card/device during the data transfer
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
> + ? ? ? ? ? ? ? /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
> + ? ? ? ? ? ? ? ?* exceeded the data timeout period without completing the
> + ? ? ? ? ? ? ? ?* transfer
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
> + ? ? ? ? ? ? ? /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
> + ? ? ? ? ? ? ? ?* receive data from the card before empty storage for new
> + ? ? ? ? ? ? ? ?* received data was available.
> + ? ? ? ? ? ? ? ?* Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
> + ? ? ? ? ? ? ? ?* the data xfer.
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
> + ? ? ? ? ? ? ? /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> + ? ? ? ? ? ? ? ?* so no need to verify for now
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> + ? ? ? ? ? ? ? /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
> + ? ? ? ? ? ? ? ?* data to the card before new data for sending was available.
> + ? ? ? ? ? ? ? ?* Verify that bit FLOW_ENA in MCI_CLK
> + ? ? ? ? ? ? ? ?* is set to 1 during the data xfer.
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
> + ? ? ? ? ? ? ? /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> + ? ? ? ? ? ? ? ?* so skipping it now
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> +
> + ? ? ? return mmc_ret;
> +}
> +
> +/*
> + * Read data to SDC FIFO.
> + */
> +static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned int ?data_len,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct mmc *mmc)
> +{


Why is mmc_ptr an unsigned int *?


> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> + ? ? ? unsigned int mmc_status = 0;
> + ? ? ? unsigned int mmc_count = 0;
> + ? ? ? unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MMC_BOOT_MCI_STAT_DATA_TIMEOUT ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MMC_BOOT_MCI_STAT_RX_OVRRUN;
> + ? ? ? unsigned int i;
> + ? ? ? struct mmc_priv *priv = (struct mmc_priv ?*)mmc->priv;


Unnecessary cast


> + ? ? ? unsigned long reg_status, reg_fifo;
> +
> + ? ? ? reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
> + ? ? ? reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
> +
> + ? ? ? /* Read the data from the MCI_FIFO register as long as
> + ? ? ? ?* RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
> + ? ? ? ?* DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
> + ? ? ? ?* register are cleared to 0.
> + ? ? ? ?* Continue the reads until the whole transfer data is received
> + ? ? ? ?*/
> +
> + ? ? ? do {
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_SUCCESS;
> + ? ? ? ? ? ? ? mmc_status = readl(reg_status);
> +
> + ? ? ? ? ? ? ? if (mmc_status & read_error) {
> + ? ? ? ? ? ? ? ? ? ? ? mmc_ret = mmc_boot_status_error(mmc_status);
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
> + ? ? ? ? ? ? ? ? ? ? ? unsigned read_count = 1;
> + ? ? ? ? ? ? ? ? ? ? ? if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? read_count = MMC_BOOT_MCI_HFIFO_COUNT;
> +
> + ? ? ? ? ? ? ? ? ? ? ? for (i = 0; i < read_count; i++) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* FIFO contains 16 32-bit data buffer
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * on 16 sequential addresses
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *mmc_ptr = readl(reg_fifo +
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc_ptr++;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* increase mmc_count by word size */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc_count += sizeof(unsigned int);


I don't remember if readl is explicitly sized, but it seems like there
are some implicit and explicit size dependencies, and they aren't
currently guaranteed to line up. If you're going to do this, I think
mmc_ptr should be u32*. And you should update mmc_count by
sizeof(*mmc_ptr) to lock in the connection between the increase in
mmc_count and the amount of data read.

Out of curiosity, I notice that you will read from the start of the
FIFO each time this function is called. Is there something that resets
the FIFO to put the oldest data at the first address? Or is this only
called once?


> +static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
> + ? ? ? ? ? ? ? ? ? ? ? struct mmc_data *data)
> +{
> + ? ? ? uint32_t data_ctrl, mmc_reg, data_len;
> + ? ? ? struct mmc_priv *priv = (struct mmc_priv ?*)mmc->priv;


Unnecessary cast


> + ? ? ? unsigned long reg;
> +
> + ? ? ? /* Write data timeout period to MCI_DATA_TIMER register. */
> + ? ? ? /* Data timeout period should be in card bus clock periods */
> + ? ? ? mmc_reg = (unsigned long)(((struct mmc_priv *)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (mmc->priv))->rd_timeout_ns /
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1000000) * (mmc->clock / 1000);


You've got priv already, why access it via complicated cast?


> + ? ? ? /* add some extra clock cycles to be safe */
> + ? ? ? mmc_reg += 1000;
> + ? ? ? mmc_reg = mmc_reg/2;


I'd prefer that the variables have names that indicate their purpose
(e.g. - mmc_timeout). It took me a few times looking at this to
realize you were updating a variable that will be written to a reg,
rather than a pointer to your mmc register space.

Also, I'm assuming that the register defines the timeout field so that
you need ns/2, but you might want to document that as why you divide
by 2.


> +
> + ? ? ? reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
> + ? ? ? writel(mmc_reg, reg);


If you're going to repeat a sequence like this, frequently, it might
be better to create a qc_mmc_write() function which takes priv, reg,
and value as arguments:

qc_mmc_write(priv, MMC_BOOT_MCI_DATA_TIMER, mmc_reg);

BTW, are all of these prefixed with MMC_BOOT because this is only used
at boot time? Seems limiting. And it makes the constant names very
long.

> +
> + ? ? ? /* Write the total size of the transfer data to MCI_DATA_LENGTH
> + ? ? ? ?* register. For block xfer it must be multiple of the block
> + ? ? ? ?* size.
> + ? ? ? ?*/
> +
> + ? ? ? data_len = data->blocks*data->blocksize;
> + ? ? ? reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
> + ? ? ? writel(data_len, reg);
> +
> + ? ? ? /* Writes to MCI port are not effective for 3 ticks of PCLK.
> + ? ? ? ?* ticks calculated using 400KHz clock speed
> + ? ? ? ?*/
> + ? ? ? udelay(8);
> +
> + ? ? ? data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
> + ? ? ? ? ? ? ? (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
> +
> +
> + ? ? ? if (data->flags == MMC_DATA_READ)
> + ? ? ? ? ? ? ? data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
> +
> + ? ? ? reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
> + ? ? ? writel(data_ctrl, reg);
> +
> + ? ? ? /* Writes to MCI port are not effective for 3 ticks of PCLK.
> + ? ? ? ?* ticks calculated using 400KHz clock speed
> + ? ? ? ?*/
> + ? ? ? udelay(8);
> +
> +}
> +
> +/*
> + * Function to map mmc send command to board send command
> + */


This sounds...odd.


> +int mmc_boot_send_command_map(struct mmc *mmc,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct mmc_cmd *cmd,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct mmc_data *data)
> +{
> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + ? ? ? /* ?todo: do we need to fill in command type ?? */
> +
> + ? ? ? if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
> + ? ? ? ? ? ? ? /* u-boot doesn't fill in the correct argument value */
> + ? ? ? ? ? ? ? cmd->cmdarg = ?mmc->rca << 16;


I'm not sure what this means. But if you think U-Boot should be
filling in a different value, we should change it in mmc.c, not
one-at-a-time in each driver...


> + ? ? ? ? ? ? ? /* this is to explicitly disable the prg enabled flag */
> + ? ? ? ? ? ? ? cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;


1) I'm not sure this field is ever used for anything
2) You shouldn't define your own constants for inspecting/setting data
in fields that haven't been explicitly set aside for driver-specific
implementation. While it doesn't look like any of the mmc code ever
sets this field, it could one day, and break your driver.


> +
> + ? ? ? } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
> + ? ? ? ? ? ? ? if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc->version & SD_VERSION_SD) {
> + ? ? ? ? ? ? ? ? ? ? ? mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? ? ? ? ? data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? }
> + ? ? ? } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
> + ? ? ? ? ? ? ? ? ? ? ? if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc->version & SD_VERSION_SD) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
> + ? ? ? ? ? ? ? ? ? ? ? /* explicitly disable the prg enabled flag */
> + ? ? ? ? ? ? ? ? ? ? ? cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
> + ? ? ? ? ? ? ? ? ? ? ? /* set the XFER mode */
> + ? ? ? ? ? ? ? ? ? ? ? cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
> + ? ? ? }
> +
> +
> + ? ? ? /* For Data cmd's */


nit: no apostrophe needed



> +/*
> + * Initialize host structure, set and enable clock-rate and power mode.
> + */
> +unsigned int mmc_boot_init(struct mmc *mmc)
> +{
> + ? ? ? unsigned int mmc_pwr = 0;
> + ? ? ? struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;


No cast


> + ? ? ? int mmc_slot = priv->instance;


Whenever a driver has to be told which instance it is, a kitten
dies.... Ok, after reading through I see that it's only used to set
clocking. That's probably fine. More on this later.



> +/*
> + * Board specific initializations
> + */
> +unsigned int mmc_boot_main(struct mmc *mmc)
> +{
> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + ? ? ? /* Initialize necessary data structure and enable/set clock and power */
> + ? ? ? debug(" Initializing MMC host data structure and clock!\n");
> + ? ? ? mmc_ret = mmc_boot_init(mmc);
> + ? ? ? if (mmc_ret != MMC_BOOT_E_SUCCESS) {
> + ? ? ? ? ? ? ? printf("MMC Boot: Error Initializing MMC Card!!!\n");
> + ? ? ? ? ? ? ? return MMC_BOOT_E_FAILURE;
> + ? ? ? }
> +
> + ? ? ? return MMC_BOOT_E_SUCCESS;
> +}


Why not put the actual initialization function here? We usually want
to contain the driver information, here. It looks like you have two
different initialization paths, but there should be some way to codify
that so that future readers/writers can understand which parts of the
driver are being used under a given set of conditions. As it currently
stands, they will have to investigate the board file to figure it out.
Use the board init function to pass in parameters the driver can use
to make those choices. For instance, the


>
> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and ?using or disseminating the information, ?and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"


These sorts of disclaimers really serve to irritate open source
developers. Also, it puts me in the legal void, as you neglected to CC
me, which means I might be an unintended recipient. In defiance of
your disclaimer, I decided to take action, anyway. Feel free to sue
me. :P

Andy
Mohamed Haneef
2012-05-10 11:37:14 UTC
Permalink
Hi,



NAK, allow me to explain below:

On Mon, Mar 5, 2012 at 8:40 AM, Mohamed Haneef
<mohamed.haneef at lntinfotech.com> wrote:
> * Support for qc_mmc MMC Controller
>
> Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
> ---
> +#ifndef __MMC_H__
> +#define __MMC_H__
> +
> +#ifndef MMC_SLOT
> +#define MMC_SLOT 0
> +#endif


This sort of thing should probably be passed in by the board code.

it is removed.


> +
> +#if 0
> +#define MSM_SDC1_BASE 0x12400000
> +#define MSM_SDC2_BASE 0x12140000
> +#define MSM_SDC3_BASE 0x12180000
> +#define MSM_SDC4_BASE 0x121C0000
> +#endif


Why's this still here?

this got removed as well


> diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
> new file mode 100644
> index 0000000..7b7a1ed
> --- /dev/null
> +++ b/drivers/mmc/qc_mmc.c
> @@ -0,0 +1,584 @@

> +#if MMC_BOOT_ADM
> +#include "adm.h"
> +#endif
> +
> +#ifndef NULL
> +#define NULL 0
> +#endif


?? Is NULL ever undefined in C?



> +
> +#define MMC_BOOT_DATA_READ 0
> +#define MMC_BOOT_DATA_WRITE 1
> +/*
> + * Calculates the address of registers according to the base address
> + */
> +unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
> +{
> + return base + offset;
> +}
> +
> +
> +/*
> + * Sets a timeout for read operation.
> + */
> +static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
> +{
> + if (mmc == NULL)
> + return MMC_BOOT_E_INVAL;
> +
> + /* todo: Add a check for HC, only if HC do this.
> + * If not, taac and nsac must be taken into account
> + */
> + ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
> + debug(" Read timeout set: %d ns\n",
> + ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);


I think it's preferable to do:

struct mmc_priv *priv = mmc->priv;

priv->rd_timeout_ns = 100000000;


> +
> + return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Check to ensure that there is no alignment or data length errors
> + */
> +static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
> +{
> +
> + if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
> + return MMC_BOOT_E_BLOCKLEN_ERR;
> +
> + /* Misaligned address not matching block length */
> + if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
> + return MMC_BOOT_E_ADDRESS_ERR;
> +
> + return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Decode type of error caused during read and write
> + */
> +static unsigned int mmc_boot_status_error(unsigned mmc_status)
> +{
> + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + /* If DATA_CRC_FAIL bit is set to 1 then CRC error
> + * was detected by card/device during the data transfer
> + */
> + if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
> + mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
> + /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
> + * exceeded the data timeout period without completing the
> + * transfer
> + */
> + else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
> + mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
> + /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
> + * receive data from the card before empty storage for new
> + * received data was available.
> + * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
> + * the data xfer.
> + */
> + else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
> + /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> + * so no need to verify for now
> + */
> + mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> + /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
> + * data to the card before new data for sending was available.
> + * Verify that bit FLOW_ENA in MCI_CLK
> + * is set to 1 during the data xfer.
> + */
> + else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
> + /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> + * so skipping it now
> + */
> + mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> +
> + return mmc_ret;
> +}
> +
> +/*
> + * Read data to SDC FIFO.
> + */
> +static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
> + unsigned int data_len,
> + struct mmc *mmc)
> +{


Why is mmc_ptr an unsigned int *?


> + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> + unsigned int mmc_status = 0;
> + unsigned int mmc_count = 0;
> + unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
> + MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \
> + MMC_BOOT_MCI_STAT_RX_OVRRUN;
> + unsigned int i;
> + struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;


Unnecessary cast


> + unsigned long reg_status, reg_fifo;
> +
> + reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
> + reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
> +
> + /* Read the data from the MCI_FIFO register as long as
> + * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
> + * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
> + * register are cleared to 0.
> + * Continue the reads until the whole transfer data is received
> + */
> +
> + do {
> + mmc_ret = MMC_BOOT_E_SUCCESS;
> + mmc_status = readl(reg_status);
> +
> + if (mmc_status & read_error) {
> + mmc_ret = mmc_boot_status_error(mmc_status);
> + break;
> + }
> +
> + if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
> + unsigned read_count = 1;
> + if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
> + read_count = MMC_BOOT_MCI_HFIFO_COUNT;
> +
> + for (i = 0; i < read_count; i++) {
> + /* FIFO contains 16 32-bit data buffer
> + * on 16 sequential addresses
> + */
> + *mmc_ptr = readl(reg_fifo +
> + (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
> + mmc_ptr++;
> + /* increase mmc_count by word size */
> + mmc_count += sizeof(unsigned int);


I don't remember if readl is explicitly sized, but it seems like there
are some implicit and explicit size dependencies, and they aren't
currently guaranteed to line up. If you're going to do this, I think
mmc_ptr should be u32*. And you should update mmc_count by
sizeof(*mmc_ptr) to lock in the connection between the increase in
mmc_count and the amount of data read.

Out of curiosity, I notice that you will read from the start of the
FIFO each time this function is called. Is there something that resets
the FIFO to put the oldest data at the first address? Or is this only
called once?


> +static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
> + struct mmc_data *data)
> +{
> + uint32_t data_ctrl, mmc_reg, data_len;
> + struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;


Unnecessary cast


> + unsigned long reg;
> +
> + /* Write data timeout period to MCI_DATA_TIMER register. */
> + /* Data timeout period should be in card bus clock periods */
> + mmc_reg = (unsigned long)(((struct mmc_priv *)
> + (mmc->priv))->rd_timeout_ns /
> + 1000000) * (mmc->clock / 1000);


You've got priv already, why access it via complicated cast?


> + /* add some extra clock cycles to be safe */
> + mmc_reg += 1000;
> + mmc_reg = mmc_reg/2;


I'd prefer that the variables have names that indicate their purpose
(e.g. - mmc_timeout). It took me a few times looking at this to
realize you were updating a variable that will be written to a reg,
rather than a pointer to your mmc register space.

Also, I'm assuming that the register defines the timeout field so that
you need ns/2, but you might want to document that as why you divide
by 2.


> +
> + reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
> + writel(mmc_reg, reg);


If you're going to repeat a sequence like this, frequently, it might
be better to create a qc_mmc_write() function which takes priv, reg,
and value as arguments:

qc_mmc_write(priv, MMC_BOOT_MCI_DATA_TIMER, mmc_reg);

BTW, are all of these prefixed with MMC_BOOT because this is only used
at boot time? Seems limiting. And it makes the constant names very
long.

> +
> + /* Write the total size of the transfer data to MCI_DATA_LENGTH
> + * register. For block xfer it must be multiple of the block
> + * size.
> + */
> +
> + data_len = data->blocks*data->blocksize;
> + reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
> + writel(data_len, reg);
> +
> + /* Writes to MCI port are not effective for 3 ticks of PCLK.
> + * ticks calculated using 400KHz clock speed
> + */
> + udelay(8);
> +
> + data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
> + (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
> +
> +
> + if (data->flags == MMC_DATA_READ)
> + data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
> +
> + reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
> + writel(data_ctrl, reg);
> +
> + /* Writes to MCI port are not effective for 3 ticks of PCLK.
> + * ticks calculated using 400KHz clock speed
> + */
> + udelay(8);
> +
> +}
> +
> +/*
> + * Function to map mmc send command to board send command
> + */


This sounds...odd.


> +int mmc_boot_send_command_map(struct mmc *mmc,
> + struct mmc_cmd *cmd,
> + struct mmc_data *data)
> +{
> + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + /* todo: do we need to fill in command type ?? */
> +
> + if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
> + /* u-boot doesn't fill in the correct argument value */
> + cmd->cmdarg = mmc->rca << 16;


I'm not sure what this means. But if you think U-Boot should be
filling in a different value, we should change it in mmc.c, not
one-at-a-time in each driver...


> + /* this is to explicitly disable the prg enabled flag */
> + cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;


1) I'm not sure this field is ever used for anything
2) You shouldn't define your own constants for inspecting/setting data
in fields that haven't been explicitly set aside for driver-specific
implementation. While it doesn't look like any of the mmc code ever
sets this field, it could one day, and break your driver.


> +
> + } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
> + if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> + mmc->version & SD_VERSION_SD) {
> + mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> + data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> + }
> + } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
> + if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> + mmc->version & SD_VERSION_SD) {
> + mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> + data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> + }
> + } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
> + /* explicitly disable the prg enabled flag */
> + cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
> + /* set the XFER mode */
> + cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
> + }
> +
> +
> + /* For Data cmd's */


nit: no apostrophe needed



> +/*
> + * Initialize host structure, set and enable clock-rate and power mode.
> + */
> +unsigned int mmc_boot_init(struct mmc *mmc)
> +{
> + unsigned int mmc_pwr = 0;
> + struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;


No cast


> + int mmc_slot = priv->instance;


Whenever a driver has to be told which instance it is, a kitten
dies.... Ok, after reading through I see that it's only used to set
clocking. That's probably fine. More on this later.



> +/*
> + * Board specific initializations
> + */
> +unsigned int mmc_boot_main(struct mmc *mmc)
> +{
> + unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + /* Initialize necessary data structure and enable/set clock and power */
> + debug(" Initializing MMC host data structure and clock!\n");
> + mmc_ret = mmc_boot_init(mmc);
> + if (mmc_ret != MMC_BOOT_E_SUCCESS) {
> + printf("MMC Boot: Error Initializing MMC Card!!!\n");
> + return MMC_BOOT_E_FAILURE;
> + }
> +
> + return MMC_BOOT_E_SUCCESS;
> +}


Why not put the actual initialization function here? We usually want
to contain the driver information, here. It looks like you have two
different initialization paths, but there should be some way to codify
that so that future readers/writers can understand which parts of the
driver are being used under a given set of conditions. As it currently
stands, they will have to investigate the board file to figure it out.
Use the board init function to pass in parameters the driver can use
to make those choices. For instance, the


>
> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"


These sorts of disclaimers really serve to irritate open source
developers. Also, it puts me in the legal void, as you neglected to CC
me, which means I might be an unintended recipient. In defiance of
your disclaimer, I decided to take action, anyway. Feel free to sue
me. :P
mohamed.haneef
2012-02-16 02:59:18 UTC
Permalink
From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>

This is a patch series for msm7630 board. The Patches contain the following support
* low speed uart for msm7630
* interprocessor communication
* msm7630 soc
* msm7630 surf board


Mohamed Haneef (5):
msm7x30: Add support for low speed uart on msm7x30
msm7x30: Add support for interprocessor communication
msm7x30: Add support for Qualcomm msm7630 soc
Add support for mmc read and writes
msm7x30: Add support for msm7630_surf board

arch/arm/cpu/armv7/msm7630/Makefile | 59 +++
arch/arm/cpu/armv7/msm7630/acpuclock.c | 328 +++++++++++++
arch/arm/cpu/armv7/msm7630/board.c | 58 +++
arch/arm/cpu/armv7/msm7630/config.mk | 1 +
arch/arm/cpu/armv7/msm7630/gpio.c | 229 +++++++++
arch/arm/cpu/armv7/msm7630/lowlevel_init.S | 626 +++++++++++++++++++++++++
arch/arm/cpu/armv7/msm7630/timer.c | 148 ++++++
arch/arm/include/asm/arch-msm7630/adm.h | 28 ++
arch/arm/include/asm/arch-msm7630/gpio.h | 47 ++
arch/arm/include/asm/arch-msm7630/gpio_hw.h | 168 +++++++
arch/arm/include/asm/arch-msm7630/iomap.h | 96 ++++
arch/arm/include/asm/arch-msm7630/mmc.h | 399 ++++++++++++++++
arch/arm/include/asm/arch-msm7630/proc_comm.h | 42 ++
arch/arm/include/asm/arch-msm7630/sys_proto.h | 29 ++
board/qcom/msm7630_surf/Makefile | 55 +++
board/qcom/msm7630_surf/msm7630_surf.c | 155 ++++++
board/qcom/msm7630_surf/msm7630_surf.h | 30 ++
boards.cfg | 1 +
drivers/misc/Makefile | 1 +
drivers/misc/msm_proc_comm.c | 303 ++++++++++++
drivers/mmc/Makefile | 1 +
drivers/mmc/qc_mmc.c | 584 +++++++++++++++++++++++
drivers/serial/Makefile | 1 +
drivers/serial/serial_msm_uart.c | 206 ++++++++
include/configs/msm7630_surf.h | 131 +++++
25 files changed, 3726 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h
create mode 100644 board/qcom/msm7630_surf/Makefile
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.c
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.h
create mode 100644 drivers/misc/msm_proc_comm.c
create mode 100644 drivers/mmc/qc_mmc.c
create mode 100644 drivers/serial/serial_msm_uart.c
create mode 100644 include/configs/msm7630_surf.h


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Mohamed Haneef
2012-02-23 08:59:10 UTC
Permalink
This is a humbel reminder for verification of patch series for msm7630 board. The Patches contain the following support
* low speed uart for msm7630
* interprocessor communication
* msm7630 soc
* msm7630 surf board


Mohamed Haneef (5):
msm7x30: Add support for low speed uart on msm7x30
msm7x30: Add support for interprocessor communication
msm7x30: Add support for Qualcomm msm7630 soc
Add support for mmc read and writes
msm7x30: Add support for msm7630_surf board

arch/arm/cpu/armv7/msm7630/Makefile | 59 +++
arch/arm/cpu/armv7/msm7630/acpuclock.c | 328 +++++++++++++
arch/arm/cpu/armv7/msm7630/board.c | 58 +++
arch/arm/cpu/armv7/msm7630/config.mk | 1 +
arch/arm/cpu/armv7/msm7630/gpio.c | 229 +++++++++
arch/arm/cpu/armv7/msm7630/lowlevel_init.S | 626 +++++++++++++++++++++++++
arch/arm/cpu/armv7/msm7630/timer.c | 148 ++++++
arch/arm/include/asm/arch-msm7630/adm.h | 28 ++
arch/arm/include/asm/arch-msm7630/gpio.h | 47 ++
arch/arm/include/asm/arch-msm7630/gpio_hw.h | 168 +++++++
arch/arm/include/asm/arch-msm7630/iomap.h | 96 ++++
arch/arm/include/asm/arch-msm7630/mmc.h | 399 ++++++++++++++++
arch/arm/include/asm/arch-msm7630/proc_comm.h | 42 ++
arch/arm/include/asm/arch-msm7630/sys_proto.h | 29 ++
board/qcom/msm7630_surf/Makefile | 55 +++
board/qcom/msm7630_surf/msm7630_surf.c | 155 ++++++
board/qcom/msm7630_surf/msm7630_surf.h | 30 ++
boards.cfg | 1 +
drivers/misc/Makefile | 1 +
drivers/misc/msm_proc_comm.c | 303 ++++++++++++
drivers/mmc/Makefile | 1 +
drivers/mmc/qc_mmc.c | 584 +++++++++++++++++++++++
drivers/serial/Makefile | 1 +
drivers/serial/serial_msm_uart.c | 206 ++++++++
include/configs/msm7630_surf.h | 131 +++++
25 files changed, 3726 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h
create mode 100644 board/qcom/msm7630_surf/Makefile
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.c
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.h
create mode 100644 drivers/misc/msm_proc_comm.c
create mode 100644 drivers/mmc/qc_mmc.c
create mode 100644 drivers/serial/serial_msm_uart.c
create mode 100644 include/configs/msm7630_surf.h


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Albert ARIBAUD
2012-10-26 21:15:59 UTC
Permalink
Hi mohamed.haneef at lntinfotech.com,

On Thu, 16 Feb 2012 08:29:18 +0530, <mohamed.haneef at lntinfotech.com>
wrote:

> From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
>
> This is a patch series for msm7630 board. The Patches contain the following support
> * low speed uart for msm7630
> * interprocessor communication
> * msm7630 soc
> * msm7630 surf board
>
>
> Mohamed Haneef (5):
> msm7x30: Add support for low speed uart on msm7x30
> msm7x30: Add support for interprocessor communication
> msm7x30: Add support for Qualcomm msm7630 soc
> Add support for mmc read and writes
> msm7x30: Add support for msm7630_surf board

There were successive versions of this patch series, and not all change
requests were answered -- notably patch 4/5 V2 was NAKed and a 3rd
version seemed to be expected. Is a new series in the works?

Amicalement,
--
Albert.
mohamed.haneef
2012-02-16 02:59:21 UTC
Permalink
From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>

*Support for Qualcomm msm7630 soc

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---
arch/arm/cpu/armv7/msm7630/Makefile | 59 +++
arch/arm/cpu/armv7/msm7630/acpuclock.c | 328 +++++++++++++
arch/arm/cpu/armv7/msm7630/board.c | 58 +++
arch/arm/cpu/armv7/msm7630/config.mk | 1 +
arch/arm/cpu/armv7/msm7630/gpio.c | 229 +++++++++
arch/arm/cpu/armv7/msm7630/lowlevel_init.S | 626 +++++++++++++++++++++++++
arch/arm/cpu/armv7/msm7630/timer.c | 148 ++++++
arch/arm/include/asm/arch-msm7630/adm.h | 28 ++
arch/arm/include/asm/arch-msm7630/gpio.h | 47 ++
arch/arm/include/asm/arch-msm7630/gpio_hw.h | 168 +++++++
arch/arm/include/asm/arch-msm7630/iomap.h | 96 ++++
arch/arm/include/asm/arch-msm7630/proc_comm.h | 42 ++
arch/arm/include/asm/arch-msm7630/sys_proto.h | 29 ++
13 files changed, 1859 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h

diff --git a/arch/arm/cpu/armv7/msm7630/Makefile b/arch/arm/cpu/armv7/msm7630/Makefile
new file mode 100644
index 0000000..d9dfade
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/Makefile
@@ -0,0 +1,59 @@
+#
+# (C) Copyright 2012
+# LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+#
+# (C) Copyright 2010,2011 Nvidia Corporation.
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+# The AVP is ARMv4T architecture so we must use special compiler
+# flags for any startup files it might use.
+#CFLAGS_arch/arm/cpu/armv7/tegra2/ap20.o += -march=armv4t
+#CFLAGS_arch/arm/cpu/armv7/tegra2/clock.o += -march=armv4t
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).o
+
+SOBJS-y := lowlevel_init.o
+COBJS-y := board.o
+COBJS-y += timer.o
+COBJS-y += acpuclock.o
+COBJS-y += gpio.o
+
+ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS-y))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/msm7630/acpuclock.c b/arch/arm/cpu/armv7/msm7630/acpuclock.c
new file mode 100644
index 0000000..035ce04
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/acpuclock.c
@@ -0,0 +1,328 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <common.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/proc_comm.h>
+#define ACPU_806MHZ 42
+#define ACPU_1024MHZ 53
+#define ACPU_1200MHZ 125
+#define ACPU_1400MHZ 73
+
+/* Macros to select PLL2 with divide by 1 */
+#define ACPU_SRC_SEL 3
+#define ACPU_SRC_DIV 0
+
+#define BIT(n) (1 << (n))
+#define VREG_CONFIG (BIT(7) | BIT(6))
+#define VREG_DATA (VREG_CONFIG | (VREF_SEL << 5))
+#define VREF_SEL 1 /* 0: 0.625V (50mV step), 1: 0.3125V (25mV step). */
+#define V_STEP (25 * (2 - VREF_SEL)) /* Minimum voltage step size. */
+#define MV(mv) ((mv) / (!((mv) % V_STEP)))
+/* mv = (750mV + (raw * 25mV)) * (2 - VREF_SEL) */
+#define VDD_RAW(mv) (((MV(mv) / V_STEP) - 30) | VREG_DATA)
+
+
+/* enum for SDC CLK IDs */
+enum {
+ SDC1_CLK = 19,
+ SDC1_PCLK = 20,
+ SDC2_CLK = 21,
+ SDC2_PCLK = 22,
+ SDC3_CLK = 23,
+ SDC3_PCLK = 24,
+ SDC4_CLK = 25,
+ SDC4_PCLK = 26
+};
+
+/* Zero'th entry is dummy */
+static uint8_t sdc_clk[] = {0, SDC1_CLK, SDC2_CLK, SDC3_CLK, SDC4_CLK};
+static uint8_t sdc_pclk[] = {0, SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK};
+
+void spm_init(void)
+{
+ writel(0x05, MSM_SAW_BASE + 0x10); /* MSM_SPM_REG_SAW_CFG */
+ writel(0x18, MSM_SAW_BASE + 0x14); /* MSM_SPM_REG_SAW_SPM_CTL */
+ writel(0x00006666, MSM_SAW_BASE + 0x18);
+ /* MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY */
+ writel(0xFF000666, MSM_SAW_BASE + 0x1C);
+ /* MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY */
+ writel(0x01, MSM_SAW_BASE + 0x24); /* MSM_SPM_REG_SAW_SLP_CLK_EN */
+ writel(0x03, MSM_SAW_BASE + 0x28);
+ /* MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN */
+ writel(0x00, MSM_SAW_BASE + 0x2C);
+ /* MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN */
+ writel(0x01, MSM_SAW_BASE + 0x30); /* MSM_SPM_REG_SAW_SLP_CLMP_EN */
+ writel(0x00, MSM_SAW_BASE + 0x34); /* MSM_SPM_REG_SAW_SLP_RST_EN */
+ writel(0x00, MSM_SAW_BASE + 0x38); /* MSM_SPM_REG_SAW_SPM_MPM_CFG */
+}
+
+/* Configures msmc2 voltage. vlevel is in mV */
+void msmc2_config(unsigned vlevel)
+{
+ unsigned val;
+ val = readl(MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+ val &= ~0xFF;
+ val |= VDD_RAW(vlevel);
+ writel(val, MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+ /* Wait for PMIC state to return to idle and for VDD to stabilize */
+ while (((readl(MSM_SAW_BASE + 0x0C) >> 20) & 0x3) != 0)
+ ;
+ udelay(160);
+}
+
+void enable_pll(unsigned num)
+{
+ unsigned reg_val;
+ reg_val = readl(PLL_ENA_REG);
+ reg_val |= (1 << num);
+ writel(reg_val, PLL_ENA_REG);
+ /* Wait until PLL is enabled */
+ while ((readl(PLL2_STATUS_BASE_REG) & (1 << 16)) == 0)
+ ;
+}
+
+void acpu_clock_init(void)
+{
+ unsigned clk, reg_clksel, reg_clkctl, src_sel;
+ /* Fixing msmc2 voltage */
+ spm_init();
+ clk = readl(PLL2_L_VAL_ADDR) & 0xFF;
+ if (clk == ACPU_806MHZ)
+ msmc2_config(1100);
+ else if (clk == ACPU_1024MHZ || clk == ACPU_1200MHZ)
+ msmc2_config(1200);
+ else if (clk == ACPU_1400MHZ)
+ msmc2_config(1250);
+ /* Enable pll 2 */
+ enable_pll(2);
+ reg_clksel = readl(SCSS_CLK_SEL);
+ /* CLK_SEL_SRC1NO */
+ src_sel = reg_clksel & 1;
+ /* Program clock source and divider. */
+ reg_clkctl = readl(SCSS_CLK_CTL);
+ reg_clkctl &= ~(0xFF << (8 * src_sel));
+ reg_clkctl |= ACPU_SRC_SEL << (4 + 8 * src_sel);
+ reg_clkctl |= ACPU_SRC_DIV << (0 + 8 * src_sel);
+ writel(reg_clkctl, SCSS_CLK_CTL);
+ /* Toggle clock source. */
+ reg_clksel ^= 1;
+ /* Program clock source selection. */
+ writel(reg_clksel, SCSS_CLK_SEL);
+}
+
+void hsusb_clock_init(void)
+{
+ int val = 0;
+ unsigned sh2_own_row2;
+ unsigned sh2_own_row2_hsusb_mask = (1 << 11);
+
+ sh2_own_row2 = readl(SH2_OWN_ROW2_BASE_REG);
+ if (sh2_own_row2 & sh2_own_row2_hsusb_mask) {
+ /* USB local clock control enabled */
+ /* Set value in MD register */
+ val = 0x5DF;
+ writel(val, SH2_USBH_MD_REG);
+ /* Set value in NS register */
+ val = 1 << 8;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ val = 1 << 11;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ val = 1 << 9;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ val = 1 << 13;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ /* Enable USBH_P_CLK */
+ val = 1 << 25;
+ val = val | readl(SH2_GLBL_CLK_ENA_SC);
+ writel(val, SH2_GLBL_CLK_ENA_SC);
+ } else
+ /* USB local clock control not enabled; use proc comm */
+ usb_clock_init();
+
+}
+
+void adm_enable_clock(void)
+{
+ unsigned int val = 0;
+
+ /* Enable ADM_CLK */
+ val = 1 << 5;
+ val = val | readl(SH2_GLBL_CLK_ENA_SC);
+ writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+void mdp_lcdc_clock_init(void)
+{
+ unsigned int val = 0;
+ unsigned sh2_own_apps2;
+ unsigned sh2_own_apps2_lcdc_mask = (1 << 3);
+
+ sh2_own_apps2 = readl(SH2_OWN_APPS2_BASE_REG);
+ if (sh2_own_apps2 & sh2_own_apps2_lcdc_mask) {
+ /* MDP local clock control enabled */
+ /* Select clock source and divider */
+ val = 0x29;
+ val = val | readl(SH2_MDP_NS_REG);
+ writel(val, SH2_MDP_NS_REG);
+
+ /* Enable MDP source clock(root) */
+ val = 1 << 11;
+ val = val | readl(SH2_MDP_NS_REG);
+ writel(val, SH2_MDP_NS_REG);
+
+ /* Enable graphics clock(branch) */
+ val = 1 << 9;
+ val = val | readl(SH2_MDP_NS_REG);
+ writel(val, SH2_MDP_NS_REG);
+
+ /* Enable MDP_P_CLK */
+ val = 1 << 6;
+ val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+ writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+ /* Enable AXI_MDP_CLK */
+ val = 1 << 29;
+ val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+ writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+ /* LCDC local clock control enabled */
+ /* Set value in MD register */
+ val = 0x1FFF9;
+ writel(val, SH2_MDP_LCDC_MD_REG);
+
+ /* Set MDP_LCDC_N_VAL in NS register */
+ val = 0xFFFA << 16;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Set clock source */
+ val = 1;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Set divider */
+ val = 3 << 3;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Set MN counter mode */
+ val = 2 << 5;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable MN counter */
+ val = 1 << 8;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable mdp_lcdc_src(root) clock */
+ val = 1 << 11;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable mdp_lcdc_pclk(branch) clock */
+ val = 1 << 9;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable mdp_lcdc_pad_pclk(branch) clock */
+ val = 1 << 12;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+ } else {
+ /* MDP local clock control not enabled; use proc comm */
+ mdp_clock_init(122880000);
+ /* LCDC local clock control not enabled; use proc comm */
+ lcdc_clock_init(27648000);
+ }
+}
+
+void mddi_pmdh_clock_init(void)
+{
+ unsigned int val = 0;
+ unsigned sh2_own_row1;
+ unsigned sh2_own_row1_pmdh_mask = (1 << 19);
+
+ sh2_own_row1 = readl(SH2_OWN_ROW1_BASE_REG);
+ if (sh2_own_row1 & sh2_own_row1_pmdh_mask) {
+ /* Select clock source and divider */
+ val = 1;
+ val |= (1 << 3);
+ val = val | readl(SH2_PMDH_NS_REG);
+ writel(val, SH2_PMDH_NS_REG);
+
+ /* Enable PMDH_SRC (root) signal */
+ val = 1 << 11;
+ val = val | readl(SH2_PMDH_NS_REG);
+ writel(val, SH2_PMDH_NS_REG);
+
+ /* Enable PMDH_P_CLK */
+ val = 1 << 4;
+ val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+ writel(val, SH2_GLBL_CLK_ENA_2_SC);
+ } else
+ /* MDDI local clock control not enabled; use proc comm */
+ mddi_clock_init(0, 480000000);
+}
+
+void ce_clock_init(void)
+{
+ unsigned int val = 0;
+
+ /* Enable CE_CLK */
+ val = 1 << 6;
+ val = val | readl(SH2_GLBL_CLK_ENA_SC);
+ writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+#ifdef CONFIG_QC_MMC
+/* Configure MMC clock */
+void clock_config_mmc(uint32_t interface, uint32_t freq)
+{
+ uint32_t reg = 0;
+
+ if (mmc_clock_set_rate(sdc_clk[interface], freq) < 0)
+ printf("Failure setting clock rate for MCLK - "
+ "clk_rate: %d\n!", freq);
+
+ /* enable clock */
+ if (mmc_clock_enable_disable(sdc_clk[interface], MMC_CLK_ENABLE) < 0)
+ printf("Failure enabling MMC Clock!\n");
+
+ reg |= MMC_BOOT_MCI_CLK_ENABLE;
+ reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
+ reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
+ writel(reg, MMC_BOOT_MCI_CLK);
+}
+
+/* Intialize MMC clock */
+void clock_init_mmc(uint32_t interface)
+{
+ if (mmc_clock_enable_disable(sdc_pclk[interface], MMC_CLK_ENABLE) < 0)
+ printf("Failure enabling PCLK!\n");
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/board.c b/arch/arm/cpu/armv7/msm7630/board.c
new file mode 100644
index 0000000..8dd61b4
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/board.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/sys_proto.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void set_vector_base(unsigned long addr)
+{
+ __asm__ volatile ("mcr p15, 0, %0, c12, c0, 0" : : "r" (addr));
+}
+
+int dram_init(void)
+{
+ /* We do not initialise DRAM here. We just query the size */
+ gd->ram_size = PHYS_SDRAM_1_SIZE;
+ /* Now check it dynamically */
+ return 0;
+}
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+
+}
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init()
+{
+ __cpu_early_init();
+ return 0;
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/config.mk b/arch/arm/cpu/armv7/msm7630/config.mk
new file mode 100644
index 0000000..935a147
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/config.mk
@@ -0,0 +1 @@
+PLATFORM_CPPFLAGS += -march=armv7-a
diff --git a/arch/arm/cpu/armv7/msm7630/gpio.c b/arch/arm/cpu/armv7/msm7630/gpio.c
new file mode 100644
index 0000000..daa6d66
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/gpio.c
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/proc_comm.h>
+#include <asm/arch/gpio_hw.h>
+
+struct gpioregs {
+ unsigned out;
+ unsigned in;
+ unsigned int_status;
+ unsigned int_clear;
+ unsigned int_en;
+ unsigned int_edge;
+ unsigned int_pos;
+ unsigned oe;
+};
+
+static struct gpioregs GPIO_REGS[] = {
+ {
+ .out = GPIO_OUT_0,
+ .in = GPIO_IN_0,
+ .int_status = GPIO_INT_STATUS_0,
+ .int_clear = GPIO_INT_CLEAR_0,
+ .int_en = GPIO_INT_EN_0,
+ .int_edge = GPIO_INT_EDGE_0,
+ .int_pos = GPIO_INT_POS_0,
+ .oe = GPIO_OE_0,
+ },
+ {
+ .out = GPIO_OUT_1,
+ .in = GPIO_IN_1,
+ .int_status = GPIO_INT_STATUS_1,
+ .int_clear = GPIO_INT_CLEAR_1,
+ .int_en = GPIO_INT_EN_1,
+ .int_edge = GPIO_INT_EDGE_1,
+ .int_pos = GPIO_INT_POS_1,
+ .oe = GPIO_OE_1,
+ },
+ {
+ .out = GPIO_OUT_2,
+ .in = GPIO_IN_2,
+ .int_status = GPIO_INT_STATUS_2,
+ .int_clear = GPIO_INT_CLEAR_2,
+ .int_en = GPIO_INT_EN_2,
+ .int_edge = GPIO_INT_EDGE_2,
+ .int_pos = GPIO_INT_POS_2,
+ .oe = GPIO_OE_2,
+ },
+ {
+ .out = GPIO_OUT_3,
+ .in = GPIO_IN_3,
+ .int_status = GPIO_INT_STATUS_3,
+ .int_clear = GPIO_INT_CLEAR_3,
+ .int_en = GPIO_INT_EN_3,
+ .int_edge = GPIO_INT_EDGE_3,
+ .int_pos = GPIO_INT_POS_3,
+ .oe = GPIO_OE_3,
+ },
+ {
+ .out = GPIO_OUT_4,
+ .in = GPIO_IN_4,
+ .int_status = GPIO_INT_STATUS_4,
+ .int_clear = GPIO_INT_CLEAR_4,
+ .int_en = GPIO_INT_EN_4,
+ .int_edge = GPIO_INT_EDGE_4,
+ .int_pos = GPIO_INT_POS_4,
+ .oe = GPIO_OE_4,
+ },
+ {
+ .out = GPIO_OUT_5,
+ .in = GPIO_IN_5,
+ .int_status = GPIO_INT_STATUS_5,
+ .int_clear = GPIO_INT_CLEAR_5,
+ .int_en = GPIO_INT_EN_5,
+ .int_edge = GPIO_INT_EDGE_5,
+ .int_pos = GPIO_INT_POS_5,
+ .oe = GPIO_OE_5,
+ },
+ {
+ .out = GPIO_OUT_6,
+ .in = GPIO_IN_6,
+ .int_status = GPIO_INT_STATUS_6,
+ .int_clear = GPIO_INT_CLEAR_6,
+ .int_en = GPIO_INT_EN_6,
+ .int_edge = GPIO_INT_EDGE_6,
+ .int_pos = GPIO_INT_POS_6,
+ .oe = GPIO_OE_6,
+ },
+ {
+ .out = GPIO_OUT_7,
+ .in = GPIO_IN_7,
+ .int_status = GPIO_INT_STATUS_7,
+ .int_clear = GPIO_INT_CLEAR_7,
+ .int_en = GPIO_INT_EN_7,
+ .int_edge = GPIO_INT_EDGE_7,
+ .int_pos = GPIO_INT_POS_7,
+ .oe = GPIO_OE_7,
+ },
+};
+
+static struct gpioregs *find_gpio(unsigned n, unsigned *bit)
+{
+ if (n > 150) {
+ *bit = 1 << (n - 151);
+ return GPIO_REGS + 7;
+ }
+ if (n > 133) {
+ *bit = 1 << (n - 134);
+ return GPIO_REGS + 6;
+ }
+ if (n > 106) {
+ *bit = 1 << (n - 107);
+ return GPIO_REGS + 5;
+ }
+ if (n > 94) {
+ *bit = 1 << (n - 95);
+ return GPIO_REGS + 4;
+ }
+ if (n > 67) {
+ *bit = 1 << (n - 68);
+ return GPIO_REGS + 3;
+ }
+ if (n > 43) {
+ *bit = 1 << (n - 44);
+ return GPIO_REGS + 2;
+ }
+ if (n > 15) {
+ *bit = 1 << (n - 16);
+ return GPIO_REGS + 1;
+ }
+ *bit = 1 << n;
+ return GPIO_REGS + 0;
+}
+
+int gpio_config(unsigned n, unsigned flags)
+{
+ struct gpioregs *r;
+ unsigned b;
+ unsigned v;
+
+ r = find_gpio(n, &b);
+ if (!r)
+ return -1;
+
+ v = readl(r->oe);
+ if (flags & GPIO_OUTPUT)
+ writel(v | b, r->oe);
+ else
+ writel(v & (~b), r->oe);
+ return 0;
+}
+
+void gpio_set(unsigned n, unsigned on)
+{
+ struct gpioregs *r;
+ unsigned b;
+ unsigned v;
+
+ r = find_gpio(n, &b);
+ if (r == 0)
+ return;
+
+ v = readl(r->out);
+ if (on)
+ writel(v | b, r->out);
+ else
+ writel(v & (~b), r->out);
+}
+
+int gpio_get(unsigned n)
+{
+ struct gpioregs *r;
+ unsigned b;
+
+ r = find_gpio(n, &b);
+ if (r == 0)
+ return 0;
+ return (readl(r->in) & b) ? 1 : 0;
+}
+
+void platform_config_interleaved_mode_gpios(void)
+{
+ /* configure EB2_CS1 through GPIO86 */
+ writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
+ writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
+ /* configure the EBI2_BUSY1_N through GPIO115 */
+ writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
+ writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
+}
+
+/* Enables all gpios passed in table*/
+int platform_gpios_enable(const struct msm_gpio *table, int size)
+{
+ int rc;
+ int i;
+ const struct msm_gpio *g;
+ for (i = 0; i < size; i++) {
+ g = table + i;
+ /* Enable gpio */
+ rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
+ if (rc)
+ goto err;
+ }
+ return 0;
+err:
+ return rc;
+}
+
diff --git a/arch/arm/cpu/armv7/msm7630/lowlevel_init.S b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
new file mode 100644
index 0000000..d8d5b46
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
@@ -0,0 +1,626 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+#include <version.h>
+
+.text
+.code 32
+
+#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
+#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
+
+/*
+ ; LVT Ring Osc counter
+ ; used to determine sense amp settings
+ ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11
+*/
+.equ CLK_CTL_BASE, 0xA8600000
+.equ A_GLBL_CLK_ENA, 0x0000
+.equ A_PRPH_WEB_NS_REG,0x0080
+.equ A_MSM_CLK_RINGOSC,0x00D0
+.equ A_TCXO_CNT, 0x00D4
+.equ A_TCXO_CNT_DONE, 0x00D8
+.equ A_RINGOSC_CNT, 0x00DC
+.equ A_MISC_CLK_CTL, 0x0108
+.equ CLK_TEST, 0xA8600114
+.equ SPSS_CSR_BASE, 0xAC100000
+.equ A_SCRINGOSC, 0x0510
+
+//;; Number of TCXO cycles to count ring oscillations
+.equ TCXO_CNT_VAL, 0x100
+
+//; Halcyon addresses
+.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register
+.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register
+
+//; SCORPION_L1_ACC (1:0) Fuses bit location
+.equ L1_ACC_BIT_0, 12 //;12th bit of TCSR_CONF_FUSE_4
+.equ L1_ACC_BIT_1, 13 //;13th bit of TCSR_CONF_FUSE_4
+//; SCORPION_L2_ACC (2:0) Fuses bit location
+.equ L2_ACC_BIT_0, 25 //;25th bit of TCSR_CONF_FUSE_1
+.equ L2_ACC_BIT_1, 10 //;10th bit of TCSR_CONF_FUSE_4
+.equ L2_ACC_BIT_2, 11 //;11th bit of TCSR_CONF_FUSE_4
+
+//; CP15: PVR2F0 values according to SCORPION_L1_ACC (1:0)
+.equ PVR2F0_00, 0x00000000
+.equ PVR2F0_01, 0x04000000
+.equ PVR2F0_10, 0x08000000
+.equ PVR2F0_11, 0x0C000000
+
+//; CP15: PVR2F1 values according to SCORPION_L1_ACC (1:0)
+.equ PVR2F1_00, 0x00000008
+.equ PVR2F1_01, 0x00000008
+.equ PVR2F1_10, 0x00000208
+.equ PVR2F1_11, 0x00000208
+
+//; CP15: PVR0F2 values according to SCORPION_L1_ACC (1:0)
+.equ PVR0F2_00, 0x00000000
+.equ PVR0F2_01, 0x00000000
+.equ PVR0F2_10, 0x00000200
+.equ PVR0F2_11, 0x00000200
+
+//; CP15: PVR0F0 values according to SCORPION_L1_ACC (1:0)
+.equ PVR0F0_00, 0x7F000000
+.equ PVR0F0_01, 0x7F000400
+.equ PVR0F0_10, 0x7F000000
+.equ PVR0F0_11, 0x7F000400
+
+//; CP15: L2VR3F1 values according to SCORPION_L2_ACC (2:0)
+.equ L2VR3F1_000, 0x00FFFF60
+.equ L2VR3F1_001, 0x00FFFF40
+.equ L2VR3F1_010, 0x00FFFC60
+.equ L2VR3F1_011, 0x00FFFC40
+.equ L2VR3F1_100, 0x00FCFF60
+.equ L2VR3F1_101, 0x00FCFF40
+.equ L2VR3F1_110, 0x00FCFC60
+.equ L2VR3F1_111, 0x00FCFC40
+
+
+
+
+_TEXT_BASE:
+ .word CONFIG_SYS_TEXT_BASE @ sdram load addr from config file
+
+.global invalidate_dcache
+invalidate_dcache:
+ mov pc, lr
+
+ .align 5
+.globl lowlevel_init
+lowlevel_init:
+ mov pc, lr @ back to arch calling code
+
+.global reset_cpu
+reset_cpu:
+_loop_forever:
+ b _loop_forever
+
+.globl SET_SA
+SET_SA:
+
+ //;--------------------------------------------------------------------
+ //; Fuse bits used to determine sense amp settings
+ //;--------------------------------------------------------------------
+
+ //; Reading L1_ACC
+ ldr r4, = 0x0
+
+ //; Read L1_ACC_BIT_0
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L1_ACC_BIT_0
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ orr r4, r3, r4
+
+ //; Read L1_ACC_BIT_1
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L1_ACC_BIT_1
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ mov r3, r3, LSL #1
+ orr r4, r3, r4
+
+l1_ck_0:
+ //; if L1_[1:0] == 00
+ ldr r5, = 0x0
+ cmp r4, r5
+ bne l1_ck_1
+ ldr r0, =PVR0F0_00
+ ldr r1, =PVR0F2_00
+ ldr r2, =PVR2F0_00
+ ldr r3, =PVR2F1_00
+ b WRITE_L1_SA_SETTINGS
+
+l1_ck_1:
+ //; if L1_[1:0] == 01
+ ldr r1, = 0x01
+ cmp r4, r1
+ bne l1_ck_2
+ ldr r0, =PVR0F0_01
+ ldr r1, =PVR0F2_01
+ ldr r2, =PVR2F0_01
+ ldr r3, =PVR2F1_01
+ b WRITE_L1_SA_SETTINGS
+
+l1_ck_2:
+ //; if L1_[2:0] == 10
+ ldr r1, = 0x02
+ cmp r4, r1
+ bne l1_ck_3
+ ldr r0, =PVR0F0_10
+ ldr r1, =PVR0F2_10
+ ldr r2, =PVR2F0_10
+ ldr r3, =PVR2F1_10
+ b WRITE_L1_SA_SETTINGS
+
+l1_ck_3:
+ //; if L1_[2:0] == 11
+ ldr r1, = 0x03
+ cmp r4, r1
+ ldr r0, =PVR0F0_11
+ ldr r1, =PVR0F2_11
+ ldr r2, =PVR2F0_11
+ ldr r3, =PVR2F1_11
+ b WRITE_L1_SA_SETTINGS
+
+
+WRITE_L1_SA_SETTINGS:
+
+ //;WCP15_PVR0F0 r0
+ mcr p15, 0x0, r0, c15, c15, 0x0 //; write R0 to PVR0F0
+
+ //;WCP15_PVR0F2 r1
+ mcr p15, 0x0, r1, c15, c15, 0x2 //; write R1 to PVR0F2
+
+ //;WCP15_PVR2F0 r2
+ mcr p15, 0x2, r2, c15, c15, 0x0 //; write R2 to PVR2F0
+
+ // Disable predecode repair cache on certain Scorpion revisions
+ // (Raptor V2 and earlier, or Halcyon V1)
+ mrc p15, 0, r1, c0, c0, 0 //; MIDR
+ BIC r2, r1, #0xf0 //; check for Halcyon V1
+ ldr r4, =0x511f0000
+ cmp r2, r4
+ bne PVR2F1
+
+DPRC:
+ mrc p15, 0, r1, c15, c15, 2 //; PVR0F2
+ orr r1, r1, #0x10 //; enable bit 4
+ mcr p15, 0, r1, c15, c15, 2 //; disable predecode repair cache
+
+PVR2F1:
+ //;WCP15_PVR2F1 r3
+ mcr p15, 0x2, r3, c15, c15, 0x1 //; write R3 to PVR2F1
+
+ //; Reading L2_ACC
+ ldr r4, = 0x0
+
+ //; Read L2_ACC_BIT_0
+ ldr r1, =TCSR_CONF_FUSE_1
+ ldr r2, =L2_ACC_BIT_0
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ orr r4, r3, r4
+
+ //; Read L2_ACC_BIT_1
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L2_ACC_BIT_1
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ mov r3, r3, LSL #1
+ orr r4, r3, r4
+
+ //; Read L2_ACC_BIT_2
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L2_ACC_BIT_2
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ mov r3, r3, LSL #2
+ orr r4, r3, r4
+
+l2_ck_0:
+ //; if L2_[2:0] == 000
+ ldr r5, = 0x0
+ cmp r4, r5
+ bne l2_ck_1
+ ldr r0, =L2VR3F1_000
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_1:
+ //; if L2_[2:0] == 001
+ ldr r5, = 0x1
+ cmp r4, r5
+ bne l2_ck_2
+ ldr r0, =L2VR3F1_001
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_2:
+ //; if L2_[2:0] == 010
+ ldr r5, = 0x2
+ cmp r4, r5
+ bne l2_ck_3
+ ldr r0, =L2VR3F1_010
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_3:
+ //; if L2_[2:0] == 011
+ ldr r5, = 0x3
+ cmp r4, r5
+ bne l2_ck_4
+ ldr r0, =L2VR3F1_011
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_4:
+ //; if L2_[2:0] == 100
+ ldr r5, = 0x4
+ cmp r4, r5
+ bne l2_ck_5
+ ldr r0, =L2VR3F1_100
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_5:
+ //; if L2_[2:0] == 101
+ ldr r5, = 0x5
+ cmp r4, r5
+ bne l2_ck_6
+ ldr r0, =L2VR3F1_101
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_6:
+ //; if L2_[2:0] == 110
+ ldr r5, = 0x6
+ cmp r4, r5
+ bne l2_ck_7
+ ldr r0, =L2VR3F1_110
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_7:
+ //; if L2_[2:0] == 111
+ ldr r5, = 0x7
+ cmp r4, r5
+ ldr r0, =L2VR3F1_111
+ b WRITE_L2_SA_SETTINGS
+
+WRITE_L2_SA_SETTINGS:
+ //;WCP15_L2VR3F1 r0
+ mcr p15, 0x3, r0, c15, c15, 0x1 //;write r0 to L2VR3F1
+ DSB
+ ISB
+
+ ldr r0, =0 //;make sure the registers we touched
+ ldr r1, =0 //;are cleared when we return
+ ldr r2, =0
+ ldr r3, =0
+ ldr r4, =0
+ ldr r5, =0
+
+ mrs r0, cpsr
+ orr r0, r0, #(1<<7)
+ msr cpsr_c, r0
+
+ //; routine complete
+ pop {r5-r12,pc}
+
+.ltorg
+
+.globl __cpu_early_init
+__cpu_early_init:
+
+ //; Zero out r0 for use throughout this code. All other GPRs
+ //; (r1-r3) are set throughout this code to help establish
+ //; a consistent startup state for any code that follows.
+ //; Users should add code at the end of this routine to establish
+ //; their own stack address (r13), add translation page tables, enable
+ //; the caches, etc.
+ push {r5-r12,r14}
+ mov r0, #0x0
+
+
+ //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA
+ //; API to dynamically configure cache for slow/nominal/fast parts
+
+ //; DCIALL to invalidate L2 cache bank (needs to be run 4 times,
+ //; once per bank)
+ //; This must be done early in code (prior to enabling the caches)
+ mov r1, #0x2
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank D ([15:14] == 2'b00)
+ orr r1, r1, #0x00004000
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank C ([15:14] == 2'b01)
+ add r1, r1, #0x00004000
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank B ([15:14] == 2'b10)
+ add r1, r1, #0x00004000
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank A ([15:14] == 2'b11)
+
+ //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's
+ //; and have all address bits (AM) participate.
+ //; Different settings can be used to improve performance
+ // movW r1, #0x01FF
+.word 0xe30011ff // hardcoded movW instruction due to lack of compiler support
+ // movT r1, #0x01FF
+.word 0xe34011ff // hardcoded movT instruction due to lack of compiler support
+ mcr p15, 7, r1, c15, c0, 2 //; WCP15_BPCR
+
+
+ //; Initialize all I$ Victim Registers to 0 for startup
+ mcr p15, 0, r0, c9, c1, 0 //; WCP15_ICVIC0 r0
+ mcr p15, 0, r0, c9, c1, 1 //; WCP15_ICVIC1 r0
+ mcr p15, 0, r0, c9, c1, 2 //; WCP15_ICVIC2 r0
+ mcr p15, 0, r0, c9, c1, 3 //; WCP15_ICVIC3 r0
+ mcr p15, 0, r0, c9, c1, 4 //; WCP15_ICVIC4 r0
+ mcr p15, 0, r0, c9, c1, 5 //; WCP15_ICVIC5 r0
+ mcr p15, 0, r0, c9, c1, 6 //; WCP15_ICVIC5 r0
+ mcr p15, 0, r0, c9, c1, 7 //; WCP15_ICVIC7 r0
+
+ //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0
+ mcr p15, 1, r0, c9, c1, 0 //; WCP15_ICFLOOR0 r0
+ mcr p15, 1, r0, c9, c1, 1 //; WCP15_ICFLOOR1 r0
+ mcr p15, 1, r0, c9, c1, 2 //; WCP15_ICFLOOR2 r0
+ mcr p15, 1, r0, c9, c1, 3 //; WCP15_ICFLOOR3 r0
+ mcr p15, 1, r0, c9, c1, 4 //; WCP15_ICFLOOR4 r0
+ mcr p15, 1, r0, c9, c1, 5 //; WCP15_ICFLOOR5 r0
+ mcr p15, 1, r0, c9, c1, 6 //; WCP15_ICFLOOR6 r0
+ mcr p15, 1, r0, c9, c1, 7 //; WCP15_ICFLOOR7 r0
+
+ //; Initialize all D$ Victim Registers to 0
+ mcr p15, 2, r0, c9, c1, 0 //; WP15_DCVIC0 r0
+ mcr p15, 2, r0, c9, c1, 1 //; WP15_DCVIC1 r0
+ mcr p15, 2, r0, c9, c1, 2 //; WP15_DCVIC2 r0
+ mcr p15, 2, r0, c9, c1, 3 //; WP15_DCVIC3 r0
+ mcr p15, 2, r0, c9, c1, 4 //; WP15_DCVIC4 r0
+ mcr p15, 2, r0, c9, c1, 5 //; WP15_DCVIC5 r0
+ mcr p15, 2, r0, c9, c1, 6 //; WP15_DCVIC6 r0
+ mcr p15, 2, r0, c9, c1, 7 //; WP15_DCVIC7 r0
+
+ //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0
+ mcr p15, 3, r0, c9, c1, 0 //; WCP15_DCFLOOR0 r0
+ mcr p15, 3, r0, c9, c1, 1 //; WCP15_DCFLOOR1 r0
+ mcr p15, 3, r0, c9, c1, 2 //; WCP15_DCFLOOR2 r0
+ mcr p15, 3, r0, c9, c1, 3 //; WCP15_DCFLOOR3 r0
+ mcr p15, 3, r0, c9, c1, 4 //; WCP15_DCFLOOR4 r0
+ mcr p15, 3, r0, c9, c1, 5 //; WCP15_DCFLOOR5 r0
+ mcr p15, 3, r0, c9, c1, 6 //; WCP15_DCFLOOR6 r0
+ mcr p15, 3, r0, c9, c1, 7 //; WCP15_DCFLOOR7 r0
+
+ //; Initialize ASID to zero
+ mcr p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0
+
+ //; ICIALL to invalidate entire I-Cache
+ mcr p15, 0, r0, c7, c5, 0 //; ICIALLU
+
+ //; DCIALL to invalidate entire D-Cache
+ mcr p15, 0, r0, c9, c0, 6 //; DCIALL r0
+
+ //; Initialize ADFSR to zero
+ mcr p15, 0, r0, c5, c1, 0 //; ADFSR r0
+
+ //; Initialize EFSR to zero
+ mcr p15, 7, r0, c15, c0, 1 //; EFSR r0
+
+ //; The VBAR (Vector Base Address Register) should be initialized
+ //; early in your code. We are setting it to zero
+ mcr p15, 0, r0, c12, c0, 0 //; WCP15_VBAR r0
+
+ //; Ensure the mcr's above have completed their operation
+ //; before continuing
+ DSB
+ ISB
+
+ //; Setup CCPR - Cache Coherency Policy Register
+ //; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing)
+ //; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable)
+ movw r2, #0x88
+ mcr p15, 0, r2, c10, c4, 2
+
+ //;-------------------------------------------------------------------
+ //; There are a number of registers that must be set prior to enabling
+ //; the MMU. The DCAR is one of these registers. We are setting
+ //; it to zero (no access) to easily detect improper setup in subsequent
+ //; code sequences
+ //;-------------------------------------------------------------------
+ //; Setup DACR (Domain Access Control Register) to zero
+ mcr p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0
+
+ //; Setup DCLKCR to allow normal D-Cache line fills
+ mcr p15, 1, r0, c9, c0, 7 //; WCP15_DCLKCR r0
+
+ //; Setup the TLBLKCR
+ //; Victim = 6'b000000; Floor = 6'b000000;
+ //; IASIDCFG =
+ //;2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0;
+ mov r1, #0x02
+ mcr p15, 0, r1, c10, c1, 3 //; WCP15_TLBLKCR r1
+
+ //;Make sure TLBLKCR is complete before continuing
+ ISB
+
+ //; Invalidate the UTLB
+ mcr p15, 0, r0, c8, c7, 0 //; UTLBIALL
+
+ //; Make sure UTLB request has been presented to macro before continuing
+ ISB
+
+SYSI2:
+ //; setup L2CR1 to some default Instruction and data prefetching values
+ //; Users may want specific settings for various performance
+ //; enhancements
+ //; In Halcyon we do not have broadcasting barriers. So we need to turn
+ // ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast )
+ ldr r2, =0x133
+ mcr p15, 3, r2, c15, c0, 3 //; WCP15_L2CR1 r0
+
+
+ //; Enable Z bit to enable branch prediction (default is off)
+ mrc p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2
+ orr r2, r2, #0x00000800
+ mcr p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2
+
+ //; Make sure Link stack is initialized with branch and links to
+ //; sequential addresses
+ //; This aids in creating a predictable startup environment
+ bl SEQ1
+SEQ1: bl SEQ2
+SEQ2: bl SEQ3
+SEQ3: bl SEQ4
+SEQ4: bl SEQ5
+SEQ5: bl SEQ6
+SEQ6: bl SEQ7
+SEQ7: bl SEQ8
+SEQ8:
+
+ //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA
+ //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the
+ //;debug registers
+ //; Writing anything but the "secret code" to the DBGOSLAR clears the
+ //;DBGOSLSR[LOCK] bit
+ mcr p14, 0, r0, c1, c0, 4 //; WCP14_DBGOSLAR r0
+
+
+ //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD]
+ //; Any read to DBGPRSR clear the STICKYPD bit
+ //; ISB guarantees the read completes before attempting to
+ //; execute a CP14 instruction.
+ mrc p14, 0, r3, c1, c5, 4 //; RCP14_DBGPRSR r3
+ ISB
+
+ //; Initialize the Watchpoint Control Registers to zero (optional)
+ //;;; mcr p14, 0, r0, c0, c0, 7 ; WCP14_DBGWCR0 r0
+ //;;; mcr p14, 0, r0, c0, c1, 7 ; WCP14_DBGWCR1 r0
+
+
+ //;--------------------------------------------------------------------
+ //; The saved Program Status Registers (SPSRs) should be setup
+ //; prior to any automatic mode switches. The following
+ //; code sets these registers up to a known state. Users will need to
+ //; customize these settings to meet their needs.
+ //;--------------------------------------------------------------------
+ mov r2, #0x1f
+ mov r1, #0xd7 //;ABT mode
+ msr cpsr_c, r1 //;ABT mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xdb //;UND mode
+ msr cpsr_c, r1 //;UND mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd1 //;FIQ mode
+ msr cpsr_c, r1 //;FIQ mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd2 //;IRQ mode
+ msr cpsr_c, r1 //;IRQ mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd6 //;Monitor mode
+ msr cpsr_c, r1 //;Monitor mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd3 //;SVC mode
+ msr cpsr_c, r1 //;SVC mode
+ msr spsr_cxfs, r2 //;clear the spsr
+
+
+ //;--------------------------------------------------------------------
+ //; Enabling Error reporting is something users may want to do at
+ //; some other point in time. We have chosen some default settings
+ //; that should be reviewed. Most of these registers come up in an
+ //; unpredictable state after reset.
+ //;--------------------------------------------------------------------
+//;Start of error and control setting
+
+ //; setup L2CR0 with various L2/TCM control settings
+ //; enable out of order bus attributes and error reporting
+ //; this register comes up unpredictable after reset
+ // movw r1, #0x0F0F
+.word 0xe3001f0f // hardcoded movw instruction due to lack of compiler support
+ // movT r1, #0xC005
+.word 0xe34c1005 // hardcoded movw instruction due to lack of compiler support
+ mcr p15, 3, r1, c15, c0, 1 //; WCP15_L2CR0 r1
+
+ //; setup L2CPUCR
+ //; mov r2, #0xFF
+ //; Enable I and D cache parity
+ //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified,
+ //;tag, and data parity errors
+ mov r2, #0xe0
+ mcr p15, 3, r2, c15, c0, 2 //; WCP15_L2CPUCR r2
+
+ //; setup SPCR
+ //; enable all error reporting
+ //;(reset value is unpredicatble for most bits)
+ mov r3, #0x0F
+ mcr p15, 0, r3, c9, c7, 0 //; WCP15_SPCR r3
+
+ //; setup DMACHCRs (reset value unpredictable)
+ //; control setting and enable all error reporting
+ mov r1, #0x0F
+
+ //; DMACHCR0 = 0000000F
+ mov r2, #0x00 //; channel 0
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; DMACHCR1 = 0000000F
+ mov r2, #0x01 //; channel 1
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; DMACHCR2 = 0000000F
+ mov r2, #0x02 //; channel 2
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; DMACHCR3 = 0000000F
+ mov r2, #0x03 //; channel 3
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; Set ACTLR (reset unpredictable)
+ //; Set AVIVT control, error reporting, etc.
+ //; mov r3, #0x07
+ //; Enable I and D cache parity
+ //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$)
+ //;ACTLR[5:4] = 2'h3 - enable parity
+ //;ACTLR[19:18] =2'h3 - always generate and
+ //;check parity(when MMU disabled).
+ //;Value to be written #0xC0037
+ // movw r3, #0x0037
+.word 0xe3003037 // hardcoded movw instruction due to lack of compiler support
+ // movT r3, #0x000C
+.word 0xe340300c // hardcoded movw instruction due to lack of compiler support
+ mcr p15, 0, r3, c1, c0, 1 //; WCP15_ACTLR r3
+
+//;End of error and control setting
+
+ //;---------------------------------------------------------------------
+ //; Unlock ETM and read StickyPD to halt the ETM clocks from running.
+ //; This is required for power saving whether the ETM is used or not.
+ //;---------------------------------------------------------------------
+
+ //;Clear ETMOSLSR[LOCK] bit
+ mov r1, #0x00000000
+ mcr p14, 1, r1, c1, c0, 4 //; WCP14_ETMOSLAR r1
+
+ //;Clear ETMPDSR[STICKYPD] bit
+ mrc p14, 1, r2, c1, c5, 4 //; RCP14_ETMPDSR r2
+ b SET_SA
+
+
+.ltorg
diff --git a/arch/arm/cpu/armv7/msm7630/timer.c b/arch/arm/cpu/armv7/msm7630/timer.c
new file mode 100644
index 0000000..1c3f7ba
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/timer.c
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <r-woodruff2 at ti.com>
+ * Syed Moahmmed Khasim <khasim at ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger at sysgo.de>
+ * Alex Zuepke <azu at sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj at denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <config.h>
+#include <common.h>
+#include <asm/types.h>
+#define TIMER_LOAD_VAL 0x21
+
+#define GPT_ENABLE_CLR_ON_MATCH_EN 2
+#define GPT_ENABLE_EN 1
+#define DGT_ENABLE_CLR_ON_MATCH_EN 2
+#define DGT_ENABLE_EN 1
+
+#define SPSS_TIMER_STATUS_DGT_EN (1 << 0)
+
+
+#define READ_TIMER readl(GPT_COUNT_VAL)
+
+static ulong timestamp;
+static ulong lastinc;
+#define DGT_HZ 6750000 /* Uses LPXO/4 (27.0 MHz / 4) */
+
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init(void)
+{
+ uint32_t val = 0;
+
+ /* Disable timer */
+ writel(0, DGT_ENABLE);
+
+ /* Check for the hardware revision */
+ val = readl(HW_REVISION_NUMBER);
+ val = (val >> 28) & 0x0F;
+ if (val >= 1)
+ writel(1, DGT_CLK_CTL);
+ return 0;
+}
+
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void __udelay(unsigned long usecs)
+{
+ unsigned int val;
+ usecs = (usecs * 33 + 1000 - 33) / 1000;
+
+ writel(0, GPT_CLEAR);
+ writel(0, GPT_ENABLE);
+ do {
+ val = 0;
+ val = readl(GPT_COUNT_VAL);
+ } while (val != 0);
+
+ writel(GPT_ENABLE_EN, GPT_ENABLE);
+ do {
+ val = 0;
+ val = readl(GPT_COUNT_VAL);
+ } while (val < usecs) ;
+
+ writel(0, GPT_ENABLE);
+ writel(0, GPT_CLEAR);
+
+}
+
+void reset_timer_masked(void)
+{
+ /* reset time */
+ lastinc = READ_TIMER; /* capure current decrementer value time */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked(void)
+{
+ ulong now = READ_TIMER; /* current tick value */
+
+ if (lastinc <= now) { /* normal mode (non roll) */
+ /* normal mode */
+ timestamp += now - lastinc;
+ /* move stamp forward with absolute diff ticks */
+ } else { /* we have overflow of the count down timer */
+ timestamp += now + (TIMER_LOAD_VAL - lastinc);
+ }
+ lastinc = now;
+
+ return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return 19200000;
+}
diff --git a/arch/arm/include/asm/arch-msm7630/adm.h b/arch/arm/include/asm/arch-msm7630/adm.h
new file mode 100644
index 0000000..0e8af85
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/adm.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ADM_H
+#define __ADM_H
+
+/* Channel #s and security domain */
+#define ADM_CHN 8
+#define ADM_SD 2
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio.h b/arch/arm/include/asm/arch-msm7630/gpio.h
new file mode 100644
index 0000000..af6ddaa
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio.h
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __GPIO_H
+#define __GPIO_H
+
+#ifndef GPIO_INPUT
+#define GPIO_INPUT 0x0000
+#endif
+#ifndef GPIO_OUTPUT
+#define GPIO_OUTPUT 0x0001
+#endif
+
+#define GPIO_LEVEL 0x0000
+#define GPIO_EDGE 0x0010
+
+#define GPIO_RISING 0x0020
+#define GPIO_FALLING 0x0040
+
+#define GPIO_HIGH 0x0020
+#define GPIO_LOW 0x0040
+
+#define GPIO_PULLUP 0x0100
+#define GPIO_PULLDOWN 0x0200
+
+int gpio_config(unsigned nr, unsigned flags);
+void gpio_set(unsigned nr, unsigned on);
+int gpio_get(unsigned nr);
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio_hw.h b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
new file mode 100644
index 0000000..c8244d8
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
@@ -0,0 +1,168 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __GPIO_HW_H
+#define __GPIO_HW_H
+
+#define MSM_GPIO1_BASE 0xAC001000
+#define MSM_GPIO2_BASE 0xAC101000
+
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+
+/* output value */
+#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
+#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 43-16 */
+#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-44 */
+#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
+#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */
+#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 133-107 */
+#define GPIO_OUT_6 GPIO1_REG(0xC4) /* gpio 150-134 */
+#define GPIO_OUT_7 GPIO1_REG(0x214) /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0 GPIO1_REG(0x10)
+#define GPIO_OE_1 GPIO2_REG(0x08)
+#define GPIO_OE_2 GPIO1_REG(0x14)
+#define GPIO_OE_3 GPIO1_REG(0x18)
+#define GPIO_OE_4 GPIO1_REG(0x1C)
+#define GPIO_OE_5 GPIO1_REG(0x54)
+#define GPIO_OE_6 GPIO1_REG(0xC8)
+#define GPIO_OE_7 GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0 GPIO1_REG(0x34)
+#define GPIO_IN_1 GPIO2_REG(0x20)
+#define GPIO_IN_2 GPIO1_REG(0x38)
+#define GPIO_IN_3 GPIO1_REG(0x3C)
+#define GPIO_IN_4 GPIO1_REG(0x40)
+#define GPIO_IN_5 GPIO1_REG(0x44)
+#define GPIO_IN_6 GPIO1_REG(0xCC)
+#define GPIO_IN_7 GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0)
+#define GPIO_INT_EDGE_6 GPIO1_REG(0xD0)
+#define GPIO_INT_EDGE_7 GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0 GPIO1_REG(0x70)
+#define GPIO_INT_POS_1 GPIO2_REG(0x58)
+#define GPIO_INT_POS_2 GPIO1_REG(0x74)
+#define GPIO_INT_POS_3 GPIO1_REG(0x78)
+#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5 GPIO1_REG(0xBC)
+#define GPIO_INT_POS_6 GPIO1_REG(0xD4)
+#define GPIO_INT_POS_7 GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0 GPIO1_REG(0x80)
+#define GPIO_INT_EN_1 GPIO2_REG(0x60)
+#define GPIO_INT_EN_2 GPIO1_REG(0x84)
+#define GPIO_INT_EN_3 GPIO1_REG(0x88)
+#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5 GPIO1_REG(0xB8)
+#define GPIO_INT_EN_6 GPIO1_REG(0xD8)
+#define GPIO_INT_EN_7 GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4)
+#define GPIO_INT_CLEAR_6 GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_7 GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0)
+#define GPIO_INT_STATUS_6 GPIO1_REG(0xE0)
+#define GPIO_INT_STATUS_7 GPIO1_REG(0x234)
+
+
+#define GPIO_OUT_VAL_REG_BASE 0xABC00000
+#define GPIO_ALT_FUNC_PAGE_REG (GPIO_OUT_VAL_REG_BASE + 0x20)
+#define GPIO_ALT_FUNC_CFG_REG (GPIO_OUT_VAL_REG_BASE + 0x24)
+
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER 2
+#define GPIO_PULL_UP 3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA 0
+#define GPIO_4MA 1
+#define GPIO_6MA 2
+#define GPIO_8MA 3
+#define GPIO_10MA 4
+#define GPIO_12MA 5
+#define GPIO_14MA 6
+#define GPIO_16MA 7
+
+#define GPIO38_GPIO_CNTRL 0x175
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE 0
+#define GPIO_DISABLE 1
+
+#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
+ ((((gpio) & 0x3FF) << 4) | \
+ ((func) & 0xf) | \
+ (((dir) & 0x1) << 14) | \
+ (((pull) & 0x3) << 15) | \
+ (((drvstr) & 0xF) << 17))
+
+/**
+ * struct msm_gpio - GPIO pin description
+ * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
+ * @label - textual label
+ *
+ * Usually, GPIO's are operated by sets.
+ * This struct accumulate all GPIO information in single source
+ * and facilitete group operations provided by msm_gpios_xxx()
+ */
+struct msm_gpio {
+ unsigned gpio_cfg;
+ const char *label;
+};
+
+/**
+ * extract GPIO pin from bit-field used for gpio_tlmm_config
+ */
+#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff)
+#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf)
+#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1)
+#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3)
+#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/iomap.h b/arch/arm/include/asm/arch-msm7630/iomap.h
new file mode 100644
index 0000000..186c6c2
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/iomap.h
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __IOMAP_H_
+#define __IOMAP_H_
+
+#define MSM_UART1_BASE 0xACA00000
+#define MSM_UART2_BASE 0xACB00000
+#define MSM_UART3_BASE 0xACC00000
+
+#define MSM_VIC_BASE 0xC0080000
+#define MSM_TMR_BASE 0xC0100000
+
+#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
+#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
+#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
+
+#define GPT_REG(off) (MSM_GPT_BASE + (off))
+#define DGT_REG(off) (MSM_DGT_BASE + (off))
+
+#define GPT_MATCH_VAL GPT_REG(0x0000)
+#define GPT_COUNT_VAL GPT_REG(0x0004)
+#define GPT_ENABLE GPT_REG(0x0008)
+#define GPT_CLEAR GPT_REG(0x000C)
+
+#define DGT_MATCH_VAL DGT_REG(0x0000)
+#define DGT_COUNT_VAL DGT_REG(0x0004)
+#define DGT_ENABLE DGT_REG(0x0008)
+#define DGT_CLEAR DGT_REG(0x000C)
+#define DGT_CLK_CTL DGT_REG(0x0010)
+
+#define HW_REVISION_NUMBER 0xABC00270
+
+#define MSM_CSR_BASE 0xC0100000
+#define MSM_GCC_BASE 0xC0182000
+
+#define MSM_SDC1_BASE 0xA0400000
+#define MSM_SDC2_BASE 0xA0500000
+#define MSM_SDC3_BASE 0xA3000000
+#define MSM_SDC4_BASE 0xA3100000
+
+#define MSM_SHARED_BASE 0x00100000
+#define MSM_CLK_CTL_BASE 0xAB800000
+#define MSM_CLK_CTL_SH2_BASE 0xABA01000
+
+#define REG_BASE(off) (MSM_CLK_CTL_BASE + (off))
+#define REG_SH2_BASE(off) (MSM_CLK_CTL_SH2_BASE + (off))
+
+#define SCSS_CLK_CTL 0xC0101004
+#define SCSS_CLK_SEL 0xC0101008
+
+#define MSM_USB_BASE 0xA3600000
+#define MSM_CRYPTO_BASE 0xA8400000
+
+#define SH2_USBH_MD_REG REG_SH2_BASE(0x2BC)
+#define SH2_USBH_NS_REG REG_SH2_BASE(0x2C0)
+
+#define SH2_MDP_NS_REG REG_SH2_BASE(0x14C)
+#define SH2_MDP_LCDC_MD_REG REG_SH2_BASE(0x38C)
+#define SH2_MDP_LCDC_NS_REG REG_SH2_BASE(0x390)
+#define SH2_MDP_VSYNC_REG REG_SH2_BASE(0x460)
+#define SH2_PMDH_NS_REG REG_SH2_BASE(0x8C)
+
+#define SH2_GLBL_CLK_ENA_SC REG_SH2_BASE(0x3BC)
+#define SH2_GLBL_CLK_ENA_2_SC REG_SH2_BASE(0x3C0)
+
+#define SH2_OWN_ROW1_BASE_REG REG_BASE(0x041C)
+#define SH2_OWN_ROW2_BASE_REG REG_BASE(0x0424)
+#define SH2_OWN_APPS2_BASE_REG REG_BASE(0x0414)
+
+#define MSM_ADM_BASE 0xAC200000
+#define MSM_ADM_SD_OFFSET 0x00100400
+
+#define MSM_SAW_BASE 0xC0102000
+
+#define PLL_ENA_REG REG_SH2_BASE(0x0264)
+#define PLL2_STATUS_BASE_REG REG_BASE(0x0350)
+#define PLL2_L_VAL_ADDR REG_BASE(0x033C)
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/proc_comm.h b/arch/arm/include/asm/arch-msm7630/proc_comm.h
new file mode 100644
index 0000000..3df08b9
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/proc_comm.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PROC_COMM_H_
+#define __PROC_COMM_H_
+
+void usb_clock_init(void);
+void lcdc_clock_init(unsigned rate);
+void mdp_clock_init(unsigned rate);
+void uart3_clock_init(void);
+void uart2_clock_init(void);
+void uart1_clock_init(void);
+void mddi_clock_init(unsigned num, unsigned rate);
+void reboot(unsigned reboot_reason);
+int mmc_clock_enable_disable(unsigned id, unsigned enable);
+int mmc_clock_set_rate(unsigned id, unsigned rate);
+int mmc_clock_get_rate(unsigned id);
+int gpio_tlmm_config(unsigned config, unsigned disable);
+int vreg_set_level(unsigned id, unsigned mv);
+int vreg_enable(unsigned id);
+int vreg_disable(unsigned id);
+
+#endif
+
+
diff --git a/arch/arm/include/asm/arch-msm7630/sys_proto.h b/arch/arm/include/asm/arch-msm7630/sys_proto.h
new file mode 100644
index 0000000..c679d92
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/sys_proto.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void pll8_enable(void);
+void clock_init(void);
+void __cpu_early_init(void);
+
+#endif
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Albert ARIBAUD
2012-02-29 00:00:43 UTC
Permalink
Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :

> +#define BIT(n) (1<< (n))
> +#define VREG_CONFIG (BIT(7) | BIT(6))

BIT() is not used elsewhere. It would be simpler not to define it and to
define VREG_CONFIG as (3 << 6).

Besides, isn't that rather a VREG_CONFIG_MASK?

> +void set_vector_base(unsigned long addr)
> +{
> + __asm__ volatile ("mcr p15, 0, %0, c12, c0, 0" : : "r" (addr));
> +}

Where is it used?

> +int dram_init(void)
> +{
> + /* We do not initialise DRAM here. We just query the size */
> + gd->ram_size = PHYS_SDRAM_1_SIZE;
> + /* Now check it dynamically */

It says 'check it dynamically', but does not seem to. Any reason not to
detect RAM size dynamically?

> +static struct gpioregs *find_gpio(unsigned n, unsigned *bit)
> +{
> + if (n> 150) {
> + *bit = 1<< (n - 151);
> + return GPIO_REGS + 7;
> + }
> + if (n> 133) {
> + *bit = 1<< (n - 134);
> + return GPIO_REGS + 6;
> + }
> + if (n> 106) {
> + *bit = 1<< (n - 107);
> + return GPIO_REGS + 5;
> + }
> + if (n> 94) {
> + *bit = 1<< (n - 95);
> + return GPIO_REGS + 4;
> + }
> + if (n> 67) {
> + *bit = 1<< (n - 68);
> + return GPIO_REGS + 3;
> + }
> + if (n> 43) {
> + *bit = 1<< (n - 44);
> + return GPIO_REGS + 2;
> + }
> + if (n> 15) {
> + *bit = 1<< (n - 16);
> + return GPIO_REGS + 1;
> + }
> + *bit = 1<< n;
> + return GPIO_REGS + 0;
> +}
> +
> +int gpio_config(unsigned n, unsigned flags)
> +{
> + struct gpioregs *r;
> + unsigned b;
> + unsigned v;
> +
> + r = find_gpio(n,&b);
> + if (!r)
> + return -1;
> +
> + v = readl(r->oe);
> + if (flags& GPIO_OUTPUT)
> + writel(v | b, r->oe);
> + else
> + writel(v& (~b), r->oe);
> + return 0;
> +}
> +
> +void gpio_set(unsigned n, unsigned on)
> +{
> + struct gpioregs *r;
> + unsigned b;
> + unsigned v;
> +
> + r = find_gpio(n,&b);
> + if (r == 0)
> + return;
> +
> + v = readl(r->out);
> + if (on)
> + writel(v | b, r->out);
> + else
> + writel(v& (~b), r->out);
> +}
> +
> +int gpio_get(unsigned n)
> +{
> + struct gpioregs *r;
> + unsigned b;
> +
> + r = find_gpio(n,&b);
> + if (r == 0)
> + return 0;
> + return (readl(r->in)& b) ? 1 : 0;
> +}
> +
> +void platform_config_interleaved_mode_gpios(void)
> +{
> + /* configure EB2_CS1 through GPIO86 */
> + writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
> + writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
> + /* configure the EBI2_BUSY1_N through GPIO115 */
> + writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
> + writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
> +}
> +
> +/* Enables all gpios passed in table*/
> +int platform_gpios_enable(const struct msm_gpio *table, int size)
> +{
> + int rc;
> + int i;
> + const struct msm_gpio *g;
> + for (i = 0; i< size; i++) {
> + g = table + i;
> + /* Enable gpio */
> + rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
> + if (rc)
> + goto err;
> + }
> + return 0;
> +err:
> + return rc;
> +}
> +
> diff --git a/arch/arm/cpu/armv7/msm7630/lowlevel_init.S b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
> new file mode 100644
> index 0000000..d8d5b46
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
> @@ -0,0 +1,626 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#include<config.h>
> +#include<version.h>
> +
> +.text
> +.code 32
> +
> +#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
> +#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
> +
> +/*
> + ; LVT Ring Osc counter
> + ; used to determine sense amp settings
> + ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11
> +*/
> +.equ CLK_CTL_BASE, 0xA8600000
> +.equ A_GLBL_CLK_ENA, 0x0000
> +.equ A_PRPH_WEB_NS_REG,0x0080
> +.equ A_MSM_CLK_RINGOSC,0x00D0
> +.equ A_TCXO_CNT, 0x00D4
> +.equ A_TCXO_CNT_DONE, 0x00D8
> +.equ A_RINGOSC_CNT, 0x00DC
> +.equ A_MISC_CLK_CTL, 0x0108
> +.equ CLK_TEST, 0xA8600114
> +.equ SPSS_CSR_BASE, 0xAC100000
> +.equ A_SCRINGOSC, 0x0510
> +
> +//;; Number of TCXO cycles to count ring oscillations
> +.equ TCXO_CNT_VAL, 0x100
> +
> +//; Halcyon addresses
> +.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register
> +.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register
> +
> +//; SCORPION_L1_ACC (1:0) Fuses bit location
> +.equ L1_ACC_BIT_0, 12 //;12th bit of TCSR_CONF_FUSE_4
> +.equ L1_ACC_BIT_1, 13 //;13th bit of TCSR_CONF_FUSE_4
> +//; SCORPION_L2_ACC (2:0) Fuses bit location
> +.equ L2_ACC_BIT_0, 25 //;25th bit of TCSR_CONF_FUSE_1
> +.equ L2_ACC_BIT_1, 10 //;10th bit of TCSR_CONF_FUSE_4
> +.equ L2_ACC_BIT_2, 11 //;11th bit of TCSR_CONF_FUSE_4
> +
> +//; CP15: PVR2F0 values according to SCORPION_L1_ACC (1:0)
> +.equ PVR2F0_00, 0x00000000
> +.equ PVR2F0_01, 0x04000000
> +.equ PVR2F0_10, 0x08000000
> +.equ PVR2F0_11, 0x0C000000
> +
> +//; CP15: PVR2F1 values according to SCORPION_L1_ACC (1:0)
> +.equ PVR2F1_00, 0x00000008
> +.equ PVR2F1_01, 0x00000008
> +.equ PVR2F1_10, 0x00000208
> +.equ PVR2F1_11, 0x00000208
> +
> +//; CP15: PVR0F2 values according to SCORPION_L1_ACC (1:0)
> +.equ PVR0F2_00, 0x00000000
> +.equ PVR0F2_01, 0x00000000
> +.equ PVR0F2_10, 0x00000200
> +.equ PVR0F2_11, 0x00000200
> +
> +//; CP15: PVR0F0 values according to SCORPION_L1_ACC (1:0)
> +.equ PVR0F0_00, 0x7F000000
> +.equ PVR0F0_01, 0x7F000400
> +.equ PVR0F0_10, 0x7F000000
> +.equ PVR0F0_11, 0x7F000400
> +
> +//; CP15: L2VR3F1 values according to SCORPION_L2_ACC (2:0)
> +.equ L2VR3F1_000, 0x00FFFF60
> +.equ L2VR3F1_001, 0x00FFFF40
> +.equ L2VR3F1_010, 0x00FFFC60
> +.equ L2VR3F1_011, 0x00FFFC40
> +.equ L2VR3F1_100, 0x00FCFF60
> +.equ L2VR3F1_101, 0x00FCFF40
> +.equ L2VR3F1_110, 0x00FCFC60
> +.equ L2VR3F1_111, 0x00FCFC40
> +
> +
> +
> +
> +_TEXT_BASE:
> + .word CONFIG_SYS_TEXT_BASE @ sdram load addr from config file
> +
> +.global invalidate_dcache
> +invalidate_dcache:
> + mov pc, lr
> +
> + .align 5
> +.globl lowlevel_init
> +lowlevel_init:
> + mov pc, lr @ back to arch calling code
> +
> +.global reset_cpu
> +reset_cpu:
> +_loop_forever:
> + b _loop_forever
> +
> +.globl SET_SA
> +SET_SA:
> +
> + //;--------------------------------------------------------------------
> + //; Fuse bits used to determine sense amp settings
> + //;--------------------------------------------------------------------
> +
> + //; Reading L1_ACC
> + ldr r4, = 0x0
> +
> + //; Read L1_ACC_BIT_0
> + ldr r1, =TCSR_CONF_FUSE_4
> + ldr r2, =L1_ACC_BIT_0
> + ldr r3, [r1]
> + mov r3, r3, LSR r2
> + and r3, r3, #1
> + orr r4, r3, r4
> +
> + //; Read L1_ACC_BIT_1
> + ldr r1, =TCSR_CONF_FUSE_4
> + ldr r2, =L1_ACC_BIT_1
> + ldr r3, [r1]
> + mov r3, r3, LSR r2
> + and r3, r3, #1
> + mov r3, r3, LSL #1
> + orr r4, r3, r4
> +
> +l1_ck_0:
> + //; if L1_[1:0] == 00
> + ldr r5, = 0x0
> + cmp r4, r5
> + bne l1_ck_1
> + ldr r0, =PVR0F0_00
> + ldr r1, =PVR0F2_00
> + ldr r2, =PVR2F0_00
> + ldr r3, =PVR2F1_00
> + b WRITE_L1_SA_SETTINGS
> +
> +l1_ck_1:
> + //; if L1_[1:0] == 01
> + ldr r1, = 0x01
> + cmp r4, r1
> + bne l1_ck_2
> + ldr r0, =PVR0F0_01
> + ldr r1, =PVR0F2_01
> + ldr r2, =PVR2F0_01
> + ldr r3, =PVR2F1_01
> + b WRITE_L1_SA_SETTINGS
> +
> +l1_ck_2:
> + //; if L1_[2:0] == 10
> + ldr r1, = 0x02
> + cmp r4, r1
> + bne l1_ck_3
> + ldr r0, =PVR0F0_10
> + ldr r1, =PVR0F2_10
> + ldr r2, =PVR2F0_10
> + ldr r3, =PVR2F1_10
> + b WRITE_L1_SA_SETTINGS
> +
> +l1_ck_3:
> + //; if L1_[2:0] == 11
> + ldr r1, = 0x03
> + cmp r4, r1
> + ldr r0, =PVR0F0_11
> + ldr r1, =PVR0F2_11
> + ldr r2, =PVR2F0_11
> + ldr r3, =PVR2F1_11
> + b WRITE_L1_SA_SETTINGS
> +
> +
> +WRITE_L1_SA_SETTINGS:
> +
> + //;WCP15_PVR0F0 r0
> + mcr p15, 0x0, r0, c15, c15, 0x0 //; write R0 to PVR0F0
> +
> + //;WCP15_PVR0F2 r1
> + mcr p15, 0x0, r1, c15, c15, 0x2 //; write R1 to PVR0F2
> +
> + //;WCP15_PVR2F0 r2
> + mcr p15, 0x2, r2, c15, c15, 0x0 //; write R2 to PVR2F0
> +
> + // Disable predecode repair cache on certain Scorpion revisions
> + // (Raptor V2 and earlier, or Halcyon V1)
> + mrc p15, 0, r1, c0, c0, 0 //; MIDR
> + BIC r2, r1, #0xf0 //; check for Halcyon V1
> + ldr r4, =0x511f0000
> + cmp r2, r4
> + bne PVR2F1
> +
> +DPRC:
> + mrc p15, 0, r1, c15, c15, 2 //; PVR0F2
> + orr r1, r1, #0x10 //; enable bit 4
> + mcr p15, 0, r1, c15, c15, 2 //; disable predecode repair cache
> +
> +PVR2F1:
> + //;WCP15_PVR2F1 r3
> + mcr p15, 0x2, r3, c15, c15, 0x1 //; write R3 to PVR2F1
> +
> + //; Reading L2_ACC
> + ldr r4, = 0x0
> +
> + //; Read L2_ACC_BIT_0
> + ldr r1, =TCSR_CONF_FUSE_1
> + ldr r2, =L2_ACC_BIT_0
> + ldr r3, [r1]
> + mov r3, r3, LSR r2
> + and r3, r3, #1
> + orr r4, r3, r4
> +
> + //; Read L2_ACC_BIT_1
> + ldr r1, =TCSR_CONF_FUSE_4
> + ldr r2, =L2_ACC_BIT_1
> + ldr r3, [r1]
> + mov r3, r3, LSR r2
> + and r3, r3, #1
> + mov r3, r3, LSL #1
> + orr r4, r3, r4
> +
> + //; Read L2_ACC_BIT_2
> + ldr r1, =TCSR_CONF_FUSE_4
> + ldr r2, =L2_ACC_BIT_2
> + ldr r3, [r1]
> + mov r3, r3, LSR r2
> + and r3, r3, #1
> + mov r3, r3, LSL #2
> + orr r4, r3, r4
> +
> +l2_ck_0:
> + //; if L2_[2:0] == 000
> + ldr r5, = 0x0
> + cmp r4, r5
> + bne l2_ck_1
> + ldr r0, =L2VR3F1_000
> + b WRITE_L2_SA_SETTINGS
> +
> +l2_ck_1:
> + //; if L2_[2:0] == 001
> + ldr r5, = 0x1
> + cmp r4, r5
> + bne l2_ck_2
> + ldr r0, =L2VR3F1_001
> + b WRITE_L2_SA_SETTINGS
> +
> +l2_ck_2:
> + //; if L2_[2:0] == 010
> + ldr r5, = 0x2
> + cmp r4, r5
> + bne l2_ck_3
> + ldr r0, =L2VR3F1_010
> + b WRITE_L2_SA_SETTINGS
> +
> +l2_ck_3:
> + //; if L2_[2:0] == 011
> + ldr r5, = 0x3
> + cmp r4, r5
> + bne l2_ck_4
> + ldr r0, =L2VR3F1_011
> + b WRITE_L2_SA_SETTINGS
> +
> +l2_ck_4:
> + //; if L2_[2:0] == 100
> + ldr r5, = 0x4
> + cmp r4, r5
> + bne l2_ck_5
> + ldr r0, =L2VR3F1_100
> + b WRITE_L2_SA_SETTINGS
> +
> +l2_ck_5:
> + //; if L2_[2:0] == 101
> + ldr r5, = 0x5
> + cmp r4, r5
> + bne l2_ck_6
> + ldr r0, =L2VR3F1_101
> + b WRITE_L2_SA_SETTINGS
> +
> +l2_ck_6:
> + //; if L2_[2:0] == 110
> + ldr r5, = 0x6
> + cmp r4, r5
> + bne l2_ck_7
> + ldr r0, =L2VR3F1_110
> + b WRITE_L2_SA_SETTINGS
> +
> +l2_ck_7:
> + //; if L2_[2:0] == 111
> + ldr r5, = 0x7
> + cmp r4, r5
> + ldr r0, =L2VR3F1_111
> + b WRITE_L2_SA_SETTINGS
> +
> +WRITE_L2_SA_SETTINGS:
> + //;WCP15_L2VR3F1 r0
> + mcr p15, 0x3, r0, c15, c15, 0x1 //;write r0 to L2VR3F1
> + DSB
> + ISB
> +
> + ldr r0, =0 //;make sure the registers we touched
> + ldr r1, =0 //;are cleared when we return
> + ldr r2, =0
> + ldr r3, =0
> + ldr r4, =0
> + ldr r5, =0
> +
> + mrs r0, cpsr
> + orr r0, r0, #(1<<7)
> + msr cpsr_c, r0
> +
> + //; routine complete
> + pop {r5-r12,pc}
> +
> +.ltorg
> +
> +.globl __cpu_early_init
> +__cpu_early_init:
> +
> + //; Zero out r0 for use throughout this code. All other GPRs
> + //; (r1-r3) are set throughout this code to help establish
> + //; a consistent startup state for any code that follows.
> + //; Users should add code at the end of this routine to establish
> + //; their own stack address (r13), add translation page tables, enable
> + //; the caches, etc.
> + push {r5-r12,r14}
> + mov r0, #0x0
> +
> +
> + //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA
> + //; API to dynamically configure cache for slow/nominal/fast parts
> +
> + //; DCIALL to invalidate L2 cache bank (needs to be run 4 times,
> + //; once per bank)
> + //; This must be done early in code (prior to enabling the caches)
> + mov r1, #0x2
> + mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank D ([15:14] == 2'b00)
> + orr r1, r1, #0x00004000
> + mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank C ([15:14] == 2'b01)
> + add r1, r1, #0x00004000
> + mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank B ([15:14] == 2'b10)
> + add r1, r1, #0x00004000
> + mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank A ([15:14] == 2'b11)
> +
> + //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's
> + //; and have all address bits (AM) participate.
> + //; Different settings can be used to improve performance
> + // movW r1, #0x01FF
> +.word 0xe30011ff // hardcoded movW instruction due to lack of compiler support
> + // movT r1, #0x01FF
> +.word 0xe34011ff // hardcoded movT instruction due to lack of compiler support
> + mcr p15, 7, r1, c15, c0, 2 //; WCP15_BPCR
> +
> +
> + //; Initialize all I$ Victim Registers to 0 for startup
> + mcr p15, 0, r0, c9, c1, 0 //; WCP15_ICVIC0 r0
> + mcr p15, 0, r0, c9, c1, 1 //; WCP15_ICVIC1 r0
> + mcr p15, 0, r0, c9, c1, 2 //; WCP15_ICVIC2 r0
> + mcr p15, 0, r0, c9, c1, 3 //; WCP15_ICVIC3 r0
> + mcr p15, 0, r0, c9, c1, 4 //; WCP15_ICVIC4 r0
> + mcr p15, 0, r0, c9, c1, 5 //; WCP15_ICVIC5 r0
> + mcr p15, 0, r0, c9, c1, 6 //; WCP15_ICVIC5 r0
> + mcr p15, 0, r0, c9, c1, 7 //; WCP15_ICVIC7 r0
> +
> + //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0
> + mcr p15, 1, r0, c9, c1, 0 //; WCP15_ICFLOOR0 r0
> + mcr p15, 1, r0, c9, c1, 1 //; WCP15_ICFLOOR1 r0
> + mcr p15, 1, r0, c9, c1, 2 //; WCP15_ICFLOOR2 r0
> + mcr p15, 1, r0, c9, c1, 3 //; WCP15_ICFLOOR3 r0
> + mcr p15, 1, r0, c9, c1, 4 //; WCP15_ICFLOOR4 r0
> + mcr p15, 1, r0, c9, c1, 5 //; WCP15_ICFLOOR5 r0
> + mcr p15, 1, r0, c9, c1, 6 //; WCP15_ICFLOOR6 r0
> + mcr p15, 1, r0, c9, c1, 7 //; WCP15_ICFLOOR7 r0
> +
> + //; Initialize all D$ Victim Registers to 0
> + mcr p15, 2, r0, c9, c1, 0 //; WP15_DCVIC0 r0
> + mcr p15, 2, r0, c9, c1, 1 //; WP15_DCVIC1 r0
> + mcr p15, 2, r0, c9, c1, 2 //; WP15_DCVIC2 r0
> + mcr p15, 2, r0, c9, c1, 3 //; WP15_DCVIC3 r0
> + mcr p15, 2, r0, c9, c1, 4 //; WP15_DCVIC4 r0
> + mcr p15, 2, r0, c9, c1, 5 //; WP15_DCVIC5 r0
> + mcr p15, 2, r0, c9, c1, 6 //; WP15_DCVIC6 r0
> + mcr p15, 2, r0, c9, c1, 7 //; WP15_DCVIC7 r0
> +
> + //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0
> + mcr p15, 3, r0, c9, c1, 0 //; WCP15_DCFLOOR0 r0
> + mcr p15, 3, r0, c9, c1, 1 //; WCP15_DCFLOOR1 r0
> + mcr p15, 3, r0, c9, c1, 2 //; WCP15_DCFLOOR2 r0
> + mcr p15, 3, r0, c9, c1, 3 //; WCP15_DCFLOOR3 r0
> + mcr p15, 3, r0, c9, c1, 4 //; WCP15_DCFLOOR4 r0
> + mcr p15, 3, r0, c9, c1, 5 //; WCP15_DCFLOOR5 r0
> + mcr p15, 3, r0, c9, c1, 6 //; WCP15_DCFLOOR6 r0
> + mcr p15, 3, r0, c9, c1, 7 //; WCP15_DCFLOOR7 r0
> +
> + //; Initialize ASID to zero
> + mcr p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0
> +
> + //; ICIALL to invalidate entire I-Cache
> + mcr p15, 0, r0, c7, c5, 0 //; ICIALLU
> +
> + //; DCIALL to invalidate entire D-Cache
> + mcr p15, 0, r0, c9, c0, 6 //; DCIALL r0
> +
> + //; Initialize ADFSR to zero
> + mcr p15, 0, r0, c5, c1, 0 //; ADFSR r0
> +
> + //; Initialize EFSR to zero
> + mcr p15, 7, r0, c15, c0, 1 //; EFSR r0
> +
> + //; The VBAR (Vector Base Address Register) should be initialized
> + //; early in your code. We are setting it to zero
> + mcr p15, 0, r0, c12, c0, 0 //; WCP15_VBAR r0
> +
> + //; Ensure the mcr's above have completed their operation
> + //; before continuing
> + DSB
> + ISB
> +
> + //; Setup CCPR - Cache Coherency Policy Register
> + //; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing)
> + //; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable)
> + movw r2, #0x88
> + mcr p15, 0, r2, c10, c4, 2
> +
> + //;-------------------------------------------------------------------
> + //; There are a number of registers that must be set prior to enabling
> + //; the MMU. The DCAR is one of these registers. We are setting
> + //; it to zero (no access) to easily detect improper setup in subsequent
> + //; code sequences
> + //;-------------------------------------------------------------------
> + //; Setup DACR (Domain Access Control Register) to zero
> + mcr p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0
> +
> + //; Setup DCLKCR to allow normal D-Cache line fills
> + mcr p15, 1, r0, c9, c0, 7 //; WCP15_DCLKCR r0
> +
> + //; Setup the TLBLKCR
> + //; Victim = 6'b000000; Floor = 6'b000000;
> + //; IASIDCFG =
> + //;2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0;
> + mov r1, #0x02
> + mcr p15, 0, r1, c10, c1, 3 //; WCP15_TLBLKCR r1
> +
> + //;Make sure TLBLKCR is complete before continuing
> + ISB
> +
> + //; Invalidate the UTLB
> + mcr p15, 0, r0, c8, c7, 0 //; UTLBIALL
> +
> + //; Make sure UTLB request has been presented to macro before continuing
> + ISB
> +
> +SYSI2:
> + //; setup L2CR1 to some default Instruction and data prefetching values
> + //; Users may want specific settings for various performance
> + //; enhancements
> + //; In Halcyon we do not have broadcasting barriers. So we need to turn
> + // ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast )
> + ldr r2, =0x133
> + mcr p15, 3, r2, c15, c0, 3 //; WCP15_L2CR1 r0
> +
> +
> + //; Enable Z bit to enable branch prediction (default is off)
> + mrc p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2
> + orr r2, r2, #0x00000800
> + mcr p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2
> +
> + //; Make sure Link stack is initialized with branch and links to
> + //; sequential addresses
> + //; This aids in creating a predictable startup environment
> + bl SEQ1
> +SEQ1: bl SEQ2
> +SEQ2: bl SEQ3
> +SEQ3: bl SEQ4
> +SEQ4: bl SEQ5
> +SEQ5: bl SEQ6
> +SEQ6: bl SEQ7
> +SEQ7: bl SEQ8
> +SEQ8:
> +
> + //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA
> + //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the
> + //;debug registers
> + //; Writing anything but the "secret code" to the DBGOSLAR clears the
> + //;DBGOSLSR[LOCK] bit
> + mcr p14, 0, r0, c1, c0, 4 //; WCP14_DBGOSLAR r0
> +
> +
> + //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD]
> + //; Any read to DBGPRSR clear the STICKYPD bit
> + //; ISB guarantees the read completes before attempting to
> + //; execute a CP14 instruction.
> + mrc p14, 0, r3, c1, c5, 4 //; RCP14_DBGPRSR r3
> + ISB
> +
> + //; Initialize the Watchpoint Control Registers to zero (optional)

If that is optional, why do it?

> + //;;; mcr p14, 0, r0, c0, c0, 7 ; WCP14_DBGWCR0 r0
> + //;;; mcr p14, 0, r0, c0, c1, 7 ; WCP14_DBGWCR1 r0
> +
> +
> + //;--------------------------------------------------------------------
> + //; The saved Program Status Registers (SPSRs) should be setup
> + //; prior to any automatic mode switches. The following
> + //; code sets these registers up to a known state. Users will need to
> + //; customize these settings to meet their needs.
> + //;--------------------------------------------------------------------
> + mov r2, #0x1f
> + mov r1, #0xd7 //;ABT mode
> + msr cpsr_c, r1 //;ABT mode
> + msr spsr_cxfs, r2 //;clear the spsr
> + mov r1, #0xdb //;UND mode
> + msr cpsr_c, r1 //;UND mode
> + msr spsr_cxfs, r2 //;clear the spsr
> + mov r1, #0xd1 //;FIQ mode
> + msr cpsr_c, r1 //;FIQ mode
> + msr spsr_cxfs, r2 //;clear the spsr
> + mov r1, #0xd2 //;IRQ mode
> + msr cpsr_c, r1 //;IRQ mode
> + msr spsr_cxfs, r2 //;clear the spsr
> + mov r1, #0xd6 //;Monitor mode
> + msr cpsr_c, r1 //;Monitor mode
> + msr spsr_cxfs, r2 //;clear the spsr
> + mov r1, #0xd3 //;SVC mode
> + msr cpsr_c, r1 //;SVC mode
> + msr spsr_cxfs, r2 //;clear the spsr
> +
> +
> + //;--------------------------------------------------------------------
> + //; Enabling Error reporting is something users may want to do at
> + //; some other point in time. We have chosen some default settings
> + //; that should be reviewed. Most of these registers come up in an
> + //; unpredictable state after reset.
> + //;--------------------------------------------------------------------
> +//;Start of error and control setting
> +
> + //; setup L2CR0 with various L2/TCM control settings
> + //; enable out of order bus attributes and error reporting
> + //; this register comes up unpredictable after reset
> + // movw r1, #0x0F0F
> +.word 0xe3001f0f // hardcoded movw instruction due to lack of compiler support
> + // movT r1, #0xC005
> +.word 0xe34c1005 // hardcoded movw instruction due to lack of compiler support
> + mcr p15, 3, r1, c15, c0, 1 //; WCP15_L2CR0 r1
> +
> + //; setup L2CPUCR
> + //; mov r2, #0xFF
> + //; Enable I and D cache parity
> + //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified,
> + //;tag, and data parity errors
> + mov r2, #0xe0
> + mcr p15, 3, r2, c15, c0, 2 //; WCP15_L2CPUCR r2
> +
> + //; setup SPCR
> + //; enable all error reporting
> + //;(reset value is unpredicatble for most bits)
> + mov r3, #0x0F
> + mcr p15, 0, r3, c9, c7, 0 //; WCP15_SPCR r3
> +
> + //; setup DMACHCRs (reset value unpredictable)
> + //; control setting and enable all error reporting
> + mov r1, #0x0F
> +
> + //; DMACHCR0 = 0000000F
> + mov r2, #0x00 //; channel 0
> + mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
> + mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
> +
> + //; DMACHCR1 = 0000000F
> + mov r2, #0x01 //; channel 1
> + mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
> + mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
> +
> + //; DMACHCR2 = 0000000F
> + mov r2, #0x02 //; channel 2
> + mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
> + mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
> +
> + //; DMACHCR3 = 0000000F
> + mov r2, #0x03 //; channel 3
> + mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
> + mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
> +
> + //; Set ACTLR (reset unpredictable)
> + //; Set AVIVT control, error reporting, etc.
> + //; mov r3, #0x07
> + //; Enable I and D cache parity
> + //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$)
> + //;ACTLR[5:4] = 2'h3 - enable parity
> + //;ACTLR[19:18] =2'h3 - always generate and
> + //;check parity(when MMU disabled).
> + //;Value to be written #0xC0037
> + // movw r3, #0x0037
> +.word 0xe3003037 // hardcoded movw instruction due to lack of compiler support
> + // movT r3, #0x000C
> +.word 0xe340300c // hardcoded movw instruction due to lack of compiler support
> + mcr p15, 0, r3, c1, c0, 1 //; WCP15_ACTLR r3
> +
> +//;End of error and control setting
> +
> + //;---------------------------------------------------------------------
> + //; Unlock ETM and read StickyPD to halt the ETM clocks from running.
> + //; This is required for power saving whether the ETM is used or not.
> + //;---------------------------------------------------------------------
> +
> + //;Clear ETMOSLSR[LOCK] bit
> + mov r1, #0x00000000
> + mcr p14, 1, r1, c1, c0, 4 //; WCP14_ETMOSLAR r1
> +
> + //;Clear ETMPDSR[STICKYPD] bit
> + mrc p14, 1, r2, c1, c5, 4 //; RCP14_ETMPDSR r2
> + b SET_SA
> +
> +
> +.ltorg
> diff --git a/arch/arm/cpu/armv7/msm7630/timer.c b/arch/arm/cpu/armv7/msm7630/timer.c
> new file mode 100644
> index 0000000..1c3f7ba
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/msm7630/timer.c
> @@ -0,0 +1,148 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * (C) Copyright 2010,2011
> + * NVIDIA Corporation<www.nvidia.com>
> + *
> + * (C) Copyright 2008
> + * Texas Instruments
> + *
> + * Richard Woodruff<r-woodruff2 at ti.com>
> + * Syed Moahmmed Khasim<khasim at ti.com>
> + *
> + * (C) Copyright 2002
> + * Sysgo Real-Time Solutions, GmbH<www.elinos.com>
> + * Marius Groeger<mgroeger at sysgo.de>
> + * Alex Zuepke<azu at sysgo.de>
> + *
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering,<garyj at denx.de>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include<asm/arch/iomap.h>
> +#include<asm/io.h>
> +#include<config.h>
> +#include<common.h>
> +#include<asm/types.h>
> +#define TIMER_LOAD_VAL 0x21
> +
> +#define GPT_ENABLE_CLR_ON_MATCH_EN 2
> +#define GPT_ENABLE_EN 1
> +#define DGT_ENABLE_CLR_ON_MATCH_EN 2
> +#define DGT_ENABLE_EN 1
> +
> +#define SPSS_TIMER_STATUS_DGT_EN (1<< 0)
> +
> +
> +#define READ_TIMER readl(GPT_COUNT_VAL)
> +
> +static ulong timestamp;
> +static ulong lastinc;
> +#define DGT_HZ 6750000 /* Uses LPXO/4 (27.0 MHz / 4) */
> +
> +
> +/* nothing really to do with interrupts, just starts up a counter. */
> +int timer_init(void)
> +{
> + uint32_t val = 0;
> +
> + /* Disable timer */
> + writel(0, DGT_ENABLE);
> +
> + /* Check for the hardware revision */
> + val = readl(HW_REVISION_NUMBER);
> + val = (val>> 28)& 0x0F;
> + if (val>= 1)
> + writel(1, DGT_CLK_CTL);
> + return 0;
> +}
> +
> +
> +ulong get_timer(ulong base)
> +{
> + return get_timer_masked() - base;
> +}
> +
> +/* delay x useconds AND perserve advance timstamp value */
> +void __udelay(unsigned long usecs)
> +{
> + unsigned int val;
> + usecs = (usecs * 33 + 1000 - 33) / 1000;
> +
> + writel(0, GPT_CLEAR);
> + writel(0, GPT_ENABLE);
> + do {
> + val = 0;
> + val = readl(GPT_COUNT_VAL);
> + } while (val != 0);
> +
> + writel(GPT_ENABLE_EN, GPT_ENABLE);
> + do {
> + val = 0;
> + val = readl(GPT_COUNT_VAL);
> + } while (val< usecs) ;
> +
> + writel(0, GPT_ENABLE);
> + writel(0, GPT_CLEAR);
> +
> +}
> +
> +void reset_timer_masked(void)

Why do you need a timer reset function?

> +{
> + /* reset time */
> + lastinc = READ_TIMER; /* capure current decrementer value time */
> + timestamp = 0; /* start "advancing" time stamp from 0 */
> +}
> +
> +ulong get_timer_masked(void)
> +{
> + ulong now = READ_TIMER; /* current tick value */
> +
> + if (lastinc<= now) { /* normal mode (non roll) */
> + /* normal mode */
> + timestamp += now - lastinc;
> + /* move stamp forward with absolute diff ticks */
> + } else { /* we have overflow of the count down timer */
> + timestamp += now + (TIMER_LOAD_VAL - lastinc);
> + }
> + lastinc = now;
> +
> + return timestamp;
> +}
> +
> +/*
> + * This function is derived from PowerPC code (read timebase as long long).
> + * On ARM it just returns the timer value.
> + */
> +unsigned long long get_ticks(void)
> +{
> + return get_timer(0);
> +}
> +
> +/*
> + * This function is derived from PowerPC code (timebase clock frequency).
> + * On ARM it returns the number of timer ticks per second.
> + */
> +ulong get_tbclk(void)
> +{
> + return 19200000;
> +}
> diff --git a/arch/arm/include/asm/arch-msm7630/adm.h b/arch/arm/include/asm/arch-msm7630/adm.h
> new file mode 100644
> index 0000000..0e8af85
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/adm.h
> @@ -0,0 +1,28 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#ifndef __ADM_H
> +#define __ADM_H
> +
> +/* Channel #s and security domain */
> +#define ADM_CHN 8
> +#define ADM_SD 2
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/gpio.h b/arch/arm/include/asm/arch-msm7630/gpio.h
> new file mode 100644
> index 0000000..af6ddaa
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/gpio.h
> @@ -0,0 +1,47 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#ifndef __GPIO_H
> +#define __GPIO_H
> +
> +#ifndef GPIO_INPUT
> +#define GPIO_INPUT 0x0000
> +#endif
> +#ifndef GPIO_OUTPUT
> +#define GPIO_OUTPUT 0x0001
> +#endif
> +
> +#define GPIO_LEVEL 0x0000
> +#define GPIO_EDGE 0x0010
> +
> +#define GPIO_RISING 0x0020
> +#define GPIO_FALLING 0x0040
> +
> +#define GPIO_HIGH 0x0020
> +#define GPIO_LOW 0x0040
> +
> +#define GPIO_PULLUP 0x0100
> +#define GPIO_PULLDOWN 0x0200
> +
> +int gpio_config(unsigned nr, unsigned flags);
> +void gpio_set(unsigned nr, unsigned on);
> +int gpio_get(unsigned nr);
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/gpio_hw.h b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
> new file mode 100644
> index 0000000..c8244d8
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
> @@ -0,0 +1,168 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#ifndef __GPIO_HW_H
> +#define __GPIO_HW_H
> +
> +#define MSM_GPIO1_BASE 0xAC001000
> +#define MSM_GPIO2_BASE 0xAC101000
> +
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
> +
> +/* output value */
> +#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
> +#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 43-16 */
> +#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-44 */
> +#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
> +#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */
> +#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 133-107 */
> +#define GPIO_OUT_6 GPIO1_REG(0xC4) /* gpio 150-134 */
> +#define GPIO_OUT_7 GPIO1_REG(0x214) /* gpio 181-151 */
> +
> +/* same pin map as above, output enable */
> +#define GPIO_OE_0 GPIO1_REG(0x10)
> +#define GPIO_OE_1 GPIO2_REG(0x08)
> +#define GPIO_OE_2 GPIO1_REG(0x14)
> +#define GPIO_OE_3 GPIO1_REG(0x18)
> +#define GPIO_OE_4 GPIO1_REG(0x1C)
> +#define GPIO_OE_5 GPIO1_REG(0x54)
> +#define GPIO_OE_6 GPIO1_REG(0xC8)
> +#define GPIO_OE_7 GPIO1_REG(0x218)
> +
> +/* same pin map as above, input read */
> +#define GPIO_IN_0 GPIO1_REG(0x34)
> +#define GPIO_IN_1 GPIO2_REG(0x20)
> +#define GPIO_IN_2 GPIO1_REG(0x38)
> +#define GPIO_IN_3 GPIO1_REG(0x3C)
> +#define GPIO_IN_4 GPIO1_REG(0x40)
> +#define GPIO_IN_5 GPIO1_REG(0x44)
> +#define GPIO_IN_6 GPIO1_REG(0xCC)
> +#define GPIO_IN_7 GPIO1_REG(0x21C)
> +
> +/* same pin map as above, 1=edge 0=level interrup */
> +#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
> +#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
> +#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
> +#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
> +#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
> +#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0)
> +#define GPIO_INT_EDGE_6 GPIO1_REG(0xD0)
> +#define GPIO_INT_EDGE_7 GPIO1_REG(0x240)
> +
> +/* same pin map as above, 1=positive 0=negative */
> +#define GPIO_INT_POS_0 GPIO1_REG(0x70)
> +#define GPIO_INT_POS_1 GPIO2_REG(0x58)
> +#define GPIO_INT_POS_2 GPIO1_REG(0x74)
> +#define GPIO_INT_POS_3 GPIO1_REG(0x78)
> +#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
> +#define GPIO_INT_POS_5 GPIO1_REG(0xBC)
> +#define GPIO_INT_POS_6 GPIO1_REG(0xD4)
> +#define GPIO_INT_POS_7 GPIO1_REG(0x228)
> +
> +/* same pin map as above, interrupt enable */
> +#define GPIO_INT_EN_0 GPIO1_REG(0x80)
> +#define GPIO_INT_EN_1 GPIO2_REG(0x60)
> +#define GPIO_INT_EN_2 GPIO1_REG(0x84)
> +#define GPIO_INT_EN_3 GPIO1_REG(0x88)
> +#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
> +#define GPIO_INT_EN_5 GPIO1_REG(0xB8)
> +#define GPIO_INT_EN_6 GPIO1_REG(0xD8)
> +#define GPIO_INT_EN_7 GPIO1_REG(0x22C)
> +
> +/* same pin map as above, write 1 to clear interrupt */
> +#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
> +#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
> +#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
> +#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
> +#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
> +#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4)
> +#define GPIO_INT_CLEAR_6 GPIO1_REG(0xDC)
> +#define GPIO_INT_CLEAR_7 GPIO1_REG(0x230)
> +
> +/* same pin map as above, 1=interrupt pending */
> +#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
> +#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
> +#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
> +#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
> +#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
> +#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0)
> +#define GPIO_INT_STATUS_6 GPIO1_REG(0xE0)
> +#define GPIO_INT_STATUS_7 GPIO1_REG(0x234)
> +
> +
> +#define GPIO_OUT_VAL_REG_BASE 0xABC00000
> +#define GPIO_ALT_FUNC_PAGE_REG (GPIO_OUT_VAL_REG_BASE + 0x20)
> +#define GPIO_ALT_FUNC_CFG_REG (GPIO_OUT_VAL_REG_BASE + 0x24)
> +
> +
> +/* GPIO TLMM: Pullup/Pulldown */
> +#define GPIO_NO_PULL 0
> +#define GPIO_PULL_DOWN 1
> +#define GPIO_KEEPER 2
> +#define GPIO_PULL_UP 3
> +
> +/* GPIO TLMM: Drive Strength */
> +#define GPIO_2MA 0
> +#define GPIO_4MA 1
> +#define GPIO_6MA 2
> +#define GPIO_8MA 3
> +#define GPIO_10MA 4
> +#define GPIO_12MA 5
> +#define GPIO_14MA 6
> +#define GPIO_16MA 7
> +
> +#define GPIO38_GPIO_CNTRL 0x175
> +
> +/* GPIO TLMM: Status */
> +#define GPIO_ENABLE 0
> +#define GPIO_DISABLE 1
> +
> +#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
> + ((((gpio)& 0x3FF)<< 4) | \
> + ((func)& 0xf) | \
> + (((dir)& 0x1)<< 14) | \
> + (((pull)& 0x3)<< 15) | \
> + (((drvstr)& 0xF)<< 17))
> +
> +/**
> + * struct msm_gpio - GPIO pin description
> + * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
> + * @label - textual label
> + *
> + * Usually, GPIO's are operated by sets.
> + * This struct accumulate all GPIO information in single source
> + * and facilitete group operations provided by msm_gpios_xxx()
> + */
> +struct msm_gpio {
> + unsigned gpio_cfg;
> + const char *label;
> +};
> +
> +/**
> + * extract GPIO pin from bit-field used for gpio_tlmm_config
> + */
> +#define GPIO_PIN(gpio_cfg) (((gpio_cfg)>> 4)& 0x3ff)
> +#define GPIO_FUNC(gpio_cfg) (((gpio_cfg)>> 0)& 0xf)
> +#define GPIO_DIR(gpio_cfg) (((gpio_cfg)>> 14)& 0x1)
> +#define GPIO_PULL(gpio_cfg) (((gpio_cfg)>> 15)& 0x3)
> +#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg)>> 17)& 0xf)
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/iomap.h b/arch/arm/include/asm/arch-msm7630/iomap.h
> new file mode 100644
> index 0000000..186c6c2
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/iomap.h
> @@ -0,0 +1,96 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#ifndef __IOMAP_H_
> +#define __IOMAP_H_
> +
> +#define MSM_UART1_BASE 0xACA00000
> +#define MSM_UART2_BASE 0xACB00000
> +#define MSM_UART3_BASE 0xACC00000
> +
> +#define MSM_VIC_BASE 0xC0080000
> +#define MSM_TMR_BASE 0xC0100000
> +
> +#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
> +#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
> +#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
> +
> +#define GPT_REG(off) (MSM_GPT_BASE + (off))
> +#define DGT_REG(off) (MSM_DGT_BASE + (off))
> +
> +#define GPT_MATCH_VAL GPT_REG(0x0000)
> +#define GPT_COUNT_VAL GPT_REG(0x0004)
> +#define GPT_ENABLE GPT_REG(0x0008)
> +#define GPT_CLEAR GPT_REG(0x000C)
> +
> +#define DGT_MATCH_VAL DGT_REG(0x0000)
> +#define DGT_COUNT_VAL DGT_REG(0x0004)
> +#define DGT_ENABLE DGT_REG(0x0008)
> +#define DGT_CLEAR DGT_REG(0x000C)
> +#define DGT_CLK_CTL DGT_REG(0x0010)
> +
> +#define HW_REVISION_NUMBER 0xABC00270
> +
> +#define MSM_CSR_BASE 0xC0100000
> +#define MSM_GCC_BASE 0xC0182000
> +
> +#define MSM_SDC1_BASE 0xA0400000
> +#define MSM_SDC2_BASE 0xA0500000
> +#define MSM_SDC3_BASE 0xA3000000
> +#define MSM_SDC4_BASE 0xA3100000
> +
> +#define MSM_SHARED_BASE 0x00100000
> +#define MSM_CLK_CTL_BASE 0xAB800000
> +#define MSM_CLK_CTL_SH2_BASE 0xABA01000
> +
> +#define REG_BASE(off) (MSM_CLK_CTL_BASE + (off))
> +#define REG_SH2_BASE(off) (MSM_CLK_CTL_SH2_BASE + (off))
> +
> +#define SCSS_CLK_CTL 0xC0101004
> +#define SCSS_CLK_SEL 0xC0101008
> +
> +#define MSM_USB_BASE 0xA3600000
> +#define MSM_CRYPTO_BASE 0xA8400000
> +
> +#define SH2_USBH_MD_REG REG_SH2_BASE(0x2BC)
> +#define SH2_USBH_NS_REG REG_SH2_BASE(0x2C0)
> +
> +#define SH2_MDP_NS_REG REG_SH2_BASE(0x14C)
> +#define SH2_MDP_LCDC_MD_REG REG_SH2_BASE(0x38C)
> +#define SH2_MDP_LCDC_NS_REG REG_SH2_BASE(0x390)
> +#define SH2_MDP_VSYNC_REG REG_SH2_BASE(0x460)
> +#define SH2_PMDH_NS_REG REG_SH2_BASE(0x8C)
> +
> +#define SH2_GLBL_CLK_ENA_SC REG_SH2_BASE(0x3BC)
> +#define SH2_GLBL_CLK_ENA_2_SC REG_SH2_BASE(0x3C0)
> +
> +#define SH2_OWN_ROW1_BASE_REG REG_BASE(0x041C)
> +#define SH2_OWN_ROW2_BASE_REG REG_BASE(0x0424)
> +#define SH2_OWN_APPS2_BASE_REG REG_BASE(0x0414)
> +
> +#define MSM_ADM_BASE 0xAC200000
> +#define MSM_ADM_SD_OFFSET 0x00100400
> +
> +#define MSM_SAW_BASE 0xC0102000
> +
> +#define PLL_ENA_REG REG_SH2_BASE(0x0264)
> +#define PLL2_STATUS_BASE_REG REG_BASE(0x0350)
> +#define PLL2_L_VAL_ADDR REG_BASE(0x033C)
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/proc_comm.h b/arch/arm/include/asm/arch-msm7630/proc_comm.h
> new file mode 100644
> index 0000000..3df08b9
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/proc_comm.h
> @@ -0,0 +1,42 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#ifndef __PROC_COMM_H_
> +#define __PROC_COMM_H_
> +
> +void usb_clock_init(void);
> +void lcdc_clock_init(unsigned rate);
> +void mdp_clock_init(unsigned rate);
> +void uart3_clock_init(void);
> +void uart2_clock_init(void);
> +void uart1_clock_init(void);
> +void mddi_clock_init(unsigned num, unsigned rate);
> +void reboot(unsigned reboot_reason);
> +int mmc_clock_enable_disable(unsigned id, unsigned enable);
> +int mmc_clock_set_rate(unsigned id, unsigned rate);
> +int mmc_clock_get_rate(unsigned id);
> +int gpio_tlmm_config(unsigned config, unsigned disable);
> +int vreg_set_level(unsigned id, unsigned mv);
> +int vreg_enable(unsigned id);
> +int vreg_disable(unsigned id);
> +
> +#endif
> +
> +
> diff --git a/arch/arm/include/asm/arch-msm7630/sys_proto.h b/arch/arm/include/asm/arch-msm7630/sys_proto.h
> new file mode 100644
> index 0000000..c679d92
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/sys_proto.h
> @@ -0,0 +1,29 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN& TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#ifndef _SYS_PROTO_H_
> +#define _SYS_PROTO_H_
> +
> +void pll8_enable(void);
> +void clock_init(void);
> +void __cpu_early_init(void);
> +
> +#endif
> +
> --
> 1.7.1
>
>
> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
>


Amicalement,
--
Albert.
Mohamed Haneef
2012-03-05 14:39:14 UTC
Permalink
* Support for Qualcomm msm7630 SoC

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---

Changes for v2:
- removed BIT() macro and replacing with (3 << 6) in the macro VERG_CONFIG
- removed the unwanted comment line
- removed Intitalize the Watchpoint Controll Register to zero, since optional
- removed reset_timer_masked function since it is not used any where


arch/arm/cpu/armv7/msm7630/Makefile | 59 +++
arch/arm/cpu/armv7/msm7630/acpuclock.c | 327 +++++++++++++
arch/arm/cpu/armv7/msm7630/board.c | 57 +++
arch/arm/cpu/armv7/msm7630/config.mk | 1 +
arch/arm/cpu/armv7/msm7630/gpio.c | 229 +++++++++
arch/arm/cpu/armv7/msm7630/lowlevel_init.S | 623 +++++++++++++++++++++++++
arch/arm/cpu/armv7/msm7630/timer.c | 142 ++++++
arch/arm/include/asm/arch-msm7630/adm.h | 28 ++
arch/arm/include/asm/arch-msm7630/gpio.h | 47 ++
arch/arm/include/asm/arch-msm7630/gpio_hw.h | 168 +++++++
arch/arm/include/asm/arch-msm7630/iomap.h | 96 ++++
arch/arm/include/asm/arch-msm7630/proc_comm.h | 42 ++
arch/arm/include/asm/arch-msm7630/sys_proto.h | 29 ++
13 files changed, 1848 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h

diff --git a/arch/arm/cpu/armv7/msm7630/Makefile b/arch/arm/cpu/armv7/msm7630/Makefile
new file mode 100644
index 0000000..d9dfade
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/Makefile
@@ -0,0 +1,59 @@
+#
+# (C) Copyright 2012
+# LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+#
+# (C) Copyright 2010,2011 Nvidia Corporation.
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+# The AVP is ARMv4T architecture so we must use special compiler
+# flags for any startup files it might use.
+#CFLAGS_arch/arm/cpu/armv7/tegra2/ap20.o += -march=armv4t
+#CFLAGS_arch/arm/cpu/armv7/tegra2/clock.o += -march=armv4t
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).o
+
+SOBJS-y := lowlevel_init.o
+COBJS-y := board.o
+COBJS-y += timer.o
+COBJS-y += acpuclock.o
+COBJS-y += gpio.o
+
+ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS-y))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/msm7630/acpuclock.c b/arch/arm/cpu/armv7/msm7630/acpuclock.c
new file mode 100644
index 0000000..73570fc
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/acpuclock.c
@@ -0,0 +1,327 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <common.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/proc_comm.h>
+#define ACPU_806MHZ 42
+#define ACPU_1024MHZ 53
+#define ACPU_1200MHZ 125
+#define ACPU_1400MHZ 73
+
+/* Macros to select PLL2 with divide by 1 */
+#define ACPU_SRC_SEL 3
+#define ACPU_SRC_DIV 0
+
+#define VREG_CONFIG (3 << 6)
+#define VREG_DATA (VREG_CONFIG | (VREF_SEL << 5))
+#define VREF_SEL 1 /* 0: 0.625V (50mV step), 1: 0.3125V (25mV step). */
+#define V_STEP (25 * (2 - VREF_SEL)) /* Minimum voltage step size. */
+#define MV(mv) ((mv) / (!((mv) % V_STEP)))
+/* mv = (750mV + (raw * 25mV)) * (2 - VREF_SEL) */
+#define VDD_RAW(mv) (((MV(mv) / V_STEP) - 30) | VREG_DATA)
+
+
+/* enum for SDC CLK IDs */
+enum {
+ SDC1_CLK = 19,
+ SDC1_PCLK = 20,
+ SDC2_CLK = 21,
+ SDC2_PCLK = 22,
+ SDC3_CLK = 23,
+ SDC3_PCLK = 24,
+ SDC4_CLK = 25,
+ SDC4_PCLK = 26
+};
+
+/* Zero'th entry is dummy */
+static uint8_t sdc_clk[] = {0, SDC1_CLK, SDC2_CLK, SDC3_CLK, SDC4_CLK};
+static uint8_t sdc_pclk[] = {0, SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK};
+
+void spm_init(void)
+{
+ writel(0x05, MSM_SAW_BASE + 0x10); /* MSM_SPM_REG_SAW_CFG */
+ writel(0x18, MSM_SAW_BASE + 0x14); /* MSM_SPM_REG_SAW_SPM_CTL */
+ writel(0x00006666, MSM_SAW_BASE + 0x18);
+ /* MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY */
+ writel(0xFF000666, MSM_SAW_BASE + 0x1C);
+ /* MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY */
+ writel(0x01, MSM_SAW_BASE + 0x24); /* MSM_SPM_REG_SAW_SLP_CLK_EN */
+ writel(0x03, MSM_SAW_BASE + 0x28);
+ /* MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN */
+ writel(0x00, MSM_SAW_BASE + 0x2C);
+ /* MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN */
+ writel(0x01, MSM_SAW_BASE + 0x30); /* MSM_SPM_REG_SAW_SLP_CLMP_EN */
+ writel(0x00, MSM_SAW_BASE + 0x34); /* MSM_SPM_REG_SAW_SLP_RST_EN */
+ writel(0x00, MSM_SAW_BASE + 0x38); /* MSM_SPM_REG_SAW_SPM_MPM_CFG */
+}
+
+/* Configures msmc2 voltage. vlevel is in mV */
+void msmc2_config(unsigned vlevel)
+{
+ unsigned val;
+ val = readl(MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+ val &= ~0xFF;
+ val |= VDD_RAW(vlevel);
+ writel(val, MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+ /* Wait for PMIC state to return to idle and for VDD to stabilize */
+ while (((readl(MSM_SAW_BASE + 0x0C) >> 20) & 0x3) != 0)
+ ;
+ udelay(160);
+}
+
+void enable_pll(unsigned num)
+{
+ unsigned reg_val;
+ reg_val = readl(PLL_ENA_REG);
+ reg_val |= (1 << num);
+ writel(reg_val, PLL_ENA_REG);
+ /* Wait until PLL is enabled */
+ while ((readl(PLL2_STATUS_BASE_REG) & (1 << 16)) == 0)
+ ;
+}
+
+void acpu_clock_init(void)
+{
+ unsigned clk, reg_clksel, reg_clkctl, src_sel;
+ /* Fixing msmc2 voltage */
+ spm_init();
+ clk = readl(PLL2_L_VAL_ADDR) & 0xFF;
+ if (clk == ACPU_806MHZ)
+ msmc2_config(1100);
+ else if (clk == ACPU_1024MHZ || clk == ACPU_1200MHZ)
+ msmc2_config(1200);
+ else if (clk == ACPU_1400MHZ)
+ msmc2_config(1250);
+ /* Enable pll 2 */
+ enable_pll(2);
+ reg_clksel = readl(SCSS_CLK_SEL);
+ /* CLK_SEL_SRC1NO */
+ src_sel = reg_clksel & 1;
+ /* Program clock source and divider. */
+ reg_clkctl = readl(SCSS_CLK_CTL);
+ reg_clkctl &= ~(0xFF << (8 * src_sel));
+ reg_clkctl |= ACPU_SRC_SEL << (4 + 8 * src_sel);
+ reg_clkctl |= ACPU_SRC_DIV << (0 + 8 * src_sel);
+ writel(reg_clkctl, SCSS_CLK_CTL);
+ /* Toggle clock source. */
+ reg_clksel ^= 1;
+ /* Program clock source selection. */
+ writel(reg_clksel, SCSS_CLK_SEL);
+}
+
+void hsusb_clock_init(void)
+{
+ int val = 0;
+ unsigned sh2_own_row2;
+ unsigned sh2_own_row2_hsusb_mask = (1 << 11);
+
+ sh2_own_row2 = readl(SH2_OWN_ROW2_BASE_REG);
+ if (sh2_own_row2 & sh2_own_row2_hsusb_mask) {
+ /* USB local clock control enabled */
+ /* Set value in MD register */
+ val = 0x5DF;
+ writel(val, SH2_USBH_MD_REG);
+ /* Set value in NS register */
+ val = 1 << 8;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ val = 1 << 11;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ val = 1 << 9;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ val = 1 << 13;
+ val = val | readl(SH2_USBH_NS_REG);
+ writel(val, SH2_USBH_NS_REG);
+ /* Enable USBH_P_CLK */
+ val = 1 << 25;
+ val = val | readl(SH2_GLBL_CLK_ENA_SC);
+ writel(val, SH2_GLBL_CLK_ENA_SC);
+ } else
+ /* USB local clock control not enabled; use proc comm */
+ usb_clock_init();
+
+}
+
+void adm_enable_clock(void)
+{
+ unsigned int val = 0;
+
+ /* Enable ADM_CLK */
+ val = 1 << 5;
+ val = val | readl(SH2_GLBL_CLK_ENA_SC);
+ writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+void mdp_lcdc_clock_init(void)
+{
+ unsigned int val = 0;
+ unsigned sh2_own_apps2;
+ unsigned sh2_own_apps2_lcdc_mask = (1 << 3);
+
+ sh2_own_apps2 = readl(SH2_OWN_APPS2_BASE_REG);
+ if (sh2_own_apps2 & sh2_own_apps2_lcdc_mask) {
+ /* MDP local clock control enabled */
+ /* Select clock source and divider */
+ val = 0x29;
+ val = val | readl(SH2_MDP_NS_REG);
+ writel(val, SH2_MDP_NS_REG);
+
+ /* Enable MDP source clock(root) */
+ val = 1 << 11;
+ val = val | readl(SH2_MDP_NS_REG);
+ writel(val, SH2_MDP_NS_REG);
+
+ /* Enable graphics clock(branch) */
+ val = 1 << 9;
+ val = val | readl(SH2_MDP_NS_REG);
+ writel(val, SH2_MDP_NS_REG);
+
+ /* Enable MDP_P_CLK */
+ val = 1 << 6;
+ val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+ writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+ /* Enable AXI_MDP_CLK */
+ val = 1 << 29;
+ val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+ writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+ /* LCDC local clock control enabled */
+ /* Set value in MD register */
+ val = 0x1FFF9;
+ writel(val, SH2_MDP_LCDC_MD_REG);
+
+ /* Set MDP_LCDC_N_VAL in NS register */
+ val = 0xFFFA << 16;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Set clock source */
+ val = 1;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Set divider */
+ val = 3 << 3;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Set MN counter mode */
+ val = 2 << 5;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable MN counter */
+ val = 1 << 8;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable mdp_lcdc_src(root) clock */
+ val = 1 << 11;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable mdp_lcdc_pclk(branch) clock */
+ val = 1 << 9;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+
+ /* Enable mdp_lcdc_pad_pclk(branch) clock */
+ val = 1 << 12;
+ val = val | readl(SH2_MDP_LCDC_NS_REG);
+ writel(val, SH2_MDP_LCDC_NS_REG);
+ } else {
+ /* MDP local clock control not enabled; use proc comm */
+ mdp_clock_init(122880000);
+ /* LCDC local clock control not enabled; use proc comm */
+ lcdc_clock_init(27648000);
+ }
+}
+
+void mddi_pmdh_clock_init(void)
+{
+ unsigned int val = 0;
+ unsigned sh2_own_row1;
+ unsigned sh2_own_row1_pmdh_mask = (1 << 19);
+
+ sh2_own_row1 = readl(SH2_OWN_ROW1_BASE_REG);
+ if (sh2_own_row1 & sh2_own_row1_pmdh_mask) {
+ /* Select clock source and divider */
+ val = 1;
+ val |= (1 << 3);
+ val = val | readl(SH2_PMDH_NS_REG);
+ writel(val, SH2_PMDH_NS_REG);
+
+ /* Enable PMDH_SRC (root) signal */
+ val = 1 << 11;
+ val = val | readl(SH2_PMDH_NS_REG);
+ writel(val, SH2_PMDH_NS_REG);
+
+ /* Enable PMDH_P_CLK */
+ val = 1 << 4;
+ val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+ writel(val, SH2_GLBL_CLK_ENA_2_SC);
+ } else
+ /* MDDI local clock control not enabled; use proc comm */
+ mddi_clock_init(0, 480000000);
+}
+
+void ce_clock_init(void)
+{
+ unsigned int val = 0;
+
+ /* Enable CE_CLK */
+ val = 1 << 6;
+ val = val | readl(SH2_GLBL_CLK_ENA_SC);
+ writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+#ifdef CONFIG_QC_MMC
+/* Configure MMC clock */
+void clock_config_mmc(uint32_t interface, uint32_t freq)
+{
+ uint32_t reg = 0;
+
+ if (mmc_clock_set_rate(sdc_clk[interface], freq) < 0)
+ printf("Failure setting clock rate for MCLK - "
+ "clk_rate: %d\n!", freq);
+
+ /* enable clock */
+ if (mmc_clock_enable_disable(sdc_clk[interface], MMC_CLK_ENABLE) < 0)
+ printf("Failure enabling MMC Clock!\n");
+
+ reg |= MMC_BOOT_MCI_CLK_ENABLE;
+ reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
+ reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
+ writel(reg, MMC_BOOT_MCI_CLK);
+}
+
+/* Intialize MMC clock */
+void clock_init_mmc(uint32_t interface)
+{
+ if (mmc_clock_enable_disable(sdc_pclk[interface], MMC_CLK_ENABLE) < 0)
+ printf("Failure enabling PCLK!\n");
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/board.c b/arch/arm/cpu/armv7/msm7630/board.c
new file mode 100644
index 0000000..c7b8204
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/board.c
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/sys_proto.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void set_vector_base(unsigned long addr)
+{
+ __asm__ volatile ("mcr p15, 0, %0, c12, c0, 0" : : "r" (addr));
+}
+
+int dram_init(void)
+{
+ /* We do not initialise DRAM here. We just query the size */
+ gd->ram_size = PHYS_SDRAM_1_SIZE;
+ return 0;
+}
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+
+}
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init()
+{
+ __cpu_early_init();
+ return 0;
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/config.mk b/arch/arm/cpu/armv7/msm7630/config.mk
new file mode 100644
index 0000000..935a147
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/config.mk
@@ -0,0 +1 @@
+PLATFORM_CPPFLAGS += -march=armv7-a
diff --git a/arch/arm/cpu/armv7/msm7630/gpio.c b/arch/arm/cpu/armv7/msm7630/gpio.c
new file mode 100644
index 0000000..daa6d66
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/gpio.c
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/proc_comm.h>
+#include <asm/arch/gpio_hw.h>
+
+struct gpioregs {
+ unsigned out;
+ unsigned in;
+ unsigned int_status;
+ unsigned int_clear;
+ unsigned int_en;
+ unsigned int_edge;
+ unsigned int_pos;
+ unsigned oe;
+};
+
+static struct gpioregs GPIO_REGS[] = {
+ {
+ .out = GPIO_OUT_0,
+ .in = GPIO_IN_0,
+ .int_status = GPIO_INT_STATUS_0,
+ .int_clear = GPIO_INT_CLEAR_0,
+ .int_en = GPIO_INT_EN_0,
+ .int_edge = GPIO_INT_EDGE_0,
+ .int_pos = GPIO_INT_POS_0,
+ .oe = GPIO_OE_0,
+ },
+ {
+ .out = GPIO_OUT_1,
+ .in = GPIO_IN_1,
+ .int_status = GPIO_INT_STATUS_1,
+ .int_clear = GPIO_INT_CLEAR_1,
+ .int_en = GPIO_INT_EN_1,
+ .int_edge = GPIO_INT_EDGE_1,
+ .int_pos = GPIO_INT_POS_1,
+ .oe = GPIO_OE_1,
+ },
+ {
+ .out = GPIO_OUT_2,
+ .in = GPIO_IN_2,
+ .int_status = GPIO_INT_STATUS_2,
+ .int_clear = GPIO_INT_CLEAR_2,
+ .int_en = GPIO_INT_EN_2,
+ .int_edge = GPIO_INT_EDGE_2,
+ .int_pos = GPIO_INT_POS_2,
+ .oe = GPIO_OE_2,
+ },
+ {
+ .out = GPIO_OUT_3,
+ .in = GPIO_IN_3,
+ .int_status = GPIO_INT_STATUS_3,
+ .int_clear = GPIO_INT_CLEAR_3,
+ .int_en = GPIO_INT_EN_3,
+ .int_edge = GPIO_INT_EDGE_3,
+ .int_pos = GPIO_INT_POS_3,
+ .oe = GPIO_OE_3,
+ },
+ {
+ .out = GPIO_OUT_4,
+ .in = GPIO_IN_4,
+ .int_status = GPIO_INT_STATUS_4,
+ .int_clear = GPIO_INT_CLEAR_4,
+ .int_en = GPIO_INT_EN_4,
+ .int_edge = GPIO_INT_EDGE_4,
+ .int_pos = GPIO_INT_POS_4,
+ .oe = GPIO_OE_4,
+ },
+ {
+ .out = GPIO_OUT_5,
+ .in = GPIO_IN_5,
+ .int_status = GPIO_INT_STATUS_5,
+ .int_clear = GPIO_INT_CLEAR_5,
+ .int_en = GPIO_INT_EN_5,
+ .int_edge = GPIO_INT_EDGE_5,
+ .int_pos = GPIO_INT_POS_5,
+ .oe = GPIO_OE_5,
+ },
+ {
+ .out = GPIO_OUT_6,
+ .in = GPIO_IN_6,
+ .int_status = GPIO_INT_STATUS_6,
+ .int_clear = GPIO_INT_CLEAR_6,
+ .int_en = GPIO_INT_EN_6,
+ .int_edge = GPIO_INT_EDGE_6,
+ .int_pos = GPIO_INT_POS_6,
+ .oe = GPIO_OE_6,
+ },
+ {
+ .out = GPIO_OUT_7,
+ .in = GPIO_IN_7,
+ .int_status = GPIO_INT_STATUS_7,
+ .int_clear = GPIO_INT_CLEAR_7,
+ .int_en = GPIO_INT_EN_7,
+ .int_edge = GPIO_INT_EDGE_7,
+ .int_pos = GPIO_INT_POS_7,
+ .oe = GPIO_OE_7,
+ },
+};
+
+static struct gpioregs *find_gpio(unsigned n, unsigned *bit)
+{
+ if (n > 150) {
+ *bit = 1 << (n - 151);
+ return GPIO_REGS + 7;
+ }
+ if (n > 133) {
+ *bit = 1 << (n - 134);
+ return GPIO_REGS + 6;
+ }
+ if (n > 106) {
+ *bit = 1 << (n - 107);
+ return GPIO_REGS + 5;
+ }
+ if (n > 94) {
+ *bit = 1 << (n - 95);
+ return GPIO_REGS + 4;
+ }
+ if (n > 67) {
+ *bit = 1 << (n - 68);
+ return GPIO_REGS + 3;
+ }
+ if (n > 43) {
+ *bit = 1 << (n - 44);
+ return GPIO_REGS + 2;
+ }
+ if (n > 15) {
+ *bit = 1 << (n - 16);
+ return GPIO_REGS + 1;
+ }
+ *bit = 1 << n;
+ return GPIO_REGS + 0;
+}
+
+int gpio_config(unsigned n, unsigned flags)
+{
+ struct gpioregs *r;
+ unsigned b;
+ unsigned v;
+
+ r = find_gpio(n, &b);
+ if (!r)
+ return -1;
+
+ v = readl(r->oe);
+ if (flags & GPIO_OUTPUT)
+ writel(v | b, r->oe);
+ else
+ writel(v & (~b), r->oe);
+ return 0;
+}
+
+void gpio_set(unsigned n, unsigned on)
+{
+ struct gpioregs *r;
+ unsigned b;
+ unsigned v;
+
+ r = find_gpio(n, &b);
+ if (r == 0)
+ return;
+
+ v = readl(r->out);
+ if (on)
+ writel(v | b, r->out);
+ else
+ writel(v & (~b), r->out);
+}
+
+int gpio_get(unsigned n)
+{
+ struct gpioregs *r;
+ unsigned b;
+
+ r = find_gpio(n, &b);
+ if (r == 0)
+ return 0;
+ return (readl(r->in) & b) ? 1 : 0;
+}
+
+void platform_config_interleaved_mode_gpios(void)
+{
+ /* configure EB2_CS1 through GPIO86 */
+ writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
+ writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
+ /* configure the EBI2_BUSY1_N through GPIO115 */
+ writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
+ writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
+}
+
+/* Enables all gpios passed in table*/
+int platform_gpios_enable(const struct msm_gpio *table, int size)
+{
+ int rc;
+ int i;
+ const struct msm_gpio *g;
+ for (i = 0; i < size; i++) {
+ g = table + i;
+ /* Enable gpio */
+ rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
+ if (rc)
+ goto err;
+ }
+ return 0;
+err:
+ return rc;
+}
+
diff --git a/arch/arm/cpu/armv7/msm7630/lowlevel_init.S b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
new file mode 100644
index 0000000..ef63770
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
@@ -0,0 +1,623 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+#include <version.h>
+
+.text
+.code 32
+
+#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
+#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
+
+/*
+ ; LVT Ring Osc counter
+ ; used to determine sense amp settings
+ ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11
+*/
+.equ CLK_CTL_BASE, 0xA8600000
+.equ A_GLBL_CLK_ENA, 0x0000
+.equ A_PRPH_WEB_NS_REG,0x0080
+.equ A_MSM_CLK_RINGOSC,0x00D0
+.equ A_TCXO_CNT, 0x00D4
+.equ A_TCXO_CNT_DONE, 0x00D8
+.equ A_RINGOSC_CNT, 0x00DC
+.equ A_MISC_CLK_CTL, 0x0108
+.equ CLK_TEST, 0xA8600114
+.equ SPSS_CSR_BASE, 0xAC100000
+.equ A_SCRINGOSC, 0x0510
+
+//;; Number of TCXO cycles to count ring oscillations
+.equ TCXO_CNT_VAL, 0x100
+
+//; Halcyon addresses
+.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register
+.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register
+
+//; SCORPION_L1_ACC (1:0) Fuses bit location
+.equ L1_ACC_BIT_0, 12 //;12th bit of TCSR_CONF_FUSE_4
+.equ L1_ACC_BIT_1, 13 //;13th bit of TCSR_CONF_FUSE_4
+//; SCORPION_L2_ACC (2:0) Fuses bit location
+.equ L2_ACC_BIT_0, 25 //;25th bit of TCSR_CONF_FUSE_1
+.equ L2_ACC_BIT_1, 10 //;10th bit of TCSR_CONF_FUSE_4
+.equ L2_ACC_BIT_2, 11 //;11th bit of TCSR_CONF_FUSE_4
+
+//; CP15: PVR2F0 values according to SCORPION_L1_ACC (1:0)
+.equ PVR2F0_00, 0x00000000
+.equ PVR2F0_01, 0x04000000
+.equ PVR2F0_10, 0x08000000
+.equ PVR2F0_11, 0x0C000000
+
+//; CP15: PVR2F1 values according to SCORPION_L1_ACC (1:0)
+.equ PVR2F1_00, 0x00000008
+.equ PVR2F1_01, 0x00000008
+.equ PVR2F1_10, 0x00000208
+.equ PVR2F1_11, 0x00000208
+
+//; CP15: PVR0F2 values according to SCORPION_L1_ACC (1:0)
+.equ PVR0F2_00, 0x00000000
+.equ PVR0F2_01, 0x00000000
+.equ PVR0F2_10, 0x00000200
+.equ PVR0F2_11, 0x00000200
+
+//; CP15: PVR0F0 values according to SCORPION_L1_ACC (1:0)
+.equ PVR0F0_00, 0x7F000000
+.equ PVR0F0_01, 0x7F000400
+.equ PVR0F0_10, 0x7F000000
+.equ PVR0F0_11, 0x7F000400
+
+//; CP15: L2VR3F1 values according to SCORPION_L2_ACC (2:0)
+.equ L2VR3F1_000, 0x00FFFF60
+.equ L2VR3F1_001, 0x00FFFF40
+.equ L2VR3F1_010, 0x00FFFC60
+.equ L2VR3F1_011, 0x00FFFC40
+.equ L2VR3F1_100, 0x00FCFF60
+.equ L2VR3F1_101, 0x00FCFF40
+.equ L2VR3F1_110, 0x00FCFC60
+.equ L2VR3F1_111, 0x00FCFC40
+
+
+
+
+_TEXT_BASE:
+ .word CONFIG_SYS_TEXT_BASE @ sdram load addr from config file
+
+.global invalidate_dcache
+invalidate_dcache:
+ mov pc, lr
+
+ .align 5
+.globl lowlevel_init
+lowlevel_init:
+ mov pc, lr @ back to arch calling code
+
+.global reset_cpu
+reset_cpu:
+_loop_forever:
+ b _loop_forever
+
+.globl SET_SA
+SET_SA:
+
+ //;--------------------------------------------------------------------
+ //; Fuse bits used to determine sense amp settings
+ //;--------------------------------------------------------------------
+
+ //; Reading L1_ACC
+ ldr r4, = 0x0
+
+ //; Read L1_ACC_BIT_0
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L1_ACC_BIT_0
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ orr r4, r3, r4
+
+ //; Read L1_ACC_BIT_1
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L1_ACC_BIT_1
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ mov r3, r3, LSL #1
+ orr r4, r3, r4
+
+l1_ck_0:
+ //; if L1_[1:0] == 00
+ ldr r5, = 0x0
+ cmp r4, r5
+ bne l1_ck_1
+ ldr r0, =PVR0F0_00
+ ldr r1, =PVR0F2_00
+ ldr r2, =PVR2F0_00
+ ldr r3, =PVR2F1_00
+ b WRITE_L1_SA_SETTINGS
+
+l1_ck_1:
+ //; if L1_[1:0] == 01
+ ldr r1, = 0x01
+ cmp r4, r1
+ bne l1_ck_2
+ ldr r0, =PVR0F0_01
+ ldr r1, =PVR0F2_01
+ ldr r2, =PVR2F0_01
+ ldr r3, =PVR2F1_01
+ b WRITE_L1_SA_SETTINGS
+
+l1_ck_2:
+ //; if L1_[2:0] == 10
+ ldr r1, = 0x02
+ cmp r4, r1
+ bne l1_ck_3
+ ldr r0, =PVR0F0_10
+ ldr r1, =PVR0F2_10
+ ldr r2, =PVR2F0_10
+ ldr r3, =PVR2F1_10
+ b WRITE_L1_SA_SETTINGS
+
+l1_ck_3:
+ //; if L1_[2:0] == 11
+ ldr r1, = 0x03
+ cmp r4, r1
+ ldr r0, =PVR0F0_11
+ ldr r1, =PVR0F2_11
+ ldr r2, =PVR2F0_11
+ ldr r3, =PVR2F1_11
+ b WRITE_L1_SA_SETTINGS
+
+
+WRITE_L1_SA_SETTINGS:
+
+ //;WCP15_PVR0F0 r0
+ mcr p15, 0x0, r0, c15, c15, 0x0 //; write R0 to PVR0F0
+
+ //;WCP15_PVR0F2 r1
+ mcr p15, 0x0, r1, c15, c15, 0x2 //; write R1 to PVR0F2
+
+ //;WCP15_PVR2F0 r2
+ mcr p15, 0x2, r2, c15, c15, 0x0 //; write R2 to PVR2F0
+
+ // Disable predecode repair cache on certain Scorpion revisions
+ // (Raptor V2 and earlier, or Halcyon V1)
+ mrc p15, 0, r1, c0, c0, 0 //; MIDR
+ BIC r2, r1, #0xf0 //; check for Halcyon V1
+ ldr r4, =0x511f0000
+ cmp r2, r4
+ bne PVR2F1
+
+DPRC:
+ mrc p15, 0, r1, c15, c15, 2 //; PVR0F2
+ orr r1, r1, #0x10 //; enable bit 4
+ mcr p15, 0, r1, c15, c15, 2 //; disable predecode repair cache
+
+PVR2F1:
+ //;WCP15_PVR2F1 r3
+ mcr p15, 0x2, r3, c15, c15, 0x1 //; write R3 to PVR2F1
+
+ //; Reading L2_ACC
+ ldr r4, = 0x0
+
+ //; Read L2_ACC_BIT_0
+ ldr r1, =TCSR_CONF_FUSE_1
+ ldr r2, =L2_ACC_BIT_0
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ orr r4, r3, r4
+
+ //; Read L2_ACC_BIT_1
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L2_ACC_BIT_1
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ mov r3, r3, LSL #1
+ orr r4, r3, r4
+
+ //; Read L2_ACC_BIT_2
+ ldr r1, =TCSR_CONF_FUSE_4
+ ldr r2, =L2_ACC_BIT_2
+ ldr r3, [r1]
+ mov r3, r3, LSR r2
+ and r3, r3, #1
+ mov r3, r3, LSL #2
+ orr r4, r3, r4
+
+l2_ck_0:
+ //; if L2_[2:0] == 000
+ ldr r5, = 0x0
+ cmp r4, r5
+ bne l2_ck_1
+ ldr r0, =L2VR3F1_000
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_1:
+ //; if L2_[2:0] == 001
+ ldr r5, = 0x1
+ cmp r4, r5
+ bne l2_ck_2
+ ldr r0, =L2VR3F1_001
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_2:
+ //; if L2_[2:0] == 010
+ ldr r5, = 0x2
+ cmp r4, r5
+ bne l2_ck_3
+ ldr r0, =L2VR3F1_010
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_3:
+ //; if L2_[2:0] == 011
+ ldr r5, = 0x3
+ cmp r4, r5
+ bne l2_ck_4
+ ldr r0, =L2VR3F1_011
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_4:
+ //; if L2_[2:0] == 100
+ ldr r5, = 0x4
+ cmp r4, r5
+ bne l2_ck_5
+ ldr r0, =L2VR3F1_100
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_5:
+ //; if L2_[2:0] == 101
+ ldr r5, = 0x5
+ cmp r4, r5
+ bne l2_ck_6
+ ldr r0, =L2VR3F1_101
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_6:
+ //; if L2_[2:0] == 110
+ ldr r5, = 0x6
+ cmp r4, r5
+ bne l2_ck_7
+ ldr r0, =L2VR3F1_110
+ b WRITE_L2_SA_SETTINGS
+
+l2_ck_7:
+ //; if L2_[2:0] == 111
+ ldr r5, = 0x7
+ cmp r4, r5
+ ldr r0, =L2VR3F1_111
+ b WRITE_L2_SA_SETTINGS
+
+WRITE_L2_SA_SETTINGS:
+ //;WCP15_L2VR3F1 r0
+ mcr p15, 0x3, r0, c15, c15, 0x1 //;write r0 to L2VR3F1
+ DSB
+ ISB
+
+ ldr r0, =0 //;make sure the registers we touched
+ ldr r1, =0 //;are cleared when we return
+ ldr r2, =0
+ ldr r3, =0
+ ldr r4, =0
+ ldr r5, =0
+
+ mrs r0, cpsr
+ orr r0, r0, #(1<<7)
+ msr cpsr_c, r0
+
+ //; routine complete
+ pop {r5-r12,pc}
+
+.ltorg
+
+.globl __cpu_early_init
+__cpu_early_init:
+
+ //; Zero out r0 for use throughout this code. All other GPRs
+ //; (r1-r3) are set throughout this code to help establish
+ //; a consistent startup state for any code that follows.
+ //; Users should add code at the end of this routine to establish
+ //; their own stack address (r13), add translation page tables, enable
+ //; the caches, etc.
+ push {r5-r12,r14}
+ mov r0, #0x0
+
+
+ //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA
+ //; API to dynamically configure cache for slow/nominal/fast parts
+
+ //; DCIALL to invalidate L2 cache bank (needs to be run 4 times,
+ //; once per bank)
+ //; This must be done early in code (prior to enabling the caches)
+ mov r1, #0x2
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank D ([15:14] == 2'b00)
+ orr r1, r1, #0x00004000
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank C ([15:14] == 2'b01)
+ add r1, r1, #0x00004000
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank B ([15:14] == 2'b10)
+ add r1, r1, #0x00004000
+ mcr p15, 0, r1, c9, c0, 6 //; DCIALL bank A ([15:14] == 2'b11)
+
+ //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's
+ //; and have all address bits (AM) participate.
+ //; Different settings can be used to improve performance
+ // movW r1, #0x01FF
+.word 0xe30011ff // hardcoded movW instruction due to lack of compiler support
+ // movT r1, #0x01FF
+.word 0xe34011ff // hardcoded movT instruction due to lack of compiler support
+ mcr p15, 7, r1, c15, c0, 2 //; WCP15_BPCR
+
+
+ //; Initialize all I$ Victim Registers to 0 for startup
+ mcr p15, 0, r0, c9, c1, 0 //; WCP15_ICVIC0 r0
+ mcr p15, 0, r0, c9, c1, 1 //; WCP15_ICVIC1 r0
+ mcr p15, 0, r0, c9, c1, 2 //; WCP15_ICVIC2 r0
+ mcr p15, 0, r0, c9, c1, 3 //; WCP15_ICVIC3 r0
+ mcr p15, 0, r0, c9, c1, 4 //; WCP15_ICVIC4 r0
+ mcr p15, 0, r0, c9, c1, 5 //; WCP15_ICVIC5 r0
+ mcr p15, 0, r0, c9, c1, 6 //; WCP15_ICVIC5 r0
+ mcr p15, 0, r0, c9, c1, 7 //; WCP15_ICVIC7 r0
+
+ //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0
+ mcr p15, 1, r0, c9, c1, 0 //; WCP15_ICFLOOR0 r0
+ mcr p15, 1, r0, c9, c1, 1 //; WCP15_ICFLOOR1 r0
+ mcr p15, 1, r0, c9, c1, 2 //; WCP15_ICFLOOR2 r0
+ mcr p15, 1, r0, c9, c1, 3 //; WCP15_ICFLOOR3 r0
+ mcr p15, 1, r0, c9, c1, 4 //; WCP15_ICFLOOR4 r0
+ mcr p15, 1, r0, c9, c1, 5 //; WCP15_ICFLOOR5 r0
+ mcr p15, 1, r0, c9, c1, 6 //; WCP15_ICFLOOR6 r0
+ mcr p15, 1, r0, c9, c1, 7 //; WCP15_ICFLOOR7 r0
+
+ //; Initialize all D$ Victim Registers to 0
+ mcr p15, 2, r0, c9, c1, 0 //; WP15_DCVIC0 r0
+ mcr p15, 2, r0, c9, c1, 1 //; WP15_DCVIC1 r0
+ mcr p15, 2, r0, c9, c1, 2 //; WP15_DCVIC2 r0
+ mcr p15, 2, r0, c9, c1, 3 //; WP15_DCVIC3 r0
+ mcr p15, 2, r0, c9, c1, 4 //; WP15_DCVIC4 r0
+ mcr p15, 2, r0, c9, c1, 5 //; WP15_DCVIC5 r0
+ mcr p15, 2, r0, c9, c1, 6 //; WP15_DCVIC6 r0
+ mcr p15, 2, r0, c9, c1, 7 //; WP15_DCVIC7 r0
+
+ //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0
+ mcr p15, 3, r0, c9, c1, 0 //; WCP15_DCFLOOR0 r0
+ mcr p15, 3, r0, c9, c1, 1 //; WCP15_DCFLOOR1 r0
+ mcr p15, 3, r0, c9, c1, 2 //; WCP15_DCFLOOR2 r0
+ mcr p15, 3, r0, c9, c1, 3 //; WCP15_DCFLOOR3 r0
+ mcr p15, 3, r0, c9, c1, 4 //; WCP15_DCFLOOR4 r0
+ mcr p15, 3, r0, c9, c1, 5 //; WCP15_DCFLOOR5 r0
+ mcr p15, 3, r0, c9, c1, 6 //; WCP15_DCFLOOR6 r0
+ mcr p15, 3, r0, c9, c1, 7 //; WCP15_DCFLOOR7 r0
+
+ //; Initialize ASID to zero
+ mcr p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0
+
+ //; ICIALL to invalidate entire I-Cache
+ mcr p15, 0, r0, c7, c5, 0 //; ICIALLU
+
+ //; DCIALL to invalidate entire D-Cache
+ mcr p15, 0, r0, c9, c0, 6 //; DCIALL r0
+
+ //; Initialize ADFSR to zero
+ mcr p15, 0, r0, c5, c1, 0 //; ADFSR r0
+
+ //; Initialize EFSR to zero
+ mcr p15, 7, r0, c15, c0, 1 //; EFSR r0
+
+ //; The VBAR (Vector Base Address Register) should be initialized
+ //; early in your code. We are setting it to zero
+ mcr p15, 0, r0, c12, c0, 0 //; WCP15_VBAR r0
+
+ //; Ensure the mcr's above have completed their operation
+ //; before continuing
+ DSB
+ ISB
+
+ //; Setup CCPR - Cache Coherency Policy Register
+ //; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing)
+ //; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable)
+ movw r2, #0x88
+ mcr p15, 0, r2, c10, c4, 2
+
+ //;-------------------------------------------------------------------
+ //; There are a number of registers that must be set prior to enabling
+ //; the MMU. The DCAR is one of these registers. We are setting
+ //; it to zero (no access) to easily detect improper setup in subsequent
+ //; code sequences
+ //;-------------------------------------------------------------------
+ //; Setup DACR (Domain Access Control Register) to zero
+ mcr p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0
+
+ //; Setup DCLKCR to allow normal D-Cache line fills
+ mcr p15, 1, r0, c9, c0, 7 //; WCP15_DCLKCR r0
+
+ //; Setup the TLBLKCR
+ //; Victim = 6'b000000; Floor = 6'b000000;
+ //; IASIDCFG =
+ //;2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0;
+ mov r1, #0x02
+ mcr p15, 0, r1, c10, c1, 3 //; WCP15_TLBLKCR r1
+
+ //;Make sure TLBLKCR is complete before continuing
+ ISB
+
+ //; Invalidate the UTLB
+ mcr p15, 0, r0, c8, c7, 0 //; UTLBIALL
+
+ //; Make sure UTLB request has been presented to macro before continuing
+ ISB
+
+SYSI2:
+ //; setup L2CR1 to some default Instruction and data prefetching values
+ //; Users may want specific settings for various performance
+ //; enhancements
+ //; In Halcyon we do not have broadcasting barriers. So we need to turn
+ // ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast )
+ ldr r2, =0x133
+ mcr p15, 3, r2, c15, c0, 3 //; WCP15_L2CR1 r0
+
+
+ //; Enable Z bit to enable branch prediction (default is off)
+ mrc p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2
+ orr r2, r2, #0x00000800
+ mcr p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2
+
+ //; Make sure Link stack is initialized with branch and links to
+ //; sequential addresses
+ //; This aids in creating a predictable startup environment
+ bl SEQ1
+SEQ1: bl SEQ2
+SEQ2: bl SEQ3
+SEQ3: bl SEQ4
+SEQ4: bl SEQ5
+SEQ5: bl SEQ6
+SEQ6: bl SEQ7
+SEQ7: bl SEQ8
+SEQ8:
+
+ //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA
+ //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the
+ //;debug registers
+ //; Writing anything but the "secret code" to the DBGOSLAR clears the
+ //;DBGOSLSR[LOCK] bit
+ mcr p14, 0, r0, c1, c0, 4 //; WCP14_DBGOSLAR r0
+
+
+ //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD]
+ //; Any read to DBGPRSR clear the STICKYPD bit
+ //; ISB guarantees the read completes before attempting to
+ //; execute a CP14 instruction.
+ mrc p14, 0, r3, c1, c5, 4 //; RCP14_DBGPRSR r3
+ ISB
+
+
+
+ //;--------------------------------------------------------------------
+ //; The saved Program Status Registers (SPSRs) should be setup
+ //; prior to any automatic mode switches. The following
+ //; code sets these registers up to a known state. Users will need to
+ //; customize these settings to meet their needs.
+ //;--------------------------------------------------------------------
+ mov r2, #0x1f
+ mov r1, #0xd7 //;ABT mode
+ msr cpsr_c, r1 //;ABT mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xdb //;UND mode
+ msr cpsr_c, r1 //;UND mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd1 //;FIQ mode
+ msr cpsr_c, r1 //;FIQ mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd2 //;IRQ mode
+ msr cpsr_c, r1 //;IRQ mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd6 //;Monitor mode
+ msr cpsr_c, r1 //;Monitor mode
+ msr spsr_cxfs, r2 //;clear the spsr
+ mov r1, #0xd3 //;SVC mode
+ msr cpsr_c, r1 //;SVC mode
+ msr spsr_cxfs, r2 //;clear the spsr
+
+
+ //;--------------------------------------------------------------------
+ //; Enabling Error reporting is something users may want to do at
+ //; some other point in time. We have chosen some default settings
+ //; that should be reviewed. Most of these registers come up in an
+ //; unpredictable state after reset.
+ //;--------------------------------------------------------------------
+//;Start of error and control setting
+
+ //; setup L2CR0 with various L2/TCM control settings
+ //; enable out of order bus attributes and error reporting
+ //; this register comes up unpredictable after reset
+ // movw r1, #0x0F0F
+.word 0xe3001f0f // hardcoded movw instruction due to lack of compiler support
+ // movT r1, #0xC005
+.word 0xe34c1005 // hardcoded movw instruction due to lack of compiler support
+ mcr p15, 3, r1, c15, c0, 1 //; WCP15_L2CR0 r1
+
+ //; setup L2CPUCR
+ //; mov r2, #0xFF
+ //; Enable I and D cache parity
+ //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified,
+ //;tag, and data parity errors
+ mov r2, #0xe0
+ mcr p15, 3, r2, c15, c0, 2 //; WCP15_L2CPUCR r2
+
+ //; setup SPCR
+ //; enable all error reporting
+ //;(reset value is unpredicatble for most bits)
+ mov r3, #0x0F
+ mcr p15, 0, r3, c9, c7, 0 //; WCP15_SPCR r3
+
+ //; setup DMACHCRs (reset value unpredictable)
+ //; control setting and enable all error reporting
+ mov r1, #0x0F
+
+ //; DMACHCR0 = 0000000F
+ mov r2, #0x00 //; channel 0
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; DMACHCR1 = 0000000F
+ mov r2, #0x01 //; channel 1
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; DMACHCR2 = 0000000F
+ mov r2, #0x02 //; channel 2
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; DMACHCR3 = 0000000F
+ mov r2, #0x03 //; channel 3
+ mcr p15, 0, r2, c11, c0, 0 //; WCP15_DMASELR r2
+ mcr p15, 0, r1, c11, c0, 2 //; WCP15_DMACHCR r1
+
+ //; Set ACTLR (reset unpredictable)
+ //; Set AVIVT control, error reporting, etc.
+ //; mov r3, #0x07
+ //; Enable I and D cache parity
+ //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$)
+ //;ACTLR[5:4] = 2'h3 - enable parity
+ //;ACTLR[19:18] =2'h3 - always generate and
+ //;check parity(when MMU disabled).
+ //;Value to be written #0xC0037
+ // movw r3, #0x0037
+.word 0xe3003037 // hardcoded movw instruction due to lack of compiler support
+ // movT r3, #0x000C
+.word 0xe340300c // hardcoded movw instruction due to lack of compiler support
+ mcr p15, 0, r3, c1, c0, 1 //; WCP15_ACTLR r3
+
+//;End of error and control setting
+
+ //;---------------------------------------------------------------------
+ //; Unlock ETM and read StickyPD to halt the ETM clocks from running.
+ //; This is required for power saving whether the ETM is used or not.
+ //;---------------------------------------------------------------------
+
+ //;Clear ETMOSLSR[LOCK] bit
+ mov r1, #0x00000000
+ mcr p14, 1, r1, c1, c0, 4 //; WCP14_ETMOSLAR r1
+
+ //;Clear ETMPDSR[STICKYPD] bit
+ mrc p14, 1, r2, c1, c5, 4 //; RCP14_ETMPDSR r2
+ b SET_SA
+
+
+.ltorg
diff --git a/arch/arm/cpu/armv7/msm7630/timer.c b/arch/arm/cpu/armv7/msm7630/timer.c
new file mode 100644
index 0000000..007314e
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/timer.c
@@ -0,0 +1,142 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <r-woodruff2 at ti.com>
+ * Syed Moahmmed Khasim <khasim at ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger at sysgo.de>
+ * Alex Zuepke <azu at sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj at denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <config.h>
+#include <common.h>
+#include <asm/types.h>
+#define TIMER_LOAD_VAL 0x21
+
+#define GPT_ENABLE_CLR_ON_MATCH_EN 2
+#define GPT_ENABLE_EN 1
+#define DGT_ENABLE_CLR_ON_MATCH_EN 2
+#define DGT_ENABLE_EN 1
+
+#define SPSS_TIMER_STATUS_DGT_EN (1 << 0)
+
+
+#define READ_TIMER readl(GPT_COUNT_VAL)
+
+static ulong timestamp;
+static ulong lastinc;
+#define DGT_HZ 6750000 /* Uses LPXO/4 (27.0 MHz / 4) */
+
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init(void)
+{
+ uint32_t val = 0;
+
+ /* Disable timer */
+ writel(0, DGT_ENABLE);
+
+ /* Check for the hardware revision */
+ val = readl(HW_REVISION_NUMBER);
+ val = (val >> 28) & 0x0F;
+ if (val >= 1)
+ writel(1, DGT_CLK_CTL);
+ return 0;
+}
+
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void __udelay(unsigned long usecs)
+{
+ unsigned int val;
+ usecs = (usecs * 33 + 1000 - 33) / 1000;
+
+ writel(0, GPT_CLEAR);
+ writel(0, GPT_ENABLE);
+ do {
+ val = 0;
+ val = readl(GPT_COUNT_VAL);
+ } while (val != 0);
+
+ writel(GPT_ENABLE_EN, GPT_ENABLE);
+ do {
+ val = 0;
+ val = readl(GPT_COUNT_VAL);
+ } while (val < usecs) ;
+
+ writel(0, GPT_ENABLE);
+ writel(0, GPT_CLEAR);
+
+}
+
+
+ulong get_timer_masked(void)
+{
+ ulong now = READ_TIMER; /* current tick value */
+
+ if (lastinc <= now) { /* normal mode (non roll) */
+ /* normal mode */
+ timestamp += now - lastinc;
+ /* move stamp forward with absolute diff ticks */
+ } else { /* we have overflow of the count down timer */
+ timestamp += now + (TIMER_LOAD_VAL - lastinc);
+ }
+ lastinc = now;
+
+ return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return 19200000;
+}
diff --git a/arch/arm/include/asm/arch-msm7630/adm.h b/arch/arm/include/asm/arch-msm7630/adm.h
new file mode 100644
index 0000000..0e8af85
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/adm.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ADM_H
+#define __ADM_H
+
+/* Channel #s and security domain */
+#define ADM_CHN 8
+#define ADM_SD 2
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio.h b/arch/arm/include/asm/arch-msm7630/gpio.h
new file mode 100644
index 0000000..af6ddaa
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio.h
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __GPIO_H
+#define __GPIO_H
+
+#ifndef GPIO_INPUT
+#define GPIO_INPUT 0x0000
+#endif
+#ifndef GPIO_OUTPUT
+#define GPIO_OUTPUT 0x0001
+#endif
+
+#define GPIO_LEVEL 0x0000
+#define GPIO_EDGE 0x0010
+
+#define GPIO_RISING 0x0020
+#define GPIO_FALLING 0x0040
+
+#define GPIO_HIGH 0x0020
+#define GPIO_LOW 0x0040
+
+#define GPIO_PULLUP 0x0100
+#define GPIO_PULLDOWN 0x0200
+
+int gpio_config(unsigned nr, unsigned flags);
+void gpio_set(unsigned nr, unsigned on);
+int gpio_get(unsigned nr);
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio_hw.h b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
new file mode 100644
index 0000000..c8244d8
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
@@ -0,0 +1,168 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __GPIO_HW_H
+#define __GPIO_HW_H
+
+#define MSM_GPIO1_BASE 0xAC001000
+#define MSM_GPIO2_BASE 0xAC101000
+
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+
+/* output value */
+#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
+#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 43-16 */
+#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-44 */
+#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
+#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */
+#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 133-107 */
+#define GPIO_OUT_6 GPIO1_REG(0xC4) /* gpio 150-134 */
+#define GPIO_OUT_7 GPIO1_REG(0x214) /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0 GPIO1_REG(0x10)
+#define GPIO_OE_1 GPIO2_REG(0x08)
+#define GPIO_OE_2 GPIO1_REG(0x14)
+#define GPIO_OE_3 GPIO1_REG(0x18)
+#define GPIO_OE_4 GPIO1_REG(0x1C)
+#define GPIO_OE_5 GPIO1_REG(0x54)
+#define GPIO_OE_6 GPIO1_REG(0xC8)
+#define GPIO_OE_7 GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0 GPIO1_REG(0x34)
+#define GPIO_IN_1 GPIO2_REG(0x20)
+#define GPIO_IN_2 GPIO1_REG(0x38)
+#define GPIO_IN_3 GPIO1_REG(0x3C)
+#define GPIO_IN_4 GPIO1_REG(0x40)
+#define GPIO_IN_5 GPIO1_REG(0x44)
+#define GPIO_IN_6 GPIO1_REG(0xCC)
+#define GPIO_IN_7 GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0)
+#define GPIO_INT_EDGE_6 GPIO1_REG(0xD0)
+#define GPIO_INT_EDGE_7 GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0 GPIO1_REG(0x70)
+#define GPIO_INT_POS_1 GPIO2_REG(0x58)
+#define GPIO_INT_POS_2 GPIO1_REG(0x74)
+#define GPIO_INT_POS_3 GPIO1_REG(0x78)
+#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5 GPIO1_REG(0xBC)
+#define GPIO_INT_POS_6 GPIO1_REG(0xD4)
+#define GPIO_INT_POS_7 GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0 GPIO1_REG(0x80)
+#define GPIO_INT_EN_1 GPIO2_REG(0x60)
+#define GPIO_INT_EN_2 GPIO1_REG(0x84)
+#define GPIO_INT_EN_3 GPIO1_REG(0x88)
+#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5 GPIO1_REG(0xB8)
+#define GPIO_INT_EN_6 GPIO1_REG(0xD8)
+#define GPIO_INT_EN_7 GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4)
+#define GPIO_INT_CLEAR_6 GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_7 GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0)
+#define GPIO_INT_STATUS_6 GPIO1_REG(0xE0)
+#define GPIO_INT_STATUS_7 GPIO1_REG(0x234)
+
+
+#define GPIO_OUT_VAL_REG_BASE 0xABC00000
+#define GPIO_ALT_FUNC_PAGE_REG (GPIO_OUT_VAL_REG_BASE + 0x20)
+#define GPIO_ALT_FUNC_CFG_REG (GPIO_OUT_VAL_REG_BASE + 0x24)
+
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER 2
+#define GPIO_PULL_UP 3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA 0
+#define GPIO_4MA 1
+#define GPIO_6MA 2
+#define GPIO_8MA 3
+#define GPIO_10MA 4
+#define GPIO_12MA 5
+#define GPIO_14MA 6
+#define GPIO_16MA 7
+
+#define GPIO38_GPIO_CNTRL 0x175
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE 0
+#define GPIO_DISABLE 1
+
+#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
+ ((((gpio) & 0x3FF) << 4) | \
+ ((func) & 0xf) | \
+ (((dir) & 0x1) << 14) | \
+ (((pull) & 0x3) << 15) | \
+ (((drvstr) & 0xF) << 17))
+
+/**
+ * struct msm_gpio - GPIO pin description
+ * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
+ * @label - textual label
+ *
+ * Usually, GPIO's are operated by sets.
+ * This struct accumulate all GPIO information in single source
+ * and facilitete group operations provided by msm_gpios_xxx()
+ */
+struct msm_gpio {
+ unsigned gpio_cfg;
+ const char *label;
+};
+
+/**
+ * extract GPIO pin from bit-field used for gpio_tlmm_config
+ */
+#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff)
+#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf)
+#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1)
+#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3)
+#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/iomap.h b/arch/arm/include/asm/arch-msm7630/iomap.h
new file mode 100644
index 0000000..186c6c2
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/iomap.h
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __IOMAP_H_
+#define __IOMAP_H_
+
+#define MSM_UART1_BASE 0xACA00000
+#define MSM_UART2_BASE 0xACB00000
+#define MSM_UART3_BASE 0xACC00000
+
+#define MSM_VIC_BASE 0xC0080000
+#define MSM_TMR_BASE 0xC0100000
+
+#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
+#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
+#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
+
+#define GPT_REG(off) (MSM_GPT_BASE + (off))
+#define DGT_REG(off) (MSM_DGT_BASE + (off))
+
+#define GPT_MATCH_VAL GPT_REG(0x0000)
+#define GPT_COUNT_VAL GPT_REG(0x0004)
+#define GPT_ENABLE GPT_REG(0x0008)
+#define GPT_CLEAR GPT_REG(0x000C)
+
+#define DGT_MATCH_VAL DGT_REG(0x0000)
+#define DGT_COUNT_VAL DGT_REG(0x0004)
+#define DGT_ENABLE DGT_REG(0x0008)
+#define DGT_CLEAR DGT_REG(0x000C)
+#define DGT_CLK_CTL DGT_REG(0x0010)
+
+#define HW_REVISION_NUMBER 0xABC00270
+
+#define MSM_CSR_BASE 0xC0100000
+#define MSM_GCC_BASE 0xC0182000
+
+#define MSM_SDC1_BASE 0xA0400000
+#define MSM_SDC2_BASE 0xA0500000
+#define MSM_SDC3_BASE 0xA3000000
+#define MSM_SDC4_BASE 0xA3100000
+
+#define MSM_SHARED_BASE 0x00100000
+#define MSM_CLK_CTL_BASE 0xAB800000
+#define MSM_CLK_CTL_SH2_BASE 0xABA01000
+
+#define REG_BASE(off) (MSM_CLK_CTL_BASE + (off))
+#define REG_SH2_BASE(off) (MSM_CLK_CTL_SH2_BASE + (off))
+
+#define SCSS_CLK_CTL 0xC0101004
+#define SCSS_CLK_SEL 0xC0101008
+
+#define MSM_USB_BASE 0xA3600000
+#define MSM_CRYPTO_BASE 0xA8400000
+
+#define SH2_USBH_MD_REG REG_SH2_BASE(0x2BC)
+#define SH2_USBH_NS_REG REG_SH2_BASE(0x2C0)
+
+#define SH2_MDP_NS_REG REG_SH2_BASE(0x14C)
+#define SH2_MDP_LCDC_MD_REG REG_SH2_BASE(0x38C)
+#define SH2_MDP_LCDC_NS_REG REG_SH2_BASE(0x390)
+#define SH2_MDP_VSYNC_REG REG_SH2_BASE(0x460)
+#define SH2_PMDH_NS_REG REG_SH2_BASE(0x8C)
+
+#define SH2_GLBL_CLK_ENA_SC REG_SH2_BASE(0x3BC)
+#define SH2_GLBL_CLK_ENA_2_SC REG_SH2_BASE(0x3C0)
+
+#define SH2_OWN_ROW1_BASE_REG REG_BASE(0x041C)
+#define SH2_OWN_ROW2_BASE_REG REG_BASE(0x0424)
+#define SH2_OWN_APPS2_BASE_REG REG_BASE(0x0414)
+
+#define MSM_ADM_BASE 0xAC200000
+#define MSM_ADM_SD_OFFSET 0x00100400
+
+#define MSM_SAW_BASE 0xC0102000
+
+#define PLL_ENA_REG REG_SH2_BASE(0x0264)
+#define PLL2_STATUS_BASE_REG REG_BASE(0x0350)
+#define PLL2_L_VAL_ADDR REG_BASE(0x033C)
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/proc_comm.h b/arch/arm/include/asm/arch-msm7630/proc_comm.h
new file mode 100644
index 0000000..3df08b9
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/proc_comm.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PROC_COMM_H_
+#define __PROC_COMM_H_
+
+void usb_clock_init(void);
+void lcdc_clock_init(unsigned rate);
+void mdp_clock_init(unsigned rate);
+void uart3_clock_init(void);
+void uart2_clock_init(void);
+void uart1_clock_init(void);
+void mddi_clock_init(unsigned num, unsigned rate);
+void reboot(unsigned reboot_reason);
+int mmc_clock_enable_disable(unsigned id, unsigned enable);
+int mmc_clock_set_rate(unsigned id, unsigned rate);
+int mmc_clock_get_rate(unsigned id);
+int gpio_tlmm_config(unsigned config, unsigned disable);
+int vreg_set_level(unsigned id, unsigned mv);
+int vreg_enable(unsigned id);
+int vreg_disable(unsigned id);
+
+#endif
+
+
diff --git a/arch/arm/include/asm/arch-msm7630/sys_proto.h b/arch/arm/include/asm/arch-msm7630/sys_proto.h
new file mode 100644
index 0000000..c679d92
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/sys_proto.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void pll8_enable(void);
+void clock_init(void);
+void __cpu_early_init(void);
+
+#endif
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
mohamed.haneef
2012-02-16 02:59:19 UTC
Permalink
From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>

* Support for low speed uart

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---
drivers/serial/Makefile | 1 +
drivers/serial/serial_msm_uart.c | 206 ++++++++++++++++++++++++++++++++++++++
2 files changed, 207 insertions(+), 0 deletions(-)
create mode 100644 drivers/serial/serial_msm_uart.c

diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 616b857..2801edc 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -55,6 +55,7 @@ COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
+COBJS-$(CONFIG_MSM_UART) += serial_msm_uart.o

ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/serial_msm_uart.c b/drivers/serial/serial_msm_uart.c
new file mode 100644
index 0000000..8cafa7a
--- /dev/null
+++ b/drivers/serial/serial_msm_uart.c
@@ -0,0 +1,206 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <asm/types.h>
+
+#define UART_MR1 0x0000
+
+#define UART_MR1_AUTO_RFR_LEVEL0(n) (((n) & 0x3f) << 8)
+#define UART_MR1_RX_RDY_CTL (1 << 7)
+#define UART_MR1_CTS_CTL (1 << 6)
+#define UART_MR1_AUTO_RFR_LEVEL1(n) ((n) & 0x3f)
+
+#define UART_MR2 0x0004
+#define UART_MR2_ERROR_MODE (1 << 6)
+#define UART_MR2_BITS_PER_CHAR_5 (0 << 4)
+#define UART_MR2_BITS_PER_CHAR_6 (1 << 4)
+#define UART_MR2_BITS_PER_CHAR_7 (2 << 4)
+#define UART_MR2_BITS_PER_CHAR_8 (3 << 4)
+#define UART_MR2_STOP_BIT_LEN_0563 (0 << 2)
+#define UART_MR2_STOP_BIT_LEN_1000 (1 << 2)
+#define UART_MR2_STOP_BIT_LEN_1563 (2 << 2)
+#define UART_MR2_STOP_BIT_LEN_2000 (3 << 2)
+#define UART_MR2_PARITY_MODE_NONE (0)
+#define UART_MR2_PARITY_MODE_ODD (1)
+#define UART_MR2_PARITY_MODE_EVEN (2)
+#define UART_MR2_PARITY_MODE_SPACE (3)
+
+#define UART_CSR 0x0008
+#define UART_CSR_115200 0xFF
+#define UART_CSR_57600 0xEE
+#define UART_CSR_38400 0xDD
+#define UART_CSR_19200 0xBB
+
+#define UART_TF 0x000C
+
+#define UART_CR 0x0010
+#define UART_CR_CMD_NULL (0 << 4)
+#define UART_CR_CMD_RESET_RX (1 << 4)
+#define UART_CR_CMD_RESET_TX (2 << 4)
+#define UART_CR_CMD_RESET_ERR (3 << 4)
+#define UART_CR_CMD_RESET_BCI (4 << 4)
+#define UART_CR_CMD_START_BREAK (5 << 4)
+#define UART_CR_CMD_STOP_BREAK (6 << 4)
+#define UART_CR_CMD_RESET_CTS_N (7 << 4)
+#define UART_CR_CMD_PACKET_MODE (9 << 4)
+#define UART_CR_CMD_MODE_RESET (12 << 4)
+#define UART_CR_CMD_SET_RFR_N (13 << 4)
+#define UART_CR_CMD_RESET_RFR_ND (14 << 4)
+#define UART_CR_TX_DISABLE (1 << 3)
+#define UART_CR_TX_ENABLE (1 << 3)
+#define UART_CR_RX_DISABLE (1 << 3)
+#define UART_CR_RX_ENABLE (1 << 3)
+
+#define UART_IMR 0x0014
+#define UART_IMR_RXLEV (1 << 4)
+#define UART_IMR_TXLEV (1 << 0)
+
+#define UART_IPR 0x0018
+#define UART_TFWR 0x001C
+#define UART_RFWR 0x0020
+#define UART_HCR 0x0024
+
+#define UART_MREG 0x0028
+#define UART_NREG 0x002C
+#define UART_DREG 0x0030
+#define UART_MNDREG 0x0034
+#define UART_IRDA 0x0038
+#define UART_MISR_MODE 0x0040
+#define UART_MISR_RESET 0x0044
+#define UART_MISR_EXPORT 0x0048
+#define UART_MISR_VAL 0x004C
+#define UART_TEST_CTRL 0x0050
+
+#define UART_SR 0x0008
+#define UART_SR_HUNT_CHAR (1 << 7)
+#define UART_SR_RX_BREAK (1 << 6)
+#define UART_SR_PAR_FRAME_ERR (1 << 5)
+#define UART_SR_OVERRUN (1 << 4)
+#define UART_SR_TX_EMPTY (1 << 3)
+#define UART_SR_TX_READY (1 << 2)
+#define UART_SR_RX_FULL (1 << 1)
+#define UART_SR_RX_READY (1 << 0)
+
+#define UART_RF 0x000C
+#define UART_MISR 0x0010
+#define UART_ISR 0x0014
+
+
+#if PLATFORM_MSM7X30
+static unsigned uart_base = MSM_UART2_BASE;
+#elif PLATFORM_MSM7X27A
+static unsigned uart_base = MSM_UART1_BASE;
+#else
+static unsigned uart_base = MSM_UART3_BASE;
+#endif
+
+#define uwr(v, a) writel(v, uart_base + (a))
+#define urd(a) readl(uart_base + (a))
+
+void uart_init(void)
+{
+ uwr(0x0A, UART_CR); /* disable TX and RX */
+ uwr(0x30, UART_CR); /* reset error status */
+ uwr(0x10, UART_CR); /* reset receiver */
+ uwr(0x20, UART_CR); /* reset transmitter */
+#if PLATFORM_QSD8K || PLATFORM_MSM7X30 || PLATFORM_MSM7X27A
+ /* TCXO */
+ uwr(0x06, UART_MREG);
+ uwr(0xF1, UART_NREG);
+ uwr(0x0F, UART_DREG);
+ uwr(0x1A, UART_MNDREG);
+#else
+ /* TCXO/4 */
+ uwr(0xC0, UART_MREG);
+ uwr(0xAF, UART_NREG);
+ uwr(0x80, UART_DREG);
+ uwr(0x19, UART_MNDREG);
+#endif
+ uwr(0x10, UART_CR); /* reset RX */
+ uwr(0x20, UART_CR); /* reset TX */
+ uwr(0x30, UART_CR); /* reset error status */
+ uwr(0x40, UART_CR); /* reset RX break */
+ uwr(0x70, UART_CR); /* rest? */
+ uwr(0xD0, UART_CR); /* reset */
+ uwr(0x7BF, UART_IPR); /* stale timeout = 630 * bitrate */
+ uwr(0, UART_IMR);
+ uwr(115, UART_RFWR); /* RX watermark = 58 * 2 - 1 */
+ uwr(10, UART_TFWR); /* TX watermark */
+ uwr(0, UART_RFWR);
+ uwr(UART_CSR_115200, UART_CSR);
+ uwr(0, UART_IRDA);
+ uwr(0x1E, UART_HCR);
+ uwr(16, UART_MR1);
+ uwr(0x34, UART_MR2); /* 8N1 */
+ uwr(0x05, UART_CR); /* enable TX & RX */
+
+}
+
+static int _uart_putc(int port, char c)
+{
+ while (!(urd(UART_SR) & UART_SR_TX_READY))
+ ;
+ uwr(c, UART_TF);
+ return 0;
+}
+
+int serial_init(void)
+{
+ uart_init();
+ return 0;
+}
+
+void serial_putc(char c)
+{
+ if (c == '\n')
+ _uart_putc(0, '\r');
+ _uart_putc(0, c);
+}
+
+void serial_putc_raw(const char c)
+{
+ _uart_putc(0, c);
+}
+
+void serial_puts(const char *s)
+{
+ while (*s)
+ serial_putc(*s++);
+}
+
+int serial_getc()
+{
+ while (!(urd(UART_SR) & UART_SR_RX_READY))
+ ;
+ return urd(UART_RF);
+}
+
+int serial_tstc()
+{
+ return urd(UART_SR) & UART_SR_RX_READY;
+}
+
+void serial_setbrg()
+{
+}
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Albert ARIBAUD
2012-02-28 23:44:15 UTC
Permalink
Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :

> +#define UART_CR_TX_DISABLE (1<< 3)
> +#define UART_CR_TX_ENABLE (1<< 3)

I doubt the same bit value can mean both enable and disable.

> +#define UART_CR_RX_DISABLE (1<< 3)
> +#define UART_CR_RX_ENABLE (1<< 3)

Ditto.

Besides, neither of these defines are used anyway. What's the point of
having them? I suspect many others are unused, too. Unless there is a
compelling reason to keep useless defines, remove them.

> The contents of this e-mail and any attachment(s) may contain
> confidential or privileged information for the intended recipient(s).
> Unintended recipients are prohibited from taking action on the basis
> of information in this e-mail and using or disseminating the
> information, and must notify the sender and delete it from their
> system. L&T Infotech will not accept responsibility or liability for
> the accuracy or completeness of, or the presence of any virus or
> disabling code in this e-mail"

Please do not post with this footer on the list. It os obnoxious (and
quite purposeless on a public list :) )

Amicalement,
--
Albert.
Mohamed Haneef
2012-03-05 14:34:05 UTC
Permalink
* Support for low speed uart

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---
Changes for v2:
- Removed unused macros

drivers/serial/Makefile | 1 +
drivers/serial/serial_msm_uart.c | 156 ++++++++++++++++++++++++++++++++++++++
2 files changed, 157 insertions(+), 0 deletions(-)
create mode 100644 drivers/serial/serial_msm_uart.c

diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 616b857..2801edc 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -55,6 +55,7 @@ COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
+COBJS-$(CONFIG_MSM_UART) += serial_msm_uart.o

ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/serial_msm_uart.c b/drivers/serial/serial_msm_uart.c
new file mode 100644
index 0000000..8f80561
--- /dev/null
+++ b/drivers/serial/serial_msm_uart.c
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <asm/types.h>
+
+#define UART_MR1 0x0000
+
+
+#define UART_MR2 0x0004
+
+#define UART_CSR 0x0008
+#define UART_CSR_115200 0xFF
+
+#define UART_TF 0x000C
+
+#define UART_CR 0x0010
+#define UART_CR_CMD_MODE_RESET (12 << 4)
+
+#define UART_IMR 0x0014
+
+#define UART_IPR 0x0018
+#define UART_TFWR 0x001C
+#define UART_RFWR 0x0020
+#define UART_HCR 0x0024
+
+#define UART_MREG 0x0028
+#define UART_NREG 0x002C
+#define UART_DREG 0x0030
+#define UART_MNDREG 0x0034
+#define UART_IRDA 0x0038
+
+#define UART_SR 0x0008
+#define UART_SR_TX_READY (1 << 2)
+#define UART_SR_RX_READY (1 << 0)
+
+#define UART_RF 0x000C
+
+
+#if PLATFORM_MSM7X30
+static unsigned uart_base = MSM_UART2_BASE;
+#elif PLATFORM_MSM7X27A
+static unsigned uart_base = MSM_UART1_BASE;
+#else
+static unsigned uart_base = MSM_UART3_BASE;
+#endif
+
+#define uwr(v, a) writel(v, uart_base + (a))
+#define urd(a) readl(uart_base + (a))
+
+void uart_init(void)
+{
+ uwr(0x0A, UART_CR); /* disable TX and RX */
+ uwr(0x30, UART_CR); /* reset error status */
+ uwr(0x10, UART_CR); /* reset receiver */
+ uwr(0x20, UART_CR); /* reset transmitter */
+#if PLATFORM_QSD8K || PLATFORM_MSM7X30 || PLATFORM_MSM7X27A
+ /* TCXO */
+ uwr(0x06, UART_MREG);
+ uwr(0xF1, UART_NREG);
+ uwr(0x0F, UART_DREG);
+ uwr(0x1A, UART_MNDREG);
+#else
+ /* TCXO/4 */
+ uwr(0xC0, UART_MREG);
+ uwr(0xAF, UART_NREG);
+ uwr(0x80, UART_DREG);
+ uwr(0x19, UART_MNDREG);
+#endif
+ uwr(0x10, UART_CR); /* reset RX */
+ uwr(0x20, UART_CR); /* reset TX */
+ uwr(0x30, UART_CR); /* reset error status */
+ uwr(0x40, UART_CR); /* reset RX break */
+ uwr(0x70, UART_CR); /* rest? */
+ uwr(0xD0, UART_CR); /* reset */
+ uwr(0x7BF, UART_IPR); /* stale timeout = 630 * bitrate */
+ uwr(0, UART_IMR);
+ uwr(115, UART_RFWR); /* RX watermark = 58 * 2 - 1 */
+ uwr(10, UART_TFWR); /* TX watermark */
+ uwr(0, UART_RFWR);
+ uwr(UART_CSR_115200, UART_CSR);
+ uwr(0, UART_IRDA);
+ uwr(0x1E, UART_HCR);
+ uwr(16, UART_MR1);
+ uwr(0x34, UART_MR2); /* 8N1 */
+ uwr(0x05, UART_CR); /* enable TX & RX */
+
+}
+
+static int _uart_putc(int port, char c)
+{
+ while (!(urd(UART_SR) & UART_SR_TX_READY))
+ ;
+ uwr(c, UART_TF);
+ return 0;
+}
+
+int serial_init(void)
+{
+ uart_init();
+ return 0;
+}
+
+void serial_putc(char c)
+{
+ if (c == '\n')
+ _uart_putc(0, '\r');
+ _uart_putc(0, c);
+}
+
+void serial_putc_raw(const char c)
+{
+ _uart_putc(0, c);
+}
+
+void serial_puts(const char *s)
+{
+ while (*s)
+ serial_putc(*s++);
+}
+
+int serial_getc()
+{
+ while (!(urd(UART_SR) & UART_SR_RX_READY))
+ ;
+ return urd(UART_RF);
+}
+
+int serial_tstc()
+{
+ return urd(UART_SR) & UART_SR_RX_READY;
+}
+
+void serial_setbrg()
+{
+}
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
mohamed.haneef
2012-03-22 08:50:19 UTC
Permalink
From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>

This is a humbel reminder for review of patch series for msm7630 board after making the changes proposed by u-boot community. The Patches contain the following support
* low speed uart for msm7630
* interprocessor communication
* qc_mmc microcontroller
* msm7630 soc
* msm7630 surf board


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
mohamed.haneef
2012-04-23 09:24:19 UTC
Permalink
The patch for msm7630 was released to the u-boot community on 16-feb-2-2012 can this be mainlined in v2012.07 release.The Patches contain the following support
* low speed uart for msm7630
* interprocessor communication
* qc_mmc microcontroller
* msm7630 soc
* msm7630 surf board

Thanks and regards,
Mohamed Haneef M.A

The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
mohamed.haneef
2012-04-23 09:31:59 UTC
Permalink
The patch for msm7630 was released to the u-boot community on 16-feb-2-2012 can this be mainlined in v2012.07 release.The Patches contain the following support
* low speed uart for msm7630
* interprocessor communication
* qc_mmc microcontroller
* msm7630 soc
* msm7630 surf board

Thanks and regards,
Mohamed Haneef M.A

The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Marek Vasut
2012-05-03 00:09:34 UTC
Permalink
Dear mohamed.haneef at lntinfotech.com,

> The patch for msm7630 was released to the u-boot community on 16-feb-2-2012
> can this be mainlined in v2012.07 release.The Patches contain the
> following support * low speed uart for msm7630
> * interprocessor communication
> * qc_mmc microcontroller
> * msm7630 soc
> * msm7630 surf board


It'd be great, CCing albert to review it as we don't have MSM maintainer.

>
> Thanks and regards,
> Mohamed Haneef M.A
>
> The contents of this e-mail and any attachment(s) may contain confidential
> or privileged information for the intended recipient(s). Unintended
> recipients are prohibited from taking action on the basis of information
> in this e-mail and using or disseminating the information, and must
> notify the sender and delete it from their system. L&T Infotech will not
> accept responsibility or liability for the accuracy or completeness of, or
> the presence of any virus or disabling code in this e-mail"
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

Best regards,
Marek Vasut
mohamed.haneef
2012-02-16 02:59:20 UTC
Permalink
From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>

*Support for msm7x30 interprocessor communication

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---
drivers/misc/Makefile | 1 +
drivers/misc/msm_proc_comm.c | 303 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 304 insertions(+), 0 deletions(-)
create mode 100644 drivers/misc/msm_proc_comm.c

diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a709707..b324d73 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -39,6 +39,7 @@ COBJS-$(CONFIG_PMIC_FSL) += pmic_fsl.o
COBJS-$(CONFIG_PMIC_I2C) += pmic_i2c.o
COBJS-$(CONFIG_PMIC_SPI) += pmic_spi.o
COBJS-$(CONFIG_PMIC_MAX8998) += pmic_max8998.o
+COBJS-$(CONFIG_MSM_PCOMM) += msm_proc_comm.o

COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/misc/msm_proc_comm.c b/drivers/misc/msm_proc_comm.c
new file mode 100644
index 0000000..f1db917
--- /dev/null
+++ b/drivers/misc/msm_proc_comm.c
@@ -0,0 +1,303 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomap.h>
+#define ACPU_CLK 0 /* Applications processor clock */
+#define ADM_CLK 1 /* Applications data mover clock */
+#define ADSP_CLK 2 /* ADSP clock */
+#define EBI1_CLK 3 /* External bus interface 1 clock */
+#define EBI2_CLK 4 /* External bus interface 2 clock */
+#define ECODEC_CLK 5 /* External CODEC clock */
+#define EMDH_CLK 6 /* External MDDI host clock */
+#define GP_CLK 7 /* General purpose clock */
+#define GRP_CLK 8 /* Graphics clock */
+#define I2C_CLK 9 /* I2C clock */
+#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
+#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
+#define IMEM_CLK 12 /* Internal graphics memory clock */
+#define MDC_CLK 13 /* MDDI client clock */
+#define MDP_CLK 14 /* Mobile display processor clock */
+#define PBUS_CLK 15 /* Peripheral bus clock */
+#define PCM_CLK 16 /* PCM clock */
+#define PMDH_CLK 17 /* Primary MDDI host clock */
+#define SDAC_CLK 18 /* Stereo DAC clock */
+#define SDC1_CLK 19 /* Secure Digital Card clocks */
+#define SDC1_PCLK 20
+#define SDC2_CLK 21
+#define SDC2_PCLK 22
+#define SDC3_CLK 23
+#define SDC3_PCLK 24
+#define SDC4_CLK 25
+#define SDC4_PCLK 26
+#define TSIF_CLK 27 /* Transport Stream Interface clocks */
+#define TSIF_REF_CLK 28
+#define TV_DAC_CLK 29 /* TV clocks */
+#define TV_ENC_CLK 30
+#define UART1_CLK 31 /* UART clocks */
+#define UART2_CLK 32
+#define UART3_CLK 33
+#define UART1DM_CLK 34
+#define UART2DM_CLK 35
+#define USB_HS_CLK 36 /* High speed USB core clock */
+#define USB_HS_PCLK 37 /* High speed USB pbus clock */
+#define USB_OTG_CLK 38 /* Full speed USB clock */
+#define VDC_CLK 39 /* Video controller clock */
+#define VFE_CLK 40 /* Camera / Video Front End clock */
+#define VFE_MDC_CLK 41 /* VFE MDDI client clock */
+
+/* qsd8k adds... */
+#define MDP_LCDC_PCLK_CLK 42
+#define MDP_LCDC_PAD_PCLK_CLK 43
+#define MDP_VSYNC_CLK 44
+
+#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */
+/* msm7x30 adds... */
+#define PMDH_P_CLK 82
+#define MDP_P_CLK 86
+
+enum {
+ PCOM_CMD_IDLE = 0x0,
+ PCOM_CMD_DONE,
+ PCOM_RESET_APPS,
+ PCOM_RESET_CHIP,
+ PCOM_CONFIG_NAND_MPU,
+ PCOM_CONFIG_USB_CLKS,
+ PCOM_GET_POWER_ON_STATUS,
+ PCOM_GET_WAKE_UP_STATUS,
+ PCOM_GET_BATT_LEVEL,
+ PCOM_CHG_IS_CHARGING,
+ PCOM_POWER_DOWN,
+ PCOM_USB_PIN_CONFIG,
+ PCOM_USB_PIN_SEL,
+ PCOM_SET_RTC_ALARM,
+ PCOM_NV_READ,
+ PCOM_NV_WRITE,
+ PCOM_GET_UUID_HIGH,
+ PCOM_GET_UUID_LOW,
+ PCOM_GET_HW_ENTROPY,
+ PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
+ PCOM_CLKCTL_RPC_ENABLE,
+ PCOM_CLKCTL_RPC_DISABLE,
+ PCOM_CLKCTL_RPC_RESET,
+ PCOM_CLKCTL_RPC_SET_FLAGS,
+ PCOM_CLKCTL_RPC_SET_RATE,
+ PCOM_CLKCTL_RPC_MIN_RATE,
+ PCOM_CLKCTL_RPC_MAX_RATE,
+ PCOM_CLKCTL_RPC_RATE,
+ PCOM_CLKCTL_RPC_PLL_REQUEST,
+ PCOM_CLKCTL_RPC_ENABLED,
+ PCOM_VREG_SWITCH,
+ PCOM_VREG_SET_LEVEL,
+ PCOM_GPIO_TLMM_CONFIG_GROUP,
+ PCOM_GPIO_TLMM_UNCONFIG_GROUP,
+ PCOM_NV_READ_HIGH_BITS,
+ PCOM_NV_WRITE_HIGH_BITS,
+ PCOM_RPC_GPIO_TLMM_CONFIG_EX = 0x25,
+ PCOM_NUM_CMDS,
+};
+
+enum {
+ PCOM_INVALID_STATUS = 0x0,
+ PCOM_READY,
+ PCOM_CMD_RUNNING,
+ PCOM_CMD_SUCCESS,
+ PCOM_CMD_FAIL,
+};
+
+#ifndef PLATFORM_MSM7X30
+#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+#endif
+static inline void notify_other_proc_comm(void)
+{
+#ifndef PLATFORM_MSM7X30
+ writel(1, MSM_A2M_INT(6));
+#else
+ writel(1<<6, (MSM_GCC_BASE + 0x8));
+#endif
+}
+
+#define APP_COMMAND (MSM_SHARED_BASE + 0x00)
+#define APP_STATUS (MSM_SHARED_BASE + 0x04)
+#define APP_DATA1 (MSM_SHARED_BASE + 0x08)
+#define APP_DATA2 (MSM_SHARED_BASE + 0x0C)
+
+#define MDM_COMMAND (MSM_SHARED_BASE + 0x10)
+#define MDM_STATUS (MSM_SHARED_BASE + 0x14)
+#define MDM_DATA1 (MSM_SHARED_BASE + 0x18)
+#define MDM_DATA2 (MSM_SHARED_BASE + 0x1C)
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
+{
+ int ret = -1;
+ unsigned status;
+
+ while (readl(MDM_STATUS) != PCOM_READY)
+ /* XXX check for A9 reset */
+ ;
+ writel(cmd, APP_COMMAND);
+ if (data1)
+ writel(*data1, APP_DATA1);
+ if (data2)
+ writel(*data2, APP_DATA2);
+
+ notify_other_proc_comm();
+ while (readl(APP_COMMAND) != PCOM_CMD_DONE)
+ /* XXX check for A9 reset */
+ ;
+ status = readl(APP_STATUS);
+
+ if (status != PCOM_CMD_FAIL) {
+ if (data1)
+ *data1 = readl(APP_DATA1);
+ if (data2)
+ *data2 = readl(APP_DATA2);
+ ret = 0;
+ }
+ return ret;
+}
+
+static int clock_enable(unsigned id)
+{
+ return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, 0);
+}
+
+static int clock_disable(unsigned id)
+{
+ return msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, 0);
+}
+
+static int clock_set_rate(unsigned id, unsigned rate)
+{
+ return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+}
+
+static int clock_get_rate(unsigned id)
+{
+ if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, 0))
+ return -1;
+ else
+ return (int) id;
+
+}
+
+void usb_clock_init(void)
+{
+ clock_enable(USB_HS_PCLK);
+ clock_enable(USB_HS_CLK);
+ clock_enable(P_USB_HS_CORE_CLK);
+}
+
+void lcdc_clock_init(unsigned rate)
+{
+ clock_set_rate(MDP_LCDC_PCLK_CLK, rate);
+ clock_enable(MDP_LCDC_PCLK_CLK);
+ clock_enable(MDP_LCDC_PAD_PCLK_CLK);
+}
+
+void mdp_clock_init(unsigned rate)
+{
+ clock_set_rate(MDP_CLK, rate);
+ clock_enable(MDP_CLK);
+ clock_enable(MDP_P_CLK);
+}
+
+void uart3_clock_init(void)
+{
+ clock_enable(UART3_CLK);
+ clock_set_rate(UART3_CLK, 19200000 / 4);
+}
+
+void uart2_clock_init(void)
+{
+ clock_enable(UART2_CLK);
+ clock_set_rate(UART2_CLK, 19200000);
+}
+
+void uart1_clock_init(void)
+{
+ clock_enable(UART1_CLK);
+ clock_set_rate(UART1_CLK, 19200000 / 4);
+}
+
+void mddi_clock_init(unsigned num, unsigned rate)
+{
+ unsigned clock_id;
+
+ if (num == 0)
+ clock_id = PMDH_CLK;
+ else
+ clock_id = EMDH_CLK;
+
+ clock_enable(clock_id);
+ clock_set_rate(clock_id, rate);
+#ifdef PLATFORM_MSM7X30
+ clock_enable(PMDH_P_CLK);
+#endif
+}
+
+void reboot(unsigned reboot_reason)
+{
+ msm_proc_comm(PCOM_RESET_CHIP, &reboot_reason, 0);
+ for (;;)
+ ;
+}
+
+int mmc_clock_enable_disable(unsigned id, unsigned enable)
+{
+ if (enable)
+ return clock_enable(id); /*Enable mmc clock rate*/
+ else
+ return clock_disable(id); /*Disable mmc clock rate*/
+}
+
+int mmc_clock_set_rate(unsigned id, unsigned rate)
+{
+ return clock_set_rate(id, rate); /*Set mmc clock rate*/
+}
+
+int mmc_clock_get_rate(unsigned id)
+{
+ return clock_get_rate(id); /*Get mmc clock rate*/
+}
+
+int gpio_tlmm_config(unsigned config, unsigned disable)
+{
+ return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable);
+}
+
+int vreg_set_level(unsigned id, unsigned mv)
+{
+ return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+}
+
+int vreg_enable(unsigned id)
+{
+ unsigned enable = 1;
+ return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+}
+
+int vreg_disable(unsigned id)
+{
+ unsigned enable = 0;
+ return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+}
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Albert ARIBAUD
2012-02-28 23:46:28 UTC
Permalink
Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :
> From: Mohamed Haneef<mohamed.haneef at lntinfotech.com>
>
> *Support for msm7x30 interprocessor communication

Is this used at some point in the patch set? If not, remove it and
introduce it back within a patchset that uses it.

Amicalement,
--
Albert.
Mohamed Haneef
2012-03-05 14:33:36 UTC
Permalink
Hi Albert,

This driver uses shared memory region to pass message. this is used in acpuclock.c, gpio.c files. So need to retain this patch as it is.

Thanks and Regards,
Mohamed Haneef M.A
08985734122
________________________________________
From: Albert ARIBAUD [albert.u.boot at aribaud.net]
Sent: Wednesday, February 29, 2012 5:16 AM
To: Mohamed Haneef
Cc: u-boot at lists.denx.de; wd at denx.de
Subject: Re: [PATCH 2/5] msm7x30: Add support for interprocessor communication

Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :
> From: Mohamed Haneef<mohamed.haneef at lntinfotech.com>
>
> *Support for msm7x30 interprocessor communication

Is this used at some point in the patch set? If not, remove it and
introduce it back within a patchset that uses it.

Amicalement,
--
Albert.

The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
mohamed.haneef
2012-02-16 02:59:23 UTC
Permalink
From: Mohamed Haneef <mohamed.haneef at lntinfotech.com>

*Support for msm7630_surf board

Signed-off-by: Mohamed Haneef <mohamed.haneef at lntinfotech.com>
---
board/qcom/msm7630_surf/Makefile | 55 +++++++++++
board/qcom/msm7630_surf/msm7630_surf.c | 155 ++++++++++++++++++++++++++++++++
board/qcom/msm7630_surf/msm7630_surf.h | 30 ++++++
boards.cfg | 1 +
include/configs/msm7630_surf.h | 131 +++++++++++++++++++++++++++
5 files changed, 372 insertions(+), 0 deletions(-)
create mode 100644 board/qcom/msm7630_surf/Makefile
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.c
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.h
create mode 100644 include/configs/msm7630_surf.h

diff --git a/board/qcom/msm7630_surf/Makefile b/board/qcom/msm7630_surf/Makefile
new file mode 100644
index 0000000..f9dec32
--- /dev/null
+++ b/board/qcom/msm7630_surf/Makefile
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2012
+# LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+#
+# (C) Copyright 2010,2011
+# NVIDIA Corporation <www.nvidia.com>
+#
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../../qcom/msm7630_surf/)
+endif
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := $(BOARD).o
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+clean:
+ rm -f $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/qcom/msm7630_surf/msm7630_surf.c b/board/qcom/msm7630_surf/msm7630_surf.c
new file mode 100644
index 0000000..eb941c7
--- /dev/null
+++ b/board/qcom/msm7630_surf/msm7630_surf.c
@@ -0,0 +1,155 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/gpio.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/arch/mmc.h>
+#include <linux/string.h>
+#include <asm/mach-types.h>
+#include <asm/arch/proc_comm.h>
+#include "msm7630_surf.h"
+
+static struct msm_gpio uart2_gpio_table[] = {
+ {
+ .gpio_cfg = GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+ {
+ .gpio_cfg = GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+ {
+ .gpio_cfg = GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+ {
+ .gpio_cfg = GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+};
+
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void uart2_mux_init(void)
+{
+ platform_gpios_enable(uart2_gpio_table, ARRAY_SIZE(uart2_gpio_table));
+}
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f()
+{
+ uart2_mux_init();
+ uart2_clock_init();
+ return 0;
+}
+#endif
+int board_init()
+{
+ unsigned long new_addr;
+ unsigned long offset;
+ offset = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
+ new_addr = CONFIG_SYS_TEXT_BASE + offset;
+ set_vector_base(new_addr);
+ bd_t *bd = gd->bd;
+ bd->bi_arch_number = MACH_TYPE_MSM7X30_SURF;
+ acpu_clock_init();
+ adm_enable_clock();
+ return 0;
+}
+
+#ifdef CONFIG_QC_MMC
+
+/* called during the scan of each mmc device */
+int qc_board_mmc_init(struct mmc *mmc)
+{
+
+ struct mmc_priv *sd = (struct mmc_priv *)mmc->priv;
+ u32 smem_val;
+ do {
+ smem_val = 0;
+ smem_val = readl(MSM_SHARED_BASE + 0x14);
+ } while (smem_val != 1);
+
+ if (sd->instance == 2 || sd->instance == 4) {
+ mmc_boot_main(mmc);
+ return 0;
+ } else
+ /* this board does not have an sd/mmc card on this interface. */
+ return 1;
+ }
+int board_mmc_init(bd_t *bis)
+{
+#ifdef QC_SD
+ struct mmc *mmc_4;
+ struct mmc_priv *sdcc_4;
+ mmc_4 = (struct mmc *) malloc(sizeof(struct mmc));
+ if (!mmc_4)
+ return 1;
+ sdcc_4 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv));
+ if (!sdcc_4) {
+ free(mmc_4);
+ return 1;
+ }
+ sdcc_4->instance = 4;
+ sdcc_4->base = MSM_SDC4_BASE;
+ mmc_4->priv = sdcc_4;
+ mmc_4->send_cmd = mmc_boot_send_command_map;
+ mmc_4->set_ios = mmc_boot_set_ios;
+ mmc_4->init = qc_board_mmc_init;
+ mmc_4->voltages = MMC_VDD_29_30|MMC_VDD_165_195;
+ mmc_4->host_caps = MMC_MODE_4BIT|MMC_MODE_HS;
+ mmc_4->f_min = MMC_CLK_400KHZ;
+ mmc_4->f_max = MMC_CLK_48MHZ;
+ sprintf(mmc_4->name, "External_Card");
+ mmc_register(mmc_4);
+#else
+ struct mmc *mmc_2;
+ struct mmc_priv *sdcc_2;
+ mmc_2 = (struct mmc *) malloc(sizeof(struct mmc));
+ if (!mmc_2)
+ return 1;
+ sdcc_2 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv));
+ if (!sdcc_2) {
+ free(mmc_2);
+ return 1;
+ }
+ sdcc_2->instance = 2;
+ sdcc_2->base = MSM_SDC2_BASE;
+ mmc_2->priv = sdcc_2;
+ mmc_2->send_cmd = mmc_boot_send_command_map;
+ mmc_2->set_ios = mmc_boot_set_ios;
+ mmc_2->init = qc_board_mmc_init;
+ mmc_2->voltages = MMC_VDD_29_30|MMC_VDD_165_195;
+ mmc_2->host_caps = MMC_MODE_4BIT|MMC_MODE_HS|MMC_MODE_8BIT|
+ MMC_MODE_HS_52MHz;
+ mmc_2->f_min = MMC_CLK_400KHZ;
+ mmc_2->f_max = MMC_CLK_48MHZ;
+ sprintf(mmc_2->name, "Internal_Card");
+ mmc_register(mmc_2);
+#endif
+ return 0;
+}
+#endif
diff --git a/board/qcom/msm7630_surf/msm7630_surf.h b/board/qcom/msm7630_surf/msm7630_surf.h
new file mode 100644
index 0000000..a3d4bde
--- /dev/null
+++ b/board/qcom/msm7630_surf/msm7630_surf.h
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MSM7630_SURF_H_
+#define __MSM7630_SURF_H_
+#include <asm/arch/gpio_hw.h>
+
+extern void set_vector_base(unsigned long);
+extern void adm_enable_clock(void);
+extern void acpu_clock_init(void);
+extern void uart2_clock_init(void);
+extern int platform_gpios_enable(const struct msm_gpio *table, int size);
+#endif
diff --git a/boards.cfg b/boards.cfg
index bf71a66..4ab9330 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -190,6 +190,7 @@ integratorcp_cm946es arm arm946es integrator armltd
ca9x4_ct_vxp arm armv7 vexpress armltd
am335x_evm arm armv7 am335x ti am33xx
highbank arm armv7 highbank - highbank
+msm7630_surf arm armv7 msm7630_surf qcom msm7630
efikamx arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/efikamx/imximage_mx.cfg
efikasb arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKASB,IMX_CONFIG=board/efikamx/imximage_sb.cfg
mx51evk arm armv7 mx51evk freescale mx5 mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg
diff --git a/include/configs/msm7630_surf.h b/include/configs/msm7630_surf.h
new file mode 100644
index 0000000..3356611
--- /dev/null
+++ b/include/configs/msm7630_surf.h
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/sizes.h>
+#define PLATFORM_MSM7X30 1
+#define CONFIG_MSM_UART
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_L2_OFF
+#define CONFIG_SKIP_LOWLEVEL_INIT
+/* Environment */
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE 0x20000 /* Total Size Environment */
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MSM_PCOMM
+#define CONFIG_ARCH_CPU_INIT
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN (4 * 1024) /* 4KB */
+#define CONFIG_MSM7630
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_CONS_INDEX 1
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
+ 115200}
+
+#include <config_cmd_default.h>
+
+/* remove unused commands */
+#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */
+#undef CONFIG_CMD_FPGA /* FPGA configuration support */
+#undef CONFIG_CMD_IMI
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NFS /* NFS support */
+#undef CONFIG_CMD_NET /* network support */
+#undef CONFIG_SYS_MAX_FLASH_SECT
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "console=ttyS0,115200n8\0" \
+
+#define CONFIG_BOOTDELAY 2 /* -1 to disable auto boot */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define V_PROMPT "(MSM 7x30) # "
+#define CONFIG_SYS_PROMPT V_PROMPT
+/*
+ * Increasing the size of the IO buffer as default nfsargs size is more
+ * than 256 and so it is not possible to edit it
+ */
+#define CONFIG_SYS_CBSIZE (256 * 2) /* Console I/O Buffer Size */
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE)
+
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_LOAD_ADDR 0x00208000
+#define CONFIG_SYS_MEMTEST_START 0x08008000
+#define CONFIG_SYS_MEMTEST_END 0x08008001
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+
+#define CONFIG_GENERIC_MMC
+#define CONFIG_QC_MMC
+
+/*---------------------------------------------------------------------
+ * IRQ Settings
+ */
+
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+
+
+#define CONFIG_NR_DRAM_BANKS 2
+
+#define PHYS_SDRAM_1 0x00200000
+#define PHYS_SDRAM_1_SIZE (60*1024*1024) /* 512M */
+
+
+#define PHYS_SDRAM_2 0x07A00000
+#define PHYS_SDRAM_2_SIZE (134*1024*1024)
+
+#define CONFIG_SYS_TEXT_BASE 0x00000000
+#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000
+#define CONFIG_SYS_INIT_RAM_SIZE 0x00100000
+
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
+ CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
+
+#endif
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
Albert ARIBAUD
2012-10-03 08:19:33 UTC
Permalink
Hi Mohamed,

There never seemed to be a 4/5 patch in this set, neither on the list
nor in patchwork. Was it lost somehow?

Also, could you please not append this to your mails to the list?

> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

Amicalement,
--
Albert.
Murali Karicheri
2014-02-07 23:23:07 UTC
Permalink
- Resending since I missed some in the CC

This patch series add support for keystone2 SoC and K2HK EVM.

Following patches were reviewed before in this list and v1 of the
same is send with review comments incorporated:-
- tools: mkimage: add support for gpimage format
- arm: add support for arch timer
- NAND: DaVinci: allow forced disable of subpage writes

The patch below is added as a seperate patch based on comments:-
- tools: sort the entries in Makefile

Murali Karicheri (5):
tools: sort the entries in Makefile
tools: mkimage: add support for gpimage format
NAND: DaVinci: allow forced disable of subpage writes
k2hk: add support for k2hk SOC and EVM
keystone2: net: add keystone ethernet driver

Vitaly Andrianov (2):
fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
arm: add support for arch timer

Makefile | 19 +
README | 5 +
arch/arm/cpu/armv7/keystone/Makefile | 19 +
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/keystone_nav.c | 377 +++++++++
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/emac_defs.h | 255 ++++++
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/keystone_nav.h | 194 +++++
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 +
arch/arm/lib/Makefile | 1 +
arch/arm/lib/arch_timer.c | 58 ++
board/ti/k2hk_evm/Makefile | 9 +
board/ti/k2hk_evm/README | 56 ++
board/ti/k2hk_evm/board.c | 311 +++++++
board/ti/k2hk_evm/ddr3.c | 269 ++++++
boards.cfg | 1 +
common/image-fdt.c | 5 +
common/image.c | 1 +
drivers/i2c/Makefile | 1 +
drivers/i2c/keystone_i2c.c | 372 +++++++++
drivers/mtd/nand/davinci_nand.c | 3 +
drivers/net/Makefile | 1 +
drivers/net/keystone_net.c | 857 ++++++++++++++++++++
drivers/serial/ns16550.c | 8 +
include/configs/k2hk_evm.h | 259 ++++++
include/fdt_support.h | 1 +
include/image.h | 1 +
tools/Makefile | 20 +-
tools/gpheader.h | 40 +
tools/gpimage-common.c | 80 ++
tools/gpimage.c | 77 ++
tools/imagetool.c | 2 +
tools/imagetool.h | 1 +
tools/omapimage.c | 104 +--
tools/omapimage.h | 5 -
54 files changed, 5295 insertions(+), 100 deletions(-)
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/keystone_nav.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/emac_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/keystone_nav.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 arch/arm/lib/arch_timer.c
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 drivers/net/keystone_net.c
create mode 100644 include/configs/k2hk_evm.h
create mode 100644 tools/gpheader.h
create mode 100644 tools/gpimage-common.c
create mode 100644 tools/gpimage.c

--
1.7.9.5
Murali Karicheri
2014-02-07 23:23:11 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

This patch add basic support for the architecture timer found on recent
ARMv7 based SoCs.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- Resending with some more in cc
- Resending the patch along with SoC/board patch
arch/arm/lib/Makefile | 1 +
arch/arm/lib/arch_timer.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
create mode 100644 arch/arm/lib/arch_timer.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 321997c..726f229 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
else
obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
endif
+obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o

ifdef CONFIG_ARM64
obj-y += interrupts_64.o
diff --git a/arch/arm/lib/arch_timer.c b/arch/arm/lib/arch_timer.c
new file mode 100644
index 0000000..0588e2b
--- /dev/null
+++ b/arch/arm/lib/arch_timer.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <div64.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int timer_init(void)
+{
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+
+ gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ;
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ ulong nowl, nowu;
+
+ asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu));
+
+ gd->arch.tbl = nowl;
+ gd->arch.tbu = nowu;
+
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+
+ulong get_timer(ulong base)
+{
+ return lldiv(get_ticks(), gd->arch.timer_rate_hz) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ unsigned long long endtime;
+
+ endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz,
+ 1000UL);
+
+ endtime += get_ticks();
+
+ while (get_ticks() < endtime)
+ ;
+}
+
+ulong get_tbclk(void)
+{
+ return gd->arch.timer_rate_hz;
+}
--
1.7.9.5
Murali Karicheri
2014-02-07 23:23:12 UTC
Permalink
This patch introduces a configurable mechanism to disable
subpage writes in the DaVinci NAND driver.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- Resend with some more in cc
- Updated README to include the option as per review comments
README | 5 +++++
drivers/mtd/nand/davinci_nand.c | 3 +++
2 files changed, 8 insertions(+)

diff --git a/README b/README
index aea82be..caf60a2 100644
--- a/README
+++ b/README
@@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
- CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
Enables the RTC32K OSC on AM33xx based plattforms

+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+ Option to disable subpage write in NAND driver
+ Example driver that use this:
+ drivers/mtd/nand/davinci_nand.c
+
Freescale QE/FMAN Firmware Support:
-----------------------------------

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 5b17d7b..75b03a7 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -609,6 +609,9 @@ void davinci_nand_init(struct nand_chip *nand)
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
nand->bbt_options |= NAND_BBT_USE_FLASH;
#endif
+#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+ nand->options |= NAND_NO_SUBPAGE_WRITE;
+#endif
#ifdef CONFIG_SYS_NAND_HW_ECC
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.size = 512;
--
1.7.9.5
Murali Karicheri
2014-02-07 23:23:08 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

The keystone2 SOC requires to fix all 32 bit aliased addresses
to their 36 physical format. This has to happen after all fdt
nodes are added or modified.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
---
- Resending with some more in cc
common/image-fdt.c | 5 +++++
include/fdt_support.h | 1 +
2 files changed, 6 insertions(+)

diff --git a/common/image-fdt.c b/common/image-fdt.c
index 6f9ce7d..ee4dd6f 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -487,5 +487,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
if (!ft_verify_fdt(blob))
return -1;

+#ifdef CONFIG_SOC_K2HK
+ if (IMAAGE_OF_BOARD_SETUP)
+ ft_board_setup_ex(blob, gd->bd);
+#endif
+
return 0;
}
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 9871e2f..4c1416d 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -63,6 +63,7 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
#endif

void ft_board_setup(void *blob, bd_t *bd);
+void ft_board_setup_ex(void *blob, bd_t *bd);
void ft_cpu_setup(void *blob, bd_t *bd);
void ft_pci_setup(void *blob, bd_t *bd);

--
1.7.9.5
Tom Rini
2014-02-10 21:25:30 UTC
Permalink
On Fri, Feb 07, 2014 at 06:23:08PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya at ti.com>
>
> The keystone2 SOC requires to fix all 32 bit aliased addresses
> to their 36 physical format. This has to happen after all fdt
> nodes are added or modified.
>
> Signed-off-by: Vitaly Andrianov <vitalya at ti.com>

Why can't this be done with the existing CONFIG_OF_BOARD_SETUP and 'fdt
boardsetup' command?

--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140210/e1d775a1/attachment.pgp>
Vitaly Andrianov
2014-02-11 01:05:20 UTC
Permalink
On 02/10/2014 04:25 PM, Tom Rini wrote:
> On Fri, Feb 07, 2014 at 06:23:08PM -0500, Murali Karicheri wrote:
>
>> From: Vitaly Andrianov <vitalya at ti.com>
>>
>> The keystone2 SOC requires to fix all 32 bit aliased addresses
>> to their 36 physical format. This has to happen after all fdt
>> nodes are added or modified.
>>
>> Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
> Why can't this be done with the existing CONFIG_OF_BOARD_SETUP and 'fdt
> boardsetup' command?
>
Hi Tom,

The fdt_board_setup() is called at the beginning of the
image_setup_libfdt().
After that fdt can be updated by fdt_resize(), fdt_initrd() etc. All
those updates
have to be fixed. That is why we have to call the ft_board_setup_ex() at
the end
of the image_setup_libfdt().

Thanks,
Vitaly Andrianov.
Murali Karicheri
2014-02-07 23:23:09 UTC
Permalink
The NOPED_OBJ_FILES, dumpimage and mkimage object file
entries are to be kept sorted. This patch fix this issue.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- Resend with some more in cc
- As per review comments
tools/Makefile | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/Makefile b/tools/Makefile
index 328cea3..3c719b3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,10 +77,10 @@ NOPED_OBJ_FILES-y += aisimage.o
NOPED_OBJ_FILES-y += default_image.o
NOPED_OBJ_FILES-y += dumpimage.o
NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += imagetool.o
NOPED_OBJ_FILES-y += image-host.o
NOPED_OBJ_FILES-y += imximage.o
NOPED_OBJ_FILES-y += kwbimage.o
-NOPED_OBJ_FILES-y += imagetool.o
NOPED_OBJ_FILES-y += mkenvimage.o
NOPED_OBJ_FILES-y += mkimage.o
NOPED_OBJ_FILES-y += mxsimage.o
@@ -88,8 +88,8 @@ NOPED_OBJ_FILES-y += omapimage.o
NOPED_OBJ_FILES-y += os_support.o
NOPED_OBJ_FILES-y += pblimage.o
NOPED_OBJ_FILES-y += proftool.o
-NOPED_OBJ_FILES-y += ublimage.o
NOPED_OBJ_FILES-y += relocate-rela.o
+NOPED_OBJ_FILES-y += ublimage.o
OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
@@ -209,14 +209,14 @@ $(obj)dumpimage$(SFX): $(obj)aisimage.o \
$(FIT_SIG_OBJS) \
$(obj)crc32.o \
$(obj)default_image.o \
+ $(obj)dumpimage.o \
$(obj)fit_image.o \
- $(obj)image-fit.o \
$(obj)image.o \
- $(obj)image-host.o \
$(obj)imagetool.o \
+ $(obj)image-fit.o \
+ $(obj)image-host.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
- $(obj)dumpimage.o \
$(obj)md5.o \
$(obj)mxsimage.o \
$(obj)omapimage.o \
@@ -239,10 +239,10 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \
$(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
- $(obj)image-fit.o \
- $(obj)image-host.o \
$(obj)image.o \
$(obj)imagetool.o \
+ $(obj)image-host.o \
+ $(obj)image-fit.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
$(obj)md5.o \
--
1.7.9.5
Murali Karicheri
2014-02-07 23:23:10 UTC
Permalink
This patch add support for gpimage format as a preparatory
patch for porting u-boot for keystone2 devices and is
based on omapimage format. It re-uses gph header to store the
size and loadaddr as done in omapimage.c

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- Resending with some more in cc
- Addressed review comments against initial version
- refactored the code to avoid redundant code
common/image.c | 1 +
include/image.h | 1 +
tools/Makefile | 6 +++
tools/gpheader.h | 40 +++++++++++++++++++
tools/gpimage-common.c | 80 +++++++++++++++++++++++++++++++++++++
tools/gpimage.c | 77 +++++++++++++++++++++++++++++++++++
tools/imagetool.c | 2 +
tools/imagetool.h | 1 +
tools/omapimage.c | 104 ++++++++----------------------------------------
tools/omapimage.h | 5 ---
10 files changed, 224 insertions(+), 93 deletions(-)
create mode 100644 tools/gpheader.h
create mode 100644 tools/gpimage-common.c
create mode 100644 tools/gpimage.c

diff --git a/common/image.c b/common/image.c
index ae95c3f..cb5c656 100644
--- a/common/image.c
+++ b/common/image.c
@@ -124,6 +124,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", },
{ IH_TYPE_FIRMWARE, "firmware", "Firmware", },
{ IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", },
+ { IH_TYPE_GPIMAGE, "gpimage", "TI Keystone SPL Image",},
{ IH_TYPE_KERNEL, "kernel", "Kernel Image", },
{ IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", },
{ IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",},
diff --git a/include/image.h b/include/image.h
index 7de2bb2..0a3d346 100644
--- a/include/image.h
+++ b/include/image.h
@@ -214,6 +214,7 @@ struct lmb;
#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */
#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */
#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */
+#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */

/*
* Compression Types
diff --git a/tools/Makefile b/tools/Makefile
index 3c719b3..421aba5 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,6 +77,8 @@ NOPED_OBJ_FILES-y += aisimage.o
NOPED_OBJ_FILES-y += default_image.o
NOPED_OBJ_FILES-y += dumpimage.o
NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += gpimage.o
+NOPED_OBJ_FILES-y += gpimage-common.o
NOPED_OBJ_FILES-y += imagetool.o
NOPED_OBJ_FILES-y += image-host.o
NOPED_OBJ_FILES-y += imximage.o
@@ -211,6 +213,8 @@ $(obj)dumpimage$(SFX): $(obj)aisimage.o \
$(obj)default_image.o \
$(obj)dumpimage.o \
$(obj)fit_image.o \
+ $(obj)gpimage.o \
+ $(obj)gpimage-common.o \
$(obj)image.o \
$(obj)imagetool.o \
$(obj)image-fit.o \
@@ -239,6 +243,8 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \
$(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
+ $(obj)gpimage.o \
+ $(obj)gpimage-common.o \
$(obj)image.o \
$(obj)imagetool.o \
$(obj)image-host.o \
diff --git a/tools/gpheader.h b/tools/gpheader.h
new file mode 100644
index 0000000..63a28a2
--- /dev/null
+++ b/tools/gpheader.h
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c. Include this common
+ * header file
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby at linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _GPIMAGE_H_
+#define _GPIMAGE_H_
+
+/* common headers for gpimage and omapimage formats */
+struct gp_header {
+ uint32_t size;
+ uint32_t load_addr;
+};
+#define GPIMAGE_HDR_SIZE (sizeof(struct gp_header))
+
+/* common functions across gpimage and omapimage handlers */
+int valid_gph_size(uint32_t size);
+int valid_gph_load_addr(uint32_t load_addr);
+int gph_verify_header(struct gp_header *gph, int be);
+void gph_print_header(const struct gp_header *gph, int be);
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+ int be);
+int gpimage_check_params(struct image_tool_params *params);
+#endif
diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c
new file mode 100644
index 0000000..b343a3a
--- /dev/null
+++ b/tools/gpimage-common.c
@@ -0,0 +1,80 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c.
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby at linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+/* Helper to convert size and load_addr to big endian */
+void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr)
+{
+ *gph_size = cpu_to_be32(*gph_size);
+ *gph_load_addr = cpu_to_be32(*gph_load_addr);
+}
+
+int gph_verify_header(struct gp_header *gph, int be)
+{
+ uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+ if (be)
+ to_be32(&gph_size, &gph_load_addr);
+
+ if (!gph_size || !gph_load_addr)
+ return -1;
+
+ return 0;
+}
+
+void gph_print_header(const struct gp_header *gph, int be)
+{
+ uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+ if (be)
+ to_be32(&gph_size, &gph_load_addr);
+
+ if (!gph_size) {
+ fprintf(stderr, "Error: invalid image size %x\n", gph_size);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!gph_load_addr) {
+ fprintf(stderr, "Error: invalid image load address %x\n",
+ gph_load_addr);
+ exit(EXIT_FAILURE);
+ }
+ printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+}
+
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+ int be)
+{
+ gph->size = size;
+ gph->load_addr = load_addr;
+ if (be)
+ to_be32(&gph->size, &gph->load_addr);
+}
+
+int gpimage_check_params(struct image_tool_params *params)
+{
+ return (params->dflag && (params->fflag || params->lflag)) ||
+ (params->fflag && (params->dflag || params->lflag)) ||
+ (params->lflag && (params->dflag || params->fflag));
+}
diff --git a/tools/gpimage.c b/tools/gpimage.c
new file mode 100644
index 0000000..1cabb5b
--- /dev/null
+++ b/tools/gpimage.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Add gpimage format for keystone devices to format spl image. This is
+ * Based on omapimage.c
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby at linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+static uint8_t gpimage_header[GPIMAGE_HDR_SIZE];
+
+/* to be in keystone gpimage */
+static int gpimage_check_image_types(uint8_t type)
+{
+ if (type == IH_TYPE_GPIMAGE)
+ return EXIT_SUCCESS;
+ return EXIT_FAILURE;
+}
+
+static int gpimage_verify_header(unsigned char *ptr, int image_size,
+ struct image_tool_params *params)
+{
+ struct gp_header *gph = (struct gp_header *)ptr;
+
+ return gph_verify_header(gph, 1);
+}
+
+static void gpimage_print_header(const void *ptr)
+{
+ const struct gp_header *gph = (struct gp_header *)ptr;
+
+ gph_print_header(gph, 1);
+}
+
+static void gpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
+ struct image_tool_params *params)
+{
+ struct gp_header *gph = (struct gp_header *)ptr;
+
+ gph_set_header(gph, sbuf->st_size - GPIMAGE_HDR_SIZE, params->addr, 1);
+}
+
+/*
+ * gpimage parameters
+ */
+static struct image_type_params gpimage_params = {
+ .name = "TI KeyStone GP Image support",
+ .header_size = GPIMAGE_HDR_SIZE,
+ .hdr = (void *)&gpimage_header,
+ .check_image_type = gpimage_check_image_types,
+ .verify_header = gpimage_verify_header,
+ .print_header = gpimage_print_header,
+ .set_header = gpimage_set_header,
+ .check_params = gpimage_check_params,
+};
+
+void init_gpimage_type(void)
+{
+ register_image_type(&gpimage_params);
+}
diff --git a/tools/imagetool.c b/tools/imagetool.c
index 29d2189..da72115 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -45,6 +45,8 @@ void register_image_tool(imagetool_register_t image_register)
init_ubl_image_type();
/* Init Davinci AIS support */
init_ais_image_type();
+ /* Init TI Keystone boot image generation/list support */
+ init_gpimage_type();
}

/*
diff --git a/tools/imagetool.h b/tools/imagetool.h
index c2c9aea..a3e9d30 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -167,6 +167,7 @@ void init_mxs_image_type(void);
void init_fit_image_type(void);
void init_ubl_image_type(void);
void init_omap_image_type(void);
+void init_gpimage_type(void);

void pbl_load_uboot(int fd, struct image_tool_params *mparams);

diff --git a/tools/omapimage.c b/tools/omapimage.c
index d59bc4d..1e0c164 100644
--- a/tools/omapimage.c
+++ b/tools/omapimage.c
@@ -15,57 +15,24 @@
*/

#include "imagetool.h"
+#include <compiler.h>
#include <image.h>
+#include "gpheader.h"
#include "omapimage.h"

/* Header size is CH header rounded up to 512 bytes plus GP header */
#define OMAP_CH_HDR_SIZE 512
-#define OMAP_GP_HDR_SIZE (sizeof(struct gp_header))
-#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE)
+#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE + GPIMAGE_HDR_SIZE)

static int do_swap32 = 0;

-static uint32_t omapimage_swap32(uint32_t data)
-{
- uint32_t result = 0;
- result = (data & 0xFF000000) >> 24;
- result |= (data & 0x00FF0000) >> 8;
- result |= (data & 0x0000FF00) << 8;
- result |= (data & 0x000000FF) << 24;
- return result;
-}
-
static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];

static int omapimage_check_image_types(uint8_t type)
{
if (type == IH_TYPE_OMAPIMAGE)
return EXIT_SUCCESS;
- else {
- return EXIT_FAILURE;
- }
-}
-
-/*
- * Only the simplest image type is currently supported:
- * TOC pointing to CHSETTINGS
- * TOC terminator
- * CHSETTINGS
- *
- * padding to OMAP_CH_HDR_SIZE bytes
- *
- * gp header
- * size
- * load_addr
- */
-static int valid_gph_size(uint32_t size)
-{
- return size;
-}
-
-static int valid_gph_load_addr(uint32_t load_addr)
-{
- return load_addr;
+ return EXIT_FAILURE;
}

static int omapimage_verify_header(unsigned char *ptr, int image_size,
@@ -73,13 +40,13 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
{
struct ch_toc *toc = (struct ch_toc *)ptr;
struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
- uint32_t offset, size, gph_size, gph_load_addr;
+ uint32_t offset, size;

while (toc->section_offset != 0xffffffff
&& toc->section_size != 0xffffffff) {
if (do_swap32) {
- offset = omapimage_swap32(toc->section_offset);
- size = omapimage_swap32(toc->section_size);
+ offset = cpu_to_be32(toc->section_offset);
+ size = cpu_to_be32(toc->section_size);
} else {
offset = toc->section_offset;
size = toc->section_size;
@@ -92,20 +59,7 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
toc++;
}

- if (do_swap32) {
- gph_size = omapimage_swap32(gph->size);
- gph_load_addr = omapimage_swap32(gph->load_addr);
- } else {
- gph_size = gph->size;
- gph_load_addr = gph->load_addr;
- }
-
- if (!valid_gph_size(gph_size))
- return -1;
- if (!valid_gph_load_addr(gph_load_addr))
- return -1;
-
- return 0;
+ return gph_verify_header(gph, do_swap32);
}

static void omapimage_print_section(struct ch_settings *chs)
@@ -135,13 +89,13 @@ static void omapimage_print_header(const void *ptr)
const struct ch_toc *toc = (struct ch_toc *)ptr;
const struct gp_header *gph =
(struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
- uint32_t offset, size, gph_size, gph_load_addr;
+ uint32_t offset, size;

while (toc->section_offset != 0xffffffff
&& toc->section_size != 0xffffffff) {
if (do_swap32) {
- offset = omapimage_swap32(toc->section_offset);
- size = omapimage_swap32(toc->section_size);
+ offset = cpu_to_be32(toc->section_offset);
+ size = cpu_to_be32(toc->section_size);
} else {
offset = toc->section_offset;
size = toc->section_size;
@@ -160,26 +114,7 @@ static void omapimage_print_header(const void *ptr)
toc++;
}

- if (do_swap32) {
- gph_size = omapimage_swap32(gph->size);
- gph_load_addr = omapimage_swap32(gph->load_addr);
- } else {
- gph_size = gph->size;
- gph_load_addr = gph->load_addr;
- }
-
- if (!valid_gph_size(gph_size)) {
- fprintf(stderr, "Error: invalid image size %x\n", gph_size);
- exit(EXIT_FAILURE);
- }
-
- if (!valid_gph_load_addr(gph_load_addr)) {
- fprintf(stderr, "Error: invalid image load address %x\n",
- gph_load_addr);
- exit(EXIT_FAILURE);
- }
-
- printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+ gph_print_header(gph, do_swap32);
}

static int toc_offset(void *hdr, void *member)
@@ -208,8 +143,8 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
toc++;
memset(toc, 0xff, sizeof(*toc));

- gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE;
- gph->load_addr = params->addr;
+ gph_set_header(gph, sbuf->st_size - OMAP_FILE_HDR_SIZE,
+ params->addr, 0);

if (strncmp(params->imagename, "byteswap", 8) == 0) {
do_swap32 = 1;
@@ -217,20 +152,13 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
uint32_t *data = (uint32_t *)ptr;

while (swapped <= (sbuf->st_size / sizeof(uint32_t))) {
- *data = omapimage_swap32(*data);
+ *data = cpu_to_be32(*data);
swapped++;
data++;
}
}
}

-int omapimage_check_params(struct image_tool_params *params)
-{
- return (params->dflag && (params->fflag || params->lflag)) ||
- (params->fflag && (params->dflag || params->lflag)) ||
- (params->lflag && (params->dflag || params->fflag));
-}
-
/*
* omapimage parameters
*/
@@ -242,7 +170,7 @@ static struct image_type_params omapimage_params = {
.verify_header = omapimage_verify_header,
.print_header = omapimage_print_header,
.set_header = omapimage_set_header,
- .check_params = omapimage_check_params,
+ .check_params = gpimage_check_params,
};

void init_omap_image_type(void)
diff --git a/tools/omapimage.h b/tools/omapimage.h
index 45d14ea..8744ae7 100644
--- a/tools/omapimage.h
+++ b/tools/omapimage.h
@@ -25,10 +25,5 @@ struct ch_settings {
uint32_t flags;
};

-struct gp_header {
- uint32_t size;
- uint32_t load_addr;
-};
-
#define KEY_CHSETTINGS 0xC0C0C0C1
#endif /* _OMAPIMAGE_H_ */
--
1.7.9.5
Murali Karicheri
2014-02-07 23:23:13 UTC
Permalink
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 at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
Signed-off-by: WingMan Kwok <w-kwok2 at ti.com>
Signed-off-by: Sandeep Nair <sandeep_n at 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

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 at 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 at 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 at 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 at 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 at monstr.eu>:Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
Active arm armv7 zynq xilinx zynq zynq_zc770_xm012 zynq_zc770:ZC770_XM012 Michal Simek <monstr at monstr.eu>:Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
Active arm armv7 zynq xilinx zynq zynq_zc770_xm013 zynq_zc770:ZC770_XM013 Michal Simek <monstr at monstr.eu>:Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
+Active arm armv7 keystone ti k2hk_evm k2hk_evm - Vitaly Andrianov <vitalya at ti.com>
Active arm armv7:arm720t tegra114 nvidia dalmore dalmore - Tom Warren <twarren at nvidia.com>
Active arm armv7:arm720t tegra20 avionic-design medcom-wide medcom-wide - Alban Bedel <alban.bedel at avionic-design.de>
Active arm armv7:arm720t tegra20 avionic-design plutux plutux - Alban Bedel <alban.bedel at 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 at 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 */
--
1.7.9.5
Tom Rini
2014-02-10 21:25:39 UTC
Permalink
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?

--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140210/a45b7e91/attachment.pgp>
Vitaly Andrianov
2014-02-11 01:44:01 UTC
Permalink
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
2014-02-12 12:53:30 UTC
Permalink
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
Tom Rini
2014-02-17 21:57:41 UTC
Permalink
On 02/17/2014 04:19 PM, Andrianov, Vitaly wrote:
>> -----Original Message-----
>> From: Tom Rini [mailto:tom.rini at gmail.com] On Behalf Of Rini, Tom
>> Sent: Monday, February 10, 2014 4:26 PM
>> To: Karicheri, Muralidharan
>> Cc: u-boot at lists.denx.de; Sandeep at 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
Andrianov, Vitaly
2014-02-20 17:27:57 UTC
Permalink
> -----Original Message-----
> From: Rini, Tom
> Sent: Monday, February 17, 2014 4:58 PM
> To: Andrianov, Vitaly
> Cc: Karicheri, Muralidharan; u-boot at lists.denx.de;
> Sandeep at 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 at gmail.com] On Behalf Of Rini, Tom
> >> Sent: Monday, February 10, 2014 4:26 PM
> >> To: Karicheri, Muralidharan
> >> Cc: u-boot at lists.denx.de; Sandeep at 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
Andrianov, Vitaly
2014-02-17 21:19:43 UTC
Permalink
> -----Original Message-----
> From: Tom Rini [mailto:tom.rini at gmail.com] On Behalf Of Rini, Tom
> Sent: Monday, February 10, 2014 4:26 PM
> To: Karicheri, Muralidharan
> Cc: u-boot at lists.denx.de; Sandeep at 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
Albert ARIBAUD
2014-02-10 08:32:31 UTC
Permalink
Hi Murali,

On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
<m-karicheri2 at ti.com> wrote:

> - Resending since I missed some in the CC
>
> This patch series add support for keystone2 SoC and K2HK EVM.
>
> Following patches were reviewed before in this list and v1 of the
> same is send with review comments incorporated:-
> - tools: mkimage: add support for gpimage format
> - arm: add support for arch timer
> - NAND: DaVinci: allow forced disable of subpage writes
>
> The patch below is added as a seperate patch based on comments:-
> - tools: sort the entries in Makefile
>
> Murali Karicheri (5):
> tools: sort the entries in Makefile

> tools: mkimage: add support for gpimage format

Is this image format required? Can't one of the existing image formats
be used?

> NAND: DaVinci: allow forced disable of subpage writes
> k2hk: add support for k2hk SOC and EVM
> keystone2: net: add keystone ethernet driver

Amicalement,
--
Albert.
Murali Karicheri
2014-02-10 17:22:53 UTC
Permalink
On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
> Hi Murali,
>
> On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
> <m-karicheri2 at ti.com> wrote:
>
>> - Resending since I missed some in the CC
>>
>> This patch series add support for keystone2 SoC and K2HK EVM.
>>
>> Following patches were reviewed before in this list and v1 of the
>> same is send with review comments incorporated:-
>> - tools: mkimage: add support for gpimage format
>> - arm: add support for arch timer
>> - NAND: DaVinci: allow forced disable of subpage writes
>>
>> The patch below is added as a seperate patch based on comments:-
>> - tools: sort the entries in Makefile
>>
>> Murali Karicheri (5):
>> tools: sort the entries in Makefile
>> tools: mkimage: add support for gpimage format
> Is this image format required? Can't one of the existing image formats
> be used?
Alebert,

Thanks for your response.

We are actually re-using part of the OMAP image format by factoring out
the common code
and re-using. So this is not a new format. Please review the code.

Murali
>> NAND: DaVinci: allow forced disable of subpage writes
>> k2hk: add support for k2hk SOC and EVM
>> keystone2: net: add keystone ethernet driver
> Amicalement,
Albert ARIBAUD
2014-02-10 18:01:33 UTC
Permalink
Hi Murali,

On Mon, 10 Feb 2014 12:22:53 -0500, Murali Karicheri
<m-karicheri2 at ti.com> wrote:

> On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
> > Hi Murali,
> >
> > On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
> > <m-karicheri2 at ti.com> wrote:
> >
> >> - Resending since I missed some in the CC
> >>
> >> This patch series add support for keystone2 SoC and K2HK EVM.
> >>
> >> Following patches were reviewed before in this list and v1 of the
> >> same is send with review comments incorporated:-
> >> - tools: mkimage: add support for gpimage format
> >> - arm: add support for arch timer
> >> - NAND: DaVinci: allow forced disable of subpage writes
> >>
> >> The patch below is added as a seperate patch based on comments:-
> >> - tools: sort the entries in Makefile
> >>
> >> Murali Karicheri (5):
> >> tools: sort the entries in Makefile
> >> tools: mkimage: add support for gpimage format
> > Is this image format required? Can't one of the existing image formats
> > be used?
> Alebert,
>
> Thanks for your response.
>
> We are actually re-using part of the OMAP image format by factoring out
> the common code
> and re-using. So this is not a new format. Please review the code.

Thanks. This describes what you do and how you do it, but it does not
tell me why you are doing it and why you can't do otherwise. Let me
rephrase my question since you're mentioning branching off the OMAP
image format: why branch off? Why not simply use the existing OMAP image
format? Or another one?

> Murali

Amicalement,
--
Albert.
Murali Karicheri
2014-02-10 19:42:14 UTC
Permalink
On 2/10/2014 1:01 PM, Albert ARIBAUD wrote:
> Hi Murali,
>
> On Mon, 10 Feb 2014 12:22:53 -0500, Murali Karicheri
> <m-karicheri2 at ti.com> wrote:
>
>> On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
>>> Hi Murali,
>>>
>>> On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
>>> <m-karicheri2 at ti.com> wrote:
>>>
>>>> - Resending since I missed some in the CC
>>>>
>>>> This patch series add support for keystone2 SoC and K2HK EVM.
>>>>
>>>> Following patches were reviewed before in this list and v1 of the
>>>> same is send with review comments incorporated:-
>>>> - tools: mkimage: add support for gpimage format
>>>> - arm: add support for arch timer
>>>> - NAND: DaVinci: allow forced disable of subpage writes
>>>>
>>>> The patch below is added as a seperate patch based on comments:-
>>>> - tools: sort the entries in Makefile
>>>>
>>>> Murali Karicheri (5):
>>>> tools: sort the entries in Makefile
>>>> tools: mkimage: add support for gpimage format
>>> Is this image format required? Can't one of the existing image formats
>>> be used?
>> Alebert,
>>
>> Thanks for your response.
>>
>> We are actually re-using part of the OMAP image format by factoring out
>> the common code
>> and re-using. So this is not a new format. Please review the code.
> Thanks. This describes what you do and how you do it, but it does not
> tell me why you are doing it and why you can't do otherwise. Let me
> rephrase my question since you're mentioning branching off the OMAP
> image format: why branch off? Why not simply use the existing OMAP image
> format? Or another one?
Because the ROM bootloader in our platform (keystone2) expect the header
to be in
the following format :-

<size - 4 byte> <load addr- 4 byte> <data>

OMAP uses different format
<omap header 512 bytes> <size - 4 byte> <load addr - 4 bytes>

gp header (size, loadaddr) is common between the two image formats. So that
is factored out and used in our platform. Hope this is clear now.

Regards,

Murali
>> Murali
> Amicalement,
Albert ARIBAUD
2014-02-10 19:58:10 UTC
Permalink
Hi Murali,

On Mon, 10 Feb 2014 14:42:14 -0500, Murali Karicheri
<m-karicheri2 at ti.com> wrote:

> On 2/10/2014 1:01 PM, Albert ARIBAUD wrote:
> > Hi Murali,
> >
> > On Mon, 10 Feb 2014 12:22:53 -0500, Murali Karicheri
> > <m-karicheri2 at ti.com> wrote:
> >
> >> On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
> >>> Hi Murali,
> >>>
> >>> On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
> >>> <m-karicheri2 at ti.com> wrote:
> >>>
> >>>> - Resending since I missed some in the CC
> >>>>
> >>>> This patch series add support for keystone2 SoC and K2HK EVM.
> >>>>
> >>>> Following patches were reviewed before in this list and v1 of the
> >>>> same is send with review comments incorporated:-
> >>>> - tools: mkimage: add support for gpimage format
> >>>> - arm: add support for arch timer
> >>>> - NAND: DaVinci: allow forced disable of subpage writes
> >>>>
> >>>> The patch below is added as a seperate patch based on comments:-
> >>>> - tools: sort the entries in Makefile
> >>>>
> >>>> Murali Karicheri (5):
> >>>> tools: sort the entries in Makefile
> >>>> tools: mkimage: add support for gpimage format
> >>> Is this image format required? Can't one of the existing image formats
> >>> be used?
> >> Alebert,
> >>
> >> Thanks for your response.
> >>
> >> We are actually re-using part of the OMAP image format by factoring out
> >> the common code
> >> and re-using. So this is not a new format. Please review the code.
> > Thanks. This describes what you do and how you do it, but it does not
> > tell me why you are doing it and why you can't do otherwise. Let me
> > rephrase my question since you're mentioning branching off the OMAP
> > image format: why branch off? Why not simply use the existing OMAP image
> > format? Or another one?
> Because the ROM bootloader in our platform (keystone2) expect the header
> to be in
> the following format :-
>
> <size - 4 byte> <load addr- 4 byte> <data>
>
> OMAP uses different format
> <omap header 512 bytes> <size - 4 byte> <load addr - 4 bytes>
>
> gp header (size, loadaddr) is common between the two image formats. So that
> is factored out and used in our platform. Hope this is clear now.

Ok, thanks.

> Regards,
>
> Murali

Amicalement,
--
Albert.
Tom Rini
2014-02-10 21:23:23 UTC
Permalink
On Fri, Feb 07, 2014 at 06:23:07PM -0500, Murali Karicheri wrote:

> - Resending since I missed some in the CC
>
> This patch series add support for keystone2 SoC and K2HK EVM.
>
> Following patches were reviewed before in this list and v1 of the
> same is send with review comments incorporated:-
> - tools: mkimage: add support for gpimage format
> - arm: add support for arch timer
> - NAND: DaVinci: allow forced disable of subpage writes
>
> The patch below is added as a seperate patch based on comments:-
> - tools: sort the entries in Makefile
>
> Murali Karicheri (5):
> tools: sort the entries in Makefile
> tools: mkimage: add support for gpimage format
> NAND: DaVinci: allow forced disable of subpage writes
> k2hk: add support for k2hk SOC and EVM
> keystone2: net: add keystone ethernet driver
>
> Vitaly Andrianov (2):
> fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
> arm: add support for arch timer

For the next go-round, you shouldn't need to give git send-email
anything more than --subject-prefix='PATCH v3' to get the subject
correct and shorter.

In general:
- 7/7 got lost? Or did I just miss it?
- There's a lot of what looks like copy/paste from davinci drivers, we
need to better re-use the code in place (and move to common locations
as needed).

--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140210/e605d9fb/attachment.pgp>
Murali Karicheri
2014-02-20 17:55:02 UTC
Permalink
This patch series add support for keystone2 SoC and K2HK EVM

Change history:
v2
- Review comments incorporated. Following are major comments
addressed
- split network driver to navigator driver + ethernet
driver
- replaced register base + offset implemenation with struct
based register access implementation
- Added Readme for NAND no subpage write option
- re-use code for davinci i2c driver on keystone2 with updates
- clock-k2hk.c merged to clock.c
- currently keeping board specific getclk() command. See the thread
for the rational.
- Added update to davinci spi driver to re-use on keystone

v1
- added separate patch for sorting tools/Makefile entries
- reworked gpimage patch to allow more re-use across omapimage/gpimage
- dropped patch related to ubifs file size
- added keystone SoC and K2HK EVM support

v0
- preparatory patch for keystone

Murali Karicheri (5):
tools: sort the entries in Makefile
tools: mkimage: add support for gpimage format
NAND: DaVinci: allow forced disable of subpage writes
i2c, davinci: move i2c_defs.h to the drivers/i2c directory
k2hk-evm: add configuration for spi1 and spi2 support

Rex Chang (1):
spi: davinci: add support for multiple bus and chip select

Vitaly Andrianov (6):
fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
arm: add support for arch timer
i2c, davinci: add support for multiple i2c buses
k2hk: add support for k2hk SOC and EVM
keystone2: add keystone multicore navigator driver
keystone2: net: add keystone ethernet driver

Makefile | 19 +
README | 5 +
arch/arm/cpu/armv7/keystone/Makefile | 18 +
arch/arm/cpu/armv7/keystone/aemif.c | 71 ++
arch/arm/cpu/armv7/keystone/clock.c | 313 +++++++
arch/arm/cpu/armv7/keystone/cmd_clock.c | 124 +++
arch/arm/cpu/armv7/keystone/cmd_mon.c | 131 +++
arch/arm/cpu/armv7/keystone/config.mk | 15 +
arch/arm/cpu/armv7/keystone/ddr3.c | 69 ++
arch/arm/cpu/armv7/keystone/init.c | 56 ++
arch/arm/cpu/armv7/keystone/keystone_nav.c | 376 +++++++++
arch/arm/cpu/armv7/keystone/msmc.c | 68 ++
arch/arm/cpu/armv7/keystone/psc.c | 238 ++++++
arch/arm/cpu/armv7/keystone/spl.c | 45 +
arch/arm/include/asm/arch-davinci/i2c_defs.h | 71 +-
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 | 121 +++
arch/arm/include/asm/arch-keystone/emac_defs.h | 250 ++++++
arch/arm/include/asm/arch-keystone/emif_defs.h | 73 ++
arch/arm/include/asm/arch-keystone/hardware-k2hk.h | 145 ++++
arch/arm/include/asm/arch-keystone/hardware.h | 175 ++++
arch/arm/include/asm/arch-keystone/i2c_defs.h | 17 +
arch/arm/include/asm/arch-keystone/keystone_nav.h | 193 +++++
arch/arm/include/asm/arch-keystone/nand_defs.h | 25 +
arch/arm/include/asm/arch-keystone/psc_defs.h | 90 ++
arch/arm/include/asm/arch-keystone/spl.h | 12 +
arch/arm/lib/Makefile | 1 +
arch/arm/lib/arch_timer.c | 58 ++
board/ti/k2hk_evm/Makefile | 9 +
board/ti/k2hk_evm/README | 56 ++
board/ti/k2hk_evm/board.c | 301 +++++++
board/ti/k2hk_evm/ddr3.c | 269 ++++++
boards.cfg | 1 +
common/image-fdt.c | 5 +
common/image.c | 1 +
drivers/i2c/davinci_i2c.c | 345 ++++----
drivers/i2c/davinci_i2c.h | 78 ++
drivers/mtd/nand/davinci_nand.c | 3 +
drivers/net/Makefile | 1 +
drivers/net/keystone_net.c | 859 ++++++++++++++++++++
drivers/serial/ns16550.c | 8 +
drivers/spi/davinci_spi.c | 62 +-
drivers/spi/davinci_spi.h | 33 +
include/configs/k2hk_evm.h | 268 ++++++
include/fdt_support.h | 1 +
include/image.h | 1 +
tools/Makefile | 20 +-
tools/gpheader.h | 40 +
tools/gpimage-common.c | 80 ++
tools/gpimage.c | 77 ++
tools/imagetool.c | 2 +
tools/imagetool.h | 1 +
tools/omapimage.c | 104 +--
tools/omapimage.h | 5 -
55 files changed, 5222 insertions(+), 313 deletions(-)
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.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/keystone_nav.c
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/emac_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/keystone_nav.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 arch/arm/lib/arch_timer.c
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/davinci_i2c.h
create mode 100644 drivers/net/keystone_net.c
create mode 100644 include/configs/k2hk_evm.h
create mode 100644 tools/gpheader.h
create mode 100644 tools/gpimage-common.c
create mode 100644 tools/gpimage.c

--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:03 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

The keystone2 SOC requires to fix all 32 bit aliased addresses
to their 36 physical format. This has to happen after all fdt
nodes are added or modified.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
---
- no update since v1
common/image-fdt.c | 5 +++++
include/fdt_support.h | 1 +
2 files changed, 6 insertions(+)

diff --git a/common/image-fdt.c b/common/image-fdt.c
index 6f9ce7d..ee4dd6f 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -487,5 +487,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
if (!ft_verify_fdt(blob))
return -1;

+#ifdef CONFIG_SOC_K2HK
+ if (IMAAGE_OF_BOARD_SETUP)
+ ft_board_setup_ex(blob, gd->bd);
+#endif
+
return 0;
}
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 9871e2f..4c1416d 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -63,6 +63,7 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
#endif

void ft_board_setup(void *blob, bd_t *bd);
+void ft_board_setup_ex(void *blob, bd_t *bd);
void ft_cpu_setup(void *blob, bd_t *bd);
void ft_pci_setup(void *blob, bd_t *bd);

--
1.7.9.5
Tom Rini
2014-02-25 22:10:53 UTC
Permalink
On Thu, Feb 20, 2014 at 12:55:03PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya at ti.com>
>
> The keystone2 SOC requires to fix all 32 bit aliased addresses
> to their 36 physical format. This has to happen after all fdt
> nodes are added or modified.
>
> Signed-off-by: Vitaly Andrianov <vitalya at ti.com>

Acked-by: Tom Rini <trini at ti.com>

--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/a5326cc6/attachment.pgp>
Murali Karicheri
2014-02-20 17:55:07 UTC
Permalink
This patch introduces a configurable mechanism to disable
subpage writes in the DaVinci NAND driver.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- Added README
README | 5 +++++
drivers/mtd/nand/davinci_nand.c | 3 +++
2 files changed, 8 insertions(+)

diff --git a/README b/README
index aea82be..caf60a2 100644
--- a/README
+++ b/README
@@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
- CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
Enables the RTC32K OSC on AM33xx based plattforms

+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+ Option to disable subpage write in NAND driver
+ Example driver that use this:
+ drivers/mtd/nand/davinci_nand.c
+
Freescale QE/FMAN Firmware Support:
-----------------------------------

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 5b17d7b..75b03a7 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -609,6 +609,9 @@ void davinci_nand_init(struct nand_chip *nand)
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
nand->bbt_options |= NAND_BBT_USE_FLASH;
#endif
+#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+ nand->options |= NAND_NO_SUBPAGE_WRITE;
+#endif
#ifdef CONFIG_SYS_NAND_HW_ECC
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.size = 512;
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:06 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

This patch add basic support for the architecture timer found on recent
ARMv7 based SoCs.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- No update since v1
arch/arm/lib/Makefile | 1 +
arch/arm/lib/arch_timer.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
create mode 100644 arch/arm/lib/arch_timer.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 321997c..726f229 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
else
obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
endif
+obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o

ifdef CONFIG_ARM64
obj-y += interrupts_64.o
diff --git a/arch/arm/lib/arch_timer.c b/arch/arm/lib/arch_timer.c
new file mode 100644
index 0000000..0588e2b
--- /dev/null
+++ b/arch/arm/lib/arch_timer.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <div64.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int timer_init(void)
+{
+ gd->arch.tbl = 0;
+ gd->arch.tbu = 0;
+
+ gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ;
+
+ return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+ ulong nowl, nowu;
+
+ asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu));
+
+ gd->arch.tbl = nowl;
+ gd->arch.tbu = nowu;
+
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+
+ulong get_timer(ulong base)
+{
+ return lldiv(get_ticks(), gd->arch.timer_rate_hz) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ unsigned long long endtime;
+
+ endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz,
+ 1000UL);
+
+ endtime += get_ticks();
+
+ while (get_ticks() < endtime)
+ ;
+}
+
+ulong get_tbclk(void)
+{
+ return gd->arch.timer_rate_hz;
+}
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:04 UTC
Permalink
The NOPED_OBJ_FILES, dumpimage and mkimage object file
entries are to be kept sorted. This patch fix this issue.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- No update since v1
tools/Makefile | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/Makefile b/tools/Makefile
index 328cea3..3c719b3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,10 +77,10 @@ NOPED_OBJ_FILES-y += aisimage.o
NOPED_OBJ_FILES-y += default_image.o
NOPED_OBJ_FILES-y += dumpimage.o
NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += imagetool.o
NOPED_OBJ_FILES-y += image-host.o
NOPED_OBJ_FILES-y += imximage.o
NOPED_OBJ_FILES-y += kwbimage.o
-NOPED_OBJ_FILES-y += imagetool.o
NOPED_OBJ_FILES-y += mkenvimage.o
NOPED_OBJ_FILES-y += mkimage.o
NOPED_OBJ_FILES-y += mxsimage.o
@@ -88,8 +88,8 @@ NOPED_OBJ_FILES-y += omapimage.o
NOPED_OBJ_FILES-y += os_support.o
NOPED_OBJ_FILES-y += pblimage.o
NOPED_OBJ_FILES-y += proftool.o
-NOPED_OBJ_FILES-y += ublimage.o
NOPED_OBJ_FILES-y += relocate-rela.o
+NOPED_OBJ_FILES-y += ublimage.o
OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
@@ -209,14 +209,14 @@ $(obj)dumpimage$(SFX): $(obj)aisimage.o \
$(FIT_SIG_OBJS) \
$(obj)crc32.o \
$(obj)default_image.o \
+ $(obj)dumpimage.o \
$(obj)fit_image.o \
- $(obj)image-fit.o \
$(obj)image.o \
- $(obj)image-host.o \
$(obj)imagetool.o \
+ $(obj)image-fit.o \
+ $(obj)image-host.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
- $(obj)dumpimage.o \
$(obj)md5.o \
$(obj)mxsimage.o \
$(obj)omapimage.o \
@@ -239,10 +239,10 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \
$(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
- $(obj)image-fit.o \
- $(obj)image-host.o \
$(obj)image.o \
$(obj)imagetool.o \
+ $(obj)image-host.o \
+ $(obj)image-fit.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
$(obj)md5.o \
--
1.7.9.5
Tom Rini
2014-02-25 22:10:59 UTC
Permalink
On Thu, Feb 20, 2014 at 12:55:04PM -0500, Murali Karicheri wrote:

> The NOPED_OBJ_FILES, dumpimage and mkimage object file
> entries are to be kept sorted. This patch fix this issue.
>
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>

Acked-by: Tom Rini <trini at ti.com>

--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/391164dc/attachment.pgp>
Murali Karicheri
2014-02-20 17:55:09 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
---
drivers/i2c/davinci_i2c.c | 344 ++++++++++++++++++++++++++-------------------
drivers/i2c/davinci_i2c.h | 27 ++--
2 files changed, 218 insertions(+), 153 deletions(-)

diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index 6e5260c..c584a11 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -1,25 +1,37 @@
/*
* TI DaVinci (TMS320DM644x) I2C driver.
*
- * Copyright (C) 2007 Sergey Kubushyn <ksi at koi8.net>
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi at koi8.net>
*
- * --------------------------------------------------------
- *
- * SPDX-License-Identifier: GPL-2.0+
+ * 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>
#include "davinci_i2c.h"

+DECLARE_GLOBAL_DATA_PTR;
+
+static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
+ (struct i2c_regs *)I2C_BASE;
+
+#ifdef CONFIG_I2C_MULTI_BUS
+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;
+#endif
+
#define CHECK_NACK() \
do {\
if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
- REG(I2C_CON) = 0;\
- return(1);\
- }\
+ REG(&(i2c_base->i2c_con)) = 0;\
+ return 1;\
+ } \
} while (0)


@@ -27,20 +39,21 @@ static int wait_for_bus(void)
{
int stat, timeout;

- REG(I2C_STAT) = 0xffff;
+ REG(&(i2c_base->i2c_stat)) = 0xffff;

for (timeout = 0; timeout < 10; timeout++) {
- if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
- REG(I2C_STAT) = 0xffff;
- return(0);
+ stat = REG(&(i2c_base->i2c_stat));
+ if (!((stat) & I2C_STAT_BB)) {
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ return 0;
}

- REG(I2C_STAT) = stat;
+ REG(&(i2c_base->i2c_stat)) = stat;
udelay(50000);
}

- REG(I2C_STAT) = 0xffff;
- return(1);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ return 1;
}


@@ -50,25 +63,24 @@ static int poll_i2c_irq(int mask)

for (timeout = 0; timeout < 10; timeout++) {
udelay(1000);
- stat = REG(I2C_STAT);
- if (stat & mask) {
- return(stat);
- }
+ stat = REG(&(i2c_base->i2c_stat));
+ if (stat & mask)
+ return stat;
}

- REG(I2C_STAT) = 0xffff;
- return(stat | I2C_TIMEOUT);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ return stat | I2C_TIMEOUT;
}


void flush_rx(void)
{
while (1) {
- if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
+ if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
break;

- REG(I2C_DRR);
- REG(I2C_STAT) = I2C_STAT_RRDY;
+ REG(&(i2c_base->i2c_drr));
+ REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
udelay(1000);
}
}
@@ -78,28 +90,33 @@ void i2c_init(int speed, int slaveadd)
{
u_int32_t div, psc;

- if (REG(I2C_CON) & I2C_CON_EN) {
- REG(I2C_CON) = 0;
- udelay (50000);
+ 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; /* SCLL + SCLH */
- REG(I2C_PSC) = psc; /* 27MHz / (2 + 1) = 9MHz */
- REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */
- REG(I2C_SCLH) = div - REG(I2C_SCLL);
+ 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_OA) = slaveadd;
- REG(I2C_CNT) = 0;
+ REG(&(i2c_base->i2c_oa)) = slaveadd;
+ REG(&(i2c_base->i2c_cnt)) = 0;

/* Interrupts must be enabled or I2C module won't work */
- REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+ 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_CON) = I2C_CON_EN;
+ REG(&(i2c_base->i2c_con)) = I2C_CON_EN;

udelay(1000);
+
+#ifdef CONFIG_I2C_MULTI_BUS
+ if (gd->flags & GD_FLG_RELOC)
+ bus_initialized[current_bus] = 1;
+#endif
}

int i2c_set_bus_speed(unsigned int speed)
@@ -112,34 +129,36 @@ int i2c_probe(u_int8_t chip)
{
int rc = 1;

- if (chip == REG(I2C_OA)) {
- return(rc);
- }
+ if (chip == REG(&(i2c_base->i2c_oa)))
+ return rc;

- REG(I2C_CON) = 0;
- if (wait_for_bus()) {return(1);}
+ REG(&(i2c_base->i2c_con)) = 0;
+ if (wait_for_bus())
+ return 1;

/* try to read one byte from current (or only) address */
- REG(I2C_CNT) = 1;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
- udelay (50000);
+ 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_STAT) & I2C_STAT_NACK)) {
+ if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
rc = 0;
flush_rx();
- REG(I2C_STAT) = 0xffff;
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
} else {
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CON) |= I2C_CON_STP;
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
udelay(20000);
- if (wait_for_bus()) {return(1);}
+ if (wait_for_bus())
+ return 1;
}

flush_rx();
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CNT) = 0;
- return(rc);
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_cnt)) = 0;
+ return rc;
}


@@ -149,73 +168,76 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
int i;

if ((alen < 0) || (alen > 2)) {
- printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
- return(1);
+ printf("%s(): bogus address length %x\n", __func__, alen);
+ return 1;
}

- if (wait_for_bus()) {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_CNT) = alen;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = tmp;
+ 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_DXR) = (addr >> 8) & 0xff;
- } else {
- REG(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_DXR) = addr & 0xff;
- } else {
- REG(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_CON) = 0;
- return(1);
- }
+ 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_CNT) = len & 0xffff;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = tmp;
+ 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);
+ tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK |
+ I2C_STAT_ROVR);

CHECK_NACK();

if (tmp & I2C_STAT_RRDY) {
- buf[i] = REG(I2C_DRR);
+ buf[i] = REG(&(i2c_base->i2c_drr));
} else {
- REG(I2C_CON) = 0;
- return(1);
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
}
}

@@ -224,16 +246,16 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
CHECK_NACK();

if (!(tmp & I2C_STAT_SCD)) {
- REG(I2C_CON) = 0;
- return(1);
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
}

flush_rx();
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CNT) = 0;
- REG(I2C_CON) = 0;
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_cnt)) = 0;
+ REG(&(i2c_base->i2c_con)) = 0;

- return(0);
+ return 0;
}


@@ -243,48 +265,51 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
int i;

if ((alen < 0) || (alen > 2)) {
- printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
- return(1);
+ printf("%s(): bogus address length %x\n", __func__, alen);
+ return 1;
}
if (len < 0) {
- printf("%s(): bogus length %x\n", __FUNCTION__, len);
- return(1);
+ printf("%s(): bogus length %x\n", __func__, len);
+ return 1;
}

- if (wait_for_bus()) {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_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
- REG(I2C_SA) = chip;
- REG(I2C_CON) = tmp;
+ 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);
+ case 2:
+ /* Send address MSByte */
+ tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);

- CHECK_NACK();
+ CHECK_NACK();

- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = (addr >> 8) & 0xff;
- } else {
- REG(I2C_CON) = 0;
- return(1);
- }
- /* No break, fall through */
- case 1:
- /* Send address LSByte */
- tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_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();
+ CHECK_NACK();

- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = addr & 0xff;
- } else {
- REG(I2C_CON) = 0;
- return(1);
- }
+ 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++) {
@@ -292,11 +317,10 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)

CHECK_NACK();

- if (tmp & I2C_STAT_XRDY) {
- REG(I2C_DXR) = buf[i];
- } else {
- return(1);
- }
+ 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);
@@ -304,14 +328,52 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
CHECK_NACK();

if (!(tmp & I2C_STAT_SCD)) {
- REG(I2C_CON) = 0;
- return(1);
+ REG(&(i2c_base->i2c_con)) = 0;
+ return 1;
}

flush_rx();
- REG(I2C_STAT) = 0xffff;
- REG(I2C_CNT) = 0;
- REG(I2C_CON) = 0;
+ REG(&(i2c_base->i2c_stat)) = 0xffff;
+ REG(&(i2c_base->i2c_cnt)) = 0;
+ REG(&(i2c_base->i2c_con)) = 0;
+
+ return 0;
+}
+
+#ifdef CONFIG_I2C_MULTI_BUS
+int i2c_set_bus_num(unsigned int bus)
+{
+ if ((bus < 0) || (bus >= I2C_BUS_MAX)) {
+ printf("Bad bus: %d\n", bus);
+ return -1;
+ }

- return(0);
+ 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;
}
+#endif
diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h
index 79ff7a3..20d4342 100644
--- a/drivers/i2c/davinci_i2c.h
+++ b/drivers/i2c/davinci_i2c.h
@@ -12,18 +12,21 @@
#define I2C_WRITE 0
#define I2C_READ 1

-#define I2C_OA (I2C_BASE + 0x00)
-#define I2C_IE (I2C_BASE + 0x04)
-#define I2C_STAT (I2C_BASE + 0x08)
-#define I2C_SCLL (I2C_BASE + 0x0c)
-#define I2C_SCLH (I2C_BASE + 0x10)
-#define I2C_CNT (I2C_BASE + 0x14)
-#define I2C_DRR (I2C_BASE + 0x18)
-#define I2C_SA (I2C_BASE + 0x1c)
-#define I2C_DXR (I2C_BASE + 0x20)
-#define I2C_CON (I2C_BASE + 0x24)
-#define I2C_IV (I2C_BASE + 0x28)
-#define I2C_PSC (I2C_BASE + 0x30)
+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 */

--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:05 UTC
Permalink
This patch add support for gpimage format as a preparatory
patch for porting u-boot for keystone2 devices and is
based on omapimage format. It re-uses gph header to store the
size and loadaddr as done in omapimage.c

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
- No update since v1
common/image.c | 1 +
include/image.h | 1 +
tools/Makefile | 6 +++
tools/gpheader.h | 40 +++++++++++++++++++
tools/gpimage-common.c | 80 +++++++++++++++++++++++++++++++++++++
tools/gpimage.c | 77 +++++++++++++++++++++++++++++++++++
tools/imagetool.c | 2 +
tools/imagetool.h | 1 +
tools/omapimage.c | 104 ++++++++----------------------------------------
tools/omapimage.h | 5 ---
10 files changed, 224 insertions(+), 93 deletions(-)
create mode 100644 tools/gpheader.h
create mode 100644 tools/gpimage-common.c
create mode 100644 tools/gpimage.c

diff --git a/common/image.c b/common/image.c
index ae95c3f..cb5c656 100644
--- a/common/image.c
+++ b/common/image.c
@@ -124,6 +124,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", },
{ IH_TYPE_FIRMWARE, "firmware", "Firmware", },
{ IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", },
+ { IH_TYPE_GPIMAGE, "gpimage", "TI Keystone SPL Image",},
{ IH_TYPE_KERNEL, "kernel", "Kernel Image", },
{ IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", },
{ IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",},
diff --git a/include/image.h b/include/image.h
index 7de2bb2..0a3d346 100644
--- a/include/image.h
+++ b/include/image.h
@@ -214,6 +214,7 @@ struct lmb;
#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */
#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */
#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */
+#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */

/*
* Compression Types
diff --git a/tools/Makefile b/tools/Makefile
index 3c719b3..421aba5 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,6 +77,8 @@ NOPED_OBJ_FILES-y += aisimage.o
NOPED_OBJ_FILES-y += default_image.o
NOPED_OBJ_FILES-y += dumpimage.o
NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += gpimage.o
+NOPED_OBJ_FILES-y += gpimage-common.o
NOPED_OBJ_FILES-y += imagetool.o
NOPED_OBJ_FILES-y += image-host.o
NOPED_OBJ_FILES-y += imximage.o
@@ -211,6 +213,8 @@ $(obj)dumpimage$(SFX): $(obj)aisimage.o \
$(obj)default_image.o \
$(obj)dumpimage.o \
$(obj)fit_image.o \
+ $(obj)gpimage.o \
+ $(obj)gpimage-common.o \
$(obj)image.o \
$(obj)imagetool.o \
$(obj)image-fit.o \
@@ -239,6 +243,8 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \
$(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
+ $(obj)gpimage.o \
+ $(obj)gpimage-common.o \
$(obj)image.o \
$(obj)imagetool.o \
$(obj)image-host.o \
diff --git a/tools/gpheader.h b/tools/gpheader.h
new file mode 100644
index 0000000..63a28a2
--- /dev/null
+++ b/tools/gpheader.h
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c. Include this common
+ * header file
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby at linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _GPIMAGE_H_
+#define _GPIMAGE_H_
+
+/* common headers for gpimage and omapimage formats */
+struct gp_header {
+ uint32_t size;
+ uint32_t load_addr;
+};
+#define GPIMAGE_HDR_SIZE (sizeof(struct gp_header))
+
+/* common functions across gpimage and omapimage handlers */
+int valid_gph_size(uint32_t size);
+int valid_gph_load_addr(uint32_t load_addr);
+int gph_verify_header(struct gp_header *gph, int be);
+void gph_print_header(const struct gp_header *gph, int be);
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+ int be);
+int gpimage_check_params(struct image_tool_params *params);
+#endif
diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c
new file mode 100644
index 0000000..b343a3a
--- /dev/null
+++ b/tools/gpimage-common.c
@@ -0,0 +1,80 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c.
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby at linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+/* Helper to convert size and load_addr to big endian */
+void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr)
+{
+ *gph_size = cpu_to_be32(*gph_size);
+ *gph_load_addr = cpu_to_be32(*gph_load_addr);
+}
+
+int gph_verify_header(struct gp_header *gph, int be)
+{
+ uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+ if (be)
+ to_be32(&gph_size, &gph_load_addr);
+
+ if (!gph_size || !gph_load_addr)
+ return -1;
+
+ return 0;
+}
+
+void gph_print_header(const struct gp_header *gph, int be)
+{
+ uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+ if (be)
+ to_be32(&gph_size, &gph_load_addr);
+
+ if (!gph_size) {
+ fprintf(stderr, "Error: invalid image size %x\n", gph_size);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!gph_load_addr) {
+ fprintf(stderr, "Error: invalid image load address %x\n",
+ gph_load_addr);
+ exit(EXIT_FAILURE);
+ }
+ printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+}
+
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+ int be)
+{
+ gph->size = size;
+ gph->load_addr = load_addr;
+ if (be)
+ to_be32(&gph->size, &gph->load_addr);
+}
+
+int gpimage_check_params(struct image_tool_params *params)
+{
+ return (params->dflag && (params->fflag || params->lflag)) ||
+ (params->fflag && (params->dflag || params->lflag)) ||
+ (params->lflag && (params->dflag || params->fflag));
+}
diff --git a/tools/gpimage.c b/tools/gpimage.c
new file mode 100644
index 0000000..1cabb5b
--- /dev/null
+++ b/tools/gpimage.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Add gpimage format for keystone devices to format spl image. This is
+ * Based on omapimage.c
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby at linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+static uint8_t gpimage_header[GPIMAGE_HDR_SIZE];
+
+/* to be in keystone gpimage */
+static int gpimage_check_image_types(uint8_t type)
+{
+ if (type == IH_TYPE_GPIMAGE)
+ return EXIT_SUCCESS;
+ return EXIT_FAILURE;
+}
+
+static int gpimage_verify_header(unsigned char *ptr, int image_size,
+ struct image_tool_params *params)
+{
+ struct gp_header *gph = (struct gp_header *)ptr;
+
+ return gph_verify_header(gph, 1);
+}
+
+static void gpimage_print_header(const void *ptr)
+{
+ const struct gp_header *gph = (struct gp_header *)ptr;
+
+ gph_print_header(gph, 1);
+}
+
+static void gpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
+ struct image_tool_params *params)
+{
+ struct gp_header *gph = (struct gp_header *)ptr;
+
+ gph_set_header(gph, sbuf->st_size - GPIMAGE_HDR_SIZE, params->addr, 1);
+}
+
+/*
+ * gpimage parameters
+ */
+static struct image_type_params gpimage_params = {
+ .name = "TI KeyStone GP Image support",
+ .header_size = GPIMAGE_HDR_SIZE,
+ .hdr = (void *)&gpimage_header,
+ .check_image_type = gpimage_check_image_types,
+ .verify_header = gpimage_verify_header,
+ .print_header = gpimage_print_header,
+ .set_header = gpimage_set_header,
+ .check_params = gpimage_check_params,
+};
+
+void init_gpimage_type(void)
+{
+ register_image_type(&gpimage_params);
+}
diff --git a/tools/imagetool.c b/tools/imagetool.c
index 29d2189..da72115 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -45,6 +45,8 @@ void register_image_tool(imagetool_register_t image_register)
init_ubl_image_type();
/* Init Davinci AIS support */
init_ais_image_type();
+ /* Init TI Keystone boot image generation/list support */
+ init_gpimage_type();
}

/*
diff --git a/tools/imagetool.h b/tools/imagetool.h
index c2c9aea..a3e9d30 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -167,6 +167,7 @@ void init_mxs_image_type(void);
void init_fit_image_type(void);
void init_ubl_image_type(void);
void init_omap_image_type(void);
+void init_gpimage_type(void);

void pbl_load_uboot(int fd, struct image_tool_params *mparams);

diff --git a/tools/omapimage.c b/tools/omapimage.c
index d59bc4d..1e0c164 100644
--- a/tools/omapimage.c
+++ b/tools/omapimage.c
@@ -15,57 +15,24 @@
*/

#include "imagetool.h"
+#include <compiler.h>
#include <image.h>
+#include "gpheader.h"
#include "omapimage.h"

/* Header size is CH header rounded up to 512 bytes plus GP header */
#define OMAP_CH_HDR_SIZE 512
-#define OMAP_GP_HDR_SIZE (sizeof(struct gp_header))
-#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE)
+#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE + GPIMAGE_HDR_SIZE)

static int do_swap32 = 0;

-static uint32_t omapimage_swap32(uint32_t data)
-{
- uint32_t result = 0;
- result = (data & 0xFF000000) >> 24;
- result |= (data & 0x00FF0000) >> 8;
- result |= (data & 0x0000FF00) << 8;
- result |= (data & 0x000000FF) << 24;
- return result;
-}
-
static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];

static int omapimage_check_image_types(uint8_t type)
{
if (type == IH_TYPE_OMAPIMAGE)
return EXIT_SUCCESS;
- else {
- return EXIT_FAILURE;
- }
-}
-
-/*
- * Only the simplest image type is currently supported:
- * TOC pointing to CHSETTINGS
- * TOC terminator
- * CHSETTINGS
- *
- * padding to OMAP_CH_HDR_SIZE bytes
- *
- * gp header
- * size
- * load_addr
- */
-static int valid_gph_size(uint32_t size)
-{
- return size;
-}
-
-static int valid_gph_load_addr(uint32_t load_addr)
-{
- return load_addr;
+ return EXIT_FAILURE;
}

static int omapimage_verify_header(unsigned char *ptr, int image_size,
@@ -73,13 +40,13 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
{
struct ch_toc *toc = (struct ch_toc *)ptr;
struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
- uint32_t offset, size, gph_size, gph_load_addr;
+ uint32_t offset, size;

while (toc->section_offset != 0xffffffff
&& toc->section_size != 0xffffffff) {
if (do_swap32) {
- offset = omapimage_swap32(toc->section_offset);
- size = omapimage_swap32(toc->section_size);
+ offset = cpu_to_be32(toc->section_offset);
+ size = cpu_to_be32(toc->section_size);
} else {
offset = toc->section_offset;
size = toc->section_size;
@@ -92,20 +59,7 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
toc++;
}

- if (do_swap32) {
- gph_size = omapimage_swap32(gph->size);
- gph_load_addr = omapimage_swap32(gph->load_addr);
- } else {
- gph_size = gph->size;
- gph_load_addr = gph->load_addr;
- }
-
- if (!valid_gph_size(gph_size))
- return -1;
- if (!valid_gph_load_addr(gph_load_addr))
- return -1;
-
- return 0;
+ return gph_verify_header(gph, do_swap32);
}

static void omapimage_print_section(struct ch_settings *chs)
@@ -135,13 +89,13 @@ static void omapimage_print_header(const void *ptr)
const struct ch_toc *toc = (struct ch_toc *)ptr;
const struct gp_header *gph =
(struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
- uint32_t offset, size, gph_size, gph_load_addr;
+ uint32_t offset, size;

while (toc->section_offset != 0xffffffff
&& toc->section_size != 0xffffffff) {
if (do_swap32) {
- offset = omapimage_swap32(toc->section_offset);
- size = omapimage_swap32(toc->section_size);
+ offset = cpu_to_be32(toc->section_offset);
+ size = cpu_to_be32(toc->section_size);
} else {
offset = toc->section_offset;
size = toc->section_size;
@@ -160,26 +114,7 @@ static void omapimage_print_header(const void *ptr)
toc++;
}

- if (do_swap32) {
- gph_size = omapimage_swap32(gph->size);
- gph_load_addr = omapimage_swap32(gph->load_addr);
- } else {
- gph_size = gph->size;
- gph_load_addr = gph->load_addr;
- }
-
- if (!valid_gph_size(gph_size)) {
- fprintf(stderr, "Error: invalid image size %x\n", gph_size);
- exit(EXIT_FAILURE);
- }
-
- if (!valid_gph_load_addr(gph_load_addr)) {
- fprintf(stderr, "Error: invalid image load address %x\n",
- gph_load_addr);
- exit(EXIT_FAILURE);
- }
-
- printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+ gph_print_header(gph, do_swap32);
}

static int toc_offset(void *hdr, void *member)
@@ -208,8 +143,8 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
toc++;
memset(toc, 0xff, sizeof(*toc));

- gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE;
- gph->load_addr = params->addr;
+ gph_set_header(gph, sbuf->st_size - OMAP_FILE_HDR_SIZE,
+ params->addr, 0);

if (strncmp(params->imagename, "byteswap", 8) == 0) {
do_swap32 = 1;
@@ -217,20 +152,13 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
uint32_t *data = (uint32_t *)ptr;

while (swapped <= (sbuf->st_size / sizeof(uint32_t))) {
- *data = omapimage_swap32(*data);
+ *data = cpu_to_be32(*data);
swapped++;
data++;
}
}
}

-int omapimage_check_params(struct image_tool_params *params)
-{
- return (params->dflag && (params->fflag || params->lflag)) ||
- (params->fflag && (params->dflag || params->lflag)) ||
- (params->lflag && (params->dflag || params->fflag));
-}
-
/*
* omapimage parameters
*/
@@ -242,7 +170,7 @@ static struct image_type_params omapimage_params = {
.verify_header = omapimage_verify_header,
.print_header = omapimage_print_header,
.set_header = omapimage_set_header,
- .check_params = omapimage_check_params,
+ .check_params = gpimage_check_params,
};

void init_omap_image_type(void)
diff --git a/tools/omapimage.h b/tools/omapimage.h
index 45d14ea..8744ae7 100644
--- a/tools/omapimage.h
+++ b/tools/omapimage.h
@@ -25,10 +25,5 @@ struct ch_settings {
uint32_t flags;
};

-struct gp_header {
- uint32_t size;
- uint32_t load_addr;
-};
-
#define KEY_CHSETTINGS 0xC0C0C0C1
#endif /* _OMAPIMAGE_H_ */
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:11 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

Multicore navigator consists of Network Coprocessor (NetCP) and
Queue Manager sub system. More details on the hardware can
be obtained from the following links:-

Network Coprocessor: http://www.ti.com/lit/pdf/sprugz6
Multicore Navigator: http://www.ti.com/lit/pdf/sprugr9

Multicore navigator driver implements APIs to configure
the Queue Manager and NetCP Pkt DMA.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
Signed-off-by: WingMan Kwok <w-kwok2 at ti.com>
---
- Updated based on review comments
arch/arm/cpu/armv7/keystone/Makefile | 1 +
arch/arm/cpu/armv7/keystone/keystone_nav.c | 376 +++++++++++++++++++++
arch/arm/include/asm/arch-keystone/keystone_nav.h | 193 +++++++++++
3 files changed, 570 insertions(+)
create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c
create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h

diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile
index 7924cfa..7d0374b 100644
--- a/arch/arm/cpu/armv7/keystone/Makefile
+++ b/arch/arm/cpu/armv7/keystone/Makefile
@@ -11,6 +11,7 @@ obj-y += psc.o
obj-y += clock.o
obj-y += cmd_clock.o
obj-y += cmd_mon.o
+obj-y += keystone_nav.o
obj-y += msmc.o
obj-$(CONFIG_SPL_BUILD) += spl.o
obj-y += ddr3.o
diff --git a/arch/arm/cpu/armv7/keystone/keystone_nav.c b/arch/arm/cpu/armv7/keystone/keystone_nav.c
new file mode 100644
index 0000000..39d6f99
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/keystone_nav.c
@@ -0,0 +1,376 @@
+/*
+ * Multicore Navigator driver for TI Keystone 2 devices.
+ *
+ * (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/keystone_nav.h>
+
+static int soc_type =
+#ifdef CONFIG_SOC_K2HK
+ k2hk;
+#endif
+
+struct qm_config k2hk_qm_memmap = {
+ .stat_cfg = 0x02a40000,
+ .queue = (struct qm_reg_queue *)0x02a80000,
+ .mngr_vbusm = 0x23a80000,
+ .i_lram = 0x00100000,
+ .proxy = (struct qm_reg_queue *)0x02ac0000,
+ .status_ram = 0x02a06000,
+ .mngr_cfg = (struct qm_cfg_reg *)0x02a02000,
+ .intd_cfg = 0x02a0c000,
+ .desc_mem = (struct descr_mem_setup_reg *)0x02a03000,
+ .region_num = 64,
+ .pdsp_cmd = 0x02a20000,
+ .pdsp_ctl = 0x02a0f000,
+ .pdsp_iram = 0x02a10000,
+ .qpool_num = 4000,
+};
+
+/*
+ * We are going to use only one type of descriptors - host packet
+ * descriptors. We staticaly allocate memory for them here
+ */
+struct qm_host_desc desc_pool[HDESC_NUM] __aligned(sizeof(struct qm_host_desc));
+
+static struct qm_config *qm_cfg;
+
+inline int num_of_desc_to_reg(int num_descr)
+{
+ int j, num;
+
+ for (j = 0, num = 32; j < 15; j++, num *= 2) {
+ if (num_descr <= num)
+ return j;
+ }
+
+ return 15;
+}
+
+static int _qm_init(struct qm_config *cfg)
+{
+ u32 j;
+
+ if (cfg == NULL)
+ return QM_ERR;
+
+ qm_cfg = cfg;
+
+ qm_cfg->mngr_cfg->link_ram_base0 = qm_cfg->i_lram;
+ qm_cfg->mngr_cfg->link_ram_size0 = HDESC_NUM * 8;
+ qm_cfg->mngr_cfg->link_ram_base1 = 0;
+ qm_cfg->mngr_cfg->link_ram_size1 = 0;
+ qm_cfg->mngr_cfg->link_ram_base2 = 0;
+
+ qm_cfg->desc_mem[0].base_addr = (u32)desc_pool;
+ qm_cfg->desc_mem[0].start_idx = 0;
+ qm_cfg->desc_mem[0].desc_reg_size =
+ (((sizeof(struct qm_host_desc) >> 4) - 1) << 16) |
+ num_of_desc_to_reg(HDESC_NUM);
+
+ memset(desc_pool, 0, sizeof(desc_pool));
+ for (j = 0; j < HDESC_NUM; j++)
+ qm_push(&desc_pool[j], qm_cfg->qpool_num);
+
+ return QM_OK;
+}
+
+int qm_init(void)
+{
+ switch (soc_type) {
+ case k2hk:
+ return _qm_init(&k2hk_qm_memmap);
+ }
+
+ return QM_ERR;
+}
+
+void qm_close(void)
+{
+ u32 j;
+
+ if (qm_cfg == NULL)
+ return;
+
+ queue_close(qm_cfg->qpool_num);
+
+ qm_cfg->mngr_cfg->link_ram_base0 = 0;
+ qm_cfg->mngr_cfg->link_ram_size0 = 0;
+ qm_cfg->mngr_cfg->link_ram_base1 = 0;
+ qm_cfg->mngr_cfg->link_ram_size1 = 0;
+ qm_cfg->mngr_cfg->link_ram_base2 = 0;
+
+ for (j = 0; j < qm_cfg->region_num; j++) {
+ qm_cfg->desc_mem[j].base_addr = 0;
+ qm_cfg->desc_mem[j].start_idx = 0;
+ qm_cfg->desc_mem[j].desc_reg_size = 0;
+ }
+
+ qm_cfg = NULL;
+}
+
+void qm_push(struct qm_host_desc *hd, u32 qnum)
+{
+ u32 regd;
+
+ if (!qm_cfg)
+ return;
+
+ cpu_to_bus((u32 *)hd, sizeof(struct qm_host_desc)/4);
+ regd = (u32)hd | ((sizeof(struct qm_host_desc) >> 4) - 1);
+ writel(regd, &qm_cfg->queue[qnum].ptr_size_thresh);
+}
+
+void qm_buff_push(struct qm_host_desc *hd, u32 qnum,
+ void *buff_ptr, u32 buff_len)
+{
+ hd->orig_buff_len = buff_len;
+ hd->buff_len = buff_len;
+ hd->orig_buff_ptr = (u32)buff_ptr;
+ hd->buff_ptr = (u32)buff_ptr;
+ qm_push(hd, qnum);
+}
+
+struct qm_host_desc *qm_pop(u32 qnum)
+{
+ u32 uhd;
+
+ if (!qm_cfg)
+ return NULL;
+
+ uhd = readl(&qm_cfg->queue[qnum].ptr_size_thresh) & ~0xf;
+ if (uhd)
+ cpu_to_bus((u32 *)uhd, sizeof(struct qm_host_desc)/4);
+
+ return (struct qm_host_desc *)uhd;
+}
+
+struct qm_host_desc *qm_pop_from_free_pool(void)
+{
+ if (!qm_cfg)
+ return NULL;
+
+ return qm_pop(qm_cfg->qpool_num);
+}
+
+void queue_close(u32 qnum)
+{
+ struct qm_host_desc *hd;
+
+ while ((hd = qm_pop(qnum)))
+ ;
+}
+
+/*
+ * DMA API
+ */
+
+struct pktdma_cfg k2hk_netcp_pktdma = {
+ .global = (struct global_ctl_regs *)0x02004000,
+ .tx_ch = (struct tx_chan_regs *)0x02004400,
+ .tx_ch_num = 9,
+ .rx_ch = (struct rx_chan_regs *)0x02004800,
+ .rx_ch_num = 26,
+ .tx_sched = (u32 *)0x02004c00,
+ .rx_flows = (struct rx_flow_regs *)0x02005000,
+ .rx_flow_num = 32,
+ .rx_free_q = 4001,
+ .rx_rcv_q = 4002,
+ .tx_snd_q = 648,
+};
+
+struct pktdma_cfg *netcp;
+
+static int netcp_rx_disable(void)
+{
+ u32 j, v, k;
+
+ for (j = 0; j < netcp->rx_ch_num; j++) {
+ v = readl(&netcp->rx_ch[j].cfg_a);
+ if (!(v & CPDMA_CHAN_A_ENABLE))
+ continue;
+
+ writel(v | CPDMA_CHAN_A_TDOWN, &netcp->rx_ch[j].cfg_a);
+ for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) {
+ udelay(100);
+ v = readl(&netcp->rx_ch[j].cfg_a);
+ if (!(v & CPDMA_CHAN_A_ENABLE))
+ continue;
+ }
+ /* TODO: teardown error on if TDOWN_TIMEOUT_COUNT is reached */
+ }
+
+ /* Clear all of the flow registers */
+ for (j = 0; j < netcp->rx_flow_num; j++) {
+ writel(0, &netcp->rx_flows[j].control);
+ writel(0, &netcp->rx_flows[j].tags);
+ writel(0, &netcp->rx_flows[j].tag_sel);
+ writel(0, &netcp->rx_flows[j].fdq_sel[0]);
+ writel(0, &netcp->rx_flows[j].fdq_sel[1]);
+ writel(0, &netcp->rx_flows[j].thresh[0]);
+ writel(0, &netcp->rx_flows[j].thresh[1]);
+ writel(0, &netcp->rx_flows[j].thresh[2]);
+ }
+
+ return QM_OK;
+}
+
+static int netcp_tx_disable(void)
+{
+ u32 j, v, k;
+
+ for (j = 0; j < netcp->tx_ch_num; j++) {
+ v = readl(&netcp->tx_ch[j].cfg_a);
+ if (!(v & CPDMA_CHAN_A_ENABLE))
+ continue;
+
+ writel(v | CPDMA_CHAN_A_TDOWN, &netcp->tx_ch[j].cfg_a);
+ for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) {
+ udelay(100);
+ v = readl(&netcp->tx_ch[j].cfg_a);
+ if (!(v & CPDMA_CHAN_A_ENABLE))
+ continue;
+ }
+ /* TODO: teardown error on if TDOWN_TIMEOUT_COUNT is reached */
+ }
+
+ return QM_OK;
+}
+
+static int _netcp_init(struct pktdma_cfg *netcp_cfg,
+ struct rx_buff_desc *rx_buffers)
+{
+ u32 j, v;
+ struct qm_host_desc *hd;
+ u8 *rx_ptr;
+
+ if (netcp_cfg == NULL || rx_buffers == NULL ||
+ rx_buffers->buff_ptr == NULL || qm_cfg == NULL)
+ return QM_ERR;
+
+ netcp = netcp_cfg;
+ netcp->rx_flow = rx_buffers->rx_flow;
+
+ /* init rx queue */
+ rx_ptr = rx_buffers->buff_ptr;
+
+ for (j = 0; j < rx_buffers->num_buffs; j++) {
+ hd = qm_pop(qm_cfg->qpool_num);
+ if (hd == NULL)
+ return QM_ERR;
+
+ qm_buff_push(hd, netcp->rx_free_q,
+ rx_ptr, rx_buffers->buff_len);
+
+ rx_ptr += rx_buffers->buff_len;
+ }
+
+ netcp_rx_disable();
+
+ /* configure rx channels */
+ v = CPDMA_REG_VAL_MAKE_RX_FLOW_A(1, 1, 0, 0, 0, 0, 0, netcp->rx_rcv_q);
+ writel(v, &netcp->rx_flows[netcp->rx_flow].control);
+ writel(0, &netcp->rx_flows[netcp->rx_flow].tags);
+ writel(0, &netcp->rx_flows[netcp->rx_flow].tag_sel);
+
+ v = CPDMA_REG_VAL_MAKE_RX_FLOW_D(0, netcp->rx_free_q, 0,
+ netcp->rx_free_q);
+
+ writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[0]);
+ writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[1]);
+ writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[0]);
+ writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[1]);
+ writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[2]);
+
+ for (j = 0; j < netcp->rx_ch_num; j++)
+ writel(CPDMA_CHAN_A_ENABLE, &netcp->rx_ch[j].cfg_a);
+
+ /* configure tx channels */
+ /* Disable loopback in the tx direction */
+ writel(0, &netcp->global->emulation_control);
+
+/* TODO: make it dependend on a soc type variable */
+#ifdef CONFIG_SOC_K2HK
+ /* Set QM base address, only for K2x devices */
+ writel(0x23a80000, &netcp->global->qm_base_addr[0]);
+#endif
+
+ /* Enable all channels. The current state isn't important */
+ for (j = 0; j < netcp->tx_ch_num; j++) {
+ writel(0, &netcp->tx_ch[j].cfg_b);
+ writel(CPDMA_CHAN_A_ENABLE, &netcp->tx_ch[j].cfg_a);
+ }
+
+ return QM_OK;
+}
+
+int netcp_init(struct rx_buff_desc *rx_buffers)
+{
+ switch (soc_type) {
+ case k2hk:
+ _netcp_init(&k2hk_netcp_pktdma, rx_buffers);
+ return QM_OK;
+ }
+ return QM_ERR;
+}
+
+int netcp_close(void)
+{
+ if (!netcp)
+ return QM_ERR;
+
+ netcp_tx_disable();
+ netcp_rx_disable();
+
+ queue_close(netcp->rx_free_q);
+ queue_close(netcp->rx_rcv_q);
+ queue_close(netcp->tx_snd_q);
+
+ return QM_OK;
+}
+
+int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2)
+{
+ struct qm_host_desc *hd;
+
+ hd = qm_pop(qm_cfg->qpool_num);
+ if (hd == NULL)
+ return QM_ERR;
+
+ hd->desc_info = num_bytes;
+ hd->swinfo[2] = swinfo2;
+ hd->packet_info = qm_cfg->qpool_num;
+
+ qm_buff_push(hd, netcp->tx_snd_q, pkt, num_bytes);
+
+ return QM_OK;
+}
+
+void *netcp_recv(u32 **pkt, int *num_bytes)
+{
+ struct qm_host_desc *hd;
+
+ hd = qm_pop(netcp->rx_rcv_q);
+ if (!hd)
+ return NULL;
+
+ *pkt = (u32 *)hd->buff_ptr;
+ *num_bytes = hd->desc_info & 0x3fffff;
+
+ return hd;
+}
+
+void netcp_release_rxhd(void *hd)
+{
+ struct qm_host_desc *_hd = (struct qm_host_desc *)hd;
+
+ _hd->buff_len = _hd->orig_buff_len;
+ _hd->buff_ptr = _hd->orig_buff_ptr;
+
+ qm_push(_hd, netcp->rx_free_q);
+}
diff --git a/arch/arm/include/asm/arch-keystone/keystone_nav.h b/arch/arm/include/asm/arch-keystone/keystone_nav.h
new file mode 100644
index 0000000..d422bff
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/keystone_nav.h
@@ -0,0 +1,193 @@
+/*
+ * Multicore Navigator definitions
+ *
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _KEYSTONE_NAV_H_
+#define _KEYSTONE_NAV_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+enum soc_type_t {
+ k2hk
+};
+
+#define QM_OK 0
+#define QM_ERR -1
+#define QM_DESC_TYPE_HOST 0
+#define QM_DESC_PSINFO_IN_DESCR 0
+#define QM_DESC_DEFAULT_DESCINFO (QM_DESC_TYPE_HOST << 30) | \
+ (QM_DESC_PSINFO_IN_DESCR << 22)
+
+/* Packet Info */
+#define QM_DESC_PINFO_EPIB 1
+#define QM_DESC_PINFO_RETURN_OWN 1
+#define QM_DESC_DEFAULT_PINFO (QM_DESC_PINFO_EPIB << 31) | \
+ (QM_DESC_PINFO_RETURN_OWN << 15)
+
+struct qm_cfg_reg {
+ u32 revision;
+ u32 __pad1;
+ u32 divert;
+ u32 link_ram_base0;
+ u32 link_ram_size0;
+ u32 link_ram_base1;
+ u32 link_ram_size1;
+ u32 link_ram_base2;
+ u32 starvation[0];
+};
+
+struct descr_mem_setup_reg {
+ u32 base_addr;
+ u32 start_idx;
+ u32 desc_reg_size;
+ u32 _res0;
+};
+
+struct qm_reg_queue {
+ u32 entry_count;
+ u32 byte_count;
+ u32 packet_size;
+ u32 ptr_size_thresh;
+};
+
+struct qm_config {
+ /* QM module addresses */
+ u32 stat_cfg; /* status and config */
+ struct qm_reg_queue *queue; /* management region */
+ u32 mngr_vbusm; /* management region (VBUSM) */
+ u32 i_lram; /* internal linking RAM */
+ struct qm_reg_queue *proxy;
+ u32 status_ram;
+ struct qm_cfg_reg *mngr_cfg;
+ /* Queue manager config region */
+ u32 intd_cfg; /* QMSS INTD config region */
+ struct descr_mem_setup_reg *desc_mem;
+ /* descritor memory setup region*/
+ u32 region_num;
+ u32 pdsp_cmd; /* PDSP1 command interface */
+ u32 pdsp_ctl; /* PDSP1 control registers */
+ u32 pdsp_iram;
+ /* QM configuration parameters */
+
+ u32 qpool_num; /* */
+};
+
+struct qm_host_desc {
+ u32 desc_info;
+ u32 tag_info;
+ u32 packet_info;
+ u32 buff_len;
+ u32 buff_ptr;
+ u32 next_bdptr;
+ u32 orig_buff_len;
+ u32 orig_buff_ptr;
+ u32 timestamp;
+ u32 swinfo[3];
+ u32 ps_data[20];
+};
+
+#define HDESC_NUM 256
+
+int qm_init(void);
+void qm_close(void);
+void qm_push(struct qm_host_desc *hd, u32 qnum);
+struct qm_host_desc *qm_pop(u32 qnum);
+
+void qm_buff_push(struct qm_host_desc *hd, u32 qnum,
+ void *buff_ptr, u32 buff_len);
+
+struct qm_host_desc *qm_pop_from_free_pool(void);
+void queue_close(u32 qnum);
+
+/*
+ * DMA API
+ */
+#define CPDMA_REG_VAL_MAKE_RX_FLOW_A(einfo, psinfo, rxerr, desc, \
+ psloc, sopoff, qmgr, qnum) \
+ (((einfo & 1) << 30) | \
+ ((psinfo & 1) << 29) | \
+ ((rxerr & 1) << 28) | \
+ ((desc & 3) << 26) | \
+ ((psloc & 1) << 25) | \
+ ((sopoff & 0x1ff) << 16) | \
+ ((qmgr & 3) << 12) | \
+ ((qnum & 0xfff) << 0))
+
+#define CPDMA_REG_VAL_MAKE_RX_FLOW_D(fd0qm, fd0qnum, fd1qm, fd1qnum) \
+ (((fd0qm & 3) << 28) | \
+ ((fd0qnum & 0xfff) << 16) | \
+ ((fd1qm & 3) << 12) | \
+ ((fd1qnum & 0xfff) << 0))
+
+#define CPDMA_CHAN_A_ENABLE ((u32)1 << 31)
+#define CPDMA_CHAN_A_TDOWN (1 << 30)
+#define TDOWN_TIMEOUT_COUNT 100
+
+struct global_ctl_regs {
+ u32 revision;
+ u32 perf_control;
+ u32 emulation_control;
+ u32 priority_control;
+ u32 qm_base_addr[4];
+};
+
+struct tx_chan_regs {
+ u32 cfg_a;
+ u32 cfg_b;
+ u32 res[6];
+};
+
+struct rx_chan_regs {
+ u32 cfg_a;
+ u32 res[7];
+};
+
+struct rx_flow_regs {
+ u32 control;
+ u32 tags;
+ u32 tag_sel;
+ u32 fdq_sel[2];
+ u32 thresh[3];
+};
+
+struct pktdma_cfg {
+ struct global_ctl_regs *global;
+ struct tx_chan_regs *tx_ch;
+ u32 tx_ch_num;
+ struct rx_chan_regs *rx_ch;
+ u32 rx_ch_num;
+ u32 *tx_sched;
+ struct rx_flow_regs *rx_flows;
+ u32 rx_flow_num;
+
+ u32 rx_free_q;
+ u32 rx_rcv_q;
+ u32 tx_snd_q;
+
+ u32 rx_flow; /* flow that is used for RX */
+};
+
+/*
+ * packet dma user allocates memory for rx buffers
+ * and describe it in the following structure
+ */
+struct rx_buff_desc {
+ u8 *buff_ptr;
+ u32 num_buffs;
+ u32 buff_len;
+ u32 rx_flow;
+};
+
+int netcp_close(void);
+int netcp_init(struct rx_buff_desc *rx_buffers);
+int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2);
+void *netcp_recv(u32 **pkt, int *num_bytes);
+void netcp_release_rxhd(void *hd);
+
+#endif /* _KEYSTONE_NAV_H_ */
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:10 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

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 at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
Signed-off-by: WingMan Kwok <w-kwok2 at ti.com>
Signed-off-by: Sandeep Nair <sandeep_n at ti.com>
---
- Updated based on review comments
Makefile | 19 ++
arch/arm/cpu/armv7/keystone/Makefile | 17 ++
arch/arm/cpu/armv7/keystone/aemif.c | 71 +++++
arch/arm/cpu/armv7/keystone/clock.c | 313 ++++++++++++++++++++
arch/arm/cpu/armv7/keystone/cmd_clock.c | 124 ++++++++
arch/arm/cpu/armv7/keystone/cmd_mon.c | 131 ++++++++
arch/arm/cpu/armv7/keystone/config.mk | 15 +
arch/arm/cpu/armv7/keystone/ddr3.c | 69 +++++
arch/arm/cpu/armv7/keystone/init.c | 56 ++++
arch/arm/cpu/armv7/keystone/msmc.c | 68 +++++
arch/arm/cpu/armv7/keystone/psc.c | 238 +++++++++++++++
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 | 121 ++++++++
arch/arm/include/asm/arch-keystone/emif_defs.h | 73 +++++
arch/arm/include/asm/arch-keystone/hardware-k2hk.h | 145 +++++++++
arch/arm/include/asm/arch-keystone/hardware.h | 175 +++++++++++
arch/arm/include/asm/arch-keystone/i2c_defs.h | 17 ++
arch/arm/include/asm/arch-keystone/nand_defs.h | 25 ++
arch/arm/include/asm/arch-keystone/psc_defs.h | 90 ++++++
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 | 236 +++++++++++++++
board/ti/k2hk_evm/ddr3.c | 269 +++++++++++++++++
boards.cfg | 1 +
drivers/serial/ns16550.c | 8 +
include/configs/k2hk_evm.h | 221 ++++++++++++++
29 files changed, 2750 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.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/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 include/configs/k2hk_evm.h

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..7924cfa
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/Makefile
@@ -0,0 +1,17 @@
+#
+# (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-$(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..9b26886
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/aemif.c
@@ -0,0 +1,71 @@
+/*
+ * 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>
+#include <asm/arch/emif_defs.h>
+
+#define AEMIF_CFG_SELECT_STROBE(v) ((v) ? 1 << 31 : 0)
+#define AEMIF_CFG_EXTEND_WAIT(v) ((v) ? 1 << 30 : 0)
+#define AEMIF_CFG_WR_SETUP(v) (((v) & 0x0f) << 26)
+#define AEMIF_CFG_WR_STROBE(v) (((v) & 0x3f) << 20)
+#define AEMIF_CFG_WR_HOLD(v) (((v) & 0x07) << 17)
+#define AEMIF_CFG_RD_SETUP(v) (((v) & 0x0f) << 13)
+#define AEMIF_CFG_RD_STROBE(v) (((v) & 0x3f) << 7)
+#define AEMIF_CFG_RD_HOLD(v) (((v) & 0x07) << 4)
+#define AEMIF_CFG_TURN_AROUND(v) (((v) & 0x03) << 2)
+#define AEMIF_CFG_WIDTH(v) (((v) & 0x03) << 0)
+
+#define set_config_field(reg, field, val) \
+ do { \
+ if (val != -1) { \
+ reg &= ~AEMIF_CFG_##field(0xffffffff); \
+ reg |= AEMIF_CFG_##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(&davinci_emif_regs->nandfcr);
+ tmp |= (1 << cs);
+ __raw_writel(tmp, &davinci_emif_regs->nandfcr);
+
+ } else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) {
+ tmp = __raw_readl(&davinci_emif_regs->one_nand_cr);
+ tmp |= (1 << cs);
+ __raw_writel(tmp, &davinci_emif_regs->one_nand_cr);
+ }
+
+ tmp = __raw_readl(&davinci_emif_regs->abncr[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, &davinci_emif_regs->abncr[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.c b/arch/arm/cpu/armv7/keystone/clock.c
new file mode 100644
index 0000000..87d7c7f
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock.c
@@ -0,0 +1,313 @@
+/*
+ * 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 wait_for_completion(const struct pll_init_data *data)
+{
+ int i;
+ for (i = 0; i < 100; i++) {
+ sdelay(450);
+ if ((pllctl_reg_read(data->pll, stat) & PLLSTAT_GO) == 0)
+ break;
+ }
+}
+
+struct pll_regs {
+ u32 reg0, reg1;
+};
+
+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 & PLL_DIV_MASK) + 1;
+ mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) |
+ (pllctl_reg_read(pll, mult) &
+ PLLM_MULT_LO_MASK)) + 1;
+ output_div = ((pllctl_reg_read(pll, secctl) >>
+ PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 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 & PLLCTL_BYPASS)) {
+ /* Bypass disabled */
+ prediv = (tmp & PLL_DIV_MASK) + 1;
+ mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1;
+ output_div = ((tmp >> PLL_CLKOD_SHIFT) &
+ PLL_CLKOD_MASK) + 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;
+}
+
+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) & PLL_DIV_MASK;
+ pllod = (data->pll_od - 1) & PLL_CLKOD_MASK;
+
+ if (data->pll == MAIN_PLL) {
+ sdelay(210000);
+
+ 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);
+ sdelay(340);
+
+ pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS);
+ pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+ sdelay(21000);
+
+ pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+ } else {
+ pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
+ PLLCTL_PLLENSRC);
+ sdelay(340);
+ }
+
+ pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK);
+
+ reg_rmw(pll_regs[data->pll].reg0, PLLM_MULT_HI_SMASK,
+ (pllm << 6));
+
+ /* Set the BWADJ (12 bit field) */
+ tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */
+ reg_rmw(pll_regs[data->pll].reg0, PLL_BWADJ_LO_SMASK,
+ (tmp_ctl << PLL_BWADJ_LO_SHIFT));
+ reg_rmw(pll_regs[data->pll].reg1, PLL_BWADJ_HI_MASK,
+ (tmp_ctl >> 8));
+
+ /*
+ * Set the pll divider (6 bit field) *
+ * PLLD[5:0] is located in MAINPLLCTL0
+ */
+ reg_rmw(pll_regs[data->pll].reg0, PLL_DIV_MASK, plld);
+
+ /* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */
+ pllctl_reg_rmw(data->pll, secctl, PLL_CLKOD_SMASK,
+ (pllod << PLL_CLKOD_SHIFT));
+ wait_for_completion(data);
+
+ pllctl_reg_write(data->pll, div1, PLLM_RATIO_DIV1);
+ pllctl_reg_write(data->pll, div2, PLLM_RATIO_DIV2);
+ pllctl_reg_write(data->pll, div3, PLLM_RATIO_DIV3);
+ pllctl_reg_write(data->pll, div4, PLLM_RATIO_DIV4);
+ pllctl_reg_write(data->pll, div5, PLLM_RATIO_DIV5);
+
+ 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, PLLSTAT_GO);
+ sdelay(1500); /* wait for the phase adj */
+ wait_for_completion(data);
+
+ /* Reset PLL */
+ pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
+ sdelay(21000); /* Wait for a minimum of 7 us*/
+ pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
+ sdelay(105000); /* 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, PLLCTL_BYPASS);
+ /*
+ * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass)
+ * only applicable for Kepler
+ */
+ reg_clrbits(K2HK_MISC_CTRL, ARM_PLL_EN);
+ /* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */
+ reg_setbits(pll_regs[data->pll].reg1 ,
+ PLL_PLLRST | PLLCTL_ENSAT);
+
+ /*
+ * 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 & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) |
+ (pllm << 6) |
+ (plld & PLL_DIV_MASK) |
+ (pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS;
+ __raw_writel(tmp, pll_regs[data->pll].reg0);
+
+ /* Set BWADJ[11:8] bits */
+ tmp = __raw_readl(pll_regs[data->pll].reg1);
+ tmp &= ~(PLL_BWADJ_HI_MASK);
+ tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK);
+ __raw_writel(tmp, pll_regs[data->pll].reg1);
+ /*
+ * 5 Wait for at least 5 us based on the reference
+ * clock (PLL reset time)
+ */
+ sdelay(21000); /* Wait for a minimum of 7 us*/
+
+ /* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */
+ reg_clrbits(pll_regs[data->pll].reg1, PLL_PLLRST);
+ /*
+ * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1)
+ * (PLL lock time)
+ */
+ sdelay(105000);
+ /* 8 disable bypass */
+ reg_clrbits(pll_regs[data->pll].reg0, PLLCTL_BYPASS);
+ /*
+ * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass)
+ * only applicable for Kepler
+ */
+ reg_setbits(K2HK_MISC_CTRL, ARM_PLL_EN);
+ } else {
+ reg_setbits(pll_regs[data->pll].reg1, PLLCTL_ENSAT);
+ /*
+ * process keeps state of Bypass bit while programming
+ * all other DDR PLL settings
+ */
+ tmp = __raw_readl(pll_regs[data->pll].reg0);
+ tmp &= PLLCTL_BYPASS; /* clear everything except Bypass */
+
+ /*
+ * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0,
+ * bypass disabled
+ */
+ bwadj = pllm >> 1;
+ tmp |= ((bwadj & PLL_BWADJ_LO_SHIFT) << PLL_BWADJ_LO_SHIFT) |
+ (pllm << PLL_MULT_SHIFT) |
+ (plld & PLL_DIV_MASK) |
+ (pllod << PLL_CLKOD_SHIFT);
+ __raw_writel(tmp, pll_regs[data->pll].reg0);
+
+ /* Set BWADJ[11:8] bits */
+ tmp = __raw_readl(pll_regs[data->pll].reg1);
+ tmp &= ~(PLL_BWADJ_HI_MASK);
+ tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK);
+
+ /* set PLL Select (bit 13) for PASS PLL */
+ if (data->pll == PASS_PLL)
+ tmp |= PLLCTL_PAPLL;
+
+ __raw_writel(tmp, pll_regs[data->pll].reg1);
+
+ /* Reset bit: bit 14 for both DDR3 & PASS PLL */
+ tmp = PLL_PLLRST;
+ /* Set RESET bit = 1 */
+ reg_setbits(pll_regs[data->pll].reg1, tmp);
+ /* Wait for a minimum of 7 us*/
+ sdelay(21000);
+ /* Clear RESET bit */
+ reg_clrbits(pll_regs[data->pll].reg1, tmp);
+ sdelay(105000);
+
+ /* clear BYPASS (Enable PLL Mode) */
+ reg_clrbits(pll_regs[data->pll].reg0, PLLCTL_BYPASS);
+ sdelay(21000); /* Wait for a minimum of 7 us*/
+ }
+
+ sdelay(210000);
+}
+
+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..afd30f3
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
@@ -0,0 +1,124 @@
+/*
+ * 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>
+
+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 = simple_strtoul(argv[2], NULL, 10);
+ cmd_pll_data.pll_d = simple_strtoul(argv[3], NULL, 10);
+ cmd_pll_data.pll_od = simple_strtoul(argv[4], 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"
+);
+
+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 = simple_strtoul(argv[1], NULL, 10);
+
+ 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 = simple_strtoul(argv[1], NULL, 10);
+ 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..1c8769c
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/config.mk
@@ -0,0 +1,15 @@
+# (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
+#
+# =========================================================================
+PF_CPPFLAGS_SLB +=$(call cc-option,-mshort-load-bytes,\
+ $(call cc-option,-malignment-traps,))
+PLATFORM_RELFLAGS += $(PF_CPPFLAGS_SLB)
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..1b7e52a
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/init.c
@@ -0,0 +1,56 @@
+/*
+ * 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 (;;)
+ ;
+}
+
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+#endif
+}
diff --git a/arch/arm/cpu/armv7/keystone/msmc.c b/arch/arm/cpu/armv7/keystone/msmc.c
new file mode 100644
index 0000000..f3f1621
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/msmc.c
@@ -0,0 +1,68 @@
+/*
+ * 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..fecf918
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/psc.c
@@ -0,0 +1,238 @@
+/*
+ * Keystone: PSC configuration module
+ *
+ * (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/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..61b6b62
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock_defs.h
@@ -0,0 +1,121 @@
+/*
+ * 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 PLL_PLLRST BIT(14)
+#define PLLCTL_PAPLL BIT(13)
+#define PLLCTL_CLKMODE BIT(8)
+#define PLLCTL_PLLSELB BIT(7)
+#define PLLCTL_ENSAT BIT(6)
+#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 PLLSTAT_GO BIT(0)
+
+#define MAIN_ENSAT_OFFSET 6
+
+#define PLLDIV_ENABLE BIT(15)
+
+#define PLL_DIV_MASK 0x3f
+#define PLL_MULT_MASK 0x1fff
+#define PLL_MULT_SHIFT 6
+#define PLLM_MULT_HI_MASK 0x7f
+#define PLLM_MULT_HI_SHIFT 12
+#define PLLM_MULT_HI_SMASK (PLLM_MULT_HI_MASK << PLLM_MULT_HI_SHIFT)
+#define PLLM_MULT_LO_MASK 0x3f
+#define PLL_CLKOD_MASK 0xf
+#define PLL_CLKOD_SHIFT 19
+#define PLL_CLKOD_SMASK (PLL_CLKOD_MASK << PLL_CLKOD_SHIFT)
+#define PLL_BWADJ_LO_MASK 0xff
+#define PLL_BWADJ_LO_SHIFT 24
+#define PLL_BWADJ_LO_SMASK (PLL_BWADJ_LO_MASK << PLL_BWADJ_LO_SHIFT)
+#define PLL_BWADJ_HI_MASK 0xf
+
+#define PLLM_RATIO_DIV1 (PLLDIV_ENABLE | 0)
+#define PLLM_RATIO_DIV2 (PLLDIV_ENABLE | 0)
+#define PLLM_RATIO_DIV3 (PLLDIV_ENABLE | 1)
+#define PLLM_RATIO_DIV4 (PLLDIV_ENABLE | 4)
+#define PLLM_RATIO_DIV5 (PLLDIV_ENABLE | 17)
+
+#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..4e88ae6
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/emif_defs.h
@@ -0,0 +1,73 @@
+/*
+ * 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 at 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 abncr[4];
+ 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_int32_t rsvd0;
+ u_int32_t one_nand_cr;
+ u_int32_t nandfcr;
+ u_int32_t nandfsr;
+ u_int32_t rsvd1[2];
+ u_int32_t nandfecc[4];
+ u_int32_t rsvd2[15];
+ 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..034b655
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
@@ -0,0 +1,145 @@
+/*
+ * 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_MISC_CTRL (KS2_DEVICE_STATE_CTRL_BASE + 0xc7c)
+
+#define ARM_PLL_EN BIT(13)
+
+#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..a72686d
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware.h
@@ -0,0 +1,175 @@
+/*
+ * 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);
+void sdelay(unsigned long);
+
+#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..d425652
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/i2c_defs.h
@@ -0,0 +1,17 @@
+/*
+ * keystone: i2c driver definitions
+ *
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _I2C_DEFS_H_
+#define _I2C_DEFS_H_
+
+#define I2C0_BASE 0x02530000
+#define I2C1_BASE 0x02530400
+#define I2C2_BASE 0x02530800
+#define I2C_BASE I2C0_BASE
+
+#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 at 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..e0095d9
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/psc_defs.h
@@ -0,0 +1,90 @@
+/*
+ * (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))
+
+/* 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 at 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..14dc7e4
--- /dev/null
+++ b/board/ti/k2hk_evm/board.c
@@ -0,0 +1,236 @@
+/*
+ * 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_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+ return 0;
+}
+
+#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 at monstr.eu>:Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
Active arm armv7 zynq xilinx zynq zynq_zc770_xm012 zynq_zc770:ZC770_XM012 Michal Simek <monstr at monstr.eu>:Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
Active arm armv7 zynq xilinx zynq zynq_zc770_xm013 zynq_zc770:ZC770_XM013 Michal Simek <monstr at monstr.eu>:Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
+Active arm armv7 keystone ti k2hk_evm k2hk_evm - Vitaly Andrianov <vitalya at ti.com>
Active arm armv7:arm720t tegra114 nvidia dalmore dalmore - Tom Warren <twarren at nvidia.com>
Active arm armv7:arm720t tegra20 avionic-design medcom-wide medcom-wide - Alban Bedel <alban.bedel at avionic-design.de>
Active arm armv7:arm720t tegra20 avionic-design plutux plutux - Alban Bedel <alban.bedel at avionic-design.de>
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..985db8e
--- /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_DAVINCI_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 */
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:12 UTC
Permalink
From: Vitaly Andrianov <vitalya at ti.com>

Ethernet driver configures the CPSW, SGMI and Phy and uses
the the Navigator APIs. The driver supports 4 Ethernet ports and
can work with only one port at a time.

Port configurations are defined in board.c.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
Signed-off-by: WingMan Kwok <w-kwok2 at ti.com>
---
- updated based on review comments
arch/arm/include/asm/arch-keystone/emac_defs.h | 250 +++++++
board/ti/k2hk_evm/board.c | 65 ++
drivers/net/Makefile | 1 +
drivers/net/keystone_net.c | 859 ++++++++++++++++++++++++
include/configs/k2hk_evm.h | 38 ++
5 files changed, 1213 insertions(+)
create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h
create mode 100644 drivers/net/keystone_net.c

diff --git a/arch/arm/include/asm/arch-keystone/emac_defs.h b/arch/arm/include/asm/arch-keystone/emac_defs.h
new file mode 100644
index 0000000..9c1c5bc
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/emac_defs.h
@@ -0,0 +1,250 @@
+/*
+ * emac definitions for keystone2 devices
+ *
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _EMAC_DEFS_H_
+#define _EMAC_DEFS_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#define DEVICE_REG32_R(a) readl(a)
+#define DEVICE_REG32_W(a, v) writel(v, a)
+
+/*#define chipLmbd(x,y) _lmbd(x,y) */
+
+#define EMAC_EMACSL_BASE_ADDR (KS2_PASS_BASE + 0x00090900)
+#define EMAC_MDIO_BASE_ADDR (KS2_PASS_BASE + 0x00090300)
+#define EMAC_SGMII_BASE_ADDR (KS2_PASS_BASE + 0x00090100)
+
+#define KEYSTONE2_EMAC_GIG_ENABLE
+
+#define MAC_ID_BASE_ADDR (KS2_DEVICE_STATE_CTRL_BASE + 0x110)
+
+#ifdef CONFIG_SOC_K2HK
+/* MDIO module input frequency */
+#define EMAC_MDIO_BUS_FREQ (clk_get_rate(pass_pll_clk))
+/* MDIO clock output frequency */
+#define EMAC_MDIO_CLOCK_FREQ 1000000 /* 1.0 MHz */
+#endif
+
+/* MII Status Register */
+#define MII_STATUS_REG 1
+#define MII_STATUS_LINK_MASK (0x4)
+
+/* Marvell 88E1111 PHY ID */
+#define PHY_MARVELL_88E1111 (0x01410cc0)
+
+#define MDIO_CONTROL_IDLE (0x80000000)
+#define MDIO_CONTROL_ENABLE (0x40000000)
+#define MDIO_CONTROL_FAULT_ENABLE (0x40000)
+#define MDIO_CONTROL_FAULT (0x80000)
+#define MDIO_USERACCESS0_GO (0x80000000)
+#define MDIO_USERACCESS0_WRITE_READ (0x0)
+#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000)
+#define MDIO_USERACCESS0_ACK (0x20000000)
+
+#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20)
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1)
+#define EMAC_MACCONTROL_GIGABIT_ENABLE (1 << 7)
+#define EMAC_MACCONTROL_GIGFORCE (1 << 17)
+#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15)
+
+#define EMAC_MIN_ETHERNET_PKT_SIZE 60
+
+struct mac_sl_cfg {
+ u_int32_t max_rx_len; /* Maximum receive packet length. */
+ u_int32_t ctl; /* Control bitfield */
+};
+
+/*
+ * Definition: Control bitfields used in the ctl field of hwGmacSlCfg_t
+ */
+#define GMACSL_RX_ENABLE_RCV_CONTROL_FRAMES (1 << 24)
+#define GMACSL_RX_ENABLE_RCV_SHORT_FRAMES (1 << 23)
+#define GMACSL_RX_ENABLE_RCV_ERROR_FRAMES (1 << 22)
+#define GMACSL_RX_ENABLE_EXT_CTL (1 << 18)
+#define GMACSL_RX_ENABLE_GIG_FORCE (1 << 17)
+#define GMACSL_RX_ENABLE_IFCTL_B (1 << 16)
+#define GMACSL_RX_ENABLE_IFCTL_A (1 << 15)
+#define GMACSL_RX_ENABLE_CMD_IDLE (1 << 11)
+#define GMACSL_TX_ENABLE_SHORT_GAP (1 << 10)
+#define GMACSL_ENABLE_GIG_MODE (1 << 7)
+#define GMACSL_TX_ENABLE_PACE (1 << 6)
+#define GMACSL_ENABLE (1 << 5)
+#define GMACSL_TX_ENABLE_FLOW_CTL (1 << 4)
+#define GMACSL_RX_ENABLE_FLOW_CTL (1 << 3)
+#define GMACSL_ENABLE_LOOPBACK (1 << 1)
+#define GMACSL_ENABLE_FULL_DUPLEX (1 << 0)
+
+/*
+ * DEFINTITION: function return values
+ */
+#define GMACSL_RET_OK 0
+#define GMACSL_RET_INVALID_PORT -1
+#define GMACSL_RET_WARN_RESET_INCOMPLETE -2
+#define GMACSL_RET_WARN_MAXLEN_TOO_BIG -3
+#define GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE -4
+
+/* Register offsets */
+#define CPGMACSL_REG_ID 0x00
+#define CPGMACSL_REG_CTL 0x04
+#define CPGMACSL_REG_STATUS 0x08
+#define CPGMACSL_REG_RESET 0x0c
+#define CPGMACSL_REG_MAXLEN 0x10
+#define CPGMACSL_REG_BOFF 0x14
+#define CPGMACSL_REG_RX_PAUSE 0x18
+#define CPGMACSL_REG_TX_PAURSE 0x1c
+#define CPGMACSL_REG_EM_CTL 0x20
+#define CPGMACSL_REG_PRI 0x24
+
+/* Soft reset register values */
+#define CPGMAC_REG_RESET_VAL_RESET_MASK (1 << 0)
+#define CPGMAC_REG_RESET_VAL_RESET (1 << 0)
+
+/* Maxlen register values */
+#define CPGMAC_REG_MAXLEN_LEN 0x3fff
+
+/* Control bitfields */
+#define CPSW_CTL_P2_PASS_PRI_TAGGED (1 << 5)
+#define CPSW_CTL_P1_PASS_PRI_TAGGED (1 << 4)
+#define CPSW_CTL_P0_PASS_PRI_TAGGED (1 << 3)
+#define CPSW_CTL_P0_ENABLE (1 << 2)
+#define CPSW_CTL_VLAN_AWARE (1 << 1)
+#define CPSW_CTL_FIFO_LOOPBACK (1 << 0)
+
+#define DEVICE_CPSW_NUM_PORTS 5 /* 5 switch ports */
+#define DEVICE_CPSW_BASE (0x02090800)
+#define target_get_switch_ctl() CPSW_CTL_P0_ENABLE /* Enable port 0 */
+#define SWITCH_MAX_PKT_SIZE 9000
+
+/* Register offsets */
+#define CPSW_REG_CTL 0x004
+#define CPSW_REG_STAT_PORT_EN 0x00c
+#define CPSW_REG_MAXLEN 0x040
+#define CPSW_REG_ALE_CONTROL 0x608
+#define CPSW_REG_ALE_PORTCTL(x) (0x640 + (x)*4)
+
+/* Register values */
+#define CPSW_REG_VAL_STAT_ENABLE_ALL 0xf
+#define CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE ((u_int32_t)0xc0000000)
+#define CPSW_REG_VAL_ALE_CTL_BYPASS ((u_int32_t)0x00000010)
+#define CPSW_REG_VAL_PORTCTL_FORWARD_MODE 0x3
+
+#define SGMII_REG_STATUS_LOCK BIT(4)
+#define SGMII_REG_STATUS_LINK BIT(0)
+#define SGMII_REG_STATUS_AUTONEG BIT(2)
+#define SGMII_REG_CONTROL_AUTONEG BIT(0)
+#define SGMII_REG_CONTROL_MASTER BIT(5)
+#define SGMII_REG_MR_ADV_ENABLE BIT(0)
+#define SGMII_REG_MR_ADV_LINK BIT(15)
+#define SGMII_REG_MR_ADV_FULL_DUPLEX BIT(12)
+#define SGMII_REG_MR_ADV_GIG_MODE BIT(11)
+
+#define SGMII_LINK_MAC_MAC_AUTONEG 0
+#define SGMII_LINK_MAC_PHY 1
+#define SGMII_LINK_MAC_MAC_FORCED 2
+#define SGMII_LINK_MAC_FIBER 3
+#define SGMII_LINK_MAC_PHY_FORCED 4
+
+#define TARGET_SGMII_BASE KS2_PASS_BASE + 0x00090100
+#define TARGET_SGMII_BASE_ADDRESSES {KS2_PASS_BASE+0x00090100, \
+ KS2_PASS_BASE+0x00090200, \
+ KS2_PASS_BASE+0x00090400, \
+ KS2_PASS_BASE+0x00090500 }
+
+#define SGMII_OFFSET(x) ((x <= 1) ? (x * 0x100) : ((x * 0x100) + 0x100))
+
+/*
+ * SGMII registers
+ */
+#define SGMII_IDVER_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x000)
+#define SGMII_SRESET_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x004)
+#define SGMII_CTL_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x010)
+#define SGMII_STATUS_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x014)
+#define SGMII_MRADV_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x018)
+#define SGMII_LPADV_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x020)
+#define SGMII_TXCFG_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x030)
+#define SGMII_RXCFG_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x034)
+#define SGMII_AUXCFG_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x038)
+
+#define DEVICE_EMACSL_BASE(x) (KS2_PASS_BASE + 0x00090900 + (x)*0x040)
+#define DEVICE_N_GMACSL_PORTS 4
+#define DEVICE_EMACSL_RESET_POLL_COUNT 100
+
+#define DEVICE_PSTREAM_CFG_REG_ADDR (KS2_PASS_BASE + 0x604)
+
+#ifdef CONFIG_SOC_K2HK
+#define DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI 0x06060606
+#endif
+
+#define hw_config_streaming_switch() \
+ DEVICE_REG32_W(DEVICE_PSTREAM_CFG_REG_ADDR, \
+ DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI);
+
+/* EMAC MDIO Registers Structure */
+struct mdio_regs {
+ dv_reg VERSION;
+ dv_reg CONTROL;
+ dv_reg ALIVE;
+ dv_reg LINK;
+ dv_reg LINKINTRAW;
+ dv_reg LINKINTMASKED;
+ u_int8_t RSVD0[8];
+ dv_reg USERINTRAW;
+ dv_reg USERINTMASKED;
+ dv_reg USERINTMASKSET;
+ dv_reg USERINTMASKCLEAR;
+ u_int8_t RSVD1[80];
+ dv_reg USERACCESS0;
+ dv_reg USERPHYSEL0;
+ dv_reg USERACCESS1;
+ dv_reg USERPHYSEL1;
+};
+
+/* Ethernet MAC Registers Structure */
+struct emac_regs {
+ dv_reg IDVER;
+ dv_reg MACCONTROL;
+ dv_reg MACSTATUS;
+ dv_reg SOFT_RESET;
+ dv_reg RX_MAXLEN;
+ u32 RSVD0;
+ dv_reg RX_PAUSE;
+ dv_reg TX_PAUSE;
+ dv_reg EMCONTROL;
+ dv_reg PRI_MAP;
+ u32 RSVD1[6];
+};
+
+struct phy_t {
+ char name[64];
+ int (*init)(int phy_addr);
+ int (*is_phy_connected)(int phy_addr);
+ int (*get_link_speed)(int phy_addr);
+ int (*auto_negotiate)(int phy_addr);
+};
+
+#define SGMII_ACCESS(port, reg) \
+ *((volatile unsigned int *)(sgmiis[port] + reg))
+
+struct eth_priv_t {
+ char int_name[32];
+ int rx_flow;
+ int phy_addr;
+ int slave_port;
+ int sgmii_link_type;
+};
+
+extern struct eth_priv_t eth_priv_cfg[];
+
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv);
+void sgmii_serdes_setup_156p25mhz(void);
+void sgmii_serdes_shutdown(void);
+
+#endif /* _EMAC_DEFS_H_ */
diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c
index 14dc7e4..81f5ca4 100644
--- a/board/ti/k2hk_evm/board.c
+++ b/board/ti/k2hk_evm/board.c
@@ -17,6 +17,7 @@
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/arch/nand_defs.h>
+#include <asm/arch/emac_defs.h>
#include <asm/arch/psc_defs.h>

DECLARE_GLOBAL_DATA_PTR;
@@ -70,6 +71,70 @@ int dram_init(void)
return 0;
}

+#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
+struct eth_priv_t eth_priv_cfg[] = {
+ {
+ .int_name = "K2HK_EMAC",
+ .rx_flow = 22,
+ .phy_addr = 0,
+ .slave_port = 1,
+ .sgmii_link_type = SGMII_LINK_MAC_PHY,
+ },
+ {
+ .int_name = "K2HK_EMAC1",
+ .rx_flow = 23,
+ .phy_addr = 1,
+ .slave_port = 2,
+ .sgmii_link_type = SGMII_LINK_MAC_PHY,
+ },
+ {
+ .int_name = "K2HK_EMAC2",
+ .rx_flow = 24,
+ .phy_addr = 2,
+ .slave_port = 3,
+ .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+ },
+ {
+ .int_name = "K2HK_EMAC3",
+ .rx_flow = 25,
+ .phy_addr = 3,
+ .slave_port = 4,
+ .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+ },
+};
+
+int get_eth_env_param(char *env_name)
+{
+ char *env;
+ int res = -1;
+
+ env = getenv(env_name);
+ if (env)
+ res = simple_strtol(env, NULL, 0);
+
+ return res;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int j;
+ int res;
+ char link_type_name[32];
+
+ for (j = 0; j < (sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t));
+ j++) {
+ sprintf(link_type_name, "sgmii%d_link_type", j);
+ res = get_eth_env_param(link_type_name);
+ if (res >= 0)
+ eth_priv_cfg[j].sgmii_link_type = res;
+
+ keystone2_emac_initialize(&eth_priv_cfg[j]);
+ }
+
+ return 0;
+}
+#endif
+
/* Byte swap the 32-bit data if the device is BE */
int cpu_to_bus(u32 *ptr, u32 length)
{
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7f9ce90..6005f7e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_FTMAC110) += ftmac110.o
obj-$(CONFIG_FTMAC100) += ftmac100.o
obj-$(CONFIG_GRETH) += greth.o
obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o
obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
obj-$(CONFIG_LAN91C96) += lan91c96.o
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
new file mode 100644
index 0000000..473a4b1
--- /dev/null
+++ b/drivers/net/keystone_net.c
@@ -0,0 +1,859 @@
+/*
+ * Ethernet driver for TI K2HK EVM.
+ *
+ * (C) Copyright 2012-2014
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <asm/arch/emac_defs.h>
+#include <asm/arch/psc_defs.h>
+#include <asm/arch/keystone_nav.h>
+
+unsigned int emac_dbg;
+#define debug_emac(fmt, args...) if (emac_dbg) printf(fmt, ##args)
+
+unsigned int emac_open;
+static unsigned int sys_has_mdio = 1;
+
+#ifdef KEYSTONE2_EMAC_GIG_ENABLE
+#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x)
+#else
+#define emac_gigabit_enable(x) /* no gigabit to enable */
+#endif
+
+#define RX_BUFF_NUMS 24
+#define RX_BUFF_LEN 1520
+#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN
+
+static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
+
+struct rx_buff_desc net_rx_buffs = {
+ .buff_ptr = rx_buffs,
+ .num_buffs = RX_BUFF_NUMS,
+ .buff_len = RX_BUFF_LEN,
+ .rx_flow = 22,
+};
+
+static void keystone2_eth_mdio_enable(void);
+
+static int gen_init_phy(int phy_addr);
+static int gen_is_phy_connected(int phy_addr);
+static int gen_get_link_speed(int phy_addr);
+static int gen_auto_negotiate(int phy_addr);
+
+static int marvell_88e1111_init_phy(int phy_addr);
+static int marvell_88e1111_is_phy_connected(int phy_addr);
+static int marvell_88e1111_get_link_speed(int phy_addr);
+static int marvell_88e1111_auto_negotiate(int phy_addr);
+
+/* EMAC Addresses */
+static volatile struct emac_regs *adap_emac =
+ (struct emac_regs *)EMAC_EMACSL_BASE_ADDR;
+static volatile struct mdio_regs *adap_mdio =
+ (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+struct phy_t phy;
+
+static void chip_delay(u32 del)
+{
+ volatile unsigned int i;
+
+ for (i = 0; i < (del / 8); i++)
+ ;
+}
+
+int keystone2_eth_read_mac_addr(struct eth_device *dev)
+{
+ struct eth_priv_t *eth_priv;
+ u32 maca = 0;
+ u32 macb = 0;
+
+ eth_priv = (struct eth_priv_t *)dev->priv;
+
+ /* Read the e-fuse mac address */
+ if (eth_priv->slave_port == 1) {
+ maca = __raw_readl(MAC_ID_BASE_ADDR);
+ macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
+ }
+
+ dev->enetaddr[0] = (macb >> 8) & 0xff;
+ dev->enetaddr[1] = (macb >> 0) & 0xff;
+ dev->enetaddr[2] = (maca >> 24) & 0xff;
+ dev->enetaddr[3] = (maca >> 16) & 0xff;
+ dev->enetaddr[4] = (maca >> 8) & 0xff;
+ dev->enetaddr[5] = (maca >> 0) & 0xff;
+
+ return 0;
+}
+
+static void keystone2_eth_mdio_enable(void)
+{
+ u_int32_t clkdiv;
+
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+ writel((clkdiv & 0xffff) |
+ MDIO_CONTROL_ENABLE |
+ MDIO_CONTROL_FAULT |
+ MDIO_CONTROL_FAULT_ENABLE,
+ &adap_mdio->CONTROL);
+
+ while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
+ ;
+}
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+ int tmp;
+
+ while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+ ;
+
+ writel(MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_READ |
+ ((reg_num & 0x1f) << 21) |
+ ((phy_addr & 0x1f) << 16),
+ &adap_mdio->USERACCESS0);
+
+ /* Wait for command to complete */
+ while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
+ ;
+
+ if (tmp & MDIO_USERACCESS0_ACK) {
+ *data = tmp & 0xffff;
+ return 0;
+ }
+
+ *data = -1;
+ return -1;
+}
+
+/*
+ * Write to a PHY register via MDIO inteface.
+ * Blocks until operation is complete.
+ */
+int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+ while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+ ;
+
+ writel(MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_WRITE |
+ ((reg_num & 0x1f) << 21) |
+ ((phy_addr & 0x1f) << 16) |
+ (data & 0xffff),
+ &adap_mdio->USERACCESS0);
+
+ /* Wait for command to complete */
+ while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+ ;
+
+ return 0;
+}
+
+/* PHY functions for a generic PHY */
+static int __attribute__((unused)) gen_init_phy(int phy_addr)
+{
+ int ret = -1;
+
+ if (!gen_get_link_speed(phy_addr)) {
+ /* Try another time */
+ ret = gen_get_link_speed(phy_addr);
+ }
+
+ return ret;
+}
+
+static int __attribute__((unused)) gen_is_phy_connected(int phy_addr)
+{
+ u_int16_t dummy;
+
+ return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+static int gen_get_link_speed(int phy_addr)
+{
+ u_int16_t tmp;
+
+ if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
+ (tmp & 0x04)) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static int __attribute__((unused)) gen_auto_negotiate(int phy_addr)
+{
+ u_int16_t tmp;
+
+ if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+ return -1;
+
+ /* Restart Auto_negotiation */
+ tmp |= BMCR_ANENABLE;
+ keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);
+
+ /*check AutoNegotiate complete */
+ udelay(10000);
+ if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+ return -1;
+
+ if (!(tmp & BMSR_ANEGCOMPLETE))
+ return 0;
+
+ return gen_get_link_speed(phy_addr);
+}
+
+/* PHY functions for Marvell 88E1111 PHY */
+static int marvell_88e1111_init_phy(int phy_addr)
+{
+ int ret = -1;
+
+ if (!marvell_88e1111_get_link_speed(phy_addr)) {
+ /* Try another time */
+ ret = marvell_88e1111_get_link_speed(phy_addr);
+ }
+
+ return ret;
+}
+
+static int marvell_88e1111_is_phy_connected(int phy_addr)
+{
+ u_int16_t dummy;
+
+ return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+static int marvell_88e1111_get_link_speed(int phy_addr)
+{
+ u_int16_t tmp;
+
+ if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
+ (tmp & MII_STATUS_LINK_MASK)) {
+ return 0;
+ }
+
+ return -1;
+}
+
+static int marvell_88e1111_auto_negotiate(int phy_addr)
+{
+ u_int16_t tmp;
+
+ if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+ return -1;
+
+ /* Restart Auto_negotiation */
+ tmp |= BMCR_ANENABLE;
+ keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);
+
+ /*check AutoNegotiate complete */
+ udelay(10000);
+ if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+ return -1;
+
+ if (!(tmp & BMSR_ANEGCOMPLETE))
+ return 0;
+
+ return marvell_88e1111_get_link_speed(phy_addr);
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int keystone2_mii_phy_read(const char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *value)
+{
+ return keystone2_eth_phy_read(addr, reg, value) ? -1 : 0;
+}
+
+static int keystone2_mii_phy_write(const char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value)
+{
+ return keystone2_eth_phy_write(addr, reg, value) ? -1 : 0;
+}
+#endif
+
+static void __attribute__((unused))
+ keystone2_eth_gigabit_enable(struct eth_device *dev)
+{
+ u_int16_t data;
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+ if (sys_has_mdio) {
+ if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) ||
+ !(data & (1 << 6))) /* speed selection MSB */
+ return;
+ }
+
+ /*
+ * Check if link detected is giga-bit
+ * If Gigabit mode detected, enable gigbit in MAC
+ */
+ writel(readl(&(adap_emac[eth_priv->slave_port - 1].MACCONTROL)) |
+ EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
+ &(adap_emac[eth_priv->slave_port - 1].MACCONTROL))
+ ;
+}
+
+int keystone_sgmii_link_status(int port)
+{
+ u32 status = 0;
+
+ status = __raw_readl(SGMII_STATUS_REG(port));
+
+ return status & SGMII_REG_STATUS_LINK;
+}
+
+
+int keystone_get_link_status(struct eth_device *dev)
+{
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+ int sgmii_link;
+ int link_state = 0;
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+ int j;
+
+ for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
+ j++) {
+#endif
+ sgmii_link =
+ keystone_sgmii_link_status(eth_priv->slave_port - 1);
+
+ if (sgmii_link) {
+ link_state = 1;
+
+ if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
+ if (phy.get_link_speed(eth_priv->phy_addr))
+ link_state = 0;
+ }
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+ }
+#endif
+ return link_state;
+}
+
+int keystone_sgmii_config(int port, int interface)
+{
+ unsigned int i, status, mask;
+ unsigned int mr_adv_ability, control;
+
+ switch (interface) {
+ case SGMII_LINK_MAC_MAC_AUTONEG:
+ mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
+ SGMII_REG_MR_ADV_LINK |
+ SGMII_REG_MR_ADV_FULL_DUPLEX |
+ SGMII_REG_MR_ADV_GIG_MODE);
+ control = (SGMII_REG_CONTROL_MASTER |
+ SGMII_REG_CONTROL_AUTONEG);
+
+ break;
+ case SGMII_LINK_MAC_PHY:
+ case SGMII_LINK_MAC_PHY_FORCED:
+ mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
+ control = SGMII_REG_CONTROL_AUTONEG;
+
+ break;
+ case SGMII_LINK_MAC_MAC_FORCED:
+ mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE |
+ SGMII_REG_MR_ADV_LINK |
+ SGMII_REG_MR_ADV_FULL_DUPLEX |
+ SGMII_REG_MR_ADV_GIG_MODE);
+ control = SGMII_REG_CONTROL_MASTER;
+
+ break;
+ case SGMII_LINK_MAC_FIBER:
+ mr_adv_ability = 0x20;
+ control = SGMII_REG_CONTROL_AUTONEG;
+
+ break;
+ default:
+ mr_adv_ability = SGMII_REG_MR_ADV_ENABLE;
+ control = SGMII_REG_CONTROL_AUTONEG;
+ }
+
+ __raw_writel(0, SGMII_CTL_REG(port));
+
+ /*
+ * Wait for the SerDes pll to lock,
+ * but don't trap if lock is never read
+ */
+ for (i = 0; i < 1000; i++) {
+ udelay(2000);
+ status = __raw_readl(SGMII_STATUS_REG(port));
+ if ((status & SGMII_REG_STATUS_LOCK) != 0)
+ break;
+ }
+
+ __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port));
+ __raw_writel(control, SGMII_CTL_REG(port));
+
+
+ mask = SGMII_REG_STATUS_LINK;
+
+ if (control & SGMII_REG_CONTROL_AUTONEG)
+ mask |= SGMII_REG_STATUS_AUTONEG;
+
+ for (i = 0; i < 1000; i++) {
+ status = __raw_readl(SGMII_STATUS_REG(port));
+ if ((status & mask) == mask)
+ break;
+ }
+
+ return 0;
+}
+
+int mac_sl_reset(u32 port)
+{
+ u32 i, v;
+
+ if (port >= DEVICE_N_GMACSL_PORTS)
+ return GMACSL_RET_INVALID_PORT;
+
+ /* Set the soft reset bit */
+ DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) +
+ CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET);
+
+ /* Wait for the bit to clear */
+ for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+ v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+ CPGMACSL_REG_RESET);
+ if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+ CPGMAC_REG_RESET_VAL_RESET)
+ return GMACSL_RET_OK;
+ }
+
+ /* Timeout on the reset */
+ return GMACSL_RET_WARN_RESET_INCOMPLETE;
+}
+
+int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
+{
+ u32 v, i;
+ int ret = GMACSL_RET_OK;
+
+ if (port >= DEVICE_N_GMACSL_PORTS)
+ return GMACSL_RET_INVALID_PORT;
+
+ if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
+ cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
+ ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
+ }
+
+ /* Must wait if the device is undergoing reset */
+ for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+ v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+ CPGMACSL_REG_RESET);
+ if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+ CPGMAC_REG_RESET_VAL_RESET)
+ break;
+ }
+
+ if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
+ return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE;
+
+ DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN,
+ cfg->max_rx_len);
+
+ DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL,
+ cfg->ctl);
+
+ return ret;
+}
+
+int ethss_config(u32 ctl, u32 max_pkt_size)
+{
+ u32 i;
+
+ /* Max length register */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, max_pkt_size);
+
+ /* Control register */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl);
+
+ /* All statistics enabled by default */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN,
+ CPSW_REG_VAL_STAT_ENABLE_ALL);
+
+ /* Reset and enable the ALE */
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL,
+ CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
+ CPSW_REG_VAL_ALE_CTL_BYPASS);
+
+ /* All ports put into forward mode */
+ for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++)
+ DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i),
+ CPSW_REG_VAL_PORTCTL_FORWARD_MODE);
+
+ return 0;
+}
+
+int ethss_start(void)
+{
+ int i;
+ struct mac_sl_cfg cfg;
+
+ cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER;
+ cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL;
+
+ for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
+ mac_sl_reset(i);
+ mac_sl_config(i, &cfg);
+ }
+
+ return 0;
+}
+
+int ethss_stop(void)
+{
+ int i;
+
+ for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++)
+ mac_sl_reset(i);
+
+ return 0;
+}
+
+int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
+{
+ if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
+ num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
+
+ return netcp_send(buffer, num_bytes, (slave_port_num) << 16);
+}
+
+/* Eth device open */
+static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
+{
+ u_int32_t clkdiv;
+ int link;
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+ debug_emac("+ emac_open\n");
+
+ net_rx_buffs.rx_flow = eth_priv->rx_flow;
+
+ sys_has_mdio =
+ (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
+
+ psc_enable_module(KS2_LPSC_PA);
+ psc_enable_module(KS2_LPSC_CPGMAC);
+
+ sgmii_serdes_setup_156p25mhz();
+
+ if (sys_has_mdio)
+ keystone2_eth_mdio_enable();
+
+ keystone_sgmii_config(eth_priv->slave_port - 1,
+ eth_priv->sgmii_link_type);
+
+ udelay(10000);
+
+ /* On chip switch configuration */
+ ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
+
+ /* TODO: add error handling code */
+ if (qm_init()) {
+ printf("ERROR: qm_init()\n");
+ return -1;
+ }
+ if (netcp_init(&net_rx_buffs)) {
+ qm_close();
+ printf("ERROR: netcp_init()\n");
+ return -1;
+ }
+
+ /*
+ * Streaming switch configuration. If not present this
+ * statement is defined to void in target.h.
+ * If present this is usually defined to a series of register writes
+ */
+ hw_config_streaming_switch();
+
+ if (sys_has_mdio) {
+ /* Init MDIO & get link state */
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+ writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE |
+ MDIO_CONTROL_FAULT, &adap_mdio->CONTROL)
+ ;
+
+ /* We need to wait for MDIO to start */
+ udelay(1000);
+
+ link = keystone_get_link_status(dev);
+ if (link == 0) {
+ netcp_close();
+ qm_close();
+ return -1;
+ }
+ }
+
+ emac_gigabit_enable(dev);
+
+ ethss_start();
+
+ debug_emac("- emac_open\n");
+
+ emac_open = 1;
+
+ return 0;
+}
+
+/* Eth device close */
+void keystone2_eth_close(struct eth_device *dev)
+{
+ debug_emac("+ emac_close\n");
+
+ if (!emac_open)
+ return;
+
+ ethss_stop();
+
+ netcp_close();
+ qm_close();
+
+ emac_open = 0;
+
+ debug_emac("- emac_close\n");
+}
+
+static int tx_send_loop;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int keystone2_eth_send_packet(struct eth_device *dev,
+ void *packet, int length)
+{
+ int ret_status = -1;
+ struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+ tx_send_loop = 0;
+
+ if (keystone_get_link_status(dev) == 0)
+ return -1;
+
+ emac_gigabit_enable(dev);
+
+ if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
+ return ret_status;
+
+ if (keystone_get_link_status(dev) == 0)
+ return -1;
+
+ emac_gigabit_enable(dev);
+
+ return length;
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int keystone2_eth_rcv_packet(struct eth_device *dev)
+{
+ void *hd;
+ int pkt_size;
+ u32 *pkt;
+
+ hd = netcp_recv(&pkt, &pkt_size);
+ if (hd == NULL)
+ return 0;
+
+ NetReceive((uchar *)pkt, pkt_size);
+
+ netcp_release_rxhd(hd);
+
+ return pkt_size;
+}
+
+/*
+ * This function initializes the EMAC hardware. It does NOT initialize
+ * EMAC modules power or pin multiplexors, that is done by board_init()
+ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
+ */
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
+{
+ struct eth_device *dev;
+ static int phy_registered;
+
+ dev = malloc(sizeof(struct eth_device));
+ if (dev == NULL)
+ return -1;
+
+ memset(dev, 0, sizeof(struct eth_device));
+
+ strcpy(dev->name, eth_priv->int_name);
+ dev->priv = eth_priv;
+
+ keystone2_eth_read_mac_addr(dev);
+
+ dev->iobase = 0;
+ dev->init = keystone2_eth_open;
+ dev->halt = keystone2_eth_close;
+ dev->send = keystone2_eth_send_packet;
+ dev->recv = keystone2_eth_rcv_packet;
+
+ eth_register(dev);
+
+ if (sys_has_mdio && !phy_registered) {
+ phy_registered = 1;
+#ifdef CONFIG_ETH_PHY_MARVEL_88E1111
+ sprintf(phy.name, "88E1111");
+ phy.init = marvell_88e1111_init_phy;
+ phy.is_phy_connected = marvell_88e1111_is_phy_connected;
+ phy.get_link_speed = marvell_88e1111_get_link_speed;
+ phy.auto_negotiate = marvell_88e1111_auto_negotiate;
+#else
+ sprintf(phy.name, "GENERIC");
+ phy.init = gen_init_phy;
+ phy.is_phy_connected = gen_is_phy_connected;
+ phy.get_link_speed = gen_get_link_speed;
+ phy.auto_negotiate = gen_auto_negotiate;
+#endif
+ miiphy_register(phy.name, keystone2_mii_phy_read,
+ keystone2_mii_phy_write);
+ }
+
+ return 0;
+}
+
+#define reg_rmw(addr, value, mask) \
+ writel(((readl(addr) & (~(mask))) | (value)), (addr))
+
+void sgmii_serdes_setup_156p25mhz()
+{
+ unsigned int cnt;
+
+ reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
+ reg_rmw(0x0232a014, 0x00008282, 0x0000ffff);
+ reg_rmw(0x0232a060, 0x00142438, 0x00ffffff);
+ reg_rmw(0x0232a064, 0x00c3c700, 0x00ffff00);
+ reg_rmw(0x0232a078, 0x0000c000, 0x0000ff00);
+
+ reg_rmw(0x0232a204, 0x38000080, 0xff0000ff);
+ reg_rmw(0x0232a208, 0x00000000, 0x000000ff);
+ reg_rmw(0x0232a20c, 0x02000000, 0xff000000);
+ reg_rmw(0x0232a210, 0x1b000000, 0xff000000);
+ reg_rmw(0x0232a214, 0x00006fb8, 0x0000ffff);
+ reg_rmw(0x0232a218, 0x758000e4, 0xffff00ff);
+ reg_rmw(0x0232a2ac, 0x00004400, 0x0000ff00);
+ reg_rmw(0x0232a22c, 0x00200800, 0x00ffff00);
+ reg_rmw(0x0232a280, 0x00820082, 0x00ff00ff);
+ reg_rmw(0x0232a284, 0x1d0f0385, 0xffffffff);
+
+ reg_rmw(0x0232a404, 0x38000080, 0xff0000ff);
+ reg_rmw(0x0232a408, 0x00000000, 0x000000ff);
+ reg_rmw(0x0232a40c, 0x02000000, 0xff000000);
+ reg_rmw(0x0232a410, 0x1b000000, 0xff000000);
+ reg_rmw(0x0232a414, 0x00006fb8, 0x0000ffff);
+ reg_rmw(0x0232a418, 0x758000e4, 0xffff00ff);
+ reg_rmw(0x0232a4ac, 0x00004400, 0x0000ff00);
+ reg_rmw(0x0232a42c, 0x00200800, 0x00ffff00);
+ reg_rmw(0x0232a480, 0x00820082, 0x00ff00ff);
+ reg_rmw(0x0232a484, 0x1d0f0385, 0xffffffff);
+
+ reg_rmw(0x0232a604, 0x38000080, 0xff0000ff);
+ reg_rmw(0x0232a608, 0x00000000, 0x000000ff);
+ reg_rmw(0x0232a60c, 0x02000000, 0xff000000);
+ reg_rmw(0x0232a610, 0x1b000000, 0xff000000);
+ reg_rmw(0x0232a614, 0x00006fb8, 0x0000ffff);
+ reg_rmw(0x0232a618, 0x758000e4, 0xffff00ff);
+ reg_rmw(0x0232a6ac, 0x00004400, 0x0000ff00);
+ reg_rmw(0x0232a62c, 0x00200800, 0x00ffff00);
+ reg_rmw(0x0232a680, 0x00820082, 0x00ff00ff);
+ reg_rmw(0x0232a684, 0x1d0f0385, 0xffffffff);
+
+ reg_rmw(0x0232a804, 0x38000080, 0xff0000ff);
+ reg_rmw(0x0232a808, 0x00000000, 0x000000ff);
+ reg_rmw(0x0232a80c, 0x02000000, 0xff000000);
+ reg_rmw(0x0232a810, 0x1b000000, 0xff000000);
+ reg_rmw(0x0232a814, 0x00006fb8, 0x0000ffff);
+ reg_rmw(0x0232a818, 0x758000e4, 0xffff00ff);
+ reg_rmw(0x0232a8ac, 0x00004400, 0x0000ff00);
+ reg_rmw(0x0232a82c, 0x00200800, 0x00ffff00);
+ reg_rmw(0x0232a880, 0x00820082, 0x00ff00ff);
+ reg_rmw(0x0232a884, 0x1d0f0385, 0xffffffff);
+
+ reg_rmw(0x0232aa00, 0x00000800, 0x0000ff00);
+ reg_rmw(0x0232aa08, 0x38a20000, 0xffff0000);
+ reg_rmw(0x0232aa30, 0x008a8a00, 0x00ffff00);
+ reg_rmw(0x0232aa84, 0x00000600, 0x0000ff00);
+ reg_rmw(0x0232aa94, 0x10000000, 0xff000000);
+ reg_rmw(0x0232aaa0, 0x81000000, 0xff000000);
+ reg_rmw(0x0232aabc, 0xff000000, 0xff000000);
+ reg_rmw(0x0232aac0, 0x0000008b, 0x000000ff);
+ reg_rmw(0x0232ab08, 0x583f0000, 0xffff0000);
+ reg_rmw(0x0232ab0c, 0x0000004e, 0x000000ff);
+ reg_rmw(0x0232a000, 0x00000003, 0x000000ff);
+ reg_rmw(0x0232aa00, 0x0000005f, 0x000000ff);
+
+ reg_rmw(0x0232aa48, 0x00fd8c00, 0x00ffff00);
+ reg_rmw(0x0232aa54, 0x002fec72, 0x00ffffff);
+ reg_rmw(0x0232aa58, 0x00f92100, 0xffffff00);
+ reg_rmw(0x0232aa5c, 0x00040060, 0xffffffff);
+ reg_rmw(0x0232aa60, 0x00008000, 0xffffffff);
+ reg_rmw(0x0232aa64, 0x0c581220, 0xffffffff);
+ reg_rmw(0x0232aa68, 0xe13b0602, 0xffffffff);
+ reg_rmw(0x0232aa6c, 0xb8074cc1, 0xffffffff);
+ reg_rmw(0x0232aa70, 0x3f02e989, 0xffffffff);
+ reg_rmw(0x0232aa74, 0x00000001, 0x000000ff);
+ reg_rmw(0x0232ab20, 0x00370000, 0x00ff0000);
+ reg_rmw(0x0232ab1c, 0x37000000, 0xff000000);
+ reg_rmw(0x0232ab20, 0x0000005d, 0x000000ff);
+
+ /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/
+ reg_rmw(0x0232a010, 0x00000000, 1 << 28);
+
+ /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */
+ reg_rmw(0x0232a228, 0x00000000, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfe0);
+ reg_rmw(0x0232a428, 0x00000000, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfe4);
+ reg_rmw(0x0232a628, 0x00000000, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfe8);
+ reg_rmw(0x0232a828, 0x00000000, 1 << 29);
+ writel(0xF800F8C0, 0x0232bfec);
+
+ /*Enable pll via the pll_ctrl 0x0014*/
+ writel(0xe0000000, 0x0232bff4)
+ ;
+
+ /*Waiting for SGMII Serdes PLL lock.*/
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--)
+ ;
+
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--)
+ ;
+
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--)
+ ;
+
+ for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--)
+ ;
+
+ chip_delay(45000);
+}
+
+void sgmii_serdes_shutdown()
+{
+ reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
+ reg_rmw(0x02320228, 1 << 29, 1 << 29);
+ reg_rmw(0x0232bfe4, 0, 3 << 29 | 3 << 13);
+ reg_rmw(0x02320428, 1 << 29, 1 << 29);
+ reg_rmw(0x0232bfe8, 0, 3 << 29 | 3 << 13);
+ reg_rmw(0x02320628, 1 << 29, 1 << 29);
+ reg_rmw(0x0232bfec, 0, 3 << 29 | 3 << 13);
+ reg_rmw(0x02320828, 1 << 29, 1 << 29);
+
+ reg_rmw(0x02320034, 0, 3 << 29);
+ reg_rmw(0x02320010, 1 << 28, 1 << 28);
+}
+
diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
index 985db8e..33c7551 100644
--- a/include/configs/k2hk_evm.h
+++ b/include/configs/k2hk_evm.h
@@ -106,6 +106,23 @@
#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20
#define CONFIG_ENV_EEPROM_IS_ON_I2C

+/* Network Configuration */
+#define CONFIG_ETH_PHY_MARVEL_88E1111
+
+#define CONFIG_DRIVER_TI_KEYSTONE_NET
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT 32
+#define CONFIG_NET_MULTI
+#define CONFIG_GET_LINK_STATUS_ATTEMPTS 5
+
+#define CONFIG_SYS_SGMII_REFCLK_MHZ 312
+#define CONFIG_SYS_SGMII_LINERATE_MHZ 1250
+#define CONFIG_SYS_SGMII_RATESCALE 2
+
/* NAND Configuration */
#define CONFIG_NAND_DAVINCI
#define CONFIG_SYS_NAND_CS 2
@@ -179,24 +196,45 @@
"addr_fs=0x82000000\0" \
"addr_ubi=0x82000000\0" \
"fdt_high=0xffffffff\0" \
+ "name_fdt=uImage-k2hk-evm.dtb\0" \
+ "name_fs=arago-console-image.cpio.gz\0" \
+ "name_kern=uImage-keystone-evm.bin\0" \
+ "name_mon=skern-keystone-evm.bin\0" \
+ "name_uboot=u-boot-spi-keystone-evm.gph\0" \
+ "name_ubi=keystone-evm-ubifs.ubi\0" \
"run_mon=mon_install ${addr_mon}\0" \
"run_kern=bootm ${addr_kern} - ${addr_fdt}\0" \
+ "init_net=run args_all args_net\0" \
"init_ubi=run args_all args_ubi; " \
"ubi part ubifs; ubifsmount boot\0" \
+ "get_fdt_net=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0" \
"get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0" \
+ "get_kern_net=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0" \
"get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0" \
+ "get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \
"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0" \
+ "get_uboot_net=dhcp ${addr_uboot} ${tftp_root}/${name_uboot}\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" \
+ "args_net=setenv bootargs ${bootargs} rootfstype=nfs " \
+ "root=/dev/nfs rw nfsroot=${serverip}:${nfs_root}," \
+ "${nfs_options} ip=dhcp\0" \
+ "nfs_options=v3,tcp,rsize=4096,wsize=4096\0" \
+ "get_fdt_ramfs=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0" \
+ "get_kern_ramfs=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0" \
+ "get_mon_ramfs=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \
+ "get_fs_ramfs=dhcp ${addr_fs} ${tftp_root}/${name_fs}\0" \
+ "get_ubi_net=dhcp ${addr_ubi} ${tftp_root}/${name_ubi}\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" \
+ "no_post=1\0" \
"mtdparts=mtdparts=davinci_nand.0:" \
"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
#define CONFIG_BOOTCOMMAND \
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:08 UTC
Permalink
This patch moves the davinci i2c_defs.h file to drivers.i2c directory.
It will allow to reuse the davinci_i2c driver for TI Keystone2 SOCs.

Not used "git mv" command to move the file because small part of
it with definitions specific for Davinci SOCs has to remain in the
arch/arm/include/asm/arch-davinci.

Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
---
- updated based on review comments
arch/arm/include/asm/arch-davinci/i2c_defs.h | 71 ++----------------------
drivers/i2c/davinci_i2c.c | 1 +
drivers/i2c/davinci_i2c.h | 75 ++++++++++++++++++++++++++
3 files changed, 79 insertions(+), 68 deletions(-)
create mode 100644 drivers/i2c/davinci_i2c.h

diff --git a/arch/arm/include/asm/arch-davinci/i2c_defs.h b/arch/arm/include/asm/arch-davinci/i2c_defs.h
index c388dc0..06da894 100644
--- a/arch/arm/include/asm/arch-davinci/i2c_defs.h
+++ b/arch/arm/include/asm/arch-davinci/i2c_defs.h
@@ -1,16 +1,13 @@
/*
- * (C) Copyright 2004
+ * (C) Copyright 2004-2014
* Texas Instruments, <www.ti.com>
*
* Some changes copyright (C) 2007 Sergey Kubushyn <ksi at koi8.net>
*
* SPDX-License-Identifier: GPL-2.0+
*/
-#ifndef _DAVINCI_I2C_H_
-#define _DAVINCI_I2C_H_
-
-#define I2C_WRITE 0
-#define I2C_READ 1
+#ifndef _I2C_DEFS_H_
+#define _I2C_DEFS_H_

#ifndef CONFIG_SOC_DA8XX
#define I2C_BASE 0x01c21000
@@ -18,66 +15,4 @@
#define I2C_BASE 0x01c22000
#endif

-#define I2C_OA (I2C_BASE + 0x00)
-#define I2C_IE (I2C_BASE + 0x04)
-#define I2C_STAT (I2C_BASE + 0x08)
-#define I2C_SCLL (I2C_BASE + 0x0c)
-#define I2C_SCLH (I2C_BASE + 0x10)
-#define I2C_CNT (I2C_BASE + 0x14)
-#define I2C_DRR (I2C_BASE + 0x18)
-#define I2C_SA (I2C_BASE + 0x1c)
-#define I2C_DXR (I2C_BASE + 0x20)
-#define I2C_CON (I2C_BASE + 0x24)
-#define I2C_IV (I2C_BASE + 0x28)
-#define I2C_PSC (I2C_BASE + 0x30)
-
-/* I2C masks */
-
-/* I2C Interrupt Enable Register (I2C_IE): */
-#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */
-#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
-#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
-#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
-#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
-#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
-
-/* 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 interrupt enable */
-#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
-
-
-/* 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/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index e56fe75..6e5260c 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -12,6 +12,7 @@
#include <i2c.h>
#include <asm/arch/hardware.h>
#include <asm/arch/i2c_defs.h>
+#include "davinci_i2c.h"

#define CHECK_NACK() \
do {\
diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h
new file mode 100644
index 0000000..79ff7a3
--- /dev/null
+++ b/drivers/i2c/davinci_i2c.h
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2004-2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * Some changes copyright (C) 2007 Sergey Kubushyn <ksi at koi8.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _DAVINCI_I2C_H_
+#define _DAVINCI_I2C_H_
+
+#define I2C_WRITE 0
+#define I2C_READ 1
+
+#define I2C_OA (I2C_BASE + 0x00)
+#define I2C_IE (I2C_BASE + 0x04)
+#define I2C_STAT (I2C_BASE + 0x08)
+#define I2C_SCLL (I2C_BASE + 0x0c)
+#define I2C_SCLH (I2C_BASE + 0x10)
+#define I2C_CNT (I2C_BASE + 0x14)
+#define I2C_DRR (I2C_BASE + 0x18)
+#define I2C_SA (I2C_BASE + 0x1c)
+#define I2C_DXR (I2C_BASE + 0x20)
+#define I2C_CON (I2C_BASE + 0x24)
+#define I2C_IV (I2C_BASE + 0x28)
+#define I2C_PSC (I2C_BASE + 0x30)
+
+/* I2C masks */
+
+/* I2C Interrupt Enable Register (I2C_IE): */
+#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */
+#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
+#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
+#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
+#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
+#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
+
+/* 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 interrupt enable */
+#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
+
+/* 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) /* Tx/Rx 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
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:13 UTC
Permalink
From: Rex Chang <rchang at ti.com>

Currently davinci spi driver supports only bus 0 cs 0.
This patch allows driver to support bus 1 and bus 2 with
configurable number of chip selects. Also defaults are
selected in a way to avoid regression on other platforms
that uses davinci spi driver and has only one spi bus.

Signed-off-by: Rex Chang <rchang at ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
drivers/spi/davinci_spi.c | 62 ++++++++++++++++++++++++++++++++++++++++++---
drivers/spi/davinci_spi.h | 33 ++++++++++++++++++++++++
2 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index e3fb321..c708a04 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -23,7 +23,7 @@ void spi_init()
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
- struct davinci_spi_slave *ds;
+ struct davinci_spi_slave *ds;

if (!spi_cs_is_valid(bus, cs))
return NULL;
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!ds)
return NULL;

- ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+ ds->slave.bus = bus;
+ ds->slave.cs = cs;
+
+ switch (bus) {
+ case SPI0_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+ break;
+#ifdef CONFIG_SYS_SPI1
+ case SPI1_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+ break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+ case SPI2_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+ break;
+#endif
+ default: /* Invalid bus number */
+ return NULL;
+ }
+
ds->freq = max_hz;

return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);

/* CS, CLK, SIMO and SOMI are functional pins */
- writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+ writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);

/* setup format */
@@ -262,9 +282,43 @@ out:
return 0;
}

+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+ if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+ return 1;
+ return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+ if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+ return 1;
+ return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+ return 0;
+}
+#endif
+
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
- return bus == 0 && cs == 0;
+ if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+ return 1;
+ else if (bus1_cs_valid(bus, cs))
+ return 1;
+ else if (bus2_cs_valid(bus, cs))
+ return 1;
+ return 0;
}

void spi_cs_activate(struct spi_slave *slave)
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h
index 33f69b5..d4612d3 100644
--- a/drivers/spi/davinci_spi.h
+++ b/drivers/spi/davinci_spi.h
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
/* SPIDEF */
#define SPIDEF_CSDEF0_MASK BIT(0)

+#define SPI0_BUS 0
+#define SPI0_BASE CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses this
+ * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS 1
+#else
+#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI1
+#define SPI1_BUS 1
+#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI2
+#define SPI2_BUS 2
+#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE CONFIG_SYS_SPI2_BASE
+#endif
+
struct davinci_spi_slave {
struct spi_slave slave;
struct davinci_spi_regs *regs;
--
1.7.9.5
Murali Karicheri
2014-02-20 17:55:14 UTC
Permalink
currently only spi0 is enabled on k2hk evm. This
configuration update is needed to enable spi1 and spi2.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
include/configs/k2hk_evm.h | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
index 33c7551..861010a 100644
--- a/include/configs/k2hk_evm.h
+++ b/include/configs/k2hk_evm.h
@@ -85,7 +85,16 @@
#define CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_STMICRO
#define CONFIG_DAVINCI_SPI
+#define CONFIG_SYS_SPI0
#define CONFIG_SYS_SPI_BASE K2HK_SPI_BASE
+#define CONFIG_SYS_SPI0_NUM_CS 4
+#define CONFIG_SYS_SPI1
+#define CONFIG_SYS_SPI1_BASE K2HK_SPI1_BASE
+#define CONFIG_SYS_SPI1_NUM_CS 4
+#define CONFIG_SYS_SPI2
+#define CONFIG_SYS_SPI2_NUM_CS 4
+#define CONFIG_SYS_SPI2_BASE K2HK_SPI2_BASE
+#define CONFIG_CMD_SPI
#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
--
1.7.9.5
Tom Rini
2014-02-25 22:10:46 UTC
Permalink
On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:

> This patch series add support for keystone2 SoC and K2HK EVM

In general, you ran checkpatch.pl right? I see some '#define<tab>'
cases that need manual fixing up as well. Further comments and acks
coming.

--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/97d00e35/attachment.pgp>
Loading...