summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2011-10-12 22:47:15 +0200
committerWolfgang Denk <wd@denx.de>2011-10-12 22:47:15 +0200
commitd8fffa057c9430fd0c5104ab6ff7db4cdb03db51 (patch)
tree2e98334405e9a602441091317ae69e09c32d3d51
parent0dd78fb9430e57ccc8e63369c6082b1c730f8aeb (diff)
parent3c945542dad99b1ec4a324ad6b69b8de8829827b (diff)
downloadu-boot-imx-d8fffa057c9430fd0c5104ab6ff7db4cdb03db51.zip
u-boot-imx-d8fffa057c9430fd0c5104ab6ff7db4cdb03db51.tar.gz
u-boot-imx-d8fffa057c9430fd0c5104ab6ff7db4cdb03db51.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-mips
* 'master' of git://git.denx.de/u-boot-mips: MIPS: Jz4740: Add qi_lb60 board support MIPS: Jz4740: Add NAND driver MIPS: Ingenic XBurst Jz4740 processor support
-rw-r--r--MAINTAINERS4
-rwxr-xr-xMAKEALL4
-rw-r--r--README1
-rw-r--r--arch/mips/cpu/xburst/Makefile49
-rw-r--r--arch/mips/cpu/xburst/config.mk24
-rw-r--r--arch/mips/cpu/xburst/cpu.c152
-rw-r--r--arch/mips/cpu/xburst/jz4740.c248
-rw-r--r--arch/mips/cpu/xburst/jz_serial.c114
-rw-r--r--arch/mips/cpu/xburst/start.S171
-rw-r--r--arch/mips/cpu/xburst/timer.c162
-rw-r--r--arch/mips/include/asm/global_data.h11
-rw-r--r--arch/mips/include/asm/jz4740.h1150
-rw-r--r--board/qi/qi_lb60/Makefile45
-rw-r--r--board/qi/qi_lb60/config.mk31
-rw-r--r--board/qi/qi_lb60/qi_lb60.c104
-rw-r--r--board/qi/qi_lb60/u-boot.lds61
-rw-r--r--boards.cfg1
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/jz4740_nand.c261
-rw-r--r--include/configs/qi_lb60.h211
20 files changed, 2804 insertions, 1 deletions
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 52bc355..f582f8b 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/README b/README
index 36f5a11..7e032a9 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..e976341
--- /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" \
+ "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
index 0000000..c0b9817
--- /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..de6f5da
--- /dev/null
+++ b/arch/mips/cpu/xburst/timer.c
@@ -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;
+}
diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
index b193517..f6cf9fe 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;
+#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
index 0000000..7a7cfff
--- /dev/null
+++ b/arch/mips/include/asm/jz4740.h
@@ -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__ */
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..3583d01
--- /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 = readw(&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;
+
+ writew(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 65482ac..d3d610d 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -302,6 +302,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/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index dae2442..1eeba5c 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -45,6 +45,7 @@ COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_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..3ec34f3
--- /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;
+}
diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
new file mode 100644
index 0000000..f989595
--- /dev/null
+++ b/include/configs/qi_lb60.h
@@ -0,0 +1,211 @@
+/*
+ * 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
+#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"
+
+/*
+ * 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_MAXARGS 16
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "NanoNote# "
+#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+
+#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
+#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)
+#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * NANONOTE_NAND_SIZE << 10)
+/* nand bad block was marked at 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 */
+
+/* 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