~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/boot/compressed/sdhi-shmobile.c

Version: ~ [ linux-5.6-rc3 ] ~ [ linux-5.5.6 ] ~ [ linux-5.4.22 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.106 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.171 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.214 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.214 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * SuperH Mobile SDHI
  3  *
  4  * Copyright (C) 2010 Magnus Damm
  5  * Copyright (C) 2010 Kuninori Morimoto
  6  * Copyright (C) 2010 Simon Horman
  7  *
  8  * This file is subject to the terms and conditions of the GNU General Public
  9  * License.  See the file "COPYING" in the main directory of this archive
 10  * for more details.
 11  *
 12  * Parts inspired by u-boot
 13  */
 14 
 15 #include <linux/io.h>
 16 #include <linux/mmc/host.h>
 17 #include <linux/mmc/core.h>
 18 #include <linux/mmc/mmc.h>
 19 #include <linux/mmc/sd.h>
 20 #include <linux/mmc/tmio.h>
 21 #include <mach/sdhi.h>
 22 
 23 #define OCR_FASTBOOT            (1<<29)
 24 #define OCR_HCS                 (1<<30)
 25 #define OCR_BUSY                (1<<31)
 26 
 27 #define RESP_CMD12              0x00000030
 28 
 29 static inline u16 sd_ctrl_read16(void __iomem *base, int addr)
 30 {
 31         return __raw_readw(base + addr);
 32 }
 33 
 34 static inline u32 sd_ctrl_read32(void __iomem *base, int addr)
 35 {
 36         return __raw_readw(base + addr) |
 37                __raw_readw(base + addr + 2) << 16;
 38 }
 39 
 40 static inline void sd_ctrl_write16(void __iomem *base, int addr, u16 val)
 41 {
 42         __raw_writew(val, base + addr);
 43 }
 44 
 45 static inline void sd_ctrl_write32(void __iomem *base, int addr, u32 val)
 46 {
 47         __raw_writew(val, base + addr);
 48         __raw_writew(val >> 16, base + addr + 2);
 49 }
 50 
 51 #define ALL_ERROR (TMIO_STAT_CMD_IDX_ERR | TMIO_STAT_CRCFAIL |          \
 52                    TMIO_STAT_STOPBIT_ERR | TMIO_STAT_DATATIMEOUT |      \
 53                    TMIO_STAT_RXOVERFLOW | TMIO_STAT_TXUNDERRUN |        \
 54                    TMIO_STAT_CMDTIMEOUT | TMIO_STAT_ILL_ACCESS |        \
 55                    TMIO_STAT_ILL_FUNC)
 56 
 57 static int sdhi_intr(void __iomem *base)
 58 {
 59         unsigned long state = sd_ctrl_read32(base, CTL_STATUS);
 60 
 61         if (state & ALL_ERROR) {
 62                 sd_ctrl_write32(base, CTL_STATUS, ~ALL_ERROR);
 63                 sd_ctrl_write32(base, CTL_IRQ_MASK,
 64                                 ALL_ERROR |
 65                                 sd_ctrl_read32(base, CTL_IRQ_MASK));
 66                 return -EINVAL;
 67         }
 68         if (state & TMIO_STAT_CMDRESPEND) {
 69                 sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND);
 70                 sd_ctrl_write32(base, CTL_IRQ_MASK,
 71                                 TMIO_STAT_CMDRESPEND |
 72                                 sd_ctrl_read32(base, CTL_IRQ_MASK));
 73                 return 0;
 74         }
 75         if (state & TMIO_STAT_RXRDY) {
 76                 sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_RXRDY);
 77                 sd_ctrl_write32(base, CTL_IRQ_MASK,
 78                                 TMIO_STAT_RXRDY | TMIO_STAT_TXUNDERRUN |
 79                                 sd_ctrl_read32(base, CTL_IRQ_MASK));
 80                 return 0;
 81         }
 82         if (state & TMIO_STAT_DATAEND) {
 83                 sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_DATAEND);
 84                 sd_ctrl_write32(base, CTL_IRQ_MASK,
 85                                 TMIO_STAT_DATAEND |
 86                                 sd_ctrl_read32(base, CTL_IRQ_MASK));
 87                 return 0;
 88         }
 89 
 90         return -EAGAIN;
 91 }
 92 
 93 static int sdhi_boot_wait_resp_end(void __iomem *base)
 94 {
 95         int err = -EAGAIN, timeout = 10000000;
 96 
 97         while (timeout--) {
 98                 err = sdhi_intr(base);
 99                 if (err != -EAGAIN)
100                         break;
101                 udelay(1);
102         }
103 
104         return err;
105 }
106 
107 /* SDHI_CLK_CTRL */
108 #define CLK_MMC_ENABLE                 (1 << 8)
109 #define CLK_MMC_INIT                   (1 << 6)        /* clk / 256 */
110 
111 static void sdhi_boot_mmc_clk_stop(void __iomem *base)
112 {
113         sd_ctrl_write16(base, CTL_CLK_AND_WAIT_CTL, 0x0000);
114         msleep(10);
115         sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL, ~CLK_MMC_ENABLE &
116                 sd_ctrl_read16(base, CTL_SD_CARD_CLK_CTL));
117         msleep(10);
118 }
119 
120 static void sdhi_boot_mmc_clk_start(void __iomem *base)
121 {
122         sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL, CLK_MMC_ENABLE |
123                 sd_ctrl_read16(base, CTL_SD_CARD_CLK_CTL));
124         msleep(10);
125         sd_ctrl_write16(base, CTL_CLK_AND_WAIT_CTL, CLK_MMC_ENABLE);
126         msleep(10);
127 }
128 
129 static void sdhi_boot_reset(void __iomem *base)
130 {
131         sd_ctrl_write16(base, CTL_RESET_SD, 0x0000);
132         msleep(10);
133         sd_ctrl_write16(base, CTL_RESET_SD, 0x0001);
134         msleep(10);
135 }
136 
137 /* Set MMC clock / power.
138  * Note: This controller uses a simple divider scheme therefore it cannot
139  * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
140  * MMC wont run that fast, it has to be clocked at 12MHz which is the next
141  * slowest setting.
142  */
143 static int sdhi_boot_mmc_set_ios(void __iomem *base, struct mmc_ios *ios)
144 {
145         if (sd_ctrl_read32(base, CTL_STATUS) & TMIO_STAT_CMD_BUSY)
146                 return -EBUSY;
147 
148         if (ios->clock)
149                 sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL,
150                                 ios->clock | CLK_MMC_ENABLE);
151 
152         /* Power sequence - OFF -> ON -> UP */
153         switch (ios->power_mode) {
154         case MMC_POWER_OFF: /* power down SD bus */
155                 sdhi_boot_mmc_clk_stop(base);
156                 break;
157         case MMC_POWER_ON: /* power up SD bus */
158                 break;
159         case MMC_POWER_UP: /* start bus clock */
160                 sdhi_boot_mmc_clk_start(base);
161                 break;
162         }
163 
164         switch (ios->bus_width) {
165         case MMC_BUS_WIDTH_1:
166                 sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x80e0);
167         break;
168         case MMC_BUS_WIDTH_4:
169                 sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x00e0);
170         break;
171         }
172 
173         /* Let things settle. delay taken from winCE driver */
174         udelay(140);
175 
176         return 0;
177 }
178 
179 /* These are the bitmasks the tmio chip requires to implement the MMC response
180  * types. Note that R1 and R6 are the same in this scheme. */
181 #define RESP_NONE      0x0300
182 #define RESP_R1        0x0400
183 #define RESP_R1B       0x0500
184 #define RESP_R2        0x0600
185 #define RESP_R3        0x0700
186 #define DATA_PRESENT   0x0800
187 #define TRANSFER_READ  0x1000
188 
189 static int sdhi_boot_request(void __iomem *base, struct mmc_command *cmd)
190 {
191         int err, c = cmd->opcode;
192 
193         switch (mmc_resp_type(cmd)) {
194         case MMC_RSP_NONE: c |= RESP_NONE; break;
195         case MMC_RSP_R1:   c |= RESP_R1;   break;
196         case MMC_RSP_R1B:  c |= RESP_R1B;  break;
197         case MMC_RSP_R2:   c |= RESP_R2;   break;
198         case MMC_RSP_R3:   c |= RESP_R3;   break;
199         default:
200                 return -EINVAL;
201         }
202 
203         /* No interrupts so this may not be cleared */
204         sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND);
205 
206         sd_ctrl_write32(base, CTL_IRQ_MASK, TMIO_STAT_CMDRESPEND |
207                         sd_ctrl_read32(base, CTL_IRQ_MASK));
208         sd_ctrl_write32(base, CTL_ARG_REG, cmd->arg);
209         sd_ctrl_write16(base, CTL_SD_CMD, c);
210 
211 
212         sd_ctrl_write32(base, CTL_IRQ_MASK,
213                         ~(TMIO_STAT_CMDRESPEND | ALL_ERROR) &
214                         sd_ctrl_read32(base, CTL_IRQ_MASK));
215 
216         err = sdhi_boot_wait_resp_end(base);
217         if (err)
218                 return err;
219 
220         cmd->resp[0] = sd_ctrl_read32(base, CTL_RESPONSE);
221 
222         return 0;
223 }
224 
225 static int sdhi_boot_do_read_single(void __iomem *base, int high_capacity,
226                                     unsigned long block, unsigned short *buf)
227 {
228         int err, i;
229 
230         /* CMD17 - Read */
231         {
232                 struct mmc_command cmd;
233 
234                 cmd.opcode = MMC_READ_SINGLE_BLOCK | \
235                              TRANSFER_READ | DATA_PRESENT;
236                 if (high_capacity)
237                         cmd.arg = block;
238                 else
239                         cmd.arg = block * TMIO_BBS;
240                 cmd.flags = MMC_RSP_R1;
241                 err = sdhi_boot_request(base, &cmd);
242                 if (err)
243                         return err;
244         }
245 
246         sd_ctrl_write32(base, CTL_IRQ_MASK,
247                         ~(TMIO_STAT_DATAEND | TMIO_STAT_RXRDY |
248                           TMIO_STAT_TXUNDERRUN) &
249                         sd_ctrl_read32(base, CTL_IRQ_MASK));
250         err = sdhi_boot_wait_resp_end(base);
251         if (err)
252                 return err;
253 
254         sd_ctrl_write16(base, CTL_SD_XFER_LEN, TMIO_BBS);
255         for (i = 0; i < TMIO_BBS / sizeof(*buf); i++)
256                 *buf++ = sd_ctrl_read16(base, RESP_CMD12);
257 
258         err = sdhi_boot_wait_resp_end(base);
259         if (err)
260                 return err;
261 
262         return 0;
263 }
264 
265 int sdhi_boot_do_read(void __iomem *base, int high_capacity,
266                       unsigned long offset, unsigned short count,
267                       unsigned short *buf)
268 {
269         unsigned long i;
270         int err = 0;
271 
272         for (i = 0; i < count; i++) {
273                 err = sdhi_boot_do_read_single(base, high_capacity, offset + i,
274                                                buf + (i * TMIO_BBS /
275                                                       sizeof(*buf)));
276                 if (err)
277                         return err;
278         }
279 
280         return 0;
281 }
282 
283 #define VOLTAGES (MMC_VDD_32_33 | MMC_VDD_33_34)
284 
285 int sdhi_boot_init(void __iomem *base)
286 {
287         bool sd_v2 = false, sd_v1_0 = false;
288         unsigned short cid;
289         int err, high_capacity = 0;
290 
291         sdhi_boot_mmc_clk_stop(base);
292         sdhi_boot_reset(base);
293 
294         /* mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0 */
295         {
296                 struct mmc_ios ios;
297                 ios.power_mode = MMC_POWER_ON;
298                 ios.bus_width = MMC_BUS_WIDTH_1;
299                 ios.clock = CLK_MMC_INIT;
300                 err = sdhi_boot_mmc_set_ios(base, &ios);
301                 if (err)
302                         return err;
303         }
304 
305         /* CMD0 */
306         {
307                 struct mmc_command cmd;
308                 msleep(1);
309                 cmd.opcode = MMC_GO_IDLE_STATE;
310                 cmd.arg = 0;
311                 cmd.flags = MMC_RSP_NONE;
312                 err = sdhi_boot_request(base, &cmd);
313                 if (err)
314                         return err;
315                 msleep(2);
316         }
317 
318         /* CMD8 - Test for SD version 2 */
319         {
320                 struct mmc_command cmd;
321                 cmd.opcode = SD_SEND_IF_COND;
322                 cmd.arg = (VOLTAGES != 0) << 8 | 0xaa;
323                 cmd.flags = MMC_RSP_R1;
324                 err = sdhi_boot_request(base, &cmd); /* Ignore error */
325                 if ((cmd.resp[0] & 0xff) == 0xaa)
326                         sd_v2 = true;
327         }
328 
329         /* CMD55 - Get OCR (SD) */
330         {
331                 int timeout = 1000;
332                 struct mmc_command cmd;
333 
334                 cmd.arg = 0;
335 
336                 do {
337                         cmd.opcode = MMC_APP_CMD;
338                         cmd.flags = MMC_RSP_R1;
339                         cmd.arg = 0;
340                         err = sdhi_boot_request(base, &cmd);
341                         if (err)
342                                 break;
343 
344                         cmd.opcode = SD_APP_OP_COND;
345                         cmd.flags = MMC_RSP_R3;
346                         cmd.arg = (VOLTAGES & 0xff8000);
347                         if (sd_v2)
348                                 cmd.arg |= OCR_HCS;
349                         cmd.arg |= OCR_FASTBOOT;
350                         err = sdhi_boot_request(base, &cmd);
351                         if (err)
352                                 break;
353 
354                         msleep(1);
355                 } while((!(cmd.resp[0] & OCR_BUSY)) && --timeout);
356 
357                 if (!err && timeout) {
358                         if (!sd_v2)
359                                 sd_v1_0 = true;
360                         high_capacity = (cmd.resp[0] & OCR_HCS) == OCR_HCS;
361                 }
362         }
363 
364         /* CMD1 - Get OCR (MMC) */
365         if (!sd_v2 && !sd_v1_0) {
366                 int timeout = 1000;
367                 struct mmc_command cmd;
368 
369                 do {
370                         cmd.opcode = MMC_SEND_OP_COND;
371                         cmd.arg = VOLTAGES | OCR_HCS;
372                         cmd.flags = MMC_RSP_R3;
373                         err = sdhi_boot_request(base, &cmd);
374                         if (err)
375                                 return err;
376 
377                         msleep(1);
378                 } while((!(cmd.resp[0] & OCR_BUSY)) && --timeout);
379 
380                 if (!timeout)
381                         return -EAGAIN;
382 
383                 high_capacity = (cmd.resp[0] & OCR_HCS) == OCR_HCS;
384         }
385 
386         /* CMD2 - Get CID */
387         {
388                 struct mmc_command cmd;
389                 cmd.opcode = MMC_ALL_SEND_CID;
390                 cmd.arg = 0;
391                 cmd.flags = MMC_RSP_R2;
392                 err = sdhi_boot_request(base, &cmd);
393                 if (err)
394                         return err;
395         }
396 
397         /* CMD3
398          * MMC: Set the relative address
399          * SD:  Get the relative address
400          * Also puts the card into the standby state
401          */
402         {
403                 struct mmc_command cmd;
404                 cmd.opcode = MMC_SET_RELATIVE_ADDR;
405                 cmd.arg = 0;
406                 cmd.flags = MMC_RSP_R1;
407                 err = sdhi_boot_request(base, &cmd);
408                 if (err)
409                         return err;
410                 cid = cmd.resp[0] >> 16;
411         }
412 
413         /* CMD9 - Get CSD */
414         {
415                 struct mmc_command cmd;
416                 cmd.opcode = MMC_SEND_CSD;
417                 cmd.arg = cid << 16;
418                 cmd.flags = MMC_RSP_R2;
419                 err = sdhi_boot_request(base, &cmd);
420                 if (err)
421                         return err;
422         }
423 
424         /* CMD7 - Select the card */
425         {
426                 struct mmc_command cmd;
427                 cmd.opcode = MMC_SELECT_CARD;
428                 //cmd.arg = rca << 16;
429                 cmd.arg = cid << 16;
430                 //cmd.flags = MMC_RSP_R1B;
431                 cmd.flags = MMC_RSP_R1;
432                 err = sdhi_boot_request(base, &cmd);
433                 if (err)
434                         return err;
435         }
436 
437         /* CMD16 - Set the block size */
438         {
439                 struct mmc_command cmd;
440                 cmd.opcode = MMC_SET_BLOCKLEN;
441                 cmd.arg = TMIO_BBS;
442                 cmd.flags = MMC_RSP_R1;
443                 err = sdhi_boot_request(base, &cmd);
444                 if (err)
445                         return err;
446         }
447 
448         return high_capacity;
449 }
450 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp