blob: b65030e7d8bc9526ced5acb85c354248b7e03800 [file] [log] [blame]
Sam Lewisdb3fbf22020-08-19 21:13:19 +10001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <inttypes.h>
4#include <string.h>
5#include <console/console.h>
6#include <commonlib/sd_mmc_ctrlr.h>
7#include <device/mmio.h>
8#include <timer.h>
9#include "mmc.h"
10
11#define AM335X_TIMEOUT_MSEC 1000
12
13#define SYSCONFIG_SOFTRESET (0x1 << 1)
14
15#define SYSSTATUS_RESETDONE (0x01 << 0)
16
17#define CON_INIT (0x1 << 1)
18
19#define CMD_INDEX(x) (x << 24)
20#define CMD_RSP_TYPE_NO_RESP (0x0 << 16)
21#define CMD_RSP_TYPE_136B (0x1 << 16)
22#define CMD_RSP_TYPE_48B (0x2 << 16)
23#define CMD_RSP_TYPE_48B_BUSY (0x3 << 16)
24#define CMD_DP_DATA (0x1 << 21)
25#define CMD_DDIR_READ (0x1 << 4)
26
27#define HCTL_DTW_1BIT (0x0 << 1)
28#define HCTL_SDBP (0x1 << 8)
29#define HCTL_SDVS_VS30 (0x6 << 9)
30
31#define SYSCTL_ICE (0x1 << 0)
32#define SYSCTL_ICS (0x1 << 1)
33#define SYSCTL_CEN (0x1 << 2)
34#define SYSCTL_DTO_15 (0xE << 16)
35
36#define STAT_ERRI (0x01 << 15)
37#define STAT_ERROR_MASK (0xff << 15 | 0x3 << 24 | 0x03 << 28)
38#define STAT_CC (0x1 << 0)
39
40#define IE_CC (0x1 << 0)
41#define IE_TC (0x1 << 1)
42#define IE_BRR (0x1 << 5)
43#define IE_ERRORS (0xff << 15 | 0x3 << 24 | 0x03 << 28)
44
45#define CAPA_VS18 (0x01 << 26)
46#define CAPA_VS30 (0x01 << 25)
47
48static int am335x_wait_for_reg(const void *addr, uint32_t mask, unsigned long timeout)
49{
50 struct mono_time current, end;
51
52 timer_monotonic_get(&current);
53 end = current;
54 mono_time_add_msecs(&end, timeout);
55
56 do {
57 if ((read32(addr) & mask))
58 return 0;
59
60 timer_monotonic_get(&current);
61 } while (!mono_time_after(&current, &end));
62
63 printk(BIOS_DEBUG, "am335x MMC timeout: %ld msec\n", timeout);
64 return -1;
65}
66
67static int am335x_mmc_init(struct am335x_mmc *mmc)
68{
69 // Follows the initialisiation from the AM335X technical reference manual
70 setbits32(&mmc->sysconfig, SYSCONFIG_SOFTRESET);
71
72 if (am335x_wait_for_reg(&mmc->sysstatus, SYSSTATUS_RESETDONE, AM335X_TIMEOUT_MSEC))
73 return -1;
74
75 setbits32(&mmc->capa, CAPA_VS30);
76 setbits32(&mmc->hctl, HCTL_SDVS_VS30 | HCTL_DTW_1BIT);
77 setbits32(&mmc->hctl, HCTL_SDBP);
78
79 if (am335x_wait_for_reg(&mmc->hctl, HCTL_SDBP, AM335X_TIMEOUT_MSEC))
80 return -1;
81
82 // Assumes the default input clock speed of 96MHz to set a minimum SD
83 // speed of 400 KHz
84 write32(&mmc->sysctl, read32(&mmc->sysctl) | 240 << 6 | SYSCTL_DTO_15);
85
86 setbits32(&mmc->sysctl, SYSCTL_ICE | SYSCTL_CEN);
87
88 if (am335x_wait_for_reg(&mmc->sysctl, SYSCTL_ICS, AM335X_TIMEOUT_MSEC))
89 return -1;
90
91 write32(&mmc->ie, IE_ERRORS | IE_TC | IE_CC);
92
93 // Clear interrupts
94 write32(&mmc->stat, 0xffffffffu);
95
96 setbits32(&mmc->con, CON_INIT);
97 write32(&mmc->cmd, 0x00);
98
99 if (am335x_wait_for_reg(&mmc->stat, STAT_CC, AM335X_TIMEOUT_MSEC))
100 return -1;
101
102 write32(&mmc->stat, 0xffffffffu);
103 clrbits32(&mmc->con, CON_INIT);
104
105 return 0;
106}
107
108static int am335x_send_cmd(struct sd_mmc_ctrlr *ctrlr, struct mmc_command *cmd,
109 struct mmc_data *data)
110{
111 struct am335x_mmc_host *mmc;
112 struct am335x_mmc *reg;
113
114 mmc = container_of(ctrlr, struct am335x_mmc_host, sd_mmc_ctrlr);
115 reg = mmc->reg;
116
117 if (read32(&reg->stat)) {
118 printk(BIOS_WARNING, "AM335X MMC: Interrupt already raised\n");
119 return 1;
120 }
121
122 uint32_t transfer_type = 0;
123
124 if (data) {
125 if (data->flags & DATA_FLAG_READ) {
126 setbits32(&mmc->reg->ie, IE_BRR);
127 write32(&mmc->reg->blk, data->blocksize);
128 transfer_type |= CMD_DP_DATA | CMD_DDIR_READ;
129 }
130
131 if (data->flags & DATA_FLAG_WRITE) {
132 printk(BIOS_ERR, "AM335X MMC: Writes currently not supported\n");
133 return 1;
134 }
135 }
136
137 switch (cmd->resp_type) {
138 case CARD_RSP_R1b:
139 transfer_type |= CMD_RSP_TYPE_48B_BUSY;
140 break;
141 case CARD_RSP_R1:
142 case CARD_RSP_R3:
143 transfer_type |= CMD_RSP_TYPE_48B;
144 break;
145 case CARD_RSP_R2:
146 transfer_type |= CMD_RSP_TYPE_136B;
147 break;
148 case CARD_RSP_NONE:
149 transfer_type |= CMD_RSP_TYPE_NO_RESP;
150 break;
151 default:
152 printk(BIOS_ERR, "AM335X MMC: Unknown response type\n");
153 return 1;
154 }
155
156 if (cmd->cmdidx == MMC_CMD_SET_BLOCKLEN) {
157 // todo: Support bigger blocks for faster transfers
158 return 0;
159 }
160
161 write32(&reg->arg, cmd->cmdarg);
162 write32(&reg->cmd, CMD_INDEX(cmd->cmdidx) | transfer_type);
163
164 // Wait for any interrupt
165 if (am335x_wait_for_reg(&reg->stat, 0xffffffff, AM335X_TIMEOUT_MSEC))
166 return -1;
167
168 // Check to ensure that there was not any errors
169 if (read32(&reg->stat) & STAT_ERRI) {
170 printk(BIOS_WARNING, "AM335X MMC: Error while reading %08x\n",
171 read32(&reg->stat));
172
173 // Clear the errors
174 write32(&reg->stat, STAT_ERROR_MASK);
175 return 1;
176 }
177
178 if (cmd->resp_type == CARD_RSP_R1b) {
179 if (am335x_wait_for_reg(&reg->stat, IE_TC, AM335X_TIMEOUT_MSEC))
180 return -1;
181
182 write32(&reg->stat, IE_TC);
183 }
184
185 write32(&reg->stat, IE_CC);
186
187 switch (cmd->resp_type) {
188 case CARD_RSP_R1:
189 case CARD_RSP_R1b:
190 case CARD_RSP_R3:
191 cmd->response[0] = read32(&reg->rsp10);
192 break;
193 case CARD_RSP_R2:
194 cmd->response[3] = read32(&reg->rsp10);
195 cmd->response[2] = read32(&reg->rsp32);
196 cmd->response[1] = read32(&reg->rsp54);
197 cmd->response[0] = read32(&reg->rsp76);
198 break;
199 case CARD_RSP_NONE:
200 break;
201 }
202
203 if (data != NULL && data->flags & DATA_FLAG_READ) {
204 if (am335x_wait_for_reg(&reg->stat, IE_BRR, AM335X_TIMEOUT_MSEC))
205 return -1;
206
207 uint32_t *dest32 = (uint32_t *)data->dest;
208
209 for (int count = 0; count < data->blocksize; count += 4) {
210 *dest32 = read32(&reg->data);
211 dest32++;
212 }
213
214 write32(&reg->stat, IE_TC);
215 write32(&reg->stat, IE_BRR);
216 clrbits32(&reg->ie, IE_BRR);
217 }
218
219 return 0;
220}
221
222static void set_ios(struct sd_mmc_ctrlr *ctrlr)
223{
224 struct am335x_mmc_host *mmc;
225 struct am335x_mmc *reg;
226
227 mmc = container_of(ctrlr, struct am335x_mmc_host, sd_mmc_ctrlr);
228 reg = mmc->reg;
229
230 if (ctrlr->request_hz != ctrlr->bus_hz) {
231 uint32_t requested_hz = ctrlr->request_hz;
232
233 requested_hz = MIN(requested_hz, ctrlr->f_min);
234 requested_hz = MAX(requested_hz, ctrlr->f_max);
235
236 uint32_t divisor = mmc->sd_clock_hz / requested_hz;
237 uint32_t actual = mmc->sd_clock_hz * divisor;
238
239 if (actual != ctrlr->bus_hz) {
240 clrbits32(&reg->sysctl, SYSCTL_CEN);
241
242 uint32_t new_sysctl = read32(&reg->sysctl);
243 new_sysctl &= ~(0x3ff << 6);
244 new_sysctl |= ((divisor & 0x3ff) << 6);
245
246 write32(&reg->sysctl, new_sysctl);
247
248 // Wait for clock stability
249 am335x_wait_for_reg(&reg->sysctl, SYSCTL_ICS, AM335X_TIMEOUT_MSEC);
250
251 setbits32(&reg->sysctl, SYSCTL_CEN);
252
253 ctrlr->bus_hz = mmc->sd_clock_hz / divisor;
254 }
255 }
256}
257
258int am335x_mmc_init_storage(struct am335x_mmc_host *mmc_host)
259{
260 int err = 0;
261
262 struct sd_mmc_ctrlr *mmc_ctrlr = &mmc_host->sd_mmc_ctrlr;
Angel Ponsda335ab2021-04-02 18:05:31 +0200263 memset(mmc_ctrlr, 0, sizeof(*mmc_ctrlr));
Sam Lewisdb3fbf22020-08-19 21:13:19 +1000264
265
266 err = am335x_mmc_init(mmc_host->reg);
267 if (err != 0) {
Julius Wernere9665952022-01-21 17:06:20 -0800268 printk(BIOS_ERR, "Initialising AM335X SD failed.\n");
Sam Lewisdb3fbf22020-08-19 21:13:19 +1000269 return err;
270 }
271
272 mmc_ctrlr->send_cmd = &am335x_send_cmd;
273 mmc_ctrlr->set_ios = &set_ios;
274
275 mmc_ctrlr->voltages = MMC_VDD_30_31;
276 mmc_ctrlr->b_max = 1;
277 mmc_ctrlr->bus_width = 1;
278 mmc_ctrlr->f_max = 48000000;
279 mmc_ctrlr->f_min = 400000;
280 mmc_ctrlr->bus_hz = 400000;
281
282 return 0;
283}