[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