mb/system76/cml-u/dt: Make use of chipset devicetree
[coreboot.git] / src / soc / mediatek / common / msdc.c
blobdf59b0ee377c674ded1ca53bb76aebf4f00e5b70
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * MTK MSDC Host Controller interface specific code
4 */
5 #include <assert.h>
6 #include <commonlib/bsd/helpers.h>
7 #include <commonlib/storage/sd_mmc.h>
8 #include <delay.h>
9 #include <device/mmio.h>
10 #include <lib.h>
11 #include <soc/msdc.h>
12 #include <string.h>
13 #include <timer.h>
15 static inline void msdc_set_field(void *reg, u32 field, u32 val)
17 clrsetbits32(reg, field, val << __ffs(field));
21 * Periodically poll an address until a condition is met or a timeout occurs
22 * @addr: Address to poll
23 * @mask: mask condition
24 * @timeout: Timeout in us, 0 means never timeout
26 * Returns 0 on success and -MSDC_NOT_READY upon a timeout.
28 static int msdc_poll_timeout(void *addr, u32 mask)
30 struct stopwatch timer;
31 stopwatch_init_usecs_expire(&timer, MSDC_TIMEOUT_US);
32 u32 reg;
34 do {
35 reg = read32(addr);
36 if (stopwatch_expired(&timer))
37 return -MSDC_NOT_READY;
38 udelay(1);
39 } while (reg & mask);
41 return MSDC_SUCCESS;
45 * Wait for a bit mask in a given register. To avoid endless loops, a
46 * time-out is implemented here.
48 static int msdc_wait_done(void *addr, u32 mask, u32 *status)
50 struct stopwatch timer;
51 stopwatch_init_usecs_expire(&timer, CMD_TIMEOUT_MS);
52 u32 reg;
54 do {
55 reg = read32(addr);
56 if (stopwatch_expired(&timer)) {
57 if (status)
58 *status = reg;
59 return -MSDC_NOT_READY;
61 udelay(1);
62 } while (!(reg & mask));
64 if (status)
65 *status = reg;
67 return MSDC_SUCCESS;
70 static void msdc_reset_hw(struct msdc_ctrlr *host)
72 u32 val;
74 setbits32(host->base + MSDC_CFG, MSDC_CFG_RST);
75 if (msdc_poll_timeout(host->base + MSDC_CFG, MSDC_CFG_RST) != MSDC_SUCCESS)
76 msdc_error("Softwave reset timeout!\n");
78 setbits32(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
79 if (msdc_poll_timeout(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR) != MSDC_SUCCESS)
80 msdc_error("Clear FIFO timeout!\n");
82 val = read32(host->base + MSDC_INT);
83 write32(host->base + MSDC_INT, val);
86 static void msdc_init_hw(struct msdc_ctrlr *host)
88 /* Configure to MMC/SD mode */
89 setbits32(host->base + MSDC_CFG, MSDC_CFG_MODE);
91 /* Reset */
92 msdc_reset_hw(host);
94 /* Set PIO mode */
95 setbits32(host->base + MSDC_CFG, MSDC_CFG_PIO);
97 write32(host->top_base + EMMC_TOP_CONTROL, 0);
98 write32(host->top_base + EMMC_TOP_CMD, 0);
100 write32(host->base + MSDC_IOCON, 0);
101 clrbits32(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL);
102 write32(host->base + MSDC_PATCH_BIT, 0x403c0046);
103 msdc_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
104 write32(host->base + MSDC_PATCH_BIT1, 0xffff4089);
105 setbits32(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
107 msdc_set_field(host->base + MSDC_PATCH_BIT1,
108 MSDC_PATCH_BIT1_STOP_DLY, 3);
109 clrbits32(host->base + SDC_FIFO_CFG, SDC_FIFO_CFG_WRVALIDSEL);
110 clrbits32(host->base + SDC_FIFO_CFG, SDC_FIFO_CFG_RDVALIDSEL);
112 clrbits32(host->base + MSDC_PATCH_BIT1, (1 << 7));
114 msdc_set_field(host->base + MSDC_PATCH_BIT2, MSDC_PB2_RESPWAIT, 3);
115 if (host->top_base)
116 setbits32(host->top_base + EMMC_TOP_CONTROL, SDC_RX_ENH_EN);
117 else
118 setbits32(host->base + SDC_ADV_CFG0, SDC_RX_ENHANCE_EN);
119 /* Use async fifo, then no need to tune internal delay */
120 clrbits32(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGRESP);
121 setbits32(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS);
123 if (host->top_base) {
124 setbits32(host->top_base + EMMC_TOP_CONTROL,
125 PAD_DAT_RD_RXDLY_SEL);
126 clrbits32(host->top_base + EMMC_TOP_CONTROL, DATA_K_VALUE_SEL);
127 setbits32(host->top_base + EMMC_TOP_CMD, PAD_CMD_RD_RXDLY_SEL);
128 } else {
129 setbits32(host->base + MSDC_PAD_TUNE,
130 MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
133 /* Configure to enable SDIO mode. Otherwise, sdio cmd5 will fail. */
134 setbits32(host->base + SDC_CFG, SDC_CFG_SDIO);
136 /* Config SDIO device detect interrupt function */
137 clrbits32(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
138 setbits32(host->base + SDC_ADV_CFG0, SDC_DAT1_IRQ_TRIGGER);
140 /* Configure to default data timeout */
141 msdc_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
143 msdc_debug("init hardware done!\n");
146 static void msdc_fifo_clr(struct msdc_ctrlr *host)
148 setbits32(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
150 if (msdc_poll_timeout(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR) != MSDC_SUCCESS)
151 msdc_error("Clear FIFO timeout!\n");
154 static u32 msdc_cmd_find_resp(struct msdc_ctrlr *host, struct mmc_command *cmd)
156 switch (cmd->resp_type) {
157 case CARD_RSP_R1:
158 return 0x1;
159 case CARD_RSP_R1b:
160 return 0x7;
161 case CARD_RSP_R2:
162 return 0x2;
163 case CARD_RSP_R3:
164 return 0x3;
165 case CARD_RSP_NONE:
166 default:
167 return 0x0;
171 static bool msdc_cmd_is_ready(struct msdc_ctrlr *host)
173 int ret;
175 ret = msdc_poll_timeout(host->base + SDC_STS, SDC_STS_CMDBUSY);
176 if (ret != MSDC_SUCCESS) {
177 msdc_error("CMD bus busy detected, SDC_STS: %#x\n",
178 read32(host->base + SDC_STS));
179 msdc_reset_hw(host);
180 return false;
183 ret = msdc_poll_timeout(host->base + SDC_STS, SDC_STS_SDCBUSY);
184 if (ret != MSDC_SUCCESS) {
185 msdc_error("SD controller busy detected, SDC_STS: %#x\n",
186 read32(host->base + SDC_STS));
187 msdc_reset_hw(host);
188 return false;
191 return true;
194 static u32 msdc_cmd_prepare_raw_cmd(struct msdc_ctrlr *host,
195 struct mmc_command *cmd,
196 struct mmc_data *data)
198 u32 opcode = cmd->cmdidx;
199 u32 resp_type = msdc_cmd_find_resp(host, cmd);
200 u32 blocksize = 0;
201 u32 dtype = 0;
202 u32 rawcmd = 0;
204 switch (opcode) {
205 case MMC_CMD_WRITE_MULTIPLE_BLOCK:
206 case MMC_CMD_READ_MULTIPLE_BLOCK:
207 dtype = 2;
208 break;
209 case MMC_CMD_WRITE_SINGLE_BLOCK:
210 case MMC_CMD_READ_SINGLE_BLOCK:
211 case MMC_CMD_AUTO_TUNING_SEQUENCE:
212 dtype = 1;
213 break;
214 case MMC_CMD_SEND_STATUS:
215 if (data)
216 dtype = 1;
219 if (data) {
220 if (data->flags == DATA_FLAG_READ)
221 rawcmd |= SDC_CMD_WR;
223 if (data->blocks > 1)
224 dtype = 2;
226 blocksize = data->blocksize;
229 rawcmd |= (opcode << SDC_CMD_CMD_S) & SDC_CMD_CMD_M;
230 rawcmd |= (resp_type << SDC_CMD_RSPTYP_S) & SDC_CMD_RSPTYP_M;
231 rawcmd |= (blocksize << SDC_CMD_BLK_LEN_S) & SDC_CMD_BLK_LEN_M;
232 rawcmd |= (dtype << SDC_CMD_DTYPE_S) & SDC_CMD_DTYPE_M;
234 if (opcode == MMC_CMD_STOP_TRANSMISSION)
235 rawcmd |= SDC_CMD_STOP;
237 return rawcmd;
240 static int msdc_cmd_done(struct msdc_ctrlr *host, int events,
241 struct mmc_command *cmd)
243 u32 *rsp = cmd->response;
244 int ret = 0;
246 if (cmd->resp_type & CARD_RSP_PRESENT) {
247 if (cmd->resp_type & CARD_RSP_136) {
248 rsp[0] = read32(host->base + SDC_RESP3);
249 rsp[1] = read32(host->base + SDC_RESP2);
250 rsp[2] = read32(host->base + SDC_RESP1);
251 rsp[3] = read32(host->base + SDC_RESP0);
252 } else {
253 rsp[0] = read32(host->base + SDC_RESP0);
257 if (!(events & MSDC_INT_CMDRDY)) {
258 if (cmd->cmdidx != MMC_CMD_AUTO_TUNING_SEQUENCE) {
260 * should not clear fifo/interrupt as the tune data
261 * may have already come.
263 msdc_reset_hw(host);
265 if (events & MSDC_INT_CMDTMO)
266 ret = -ETIMEDOUT;
267 else
268 ret = -EIO;
271 return ret;
274 static int msdc_start_command(struct msdc_ctrlr *host, struct mmc_command *cmd,
275 struct mmc_data *data)
277 u32 rawcmd, status;
278 u32 blocks = 0;
279 int ret;
281 if (!msdc_cmd_is_ready(host))
282 return -EIO;
284 if (read32(host->base + MSDC_FIFOCS) &
285 (MSDC_FIFOCS_TXCNT | MSDC_FIFOCS_RXCNT)) {
286 msdc_error("TX/RX FIFO non-empty before start of IO. Reset\n");
287 msdc_reset_hw(host);
290 msdc_fifo_clr(host);
292 rawcmd = msdc_cmd_prepare_raw_cmd(host, cmd, data);
294 if (data)
295 blocks = data->blocks;
297 write32(host->base + MSDC_INT, CMD_INTS_MASK);
298 write32(host->base + SDC_BLK_NUM, blocks);
299 write32(host->base + SDC_ARG, cmd->cmdarg);
300 write32(host->base + SDC_CMD, rawcmd);
302 ret = msdc_wait_done(host->base + MSDC_INT, CMD_INTS_MASK, &status);
303 if (ret != MSDC_SUCCESS)
304 status = MSDC_INT_CMDTMO;
306 return msdc_cmd_done(host, status, cmd);
309 static int msdc_send_command(struct sd_mmc_ctrlr *ctrlr,
310 struct mmc_command *cmd, struct mmc_data *data)
312 struct msdc_ctrlr *host;
314 host = container_of(ctrlr, struct msdc_ctrlr, sd_mmc_ctrlr);
316 return msdc_start_command(host, cmd, data);
319 static void msdc_set_clock(struct msdc_ctrlr *host, u32 clock)
321 u32 mode, mode_shift;
322 u32 div, div_mask;
323 const u32 div_width = 12;
324 u32 sclk;
325 u32 hclk = host->src_hz;
326 struct sd_mmc_ctrlr *ctrlr = &host->sd_mmc_ctrlr;
328 if (clock >= hclk) {
329 mode = 0x1; /* no divisor */
330 div = 0;
331 sclk = hclk;
332 } else {
333 mode = 0x0; /* use divisor */
334 if (clock >= (hclk / 2)) {
335 div = 0; /* mean div = 1/2 */
336 sclk = hclk / 2; /* sclk = clk / 2 */
337 } else {
338 div = DIV_ROUND_UP(hclk, clock * 4);
339 sclk = (hclk >> 2) / div;
343 div_mask = (1 << div_width) - 1;
344 mode_shift = 8 + div_width;
345 assert(div <= div_mask);
347 clrsetbits_le32(host->base + MSDC_CFG, (0x3 << mode_shift) | (div_mask << 8),
348 (mode << mode_shift) | (div << 8));
349 if (msdc_wait_done(host->base + MSDC_CFG, MSDC_CFG_CKSTB, NULL) != MSDC_SUCCESS)
350 msdc_error("Failed while wait clock stable!\n");
352 ctrlr->bus_hz = sclk;
353 msdc_debug("sclk: %d\n", sclk);
356 static void msdc_set_buswidth(struct msdc_ctrlr *host, u32 width)
358 u32 val = read32(host->base + SDC_CFG);
360 val &= ~SDC_CFG_BUSWIDTH;
362 switch (width) {
363 default:
364 case 1:
365 val |= (MSDC_BUS_1BITS << 16);
366 break;
367 case 4:
368 val |= (MSDC_BUS_4BITS << 16);
369 break;
370 case 8:
371 val |= (MSDC_BUS_8BITS << 16);
372 break;
375 write32(host->base + SDC_CFG, val);
376 msdc_trace("Bus Width = %d\n", width);
379 static void msdc_set_ios(struct sd_mmc_ctrlr *ctrlr)
381 struct msdc_ctrlr *host;
383 host = container_of(ctrlr, struct msdc_ctrlr, sd_mmc_ctrlr);
385 /* Set the clock frequency */
386 if (ctrlr->bus_hz != ctrlr->request_hz)
387 msdc_set_clock(host, ctrlr->request_hz);
389 msdc_set_buswidth(host, ctrlr->bus_width);
392 static void msdc_update_pointers(struct msdc_ctrlr *host)
394 struct sd_mmc_ctrlr *ctrlr = &host->sd_mmc_ctrlr;
396 /* Update the routine pointers */
397 ctrlr->send_cmd = &msdc_send_command;
398 ctrlr->set_ios = &msdc_set_ios;
400 ctrlr->f_min = 400 * 1000;
401 ctrlr->f_max = 52 * 1000 * 1000;
402 ctrlr->bus_width = 1;
403 ctrlr->caps |= DRVR_CAP_HS | DRVR_CAP_HC;
404 ctrlr->voltages = 0x40ff8080;
407 static void add_msdc(struct msdc_ctrlr *host)
409 struct sd_mmc_ctrlr *ctrlr = &host->sd_mmc_ctrlr;
411 msdc_update_pointers(host);
413 /* Initialize the MTK MSDC controller */
414 msdc_init_hw(host);
416 /* Display the results */
417 msdc_trace("%#010x: ctrlr->caps\n", ctrlr->caps);
418 msdc_trace("%d.%03d MHz: ctrlr->f_max\n",
419 ctrlr->f_max / 1000000,
420 (ctrlr->f_max / 1000) % 1000);
421 msdc_trace("%d.%03d MHz: ctrlr->f_min\n",
422 ctrlr->f_min / 1000000,
423 (ctrlr->f_min / 1000) % 1000);
424 msdc_trace("%#010x: ctrlr->voltages\n", ctrlr->voltages);
427 static void msdc_controller_init(struct msdc_ctrlr *host, void *base, void *top_base)
429 memset(host, 0, sizeof(*host));
430 host->base = base;
431 host->top_base = top_base;
432 host->src_hz = 50 * 1000 * 1000;
434 add_msdc(host);
437 int mtk_emmc_early_init(void *base, void *top_base)
439 struct storage_media media = { 0 };
440 struct msdc_ctrlr msdc_host;
441 struct sd_mmc_ctrlr *mmc_ctrlr = &msdc_host.sd_mmc_ctrlr;
443 /* Init mtk mmc ctrlr */
444 msdc_controller_init(&msdc_host, base, top_base);
446 media.ctrlr = mmc_ctrlr;
447 SET_CLOCK(mmc_ctrlr, 400 * 1000);
448 SET_BUS_WIDTH(mmc_ctrlr, 1);
450 /* Send CMD1 */
451 return mmc_send_cmd1(&media);