Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0
0002  *
0003  * SuperH FLCTL nand controller
0004  *
0005  * Copyright © 2008 Renesas Solutions Corp.
0006  */
0007 
0008 #ifndef __SH_FLCTL_H__
0009 #define __SH_FLCTL_H__
0010 
0011 #include <linux/completion.h>
0012 #include <linux/mtd/mtd.h>
0013 #include <linux/mtd/rawnand.h>
0014 #include <linux/mtd/partitions.h>
0015 #include <linux/pm_qos.h>
0016 
0017 /* FLCTL registers */
0018 #define FLCMNCR(f)      (f->reg + 0x0)
0019 #define FLCMDCR(f)      (f->reg + 0x4)
0020 #define FLCMCDR(f)      (f->reg + 0x8)
0021 #define FLADR(f)        (f->reg + 0xC)
0022 #define FLADR2(f)       (f->reg + 0x3C)
0023 #define FLDATAR(f)      (f->reg + 0x10)
0024 #define FLDTCNTR(f)     (f->reg + 0x14)
0025 #define FLINTDMACR(f)       (f->reg + 0x18)
0026 #define FLBSYTMR(f)     (f->reg + 0x1C)
0027 #define FLBSYCNT(f)     (f->reg + 0x20)
0028 #define FLDTFIFO(f)     (f->reg + 0x24)
0029 #define FLECFIFO(f)     (f->reg + 0x28)
0030 #define FLTRCR(f)       (f->reg + 0x2C)
0031 #define FLHOLDCR(f)     (f->reg + 0x38)
0032 #define FL4ECCRESULT0(f)    (f->reg + 0x80)
0033 #define FL4ECCRESULT1(f)    (f->reg + 0x84)
0034 #define FL4ECCRESULT2(f)    (f->reg + 0x88)
0035 #define FL4ECCRESULT3(f)    (f->reg + 0x8C)
0036 #define FL4ECCCR(f)     (f->reg + 0x90)
0037 #define FL4ECCCNT(f)        (f->reg + 0x94)
0038 #define FLERRADR(f)     (f->reg + 0x98)
0039 
0040 /* FLCMNCR control bits */
0041 #define _4ECCCNTEN  (0x1 << 24)
0042 #define _4ECCEN     (0x1 << 23)
0043 #define _4ECCCORRECT    (0x1 << 22)
0044 #define SHBUSSEL    (0x1 << 20)
0045 #define SEL_16BIT   (0x1 << 19)
0046 #define SNAND_E     (0x1 << 18) /* SNAND (0=512 1=2048)*/
0047 #define QTSEL_E     (0x1 << 17)
0048 #define ENDIAN      (0x1 << 16) /* 1 = little endian */
0049 #define FCKSEL_E    (0x1 << 15)
0050 #define ACM_SACCES_MODE (0x01 << 10)
0051 #define NANWF_E     (0x1 << 9)
0052 #define SE_D        (0x1 << 8)  /* Spare area disable */
0053 #define CE1_ENABLE  (0x1 << 4)  /* Chip Enable 1 */
0054 #define CE0_ENABLE  (0x1 << 3)  /* Chip Enable 0 */
0055 #define TYPESEL_SET (0x1 << 0)
0056 
0057 /*
0058  * Clock settings using the PULSEx registers from FLCMNCR
0059  *
0060  * Some hardware uses bits called PULSEx instead of FCKSEL_E and QTSEL_E
0061  * to control the clock divider used between the High-Speed Peripheral Clock
0062  * and the FLCTL internal clock. If so, use CLK_8_BIT_xxx for connecting 8 bit
0063  * and CLK_16_BIT_xxx for connecting 16 bit bus bandwith NAND chips. For the 16
0064  * bit version the divider is seperate for the pulse width of high and low
0065  * signals.
0066  */
0067 #define PULSE3  (0x1 << 27)
0068 #define PULSE2  (0x1 << 17)
0069 #define PULSE1  (0x1 << 15)
0070 #define PULSE0  (0x1 << 9)
0071 #define CLK_8B_0_5          PULSE1
0072 #define CLK_8B_1            0x0
0073 #define CLK_8B_1_5          (PULSE1 | PULSE2)
0074 #define CLK_8B_2            PULSE0
0075 #define CLK_8B_3            (PULSE0 | PULSE1 | PULSE2)
0076 #define CLK_8B_4            (PULSE0 | PULSE2)
0077 #define CLK_16B_6L_2H           PULSE0
0078 #define CLK_16B_9L_3H           (PULSE0 | PULSE1 | PULSE2)
0079 #define CLK_16B_12L_4H          (PULSE0 | PULSE2)
0080 
0081 /* FLCMDCR control bits */
0082 #define ADRCNT2_E   (0x1 << 31) /* 5byte address enable */
0083 #define ADRMD_E     (0x1 << 26) /* Sector address access */
0084 #define CDSRC_E     (0x1 << 25) /* Data buffer selection */
0085 #define DOSR_E      (0x1 << 24) /* Status read check */
0086 #define SELRW       (0x1 << 21) /*  0:read 1:write */
0087 #define DOADR_E     (0x1 << 20) /* Address stage execute */
0088 #define ADRCNT_1    (0x00 << 18)    /* Address data bytes: 1byte */
0089 #define ADRCNT_2    (0x01 << 18)    /* Address data bytes: 2byte */
0090 #define ADRCNT_3    (0x02 << 18)    /* Address data bytes: 3byte */
0091 #define ADRCNT_4    (0x03 << 18)    /* Address data bytes: 4byte */
0092 #define DOCMD2_E    (0x1 << 17) /* 2nd cmd stage execute */
0093 #define DOCMD1_E    (0x1 << 16) /* 1st cmd stage execute */
0094 
0095 /* FLINTDMACR control bits */
0096 #define ESTERINTE   (0x1 << 24) /* ECC error interrupt enable */
0097 #define AC1CLR      (0x1 << 19) /* ECC FIFO clear */
0098 #define AC0CLR      (0x1 << 18) /* Data FIFO clear */
0099 #define DREQ0EN     (0x1 << 16) /* FLDTFIFODMA Request Enable */
0100 #define ECERB       (0x1 << 9)  /* ECC error */
0101 #define STERB       (0x1 << 8)  /* Status error */
0102 #define STERINTE    (0x1 << 4)  /* Status error enable */
0103 
0104 /* FLTRCR control bits */
0105 #define TRSTRT      (0x1 << 0)  /* translation start */
0106 #define TREND       (0x1 << 1)  /* translation end */
0107 
0108 /*
0109  * FLHOLDCR control bits
0110  *
0111  * HOLDEN: Bus Occupancy Enable (inverted)
0112  * Enable this bit when the external bus might be used in between transfers.
0113  * If not set and the bus gets used by other modules, a deadlock occurs.
0114  */
0115 #define HOLDEN      (0x1 << 0)
0116 
0117 /* FL4ECCCR control bits */
0118 #define _4ECCFA     (0x1 << 2)  /* 4 symbols correct fault */
0119 #define _4ECCEND    (0x1 << 1)  /* 4 symbols end */
0120 #define _4ECCEXST   (0x1 << 0)  /* 4 symbols exist */
0121 
0122 #define LOOP_TIMEOUT_MAX    0x00010000
0123 
0124 enum flctl_ecc_res_t {
0125     FL_SUCCESS,
0126     FL_REPAIRABLE,
0127     FL_ERROR,
0128     FL_TIMEOUT
0129 };
0130 
0131 struct dma_chan;
0132 
0133 struct sh_flctl {
0134     struct nand_chip    chip;
0135     struct platform_device  *pdev;
0136     struct dev_pm_qos_request pm_qos;
0137     void __iomem        *reg;
0138     resource_size_t     fifo;
0139 
0140     uint8_t done_buff[2048 + 64];   /* max size 2048 + 64 */
0141     int read_bytes;
0142     unsigned int index;
0143     int seqin_column;       /* column in SEQIN cmd */
0144     int seqin_page_addr;    /* page_addr in SEQIN cmd */
0145     uint32_t seqin_read_cmd;        /* read cmd in SEQIN cmd */
0146     int erase1_page_addr;   /* page_addr in ERASE1 cmd */
0147     uint32_t erase_ADRCNT;      /* bits of FLCMDCR in ERASE1 cmd */
0148     uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */
0149     uint32_t flcmncr_base;  /* base value of FLCMNCR */
0150     uint32_t flintdmacr_base;   /* irq enable bits */
0151 
0152     unsigned page_size:1;   /* NAND page size (0 = 512, 1 = 2048) */
0153     unsigned hwecc:1;   /* Hardware ECC (0 = disabled, 1 = enabled) */
0154     unsigned holden:1;  /* Hardware has FLHOLDCR and HOLDEN is set */
0155     unsigned qos_request:1; /* QoS request to prevent deep power shutdown */
0156 
0157     /* DMA related objects */
0158     struct dma_chan     *chan_fifo0_rx;
0159     struct dma_chan     *chan_fifo0_tx;
0160     struct completion   dma_complete;
0161 };
0162 
0163 struct sh_flctl_platform_data {
0164     struct mtd_partition    *parts;
0165     int         nr_parts;
0166     unsigned long       flcmncr_val;
0167 
0168     unsigned has_hwecc:1;
0169     unsigned use_holden:1;
0170 
0171     unsigned int            slave_id_fifo0_tx;
0172     unsigned int            slave_id_fifo0_rx;
0173 };
0174 
0175 static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo)
0176 {
0177     return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip);
0178 }
0179 
0180 #endif  /* __SH_FLCTL_H__ */