1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <commonlib/sd_mmc_ctrlr.h>
6 #include <device/mmio.h>
10 #define AM335X_TIMEOUT_MSEC 1000
12 #define SYSCONFIG_SOFTRESET (0x1 << 1)
14 #define SYSSTATUS_RESETDONE (0x01 << 0)
16 #define CON_INIT (0x1 << 1)
18 #define CMD_INDEX(x) (x << 24)
19 #define CMD_RSP_TYPE_NO_RESP (0x0 << 16)
20 #define CMD_RSP_TYPE_136B (0x1 << 16)
21 #define CMD_RSP_TYPE_48B (0x2 << 16)
22 #define CMD_RSP_TYPE_48B_BUSY (0x3 << 16)
23 #define CMD_DP_DATA (0x1 << 21)
24 #define CMD_DDIR_READ (0x1 << 4)
26 #define HCTL_DTW_1BIT (0x0 << 1)
27 #define HCTL_SDBP (0x1 << 8)
28 #define HCTL_SDVS_VS30 (0x6 << 9)
30 #define SYSCTL_ICE (0x1 << 0)
31 #define SYSCTL_ICS (0x1 << 1)
32 #define SYSCTL_CEN (0x1 << 2)
33 #define SYSCTL_DTO_15 (0xE << 16)
35 #define STAT_ERRI (0x01 << 15)
36 #define STAT_ERROR_MASK (0xff << 15 | 0x3 << 24 | 0x03 << 28)
37 #define STAT_CC (0x1 << 0)
39 #define IE_CC (0x1 << 0)
40 #define IE_TC (0x1 << 1)
41 #define IE_BRR (0x1 << 5)
42 #define IE_ERRORS (0xff << 15 | 0x3 << 24 | 0x03 << 28)
44 #define CAPA_VS18 (0x01 << 26)
45 #define CAPA_VS30 (0x01 << 25)
47 static int am335x_wait_for_reg(const void *addr
, uint32_t mask
, unsigned long timeout
)
49 struct mono_time current
, end
;
51 timer_monotonic_get(¤t
);
53 mono_time_add_msecs(&end
, timeout
);
56 if ((read32(addr
) & mask
))
59 timer_monotonic_get(¤t
);
60 } while (!mono_time_after(¤t
, &end
));
62 printk(BIOS_DEBUG
, "am335x MMC timeout: %ld msec\n", timeout
);
66 static int am335x_mmc_init(struct am335x_mmc
*mmc
)
68 // Follows the initialisiation from the AM335X technical reference manual
69 setbits32(&mmc
->sysconfig
, SYSCONFIG_SOFTRESET
);
71 if (am335x_wait_for_reg(&mmc
->sysstatus
, SYSSTATUS_RESETDONE
, AM335X_TIMEOUT_MSEC
))
74 setbits32(&mmc
->capa
, CAPA_VS30
);
75 setbits32(&mmc
->hctl
, HCTL_SDVS_VS30
| HCTL_DTW_1BIT
);
76 setbits32(&mmc
->hctl
, HCTL_SDBP
);
78 if (am335x_wait_for_reg(&mmc
->hctl
, HCTL_SDBP
, AM335X_TIMEOUT_MSEC
))
81 // Assumes the default input clock speed of 96MHz to set a minimum SD
83 write32(&mmc
->sysctl
, read32(&mmc
->sysctl
) | 240 << 6 | SYSCTL_DTO_15
);
85 setbits32(&mmc
->sysctl
, SYSCTL_ICE
| SYSCTL_CEN
);
87 if (am335x_wait_for_reg(&mmc
->sysctl
, SYSCTL_ICS
, AM335X_TIMEOUT_MSEC
))
90 write32(&mmc
->ie
, IE_ERRORS
| IE_TC
| IE_CC
);
93 write32(&mmc
->stat
, 0xffffffffu
);
95 setbits32(&mmc
->con
, CON_INIT
);
96 write32(&mmc
->cmd
, 0x00);
98 if (am335x_wait_for_reg(&mmc
->stat
, STAT_CC
, AM335X_TIMEOUT_MSEC
))
101 write32(&mmc
->stat
, 0xffffffffu
);
102 clrbits32(&mmc
->con
, CON_INIT
);
107 static int am335x_send_cmd(struct sd_mmc_ctrlr
*ctrlr
, struct mmc_command
*cmd
,
108 struct mmc_data
*data
)
110 struct am335x_mmc_host
*mmc
;
111 struct am335x_mmc
*reg
;
113 mmc
= container_of(ctrlr
, struct am335x_mmc_host
, sd_mmc_ctrlr
);
116 if (read32(®
->stat
)) {
117 printk(BIOS_WARNING
, "AM335X MMC: Interrupt already raised\n");
121 uint32_t transfer_type
= 0;
124 if (data
->flags
& DATA_FLAG_READ
) {
125 setbits32(&mmc
->reg
->ie
, IE_BRR
);
126 write32(&mmc
->reg
->blk
, data
->blocksize
);
127 transfer_type
|= CMD_DP_DATA
| CMD_DDIR_READ
;
130 if (data
->flags
& DATA_FLAG_WRITE
) {
131 printk(BIOS_ERR
, "AM335X MMC: Writes currently not supported\n");
136 switch (cmd
->resp_type
) {
138 transfer_type
|= CMD_RSP_TYPE_48B_BUSY
;
142 transfer_type
|= CMD_RSP_TYPE_48B
;
145 transfer_type
|= CMD_RSP_TYPE_136B
;
148 transfer_type
|= CMD_RSP_TYPE_NO_RESP
;
151 printk(BIOS_ERR
, "AM335X MMC: Unknown response type\n");
155 if (cmd
->cmdidx
== MMC_CMD_SET_BLOCKLEN
) {
156 // todo: Support bigger blocks for faster transfers
160 write32(®
->arg
, cmd
->cmdarg
);
161 write32(®
->cmd
, CMD_INDEX(cmd
->cmdidx
) | transfer_type
);
163 // Wait for any interrupt
164 if (am335x_wait_for_reg(®
->stat
, 0xffffffff, AM335X_TIMEOUT_MSEC
))
167 // Check to ensure that there was not any errors
168 if (read32(®
->stat
) & STAT_ERRI
) {
169 printk(BIOS_WARNING
, "AM335X MMC: Error while reading %08x\n",
173 write32(®
->stat
, STAT_ERROR_MASK
);
177 if (cmd
->resp_type
== CARD_RSP_R1b
) {
178 if (am335x_wait_for_reg(®
->stat
, IE_TC
, AM335X_TIMEOUT_MSEC
))
181 write32(®
->stat
, IE_TC
);
184 write32(®
->stat
, IE_CC
);
186 switch (cmd
->resp_type
) {
190 cmd
->response
[0] = read32(®
->rsp10
);
193 cmd
->response
[3] = read32(®
->rsp10
);
194 cmd
->response
[2] = read32(®
->rsp32
);
195 cmd
->response
[1] = read32(®
->rsp54
);
196 cmd
->response
[0] = read32(®
->rsp76
);
202 if (data
!= NULL
&& data
->flags
& DATA_FLAG_READ
) {
203 if (am335x_wait_for_reg(®
->stat
, IE_BRR
, AM335X_TIMEOUT_MSEC
))
206 uint32_t *dest32
= (uint32_t *)data
->dest
;
208 for (int count
= 0; count
< data
->blocksize
; count
+= 4) {
209 *dest32
= read32(®
->data
);
213 write32(®
->stat
, IE_TC
);
214 write32(®
->stat
, IE_BRR
);
215 clrbits32(®
->ie
, IE_BRR
);
221 static void set_ios(struct sd_mmc_ctrlr
*ctrlr
)
223 struct am335x_mmc_host
*mmc
;
224 struct am335x_mmc
*reg
;
226 mmc
= container_of(ctrlr
, struct am335x_mmc_host
, sd_mmc_ctrlr
);
229 if (ctrlr
->request_hz
!= ctrlr
->bus_hz
) {
230 uint32_t requested_hz
= ctrlr
->request_hz
;
232 requested_hz
= MIN(requested_hz
, ctrlr
->f_min
);
233 requested_hz
= MAX(requested_hz
, ctrlr
->f_max
);
235 uint32_t divisor
= mmc
->sd_clock_hz
/ requested_hz
;
236 uint32_t actual
= mmc
->sd_clock_hz
* divisor
;
238 if (actual
!= ctrlr
->bus_hz
) {
239 clrbits32(®
->sysctl
, SYSCTL_CEN
);
241 uint32_t new_sysctl
= read32(®
->sysctl
);
242 new_sysctl
&= ~(0x3ff << 6);
243 new_sysctl
|= ((divisor
& 0x3ff) << 6);
245 write32(®
->sysctl
, new_sysctl
);
247 // Wait for clock stability
248 am335x_wait_for_reg(®
->sysctl
, SYSCTL_ICS
, AM335X_TIMEOUT_MSEC
);
250 setbits32(®
->sysctl
, SYSCTL_CEN
);
252 ctrlr
->bus_hz
= mmc
->sd_clock_hz
/ divisor
;
257 int am335x_mmc_init_storage(struct am335x_mmc_host
*mmc_host
)
261 struct sd_mmc_ctrlr
*mmc_ctrlr
= &mmc_host
->sd_mmc_ctrlr
;
262 memset(mmc_ctrlr
, 0, sizeof(*mmc_ctrlr
));
265 err
= am335x_mmc_init(mmc_host
->reg
);
267 printk(BIOS_ERR
, "Initialising AM335X SD failed.\n");
271 mmc_ctrlr
->send_cmd
= &am335x_send_cmd
;
272 mmc_ctrlr
->set_ios
= &set_ios
;
274 mmc_ctrlr
->voltages
= MMC_VDD_30_31
;
275 mmc_ctrlr
->b_max
= 1;
276 mmc_ctrlr
->bus_width
= 1;
277 mmc_ctrlr
->f_max
= 48000000;
278 mmc_ctrlr
->f_min
= 400000;
279 mmc_ctrlr
->bus_hz
= 400000;