blob: e95742b35b5e549001c11764f2464ac512ef944a [file] [log] [blame]
Lee Leahyeef40eb2017-03-23 10:54:57 -07001/*
2 * Copyright 2011, Marvell Semiconductor Inc.
3 * Lei Wen <leiwen@marvell.com>
4 *
5 * Copyright 2017 Intel Corporation
6 *
7 * Secure Digital (SD) Host Controller interface DMA support code
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <assert.h>
Lee Leahy48dbc662017-05-08 16:56:03 -070021#include <commonlib/sdhci.h>
22#include <commonlib/storage.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070023#include <delay.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070024#include <endian.h>
25#include "sdhci.h"
26#include "sd_mmc.h"
27#include "storage.h"
28#include <string.h>
29#include <timer.h>
30
31static void sdhci_alloc_adma_descs(struct sdhci_ctrlr *sdhci_ctrlr,
32 u32 need_descriptors)
33{
34 if (sdhci_ctrlr->adma_descs) {
35 if (sdhci_ctrlr->adma_desc_count < need_descriptors) {
36 /* Previously allocated array is too small */
37 free(sdhci_ctrlr->adma_descs);
38 sdhci_ctrlr->adma_desc_count = 0;
39 sdhci_ctrlr->adma_descs = NULL;
40 }
41 }
42
43 /* use dma_malloc() to make sure we get the coherent/uncached memory */
44 if (!sdhci_ctrlr->adma_descs) {
45 sdhci_ctrlr->adma_descs = malloc(need_descriptors
46 * sizeof(*sdhci_ctrlr->adma_descs));
47 if (sdhci_ctrlr->adma_descs == NULL)
48 die("fail to malloc adma_descs\n");
49 sdhci_ctrlr->adma_desc_count = need_descriptors;
50 }
51
52 memset(sdhci_ctrlr->adma_descs, 0, sizeof(*sdhci_ctrlr->adma_descs)
53 * need_descriptors);
54}
55
56static void sdhci_alloc_adma64_descs(struct sdhci_ctrlr *sdhci_ctrlr,
57 u32 need_descriptors)
58{
59 if (sdhci_ctrlr->adma64_descs) {
60 if (sdhci_ctrlr->adma_desc_count < need_descriptors) {
61 /* Previously allocated array is too small */
62 free(sdhci_ctrlr->adma64_descs);
63 sdhci_ctrlr->adma_desc_count = 0;
64 sdhci_ctrlr->adma64_descs = NULL;
65 }
66 }
67
68 /* use dma_malloc() to make sure we get the coherent/uncached memory */
69 if (!sdhci_ctrlr->adma64_descs) {
70 sdhci_ctrlr->adma64_descs = malloc(need_descriptors
71 * sizeof(*sdhci_ctrlr->adma64_descs));
72 if (sdhci_ctrlr->adma64_descs == NULL)
73 die("fail to malloc adma64_descs\n");
74
75 sdhci_ctrlr->adma_desc_count = need_descriptors;
76 }
77
78 memset(sdhci_ctrlr->adma64_descs, 0, sizeof(*sdhci_ctrlr->adma64_descs)
79 * need_descriptors);
80}
81
82int sdhci_setup_adma(struct sdhci_ctrlr *sdhci_ctrlr, struct mmc_data *data)
83{
84 int i, togo, need_descriptors;
85 int dma64;
86 char *buffer_data;
87 u16 attributes;
88
89 togo = data->blocks * data->blocksize;
90 if (!togo) {
91 sdhc_error("%s: MmcData corrupted: %d blocks of %d bytes\n",
92 __func__, data->blocks, data->blocksize);
93 return -1;
94 }
95
96 need_descriptors = 1 + togo / SDHCI_MAX_PER_DESCRIPTOR;
97 dma64 = sdhci_ctrlr->sd_mmc_ctrlr.caps & DRVR_CAP_DMA_64BIT;
98 if (dma64)
99 sdhci_alloc_adma64_descs(sdhci_ctrlr, need_descriptors);
100 else
101 sdhci_alloc_adma_descs(sdhci_ctrlr, need_descriptors);
102 buffer_data = data->dest;
103
104 /* Now set up the descriptor chain. */
105 for (i = 0; togo; i++) {
106 unsigned int desc_length;
107
108 if (togo < SDHCI_MAX_PER_DESCRIPTOR)
109 desc_length = togo;
110 else
111 desc_length = SDHCI_MAX_PER_DESCRIPTOR;
112 togo -= desc_length;
113
114 attributes = SDHCI_ADMA_VALID | SDHCI_ACT_TRAN;
115 if (togo == 0)
116 attributes |= SDHCI_ADMA_END;
117
118 if (dma64) {
119 sdhci_ctrlr->adma64_descs[i].addr =
120 (uintptr_t)buffer_data;
121 sdhci_ctrlr->adma64_descs[i].addr_hi = 0;
122 sdhci_ctrlr->adma64_descs[i].length = desc_length;
123 sdhci_ctrlr->adma64_descs[i].attributes = attributes;
124
125 } else {
126 sdhci_ctrlr->adma_descs[i].addr =
127 (uintptr_t)buffer_data;
128 sdhci_ctrlr->adma_descs[i].length = desc_length;
129 sdhci_ctrlr->adma_descs[i].attributes = attributes;
130 }
131
132 buffer_data += desc_length;
133 }
134
135 if (dma64)
136 sdhci_writel(sdhci_ctrlr, (uintptr_t) sdhci_ctrlr->adma64_descs,
137 SDHCI_ADMA_ADDRESS);
138 else
139 sdhci_writel(sdhci_ctrlr, (uintptr_t) sdhci_ctrlr->adma_descs,
140 SDHCI_ADMA_ADDRESS);
141
142 return 0;
143}
144
145int sdhci_complete_adma(struct sdhci_ctrlr *sdhci_ctrlr,
146 struct mmc_command *cmd)
147{
148 int retry;
149 u32 stat = 0, mask;
150
151 mask = SDHCI_INT_RESPONSE | SDHCI_INT_ERROR;
152
153 retry = 10000; /* Command should be done in way less than 10 ms. */
154 while (--retry) {
155 stat = sdhci_readl(sdhci_ctrlr, SDHCI_INT_STATUS);
156 if (stat & mask)
157 break;
158 udelay(1);
159 }
160
161 sdhci_writel(sdhci_ctrlr, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
162
163 if (retry && !(stat & SDHCI_INT_ERROR)) {
164 /* Command OK, let's wait for data transfer completion. */
165 mask = SDHCI_INT_DATA_END |
166 SDHCI_INT_ERROR | SDHCI_INT_ADMA_ERROR;
167
168 /* Transfer should take 10 seconds tops. */
169 retry = 10 * 1000 * 1000;
170 while (--retry) {
171 stat = sdhci_readl(sdhci_ctrlr, SDHCI_INT_STATUS);
172 if (stat & mask)
173 break;
174 udelay(1);
175 }
176
177 sdhci_writel(sdhci_ctrlr, stat, SDHCI_INT_STATUS);
178 if (retry && !(stat & SDHCI_INT_ERROR)) {
179 sdhci_cmd_done(sdhci_ctrlr, cmd);
180 return 0;
181 }
182 }
183
184 sdhc_error("%s: transfer error, stat %#x, adma error %#x, retry %d\n",
185 __func__, stat, sdhci_readl(sdhci_ctrlr, SDHCI_ADMA_ERROR),
186 retry);
187
188 sdhci_reset(sdhci_ctrlr, SDHCI_RESET_CMD);
189 sdhci_reset(sdhci_ctrlr, SDHCI_RESET_DATA);
190
191 if (stat & SDHCI_INT_TIMEOUT)
192 return CARD_TIMEOUT;
193 return CARD_COMM_ERR;
194}