1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "onfi.h"
6
7 #include <string.h>
8 #include <unistd.h>
9
10 #include <ddk/debug.h>
11
12 /*
13 * Database of settings for the NAND flash devices we support.
14 * Note on chip_delay: chip_delay is the delay after we enqueue certain ONFI
15 * commands (RESET, READSTART). The value of 30us was experimentally picked for
16 * the Samsung NAND, and 20us for the Toshiba NAND. It turns out that a value
17 * of 25us works better for the Micron NAND (25us reduces the number of ECC
18 * errors significantly).
19 * TODO(ZX-2696): Determine the value of chip delay more scientifically.
20 */
21 struct nand_chip_table nand_chip_table[] = {
22 {0x2C, 0xDC, "Micron", "MT29F4G08ABAEA", {20, 16, 15}, 25, true, 512, 0, 0, 0, 0},
23 {0xEC, 0xDC, "Samsung", "K9F4G08U0F", {25, 20, 15}, 30, true, 512, 0, 0, 0, 0},
24 /* TODO: This works. but doublecheck Toshiba nand_timings from datasheet */
25 {0x98, 0xDC, "Toshiba", "TC58NVG2S0F", {25, 20, /* 15 */ 25}, 25, true, 512, 0, 0, 0, 0},
26 };
27
28 #define NAND_CHIP_TABLE_SIZE \
29 (sizeof(nand_chip_table) / sizeof(struct nand_chip_table))
30
31 /*
32 * Find the entry in the NAND chip table database based on manufacturer
33 * id and device id
34 */
find_nand_chip_table(uint8_t manuf_id,uint8_t device_id)35 struct nand_chip_table* find_nand_chip_table(uint8_t manuf_id,
36 uint8_t device_id) {
37 for (uint32_t i = 0; i < NAND_CHIP_TABLE_SIZE; i++)
38 if (manuf_id == nand_chip_table[i].manufacturer_id &&
39 device_id == nand_chip_table[i].device_id)
40 return &nand_chip_table[i];
41 return NULL;
42 }
43
44 /*
45 * onfi_wait() and onfi_command() are generic ONFI protocol compliant.
46 *
47 * Generic wait function used by both program (write) and erase
48 * functionality.
49 */
onfi_wait(onfi_callback_t * cb,uint32_t timeout_ms)50 zx_status_t onfi_wait(onfi_callback_t* cb, uint32_t timeout_ms) {
51 uint64_t total_time = 0;
52 uint8_t cmd_status;
53
54 cb->cmd_ctrl(cb->ctx, NAND_CMD_STATUS, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
55 cb->cmd_ctrl(cb->ctx, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
56 while (!((cmd_status = cb->read_byte(cb->ctx)) & NAND_STATUS_READY)) {
57 usleep(10);
58 total_time += 10;
59 if (total_time > (timeout_ms * 1000)) {
60 break;
61 }
62 }
63 if (!(cmd_status & NAND_STATUS_READY)) {
64 zxlogf(ERROR, "nand command wait timed out\n");
65 return ZX_ERR_TIMED_OUT;
66 }
67 if (cmd_status & NAND_STATUS_FAIL) {
68 zxlogf(ERROR, "%s: nand command returns error\n", __func__);
69 return ZX_ERR_IO;
70 }
71 return ZX_OK;
72 }
73
74 /*
75 * Send onfi command down to the controller.
76 */
onfi_command(onfi_callback_t * cb,uint32_t command,int32_t column,int32_t page_addr,uint32_t capacity_mb,uint32_t chip_delay_us,int buswidth_16)77 void onfi_command(onfi_callback_t* cb, uint32_t command,
78 int32_t column, int32_t page_addr,
79 uint32_t capacity_mb, uint32_t chip_delay_us,
80 int buswidth_16) {
81 cb->cmd_ctrl(cb->ctx, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
82 if (column != -1 || page_addr != -1) {
83 uint32_t ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
84
85 if (column != -1) {
86 /* 16 bit buswidth ? */
87 if (buswidth_16)
88 column >>= 1;
89 cb->cmd_ctrl(cb->ctx, column, ctrl);
90 ctrl &= ~NAND_CTRL_CHANGE;
91 cb->cmd_ctrl(cb->ctx, column >> 8, ctrl);
92 }
93 if (page_addr != -1) {
94 cb->cmd_ctrl(cb->ctx, page_addr, ctrl);
95 cb->cmd_ctrl(cb->ctx, page_addr >> 8,
96 NAND_NCE | NAND_ALE);
97 /* one more address cycle for devices > 128M */
98 if (capacity_mb > 128)
99 cb->cmd_ctrl(cb->ctx, page_addr >> 16, NAND_NCE | NAND_ALE);
100 }
101 }
102 cb->cmd_ctrl(cb->ctx, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
103
104 if (command == NAND_CMD_ERASE1 || command == NAND_CMD_ERASE2 ||
105 command == NAND_CMD_SEQIN || command == NAND_CMD_PAGEPROG)
106 return;
107 if (command == NAND_CMD_RESET) {
108 usleep(chip_delay_us);
109 cb->cmd_ctrl(cb->ctx, NAND_CMD_STATUS, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
110 cb->cmd_ctrl(cb->ctx, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
111 /* We have to busy loop until ready */
112 while (!(cb->read_byte(cb->ctx) & NAND_STATUS_READY))
113 ;
114 return;
115 }
116 if (command == NAND_CMD_READ0) {
117 cb->cmd_ctrl(cb->ctx, NAND_CMD_READSTART, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
118 cb->cmd_ctrl(cb->ctx, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
119 }
120 usleep(chip_delay_us);
121 }
122