diff options
| author | Wolfgang Denk <wd@denx.de> | 2011-10-12 22:47:15 +0200 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2011-10-12 22:47:15 +0200 | 
| commit | d8fffa057c9430fd0c5104ab6ff7db4cdb03db51 (patch) | |
| tree | 2e98334405e9a602441091317ae69e09c32d3d51 | |
| parent | 0dd78fb9430e57ccc8e63369c6082b1c730f8aeb (diff) | |
| parent | 3c945542dad99b1ec4a324ad6b69b8de8829827b (diff) | |
| download | olio-uboot-2014.01-d8fffa057c9430fd0c5104ab6ff7db4cdb03db51.tar.xz olio-uboot-2014.01-d8fffa057c9430fd0c5104ab6ff7db4cdb03db51.zip | |
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-- | MAINTAINERS | 4 | ||||
| -rwxr-xr-x | MAKEALL | 4 | ||||
| -rw-r--r-- | README | 1 | ||||
| -rw-r--r-- | arch/mips/cpu/xburst/Makefile | 49 | ||||
| -rw-r--r-- | arch/mips/cpu/xburst/config.mk | 24 | ||||
| -rw-r--r-- | arch/mips/cpu/xburst/cpu.c | 152 | ||||
| -rw-r--r-- | arch/mips/cpu/xburst/jz4740.c | 248 | ||||
| -rw-r--r-- | arch/mips/cpu/xburst/jz_serial.c | 114 | ||||
| -rw-r--r-- | arch/mips/cpu/xburst/start.S | 171 | ||||
| -rw-r--r-- | arch/mips/cpu/xburst/timer.c | 162 | ||||
| -rw-r--r-- | arch/mips/include/asm/global_data.h | 11 | ||||
| -rw-r--r-- | arch/mips/include/asm/jz4740.h | 1150 | ||||
| -rw-r--r-- | board/qi/qi_lb60/Makefile | 45 | ||||
| -rw-r--r-- | board/qi/qi_lb60/config.mk | 31 | ||||
| -rw-r--r-- | board/qi/qi_lb60/qi_lb60.c | 104 | ||||
| -rw-r--r-- | board/qi/qi_lb60/u-boot.lds | 61 | ||||
| -rw-r--r-- | boards.cfg | 1 | ||||
| -rw-r--r-- | drivers/mtd/nand/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mtd/nand/jz4740_nand.c | 261 | ||||
| -rw-r--r-- | include/configs/qi_lb60.h | 211 | 
20 files changed, 2804 insertions, 1 deletions
| diff --git a/MAINTAINERS b/MAINTAINERS index 3ab38fa98..bb95e6df9 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:							#  #									# @@ -400,7 +400,9 @@ LIST_mips="		\  ## MIPS Systems		(little endian)  ######################################################################### -LIST_mips4kc_el="" +LIST_mips4kc_el="	\ +	qi_lb60		\ +"  LIST_mips5kc_el="" @@ -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 000000000..b1f2ae420 --- /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 000000000..bce0c1bcb --- /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 000000000..e97634159 --- /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 000000000..c0b9817ab --- /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 000000000..e6c48e089 --- /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 000000000..d846104d1 --- /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 000000000..de6f5daa3 --- /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 b19351788..f6cf9fe9f 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 000000000..7a7cfff29 --- /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 000000000..2f5b4be2b --- /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 000000000..858e6a2f9 --- /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 000000000..3583d01c7 --- /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 000000000..731765256 --- /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 65482aca1..d3d610d69 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 dae244299..1eeba5cf2 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 000000000..3ec34f3c9 --- /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 000000000..f989595d0 --- /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 |