mb/system76/cml-u/dt: Make use of chipset devicetree
[coreboot.git] / src / soc / ti / am335x / mmc.c
blob577434c0bac5db1e2e2e25d0dc249808923b5e65
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <string.h>
4 #include <console/console.h>
5 #include <commonlib/sd_mmc_ctrlr.h>
6 #include <device/mmio.h>
7 #include <timer.h>
8 #include "mmc.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(&current);
52 end = current;
53 mono_time_add_msecs(&end, timeout);
55 do {
56 if ((read32(addr) & mask))
57 return 0;
59 timer_monotonic_get(&current);
60 } while (!mono_time_after(&current, &end));
62 printk(BIOS_DEBUG, "am335x MMC timeout: %ld msec\n", timeout);
63 return -1;
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))
72 return -1;
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))
79 return -1;
81 // Assumes the default input clock speed of 96MHz to set a minimum SD
82 // speed of 400 KHz
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))
88 return -1;
90 write32(&mmc->ie, IE_ERRORS | IE_TC | IE_CC);
92 // Clear interrupts
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))
99 return -1;
101 write32(&mmc->stat, 0xffffffffu);
102 clrbits32(&mmc->con, CON_INIT);
104 return 0;
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);
114 reg = mmc->reg;
116 if (read32(&reg->stat)) {
117 printk(BIOS_WARNING, "AM335X MMC: Interrupt already raised\n");
118 return 1;
121 uint32_t transfer_type = 0;
123 if (data) {
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");
132 return 1;
136 switch (cmd->resp_type) {
137 case CARD_RSP_R1b:
138 transfer_type |= CMD_RSP_TYPE_48B_BUSY;
139 break;
140 case CARD_RSP_R1:
141 case CARD_RSP_R3:
142 transfer_type |= CMD_RSP_TYPE_48B;
143 break;
144 case CARD_RSP_R2:
145 transfer_type |= CMD_RSP_TYPE_136B;
146 break;
147 case CARD_RSP_NONE:
148 transfer_type |= CMD_RSP_TYPE_NO_RESP;
149 break;
150 default:
151 printk(BIOS_ERR, "AM335X MMC: Unknown response type\n");
152 return 1;
155 if (cmd->cmdidx == MMC_CMD_SET_BLOCKLEN) {
156 // todo: Support bigger blocks for faster transfers
157 return 0;
160 write32(&reg->arg, cmd->cmdarg);
161 write32(&reg->cmd, CMD_INDEX(cmd->cmdidx) | transfer_type);
163 // Wait for any interrupt
164 if (am335x_wait_for_reg(&reg->stat, 0xffffffff, AM335X_TIMEOUT_MSEC))
165 return -1;
167 // Check to ensure that there was not any errors
168 if (read32(&reg->stat) & STAT_ERRI) {
169 printk(BIOS_WARNING, "AM335X MMC: Error while reading %08x\n",
170 read32(&reg->stat));
172 // Clear the errors
173 write32(&reg->stat, STAT_ERROR_MASK);
174 return 1;
177 if (cmd->resp_type == CARD_RSP_R1b) {
178 if (am335x_wait_for_reg(&reg->stat, IE_TC, AM335X_TIMEOUT_MSEC))
179 return -1;
181 write32(&reg->stat, IE_TC);
184 write32(&reg->stat, IE_CC);
186 switch (cmd->resp_type) {
187 case CARD_RSP_R1:
188 case CARD_RSP_R1b:
189 case CARD_RSP_R3:
190 cmd->response[0] = read32(&reg->rsp10);
191 break;
192 case CARD_RSP_R2:
193 cmd->response[3] = read32(&reg->rsp10);
194 cmd->response[2] = read32(&reg->rsp32);
195 cmd->response[1] = read32(&reg->rsp54);
196 cmd->response[0] = read32(&reg->rsp76);
197 break;
198 case CARD_RSP_NONE:
199 break;
202 if (data != NULL && data->flags & DATA_FLAG_READ) {
203 if (am335x_wait_for_reg(&reg->stat, IE_BRR, AM335X_TIMEOUT_MSEC))
204 return -1;
206 uint32_t *dest32 = (uint32_t *)data->dest;
208 for (int count = 0; count < data->blocksize; count += 4) {
209 *dest32 = read32(&reg->data);
210 dest32++;
213 write32(&reg->stat, IE_TC);
214 write32(&reg->stat, IE_BRR);
215 clrbits32(&reg->ie, IE_BRR);
218 return 0;
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);
227 reg = mmc->reg;
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(&reg->sysctl, SYSCTL_CEN);
241 uint32_t new_sysctl = read32(&reg->sysctl);
242 new_sysctl &= ~(0x3ff << 6);
243 new_sysctl |= ((divisor & 0x3ff) << 6);
245 write32(&reg->sysctl, new_sysctl);
247 // Wait for clock stability
248 am335x_wait_for_reg(&reg->sysctl, SYSCTL_ICS, AM335X_TIMEOUT_MSEC);
250 setbits32(&reg->sysctl, SYSCTL_CEN);
252 ctrlr->bus_hz = mmc->sd_clock_hz / divisor;
257 int am335x_mmc_init_storage(struct am335x_mmc_host *mmc_host)
259 int err = 0;
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);
266 if (err != 0) {
267 printk(BIOS_ERR, "Initialising AM335X SD failed.\n");
268 return err;
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;
281 return 0;