xref: /aosp_15_r20/external/coreboot/src/soc/ti/am335x/mmc.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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"
9 
10 #define AM335X_TIMEOUT_MSEC 1000
11 
12 #define SYSCONFIG_SOFTRESET (0x1 << 1)
13 
14 #define SYSSTATUS_RESETDONE (0x01 << 0)
15 
16 #define CON_INIT (0x1 << 1)
17 
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)
25 
26 #define HCTL_DTW_1BIT (0x0 << 1)
27 #define HCTL_SDBP (0x1 << 8)
28 #define HCTL_SDVS_VS30 (0x6 << 9)
29 
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)
34 
35 #define STAT_ERRI (0x01 << 15)
36 #define STAT_ERROR_MASK (0xff << 15 | 0x3 << 24 | 0x03 << 28)
37 #define STAT_CC (0x1 << 0)
38 
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)
43 
44 #define CAPA_VS18 (0x01 << 26)
45 #define CAPA_VS30 (0x01 << 25)
46 
am335x_wait_for_reg(const void * addr,uint32_t mask,unsigned long timeout)47 static int am335x_wait_for_reg(const void *addr, uint32_t mask, unsigned long timeout)
48 {
49 	struct mono_time current, end;
50 
51 	timer_monotonic_get(&current);
52 	end = current;
53 	mono_time_add_msecs(&end, timeout);
54 
55 	do {
56 		if ((read32(addr) & mask))
57 			return 0;
58 
59 		timer_monotonic_get(&current);
60 	} while (!mono_time_after(&current, &end));
61 
62 	printk(BIOS_DEBUG, "am335x MMC timeout: %ld msec\n", timeout);
63 	return -1;
64 }
65 
am335x_mmc_init(struct am335x_mmc * mmc)66 static int am335x_mmc_init(struct am335x_mmc *mmc)
67 {
68 	// Follows the initialisiation from the AM335X technical reference manual
69 	setbits32(&mmc->sysconfig, SYSCONFIG_SOFTRESET);
70 
71 	if (am335x_wait_for_reg(&mmc->sysstatus, SYSSTATUS_RESETDONE, AM335X_TIMEOUT_MSEC))
72 		return -1;
73 
74 	setbits32(&mmc->capa, CAPA_VS30);
75 	setbits32(&mmc->hctl, HCTL_SDVS_VS30 | HCTL_DTW_1BIT);
76 	setbits32(&mmc->hctl, HCTL_SDBP);
77 
78 	if (am335x_wait_for_reg(&mmc->hctl, HCTL_SDBP, AM335X_TIMEOUT_MSEC))
79 		return -1;
80 
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);
84 
85 	setbits32(&mmc->sysctl, SYSCTL_ICE | SYSCTL_CEN);
86 
87 	if (am335x_wait_for_reg(&mmc->sysctl, SYSCTL_ICS, AM335X_TIMEOUT_MSEC))
88 		return -1;
89 
90 	write32(&mmc->ie, IE_ERRORS | IE_TC | IE_CC);
91 
92 	// Clear interrupts
93 	write32(&mmc->stat, 0xffffffffu);
94 
95 	setbits32(&mmc->con, CON_INIT);
96 	write32(&mmc->cmd, 0x00);
97 
98 	if (am335x_wait_for_reg(&mmc->stat, STAT_CC, AM335X_TIMEOUT_MSEC))
99 		return -1;
100 
101 	write32(&mmc->stat, 0xffffffffu);
102 	clrbits32(&mmc->con, CON_INIT);
103 
104 	return 0;
105 }
106 
am335x_send_cmd(struct sd_mmc_ctrlr * ctrlr,struct mmc_command * cmd,struct mmc_data * data)107 static int am335x_send_cmd(struct sd_mmc_ctrlr *ctrlr, struct mmc_command *cmd,
108 			   struct mmc_data *data)
109 {
110 	struct am335x_mmc_host *mmc;
111 	struct am335x_mmc *reg;
112 
113 	mmc = container_of(ctrlr, struct am335x_mmc_host, sd_mmc_ctrlr);
114 	reg = mmc->reg;
115 
116 	if (read32(&reg->stat)) {
117 		printk(BIOS_WARNING, "AM335X MMC: Interrupt already raised\n");
118 		return 1;
119 	}
120 
121 	uint32_t transfer_type = 0;
122 
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;
128 		}
129 
130 		if (data->flags & DATA_FLAG_WRITE) {
131 			printk(BIOS_ERR, "AM335X MMC: Writes currently not supported\n");
132 			return 1;
133 		}
134 	}
135 
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;
153 	}
154 
155 	if (cmd->cmdidx == MMC_CMD_SET_BLOCKLEN) {
156 		// todo: Support bigger blocks for faster transfers
157 		return 0;
158 	}
159 
160 	write32(&reg->arg, cmd->cmdarg);
161 	write32(&reg->cmd, CMD_INDEX(cmd->cmdidx) | transfer_type);
162 
163 	// Wait for any interrupt
164 	if (am335x_wait_for_reg(&reg->stat, 0xffffffff, AM335X_TIMEOUT_MSEC))
165 		return -1;
166 
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));
171 
172 		// Clear the errors
173 		write32(&reg->stat, STAT_ERROR_MASK);
174 		return 1;
175 	}
176 
177 	if (cmd->resp_type == CARD_RSP_R1b) {
178 		if (am335x_wait_for_reg(&reg->stat, IE_TC, AM335X_TIMEOUT_MSEC))
179 			return -1;
180 
181 		write32(&reg->stat, IE_TC);
182 	}
183 
184 	write32(&reg->stat, IE_CC);
185 
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;
200 	}
201 
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;
205 
206 		uint32_t *dest32 = (uint32_t *)data->dest;
207 
208 		for (int count = 0; count < data->blocksize; count += 4) {
209 			*dest32 = read32(&reg->data);
210 			dest32++;
211 		}
212 
213 		write32(&reg->stat, IE_TC);
214 		write32(&reg->stat, IE_BRR);
215 		clrbits32(&reg->ie, IE_BRR);
216 	}
217 
218 	return 0;
219 }
220 
set_ios(struct sd_mmc_ctrlr * ctrlr)221 static void set_ios(struct sd_mmc_ctrlr *ctrlr)
222 {
223 	struct am335x_mmc_host *mmc;
224 	struct am335x_mmc *reg;
225 
226 	mmc = container_of(ctrlr, struct am335x_mmc_host, sd_mmc_ctrlr);
227 	reg = mmc->reg;
228 
229 	if (ctrlr->request_hz != ctrlr->bus_hz) {
230 		uint32_t requested_hz = ctrlr->request_hz;
231 
232 		requested_hz = MIN(requested_hz, ctrlr->f_min);
233 		requested_hz = MAX(requested_hz, ctrlr->f_max);
234 
235 		uint32_t divisor = mmc->sd_clock_hz / requested_hz;
236 		uint32_t actual = mmc->sd_clock_hz * divisor;
237 
238 		if (actual != ctrlr->bus_hz) {
239 			clrbits32(&reg->sysctl, SYSCTL_CEN);
240 
241 			uint32_t new_sysctl = read32(&reg->sysctl);
242 			new_sysctl &= ~(0x3ff << 6);
243 			new_sysctl |= ((divisor & 0x3ff) << 6);
244 
245 			write32(&reg->sysctl, new_sysctl);
246 
247 			// Wait for clock stability
248 			am335x_wait_for_reg(&reg->sysctl, SYSCTL_ICS, AM335X_TIMEOUT_MSEC);
249 
250 			setbits32(&reg->sysctl, SYSCTL_CEN);
251 
252 			ctrlr->bus_hz = mmc->sd_clock_hz / divisor;
253 		}
254 	}
255 }
256 
am335x_mmc_init_storage(struct am335x_mmc_host * mmc_host)257 int am335x_mmc_init_storage(struct am335x_mmc_host *mmc_host)
258 {
259 	int err = 0;
260 
261 	struct sd_mmc_ctrlr *mmc_ctrlr = &mmc_host->sd_mmc_ctrlr;
262 	memset(mmc_ctrlr, 0, sizeof(*mmc_ctrlr));
263 
264 
265 	err = am335x_mmc_init(mmc_host->reg);
266 	if (err != 0) {
267 		printk(BIOS_ERR, "Initialising AM335X SD failed.\n");
268 		return err;
269 	}
270 
271 	mmc_ctrlr->send_cmd = &am335x_send_cmd;
272 	mmc_ctrlr->set_ios = &set_ios;
273 
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;
280 
281 	return 0;
282 }
283