~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/socrates/nand.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2008
 
3
 * Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com.
 
4
 *
 
5
 * SPDX-License-Identifier:     GPL-2.0+
 
6
 */
 
7
 
 
8
#include <common.h>
 
9
 
 
10
#if defined(CONFIG_SYS_NAND_BASE)
 
11
#include <nand.h>
 
12
#include <asm/errno.h>
 
13
#include <asm/io.h>
 
14
 
 
15
static int state;
 
16
static void sc_nand_write_byte(struct mtd_info *mtd, u_char byte);
 
17
static void sc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
 
18
static u_char sc_nand_read_byte(struct mtd_info *mtd);
 
19
static u16 sc_nand_read_word(struct mtd_info *mtd);
 
20
static void sc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
 
21
static int sc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
 
22
static int sc_nand_device_ready(struct mtd_info *mtdinfo);
 
23
 
 
24
#define FPGA_NAND_CMD_MASK              (0x7 << 28)
 
25
#define FPGA_NAND_CMD_COMMAND           (0x0 << 28)
 
26
#define FPGA_NAND_CMD_ADDR              (0x1 << 28)
 
27
#define FPGA_NAND_CMD_READ              (0x2 << 28)
 
28
#define FPGA_NAND_CMD_WRITE             (0x3 << 28)
 
29
#define FPGA_NAND_BUSY                  (0x1 << 15)
 
30
#define FPGA_NAND_ENABLE                (0x1 << 31)
 
31
#define FPGA_NAND_DATA_SHIFT            16
 
32
 
 
33
/**
 
34
 * sc_nand_write_byte -  write one byte to the chip
 
35
 * @mtd:        MTD device structure
 
36
 * @byte:       pointer to data byte to write
 
37
 */
 
38
static void sc_nand_write_byte(struct mtd_info *mtd, u_char byte)
 
39
{
 
40
        sc_nand_write_buf(mtd, (const uchar *)&byte, sizeof(byte));
 
41
}
 
42
 
 
43
/**
 
44
 * sc_nand_write_buf -  write buffer to chip
 
45
 * @mtd:        MTD device structure
 
46
 * @buf:        data buffer
 
47
 * @len:        number of bytes to write
 
48
 */
 
49
static void sc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 
50
{
 
51
        int i;
 
52
        struct nand_chip *this = mtd->priv;
 
53
 
 
54
        for (i = 0; i < len; i++) {
 
55
                out_be32(this->IO_ADDR_W,
 
56
                         state | (buf[i] << FPGA_NAND_DATA_SHIFT));
 
57
        }
 
58
}
 
59
 
 
60
 
 
61
/**
 
62
 * sc_nand_read_byte -  read one byte from the chip
 
63
 * @mtd:        MTD device structure
 
64
 */
 
65
static u_char sc_nand_read_byte(struct mtd_info *mtd)
 
66
{
 
67
        u8 byte;
 
68
        sc_nand_read_buf(mtd, (uchar *)&byte, sizeof(byte));
 
69
        return byte;
 
70
}
 
71
 
 
72
/**
 
73
 * sc_nand_read_word -  read one word from the chip
 
74
 * @mtd:        MTD device structure
 
75
 */
 
76
static u16 sc_nand_read_word(struct mtd_info *mtd)
 
77
{
 
78
        u16 word;
 
79
        sc_nand_read_buf(mtd, (uchar *)&word, sizeof(word));
 
80
        return word;
 
81
}
 
82
 
 
83
/**
 
84
 * sc_nand_read_buf -  read chip data into buffer
 
85
 * @mtd:        MTD device structure
 
86
 * @buf:        buffer to store date
 
87
 * @len:        number of bytes to read
 
88
 */
 
89
static void sc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 
90
{
 
91
        int i;
 
92
        struct nand_chip *this = mtd->priv;
 
93
        int val;
 
94
 
 
95
        val = (state & FPGA_NAND_ENABLE) | FPGA_NAND_CMD_READ;
 
96
 
 
97
        out_be32(this->IO_ADDR_W, val);
 
98
        for (i = 0; i < len; i++) {
 
99
                buf[i] = (in_be32(this->IO_ADDR_R) >> FPGA_NAND_DATA_SHIFT) & 0xff;
 
100
        }
 
101
}
 
102
 
 
103
/**
 
104
 * sc_nand_verify_buf -  Verify chip data against buffer
 
105
 * @mtd:        MTD device structure
 
106
 * @buf:        buffer containing the data to compare
 
107
 * @len:        number of bytes to compare
 
108
 */
 
109
static int sc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 
110
{
 
111
        int i;
 
112
 
 
113
        for (i = 0; i < len; i++) {
 
114
                if (buf[i] != sc_nand_read_byte(mtd));
 
115
                        return -EFAULT;
 
116
        }
 
117
        return 0;
 
118
}
 
119
 
 
120
/**
 
121
 * sc_nand_device_ready - Check the NAND device is ready for next command.
 
122
 * @mtd:        MTD device structure
 
123
 */
 
124
static int sc_nand_device_ready(struct mtd_info *mtdinfo)
 
125
{
 
126
        struct nand_chip *this = mtdinfo->priv;
 
127
 
 
128
        if (in_be32(this->IO_ADDR_W) & FPGA_NAND_BUSY)
 
129
                return 0; /* busy */
 
130
        return 1;
 
131
}
 
132
 
 
133
/**
 
134
 * sc_nand_hwcontrol - NAND control functions wrapper.
 
135
 * @mtd:        MTD device structure
 
136
 * @cmd:        Command
 
137
 */
 
138
static void sc_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl)
 
139
{
 
140
        if (ctrl & NAND_CTRL_CHANGE) {
 
141
                state &= ~(FPGA_NAND_CMD_MASK | FPGA_NAND_ENABLE);
 
142
 
 
143
                switch (ctrl & (NAND_ALE | NAND_CLE)) {
 
144
                case 0:
 
145
                        state |= FPGA_NAND_CMD_WRITE;
 
146
                        break;
 
147
 
 
148
                case NAND_ALE:
 
149
                        state |= FPGA_NAND_CMD_ADDR;
 
150
                        break;
 
151
 
 
152
                case NAND_CLE:
 
153
                        state |= FPGA_NAND_CMD_COMMAND;
 
154
                        break;
 
155
 
 
156
                default:
 
157
                        printf("%s: unknown ctrl %#x\n", __FUNCTION__, ctrl);
 
158
                }
 
159
 
 
160
                if (ctrl & NAND_NCE)
 
161
                        state |= FPGA_NAND_ENABLE;
 
162
        }
 
163
 
 
164
        if (cmd != NAND_CMD_NONE)
 
165
                sc_nand_write_byte(mtdinfo, cmd);
 
166
}
 
167
 
 
168
int board_nand_init(struct nand_chip *nand)
 
169
{
 
170
        nand->cmd_ctrl = sc_nand_hwcontrol;
 
171
        nand->ecc.mode = NAND_ECC_SOFT;
 
172
        nand->dev_ready = sc_nand_device_ready;
 
173
        nand->read_byte = sc_nand_read_byte;
 
174
        nand->read_word = sc_nand_read_word;
 
175
        nand->write_buf = sc_nand_write_buf;
 
176
        nand->read_buf = sc_nand_read_buf;
 
177
        nand->verify_buf = sc_nand_verify_buf;
 
178
 
 
179
        return 0;
 
180
}
 
181
 
 
182
#endif