~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/mmc/davinci_mmc.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Davinci MMC Controller Driver
 
3
 *
 
4
 * Copyright (C) 2010 Texas Instruments Incorporated
 
5
 *
 
6
 * SPDX-License-Identifier:     GPL-2.0+
 
7
 */
 
8
 
 
9
#include <config.h>
 
10
#include <common.h>
 
11
#include <command.h>
 
12
#include <mmc.h>
 
13
#include <part.h>
 
14
#include <malloc.h>
 
15
#include <asm/io.h>
 
16
#include <asm/arch/sdmmc_defs.h>
 
17
 
 
18
#define DAVINCI_MAX_BLOCKS      (32)
 
19
#define WATCHDOG_COUNT          (100000)
 
20
 
 
21
#define get_val(addr)           REG(addr)
 
22
#define set_val(addr, val)      REG(addr) = (val)
 
23
#define set_bit(addr, val)      set_val((addr), (get_val(addr) | (val)))
 
24
#define clear_bit(addr, val)    set_val((addr), (get_val(addr) & ~(val)))
 
25
 
 
26
/* Set davinci clock prescalar value based on the required clock in HZ */
 
27
static void dmmc_set_clock(struct mmc *mmc, uint clock)
 
28
{
 
29
        struct davinci_mmc *host = mmc->priv;
 
30
        struct davinci_mmc_regs *regs = host->reg_base;
 
31
        uint clkrt, sysclk2, act_clock;
 
32
 
 
33
        if (clock < mmc->cfg->f_min)
 
34
                clock = mmc->cfg->f_min;
 
35
        if (clock > mmc->cfg->f_max)
 
36
                clock = mmc->cfg->f_max;
 
37
 
 
38
        set_val(&regs->mmcclk, 0);
 
39
        sysclk2 = host->input_clk;
 
40
        clkrt = (sysclk2 / (2 * clock)) - 1;
 
41
 
 
42
        /* Calculate the actual clock for the divider used */
 
43
        act_clock = (sysclk2 / (2 * (clkrt + 1)));
 
44
 
 
45
        /* Adjust divider if actual clock exceeds the required clock */
 
46
        if (act_clock > clock)
 
47
                clkrt++;
 
48
 
 
49
        /* check clock divider boundary and correct it */
 
50
        if (clkrt > 0xFF)
 
51
                clkrt = 0xFF;
 
52
 
 
53
        set_val(&regs->mmcclk, (clkrt | MMCCLK_CLKEN));
 
54
}
 
55
 
 
56
/* Status bit wait loop for MMCST1 */
 
57
static int
 
58
dmmc_wait_fifo_status(volatile struct davinci_mmc_regs *regs, uint status)
 
59
{
 
60
        uint wdog = WATCHDOG_COUNT;
 
61
 
 
62
        while (--wdog && ((get_val(&regs->mmcst1) & status) != status))
 
63
                udelay(10);
 
64
 
 
65
        if (!(get_val(&regs->mmcctl) & MMCCTL_WIDTH_4_BIT))
 
66
                udelay(100);
 
67
 
 
68
        if (wdog == 0)
 
69
                return COMM_ERR;
 
70
 
 
71
        return 0;
 
72
}
 
73
 
 
74
/* Busy bit wait loop for MMCST1 */
 
75
static int dmmc_busy_wait(volatile struct davinci_mmc_regs *regs)
 
76
{
 
77
        uint wdog = WATCHDOG_COUNT;
 
78
 
 
79
        while (--wdog && (get_val(&regs->mmcst1) & MMCST1_BUSY))
 
80
                udelay(10);
 
81
 
 
82
        if (wdog == 0)
 
83
                return COMM_ERR;
 
84
 
 
85
        return 0;
 
86
}
 
87
 
 
88
/* Status bit wait loop for MMCST0 - Checks for error bits as well */
 
89
static int dmmc_check_status(volatile struct davinci_mmc_regs *regs,
 
90
                uint *cur_st, uint st_ready, uint st_error)
 
91
{
 
92
        uint wdog = WATCHDOG_COUNT;
 
93
        uint mmcstatus = *cur_st;
 
94
 
 
95
        while (wdog--) {
 
96
                if (mmcstatus & st_ready) {
 
97
                        *cur_st = mmcstatus;
 
98
                        mmcstatus = get_val(&regs->mmcst1);
 
99
                        return 0;
 
100
                } else if (mmcstatus & st_error) {
 
101
                        if (mmcstatus & MMCST0_TOUTRS)
 
102
                                return TIMEOUT;
 
103
                        printf("[ ST0 ERROR %x]\n", mmcstatus);
 
104
                        /*
 
105
                         * Ignore CRC errors as some MMC cards fail to
 
106
                         * initialize on DM365-EVM on the SD1 slot
 
107
                         */
 
108
                        if (mmcstatus & MMCST0_CRCRS)
 
109
                                return 0;
 
110
                        return COMM_ERR;
 
111
                }
 
112
                udelay(10);
 
113
 
 
114
                mmcstatus = get_val(&regs->mmcst0);
 
115
        }
 
116
 
 
117
        printf("Status %x Timeout ST0:%x ST1:%x\n", st_ready, mmcstatus,
 
118
                        get_val(&regs->mmcst1));
 
119
        return COMM_ERR;
 
120
}
 
121
 
 
122
/*
 
123
 * Sends a command out on the bus.  Takes the mmc pointer,
 
124
 * a command pointer, and an optional data pointer.
 
125
 */
 
126
static int
 
127
dmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
128
{
 
129
        struct davinci_mmc *host = mmc->priv;
 
130
        volatile struct davinci_mmc_regs *regs = host->reg_base;
 
131
        uint mmcstatus, status_rdy, status_err;
 
132
        uint i, cmddata, bytes_left = 0;
 
133
        int fifo_words, fifo_bytes, err;
 
134
        char *data_buf = NULL;
 
135
 
 
136
        /* Clear status registers */
 
137
        mmcstatus = get_val(&regs->mmcst0);
 
138
        fifo_words = (host->version == MMC_CTLR_VERSION_2) ? 16 : 8;
 
139
        fifo_bytes = fifo_words << 2;
 
140
 
 
141
        /* Wait for any previous busy signal to be cleared */
 
142
        dmmc_busy_wait(regs);
 
143
 
 
144
        cmddata = cmd->cmdidx;
 
145
        cmddata |= MMCCMD_PPLEN;
 
146
 
 
147
        /* Send init clock for CMD0 */
 
148
        if (cmd->cmdidx == MMC_CMD_GO_IDLE_STATE)
 
149
                cmddata |= MMCCMD_INITCK;
 
150
 
 
151
        switch (cmd->resp_type) {
 
152
        case MMC_RSP_R1b:
 
153
                cmddata |= MMCCMD_BSYEXP;
 
154
                /* Fall-through */
 
155
        case MMC_RSP_R1:    /* R1, R1b, R5, R6, R7 */
 
156
                cmddata |= MMCCMD_RSPFMT_R1567;
 
157
                break;
 
158
        case MMC_RSP_R2:
 
159
                cmddata |= MMCCMD_RSPFMT_R2;
 
160
                break;
 
161
        case MMC_RSP_R3: /* R3, R4 */
 
162
                cmddata |= MMCCMD_RSPFMT_R3;
 
163
                break;
 
164
        }
 
165
 
 
166
        set_val(&regs->mmcim, 0);
 
167
 
 
168
        if (data) {
 
169
                /* clear previous data transfer if any and set new one */
 
170
                bytes_left = (data->blocksize * data->blocks);
 
171
 
 
172
                /* Reset FIFO - Always use 32 byte fifo threshold */
 
173
                set_val(&regs->mmcfifoctl,
 
174
                                (MMCFIFOCTL_FIFOLEV | MMCFIFOCTL_FIFORST));
 
175
 
 
176
                if (host->version == MMC_CTLR_VERSION_2)
 
177
                        cmddata |= MMCCMD_DMATRIG;
 
178
 
 
179
                cmddata |= MMCCMD_WDATX;
 
180
                if (data->flags == MMC_DATA_READ) {
 
181
                        set_val(&regs->mmcfifoctl, MMCFIFOCTL_FIFOLEV);
 
182
                } else if (data->flags == MMC_DATA_WRITE) {
 
183
                        set_val(&regs->mmcfifoctl,
 
184
                                        (MMCFIFOCTL_FIFOLEV |
 
185
                                         MMCFIFOCTL_FIFODIR));
 
186
                        cmddata |= MMCCMD_DTRW;
 
187
                }
 
188
 
 
189
                set_val(&regs->mmctod, 0xFFFF);
 
190
                set_val(&regs->mmcnblk, (data->blocks & MMCNBLK_NBLK_MASK));
 
191
                set_val(&regs->mmcblen, (data->blocksize & MMCBLEN_BLEN_MASK));
 
192
 
 
193
                if (data->flags == MMC_DATA_WRITE) {
 
194
                        uint val;
 
195
                        data_buf = (char *)data->src;
 
196
                        /* For write, fill FIFO with data before issue of CMD */
 
197
                        for (i = 0; (i < fifo_words) && bytes_left; i++) {
 
198
                                memcpy((char *)&val, data_buf, 4);
 
199
                                set_val(&regs->mmcdxr, val);
 
200
                                data_buf += 4;
 
201
                                bytes_left -= 4;
 
202
                        }
 
203
                }
 
204
        } else {
 
205
                set_val(&regs->mmcblen, 0);
 
206
                set_val(&regs->mmcnblk, 0);
 
207
        }
 
208
 
 
209
        set_val(&regs->mmctor, 0x1FFF);
 
210
 
 
211
        /* Send the command */
 
212
        set_val(&regs->mmcarghl, cmd->cmdarg);
 
213
        set_val(&regs->mmccmd, cmddata);
 
214
 
 
215
        status_rdy = MMCST0_RSPDNE;
 
216
        status_err = (MMCST0_TOUTRS | MMCST0_TOUTRD |
 
217
                        MMCST0_CRCWR | MMCST0_CRCRD);
 
218
        if (cmd->resp_type & MMC_RSP_CRC)
 
219
                status_err |= MMCST0_CRCRS;
 
220
 
 
221
        mmcstatus = get_val(&regs->mmcst0);
 
222
        err = dmmc_check_status(regs, &mmcstatus, status_rdy, status_err);
 
223
        if (err)
 
224
                return err;
 
225
 
 
226
        /* For R1b wait for busy done */
 
227
        if (cmd->resp_type == MMC_RSP_R1b)
 
228
                dmmc_busy_wait(regs);
 
229
 
 
230
        /* Collect response from controller for specific commands */
 
231
        if (mmcstatus & MMCST0_RSPDNE) {
 
232
                /* Copy the response to the response buffer */
 
233
                if (cmd->resp_type & MMC_RSP_136) {
 
234
                        cmd->response[0] = get_val(&regs->mmcrsp67);
 
235
                        cmd->response[1] = get_val(&regs->mmcrsp45);
 
236
                        cmd->response[2] = get_val(&regs->mmcrsp23);
 
237
                        cmd->response[3] = get_val(&regs->mmcrsp01);
 
238
                } else if (cmd->resp_type & MMC_RSP_PRESENT) {
 
239
                        cmd->response[0] = get_val(&regs->mmcrsp67);
 
240
                }
 
241
        }
 
242
 
 
243
        if (data == NULL)
 
244
                return 0;
 
245
 
 
246
        if (data->flags == MMC_DATA_READ) {
 
247
                /* check for DATDNE along with DRRDY as the controller might
 
248
                 * set the DATDNE without DRRDY for smaller transfers with
 
249
                 * less than FIFO threshold bytes
 
250
                 */
 
251
                status_rdy = MMCST0_DRRDY | MMCST0_DATDNE;
 
252
                status_err = MMCST0_TOUTRD | MMCST0_CRCRD;
 
253
                data_buf = data->dest;
 
254
        } else {
 
255
                status_rdy = MMCST0_DXRDY | MMCST0_DATDNE;
 
256
                status_err = MMCST0_CRCWR;
 
257
        }
 
258
 
 
259
        /* Wait until all of the blocks are transferred */
 
260
        while (bytes_left) {
 
261
                err = dmmc_check_status(regs, &mmcstatus, status_rdy,
 
262
                                status_err);
 
263
                if (err)
 
264
                        return err;
 
265
 
 
266
                if (data->flags == MMC_DATA_READ) {
 
267
                        /*
 
268
                         * MMC controller sets the Data receive ready bit
 
269
                         * (DRRDY) in MMCST0 even before the entire FIFO is
 
270
                         * full. This results in erratic behavior if we start
 
271
                         * reading the FIFO soon after DRRDY.  Wait for the
 
272
                         * FIFO full bit in MMCST1 for proper FIFO clearing.
 
273
                         */
 
274
                        if (bytes_left > fifo_bytes)
 
275
                                dmmc_wait_fifo_status(regs, 0x4a);
 
276
                        else if (bytes_left == fifo_bytes) {
 
277
                                dmmc_wait_fifo_status(regs, 0x40);
 
278
                                if (cmd->cmdidx == MMC_CMD_SEND_EXT_CSD)
 
279
                                        udelay(600);
 
280
                        }
 
281
 
 
282
                        for (i = 0; bytes_left && (i < fifo_words); i++) {
 
283
                                cmddata = get_val(&regs->mmcdrr);
 
284
                                memcpy(data_buf, (char *)&cmddata, 4);
 
285
                                data_buf += 4;
 
286
                                bytes_left -= 4;
 
287
                        }
 
288
                } else {
 
289
                        /*
 
290
                         * MMC controller sets the Data transmit ready bit
 
291
                         * (DXRDY) in MMCST0 even before the entire FIFO is
 
292
                         * empty. This results in erratic behavior if we start
 
293
                         * writing the FIFO soon after DXRDY.  Wait for the
 
294
                         * FIFO empty bit in MMCST1 for proper FIFO clearing.
 
295
                         */
 
296
                        dmmc_wait_fifo_status(regs, MMCST1_FIFOEMP);
 
297
                        for (i = 0; bytes_left && (i < fifo_words); i++) {
 
298
                                memcpy((char *)&cmddata, data_buf, 4);
 
299
                                set_val(&regs->mmcdxr, cmddata);
 
300
                                data_buf += 4;
 
301
                                bytes_left -= 4;
 
302
                        }
 
303
                        dmmc_busy_wait(regs);
 
304
                }
 
305
        }
 
306
 
 
307
        err = dmmc_check_status(regs, &mmcstatus, MMCST0_DATDNE, status_err);
 
308
        if (err)
 
309
                return err;
 
310
 
 
311
        return 0;
 
312
}
 
313
 
 
314
/* Initialize Davinci MMC controller */
 
315
static int dmmc_init(struct mmc *mmc)
 
316
{
 
317
        struct davinci_mmc *host = mmc->priv;
 
318
        struct davinci_mmc_regs *regs = host->reg_base;
 
319
 
 
320
        /* Clear status registers explicitly - soft reset doesn't clear it
 
321
         * If Uboot is invoked from UBL with SDMMC Support, the status
 
322
         * registers can have uncleared bits
 
323
         */
 
324
        get_val(&regs->mmcst0);
 
325
        get_val(&regs->mmcst1);
 
326
 
 
327
        /* Hold software reset */
 
328
        set_bit(&regs->mmcctl, MMCCTL_DATRST);
 
329
        set_bit(&regs->mmcctl, MMCCTL_CMDRST);
 
330
        udelay(10);
 
331
 
 
332
        set_val(&regs->mmcclk, 0x0);
 
333
        set_val(&regs->mmctor, 0x1FFF);
 
334
        set_val(&regs->mmctod, 0xFFFF);
 
335
 
 
336
        /* Clear software reset */
 
337
        clear_bit(&regs->mmcctl, MMCCTL_DATRST);
 
338
        clear_bit(&regs->mmcctl, MMCCTL_CMDRST);
 
339
 
 
340
        udelay(10);
 
341
 
 
342
        /* Reset FIFO - Always use the maximum fifo threshold */
 
343
        set_val(&regs->mmcfifoctl, (MMCFIFOCTL_FIFOLEV | MMCFIFOCTL_FIFORST));
 
344
        set_val(&regs->mmcfifoctl, MMCFIFOCTL_FIFOLEV);
 
345
 
 
346
        return 0;
 
347
}
 
348
 
 
349
/* Set buswidth or clock as indicated by the GENERIC_MMC framework */
 
350
static void dmmc_set_ios(struct mmc *mmc)
 
351
{
 
352
        struct davinci_mmc *host = mmc->priv;
 
353
        struct davinci_mmc_regs *regs = host->reg_base;
 
354
 
 
355
        /* Set the bus width */
 
356
        if (mmc->bus_width == 4)
 
357
                set_bit(&regs->mmcctl, MMCCTL_WIDTH_4_BIT);
 
358
        else
 
359
                clear_bit(&regs->mmcctl, MMCCTL_WIDTH_4_BIT);
 
360
 
 
361
        /* Set clock speed */
 
362
        if (mmc->clock)
 
363
                dmmc_set_clock(mmc, mmc->clock);
 
364
}
 
365
 
 
366
static const struct mmc_ops dmmc_ops = {
 
367
        .send_cmd       = dmmc_send_cmd,
 
368
        .set_ios        = dmmc_set_ios,
 
369
        .init           = dmmc_init,
 
370
};
 
371
 
 
372
/* Called from board_mmc_init during startup. Can be called multiple times
 
373
 * depending on the number of slots available on board and controller
 
374
 */
 
375
int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)
 
376
{
 
377
        host->cfg.name = "davinci";
 
378
        host->cfg.ops = &dmmc_ops;
 
379
        host->cfg.f_min = 200000;
 
380
        host->cfg.f_max = 25000000;
 
381
        host->cfg.voltages = host->voltages;
 
382
        host->cfg.host_caps = host->host_caps;
 
383
 
 
384
        host->cfg.b_max = DAVINCI_MAX_BLOCKS;
 
385
 
 
386
        mmc_create(&host->cfg, host);
 
387
 
 
388
        return 0;
 
389
}