xref: /NextBSD/sys/powerpc/mpc85xx/fsl_sdhc.h (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /*-
2  * Copyright (c) 2011-2012 Semihalf
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #ifndef FSL_SDHC_H_
30 #define FSL_SDHC_H_
31 
32 #include <sys/cdefs.h>
33 
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/kernel.h>
37 #include <sys/lock.h>
38 #include <sys/module.h>
39 #include <sys/mutex.h>
40 #include <sys/rman.h>
41 #include <sys/sysctl.h>
42 #include <sys/systm.h>
43 #include <sys/taskqueue.h>
44 
45 #include <machine/bus.h>
46 
47 #include <dev/mmc/bridge.h>
48 #include <dev/mmc/mmcreg.h>
49 #include <dev/mmc/mmcvar.h>
50 #include <dev/mmc/mmcbrvar.h>
51 
52 #include "mmcbr_if.h"
53 
54 
55 /*****************************************************************************
56  * Private defines
57  *****************************************************************************/
58 struct slot {
59 	uint32_t	clock;
60 };
61 
62 struct fsl_sdhc_softc {
63 	device_t		self;
64 	device_t		child;
65 
66 	bus_space_handle_t	bsh;
67 	bus_space_tag_t		bst;
68 
69 	struct resource		*mem_resource;
70 	int			mem_rid;
71 	struct resource		*irq_resource;
72 	int			irq_rid;
73 	void			*ihl;
74 
75 	bus_dma_tag_t		dma_tag;
76 	bus_dmamap_t		dma_map;
77 	uint32_t*		dma_mem;
78 	bus_addr_t		dma_phys;
79 
80 	struct mtx		mtx;
81 
82 	struct task		card_detect_task;
83 	struct callout		card_detect_callout;
84 
85 	struct mmc_host		mmc_host;
86 
87 	struct slot		slot;
88 	uint32_t		bus_busy;
89 	uint32_t		platform_clock;
90 
91 	struct mmc_request	*request;
92 	int			data_done;
93 	int			command_done;
94 	int			use_dma;
95 	uint32_t*		data_ptr;
96 	uint32_t		data_offset;
97 };
98 
99 #define FSL_SDHC_RESET_DELAY 50
100 
101 #define	FSL_SDHC_BASE_CLOCK_DIV		(2)
102 #define	FSL_SDHC_MAX_DIV		(FSL_SDHC_BASE_CLOCK_DIV * 256 * 16)
103 #define	FSL_SDHC_MIN_DIV		(FSL_SDHC_BASE_CLOCK_DIV * 2)
104 #define	FSL_SDHC_MAX_CLOCK		(50000000)
105 
106 #define	FSL_SDHC_MAX_BLOCK_COUNT	(65535)
107 #define	FSL_SDHC_MAX_BLOCK_SIZE		(4096)
108 
109 #define FSL_SDHC_FIFO_BUF_SIZE		(64)	/* Water-mark level. */
110 #define FSL_SDHC_FIFO_BUF_WORDS		(FSL_SDHC_FIFO_BUF_SIZE / 4)
111 
112 #define FSL_SDHC_DMA_SEGMENT_SIZE	(1024)
113 #define	FSL_SDHC_DMA_ALIGNMENT		(4)
114 #define	FSL_SDHC_DMA_BLOCK_SIZE		FSL_SDHC_MAX_BLOCK_SIZE
115 
116 
117 /*
118  * Offsets of SD HC registers
119  */
120 enum sdhc_reg_off {
121 	SDHC_DSADDR	= 0x000,
122 	SDHC_BLKATTR	= 0x004,
123 	SDHC_CMDARG	= 0x008,
124 	SDHC_XFERTYP	= 0x00c,
125 	SDHC_CMDRSP0	= 0x010,
126 	SDHC_CMDRSP1	= 0x014,
127 	SDHC_CMDRSP2	= 0x018,
128 	SDHC_CMDRSP3	= 0x01c,
129 	SDHC_DATPORT	= 0x020,
130 	SDHC_PRSSTAT	= 0x024,
131 	SDHC_PROCTL	= 0x028,
132 	SDHC_SYSCTL	= 0x02c,
133 	SDHC_IRQSTAT	= 0x030,
134 	SDHC_IRQSTATEN	= 0x034,
135 	SDHC_IRQSIGEN	= 0x038,
136 	SDHC_AUTOC12ERR	= 0x03c,
137 	SDHC_HOSTCAPBLT	= 0x040,
138 	SDHC_WML	= 0x044,
139 	SDHC_FEVT	= 0x050,
140 	SDHC_HOSTVER	= 0x0fc,
141 	SDHC_DCR	= 0x40c
142 };
143 
144 enum sysctl_bit {
145 	SYSCTL_INITA	= 0x08000000,
146 	SYSCTL_RSTD	= 0x04000000,
147 	SYSCTL_RSTC	= 0x02000000,
148 	SYSCTL_RSTA	= 0x01000000,
149 	SYSCTL_DTOCV	= 0x000f0000,
150 	SYSCTL_SDCLKFS	= 0x0000ff00,
151 	SYSCTL_DVS	= 0x000000f0,
152 	SYSCTL_PEREN	= 0x00000004,
153 	SYSCTL_HCKEN	= 0x00000002,
154 	SYSCTL_IPGEN	= 0x00000001
155 };
156 
157 #define HEX_LEFT_SHIFT(x)	(4 * x)
158 enum sysctl_shift {
159 	SHIFT_DTOCV	= HEX_LEFT_SHIFT(4),
160 	SHIFT_SDCLKFS	= HEX_LEFT_SHIFT(2),
161 	SHIFT_DVS	= HEX_LEFT_SHIFT(1)
162 };
163 
164 enum proctl_bit {
165 	PROCTL_WECRM	= 0x04000000,
166 	PROCTL_WECINS	= 0x02000000,
167 	PROCTL_WECINT	= 0x01000000,
168 	PROCTL_RWCTL	= 0x00040000,
169 	PROCTL_CREQ	= 0x00020000,
170 	PROCTL_SABGREQ	= 0x00010000,
171 	PROCTL_CDSS	= 0x00000080,
172 	PROCTL_CDTL	= 0x00000040,
173 	PROCTL_EMODE	= 0x00000030,
174 	PROCTL_D3CD	= 0x00000008,
175 	PROCTL_DTW	= 0x00000006
176 };
177 
178 enum dtw {
179 	DTW_1	= 0x00000000,
180 	DTW_4	= 0x00000002,
181 	DTW_8	= 0x00000004
182 };
183 
184 enum prsstat_bit {
185 	PRSSTAT_DLSL	= 0xff000000,
186 	PRSSTAT_CLSL	= 0x00800000,
187 	PRSSTAT_WPSPL	= 0x00080000,
188 	PRSSTAT_CDPL	= 0x00040000,
189 	PRSSTAT_CINS	= 0x00010000,
190 	PRSSTAT_BREN	= 0x00000800,
191 	PRSSTAT_BWEN	= 0x00000400,
192 	PRSSTAT_RTA	= 0x00000200,
193 	PRSSTAT_WTA	= 0x00000100,
194 	PRSSTAT_SDOFF	= 0x00000080,
195 	PRSSTAT_PEROFF	= 0x00000040,
196 	PRSSTAT_HCKOFF	= 0x00000020,
197 	PRSSTAT_IPGOFF	= 0x00000010,
198 	PRSSTAT_DLA	= 0x00000004,
199 	PRSSTAT_CDIHB	= 0x00000002,
200 	PRSSTAT_CIHB	= 0x00000001
201 
202 };
203 
204 enum irq_bits {
205 	IRQ_DMAE	= 0x10000000,
206 	IRQ_AC12E	= 0x01000000,
207 	IRQ_DEBE	= 0x00400000,
208 	IRQ_DCE		= 0x00200000,
209 	IRQ_DTOE	= 0x00100000,
210 	IRQ_CIE		= 0x00080000,
211 	IRQ_CEBE	= 0x00040000,
212 	IRQ_CCE		= 0x00020000,
213 	IRQ_CTOE	= 0x00010000,
214 	IRQ_CINT	= 0x00000100,
215 	IRQ_CRM		= 0x00000080,
216 	IRQ_CINS	= 0x00000040,
217 	IRQ_BRR		= 0x00000020,
218 	IRQ_BWR		= 0x00000010,
219 	IRQ_DINT	= 0x00000008,
220 	IRQ_BGE		= 0x00000004,
221 	IRQ_TC		= 0x00000002,
222 	IRQ_CC		= 0x00000001
223 };
224 
225 enum irq_masks {
226 	IRQ_ERROR_DATA_MASK	= IRQ_DMAE | IRQ_DEBE | IRQ_DCE | IRQ_DTOE,
227 	IRQ_ERROR_CMD_MASK	= IRQ_AC12E | IRQ_CIE | IRQ_CTOE | IRQ_CCE |
228 				  IRQ_CEBE
229 };
230 
231 enum dcr_bits {
232 	DCR_PRI			= 0x0000c000,
233 	DCR_SNOOP		= 0x00000040,
234 	DCR_AHB2MAG_BYPASS	= 0x00000020,
235 	DCR_RD_SAFE		= 0x00000004,
236 	DCR_RD_PFE		= 0x00000002,
237 	DCR_RD_PF_SIZE		= 0x00000001
238 };
239 
240 #define	DCR_PRI_SHIFT	(14)
241 
242 enum xfertyp_bits {
243 	XFERTYP_CMDINX	= 0x3f000000,
244 	XFERTYP_CMDTYP	= 0x00c00000,
245 	XFERTYP_DPSEL	= 0x00200000,
246 	XFERTYP_CICEN	= 0x00100000,
247 	XFERTYP_CCCEN	= 0x00080000,
248 	XFERTYP_RSPTYP	= 0x00030000,
249 	XFERTYP_MSBSEL	= 0x00000020,
250 	XFERTYP_DTDSEL	= 0x00000010,
251 	XFERTYP_AC12EN	= 0x00000004,
252 	XFERTYP_BCEN	= 0x00000002,
253 	XFERTYP_DMAEN	= 0x00000001
254 };
255 
256 #define	CMDINX_SHIFT	(24)
257 
258 enum xfertyp_cmdtyp {
259 	CMDTYP_NORMAL	= 0x00000000,
260 	CMDYTP_SUSPEND	= 0x00400000,
261 	CMDTYP_RESUME	= 0x00800000,
262 	CMDTYP_ABORT	= 0x00c00000
263 };
264 
265 enum xfertyp_rsptyp {
266 	RSPTYP_NONE	= 0x00000000,
267 	RSPTYP_136	= 0x00010000,
268 	RSPTYP_48	= 0x00020000,
269 	RSPTYP_48_BUSY	= 0x00030000
270 };
271 
272 enum blkattr_bits {
273 	BLKATTR_BLKSZE	= 0x00001fff,
274 	BLKATTR_BLKCNT	= 0xffff0000
275 };
276 #define	BLKATTR_BLOCK_COUNT(x)	(x << 16)
277 
278 enum wml_bits {
279 	WR_WML	= 0x00ff0000,
280 	RD_WML	= 0x000000ff,
281 };
282 
283 enum sdhc_bit_mask {
284 	MASK_CLOCK_CONTROL	= 0x0000ffff,
285 	MASK_IRQ_ALL		= IRQ_DMAE | IRQ_AC12E | IRQ_DEBE | IRQ_DCE |
286 				  IRQ_DTOE | IRQ_CIE | IRQ_CEBE | IRQ_CCE |
287 				  IRQ_CTOE | IRQ_CINT | IRQ_CRM | IRQ_CINS |
288 				  IRQ_BRR | IRQ_BWR | IRQ_DINT | IRQ_BGE |
289 				  IRQ_TC | IRQ_CC,
290 };
291 
292 enum sdhc_line {
293 	SDHC_DAT_LINE	= 0x2,
294 	SDHC_CMD_LINE	= 0x1
295 };
296 
297 #endif /* FSL_SDHC_H_ */
298