]> git.sur5r.net Git - u-boot/commitdiff
MIPS: Ingenic XBurst Jz4740 processor support
authorXiangfu Liu <xiangfu@openmobilefree.net>
Wed, 12 Oct 2011 04:24:06 +0000 (12:24 +0800)
committerShinya Kuribayashi <skuribay@pobox.com>
Mon, 10 Oct 2011 13:06:12 +0000 (22:06 +0900)
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>
README
arch/mips/cpu/xburst/Makefile [new file with mode: 0644]
arch/mips/cpu/xburst/config.mk [new file with mode: 0644]
arch/mips/cpu/xburst/cpu.c [new file with mode: 0644]
arch/mips/cpu/xburst/jz4740.c [new file with mode: 0644]
arch/mips/cpu/xburst/jz_serial.c [new file with mode: 0644]
arch/mips/cpu/xburst/start.S [new file with mode: 0644]
arch/mips/cpu/xburst/timer.c [new file with mode: 0644]
arch/mips/include/asm/global_data.h
arch/mips/include/asm/jz4740.h [new file with mode: 0644]

diff --git a/README b/README
index 3a8938f4e3cb6d52a9ad16a707f35f6e43d796ce..323ba61f6099d84d480f76f837987427aa56bfba 100644 (file)
--- 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 (file)
index 0000000..b1f2ae4
--- /dev/null
@@ -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 (file)
index 0000000..bce0c1b
--- /dev/null
@@ -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 (file)
index 0000000..e976341
--- /dev/null
@@ -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"        \
+               "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); */
+       writew(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 (file)
index 0000000..c0b9817
--- /dev/null
@@ -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 (file)
index 0000000..e6c48e0
--- /dev/null
@@ -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 (file)
index 0000000..d846104
--- /dev/null
@@ -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 (file)
index 0000000..de6f5da
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ *  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 */
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE;
+
+void reset_timer_masked(void)
+{
+       /* reset time */
+       gd->lastinc = readw(&tcu->tcnt0);
+       gd->tbl = 0;
+}
+
+ulong get_timer_masked(void)
+{
+       ulong now = readw(&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);
+}
+
+int timer_init(void)
+{
+       writew(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0);
+
+       writew(0, &tcu->tcnt0);
+       writew(0, &tcu->tdhr0);
+       writew(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 */
+       writeb(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)
+               ;
+}
+
+/*
+ * 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;
+}
index b193517889e001fbb91e467ce6aa44b0bdda42dc..f6cf9fe9fd5e08fba29d3f237a82ffca32006466 100644 (file)
 typedef        struct  global_data {
        bd_t            *bd;
        unsigned long   flags;
+#ifdef 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 */
 #ifdef CONFIG_PRE_CONSOLE_BUFFER
diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
new file mode 100644 (file)
index 0000000..7a7cfff
--- /dev/null
@@ -0,0 +1,1150 @@
+/*
+ * 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 */
+
+/* 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) /* Use 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 */
+#define EMC_NFINTE_DECFE       (1 << 3) /* Decoding Finished Interrupt */
+#define EMC_NFINTE_ENCFE       (1 << 2) /* Encoding Finished Interrupt */
+#define EMC_NFINTE_UNCORE      (1 << 1) /* Uncorrectable Error Occurred Intr */
+#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 */
+/* FIFO mode select, set when UART_FCR.FE is set to 1 */
+#define UART_ISR_FFMS  (3 << 6)
+#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 */
+/* 0: access UART_RDR/TDR/IER  1: access UART_DLLR/DLHR */
+#define UART_LCR_DLAB  (1 << 7)
+
+/*
+ * Define macros for UART_LSR
+ * UART Line Status Register
+ */
+/* 0: receive FIFO is empty  1: receive data is ready */
+#define UART_LSR_DR    (1 << 0)
+/* 0: no overrun error */
+#define UART_LSR_ORER  (1 << 1)
+/* 0: no parity error */
+#define UART_LSR_PER   (1 << 2)
+/* 0; no framing error */
+#define UART_LSR_FER   (1 << 3)
+/* 0: no break detected  1: receive a break signal */
+#define UART_LSR_BRK   (1 << 4)
+/* 1: transmit FIFO half "empty" */
+#define UART_LSR_TDRQ  (1 << 5)
+/* 1: transmit FIFO and shift registers empty */
+#define UART_LSR_TEMT  (1 << 6)
+/* 0: no receive error  1: receive error in FIFO mode */
+#define UART_LSR_RFER  (1 << 7)
+
+/*
+ * 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 */
+/* 0: UART_MSR.RI is set to 0 and RI_ input high */
+#define UART_MCR_OUT1  (1 << 2)
+/* 0: UART_MSR.DCD is set to 0 and DCD_ input high */
+#define UART_MCR_OUT2  (1 << 3)
+#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_ since last read */
+#define UART_MSR_DDSR  (1 << 1) /* 0: no change on DSR_ since last read */
+#define UART_MSR_DRI   (1 << 2) /* 0: no change on RI_  since last read */
+#define UART_MSR_DDCD  (1 << 3) /* 0: no change on DCD_ since last read */
+#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: TX is in UART mode 1: IrDA mode */
+#define SIRCR_RSIRE (1 << 1) /* 0: RX 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)
+#define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT)
+
+/* 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)
+/* No error on transmission of data */
+  #define MSC_STAT_CRC_WRITE_ERROR_NO  (0 << MSC_STAT_CRC_WRITE_ERROR_BIT)
+/* Card observed erroneous transmission of data */
+  #define MSC_STAT_CRC_WRITE_ERROR     (1 << MSC_STAT_CRC_WRITE_ERROR_BIT)
+/* No CRC status is sent back */
+  #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT)
+#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)
+  #define MSC_CLKRT_CLK_RATE_DIV_2  (0x1 << MSC_CLKRT_CLK_RATE_BIT)
+  #define MSC_CLKRT_CLK_RATE_DIV_4  (0x2 << MSC_CLKRT_CLK_RATE_BIT)
+  #define MSC_CLKRT_CLK_RATE_DIV_8  (0x3 << MSC_CLKRT_CLK_RATE_BIT)
+  #define MSC_CLKRT_CLK_RATE_DIV_16  (0x4 << MSC_CLKRT_CLK_RATE_BIT)
+  #define MSC_CLKRT_CLK_RATE_DIV_32  (0x5 << MSC_CLKRT_CLK_RATE_BIT)
+  #define MSC_CLKRT_CLK_RATE_DIV_64  (0x6 << MSC_CLKRT_CLK_RATE_BIT)
+  #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT)
+
+/* 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)
+
+#ifndef __ASSEMBLY__
+/* 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 */
+};
+
+/* 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 */
+};
+
+#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 + 0x00) & CPM_CPCCR_HDIV_MASK)  \
+        >> CPM_CPCCR_HDIV_BIT)
+#define __cpm_get_pdiv()                                       \
+       ((readl(JZ4740_CPM_BASE + 0x00) & CPM_CPCCR_PDIV_MASK)  \
+        >> CPM_CPCCR_PDIV_BIT)
+#define __cpm_get_cdiv()                                       \
+       ((readl(JZ4740_CPM_BASE + 0x00) & CPM_CPCCR_CDIV_MASK)  \
+        >> CPM_CPCCR_CDIV_BIT)
+#define __cpm_get_mdiv()                                       \
+       ((readl(JZ4740_CPM_BASE + 0x00) & CPM_CPCCR_MDIV_MASK)  \
+        >> CPM_CPCCR_MDIV_BIT)
+
+static inline unsigned int __cpm_get_pllout(void)
+{
+       uint32_t m, n, no, pllout;
+       uint32_t od[4] = {1, 2, 2, 4};
+
+       struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE;
+       uint32_t cppcr = readl(&cpm->cppcr);
+
+       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;
+}
+
+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__ */