9 Nand_chip::Nand_chip(Nand_ctrl *ctrl, Dev_desc *dev, Mfr_desc *mfr, int ext_id)
10 : _state(Ready), _ongoing_op(0), _ctrl(ctrl), _dev(dev), _mfr(mfr)
12 /* New devices have all the information in additional id bytes */
15 /* The 3rd id byte holds MLC / multichip data */
16 _sz_write = 1024 << (ext_id & 0x3);
18 _sz_spare = (8 << (ext_id & 0x01)) * (_sz_write >> 9);
20 _sz_erase = (64 * 1024) << (ext_id & 0x03);
22 _bus_width = (ext_id & 0x01) ? Opt_buswidth_16 : 0;
24 /* Old devices have chip data hardcoded in the device id table */
27 _sz_write = dev->sz_page;
28 _sz_spare = dev->sz_spare ? dev->sz_spare : _sz_write / 32;
29 _sz_erase = dev->sz_erase;
30 _bus_width = dev->options & Opt_buswidth_16;
32 _sz_chip = (long long unsigned)dev->sz_chip << 20;
34 if (_bus_width != (_options & Opt_buswidth_16))
36 printf("NAND bus width %d instead %d bit\n",
37 (_options & Opt_buswidth_16) ? 16 : 8, _bus_width ? 16 : 8);
40 _options |= dev->options;
41 _options |= Opt_no_autoincr;
43 printf("NAND chip: Mfr ID: 0x%02x(%s), Device ID: 0x%02x(%s)\n",
44 mfr->id, mfr->name, dev->id, dev->name);
47 int Nand_chip::handle_irq()
52 return _ctrl->done_read(static_cast<Read_op *>(_ongoing_op));
56 return _ctrl->done_write(static_cast<Write_op *>(_ongoing_op));
60 return _ctrl->done_erase(static_cast<Erase_op *>(_ongoing_op));
70 bool Nand_ctrl::is_wp()
73 return (rd_dat() & Status_wp) ? false : true;
76 int Nand_ctrl::get_status()
82 int Nand_ctrl::read(Read_op *op)
84 Nand_chip *chip = select(op->addr);
86 if (!op->transfer->len)
89 u16 col = op->addr & (chip->sz_write() - 1);
90 u32 row = (op->addr >> chip->page_shift()) & chip->page_mask();
93 assert(op->transfer->len + col <= (chip->sz_write() + chip->sz_spare()));
101 wr_cmd(Cmd_readstart);
103 chip->set_state(Nand_chip::Reading, op);
108 int Nand_ctrl::done_read(Read_op *op)
110 Nand_chip *chip = select(op->addr);
111 assert(chip->state() == Nand_chip::Reading);
113 for (unsigned i = 0; i < op->transfer->num; ++i)
114 rd_dat((u8 *)(*op->transfer)[i].addr, (*op->transfer)[i].size);
116 chip->set_state(Nand_chip::Ready);
120 int Nand_ctrl::write(Write_op *op)
122 Nand_chip *chip = select(op->addr);
124 if (!op->transfer->len)
127 // check end of device
128 if ((op->addr + op->transfer->len) > size)
131 // check page aligning
132 if (!aligned(op->addr))
134 printf("NAND: Attempt to write not page aligned data\n");
140 printf("NAND: Device is write protected\n");
144 u32 page = (op->addr >> chip->page_shift()) & chip->page_mask();
153 for (unsigned i = 0; i < op->transfer->num; ++i)
154 wr_dat((u8 *)(*op->transfer)[i].addr, (*op->transfer)[i].size);
156 wr_cmd(Cmd_pageprog);
157 chip->set_state(Nand_chip::Writing, op);
162 int Nand_ctrl::done_write(Write_op *op)
164 Nand_chip *chip = select(op->addr);
165 assert(chip->state() == Nand_chip::Writing);
166 chip->set_state(Nand_chip::Ready);
167 return (get_status() & Status_fail) ? -EIO : 0;
170 int Nand_ctrl::erase(Erase_op *op)
172 Nand_chip *chip = select(op->addr);
175 printf("nand: erase: start = 0x%08x, len = %u\n",
176 (unsigned int) op->addr, op->len);
179 /* address must align on block boundary */
180 if (op->addr & chip->erase_mask())
182 printf("nand: erase: Unaligned address\n");
186 /* length must align on block boundary */
187 if (op->len & chip->erase_mask())
189 printf("nand: erase: Length not block aligned\n");
193 /* Do not allow erase past end of device */
194 if ((op->len + op->addr) > size)
196 printf("nand: erase: Erase past end of device\n");
200 /* Check, if it is write protected */
203 printf("nand_erase: Device is write protected!!!\n");
207 int page = op->addr >> chip->page_shift();
215 chip->set_state(Nand_chip::Erasing, op);
220 int Nand_ctrl::done_erase(Erase_op *op)
222 Nand_chip *chip = select(op->addr);
223 assert(chip->state() == Nand_chip::Erasing);
224 chip->set_state(Nand_chip::Ready);
225 return (get_status() & Status_fail) ? -EIO : 0;
228 int Nand_ctrl::get_id(char id[4])
242 int Nand_ctrl::scan(int maxchips)
244 for (int i = 0; i < maxchips; ++i)
249 while (!(rd_dat() & Status_ready));
255 if (id1[0] != id2[0] || id1[1] != id2[1])
257 printf("manufacturer or device id corrupt:\n");
258 printf("mfr-id1:%02x mfr-id2:%02x\n", id1[0], id2[0]);
259 printf("dev-id1:%02x dev-id2:%02x\n", id1[1], id2[1]);
263 /* identify manufacturer */
265 for (int j = 0; _mfr_ids[j].id != 0; j++)
267 if (id1[0] == _mfr_ids[j].id)
274 /* identify device */
276 for (int j = 0; _dev_ids[j].name != 0; j++)
278 if (id1[1] == _dev_ids[j].id)
287 printf("no device device found\n");
292 printf("no manufacturer found\n");
296 Nand_chip *chip = new Nand_chip(this, dev, mfr, id1[3]);
299 // XXX all chips should have the same features
300 sz_write = chip->sz_write();
301 sz_spare = chip->sz_spare();
302 sz_erase = chip->sz_erase();
304 size += chip->sz_chip();
308 //printf("%d NAND chips detected\n", numchips);
313 Nand_ctrl::Nand_ctrl()