public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board
@ 2011-10-02 13:52 Shinya Kuribayashi
  2011-10-02 13:54 ` [U-Boot] [PATCH v7 1/3] MIPS: Ingenic XBurst Jz4740 processor support Shinya Kuribayashi
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Shinya Kuribayashi @ 2011-10-02 13:52 UTC (permalink / raw)
  To: u-boot

Hi,

Here's seventh patchset for Ben NanoNote initial support.  I've been
working with Xiangfu past six months to polish v6 patches.  We have
addressed all comments from Wolfgang and Scott so far, drop nand_spl
and USB_boot functions to make the initial bring-up minimum and simple.

I think the patchset is now in good shape, so will merge and make a
pull-request during this merge window.  Please give it a final review
and if something to fix, please let us know.

Scott and Wolfgang, I know NAND land changes should go through Scott's
tree, but the NAND driver is part of the initial support.  May I take
it through MIPS tree?  Hope it's Ok with you.

Changes since v6 patchset are described in each patch.

  Shinya

--- 8< ---
Boilerplate from Xiangfu Liu:

  those patches are for add xburst jz4740 base file and Ben NanoNote
  (codename qi_lb60) to U-Boot
  
some info about xburst jz4740:
  the xburst jz4740 is recently added to linux 2.6.36
  and it's support the device Ben NanoNote out of box,

  this xburst jz4740 cpu have one feature is Boot From USB, there is a 
  small rom in jz4740, but LOW some PIN, the cpu will boot to this small
  rom, then init cpu and USB module, then we can send 8KB bin file to 
  the cpu by USB(by using 'xbboot' or 'usbboot'[1]).

  which means if your bootloader is borken,(the first few KBs in NAND)
  you can always boot the device from usb, then reflash the nand.

  in OpenMoko FreeRunner, there are NOR and NAND. when people broken the 
  nand bootloader, it's must boot from NOR, reflash the bootloader back
  when people broken the NAND and NOR, he(she) must reflash by using JTAG
  but in Ben NanoNote, we just need boot from usb. flash the nand again :)

  BTW:there are a lot of PMP, Audio device in China use the Xburst cpu,
  but I think they are all base on u-boot 1.1.6. by working on
  Ben NanoNote (http://en.qi-hardware.com) one year, we try to
  update the u-boot to last version and send it to upstream. :)

  for more info about Ingenic Xburst JZ4740
    http://www.ingenic.cn/eng/default.aspx
    http://www.linux-mips.org/wiki/Ingenic

Xiangfu Liu (3):
      MIPS: Ingenic XBurst Jz4740 processor support
      MIPS: Jz4740: Add NAND driver
      MIPS: JZ4740: Add qi_lb60 board support

 MAINTAINERS                         |    4 +
 MAKEALL                             |    4 +-
 README                              |    1 +
 arch/mips/cpu/xburst/Makefile       |   49 ++
 arch/mips/cpu/xburst/config.mk      |   24 +
 arch/mips/cpu/xburst/cpu.c          |  152 +++++
 arch/mips/cpu/xburst/jz4740.c       |  248 ++++++++
 arch/mips/cpu/xburst/jz_serial.c    |  114 ++++
 arch/mips/cpu/xburst/start.S        |  171 ++++++
 arch/mips/cpu/xburst/timer.c        |  169 ++++++
 arch/mips/include/asm/global_data.h |   11 +
 arch/mips/include/asm/jz4740.h      | 1115 +++++++++++++++++++++++++++++++++++
 board/qi/qi_lb60/Makefile           |   45 ++
 board/qi/qi_lb60/config.mk          |   31 +
 board/qi/qi_lb60/qi_lb60.c          |  104 ++++
 board/qi/qi_lb60/u-boot.lds         |   61 ++
 boards.cfg                          |    1 +
 drivers/mtd/nand/Makefile           |    1 +
 drivers/mtd/nand/jz4740_nand.c      |  261 ++++++++
 include/configs/qi_lb60.h           |  210 +++++++
 20 files changed, 2775 insertions(+), 1 deletions(-)
 create mode 100644 arch/mips/cpu/xburst/Makefile
 create mode 100644 arch/mips/cpu/xburst/config.mk
 create mode 100644 arch/mips/cpu/xburst/cpu.c
 create mode 100644 arch/mips/cpu/xburst/jz4740.c
 create mode 100644 arch/mips/cpu/xburst/jz_serial.c
 create mode 100644 arch/mips/cpu/xburst/start.S
 create mode 100644 arch/mips/cpu/xburst/timer.c
 create mode 100644 arch/mips/include/asm/jz4740.h
 create mode 100644 board/qi/qi_lb60/Makefile
 create mode 100644 board/qi/qi_lb60/config.mk
 create mode 100644 board/qi/qi_lb60/qi_lb60.c
 create mode 100644 board/qi/qi_lb60/u-boot.lds
 create mode 100644 drivers/mtd/nand/jz4740_nand.c
 create mode 100644 include/configs/qi_lb60.h

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

* [U-Boot] [PATCH v7 1/3] MIPS: Ingenic XBurst Jz4740 processor support
  2011-10-02 13:52 [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Shinya Kuribayashi
@ 2011-10-02 13:54 ` Shinya Kuribayashi
  2011-10-06 21:12   ` Wolfgang Denk
  2011-10-02 13:56 ` [U-Boot] [PATCH v7 2/3] MIPS: Jz4740: Add NAND driver Shinya Kuribayashi
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Shinya Kuribayashi @ 2011-10-02 13:54 UTC (permalink / raw)
  To: u-boot

From: Xiangfu Liu <xiangfu@openmobilefree.net>
Date: Fri, 19 Aug 2011 14:35:29 +0800

Jz4740 is a multimedia application processor targeting for mobile
devices like e-Dictionary, eBook, portable media player (PMP) and
GPS navigator.  Jz4740 is powered by Ingenic 360 MHz XBurst CPU core
(JzRISC), in which RISC/SIMD/DSP hybrid instruction set architecture
provides high integration, high performance and low power consumption.

JzRISC incorporated in Jz4740 is the advanced and power-efficient
32-bit RISC core, compatible with MIPS32, with 16K I-Cache and 16K
D-Cache, and can operate at speeds up to 400 MHz.

On-chip modules such as LCD controller, embedded audio codec, multi-
channel SAR-ADC, AC97/I2S controller and camera I/F offer a rich
suite of peripherals for multimedia application.  NAND controller
(SLC/MLC), USB (host 1.1 and device 2.0), UART, I2C, SPI, etc. are
also available.

For more info about Ingenic XBurst Jz4740:
  http://en.ingenic.cn/eng/
  http://www.linux-mips.org/wiki/Ingenic

This patch introduces XBurst CPU support in U-Boot.  It's compatible
with MIPS32, but requires a bit different cache maintenance, timer
routines, and boot mechanism using USB boot tool, so XBurst support
can go into a separate new home, cpu/xburst/.

Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net>
Acked-by: Daniel <zpxu@ingenic.cn>
Signed-off-by: Shinya Kuribayashi <skuribay@pobox.com>
---

Changes since v6:

* Rebased against the latest U-Boot/MIPS codebase (the previous patches
  up to v6 were based on v1.1.6).  $gp usage, relocation code and so on
  are getting synced with the current MIPS support in U-Boot.

* Use -mach=mips32, pass -EL specifiers in PLATFORM_CPPFLAGS and
  PLATFORM_LDFLAGS.  This port works in Little-endian.

* Remove NAND-boot stuff.  Those bits will be submitted as a nand_spl
  support, once this Jz4740 base support is merged.

* jzsoc_init() is removed.  calc_clocks() and rtc_init() will be
  called through board_early_init_f().

* jz_serial.c is almost the same with standard ns16550 driver, but
  we dont' use it, because it need a special tweak for jz4740 like
  this:

@@ -39,7 +39,11 @@ void NS16550_init (NS16550_t com_port, int baud_divisor)
 	serial_out(0, &com_port->dlm);
 	serial_out(UART_LCRVAL, &com_port->lcr);
 	serial_out(UART_MCRVAL, &com_port->mcr);
+#if defined(CONFIG_JZ4740)	/* 0x10: for JZ4740 UART Module Enable */
+	serial_out(UART_FCRVAL | 0x10, &com_port->fcr);
+#else
 	serial_out(UART_FCRVAL, &com_port->fcr);
+#endif
 	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
 	serial_out(baud_divisor & 0xff, &com_port->dll);
 	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);

  If this is acceptable, we'll change to use standard ns16550 later.

* Coding styles and build warnings fixed

 README                              |    1 +
 arch/mips/cpu/xburst/Makefile       |   49 ++
 arch/mips/cpu/xburst/config.mk      |   24 +
 arch/mips/cpu/xburst/cpu.c          |  152 +++++
 arch/mips/cpu/xburst/jz4740.c       |  248 ++++++++
 arch/mips/cpu/xburst/jz_serial.c    |  114 ++++
 arch/mips/cpu/xburst/start.S        |  171 ++++++
 arch/mips/cpu/xburst/timer.c        |  169 ++++++
 arch/mips/include/asm/global_data.h |   11 +
 arch/mips/include/asm/jz4740.h      | 1115 +++++++++++++++++++++++++++++++++++
 10 files changed, 2054 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/cpu/xburst/Makefile
 create mode 100644 arch/mips/cpu/xburst/config.mk
 create mode 100644 arch/mips/cpu/xburst/cpu.c
 create mode 100644 arch/mips/cpu/xburst/jz4740.c
 create mode 100644 arch/mips/cpu/xburst/jz_serial.c
 create mode 100644 arch/mips/cpu/xburst/start.S
 create mode 100644 arch/mips/cpu/xburst/timer.c
 create mode 100644 arch/mips/include/asm/jz4740.h

diff --git a/README b/README
index a43da97..e9306c5 100644
--- a/README
+++ b/README
@@ -181,6 +181,7 @@ Directory Hierarchy:
   /mips			Files generic to MIPS architecture
     /cpu		CPU specific files
       /mips32		Files specific to MIPS32 CPUs
+      /xburst		Files specific to Ingenic XBurst CPUs
     /lib		Architecture specific library files
   /nios2		Files generic to Altera NIOS2 architecture
     /cpu		CPU specific files
diff --git a/arch/mips/cpu/xburst/Makefile b/arch/mips/cpu/xburst/Makefile
new file mode 100644
index 0000000..b1f2ae4
--- /dev/null
+++ b/arch/mips/cpu/xburst/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2011 Xiangfu Liu <xiangfu@openmobilefree.net>
+#
+# 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
+
+LIB	= $(obj)lib$(CPU).o
+
+START	= start.o
+SOBJS-y	=
+COBJS-y	= cpu.o timer.o jz_serial.o
+
+COBJS-$(CONFIG_JZ4740) += jz4740.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk
new file mode 100644
index 0000000..bce0c1b
--- /dev/null
+++ b/arch/mips/cpu/xburst/config.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2011 Xiangfu Liu <xiangfu@openmobilefree.net>
+#
+# 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
+#
+
+PLATFORM_CPPFLAGS += -march=mips32 -EL
+PLATFORM_LDFLAGS += -EL
diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c
new file mode 100644
index 0000000..3856073
--- /dev/null
+++ b/arch/mips/cpu/xburst/cpu.c
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ * (C) Copyright 2011
+ * Xiangfu Liu <xiangfu@openmobilefree.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheops.h>
+#include <asm/reboot.h>
+#include <asm/io.h>
+#include <asm/jz4740.h>
+
+#define cache_op(op,addr)						\
+	__asm__ __volatile__(						\
+	"	.set	push					\n"	\
+	"	.set	noreorder				\n"	\
+	"	.set	mips3\n\t				\n"	\
+	"	cache	%0, %1					\n"	\
+	"	.set	pop					\n"	\
+	:								\
+	: "i" (op), "R" (*(unsigned char *)(addr)))
+
+void __attribute__((weak)) _machine_restart(void)
+{
+	struct jz4740_wdt *wdt = (struct jz4740_wdt *)JZ4740_WDT_BASE;
+	struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE;
+	u16 tmp;
+
+	/* wdt_select_extalclk() */
+	tmp = readw(&wdt->tcsr);
+	tmp &= ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN);
+	tmp |= WDT_TCSR_EXT_EN;
+	writew(tmp, &wdt->tcsr);
+
+	/* wdt_select_clk_div64() */
+	tmp = readw(&wdt->tcsr);
+	tmp &= ~WDT_TCSR_PRESCALE_MASK;
+	tmp |= WDT_TCSR_PRESCALE64,
+	writew(tmp, &wdt->tcsr);
+
+	writew(100, &wdt->tdr); /* wdt_set_data(100) */
+	writew(0, &wdt->tcnt); /* wdt_set_count(0); */
+	writel(TCU_TSSR_WDTSC, &tcu->tscr); /* tcu_start_wdt_clock */
+	writeb(readb(&wdt->tcer) | WDT_TCER_TCEN, &wdt->tcer); /* wdt start */
+
+	while (1)
+		;
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	_machine_restart();
+
+	fprintf(stderr, "*** reset failed ***\n");
+	return 0;
+}
+
+void flush_cache(ulong start_addr, ulong size)
+{
+	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+	unsigned long addr = start_addr & ~(lsize - 1);
+	unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
+
+	for (;addr <= aend; addr += lsize) {
+		cache_op(Hit_Writeback_Inv_D, addr);
+		cache_op(Hit_Invalidate_I, addr);
+	}
+}
+
+void flush_dcache_range(ulong start_addr, ulong stop)
+{
+	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+	unsigned long addr = start_addr & ~(lsize - 1);
+	unsigned long aend = (stop - 1) & ~(lsize - 1);
+
+	for (;addr <= aend; addr += lsize)
+		cache_op(Hit_Writeback_Inv_D, addr);
+}
+
+void invalidate_dcache_range(ulong start_addr, ulong stop)
+{
+	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+	unsigned long addr = start_addr & ~(lsize - 1);
+	unsigned long aend = (stop - 1) & ~(lsize - 1);
+
+	for (;addr <= aend; addr += lsize)
+		cache_op(Hit_Invalidate_D, addr);
+}
+
+void flush_icache_all(void)
+{
+	u32 addr, t = 0;
+
+	__asm__ __volatile__("mtc0 $0, $28"); /* Clear Taglo */
+	__asm__ __volatile__("mtc0 $0, $29"); /* Clear TagHi */
+
+	for (addr = CKSEG0; addr < CKSEG0 + CONFIG_SYS_ICACHE_SIZE;
+	     addr += CONFIG_SYS_CACHELINE_SIZE) {
+		cache_op(Index_Store_Tag_I, addr);
+	}
+
+	/* invalidate btb */
+	__asm__ __volatile__(
+		".set mips32\n\t"
+		"mfc0 %0, $16, 7\n\t"
+		"nop\n\t"
+		"ori %0,2\n\t"
+		"mtc0 %0, $16, 7\n\t"
+		".set mips2\n\t"
+		:
+		: "r" (t));
+}
+
+void flush_dcache_all(void)
+{
+	u32 addr;
+
+	for (addr = CKSEG0; addr < CKSEG0 + CONFIG_SYS_DCACHE_SIZE;
+	     addr += CONFIG_SYS_CACHELINE_SIZE) {
+		cache_op(Index_Writeback_Inv_D, addr);
+	}
+
+	__asm__ __volatile__("sync");
+}
+
+void flush_cache_all(void)
+{
+	flush_dcache_all();
+	flush_icache_all();
+}
diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c
new file mode 100644
index 0000000..9049274
--- /dev/null
+++ b/arch/mips/cpu/xburst/jz4740.c
@@ -0,0 +1,248 @@
+/*
+ * Jz4740 common routines
+ * Copyright (c) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
+ *
+ * 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 <common.h>
+#include <asm/io.h>
+#include <asm/jz4740.h>
+
+void enable_interrupts(void)
+{
+}
+
+int disable_interrupts(void)
+{
+	return 0;
+}
+
+/*
+ * PLL output clock = EXTAL * NF / (NR * NO)
+ * NF = FD + 2, NR = RD + 2
+ * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
+ */
+void pll_init(void)
+{
+	struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE;
+
+	register unsigned int cfcr, plcr1;
+	int n2FR[33] = {
+		0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
+		7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
+		9
+	};
+	int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
+	int nf, pllout2;
+
+	cfcr =	CPM_CPCCR_CLKOEN |
+		CPM_CPCCR_PCS |
+		(n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
+		(n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
+		(n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
+		(n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
+		(n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
+
+	pllout2 = (cfcr & CPM_CPCCR_PCS) ?
+		CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
+
+	/* Init USB Host clock, pllout2 must be n*48MHz */
+	writel(pllout2 / 48000000 - 1, &cpm->uhccdr);
+
+	nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
+	plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
+		(0 << CPM_CPPCR_PLLN_BIT) |	/* RD=0, NR=2 */
+		(0 << CPM_CPPCR_PLLOD_BIT) |	/* OD=0, NO=1 */
+		(0x20 << CPM_CPPCR_PLLST_BIT) |	/* PLL stable time */
+		CPM_CPPCR_PLLEN;		/* enable PLL */
+
+	/* init PLL */
+	writel(cfcr, &cpm->cpccr);
+	writel(plcr1, &cpm->cppcr);
+}
+
+void sdram_init(void)
+{
+	struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE;
+
+	register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
+
+	unsigned int cas_latency_sdmr[2] = {
+		EMC_SDMR_CAS_2,
+		EMC_SDMR_CAS_3,
+	};
+
+	unsigned int cas_latency_dmcr[2] = {
+		1 << EMC_DMCR_TCL_BIT,	/* CAS latency is 2 */
+		2 << EMC_DMCR_TCL_BIT	/* CAS latency is 3 */
+	};
+
+	int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+
+	cpu_clk = CONFIG_SYS_CPU_SPEED;
+	mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
+
+	writel(0, &emc->bcr);	/* Disable bus release */
+	writew(0, &emc->rtcsr);	/* Disable clock for counting */
+
+	/* Fault DMCR value for mode register setting*/
+#define SDRAM_ROW0	11
+#define SDRAM_COL0	8
+#define SDRAM_BANK40	0
+
+	dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
+		((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
+		(SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
+		(SDRAM_BW16 << EMC_DMCR_BW_BIT) |
+		EMC_DMCR_EPIN |
+		cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
+
+	/* Basic DMCR value */
+	dmcr = ((SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
+		((SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
+		(SDRAM_BANK4 << EMC_DMCR_BA_BIT) |
+		(SDRAM_BW16 << EMC_DMCR_BW_BIT) |
+		EMC_DMCR_EPIN |
+		cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
+
+	/* SDRAM timimg */
+	ns = 1000000000 / mem_clk;
+	tmp = SDRAM_TRAS / ns;
+	if (tmp < 4)
+		tmp = 4;
+	if (tmp > 11)
+		tmp = 11;
+	dmcr |= (tmp - 4) << EMC_DMCR_TRAS_BIT;
+	tmp = SDRAM_RCD / ns;
+
+	if (tmp > 3)
+		tmp = 3;
+	dmcr |= tmp << EMC_DMCR_RCD_BIT;
+	tmp = SDRAM_TPC / ns;
+
+	if (tmp > 7)
+		tmp = 7;
+	dmcr |= tmp << EMC_DMCR_TPC_BIT;
+	tmp = SDRAM_TRWL / ns;
+
+	if (tmp > 3)
+		tmp = 3;
+	dmcr |= tmp << EMC_DMCR_TRWL_BIT;
+	tmp = (SDRAM_TRAS + SDRAM_TPC) / ns;
+
+	if (tmp > 14)
+		tmp = 14;
+	dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT;
+
+	/* SDRAM mode value */
+	sdmode = EMC_SDMR_BT_SEQ |
+		 EMC_SDMR_OM_NORMAL |
+		 EMC_SDMR_BL_4 |
+		 cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
+
+	/* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
+	writel(dmcr, &emc->dmcr);
+	writeb(0, JZ4740_EMC_SDMR0 | sdmode);
+
+	/* Wait for precharge, > 200us */
+	tmp = (cpu_clk / 1000000) * 1000;
+	while (tmp--)
+		;
+
+	/* Stage 2. Enable auto-refresh */
+	writel(dmcr | EMC_DMCR_RFSH, &emc->dmcr);
+
+	tmp = SDRAM_TREF / ns;
+	tmp = tmp / 64 + 1;
+	if (tmp > 0xff)
+		tmp = 0xff;
+	writew(tmp, &emc->rtcor);
+	writew(0, &emc->rtcnt);
+	/* Divisor is 64, CKO/64 */
+	writew(EMC_RTCSR_CKS_64, &emc->rtcsr);
+
+	/* Wait for number of auto-refresh cycles */
+	tmp = (cpu_clk / 1000000) * 1000;
+	while (tmp--)
+		;
+
+	/* Stage 3. Mode Register Set */
+	writel(dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
+	writeb(0, JZ4740_EMC_SDMR0 | sdmode);
+
+        /* Set back to basic DMCR value */
+	writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
+
+	/* everything is ok now */
+}
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void calc_clocks(void)
+{
+	unsigned int pllout;
+	unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+
+	pllout = __cpm_get_pllout();
+
+	gd->cpu_clk = pllout / div[__cpm_get_cdiv()];
+	gd->sys_clk = pllout / div[__cpm_get_hdiv()];
+	gd->per_clk = pllout / div[__cpm_get_pdiv()];
+	gd->mem_clk = pllout / div[__cpm_get_mdiv()];
+	gd->dev_clk = CONFIG_SYS_EXTAL;
+}
+
+void rtc_init(void)
+{
+	struct jz4740_rtc *rtc = (struct jz4740_rtc *)JZ4740_RTC_BASE;
+
+	while (!(readl(&rtc->rcr) & RTC_RCR_WRDY))
+		;
+	writel(readl(&rtc->rcr) | RTC_RCR_AE, &rtc->rcr); /* enable alarm */
+
+	while (!(readl(&rtc->rcr) & RTC_RCR_WRDY))
+		;
+	writel(0x00007fff, &rtc->rgr); /* type value */
+
+	while (!(readl(&rtc->rcr) & RTC_RCR_WRDY))
+		;
+	writel(0x0000ffe0, &rtc->hwfcr); /* Power on delay 2s */
+
+	while (!(readl(&rtc->rcr) & RTC_RCR_WRDY))
+		;
+	writel(0x00000fe0, &rtc->hrcr); /* reset delay 125ms */
+}
+
+/* U-Boot common routines */
+phys_size_t initdram(int board_type)
+{
+	struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE;
+	u32 dmcr;
+	u32 rows, cols, dw, banks;
+	ulong size;
+
+	dmcr = readl(&emc->dmcr);
+	rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
+	cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT);
+	dw = (dmcr & EMC_DMCR_BW) ? 2 : 4;
+	banks = (dmcr & EMC_DMCR_BA) ? 4 : 2;
+
+	size = (1 << (rows + cols)) * dw * banks;
+
+	return size;
+}
diff --git a/arch/mips/cpu/xburst/jz_serial.c b/arch/mips/cpu/xburst/jz_serial.c
new file mode 100644
index 0000000..e6c48e0
--- /dev/null
+++ b/arch/mips/cpu/xburst/jz_serial.c
@@ -0,0 +1,114 @@
+/*
+ * Jz4740 UART support
+ * Copyright (c) 2011
+ * Qi Hardware, Xiangfu Liu <xiangfu@sharism.cc>
+ *
+ * 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 <common.h>
+#include <asm/io.h>
+#include <asm/jz4740.h>
+
+/*
+ * serial_init - initialize a channel
+ *
+ * This routine initializes the number of data bits, parity
+ * and set the selected baud rate. Interrupts are disabled.
+ * Set the modem control signals if the option is selected.
+ *
+ * RETURNS: N/A
+ */
+struct jz4740_uart *uart = (struct jz4740_uart *)CONFIG_SYS_UART_BASE;
+
+int serial_init(void)
+{
+	/* Disable port interrupts while changing hardware */
+	writeb(0, &uart->dlhr_ier);
+
+	/* Disable UART unit function */
+	writeb(~UART_FCR_UUE, &uart->iir_fcr);
+
+	/* Set both receiver and transmitter in UART mode (not SIR) */
+	writeb(~(SIRCR_RSIRE | SIRCR_TSIRE), &uart->isr);
+
+	/*
+	 * Set databits, stopbits and parity.
+	 * (8-bit data, 1 stopbit, no parity)
+	 */
+	writeb(UART_LCR_WLEN_8 | UART_LCR_STOP_1, &uart->lcr);
+
+	/* Set baud rate */
+	serial_setbrg();
+
+	/* Enable UART unit, enable and clear FIFO */
+	writeb(UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS,
+	       &uart->iir_fcr);
+
+	return 0;
+}
+
+void serial_setbrg(void)
+{
+	u32 baud_div, tmp;
+
+	baud_div = CONFIG_SYS_EXTAL / 16 / CONFIG_BAUDRATE;
+
+	tmp = readb(&uart->lcr);
+	tmp |= UART_LCR_DLAB;
+	writeb(tmp, &uart->lcr);
+
+	writeb((baud_div >> 8) & 0xff, &uart->dlhr_ier);
+	writeb(baud_div & 0xff, &uart->rbr_thr_dllr);
+
+	tmp &= ~UART_LCR_DLAB;
+	writeb(tmp, &uart->lcr);
+}
+
+int serial_tstc(void)
+{
+	if (readb(&uart->lsr) & UART_LSR_DR)
+		return 1;
+
+	return 0;
+}
+
+void serial_putc(const char c)
+{
+	if (c == '\n')
+		serial_putc('\r');
+
+	/* Wait for fifo to shift out some bytes */
+	while (!((readb(&uart->lsr) & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60))
+		;
+
+	writeb((u8)c, &uart->rbr_thr_dllr);
+}
+
+int serial_getc(void)
+{
+	while (!serial_tstc())
+		;
+
+	return readb(&uart->rbr_thr_dllr);
+}
+
+void serial_puts(const char *s)
+{
+	while (*s)
+		serial_putc(*s++);
+}
diff --git a/arch/mips/cpu/xburst/start.S b/arch/mips/cpu/xburst/start.S
new file mode 100644
index 0000000..d846104
--- /dev/null
+++ b/arch/mips/cpu/xburst/start.S
@@ -0,0 +1,171 @@
+/*
+ *  Startup Code for MIPS32 XBURST CPU-core
+ *
+ *  Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
+ *
+ * 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 <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+
+	.set noreorder
+
+	.globl _start
+	.text
+_start:
+	/* Initialize $gp */
+	bal	1f
+	 nop
+	.word	_gp
+1:
+	lw	gp, 0(ra)
+
+	/* Set up temporary stack */
+	li	sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
+
+	la	t9, board_init_f
+	jr	t9
+	 nop
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * a0 = addr_sp
+ * a1 = gd
+ * a2 = destination address
+ */
+	.globl	relocate_code
+	.ent	relocate_code
+relocate_code:
+	move	sp, a0			# set new stack pointer
+
+	li	t0, CONFIG_SYS_MONITOR_BASE
+	la	t3, in_ram
+	lw	t2, -12(t3)		# t2 <-- uboot_end_data
+	move	t1, a2
+
+	/*
+	 * Fix $gp:
+	 *
+	 * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address
+	 */
+	move	t6, gp
+	sub	gp, CONFIG_SYS_MONITOR_BASE
+	add	gp, a2			# gp now adjusted
+	sub	t6, gp, t6		# t6 <-- relocation offset
+
+	/*
+	 * t0 = source address
+	 * t1 = target address
+	 * t2 = source end address
+	 */
+1:
+	lw	t3, 0(t0)
+	sw	t3, 0(t1)
+	addu	t0, 4
+	ble	t0, t2, 1b
+	 addu	t1, 4
+
+	/* If caches were enabled, we would have to flush them here. */
+
+	/* flush d-cache */
+	li	t0, KSEG0
+	addi	t1, t0, CONFIG_SYS_DCACHE_SIZE
+2:
+	cache	Index_Writeback_Inv_D, 0(t0)
+	bne	t0, t1, 2b
+	 addi	t0, CONFIG_SYS_CACHELINE_SIZE
+
+	sync
+
+	/* flush i-cache */
+	li	t0, KSEG0
+	addi	t1, t0, CONFIG_SYS_ICACHE_SIZE
+3:
+	cache	Index_Invalidate_I, 0(t0)
+	bne	t0, t1, 3b
+	 addi	t0, CONFIG_SYS_CACHELINE_SIZE
+
+	/* Invalidate BTB */
+	mfc0	t0, CP0_CONFIG, 7
+	nop
+	ori	t0, 2
+	mtc0	t0, CP0_CONFIG, 7
+	nop
+
+	/* Jump to where we've relocated ourselves */
+	addi	t0, a2, in_ram - _start
+	jr	t0
+	 nop
+
+	.word	_gp
+	.word	_GLOBAL_OFFSET_TABLE_
+	.word	uboot_end_data
+	.word	uboot_end
+	.word	num_got_entries
+
+in_ram:
+	/*
+	 * Now we want to update GOT.
+	 *
+	 * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
+	 * generated by GNU ld. Skip these reserved entries from relocation.
+	 */
+	lw	t3, -4(t0)		# t3 <-- num_got_entries
+	lw	t4, -16(t0)		# t4 <-- _GLOBAL_OFFSET_TABLE_
+	lw	t5, -20(t0)		# t5 <-- _gp
+	sub	t4, t5			# compute offset
+	add	t4, t4, gp		# t4 now holds relocated _G_O_T_
+	addi	t4, t4, 8		# skipping first two entries
+	li	t2, 2
+1:
+	lw	t1, 0(t4)
+	beqz	t1, 2f
+	 add	t1, t6
+	sw	t1, 0(t4)
+2:
+	addi	t2, 1
+	blt	t2, t3, 1b
+	 addi	t4, 4
+
+	/* Clear BSS */
+	lw	t1, -12(t0)		# t1 <-- uboot_end_data
+	lw	t2, -8(t0)		# t2 <-- uboot_end
+	add	t1, t6			# adjust pointers
+	add	t2, t6
+
+	sub	t1, 4
+1:	addi	t1, 4
+	bltl	t1, t2, 1b
+	 sw	zero, 0(t1)
+
+	move	a0, a1			# a0 <-- gd
+	la	t9, board_init_r
+	jr	t9
+	 move	a1, a2
+
+	.end	relocate_code
diff --git a/arch/mips/cpu/xburst/timer.c b/arch/mips/cpu/xburst/timer.c
new file mode 100644
index 0000000..4421bd5
--- /dev/null
+++ b/arch/mips/cpu/xburst/timer.c
@@ -0,0 +1,169 @@
+/*
+ *  Copyright (c) 2006
+ *  Ingenic Semiconductor, <jlwei@ingenic.cn>
+ *
+ * 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 <common.h>
+#include <asm/io.h>
+
+#include <asm/jz4740.h>
+
+#define TIMER_CHAN  0
+#define TIMER_FDATA 0xffff  /* Timer full data value */
+
+void reset_timer_masked(void);
+ulong get_timer_masked(void);
+void udelay_masked(unsigned long usec);
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE;
+
+/*
+ * timer without interrupts
+ */
+int timer_init(void)
+{
+	writel(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0);
+
+	writel(0, &tcu->tcnt0);
+	writel(0, &tcu->tdhr0);
+	writel(TIMER_FDATA, &tcu->tdfr0);
+
+	/* mask irqs */
+	writel((1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)), &tcu->tmsr);
+	writel(1 << TIMER_CHAN, &tcu->tscr); /* enable timer clock */
+	writel(1 << TIMER_CHAN, &tcu->tesr); /* start counting up */
+
+	gd->lastinc = 0;
+	gd->tbl = 0;
+
+	return 0;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	gd->tbl = t;
+}
+
+void __udelay(unsigned long usec)
+{
+	ulong tmo, tmp;
+
+	/* normalize */
+	if (usec >= 1000) {
+		tmo = usec / 1000;
+		tmo *= CONFIG_SYS_HZ;
+		tmo /= 1000;
+	} else {
+		if (usec >= 1) {
+			tmo = usec * CONFIG_SYS_HZ;
+			tmo /= 1000 * 1000;
+		} else
+			tmo = 1;
+	}
+
+	/* check for rollover during this delay */
+	tmp = get_timer(0);
+	if ((tmp + tmo) < tmp)
+		reset_timer_masked();  /* timer would roll over */
+	else
+		tmo += tmp;
+
+	while (get_timer_masked() < tmo)
+		;
+}
+
+void reset_timer_masked(void)
+{
+	/* reset time */
+	gd->lastinc = readl(&tcu->tcnt0);
+	gd->tbl = 0;
+}
+
+ulong get_timer_masked(void)
+{
+	ulong now = readl(&tcu->tcnt0);
+
+	if (gd->lastinc <= now)
+		gd->tbl += now - gd->lastinc; /* normal mode */
+	else {
+		/* we have an overflow ... */
+		gd->tbl += TIMER_FDATA + now - gd->lastinc;
+	}
+
+	gd->lastinc = now;
+
+	return gd->tbl;
+}
+
+void udelay_masked(unsigned long usec)
+{
+	ulong tmo;
+	ulong endtime;
+	signed long diff;
+
+	/* normalize */
+	if (usec >= 1000) {
+		tmo = usec / 1000;
+		tmo *= CONFIG_SYS_HZ;
+		tmo /= 1000;
+	} else {
+		if (usec > 1) {
+			tmo = usec * CONFIG_SYS_HZ;
+			tmo /= 1000*1000;
+		} else
+			tmo = 1;
+	}
+
+	endtime = get_timer_masked() + tmo;
+
+	do {
+		ulong now = get_timer_masked();
+		diff = endtime - now;
+	} while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On MIPS 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 MIPS it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
index 271a290..2032762 100644
--- a/arch/mips/include/asm/global_data.h
+++ b/arch/mips/include/asm/global_data.h
@@ -39,6 +39,17 @@
 typedef	struct	global_data {
 	bd_t		*bd;
 	unsigned long	flags;
+#if defined(CONFIG_JZSOC)
+	/* There are other clocks in the jz4740 */
+	unsigned long	cpu_clk;	/* CPU core clock */
+	unsigned long	sys_clk;	/* System bus clock */
+	unsigned long	per_clk;	/* Peripheral bus clock */
+	unsigned long	mem_clk;	/* Memory bus clock */
+	unsigned long	dev_clk;	/* Device clock */
+	/* "static data" needed by most of timer.c */
+	unsigned long	tbl;
+	unsigned long	lastinc;
+#endif
 	unsigned long	baudrate;
 	unsigned long	have_console;	/* serial_init() was called */
 	phys_size_t	ram_size;	/* RAM size */
diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
new file mode 100644
index 0000000..9d106f6
--- /dev/null
+++ b/arch/mips/include/asm/jz4740.h
@@ -0,0 +1,1115 @@
+/*
+ * head file for Ingenic Semiconductor's JZ4740 CPU.
+ */
+#ifndef __JZ4740_H__
+#define __JZ4740_H__
+
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+
+/* Boot ROM Specification  */
+/* NOR Boot config */
+#define JZ4740_NORBOOT_8BIT	0x00000000	/* 8-bit data bus flash */
+#define JZ4740_NORBOOT_16BIT	0x10101010	/* 16-bit data bus flash */
+#define JZ4740_NORBOOT_32BIT	0x20202020	/* 32-bit data bus flash */
+/* NAND Boot config */
+#define JZ4740_NANDBOOT_B8R3	0xffffffff	/* 8-bit bus & 3 row cycles */
+#define JZ4740_NANDBOOT_B8R2	0xf0f0f0f0	/* 8-bit bus & 2 row cycles */
+#define JZ4740_NANDBOOT_B16R3	0x0f0f0f0f	/* 16-bit bus & 3 row cycles */
+#define JZ4740_NANDBOOT_B16R2	0x00000000	/* 16-bit bus & 2 row cycles */
+
+/* 1st-level interrupts */
+#define JZ4740_IRQ_I2C		1
+#define JZ4740_IRQ_UHC		3
+#define JZ4740_IRQ_UART0	9
+#define JZ4740_IRQ_SADC		12
+#define JZ4740_IRQ_MSC		14
+#define JZ4740_IRQ_RTC		15
+#define JZ4740_IRQ_SSI		16
+#define JZ4740_IRQ_CIM		17
+#define JZ4740_IRQ_AIC		18
+#define JZ4740_IRQ_ETH		19
+#define JZ4740_IRQ_DMAC		20
+#define JZ4740_IRQ_TCU2		21
+#define JZ4740_IRQ_TCU1		22
+#define JZ4740_IRQ_TCU0		23
+#define JZ4740_IRQ_UDC		24
+#define JZ4740_IRQ_GPIO3	25
+#define JZ4740_IRQ_GPIO2	26
+#define JZ4740_IRQ_GPIO1	27
+#define JZ4740_IRQ_GPIO0	28
+#define JZ4740_IRQ_IPU		29
+#define JZ4740_IRQ_LCD		30
+/* 2nd-level interrupts */
+#define JZ4740_IRQ_DMA_0	32  /* 32 to 37 for DMAC channel 0 to 5 */
+#define JZ4740_IRQ_GPIO_0	48  /* 48 to 175 for GPIO pin 0 to 127 */
+
+/* Register Definitions */
+#define JZ4740_CPM_BASE		0x10000000
+#define JZ4740_INTC_BASE	0x10001000
+#define JZ4740_TCU_BASE		0x10002000
+#define JZ4740_WDT_BASE		0x10002000
+#define JZ4740_RTC_BASE		0x10003000
+#define JZ4740_GPIO_BASE	0x10010000
+#define JZ4740_AIC_BASE		0x10020000
+#define JZ4740_ICDC_BASE	0x10020000
+#define JZ4740_MSC_BASE		0x10021000
+#define JZ4740_UART0_BASE	0x10030000
+#define JZ4740_I2C_BASE		0x10042000
+#define JZ4740_SSI_BASE		0x10043000
+#define JZ4740_SADC_BASE	0x10070000
+#define JZ4740_EMC_BASE		0x13010000
+#define JZ4740_DMAC_BASE	0x13020000
+#define JZ4740_UHC_BASE		0x13030000
+#define JZ4740_UDC_BASE		0x13040000
+#define JZ4740_LCD_BASE		0x13050000
+#define JZ4740_SLCD_BASE	0x13050000
+#define JZ4740_CIM_BASE		0x13060000
+#define JZ4740_ETH_BASE		0x13100000
+
+/* 8bit Mode Register of SDRAM bank 0 */
+#define JZ4740_EMC_SDMR0	(JZ4740_EMC_BASE + 0xa000)
+
+/* GPIO (General-Purpose I/O Ports) */
+/*  = 0,1,2,3 */
+#define GPIO_PXPIN(n)	(JZ4740_GPIO_BASE + (0x00 + (n)*0x100)) /* PIN Level Register */
+#define GPIO_PXDAT(n)	(JZ4740_GPIO_BASE + (0x10 + (n)*0x100)) /* Port Data Register */
+#define GPIO_PXDATS(n)	(JZ4740_GPIO_BASE + (0x14 + (n)*0x100)) /* Port Data Set Register */
+#define GPIO_PXDATC(n)	(JZ4740_GPIO_BASE + (0x18 + (n)*0x100)) /* Port Data Clear Register */
+#define GPIO_PXIM(n)	(JZ4740_GPIO_BASE + (0x20 + (n)*0x100)) /* Interrupt Mask Register */
+#define GPIO_PXIMS(n)	(JZ4740_GPIO_BASE + (0x24 + (n)*0x100)) /* Interrupt Mask Set Reg */
+#define GPIO_PXIMC(n)	(JZ4740_GPIO_BASE + (0x28 + (n)*0x100)) /* Interrupt Mask Clear Reg */
+#define GPIO_PXPE(n)	(JZ4740_GPIO_BASE + (0x30 + (n)*0x100)) /* Pull Enable Register */
+#define GPIO_PXPES(n)	(JZ4740_GPIO_BASE + (0x34 + (n)*0x100)) /* Pull Enable Set Reg. */
+#define GPIO_PXPEC(n)	(JZ4740_GPIO_BASE + (0x38 + (n)*0x100)) /* Pull Enable Clear Reg. */
+#define GPIO_PXFUN(n)	(JZ4740_GPIO_BASE + (0x40 + (n)*0x100)) /* Function Register */
+#define GPIO_PXFUNS(n)	(JZ4740_GPIO_BASE + (0x44 + (n)*0x100)) /* Function Set Register */
+#define GPIO_PXFUNC(n)	(JZ4740_GPIO_BASE + (0x48 + (n)*0x100)) /* Function Clear Register */
+#define GPIO_PXSEL(n)	(JZ4740_GPIO_BASE + (0x50 + (n)*0x100)) /* Select Register */
+#define GPIO_PXSELS(n)	(JZ4740_GPIO_BASE + (0x54 + (n)*0x100)) /* Select Set Register */
+#define GPIO_PXSELC(n)	(JZ4740_GPIO_BASE + (0x58 + (n)*0x100)) /* Select Clear Register */
+#define GPIO_PXDIR(n)	(JZ4740_GPIO_BASE + (0x60 + (n)*0x100)) /* Direction Register */
+#define GPIO_PXDIRS(n)	(JZ4740_GPIO_BASE + (0x64 + (n)*0x100)) /* Direction Set Register */
+#define GPIO_PXDIRC(n)	(JZ4740_GPIO_BASE + (0x68 + (n)*0x100)) /* Direction Clear Register */
+#define GPIO_PXTRG(n)	(JZ4740_GPIO_BASE + (0x70 + (n)*0x100)) /* Trigger Register */
+#define GPIO_PXTRGS(n)	(JZ4740_GPIO_BASE + (0x74 + (n)*0x100)) /* Trigger Set Register */
+#define GPIO_PXTRGC(n)	(JZ4740_GPIO_BASE + (0x78 + (n)*0x100)) /* Trigger Set Register */
+#define GPIO_PXFLG(n)	(JZ4740_GPIO_BASE + (0x80 + (n)*0x100)) /* Port Flag Register */
+#define GPIO_PXFLGC(n)	(JZ4740_GPIO_BASE + (0x14 + (n)*0x100)) /* Port Flag clear Register */
+
+/* Static Memory Control Register */
+#define EMC_SMCR_STRV_BIT	24
+#define EMC_SMCR_STRV_MASK	(0x0f << EMC_SMCR_STRV_BIT)
+#define EMC_SMCR_TAW_BIT	20
+#define EMC_SMCR_TAW_MASK	(0x0f << EMC_SMCR_TAW_BIT)
+#define EMC_SMCR_TBP_BIT	16
+#define EMC_SMCR_TBP_MASK	(0x0f << EMC_SMCR_TBP_BIT)
+#define EMC_SMCR_TAH_BIT	12
+#define EMC_SMCR_TAH_MASK	(0x07 << EMC_SMCR_TAH_BIT)
+#define EMC_SMCR_TAS_BIT	8
+#define EMC_SMCR_TAS_MASK	(0x07 << EMC_SMCR_TAS_BIT)
+#define EMC_SMCR_BW_BIT		6
+#define EMC_SMCR_BW_MASK	(0x03 << EMC_SMCR_BW_BIT)
+  #define EMC_SMCR_BW_8BIT	(0 << EMC_SMCR_BW_BIT)
+  #define EMC_SMCR_BW_16BIT	(1 << EMC_SMCR_BW_BIT)
+  #define EMC_SMCR_BW_32BIT	(2 << EMC_SMCR_BW_BIT)
+#define EMC_SMCR_BCM		(1 << 3)
+#define EMC_SMCR_BL_BIT		1
+#define EMC_SMCR_BL_MASK	(0x03 << EMC_SMCR_BL_BIT)
+  #define EMC_SMCR_BL_4		(0 << EMC_SMCR_BL_BIT)
+  #define EMC_SMCR_BL_8		(1 << EMC_SMCR_BL_BIT)
+  #define EMC_SMCR_BL_16	(2 << EMC_SMCR_BL_BIT)
+  #define EMC_SMCR_BL_32	(3 << EMC_SMCR_BL_BIT)
+#define EMC_SMCR_SMT		(1 << 0)
+
+/* Static Memory Bank Addr Config Reg */
+#define EMC_SACR_BASE_BIT	8
+#define EMC_SACR_BASE_MASK	(0xff << EMC_SACR_BASE_BIT)
+#define EMC_SACR_MASK_BIT	0
+#define EMC_SACR_MASK_MASK	(0xff << EMC_SACR_MASK_BIT)
+
+/* NAND Flash Control/Status Register */
+#define EMC_NFCSR_NFCE4		(1 << 7) /* NAND Flash Enable */
+#define EMC_NFCSR_NFE4		(1 << 6) /* NAND Flash FCE# Assertion Enable */
+#define EMC_NFCSR_NFCE3		(1 << 5)
+#define EMC_NFCSR_NFE3		(1 << 4)
+#define EMC_NFCSR_NFCE2		(1 << 3)
+#define EMC_NFCSR_NFE2		(1 << 2)
+#define EMC_NFCSR_NFCE1		(1 << 1)
+#define EMC_NFCSR_NFE1		(1 << 0)
+
+/* NAND Flash ECC Control Register */
+#define EMC_NFECR_PRDY		(1 << 4) /* Parity Ready */
+#define EMC_NFECR_RS_DECODING	(0 << 3) /* RS is in decoding phase */
+#define EMC_NFECR_RS_ENCODING	(1 << 3) /* RS is in encoding phase */
+#define EMC_NFECR_HAMMING	(0 << 2) /* Select HAMMING Correction Algorithm */
+#define EMC_NFECR_RS		(1 << 2) /* Select RS Correction Algorithm */
+#define EMC_NFECR_ERST		(1 << 1) /* ECC Reset */
+#define EMC_NFECR_ECCE		(1 << 0) /* ECC Enable */
+
+/* NAND Flash ECC Data Register */
+#define EMC_NFECC_ECC2_BIT	16
+#define EMC_NFECC_ECC2_MASK	(0xff << EMC_NFECC_ECC2_BIT)
+#define EMC_NFECC_ECC1_BIT	8
+#define EMC_NFECC_ECC1_MASK	(0xff << EMC_NFECC_ECC1_BIT)
+#define EMC_NFECC_ECC0_BIT	0
+#define EMC_NFECC_ECC0_MASK	(0xff << EMC_NFECC_ECC0_BIT)
+
+/* NAND Flash Interrupt Status Register */
+#define EMC_NFINTS_ERRCNT_BIT	29       /* Error Count */
+#define EMC_NFINTS_ERRCNT_MASK	(0x7 << EMC_NFINTS_ERRCNT_BIT)
+#define EMC_NFINTS_PADF		(1 << 4) /* Padding Finished */
+#define EMC_NFINTS_DECF		(1 << 3) /* Decoding Finished */
+#define EMC_NFINTS_ENCF		(1 << 2) /* Encoding Finished */
+#define EMC_NFINTS_UNCOR	(1 << 1) /* Uncorrectable Error Occurred */
+#define EMC_NFINTS_ERR		(1 << 0) /* Error Occurred */
+
+/* NAND Flash Interrupt Enable Register */
+#define EMC_NFINTE_PADFE	(1 << 4) /* Padding Finished Interrupt Enable */
+#define EMC_NFINTE_DECFE	(1 << 3) /* Decoding Finished Interrupt Enable */
+#define EMC_NFINTE_ENCFE	(1 << 2) /* Encoding Finished Interrupt Enable */
+#define EMC_NFINTE_UNCORE	(1 << 1) /* Uncorrectable Error Occurred Intr Enable */
+#define EMC_NFINTE_ERRE		(1 << 0) /* Error Occurred Interrupt */
+
+/* NAND Flash RS Error Report Register */
+#define EMC_NFERR_INDEX_BIT	16       /* Error Symbol Index */
+#define EMC_NFERR_INDEX_MASK	(0x1ff << EMC_NFERR_INDEX_BIT)
+#define EMC_NFERR_MASK_BIT	0        /* Error Symbol Value */
+#define EMC_NFERR_MASK_MASK	(0x1ff << EMC_NFERR_MASK_BIT)
+
+/* DRAM Control Register */
+#define EMC_DMCR_BW_BIT		31
+#define EMC_DMCR_BW		(1 << EMC_DMCR_BW_BIT)
+#define EMC_DMCR_CA_BIT		26
+#define EMC_DMCR_CA_MASK	(0x07 << EMC_DMCR_CA_BIT)
+  #define EMC_DMCR_CA_8		(0 << EMC_DMCR_CA_BIT)
+  #define EMC_DMCR_CA_9		(1 << EMC_DMCR_CA_BIT)
+  #define EMC_DMCR_CA_10	(2 << EMC_DMCR_CA_BIT)
+  #define EMC_DMCR_CA_11	(3 << EMC_DMCR_CA_BIT)
+  #define EMC_DMCR_CA_12	(4 << EMC_DMCR_CA_BIT)
+#define EMC_DMCR_RMODE		(1 << 25)
+#define EMC_DMCR_RFSH		(1 << 24)
+#define EMC_DMCR_MRSET		(1 << 23)
+#define EMC_DMCR_RA_BIT		20
+#define EMC_DMCR_RA_MASK	(0x03 << EMC_DMCR_RA_BIT)
+  #define EMC_DMCR_RA_11	(0 << EMC_DMCR_RA_BIT)
+  #define EMC_DMCR_RA_12	(1 << EMC_DMCR_RA_BIT)
+  #define EMC_DMCR_RA_13	(2 << EMC_DMCR_RA_BIT)
+#define EMC_DMCR_BA_BIT		19
+#define EMC_DMCR_BA		(1 << EMC_DMCR_BA_BIT)
+#define EMC_DMCR_PDM		(1 << 18)
+#define EMC_DMCR_EPIN		(1 << 17)
+#define EMC_DMCR_TRAS_BIT	13
+#define EMC_DMCR_TRAS_MASK	(0x07 << EMC_DMCR_TRAS_BIT)
+#define EMC_DMCR_RCD_BIT	11
+#define EMC_DMCR_RCD_MASK	(0x03 << EMC_DMCR_RCD_BIT)
+#define EMC_DMCR_TPC_BIT	8
+#define EMC_DMCR_TPC_MASK	(0x07 << EMC_DMCR_TPC_BIT)
+#define EMC_DMCR_TRWL_BIT	5
+#define EMC_DMCR_TRWL_MASK	(0x03 << EMC_DMCR_TRWL_BIT)
+#define EMC_DMCR_TRC_BIT	2
+#define EMC_DMCR_TRC_MASK	(0x07 << EMC_DMCR_TRC_BIT)
+#define EMC_DMCR_TCL_BIT	0
+#define EMC_DMCR_TCL_MASK	(0x03 << EMC_DMCR_TCL_BIT)
+
+/* Refresh Time Control/Status Register */
+#define EMC_RTCSR_CMF		(1 << 7)
+#define EMC_RTCSR_CKS_BIT	0
+#define EMC_RTCSR_CKS_MASK	(0x07 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_DISABLE	(0 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_4	(1 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_16	(2 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_64	(3 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_256	(4 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_1024	(5 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_2048	(6 << EMC_RTCSR_CKS_BIT)
+  #define EMC_RTCSR_CKS_4096	(7 << EMC_RTCSR_CKS_BIT)
+
+/* SDRAM Bank Address Configuration Register */
+#define EMC_DMAR_BASE_BIT	8
+#define EMC_DMAR_BASE_MASK	(0xff << EMC_DMAR_BASE_BIT)
+#define EMC_DMAR_MASK_BIT	0
+#define EMC_DMAR_MASK_MASK	(0xff << EMC_DMAR_MASK_BIT)
+
+/* Mode Register of SDRAM bank 0 */
+#define EMC_SDMR_BM		(1 << 9) /* Write Burst Mode */
+#define EMC_SDMR_OM_BIT		7        /* Operating Mode */
+#define EMC_SDMR_OM_MASK	(3 << EMC_SDMR_OM_BIT)
+  #define EMC_SDMR_OM_NORMAL	(0 << EMC_SDMR_OM_BIT)
+#define EMC_SDMR_CAS_BIT	4        /* CAS Latency */
+#define EMC_SDMR_CAS_MASK	(7 << EMC_SDMR_CAS_BIT)
+  #define EMC_SDMR_CAS_1	(1 << EMC_SDMR_CAS_BIT)
+  #define EMC_SDMR_CAS_2	(2 << EMC_SDMR_CAS_BIT)
+  #define EMC_SDMR_CAS_3	(3 << EMC_SDMR_CAS_BIT)
+#define EMC_SDMR_BT_BIT		3        /* Burst Type */
+#define EMC_SDMR_BT_MASK	(1 << EMC_SDMR_BT_BIT)
+  #define EMC_SDMR_BT_SEQ	(0 << EMC_SDMR_BT_BIT) /* Sequential */
+  #define EMC_SDMR_BT_INT	(1 << EMC_SDMR_BT_BIT) /* Interleave */
+#define EMC_SDMR_BL_BIT		0        /* Burst Length */
+#define EMC_SDMR_BL_MASK	(7 << EMC_SDMR_BL_BIT)
+  #define EMC_SDMR_BL_1		(0 << EMC_SDMR_BL_BIT)
+  #define EMC_SDMR_BL_2		(1 << EMC_SDMR_BL_BIT)
+  #define EMC_SDMR_BL_4		(2 << EMC_SDMR_BL_BIT)
+  #define EMC_SDMR_BL_8		(3 << EMC_SDMR_BL_BIT)
+
+#define EMC_SDMR_CAS2_16BIT \
+  (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2)
+#define EMC_SDMR_CAS2_32BIT \
+  (EMC_SDMR_CAS_2 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4)
+#define EMC_SDMR_CAS3_16BIT \
+  (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_2)
+#define EMC_SDMR_CAS3_32BIT \
+  (EMC_SDMR_CAS_3 | EMC_SDMR_BT_SEQ | EMC_SDMR_BL_4)
+
+/* RTC Control Register */
+#define RTC_RCR_WRDY	(1 << 7)  /* Write Ready Flag */
+#define RTC_RCR_HZ	(1 << 6)  /* 1Hz Flag */
+#define RTC_RCR_HZIE	(1 << 5)  /* 1Hz Interrupt Enable */
+#define RTC_RCR_AF	(1 << 4)  /* Alarm Flag */
+#define RTC_RCR_AIE	(1 << 3)  /* Alarm Interrupt Enable */
+#define RTC_RCR_AE	(1 << 2)  /* Alarm Enable */
+#define RTC_RCR_RTCE	(1 << 0)  /* RTC Enable */
+
+/* RTC Regulator Register */
+#define RTC_RGR_LOCK		(1 << 31) /* Lock Bit */
+#define RTC_RGR_ADJC_BIT	16
+#define RTC_RGR_ADJC_MASK	(0x3ff << RTC_RGR_ADJC_BIT)
+#define RTC_RGR_NC1HZ_BIT	0
+#define RTC_RGR_NC1HZ_MASK	(0xffff << RTC_RGR_NC1HZ_BIT)
+
+/* Hibernate Control Register */
+#define RTC_HCR_PD		(1 << 0)  /* Power Down */
+
+/* Hibernate Wakeup Filter Counter Register */
+#define RTC_HWFCR_BIT		5
+#define RTC_HWFCR_MASK		(0x7ff << RTC_HWFCR_BIT)
+
+/* Hibernate Reset Counter Register */
+#define RTC_HRCR_BIT		5
+#define RTC_HRCR_MASK		(0x7f << RTC_HRCR_BIT)
+
+/* Hibernate Wakeup Control Register */
+#define RTC_HWCR_EALM		(1 << 0)  /* RTC alarm wakeup enable */
+
+/* Hibernate Wakeup Status Register */
+#define RTC_HWRSR_HR		(1 << 5)  /* Hibernate reset */
+#define RTC_HWRSR_PPR		(1 << 4)  /* PPR reset */
+#define RTC_HWRSR_PIN		(1 << 1)  /* Wakeup pin status bit */
+#define RTC_HWRSR_ALM		(1 << 0)  /* RTC alarm status bit */
+
+/* Clock Control Register */
+#define CPM_CPCCR_I2CS		(1 << 31)
+#define CPM_CPCCR_CLKOEN	(1 << 30)
+#define CPM_CPCCR_UCS		(1 << 29)
+#define CPM_CPCCR_UDIV_BIT	23
+#define CPM_CPCCR_UDIV_MASK	(0x3f << CPM_CPCCR_UDIV_BIT)
+#define CPM_CPCCR_CE		(1 << 22)
+#define CPM_CPCCR_PCS		(1 << 21)
+#define CPM_CPCCR_LDIV_BIT	16
+#define CPM_CPCCR_LDIV_MASK	(0x1f << CPM_CPCCR_LDIV_BIT)
+#define CPM_CPCCR_MDIV_BIT	12
+#define CPM_CPCCR_MDIV_MASK	(0x0f << CPM_CPCCR_MDIV_BIT)
+#define CPM_CPCCR_PDIV_BIT	8
+#define CPM_CPCCR_PDIV_MASK	(0x0f << CPM_CPCCR_PDIV_BIT)
+#define CPM_CPCCR_HDIV_BIT	4
+#define CPM_CPCCR_HDIV_MASK	(0x0f << CPM_CPCCR_HDIV_BIT)
+#define CPM_CPCCR_CDIV_BIT	0
+#define CPM_CPCCR_CDIV_MASK	(0x0f << CPM_CPCCR_CDIV_BIT)
+
+/* I2S Clock Divider Register */
+#define CPM_I2SCDR_I2SDIV_BIT	0
+#define CPM_I2SCDR_I2SDIV_MASK	(0x1ff << CPM_I2SCDR_I2SDIV_BIT)
+
+/* LCD Pixel Clock Divider Register */
+#define CPM_LPCDR_PIXDIV_BIT	0
+#define CPM_LPCDR_PIXDIV_MASK	(0x1ff << CPM_LPCDR_PIXDIV_BIT)
+
+/* MSC Clock Divider Register */
+#define CPM_MSCCDR_MSCDIV_BIT	0
+#define CPM_MSCCDR_MSCDIV_MASK	(0x1f << CPM_MSCCDR_MSCDIV_BIT)
+
+/* PLL Control Register */
+#define CPM_CPPCR_PLLM_BIT	23
+#define CPM_CPPCR_PLLM_MASK	(0x1ff << CPM_CPPCR_PLLM_BIT)
+#define CPM_CPPCR_PLLN_BIT	18
+#define CPM_CPPCR_PLLN_MASK	(0x1f << CPM_CPPCR_PLLN_BIT)
+#define CPM_CPPCR_PLLOD_BIT	16
+#define CPM_CPPCR_PLLOD_MASK	(0x03 << CPM_CPPCR_PLLOD_BIT)
+#define CPM_CPPCR_PLLS		(1 << 10)
+#define CPM_CPPCR_PLLBP		(1 << 9)
+#define CPM_CPPCR_PLLEN		(1 << 8)
+#define CPM_CPPCR_PLLST_BIT	0
+#define CPM_CPPCR_PLLST_MASK	(0xff << CPM_CPPCR_PLLST_BIT)
+
+/* Low Power Control Register */
+#define CPM_LCR_DOZE_DUTY_BIT	3
+#define CPM_LCR_DOZE_DUTY_MASK	(0x1f << CPM_LCR_DOZE_DUTY_BIT)
+#define CPM_LCR_DOZE_ON		(1 << 2)
+#define CPM_LCR_LPM_BIT		0
+#define CPM_LCR_LPM_MASK	(0x3 << CPM_LCR_LPM_BIT)
+  #define CPM_LCR_LPM_IDLE	(0x0 << CPM_LCR_LPM_BIT)
+  #define CPM_LCR_LPM_SLEEP	(0x1 << CPM_LCR_LPM_BIT)
+
+/* Clock Gate Register */
+#define CPM_CLKGR_UART1		(1 << 15)
+#define CPM_CLKGR_UHC		(1 << 14)
+#define CPM_CLKGR_IPU		(1 << 13)
+#define CPM_CLKGR_DMAC		(1 << 12)
+#define CPM_CLKGR_UDC		(1 << 11)
+#define CPM_CLKGR_LCD		(1 << 10)
+#define CPM_CLKGR_CIM		(1 << 9)
+#define CPM_CLKGR_SADC		(1 << 8)
+#define CPM_CLKGR_MSC		(1 << 7)
+#define CPM_CLKGR_AIC1		(1 << 6)
+#define CPM_CLKGR_AIC2		(1 << 5)
+#define CPM_CLKGR_SSI		(1 << 4)
+#define CPM_CLKGR_I2C		(1 << 3)
+#define CPM_CLKGR_RTC		(1 << 2)
+#define CPM_CLKGR_TCU		(1 << 1)
+#define CPM_CLKGR_UART0		(1 << 0)
+
+/* Sleep Control Register */
+#define CPM_SCR_O1ST_BIT	8
+#define CPM_SCR_O1ST_MASK	(0xff << CPM_SCR_O1ST_BIT)
+#define CPM_SCR_UDCPHY_ENABLE	(1 << 6)
+#define CPM_SCR_USBPHY_DISABLE	(1 << 7)
+#define CPM_SCR_OSC_ENABLE	(1 << 4)
+
+/* Hibernate Control Register */
+#define CPM_HCR_PD		(1 << 0)
+
+/* Wakeup Filter Counter Register in Hibernate Mode */
+#define CPM_HWFCR_TIME_BIT	0
+#define CPM_HWFCR_TIME_MASK	(0x3ff << CPM_HWFCR_TIME_BIT)
+
+/* Reset Counter Register in Hibernate Mode */
+#define CPM_HRCR_TIME_BIT	0
+#define CPM_HRCR_TIME_MASK	(0x7f << CPM_HRCR_TIME_BIT)
+
+/* Wakeup Control Register in Hibernate Mode */
+#define CPM_HWCR_WLE_LOW	(0 << 2)
+#define CPM_HWCR_WLE_HIGH	(1 << 2)
+#define CPM_HWCR_PIN_WAKEUP	(1 << 1)
+#define CPM_HWCR_RTC_WAKEUP	(1 << 0)
+
+/* Wakeup Status Register in Hibernate Mode */
+#define CPM_HWSR_WSR_PIN	(1 << 1)
+#define CPM_HWSR_WSR_RTC	(1 << 0)
+
+/* Reset Status Register */
+#define CPM_RSR_HR		(1 << 2)
+#define CPM_RSR_WR		(1 << 1)
+#define CPM_RSR_PR		(1 << 0)
+
+/* Register definitions */
+#define TCU_TCSR_PWM_SD		(1 << 9)
+#define TCU_TCSR_PWM_INITL_HIGH	(1 << 8)
+#define TCU_TCSR_PWM_EN		(1 << 7)
+#define TCU_TCSR_PRESCALE_BIT	3
+#define TCU_TCSR_PRESCALE_MASK	(0x7 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1	(0x0 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE4	(0x1 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE16	(0x2 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE64	(0x3 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE256	(0x4 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1024	(0x5 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_EXT_EN		(1 << 2)
+#define TCU_TCSR_RTC_EN		(1 << 1)
+#define TCU_TCSR_PCK_EN		(1 << 0)
+
+#define TCU_TER_TCEN5		(1 << 5)
+#define TCU_TER_TCEN4		(1 << 4)
+#define TCU_TER_TCEN3		(1 << 3)
+#define TCU_TER_TCEN2		(1 << 2)
+#define TCU_TER_TCEN1		(1 << 1)
+#define TCU_TER_TCEN0		(1 << 0)
+
+#define TCU_TESR_TCST5		(1 << 5)
+#define TCU_TESR_TCST4		(1 << 4)
+#define TCU_TESR_TCST3		(1 << 3)
+#define TCU_TESR_TCST2		(1 << 2)
+#define TCU_TESR_TCST1		(1 << 1)
+#define TCU_TESR_TCST0		(1 << 0)
+
+#define TCU_TECR_TCCL5		(1 << 5)
+#define TCU_TECR_TCCL4		(1 << 4)
+#define TCU_TECR_TCCL3		(1 << 3)
+#define TCU_TECR_TCCL2		(1 << 2)
+#define TCU_TECR_TCCL1		(1 << 1)
+#define TCU_TECR_TCCL0		(1 << 0)
+
+#define TCU_TFR_HFLAG5		(1 << 21)
+#define TCU_TFR_HFLAG4		(1 << 20)
+#define TCU_TFR_HFLAG3		(1 << 19)
+#define TCU_TFR_HFLAG2		(1 << 18)
+#define TCU_TFR_HFLAG1		(1 << 17)
+#define TCU_TFR_HFLAG0		(1 << 16)
+#define TCU_TFR_FFLAG5		(1 << 5)
+#define TCU_TFR_FFLAG4		(1 << 4)
+#define TCU_TFR_FFLAG3		(1 << 3)
+#define TCU_TFR_FFLAG2		(1 << 2)
+#define TCU_TFR_FFLAG1		(1 << 1)
+#define TCU_TFR_FFLAG0		(1 << 0)
+
+#define TCU_TFSR_HFLAG5		(1 << 21)
+#define TCU_TFSR_HFLAG4		(1 << 20)
+#define TCU_TFSR_HFLAG3		(1 << 19)
+#define TCU_TFSR_HFLAG2		(1 << 18)
+#define TCU_TFSR_HFLAG1		(1 << 17)
+#define TCU_TFSR_HFLAG0		(1 << 16)
+#define TCU_TFSR_FFLAG5		(1 << 5)
+#define TCU_TFSR_FFLAG4		(1 << 4)
+#define TCU_TFSR_FFLAG3		(1 << 3)
+#define TCU_TFSR_FFLAG2		(1 << 2)
+#define TCU_TFSR_FFLAG1		(1 << 1)
+#define TCU_TFSR_FFLAG0		(1 << 0)
+
+#define TCU_TFCR_HFLAG5		(1 << 21)
+#define TCU_TFCR_HFLAG4		(1 << 20)
+#define TCU_TFCR_HFLAG3		(1 << 19)
+#define TCU_TFCR_HFLAG2		(1 << 18)
+#define TCU_TFCR_HFLAG1		(1 << 17)
+#define TCU_TFCR_HFLAG0		(1 << 16)
+#define TCU_TFCR_FFLAG5		(1 << 5)
+#define TCU_TFCR_FFLAG4		(1 << 4)
+#define TCU_TFCR_FFLAG3		(1 << 3)
+#define TCU_TFCR_FFLAG2		(1 << 2)
+#define TCU_TFCR_FFLAG1		(1 << 1)
+#define TCU_TFCR_FFLAG0		(1 << 0)
+
+#define TCU_TMR_HMASK5		(1 << 21)
+#define TCU_TMR_HMASK4		(1 << 20)
+#define TCU_TMR_HMASK3		(1 << 19)
+#define TCU_TMR_HMASK2		(1 << 18)
+#define TCU_TMR_HMASK1		(1 << 17)
+#define TCU_TMR_HMASK0		(1 << 16)
+#define TCU_TMR_FMASK5		(1 << 5)
+#define TCU_TMR_FMASK4		(1 << 4)
+#define TCU_TMR_FMASK3		(1 << 3)
+#define TCU_TMR_FMASK2		(1 << 2)
+#define TCU_TMR_FMASK1		(1 << 1)
+#define TCU_TMR_FMASK0		(1 << 0)
+
+#define TCU_TMSR_HMST5		(1 << 21)
+#define TCU_TMSR_HMST4		(1 << 20)
+#define TCU_TMSR_HMST3		(1 << 19)
+#define TCU_TMSR_HMST2		(1 << 18)
+#define TCU_TMSR_HMST1		(1 << 17)
+#define TCU_TMSR_HMST0		(1 << 16)
+#define TCU_TMSR_FMST5		(1 << 5)
+#define TCU_TMSR_FMST4		(1 << 4)
+#define TCU_TMSR_FMST3		(1 << 3)
+#define TCU_TMSR_FMST2		(1 << 2)
+#define TCU_TMSR_FMST1		(1 << 1)
+#define TCU_TMSR_FMST0		(1 << 0)
+
+#define TCU_TMCR_HMCL5		(1 << 21)
+#define TCU_TMCR_HMCL4		(1 << 20)
+#define TCU_TMCR_HMCL3		(1 << 19)
+#define TCU_TMCR_HMCL2		(1 << 18)
+#define TCU_TMCR_HMCL1		(1 << 17)
+#define TCU_TMCR_HMCL0		(1 << 16)
+#define TCU_TMCR_FMCL5		(1 << 5)
+#define TCU_TMCR_FMCL4		(1 << 4)
+#define TCU_TMCR_FMCL3		(1 << 3)
+#define TCU_TMCR_FMCL2		(1 << 2)
+#define TCU_TMCR_FMCL1		(1 << 1)
+#define TCU_TMCR_FMCL0		(1 << 0)
+
+#define TCU_TSR_WDTS		(1 << 16)
+#define TCU_TSR_STOP5		(1 << 5)
+#define TCU_TSR_STOP4		(1 << 4)
+#define TCU_TSR_STOP3		(1 << 3)
+#define TCU_TSR_STOP2		(1 << 2)
+#define TCU_TSR_STOP1		(1 << 1)
+#define TCU_TSR_STOP0		(1 << 0)
+
+#define TCU_TSSR_WDTSS		(1 << 16)
+#define TCU_TSSR_STPS5		(1 << 5)
+#define TCU_TSSR_STPS4		(1 << 4)
+#define TCU_TSSR_STPS3		(1 << 3)
+#define TCU_TSSR_STPS2		(1 << 2)
+#define TCU_TSSR_STPS1		(1 << 1)
+#define TCU_TSSR_STPS0		(1 << 0)
+
+#define TCU_TSSR_WDTSC		(1 << 16)
+#define TCU_TSSR_STPC5		(1 << 5)
+#define TCU_TSSR_STPC4		(1 << 4)
+#define TCU_TSSR_STPC3		(1 << 3)
+#define TCU_TSSR_STPC2		(1 << 2)
+#define TCU_TSSR_STPC1		(1 << 1)
+#define TCU_TSSR_STPC0		(1 << 0)
+
+/* Register definition */
+#define WDT_TCSR_PRESCALE_BIT	3
+#define WDT_TCSR_PRESCALE_MASK	(0x7 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1	(0x0 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE4	(0x1 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE16	(0x2 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE64	(0x3 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE256	(0x4 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1024	(0x5 << WDT_TCSR_PRESCALE_BIT)
+#define WDT_TCSR_EXT_EN		(1 << 2)
+#define WDT_TCSR_RTC_EN		(1 << 1)
+#define WDT_TCSR_PCK_EN		(1 << 0)
+#define WDT_TCER_TCEN		(1 << 0)
+
+/*
+ * Define macros for UART_IER
+ * UART Interrupt Enable Register
+ */
+#define UART_IER_RIE	(1 << 0)	/* 0: receive fifo "full" interrupt disable */
+#define UART_IER_TIE	(1 << 1)	/* 0: transmit fifo "empty" interrupt disable */
+#define UART_IER_RLIE	(1 << 2)	/* 0: receive line status interrupt disable */
+#define UART_IER_MIE	(1 << 3)	/* 0: modem status interrupt disable */
+#define UART_IER_RTIE	(1 << 4)	/* 0: receive timeout interrupt disable */
+
+/*
+ * Define macros for UART_ISR
+ * UART Interrupt Status Register
+ */
+#define UART_ISR_IP	(1 << 0)	/* 0: interrupt is pending  1: no interrupt */
+#define UART_ISR_IID	(7 << 1)	/* Source of Interrupt */
+#define UART_ISR_IID_MSI		(0 << 1)	/* Modem status interrupt */
+#define UART_ISR_IID_THRI	(1 << 1)	/* Transmitter holding register empty */
+#define UART_ISR_IID_RDI		(2 << 1)	/* Receiver data interrupt */
+#define UART_ISR_IID_RLSI	(3 << 1)	/* Receiver line status interrupt */
+#define UART_ISR_FFMS	(3 << 6)	/* FIFO mode select, set when UART_FCR.FE is set to 1 */
+#define UART_ISR_FFMS_NO_FIFO	(0 << 6)
+#define UART_ISR_FFMS_FIFO_MODE	(3 << 6)
+
+/*
+ * Define macros for UART_FCR
+ * UART FIFO Control Register
+ */
+#define UART_FCR_FE	(1 << 0)	/* 0: non-FIFO mode  1: FIFO mode */
+#define UART_FCR_RFLS	(1 << 1)	/* write 1 to flush receive FIFO */
+#define UART_FCR_TFLS	(1 << 2)	/* write 1 to flush transmit FIFO */
+#define UART_FCR_DMS	(1 << 3)	/* 0: disable DMA mode */
+#define UART_FCR_UUE	(1 << 4)	/* 0: disable UART */
+#define UART_FCR_RTRG	(3 << 6)	/* Receive FIFO Data Trigger */
+#define UART_FCR_RTRG_1	(0 << 6)
+#define UART_FCR_RTRG_4	(1 << 6)
+#define UART_FCR_RTRG_8	(2 << 6)
+#define UART_FCR_RTRG_15	(3 << 6)
+
+/*
+ * Define macros for UART_LCR
+ * UART Line Control Register
+ */
+#define UART_LCR_WLEN	(3 << 0)	/* word length */
+#define UART_LCR_WLEN_5	(0 << 0)
+#define UART_LCR_WLEN_6	(1 << 0)
+#define UART_LCR_WLEN_7	(2 << 0)
+#define UART_LCR_WLEN_8	(3 << 0)
+#define UART_LCR_STOP	(1 << 2)	/* 0: 1 stop bit when word length is 5,6,7,8
+					   1: 1.5 stop bits when 5; 2 stop bits when 6,7,8 */
+#define UART_LCR_STOP_1	(0 << 2)	/* 0: 1 stop bit when word length is 5,6,7,8
+					   1: 1.5 stop bits when 5; 2 stop bits when 6,7,8 */
+#define UART_LCR_STOP_2	(1 << 2)	/* 0: 1 stop bit when word length is 5,6,7,8
+					   1: 1.5 stop bits when 5; 2 stop bits when 6,7,8 */
+
+#define UART_LCR_PE	(1 << 3)	/* 0: parity disable */
+#define UART_LCR_PROE	(1 << 4)	/* 0: even parity  1: odd parity */
+#define UART_LCR_SPAR	(1 << 5)	/* 0: sticky parity disable */
+#define UART_LCR_SBRK	(1 << 6)	/* write 0 normal, write 1 send break */
+#define UART_LCR_DLAB	(1 << 7)	/* 0: access UART_RDR/TDR/IER  1: access UART_DLLR/DLHR */
+
+/*
+ * Define macros for UART_LSR
+ * UART Line Status Register
+ */
+#define UART_LSR_DR	(1 << 0)	/* 0: receive FIFO is empty  1: receive data is ready */
+#define UART_LSR_ORER	(1 << 1)	/* 0: no overrun error */
+#define UART_LSR_PER	(1 << 2)	/* 0: no parity error */
+#define UART_LSR_FER	(1 << 3)	/* 0; no framing error */
+#define UART_LSR_BRK	(1 << 4)	/* 0: no break detected  1: receive a break signal */
+#define UART_LSR_TDRQ	(1 << 5)	/* 1: transmit FIFO half "empty" */
+#define UART_LSR_TEMT	(1 << 6)	/* 1: transmit FIFO and shift registers empty */
+#define UART_LSR_RFER	(1 << 7)	/* 0: no receive error  1: receive error in FIFO mode */
+
+/*
+ * Define macros for UART_MCR
+ * UART Modem Control Register
+ */
+#define UART_MCR_DTR	(1 << 0)	/* 0: DTR_ ouput high */
+#define UART_MCR_RTS	(1 << 1)	/* 0: RTS_ output high */
+#define UART_MCR_OUT1	(1 << 2)	/* 0: UART_MSR.RI is set to 0 and RI_ input high */
+#define UART_MCR_OUT2	(1 << 3)	/* 0: UART_MSR.DCD is set to 0 and DCD_ input high */
+#define UART_MCR_LOOP	(1 << 4)	/* 0: normal  1: loopback mode */
+#define UART_MCR_MCE	(1 << 7)	/* 0: modem function is disable */
+
+/*
+ * Define macros for UART_MSR
+ * UART Modem Status Register
+ */
+#define UART_MSR_DCTS	(1 << 0)	/* 0: no change on CTS_ pin since last read of UART_MSR */
+#define UART_MSR_DDSR	(1 << 1)	/* 0: no change on DSR_ pin since last read of UART_MSR */
+#define UART_MSR_DRI	(1 << 2)	/* 0: no change on RI_ pin since last read of UART_MSR */
+#define UART_MSR_DDCD	(1 << 3)	/* 0: no change on DCD_ pin since last read of UART_MSR */
+#define UART_MSR_CTS	(1 << 4)	/* 0: CTS_ pin is high */
+#define UART_MSR_DSR	(1 << 5)	/* 0: DSR_ pin is high */
+#define UART_MSR_RI	(1 << 6)	/* 0: RI_ pin is high */
+#define UART_MSR_DCD	(1 << 7)	/* 0: DCD_ pin is high */
+
+/*
+ * Define macros for SIRCR
+ * Slow IrDA Control Register
+ */
+#define SIRCR_TSIRE	(1 << 0)	/* 0: transmitter is in UART mode  1: IrDA mode */
+#define SIRCR_RSIRE	(1 << 1)	/* 0: receiver is in UART mode  1: IrDA mode */
+#define SIRCR_TPWS	(1 << 2)	/* 0: transmit 0 pulse width is 3/16 of bit length
+					   1: 0 pulse width is 1.6us for 115.2Kbps */
+#define SIRCR_TXPL	(1 << 3)	/* 0: encoder generates a positive pulse for 0 */
+#define SIRCR_RXPL	(1 << 4)	/* 0: decoder interprets positive pulse as 0 */
+
+/* MSC Clock and Control Register (MSC_STRPCL) */
+#define MSC_STRPCL_EXIT_MULTIPLE	(1 << 7)
+#define MSC_STRPCL_EXIT_TRANSFER	(1 << 6)
+#define MSC_STRPCL_START_READWAIT	(1 << 5)
+#define MSC_STRPCL_STOP_READWAIT	(1 << 4)
+#define MSC_STRPCL_RESET		(1 << 3)
+#define MSC_STRPCL_START_OP		(1 << 2)
+#define MSC_STRPCL_CLOCK_CONTROL_BIT	0
+#define MSC_STRPCL_CLOCK_CONTROL_MASK	(0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT)
+  #define MSC_STRPCL_CLOCK_CONTROL_STOP	  (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */
+  #define MSC_STRPCL_CLOCK_CONTROL_START  (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */
+
+/* MSC Status Register (MSC_STAT) */
+#define MSC_STAT_IS_RESETTING		(1 << 15)
+#define MSC_STAT_SDIO_INT_ACTIVE	(1 << 14)
+#define MSC_STAT_PRG_DONE		(1 << 13)
+#define MSC_STAT_DATA_TRAN_DONE		(1 << 12)
+#define MSC_STAT_END_CMD_RES		(1 << 11)
+#define MSC_STAT_DATA_FIFO_AFULL	(1 << 10)
+#define MSC_STAT_IS_READWAIT		(1 << 9)
+#define MSC_STAT_CLK_EN			(1 << 8)
+#define MSC_STAT_DATA_FIFO_FULL		(1 << 7)
+#define MSC_STAT_DATA_FIFO_EMPTY	(1 << 6)
+#define MSC_STAT_CRC_RES_ERR		(1 << 5)
+#define MSC_STAT_CRC_READ_ERROR		(1 << 4)
+#define MSC_STAT_CRC_WRITE_ERROR_BIT	2
+#define MSC_STAT_CRC_WRITE_ERROR_MASK	(0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT)
+  #define MSC_STAT_CRC_WRITE_ERROR_NO		(0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */
+  #define MSC_STAT_CRC_WRITE_ERROR		(1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */
+  #define MSC_STAT_CRC_WRITE_ERROR_NOSTS	(2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */
+#define MSC_STAT_TIME_OUT_RES		(1 << 1)
+#define MSC_STAT_TIME_OUT_READ		(1 << 0)
+
+/* MSC Bus Clock Control Register (MSC_CLKRT) */
+
+#define MSC_CLKRT_CLK_RATE_BIT		0
+#define MSC_CLKRT_CLK_RATE_MASK		(0x7 << MSC_CLKRT_CLK_RATE_BIT)
+  #define MSC_CLKRT_CLK_RATE_DIV_1	  (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */
+  #define MSC_CLKRT_CLK_RATE_DIV_2	  (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */
+  #define MSC_CLKRT_CLK_RATE_DIV_4	  (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */
+  #define MSC_CLKRT_CLK_RATE_DIV_8	  (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */
+  #define MSC_CLKRT_CLK_RATE_DIV_16	  (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */
+  #define MSC_CLKRT_CLK_RATE_DIV_32	  (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */
+  #define MSC_CLKRT_CLK_RATE_DIV_64	  (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */
+  #define MSC_CLKRT_CLK_RATE_DIV_128	  (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */
+
+/* MSC Command Sequence Control Register (MSC_CMDAT) */
+#define MSC_CMDAT_IO_ABORT	(1 << 11)
+#define MSC_CMDAT_BUS_WIDTH_BIT	9
+#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT)
+#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT)
+#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT)
+#define MSC_CMDAT_DMA_EN	(1 << 8)
+#define MSC_CMDAT_INIT		(1 << 7)
+#define MSC_CMDAT_BUSY		(1 << 6)
+#define MSC_CMDAT_STREAM_BLOCK	(1 << 5)
+#define MSC_CMDAT_WRITE		(1 << 4)
+#define MSC_CMDAT_READ		(0 << 4)
+#define MSC_CMDAT_DATA_EN	(1 << 3)
+#define MSC_CMDAT_RESPONSE_BIT	0
+#define MSC_CMDAT_RESPONSE_MASK	(0x7 << MSC_CMDAT_RESPONSE_BIT)
+#define MSC_CMDAT_RESPONSE_NONE	(0x0 << MSC_CMDAT_RESPONSE_BIT)
+#define MSC_CMDAT_RESPONSE_R1	(0x1 << MSC_CMDAT_RESPONSE_BIT)
+#define MSC_CMDAT_RESPONSE_R2	(0x2 << MSC_CMDAT_RESPONSE_BIT)
+#define MSC_CMDAT_RESPONSE_R3	(0x3 << MSC_CMDAT_RESPONSE_BIT)
+#define MSC_CMDAT_RESPONSE_R4	(0x4 << MSC_CMDAT_RESPONSE_BIT)
+#define MSC_CMDAT_RESPONSE_R5	(0x5 << MSC_CMDAT_RESPONSE_BIT)
+#define MSC_CMDAT_RESPONSE_R6	(0x6 << MSC_CMDAT_RESPONSE_BIT)
+
+/* MSC Interrupts Mask Register (MSC_IMASK) */
+#define MSC_IMASK_SDIO			(1 << 7)
+#define MSC_IMASK_TXFIFO_WR_REQ		(1 << 6)
+#define MSC_IMASK_RXFIFO_RD_REQ		(1 << 5)
+#define MSC_IMASK_END_CMD_RES		(1 << 2)
+#define MSC_IMASK_PRG_DONE		(1 << 1)
+#define MSC_IMASK_DATA_TRAN_DONE	(1 << 0)
+
+/* Module Operation Definitions */
+#ifndef __ASSEMBLY__
+
+/* CS1#, CLE, ALE, FRE#, FWE#, FRB#, RDWE#/BUFD# */
+#define __gpio_as_nand()			\
+do {						\
+	writel(0x02018000, GPIO_PXFUNS(1));	\
+	writel(0x02018000, GPIO_PXSELC(1));	\
+	writel(0x02018000, GPIO_PXPES(1));	\
+	writel(0x30000000, GPIO_PXFUNS(2));	\
+	writel(0x30000000, GPIO_PXSELC(2));	\
+	writel(0x30000000, GPIO_PXPES(2));	\
+	writel(0x40000000, GPIO_PXFUNC(2));	\
+	writel(0x40000000, GPIO_PXSELC(2));	\
+	writel(0x40000000, GPIO_PXDIRC(2));	\
+	writel(0x40000000, GPIO_PXPES(2));	\
+	writel(0x00400000, GPIO_PXFUNS(1));	\
+	writel(0x00400000, GPIO_PXSELC(1));	\
+} while (0)
+
+#define __gpio_as_sdram_16bit_4720()		\
+do {						\
+	writel(0x5442bfaa, GPIO_PXFUNS(0));	\
+	writel(0x5442bfaa, GPIO_PXSELC(0));	\
+	writel(0x5442bfaa, GPIO_PXPES(0));	\
+	writel(0x81f9ffff, GPIO_PXFUNS(1));	\
+	writel(0x81f9ffff, GPIO_PXSELC(1));	\
+	writel(0x81f9ffff, GPIO_PXPES(1));	\
+	writel(0x01000000, GPIO_PXFUNS(2));	\
+	writel(0x01000000, GPIO_PXSELC(2));	\
+	writel(0x01000000, GPIO_PXPES(2));	\
+} while (0)
+
+#define __gpio_as_lcd_18bit()			\
+do {						\
+	writel(0x003fffff, GPIO_PXFUNS(2));	\
+	writel(0x003fffff, GPIO_PXSELC(2));	\
+	writel(0x003fffff, GPIO_PXPES(2));	\
+} while (0)
+
+/* MSC_CMD, MSC_CLK, MSC_D0 ~ MSC_D3 */
+#define __gpio_as_msc()				\
+do {						\
+	writel(0x00003f00, GPIO_PXFUNS(3));	\
+	writel(0x00003f00, GPIO_PXSELC(3));	\
+	writel(0x00003f00, GPIO_PXPES(3));	\
+} while (0)
+
+#define __gpio_get_port(p)	(readl(GPIO_PXPIN(p)))
+
+#define __gpio_disable_pull(n)			\
+do {						\
+	unsigned int p, o;			\
+	p = (n) / 32;				\
+	o = (n) % 32;				\
+	writel((1 << o), GPIO_PXPES(p));	\
+} while (0)
+
+#define __gpio_enable_pull(n)			\
+do {						\
+	unsigned int p, o;			\
+	p = (n) / 32;				\
+	o = (n) % 32;				\
+	writel(1 << (o), GPIO_PXPEC(p));	\
+} while (0)
+
+#define __gpio_port_as_output(p, o)		\
+do {						\
+	writel(1 << (o), GPIO_PXFUNC(p));	\
+	writel(1 << (o), GPIO_PXSELC(p));	\
+	writel(1 << (o), GPIO_PXDIRS(p));	\
+} while (0)
+
+#define __gpio_port_as_input(p, o)		\
+do {						\
+	writel(1 << (o), GPIO_PXFUNC(p));	\
+	writel(1 << (o), GPIO_PXSELC(p));	\
+	writel(1 << (o), GPIO_PXDIRC(p));	\
+} while (0)
+
+#define __gpio_as_output(n)			\
+do {						\
+	unsigned int p, o;			\
+	p = (n) / 32;				\
+	o = (n) % 32;				\
+	__gpio_port_as_output(p, o);		\
+} while (0)
+
+#define __gpio_as_input(n)			\
+do {						\
+	unsigned int p, o;			\
+	p = (n) / 32;				\
+	o = (n) % 32;				\
+	__gpio_port_as_input(p, o);		\
+} while (0)
+
+#define __gpio_set_pin(n)			\
+do {						\
+	unsigned int p, o;			\
+	p = (n) / 32;				\
+	o = (n) % 32;				\
+	writel((1 << o), GPIO_PXDATS(p));	\
+} while (0)
+
+#define __gpio_clear_pin(n)			\
+do {						\
+	unsigned int p, o;			\
+	p = (n) / 32;				\
+	o = (n) % 32;				\
+	writel((1 << o), GPIO_PXDATC(p));	\
+} while (0)
+
+#define __gpio_get_pin(n)			\
+({						\
+	unsigned int p, o, v;			\
+	p = (n) / 32;				\
+	o = (n) % 32;				\
+	if (__gpio_get_port(p) & (1 << o))	\
+		v = 1;				\
+	else					\
+		v = 0;				\
+	v;					\
+})
+
+#define __gpio_as_uart0()			\
+do {						\
+	writel(0x06000000, GPIO_PXFUNS(3));	\
+	writel(0x06000000, GPIO_PXSELS(3));	\
+	writel(0x06000000, GPIO_PXPES(3));	\
+} while (0)
+
+#define __gpio_jtag_to_uart0()			\
+do {						\
+	writel(0x80000000, GPIO_PXSELS(2));	\
+} while (0)
+
+/* Clock Control Register */
+#define __cpm_get_pllm() \
+	((readl(JZ4740_CPM_BASE + 0x10) & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT)
+#define __cpm_get_plln() \
+	((readl(JZ4740_CPM_BASE + 0x10) & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT)
+#define __cpm_get_pllod() \
+	((readl(JZ4740_CPM_BASE + 0x10) & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT)
+#define __cpm_get_hdiv() \
+	((readl(JZ4740_CPM_BASE + 0x10) & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT)
+#define __cpm_get_pdiv() \
+	((readl(JZ4740_CPM_BASE + 0x10) & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT)
+#define __cpm_get_cdiv() \
+	((readl(JZ4740_CPM_BASE + 0x10) & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT)
+#define __cpm_get_mdiv() \
+	((readl(JZ4740_CPM_BASE + 0x10) & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT)
+
+static __inline__ unsigned int __cpm_get_pllout(void)
+{
+	unsigned long m, n, no, pllout;
+	unsigned long cppcr = readl(JZ4740_CPM_BASE + 0x10); //CPM_CPPCR
+	unsigned long od[4] = {1, 2, 2, 4};
+
+	if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) {
+		m = __cpm_get_pllm() + 2;
+		n = __cpm_get_plln() + 2;
+		no = od[__cpm_get_pllod()];
+		pllout = (CONFIG_SYS_EXTAL / (n * no)) * m;
+	} else
+		pllout = CONFIG_SYS_EXTAL;
+
+	return pllout;
+}
+
+/* INTC (Interrupt Controller) */
+struct jz4740_intc {
+	uint32_t isr;		/* interrupt source register */
+	uint32_t imr;		/* interrupt mask register */
+	uint32_t imsr;		/* interrupt mask set register */
+	uint32_t imcr;		/* interrupt mask clear register */
+	uint32_t ipr;		/* interrupt pending register */
+};
+
+/* RTC */
+struct jz4740_rtc {
+	uint32_t rcr;		/* rtc control register */
+	uint32_t rsr;		/* rtc second register */
+	uint32_t rsar;		/* rtc second alarm register */
+	uint32_t rgr;		/* rtc regulator register */
+	uint32_t hcr;		/* hibernate control register */
+	uint32_t hwfcr;		/* hibernate wakeup filter counter reg */
+	uint32_t hrcr;		/* hibernate reset counter reg */
+	uint32_t hwcr;		/* hibernate wakeup control register */
+	uint32_t hwrsr;		/* hibernate wakeup status reg */
+	uint32_t hspr;		/* scratch pattern register */
+};
+
+/* CPM (Clock reset and Power control Management) */
+struct jz4740_cpm {
+	uint32_t cpccr; /* 0x00 clock control reg */
+	uint32_t lcr;	/* 0x04 low power control reg */
+	uint32_t rsr;	/* 0x08 reset status reg */
+	uint32_t pad00;
+	uint32_t cppcr; /* 0x10 pll control reg */
+	uint32_t pad01[3];
+	uint32_t clkgr;	/* 0x20 clock gate reg */
+	uint32_t scr;	/* 0x24 sleep control reg */
+	uint32_t pad02[14];
+	uint32_t i2scd; /* 0x60 I2S device clock divider reg */
+	uint32_t lpcdr; /* 0x64 LCD pix clock divider reg */
+	uint32_t msccdr; /* 0x68 MSC device clock divider reg */
+	uint32_t uhccdr; /* 0x6C UHC 48M clock divider reg */
+	uint32_t uhcts; /* 0x70 UHC PHY test point reg */
+	uint32_t ssicd; /* 0x74 SSI clock divider reg */
+};
+
+/* TCU (Timer Counter Unit) */
+struct jz4740_tcu {
+	uint32_t pad00[4];
+	uint32_t ter;	/* 0x10  Timer Counter Enable Register */
+	uint32_t tesr;	/* 0x14  Timer Counter Enable Set Register */
+	uint32_t tecr;	/* 0x18  Timer Counter Enable Clear Register */
+	uint32_t tsr;	/* 0x1C  Timer Stop Register */
+	uint32_t tfr;	/* 0x20  Timer Flag Register */
+	uint32_t tfsr;	/* 0x24  Timer Flag Set Register */
+	uint32_t tfcr;	/* 0x28  Timer Flag Clear Register */
+	uint32_t tssr;	/* 0x2C  Timer Stop Set Register */
+	uint32_t tmr;	/* 0x30  Timer Mask Register */
+	uint32_t tmsr;	/* 0x34  Timer Mask Set Register */
+	uint32_t tmcr;	/* 0x38  Timer Mask Clear Register */
+	uint32_t tscr;	/* 0x3C  Timer Stop Clear Register */
+	uint32_t tdfr0;	/* 0x40  Timer Data Full Register */
+	uint32_t tdhr0;	/* 0x44  Timer Data Half Register */
+	uint32_t tcnt0;	/* 0x48  Timer Counter Register */
+	uint32_t tcsr0;	/* 0x4C  Timer Control Register */
+	uint32_t tdfr1;	/* 0x50 */
+	uint32_t tdhr1;	/* 0x54 */
+	uint32_t tcnt1;	/* 0x58 */
+	uint32_t tcsr1;	/* 0x5C */
+	uint32_t tdfr2;	/* 0x60 */
+	uint32_t tdhr2;	/* 0x64 */
+	uint32_t tcnt2;	/* 0x68 */
+	uint32_t tcsr2;	/* 0x6C */
+	uint32_t tdfr3;	/* 0x70 */
+	uint32_t tdhr3;	/* 0x74 */
+	uint32_t tcnt3;	/* 0x78 */
+	uint32_t tcsr3;	/* 0x7C */
+	uint32_t tdfr4;	/* 0x80 */
+	uint32_t tdhr4;	/* 0x84 */
+	uint32_t tcnt4;	/* 0x88 */
+	uint32_t tcsr4;	/* 0x8C */
+	uint32_t tdfr5;	/* 0x90 */
+	uint32_t tdhr5;	/* 0x94 */
+	uint32_t tcnt5;	/* 0x98 */
+	uint32_t tcsr5;	/* 0x9C */
+	uint32_t tdfr6;	/* 0xA0 */
+	uint32_t tdhr6;	/* 0xA4 */
+	uint32_t tcnt6;	/* 0xA8 */
+	uint32_t tcsr6;	/* 0xAC */
+	uint32_t tdfr7;	/* 0xB0 */
+	uint32_t tdhr7;	/* 0xB4 */
+	uint32_t tcnt7;	/* 0xB8 */
+	uint32_t tcsr7;	/* 0xBC */
+};
+
+/* WDT (WatchDog Timer) */
+struct jz4740_wdt {
+	uint16_t tdr; /* 0x00 watchdog timer data reg*/
+	uint16_t pad00;
+	uint8_t tcer; /* 0x04 watchdog counter enable reg*/
+	uint8_t pad01[3];
+	uint16_t tcnt; /* 0x08 watchdog timer counter*/
+	uint16_t pad02;
+	uint16_t tcsr; /* 0x0C watchdog timer control reg*/
+	uint16_t pad03;
+};
+
+struct jz4740_uart {
+	uint8_t rbr_thr_dllr;
+		/* 0x00 R  8b receive buffer reg */
+		/* 0x00 W  8b transmit hold reg */
+		/* 0x00 RW 8b divisor latch low reg */
+	uint8_t pad00[3];
+	uint8_t dlhr_ier;
+		/* 0x04 RW 8b divisor latch high reg */
+		/* 0x04 RW 8b interrupt enable reg */
+	uint8_t pad01[3];
+	uint8_t iir_fcr;
+		/* 0x08 R  8b interrupt identification reg */
+		/* 0x08 W  8b FIFO control reg */
+	uint8_t pad02[3];
+	uint8_t lcr;	/* 0x0C RW 8b Line control reg */
+	uint8_t pad03[3];
+	uint8_t mcr;	/* 0x10 RW 8b modem control reg */
+	uint8_t pad04[3];
+	uint8_t lsr;	/* 0x14 R  8b line status reg */
+	uint8_t pad05[3];
+	uint8_t msr;	/* 0x18 R  8b modem status reg */
+	uint8_t pad06[3];
+	uint8_t spr;	/* 0x1C RW 8b scratch pad reg */
+	uint8_t pad07[3];
+	uint8_t isr;	/* 0x20 RW 8b infrared selection reg */
+	uint8_t pad08[3];
+	uint8_t umr;	/* 0x24 RW 8b */
+};
+
+/* MSC */
+struct jz4740_msc {
+	uint16_t strpcl;/* 0x00 */
+	uint32_t stat;	/* 0x04 */
+	uint16_t clkrt;	/* 0x08 */
+	uint32_t cmdat;	/* 0x0C */
+	uint16_t resto;	/* 0x10 */
+	uint16_t rdto;	/* 0x14 */
+	uint16_t blklen;/* 0x18 */
+	uint16_t nob;	/* 0x1C */
+	uint16_t snob;	/* 0x20 */
+	uint16_t imask;	/* 0x24 */
+	uint16_t ireg;	/* 0x28 */
+	uint8_t  cmd;	/* 0x2C */
+	uint32_t arg;	/* 0x30 */
+	uint16_t res;	/* 0x34 */
+	uint32_t rxfifo;/* 0x38 */
+	uint32_t txfifo;/* 0x3C */
+};
+
+/* External Memory Controller */
+struct jz4740_emc {
+	uint32_t bcr; /* 0x00 BCR */
+	uint32_t pad00[3];
+	uint32_t smcr[5];
+		/* x10 Static Memory Control Register 0 */
+		/* x14 Static Memory Control Register 1 */
+		/* x18 Static Memory Control Register 2 */
+		/* x1c Static Memory Control Register 3 */
+		/* x20 Static Memory Control Register 4 */
+	uint32_t pad01[3];
+	uint32_t sacr[5];
+		/* x30 Static Memory Bank 0 Addr Config Reg */
+		/* x34 Static Memory Bank 1 Addr Config Reg */
+		/* x38 Static Memory Bank 2 Addr Config Reg */
+		/* x3c Static Memory Bank 3 Addr Config Reg */
+		/* x40 Static Memory Bank 4 Addr Config Reg */
+	uint32_t pad02[3];
+	uint32_t nfcsr; /* x050 NAND Flash Control/Status Register */
+
+	uint32_t pad03[11];
+	uint32_t dmcr; /* x80 DRAM Control Register */
+	uint16_t rtcsr; /* x84 Refresh Time Control/Status Register */
+	uint16_t pad04;
+	uint16_t rtcnt; /* x88 Refresh Timer Counter */
+	uint16_t pad05;
+	uint16_t rtcor; /* x8c Refresh Time Constant Register */
+	uint16_t pad06;
+	uint32_t dmar0; /* x90 SDRAM Bank 0 Addr Config Register */
+	uint32_t pad07[27];
+	uint32_t nfecr; /* x100 NAND Flash ECC Control Register */
+	uint32_t nfecc; /* x104 NAND Flash ECC Data Register */
+	uint8_t nfpar[12];
+		/* x108 NAND Flash RS Parity 0 Register */
+		/* x10c NAND Flash RS Parity 1 Register */
+		/* x110 NAND Flash RS Parity 2 Register */
+	uint32_t nfints; /* x114 NAND Flash Interrupt Status Register */
+	uint32_t nfinte; /* x118 NAND Flash Interrupt Enable Register */
+	uint32_t nferr[4];
+		/* x11c NAND Flash RS Error Report 0 Register */
+		/* x120 NAND Flash RS Error Report 1 Register */
+		/* x124 NAND Flash RS Error Report 2 Register */
+		/* x128 NAND Flash RS Error Report 3 Register */
+};
+
+extern void pll_init(void);
+extern void sdram_init(void);
+extern void calc_clocks(void);
+extern void rtc_init(void);
+
+#endif	/* !__ASSEMBLY__ */
+#endif	/* __JZ4740_H__ */
-- 
1.7.5.4

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

* [U-Boot] [PATCH v7 2/3] MIPS: Jz4740: Add NAND driver
  2011-10-02 13:52 [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Shinya Kuribayashi
  2011-10-02 13:54 ` [U-Boot] [PATCH v7 1/3] MIPS: Ingenic XBurst Jz4740 processor support Shinya Kuribayashi
@ 2011-10-02 13:56 ` Shinya Kuribayashi
  2011-10-06 21:12   ` Wolfgang Denk
  2011-10-02 13:56 ` [U-Boot] [PATCH v7 3/3] MIPS: JZ4740: Add qi_lb60 board support Shinya Kuribayashi
  2011-10-02 15:08 ` [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Xiangfu Liu
  3 siblings, 1 reply; 8+ messages in thread
From: Shinya Kuribayashi @ 2011-10-02 13:56 UTC (permalink / raw)
  To: u-boot

From: Xiangfu Liu <xiangfu@openmobilefree.net>
Date: Fri, 19 Aug 2011 14:35:29 +0800

Jz4740 NAND flash controller can support:
* MLC NAND as well as SLC NAND
* all 8-bit/16-bit NAND flash devices
* HAMMING and RS hardware ECC
* automatic boot up from NAND flash devices

nand_ecclayout is set up for 2GiB NAND chip mounted in Qi LB60.
We'll bring up boot-from-NAND support in nand_spl/ in the future.

Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net>
Acked-by: Daniel <zpxu@ingenic.cn>
Signed-off-by: Shinya Kuribayashi <skuribay@pobox.com>
---

Changes since v6:

* Remove NAND-boot stuff.  Those bits will be submitted as a nand-spl
  support once this Jz4740 base support is merged.

* All previous comments from Scott are fixed.

* Bunch of coding style issues fixed.

 drivers/mtd/nand/Makefile      |    1 +
 drivers/mtd/nand/jz4740_nand.c |  261 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 262 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/jz4740_nand.c

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b6a7886..c257128 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
 COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
 COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
+COBJS-$(CONFIG_NAND_JZ4740) += jz4740_nand.o
 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
 COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
new file mode 100644
index 0000000..db50da3
--- /dev/null
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -0,0 +1,261 @@
+/*
+ * Platform independend driver for JZ4740.
+ *
+ * Copyright (c) 2007 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * 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.
+ */
+#include <common.h>
+
+#include <nand.h>
+#include <asm/io.h>
+#include <asm/jz4740.h>
+
+#define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000)
+#define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000)
+#define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000)
+
+#define BIT(x) (1 << (x))
+#define JZ_NAND_ECC_CTRL_ENCODING	BIT(3)
+#define JZ_NAND_ECC_CTRL_RS		BIT(2)
+#define JZ_NAND_ECC_CTRL_RESET		BIT(1)
+#define JZ_NAND_ECC_CTRL_ENABLE		BIT(0)
+
+#define EMC_SMCR1_OPT_NAND	0x094c4400
+/* Optimize the timing of nand */
+
+static struct jz4740_emc * emc = (struct jz4740_emc *)JZ4740_EMC_BASE;
+
+static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
+	.eccbytes = 72,
+	.eccpos = {
+		12, 13, 14, 15, 16, 17, 18, 19,
+		20, 21, 22, 23, 24, 25, 26, 27,
+		28, 29, 30, 31, 32, 33, 34, 35,
+		36, 37, 38, 39, 40, 41, 42, 43,
+		44, 45, 46, 47, 48, 49, 50, 51,
+		52, 53, 54, 55, 56, 57, 58, 59,
+		60, 61, 62, 63, 64, 65, 66, 67,
+		68, 69, 70, 71, 72, 73, 74, 75,
+		76, 77, 78, 79, 80, 81, 82, 83 },
+	.oobfree = {
+		{.offset = 2,
+		 .length = 10 },
+		{.offset = 84,
+		 .length = 44 } }
+};
+
+static int is_reading;
+
+static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	uint32_t reg;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_ALE)
+			this->IO_ADDR_W = JZ_NAND_ADDR_ADDR;
+		else if (ctrl & NAND_CLE)
+			this->IO_ADDR_W = JZ_NAND_CMD_ADDR;
+		else
+			this->IO_ADDR_W = JZ_NAND_DATA_ADDR;
+
+		reg = readl(&emc->nfcsr);
+		if (ctrl & NAND_NCE)
+			reg |= EMC_NFCSR_NFCE1;
+		else
+			reg &= ~EMC_NFCSR_NFCE1;
+		writel(reg, &emc->nfcsr);
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
+}
+
+static int jz_nand_device_ready(struct mtd_info *mtd)
+{
+	return (readl(GPIO_PXPIN(2)) & 0x40000000) ? 1 : 0;
+}
+
+void board_nand_select_device(struct nand_chip *nand, int chip)
+{
+	/*
+	 * Don't use "chip" to address the NAND device,
+	 * generate the cs from the address where it is encoded.
+	 */
+}
+
+static int jz_nand_rs_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
+				u_char* ecc_code)
+{
+	uint32_t status;
+	int i;
+
+	if (is_reading)
+		return 0;
+
+	do {
+		status = readl(&emc->nfints);
+	} while (!(status & EMC_NFINTS_ENCF));
+
+	/* disable ecc */
+	writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr);
+
+	for (i = 0; i < 9; i++)
+		ecc_code[i] = readb(&emc->nfpar[i]);
+
+	return 0;
+}
+
+static void jz_nand_hwctl(struct mtd_info* mtd, int mode)
+{
+	uint32_t reg;
+
+	writel(0, &emc->nfints);
+	reg = readl(&emc->nfecr);
+	reg |= JZ_NAND_ECC_CTRL_RESET;
+	reg |= JZ_NAND_ECC_CTRL_ENABLE;
+	reg |= JZ_NAND_ECC_CTRL_RS;
+
+	switch (mode) {
+	case NAND_ECC_READ:
+		reg &= ~JZ_NAND_ECC_CTRL_ENCODING;
+		is_reading = 1;
+		break;
+	case NAND_ECC_WRITE:
+		reg |= JZ_NAND_ECC_CTRL_ENCODING;
+		is_reading = 0;
+		break;
+	default:
+		break;
+	}
+
+	writel(reg, &emc->nfecr);
+}
+
+/* Correct 1~9-bit errors in 512-bytes data */
+static void jz_rs_correct(unsigned char *dat, int idx, int mask)
+{
+	int i;
+
+	idx--;
+
+	i = idx + (idx >> 3);
+	if (i >= 512)
+		return;
+
+	mask <<= (idx & 0x7);
+
+	dat[i] ^= mask & 0xff;
+	if (i < 511)
+		dat[i + 1] ^= (mask >> 8) & 0xff;
+}
+
+static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+				   u_char *read_ecc, u_char *calc_ecc)
+{
+	int k;
+	uint32_t errcnt, index, mask, status;
+
+	/* Set PAR values */
+	const uint8_t all_ff_ecc[] =
+		{0xcd, 0x9d, 0x90, 0x58, 0xf4, 0x8b, 0xff, 0xb7, 0x6f};
+
+	if (read_ecc[0] == 0xff && read_ecc[1] == 0xff &&
+	    read_ecc[2] == 0xff && read_ecc[3] == 0xff &&
+	    read_ecc[4] == 0xff && read_ecc[5] == 0xff &&
+	    read_ecc[6] == 0xff && read_ecc[7] == 0xff &&
+	    read_ecc[8] == 0xff) {
+		for (k = 0; k < 9; k++)
+			writeb(all_ff_ecc[k], &emc->nfpar[k]);
+	} else {
+		for (k = 0; k < 9; k++)
+			writeb(read_ecc[k], &emc->nfpar[k]);
+	}
+	/* Set PRDY */
+	writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr);
+
+	/* Wait for completion */
+	do {
+		status = readl(&emc->nfints);
+	} while (!(status & EMC_NFINTS_DECF));
+
+	/* disable ecc */
+	writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr);
+
+	/* Check decoding */
+	if (!(status & EMC_NFINTS_ERR))
+		return 0;
+
+	if (status & EMC_NFINTS_UNCOR) {
+		printf("uncorrectable ecc\n");
+		return -1;
+	}
+
+	errcnt = (status & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
+
+	switch (errcnt) {
+	case 4:
+		index = (readl(&emc->nferr[3]) & EMC_NFERR_INDEX_MASK) >>
+			EMC_NFERR_INDEX_BIT;
+		mask = (readl(&emc->nferr[3]) & EMC_NFERR_MASK_MASK) >>
+			EMC_NFERR_MASK_BIT;
+		jz_rs_correct(dat, index, mask);
+	case 3:
+		index = (readl(&emc->nferr[2]) & EMC_NFERR_INDEX_MASK) >>
+			EMC_NFERR_INDEX_BIT;
+		mask = (readl(&emc->nferr[2]) & EMC_NFERR_MASK_MASK) >>
+			EMC_NFERR_MASK_BIT;
+		jz_rs_correct(dat, index, mask);
+	case 2:
+		index = (readl(&emc->nferr[1]) & EMC_NFERR_INDEX_MASK) >>
+			EMC_NFERR_INDEX_BIT;
+		mask = (readl(&emc->nferr[1]) & EMC_NFERR_MASK_MASK) >>
+			EMC_NFERR_MASK_BIT;
+		jz_rs_correct(dat, index, mask);
+	case 1:
+		index = (readl(&emc->nferr[0]) & EMC_NFERR_INDEX_MASK) >>
+			EMC_NFERR_INDEX_BIT;
+		mask = (readl(&emc->nferr[0]) & EMC_NFERR_MASK_MASK) >>
+			EMC_NFERR_MASK_BIT;
+		jz_rs_correct(dat, index, mask);
+	default:
+		break;
+	}
+
+	return errcnt;
+}
+
+/*
+ * Main initialization routine
+ */
+int board_nand_init(struct nand_chip *nand)
+{
+	uint32_t reg;
+
+	reg = readl(&emc->nfcsr);
+	reg |= EMC_NFCSR_NFE1;	/* EMC setup, Set NFE bit */
+	writel(reg, &emc->nfcsr);
+
+	writel(EMC_SMCR1_OPT_NAND, &emc->smcr[1]);
+
+	nand->IO_ADDR_R		= JZ_NAND_DATA_ADDR;
+	nand->IO_ADDR_W		= JZ_NAND_DATA_ADDR;
+	nand->cmd_ctrl		= jz_nand_cmd_ctrl;
+	nand->dev_ready		= jz_nand_device_ready;
+	nand->ecc.hwctl		= jz_nand_hwctl;
+	nand->ecc.correct	= jz_nand_rs_correct_data;
+	nand->ecc.calculate	= jz_nand_rs_calculate_ecc;
+	nand->ecc.mode		= NAND_ECC_HW_OOB_FIRST;
+	nand->ecc.size		= CONFIG_SYS_NAND_ECCSIZE;
+	nand->ecc.bytes		= CONFIG_SYS_NAND_ECCBYTES;
+	nand->ecc.layout	= &qi_lb60_ecclayout_2gb;
+	nand->chip_delay	= 50;
+	nand->options		= NAND_USE_FLASH_BBT;
+
+	return 0;
+}
-- 
1.7.5.4

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

* [U-Boot] [PATCH v7 3/3] MIPS: JZ4740: Add qi_lb60 board support
  2011-10-02 13:52 [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Shinya Kuribayashi
  2011-10-02 13:54 ` [U-Boot] [PATCH v7 1/3] MIPS: Ingenic XBurst Jz4740 processor support Shinya Kuribayashi
  2011-10-02 13:56 ` [U-Boot] [PATCH v7 2/3] MIPS: Jz4740: Add NAND driver Shinya Kuribayashi
@ 2011-10-02 13:56 ` Shinya Kuribayashi
  2011-10-06 21:11   ` Wolfgang Denk
  2011-10-02 15:08 ` [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Xiangfu Liu
  3 siblings, 1 reply; 8+ messages in thread
From: Shinya Kuribayashi @ 2011-10-02 13:56 UTC (permalink / raw)
  To: u-boot

From: Xiangfu Liu <xiangfu@openmobilefree.net>
Date: Fri, 19 Aug 2011 14:35:29 +0800

Add support for the qi_lb60 (a.k.a QI Ben NanoNote) clamshell device
from Qi hardware:

http://en.qi-hardware.com/wiki/Ben_NanoNote
http://en.qi-hardware.com/wiki/Main_Page
http://en.wikipedia.org/wiki/Qi_hardware

This Jz4740-based clamshell device does not use NOR flash to boot.
The initial bring-up assumes that U-Boot is directly loaded into SDRAM
using USB boot tool, and starts from 0x80100000.

About USB boot tool
-------------------

Jz4740 is one of the XBurst processors with USB boot functionality
supported.  The CPU can boot from a small ROM in the LSI, initialize
CPU and USB module, then wait for USB commands from the USB host.
We can send 8 KB binary data to the CPU cache using USB boot tool.

USB boot tool is available to the public at Ingenic website.  Also
there is an alternative Debian package named xburst-tools.

Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net>
Acked-by: Daniel <zpxu@ingenic.cn>
Signed-off-by: Shinya Kuribayashi <skuribay@pobox.com>
---

Changes since v6:

* <nanonote.h> config files is folded into <qi_lb60.h>

* Following configs are deleted:
  CONFIG_SYS_64BIT_VSPRINTF
  CONFIG_NANDBOOT_CFG
  CONFIG_QI_LB60

 MAINTAINERS                 |    4 +
 MAKEALL                     |    4 +-
 board/qi/qi_lb60/Makefile   |   45 +++++++++
 board/qi/qi_lb60/config.mk  |   31 +++++++
 board/qi/qi_lb60/qi_lb60.c  |  104 +++++++++++++++++++++
 board/qi/qi_lb60/u-boot.lds |   61 +++++++++++++
 boards.cfg                  |    1 +
 include/configs/qi_lb60.h   |  210 +++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 459 insertions(+), 1 deletions(-)
 create mode 100644 board/qi/qi_lb60/Makefile
 create mode 100644 board/qi/qi_lb60/config.mk
 create mode 100644 board/qi/qi_lb60/qi_lb60.c
 create mode 100644 board/qi/qi_lb60/u-boot.lds
 create mode 100644 include/configs/qi_lb60.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 3ab38fa..bb95e6d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -928,6 +928,10 @@ Stefan Roese <sr@denx.de>
 
 	vct_xxx		MIPS32 4Kc
 
+Xiangfu Liu <xiangfu@openmobilefree.net>
+
+	qi_lb60		MIPS32 (XBurst Jz4740 SoC)
+
 #########################################################################
 # Nios-II Systems:							#
 #									#
diff --git a/MAKEALL b/MAKEALL
index 4d18c11..f57d47d 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -400,7 +400,9 @@ LIST_mips="		\
 ## MIPS Systems		(little endian)
 #########################################################################
 
-LIST_mips4kc_el=""
+LIST_mips4kc_el="	\
+	qi_lb60		\
+"
 
 LIST_mips5kc_el=""
 
diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
new file mode 100644
index 0000000..2f5b4be
--- /dev/null
+++ b/board/qi/qi_lb60/Makefile
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2006
+# Ingenic Semiconductor, <jlwei@ingenic.cn>
+#
+# 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
+
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= $(BOARD).o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/qi/qi_lb60/config.mk b/board/qi/qi_lb60/config.mk
new file mode 100644
index 0000000..858e6a2
--- /dev/null
+++ b/board/qi/qi_lb60/config.mk
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2006 Qi Hardware, Inc.
+# Author: Xiangfu Liu <xiangfu.z@gmail.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
+#
+
+#
+# Qi Hardware, Inc. Ben NanoNote (QI_LB60)
+#
+
+ifndef TEXT_BASE
+# ROM version
+# TEXT_BASE = 0x88000000
+
+# RAM version
+TEXT_BASE = 0x80100000
+endif
diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
new file mode 100644
index 0000000..01d9c3b
--- /dev/null
+++ b/board/qi/qi_lb60/qi_lb60.c
@@ -0,0 +1,104 @@
+/*
+ * Authors: Xiangfu Liu <xiangfu@sharism.cc>
+ *
+ * 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
+ * 3 of the License, or (at your option) any later version.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/jz4740.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void gpio_init(void)
+{
+	unsigned int i;
+
+	/* Initialize NAND Flash Pins */
+	__gpio_as_nand();
+
+	/* Initialize SDRAM pins */
+	__gpio_as_sdram_16bit_4720();
+
+	/* Initialize LCD pins */
+	__gpio_as_lcd_18bit();
+
+	/* Initialize MSC pins */
+	__gpio_as_msc();
+
+	/* Initialize Other pins */
+	for (i = 0; i < 7; i++){
+		__gpio_as_input(GPIO_KEYIN_BASE + i);
+		__gpio_enable_pull(GPIO_KEYIN_BASE + i);
+	}
+
+	for (i = 0; i < 8; i++) {
+		__gpio_as_output(GPIO_KEYOUT_BASE + i);
+		__gpio_clear_pin(GPIO_KEYOUT_BASE + i);
+	}
+
+	__gpio_as_input(GPIO_KEYIN_8);
+	__gpio_enable_pull(GPIO_KEYIN_8);
+
+	/* enable the TP4, TP5 as UART0 */
+	__gpio_jtag_to_uart0();
+
+	__gpio_as_output(GPIO_AUDIO_POP);
+	__gpio_set_pin(GPIO_AUDIO_POP);
+
+	__gpio_as_output(GPIO_LCD_CS);
+	__gpio_clear_pin(GPIO_LCD_CS);
+
+	__gpio_as_output(GPIO_AMP_EN);
+	__gpio_clear_pin(GPIO_AMP_EN);
+
+	__gpio_as_output(GPIO_SDPW_EN);
+	__gpio_disable_pull(GPIO_SDPW_EN);
+	__gpio_clear_pin(GPIO_SDPW_EN);
+
+	__gpio_as_input(GPIO_SD_DETECT);
+	__gpio_disable_pull(GPIO_SD_DETECT);
+
+	__gpio_as_input(GPIO_USB_DETECT);
+	__gpio_enable_pull(GPIO_USB_DETECT);
+}
+
+static void cpm_init(void)
+{
+	struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE;
+	uint32_t reg = readl(&cpm->clkgr);
+
+	reg |=	CPM_CLKGR_IPU |
+		CPM_CLKGR_CIM |
+		CPM_CLKGR_I2C |
+		CPM_CLKGR_SSI |
+		CPM_CLKGR_UART1 |
+		CPM_CLKGR_SADC |
+		CPM_CLKGR_UHC |
+		CPM_CLKGR_UDC |
+		CPM_CLKGR_AIC1;
+
+	writel(reg, &cpm->clkgr);
+}
+
+int board_early_init_f(void)
+{
+	gpio_init();
+	cpm_init();
+	calc_clocks();	/* calc the clocks */
+	rtc_init();	/* init rtc on any reset */
+
+	return 0;
+}
+
+/* U-Boot common routines */
+int checkboard(void)
+{
+	printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %ld MHz)\n",
+	       gd->cpu_clk / 1000000);
+
+	return 0;
+}
diff --git a/board/qi/qi_lb60/u-boot.lds b/board/qi/qi_lb60/u-boot.lds
new file mode 100644
index 0000000..7317652
--- /dev/null
+++ b/board/qi/qi_lb60/u-boot.lds
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2006
+ * Ingenic Semiconductor, <jlwei@ingenic.cn>
+ *
+ * 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
+ */
+
+OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
+
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text :
+	{
+	  *(.text*)
+	}
+
+	. = ALIGN(4);
+	.rodata  : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+	. = ALIGN(4);
+	.data  : { *(.data*) }
+
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
+
+	__got_start = .;
+	.got  : { *(.got) }
+	__got_end = .;
+
+	.sdata  : { *(.sdata*) }
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	uboot_end_data = .;
+	num_got_entries = (__got_end - __got_start) >> 2;
+
+	. = ALIGN(4);
+	.sbss  : { *(.sbss*) }
+	.bss  : { *(.bss*) . = ALIGN(4); }
+	uboot_end = .;
+}
diff --git a/boards.cfg b/boards.cfg
index e5cb91b..c21c4b3 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -298,6 +298,7 @@ vct_platinumavc              mips        mips32      vct                 microna
 vct_platinumavc_small        mips        mips32      vct                 micronas       -           vct:VCT_PLATINUMAVC,VCT_SMALL_IMAGE
 vct_platinumavc_onenand      mips        mips32      vct                 micronas       -           vct:VCT_PLATINUMAVC,VCT_ONENAND
 vct_platinumavc_onenand_small mips       mips32      vct                 micronas       -           vct:VCT_PLATINUMAVC,VCT_ONENAND,VCT_SMALL_IMAGE
+qi_lb60                      mips        xburst      qi_lb60             qi
 nios2-generic                nios2       nios2       nios2-generic       altera
 PCI5441                      nios2       nios2       pci5441             psyent
 PK1C20                       nios2       nios2       pk1c20              psyent
diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
new file mode 100644
index 0000000..9e3c319
--- /dev/null
+++ b/include/configs/qi_lb60.h
@@ -0,0 +1,210 @@
+/*
+ * Authors: Xiangfu Liu <xiangfu.z@gmail.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
+ * 3 of the License, or (at your option) any later version.
+ */
+
+#ifndef __CONFIG_QI_LB60_H
+#define __CONFIG_QI_LB60_H
+
+#define CONFIG_MIPS32		/* MIPS32 CPU core */
+#define CONFIG_JZSOC		/* Jz SoC */
+#define CONFIG_JZ4740		/* Jz4740 SoC */
+#define CONFIG_NAND_JZ4740
+
+#define CONFIG_SYS_CPU_SPEED	336000000	/* CPU clock: 336 MHz */
+#define CONFIG_SYS_EXTAL	12000000	/* EXTAL freq: 12 MHz */
+#define CONFIG_SYS_HZ		(CONFIG_SYS_EXTAL / 256) /* incrementer freq */
+#define CONFIG_SYS_MIPS_TIMER_FREQ	CONFIG_SYS_CPU_SPEED
+
+#define CONFIG_SYS_UART_BASE	JZ4740_UART0_BASE	/* Base of the UART channel */
+#define CONFIG_BAUDRATE		57600
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_SYS_FLASH_BASE	0 /* init flash_base as 0 */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BOOTP_MASK	(CONFIG_BOOTP_DEFAUL)
+#define CONFIG_BOOTDELAY	0
+
+/*
+ * Command line configuration.
+ */
+#define CONFIG_CMD_BOOTD	/* bootd			*/
+#define CONFIG_CMD_CONSOLE	/* coninfo			*/
+#define CONFIG_CMD_ECHO		/* echo arguments		*/
+
+#define CONFIG_CMD_LOADB	/* loadb			*/
+#define CONFIG_CMD_LOADS	/* loads			*/
+#define CONFIG_CMD_MEMORY	/* md mm nm mw cp cmp crc base loop mtest */
+#define CONFIG_CMD_MISC		/* Misc functions like sleep etc*/
+#define CONFIG_CMD_RUN		/* run command in env variable	*/
+#define CONFIG_CMD_SAVEENV	/* saveenv			*/
+#define CONFIG_CMD_SETGETDCR	/* DCR support on 4xx		*/
+#define CONFIG_CMD_SOURCE	/* "source" command support	*/
+#define CONFIG_CMD_NAND
+
+/*
+ * Serial download configuration
+ */
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP		/* undef to save memory */
+#define CONFIG_SYS_PROMPT		"NanoNote# "	/* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE		256	/* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+/* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS		16	/* max number of command args*/
+
+#define CONFIG_SYS_MALLOC_LEN		(4 * 1024 * 1024)
+#define CONFIG_SYS_BOOTPARAMS_LEN	(128 * 1024)
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000     /* Cached addr */
+#define CONFIG_SYS_INIT_SP_OFFSET	0x400000
+#define CONFIG_SYS_LOAD_ADDR		0x80600000     /* default load address */
+#define CONFIG_SYS_MEMTEST_START	0x80100000
+#define CONFIG_SYS_MEMTEST_END		0x80800000
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_IS_IN_NAND		/* use NAND for environment vars */
+
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+/*
+ * if board nand flash is 1GB, set to 1
+ * if board nand flash is 2GB, set to 2
+ * for change the PAGE_SIZE and BLOCK_SIZE
+ * will delete when there is no 1GB flash
+ */
+#define NANONOTE_NAND_SIZE	2
+
+#define CONFIG_SYS_NAND_PAGE_SIZE	(2048 * NANONOTE_NAND_SIZE)
+/* nand chip block size	*/
+#define CONFIG_SYS_NAND_BLOCK_SIZE	(256 * NANONOTE_NAND_SIZE << 10)
+/* nand bad block was marked@this page in a block, start from 0 */
+#define CONFIG_SYS_NAND_BADBLOCK_PAGE	127
+#define CONFIG_SYS_NAND_PAGE_COUNT	128
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS	0
+/* ECC offset position in oob area, default value is 6 if it isn't defined */
+#define CONFIG_SYS_NAND_ECC_POS		(6 * NANONOTE_NAND_SIZE)
+#define CONFIG_SYS_NAND_ECCSIZE		512
+#define CONFIG_SYS_NAND_ECCBYTES	9
+#define CONFIG_SYS_NAND_ECCSTEPS	(CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
+#define CONFIG_SYS_NAND_ECCTOTAL	(CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
+#define CONFIG_SYS_NAND_ECCPOS		\
+		{12, 13, 14, 15, 16, 17, 18, 19,\
+		20, 21, 22, 23, 24, 25, 26, 27, \
+		28, 29, 30, 31, 32, 33, 34, 35, \
+		36, 37, 38, 39, 40, 41, 42, 43, \
+		44, 45, 46, 47, 48, 49, 50, 51, \
+		52, 53, 54, 55, 56, 57, 58, 59, \
+		60, 61, 62, 63, 64, 65, 66, 67, \
+		68, 69, 70, 71, 72, 73, 74, 75, \
+		76, 77, 78, 79, 80, 81, 82, 83}
+
+#define CONFIG_SYS_NAND_OOBSIZE		128
+#define CONFIG_SYS_NAND_BASE		0xB8000000
+#define CONFIG_SYS_ONENAND_BASE		CONFIG_SYS_NAND_BASE
+#define NAND_MAX_CHIPS			1
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_SELECT_DEVICE	1 /* nand driver supports mutipl.*/
+#define CONFIG_NAND_SPL_TEXT_BASE	0x80000000
+
+/*
+ * IPL (Initial Program Loader, integrated inside CPU)
+ * Will load first 8k from NAND (SPL) into cache and execute it from there.
+ *
+ * SPL (Secondary Program Loader)
+ * Will load special U-Boot version (NUB) from NAND and execute it. This SPL
+ * has to fit into 8kByte. It sets up the CPU and configures the SDRAM
+ * controller and the NAND controller so that the special U-Boot image can be
+ * loaded from NAND to SDRAM.
+ *
+ * NUB (NAND U-Boot)
+ * This NAND U-Boot (NUB) is a special U-Boot version which can be started
+ * from RAM. Therefore it mustn't (re-)configure the SDRAM controller.
+ *
+ */
+#define CONFIG_SYS_NAND_U_BOOT_DST	0x80100000	/* Load NUB to this addr */
+#define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_NAND_U_BOOT_DST
+/* Start NUB from this addr*/
+
+/*
+ * Define the partitioning of the NAND chip (only RAM U-Boot is needed here)
+ */
+#define CONFIG_SYS_NAND_U_BOOT_OFFS	(256 << 10)	/* Offset to RAM U-Boot image */
+#define CONFIG_SYS_NAND_U_BOOT_SIZE	(512 << 10)	/* Size of RAM U-Boot image */
+
+#define CONFIG_ENV_SIZE		(4 << 10)
+#define CONFIG_ENV_OFFSET	(CONFIG_SYS_NAND_BLOCK_SIZE + CONFIG_SYS_NAND_U_BOOT_SIZE)
+#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET  + CONFIG_SYS_NAND_BLOCK_SIZE)
+
+#define CONFIG_SYS_TEXT_BASE	0x80100000
+#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE
+
+/*
+ * SDRAM Info.
+ */
+#define CONFIG_NR_DRAM_BANKS	1
+
+/*
+ * Cache Configuration
+ */
+#define CONFIG_SYS_DCACHE_SIZE	16384
+#define CONFIG_SYS_ICACHE_SIZE	16384
+#define CONFIG_SYS_CACHELINE_SIZE	32
+
+/*
+ * GPIO definition
+ */
+#define GPIO_LCD_CS	(2 * 32 + 21)
+#define GPIO_AMP_EN	(3 * 32 + 4)
+
+#define GPIO_SDPW_EN	(3 * 32 + 2)
+#define GPIO_SD_DETECT	(3 * 32 + 0)
+
+#define GPIO_BUZZ_PWM	(3 * 32 + 27)
+#define GPIO_USB_DETECT	(3 * 32 + 28)
+
+#define GPIO_AUDIO_POP	(1 * 32 + 29)
+#define GPIO_COB_TEST	(1 * 32 + 30)
+
+#define GPIO_KEYOUT_BASE	(2 * 32 + 10)
+#define GPIO_KEYIN_BASE	(3 * 32 + 18)
+#define GPIO_KEYIN_8	(3 * 32 + 26)
+
+#define GPIO_SD_CD_N	GPIO_SD_DETECT		/* SD Card insert detect */
+#define GPIO_SD_VCC_EN_N	GPIO_SDPW_EN	/* SD Card Power Enable */
+
+#define SPEN	GPIO_LCD_CS	/* LCDCS :Serial command enable      */
+#define SPDA	(2 * 32 + 22)	/* LCDSCL:Serial command clock input */
+#define SPCK	(2 * 32 + 23)	/* LCDSDA:Serial command data input  */
+
+#define CONFIG_BOOTARGS	"mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
+#define CONFIG_BOOTCOMMAND	"nand read 0x80600000 0x400000 0x200000;bootm"
+
+/* SDRAM paramters */
+#define SDRAM_BW16		1	/* Data bus width: 0-32bit, 1-16bit */
+#define SDRAM_BANK4		1	/* Banks each chip: 0-2bank, 1-4bank */
+#define SDRAM_ROW		13	/* Row address: 11 to 13 */
+#define SDRAM_COL		9	/* Column address: 8 to 12 */
+#define SDRAM_CASL		2	/* CAS latency: 2 or 3 */
+
+/* SDRAM Timings, unit: ns */
+#define SDRAM_TRAS		45	/* RAS# Active Time */
+#define SDRAM_RCD		20	/* RAS# to CAS# Delay */
+#define SDRAM_TPC		20	/* RAS# Precharge Time */
+#define SDRAM_TRWL		7	/* Write Latency Time */
+#define SDRAM_TREF		15625	/* Refresh period: 8192 cycles/64ms */
+
+#endif
-- 
1.7.5.4

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

* [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board
  2011-10-02 13:52 [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Shinya Kuribayashi
                   ` (2 preceding siblings ...)
  2011-10-02 13:56 ` [U-Boot] [PATCH v7 3/3] MIPS: JZ4740: Add qi_lb60 board support Shinya Kuribayashi
@ 2011-10-02 15:08 ` Xiangfu Liu
  3 siblings, 0 replies; 8+ messages in thread
From: Xiangfu Liu @ 2011-10-02 15:08 UTC (permalink / raw)
  To: u-boot

On 10/02/2011 09:52 PM, Shinya Kuribayashi wrote:
> Hi,
>
> Here's seventh patchset for Ben NanoNote initial support.  I've been
> working with Xiangfu past six months to polish v6 patches.  We have
> addressed all comments from Wolfgang and Scott so far, drop nand_spl
> and USB_boot functions to make the initial bring-up minimum and simple.
>
> I think the patchset is now in good shape, so will merge and make a
> pull-request during this merge window.  Please give it a final review
> and if something to fix, please let us know.
>

thanks Shinya.

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

* [U-Boot] [PATCH v7 3/3] MIPS: JZ4740: Add qi_lb60 board support
  2011-10-02 13:56 ` [U-Boot] [PATCH v7 3/3] MIPS: JZ4740: Add qi_lb60 board support Shinya Kuribayashi
@ 2011-10-06 21:11   ` Wolfgang Denk
  0 siblings, 0 replies; 8+ messages in thread
From: Wolfgang Denk @ 2011-10-06 21:11 UTC (permalink / raw)
  To: u-boot

Dear Shinya Kuribayashi,

In message <4E886DA5.1010806@pobox.com> you wrote:
> From: Xiangfu Liu <xiangfu@openmobilefree.net>
> Date: Fri, 19 Aug 2011 14:35:29 +0800
> 
> Add support for the qi_lb60 (a.k.a QI Ben NanoNote) clamshell device
> from Qi hardware:
> 
> http://en.qi-hardware.com/wiki/Ben_NanoNote
> http://en.qi-hardware.com/wiki/Main_Page
> http://en.wikipedia.org/wiki/Qi_hardware
> 
> This Jz4740-based clamshell device does not use NOR flash to boot.
> The initial bring-up assumes that U-Boot is directly loaded into SDRAM
> using USB boot tool, and starts from 0x80100000.
> 
> About USB boot tool
> -------------------
> 
> Jz4740 is one of the XBurst processors with USB boot functionality
> supported.  The CPU can boot from a small ROM in the LSI, initialize
> CPU and USB module, then wait for USB commands from the USB host.
> We can send 8 KB binary data to the CPU cache using USB boot tool.
> 
> USB boot tool is available to the public at Ingenic website.  Also
> there is an alternative Debian package named xburst-tools.
> 
> Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net>
> Acked-by: Daniel <zpxu@ingenic.cn>
> Signed-off-by: Shinya Kuribayashi <skuribay@pobox.com>
> ---
> 
> Changes since v6:
> 
> * <nanonote.h> config files is folded into <qi_lb60.h>
> 
> * Following configs are deleted:
>   CONFIG_SYS_64BIT_VSPRINTF
>   CONFIG_NANDBOOT_CFG
>   CONFIG_QI_LB60
> 
>  MAINTAINERS                 |    4 +
>  MAKEALL                     |    4 +-
>  board/qi/qi_lb60/Makefile   |   45 +++++++++
>  board/qi/qi_lb60/config.mk  |   31 +++++++
>  board/qi/qi_lb60/qi_lb60.c  |  104 +++++++++++++++++++++
>  board/qi/qi_lb60/u-boot.lds |   61 +++++++++++++
>  boards.cfg                  |    1 +
>  include/configs/qi_lb60.h   |  210 +++++++++++++++++++++++++++++++++++++++++++
>  8 files changed, 459 insertions(+), 1 deletions(-)
>  create mode 100644 board/qi/qi_lb60/Makefile
>  create mode 100644 board/qi/qi_lb60/config.mk
>  create mode 100644 board/qi/qi_lb60/qi_lb60.c
>  create mode 100644 board/qi/qi_lb60/u-boot.lds
>  create mode 100644 include/configs/qi_lb60.h

Checkpatch says:

total: 1 errors, 12 warnings, 478 lines checked

Please clean up and resubmit.  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
You humans have that emotional need  to  express  gratitude.  "You're
welcome," I believe, is the correct response.
	-- Spock, "Bread and Circuses", stardate 4041.2

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

* [U-Boot] [PATCH v7 2/3] MIPS: Jz4740: Add NAND driver
  2011-10-02 13:56 ` [U-Boot] [PATCH v7 2/3] MIPS: Jz4740: Add NAND driver Shinya Kuribayashi
@ 2011-10-06 21:12   ` Wolfgang Denk
  0 siblings, 0 replies; 8+ messages in thread
From: Wolfgang Denk @ 2011-10-06 21:12 UTC (permalink / raw)
  To: u-boot

Dear Shinya Kuribayashi,

In message <4E886D71.3040704@pobox.com> you wrote:
> From: Xiangfu Liu <xiangfu@openmobilefree.net>
> Date: Fri, 19 Aug 2011 14:35:29 +0800
> 
> Jz4740 NAND flash controller can support:
> * MLC NAND as well as SLC NAND
> * all 8-bit/16-bit NAND flash devices
> * HAMMING and RS hardware ECC
> * automatic boot up from NAND flash devices
> 
> nand_ecclayout is set up for 2GiB NAND chip mounted in Qi LB60.
> We'll bring up boot-from-NAND support in nand_spl/ in the future.
> 
> Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net>
> Acked-by: Daniel <zpxu@ingenic.cn>
> Signed-off-by: Shinya Kuribayashi <skuribay@pobox.com>
> ---
> 
> Changes since v6:
> 
> * Remove NAND-boot stuff.  Those bits will be submitted as a nand-spl
>   support once this Jz4740 base support is merged.
> 
> * All previous comments from Scott are fixed.
> 
> * Bunch of coding style issues fixed.
> 
>  drivers/mtd/nand/Makefile      |    1 +
>  drivers/mtd/nand/jz4740_nand.c |  261 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 262 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mtd/nand/jz4740_nand.c

Checkpatch says:

total: 4 errors, 0 warnings, 268 lines checked

Please clean up and resubmit.  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
If I had to live my life again,  I'd  make  the  same  mistakes, only
sooner.                                          -- Tallulah Bankhead

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

* [U-Boot] [PATCH v7 1/3] MIPS: Ingenic XBurst Jz4740 processor support
  2011-10-02 13:54 ` [U-Boot] [PATCH v7 1/3] MIPS: Ingenic XBurst Jz4740 processor support Shinya Kuribayashi
@ 2011-10-06 21:12   ` Wolfgang Denk
  0 siblings, 0 replies; 8+ messages in thread
From: Wolfgang Denk @ 2011-10-06 21:12 UTC (permalink / raw)
  To: u-boot

Dear Shinya Kuribayashi,

In message <4E886D01.5090003@pobox.com> you wrote:
> From: Xiangfu Liu <xiangfu@openmobilefree.net>
> Date: Fri, 19 Aug 2011 14:35:29 +0800
> 
> Jz4740 is a multimedia application processor targeting for mobile
> devices like e-Dictionary, eBook, portable media player (PMP) and
> GPS navigator.  Jz4740 is powered by Ingenic 360 MHz XBurst CPU core
> (JzRISC), in which RISC/SIMD/DSP hybrid instruction set architecture
> provides high integration, high performance and low power consumption.
> 
> JzRISC incorporated in Jz4740 is the advanced and power-efficient
> 32-bit RISC core, compatible with MIPS32, with 16K I-Cache and 16K
> D-Cache, and can operate at speeds up to 400 MHz.
> 
> On-chip modules such as LCD controller, embedded audio codec, multi-
> channel SAR-ADC, AC97/I2S controller and camera I/F offer a rich
> suite of peripherals for multimedia application.  NAND controller
> (SLC/MLC), USB (host 1.1 and device 2.0), UART, I2C, SPI, etc. are
> also available.
> 
> For more info about Ingenic XBurst Jz4740:
>   http://en.ingenic.cn/eng/
>   http://www.linux-mips.org/wiki/Ingenic
> 
> This patch introduces XBurst CPU support in U-Boot.  It's compatible
> with MIPS32, but requires a bit different cache maintenance, timer
> routines, and boot mechanism using USB boot tool, so XBurst support
> can go into a separate new home, cpu/xburst/.
> 
> Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net>
> Acked-by: Daniel <zpxu@ingenic.cn>
> Signed-off-by: Shinya Kuribayashi <skuribay@pobox.com>
> ---
> 
> Changes since v6:
> 
> * Rebased against the latest U-Boot/MIPS codebase (the previous patches
>   up to v6 were based on v1.1.6).  $gp usage, relocation code and so on
>   are getting synced with the current MIPS support in U-Boot.
> 
> * Use -mach=mips32, pass -EL specifiers in PLATFORM_CPPFLAGS and
>   PLATFORM_LDFLAGS.  This port works in Little-endian.
> 
> * Remove NAND-boot stuff.  Those bits will be submitted as a nand_spl
>   support, once this Jz4740 base support is merged.
> 
> * jzsoc_init() is removed.  calc_clocks() and rtc_init() will be
>   called through board_early_init_f().
> 
> * jz_serial.c is almost the same with standard ns16550 driver, but
>   we dont' use it, because it need a special tweak for jz4740 like
>   this:
> 
> @@ -39,7 +39,11 @@ void NS16550_init (NS16550_t com_port, int baud_divisor)
>  	serial_out(0, &com_port->dlm);
>  	serial_out(UART_LCRVAL, &com_port->lcr);
>  	serial_out(UART_MCRVAL, &com_port->mcr);
> +#if defined(CONFIG_JZ4740)	/* 0x10: for JZ4740 UART Module Enable */
> +	serial_out(UART_FCRVAL | 0x10, &com_port->fcr);
> +#else
>  	serial_out(UART_FCRVAL, &com_port->fcr);
> +#endif
>  	serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
>  	serial_out(baud_divisor & 0xff, &com_port->dll);
>  	serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
> 
>   If this is acceptable, we'll change to use standard ns16550 later.
> 
> * Coding styles and build warnings fixed
> 
>  README                              |    1 +
>  arch/mips/cpu/xburst/Makefile       |   49 ++
>  arch/mips/cpu/xburst/config.mk      |   24 +
>  arch/mips/cpu/xburst/cpu.c          |  152 +++++
>  arch/mips/cpu/xburst/jz4740.c       |  248 ++++++++
>  arch/mips/cpu/xburst/jz_serial.c    |  114 ++++
>  arch/mips/cpu/xburst/start.S        |  171 ++++++
>  arch/mips/cpu/xburst/timer.c        |  169 ++++++
>  arch/mips/include/asm/global_data.h |   11 +
>  arch/mips/include/asm/jz4740.h      | 1115 +++++++++++++++++++++++++++++++++++
>  10 files changed, 2054 insertions(+), 0 deletions(-)
>  create mode 100644 arch/mips/cpu/xburst/Makefile
>  create mode 100644 arch/mips/cpu/xburst/config.mk
>  create mode 100644 arch/mips/cpu/xburst/cpu.c
>  create mode 100644 arch/mips/cpu/xburst/jz4740.c
>  create mode 100644 arch/mips/cpu/xburst/jz_serial.c
>  create mode 100644 arch/mips/cpu/xburst/start.S
>  create mode 100644 arch/mips/cpu/xburst/timer.c
>  create mode 100644 arch/mips/include/asm/jz4740.h

Checkpatch says:

total: 6 errors, 94 warnings, 2077 lines checked

Please clean up and resubmit.  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
Violence in reality is quite different from theory.
	-- Spock, "The Cloud Minders", stardate 5818.4

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

end of thread, other threads:[~2011-10-06 21:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-02 13:52 [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Shinya Kuribayashi
2011-10-02 13:54 ` [U-Boot] [PATCH v7 1/3] MIPS: Ingenic XBurst Jz4740 processor support Shinya Kuribayashi
2011-10-06 21:12   ` Wolfgang Denk
2011-10-02 13:56 ` [U-Boot] [PATCH v7 2/3] MIPS: Jz4740: Add NAND driver Shinya Kuribayashi
2011-10-06 21:12   ` Wolfgang Denk
2011-10-02 13:56 ` [U-Boot] [PATCH v7 3/3] MIPS: JZ4740: Add qi_lb60 board support Shinya Kuribayashi
2011-10-06 21:11   ` Wolfgang Denk
2011-10-02 15:08 ` [U-Boot] [PATCH v7 0/3] those series patches for add ben nanonote board Xiangfu Liu

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