* [U-Boot] [PATCH 0/5] [MIPS] add jz4740 base file and Ben NanoNote
@ 2010-11-11 3:37 Xiangfu Liu
2010-11-11 3:37 ` [U-Boot] [PATCH 1/5] those files are jz4740 base files Xiangfu Liu
0 siblings, 1 reply; 11+ messages in thread
From: Xiangfu Liu @ 2010-11-11 3:37 UTC (permalink / raw)
To: u-boot
Hi Shinya
very thanks for your feed pack, and I am really sorry for so later
reply.
the "[PATCH 1/5] those files are jz4740 base files" is patch v2 of
"[PATCH] [MIPS] those files are jz4740 base files"
I have try to fix all your comments. only one thing, I am not very
understand the "flash cache" stuff, so I maybe still keep the
flash ICache DCache like before.
please give me some feedback. now I have more time working on U-Boot :)
thanks very much.
^ permalink raw reply [flat|nested] 11+ messages in thread* [U-Boot] [PATCH 1/5] those files are jz4740 base files 2010-11-11 3:37 [U-Boot] [PATCH 0/5] [MIPS] add jz4740 base file and Ben NanoNote Xiangfu Liu @ 2010-11-11 3:37 ` Xiangfu Liu [not found] ` <1289446657-12499-3-git-send-email-xiangfu@openmobilefree.net> ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Xiangfu Liu @ 2010-11-11 3:37 UTC (permalink / raw) To: u-boot From: Xiangfu Liu <xiangfu@sharism.cc> Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net> --- arch/mips/cpu/xburst/Makefile | 50 +++ arch/mips/cpu/xburst/config.mk | 33 ++ arch/mips/cpu/xburst/cpu.c | 158 +++++++ arch/mips/cpu/xburst/interrupts.c | 33 ++ arch/mips/cpu/xburst/jz4740.c | 257 +++++++++++ arch/mips/cpu/xburst/jz_serial.c | 139 ++++++ arch/mips/cpu/xburst/start.S | 165 +++++++ arch/mips/cpu/xburst/start_spl.S | 63 +++ arch/mips/cpu/xburst/timer.c | 174 ++++++++ arch/mips/cpu/xburst/usbboot.S | 880 +++++++++++++++++++++++++++++++++++++ 10 files changed, 1952 insertions(+), 0 deletions(-) create mode 100644 arch/mips/cpu/xburst/Makefile create mode 100644 arch/mips/cpu/xburst/config.mk create mode 100644 arch/mips/cpu/xburst/cpu.c create mode 100644 arch/mips/cpu/xburst/interrupts.c create mode 100644 arch/mips/cpu/xburst/jz4740.c create mode 100644 arch/mips/cpu/xburst/jz_serial.c create mode 100644 arch/mips/cpu/xburst/start.S create mode 100644 arch/mips/cpu/xburst/start_spl.S create mode 100644 arch/mips/cpu/xburst/timer.c create mode 100644 arch/mips/cpu/xburst/usbboot.S diff --git a/arch/mips/cpu/xburst/Makefile b/arch/mips/cpu/xburst/Makefile new file mode 100644 index 0000000..2e29851 --- /dev/null +++ b/arch/mips/cpu/xburst/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd at denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +SOBJS-y = +COBJS-y = cpu.o interrupts.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) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk new file mode 100644 index 0000000..f43f53b --- /dev/null +++ b/arch/mips/cpu/xburst/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2003 +# Wolfgang Denk, DENX Software Engineering, <wd@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +v=$(shell $(AS) --version | grep 'GNU assembler' | egrep -o '2\.[0-9\.]+' | cut -d. -f2) +MIPSFLAGS:=$(shell \ +if [ "$v" -lt "14" ]; then \ + echo "-mcpu=4kc"; \ +else \ + echo "-march=4kc -mtune=4kc"; \ +fi) + +MIPSFLAGS += $(ENDIANNESS) -mabicalls -mips32 + +PLATFORM_CPPFLAGS += $(MIPSFLAGS) diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c new file mode 100644 index 0000000..682debf --- /dev/null +++ b/arch/mips/cpu/xburst/cpu.c @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <netdev.h> +#include <asm/mipsregs.h> +#include <asm/cacheops.h> +#include <asm/reboot.h> +#include <asm/jz4740.h> + +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +#if !defined (CONFIG_NAND_SPL) && !defined (CONFIG_MSC_SPL) + +void __attribute__((weak)) _machine_restart(void) +{ + __wdt_select_extalclk(); + __wdt_select_clk_div64(); + __wdt_set_data(100); + __wdt_set_count(0); + __tcu_start_wdt_clock(); + __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); + + while (1) { + cache_op(Hit_Writeback_Inv_D, addr); + cache_op(Hit_Invalidate_I, addr); + if (addr == aend) + break; + addr += lsize; + } +} + +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); + + while (1) { + cache_op(Hit_Writeback_Inv_D, addr); + if (addr == aend) + break; + addr += lsize; + } +} + +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); + + while (1) { + cache_op(Hit_Invalidate_D, addr); + if (addr == aend) + break; + addr += lsize; + } +} + +void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) +{ + write_c0_entrylo0(low0); + write_c0_pagemask(pagemask); + write_c0_entrylo1(low1); + write_c0_entryhi(hi); + write_c0_index(index); + tlb_write_indexed(); +} + +#endif /* !CONFIG_NAND_SPL !CONFIG_MSC_SPL */ + +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 = KSEG0; addr < KSEG0 + 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 = KSEG0; addr < KSEG0 + 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/interrupts.c b/arch/mips/cpu/xburst/interrupts.c new file mode 100644 index 0000000..87f7a9f --- /dev/null +++ b/arch/mips/cpu/xburst/interrupts.c @@ -0,0 +1,33 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +void enable_interrupts(void) +{ +} + +int disable_interrupts(void) +{ + return 0; +} diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c new file mode 100644 index 0000000..b8e9a15 --- /dev/null +++ b/arch/mips/cpu/xburst/jz4740.c @@ -0,0 +1,257 @@ +/* + * 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/jz4740.h> + +/* 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) +{ + 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 */ + REG_CPM_UHCCDR = pllout2 / 48000000 - 1; + + 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 */ + REG_CPM_CPCCR = cfcr; + REG_CPM_CPPCR = plcr1; +} + +void sdram_init(void) +{ + 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()]; + + REG_EMC_BCR = 0; /* Disable bus release */ + REG_EMC_RTCSR = 0; /* 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 */ + REG_EMC_DMCR = dmcr; + REG8(EMC_SDMR0|sdmode) = 0; + + /* Wait for precharge, > 200us */ + tmp = (cpu_clk / 1000000) * 1000; + while (tmp--); + + /* Stage 2. Enable auto-refresh */ + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH; + + tmp = SDRAM_TREF/ns; + tmp = tmp/64 + 1; + if (tmp > 0xff) tmp = 0xff; + REG_EMC_RTCOR = tmp; + REG_EMC_RTCNT = 0; + REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ + + /* Wait for number of auto-refresh cycles */ + tmp = (cpu_clk / 1000000) * 1000; + while (tmp--); + + /* Stage 3. Mode Register Set */ + REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET; + REG8(EMC_SDMR0|sdmode) = 0; + + /* Set back to basic DMCR value */ + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; + + /* everything is ok now */ +} + +#ifndef CONFIG_NAND_SPL + +static void calc_clocks(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + 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; +} + +static void rtc_init(void) +{ + while ( !__rtc_write_ready()) ; + __rtc_enable_alarm(); /* enable alarm */ + + while ( !__rtc_write_ready()) + ; + REG_RTC_RGR = 0x00007fff; /* type value */ + + while ( !__rtc_write_ready()) + ; + REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */ + + while ( !__rtc_write_ready()) + ; + REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */ +#if 0 + unsigned long rtcsta; + + while ( !__rtc_write_ready()) + ; + rtcsta = REG_RTC_HWRSR; + while ( !__rtc_write_ready()) + ; + if (rtcsta & 0x33) { + if (rtcsta & 0x10) { + while ( !__rtc_write_ready()) + ; + REG_RTC_RSR = 0x0; + } + while ( !__rtc_write_ready()) + ; + REG_RTC_HWRSR = 0x0; + } +#endif +} + +/* U-Boot common routines */ +phys_size_t initdram(int board_type) +{ + u32 dmcr; + u32 rows, cols, dw, banks; + ulong size; + + dmcr = REG_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; +} + +/* + * jz4740 board init routine + */ +extern void board_early_init(void); +int jz_board_init(void) +{ + board_early_init(); /* init gpio, pll etc. */ +#ifndef CONFIG_NAND_U_BOOT + pll_init(); /* init PLL */ + sdram_init(); /* init sdram memory */ +#endif + calc_clocks(); /* calc the clocks */ + rtc_init(); /* init rtc on any reset: */ + return 0; +} + +#endif /* CONFIG_NAND_SPL */ diff --git a/arch/mips/cpu/xburst/jz_serial.c b/arch/mips/cpu/xburst/jz_serial.c new file mode 100644 index 0000000..c5cc28e --- /dev/null +++ b/arch/mips/cpu/xburst/jz_serial.c @@ -0,0 +1,139 @@ +/* + * Jz47xx UART support + * + * Hardcoded to UART 0 for now + * Options also hardcoded to 8N1 + * + * Copyright (c) 2005 + * 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> + +#if defined(CONFIG_JZ4740) +#include <asm/jz4740.h> +#endif + +#undef UART_BASE +#ifndef CONFIG_SYS_UART_BASE +#define UART_BASE UART0_BASE +#else +#define UART_BASE CONFIG_SYS_UART_BASE +#endif + +/****************************************************************************** +* +* 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 +*/ + +int serial_init (void) +{ +#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) + volatile u8 *uart_fcr = (volatile u8 *)(UART_BASE + OFF_FCR); + volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); + volatile u8 *uart_ier = (volatile u8 *)(UART_BASE + OFF_IER); + volatile u8 *uart_sircr = (volatile u8 *)(UART_BASE + OFF_SIRCR); + + /* Disable port interrupts while changing hardware */ + *uart_ier = 0; + + /* Disable UART unit function */ + *uart_fcr = ~UART_FCR_UUE; + + /* Set both receiver and transmitter in UART mode (not SIR) */ + *uart_sircr = ~(SIRCR_RSIRE | SIRCR_TSIRE); + + /* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ + *uart_lcr = UART_LCR_WLEN_8 | UART_LCR_STOP_1; + + /* Set baud rate */ + serial_setbrg(); + + /* Enable UART unit, enable and clear FIFO */ + *uart_fcr = UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS; +#endif + return 0; +} + +void serial_setbrg (void) +{ + volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); + volatile u8 *uart_dlhr = (volatile u8 *)(UART_BASE + OFF_DLHR); + volatile u8 *uart_dllr = (volatile u8 *)(UART_BASE + OFF_DLLR); + u32 baud_div, tmp; + + baud_div = CONFIG_SYS_EXTAL / 16 / CONFIG_BAUDRATE; + + tmp = *uart_lcr; + tmp |= UART_LCR_DLAB; + *uart_lcr = tmp; + + *uart_dlhr = (baud_div >> 8) & 0xff; + *uart_dllr = baud_div & 0xff; + + tmp &= ~UART_LCR_DLAB; + *uart_lcr = tmp; +} + +void serial_putc (const char c) +{ + volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR); + volatile u8 *uart_tdr = (volatile u8 *)(UART_BASE + OFF_TDR); + + if (c == '\n') serial_putc ('\r'); + + /* Wait for fifo to shift out some bytes */ + while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) ); + + *uart_tdr = (u8)c; +} + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +int serial_getc (void) +{ + volatile u8 *uart_rdr = (volatile u8 *)(UART_BASE + OFF_RDR); + + while (!serial_tstc()); + + return *uart_rdr; +} + +int serial_tstc (void) +{ + volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR); + + if (*uart_lsr & UART_LSR_DR) { + /* Data in rfifo */ + return (1); + } + return 0; +} + diff --git a/arch/mips/cpu/xburst/start.S b/arch/mips/cpu/xburst/start.S new file mode 100644 index 0000000..b05cc67 --- /dev/null +++ b/arch/mips/cpu/xburst/start.S @@ -0,0 +1,165 @@ +/* + * 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> + +#include <asm/jz4740.h> + + .set noreorder + + .globl _start + .text +_start: + /* Initialize GOT pointer. + */ + bal 1f + nop + .word _GLOBAL_OFFSET_TABLE_ +1: + lw gp, 0(ra) + 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, TEXT_BASE + la t3, in_ram + lw t2, -12(t3) /* t2 <-- uboot_end_data */ + move t1, a2 + + /* + * Fix GOT pointer: + * + * New GOT-PTR = (old GOT-PTR - TEXT_BASE) + Destination Address + */ + move t6, gp + sub gp, TEXT_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 /* delay slot */ + + /* If caches were enabled, we would have to flush them here. + * flush d-cache */ + .set push + 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 + + .set pop + + /* Jump to where we've relocated ourselves. + */ + addi t0, a2, in_ram - _start + j t0 + nop + + .word uboot_end_data + .word uboot_end + .word num_got_entries + +in_ram: + /* Now we want to update GOT */ + lw t3, -4(t0) /* t3 <-- num_got_entries */ + addi t4, gp, 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 /* delay slot */ + + /* 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) /* delay slot */ + + move a0, a1 + la t9, board_init_r + j t9 + move a1, a2 /* delay slot */ + + .end relocate_code + \ No newline at end of file diff --git a/arch/mips/cpu/xburst/start_spl.S b/arch/mips/cpu/xburst/start_spl.S new file mode 100644 index 0000000..f775e3a --- /dev/null +++ b/arch/mips/cpu/xburst/start_spl.S @@ -0,0 +1,63 @@ +/* + * 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 3 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> + +#include <asm/jz4740.h> + + .set noreorder + + .globl _start + .text +_start: + .word JZ4740_NANDBOOT_CFG /* fetched during NAND Boot */ +reset: + /* + * STATUS register + * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1 + */ + li t0, 0x0040FC04 + mtc0 t0, CP0_STATUS + /* CAUSE register + * IV=1, use the specical interrupt vector (0x200) */ + li t1, 0x00800000 + mtc0 t1, CP0_CAUSE + + bal 1f + nop + .word _GLOBAL_OFFSET_TABLE_ +1: + move gp, ra + lw t1, 0(ra) + move gp, t1 + + la sp, 0x80004000 + la t9, nand_boot + j t9 + nop diff --git a/arch/mips/cpu/xburst/timer.c b/arch/mips/cpu/xburst/timer.c new file mode 100644 index 0000000..5fef521 --- /dev/null +++ b/arch/mips/cpu/xburst/timer.c @@ -0,0 +1,174 @@ +/* + * 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/jz4740.h> + +/* + * Timer routines + */ +#define TIMER_CHAN 0 +#define TIMER_FDATA 0xffff /* Timer full data value */ +#define TIMER_HZ CONFIG_SYS_HZ + +#define READ_TIMER REG_TCU_TCNT(TIMER_CHAN) /* macro to read the 16 bit timer */ + +static ulong timestamp; +static ulong lastdec; + +void reset_timer_masked (void); +ulong get_timer_masked (void); +void udelay_masked (unsigned long usec); + +/* + * timer without interrupts + */ + +int timer_init(void) +{ + REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN; + REG_TCU_TCNT(TIMER_CHAN) = 0; + REG_TCU_TDHR(TIMER_CHAN) = 0; + REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA; + + REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */ + REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */ + REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */ + + lastdec = 0; + timestamp = 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) +{ + timestamp = t; +} + +void __udelay (unsigned long usec) +{ + ulong tmo,tmp; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= TIMER_HZ; + tmo /= 1000; + } + else { + if (usec >= 1) { + tmo = usec * TIMER_HZ; + tmo /= (1000*1000); + } + else + tmo = 1; + } + + /* check for rollover during this delay */ + tmp = get_timer (0); + if ((tmp + tmo) < tmp ) + reset_timer_masked(); /* timer would roll over */ + else + tmo += tmp; + + while (get_timer_masked () < tmo); +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; + + if (lastdec <= now) { + /* normal mode */ + timestamp += (now - lastdec); + } else { + /* we have an overflow ... */ + timestamp += TIMER_FDATA + now - lastdec; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= TIMER_HZ; + tmo /= 1000; + } else { + if (usec > 1) { + tmo = usec * TIMER_HZ; + tmo /= (1000*1000); + } else { + tmo = 1; + } + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On MIPS it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On MIPS it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + return TIMER_HZ; +} diff --git a/arch/mips/cpu/xburst/usbboot.S b/arch/mips/cpu/xburst/usbboot.S new file mode 100644 index 0000000..eb8faa6 --- /dev/null +++ b/arch/mips/cpu/xburst/usbboot.S @@ -0,0 +1,880 @@ +/* + * for jz4740 usb boot + * + * Copyright (c) 2009 Author: <jlwei@ingenic.cn> + * + * 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 + */ + .set noreorder + .globl usb_boot + .text + +//---------------------------------------------------------------------- +// Both NAND and USB boot load data to D-Cache first, then transfer +// data from D-Cache to I-Cache, and jump to execute the code in I-Cache. +// So init caches first and then dispatch to a proper boot routine. +//---------------------------------------------------------------------- + +.macro load_addr reg addr + li \reg, 0x80000000 + addiu \reg, \reg, \addr + la $2, usbboot_begin + subu \reg, \reg, $2 +.endm + +usb_boot: + //-------------------------------------------------------------- + // Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. + //-------------------------------------------------------------- + la $9, 0xB0000000 // CPCCR: Clock Control Register + la $8, 0x42041110 // I:S:M:P=1:2:2:2 + sw $8, 0($9) + + la $9, 0xB0000010 // CPPCR: PLL Control Register + la $8, 0x06000120 // M=12 N=0 D=0 CLK=12*(M+2)/(N+2) + sw $8, 0($9) + + mtc0 $0, $26 // CP0_ERRCTL, restore WST reset state + nop + + mtc0 $0, $16 // CP0_CONFIG + nop + + // Relocate code to beginning of the ram + + la $2, usbboot_begin + la $3, usbboot_end + li $4, 0x80000000 + +1: + lw $5, 0($2) + sw $5, 0($4) + addiu $2, $2, 4 + bne $2, $3, 1b + addiu $4, $4, 4 + + li $2, 0x80000000 + ori $3, $2, 0 + addiu $3, $3, usbboot_end + la $4, usbboot_begin + subu $3, $3, $4 + + +2: + cache 0x0, 0($2) // Index_Invalidate_I + cache 0x1, 0($2) // Index_Writeback_Inv_D + addiu $2, $2, 32 + subu $4, $3, $2 + bgtz $4, 2b + nop + + load_addr $3, usb_boot_return + + jr $3 + +usbboot_begin: + +init_caches: + li $2, 3 // cacheable for kseg0 access + mtc0 $2, $16 // CP0_CONFIG + nop + + li $2, 0x20000000 // enable idx-store-data cache insn + mtc0 $2, $26 // CP0_ERRCTL + + ori $2, $28, 0 // start address + ori $3, $2, 0x3fe0 // end address, total 16KB + mtc0 $0, $28, 0 // CP0_TAGLO + mtc0 $0, $28, 1 // CP0_DATALO +cache_clear_a_line: + cache 0x8, 0($2) // Index_Store_Tag_I + cache 0x9, 0($2) // Index_Store_Tag_D + bne $2, $3, cache_clear_a_line + addiu $2, $2, 32 // increment CACHE_LINE_SIZE + + ori $2, $28, 0 // start address + ori $3, $2, 0x3fe0 // end address, total 16KB + la $4, 0x1ffff000 // physical address and 4KB page mask +cache_alloc_a_line: + and $5, $2, $4 + ori $5, $5, 1 // V bit of the physical tag + mtc0 $5, $28, 0 // CP0_TAGLO + cache 0x8, 0($2) // Index_Store_Tag_I + cache 0x9, 0($2) // Index_Store_Tag_D + bne $2, $3, cache_alloc_a_line + addiu $2, $2, 32 // increment CACHE_LINE_SIZE + + nop + nop + nop + //-------------------------------------------------------------- + // Transfer data from dcache to icache, then jump to icache. + // + // Input parameters: + // + // $19: data length in bytes + // $20: jump target address + //-------------------------------------------------------------- +xfer_d2i: + + ori $8, $20, 0 + addu $9, $8, $19 // total 16KB + +1: + cache 0x0, 0($8) // Index_Invalidate_I + cache 0x1, 0($8) // Index_Writeback_Inv_D + bne $8, $9, 1b + addiu $8, $8, 32 + + // flush write-buffer + sync + + // Invalidate BTB + mfc0 $8, $16, 7 // CP0_CONFIG + nop + ori $8, 2 + mtc0 $8, $16, 7 + nop + + // Overwrite config to disable ram initalisation + li $2, 0xff + sb $2, 20($20) + + jalr $20 + nop + +icache_return: + //-------------------------------------------------------------- + // User code can return to here after executing itself in + // icache, by jumping to $31. + //-------------------------------------------------------------- + b usb_boot_return + nop + + +usb_boot_return: + //-------------------------------------------------------------- + // Enable the USB PHY + //-------------------------------------------------------------- + la $9, 0xB0000024 // CPM_SCR + lw $8, 0($9) + ori $8, 0x40 // USBPHY_ENABLE + sw $8, 0($9) + + //-------------------------------------------------------------- + // Initialize USB registers + //-------------------------------------------------------------- + la $27, 0xb3040000 // USB registers base address + + sb $0, 0x0b($27) // INTRUSBE: disable common USB interrupts + sh $0, 0x06($27) // INTRINE: disable EPIN interrutps + sh $0, 0x08($27) // INTROUTE: disable EPOUT interrutps + + li $9, 0x61 + sb $9, 0x01($27) // POWER: HSENAB | SUSPENDM | SOFTCONN + + //-------------------------------------------------------------- + // Initialize USB states + //-------------------------------------------------------------- + li $22, 0 // set EP0 to IDLE state + li $23, 1 // no data stage + + //-------------------------------------------------------------- + // Main loop of polling the usb commands + //-------------------------------------------------------------- +usb_command_loop: + lbu $9, 0x0a($27) // read INTRUSB + andi $9, 0x04 // check USB_INTR_RESET + beqz $9, check_intr_ep0in + nop + + //-------------------------------------------------------------- + // 1. Handle USB reset interrupt + //-------------------------------------------------------------- +handle_reset_intr: + lbu $9, 0x01($27) // read POWER + andi $9, 0x10 // test HS_MODE + bnez $9, _usb_set_maxpktsize + li $9, 512 // max packet size of HS mode + li $9, 64 // max packet size of FS mode + +_usb_set_maxpktsize: + li $8, 1 + sb $8, 0x0e($27) // set INDEX 1 + + sh $9, 0x10($27) // INMAXP + sb $0, 0x13($27) // INCSRH + sh $9, 0x14($27) // OUTMAXP + sb $0, 0x17($27) // OUTCSRH + +_usb_flush_fifo: + li $8, 0x48 // INCSR_CDT && INCSR_FF + sb $8, 0x12($27) // INCSR + li $8, 0x90 // OUTCSR_CDT && OUTCSR_FF + sb $8, 0x16($27) // OUTCSR + + li $22, 0 // set EP0 to IDLE state + li $23, 1 // no data stage + + //-------------------------------------------------------------- + // 2. Check and handle EP0 interrupt + //-------------------------------------------------------------- +check_intr_ep0in: + lhu $10, 0x02($27) // read INTRIN + andi $9, $10, 0x1 // check EP0 interrupt + beqz $9, check_intr_ep1in + nop + +handle_ep0_intr: + sb $0, 0x0e($27) // set INDEX 0 + lbu $11, 0x12($27) // read CSR0 + + andi $9, $11, 0x04 // check SENTSTALL + beqz $9, _ep0_setupend + nop + +_ep0_sentstall: + andi $9, $11, 0xdb + sb $9, 0x12($27) // clear SENDSTALL and SENTSTALL + li $22, 0 // set EP0 to IDLE state + +_ep0_setupend: + andi $9, $11, 0x10 // check SETUPEND + beqz $9, ep0_idle_state + nop + + ori $9, $11, 0x80 + sb $9, 0x12($27) // set SVDSETUPEND + li $22, 0 // set EP0 to IDLE state + +ep0_idle_state: + bnez $22, ep0_tx_state + nop + + //-------------------------------------------------------------- + // 2.1 Handle EP0 IDLE state interrupt + //-------------------------------------------------------------- + andi $9, $11, 0x01 // check OUTPKTRDY + beqz $9, check_intr_ep1in + nop + + //-------------------------------------------------------------- + // Read 8-bytes setup packet from the FIFO + //-------------------------------------------------------------- + lw $25, 0x20($27) // first word of setup packet + lw $26, 0x20($27) // second word of setup packet + + andi $9, $25, 0x60 // bRequestType & USB_TYPE_MASK + beqz $9, _ep0_std_req + nop + + //-------------------------------------------------------------- + // 2.1.1 Vendor-specific setup request + //-------------------------------------------------------------- +_ep0_vend_req: + li $22, 0 // set EP0 to IDLE state + li $23, 1 // NoData = 1 + + andi $9, $25, 0xff00 // check bRequest + srl $9, $9, 8 + beqz $9, __ep0_get_cpu_info + sub $8, $9, 0x1 + beqz $8, __ep0_set_data_address + sub $8, $9, 0x2 + beqz $8, __ep0_set_data_length + sub $8, $9, 0x3 + beqz $8, __ep0_flush_caches + sub $8, $9, 0x4 + beqz $8, __ep0_prog_start1 + sub $8, $9, 0x5 + beqz $8, __ep0_prog_start2 + nop + b _ep0_idle_state_fini // invalid request + nop + +__ep0_get_cpu_info: + load_addr $20, cpu_info_data // data pointer to transfer + li $21, 8 // bytes left to transfer + li $22, 1 // set EP0 to TX state + li $23, 0 // NoData = 0 + + b _ep0_idle_state_fini + nop + +__ep0_set_data_address: + li $9, 0xffff0000 + and $9, $25, $9 + andi $8, $26, 0xffff + or $20, $9, $8 // data address of next transfer + + b _ep0_idle_state_fini + nop + +__ep0_set_data_length: + li $9, 0xffff0000 + and $9, $25, $9 + andi $8, $26, 0xffff + or $21, $9, $8 // data length of next transfer + + li $9, 0x48 // SVDOUTPKTRDY and DATAEND + sb $9, 0x12($27) // CSR0 + + // We must write packet to FIFO before EP1-IN interrupt here. + b handle_epin1_intr + nop + +__ep0_flush_caches: + // Flush dcache and invalidate icache. + li $8, 0x80000000 + addi $9, $8, 0x3fe0 // total 16KB + +1: + cache 0x0, 0($8) // Index_Invalidate_I + cache 0x1, 0($8) // Index_Writeback_Inv_D + bne $8, $9, 1b + addiu $8, $8, 32 + + // flush write-buffer + sync + + // Invalidate BTB + mfc0 $8, $16, 7 // CP0_CONFIG + nop + ori $8, 2 + mtc0 $8, $16, 7 + nop + + b _ep0_idle_state_fini + nop + +__ep0_prog_start1: + li $9, 0x48 // SVDOUTPKTRDY and DATAEND + sb $9, 0x12($27) // CSR0 + + li $9, 0xffff0000 + and $9, $25, $9 + andi $8, $26, 0xffff + or $20, $9, $8 // target address + + b xfer_d2i + li $19, 0x2000 // 16KB data length + +__ep0_prog_start2: + li $9, 0x48 // SVDOUTPKTRDY and DATAEND + sb $9, 0x12($27) // CSR0 + + li $9, 0xffff0000 + and $9, $25, $9 + andi $8, $26, 0xffff + or $20, $9, $8 // target address + + jalr $20 // jump, and place the return address in $31 + nop + +__ep0_prog_start2_return: + // User code can return to here after executing itself, by jumping to $31. + b usb_boot_return + nop + + //-------------------------------------------------------------- + // 2.1.2 Standard setup request + //-------------------------------------------------------------- +_ep0_std_req: + andi $12, $25, 0xff00 // check bRequest + srl $12, $12, 8 + sub $9, $12, 0x05 // check USB_REQ_SET_ADDRESS + bnez $9, __ep0_req_set_config + nop + + //-------------------------------------------------------------- + // Handle USB_REQ_SET_ADDRESS + //-------------------------------------------------------------- +__ep0_req_set_addr: + srl $9, $25, 16 // get wValue + sb $9, 0x0($27) // set FADDR + li $23, 1 // NoData = 1 + b _ep0_idle_state_fini + nop + +__ep0_req_set_config: + sub $9, $12, 0x09 // check USB_REQ_SET_CONFIGURATION + bnez $9, __ep0_req_get_desc + nop + + //-------------------------------------------------------------- + // Handle USB_REQ_SET_CONFIGURATION + //-------------------------------------------------------------- + li $23, 1 // NoData = 1 + b _ep0_idle_state_fini + nop + +__ep0_req_get_desc: + sub $9, $12, 0x06 // check USB_REQ_GET_DESCRIPTOR + bnez $9, _ep0_idle_state_fini + li $23, 1 // NoData = 1 + + //-------------------------------------------------------------- + // Handle USB_REQ_GET_DESCRIPTOR + //-------------------------------------------------------------- + li $23, 0 // NoData = 0 + + srl $9, $25, 24 // wValue >> 8 + sub $8, $9, 0x01 // check USB_DT_DEVICE + beqz $8, ___ep0_get_dev_desc + srl $21, $26, 16 // get wLength + sub $8, $9, 0x02 // check USB_DT_CONFIG + beqz $8, ___ep0_get_conf_desc + sub $8, $9, 0x03 // check USB_DT_STRING + beqz $8, ___ep0_get_string_desc + sub $8, $9, 0x06 // check USB_DT_DEVICE_QUALIFIER + beqz $8, ___ep0_get_dev_qualifier + nop + b _ep0_idle_state_fini + nop + +___ep0_get_dev_desc: + load_addr $20, device_desc // data pointer + li $22, 1 // set EP0 to TX state + sub $8, $21, 18 + blez $8, _ep0_idle_state_fini // wLength <= 18 + nop + li $21, 18 // max length of device_desc + b _ep0_idle_state_fini + nop + +___ep0_get_dev_qualifier: + load_addr $20, dev_qualifier // data pointer + li $22, 1 // set EP0 to TX state + sub $8, $21, 10 + blez $8, _ep0_idle_state_fini // wLength <= 10 + nop + li $21, 10 // max length of dev_qualifier + b _ep0_idle_state_fini + nop + +___ep0_get_conf_desc: + load_addr $20, config_desc_fs // data pointer of FS mode + lbu $8, 0x01($27) // read POWER + andi $8, 0x10 // test HS_MODE + beqz $8, ___ep0_get_conf_desc2 + nop + load_addr $20, config_desc_hs // data pointer of HS mode + +___ep0_get_conf_desc2: + li $22, 1 // set EP0 to TX state + sub $8, $21, 32 + blez $8, _ep0_idle_state_fini // wLength <= 32 + nop + li $21, 32 // max length of config_desc + b _ep0_idle_state_fini + nop + +___ep0_get_string_desc: + li $22, 1 // set EP0 to TX state + + srl $9, $25, 16 // wValue & 0xff + andi $9, 0xff + + sub $8, $9, 1 + beqz $8, ___ep0_get_string_manufacture + sub $8, $9, 2 + beqz $8, ___ep0_get_string_product + nop + +___ep0_get_string_lang_ids: + load_addr $20, string_lang_ids // data pointer + b _ep0_idle_state_fini + li $21, 4 // data length + +___ep0_get_string_manufacture: + load_addr $20, string_manufacture // data pointer + b _ep0_idle_state_fini + li $21, 16 // data length + +___ep0_get_string_product: + load_addr $20, string_product // data pointer + b _ep0_idle_state_fini + li $21, 46 // data length + +_ep0_idle_state_fini: + li $9, 0x40 // SVDOUTPKTRDY + beqz $23, _ep0_idle_state_fini2 + nop + ori $9, $9, 0x08 // DATAEND +_ep0_idle_state_fini2: + sb $9, 0x12($27) // CSR0 + beqz $22, check_intr_ep1in + nop + + //-------------------------------------------------------------- + // 2.2 Handle EP0 TX state interrupt + //-------------------------------------------------------------- +ep0_tx_state: + sub $9, $22, 1 + bnez $9, check_intr_ep1in + nop + + sub $9, $21, 64 // max packetsize + blez $9, _ep0_tx_state2 // data count <= 64 + ori $19, $21, 0 + li $19, 64 + +_ep0_tx_state2: + beqz $19, _ep0_tx_state3 // send ZLP + ori $18, $19, 0 // record bytes to be transferred + sub $21, $21, $19 // decrement data count + +_ep0_fifo_write_loop: + lbu $9, 0($20) // read data + sb $9, 0x20($27) // load FIFO + sub $19, $19, 1 // decrement counter + bnez $19, _ep0_fifo_write_loop + addi $20, $20, 1 // increment data pointer + + sub $9, $18, 64 // max packetsize + beqz $9, _ep0_tx_state4 + nop + +_ep0_tx_state3: + // transferred bytes < max packetsize + li $9, 0x0a // set INPKTRDY and DATAEND + sb $9, 0x12($27) // CSR0 + li $22, 0 // set EP0 to IDLE state + b check_intr_ep1in + nop + +_ep0_tx_state4: + // transferred bytes == max packetsize + li $9, 0x02 // set INPKTRDY + sb $9, 0x12($27) // CSR0 + b check_intr_ep1in + nop + + //-------------------------------------------------------------- + // 3. Check and handle EP1 BULK-IN interrupt + //-------------------------------------------------------------- +check_intr_ep1in: + andi $9, $10, 0x2 // check EP1 IN interrupt + beqz $9, check_intr_ep1out + nop + +handle_epin1_intr: + li $9, 1 + sb $9, 0x0e($27) // set INDEX 1 + lbu $9, 0x12($27) // read INCSR + + andi $8, $9, 0x2 // check INCSR_FFNOTEMPT + bnez $8, _epin1_tx_state4 + nop + +_epin1_write_fifo: + lhu $9, 0x10($27) // get INMAXP + sub $8, $21, $9 + blez $8, _epin1_tx_state1 // bytes left <= INMAXP + ori $19, $21, 0 + ori $19, $9, 0 + +_epin1_tx_state1: + beqz $19, _epin1_tx_state4 // No data + nop + + sub $21, $21, $19 // decrement data count + + srl $5, $19, 2 // # of word + andi $6, $19, 0x3 // # of byte + beqz $5, _epin1_tx_state2 + nop + +_epin1_fifo_write_word: + lw $9, 0($20) // read data from source address + sw $9, 0x24($27) // write FIFO + sub $5, $5, 1 // decrement counter + bnez $5, _epin1_fifo_write_word + addiu $20, $20, 4 // increment dest address + +_epin1_tx_state2: + beqz $6, _epin1_tx_state3 + nop + +_epin1_fifo_write_byte: + lbu $9, 0($20) // read data from source address + sb $9, 0x24($27) // write FIFO + sub $6, $6, 1 // decrement counter + bnez $6, _epin1_fifo_write_byte + addiu $20, $20, 1 // increment dest address + +_epin1_tx_state3: + li $9, 0x1 + sb $9, 0x12($27) // INCSR, set INPKTRDY + +_epin1_tx_state4: + // nop + + //-------------------------------------------------------------- + // 4. Check and handle EP1 BULK-OUT interrupt + //-------------------------------------------------------------- +check_intr_ep1out: + lhu $9, 0x04($27) // read INTROUT + andi $9, 0x2 + beqz $9, check_status_next + nop + +handle_epout1_intr: + li $9, 1 + sb $9, 0x0e($27) // set INDEX 1 + + lbu $9, 0x16($27) // read OUTCSR + andi $9, 0x1 // check OUTPKTRDY + beqz $9, check_status_next + nop + +_epout1_read_fifo: + lhu $19, 0x18($27) // read OUTCOUNT + srl $5, $19, 2 // # of word + andi $6, $19, 0x3 // # of byte + beqz $5, _epout1_rx_state1 + nop + +_epout1_fifo_read_word: + lw $9, 0x24($27) // read FIFO + sw $9, 0($20) // store to dest address + sub $5, $5, 1 // decrement counter + bnez $5, _epout1_fifo_read_word + addiu $20, $20, 4 // increment dest address + +_epout1_rx_state1: + beqz $6, _epout1_rx_state2 + nop + +_epout1_fifo_read_byte: + lbu $9, 0x24($27) // read FIFO + sb $9, 0($20) // store to dest address + sub $6, $6, 1 // decrement counter + bnez $6, _epout1_fifo_read_byte + addiu $20, $20, 1 // increment dest address + +_epout1_rx_state2: + sb $0, 0x16($27) // clear OUTPKTRDY + +check_status_next: + b usb_command_loop + nop + +//-------------------------------------------------------------- +// Device/Configuration/Interface/Endpoint/String Descriptors +//-------------------------------------------------------------- + + .align 2 +device_desc: + .byte 0x12 // bLength + .byte 0x01 // bDescriptorType + .byte 0x00 // bcdUSB + .byte 0x02 // bcdUSB + .byte 0x00 // bDeviceClass + .byte 0x00 // bDeviceSubClass + .byte 0x00 // bDeviceProtocol + .byte 0x40 // bMaxPacketSize0 + .byte 0x1a // idVendor + .byte 0x60 // idVendor + .byte 0x40 // idProduct + .byte 0x47 // idProduct + .byte 0x00 // bcdDevice + .byte 0x01 // bcdDevice + .byte 0x01 // iManufacturer + .byte 0x02 // iProduct + .byte 0x00 // iSerialNumber + .byte 0x01 // bNumConfigurations + + .align 2 +dev_qualifier: + .byte 0x0a // bLength + .byte 0x06 // bDescriptorType + .byte 0x00 // bcdUSB + .byte 0x02 // bcdUSB + .byte 0x00 // bDeviceClass + .byte 0x00 // bDeviceSubClass + .byte 0x00 // bDeviceProtocol + .byte 0x40 // bMaxPacketSize0 + .byte 0x01 // bNumConfigurations + .byte 0x00 // bRESERVED + + .align 2 +config_desc_hs: + .byte 0x09 // bLength + .byte 0x02 // bDescriptorType + .byte 0x20 // wTotalLength + .byte 0x00 // wTotalLength + .byte 0x01 // bNumInterfaces + .byte 0x01 // bConfigurationValue + .byte 0x00 // iConfiguration + .byte 0xc0 // bmAttributes + .byte 0x01 // MaxPower +intf_desc_hs: + .byte 0x09 // bLength + .byte 0x04 // bDescriptorType + .byte 0x00 // bInterfaceNumber + .byte 0x00 // bAlternateSetting + .byte 0x02 // bNumEndpoints + .byte 0xff // bInterfaceClass + .byte 0x00 // bInterfaceSubClass + .byte 0x50 // bInterfaceProtocol + .byte 0x00 // iInterface +ep1_desc_hs: + .byte 0x07 // bLength + .byte 0x05 // bDescriptorType + .byte 0x01 // bEndpointAddress + .byte 0x02 // bmAttributes + .byte 0x00 // wMaxPacketSize + .byte 0x02 // wMaxPacketSize + .byte 0x00 // bInterval +ep2_desc_hs: + .byte 0x07 // bLength + .byte 0x05 // bDescriptorType + .byte 0x81 // bEndpointAddress + .byte 0x02 // bmAttributes + .byte 0x00 // wMaxPacketSize + .byte 0x02 // wMaxPacketSize + .byte 0x00 // bInterval + + .align 2 +config_desc_fs: + .byte 0x09 // bLength + .byte 0x02 // bDescriptorType + .byte 0x20 // wTotalLength + .byte 0x00 // wTotalLength + .byte 0x01 // bNumInterfaces + .byte 0x01 // bConfigurationValue + .byte 0x00 // iConfiguration + .byte 0xc0 // bmAttributes + .byte 0x01 // MaxPower +intf_desc_fs: + .byte 0x09 // bLength + .byte 0x04 // bDescriptorType + .byte 0x00 // bInterfaceNumber + .byte 0x00 // bAlternateSetting + .byte 0x02 // bNumEndpoints + .byte 0xff // bInterfaceClass + .byte 0x00 // bInterfaceSubClass + .byte 0x50 // bInterfaceProtocol + .byte 0x00 // iInterface +ep1_desc_fs: + .byte 0x07 // bLength + .byte 0x05 // bDescriptorType + .byte 0x01 // bEndpointAddress + .byte 0x02 // bmAttributes + .byte 0x40 // wMaxPacketSize + .byte 0x00 // wMaxPacketSize + .byte 0x00 // bInterval +ep2_desc_fs: + .byte 0x07 // bLength + .byte 0x05 // bDescriptorType + .byte 0x81 // bEndpointAddress + .byte 0x02 // bmAttributes + .byte 0x40 // wMaxPacketSize + .byte 0x00 // wMaxPacketSize + .byte 0x00 // bInterval + + .align 2 +string_lang_ids: + .byte 0x04 + .byte 0x03 + .byte 0x09 + .byte 0x04 + + .align 2 +string_manufacture: + .byte 0x10 + .byte 0x03 + .byte 0x49 + .byte 0x00 + .byte 0x6e + .byte 0x00 + .byte 0x67 + .byte 0x00 + .byte 0x65 + .byte 0x00 + .byte 0x6e + .byte 0x00 + .byte 0x69 + .byte 0x00 + .byte 0x63 + .byte 0x00 + + .align 2 +string_product: + .byte 0x2e + .byte 0x03 + .byte 0x4a + .byte 0x00 + .byte 0x5a + .byte 0x00 + .byte 0x34 + .byte 0x00 + .byte 0x37 + .byte 0x00 + .byte 0x34 + .byte 0x00 + .byte 0x30 + .byte 0x00 + .byte 0x20 + .byte 0x00 + .byte 0x55 + .byte 0x00 + .byte 0x53 + .byte 0x00 + .byte 0x42 + .byte 0x00 + .byte 0x20 + .byte 0x00 + .byte 0x42 + .byte 0x00 + .byte 0x6f + .byte 0x00 + .byte 0x6f + .byte 0x00 + .byte 0x74 + .byte 0x00 + .byte 0x20 + .byte 0x00 + .byte 0x44 + .byte 0x00 + .byte 0x65 + .byte 0x00 + .byte 0x76 + .byte 0x00 + .byte 0x69 + .byte 0x00 + .byte 0x63 + .byte 0x00 + .byte 0x65 + .byte 0x00 + + .align 2 +cpu_info_data: + .byte 0x4a + .byte 0x5a + .byte 0x34 + .byte 0x37 + .byte 0x34 + .byte 0x30 + .byte 0x56 + .byte 0x31 +usbboot_end: + + .set reorder -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
[parent not found: <1289446657-12499-3-git-send-email-xiangfu@openmobilefree.net>]
* [U-Boot] [PATCH 3/5] jz4740 nand spl files [not found] ` <1289446657-12499-3-git-send-email-xiangfu@openmobilefree.net> @ 2010-11-11 3:37 ` Xiangfu Liu 2010-11-11 3:37 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Xiangfu Liu ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Xiangfu Liu @ 2010-11-11 3:37 UTC (permalink / raw) To: u-boot From: Xiangfu Liu <xiangfu@sharism.cc> Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net> --- nand_spl/board/xburst/nanonote/Makefile | 96 +++++++ nand_spl/board/xburst/nanonote/u-boot.lds | 63 +++++ nand_spl/nand_boot_jz4740.c | 395 +++++++++++++++++++++++++++++ 3 files changed, 554 insertions(+), 0 deletions(-) create mode 100644 nand_spl/board/xburst/nanonote/Makefile create mode 100644 nand_spl/board/xburst/nanonote/u-boot.lds create mode 100644 nand_spl/nand_boot_jz4740.c diff --git a/nand_spl/board/xburst/nanonote/Makefile b/nand_spl/board/xburst/nanonote/Makefile new file mode 100644 index 0000000..f5d1eb5 --- /dev/null +++ b/nand_spl/board/xburst/nanonote/Makefile @@ -0,0 +1,96 @@ +# +# (C) Copyright 2006 +# Stefan Roese, DENX Software Engineering, sr at denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk +TEXT_BASE = 0x80000000 + +LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds +LDFLAGS = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) +AFLAGS += -DCONFIG_NAND_SPL +CFLAGS += -DCONFIG_NAND_SPL -O2 + +SOBJS = start.o usbboot.o +COBJS = nand_boot_jz4740.o cpu.o jz4740.o jz_serial.o + +SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +__OBJS := $(SOBJS) $(COBJS) +LNDIR := $(OBJTREE)/nand_spl/board/$(BOARDDIR) + +nandobj := $(OBJTREE)/nand_spl/ + +ALL = $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin +all: $(obj).depend $(ALL) + +$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl.bin + dd bs=1024 count=8 if=/dev/zero of=$(nandobj)junk1 + cat $< $(nandobj)junk1 > $(nandobj)junk2 + dd bs=1024 count=8 if=$(nandobj)junk2 of=$(nandobj)junk3 + cat $(nandobj)junk3 $(nandobj)junk3 > $(nandobj)junk4 + dd bs=1024 count=256 if=/dev/zero of=$(nandobj)junk5 + cat $(nandobj)junk4 $(nandobj)junk5 > $(nandobj)junk6 + dd bs=1024 count=256 if=$(nandobj)junk6 of=$@ + rm -f $(nandobj)junk* + +$(nandobj)u-boot-spl.bin: $(nandobj)u-boot-spl + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + +$(nandobj)u-boot-spl: $(OBJS) + cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ + -Map $(nandobj)u-boot-spl.map \ + -o $(nandobj)u-boot-spl + +# create symbolic links for common files +$(obj)start.S: + @rm -f $(obj)start.S + ln -s $(SRCTREE)/arch/mips/cpu/xburst/start_spl.S $(obj)start.S + +$(obj)usbboot.S: + @rm -f $(obj)usbboot.S + ln -s $(SRCTREE)/arch/mips/cpu/xburst/usbboot.S $(obj)usbboot.S + +$(obj)cpu.c: + @rm -f $(obj)cpu.c + ln -s $(SRCTREE)/arch/mips/cpu/xburst/cpu.c $(obj)cpu.c + +$(obj)jz4740.c: + @rm -f $(obj)jz4740.c + ln -s $(SRCTREE)/arch/mips/cpu/xburst/jz4740.c $(obj)jz4740.c + +$(obj)jz_serial.c: + @rm -f $(obj)jz_serial.c + ln -s $(SRCTREE)/arch/mips/cpu/xburst/jz_serial.c $(obj)jz_serial.c + +$(obj)nand_boot_jz4740.c: + @rm -f $(obj)nand_boot_jz4740.c + ln -s $(SRCTREE)/nand_spl/nand_boot_jz4740.c $(obj)nand_boot_jz4740.c + +$(obj)%.o: $(obj)%.S + $(CC) $(AFLAGS) -c -o $@ $< + +$(obj)%.o: $(obj)%.c + $(CC) $(CFLAGS) -c -o $@ $< + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend diff --git a/nand_spl/board/xburst/nanonote/u-boot.lds b/nand_spl/board/xburst/nanonote/u-boot.lds new file mode 100644 index 0000000..7042388 --- /dev/null +++ b/nand_spl/board/xburst/nanonote/u-boot.lds @@ -0,0 +1,63 @@ +/* + * (C) Copyright 2005 + * 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 : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .sdata : { *(.sdata) } + + _gp = ALIGN(16); + + __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) } + uboot_end = .; +} diff --git a/nand_spl/nand_boot_jz4740.c b/nand_spl/nand_boot_jz4740.c new file mode 100644 index 0000000..44fe95d --- /dev/null +++ b/nand_spl/nand_boot_jz4740.c @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2007 Ingenic Semiconductor Inc. + * Author: Peter <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 <common.h> +#include <nand.h> + +#include <asm/jz4740.h> + +#define KEY_U_OUT (32 * 2 + 16) +#define KEY_U_IN (32 * 3 + 19) + +/* + * NAND flash definitions + */ +#define NAND_DATAPORT 0xb8000000 +#define NAND_ADDRPORT 0xb8010000 +#define NAND_COMMPORT 0xb8008000 + +#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1) +#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1)) +#define __nand_ecc_rs_encoding() \ + (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING) +#define __nand_ecc_rs_decoding() \ + (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_DECODING) +#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE) +#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF)) +#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF)) +#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n)) +#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n)) +#define __nand_data8() REG8(NAND_DATAPORT) +#define __nand_data16() REG16(NAND_DATAPORT) + +#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3) + #define NAND_BUS_WIDTH 8 + #define NAND_ROW_CYCLE 3 +#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2) + #define NAND_BUS_WIDTH 8 + #define NAND_ROW_CYCLE 2 +#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3) + #define NAND_BUS_WIDTH 16 + #define NAND_ROW_CYCLE 3 +#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2) + #define NAND_BUS_WIDTH 16 + #define NAND_ROW_CYCLE 2 +#endif + +static inline void __nand_dev_ready(void) +{ + unsigned int timeout = 10000; + while ((REG_GPIO_PXPIN(2) & 0x40000000) && timeout--); + while (!(REG_GPIO_PXPIN(2) & 0x40000000)); +} + +/* + * NAND flash parameters + */ +static int page_size = 2048; +static int oob_size = 64; +static int ecc_count = 4; +static int page_per_block = 64; +static int bad_block_pos = 0; +static int block_size = 131072; +static unsigned char oob_buf[128] = {0}; + +/* + * External routines + */ +extern void flush_cache_all(void); +extern int serial_init(void); +extern void serial_puts(const char *s); +extern void sdram_init(void); +extern void pll_init(void); +extern void usb_boot(); + +/* + * NAND flash routines + */ +#if NAND_BUS_WIDTH == 16 +static inline void nand_read_buf16(void *buf, int count) +{ + int i; + u16 *p = (u16 *)buf; + + for (i = 0; i < count; i += 2) + *p++ = __nand_data16(); +} +#define nand_read_buf nand_read_buf16 + +#elif NAND_BUS_WIDTH == 8 +static inline void nand_read_buf8(void *buf, int count) +{ + int i; + u8 *p = (u8 *)buf; + + for (i = 0; i < count; i++) + *p++ = __nand_data8(); +} +#define nand_read_buf nand_read_buf8 + +#endif + +/* Correct 1~9-bit errors in 512-bytes data */ +static void 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 nand_read_oob(int page_addr, uchar *buf, int size) +{ + int col_addr; + if (page_size != 512) + col_addr = page_size; + else { + col_addr = 0; + __nand_dev_ready(); + } + + if (page_size != 512) + /* Send READ0 command */ + __nand_cmd(NAND_CMD_READ0); + else + /* Send READOOB command */ + __nand_cmd(NAND_CMD_READOOB); + + /* Send column address */ + __nand_addr(col_addr & 0xff); + if (page_size != 512) + __nand_addr((col_addr >> 8) & 0xff); + + /* Send page address */ + __nand_addr(page_addr & 0xff); + __nand_addr((page_addr >> 8) & 0xff); + #if defined NAND_ROW_CYCLE && NAND_ROW_CYCLE == 3 + __nand_addr((page_addr >> 16) & 0xff); + #endif + + /* Send READSTART command for 2048 or 4096 ps NAND */ + if (page_size != 512) + __nand_cmd(NAND_CMD_READSTART); + + /* Wait for device ready */ + __nand_dev_ready(); + + /* Read oob data */ + nand_read_buf(buf, size); + if (page_size == 512) + __nand_dev_ready(); + return 0; +} + +static int nand_read_page(int page_addr, uchar *dst, uchar *oobbuf) +{ + uchar *databuf = dst, *tmpbuf; + int i, j; + + /* + * Read oob data + */ + nand_read_oob(page_addr, oobbuf, oob_size); + + /* + * Read page data + */ + /* Send READ0 command */ + __nand_cmd(NAND_CMD_READ0); + + /* Send column address */ + __nand_addr(0); + if (page_size != 512) + __nand_addr(0); + + /* Send page address */ + __nand_addr(page_addr & 0xff); + __nand_addr((page_addr >> 8) & 0xff); + #if defined NAND_ROW_CYCLE && NAND_ROW_CYCLE == 3 + __nand_addr((page_addr >> 16) & 0xff); + #endif + + /* Send READSTART command for 2048 or 4096 ps NAND */ + if (page_size != 512) + __nand_cmd(NAND_CMD_READSTART); + + /* Wait for device ready */ + __nand_dev_ready(); + + /* Read page data */ + tmpbuf = databuf; + + for (i = 0; i < ecc_count; i++) { + volatile unsigned char *paraddr = (volatile unsigned char *)EMC_NFPAR0; + unsigned int stat; + + /* Enable RS decoding */ + REG_EMC_NFINTS = 0x0; + __nand_ecc_rs_decoding(); + + /* Read data */ + nand_read_buf((void *)tmpbuf, CONFIG_SYS_NAND_ECCSIZE); + + /* Set PAR values */ + for (j = 0; j < CONFIG_SYS_NAND_ECCBYTES; j++) + *paraddr++ = oobbuf[CONFIG_SYS_NAND_ECC_POS + i*CONFIG_SYS_NAND_ECCBYTES + j]; + + /* Set PRDY */ + REG_EMC_NFECR |= EMC_NFECR_PRDY; + + /* Wait for completion */ + __nand_ecc_decode_sync(); + + /* Disable decoding */ + __nand_ecc_disable(); + + /* Check result of decoding */ + stat = REG_EMC_NFINTS; + if (stat & EMC_NFINTS_ERR) { + /* Error occurred */ + /* serial_puts("Error occurred\n"); */ + if (stat & EMC_NFINTS_UNCOR) { + /* Uncorrectable error occurred */ + /* serial_puts("Uncorrectable error occurred\n"); */ + } else { + unsigned int errcnt, index, mask; + + errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT; + switch (errcnt) { + case 4: + index = (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; + mask = (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; + rs_correct(tmpbuf, index, mask); + /* FALL-THROUGH */ + case 3: + index = (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; + mask = (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; + rs_correct(tmpbuf, index, mask); + /* FALL-THROUGH */ + case 2: + index = (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; + mask = (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; + rs_correct(tmpbuf, index, mask); + /* FALL-THROUGH */ + case 1: + index = (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; + mask = (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; + rs_correct(tmpbuf, index, mask); + break; + default: + break; + } + } + } + tmpbuf += CONFIG_SYS_NAND_ECCSIZE; + } + + return 0; +} + +#ifndef CONFIG_SYS_NAND_BADBLOCK_PAGE +#define CONFIG_SYS_NAND_BADBLOCK_PAGE 0 /* NAND bad block was marked at this page in a block, starting from 0 */ +#endif + +static void nand_load(int offs, int uboot_size, uchar *dst) +{ + int page; + int pagecopy_count; + + __nand_enable(); + + page = offs / page_size; + pagecopy_count = 0; + while (pagecopy_count < (uboot_size / page_size)) { + if (page % page_per_block == 0) { + nand_read_oob(page + CONFIG_SYS_NAND_BADBLOCK_PAGE, oob_buf, oob_size); + if (oob_buf[bad_block_pos] != 0xff) { + page += page_per_block; + /* Skip bad block */ + continue; + } + } + /* Load this page to dst, do the ECC */ + nand_read_page(page, dst, oob_buf); + + dst += page_size; + page++; + pagecopy_count++; + } + + __nand_disable(); +} + +static void jz_nand_init(void) { + /* Optimize the timing of nand */ + REG_EMC_SMCR1 = 0x094c4400; +} + +static void gpio_init(void) +{ + /* + * Initialize SDRAM pins + */ + __gpio_as_sdram_16bit_4720(); + + /* + * Initialize UART0 pins + */ + __gpio_as_uart0(); + __gpio_jtag_to_uart0(); +} + +static int is_usb_boot() +{ + __gpio_as_input(KEY_U_IN); + __gpio_enable_pull(KEY_U_IN); + __gpio_as_output(KEY_U_OUT); + __gpio_clear_pin(KEY_U_OUT); + + if (__gpio_get_pin(KEY_U_IN) == 0) + return 1; + + return 0; +} + +void nand_boot(void) +{ + void (*uboot)(void); + + /* + * Init hardware + */ + gpio_init(); + pll_init(); + + serial_init(); + sdram_init(); + jz_nand_init(); + + serial_puts("\nNAND Boot\n"); + +#if defined(CONFIG_NANONOTE) + if(is_usb_boot()) { + serial_puts("[U] pressed, goto USBBOOT mode\n"); + usb_boot(); + } +#endif + page_size = CONFIG_SYS_NAND_PAGE_SIZE; + block_size = CONFIG_SYS_NAND_BLOCK_SIZE; + page_per_block = CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE; + bad_block_pos = (page_size == 512) ? 5 : 0; + oob_size = page_size / 32; + ecc_count = page_size / CONFIG_SYS_NAND_ECCSIZE; + + /* + * Load U-Boot image from NAND into RAM + */ + nand_load(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, + (uchar *)CONFIG_SYS_NAND_U_BOOT_DST); + + uboot = (void (*)(void))CONFIG_SYS_NAND_U_BOOT_START; + + serial_puts("Starting U-Boot ...\n"); + + /* Flush caches */ + flush_cache_all(); + + /* Jump to U-Boot image */ + (*uboot)(); +} -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 4/5] jz4740 nand driver 2010-11-11 3:37 ` [U-Boot] [PATCH 3/5] jz4740 nand spl files Xiangfu Liu @ 2010-11-11 3:37 ` Xiangfu Liu 2010-11-11 3:37 ` [U-Boot] [PATCH 5/5] add Ben NanoNote board Xiangfu Liu 2010-11-15 23:02 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Scott Wood 2010-11-11 7:32 ` [U-Boot] [PATCH 3/5] jz4740 nand spl files Wolfgang Denk 2010-11-15 22:56 ` Scott Wood 2 siblings, 2 replies; 11+ messages in thread From: Xiangfu Liu @ 2010-11-11 3:37 UTC (permalink / raw) To: u-boot From: Xiangfu Liu <xiangfu@sharism.cc> Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net> --- drivers/mtd/nand/jz4740_nand.c | 250 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 250 insertions(+), 0 deletions(-) create mode 100644 drivers/mtd/nand/jz4740_nand.c diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c new file mode 100644 index 0000000..f661b36 --- /dev/null +++ b/drivers/mtd/nand/jz4740_nand.c @@ -0,0 +1,250 @@ +/* + * 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> + +#if defined(CONFIG_CMD_NAND) +#include <nand.h> +#include <asm/io.h> +#include <asm/jz4740.h> + +#define __nand_ecc_enable() (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST ) +#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE) + +#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) + +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; + + 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; + + if (ctrl & NAND_NCE) + REG_EMC_NFCSR |= EMC_NFCSR_NFCE1; + else + REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1; + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); +} + +static int jz_nand_device_ready(struct mtd_info *mtd) +{ + udelay(20); + return (REG_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 reg, status; + int i; + volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0; + + if(is_reading) + return 0; + + do { + status = REG_EMC_NFINTS; + } while(!(status & EMC_NFINTS_ENCF)); + + __nand_ecc_disable(); + + for(i = 0; i < 9; i++) + ecc_code[i] = *(paraddr + i); + + return 0; +} + +static void jz_nand_hwctl(struct mtd_info* mtd, int mode) +{ + uint32_t reg; + REG_EMC_NFINTS = 0; + reg = REG_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; + } + + REG_EMC_NFECR = reg; +} + +/* 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 reg, status; + volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0; + + /* Set PAR values */ + static 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++) + *(paraddr + k) = all_ff_ecc[k]; + } else { + + for (k = 0; k < 9; k++) + *(paraddr + k) = read_ecc[k]; + } + /* Set PRDY */ + REG_EMC_NFECR |= EMC_NFECR_PRDY; + + /* Wait for completion */ + do { + status = REG_EMC_NFINTS; + } while (!(status & EMC_NFINTS_DECF)); + + __nand_ecc_disable(); + + /* Check decoding */ + if (status & EMC_NFINTS_ERR) { + if (status & EMC_NFINTS_UNCOR) { + printk("uncorrectable ecc\n"); + while(1); + return -1; + } + + uint32_t errcnt = (status & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT; + switch (errcnt) { + case 4: + jz_rs_correct(dat, + (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, + (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT); + case 3: + jz_rs_correct(dat, + (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, + (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT); + case 2: + jz_rs_correct(dat, + (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, + (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT); + case 1: + jz_rs_correct(dat, + (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, + (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT); + return errcnt; + default: + break; + } + } + + return 0; +} + +/* + * Main initialization routine + */ +int board_nand_init(struct nand_chip *nand) +{ + /* EMC setup, Set NFE bit */ + REG_EMC_NFCSR |= EMC_NFCSR_NFE1; + REG_EMC_SMCR1 = 0x094c4400; + /* REG_EMC_SMCR3 = 0x04444400; */ + + 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; + + return 0; +} +#endif /* (CONFIG_CMD_NAND) */ -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 5/5] add Ben NanoNote board 2010-11-11 3:37 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Xiangfu Liu @ 2010-11-11 3:37 ` Xiangfu Liu 2010-11-11 8:28 ` Wolfgang Denk 2010-11-15 23:02 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Scott Wood 1 sibling, 1 reply; 11+ messages in thread From: Xiangfu Liu @ 2010-11-11 3:37 UTC (permalink / raw) To: u-boot From: Xiangfu Liu <xiangfu@sharism.cc> Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net> --- board/xburst/nanonote/Makefile | 45 ++++++++ board/xburst/nanonote/config.mk | 31 ++++++ board/xburst/nanonote/nanonote.c | 124 ++++++++++++++++++++++ board/xburst/nanonote/u-boot-nand.lds | 63 +++++++++++ include/configs/nanonote.h | 188 +++++++++++++++++++++++++++++++++ include/configs/qi_lb60.h | 28 +++++ 6 files changed, 479 insertions(+), 0 deletions(-) create mode 100644 board/xburst/nanonote/Makefile create mode 100644 board/xburst/nanonote/config.mk create mode 100644 board/xburst/nanonote/nanonote.c create mode 100644 board/xburst/nanonote/u-boot-nand.lds create mode 100644 include/configs/nanonote.h create mode 100644 include/configs/qi_lb60.h diff --git a/board/xburst/nanonote/Makefile b/board/xburst/nanonote/Makefile new file mode 100644 index 0000000..a4f6bd0 --- /dev/null +++ b/board/xburst/nanonote/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).a + +COBJS := $(BOARD).o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +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/xburst/nanonote/config.mk b/board/xburst/nanonote/config.mk new file mode 100644 index 0000000..858e6a2 --- /dev/null +++ b/board/xburst/nanonote/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/xburst/nanonote/nanonote.c b/board/xburst/nanonote/nanonote.c new file mode 100644 index 0000000..ef9552a --- /dev/null +++ b/board/xburst/nanonote/nanonote.c @@ -0,0 +1,124 @@ +/* + * 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. + */ + +#include <common.h> +#include <command.h> +#include <asm/mipsregs.h> +#include <asm/jz4740.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void gpio_init(void) +{ + /* + * 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 + */ + unsigned int i; + 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); + } + + /* enable the TP4, TP5 as UART0 */ + __gpio_jtag_to_uart0(); + + /* + * Initialize UART0 pins, in Ben NanoNote uart0 and keyin8 use the + * same gpio, init the gpio as uart0 cause a keyboard bug. so for + * end user we disable the uart0 + */ + if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){ + /* if pressed [S] */ + printf("[S] pressed, enable UART0\n"); + gd->boot_option |= BOOT_WITH_ENABLE_UART; + __gpio_as_uart0(); + } else { + __gpio_as_input(GPIO_KEYIN_8); + __gpio_enable_pull(GPIO_KEYIN_8); + } + + __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); + + if (__gpio_get_pin(GPIO_KEYIN_BASE + 3) == 0) { + printf("[M] pressed, boot from sd card\n"); + gd->boot_option |= BOOT_FROM_SDCARD; + } +} + +static void cpm_init(void) +{ + __cpm_stop_ipu(); + __cpm_stop_cim(); + __cpm_stop_i2c(); + __cpm_stop_ssi(); + __cpm_stop_uart1(); + __cpm_stop_sadc(); + __cpm_stop_uhc(); + __cpm_stop_udc(); + __cpm_stop_aic1(); +/* __cpm_stop_aic2();*/ +} + +void board_early_init(void) +{ + gpio_init(); + cpm_init(); +} + +/* U-Boot common routines */ + +int checkboard (void) +{ + printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %d MHz)\n", + gd->cpu_clk / 1000000); + + return 0; /* success */ +} diff --git a/board/xburst/nanonote/u-boot-nand.lds b/board/xburst/nanonote/u-boot-nand.lds new file mode 100644 index 0000000..a15a96e --- /dev/null +++ b/board/xburst/nanonote/u-boot-nand.lds @@ -0,0 +1,63 @@ +/* + * (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 : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .sdata : { *(.sdata) } + + _gp = ALIGN(16); + + __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) } + uboot_end = .; +} diff --git a/include/configs/nanonote.h b/include/configs/nanonote.h new file mode 100644 index 0000000..648202e --- /dev/null +++ b/include/configs/nanonote.h @@ -0,0 +1,188 @@ +/* + * 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. + */ + +/* + * This file contains the configuration parameters for the NanoNote. + */ +#ifndef __CONFIG_NANONOTE_H +#define __CONFIG_NANONOTE_H + +#define CONFIG_MIPS32 1 /* MIPS32 CPU core */ +#define CONFIG_JZSOC 1 /* Jz SoC */ +#define CONFIG_JZ4740 1 /* Jz4740 SoC */ +#define CONFIG_NAND_JZ4740 +#define CONFIG_NANONOTE + +#define BOOT_FROM_SDCARD 1 +#define BOOT_WITH_ENABLE_UART (1 << 1) /* Vaule for global_data.h gd->boot_option */ + +#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 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 1 +#define CONFIG_BOARD_EARLY_INIT_F 1 +#define CONFIG_SYS_NO_FLASH 1 +#define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */ +#define CONFIG_ENV_OVERWRITE 1 + +#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL) +#define CONFIG_BOOTDELAY 0 +/* + * Command line configuration. + */ +#define CONFIG_CMD_BOOTD /* bootd */ +#define CONFIG_CMD_CONSOLE /* coninfo */ +#define CONFIG_CMD_ECHO /* echo arguments */ + +#define CONFIG_CMD_LOADB /* loadb */ +#define CONFIG_CMD_LOADS /* loads */ +#define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop mtest */ +#define CONFIG_CMD_MISC /* Misc functions like sleep etc*/ +#define CONFIG_CMD_RUN /* run command in env variable */ +#define CONFIG_CMD_SAVEENV /* saveenv */ +#define CONFIG_CMD_SETGETDCR /* DCR support on 4xx */ +#define CONFIG_CMD_SOURCE /* "source" command support */ +#define CONFIG_CMD_NAND + +/* + * Serial download configuration + */ +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CONFIG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_PROMPT "NanoNote# " /* Monitor Command Prompt */ +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +/* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args*/ + +#define CONFIG_SYS_MALLOC_LEN 896 * 1024 +#define CONFIG_SYS_BOOTPARAMS_LEN 128 * 1024 + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ +#define CONFIG_SYS_INIT_SP_OFFSET 0x400000 +#define CONFIG_SYS_LOAD_ADDR 0x80600000 /* default load address */ +#define CONFIG_SYS_MEMTEST_START 0x80100000 +#define CONFIG_SYS_MEMTEST_END 0x80800000 + +/* + * Environment + */ +#define CONFIG_ENV_IS_IN_NAND 1 /* use NAND for environment vars */ + +/* + * NAND FLASH configuration + */ +#define CONFIG_SYS_64BIT_VSPRINTF /* needed for nand_util.c */ + +/* NAND Boot config code */ +#define JZ4740_NANDBOOT_CFG JZ4740_NANDBOOT_B8R3 + +#define NANONOTE_NAND_SIZE 2 /* 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 CONFIG_SYS_NAND_PAGE_SIZE (2048 * NANONOTE_NAND_SIZE) +/* nand chip block size */ +#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * NANONOTE_NAND_SIZE << 10) +/* nand bad block was marked@this page in a block, start from 0 */ +#define CONFIG_SYS_NAND_BADBLOCK_PAGE 127 +/* 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_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.*/ + +/* + * 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) + +/* in board/nanonote/config.mk TEXT_BAS = 0x88000000 */ +#define CONFIG_SYS_MONITOR_BASE 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 */ +#endif /* __CONFIG_NANONOTE_H */ diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h new file mode 100644 index 0000000..29ec805 --- /dev/null +++ b/include/configs/qi_lb60.h @@ -0,0 +1,28 @@ +#ifndef __CONFIG_QI_LB60_H +#define __CONFIG_QI_LB60_H + +#include <configs/nanonote.h> + +#define CONFIG_QI_LB60 1 + +//#define DEBUG +#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait" +#define CONFIG_BOOTARGSFROMSD "mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait" +#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x200000;bootm" +#define CONFIG_BOOTCOMMANDFROMSD "mmc init; ext2load mmc 0 0x80600000 /boot/uImage; bootm" + +/* SDRAM paramters */ +#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */ +#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */ +#define SDRAM_ROW 13 /* Row address: 11 to 13 */ +#define SDRAM_COL 9 /* Column address: 8 to 12 */ +#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */ + +/* SDRAM Timings, unit: ns */ +#define SDRAM_TRAS 45 /* RAS# Active Time */ +#define SDRAM_RCD 20 /* RAS# to CAS# Delay */ +#define SDRAM_TPC 20 /* RAS# Precharge Time */ +#define SDRAM_TRWL 7 /* Write Latency Time */ +#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */ + +#endif -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 5/5] add Ben NanoNote board 2010-11-11 3:37 ` [U-Boot] [PATCH 5/5] add Ben NanoNote board Xiangfu Liu @ 2010-11-11 8:28 ` Wolfgang Denk 0 siblings, 0 replies; 11+ messages in thread From: Wolfgang Denk @ 2010-11-11 8:28 UTC (permalink / raw) To: u-boot Dear Xiangfu Liu, In message <1289446657-12499-6-git-send-email-xiangfu@openmobilefree.net> you wrote: > From: Xiangfu Liu <xiangfu@sharism.cc> > > Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net> > --- > board/xburst/nanonote/Makefile | 45 ++++++++ > board/xburst/nanonote/config.mk | 31 ++++++ > board/xburst/nanonote/nanonote.c | 124 ++++++++++++++++++++++ > board/xburst/nanonote/u-boot-nand.lds | 63 +++++++++++ > include/configs/nanonote.h | 188 +++++++++++++++++++++++++++++++++ > include/configs/qi_lb60.h | 28 +++++ > 6 files changed, 479 insertions(+), 0 deletions(-) > create mode 100644 board/xburst/nanonote/Makefile > create mode 100644 board/xburst/nanonote/config.mk > create mode 100644 board/xburst/nanonote/nanonote.c > create mode 100644 board/xburst/nanonote/u-boot-nand.lds > create mode 100644 include/configs/nanonote.h > create mode 100644 include/configs/qi_lb60.h Entry to MAINTAINERS mssing. Entry to boards.cfg missing. Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de Motto of the Electrical Engineer: Working computer hardware is a lot like an erect penis: it stays up as long as you don't fuck with it. ^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 4/5] jz4740 nand driver 2010-11-11 3:37 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Xiangfu Liu 2010-11-11 3:37 ` [U-Boot] [PATCH 5/5] add Ben NanoNote board Xiangfu Liu @ 2010-11-15 23:02 ` Scott Wood 1 sibling, 0 replies; 11+ messages in thread From: Scott Wood @ 2010-11-15 23:02 UTC (permalink / raw) To: u-boot On Thu, 11 Nov 2010 11:37:36 +0800 Xiangfu Liu <xiangfu@openmobilefree.net> wrote: > From: Xiangfu Liu <xiangfu@sharism.cc> > > Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net> > --- > drivers/mtd/nand/jz4740_nand.c | 250 ++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 250 insertions(+), 0 deletions(-) > create mode 100644 drivers/mtd/nand/jz4740_nand.c Same comments as on nand_spl. Also, this looks like the type of controller that could work with the standard nand_boot.c -- is there something preventing that? -Scott ^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 3/5] jz4740 nand spl files 2010-11-11 3:37 ` [U-Boot] [PATCH 3/5] jz4740 nand spl files Xiangfu Liu 2010-11-11 3:37 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Xiangfu Liu @ 2010-11-11 7:32 ` Wolfgang Denk 2010-11-15 22:56 ` Scott Wood 2 siblings, 0 replies; 11+ messages in thread From: Wolfgang Denk @ 2010-11-11 7:32 UTC (permalink / raw) To: u-boot Dear Xiangfu Liu, In message <1289446657-12499-4-git-send-email-xiangfu@openmobilefree.net> you wrote: > From: Xiangfu Liu <xiangfu@sharism.cc> > > Signed-off-by: Xiangfu Liu <xiangfu@openmobilefree.net> > --- > nand_spl/board/xburst/nanonote/Makefile | 96 +++++++ > nand_spl/board/xburst/nanonote/u-boot.lds | 63 +++++ > nand_spl/nand_boot_jz4740.c | 395 +++++++++++++++++++++++++++++ > 3 files changed, 554 insertions(+), 0 deletions(-) > create mode 100644 nand_spl/board/xburst/nanonote/Makefile > create mode 100644 nand_spl/board/xburst/nanonote/u-boot.lds > create mode 100644 nand_spl/nand_boot_jz4740.c You need to rework the splitting of your code into commits - as is, these patches make no sense to me. Please re-read http://www.denx.de/wiki/view/U-Boot/Patches#General_Patch_Submission_Rules > diff --git a/nand_spl/nand_boot_jz4740.c b/nand_spl/nand_boot_jz4740.c > new file mode 100644 ... > +#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1) > +#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1)) > +#define __nand_ecc_rs_encoding() \ > + (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING) > +#define __nand_ecc_rs_decoding() \ > + (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_DECODING) > +#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE) > +#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF)) > +#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF)) > +#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n)) > +#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n)) > +#define __nand_data8() REG8(NAND_DATAPORT) > +#define __nand_data16() REG16(NAND_DATAPORT) You seem to have a tendency to use "__" a lot in front of indentifiers. The C standard says: -- All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. -- All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. Please recheck your identifier names with this in mind. As mentioned before, this code needs to be converted to use I/O accessors instead of these REG*() volatile pointer accesses. Both comments apply globally. ... > + /* Check result of decoding */ > + stat = REG_EMC_NFINTS; > + if (stat & EMC_NFINTS_ERR) { > + /* Error occurred */ > + /* serial_puts("Error occurred\n"); */ > + if (stat & EMC_NFINTS_UNCOR) { > + /* Uncorrectable error occurred */ > + /* serial_puts("Uncorrectable error occurred\n"); */ > + } else { > + unsigned int errcnt, index, mask; > + > + errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT; > + switch (errcnt) { > + case 4: > + index = (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + /* FALL-THROUGH */ > + case 3: > + index = (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + /* FALL-THROUGH */ > + case 2: > + index = (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + /* FALL-THROUGH */ > + case 1: > + index = (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + break; Lines too long. I stop reviewing here. Please fix the code, and resubmit. Thanks. Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de There's no honorable way to kill, no gentle way to destroy. There is nothing good in war. Except its ending. -- Abraham Lincoln, "The Savage Curtain", stardate 5906.5 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 3/5] jz4740 nand spl files 2010-11-11 3:37 ` [U-Boot] [PATCH 3/5] jz4740 nand spl files Xiangfu Liu 2010-11-11 3:37 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Xiangfu Liu 2010-11-11 7:32 ` [U-Boot] [PATCH 3/5] jz4740 nand spl files Wolfgang Denk @ 2010-11-15 22:56 ` Scott Wood 2 siblings, 0 replies; 11+ messages in thread From: Scott Wood @ 2010-11-15 22:56 UTC (permalink / raw) To: u-boot On Thu, 11 Nov 2010 11:37:35 +0800 Xiangfu Liu <xiangfu@openmobilefree.net> wrote: > +$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl.bin > + dd bs=1024 count=8 if=/dev/zero of=$(nandobj)junk1 > + cat $< $(nandobj)junk1 > $(nandobj)junk2 > + dd bs=1024 count=8 if=$(nandobj)junk2 of=$(nandobj)junk3 > + cat $(nandobj)junk3 $(nandobj)junk3 > $(nandobj)junk4 > + dd bs=1024 count=256 if=/dev/zero of=$(nandobj)junk5 > + cat $(nandobj)junk4 $(nandobj)junk5 > $(nandobj)junk6 > + dd bs=1024 count=256 if=$(nandobj)junk6 of=$@ > + rm -f $(nandobj)junk* Why do you need all this? > +#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1) > +#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1)) > +#define __nand_ecc_rs_encoding() \ > + (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING) > +#define __nand_ecc_rs_decoding() \ > + (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_DECODING) > +#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE) > +#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF)) > +#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF)) > +#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n)) > +#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n)) > +#define __nand_data8() REG8(NAND_DATAPORT) > +#define __nand_data16() REG16(NAND_DATAPORT) Drop the leading underscores. Use I/O accessors. Consider making some of these inline functions -- or just open-coding for the really simple ones. > +#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3) > + #define NAND_BUS_WIDTH 8 > + #define NAND_ROW_CYCLE 3 > +#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2) > + #define NAND_BUS_WIDTH 8 > + #define NAND_ROW_CYCLE 2 > +#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3) > + #define NAND_BUS_WIDTH 16 > + #define NAND_ROW_CYCLE 3 > +#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2) > + #define NAND_BUS_WIDTH 16 > + #define NAND_ROW_CYCLE 2 > +#endif > + > +static inline void __nand_dev_ready(void) > +{ > + unsigned int timeout = 10000; > + while ((REG_GPIO_PXPIN(2) & 0x40000000) && timeout--); > + while (!(REG_GPIO_PXPIN(2) & 0x40000000)); > +} Hmm, why a timeout here and not on any of the other spin loops? > +/* > + * NAND flash parameters > + */ > +static int page_size = 2048; > +static int oob_size = 64; > +static int ecc_count = 4; > +static int page_per_block = 64; > +static int bad_block_pos = 0; > +static int block_size = 131072; You initialize these here, and then you set them to other constant values in nand_boot(). And then you test them for specific values later. What's going on? If you're not dynamically detecting these, then have them be constants (either #defines or "static const int"). It will allow the compiler to generate smaller code. > +static unsigned char oob_buf[128] = {0}; Be careful, this may still go into the BSS even with the assignment. Is the BSS getting cleared in the SPL boot code on this platform? Do you actually rely on it being zero initially? Either way, the assignment doesn't do much. > +/* > + * External routines > + */ > +extern void flush_cache_all(void); > +extern int serial_init(void); > +extern void serial_puts(const char *s); > +extern void sdram_init(void); > +extern void pll_init(void); > +extern void usb_boot(); Get these from the appropriate header file. > + /* Error occurred */ > + /* serial_puts("Error occurred\n"); */ > + if (stat & EMC_NFINTS_UNCOR) { > + /* Uncorrectable error occurred */ > + /* serial_puts("Uncorrectable error occurred\n"); */ Why is this commented out? If it's for space concerns, the strings could be shrunk and still get a message out. > + } else { > + unsigned int errcnt, index, mask; > + > + errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT; > + switch (errcnt) { > + case 4: > + index = (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + /* FALL-THROUGH */ > + case 3: > + index = (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + /* FALL-THROUGH */ > + case 2: > + index = (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + /* FALL-THROUGH */ > + case 1: > + index = (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT; > + mask = (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT; > + rs_correct(tmpbuf, index, mask); > + break; > + default: > + break; > + } Please keep lines under 80 columns. Consider factoring this chunk out to its own function. > + } > + } > + tmpbuf += CONFIG_SYS_NAND_ECCSIZE; > + } > + > + return 0; > +} > + > +#ifndef CONFIG_SYS_NAND_BADBLOCK_PAGE > +#define CONFIG_SYS_NAND_BADBLOCK_PAGE 0 /* NAND bad block was marked at this page in a block, starting from 0 */ > +#endif This isn't really an aspect of the controller, but of the flash chip. Many flash chips can have bad block markers in the first or second page of a block. > +static void nand_load(int offs, int uboot_size, uchar *dst) > +{ > + int page; > + int pagecopy_count; > + > + __nand_enable(); > + > + page = offs / page_size; > + pagecopy_count = 0; > + while (pagecopy_count < (uboot_size / page_size)) { Round up if uboot_size is not aligned? Any reason not to take the basic loop logic from nand_boot.c? > + if (page % page_per_block == 0) { > + nand_read_oob(page + CONFIG_SYS_NAND_BADBLOCK_PAGE, oob_buf, oob_size); > + if (oob_buf[bad_block_pos] != 0xff) { > + page += page_per_block; > + /* Skip bad block */ > + continue; > + } On 16-bit NAND isn't the bad-block marker 16-bit? > + } > + /* Load this page to dst, do the ECC */ > + nand_read_page(page, dst, oob_buf); > + > + dst += page_size; > + page++; > + pagecopy_count++; > + } > + > + __nand_disable(); > +} > + > +static void jz_nand_init(void) { Brace on its own line. > + /* Optimize the timing of nand */ > + REG_EMC_SMCR1 = 0x094c4400; > +} > + > +static void gpio_init(void) > +{ > + /* > + * Initialize SDRAM pins > + */ > + __gpio_as_sdram_16bit_4720(); > + > + /* > + * Initialize UART0 pins > + */ > + __gpio_as_uart0(); > + __gpio_jtag_to_uart0(); > +} > + > +static int is_usb_boot() > +{ > + __gpio_as_input(KEY_U_IN); > + __gpio_enable_pull(KEY_U_IN); > + __gpio_as_output(KEY_U_OUT); > + __gpio_clear_pin(KEY_U_OUT); > + > + if (__gpio_get_pin(KEY_U_IN) == 0) > + return 1; > + > + return 0; > +} > + > +void nand_boot(void) > +{ > + void (*uboot)(void); > + > + /* > + * Init hardware > + */ > + gpio_init(); > + pll_init(); > + > + serial_init(); > + sdram_init(); > + jz_nand_init(); > + > + serial_puts("\nNAND Boot\n"); > + > +#if defined(CONFIG_NANONOTE) > + if(is_usb_boot()) { Space after "if". > + serial_puts("[U] pressed, goto USBBOOT mode\n"); > + usb_boot(); > + } > +#endif I wonder how much of the above stuff belongs in nand_boot(), versus a board file. This file should focus on the NAND controller. > + page_size = CONFIG_SYS_NAND_PAGE_SIZE; > + block_size = CONFIG_SYS_NAND_BLOCK_SIZE; > + page_per_block = CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE; > + bad_block_pos = (page_size == 512) ? 5 : 0; > + oob_size = page_size / 32; > + ecc_count = page_size / CONFIG_SYS_NAND_ECCSIZE; > + > + /* > + * Load U-Boot image from NAND into RAM > + */ > + nand_load(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, > + (uchar *)CONFIG_SYS_NAND_U_BOOT_DST); Consider adding support for CONFIG_NAND_ENV_DST. -Scott ^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 1/5] those files are jz4740 base files 2010-11-11 3:37 ` [U-Boot] [PATCH 1/5] those files are jz4740 base files Xiangfu Liu [not found] ` <1289446657-12499-3-git-send-email-xiangfu@openmobilefree.net> @ 2010-11-11 7:14 ` Wolfgang Denk 2010-11-14 15:03 ` Shinya Kuribayashi 2 siblings, 0 replies; 11+ messages in thread From: Wolfgang Denk @ 2010-11-11 7:14 UTC (permalink / raw) To: u-boot Dear Xiangfu Liu, In message <1289446657-12499-2-git-send-email-xiangfu@openmobilefree.net> you wrote: > From: Xiangfu Liu <xiangfu@sharism.cc> Please use a more descriptive subject. Explain what jz4740 is; also explain what xburst is. Whos is be=hind it, what it's used for, etc. > diff --git a/arch/mips/cpu/xburst/interrupts.c b/arch/mips/cpu/xburst/interrupts.c > new file mode 100644 > index 0000000..87f7a9f > --- /dev/null > +++ b/arch/mips/cpu/xburst/interrupts.c ... > +void enable_interrupts(void) > +{ > +} > + > +int disable_interrupts(void) > +{ > + return 0; > +} It does not seem you are using interrupts? If so, then omit this file all together. > diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c > new file mode 100644 > index 0000000..b8e9a15 > --- /dev/null > +++ b/arch/mips/cpu/xburst/jz4740.c ... > + pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); Line too long. Please fix globally. > + /* Init USB Host clock, pllout2 must be n*48MHz */ > + REG_CPM_UHCCDR = pllout2 / 48000000 - 1; What's REG_CPM_UHCCDR? This symbol is not defined anywhere in this patch, which means that none of this code would ever compile. If you split patches, please make sure they contain complete, compilable code to make the commit bisectable. To me this looks as if you are implementing these register accesses as plain assignments to a volatile pointer, probably based on a register base address plus offset calculation. Please note that we will NOT accept any such code in U-Boot. Please use C structs to describe functional units, and use proper I/O accessors to access any such registers. Please fix globally. > +static void calc_clocks(void) > +{ > + DECLARE_GLOBAL_DATA_PTR; This does not work. DECLARE_GLOBAL_DATA_PTR must never be used in function scope; it must be used in file scope. > +static void rtc_init(void) > +{ > + while ( !__rtc_write_ready()) ; Please move semicolon to next line. > +#if 0 > + unsigned long rtcsta; > + > + while ( !__rtc_write_ready()) > + ; > + rtcsta = REG_RTC_HWRSR; > + while ( !__rtc_write_ready()) > + ; > + if (rtcsta & 0x33) { > + if (rtcsta & 0x10) { > + while ( !__rtc_write_ready()) > + ; > + REG_RTC_RSR = 0x0; > + } > + while ( !__rtc_write_ready()) > + ; > + REG_RTC_HWRSR = 0x0; > + } > +#endif Please remove all such dead code. > diff --git a/arch/mips/cpu/xburst/jz_serial.c b/arch/mips/cpu/xburst/jz_serial.c > new file mode 100644 > index 0000000..c5cc28e > --- /dev/null > +++ b/arch/mips/cpu/xburst/jz_serial.c > @@ -0,0 +1,139 @@ > +/* > + * Jz47xx UART support > + * > + * Hardcoded to UART 0 for now > + * Options also hardcoded to 8N1 > + * > + * Copyright (c) 2005 > + * 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> > + > +#if defined(CONFIG_JZ4740) > +#include <asm/jz4740.h> > +#endif > + > +#undef UART_BASE > +#ifndef CONFIG_SYS_UART_BASE > +#define UART_BASE UART0_BASE > +#else > +#define UART_BASE CONFIG_SYS_UART_BASE > +#endif This initial "#undef UART_BASE" looks fishy to me. Please explain why this is unavoidable here. > +/****************************************************************************** > +* > +* serial_init - initialize a channel Incorrect multiline comment style. Please fix globally. > +void serial_puts (const char *s) > +{ > + while (*s) { > + serial_putc (*s++); > + } No braces needed for single line statements. Please fix globally. > +int serial_getc (void) > +{ > + volatile u8 *uart_rdr = (volatile u8 *)(UART_BASE + OFF_RDR); > + > + while (!serial_tstc()); Please use a consistent style. Move the semicolon to the next line. Please fix globally. > +void __udelay (unsigned long usec) > +{ > + ulong tmo,tmp; > + > + /* normalize */ > + if (usec >= 1000) { > + tmo = usec / 1000; > + tmo *= TIMER_HZ; > + tmo /= 1000; > + } > + else { Incorrect brace style. > + if (usec >= 1) { > + tmo = usec * TIMER_HZ; > + tmo /= (1000*1000); > + } > + else Again. Please fix globally. > +usb_boot: > + //-------------------------------------------------------------- > + // Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. > + //-------------------------------------------------------------- > + la $9, 0xB0000000 // CPCCR: Clock Control Register > + la $8, 0x42041110 // I:S:M:P=1:2:2:2 > + sw $8, 0($9) C++ comments are not allowed in U-Boot. Please fix globally. Would it be possible to rewrite this file in C? Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de People have one thing in common: they are all different. ^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH 1/5] those files are jz4740 base files 2010-11-11 3:37 ` [U-Boot] [PATCH 1/5] those files are jz4740 base files Xiangfu Liu [not found] ` <1289446657-12499-3-git-send-email-xiangfu@openmobilefree.net> 2010-11-11 7:14 ` [U-Boot] [PATCH 1/5] those files are jz4740 base files Wolfgang Denk @ 2010-11-14 15:03 ` Shinya Kuribayashi 2 siblings, 0 replies; 11+ messages in thread From: Shinya Kuribayashi @ 2010-11-14 15:03 UTC (permalink / raw) To: u-boot On 11/11/2010 12:37 PM, Xiangfu Liu wrote: > From: Xiangfu Liu <xiangfu@sharism.cc> If possible, please describe what Jz4740 SoC is, an overview of JzRISC processor, where this patch is from or where to get the original work, and so on. It also would be nice we could have Signed-off-by: or Acked-by: from Ingenic people, as some files contains Ingenic copyright statements. Please consider. > diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk > new file mode 100644 > index 0000000..f43f53b > --- /dev/null > +++ b/arch/mips/cpu/xburst/config.mk > @@ -0,0 +1,33 @@ > +# > +# (C) Copyright 2003 > +# Wolfgang Denk, DENX Software Engineering, <wd@denx.de> > +# > +# See file CREDITS for list of people who contributed to this > +# project. > +# > +# This program is free software; you can redistribute it and/or > +# modify it under the terms of the GNU General Public License as > +# published by the Free Software Foundation; either version 2 of > +# the License, or (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, > +# MA 02111-1307 USA > +# > +v=$(shell $(AS) --version | grep 'GNU assembler' | egrep -o '2\.[0-9\.]+' | cut -d. -f2) > +MIPSFLAGS:=$(shell \ > +if [ "$v" -lt "14" ]; then \ > + echo "-mcpu=4kc"; \ > +else \ > + echo "-march=4kc -mtune=4kc"; \ > +fi) > + > +MIPSFLAGS += $(ENDIANNESS) -mabicalls -mips32 ENDIANNESS looks unused. Jz47xx series are little endian SoCs, then let's remove it. > +PLATFORM_CPPFLAGS += $(MIPSFLAGS) > diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c > new file mode 100644 > index 0000000..682debf > --- /dev/null > +++ b/arch/mips/cpu/xburst/cpu.c > @@ -0,0 +1,158 @@ [snip] > +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 = KSEG0; addr < KSEG0 + 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)); > +} As pointed out before, incorrect use of assembler control. Why set mips32 without pushing the current control info, and why set it back to mips2? 'noreorder' is also missing here. asm volatile ( ".set push\n\t" ".set noreorder\n\t" ".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 pop\n\t" : : "r" (t)); Hmm? > +void flush_dcache_all(void) > +{ > + u32 addr; > + > + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE; > + addr += CONFIG_SYS_CACHELINE_SIZE) { > + cache_op(Index_Writeback_Inv_D, addr); > + } > + > + asm volatile ("sync"); > +} > + > +void flush_cache_all(void) > +{ > + flush_dcache_all(); > + flush_icache_all(); > +} > diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c > new file mode 100644 > index 0000000..b8e9a15 > --- /dev/null > +++ b/arch/mips/cpu/xburst/jz4740.c I couldn't mention about its validity of the following DRAM init code from the technically POV. As long as it works for you, I'm ok. Most of the code looks well-written conforming to the coding styles. A few trivial cleanups, please. > @@ -0,0 +1,257 @@ > +/* > + * 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/jz4740.h> > + > +/* 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) > +{ > + 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); pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); > + /* Init USB Host clock, pllout2 must be n*48MHz */ > + REG_CPM_UHCCDR = pllout2 / 48000000 - 1; > + > + 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 */ > + REG_CPM_CPCCR = cfcr; > + REG_CPM_CPPCR = plcr1; > +} > + > +void sdram_init(void) > +{ > + 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()]; > + > + REG_EMC_BCR = 0; /* Disable bus release */ > + REG_EMC_RTCSR = 0; /* 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)]; Unless it breaks 80-charcter-wide rule, please provide whitespaces at proper places. 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)]; Ditto. > + /* 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 */ > + REG_EMC_DMCR = dmcr; > + REG8(EMC_SDMR0|sdmode) = 0; REG8(EMC_SDMR0 | sdmode) = 0; > + /* Wait for precharge, > 200us */ > + tmp = (cpu_clk / 1000000) * 1000; > + while (tmp--); > + > + /* Stage 2. Enable auto-refresh */ > + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH; > + > + tmp = SDRAM_TREF/ns; > + tmp = tmp/64 + 1; > + if (tmp > 0xff) tmp = 0xff; > + REG_EMC_RTCOR = tmp; > + REG_EMC_RTCNT = 0; > + REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ > + > + /* Wait for number of auto-refresh cycles */ > + tmp = (cpu_clk / 1000000) * 1000; > + while (tmp--); > + > + /* Stage 3. Mode Register Set */ > + REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET; > + REG8(EMC_SDMR0|sdmode) = 0; REG8(EMC_SDMR0 | sdmode) = 0; > + /* Set back to basic DMCR value */ > + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; > + > + /* everything is ok now */ > +} > + > +#ifndef CONFIG_NAND_SPL > + > +static void calc_clocks(void) > +{ > + DECLARE_GLOBAL_DATA_PTR; > + > + 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; > +} > + > +static void rtc_init(void) > +{ > + while ( !__rtc_write_ready()) ; > + __rtc_enable_alarm(); /* enable alarm */ > + > + while ( !__rtc_write_ready()) > + ; > + REG_RTC_RGR = 0x00007fff; /* type value */ > + > + while ( !__rtc_write_ready()) > + ; > + REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */ > + > + while ( !__rtc_write_ready()) > + ; > + REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */ > +#if 0 > + unsigned long rtcsta; > + > + while ( !__rtc_write_ready()) > + ; > + rtcsta = REG_RTC_HWRSR; > + while ( !__rtc_write_ready()) > + ; > + if (rtcsta & 0x33) { > + if (rtcsta & 0x10) { > + while ( !__rtc_write_ready()) > + ; > + REG_RTC_RSR = 0x0; > + } > + while ( !__rtc_write_ready()) > + ; > + REG_RTC_HWRSR = 0x0; > + } > +#endif Get rid of unused #if 0 code. > +} > + > +/* U-Boot common routines */ > +phys_size_t initdram(int board_type) > +{ > + u32 dmcr; > + u32 rows, cols, dw, banks; > + ulong size; > + > + dmcr = REG_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; > +} > + > +/* > + * jz4740 board init routine > + */ > +extern void board_early_init(void); > +int jz_board_init(void) > +{ > + board_early_init(); /* init gpio, pll etc. */ > +#ifndef CONFIG_NAND_U_BOOT > + pll_init(); /* init PLL */ > + sdram_init(); /* init sdram memory */ > +#endif > + calc_clocks(); /* calc the clocks */ > + rtc_init(); /* init rtc on any reset: */ > + return 0; > +} > + > +#endif /* CONFIG_NAND_SPL */ Inconsistent comment indentations. Use tabs, not spaces. > diff --git a/arch/mips/cpu/xburst/start.S b/arch/mips/cpu/xburst/start.S > new file mode 100644 > index 0000000..b05cc67 > --- /dev/null > +++ b/arch/mips/cpu/xburst/start.S > @@ -0,0 +1,165 @@ > +/* > + * 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> > + > +#include <asm/jz4740.h> > + > + .set noreorder > + > + .globl _start > + .text > +_start: > + /* Initialize GOT pointer. > + */ > + bal 1f > + nop > + .word _GLOBAL_OFFSET_TABLE_ > +1: > + lw gp, 0(ra) > + 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, TEXT_BASE > + la t3, in_ram > + lw t2, -12(t3) /* t2 <-- uboot_end_data */ > + move t1, a2 > + > + /* > + * Fix GOT pointer: > + * > + * New GOT-PTR = (old GOT-PTR - TEXT_BASE) + Destination Address > + */ > + move t6, gp > + sub gp, TEXT_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 /* delay slot */ > + > + /* If caches were enabled, we would have to flush them here. > + * flush d-cache */ > + .set push .Set push is expected to be followed by assembler control change(s). In this case, you probably want to set mips3 for CACHE instruction. > + 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 > + > + .set pop > + > + /* Jump to where we've relocated ourselves. > + */ > + addi t0, a2, in_ram - _start > + j t0 > + nop Use JR, not J. > + .word uboot_end_data > + .word uboot_end > + .word num_got_entries > + > +in_ram: > + /* Now we want to update GOT */ > + lw t3, -4(t0) /* t3 <-- num_got_entries */ > + addi t4, gp, 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 /* delay slot */ > + > + /* 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) /* delay slot */ > + > + move a0, a1 > + la t9, board_init_r > + j t9 > + move a1, a2 /* delay slot */ Use JR, not J. > + .end relocate_code > + > \ No newline at end of file I checked the diffs between cpu/start.S and cpu/xburst/start.S. The relocation code itself looks ok. > diff --git a/arch/mips/cpu/xburst/start_spl.S b/arch/mips/cpu/xburst/start_spl.S > new file mode 100644 > index 0000000..f775e3a > --- /dev/null > +++ b/arch/mips/cpu/xburst/start_spl.S > @@ -0,0 +1,63 @@ > +/* > + * 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 3 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> > + > +#include <asm/jz4740.h> > + > + .set noreorder > + > + .globl _start > + .text > +_start: > + .word JZ4740_NANDBOOT_CFG /* fetched during NAND Boot */ > +reset: > + /* > + * STATUS register > + * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1 > + */ > + li t0, 0x0040FC04 > + mtc0 t0, CP0_STATUS > + /* CAUSE register > + * IV=1, use the specical interrupt vector (0x200) */ > + li t1, 0x00800000 > + mtc0 t1, CP0_CAUSE > + > + bal 1f > + nop > + .word _GLOBAL_OFFSET_TABLE_ > +1: > + move gp, ra > + lw t1, 0(ra) > + move gp, t1 These three lines could be written in one-liner: lw gp, 0(ra) > + la sp, 0x80004000 > + la t9, nand_boot > + j t9 > + nop Use JR, not J. > diff --git a/arch/mips/cpu/xburst/usbboot.S b/arch/mips/cpu/xburst/usbboot.S > new file mode 100644 > index 0000000..eb8faa6 > --- /dev/null > +++ b/arch/mips/cpu/xburst/usbboot.S I'm going to approve this code as-is, except for coding style issues. Do not use '//' for comments. > @@ -0,0 +1,880 @@ > +/* > + * for jz4740 usb boot > + * > + * Copyright (c) 2009 Author: <jlwei@ingenic.cn> > + * > + * 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 > + */ > + .set noreorder > + .globl usb_boot > + .text > + > +//---------------------------------------------------------------------- > +// Both NAND and USB boot load data to D-Cache first, then transfer > +// data from D-Cache to I-Cache, and jump to execute the code in I-Cache. > +// So init caches first and then dispatch to a proper boot routine. > +//---------------------------------------------------------------------- /* * Both NAND and USB boot load data to D-Cache first, then transfer * data from D-Cache to I-Cache, and jump to execute the code in I-Cache. * So init caches first and then dispatch to a proper boot routine. */ > +.macro load_addr reg addr > + li \reg, 0x80000000 > + addiu \reg, \reg, \addr > + la $2, usbboot_begin > + subu \reg, \reg, $2 > +.endm > + > +usb_boot: > + //-------------------------------------------------------------- > + // Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. > + //-------------------------------------------------------------- > + la $9, 0xB0000000 // CPCCR: Clock Control Register > + la $8, 0x42041110 // I:S:M:P=1:2:2:2 > + sw $8, 0($9) usb_boot: /* * Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */ la $9, 0xB0000000 # CPCCR: Clock Control Register la $8, 0x42041110 # I:S:M:P=1:2:2:2 sw $8, 0($9) And so on. With such cleanups, this is ok. > + la $9, 0xB0000010 // CPPCR: PLL Control Register > + la $8, 0x06000120 // M=12 N=0 D=0 CLK=12*(M+2)/(N+2) > + sw $8, 0($9) > + > + mtc0 $0, $26 // CP0_ERRCTL, restore WST reset state > + nop > + > + mtc0 $0, $16 // CP0_CONFIG > + nop > + > + // Relocate code to beginning of the ram > + > + la $2, usbboot_begin > + la $3, usbboot_end > + li $4, 0x80000000 [snip] ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-11-15 23:02 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-11 3:37 [U-Boot] [PATCH 0/5] [MIPS] add jz4740 base file and Ben NanoNote Xiangfu Liu
2010-11-11 3:37 ` [U-Boot] [PATCH 1/5] those files are jz4740 base files Xiangfu Liu
[not found] ` <1289446657-12499-3-git-send-email-xiangfu@openmobilefree.net>
2010-11-11 3:37 ` [U-Boot] [PATCH 3/5] jz4740 nand spl files Xiangfu Liu
2010-11-11 3:37 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Xiangfu Liu
2010-11-11 3:37 ` [U-Boot] [PATCH 5/5] add Ben NanoNote board Xiangfu Liu
2010-11-11 8:28 ` Wolfgang Denk
2010-11-15 23:02 ` [U-Boot] [PATCH 4/5] jz4740 nand driver Scott Wood
2010-11-11 7:32 ` [U-Boot] [PATCH 3/5] jz4740 nand spl files Wolfgang Denk
2010-11-15 22:56 ` Scott Wood
2010-11-11 7:14 ` [U-Boot] [PATCH 1/5] those files are jz4740 base files Wolfgang Denk
2010-11-14 15:03 ` Shinya Kuribayashi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox