Commit c07361145ff9a28e129a5ef49213cf2beba911e5
Committed by
Tom Rini
1 parent
24e7412696
Exists in
v2017.01-smarct4x
and in
34 other branches
omap_gpmc: move prefetch out of CONFIG_NAND_OMAP_ELM
The prefech mode is a feature of the gpmc, not the ELM. An am3517 does not have an elm, but can do prefeches, so move the code out of the CONFIG_NAND_OMAP_ELM ifdef. Cc: Scott Wood <scottwood@freescale.com> Cc: Tom Rini <trini@konsulko.com> Cc: Daniel Mack <zonque@gmail.com> Signed-off-by: Jeroen Hofstee <jeroen@myspectrum.nl> Reviewed-by: Tom Rini <trini@konsulko.com>
Showing 1 changed file with 109 additions and 109 deletions Side-by-side Diff
drivers/mtd/nand/omap_gpmc.c
... | ... | @@ -340,6 +340,115 @@ |
340 | 340 | return 0; |
341 | 341 | } |
342 | 342 | |
343 | +#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH | |
344 | + | |
345 | +#define PREFETCH_CONFIG1_CS_SHIFT 24 | |
346 | +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 | |
347 | +#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8) | |
348 | +#define PREFETCH_STATUS_COUNT(val) (val & 0x00003fff) | |
349 | +#define PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) | |
350 | +#define ENABLE_PREFETCH (1 << 7) | |
351 | + | |
352 | +/** | |
353 | + * omap_prefetch_enable - configures and starts prefetch transfer | |
354 | + * @fifo_th: fifo threshold to be used for read/ write | |
355 | + * @count: number of bytes to be transferred | |
356 | + * @is_write: prefetch read(0) or write post(1) mode | |
357 | + * @cs: chip select to use | |
358 | + */ | |
359 | +static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs) | |
360 | +{ | |
361 | + uint32_t val; | |
362 | + | |
363 | + if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) | |
364 | + return -EINVAL; | |
365 | + | |
366 | + if (readl(&gpmc_cfg->prefetch_control)) | |
367 | + return -EBUSY; | |
368 | + | |
369 | + /* Set the amount of bytes to be prefetched */ | |
370 | + writel(count, &gpmc_cfg->prefetch_config2); | |
371 | + | |
372 | + val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) | | |
373 | + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH; | |
374 | + writel(val, &gpmc_cfg->prefetch_config1); | |
375 | + | |
376 | + /* Start the prefetch engine */ | |
377 | + writel(1, &gpmc_cfg->prefetch_control); | |
378 | + | |
379 | + return 0; | |
380 | +} | |
381 | + | |
382 | +/** | |
383 | + * omap_prefetch_reset - disables and stops the prefetch engine | |
384 | + */ | |
385 | +static void omap_prefetch_reset(void) | |
386 | +{ | |
387 | + writel(0, &gpmc_cfg->prefetch_control); | |
388 | + writel(0, &gpmc_cfg->prefetch_config1); | |
389 | +} | |
390 | + | |
391 | +static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len) | |
392 | +{ | |
393 | + int ret; | |
394 | + uint32_t cnt; | |
395 | + struct omap_nand_info *info = chip->priv; | |
396 | + | |
397 | + ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs); | |
398 | + if (ret < 0) | |
399 | + return ret; | |
400 | + | |
401 | + do { | |
402 | + int i; | |
403 | + | |
404 | + cnt = readl(&gpmc_cfg->prefetch_status); | |
405 | + cnt = PREFETCH_STATUS_FIFO_CNT(cnt); | |
406 | + | |
407 | + for (i = 0; i < cnt / 4; i++) { | |
408 | + *buf++ = readl(CONFIG_SYS_NAND_BASE); | |
409 | + len -= 4; | |
410 | + } | |
411 | + } while (len); | |
412 | + | |
413 | + omap_prefetch_reset(); | |
414 | + | |
415 | + return 0; | |
416 | +} | |
417 | + | |
418 | +static void omap_nand_read_prefetch8(struct mtd_info *mtd, uint8_t *buf, int len) | |
419 | +{ | |
420 | + int ret; | |
421 | + uint32_t head, tail; | |
422 | + struct nand_chip *chip = mtd->priv; | |
423 | + | |
424 | + /* | |
425 | + * If the destination buffer is unaligned, start with reading | |
426 | + * the overlap byte-wise. | |
427 | + */ | |
428 | + head = ((uint32_t) buf) % 4; | |
429 | + if (head) { | |
430 | + nand_read_buf(mtd, buf, head); | |
431 | + buf += head; | |
432 | + len -= head; | |
433 | + } | |
434 | + | |
435 | + /* | |
436 | + * Only transfer multiples of 4 bytes in a pre-fetched fashion. | |
437 | + * If there's a residue, care for it byte-wise afterwards. | |
438 | + */ | |
439 | + tail = len % 4; | |
440 | + | |
441 | + ret = __read_prefetch_aligned(chip, (uint32_t *) buf, len - tail); | |
442 | + if (ret < 0) { | |
443 | + /* fallback in case the prefetch engine is busy */ | |
444 | + nand_read_buf(mtd, buf, len); | |
445 | + } else if (tail) { | |
446 | + buf += len - tail; | |
447 | + nand_read_buf(mtd, buf, tail); | |
448 | + } | |
449 | +} | |
450 | +#endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */ | |
451 | + | |
343 | 452 | #ifdef CONFIG_NAND_OMAP_ELM |
344 | 453 | /* |
345 | 454 | * omap_reverse_list - re-orders list elements in reverse order [internal] |
... | ... | @@ -451,115 +560,6 @@ |
451 | 560 | } |
452 | 561 | return (err) ? err : error_count; |
453 | 562 | } |
454 | - | |
455 | -#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH | |
456 | - | |
457 | -#define PREFETCH_CONFIG1_CS_SHIFT 24 | |
458 | -#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 | |
459 | -#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8) | |
460 | -#define PREFETCH_STATUS_COUNT(val) (val & 0x00003fff) | |
461 | -#define PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) | |
462 | -#define ENABLE_PREFETCH (1 << 7) | |
463 | - | |
464 | -/** | |
465 | - * omap_prefetch_enable - configures and starts prefetch transfer | |
466 | - * @fifo_th: fifo threshold to be used for read/ write | |
467 | - * @count: number of bytes to be transferred | |
468 | - * @is_write: prefetch read(0) or write post(1) mode | |
469 | - * @cs: chip select to use | |
470 | - */ | |
471 | -static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs) | |
472 | -{ | |
473 | - uint32_t val; | |
474 | - | |
475 | - if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) | |
476 | - return -EINVAL; | |
477 | - | |
478 | - if (readl(&gpmc_cfg->prefetch_control)) | |
479 | - return -EBUSY; | |
480 | - | |
481 | - /* Set the amount of bytes to be prefetched */ | |
482 | - writel(count, &gpmc_cfg->prefetch_config2); | |
483 | - | |
484 | - val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) | | |
485 | - PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH; | |
486 | - writel(val, &gpmc_cfg->prefetch_config1); | |
487 | - | |
488 | - /* Start the prefetch engine */ | |
489 | - writel(1, &gpmc_cfg->prefetch_control); | |
490 | - | |
491 | - return 0; | |
492 | -} | |
493 | - | |
494 | -/** | |
495 | - * omap_prefetch_reset - disables and stops the prefetch engine | |
496 | - */ | |
497 | -static void omap_prefetch_reset(void) | |
498 | -{ | |
499 | - writel(0, &gpmc_cfg->prefetch_control); | |
500 | - writel(0, &gpmc_cfg->prefetch_config1); | |
501 | -} | |
502 | - | |
503 | -static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len) | |
504 | -{ | |
505 | - int ret; | |
506 | - uint32_t cnt; | |
507 | - struct omap_nand_info *info = chip->priv; | |
508 | - | |
509 | - ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs); | |
510 | - if (ret < 0) | |
511 | - return ret; | |
512 | - | |
513 | - do { | |
514 | - int i; | |
515 | - | |
516 | - cnt = readl(&gpmc_cfg->prefetch_status); | |
517 | - cnt = PREFETCH_STATUS_FIFO_CNT(cnt); | |
518 | - | |
519 | - for (i = 0; i < cnt / 4; i++) { | |
520 | - *buf++ = readl(CONFIG_SYS_NAND_BASE); | |
521 | - len -= 4; | |
522 | - } | |
523 | - } while (len); | |
524 | - | |
525 | - omap_prefetch_reset(); | |
526 | - | |
527 | - return 0; | |
528 | -} | |
529 | - | |
530 | -static void omap_nand_read_prefetch8(struct mtd_info *mtd, uint8_t *buf, int len) | |
531 | -{ | |
532 | - int ret; | |
533 | - uint32_t head, tail; | |
534 | - struct nand_chip *chip = mtd->priv; | |
535 | - | |
536 | - /* | |
537 | - * If the destination buffer is unaligned, start with reading | |
538 | - * the overlap byte-wise. | |
539 | - */ | |
540 | - head = ((uint32_t) buf) % 4; | |
541 | - if (head) { | |
542 | - nand_read_buf(mtd, buf, head); | |
543 | - buf += head; | |
544 | - len -= head; | |
545 | - } | |
546 | - | |
547 | - /* | |
548 | - * Only transfer multiples of 4 bytes in a pre-fetched fashion. | |
549 | - * If there's a residue, care for it byte-wise afterwards. | |
550 | - */ | |
551 | - tail = len % 4; | |
552 | - | |
553 | - ret = __read_prefetch_aligned(chip, (uint32_t *) buf, len - tail); | |
554 | - if (ret < 0) { | |
555 | - /* fallback in case the prefetch engine is busy */ | |
556 | - nand_read_buf(mtd, buf, len); | |
557 | - } else if (tail) { | |
558 | - buf += len - tail; | |
559 | - nand_read_buf(mtd, buf, tail); | |
560 | - } | |
561 | -} | |
562 | -#endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */ | |
563 | 563 | |
564 | 564 | /** |
565 | 565 | * omap_read_page_bch - hardware ecc based page read function |