blob: 86098ae8b02857f6fdf4ff7c58ad4a6c813e161d (
plain)
1
2
3
4
5
6
7
8
9
10
11
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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 <string.h>
#include "config.h"
#include "s5l87xx.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;
}
|