2018-07-07 14:25:20 -03:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
2011-09-08 10:47:09 +08:00
|
|
|
/*
|
|
|
|
|
* Freescale GPMI NAND Flash Driver
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
|
|
|
|
|
* Copyright (C) 2008 Embedded Alley Solutions, Inc.
|
|
|
|
|
*/
|
|
|
|
|
#ifndef __DRIVERS_MTD_NAND_GPMI_NAND_H
|
|
|
|
|
#define __DRIVERS_MTD_NAND_GPMI_NAND_H
|
|
|
|
|
|
2017-08-04 17:29:10 +02:00
|
|
|
#include <linux/mtd/rawnand.h>
|
2011-09-08 10:47:09 +08:00
|
|
|
#include <linux/platform_device.h>
|
|
|
|
|
#include <linux/dma-mapping.h>
|
2013-02-26 11:44:28 +08:00
|
|
|
#include <linux/dmaengine.h>
|
2011-09-08 10:47:09 +08:00
|
|
|
|
2012-07-02 21:39:32 -04:00
|
|
|
#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
|
2011-09-08 10:47:09 +08:00
|
|
|
struct resources {
|
2012-07-17 14:14:02 +08:00
|
|
|
void __iomem *gpmi_regs;
|
|
|
|
|
void __iomem *bch_regs;
|
2011-09-08 10:47:09 +08:00
|
|
|
unsigned int dma_low_channel;
|
|
|
|
|
unsigned int dma_high_channel;
|
2012-07-02 21:39:32 -04:00
|
|
|
struct clk *clock[GPMI_CLK_MAX];
|
2011-09-08 10:47:09 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* struct bch_geometry - BCH geometry description.
|
|
|
|
|
* @gf_len: The length of Galois Field. (e.g., 13 or 14)
|
|
|
|
|
* @ecc_strength: A number that describes the strength of the ECC
|
|
|
|
|
* algorithm.
|
|
|
|
|
* @page_size: The size, in bytes, of a physical page, including
|
|
|
|
|
* both data and OOB.
|
|
|
|
|
* @metadata_size: The size, in bytes, of the metadata.
|
|
|
|
|
* @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note
|
|
|
|
|
* the first chunk in the page includes both data and
|
|
|
|
|
* metadata, so it's a bit larger than this value.
|
|
|
|
|
* @ecc_chunk_count: The number of ECC chunks in the page,
|
|
|
|
|
* @payload_size: The size, in bytes, of the payload buffer.
|
|
|
|
|
* @auxiliary_size: The size, in bytes, of the auxiliary buffer.
|
|
|
|
|
* @auxiliary_status_offset: The offset into the auxiliary buffer at which
|
|
|
|
|
* the ECC status appears.
|
|
|
|
|
* @block_mark_byte_offset: The byte offset in the ECC-based page view at
|
|
|
|
|
* which the underlying physical block mark appears.
|
|
|
|
|
* @block_mark_bit_offset: The bit offset into the ECC-based page view at
|
|
|
|
|
* which the underlying physical block mark appears.
|
|
|
|
|
*/
|
|
|
|
|
struct bch_geometry {
|
|
|
|
|
unsigned int gf_len;
|
|
|
|
|
unsigned int ecc_strength;
|
|
|
|
|
unsigned int page_size;
|
|
|
|
|
unsigned int metadata_size;
|
|
|
|
|
unsigned int ecc_chunk_size;
|
|
|
|
|
unsigned int ecc_chunk_count;
|
|
|
|
|
unsigned int payload_size;
|
|
|
|
|
unsigned int auxiliary_size;
|
|
|
|
|
unsigned int auxiliary_status_offset;
|
|
|
|
|
unsigned int block_mark_byte_offset;
|
|
|
|
|
unsigned int block_mark_bit_offset;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* struct boot_rom_geometry - Boot ROM geometry description.
|
|
|
|
|
* @stride_size_in_pages: The size of a boot block stride, in pages.
|
|
|
|
|
* @search_area_stride_exponent: The logarithm to base 2 of the size of a
|
|
|
|
|
* search area in boot block strides.
|
|
|
|
|
*/
|
|
|
|
|
struct boot_rom_geometry {
|
|
|
|
|
unsigned int stride_size_in_pages;
|
|
|
|
|
unsigned int search_area_stride_exponent;
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-21 18:19:39 +08:00
|
|
|
enum gpmi_type {
|
|
|
|
|
IS_MX23,
|
|
|
|
|
IS_MX28,
|
2014-03-27 10:43:22 +08:00
|
|
|
IS_MX6Q,
|
2017-04-21 18:23:35 -07:00
|
|
|
IS_MX6SX,
|
|
|
|
|
IS_MX7D,
|
2014-03-21 18:19:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct gpmi_devdata {
|
|
|
|
|
enum gpmi_type type;
|
|
|
|
|
int bch_max_ecc_strength;
|
|
|
|
|
int max_chain_delay; /* See the async EDO mode */
|
2017-04-21 18:23:34 -07:00
|
|
|
const char * const *clks;
|
|
|
|
|
const int clks_count;
|
2014-03-21 18:19:39 +08:00
|
|
|
};
|
|
|
|
|
|
2018-03-02 15:38:39 +01:00
|
|
|
/**
|
|
|
|
|
* struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
|
|
|
|
|
* @must_apply_timings: Whether controller timings have already been
|
|
|
|
|
* applied or not (useful only while there is
|
|
|
|
|
* support for only one chip select)
|
|
|
|
|
* @clk_rate: The clock rate that must be used to derive the
|
2018-03-02 15:38:40 +01:00
|
|
|
* following parameters
|
|
|
|
|
* @timing0: HW_GPMI_TIMING0 register
|
|
|
|
|
* @timing1: HW_GPMI_TIMING1 register
|
|
|
|
|
* @ctrl1n: HW_GPMI_CTRL1n register
|
2018-03-02 15:38:39 +01:00
|
|
|
*/
|
|
|
|
|
struct gpmi_nfc_hardware_timing {
|
|
|
|
|
bool must_apply_timings;
|
|
|
|
|
unsigned long int clk_rate;
|
2018-03-02 15:38:40 +01:00
|
|
|
u32 timing0;
|
|
|
|
|
u32 timing1;
|
|
|
|
|
u32 ctrl1n;
|
2018-03-02 15:38:39 +01:00
|
|
|
};
|
|
|
|
|
|
2019-05-21 09:06:43 +02:00
|
|
|
#define GPMI_MAX_TRANSFERS 8
|
|
|
|
|
|
|
|
|
|
struct gpmi_transfer {
|
|
|
|
|
u8 cmdbuf[8];
|
|
|
|
|
struct scatterlist sgl;
|
|
|
|
|
enum dma_data_direction direction;
|
|
|
|
|
};
|
|
|
|
|
|
2011-09-08 10:47:09 +08:00
|
|
|
struct gpmi_nand_data {
|
2018-03-02 15:38:39 +01:00
|
|
|
/* Devdata */
|
2014-03-21 18:19:39 +08:00
|
|
|
const struct gpmi_devdata *devdata;
|
mtd: gpmi: add EDO feature for imx6q
When the frequency on the nand chip pins is above 33MHz,
the nand EDO(extended Data Out) timing could be applied.
The GPMI implements a Feedback read strobe to sample the read data in
the EDO timing mode.
This patch adds the EDO feature for the gpmi-nand driver.
For some onfi nand chips, the mode 4 is the fastest;
while for other onfi nand chips, the mode 5 is the fastest.
This patch only adds the support for the fastest asynchronous timing mode.
So this patch only supports the mode 4 and mode 5.
I tested several Micron's ONFI nand chips with EDO enabled,
take Micron MT29F32G08MAA for example (in mode 5, 100MHz):
1) The test result BEFORE we add the EDO feature:
=================================================
mtd_speedtest: MTD device: 2
mtd_speedtest: MTD device size 209715200, eraseblock size 524288,
page size 4096, count of eraseblocks 400,
pages per eraseblock 128, OOB size 218
.......................................
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 3632 KiB/s
.......................................
mtd_speedtest: testing page read speed
mtd_speedtest: page read speed is 3554 KiB/s
.......................................
mtd_speedtest: testing 2 page read speed
mtd_speedtest: 2 page read speed is 3592 KiB/s
.......................................
=================================================
2) The test result AFTER we add the EDO feature:
=================================================
mtd_speedtest: MTD device: 2
mtd_speedtest: MTD device size 209715200, eraseblock size 524288,
page size 4096, count of eraseblocks 400,
pages per eraseblock 128, OOB size 218
.......................................
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 19555 KiB/s
.......................................
mtd_speedtest: testing page read speed
mtd_speedtest: page read speed is 17319 KiB/s
.......................................
mtd_speedtest: testing 2 page read speed
mtd_speedtest: 2 page read speed is 18339 KiB/s
.......................................
=================================================
3) The read data performance is much improved by more then 5 times.
Signed-off-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
2012-09-13 14:57:59 +08:00
|
|
|
|
2011-09-08 10:47:09 +08:00
|
|
|
/* System Interface */
|
|
|
|
|
struct device *dev;
|
|
|
|
|
struct platform_device *pdev;
|
|
|
|
|
|
|
|
|
|
/* Resources */
|
|
|
|
|
struct resources resources;
|
|
|
|
|
|
|
|
|
|
/* Flash Hardware */
|
2018-03-02 15:38:39 +01:00
|
|
|
struct gpmi_nfc_hardware_timing hw;
|
2011-09-08 10:47:09 +08:00
|
|
|
|
|
|
|
|
/* BCH */
|
|
|
|
|
struct bch_geometry bch_geometry;
|
|
|
|
|
struct completion bch_done;
|
|
|
|
|
|
|
|
|
|
/* NAND Boot issue */
|
|
|
|
|
bool swap_block_mark;
|
|
|
|
|
struct boot_rom_geometry rom_geometry;
|
|
|
|
|
|
|
|
|
|
/* MTD / NAND */
|
2019-05-21 09:06:43 +02:00
|
|
|
struct nand_controller base;
|
2011-09-08 10:47:09 +08:00
|
|
|
struct nand_chip nand;
|
|
|
|
|
|
2019-05-21 09:06:43 +02:00
|
|
|
struct gpmi_transfer transfers[GPMI_MAX_TRANSFERS];
|
|
|
|
|
int ntransfers;
|
2011-09-08 10:47:09 +08:00
|
|
|
|
2019-05-21 09:06:43 +02:00
|
|
|
bool bch;
|
|
|
|
|
uint32_t bch_flashlayout0;
|
|
|
|
|
uint32_t bch_flashlayout1;
|
2011-09-08 10:47:09 +08:00
|
|
|
|
|
|
|
|
char *data_buffer_dma;
|
|
|
|
|
|
|
|
|
|
void *auxiliary_virt;
|
|
|
|
|
dma_addr_t auxiliary_phys;
|
|
|
|
|
|
2014-11-30 19:10:29 +01:00
|
|
|
void *raw_buffer;
|
|
|
|
|
|
2011-09-08 10:47:09 +08:00
|
|
|
/* DMA channels */
|
|
|
|
|
#define DMA_CHANS 8
|
|
|
|
|
struct dma_chan *dma_chans[DMA_CHANS];
|
|
|
|
|
struct completion dma_done;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* BCH : Status Block Completion Codes */
|
|
|
|
|
#define STATUS_GOOD 0x00
|
|
|
|
|
#define STATUS_ERASED 0xff
|
|
|
|
|
#define STATUS_UNCORRECTABLE 0xfe
|
|
|
|
|
|
2014-03-21 18:19:39 +08:00
|
|
|
/* Use the devdata to distinguish different Archs. */
|
|
|
|
|
#define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23)
|
|
|
|
|
#define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28)
|
|
|
|
|
#define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q)
|
2014-03-27 10:43:22 +08:00
|
|
|
#define GPMI_IS_MX6SX(x) ((x)->devdata->type == IS_MX6SX)
|
2017-04-21 18:23:35 -07:00
|
|
|
#define GPMI_IS_MX7D(x) ((x)->devdata->type == IS_MX7D)
|
2014-03-27 10:43:22 +08:00
|
|
|
|
2017-04-21 18:23:35 -07:00
|
|
|
#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \
|
|
|
|
|
GPMI_IS_MX7D(x))
|
2019-02-07 08:50:54 -02:00
|
|
|
#define GPMI_IS_MXS(x) (GPMI_IS_MX23(x) || GPMI_IS_MX28(x))
|
2011-09-08 10:47:09 +08:00
|
|
|
#endif
|