xref: /openbmc/qemu/hw/sd/ssi-sd.c (revision 6ad034e71232c2929ed546304c9d249312bb632f)
1 /*
2  * SSI to SD card adapter.
3  *
4  * Copyright (c) 2007-2009 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * Copyright (c) 2021 Wind River Systems, Inc.
8  * Improved by Bin Meng <bin.meng@windriver.com>
9  *
10  * Validated with U-Boot v2021.01 and Linux v5.10 mmc_spi driver
11  *
12  * This code is licensed under the GNU GPL v2.
13  *
14  * Contributions after 2012-01-13 are licensed under the terms of the
15  * GNU GPL, version 2 or (at your option) any later version.
16  */
17 
18 #include "qemu/osdep.h"
19 #include "system/blockdev.h"
20 #include "hw/ssi/ssi.h"
21 #include "migration/vmstate.h"
22 #include "hw/qdev-properties.h"
23 #include "hw/sd/sd.h"
24 #include "qapi/error.h"
25 #include "qemu/crc-ccitt.h"
26 #include "qemu/module.h"
27 #include "qom/object.h"
28 
29 //#define DEBUG_SSI_SD 1
30 
31 #ifdef DEBUG_SSI_SD
32 #define DPRINTF(fmt, ...) \
33 do { printf("ssi_sd: " fmt , ## __VA_ARGS__); } while (0)
34 #define BADF(fmt, ...) \
35 do { fprintf(stderr, "ssi_sd: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
36 #else
37 #define DPRINTF(fmt, ...) do {} while(0)
38 #define BADF(fmt, ...) \
39 do { fprintf(stderr, "ssi_sd: error: " fmt , ## __VA_ARGS__);} while (0)
40 #endif
41 
42 typedef enum {
43     SSI_SD_CMD = 0,
44     SSI_SD_CMDARG,
45     SSI_SD_PREP_RESP,
46     SSI_SD_RESPONSE,
47     SSI_SD_PREP_DATA,
48     SSI_SD_DATA_START,
49     SSI_SD_DATA_READ,
50     SSI_SD_DATA_CRC16,
51     SSI_SD_DATA_WRITE,
52     SSI_SD_SKIP_CRC16,
53 } ssi_sd_mode;
54 
55 struct ssi_sd_state {
56     SSIPeripheral ssidev;
57     uint32_t mode;
58     int cmd;
59     uint8_t cmdarg[4];
60     uint8_t response[5];
61     uint16_t crc16;
62     int32_t read_bytes;
63     int32_t write_bytes;
64     int32_t arglen;
65     int32_t response_pos;
66     int32_t stopping;
67     SDBus sdbus;
68 };
69 
70 #define TYPE_SSI_SD "ssi-sd"
71 OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
72 
73 /* multiple block write */
74 #define SSI_TOKEN_MULTI_WRITE   0xfc
75 /* terminate multiple block write */
76 #define SSI_TOKEN_STOP_TRAN     0xfd
77 /* single block read/write, multiple block read */
78 #define SSI_TOKEN_SINGLE        0xfe
79 
80 /* dummy value - don't care */
81 #define SSI_DUMMY               0xff
82 
83 /* data accepted */
84 #define DATA_RESPONSE_ACCEPTED  0x05
85 
86 static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
87 {
88     ssi_sd_state *s = SSI_SD(dev);
89     SDRequest request;
90     uint8_t longresp[5];
91 
92     /*
93      * Special case: allow CMD12 (STOP TRANSMISSION) while reading data.
94      *
95      * See "Physical Layer Specification Version 8.00" chapter 7.5.2.2,
96      * to avoid conflict between CMD12 response and next data block,
97      * timing of CMD12 should be controlled as follows:
98      *
99      * - CMD12 issued at the timing that end bit of CMD12 and end bit of
100      *   data block is overlapped
101      * - CMD12 issued after one clock cycle after host receives a token
102      *   (either Start Block token or Data Error token)
103      *
104      * We need to catch CMD12 in all of the data read states.
105      */
106     if (s->mode >= SSI_SD_PREP_DATA && s->mode <= SSI_SD_DATA_CRC16) {
107         if (val == 0x4c) {
108             s->mode = SSI_SD_CMD;
109             /* There must be at least one byte delay before the card responds */
110             s->stopping = 1;
111         }
112     }
113 
114     switch (s->mode) {
115     case SSI_SD_CMD:
116         switch (val) {
117         case SSI_DUMMY:
118             DPRINTF("NULL command\n");
119             return SSI_DUMMY;
120             break;
121         case SSI_TOKEN_SINGLE:
122         case SSI_TOKEN_MULTI_WRITE:
123             DPRINTF("Start write block\n");
124             s->mode = SSI_SD_DATA_WRITE;
125             return SSI_DUMMY;
126         case SSI_TOKEN_STOP_TRAN:
127             DPRINTF("Stop multiple write\n");
128 
129             /* manually issue cmd12 to stop the transfer */
130             request.cmd = 12;
131             request.arg = 0;
132             s->arglen = sdbus_do_command(&s->sdbus, &request,
133                                          longresp, sizeof(longresp));
134             if (s->arglen == 0) {
135                 s->arglen = 1;
136                 /* a zero value indicates the card is busy */
137                 s->response[0] = 0;
138                 DPRINTF("SD card busy\n");
139             } else {
140                 s->arglen = 1;
141                 /* a non-zero value indicates the card is ready */
142                 s->response[0] = SSI_DUMMY;
143             }
144 
145             return SSI_DUMMY;
146         }
147 
148         s->cmd = val & 0x3f;
149         s->mode = SSI_SD_CMDARG;
150         s->arglen = 0;
151         return SSI_DUMMY;
152     case SSI_SD_CMDARG:
153         if (s->arglen == 4) {
154             /* FIXME: Check CRC.  */
155             request.cmd = s->cmd;
156             request.arg = ldl_be_p(s->cmdarg);
157             s->arglen = sdbus_do_command(&s->sdbus, &request,
158                                          longresp, sizeof(longresp));
159             DPRINTF("CMD%d arg 0x%08x = %d\n", s->cmd, request.arg, s->arglen);
160             assert(s->arglen > 0);
161             memcpy(s->response, longresp, s->arglen);
162 
163             /* handle R1b (busy signal) */
164             if (s->cmd == 28 || s->cmd == 29 || s->cmd == 38) {
165                 s->stopping = 1;
166             }
167             s->mode = SSI_SD_PREP_RESP;
168             s->response_pos = 0;
169         } else {
170             s->cmdarg[s->arglen++] = val;
171         }
172         return SSI_DUMMY;
173     case SSI_SD_PREP_RESP:
174         DPRINTF("Prepare card response (Ncr)\n");
175         s->mode = SSI_SD_RESPONSE;
176         return SSI_DUMMY;
177     case SSI_SD_RESPONSE:
178         if (s->response_pos < s->arglen) {
179             DPRINTF("Response 0x%02x\n", s->response[s->response_pos]);
180             return s->response[s->response_pos++];
181         }
182         if (s->stopping) {
183             s->stopping = 0;
184             s->mode = SSI_SD_CMD;
185             return SSI_DUMMY;
186         }
187         if (sdbus_data_ready(&s->sdbus)) {
188             DPRINTF("Data read\n");
189             s->mode = SSI_SD_DATA_START;
190         } else {
191             DPRINTF("End of command\n");
192             s->mode = SSI_SD_CMD;
193         }
194         return SSI_DUMMY;
195     case SSI_SD_PREP_DATA:
196         DPRINTF("Prepare data block (Nac)\n");
197         s->mode = SSI_SD_DATA_START;
198         return SSI_DUMMY;
199     case SSI_SD_DATA_START:
200         DPRINTF("Start read block\n");
201         s->mode = SSI_SD_DATA_READ;
202         s->response_pos = 0;
203         return SSI_TOKEN_SINGLE;
204     case SSI_SD_DATA_READ:
205         val = sdbus_read_byte(&s->sdbus);
206         s->read_bytes++;
207         s->crc16 = crc_ccitt_false(s->crc16, (uint8_t *)&val, 1);
208         if (!sdbus_data_ready(&s->sdbus) || s->read_bytes == 512) {
209             DPRINTF("Data read end\n");
210             s->mode = SSI_SD_DATA_CRC16;
211         }
212         return val;
213     case SSI_SD_DATA_CRC16:
214         val = (s->crc16 & 0xff00) >> 8;
215         s->crc16 <<= 8;
216         s->response_pos++;
217         if (s->response_pos == 2) {
218             DPRINTF("CRC16 read end\n");
219             if (s->read_bytes == 512 && s->cmd != 17) {
220                 s->mode = SSI_SD_PREP_DATA;
221             } else {
222                 s->mode = SSI_SD_CMD;
223             }
224             s->read_bytes = 0;
225             s->response_pos = 0;
226         }
227         return val;
228     case SSI_SD_DATA_WRITE:
229         sdbus_write_byte(&s->sdbus, val);
230         s->write_bytes++;
231         if (!sdbus_receive_ready(&s->sdbus) || s->write_bytes == 512) {
232             DPRINTF("Data write end\n");
233             s->mode = SSI_SD_SKIP_CRC16;
234             s->response_pos = 0;
235         }
236         return val;
237     case SSI_SD_SKIP_CRC16:
238         /* we don't verify the crc16 */
239         s->response_pos++;
240         if (s->response_pos == 2) {
241             DPRINTF("CRC16 receive end\n");
242             s->mode = SSI_SD_RESPONSE;
243             s->write_bytes = 0;
244             s->arglen = 1;
245             s->response[0] = DATA_RESPONSE_ACCEPTED;
246             s->response_pos = 0;
247         }
248         return SSI_DUMMY;
249     }
250     /* Should never happen.  */
251     return SSI_DUMMY;
252 }
253 
254 static int ssi_sd_post_load(void *opaque, int version_id)
255 {
256     ssi_sd_state *s = (ssi_sd_state *)opaque;
257 
258     if (s->mode > SSI_SD_SKIP_CRC16) {
259         return -EINVAL;
260     }
261     if (s->mode == SSI_SD_CMDARG &&
262         (s->arglen >= ARRAY_SIZE(s->cmdarg))) {
263         return -EINVAL;
264     }
265     if (s->mode == SSI_SD_RESPONSE &&
266         (s->response_pos < 0 || s->response_pos >= ARRAY_SIZE(s->response) ||
267         (!s->stopping && s->arglen > ARRAY_SIZE(s->response)))) {
268         return -EINVAL;
269     }
270 
271     return 0;
272 }
273 
274 static const VMStateDescription vmstate_ssi_sd = {
275     .name = "ssi_sd",
276     .version_id = 7,
277     .minimum_version_id = 7,
278     .post_load = ssi_sd_post_load,
279     .fields = (const VMStateField []) {
280         VMSTATE_UINT32(mode, ssi_sd_state),
281         VMSTATE_INT32(cmd, ssi_sd_state),
282         VMSTATE_UINT8_ARRAY(cmdarg, ssi_sd_state, 4),
283         VMSTATE_UINT8_ARRAY(response, ssi_sd_state, 5),
284         VMSTATE_UINT16(crc16, ssi_sd_state),
285         VMSTATE_INT32(read_bytes, ssi_sd_state),
286         VMSTATE_INT32(write_bytes, ssi_sd_state),
287         VMSTATE_INT32(arglen, ssi_sd_state),
288         VMSTATE_INT32(response_pos, ssi_sd_state),
289         VMSTATE_INT32(stopping, ssi_sd_state),
290         VMSTATE_SSI_PERIPHERAL(ssidev, ssi_sd_state),
291         VMSTATE_END_OF_LIST()
292     }
293 };
294 
295 static void ssi_sd_realize(SSIPeripheral *d, Error **errp)
296 {
297     ssi_sd_state *s = SSI_SD(d);
298 
299     qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(d), "sd-bus");
300 }
301 
302 static void ssi_sd_reset(DeviceState *dev)
303 {
304     ssi_sd_state *s = SSI_SD(dev);
305 
306     s->mode = SSI_SD_CMD;
307     s->cmd = 0;
308     memset(s->cmdarg, 0, sizeof(s->cmdarg));
309     memset(s->response, 0, sizeof(s->response));
310     s->crc16 = 0;
311     s->read_bytes = 0;
312     s->write_bytes = 0;
313     s->arglen = 0;
314     s->response_pos = 0;
315     s->stopping = 0;
316 }
317 
318 static void ssi_sd_class_init(ObjectClass *klass, const void *data)
319 {
320     DeviceClass *dc = DEVICE_CLASS(klass);
321     SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
322 
323     k->realize = ssi_sd_realize;
324     k->transfer = ssi_sd_transfer;
325     k->cs_polarity = SSI_CS_LOW;
326     dc->vmsd = &vmstate_ssi_sd;
327     device_class_set_legacy_reset(dc, ssi_sd_reset);
328     /* Reason: GPIO chip-select line should be wired up */
329     dc->user_creatable = false;
330 }
331 
332 static const TypeInfo ssi_sd_types[] = {
333     {
334         .name           = TYPE_SSI_SD,
335         .parent         = TYPE_SSI_PERIPHERAL,
336         .instance_size  = sizeof(ssi_sd_state),
337         .class_init     = ssi_sd_class_init,
338     },
339 };
340 
341 DEFINE_TYPES(ssi_sd_types)
342