xref: /NextBSD/sys/dev/nand/nfc_fsl.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
1 /*-
2  * Copyright (C) 2012 Juniper Networks, Inc.
3  * Copyright (C) 2009-2012 Semihalf
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 /*
28  * TODO :
29  *
30  *  -- test support for small pages
31  *  -- support for reading ONFI parameters
32  *  -- support for cached and interleaving commands
33  *  -- proper setting of AL bits in FMR
34  */
35 
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/proc.h>
42 #include <sys/bus.h>
43 #include <sys/conf.h>
44 #include <sys/kernel.h>
45 #include <sys/module.h>
46 #include <sys/malloc.h>
47 #include <sys/rman.h>
48 #include <sys/sysctl.h>
49 #include <sys/time.h>
50 #include <sys/kdb.h>
51 
52 #include <machine/bus.h>
53 
54 #include <dev/ofw/ofw_bus.h>
55 #include <dev/ofw/ofw_bus_subr.h>
56 
57 #include <powerpc/mpc85xx/lbc.h>
58 
59 #include <dev/nand/nand.h>
60 #include <dev/nand/nandbus.h>
61 
62 #include "nfc_fsl.h"
63 
64 #include "nfc_if.h"
65 
66 #define LBC_READ(regname)	lbc_read_reg(dev, (LBC85XX_ ## regname))
67 #define LBC_WRITE(regname, val)	lbc_write_reg(dev, (LBC85XX_ ## regname), val)
68 
69 enum addr_type {
70 	ADDR_NONE,
71 	ADDR_ID,
72 	ADDR_ROW,
73 	ADDR_ROWCOL
74 };
75 
76 struct fsl_nfc_fcm {
77 	/* Read-only after initialization */
78 	uint32_t	reg_fmr;
79 
80 	/* To be preserved across "start_command" */
81 	u_int		buf_ofs;
82 	u_int		read_ptr;
83 	u_int		status:1;
84 
85 	/* Command state -- cleared by "start_command" */
86 	uint32_t	fcm_startzero;
87 	uint32_t	reg_fcr;
88 	uint32_t	reg_fir;
89 	uint32_t	reg_mdr;
90 	uint32_t	reg_fbcr;
91 	uint32_t	reg_fbar;
92 	uint32_t	reg_fpar;
93 	u_int		cmdnr;
94 	u_int		opnr;
95 	u_int		pg_ofs;
96 	enum addr_type	addr_type;
97 	u_int		addr_bytes;
98 	u_int		row_addr;
99 	u_int		column_addr;
100 	u_int		data_fir:8;
101 	uint32_t	fcm_endzero;
102 };
103 
104 struct fsl_nand_softc {
105 	struct nand_softc		nand_dev;
106 	device_t			dev;
107 	struct resource			*res;
108 	int				rid;		/* Resourceid */
109 	struct lbc_devinfo		*dinfo;
110 	struct fsl_nfc_fcm		fcm;
111 	uint8_t				col_cycles;
112 	uint8_t				row_cycles;
113 	uint16_t			pgsz;		/* Page size */
114 };
115 
116 static int	fsl_nand_attach(device_t dev);
117 static int	fsl_nand_probe(device_t dev);
118 static int	fsl_nand_detach(device_t dev);
119 
120 static int	fsl_nfc_select_cs(device_t dev, uint8_t cs);
121 static int	fsl_nfc_read_rnb(device_t dev);
122 static int	fsl_nfc_send_command(device_t dev, uint8_t command);
123 static int	fsl_nfc_send_address(device_t dev, uint8_t address);
124 static uint8_t	fsl_nfc_read_byte(device_t dev);
125 static int	fsl_nfc_start_command(device_t dev);
126 static void	fsl_nfc_read_buf(device_t dev, void *buf, uint32_t len);
127 static void	fsl_nfc_write_buf(device_t dev, void *buf, uint32_t len);
128 
129 static device_method_t fsl_nand_methods[] = {
130 	DEVMETHOD(device_probe,		fsl_nand_probe),
131 	DEVMETHOD(device_attach,	fsl_nand_attach),
132 	DEVMETHOD(device_detach,	fsl_nand_detach),
133 
134 	DEVMETHOD(nfc_select_cs,	fsl_nfc_select_cs),
135 	DEVMETHOD(nfc_read_rnb,		fsl_nfc_read_rnb),
136 	DEVMETHOD(nfc_start_command,	fsl_nfc_start_command),
137 	DEVMETHOD(nfc_send_command,	fsl_nfc_send_command),
138 	DEVMETHOD(nfc_send_address,	fsl_nfc_send_address),
139 	DEVMETHOD(nfc_read_byte,	fsl_nfc_read_byte),
140 	DEVMETHOD(nfc_read_buf,		fsl_nfc_read_buf),
141 	DEVMETHOD(nfc_write_buf,	fsl_nfc_write_buf),
142 	{ 0, 0 },
143 };
144 
145 static driver_t fsl_nand_driver = {
146 	"nand",
147 	fsl_nand_methods,
148 	sizeof(struct fsl_nand_softc),
149 };
150 
151 static devclass_t fsl_nand_devclass;
152 
153 DRIVER_MODULE(fsl_nand, lbc, fsl_nand_driver, fsl_nand_devclass,
154     0, 0);
155 
156 static int fsl_nand_build_address(device_t dev, uint32_t page, uint32_t column);
157 static int fsl_nand_chip_preprobe(device_t dev, struct nand_id *id);
158 
159 #ifdef NAND_DEBUG_TIMING
160 static device_t fcm_devs[8];
161 #endif
162 
163 #define CMD_SHIFT(cmd_num)	(24 - ((cmd_num) * 8))
164 #define OP_SHIFT(op_num)	(28 - ((op_num) * 4))
165 
166 #define FSL_LARGE_PAGE_SIZE	(2112)
167 #define FSL_SMALL_PAGE_SIZE	(528)
168 
169 static void
fsl_nand_init_regs(struct fsl_nand_softc * sc)170 fsl_nand_init_regs(struct fsl_nand_softc *sc)
171 {
172 	uint32_t or_v, br_v;
173 	device_t dev;
174 
175 	dev = sc->dev;
176 
177 	sc->fcm.reg_fmr = (15 << FMR_CWTO_SHIFT);
178 
179 	/*
180 	 * Setup 4 row cycles and hope that chip ignores superfluous address
181 	 * bytes.
182 	 */
183 	sc->fcm.reg_fmr |= (2 << FMR_AL_SHIFT);
184 
185 	/* Reprogram BR(x) */
186 	br_v = lbc_read_reg(dev, LBC85XX_BR(sc->dinfo->di_bank));
187 	br_v &= 0xffff8000;
188 	br_v |= 1 << 11;	/* 8-bit port size */
189 	br_v |= 0 << 9;		/* No ECC checking and generation */
190 	br_v |= 1 << 5;		/* FCM machine */
191 	br_v |= 1;		/* Valid */
192 	lbc_write_reg(dev, LBC85XX_BR(sc->dinfo->di_bank), br_v);
193 
194 	/* Reprogram OR(x) */
195 	or_v = lbc_read_reg(dev, LBC85XX_OR(sc->dinfo->di_bank));
196 	or_v &= 0xfffffc00;
197 	or_v |= 0x03AE;		/* Default POR timing */
198 	lbc_write_reg(dev, LBC85XX_OR(sc->dinfo->di_bank), or_v);
199 
200 	if (or_v & OR_FCM_PAGESIZE) {
201 		sc->pgsz = FSL_LARGE_PAGE_SIZE;
202 		sc->col_cycles = 2;
203 		nand_debug(NDBG_DRV, "%s: large page NAND device at #%d",
204 		    device_get_nameunit(dev), sc->dinfo->di_bank);
205 	} else {
206 		sc->pgsz = FSL_SMALL_PAGE_SIZE;
207 		sc->col_cycles = 1;
208 		nand_debug(NDBG_DRV, "%s: small page NAND device at #%d",
209 		    device_get_nameunit(dev), sc->dinfo->di_bank);
210 	}
211 }
212 
213 static int
fsl_nand_probe(device_t dev)214 fsl_nand_probe(device_t dev)
215 {
216 
217 	if (!ofw_bus_is_compatible(dev, "fsl,elbc-fcm-nand"))
218 		return (ENXIO);
219 
220 	device_set_desc(dev, "Freescale localbus FCM Controller");
221 	return (BUS_PROBE_DEFAULT);
222 }
223 
224 static int
fsl_nand_attach(device_t dev)225 fsl_nand_attach(device_t dev)
226 {
227 	struct fsl_nand_softc *sc;
228 	struct nand_id id;
229 	struct nand_params *param;
230 	uint32_t num_pages;
231 
232 	sc = device_get_softc(dev);
233 	sc->dev = dev;
234 	sc->dinfo = device_get_ivars(dev);
235 
236 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
237 	    RF_ACTIVE);
238 	if (sc->res == NULL) {
239 		device_printf(dev, "could not allocate resources!\n");
240 		return (ENXIO);
241 	}
242 
243 	bzero(&sc->fcm, sizeof(sc->fcm));
244 
245 	/* Init register and check if HW ECC turned on */
246 	fsl_nand_init_regs(sc);
247 
248 	/* Chip is probed, so determine number of row address cycles */
249 	fsl_nand_chip_preprobe(dev, &id);
250 	param = nand_get_params(&id);
251 	if (param != NULL) {
252 		num_pages = (param->chip_size << 20) / param->page_size;
253 		while(num_pages) {
254 			sc->row_cycles++;
255 			num_pages >>= 8;
256 		}
257 
258 		sc->fcm.reg_fmr &= ~(FMR_AL);
259 		sc->fcm.reg_fmr |= (sc->row_cycles - 2) << FMR_AL_SHIFT;
260 	}
261 
262 	nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL);
263 
264 #ifdef NAND_DEBUG_TIMING
265 	fcm_devs[sc->dinfo->di_bank] = dev;
266 #endif
267 
268 	return (nandbus_create(dev));
269 }
270 
271 static int
fsl_nand_detach(device_t dev)272 fsl_nand_detach(device_t dev)
273 {
274 	struct fsl_nand_softc *sc;
275 
276 	sc = device_get_softc(dev);
277 
278 	if (sc->res != NULL)
279 		bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res);
280 
281 	return (0);
282 }
283 
284 static int
fsl_nfc_select_cs(device_t dev,uint8_t cs)285 fsl_nfc_select_cs(device_t dev, uint8_t cs)
286 {
287 
288 	// device_printf(dev, "%s(cs=%u)\n", __func__, cs);
289 	return ((cs > 0) ? EINVAL : 0);
290 }
291 
292 static int
fsl_nfc_read_rnb(device_t dev)293 fsl_nfc_read_rnb(device_t dev)
294 {
295 
296 	// device_printf(dev, "%s()\n", __func__);
297 	return (0);
298 }
299 
300 static int
fsl_nfc_send_command(device_t dev,uint8_t command)301 fsl_nfc_send_command(device_t dev, uint8_t command)
302 {
303 	struct fsl_nand_softc *sc;
304 	struct fsl_nfc_fcm *fcm;
305 	uint8_t	fir_op;
306 
307 	// device_printf(dev, "%s(command=%u)\n", __func__, command);
308 
309 	sc = device_get_softc(dev);
310 	fcm = &sc->fcm;
311 
312 	if (command == NAND_CMD_PROG_END) {
313 		fcm->reg_fir |= (FIR_OP_WB << OP_SHIFT(fcm->opnr));
314 		fcm->opnr++;
315 	}
316 	fcm->reg_fcr |= command << CMD_SHIFT(fcm->cmdnr);
317 	fir_op = (fcm->cmdnr == 0) ? FIR_OP_CW0 : FIR_OP_CM(fcm->cmdnr);
318 	fcm->cmdnr++;
319 
320 	fcm->reg_fir |= (fir_op << OP_SHIFT(fcm->opnr));
321 	fcm->opnr++;
322 
323 	switch (command) {
324 	case NAND_CMD_READ_ID:
325 		fcm->data_fir = FIR_OP_RBW;
326 		fcm->addr_type = ADDR_ID;
327 		break;
328 	case NAND_CMD_SMALLOOB:
329 		fcm->pg_ofs += 256;
330 		/*FALLTHROUGH*/
331 	case NAND_CMD_SMALLB:
332 		fcm->pg_ofs += 256;
333 		/*FALLTHROUGH*/
334 	case NAND_CMD_READ: /* NAND_CMD_SMALLA */
335 		fcm->data_fir = FIR_OP_RBW;
336 		fcm->addr_type = ADDR_ROWCOL;
337 		break;
338 	case NAND_CMD_STATUS:
339 		fcm->data_fir = FIR_OP_RS;
340 		fcm->status = 1;
341 		break;
342 	case NAND_CMD_ERASE:
343 		fcm->addr_type = ADDR_ROW;
344 		break;
345 	case NAND_CMD_PROG:
346 		fcm->addr_type = ADDR_ROWCOL;
347 		break;
348 	}
349 	return (0);
350 }
351 
352 static int
fsl_nfc_send_address(device_t dev,uint8_t addr)353 fsl_nfc_send_address(device_t dev, uint8_t addr)
354 {
355 	struct fsl_nand_softc *sc;
356 	struct fsl_nfc_fcm *fcm;
357 	uint32_t addr_bits;
358 
359 	// device_printf(dev, "%s(address=%u)\n", __func__, addr);
360 
361 	sc = device_get_softc(dev);
362 	fcm = &sc->fcm;
363 
364 	KASSERT(fcm->addr_type != ADDR_NONE,
365 	    ("controller doesn't expect address cycle"));
366 
367 	addr_bits = addr;
368 
369 	if (fcm->addr_type == ADDR_ID) {
370 		fcm->reg_fir |= (FIR_OP_UA << OP_SHIFT(fcm->opnr));
371 		fcm->opnr++;
372 
373 		fcm->reg_fbcr = 5;
374 		fcm->reg_fbar = 0;
375 		fcm->reg_fpar = 0;
376 		fcm->reg_mdr = addr_bits;
377 		fcm->buf_ofs = 0;
378 		fcm->read_ptr = 0;
379 		return (0);
380 	}
381 
382 	if (fcm->addr_type == ADDR_ROW) {
383 		addr_bits <<= fcm->addr_bytes * 8;
384 		fcm->row_addr |= addr_bits;
385 		fcm->addr_bytes++;
386 		if (fcm->addr_bytes < sc->row_cycles)
387 			return (0);
388 	} else {
389 		if (fcm->addr_bytes < sc->col_cycles) {
390 			addr_bits <<= fcm->addr_bytes * 8;
391 			fcm->column_addr |= addr_bits;
392 		} else {
393 			addr_bits <<= (fcm->addr_bytes - sc->col_cycles) * 8;
394 			fcm->row_addr |= addr_bits;
395 		}
396 		fcm->addr_bytes++;
397 		if (fcm->addr_bytes < (sc->row_cycles + sc->col_cycles))
398 			return (0);
399 	}
400 
401 	return (fsl_nand_build_address(dev, fcm->row_addr, fcm->column_addr));
402 }
403 
404 static int
fsl_nand_build_address(device_t dev,uint32_t row,uint32_t column)405 fsl_nand_build_address(device_t dev, uint32_t row, uint32_t column)
406 {
407 	struct fsl_nand_softc *sc;
408 	struct fsl_nfc_fcm *fcm;
409 	uint32_t byte_count = 0;
410 	uint32_t block_address = 0;
411 	uint32_t page_address = 0;
412 
413 	sc = device_get_softc(dev);
414 	fcm = &sc->fcm;
415 
416 	fcm->read_ptr = 0;
417 	fcm->buf_ofs = 0;
418 
419 	if (fcm->addr_type == ADDR_ROWCOL) {
420 		fcm->reg_fir |= (FIR_OP_CA << OP_SHIFT(fcm->opnr));
421 		fcm->opnr++;
422 
423 		column += fcm->pg_ofs;
424 		fcm->pg_ofs = 0;
425 
426 		page_address |= column;
427 
428 		if (column != 0) {
429 			byte_count = sc->pgsz - column;
430 			fcm->read_ptr = column;
431 		}
432 	}
433 
434 	fcm->reg_fir |= (FIR_OP_PA << OP_SHIFT(fcm->opnr));
435 	fcm->opnr++;
436 
437 	if (sc->pgsz == FSL_LARGE_PAGE_SIZE) {
438 		block_address = row >> 6;
439 		page_address |= ((row << FPAR_LP_PI_SHIFT) & FPAR_LP_PI);
440 		fcm->buf_ofs = (row & 1) * 4096;
441 	} else {
442 		block_address = row >> 5;
443 		page_address |= ((row << FPAR_SP_PI_SHIFT) & FPAR_SP_PI);
444 		fcm->buf_ofs = (row & 7) * 1024;
445 	}
446 
447 	fcm->reg_fbcr = byte_count;
448 	fcm->reg_fbar = block_address;
449 	fcm->reg_fpar = page_address;
450 	return (0);
451 }
452 
453 static int
fsl_nfc_start_command(device_t dev)454 fsl_nfc_start_command(device_t dev)
455 {
456 	struct fsl_nand_softc *sc;
457 	struct fsl_nfc_fcm *fcm;
458 	uint32_t fmr, ltesr_v;
459 	int error, timeout;
460 
461 	// device_printf(dev, "%s()\n", __func__);
462 
463 	sc = device_get_softc(dev);
464 	fcm = &sc->fcm;
465 
466 	fmr = fcm->reg_fmr | FMR_OP;
467 
468 	if (fcm->data_fir)
469 		fcm->reg_fir |= (fcm->data_fir << OP_SHIFT(fcm->opnr));
470 
471 	LBC_WRITE(FIR, fcm->reg_fir);
472 	LBC_WRITE(FCR, fcm->reg_fcr);
473 
474 	LBC_WRITE(FMR, fmr);
475 
476 	LBC_WRITE(FBCR, fcm->reg_fbcr);
477 	LBC_WRITE(FBAR, fcm->reg_fbar);
478 	LBC_WRITE(FPAR, fcm->reg_fpar);
479 
480 	if (fcm->addr_type == ADDR_ID)
481 		LBC_WRITE(MDR, fcm->reg_mdr);
482 
483 	nand_debug(NDBG_DRV, "BEFORE:\nFMR=%#x, FIR=%#x, FCR=%#x", fmr,
484 	    fcm->reg_fir, fcm->reg_fcr);
485 	nand_debug(NDBG_DRV, "MDR=%#x, FBAR=%#x, FPAR=%#x, FBCR=%#x",
486 	    LBC_READ(MDR), fcm->reg_fbar, fcm->reg_fpar, fcm->reg_fbcr);
487 
488 	LBC_WRITE(LSOR, sc->dinfo->di_bank);
489 
490 	timeout = (cold) ? FSL_FCM_WAIT_TIMEOUT : ~0;
491 	error = 0;
492 	ltesr_v = LBC_READ(LTESR);
493 	while (!error && (ltesr_v & LTESR_CC) == 0) {
494 		if (cold) {
495 			DELAY(1000);
496 			timeout--;
497 			if (timeout < 0)
498 				error = EWOULDBLOCK;
499 		} else
500 			error = tsleep(device_get_parent(sc->dev), PRIBIO,
501 			    "nfcfsl", hz);
502 		ltesr_v = LBC_READ(LTESR);
503 	}
504 	if (error)
505 		nand_debug(NDBG_DRV, "Command complete wait timeout\n");
506 
507 	nand_debug(NDBG_DRV, "AFTER:\nLTESR=%#x, LTEDR=%#x, LTEIR=%#x,"
508 	    " LTEATR=%#x, LTEAR=%#x, LTECCR=%#x", ltesr_v,
509 	    LBC_READ(LTEDR), LBC_READ(LTEIR), LBC_READ(LTEATR),
510 	    LBC_READ(LTEAR), LBC_READ(LTECCR));
511 
512 	bzero(&fcm->fcm_startzero,
513 	    __rangeof(struct fsl_nfc_fcm, fcm_startzero, fcm_endzero));
514 
515 	if (fcm->status)
516 		sc->fcm.reg_mdr = LBC_READ(MDR);
517 
518 	/* Even if timeout occured, we should perform steps below */
519 	LBC_WRITE(LTESR, ltesr_v);
520 	LBC_WRITE(LTEATR, 0);
521 
522 	return (error);
523 }
524 
525 static uint8_t
fsl_nfc_read_byte(device_t dev)526 fsl_nfc_read_byte(device_t dev)
527 {
528 	struct fsl_nand_softc *sc = device_get_softc(dev);
529 	uint32_t offset;
530 
531 	// device_printf(dev, "%s()\n", __func__);
532 
533 	/*
534 	 * LBC controller allows us to read status into a MDR instead of FCM
535 	 * buffer. If last operation requested before read_byte() was STATUS,
536 	 * then return MDR instead of reading a single byte from a buffer.
537 	 */
538 	if (sc->fcm.status) {
539 		sc->fcm.status = 0;
540 		return (sc->fcm.reg_mdr);
541 	}
542 
543 	KASSERT(sc->fcm.read_ptr < sc->pgsz,
544 	    ("Attempt to read beyond buffer %x %x", sc->fcm.read_ptr,
545 	    sc->pgsz));
546 
547 	offset = sc->fcm.buf_ofs + sc->fcm.read_ptr;
548 	sc->fcm.read_ptr++;
549 	return (bus_read_1(sc->res, offset));
550 }
551 
552 static void
fsl_nfc_read_buf(device_t dev,void * buf,uint32_t len)553 fsl_nfc_read_buf(device_t dev, void *buf, uint32_t len)
554 {
555 	struct fsl_nand_softc *sc = device_get_softc(dev);
556 	uint32_t offset;
557 	int bytesleft = 0;
558 
559 	// device_printf(dev, "%s(buf=%p, len=%u)\n", __func__, buf, len);
560 
561 	nand_debug(NDBG_DRV, "REQUEST OF 0x%0x B (BIB=0x%0x, NTR=0x%0x)",
562 	    len, sc->pgsz, sc->fcm.read_ptr);
563 
564 	bytesleft = MIN((unsigned int)len, sc->pgsz - sc->fcm.read_ptr);
565 
566 	offset = sc->fcm.buf_ofs + sc->fcm.read_ptr;
567 	bus_read_region_1(sc->res, offset, buf, bytesleft);
568 	sc->fcm.read_ptr += bytesleft;
569 }
570 
571 static void
fsl_nfc_write_buf(device_t dev,void * buf,uint32_t len)572 fsl_nfc_write_buf(device_t dev, void *buf, uint32_t len)
573 {
574 	struct fsl_nand_softc *sc = device_get_softc(dev);
575 	uint32_t offset;
576 	int bytesleft = 0;
577 
578 	// device_printf(dev, "%s(buf=%p, len=%u)\n", __func__, buf, len);
579 
580 	KASSERT(len <= sc->pgsz - sc->fcm.read_ptr,
581 	    ("Attempt to write beyond buffer"));
582 
583 	bytesleft = MIN((unsigned int)len, sc->pgsz - sc->fcm.read_ptr);
584 
585 	nand_debug(NDBG_DRV, "REQUEST TO WRITE 0x%0x (BIB=0x%0x, NTR=0x%0x)",
586 	    bytesleft, sc->pgsz, sc->fcm.read_ptr);
587 
588 	offset = sc->fcm.buf_ofs + sc->fcm.read_ptr;
589 	bus_write_region_1(sc->res, offset, buf, bytesleft);
590 	sc->fcm.read_ptr += bytesleft;
591 }
592 
593 static int
fsl_nand_chip_preprobe(device_t dev,struct nand_id * id)594 fsl_nand_chip_preprobe(device_t dev, struct nand_id *id)
595 {
596 
597 	if (fsl_nfc_send_command(dev, NAND_CMD_RESET) != 0)
598 		return (ENXIO);
599 
600 	if (fsl_nfc_start_command(dev) != 0)
601 		return (ENXIO);
602 
603 	DELAY(1000);
604 
605 	if (fsl_nfc_send_command(dev, NAND_CMD_READ_ID))
606 		return (ENXIO);
607 
608 	if (fsl_nfc_send_address(dev, 0))
609 		return (ENXIO);
610 
611 	if (fsl_nfc_start_command(dev) != 0)
612 		return (ENXIO);
613 
614 	DELAY(25);
615 
616 	id->man_id = fsl_nfc_read_byte(dev);
617 	id->dev_id = fsl_nfc_read_byte(dev);
618 
619 	nand_debug(NDBG_DRV, "manufacturer id: %x chip id: %x",
620 	    id->man_id, id->dev_id);
621 
622 	return (0);
623 }
624 
625 #ifdef NAND_DEBUG_TIMING
626 
627 static SYSCTL_NODE(_debug, OID_AUTO, fcm, CTLFLAG_RD, 0, "FCM timing");
628 
629 static u_int csct = 1;	/* 22:    Chip select to command time (trlx). */
630 SYSCTL_UINT(_debug_fcm, OID_AUTO, csct, CTLFLAG_RW, &csct, 1,
631     "Chip select to command time: determines how far in advance -LCSn is "
632     "asserted prior to any bus activity during a NAND Flash access handled "
633     "by the FCM. This helps meet chip-select setup times for slow memories.");
634 
635 static u_int cst = 1;	/* 23:    Command setup time (trlx). */
636 SYSCTL_UINT(_debug_fcm, OID_AUTO, cst, CTLFLAG_RW, &cst, 1,
637     "Command setup time: determines the delay of -LFWE assertion relative to "
638     "the command, address, or data change when the external memory access "
639     "is handled by the FCM.");
640 
641 static u_int cht = 1;	/* 24:    Command hold time (trlx). */
642 SYSCTL_UINT(_debug_fcm, OID_AUTO, cht, CTLFLAG_RW, &cht, 1,
643     "Command hold time: determines the -LFWE negation prior to the command, "
644     "address, or data change when the external memory access is handled by "
645     "the FCM.");
646 
647 static u_int scy = 2;	/* 25-27: Cycle length in bus clocks */
648 SYSCTL_UINT(_debug_fcm, OID_AUTO, scy, CTLFLAG_RW, &scy, 2,
649     "Cycle length in bus clocks: see RM");
650 
651 static u_int rst = 1;	/* 28:    Read setup time (trlx). */
652 SYSCTL_UINT(_debug_fcm, OID_AUTO, rst, CTLFLAG_RW, &rst, 1,
653     "Read setup time: determines the delay of -LFRE assertion relative to "
654     "sampling of read data when the external memory access is handled by "
655     "the FCM.");
656 
657 static u_int trlx = 1;	/* 29:    Timing relaxed. */
658 SYSCTL_UINT(_debug_fcm, OID_AUTO, trlx, CTLFLAG_RW, &trlx, 1,
659     "Timing relaxed: modifies the settings of timing parameters for slow "
660     "memories. See RM");
661 
662 static u_int ehtr = 1;	/* 30:    Extended hold time on read accesses. */
663 SYSCTL_UINT(_debug_fcm, OID_AUTO, ehtr, CTLFLAG_RW, &ehtr, 1,
664     "Extended hold time on read accesses: indicates with TRLX how many "
665     "cycles are inserted between a read access from the current bank and "
666     "the next access.");
667 
668 static u_int
fsl_nand_get_timing(void)669 fsl_nand_get_timing(void)
670 {
671 	u_int timing;
672 
673 	timing = ((csct & 1) << 9) | ((cst & 1) << 8) | ((cht & 1) << 7) |
674 	    ((scy & 7) << 4) | ((rst & 1) << 3) | ((trlx & 1) << 2) |
675 	    ((ehtr & 1) << 1);
676 
677 	printf("nfc_fsl: timing = %u\n", timing);
678 	return (timing);
679 }
680 
681 static int
fsl_sysctl_program(SYSCTL_HANDLER_ARGS)682 fsl_sysctl_program(SYSCTL_HANDLER_ARGS)
683 {
684 	struct fsl_nand_softc *sc;
685 	int error, i;
686 	device_t dev;
687 	uint32_t or_v;
688 
689 	error = sysctl_wire_old_buffer(req, sizeof(int));
690 	if (error == 0) {
691 		i = 0;
692 		error = sysctl_handle_int(oidp, &i, 0, req);
693 	}
694 	if (error != 0 || req->newptr == NULL)
695 		return (error);
696 
697 	for (i = 0; i < 8; i++) {
698 		dev = fcm_devs[i];
699 		if (dev == NULL)
700 			continue;
701 		sc = device_get_softc(dev);
702 
703 		/* Reprogram OR(x) */
704 		or_v = lbc_read_reg(dev, LBC85XX_OR(sc->dinfo->di_bank));
705 		or_v &= 0xfffffc00;
706 		or_v |= fsl_nand_get_timing();
707 		lbc_write_reg(dev, LBC85XX_OR(sc->dinfo->di_bank), or_v);
708 	}
709 	return (0);
710 }
711 
712 SYSCTL_PROC(_debug_fcm, OID_AUTO, program, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
713     fsl_sysctl_program, "I", "write to program FCM with current values");
714 
715 #endif /* NAND_DEBUG_TIMING */
716