[U-Boot-Users] [Patch01]AS352X:U-Boot1.1.6 patch 1 for AS352X SOC(New)
thomas
shaobo.luo at gmail.com
Sat Dec 2 15:36:37 CET 2006
From:thomas.luo at ieee.org
U-Boot1.1.6 for AS352X
Port to U-boot to New ARM base SOC AS352X, support NAND flash Boot.
please ref:
http://www.austriamicrosystems.com/03products/products_detail/AS3525/AS3525.htm
Part 1:
Br
Signed-off-by: Thomas Luothomas.luo at austriamicrosystems.com
-------------------------------------------------------------------------------
diff -urN u-boot-1.1.6.org/board/as352xpb/as352xpb.c u-boot-1.1.6/board/as352xpb/as352xpb.c
--- u-boot-1.1.6.org/board/as352xpb/as352xpb.c 1970-01-01 08:00:00.000000000 +0800
+++ u-boot-1.1.6/board/as352xpb/as352xpb.c 2006-12-01 17:44:42.000000000 +0800
@@ -0,0 +1,359 @@
+/*
+* Copyright (C) 2006 Austriamicrosystems Corporation
+*
+* 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 <as352x.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Macro introduced to compensate for no support for floating point
+division operation in the processor. So to get the correct value,
+roundup is peformed to provide accurate results for certain conditions. */
+
+#define DIVIDE_AND_ROUND_UP(dividend,divisor) \
+ ( ( (dividend) + (divisor) - 1 ) / (divisor) )
+
+/* For sake of completness and for easier exchanging of round-up and round-down
+divisions provide also a round-down macro */
+
+#define DIVIDE_AND_ROUND_DOWN( a , b ) ((a)/(b))
+
+/* Macro which evaluates to the absolute value of an integer value*/
+#define ABS(A) (((A)>0)?(A):(-(A)))
+
+/* ------------------------defines for Dynamic Mem --------------------------- */
+#define AS352X_SDRAM_BASE_ADDR(offset) (0xc6030000 + offset)
+
+#define AS352X_MPMC_CONTROL AS352X_SDRAM_BASE_ADDR( 0x00 )
+#define AS352X_MPMC_CONFIG AS352X_SDRAM_BASE_ADDR( 0x08 )
+#define AS352X_MPMC_DYRDCFG AS352X_SDRAM_BASE_ADDR( 0x28 )
+#define AS352X_MPMC_DYTRP AS352X_SDRAM_BASE_ADDR( 0x30 )
+#define AS352X_MPMC_DYTRAS AS352X_SDRAM_BASE_ADDR( 0x34 )
+#define AS352X_MPMC_DYTSREX AS352X_SDRAM_BASE_ADDR( 0x38 )
+#define AS352X_MPMC_DYTAPR AS352X_SDRAM_BASE_ADDR( 0x3C )
+#define AS352X_MPMC_DYTDAL AS352X_SDRAM_BASE_ADDR( 0x40 )
+#define AS352X_MPMC_DYTWR AS352X_SDRAM_BASE_ADDR( 0x44 )
+#define AS352X_MPMC_DYTRC AS352X_SDRAM_BASE_ADDR( 0x48 )
+#define AS352X_MPMC_DYTRFC AS352X_SDRAM_BASE_ADDR( 0x4C )
+#define AS352X_MPMC_DYTXSR AS352X_SDRAM_BASE_ADDR( 0x50 )
+#define AS352X_MPMC_DYTRRD AS352X_SDRAM_BASE_ADDR( 0x54 )
+#define AS352X_MPMC_DYTMRD AS352X_SDRAM_BASE_ADDR( 0x58 )
+#define AS352X_MPMC_DYRASCAS0 AS352X_SDRAM_BASE_ADDR( 0x104 )
+#define AS352X_MPMC_DYCONFIG0 AS352X_SDRAM_BASE_ADDR( 0x100 )
+#define AS352X_MPMC_DYCNTL AS352X_SDRAM_BASE_ADDR( 0x20 )
+#define AS352X_MPMC_DYREF AS352X_SDRAM_BASE_ADDR( 0x24 )
+
+/* ------------------ MT48LC4M16A2 SDRAM & MT48LC32M16A2 SDRAM --------------------------- */
+#define MPMC_DY_TRP_IN_NS 20
+//#define MPMC_DY_TRP_IN_NS 10
+
+#define MPMC_CLK_IN_MHZ_MIN 20
+#define MPMC_1_CLKCYCLE_IN_NS_MIN 50
+
+#define MPMC_CLK_IN_MHZ 66
+//#define MPMC_CLK_IN_MHZ 24
+#if MPMC_CLK_IN_MHZ == 24
+#define MPMC_1_CLKCYCLE_IN_NS 42
+#elif MPMC_CLK_IN_MHZ == 66
+#define MPMC_1_CLKCYCLE_IN_NS 16
+#else
+#define MPMC_1_CLKCYCLE_IN_NS 16
+#endif
+
+//#define MPMC_SDRAM_TCK_IN_NS 20
+#define MPMC_SDRAM_TCK_IN_NS 10
+
+#define MPMC_DY_TRAS_MIN_IN_NS 50
+#define MPMC_DY_TRAS_IN_NS MPMC_DY_TRAS_MIN_IN_NS
+
+/* tAPR not available for micron MT48LC4M16A2 SDRAM */
+#define MPMC_DY_TAPR_INNS 0
+
+#define MPMC_DY_TDAL_IN_NS (5 * (MPMC_SDRAM_TCK_IN_NS))
+
+/* tWR can be minimum 15ns or 1CLK * 7ns */
+#define MPMC_DY_TWR_IN_NS (MPMC_1_CLKCYCLE_IN_NS + 8)
+#define MPMC_DY_TRC_IN_NS 70
+
+#define MPMC_DY_TRFC_INNS 70
+
+#define MPMC_DY_TXSR_IN_NS 80
+
+#define MPMC_DY_TRRD_IN_NS 20
+#define MPMC_DY_TMRD_IN_NS (2 * (MPMC_SDRAM_TCK_IN_NS))
+
+#define MPMC_SDRAM_CAS 0x2
+#define MPMC_SDRAM_RAS 0x2 /* hha??? */
+
+/* Low Power device bit settings */
+/* Device Type for APP Board 2.0 and 1.0 */
+/* MT48LC32M16A2 - 512Mbit and MT48LC4M16 - 64Mbit -both NOT Low Power */
+#define MPMC_SDRAM_DEVICE_TYPE (0 << 3)
+
+/*ROW and COLUMN size mapping for mpmc SoC device */
+
+/* Addr Mapping for APP Board 2.0 (MT48LC32M16A2 - 512Mbit) */
+#define MPMC_SDRAM_ADDR_MAPPING (0x11 << 7)
+
+#define MPMC_SDRAM_32BIT_EXTBUS (0 <<14)
+#define MPMC_SDRAM_BUFFER_DISABLE (0 <<19)
+#define MPMC_SDRAM_BUFFER_ENABLE (1 <<19)
+#define MPMC_SDRAM_WP_ENABLE (0 <<20)
+
+#define MPMC_SDRAM_DYN_CONFIG ((MPMC_SDRAM_DEVICE_TYPE) | \
+ (MPMC_SDRAM_ADDR_MAPPING) | \
+ (MPMC_SDRAM_32BIT_EXTBUS) | \
+ (MPMC_SDRAM_BUFFER_DISABLE) | \
+ (MPMC_SDRAM_WP_ENABLE))
+
+#define MPMC_SDRAM_START_2_REF_CYCLES 2
+/* TREF for APP Board 2.0 (MT48LC32M16A2 - 512Mbit) */
+/*64ms divided by 8192 */
+#define MPMC_SDRAM_tREF_inNs 7812
+
+
+#define MPMC_SDRAM_DYNAMIC_REF ((MPMC_SDRAM_tREF_inNs) / (MPMC_1_CLKCYCLE_IN_NS_MIN))
+
+
+
+/* CAS Latency for APP Board 2.0 (MT48LC32M16A2 - 512Mbit) */
+#if MPMC_SDRAM_CAS == 2
+#define MPMC_SDRAM_MODEVALUE (0x23 << 13)
+#else
+#define MPMC_SDRAM_MODEVALUE (0x33 << 13)
+#endif
+
+/* ----------------------------------- functions --------------------------- */
+
+static inline void delay (unsigned long loops)
+{
+ __asm__ volatile ("1:\n"
+ "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0" (loops));
+}
+void sdram_init(void )
+{
+ volatile u32 Temp;
+
+
+
+ *(volatile u32 *)AS352X_MPMC_CONTROL = 0x00000001;
+
+ *(volatile u32 *)(AS352X_MPMC_CONFIG) = 0x00000000;
+
+ *(volatile u32 *)(AS352X_MPMC_DYRDCFG) = 0x00000001;
+
+ /* MPMCDynamicRP setup */
+ *(volatile u32 *)(AS352X_MPMC_DYTRP) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TRP_IN_NS),(MPMC_1_CLKCYCLE_IN_NS)) ;
+
+ /* MPMCDytRAS setup */
+ *(volatile u32 *)(AS352X_MPMC_DYTRAS) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TRAS_IN_NS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ /* Setup MPMCDynamicSREX */
+ *(volatile u32 *)(AS352X_MPMC_DYTSREX) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TXSR_IN_NS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ /* Setup MPMCDynamictAPR */
+ *(volatile u32 *)(AS352X_MPMC_DYTAPR) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TAPR_INNS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ *(volatile u32 *)(AS352X_MPMC_DYTDAL) =
+ (1+(DIVIDE_AND_ROUND_UP((MPMC_DY_TDAL_IN_NS),(MPMC_1_CLKCYCLE_IN_NS))));
+
+ /* Setup MPMCDynamictWR */
+ *(volatile u32 *)(AS352X_MPMC_DYTWR) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TWR_IN_NS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ /* Setup MPMCDynamictRC */
+ *(volatile u32 *)(AS352X_MPMC_DYTRC) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TRC_IN_NS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ /* Setup MPMCDynamictRFC */
+ *(volatile u32 *)(AS352X_MPMC_DYTRFC) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TRFC_INNS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ /* Setup MPMCDynamictXSR */
+ *(volatile u32 *)(AS352X_MPMC_DYTXSR) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TXSR_IN_NS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ /* Setup MPMCDynamictRRD */
+ *(volatile u32 *)(AS352X_MPMC_DYTRRD) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TRRD_IN_NS),(MPMC_1_CLKCYCLE_IN_NS));
+
+ /* Setup MPMCDynamictMRD */
+ *(volatile u32 *)(AS352X_MPMC_DYTMRD) =
+ DIVIDE_AND_ROUND_UP((MPMC_DY_TMRD_IN_NS),(MPMC_1_CLKCYCLE_IN_NS));
+
+
+ *(volatile u32 *)(AS352X_MPMC_DYRASCAS0) =
+ ((MPMC_SDRAM_CAS << 0x8) | (MPMC_SDRAM_RAS));
+
+
+ *(volatile u32 *)(AS352X_MPMC_DYCONFIG0) = MPMC_SDRAM_DYN_CONFIG;
+
+ /*wait for 200uS by performing dummy read operation which consumes two */
+ /* clock cycles for each operation */
+ delay(50);
+
+ *(volatile u32 *)(AS352X_MPMC_DYCNTL) = 0x00000183; /* apply NOP */
+
+ delay(1);
+
+ /* write to MPMCDyCntl reg to start PRECHARGing: PRECHARGE ALL */
+ *(volatile u32 *)(AS352X_MPMC_DYCNTL) = 0x00000103;
+
+ delay(100);
+
+ /* start two auto refresh */
+ *(volatile u32 *)(AS352X_MPMC_DYREF) = MPMC_SDRAM_START_2_REF_CYCLES ;
+
+ /*- wait for 64 clk cycles of HCLK-*/
+ delay(128);
+
+ /* Program the operational value of the Refresh cycles, depending upon the
+ device specified period */
+ *(volatile u32 *)(AS352X_MPMC_DYREF) = MPMC_SDRAM_DYNAMIC_REF / 16;
+
+ /* Send the Mode set command to SDRAM */
+ *(volatile u32 *)(AS352X_MPMC_DYCNTL) = 0x00000083;
+
+ /*----------------------------------------------------------------------*/
+
+ /* Read the SDRAM address with the mode value, such that SDRAM will be
+ selected and the mode value will go as row address in HADDR [23:12] */
+ Temp = *(volatile u32 *) (0x30000000 + MPMC_SDRAM_MODEVALUE) ;
+
+ /* Merged with S.U. */
+#ifdef SDRAM_MT48H8M16LF
+ /* Device Type for APP Board 2.0 (MT48H8M16LF - 128Mbit - Low Power) */
+ /* Read the SDRAM address with the mode value, such that SDRAM will be
+ selected and the mode value will go as row address in HADDR [23:12] */
+ Temp = *(volatile u32 *) (0x30000000 + MPMC_SDRAM_EXMODEVALUE) ;
+#endif /*SDRAM_MT48H8M16LF*/
+
+ /*----------------------------------------------------------------------*/
+ /* Send the Normal mode set command to the SDRAM */
+ *(volatile u32 *)(AS352X_MPMC_DYCNTL) = 0x00000003;
+
+ /* Enable the buffer for the SDRAM */
+ Temp = *(volatile u32 *)(AS352X_MPMC_DYCONFIG0) ;
+ *(volatile u32 *)(AS352X_MPMC_DYCONFIG0) =
+ Temp | (MPMC_SDRAM_BUFFER_ENABLE);
+
+}
+#define CCU_COUNT_MIN_10_MICROSEC 640
+/*
+* Miscellaneous platform dependent initialisations
+*/
+
+void ccu_reset_device
+( u32 deviceMask
+ )
+{
+ int i;
+
+ /* reset devices */
+ wreg32( CCU_SRC, deviceMask );
+ wreg32( CCU_SRL, CCU_SRL_MAGIC_NUMBER );
+
+ /* hold the reset for at least 10 microseconds */
+ for ( i = CCU_COUNT_MIN_10_MICROSEC; i > 0; i-- )
+ {
+ wreg32( CCU_SRL, CCU_SRL_MAGIC_NUMBER );
+ }
+
+ /* remove lock */
+ wreg32( CCU_SRL, 0 );
+ wreg32( CCU_SRC, 0 );
+}
+
+void clk_set_async_mode()
+{
+ unsigned long i;
+ /* read CP15 register 1 into r0*/
+ asm("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
+ /*enable asynchronous clocking mode*/
+ asm("orr r0, %0, #(0x3 <<30) ": :"r"(i));
+ /* write cp15 register 1*/
+ asm("mcr p15, 0, %0, c1, c0, 0": :"r"(i));
+}
+
+
+int board_init (void)
+{
+ ccu_reset_device( CCU_RESET_ALL_BUT_MEMORY );
+
+ wreg32(CGU_REG_PERI, 0x0F802000);
+ wreg32(CGU_REG_PROC,0);
+ wreg32(CGU_REG_AUDIO,0);
+ wreg32(CGU_REG_USB,0);
+ wreg32(CGU_REG_INTCTRL,0);
+
+ wreg32(CGU_REG_COUNTA,0);
+ wreg32(CGU_REG_COUNTB,0);
+ wreg32(CGU_REG_IDE,0);
+ wreg32(CGU_REG_MEMSTICK,0);
+ wreg32(CGU_REG_DBOP,0);
+
+
+ wreg32(CGU_REG_PLLASUP,0x8);
+ wreg32(CGU_REG_PLLBSUP,0x8);
+
+ wreg32(CGU_REG_PLLA,0);
+ wreg32(CGU_REG_PLLB,0);
+
+ clk_set_async_mode();
+ //set cpu and bus default clock
+ //plla 384M, CPU 192M,mpmc 64M,pclk 64M
+
+ wreg32(CGU_REG_PLLA,0x2630);
+ wreg32(CGU_REG_PLLASUP,0);
+ wreg32(CGU_REG_COUNTA,CGU_LOCK_CNT);
+ while (!(rreg32(CGU_REG_INTCTRL)&1)) ;
+
+ wreg32( CGU_REG_PROC, 0x011);
+ wreg32(CGU_REG_PERI,0x0EF2E295);
+
+
+
+ //ccuResetDevice( CCU_RESET_ALL_BUT_MEMORY );
+
+ /* arch number of AS352X-Board */
+ gd->bd->bi_arch_number = MACH_TYPE_AS352X;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0x30000100;
+
+ sdram_init();
+
+ return 0;
+}
+
+int dram_init (void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return 0;
+}
diff -urN u-boot-1.1.6.org/board/as352xpb/config.mk u-boot-1.1.6/board/as352xpb/config.mk
--- u-boot-1.1.6.org/board/as352xpb/config.mk 1970-01-01 08:00:00.000000000 +0800
+++ u-boot-1.1.6/board/as352xpb/config.mk 2006-11-24 10:08:10.000000000 +0800
@@ -0,0 +1,23 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj at denx.de>
+# David Mueller, ELSOFT AG, <d.mueller at elsoft.ch>
+#
+# AMS AS352XPB board with AS352X (ARM922T) cpu
+#
+# see http://www.austriamicrosystems.com for more information
+#
+#
+# AS352X has 1 bank of 64 MB DRAM
+#
+# 3000'0000 to 3400'0000
+#
+# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
+# optionally with a ramdisk at 3080'0000
+#
+# we load ourself to 0000'0000
+#
+# download area is 3300'0000
+#
+
+TEXT_BASE = 0x00000000
diff -urN u-boot-1.1.6.org/board/as352xpb/lowlevel_init.S u-boot-1.1.6/board/as352xpb/lowlevel_init.S
--- u-boot-1.1.6.org/board/as352xpb/lowlevel_init.S 1970-01-01 08:00:00.000000000 +0800
+++ u-boot-1.1.6/board/as352xpb/lowlevel_init.S 2006-11-30 10:24:49.000000000 +0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006 Austriamicrosystems Corporation
+ *
+ * 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>
+
+/* some parameters for the board */
+
+/*
+ *
+ */
+
+
+_TEXT_BASE:
+ .word TEXT_BASE
+
+.globl lowlevel_init
+lowlevel_init:
+ /* everything is fine now */
+ mov pc, lr
+
+ .ltorg
+/* the literal pools origin */
diff -urN u-boot-1.1.6.org/board/as352xpb/Makefile u-boot-1.1.6/board/as352xpb/Makefile
--- u-boot-1.1.6.org/board/as352xpb/Makefile 1970-01-01 08:00:00.000000000 +0800
+++ u-boot-1.1.6/board/as352xpb/Makefile 2006-11-29 16:02:27.000000000 +0800
@@ -0,0 +1,51 @@
+#
+# (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$(BOARD).a
+
+COBJS := as352xpb.o nandas.o
+SOBJS := lowlevel_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff -urN u-boot-1.1.6.org/board/as352xpb/nandas.c u-boot-1.1.6/board/as352xpb/nandas.c
--- u-boot-1.1.6.org/board/as352xpb/nandas.c 1970-01-01 08:00:00.000000000 +0800
+++ u-boot-1.1.6/board/as352xpb/nandas.c 2006-12-01 17:47:46.000000000 +0800
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2006 Austriamicrosystems Corporation
+ *
+ * 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>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+
+#include <nand.h>
+#include <asm/errno.h>
+/*
+ * hardware specific access to control-lines
+ */
+
+#define NAF_X8_X16_CODE 0x03 /* only for big block nand */
+
+/**
+ * Power bit in NAF mode register.
+ **/
+#define NAF_POWER_ON 0x0C
+#define NAF_POWER_OFF 0x00
+
+/**
+ * NAF Config register bits.
+ **/
+#define NAF_X16 0x00000001
+#define NAF_FIFO_ENABLE 0x00000004
+#define NAF_DMA_ON 0x00000008
+
+#define NAF_READ_STROBE_H 0x00000020 /* read strobe high is 4 PLCK cycles */
+#define NAF_READ_STROBE_L 0x00000400 /* read strobe low is 5 PLCK cycles */
+#define NAF_WRITE_STROBE_H 0x00003000 /* write strobe high is 4 PCLK cycles */
+#define NAF_WRITE_STROBE_L 0x00040000 /* write strobe high is 4 PCLK cycles */
+
+#define NAF_STROBE_CONFIG \
+ ( NAF_READ_STROBE_H | NAF_READ_STROBE_L | NAF_WRITE_STROBE_H | NAF_WRITE_STROBE_L )
+
+
+/**
+ * NAF modi
+ **/
+#define NAF_MODE_CLE 1<<0
+#define NAF_MODE_ALE 1<<1
+#define NAF_MODE_NCE 1<<4
+#define NAF_MODE_WP 1<<7
+
+#define NAF_MODE_DATA_READ_NO_ECC 0x14
+#define NAF_MODE_DATA_WRITE_ECC_RESET 0xF4
+#define NAF_MODE_DATA_WRITE_NO_ECC 0x94
+/*
+ * chip R/B detection
+ */
+static int as352x_read_status;
+
+static int as352x_nand_ready(struct mtd_info *mtd)
+{
+ return ( ( rreg16( NAF_STATUS ) & 0x0080 ) == 0x0080 );
+
+}
+static int as352x_nand_strobe()
+{
+ return ( ( rreg16( NAF_STATUS ) & 0x0100 ) == 0x0100 );
+}
+static int as352x_fifo_isfull()
+{
+ return ( ( rreg16( NAF_STATUS ) & 0x01000 ) );
+}
+
+static int as352x_fifo_isempty()
+{
+ return ( ( rreg16( NAF_STATUS ) & 0x0200 ) );
+}
+/**
+ * nand_read_byte - [DEFAULT] read one byte from the chip
+ * @mtd: MTD device structure
+ *
+ * Default read function for 8bit buswith
+ */
+static u_char as352x_nand_read_byte(struct mtd_info *mtd)
+{
+ u_char data;
+ wreg8 ( NAF_CONTROL, 0x1 ); /* generate read strobe */
+ while (!as352x_nand_strobe(mtd));
+ data = rreg16( NAF_DATA );
+ if (as352x_read_status)
+ data |= 0x80;
+ return data;
+}
+
+/**
+ * nand_write_byte - [DEFAULT] write one byte to the chip
+ * @mtd: MTD device structure
+ * @byte: pointer to data byte to write
+ *
+ * Default write function for 8it buswith
+ */
+static void as352x_nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+
+ wreg16( NAF_DATA, byte );
+ while (!as352x_nand_strobe(mtd));
+}
+
+void as352x_nand_wait_fifo_empty( )
+{
+ while ( ( rreg16( NAF_STATUS ) & 0x0004 ) != 0x0004 ) ; /* wait for got empty and ready */
+}
+
+/**
+ * nand_write_buf - [DEFAULT] write buffer to chip
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ *
+ * Default write function for 8bit buswith
+ */
+static void as352x_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ int i;
+ u32 *p =(u32 *)buf;
+ struct nand_chip *this = mtd->priv;
+ len /=4;
+ wreg8( NAF_CLEAR, 0x7f );
+ wreg32( NAF_WORDS, len );
+ for (i=0; i<len; i++)
+ {
+ while (as352x_fifo_isfull());
+ wreg32( NAF_FIFODATA, p[i] );
+ }
+ as352x_nand_wait_fifo_empty();
+}
+
+/**
+ * nand_read_buf - [DEFAULT] read chip data into buffer
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
+ *
+ * Default read function for 8bit buswith
+ */
+static void as352x_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ u32 *p =(u32 *)buf;
+ len /=4;
+ wreg8( NAF_CLEAR, 0x7f );
+ wreg32( NAF_WORDS, len );
+ for (i=0; i<len; i++)
+ {
+ while (as352x_fifo_isempty());
+ p[i] = rreg32( NAF_FIFODATA );
+ }
+ as352x_nand_wait_fifo_empty( );
+}
+/**
+ * nand_verify_buf - [DEFAULT] Verify chip data against buffer
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
+ *
+ * Default verify function for 8bit buswith
+ */
+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+
+ for (i=0; i<len; i++)
+ if (buf[i] != as352x_nand_read_byte(mtd))
+ return -EFAULT;
+
+ return 0;
+}
+
+static void as352x_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+
+ struct nand_chip *this = mtd->priv;
+// ulong IO_ADDR_W = (ulong) this->IO_ADDR_W;
+
+ switch (cmd)
+ {
+ case NAND_CTL_SETCLE:
+ {
+ set_reg_bits16 ( NAF_MODE, NAF_MODE_CLE );
+ }
+ break;
+ case NAND_CTL_CLRCLE:
+ clr_reg_bits16( NAF_MODE, NAF_MODE_CLE );
+ break;
+ case NAND_CTL_SETALE:
+ {
+ set_reg_bits16 ( NAF_MODE, NAF_MODE_ALE );
+
+ }
+ break;
+ case NAND_CTL_CLRALE:
+ clr_reg_bits16( NAF_MODE, NAF_MODE_ALE );
+ break;
+ case NAND_CTL_SETNCE:
+ set_reg_bits16 ( NAF_MODE, NAF_MODE_NCE );
+ break;
+ case NAND_CTL_CLRNCE:
+ clr_reg_bits16( NAF_MODE, NAF_MODE_NCE );
+ break;
+ case NAND_CTL_SETWP:
+ set_reg_bits16 ( NAF_MODE, NAF_MODE_WP );
+ break;
+ case NAND_CTL_CLRWP:
+ clr_reg_bits16( NAF_MODE, NAF_MODE_WP );
+ break;
+
+ }
+}
+/**
+ * nand_command_lp - [DEFAULT] Send command to NAND large page device
+ * @mtd: MTD device structure
+ * @command: the command to be sent
+ * @column: the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
+ *
+ * Send command to NAND device. This is the version for the new large page devices
+ * We dont have the seperate regions as we have in the small page devices.
+ * We must emulate NAND_CMD_READOOB to keep the code compatible.
+ *
+ */
+
+static void as352x_nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+ register struct nand_chip *this = mtd->priv;
+
+ /* Emulate NAND_CMD_READOOB */
+ if (command == NAND_CMD_READOOB) {
+ column += mtd->oobblock;
+ command = NAND_CMD_READ0;
+ }
+
+ as352x_read_status =0;
+ switch (command)
+ {
+ case NAND_CMD_SEQIN:
+ case NAND_CMD_ERASE1:
+ case NAND_CMD_ERASE2:
+ {
+ wreg8( NAF_MASK, 0xFF );
+ wreg8( NAF_CLEAR, 0x7f );
+ }
+ case NAND_CMD_CACHEDPROG:
+ case NAND_CMD_PAGEPROG:
+ {
+ this->hwcontrol(mtd, NAND_CTL_SETWP);
+ }
+ break;
+ case NAND_CMD_READ0:
+ wreg8( NAF_MASK, 0xFF );
+ wreg8( NAF_CLEAR, 0x7f );
+ wreg8( NAF_MODE,NAF_MODE_DATA_READ_NO_ECC);
+ default:
+ this->hwcontrol(mtd, NAND_CTL_CLRWP);
+ }
+ /* Begin command latch cycle */
+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
+ /* Write out the command to the device. */
+ this->write_byte(mtd, command);
+ /* End command latch cycle */
+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+
+ if (column != -1 || page_addr != -1) {
+ this->hwcontrol(mtd, NAND_CTL_SETALE);
+
+ /* Serially input address */
+ if (column != -1) {
+ /* Adjust columns for 16 bit buswidth */
+ if (this->options & NAND_BUSWIDTH_16)
+ column >>= 1;
+ this->write_byte(mtd, column & 0xff);
+ this->write_byte(mtd, column >> 8);
+ }
+ if (page_addr != -1) {
+ this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
+ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
+ /* One more address cycle for devices > 128MiB */
+ if (this->chipsize > (128 << 20))
+ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
+ }
+ /* Latch in address */
+ this->hwcontrol(mtd, NAND_CTL_CLRALE);
+ }
+
+ /*
+ * program and erase have their own busy handlers
+ * status and sequential in needs no delay
+ */
+ switch (command) {
+ case NAND_CMD_SEQIN:
+ {
+ wreg8( NAF_MODE, NAF_MODE_DATA_WRITE_ECC_RESET );
+ break;
+ }
+ case NAND_CMD_ERASE1:
+ case NAND_CMD_ERASE2:
+ break;
+ case NAND_CMD_STATUS:
+ as352x_read_status =1;
+ break;
+ case NAND_CMD_CACHEDPROG:
+
+ case NAND_CMD_PAGEPROG:
+ wreg8( NAF_MODE, NAF_MODE_DATA_WRITE_NO_ECC );
+ break;
+
+
+ case NAND_CMD_RESET:
+ if (this->dev_ready)
+ break;
+ udelay(this->chip_delay);
+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
+ this->write_byte(mtd, NAND_CMD_STATUS);
+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+ while ( !(this->read_byte(mtd) & 0x40));
+ return;
+
+ case NAND_CMD_READ0:
+ /* Begin command latch cycle */
+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
+ /* Write out the start read command */
+ this->write_byte(mtd, NAND_CMD_READSTART);
+ /* End command latch cycle */
+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
+ /* Fall through into ready check */
+
+ /* This applies to read commands */
+ default:
+ /*
+ * If we don't have access to the busy pin, we apply the given
+ * command delay
+ */
+ if (!this->dev_ready) {
+ udelay (this->chip_delay);
+ return;
+ }
+ }
+
+ /* Apply this short delay always to ensure that we do wait tWB in
+ * any case on any machine. */
+ ndelay (1000);
+ /* wait until command is processed */
+ while (!this->dev_ready(mtd));
+}
+
+
+void board_nand_init(struct nand_chip *nand)
+{
+ // clear all NAF chip select bits
+ clr_reg_bits32( CCU_IO , ( CCU_IO_NAF_CE_LINE_0 | CCU_IO_NAF_CE_LINE_1
+ | CCU_IO_NAF_CE_LINE_2 | CCU_IO_NAF_CE_LINE_3 ) );
+ set_reg_bits32( CCU_IO , CCU_IO_NAF_CE_LINE_0 );
+
+ /* configure NAF */
+ wreg8( NAF_MODE, NAF_POWER_ON ); /* turn power on */
+ wreg8( NAF_MASK, 0xFF );
+ wreg8( NAF_CLEAR, 0x7f ); /* clear any pending error indication */
+
+ /* configure fifo on but dma still off */
+ wreg32( NAF_CONFIG, NAF_FIFO_ENABLE | NAF_STROBE_CONFIG );
+
+ /* 2. change into read mode */
+ wreg8 ( NAF_MODE, NAF_MODE_DATA_READ_NO_ECC );
+
+ nand->options = NAND_SAMSUNG_LP_OPTIONS;
+ nand->eccmode = NAND_ECC_SOFT;
+ nand->hwcontrol = as352x_nand_hwcontrol;
+ nand->dev_ready = as352x_nand_ready;
+ nand->chip_delay = 18;
+ nand->read_byte = as352x_nand_read_byte;
+ nand->write_byte = as352x_nand_write_byte;
+ nand->read_buf = as352x_nand_read_buf;
+ nand->write_buf = as352x_nand_write_buf;
+ nand->cmdfunc = as352x_nand_command_lp;
+}
+#endif
More information about the U-Boot
mailing list