Commit c07361145ff9a28e129a5ef49213cf2beba911e5

Authored by Jeroen Hofstee
Committed by Tom Rini
1 parent 24e7412696

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