Lines Matching full:host
3 * Amlogic Meson6/Meson8/Meson8b/Meson8m2 SDHC MMC host controller driver.
21 #include <linux/mmc/host.h>
68 static void meson_mx_sdhc_reset(struct meson_mx_sdhc_host *host) in meson_mx_sdhc_reset() argument
70 regmap_write(host->regmap, MESON_SDHC_SRST, MESON_SDHC_SRST_MAIN_CTRL | in meson_mx_sdhc_reset()
76 regmap_write(host->regmap, MESON_SDHC_SRST, 0); in meson_mx_sdhc_reset()
82 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_clear_fifo() local
85 regmap_read(host->regmap, MESON_SDHC_STAT, &stat); in meson_mx_sdhc_clear_fifo()
90 regmap_write(host->regmap, MESON_SDHC_SRST, MESON_SDHC_SRST_RXFIFO | in meson_mx_sdhc_clear_fifo()
94 regmap_read(host->regmap, MESON_SDHC_STAT, &stat); in meson_mx_sdhc_clear_fifo()
97 dev_warn(mmc_dev(host->mmc), in meson_mx_sdhc_clear_fifo()
105 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_wait_cmd_ready() local
109 ret = regmap_read_poll_timeout(host->regmap, MESON_SDHC_STAT, stat, in meson_mx_sdhc_wait_cmd_ready()
116 host->cmd->opcode); in meson_mx_sdhc_wait_cmd_ready()
117 meson_mx_sdhc_reset(host); in meson_mx_sdhc_wait_cmd_ready()
120 ret = regmap_read_poll_timeout(host->regmap, MESON_SDHC_ESTA, esta, in meson_mx_sdhc_wait_cmd_ready()
127 host->cmd->opcode); in meson_mx_sdhc_wait_cmd_ready()
128 meson_mx_sdhc_reset(host); in meson_mx_sdhc_wait_cmd_ready()
135 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_start_cmd() local
140 host->cmd = cmd; in meson_mx_sdhc_start_cmd()
167 if (host->platform->hardware_flush_all_cmds || in meson_mx_sdhc_start_cmd()
191 regmap_update_bits(host->regmap, MESON_SDHC_MISC, in meson_mx_sdhc_start_cmd()
213 regmap_write(host->regmap, MESON_SDHC_ICTL, ictl); in meson_mx_sdhc_start_cmd()
214 regmap_write(host->regmap, MESON_SDHC_ISTA, MESON_SDHC_ISTA_ALL_IRQS); in meson_mx_sdhc_start_cmd()
216 regmap_write(host->regmap, MESON_SDHC_ARGU, cmd->arg); in meson_mx_sdhc_start_cmd()
218 regmap_update_bits(host->regmap, MESON_SDHC_CTRL, in meson_mx_sdhc_start_cmd()
223 regmap_write(host->regmap, MESON_SDHC_ADDR, in meson_mx_sdhc_start_cmd()
229 host->platform->set_pdma(mmc); in meson_mx_sdhc_start_cmd()
231 if (host->platform->wait_before_send) in meson_mx_sdhc_start_cmd()
232 host->platform->wait_before_send(mmc); in meson_mx_sdhc_start_cmd()
234 regmap_write(host->regmap, MESON_SDHC_SEND, send); in meson_mx_sdhc_start_cmd()
239 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_disable_clks() local
241 if (!host->bulk_clks_enabled) in meson_mx_sdhc_disable_clks()
244 clk_bulk_disable_unprepare(MESON_SDHC_NUM_BULK_CLKS, host->bulk_clks); in meson_mx_sdhc_disable_clks()
246 host->bulk_clks_enabled = false; in meson_mx_sdhc_disable_clks()
251 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_enable_clks() local
254 if (host->bulk_clks_enabled) in meson_mx_sdhc_enable_clks()
258 host->bulk_clks); in meson_mx_sdhc_enable_clks()
262 host->bulk_clks_enabled = true; in meson_mx_sdhc_enable_clks()
269 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_set_clk() local
276 ret = clk_set_rate(host->sd_clk, ios->clock); in meson_mx_sdhc_set_clk()
280 ios->clock, host->error); in meson_mx_sdhc_set_clk()
288 mmc->actual_clock = clk_get_rate(host->sd_clk); in meson_mx_sdhc_set_clk()
294 regmap_read(host->regmap, MESON_SDHC_CLKC, &val); in meson_mx_sdhc_set_clk()
296 regmap_update_bits(host->regmap, MESON_SDHC_CLK2, in meson_mx_sdhc_set_clk()
309 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_set_ios() local
319 host->error = mmc_regulator_set_ocr(mmc, in meson_mx_sdhc_set_ios()
322 if (host->error) in meson_mx_sdhc_set_ios()
332 host->error = meson_mx_sdhc_set_clk(mmc, ios); in meson_mx_sdhc_set_ios()
333 if (host->error) in meson_mx_sdhc_set_ios()
338 regmap_update_bits(host->regmap, MESON_SDHC_CTRL, in meson_mx_sdhc_set_ios()
344 regmap_update_bits(host->regmap, MESON_SDHC_CTRL, in meson_mx_sdhc_set_ios()
350 regmap_update_bits(host->regmap, MESON_SDHC_CTRL, in meson_mx_sdhc_set_ios()
358 host->error = -EINVAL; in meson_mx_sdhc_set_ios()
383 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_request() local
386 if (!host->error) in meson_mx_sdhc_request()
387 host->error = meson_mx_sdhc_map_dma(mmc, mrq); in meson_mx_sdhc_request()
389 if (host->error) { in meson_mx_sdhc_request()
390 cmd->error = host->error; in meson_mx_sdhc_request()
395 host->mrq = mrq; in meson_mx_sdhc_request()
402 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_card_busy() local
405 regmap_read(host->regmap, MESON_SDHC_STAT, &stat); in meson_mx_sdhc_card_busy()
426 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_execute_tuning() local
435 regmap_read(host->regmap, MESON_SDHC_CLK2, &val); in meson_mx_sdhc_execute_tuning()
438 regmap_read(host->regmap, MESON_SDHC_CLKC, &val); in meson_mx_sdhc_execute_tuning()
442 regmap_update_bits(host->regmap, MESON_SDHC_CLK2, in meson_mx_sdhc_execute_tuning()
482 regmap_update_bits(host->regmap, MESON_SDHC_CLK2, in meson_mx_sdhc_execute_tuning()
504 static void meson_mx_sdhc_request_done(struct meson_mx_sdhc_host *host) in meson_mx_sdhc_request_done() argument
506 struct mmc_request *mrq = host->mrq; in meson_mx_sdhc_request_done()
507 struct mmc_host *mmc = host->mmc; in meson_mx_sdhc_request_done()
510 regmap_update_bits(host->regmap, MESON_SDHC_ICTL, in meson_mx_sdhc_request_done()
512 regmap_update_bits(host->regmap, MESON_SDHC_ISTA, in meson_mx_sdhc_request_done()
515 host->mrq = NULL; in meson_mx_sdhc_request_done()
516 host->cmd = NULL; in meson_mx_sdhc_request_done()
521 static u32 meson_mx_sdhc_read_response(struct meson_mx_sdhc_host *host, u8 idx) in meson_mx_sdhc_read_response() argument
525 regmap_update_bits(host->regmap, MESON_SDHC_PDMA, in meson_mx_sdhc_read_response()
528 regmap_update_bits(host->regmap, MESON_SDHC_PDMA, in meson_mx_sdhc_read_response()
532 regmap_read(host->regmap, MESON_SDHC_ARGU, &val); in meson_mx_sdhc_read_response()
539 struct meson_mx_sdhc_host *host = data; in meson_mx_sdhc_irq() local
540 struct mmc_command *cmd = host->cmd; in meson_mx_sdhc_irq()
543 regmap_read(host->regmap, MESON_SDHC_ICTL, &ictl); in meson_mx_sdhc_irq()
544 regmap_read(host->regmap, MESON_SDHC_ISTA, &ista); in meson_mx_sdhc_irq()
565 dev_dbg(mmc_dev(host->mmc), "CMD%d error, ISTA: 0x%08x\n", in meson_mx_sdhc_irq()
573 struct meson_mx_sdhc_host *host = irq_data; in meson_mx_sdhc_irq_thread() local
577 cmd = host->cmd; in meson_mx_sdhc_irq_thread()
582 if (!host->platform->hardware_flush_all_cmds && in meson_mx_sdhc_irq_thread()
584 meson_mx_sdhc_wait_cmd_ready(host->mmc); in meson_mx_sdhc_irq_thread()
596 regmap_update_bits(host->regmap, MESON_SDHC_PDMA, val, in meson_mx_sdhc_irq_thread()
600 dma_unmap_sg(mmc_dev(host->mmc), cmd->data->sg, in meson_mx_sdhc_irq_thread()
606 meson_mx_sdhc_wait_cmd_ready(host->mmc); in meson_mx_sdhc_irq_thread()
609 cmd->resp[0] = meson_mx_sdhc_read_response(host, 4); in meson_mx_sdhc_irq_thread()
610 cmd->resp[1] = meson_mx_sdhc_read_response(host, 3); in meson_mx_sdhc_irq_thread()
611 cmd->resp[2] = meson_mx_sdhc_read_response(host, 2); in meson_mx_sdhc_irq_thread()
612 cmd->resp[3] = meson_mx_sdhc_read_response(host, 1); in meson_mx_sdhc_irq_thread()
614 cmd->resp[0] = meson_mx_sdhc_read_response(host, 0); in meson_mx_sdhc_irq_thread()
618 meson_mx_sdhc_reset(host); in meson_mx_sdhc_irq_thread()
626 meson_mx_sdhc_clear_fifo(host->mmc); in meson_mx_sdhc_irq_thread()
628 meson_mx_sdhc_request_done(host); in meson_mx_sdhc_irq_thread()
635 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_init_hw_meson8() local
637 regmap_write(host->regmap, MESON_SDHC_MISC, in meson_mx_sdhc_init_hw_meson8()
642 regmap_write(host->regmap, MESON_SDHC_ENHC, in meson_mx_sdhc_init_hw_meson8()
651 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_set_pdma_meson8() local
653 if (host->cmd->data->flags & MMC_DATA_WRITE) in meson_mx_sdhc_set_pdma_meson8()
654 regmap_update_bits(host->regmap, MESON_SDHC_PDMA, in meson_mx_sdhc_set_pdma_meson8()
662 regmap_update_bits(host->regmap, MESON_SDHC_PDMA, in meson_mx_sdhc_set_pdma_meson8()
669 if (host->cmd->data->flags & MMC_DATA_WRITE) in meson_mx_sdhc_set_pdma_meson8()
670 regmap_update_bits(host->regmap, MESON_SDHC_PDMA, in meson_mx_sdhc_set_pdma_meson8()
677 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_wait_before_send_meson8() local
681 ret = regmap_read_poll_timeout(host->regmap, MESON_SDHC_ESTA, val, in meson_mx_sdhc_wait_before_send_meson8()
689 if (host->cmd->data && host->cmd->data->flags & MMC_DATA_WRITE) { in meson_mx_sdhc_wait_before_send_meson8()
690 ret = regmap_read_poll_timeout(host->regmap, MESON_SDHC_STAT, in meson_mx_sdhc_wait_before_send_meson8()
702 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_init_hw_meson8m2() local
704 regmap_write(host->regmap, MESON_SDHC_MISC, in meson_mx_sdhc_init_hw_meson8m2()
709 regmap_write(host->regmap, MESON_SDHC_ENHC, in meson_mx_sdhc_init_hw_meson8m2()
718 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_set_pdma_meson8m2() local
720 regmap_update_bits(host->regmap, MESON_SDHC_PDMA, in meson_mx_sdhc_set_pdma_meson8m2()
726 struct meson_mx_sdhc_host *host = mmc_priv(mmc); in meson_mx_sdhc_init_hw() local
728 meson_mx_sdhc_reset(host); in meson_mx_sdhc_init_hw()
730 regmap_write(host->regmap, MESON_SDHC_CTRL, in meson_mx_sdhc_init_hw()
740 regmap_write(host->regmap, MESON_SDHC_CLKC, MESON_SDHC_CLKC_CLK_DIV); in meson_mx_sdhc_init_hw()
742 regmap_write(host->regmap, MESON_SDHC_CLK2, in meson_mx_sdhc_init_hw()
745 regmap_write(host->regmap, MESON_SDHC_PDMA, in meson_mx_sdhc_init_hw()
753 host->platform->init_hw(mmc); in meson_mx_sdhc_init_hw()
756 regmap_write(host->regmap, MESON_SDHC_ICTL, 0); in meson_mx_sdhc_init_hw()
757 regmap_write(host->regmap, MESON_SDHC_ISTA, MESON_SDHC_ISTA_ALL_IRQS); in meson_mx_sdhc_init_hw()
763 struct meson_mx_sdhc_host *host; in meson_mx_sdhc_probe() local
768 mmc = devm_mmc_alloc_host(dev, sizeof(*host)); in meson_mx_sdhc_probe()
772 host = mmc_priv(mmc); in meson_mx_sdhc_probe()
773 host->mmc = mmc; in meson_mx_sdhc_probe()
775 platform_set_drvdata(pdev, host); in meson_mx_sdhc_probe()
777 host->platform = device_get_match_data(dev); in meson_mx_sdhc_probe()
778 if (!host->platform) in meson_mx_sdhc_probe()
785 host->regmap = devm_regmap_init_mmio(dev, base, in meson_mx_sdhc_probe()
787 if (IS_ERR(host->regmap)) in meson_mx_sdhc_probe()
788 return PTR_ERR(host->regmap); in meson_mx_sdhc_probe()
790 host->pclk = devm_clk_get(dev, "pclk"); in meson_mx_sdhc_probe()
791 if (IS_ERR(host->pclk)) in meson_mx_sdhc_probe()
792 return PTR_ERR(host->pclk); in meson_mx_sdhc_probe()
795 ret = clk_prepare_enable(host->pclk); in meson_mx_sdhc_probe()
803 ret = meson_mx_sdhc_register_clkc(dev, base, host->bulk_clks); in meson_mx_sdhc_probe()
807 host->sd_clk = host->bulk_clks[1].clk; in meson_mx_sdhc_probe()
819 mmc->f_min = clk_round_rate(host->sd_clk, 1); in meson_mx_sdhc_probe()
820 mmc->f_max = clk_round_rate(host->sd_clk, ULONG_MAX); in meson_mx_sdhc_probe()
838 NULL, host); in meson_mx_sdhc_probe()
849 clk_disable_unprepare(host->pclk); in meson_mx_sdhc_probe()
855 struct meson_mx_sdhc_host *host = platform_get_drvdata(pdev); in meson_mx_sdhc_remove() local
857 mmc_remove_host(host->mmc); in meson_mx_sdhc_remove()
859 meson_mx_sdhc_disable_clks(host->mmc); in meson_mx_sdhc_remove()
861 clk_disable_unprepare(host->pclk); in meson_mx_sdhc_remove()
906 MODULE_DESCRIPTION("Meson6, Meson8, Meson8b and Meson8m2 SDHC Host Driver");