]>
Commit | Line | Data |
---|---|---|
a111bfbf MY |
1 | /* |
2 | * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <clk.h> | |
9 | #include <fdtdec.h> | |
10 | #include <mapmem.h> | |
11 | #include <mmc.h> | |
12 | #include <dm/device.h> | |
13 | #include <linux/compat.h> | |
14 | #include <linux/io.h> | |
4f80501b | 15 | #include <linux/sizes.h> |
a111bfbf MY |
16 | #include <asm/unaligned.h> |
17 | #include <asm/dma-mapping.h> | |
18 | ||
19 | DECLARE_GLOBAL_DATA_PTR; | |
20 | ||
21 | #define UNIPHIER_SD_CMD 0x000 /* command */ | |
22 | #define UNIPHIER_SD_CMD_NOSTOP BIT(14) /* No automatic CMD12 issue */ | |
23 | #define UNIPHIER_SD_CMD_MULTI BIT(13) /* multiple block transfer */ | |
24 | #define UNIPHIER_SD_CMD_RD BIT(12) /* 1: read, 0: write */ | |
25 | #define UNIPHIER_SD_CMD_DATA BIT(11) /* data transfer */ | |
26 | #define UNIPHIER_SD_CMD_APP BIT(6) /* ACMD preceded by CMD55 */ | |
27 | #define UNIPHIER_SD_CMD_NORMAL (0 << 8)/* auto-detect of resp-type */ | |
28 | #define UNIPHIER_SD_CMD_RSP_NONE (3 << 8)/* response: none */ | |
29 | #define UNIPHIER_SD_CMD_RSP_R1 (4 << 8)/* response: R1, R5, R6, R7 */ | |
30 | #define UNIPHIER_SD_CMD_RSP_R1B (5 << 8)/* response: R1b, R5b */ | |
31 | #define UNIPHIER_SD_CMD_RSP_R2 (6 << 8)/* response: R2 */ | |
32 | #define UNIPHIER_SD_CMD_RSP_R3 (7 << 8)/* response: R3, R4 */ | |
33 | #define UNIPHIER_SD_ARG 0x008 /* command argument */ | |
34 | #define UNIPHIER_SD_STOP 0x010 /* stop action control */ | |
35 | #define UNIPHIER_SD_STOP_SEC BIT(8) /* use sector count */ | |
36 | #define UNIPHIER_SD_STOP_STP BIT(0) /* issue CMD12 */ | |
37 | #define UNIPHIER_SD_SECCNT 0x014 /* sector counter */ | |
38 | #define UNIPHIER_SD_RSP10 0x018 /* response[39:8] */ | |
39 | #define UNIPHIER_SD_RSP32 0x020 /* response[71:40] */ | |
40 | #define UNIPHIER_SD_RSP54 0x028 /* response[103:72] */ | |
41 | #define UNIPHIER_SD_RSP76 0x030 /* response[127:104] */ | |
42 | #define UNIPHIER_SD_INFO1 0x038 /* IRQ status 1 */ | |
43 | #define UNIPHIER_SD_INFO1_CD BIT(5) /* state of card detect */ | |
44 | #define UNIPHIER_SD_INFO1_INSERT BIT(4) /* card inserted */ | |
45 | #define UNIPHIER_SD_INFO1_REMOVE BIT(3) /* card removed */ | |
46 | #define UNIPHIER_SD_INFO1_CMP BIT(2) /* data complete */ | |
47 | #define UNIPHIER_SD_INFO1_RSP BIT(0) /* response complete */ | |
48 | #define UNIPHIER_SD_INFO2 0x03c /* IRQ status 2 */ | |
49 | #define UNIPHIER_SD_INFO2_ERR_ILA BIT(15) /* illegal access err */ | |
50 | #define UNIPHIER_SD_INFO2_CBSY BIT(14) /* command busy */ | |
51 | #define UNIPHIER_SD_INFO2_BWE BIT(9) /* write buffer ready */ | |
52 | #define UNIPHIER_SD_INFO2_BRE BIT(8) /* read buffer ready */ | |
53 | #define UNIPHIER_SD_INFO2_DAT0 BIT(7) /* SDDAT0 */ | |
54 | #define UNIPHIER_SD_INFO2_ERR_RTO BIT(6) /* response time out */ | |
55 | #define UNIPHIER_SD_INFO2_ERR_ILR BIT(5) /* illegal read err */ | |
56 | #define UNIPHIER_SD_INFO2_ERR_ILW BIT(4) /* illegal write err */ | |
57 | #define UNIPHIER_SD_INFO2_ERR_TO BIT(3) /* time out error */ | |
58 | #define UNIPHIER_SD_INFO2_ERR_END BIT(2) /* END bit error */ | |
59 | #define UNIPHIER_SD_INFO2_ERR_CRC BIT(1) /* CRC error */ | |
60 | #define UNIPHIER_SD_INFO2_ERR_IDX BIT(0) /* cmd index error */ | |
61 | #define UNIPHIER_SD_INFO1_MASK 0x040 | |
62 | #define UNIPHIER_SD_INFO2_MASK 0x044 | |
63 | #define UNIPHIER_SD_CLKCTL 0x048 /* clock divisor */ | |
64 | #define UNIPHIER_SD_CLKCTL_DIV_MASK 0x104ff | |
65 | #define UNIPHIER_SD_CLKCTL_DIV1024 BIT(16) /* SDCLK = CLK / 1024 */ | |
66 | #define UNIPHIER_SD_CLKCTL_DIV512 BIT(7) /* SDCLK = CLK / 512 */ | |
67 | #define UNIPHIER_SD_CLKCTL_DIV256 BIT(6) /* SDCLK = CLK / 256 */ | |
68 | #define UNIPHIER_SD_CLKCTL_DIV128 BIT(5) /* SDCLK = CLK / 128 */ | |
69 | #define UNIPHIER_SD_CLKCTL_DIV64 BIT(4) /* SDCLK = CLK / 64 */ | |
70 | #define UNIPHIER_SD_CLKCTL_DIV32 BIT(3) /* SDCLK = CLK / 32 */ | |
71 | #define UNIPHIER_SD_CLKCTL_DIV16 BIT(2) /* SDCLK = CLK / 16 */ | |
72 | #define UNIPHIER_SD_CLKCTL_DIV8 BIT(1) /* SDCLK = CLK / 8 */ | |
73 | #define UNIPHIER_SD_CLKCTL_DIV4 BIT(0) /* SDCLK = CLK / 4 */ | |
74 | #define UNIPHIER_SD_CLKCTL_DIV2 0 /* SDCLK = CLK / 2 */ | |
75 | #define UNIPHIER_SD_CLKCTL_DIV1 BIT(10) /* SDCLK = CLK */ | |
76 | #define UNIPHIER_SD_CLKCTL_OFFEN BIT(9) /* stop SDCLK when unused */ | |
77 | #define UNIPHIER_SD_CLKCTL_SCLKEN BIT(8) /* SDCLK output enable */ | |
78 | #define UNIPHIER_SD_SIZE 0x04c /* block size */ | |
79 | #define UNIPHIER_SD_OPTION 0x050 | |
80 | #define UNIPHIER_SD_OPTION_WIDTH_MASK (5 << 13) | |
81 | #define UNIPHIER_SD_OPTION_WIDTH_1 (4 << 13) | |
82 | #define UNIPHIER_SD_OPTION_WIDTH_4 (0 << 13) | |
83 | #define UNIPHIER_SD_OPTION_WIDTH_8 (1 << 13) | |
84 | #define UNIPHIER_SD_BUF 0x060 /* read/write buffer */ | |
85 | #define UNIPHIER_SD_EXTMODE 0x1b0 | |
86 | #define UNIPHIER_SD_EXTMODE_DMA_EN BIT(1) /* transfer 1: DMA, 0: pio */ | |
87 | #define UNIPHIER_SD_SOFT_RST 0x1c0 | |
88 | #define UNIPHIER_SD_SOFT_RST_RSTX BIT(0) /* reset deassert */ | |
89 | #define UNIPHIER_SD_VERSION 0x1c4 /* version register */ | |
90 | #define UNIPHIER_SD_VERSION_IP 0xff /* IP version */ | |
91 | #define UNIPHIER_SD_HOST_MODE 0x1c8 | |
92 | #define UNIPHIER_SD_IF_MODE 0x1cc | |
93 | #define UNIPHIER_SD_IF_MODE_DDR BIT(0) /* DDR mode */ | |
94 | #define UNIPHIER_SD_VOLT 0x1e4 /* voltage switch */ | |
95 | #define UNIPHIER_SD_VOLT_MASK (3 << 0) | |
96 | #define UNIPHIER_SD_VOLT_OFF (0 << 0) | |
97 | #define UNIPHIER_SD_VOLT_330 (1 << 0)/* 3.3V signal */ | |
98 | #define UNIPHIER_SD_VOLT_180 (2 << 0)/* 1.8V signal */ | |
99 | #define UNIPHIER_SD_DMA_MODE 0x410 | |
100 | #define UNIPHIER_SD_DMA_MODE_DIR_RD BIT(16) /* 1: from device, 0: to dev */ | |
101 | #define UNIPHIER_SD_DMA_MODE_ADDR_INC BIT(0) /* 1: address inc, 0: fixed */ | |
102 | #define UNIPHIER_SD_DMA_CTL 0x414 | |
103 | #define UNIPHIER_SD_DMA_CTL_START BIT(0) /* start DMA (auto cleared) */ | |
104 | #define UNIPHIER_SD_DMA_RST 0x418 | |
105 | #define UNIPHIER_SD_DMA_RST_RD BIT(9) | |
106 | #define UNIPHIER_SD_DMA_RST_WR BIT(8) | |
107 | #define UNIPHIER_SD_DMA_INFO1 0x420 | |
108 | #define UNIPHIER_SD_DMA_INFO1_END_RD2 BIT(20) /* DMA from device is complete*/ | |
109 | #define UNIPHIER_SD_DMA_INFO1_END_RD BIT(17) /* Don't use! Hardware bug */ | |
110 | #define UNIPHIER_SD_DMA_INFO1_END_WR BIT(16) /* DMA to device is complete */ | |
111 | #define UNIPHIER_SD_DMA_INFO1_MASK 0x424 | |
112 | #define UNIPHIER_SD_DMA_INFO2 0x428 | |
113 | #define UNIPHIER_SD_DMA_INFO2_ERR_RD BIT(17) | |
114 | #define UNIPHIER_SD_DMA_INFO2_ERR_WR BIT(16) | |
115 | #define UNIPHIER_SD_DMA_INFO2_MASK 0x42c | |
116 | #define UNIPHIER_SD_DMA_ADDR_L 0x440 | |
117 | #define UNIPHIER_SD_DMA_ADDR_H 0x444 | |
118 | ||
119 | /* alignment required by the DMA engine of this controller */ | |
120 | #define UNIPHIER_SD_DMA_MINALIGN 0x10 | |
121 | ||
122 | struct uniphier_sd_priv { | |
123 | struct mmc_config cfg; | |
124 | struct mmc *mmc; | |
125 | struct udevice *dev; | |
126 | void __iomem *regbase; | |
127 | unsigned long mclk; | |
128 | unsigned int version; | |
129 | u32 caps; | |
130 | #define UNIPHIER_SD_CAP_NONREMOVABLE BIT(0) /* Nonremovable e.g. eMMC */ | |
131 | #define UNIPHIER_SD_CAP_DMA_INTERNAL BIT(1) /* have internal DMA engine */ | |
132 | #define UNIPHIER_SD_CAP_DIV1024 BIT(2) /* divisor 1024 is available */ | |
133 | }; | |
134 | ||
135 | static dma_addr_t __dma_map_single(void *ptr, size_t size, | |
136 | enum dma_data_direction dir) | |
137 | { | |
138 | unsigned long addr = (unsigned long)ptr; | |
139 | ||
140 | if (dir == DMA_FROM_DEVICE) | |
141 | invalidate_dcache_range(addr, addr + size); | |
142 | else | |
143 | flush_dcache_range(addr, addr + size); | |
144 | ||
145 | return addr; | |
146 | } | |
147 | ||
148 | static void __dma_unmap_single(dma_addr_t addr, size_t size, | |
149 | enum dma_data_direction dir) | |
150 | { | |
151 | if (dir != DMA_TO_DEVICE) | |
152 | invalidate_dcache_range(addr, addr + size); | |
153 | } | |
154 | ||
155 | static int uniphier_sd_check_error(struct uniphier_sd_priv *priv) | |
156 | { | |
157 | u32 info2 = readl(priv->regbase + UNIPHIER_SD_INFO2); | |
158 | ||
159 | if (info2 & UNIPHIER_SD_INFO2_ERR_RTO) { | |
160 | /* | |
161 | * TIMEOUT must be returned for unsupported command. Do not | |
162 | * display error log since this might be a part of sequence to | |
163 | * distinguish between SD and MMC. | |
164 | */ | |
165 | return TIMEOUT; | |
166 | } | |
167 | ||
168 | if (info2 & UNIPHIER_SD_INFO2_ERR_TO) { | |
169 | dev_err(priv->dev, "timeout error\n"); | |
170 | return -ETIMEDOUT; | |
171 | } | |
172 | ||
173 | if (info2 & (UNIPHIER_SD_INFO2_ERR_END | UNIPHIER_SD_INFO2_ERR_CRC | | |
174 | UNIPHIER_SD_INFO2_ERR_IDX)) { | |
175 | dev_err(priv->dev, "communication out of sync\n"); | |
176 | return -EILSEQ; | |
177 | } | |
178 | ||
179 | if (info2 & (UNIPHIER_SD_INFO2_ERR_ILA | UNIPHIER_SD_INFO2_ERR_ILR | | |
180 | UNIPHIER_SD_INFO2_ERR_ILW)) { | |
181 | dev_err(priv->dev, "illegal access\n"); | |
182 | return -EIO; | |
183 | } | |
184 | ||
185 | return 0; | |
186 | } | |
187 | ||
188 | static int uniphier_sd_wait_for_irq(struct uniphier_sd_priv *priv, | |
189 | unsigned int reg, u32 flag) | |
190 | { | |
191 | long wait = 1000000; | |
192 | int ret; | |
193 | ||
194 | while (!(readl(priv->regbase + reg) & flag)) { | |
195 | if (wait-- < 0) { | |
196 | dev_err(priv->dev, "timeout\n"); | |
197 | return -ETIMEDOUT; | |
198 | } | |
199 | ||
200 | ret = uniphier_sd_check_error(priv); | |
201 | if (ret) | |
202 | return ret; | |
203 | ||
204 | udelay(1); | |
205 | } | |
206 | ||
207 | return 0; | |
208 | } | |
209 | ||
210 | static int uniphier_sd_pio_read_one_block(struct mmc *mmc, u32 **pbuf, | |
211 | uint blocksize) | |
212 | { | |
213 | struct uniphier_sd_priv *priv = mmc->priv; | |
214 | int i, ret; | |
215 | ||
216 | /* wait until the buffer is filled with data */ | |
217 | ret = uniphier_sd_wait_for_irq(priv, UNIPHIER_SD_INFO2, | |
218 | UNIPHIER_SD_INFO2_BRE); | |
219 | if (ret) | |
220 | return ret; | |
221 | ||
222 | /* | |
223 | * Clear the status flag _before_ read the buffer out because | |
224 | * UNIPHIER_SD_INFO2_BRE is edge-triggered, not level-triggered. | |
225 | */ | |
226 | writel(0, priv->regbase + UNIPHIER_SD_INFO2); | |
227 | ||
228 | if (likely(IS_ALIGNED((unsigned long)*pbuf, 4))) { | |
229 | for (i = 0; i < blocksize / 4; i++) | |
230 | *(*pbuf)++ = readl(priv->regbase + UNIPHIER_SD_BUF); | |
231 | } else { | |
232 | for (i = 0; i < blocksize / 4; i++) | |
233 | put_unaligned(readl(priv->regbase + UNIPHIER_SD_BUF), | |
234 | (*pbuf)++); | |
235 | } | |
236 | ||
237 | return 0; | |
238 | } | |
239 | ||
240 | static int uniphier_sd_pio_write_one_block(struct mmc *mmc, const u32 **pbuf, | |
241 | uint blocksize) | |
242 | { | |
243 | struct uniphier_sd_priv *priv = mmc->priv; | |
244 | int i, ret; | |
245 | ||
246 | /* wait until the buffer becomes empty */ | |
247 | ret = uniphier_sd_wait_for_irq(priv, UNIPHIER_SD_INFO2, | |
248 | UNIPHIER_SD_INFO2_BWE); | |
249 | if (ret) | |
250 | return ret; | |
251 | ||
252 | writel(0, priv->regbase + UNIPHIER_SD_INFO2); | |
253 | ||
254 | if (likely(IS_ALIGNED((unsigned long)*pbuf, 4))) { | |
255 | for (i = 0; i < blocksize / 4; i++) | |
256 | writel(*(*pbuf)++, priv->regbase + UNIPHIER_SD_BUF); | |
257 | } else { | |
258 | for (i = 0; i < blocksize / 4; i++) | |
259 | writel(get_unaligned((*pbuf)++), | |
260 | priv->regbase + UNIPHIER_SD_BUF); | |
261 | } | |
262 | ||
263 | return 0; | |
264 | } | |
265 | ||
266 | static int uniphier_sd_pio_xfer(struct mmc *mmc, struct mmc_data *data) | |
267 | { | |
268 | u32 *dest = (u32 *)data->dest; | |
269 | const u32 *src = (const u32 *)data->src; | |
270 | int i, ret; | |
271 | ||
272 | for (i = 0; i < data->blocks; i++) { | |
273 | if (data->flags & MMC_DATA_READ) | |
274 | ret = uniphier_sd_pio_read_one_block(mmc, &dest, | |
275 | data->blocksize); | |
276 | else | |
277 | ret = uniphier_sd_pio_write_one_block(mmc, &src, | |
278 | data->blocksize); | |
279 | if (ret) | |
280 | return ret; | |
281 | } | |
282 | ||
283 | return 0; | |
284 | } | |
285 | ||
286 | static void uniphier_sd_dma_start(struct uniphier_sd_priv *priv, | |
287 | dma_addr_t dma_addr) | |
288 | { | |
289 | u32 tmp; | |
290 | ||
291 | writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO1); | |
292 | writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO2); | |
293 | ||
294 | /* enable DMA */ | |
295 | tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE); | |
296 | tmp |= UNIPHIER_SD_EXTMODE_DMA_EN; | |
297 | writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE); | |
298 | ||
299 | writel(dma_addr & U32_MAX, priv->regbase + UNIPHIER_SD_DMA_ADDR_L); | |
300 | ||
301 | /* suppress the warning "right shift count >= width of type" */ | |
302 | dma_addr >>= min_t(int, 32, 8 * sizeof(dma_addr)); | |
303 | ||
304 | writel(dma_addr & U32_MAX, priv->regbase + UNIPHIER_SD_DMA_ADDR_H); | |
305 | ||
306 | writel(UNIPHIER_SD_DMA_CTL_START, priv->regbase + UNIPHIER_SD_DMA_CTL); | |
307 | } | |
308 | ||
309 | static int uniphier_sd_dma_wait_for_irq(struct uniphier_sd_priv *priv, u32 flag, | |
310 | unsigned int blocks) | |
311 | { | |
312 | long wait = 1000000 + 10 * blocks; | |
313 | ||
314 | while (!(readl(priv->regbase + UNIPHIER_SD_DMA_INFO1) & flag)) { | |
315 | if (wait-- < 0) { | |
316 | dev_err(priv->dev, "timeout during DMA\n"); | |
317 | return -ETIMEDOUT; | |
318 | } | |
319 | ||
320 | udelay(10); | |
321 | } | |
322 | ||
323 | if (readl(priv->regbase + UNIPHIER_SD_DMA_INFO2)) { | |
324 | dev_err(priv->dev, "error during DMA\n"); | |
325 | return -EIO; | |
326 | } | |
327 | ||
328 | return 0; | |
329 | } | |
330 | ||
331 | static int uniphier_sd_dma_xfer(struct mmc *mmc, struct mmc_data *data) | |
332 | { | |
333 | struct uniphier_sd_priv *priv = mmc->priv; | |
334 | size_t len = data->blocks * data->blocksize; | |
335 | void *buf; | |
336 | enum dma_data_direction dir; | |
337 | dma_addr_t dma_addr; | |
338 | u32 poll_flag, tmp; | |
339 | int ret; | |
340 | ||
341 | tmp = readl(priv->regbase + UNIPHIER_SD_DMA_MODE); | |
342 | ||
343 | if (data->flags & MMC_DATA_READ) { | |
344 | buf = data->dest; | |
345 | dir = DMA_FROM_DEVICE; | |
346 | poll_flag = UNIPHIER_SD_DMA_INFO1_END_RD2; | |
347 | tmp |= UNIPHIER_SD_DMA_MODE_DIR_RD; | |
348 | } else { | |
349 | buf = (void *)data->src; | |
350 | dir = DMA_TO_DEVICE; | |
351 | poll_flag = UNIPHIER_SD_DMA_INFO1_END_WR; | |
352 | tmp &= ~UNIPHIER_SD_DMA_MODE_DIR_RD; | |
353 | } | |
354 | ||
355 | writel(tmp, priv->regbase + UNIPHIER_SD_DMA_MODE); | |
356 | ||
357 | dma_addr = __dma_map_single(buf, len, dir); | |
358 | ||
359 | uniphier_sd_dma_start(priv, dma_addr); | |
360 | ||
361 | ret = uniphier_sd_dma_wait_for_irq(priv, poll_flag, data->blocks); | |
362 | ||
363 | __dma_unmap_single(dma_addr, len, dir); | |
364 | ||
365 | return ret; | |
366 | } | |
367 | ||
368 | /* check if the address is DMA'able */ | |
369 | static bool uniphier_sd_addr_is_dmaable(unsigned long addr) | |
370 | { | |
371 | if (!IS_ALIGNED(addr, UNIPHIER_SD_DMA_MINALIGN)) | |
372 | return false; | |
373 | ||
374 | #if defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARM64) && \ | |
375 | defined(CONFIG_SPL_BUILD) | |
376 | /* | |
377 | * For UniPhier ARMv7 SoCs, the stack is allocated in the locked ways | |
378 | * of L2, which is unreachable from the DMA engine. | |
379 | */ | |
380 | if (addr < CONFIG_SPL_STACK) | |
381 | return false; | |
382 | #endif | |
383 | ||
384 | return true; | |
385 | } | |
386 | ||
387 | static int uniphier_sd_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, | |
388 | struct mmc_data *data) | |
389 | { | |
390 | struct uniphier_sd_priv *priv = mmc->priv; | |
391 | int ret; | |
392 | u32 tmp; | |
393 | ||
394 | if (readl(priv->regbase + UNIPHIER_SD_INFO2) & UNIPHIER_SD_INFO2_CBSY) { | |
395 | dev_err(priv->dev, "command busy\n"); | |
396 | return -EBUSY; | |
397 | } | |
398 | ||
399 | /* clear all status flags */ | |
400 | writel(0, priv->regbase + UNIPHIER_SD_INFO1); | |
401 | writel(0, priv->regbase + UNIPHIER_SD_INFO2); | |
402 | ||
403 | /* disable DMA once */ | |
404 | tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE); | |
405 | tmp &= ~UNIPHIER_SD_EXTMODE_DMA_EN; | |
406 | writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE); | |
407 | ||
408 | writel(cmd->cmdarg, priv->regbase + UNIPHIER_SD_ARG); | |
409 | ||
410 | tmp = cmd->cmdidx; | |
411 | ||
412 | if (data) { | |
413 | writel(data->blocksize, priv->regbase + UNIPHIER_SD_SIZE); | |
414 | writel(data->blocks, priv->regbase + UNIPHIER_SD_SECCNT); | |
415 | ||
416 | /* Do not send CMD12 automatically */ | |
417 | tmp |= UNIPHIER_SD_CMD_NOSTOP | UNIPHIER_SD_CMD_DATA; | |
418 | ||
419 | if (data->blocks > 1) | |
420 | tmp |= UNIPHIER_SD_CMD_MULTI; | |
421 | ||
422 | if (data->flags & MMC_DATA_READ) | |
423 | tmp |= UNIPHIER_SD_CMD_RD; | |
424 | } | |
425 | ||
426 | /* | |
427 | * Do not use the response type auto-detection on this hardware. | |
428 | * CMD8, for example, has different response types on SD and eMMC, | |
429 | * while this controller always assumes the response type for SD. | |
430 | * Set the response type manually. | |
431 | */ | |
432 | switch (cmd->resp_type) { | |
433 | case MMC_RSP_NONE: | |
434 | tmp |= UNIPHIER_SD_CMD_RSP_NONE; | |
435 | break; | |
436 | case MMC_RSP_R1: | |
437 | tmp |= UNIPHIER_SD_CMD_RSP_R1; | |
438 | break; | |
439 | case MMC_RSP_R1b: | |
440 | tmp |= UNIPHIER_SD_CMD_RSP_R1B; | |
441 | break; | |
442 | case MMC_RSP_R2: | |
443 | tmp |= UNIPHIER_SD_CMD_RSP_R2; | |
444 | break; | |
445 | case MMC_RSP_R3: | |
446 | tmp |= UNIPHIER_SD_CMD_RSP_R3; | |
447 | break; | |
448 | default: | |
449 | dev_err(priv->dev, "unknown response type\n"); | |
450 | return -EINVAL; | |
451 | } | |
452 | ||
453 | dev_dbg(priv->dev, "sending CMD%d (SD_CMD=%08x, SD_ARG=%08x)\n", | |
454 | cmd->cmdidx, tmp, cmd->cmdarg); | |
455 | writel(tmp, priv->regbase + UNIPHIER_SD_CMD); | |
456 | ||
457 | ret = uniphier_sd_wait_for_irq(priv, UNIPHIER_SD_INFO1, | |
458 | UNIPHIER_SD_INFO1_RSP); | |
459 | if (ret) | |
460 | return ret; | |
461 | ||
462 | if (cmd->resp_type & MMC_RSP_136) { | |
463 | u32 rsp_127_104 = readl(priv->regbase + UNIPHIER_SD_RSP76); | |
464 | u32 rsp_103_72 = readl(priv->regbase + UNIPHIER_SD_RSP54); | |
465 | u32 rsp_71_40 = readl(priv->regbase + UNIPHIER_SD_RSP32); | |
466 | u32 rsp_39_8 = readl(priv->regbase + UNIPHIER_SD_RSP10); | |
467 | ||
468 | cmd->response[0] = (rsp_127_104 & 0xffffff) << 8 | | |
469 | (rsp_103_72 & 0xff); | |
470 | cmd->response[1] = (rsp_103_72 & 0xffffff) << 8 | | |
471 | (rsp_71_40 & 0xff); | |
472 | cmd->response[2] = (rsp_71_40 & 0xffffff) << 8 | | |
473 | (rsp_39_8 & 0xff); | |
474 | cmd->response[3] = (rsp_39_8 & 0xffffff) << 8; | |
475 | } else { | |
476 | /* bit 39-8 */ | |
477 | cmd->response[0] = readl(priv->regbase + UNIPHIER_SD_RSP10); | |
478 | } | |
479 | ||
480 | if (data) { | |
481 | /* use DMA if the HW supports it and the buffer is aligned */ | |
482 | if (priv->caps & UNIPHIER_SD_CAP_DMA_INTERNAL && | |
483 | uniphier_sd_addr_is_dmaable((long)data->src)) | |
484 | ret = uniphier_sd_dma_xfer(mmc, data); | |
485 | else | |
486 | ret = uniphier_sd_pio_xfer(mmc, data); | |
487 | ||
488 | ret = uniphier_sd_wait_for_irq(priv, UNIPHIER_SD_INFO1, | |
489 | UNIPHIER_SD_INFO1_CMP); | |
490 | if (ret) | |
491 | return ret; | |
492 | } | |
493 | ||
494 | return ret; | |
495 | } | |
496 | ||
497 | static void uniphier_sd_set_bus_width(struct uniphier_sd_priv *priv, | |
498 | struct mmc *mmc) | |
499 | { | |
500 | u32 val, tmp; | |
501 | ||
502 | switch (mmc->bus_width) { | |
503 | case 1: | |
504 | val = UNIPHIER_SD_OPTION_WIDTH_1; | |
505 | break; | |
506 | case 4: | |
507 | val = UNIPHIER_SD_OPTION_WIDTH_4; | |
508 | break; | |
509 | case 8: | |
510 | val = UNIPHIER_SD_OPTION_WIDTH_8; | |
511 | break; | |
512 | default: | |
513 | BUG(); | |
514 | break; | |
515 | } | |
516 | ||
517 | tmp = readl(priv->regbase + UNIPHIER_SD_OPTION); | |
518 | tmp &= ~UNIPHIER_SD_OPTION_WIDTH_MASK; | |
519 | tmp |= val; | |
520 | writel(tmp, priv->regbase + UNIPHIER_SD_OPTION); | |
521 | } | |
522 | ||
523 | static void uniphier_sd_set_ddr_mode(struct uniphier_sd_priv *priv, | |
524 | struct mmc *mmc) | |
525 | { | |
526 | u32 tmp; | |
527 | ||
528 | tmp = readl(priv->regbase + UNIPHIER_SD_IF_MODE); | |
529 | if (mmc->ddr_mode) | |
530 | tmp |= UNIPHIER_SD_IF_MODE_DDR; | |
531 | else | |
532 | tmp &= ~UNIPHIER_SD_IF_MODE_DDR; | |
533 | writel(tmp, priv->regbase + UNIPHIER_SD_IF_MODE); | |
534 | } | |
535 | ||
536 | static void uniphier_sd_set_clk_rate(struct uniphier_sd_priv *priv, | |
537 | struct mmc *mmc) | |
538 | { | |
539 | unsigned int divisor; | |
540 | u32 val, tmp; | |
541 | ||
542 | if (!mmc->clock) | |
543 | return; | |
544 | ||
545 | divisor = DIV_ROUND_UP(priv->mclk, mmc->clock); | |
546 | ||
547 | if (divisor <= 1) | |
548 | val = UNIPHIER_SD_CLKCTL_DIV1; | |
549 | else if (divisor <= 2) | |
550 | val = UNIPHIER_SD_CLKCTL_DIV2; | |
551 | else if (divisor <= 4) | |
552 | val = UNIPHIER_SD_CLKCTL_DIV4; | |
553 | else if (divisor <= 8) | |
554 | val = UNIPHIER_SD_CLKCTL_DIV8; | |
555 | else if (divisor <= 16) | |
556 | val = UNIPHIER_SD_CLKCTL_DIV16; | |
557 | else if (divisor <= 32) | |
558 | val = UNIPHIER_SD_CLKCTL_DIV32; | |
559 | else if (divisor <= 64) | |
560 | val = UNIPHIER_SD_CLKCTL_DIV64; | |
561 | else if (divisor <= 128) | |
562 | val = UNIPHIER_SD_CLKCTL_DIV128; | |
563 | else if (divisor <= 256) | |
564 | val = UNIPHIER_SD_CLKCTL_DIV256; | |
565 | else if (divisor <= 512 || !(priv->caps & UNIPHIER_SD_CAP_DIV1024)) | |
566 | val = UNIPHIER_SD_CLKCTL_DIV512; | |
567 | else | |
568 | val = UNIPHIER_SD_CLKCTL_DIV1024; | |
569 | ||
570 | tmp = readl(priv->regbase + UNIPHIER_SD_CLKCTL); | |
571 | ||
572 | /* stop the clock before changing its rate to avoid a glitch signal */ | |
573 | tmp &= ~UNIPHIER_SD_CLKCTL_SCLKEN; | |
574 | writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL); | |
575 | ||
576 | tmp &= ~UNIPHIER_SD_CLKCTL_DIV_MASK; | |
577 | tmp |= val | UNIPHIER_SD_CLKCTL_OFFEN; | |
578 | writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL); | |
579 | ||
580 | tmp |= UNIPHIER_SD_CLKCTL_SCLKEN; | |
581 | writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL); | |
582 | } | |
583 | ||
584 | static void uniphier_sd_set_ios(struct mmc *mmc) | |
585 | { | |
586 | struct uniphier_sd_priv *priv = mmc->priv; | |
587 | ||
588 | dev_dbg(priv->dev, "clock %uHz, DDRmode %d, width %u\n", | |
589 | mmc->clock, mmc->ddr_mode, mmc->bus_width); | |
590 | ||
591 | uniphier_sd_set_bus_width(priv, mmc); | |
592 | uniphier_sd_set_ddr_mode(priv, mmc); | |
593 | uniphier_sd_set_clk_rate(priv, mmc); | |
594 | ||
595 | udelay(1000); | |
596 | } | |
597 | ||
598 | static int uniphier_sd_init(struct mmc *mmc) | |
599 | { | |
600 | struct uniphier_sd_priv *priv = mmc->priv; | |
601 | u32 tmp; | |
602 | ||
603 | /* soft reset of the host */ | |
604 | tmp = readl(priv->regbase + UNIPHIER_SD_SOFT_RST); | |
605 | tmp &= ~UNIPHIER_SD_SOFT_RST_RSTX; | |
606 | writel(tmp, priv->regbase + UNIPHIER_SD_SOFT_RST); | |
607 | tmp |= UNIPHIER_SD_SOFT_RST_RSTX; | |
608 | writel(tmp, priv->regbase + UNIPHIER_SD_SOFT_RST); | |
609 | ||
610 | /* FIXME: implement eMMC hw_reset */ | |
611 | ||
612 | writel(UNIPHIER_SD_STOP_SEC, priv->regbase + UNIPHIER_SD_STOP); | |
613 | ||
614 | /* | |
615 | * Connected to 32bit AXI. | |
616 | * This register dropped backward compatibility at version 0x10. | |
617 | * Write an appropriate value depending on the IP version. | |
618 | */ | |
619 | writel(priv->version >= 0x10 ? 0x00000101 : 0x00000000, | |
620 | priv->regbase + UNIPHIER_SD_HOST_MODE); | |
621 | ||
622 | if (priv->caps & UNIPHIER_SD_CAP_DMA_INTERNAL) { | |
623 | tmp = readl(priv->regbase + UNIPHIER_SD_DMA_MODE); | |
624 | tmp |= UNIPHIER_SD_DMA_MODE_ADDR_INC; | |
625 | writel(tmp, priv->regbase + UNIPHIER_SD_DMA_MODE); | |
626 | } | |
627 | ||
628 | return 0; | |
629 | } | |
630 | ||
631 | static int uniphier_sd_getcd(struct mmc *mmc) | |
632 | { | |
633 | struct uniphier_sd_priv *priv = mmc->priv; | |
634 | ||
635 | if (priv->caps & UNIPHIER_SD_CAP_NONREMOVABLE) | |
636 | return 1; | |
637 | ||
638 | return !!(readl(priv->regbase + UNIPHIER_SD_INFO1) & | |
639 | UNIPHIER_SD_INFO1_CD); | |
640 | } | |
641 | ||
642 | static const struct mmc_ops uniphier_sd_ops = { | |
643 | .send_cmd = uniphier_sd_send_cmd, | |
644 | .set_ios = uniphier_sd_set_ios, | |
645 | .init = uniphier_sd_init, | |
646 | .getcd = uniphier_sd_getcd, | |
647 | }; | |
648 | ||
649 | int uniphier_sd_probe(struct udevice *dev) | |
650 | { | |
651 | struct uniphier_sd_priv *priv = dev_get_priv(dev); | |
652 | struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); | |
653 | fdt_addr_t base; | |
135aa950 | 654 | struct clk clk; |
a111bfbf MY |
655 | int ret; |
656 | ||
657 | priv->dev = dev; | |
658 | ||
4f80501b MY |
659 | base = dev_get_addr(dev); |
660 | if (base == FDT_ADDR_T_NONE) | |
661 | return -EINVAL; | |
662 | ||
663 | priv->regbase = map_sysmem(base, SZ_2K); | |
a111bfbf MY |
664 | if (!priv->regbase) |
665 | return -ENOMEM; | |
666 | ||
135aa950 SW |
667 | ret = clk_get_by_index(dev, 0, &clk); |
668 | if (ret < 0) { | |
a111bfbf | 669 | dev_err(dev, "failed to get host clock\n"); |
135aa950 | 670 | return ret; |
a111bfbf MY |
671 | } |
672 | ||
673 | /* set to max rate */ | |
135aa950 | 674 | priv->mclk = clk_set_rate(&clk, ULONG_MAX); |
a111bfbf MY |
675 | if (IS_ERR_VALUE(priv->mclk)) { |
676 | dev_err(dev, "failed to set rate for host clock\n"); | |
135aa950 | 677 | clk_free(&clk); |
a111bfbf MY |
678 | return priv->mclk; |
679 | } | |
680 | ||
135aa950 SW |
681 | ret = clk_enable(&clk); |
682 | clk_free(&clk); | |
a111bfbf MY |
683 | if (ret) { |
684 | dev_err(dev, "failed to enable host clock\n"); | |
685 | return ret; | |
686 | } | |
687 | ||
688 | priv->cfg.name = dev->name; | |
689 | priv->cfg.ops = &uniphier_sd_ops; | |
690 | priv->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; | |
691 | ||
692 | switch (fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 1)) { | |
693 | case 8: | |
694 | priv->cfg.host_caps |= MMC_MODE_8BIT; | |
695 | break; | |
696 | case 4: | |
697 | priv->cfg.host_caps |= MMC_MODE_4BIT; | |
698 | break; | |
699 | case 1: | |
700 | break; | |
701 | default: | |
702 | dev_err(dev, "Invalid \"bus-width\" value\n"); | |
703 | return -EINVAL; | |
704 | } | |
705 | ||
706 | if (fdt_get_property(gd->fdt_blob, dev->of_offset, "non-removable", | |
707 | NULL)) | |
708 | priv->caps |= UNIPHIER_SD_CAP_NONREMOVABLE; | |
709 | ||
710 | priv->version = readl(priv->regbase + UNIPHIER_SD_VERSION) & | |
711 | UNIPHIER_SD_VERSION_IP; | |
712 | dev_dbg(dev, "version %x\n", priv->version); | |
713 | if (priv->version >= 0x10) { | |
714 | priv->caps |= UNIPHIER_SD_CAP_DMA_INTERNAL; | |
715 | priv->caps |= UNIPHIER_SD_CAP_DIV1024; | |
716 | } | |
717 | ||
718 | priv->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; | |
719 | priv->cfg.f_min = priv->mclk / | |
720 | (priv->caps & UNIPHIER_SD_CAP_DIV1024 ? 1024 : 512); | |
721 | priv->cfg.f_max = priv->mclk; | |
722 | priv->cfg.b_max = U32_MAX; /* max value of UNIPHIER_SD_SECCNT */ | |
723 | ||
724 | priv->mmc = mmc_create(&priv->cfg, priv); | |
725 | if (!priv->mmc) | |
726 | return -EIO; | |
727 | ||
728 | upriv->mmc = priv->mmc; | |
cffe5d86 | 729 | priv->mmc->dev = dev; |
a111bfbf MY |
730 | |
731 | return 0; | |
732 | } | |
733 | ||
734 | int uniphier_sd_remove(struct udevice *dev) | |
735 | { | |
736 | struct uniphier_sd_priv *priv = dev_get_priv(dev); | |
737 | ||
738 | unmap_sysmem(priv->regbase); | |
739 | mmc_destroy(priv->mmc); | |
740 | ||
741 | return 0; | |
742 | } | |
743 | ||
744 | static const struct udevice_id uniphier_sd_match[] = { | |
745 | { .compatible = "socionext,uniphier-sdhc" }, | |
746 | { /* sentinel */ } | |
747 | }; | |
748 | ||
749 | U_BOOT_DRIVER(uniphier_mmc) = { | |
750 | .name = "uniphier-mmc", | |
751 | .id = UCLASS_MMC, | |
752 | .of_match = uniphier_sd_match, | |
753 | .probe = uniphier_sd_probe, | |
754 | .remove = uniphier_sd_remove, | |
755 | .priv_auto_alloc_size = sizeof(struct uniphier_sd_priv), | |
756 | }; |