From 5aeaa84cab08154dc451a39902c376bd8a8922f4 Mon Sep 17 00:00:00 2001 From: Bertrik Sikken Date: Sun, 9 Aug 2009 16:12:36 +0000 Subject: [PATCH] Samsung YP-S3: add beginning of a low-level NAND driver and update bootloader demo program to display the NAND ids. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22221 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/samsung_yps3.c | 14 +++ firmware/SOURCES | 1 + .../target/arm/s5l8700/yps3/nand-target.h | 33 ++++++ firmware/target/arm/s5l8700/yps3/nand-yps3.c | 109 ++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 firmware/target/arm/s5l8700/yps3/nand-target.h create mode 100644 firmware/target/arm/s5l8700/yps3/nand-yps3.c diff --git a/bootloader/samsung_yps3.c b/bootloader/samsung_yps3.c index e541ff2f53..6d12f684fc 100644 --- a/bootloader/samsung_yps3.c +++ b/bootloader/samsung_yps3.c @@ -55,6 +55,7 @@ #include "si4700.h" #include "fmradio_i2c.h" #include "wmcodec.h" +#include "nand-target.h" char version[] = APPSVERSION; #define LONG_DELAY 200000 @@ -82,6 +83,7 @@ void main(void) unsigned int button; unsigned int fm_frequency = 100700000; int audiovol = 0x60; + unsigned nand_ids[4]; // enable all peripherals PWRCON = 0; @@ -141,6 +143,11 @@ void main(void) PCON5 = (PCON5 & ~0x0000000F) | 0x00000001; PDAT5 |= 1; + nand_ll_init(); + for (i = 0; i < 4; i++) { + nand_ids[i] = nand_ll_read_id(i); + } + while (true) { line = 1; @@ -279,6 +286,13 @@ void main(void) lcd_puts(0, line++, mystring); #endif +#if 1 /* NAND debug */ + snprintf(mystring, 64, "NAND ID: %08X %08X", nand_ids[0], nand_ids[1]); + lcd_puts(0, line++, mystring); + snprintf(mystring, 64, "NAND ID: %08X %08X", nand_ids[2], nand_ids[3]); + lcd_puts(0, line++, mystring); +#endif + lcd_update(); } } diff --git a/firmware/SOURCES b/firmware/SOURCES index 6c2ba41dcc..bed22c97c8 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1421,6 +1421,7 @@ target/arm/s5l8700/yps3/button-yps3.c target/arm/s5l8700/yps3/lcd-yps3.c target/arm/s5l8700/yps3/fmradio-i2c-yps3.c target/arm/s5l8700/yps3/backlight-yps3.c +target/arm/s5l8700/yps3/nand-yps3.c target/arm/s5l8700/yps3/power-yps3.c #endif /* SAMSUNG_YPS3 */ diff --git a/firmware/target/arm/s5l8700/yps3/nand-target.h b/firmware/target/arm/s5l8700/yps3/nand-target.h new file mode 100644 index 0000000000..b617c2c27f --- /dev/null +++ b/firmware/target/arm/s5l8700/yps3/nand-target.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Bertrik Sikken + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _NAND_TARGET_H_ +#define _NAND_TARGET_H_ + +#include "config.h" + +void nand_ll_init(void); +unsigned int nand_ll_read_id(int bank); + +/* TODO later: create nand_ll_read/write/erase prototypes */ + +#endif /* _NAND_TARGET_H_ */ + diff --git a/firmware/target/arm/s5l8700/yps3/nand-yps3.c b/firmware/target/arm/s5l8700/yps3/nand-yps3.c new file mode 100644 index 0000000000..743c74261a --- /dev/null +++ b/firmware/target/arm/s5l8700/yps3/nand-yps3.c @@ -0,0 +1,109 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Bertrik Sikken + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include + +#include "config.h" +#include "s5l8700.h" +#include "nand-target.h" + +/* Driver for the S5L8700 flash memory controller for low-level access to the + NAND flash of the Samsung YP-S3. + + The YP-S3 seems to use the pins P6.5 and P6.6 as chip selects in GPIO mode + instead of using the regular pins P6.3 and P6.4. +*/ + +#define FMSTAT_RBB (1<<0) +#define FMSTAT_RBBDone (1<<1) +#define FMSTAT_CMDDone (1<<2) +#define FMSTAT_AddrDone (1<<3) +#define FMSTAT_TransDone (1<<4) +#define FMSTAT_WFIFO_HEMPTY (1<<5) +#define FMSTAT_RFIFO_HFULL (1<<6) +#define FMSTAT_WFIFO_EMPTY (1<<8) +#define FMSTAT_RFIFO_FULL (1<<9) +#define FMSTAT_EndECC (1<<10) + +#define FMCTRL1_DoTransAddr (1<<0) +#define FMCTRL1_DoReadData (1<<1) +#define FMCTRL1_DoWriteData (1<<2) +#define FMCTRL1_WriteREQSEL (1<<4) +#define FMCTRL1_ClearSyndPtr (1<<5) +#define FMCTRL1_ClearWFIFO (1<<6) +#define FMCTRL1_ClearRFIFO (1<<7) +#define FMCTRL1_ParityPtr (1<<8) +#define FMCTRL1_SyndPtr (1<<9) + +static void nand_chip_select(int bank) +{ + unsigned int select; + + select = (1 << bank); + FMCTRL0 = 0x1821 | ((select & 3) << 1); + PDAT6 = (PDAT6 & ~0x60) | ((~select & 0xC) << 3); +} + +void nand_ll_init(void) +{ + /* enable flash memory controller */ + PWRCON &= ~(1 << 1); + + /* P2.X is SMC I/O */ + PCON2 = 0x55555555; + /* P4.1 = CLE, P4.4 = nWR, P4.5 = nRD */ + PCON4 = (PCON4 & ~0x00FF00F0) | 0x00550050; + /* P6.0 = nf_rbn, P6.1 = smc_ce0, P6.2 = smc_ce1, + P6.5 = smc_ce2 (as GPIO), P6.6 = smc_ce3 (as GPIO), P6.7 = ALE */ + PCON6 = (PCON6 & ~0xFFF00FFF) | 0x51100555; + PDAT6 |= 0x60; +} + +unsigned int nand_ll_read_id(int bank) +{ + unsigned int nand_id; + + nand_chip_select(bank); + + /* send "read id" command */ + FMCMD = 0x90; + while ((FMCSTAT & FMSTAT_CMDDone) == 0); + FMCSTAT = FMSTAT_CMDDone; + + /* transfer address */ + FMANUM = 0; + FMADDR0 = 0; + FMCTRL1 = FMCTRL1_DoTransAddr; + while ((FMCSTAT & FMSTAT_AddrDone) == 0); + FMCSTAT = FMSTAT_AddrDone; + + /* read back data */ + FMDNUM = 3; + FMCTRL1 = FMCTRL1_DoReadData; + while ((FMCSTAT & FMSTAT_TransDone) == 0); + FMCSTAT = FMSTAT_TransDone; + nand_id = FMFIFO; + + /* clear read FIFO */ + FMCTRL1 = FMCTRL1_ClearRFIFO; + + return nand_id; +} +