summaryrefslogtreecommitdiff
path: root/platform/msm_shared/include/qpic_nand.h
blob: 14282ece970285797d43e3aee09f371961517af6 (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/*
 * Copyright (c) 2008, Google Inc.
 * All rights reserved.
 * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef __QPIC_NAND_H
#define __QPIC_NAND_H

#include <debug.h>
#include <dev/flash.h>
#include <platform/iomap.h>

#define NAND_REG(off)                                      (nand_base + (off))

#define NAND_FLASH_CMD                                     NAND_REG(0x0000)
#define NAND_ADDR0                                         NAND_REG(0x0004)
#define NAND_ADDR1                                         NAND_REG(0x0008)
#define NAND_FLASH_CHIP_SELECT                             NAND_REG(0x000C)
#define NAND_EXEC_CMD                                      NAND_REG(0x0010)
#define NAND_FLASH_STATUS                                  NAND_REG(0x0014)
#define NAND_BUFFER_STATUS                                 NAND_REG(0x0018)
#define NAND_DEV0_CFG0                                     NAND_REG(0x0020)
#define NAND_DEV0_CFG1                                     NAND_REG(0x0024)
#define NAND_DEV0_ECC_CFG                                  NAND_REG(0x0028)
#define NAND_DEV1_CFG0                                     NAND_REG(0x0030)
#define NAND_DEV1_CFG1                                     NAND_REG(0x0034)
#define NAND_SFLASHC_CMD                                   NAND_REG(0x0038)
#define NAND_SFLASHC_EXEC_CMD                              NAND_REG(0x003C)
#define NAND_READ_ID                                       NAND_REG(0x0040)
#define NAND_READ_STATUS                                   NAND_REG(0x0044)
#define NAND_READ_ID2                                      NAND_REG(0x0048)
#define NAND_CONFIG_DATA                                   NAND_REG(0x0050)
#define NAND_CONFIG                                        NAND_REG(0x0054)
#define NAND_CONFIG_MODE                                   NAND_REG(0x0058)
#define NAND_CONFIG_STATUS                                 NAND_REG(0x0060)
#define NAND_MACRO1_REG                                    NAND_REG(0x0064)
#define NAND_XFR_STEP1                                     NAND_REG(0x0070)
#define NAND_XFR_STEP2                                     NAND_REG(0x0074)
#define NAND_XFR_STEP3                                     NAND_REG(0x0078)
#define NAND_XFR_STEP4                                     NAND_REG(0x007C)
#define NAND_XFR_STEP5                                     NAND_REG(0x0080)
#define NAND_XFR_STEP6                                     NAND_REG(0x0084)
#define NAND_XFR_STEP7                                     NAND_REG(0x0088)
#define NAND_GENP_REG0                                     NAND_REG(0x0090)
#define NAND_GENP_REG1                                     NAND_REG(0x0094)
#define NAND_GENP_REG2                                     NAND_REG(0x0098)
#define NAND_GENP_REG3                                     NAND_REG(0x009C)
#define NAND_SFLASHC_STATUS                                NAND_REG(0x001C)
#define NAND_DEV_CMD0                                      NAND_REG(0x00A0)
#define NAND_DEV_CMD1                                      NAND_REG(0x00A4)
#define NAND_DEV_CMD2                                      NAND_REG(0x00A8)
#define NAND_DEV_CMD_VLD                                   NAND_REG(0x00AC)
#define NAND_EBI2_MISR_SIG_REG                             NAND_REG(0x00B0)
#define NAND_ADDR2                                         NAND_REG(0x00C0)
#define NAND_ADDR3                                         NAND_REG(0x00C4)
#define NAND_ADDR4                                         NAND_REG(0x00C8)
#define NAND_ADDR5                                         NAND_REG(0x00CC)
#define NAND_DEV_CMD3                                      NAND_REG(0x00D0)
#define NAND_DEV_CMD4                                      NAND_REG(0x00D4)
#define NAND_DEV_CMD5                                      NAND_REG(0x00D8)
#define NAND_DEV_CMD6                                      NAND_REG(0x00DC)
#define NAND_SFLASHC_BURST_CFG                             NAND_REG(0x00E0)
#define NAND_ADDR6                                         NAND_REG(0x00E4)
#define NAND_ERASED_CW_DETECT_CFG                          NAND_REG(0x00E8)
#define NAND_ERASED_CW_DETECT_STATUS                       NAND_REG(0x00EC)
#define NAND_EBI2_ECC_BUF_CFG                              NAND_REG(0x00F0)
#define NAND_HW_INFO                                       NAND_REG(0x00FC)
#define NAND_FLASH_BUFFER                                  NAND_REG(0x0100)

/* NANDc registers used during BAM transfer */
#define NAND_READ_LOCATION_n(n)                            (NAND_REG(0xF20) + 4 * (n))
#define NAND_RD_LOC_LAST_BIT(x)                            ((x) << 31)
#define NAND_RD_LOC_SIZE(x)                                ((x) <<  16)
#define NAND_RD_LOC_OFFSET(x)                              ((x) <<  0)

/* Shift Values */
#define NAND_DEV0_CFG1_WIDE_BUS_SHIFT                      1
#define NAND_DEV0_CFG0_DIS_STS_AFTER_WR_SHIFT              4
#define NAND_DEV0_CFG0_CW_PER_PAGE_SHIFT                   6
#define NAND_DEV0_CFG0_UD_SIZE_BYTES_SHIFT                 9
#define NAND_DEV0_CFG0_ADDR_CYCLE_SHIFT                    27
#define NAND_DEV0_CFG0_SPARE_SZ_BYTES_SHIFT                23

#define NAND_DEV0_CFG1_RECOVERY_CYCLES_SHIFT               2
#define NAND_DEV0_CFG1_CS_ACTIVE_BSY_SHIFT                 5
#define NAND_DEV0_CFG1_BAD_BLK_BYTE_NUM_SHIFT              6
#define NAND_DEV0_CFG1_BAD_BLK_IN_SPARE_SHIFT              16
#define NAND_DEV0_CFG1_WR_RD_BSY_GAP_SHIFT                 17
#define NAND_DEV0_ECC_DISABLE_SHIFT                        0
#define NAND_DEV0_ECC_SW_RESET_SHIFT                       1
#define NAND_DEV0_ECC_MODE_SHIFT                           4
#define NAND_DEV0_ECC_DISABLE_SHIFT                        0
#define NAND_DEV0_ECC_PARITY_SZ_BYTES_SHIFT                8
#define NAND_DEV0_ECC_NUM_DATA_BYTES                       16
#define NAND_DEV0_ECC_FORCE_CLK_OPEN_SHIFT                 30

#define NAND_ERASED_CW_DETECT_STATUS_PAGE_ALL_ERASED       7
#define NAND_ERASED_CW_DETECT_STATUS_CODEWORD_ALL_ERASED   6
#define NAND_ERASED_CW_DETECT_STATUS_CODEWORD_ERASED       4

#define NAND_ERASED_CW_DETECT_CFG_RESET_CTRL               1
#define NAND_ERASED_CW_DETECT_CFG_ACTIVATE_CTRL            0
#define NAND_ERASED_CW_DETECT_ERASED_CW_ECC_MASK           (1 << 1)
#define NAND_ERASED_CW_DETECT_ERASED_CW_ECC_NO_MASK        (0 << 1)

/* device commands */
#define NAND_CMD_SOFT_RESET                                0x01
#define NAND_CMD_PAGE_READ                                 0x32
#define NAND_CMD_PAGE_READ_ECC                             0x33
#define NAND_CMD_PAGE_READ_ALL                             0x34
#define NAND_CMD_SEQ_PAGE_READ                             0x15
#define NAND_CMD_PRG_PAGE                                  0x36
#define NAND_CMD_PRG_PAGE_ECC                              0x37
#define NAND_CMD_PRG_PAGE_ALL                              0x39
#define NAND_CMD_BLOCK_ERASE                               0x3A
#define NAND_CMD_FETCH_ID                                  0x0B
#define NAND_CMD_STATUS                                    0x0C
#define NAND_CMD_RESET                                     0x0D

/* NAND Status errors */
#define NAND_FLASH_MPU_ERR                                 (1 << 8)
#define NAND_FLASH_TIMEOUT_ERR                             (1 << 6)
#define NAND_FLASH_OP_ERR                                  (1 << 4)

#define NAND_FLASH_ERR                                     (NAND_FLASH_MPU_ERR | \
                                                           NAND_FLASH_TIMEOUT_ERR | \
                                                           NAND_FLASH_OP_ERR)

#define PROG_ERASE_OP_RESULT                               (1 << 7)

#define DATA_CONSUMER_PIPE_INDEX                           0
#define DATA_PRODUCER_PIPE_INDEX                           1
#define CMD_PIPE_INDEX                                     2

/* Define BAM pipe lock groups for NANDc*/
#define P_LOCK_GROUP_0                                     0

/* Define BAM pipe lock super groups for NANDc
 * Note: This is configured by TZ.
 */
#define P_LOCK_SUPERGROUP_0                                0
#define P_LOCK_SUPERGROUP_1                                1

#define ONFI_SIGNATURE                                     0x49464E4F

#define ONFI_CRC_POLYNOMIAL                                0x8005
#define ONFI_CRC_INIT_VALUE                                0x4F4E

#define ONFI_READ_PARAM_PAGE_ADDR_CYCLES                   1
#define ONFI_READ_ID_ADDR_CYCLES                           1

#define ONFI_READ_ID_CMD                                   0x90
#define ONFI_READ_PARAM_PAGE_CMD                           0xEC
#define ONFI_READ_ID_ADDR                                  0x20
#define ONFI_READ_PARAM_PAGE_ADDR                          0x00

#define NAND_CFG0_RAW_ONFI_ID                              0x88000800
#define NAND_CFG0_RAW_ONFI_PARAM_PAGE                      0x88040000
#define NAND_CFG1_RAW_ONFI_ID                              0x0005045D
#define NAND_CFG1_RAW_ONFI_PARAM_PAGE                      0x0005045D
#define NAND_CFG0                                          0x290409c0
#define NAND_CFG1                                          0x08045d5c
#define NAND_ECC_BCH_CFG                                   0x42040d10
#define NAND_Bad_Block                                     0x00000175
#define NAND_ECC_BUF_CFG                                   0x00000203

#define ONFI_READ_ID_BUFFER_SIZE                           0x4
#define ONFI_READ_PARAM_PAGE_BUFFER_SIZE                   0x200
#define ONFI_PARAM_PAGE_SIZE                               0x100

#define NAND_8BIT_DEVICE                                   0x01
#define NAND_16BIT_DEVICE                                  0x02

#define NAND_CW_SIZE_4_BIT_ECC                             528
#define NAND_CW_SIZE_8_BIT_ECC                             532

/* Indicates the data bytes in the user data portion of the code word. */
#define USER_DATA_BYTES_PER_CW                             512

/* Indicates the number of bytes covered by BCH ECC logic when
 * a codeword is written to a NAND flash device.
 * This is also the number of bytes that are part of the image in  CW.
 * 516 bytes  = (512 bytes of user data and 4 bytes of spare data)
 */
#define DATA_BYTES_IN_IMG_PER_CW                           516

#define NAND_CW_DIV_RIGHT_SHIFT                            9

/* Number of max cw's the driver allows to flash. */
#define QPIC_NAND_MAX_CWS_IN_PAGE                          10

/* Reset Values for Status registers */
#define NAND_FLASH_STATUS_RESET                            0x00000020
#define NAND_READ_STATUS_RESET                             0x000000C0

/* result type */
typedef enum {
	NANDC_RESULT_SUCCESS = 0,
	NANDC_RESULT_FAILURE = 1,
	NANDC_RESULT_TIMEOUT = 2,
	NANDC_RESULT_PARAM_INVALID = 3,
	NANDC_RESULT_DEV_NOT_SUPPORTED = 4,
	NANDC_RESULT_BAD_PAGE = 5,
	NANDC_RESULT_BAD_BLOCK = 6,
} nand_result_t;

enum nand_bad_block_value
{
	NAND_BAD_BLK_VALUE_NOT_READ,
	NAND_BAD_BLK_VALUE_IS_BAD,
	NAND_BAD_BLK_VALUE_IS_GOOD,
};

enum nand_cfg_value
{
	NAND_CFG_RAW,
	NAND_CFG,
};

struct onfi_param_page
{
	uint32_t signature;
	uint16_t rev;
	uint16_t feature_supported;
	uint16_t opt_cmd_supported;
	uint8_t reserved_1[22];
	uint8_t mib[12];
	uint8_t device_model[20];
	uint8_t manufacturer_id;
	uint16_t date_code;
	uint8_t  reserved_2[13];
	uint32_t data_per_pg;
	uint16_t spare_per_pg;
	uint32_t data_per_partial_pg;
	uint16_t spare_per_partial_pg;
	uint32_t pgs_per_blk;
	uint32_t blks_per_LUN;
	uint8_t num_LUN;
	uint8_t num_addr_cycles;
	uint8_t num_bits_per_cell;
	uint16_t bad_blks_max_per_LUN;
	uint16_t blk_endurance;
	uint8_t guaranteed_vld_blks_at_start;
	uint16_t blk_endurance_for_garunteed_vld_blks;
	uint8_t num_prg_per_pg;
	uint8_t partial_prog_attr;
	uint8_t num_bits_ecc_correctability;
	uint8_t num_interleaved_addr_bits;
	uint8_t interleaved_op_attr;
	uint8_t reserved_3[13];
	uint8_t io_pin_capcacitance;
	uint16_t timing_mode_support;
	uint16_t prog_cache_timing_mode_support;
	uint16_t max_pg_prog_time_us;
	uint16_t max_blk_erase_time_us;
	uint16_t max_pr_rd_time_us;
	uint16_t min_chg_col_setup_time_us;
	uint8_t reserved_4[23];
	uint16_t vendor_rev;
	uint8_t vendor_specific[88];
	uint16_t interity_crc;
}__PACKED;

struct cfg_params
{
	uint32_t addr0;
	uint32_t addr1;
	uint32_t cfg0;
	uint32_t cfg1;
	uint32_t cmd;
	uint32_t ecc_cfg;
	uint32_t addr_loc_0;
	uint32_t exec;
};

struct onfi_probe_params
{
	uint32_t vld;
	uint32_t dev_cmd1;
	struct cfg_params cfg;
};

/* This stucture is used to create a static list of devices we support.
 * This include a subset of values defined in the flash_info struct as
 * other values can be derived.
 */
struct flash_id
{
	unsigned flash_id;
	unsigned flash_id2;
	unsigned mask;
	unsigned mask2;
	unsigned density;
	unsigned widebus;
	unsigned pagesize;
	unsigned blksize;
	unsigned oobsize;
	unsigned ecc_8_bits;
};

/* Structure to hold the pipe numbers */
struct qpic_nand_bam_pipes
{
	unsigned read_pipe;
	unsigned write_pipe;
	unsigned cmd_pipe;
	uint8_t  read_pipe_grp;
	uint8_t  write_pipe_grp;
	uint8_t  cmd_pipe_grp;
};

/* Structure to define the initial nand config */
struct qpic_nand_init_config
{
	uint32_t nand_base;
	uint32_t bam_base;
	uint32_t ee;
	uint32_t max_desc_len;
	struct qpic_nand_bam_pipes pipes;
};

void
qpic_nand_init(struct qpic_nand_init_config *config);
unsigned flash_num_blocks(void);
unsigned
flash_block_size(void);
void
qpic_nand_uninit();
/* Api to return the nand base */
uint32_t nand_device_base();
nand_result_t qpic_nand_read(uint32_t start_page, uint32_t num_pages,
		unsigned char* buffer, unsigned char* spareaddr);
nand_result_t qpic_nand_write(uint32_t start_page, uint32_t num_pages,
		unsigned char* buffer, unsigned  write_extra_bytes);
nand_result_t qpic_nand_block_isbad(unsigned page);
nand_result_t qpic_nand_blk_erase(uint32_t page);

#endif