| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
| 2 | /* |
| 3 | * Freescale GPMI NAND Flash Driver |
| 4 | * |
| 5 | * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. |
| 6 | * Copyright (C) 2008 Embedded Alley Solutions, Inc. |
| 7 | */ |
| 8 | #ifndef __DRIVERS_MTD_NAND_GPMI_NAND_H |
| 9 | #define __DRIVERS_MTD_NAND_GPMI_NAND_H |
| 10 | |
| 11 | #include <linux/mtd/rawnand.h> |
| 12 | #include <linux/platform_device.h> |
| 13 | #include <linux/dma-mapping.h> |
| 14 | #include <linux/dmaengine.h> |
| 15 | |
| 16 | #define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */ |
| 17 | struct resources { |
| 18 | void __iomem *gpmi_regs; |
| 19 | void __iomem *bch_regs; |
| 20 | unsigned int dma_low_channel; |
| 21 | unsigned int dma_high_channel; |
| 22 | struct clk *clock[GPMI_CLK_MAX]; |
| 23 | }; |
| 24 | |
| 25 | /** |
| 26 | * struct bch_geometry - BCH geometry description. |
| 27 | * @gf_len: The length of Galois Field. (e.g., 13 or 14) |
| 28 | * @ecc_strength: A number that describes the strength of the ECC |
| 29 | * algorithm. |
| 30 | * @page_size: The size, in bytes, of a physical page, including |
| 31 | * both data and OOB. |
| 32 | * @metadata_size: The size, in bytes, of the metadata. |
| 33 | * @ecc0_chunk_size: The size, in bytes, of a first ECC chunk. |
| 34 | * @eccn_chunk_size: The size, in bytes, of a single ECC chunk after |
| 35 | * the first chunk in the page. |
| 36 | * @ecc_chunk_count: The number of ECC chunks in the page, |
| 37 | * @payload_size: The size, in bytes, of the payload buffer. |
| 38 | * @auxiliary_size: The size, in bytes, of the auxiliary buffer. |
| 39 | * @auxiliary_status_offset: The offset into the auxiliary buffer at which |
| 40 | * the ECC status appears. |
| 41 | * @block_mark_byte_offset: The byte offset in the ECC-based page view at |
| 42 | * which the underlying physical block mark appears. |
| 43 | * @block_mark_bit_offset: The bit offset into the ECC-based page view at |
| 44 | * which the underlying physical block mark appears. |
| 45 | * @ecc_for_meta: The flag to indicate if there is a dedicate ecc |
| 46 | * for meta. |
| 47 | */ |
| 48 | struct bch_geometry { |
| 49 | unsigned int gf_len; |
| 50 | unsigned int ecc_strength; |
| 51 | unsigned int page_size; |
| 52 | unsigned int metadata_size; |
| 53 | unsigned int ecc0_chunk_size; |
| 54 | unsigned int eccn_chunk_size; |
| 55 | unsigned int ecc_chunk_count; |
| 56 | unsigned int payload_size; |
| 57 | unsigned int auxiliary_size; |
| 58 | unsigned int auxiliary_status_offset; |
| 59 | unsigned int block_mark_byte_offset; |
| 60 | unsigned int block_mark_bit_offset; |
| 61 | unsigned int ecc_for_meta; /* ECC for meta data */ |
| 62 | }; |
| 63 | |
| 64 | /** |
| 65 | * struct boot_rom_geometry - Boot ROM geometry description. |
| 66 | * @stride_size_in_pages: The size of a boot block stride, in pages. |
| 67 | * @search_area_stride_exponent: The logarithm to base 2 of the size of a |
| 68 | * search area in boot block strides. |
| 69 | */ |
| 70 | struct boot_rom_geometry { |
| 71 | unsigned int stride_size_in_pages; |
| 72 | unsigned int search_area_stride_exponent; |
| 73 | }; |
| 74 | |
| 75 | enum gpmi_type { |
| 76 | IS_MX23, |
| 77 | IS_MX28, |
| 78 | IS_MX6Q, |
| 79 | IS_MX6SX, |
| 80 | IS_MX7D, |
| 81 | IS_MX8QXP, |
| 82 | }; |
| 83 | |
| 84 | struct gpmi_devdata { |
| 85 | enum gpmi_type type; |
| 86 | int bch_max_ecc_strength; |
| 87 | int max_chain_delay; /* See the SDR EDO mode */ |
| 88 | const char * const *clks; |
| 89 | const int clks_count; |
| 90 | bool support_edo_timing; |
| 91 | }; |
| 92 | |
| 93 | /** |
| 94 | * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters. |
| 95 | * @must_apply_timings: Whether controller timings have already been |
| 96 | * applied or not (useful only while there is |
| 97 | * support for only one chip select) |
| 98 | * @clk_rate: The clock rate that must be used to derive the |
| 99 | * following parameters |
| 100 | * @timing0: HW_GPMI_TIMING0 register |
| 101 | * @timing1: HW_GPMI_TIMING1 register |
| 102 | * @ctrl1n: HW_GPMI_CTRL1n register |
| 103 | */ |
| 104 | struct gpmi_nfc_hardware_timing { |
| 105 | bool must_apply_timings; |
| 106 | unsigned long int clk_rate; |
| 107 | u32 timing0; |
| 108 | u32 timing1; |
| 109 | u32 ctrl1n; |
| 110 | }; |
| 111 | |
| 112 | #define GPMI_MAX_TRANSFERS 8 |
| 113 | |
| 114 | struct gpmi_transfer { |
| 115 | u8 cmdbuf[8]; |
| 116 | struct scatterlist sgl; |
| 117 | enum dma_data_direction direction; |
| 118 | }; |
| 119 | |
| 120 | struct gpmi_nand_data { |
| 121 | /* Devdata */ |
| 122 | const struct gpmi_devdata *devdata; |
| 123 | |
| 124 | /* System Interface */ |
| 125 | struct device *dev; |
| 126 | struct platform_device *pdev; |
| 127 | |
| 128 | /* Resources */ |
| 129 | struct resources resources; |
| 130 | |
| 131 | /* Flash Hardware */ |
| 132 | struct gpmi_nfc_hardware_timing hw; |
| 133 | |
| 134 | /* BCH */ |
| 135 | struct bch_geometry bch_geometry; |
| 136 | struct completion bch_done; |
| 137 | |
| 138 | /* NAND Boot issue */ |
| 139 | bool swap_block_mark; |
| 140 | struct boot_rom_geometry rom_geometry; |
| 141 | |
| 142 | /* MTD / NAND */ |
| 143 | struct nand_controller base; |
| 144 | struct nand_chip nand; |
| 145 | |
| 146 | struct gpmi_transfer transfers[GPMI_MAX_TRANSFERS]; |
| 147 | int ntransfers; |
| 148 | |
| 149 | bool bch; |
| 150 | uint32_t bch_flashlayout0; |
| 151 | uint32_t bch_flashlayout1; |
| 152 | |
| 153 | char *data_buffer_dma; |
| 154 | |
| 155 | void *auxiliary_virt; |
| 156 | dma_addr_t auxiliary_phys; |
| 157 | |
| 158 | void *raw_buffer; |
| 159 | |
| 160 | /* DMA channels */ |
| 161 | #define DMA_CHANS 8 |
| 162 | struct dma_chan *dma_chans[DMA_CHANS]; |
| 163 | struct completion dma_done; |
| 164 | }; |
| 165 | |
| 166 | /* BCH : Status Block Completion Codes */ |
| 167 | #define STATUS_GOOD 0x00 |
| 168 | #define STATUS_ERASED 0xff |
| 169 | #define STATUS_UNCORRECTABLE 0xfe |
| 170 | |
| 171 | /* Use the devdata to distinguish different Archs. */ |
| 172 | #define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23) |
| 173 | #define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28) |
| 174 | #define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q) |
| 175 | #define GPMI_IS_MX6SX(x) ((x)->devdata->type == IS_MX6SX) |
| 176 | #define GPMI_IS_MX7D(x) ((x)->devdata->type == IS_MX7D) |
| 177 | #define GPMI_IS_MX8QXP(x) ((x)->devdata->type == IS_MX8QXP) |
| 178 | |
| 179 | #define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \ |
| 180 | GPMI_IS_MX7D(x) || GPMI_IS_MX8QXP(x)) |
| 181 | |
| 182 | #define GPMI_IS_MXS(x) (GPMI_IS_MX23(x) || GPMI_IS_MX28(x)) |
| 183 | #endif |
| 184 | |