diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2015-02-10 13:59:57 -0500 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2015-03-11 18:20:29 -0400 |
commit | 3f410690f511f9531fdc0865a931522b049d7b29 (patch) | |
tree | 85ec5c38dab6ea75421ec1109c3d18a01e6b8dd2 /drivers/mtd | |
parent | 1f42adc8880d0692c3cb7b6adb247f17c4983081 (diff) |
mtd: mxc-nand: Do the word to byte mangling in the read_byte callback
When the hardware operates in 16 bit mode it always reads 16 bits even
for operations that only have the lower 8 bits defined. So the upper
bits must be discarded. Do this in the read_byte callback instead of
when reading the NAND id to support reading byte wise more than 5 bytes
and at other occations (like reading the ONFI parameter page).
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 34 |
1 files changed, 10 insertions, 24 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index d9637ae34719..aa98a0dddcfb 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -552,30 +552,17 @@ static void send_page_v1(struct mtd_info *mtd, unsigned int ops) | |||
552 | 552 | ||
553 | static void send_read_id_v3(struct mxc_nand_host *host) | 553 | static void send_read_id_v3(struct mxc_nand_host *host) |
554 | { | 554 | { |
555 | struct nand_chip *this = &host->nand; | ||
556 | |||
557 | /* Read ID into main buffer */ | 555 | /* Read ID into main buffer */ |
558 | writel(NFC_ID, NFC_V3_LAUNCH); | 556 | writel(NFC_ID, NFC_V3_LAUNCH); |
559 | 557 | ||
560 | wait_op_done(host, true); | 558 | wait_op_done(host, true); |
561 | 559 | ||
562 | memcpy32_fromio(host->data_buf, host->main_area0, 16); | 560 | memcpy32_fromio(host->data_buf, host->main_area0, 16); |
563 | |||
564 | if (this->options & NAND_BUSWIDTH_16) { | ||
565 | /* compress the ID info */ | ||
566 | host->data_buf[1] = host->data_buf[2]; | ||
567 | host->data_buf[2] = host->data_buf[4]; | ||
568 | host->data_buf[3] = host->data_buf[6]; | ||
569 | host->data_buf[4] = host->data_buf[8]; | ||
570 | host->data_buf[5] = host->data_buf[10]; | ||
571 | } | ||
572 | } | 561 | } |
573 | 562 | ||
574 | /* Request the NANDFC to perform a read of the NAND device ID. */ | 563 | /* Request the NANDFC to perform a read of the NAND device ID. */ |
575 | static void send_read_id_v1_v2(struct mxc_nand_host *host) | 564 | static void send_read_id_v1_v2(struct mxc_nand_host *host) |
576 | { | 565 | { |
577 | struct nand_chip *this = &host->nand; | ||
578 | |||
579 | /* NANDFC buffer 0 is used for device ID output */ | 566 | /* NANDFC buffer 0 is used for device ID output */ |
580 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); | 567 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); |
581 | 568 | ||
@@ -585,15 +572,6 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) | |||
585 | wait_op_done(host, true); | 572 | wait_op_done(host, true); |
586 | 573 | ||
587 | memcpy32_fromio(host->data_buf, host->main_area0, 16); | 574 | memcpy32_fromio(host->data_buf, host->main_area0, 16); |
588 | |||
589 | if (this->options & NAND_BUSWIDTH_16) { | ||
590 | /* compress the ID info */ | ||
591 | host->data_buf[1] = host->data_buf[2]; | ||
592 | host->data_buf[2] = host->data_buf[4]; | ||
593 | host->data_buf[3] = host->data_buf[6]; | ||
594 | host->data_buf[4] = host->data_buf[8]; | ||
595 | host->data_buf[5] = host->data_buf[10]; | ||
596 | } | ||
597 | } | 575 | } |
598 | 576 | ||
599 | static uint16_t get_dev_status_v3(struct mxc_nand_host *host) | 577 | static uint16_t get_dev_status_v3(struct mxc_nand_host *host) |
@@ -719,9 +697,17 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd) | |||
719 | if (host->status_request) | 697 | if (host->status_request) |
720 | return host->devtype_data->get_dev_status(host) & 0xFF; | 698 | return host->devtype_data->get_dev_status(host) & 0xFF; |
721 | 699 | ||
722 | ret = *(uint8_t *)(host->data_buf + host->buf_start); | 700 | if (nand_chip->options & NAND_BUSWIDTH_16) { |
723 | host->buf_start++; | 701 | /* only take the lower byte of each word */ |
702 | ret = *(uint16_t *)(host->data_buf + host->buf_start); | ||
703 | |||
704 | host->buf_start += 2; | ||
705 | } else { | ||
706 | ret = *(uint8_t *)(host->data_buf + host->buf_start); | ||
707 | host->buf_start++; | ||
708 | } | ||
724 | 709 | ||
710 | pr_debug("%s: ret=0x%hhx (start=%u)\n", __func__, ret, host->buf_start); | ||
725 | return ret; | 711 | return ret; |
726 | } | 712 | } |
727 | 713 | ||