1 // SPDX-License-Identifier: GPL-2.0+
3 * Amlogic Meson6/Meson8/Meson8b/Meson8m2 SDHC MMC host controller driver.
5 * Copyright (C) 2020 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
9 #include <linux/device.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/interrupt.h>
12 #include <linux/iopoll.h>
13 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/property.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/types.h>
21 #include <linux/mmc/host.h>
22 #include <linux/mmc/mmc.h>
23 #include <linux/mmc/sdio.h>
24 #include <linux/mmc/slot-gpio.h>
26 #include "meson-mx-sdhc.h"
28 #define MESON_SDHC_NUM_BULK_CLKS 4
29 #define MESON_SDHC_MAX_BLK_SIZE 512
30 #define MESON_SDHC_NUM_TUNING_TRIES 10
32 #define MESON_SDHC_WAIT_CMD_READY_SLEEP_US 1
33 #define MESON_SDHC_WAIT_CMD_READY_TIMEOUT_US 100000
34 #define MESON_SDHC_WAIT_BEFORE_SEND_SLEEP_US 1
35 #define MESON_SDHC_WAIT_BEFORE_SEND_TIMEOUT_US 200
37 struct meson_mx_sdhc_data
{
38 void (*init_hw
)(struct mmc_host
*mmc
);
39 void (*set_pdma
)(struct mmc_host
*mmc
);
40 void (*wait_before_send
)(struct mmc_host
*mmc
);
41 bool hardware_flush_all_cmds
;
44 struct meson_mx_sdhc_host
{
47 struct mmc_request
*mrq
;
48 struct mmc_command
*cmd
;
51 struct regmap
*regmap
;
55 struct clk_bulk_data bulk_clks
[MESON_SDHC_NUM_BULK_CLKS
];
56 bool bulk_clks_enabled
;
58 const struct meson_mx_sdhc_data
*platform
;
61 static const struct regmap_config meson_mx_sdhc_regmap_config
= {
65 .max_register
= MESON_SDHC_CLK2
,
68 static void meson_mx_sdhc_reset(struct meson_mx_sdhc_host
*host
)
70 regmap_write(host
->regmap
, MESON_SDHC_SRST
, MESON_SDHC_SRST_MAIN_CTRL
|
71 MESON_SDHC_SRST_RXFIFO
| MESON_SDHC_SRST_TXFIFO
|
72 MESON_SDHC_SRST_DPHY_RX
| MESON_SDHC_SRST_DPHY_TX
|
73 MESON_SDHC_SRST_DMA_IF
);
74 usleep_range(10, 100);
76 regmap_write(host
->regmap
, MESON_SDHC_SRST
, 0);
77 usleep_range(10, 100);
80 static void meson_mx_sdhc_clear_fifo(struct mmc_host
*mmc
)
82 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
85 regmap_read(host
->regmap
, MESON_SDHC_STAT
, &stat
);
86 if (!FIELD_GET(MESON_SDHC_STAT_RXFIFO_CNT
, stat
) &&
87 !FIELD_GET(MESON_SDHC_STAT_TXFIFO_CNT
, stat
))
90 regmap_write(host
->regmap
, MESON_SDHC_SRST
, MESON_SDHC_SRST_RXFIFO
|
91 MESON_SDHC_SRST_TXFIFO
| MESON_SDHC_SRST_MAIN_CTRL
);
94 regmap_read(host
->regmap
, MESON_SDHC_STAT
, &stat
);
95 if (FIELD_GET(MESON_SDHC_STAT_RXFIFO_CNT
, stat
) ||
96 FIELD_GET(MESON_SDHC_STAT_TXFIFO_CNT
, stat
))
97 dev_warn(mmc_dev(host
->mmc
),
98 "Failed to clear FIFOs, RX: %lu, TX: %lu\n",
99 FIELD_GET(MESON_SDHC_STAT_RXFIFO_CNT
, stat
),
100 FIELD_GET(MESON_SDHC_STAT_TXFIFO_CNT
, stat
));
103 static void meson_mx_sdhc_wait_cmd_ready(struct mmc_host
*mmc
)
105 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
109 ret
= regmap_read_poll_timeout(host
->regmap
, MESON_SDHC_STAT
, stat
,
110 !(stat
& MESON_SDHC_STAT_CMD_BUSY
),
111 MESON_SDHC_WAIT_CMD_READY_SLEEP_US
,
112 MESON_SDHC_WAIT_CMD_READY_TIMEOUT_US
);
114 dev_warn(mmc_dev(mmc
),
115 "Failed to poll for CMD_BUSY while processing CMD%d\n",
117 meson_mx_sdhc_reset(host
);
120 ret
= regmap_read_poll_timeout(host
->regmap
, MESON_SDHC_ESTA
, esta
,
121 !(esta
& MESON_SDHC_ESTA_11_13
),
122 MESON_SDHC_WAIT_CMD_READY_SLEEP_US
,
123 MESON_SDHC_WAIT_CMD_READY_TIMEOUT_US
);
125 dev_warn(mmc_dev(mmc
),
126 "Failed to poll for ESTA[13:11] while processing CMD%d\n",
128 meson_mx_sdhc_reset(host
);
132 static void meson_mx_sdhc_start_cmd(struct mmc_host
*mmc
,
133 struct mmc_command
*cmd
)
135 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
136 bool manual_stop
= false;
142 ictl
= MESON_SDHC_ICTL_DATA_TIMEOUT
| MESON_SDHC_ICTL_DATA_ERR_CRC
|
143 MESON_SDHC_ICTL_RXFIFO_FULL
| MESON_SDHC_ICTL_TXFIFO_EMPTY
|
144 MESON_SDHC_ICTL_RESP_TIMEOUT
| MESON_SDHC_ICTL_RESP_ERR_CRC
;
146 send
= FIELD_PREP(MESON_SDHC_SEND_CMD_INDEX
, cmd
->opcode
);
149 send
|= MESON_SDHC_SEND_CMD_HAS_DATA
;
150 send
|= FIELD_PREP(MESON_SDHC_SEND_TOTAL_PACK
,
151 cmd
->data
->blocks
- 1);
153 if (cmd
->data
->blksz
< MESON_SDHC_MAX_BLK_SIZE
)
154 pack_len
= cmd
->data
->blksz
;
158 if (cmd
->data
->flags
& MMC_DATA_WRITE
)
159 send
|= MESON_SDHC_SEND_DATA_DIR
;
162 * If command with no data, just wait response done
163 * interrupt(int[0]), and if command with data transfer, just
164 * wait dma done interrupt(int[11]), don't need care about
167 if (host
->platform
->hardware_flush_all_cmds
||
168 cmd
->data
->flags
& MMC_DATA_WRITE
)
169 /* hardware flush: */
170 ictl
|= MESON_SDHC_ICTL_DMA_DONE
;
172 /* software flush: */
173 ictl
|= MESON_SDHC_ICTL_DATA_XFER_OK
;
176 * Mimic the logic from the vendor driver where (only)
177 * SD_IO_RW_EXTENDED commands with more than one block set the
178 * MESON_SDHC_MISC_MANUAL_STOP bit. This fixes the firmware
179 * download in the brcmfmac driver for a BCM43362/1 card.
180 * Without this sdio_memcpy_toio() (with a size of 219557
181 * bytes) times out if MESON_SDHC_MISC_MANUAL_STOP is not set.
183 manual_stop
= cmd
->data
->blocks
> 1 &&
184 cmd
->opcode
== SD_IO_RW_EXTENDED
;
188 ictl
|= MESON_SDHC_ICTL_RESP_OK
;
191 regmap_update_bits(host
->regmap
, MESON_SDHC_MISC
,
192 MESON_SDHC_MISC_MANUAL_STOP
,
193 manual_stop
? MESON_SDHC_MISC_MANUAL_STOP
: 0);
195 if (cmd
->opcode
== MMC_STOP_TRANSMISSION
)
196 send
|= MESON_SDHC_SEND_DATA_STOP
;
198 if (cmd
->flags
& MMC_RSP_PRESENT
)
199 send
|= MESON_SDHC_SEND_CMD_HAS_RESP
;
201 if (cmd
->flags
& MMC_RSP_136
) {
202 send
|= MESON_SDHC_SEND_RESP_LEN
;
203 send
|= MESON_SDHC_SEND_RESP_NO_CRC
;
206 if (!(cmd
->flags
& MMC_RSP_CRC
))
207 send
|= MESON_SDHC_SEND_RESP_NO_CRC
;
209 if (cmd
->flags
& MMC_RSP_BUSY
)
210 send
|= MESON_SDHC_SEND_R1B
;
212 /* enable the new IRQs and mask all pending ones */
213 regmap_write(host
->regmap
, MESON_SDHC_ICTL
, ictl
);
214 regmap_write(host
->regmap
, MESON_SDHC_ISTA
, MESON_SDHC_ISTA_ALL_IRQS
);
216 regmap_write(host
->regmap
, MESON_SDHC_ARGU
, cmd
->arg
);
218 regmap_update_bits(host
->regmap
, MESON_SDHC_CTRL
,
219 MESON_SDHC_CTRL_PACK_LEN
,
220 FIELD_PREP(MESON_SDHC_CTRL_PACK_LEN
, pack_len
));
223 regmap_write(host
->regmap
, MESON_SDHC_ADDR
,
224 sg_dma_address(cmd
->data
->sg
));
226 meson_mx_sdhc_wait_cmd_ready(mmc
);
229 host
->platform
->set_pdma(mmc
);
231 if (host
->platform
->wait_before_send
)
232 host
->platform
->wait_before_send(mmc
);
234 regmap_write(host
->regmap
, MESON_SDHC_SEND
, send
);
237 static void meson_mx_sdhc_disable_clks(struct mmc_host
*mmc
)
239 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
241 if (!host
->bulk_clks_enabled
)
244 clk_bulk_disable_unprepare(MESON_SDHC_NUM_BULK_CLKS
, host
->bulk_clks
);
246 host
->bulk_clks_enabled
= false;
249 static int meson_mx_sdhc_enable_clks(struct mmc_host
*mmc
)
251 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
254 if (host
->bulk_clks_enabled
)
257 ret
= clk_bulk_prepare_enable(MESON_SDHC_NUM_BULK_CLKS
,
262 host
->bulk_clks_enabled
= true;
267 static int meson_mx_sdhc_set_clk(struct mmc_host
*mmc
, struct mmc_ios
*ios
)
269 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
270 u32 val
, rx_clk_phase
;
273 meson_mx_sdhc_disable_clks(mmc
);
276 ret
= clk_set_rate(host
->sd_clk
, ios
->clock
);
278 dev_warn(mmc_dev(mmc
),
279 "Failed to set MMC clock to %uHz: %d\n",
280 ios
->clock
, host
->error
);
284 ret
= meson_mx_sdhc_enable_clks(mmc
);
288 mmc
->actual_clock
= clk_get_rate(host
->sd_clk
);
291 * Phase 90 should work in most cases. For data transmission,
292 * meson_mx_sdhc_execute_tuning() will find a accurate value
294 regmap_read(host
->regmap
, MESON_SDHC_CLKC
, &val
);
295 rx_clk_phase
= FIELD_GET(MESON_SDHC_CLKC_CLK_DIV
, val
) / 4;
296 regmap_update_bits(host
->regmap
, MESON_SDHC_CLK2
,
297 MESON_SDHC_CLK2_RX_CLK_PHASE
,
298 FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE
,
301 mmc
->actual_clock
= 0;
307 static void meson_mx_sdhc_set_ios(struct mmc_host
*mmc
, struct mmc_ios
*ios
)
309 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
310 unsigned short vdd
= ios
->vdd
;
312 switch (ios
->power_mode
) {
318 if (!IS_ERR(mmc
->supply
.vmmc
)) {
319 host
->error
= mmc_regulator_set_ocr(mmc
,
332 host
->error
= meson_mx_sdhc_set_clk(mmc
, ios
);
336 switch (ios
->bus_width
) {
337 case MMC_BUS_WIDTH_1
:
338 regmap_update_bits(host
->regmap
, MESON_SDHC_CTRL
,
339 MESON_SDHC_CTRL_DAT_TYPE
,
340 FIELD_PREP(MESON_SDHC_CTRL_DAT_TYPE
, 0));
343 case MMC_BUS_WIDTH_4
:
344 regmap_update_bits(host
->regmap
, MESON_SDHC_CTRL
,
345 MESON_SDHC_CTRL_DAT_TYPE
,
346 FIELD_PREP(MESON_SDHC_CTRL_DAT_TYPE
, 1));
349 case MMC_BUS_WIDTH_8
:
350 regmap_update_bits(host
->regmap
, MESON_SDHC_CTRL
,
351 MESON_SDHC_CTRL_DAT_TYPE
,
352 FIELD_PREP(MESON_SDHC_CTRL_DAT_TYPE
, 2));
356 dev_err(mmc_dev(mmc
), "unsupported bus width: %d\n",
358 host
->error
= -EINVAL
;
363 static int meson_mx_sdhc_map_dma(struct mmc_host
*mmc
, struct mmc_request
*mrq
)
365 struct mmc_data
*data
= mrq
->data
;
366 unsigned int dma_len
;
371 dma_len
= dma_map_sg(mmc_dev(mmc
), data
->sg
, data
->sg_len
,
372 mmc_get_dma_dir(data
));
374 dev_err(mmc_dev(mmc
), "dma_map_sg failed\n");
381 static void meson_mx_sdhc_request(struct mmc_host
*mmc
, struct mmc_request
*mrq
)
383 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
384 struct mmc_command
*cmd
= mrq
->cmd
;
387 host
->error
= meson_mx_sdhc_map_dma(mmc
, mrq
);
390 cmd
->error
= host
->error
;
391 mmc_request_done(mmc
, mrq
);
397 meson_mx_sdhc_start_cmd(mmc
, mrq
->cmd
);
400 static int meson_mx_sdhc_card_busy(struct mmc_host
*mmc
)
402 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
405 regmap_read(host
->regmap
, MESON_SDHC_STAT
, &stat
);
406 return FIELD_GET(MESON_SDHC_STAT_DAT3_0
, stat
) == 0;
409 static bool meson_mx_sdhc_tuning_point_matches(struct mmc_host
*mmc
,
412 unsigned int i
, num_matches
= 0;
415 for (i
= 0; i
< MESON_SDHC_NUM_TUNING_TRIES
; i
++) {
416 ret
= mmc_send_tuning(mmc
, opcode
, NULL
);
421 return num_matches
== MESON_SDHC_NUM_TUNING_TRIES
;
424 static int meson_mx_sdhc_execute_tuning(struct mmc_host
*mmc
, u32 opcode
)
426 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
427 int div
, start
, len
, best_start
, best_len
;
428 int curr_phase
, old_phase
, new_phase
;
435 regmap_read(host
->regmap
, MESON_SDHC_CLK2
, &val
);
436 old_phase
= FIELD_GET(MESON_SDHC_CLK2_RX_CLK_PHASE
, val
);
438 regmap_read(host
->regmap
, MESON_SDHC_CLKC
, &val
);
439 div
= FIELD_GET(MESON_SDHC_CLKC_CLK_DIV
, val
);
441 for (curr_phase
= 0; curr_phase
<= div
; curr_phase
++) {
442 regmap_update_bits(host
->regmap
, MESON_SDHC_CLK2
,
443 MESON_SDHC_CLK2_RX_CLK_PHASE
,
444 FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE
,
447 if (meson_mx_sdhc_tuning_point_matches(mmc
, opcode
)) {
451 dev_dbg(mmc_dev(mmc
),
452 "New RX phase window starts at %u\n",
458 if (len
> best_len
) {
462 dev_dbg(mmc_dev(mmc
),
463 "New best RX phase window: %u - %u\n",
464 best_start
, best_start
+ best_len
);
467 /* reset the current window */
473 /* the last window is the best (or possibly only) window */
474 new_phase
= start
+ (len
/ 2);
476 /* there was a better window than the last */
477 new_phase
= best_start
+ (best_len
/ 2);
479 /* no window was found at all, reset to the original phase */
480 new_phase
= old_phase
;
482 regmap_update_bits(host
->regmap
, MESON_SDHC_CLK2
,
483 MESON_SDHC_CLK2_RX_CLK_PHASE
,
484 FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE
,
487 if (!len
&& !best_len
)
490 dev_dbg(mmc_dev(mmc
), "Tuned RX clock phase to %u\n", new_phase
);
495 static const struct mmc_host_ops meson_mx_sdhc_ops
= {
496 .request
= meson_mx_sdhc_request
,
497 .set_ios
= meson_mx_sdhc_set_ios
,
498 .card_busy
= meson_mx_sdhc_card_busy
,
499 .execute_tuning
= meson_mx_sdhc_execute_tuning
,
500 .get_cd
= mmc_gpio_get_cd
,
501 .get_ro
= mmc_gpio_get_ro
,
504 static void meson_mx_sdhc_request_done(struct meson_mx_sdhc_host
*host
)
506 struct mmc_request
*mrq
= host
->mrq
;
507 struct mmc_host
*mmc
= host
->mmc
;
509 /* disable interrupts and mask all pending ones */
510 regmap_update_bits(host
->regmap
, MESON_SDHC_ICTL
,
511 MESON_SDHC_ICTL_ALL_IRQS
, 0);
512 regmap_update_bits(host
->regmap
, MESON_SDHC_ISTA
,
513 MESON_SDHC_ISTA_ALL_IRQS
, MESON_SDHC_ISTA_ALL_IRQS
);
518 mmc_request_done(mmc
, mrq
);
521 static u32
meson_mx_sdhc_read_response(struct meson_mx_sdhc_host
*host
, u8 idx
)
525 regmap_update_bits(host
->regmap
, MESON_SDHC_PDMA
,
526 MESON_SDHC_PDMA_DMA_MODE
, 0);
528 regmap_update_bits(host
->regmap
, MESON_SDHC_PDMA
,
529 MESON_SDHC_PDMA_PIO_RDRESP
,
530 FIELD_PREP(MESON_SDHC_PDMA_PIO_RDRESP
, idx
));
532 regmap_read(host
->regmap
, MESON_SDHC_ARGU
, &val
);
537 static irqreturn_t
meson_mx_sdhc_irq(int irq
, void *data
)
539 struct meson_mx_sdhc_host
*host
= data
;
540 struct mmc_command
*cmd
= host
->cmd
;
543 regmap_read(host
->regmap
, MESON_SDHC_ICTL
, &ictl
);
544 regmap_read(host
->regmap
, MESON_SDHC_ISTA
, &ista
);
549 if (ista
& MESON_SDHC_ISTA_RXFIFO_FULL
||
550 ista
& MESON_SDHC_ISTA_TXFIFO_EMPTY
)
552 else if (ista
& MESON_SDHC_ISTA_RESP_ERR_CRC
)
553 cmd
->error
= -EILSEQ
;
554 else if (ista
& MESON_SDHC_ISTA_RESP_TIMEOUT
)
555 cmd
->error
= -ETIMEDOUT
;
558 if (ista
& MESON_SDHC_ISTA_DATA_ERR_CRC
)
559 cmd
->data
->error
= -EILSEQ
;
560 else if (ista
& MESON_SDHC_ISTA_DATA_TIMEOUT
)
561 cmd
->data
->error
= -ETIMEDOUT
;
564 if (cmd
->error
|| (cmd
->data
&& cmd
->data
->error
))
565 dev_dbg(mmc_dev(host
->mmc
), "CMD%d error, ISTA: 0x%08x\n",
568 return IRQ_WAKE_THREAD
;
571 static irqreturn_t
meson_mx_sdhc_irq_thread(int irq
, void *irq_data
)
573 struct meson_mx_sdhc_host
*host
= irq_data
;
574 struct mmc_command
*cmd
;
581 if (cmd
->data
&& !cmd
->data
->error
) {
582 if (!host
->platform
->hardware_flush_all_cmds
&&
583 cmd
->data
->flags
& MMC_DATA_READ
) {
584 meson_mx_sdhc_wait_cmd_ready(host
->mmc
);
587 * If MESON_SDHC_PDMA_RXFIFO_MANUAL_FLUSH was
588 * previously 0x1 then it has to be set to 0x3. If it
589 * was 0x0 before then it has to be set to 0x2. Without
590 * this reading SD cards sometimes transfers garbage,
591 * which results in cards not being detected due to:
592 * unrecognised SCR structure version <random number>
594 val
= FIELD_PREP(MESON_SDHC_PDMA_RXFIFO_MANUAL_FLUSH
,
596 regmap_update_bits(host
->regmap
, MESON_SDHC_PDMA
, val
,
600 dma_unmap_sg(mmc_dev(host
->mmc
), cmd
->data
->sg
,
601 cmd
->data
->sg_len
, mmc_get_dma_dir(cmd
->data
));
603 cmd
->data
->bytes_xfered
= cmd
->data
->blksz
* cmd
->data
->blocks
;
606 meson_mx_sdhc_wait_cmd_ready(host
->mmc
);
608 if (cmd
->flags
& MMC_RSP_136
) {
609 cmd
->resp
[0] = meson_mx_sdhc_read_response(host
, 4);
610 cmd
->resp
[1] = meson_mx_sdhc_read_response(host
, 3);
611 cmd
->resp
[2] = meson_mx_sdhc_read_response(host
, 2);
612 cmd
->resp
[3] = meson_mx_sdhc_read_response(host
, 1);
614 cmd
->resp
[0] = meson_mx_sdhc_read_response(host
, 0);
617 if (cmd
->error
== -EIO
|| cmd
->error
== -ETIMEDOUT
)
618 meson_mx_sdhc_reset(host
);
621 * Clear the FIFOs after completing data transfers to prevent
622 * corrupting data on write access. It's not clear why this is
623 * needed (for reads and writes), but it mimics what the BSP
626 meson_mx_sdhc_clear_fifo(host
->mmc
);
628 meson_mx_sdhc_request_done(host
);
633 static void meson_mx_sdhc_init_hw_meson8(struct mmc_host
*mmc
)
635 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
637 regmap_write(host
->regmap
, MESON_SDHC_MISC
,
638 FIELD_PREP(MESON_SDHC_MISC_TXSTART_THRES
, 7) |
639 FIELD_PREP(MESON_SDHC_MISC_WCRC_ERR_PATT
, 5) |
640 FIELD_PREP(MESON_SDHC_MISC_WCRC_OK_PATT
, 2));
642 regmap_write(host
->regmap
, MESON_SDHC_ENHC
,
643 FIELD_PREP(MESON_SDHC_ENHC_RXFIFO_TH
, 63) |
644 MESON_SDHC_ENHC_MESON6_DMA_WR_RESP
|
645 FIELD_PREP(MESON_SDHC_ENHC_MESON6_RX_TIMEOUT
, 255) |
646 FIELD_PREP(MESON_SDHC_ENHC_SDIO_IRQ_PERIOD
, 12));
649 static void meson_mx_sdhc_set_pdma_meson8(struct mmc_host
*mmc
)
651 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
653 if (host
->cmd
->data
->flags
& MMC_DATA_WRITE
)
654 regmap_update_bits(host
->regmap
, MESON_SDHC_PDMA
,
655 MESON_SDHC_PDMA_DMA_MODE
|
656 MESON_SDHC_PDMA_RD_BURST
|
657 MESON_SDHC_PDMA_TXFIFO_FILL
,
658 MESON_SDHC_PDMA_DMA_MODE
|
659 FIELD_PREP(MESON_SDHC_PDMA_RD_BURST
, 31) |
660 MESON_SDHC_PDMA_TXFIFO_FILL
);
662 regmap_update_bits(host
->regmap
, MESON_SDHC_PDMA
,
663 MESON_SDHC_PDMA_DMA_MODE
|
664 MESON_SDHC_PDMA_RXFIFO_MANUAL_FLUSH
,
665 MESON_SDHC_PDMA_DMA_MODE
|
666 FIELD_PREP(MESON_SDHC_PDMA_RXFIFO_MANUAL_FLUSH
,
669 if (host
->cmd
->data
->flags
& MMC_DATA_WRITE
)
670 regmap_update_bits(host
->regmap
, MESON_SDHC_PDMA
,
671 MESON_SDHC_PDMA_RD_BURST
,
672 FIELD_PREP(MESON_SDHC_PDMA_RD_BURST
, 15));
675 static void meson_mx_sdhc_wait_before_send_meson8(struct mmc_host
*mmc
)
677 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
681 ret
= regmap_read_poll_timeout(host
->regmap
, MESON_SDHC_ESTA
, val
,
683 MESON_SDHC_WAIT_BEFORE_SEND_SLEEP_US
,
684 MESON_SDHC_WAIT_BEFORE_SEND_TIMEOUT_US
);
686 dev_warn(mmc_dev(mmc
),
687 "Failed to wait for ESTA to clear: 0x%08x\n", val
);
689 if (host
->cmd
->data
&& host
->cmd
->data
->flags
& MMC_DATA_WRITE
) {
690 ret
= regmap_read_poll_timeout(host
->regmap
, MESON_SDHC_STAT
,
691 val
, val
& MESON_SDHC_STAT_TXFIFO_CNT
,
692 MESON_SDHC_WAIT_BEFORE_SEND_SLEEP_US
,
693 MESON_SDHC_WAIT_BEFORE_SEND_TIMEOUT_US
);
695 dev_warn(mmc_dev(mmc
),
696 "Failed to wait for TX FIFO to fill\n");
700 static void meson_mx_sdhc_init_hw_meson8m2(struct mmc_host
*mmc
)
702 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
704 regmap_write(host
->regmap
, MESON_SDHC_MISC
,
705 FIELD_PREP(MESON_SDHC_MISC_TXSTART_THRES
, 6) |
706 FIELD_PREP(MESON_SDHC_MISC_WCRC_ERR_PATT
, 5) |
707 FIELD_PREP(MESON_SDHC_MISC_WCRC_OK_PATT
, 2));
709 regmap_write(host
->regmap
, MESON_SDHC_ENHC
,
710 FIELD_PREP(MESON_SDHC_ENHC_RXFIFO_TH
, 64) |
711 FIELD_PREP(MESON_SDHC_ENHC_MESON8M2_DEBUG
, 1) |
712 MESON_SDHC_ENHC_MESON8M2_WRRSP_MODE
|
713 FIELD_PREP(MESON_SDHC_ENHC_SDIO_IRQ_PERIOD
, 12));
716 static void meson_mx_sdhc_set_pdma_meson8m2(struct mmc_host
*mmc
)
718 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
720 regmap_update_bits(host
->regmap
, MESON_SDHC_PDMA
,
721 MESON_SDHC_PDMA_DMA_MODE
, MESON_SDHC_PDMA_DMA_MODE
);
724 static void meson_mx_sdhc_init_hw(struct mmc_host
*mmc
)
726 struct meson_mx_sdhc_host
*host
= mmc_priv(mmc
);
728 meson_mx_sdhc_reset(host
);
730 regmap_write(host
->regmap
, MESON_SDHC_CTRL
,
731 FIELD_PREP(MESON_SDHC_CTRL_RX_PERIOD
, 0xf) |
732 FIELD_PREP(MESON_SDHC_CTRL_RX_TIMEOUT
, 0x7f) |
733 FIELD_PREP(MESON_SDHC_CTRL_RX_ENDIAN
, 0x7) |
734 FIELD_PREP(MESON_SDHC_CTRL_TX_ENDIAN
, 0x7));
737 * start with a valid divider and enable the memory (un-setting
738 * MESON_SDHC_CLKC_MEM_PWR_OFF).
740 regmap_write(host
->regmap
, MESON_SDHC_CLKC
, MESON_SDHC_CLKC_CLK_DIV
);
742 regmap_write(host
->regmap
, MESON_SDHC_CLK2
,
743 FIELD_PREP(MESON_SDHC_CLK2_SD_CLK_PHASE
, 1));
745 regmap_write(host
->regmap
, MESON_SDHC_PDMA
,
746 MESON_SDHC_PDMA_DMA_URGENT
|
747 FIELD_PREP(MESON_SDHC_PDMA_WR_BURST
, 7) |
748 FIELD_PREP(MESON_SDHC_PDMA_TXFIFO_TH
, 49) |
749 FIELD_PREP(MESON_SDHC_PDMA_RD_BURST
, 15) |
750 FIELD_PREP(MESON_SDHC_PDMA_RXFIFO_TH
, 7));
752 /* some initialization bits depend on the SoC: */
753 host
->platform
->init_hw(mmc
);
755 /* disable and mask all interrupts: */
756 regmap_write(host
->regmap
, MESON_SDHC_ICTL
, 0);
757 regmap_write(host
->regmap
, MESON_SDHC_ISTA
, MESON_SDHC_ISTA_ALL_IRQS
);
760 static void meason_mx_mmc_free_host(void *data
)
765 static int meson_mx_sdhc_probe(struct platform_device
*pdev
)
767 struct device
*dev
= &pdev
->dev
;
768 struct meson_mx_sdhc_host
*host
;
769 struct mmc_host
*mmc
;
773 mmc
= mmc_alloc_host(sizeof(*host
), dev
);
777 ret
= devm_add_action_or_reset(dev
, meason_mx_mmc_free_host
, mmc
);
779 dev_err(dev
, "Failed to register mmc_free_host action\n");
783 host
= mmc_priv(mmc
);
786 platform_set_drvdata(pdev
, host
);
788 host
->platform
= device_get_match_data(dev
);
792 base
= devm_platform_ioremap_resource(pdev
, 0);
794 return PTR_ERR(base
);
796 host
->regmap
= devm_regmap_init_mmio(dev
, base
,
797 &meson_mx_sdhc_regmap_config
);
798 if (IS_ERR(host
->regmap
))
799 return PTR_ERR(host
->regmap
);
801 host
->pclk
= devm_clk_get(dev
, "pclk");
802 if (IS_ERR(host
->pclk
))
803 return PTR_ERR(host
->pclk
);
805 /* accessing any register requires the module clock to be enabled: */
806 ret
= clk_prepare_enable(host
->pclk
);
808 dev_err(dev
, "Failed to enable 'pclk' clock\n");
812 meson_mx_sdhc_init_hw(mmc
);
814 ret
= meson_mx_sdhc_register_clkc(dev
, base
, host
->bulk_clks
);
816 goto err_disable_pclk
;
818 host
->sd_clk
= host
->bulk_clks
[1].clk
;
820 /* Get regulators and the supported OCR mask */
821 ret
= mmc_regulator_get_supply(mmc
);
823 goto err_disable_pclk
;
825 mmc
->max_req_size
= SZ_128K
;
826 mmc
->max_seg_size
= mmc
->max_req_size
;
827 mmc
->max_blk_count
= FIELD_GET(MESON_SDHC_SEND_TOTAL_PACK
, ~0);
828 mmc
->max_blk_size
= MESON_SDHC_MAX_BLK_SIZE
;
829 mmc
->max_busy_timeout
= 30 * MSEC_PER_SEC
;
830 mmc
->f_min
= clk_round_rate(host
->sd_clk
, 1);
831 mmc
->f_max
= clk_round_rate(host
->sd_clk
, ULONG_MAX
);
832 mmc
->max_current_180
= 300;
833 mmc
->max_current_330
= 300;
834 mmc
->caps
|= MMC_CAP_WAIT_WHILE_BUSY
| MMC_CAP_HW_RESET
;
835 mmc
->ops
= &meson_mx_sdhc_ops
;
837 ret
= mmc_of_parse(mmc
);
839 goto err_disable_pclk
;
841 irq
= platform_get_irq(pdev
, 0);
844 goto err_disable_pclk
;
847 ret
= devm_request_threaded_irq(dev
, irq
, meson_mx_sdhc_irq
,
848 meson_mx_sdhc_irq_thread
, IRQF_ONESHOT
,
851 goto err_disable_pclk
;
853 ret
= mmc_add_host(mmc
);
855 goto err_disable_pclk
;
860 clk_disable_unprepare(host
->pclk
);
864 static void meson_mx_sdhc_remove(struct platform_device
*pdev
)
866 struct meson_mx_sdhc_host
*host
= platform_get_drvdata(pdev
);
868 mmc_remove_host(host
->mmc
);
870 meson_mx_sdhc_disable_clks(host
->mmc
);
872 clk_disable_unprepare(host
->pclk
);
875 static const struct meson_mx_sdhc_data meson_mx_sdhc_data_meson8
= {
876 .init_hw
= meson_mx_sdhc_init_hw_meson8
,
877 .set_pdma
= meson_mx_sdhc_set_pdma_meson8
,
878 .wait_before_send
= meson_mx_sdhc_wait_before_send_meson8
,
879 .hardware_flush_all_cmds
= false,
882 static const struct meson_mx_sdhc_data meson_mx_sdhc_data_meson8m2
= {
883 .init_hw
= meson_mx_sdhc_init_hw_meson8m2
,
884 .set_pdma
= meson_mx_sdhc_set_pdma_meson8m2
,
885 .hardware_flush_all_cmds
= true,
888 static const struct of_device_id meson_mx_sdhc_of_match
[] = {
890 .compatible
= "amlogic,meson8-sdhc",
891 .data
= &meson_mx_sdhc_data_meson8
894 .compatible
= "amlogic,meson8b-sdhc",
895 .data
= &meson_mx_sdhc_data_meson8
898 .compatible
= "amlogic,meson8m2-sdhc",
899 .data
= &meson_mx_sdhc_data_meson8m2
903 MODULE_DEVICE_TABLE(of
, meson_mx_sdhc_of_match
);
905 static struct platform_driver meson_mx_sdhc_driver
= {
906 .probe
= meson_mx_sdhc_probe
,
907 .remove
= meson_mx_sdhc_remove
,
909 .name
= "meson-mx-sdhc",
910 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
911 .of_match_table
= of_match_ptr(meson_mx_sdhc_of_match
),
915 module_platform_driver(meson_mx_sdhc_driver
);
917 MODULE_DESCRIPTION("Meson6, Meson8, Meson8b and Meson8m2 SDHC Host Driver");
918 MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
919 MODULE_LICENSE("GPL v2");