1 /*
2  * incude/mtd/fsmc.h
3  *
4  * ST Microelectronics
5  * Flexible Static Memory Controller (FSMC)
6  * platform data interface and header file
7  *
8  * Copyright © 2010 ST Microelectronics
9  * Vipin Kumar <vipin.kumar@st.com>
10  *
11  * This file is licensed under the terms of the GNU General Public
12  * License version 2. This program is licensed "as is" without any
13  * warranty of any kind, whether express or implied.
14  */
15 
16 #ifndef __MTD_FSMC_H
17 #define __MTD_FSMC_H
18 
19 #include <linux/io.h>
20 #include <linux/platform_device.h>
21 #include <linux/mtd/physmap.h>
22 #include <linux/types.h>
23 #include <linux/mtd/partitions.h>
24 #include <asm/param.h>
25 
26 #define FSMC_NAND_BW8		1
27 #define FSMC_NAND_BW16		2
28 
29 /*
30  * The placement of the Command Latch Enable (CLE) and
31  * Address Latch Enable (ALE) is twisted around in the
32  * SPEAR310 implementation.
33  */
34 #if defined(CONFIG_MACH_SPEAR310)
35 #define PLAT_NAND_CLE		(1 << 17)
36 #define PLAT_NAND_ALE		(1 << 16)
37 #else
38 #define PLAT_NAND_CLE		(1 << 16)
39 #define PLAT_NAND_ALE		(1 << 17)
40 #endif
41 
42 #define FSMC_MAX_NOR_BANKS	4
43 #define FSMC_MAX_NAND_BANKS	4
44 
45 #define FSMC_FLASH_WIDTH8	1
46 #define FSMC_FLASH_WIDTH16	2
47 
48 struct fsmc_nor_bank_regs {
49 	uint32_t ctrl;
50 	uint32_t ctrl_tim;
51 };
52 
53 /* ctrl register definitions */
54 #define BANK_ENABLE		(1 << 0)
55 #define MUXED			(1 << 1)
56 #define NOR_DEV			(2 << 2)
57 #define WIDTH_8			(0 << 4)
58 #define WIDTH_16		(1 << 4)
59 #define RSTPWRDWN		(1 << 6)
60 #define WPROT			(1 << 7)
61 #define WRT_ENABLE		(1 << 12)
62 #define WAIT_ENB		(1 << 13)
63 
64 /* ctrl_tim register definitions */
65 
66 struct fsmc_nand_bank_regs {
67 	uint32_t pc;
68 	uint32_t sts;
69 	uint32_t comm;
70 	uint32_t attrib;
71 	uint32_t ioata;
72 	uint32_t ecc1;
73 	uint32_t ecc2;
74 	uint32_t ecc3;
75 };
76 
77 #define FSMC_NOR_REG_SIZE	0x40
78 
79 struct fsmc_regs {
80 	struct fsmc_nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS];
81 	uint8_t reserved_1[0x40 - 0x20];
82 	struct fsmc_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
83 	uint8_t reserved_2[0xfe0 - 0xc0];
84 	uint32_t peripid0;			/* 0xfe0 */
85 	uint32_t peripid1;			/* 0xfe4 */
86 	uint32_t peripid2;			/* 0xfe8 */
87 	uint32_t peripid3;			/* 0xfec */
88 	uint32_t pcellid0;			/* 0xff0 */
89 	uint32_t pcellid1;			/* 0xff4 */
90 	uint32_t pcellid2;			/* 0xff8 */
91 	uint32_t pcellid3;			/* 0xffc */
92 };
93 
94 #define FSMC_BUSY_WAIT_TIMEOUT	(1 * HZ)
95 
96 /* pc register definitions */
97 #define FSMC_RESET		(1 << 0)
98 #define FSMC_WAITON		(1 << 1)
99 #define FSMC_ENABLE		(1 << 2)
100 #define FSMC_DEVTYPE_NAND	(1 << 3)
101 #define FSMC_DEVWID_8		(0 << 4)
102 #define FSMC_DEVWID_16		(1 << 4)
103 #define FSMC_ECCEN		(1 << 6)
104 #define FSMC_ECCPLEN_512	(0 << 7)
105 #define FSMC_ECCPLEN_256	(1 << 7)
106 #define FSMC_TCLR_1		(1 << 9)
107 #define FSMC_TAR_1		(1 << 13)
108 
109 /* sts register definitions */
110 #define FSMC_CODE_RDY		(1 << 15)
111 
112 /* comm register definitions */
113 #define FSMC_TSET_0		(0 << 0)
114 #define FSMC_TWAIT_6		(6 << 8)
115 #define FSMC_THOLD_4		(4 << 16)
116 #define FSMC_THIZ_1		(1 << 24)
117 
118 /*
119  * There are 13 bytes of ecc for every 512 byte block in FSMC version 8
120  * and it has to be read consecutively and immediately after the 512
121  * byte data block for hardware to generate the error bit offsets
122  * Managing the ecc bytes in the following way is easier. This way is
123  * similar to oobfree structure maintained already in u-boot nand driver
124  */
125 #define MAX_ECCPLACE_ENTRIES	32
126 
127 struct fsmc_nand_eccplace {
128 	uint8_t offset;
129 	uint8_t length;
130 };
131 
132 struct fsmc_eccplace {
133 	struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
134 };
135 
136 /**
137  * fsmc_nand_platform_data - platform specific NAND controller config
138  * @partitions: partition table for the platform, use a default fallback
139  * if this is NULL
140  * @nr_partitions: the number of partitions in the previous entry
141  * @options: different options for the driver
142  * @width: bus width
143  * @bank: default bank
144  * @select_bank: callback to select a certain bank, this is
145  * platform-specific. If the controller only supports one bank
146  * this may be set to NULL
147  */
148 struct fsmc_nand_platform_data {
149 	struct mtd_partition	*partitions;
150 	unsigned int		nr_partitions;
151 	unsigned int		options;
152 	unsigned int		width;
153 	unsigned int		bank;
154 	void			(*select_bank)(uint32_t bank, uint32_t busw);
155 };
156 
157 extern int __init fsmc_nor_init(struct platform_device *pdev,
158 		unsigned long base, uint32_t bank, uint32_t width);
159 extern void __init fsmc_init_board_info(struct platform_device *pdev,
160 		struct mtd_partition *partitions, unsigned int nr_partitions,
161 		unsigned int width);
162 
163 #endif /* __MTD_FSMC_H */
164