Lines Matching +full:ciu +full:- +full:drive
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd.
5 * (C) Copyright 2007-2011 Aaron Maoye <leafy.myeh@reuuimllatech.com>
6 * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch>
7 * (C) Copyright 2013-2014 David Lanzendörfer <david.lanzendoerfer@o2s.ch>
8 * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com>
13 #include <linux/clk/sunxi-ng.h>
16 #include <linux/dma-mapping.h>
27 #include <linux/mmc/slot-gpio.h>
59 #define SDXC_REG_CBCR (0x48) /* SMC CIU Byte Count Register */
73 #define SDXC_REG_DRV_DL 0x140 /* Drive Delay Control Register */
78 readl((host)->reg_base + SDXC_##reg)
80 writel((value), (host)->reg_base + SDXC_##reg)
203 * If the idma-des-size-bits of property is ie 13, bufsize bits are:
204 * Bits 0-12: buf1 size
205 * Bits 13-25: buf2 size
206 * Bits 26-31: not used
215 #define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */
317 dev_err(mmc_dev(host->mmc), "fatal err reset timeout\n"); in sunxi_mmc_reset_host()
318 return -EIO; in sunxi_mmc_reset_host()
329 return -EIO; in sunxi_mmc_init_host()
340 mmc_writel(host, REG_IMASK, host->sdio_imask); in sunxi_mmc_init_host()
348 mmc_writel(host, REG_DLBA, host->sg_dma >> host->cfg->idma_des_shift); in sunxi_mmc_init_host()
362 struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu; in sunxi_mmc_init_idma_des()
363 dma_addr_t next_desc = host->sg_dma; in sunxi_mmc_init_idma_des()
364 int i, max_len = (1 << host->cfg->idma_des_size_bits); in sunxi_mmc_init_idma_des()
366 for (i = 0; i < data->sg_len; i++) { in sunxi_mmc_init_idma_des()
371 if (data->sg[i].length == max_len) in sunxi_mmc_init_idma_des()
374 pdes[i].buf_size = cpu_to_le32(data->sg[i].length); in sunxi_mmc_init_idma_des()
378 cpu_to_le32(sg_dma_address(&data->sg[i]) >> in sunxi_mmc_init_idma_des()
379 host->cfg->idma_des_shift); in sunxi_mmc_init_idma_des()
381 host->cfg->idma_des_shift); in sunxi_mmc_init_idma_des()
385 pdes[i - 1].config |= cpu_to_le32(SDXC_IDMAC_DES0_LD | in sunxi_mmc_init_idma_des()
387 pdes[i - 1].config &= cpu_to_le32(~SDXC_IDMAC_DES0_DIC); in sunxi_mmc_init_idma_des()
388 pdes[i - 1].buf_addr_ptr2 = 0; in sunxi_mmc_init_idma_des()
391 * Avoid the io-store starting the idmac hitting io-mem before the in sunxi_mmc_init_idma_des()
392 * descriptors hit the main-mem. in sunxi_mmc_init_idma_des()
403 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, in sunxi_mmc_map_dma()
406 dev_err(mmc_dev(host->mmc), "dma_map_sg failed\n"); in sunxi_mmc_map_dma()
407 return -ENOMEM; in sunxi_mmc_map_dma()
410 for_each_sg(data->sg, sg, data->sg_len, i) { in sunxi_mmc_map_dma()
411 if (sg->offset & 3 || sg->length & 3) { in sunxi_mmc_map_dma()
412 dev_err(mmc_dev(host->mmc), in sunxi_mmc_map_dma()
414 sg->offset, sg->length); in sunxi_mmc_map_dma()
415 return -EINVAL; in sunxi_mmc_map_dma()
437 if (!(data->flags & MMC_DATA_WRITE)) in sunxi_mmc_start_dma()
453 if (req->cmd->opcode == SD_IO_RW_EXTENDED) { in sunxi_mmc_send_manual_stop()
456 ((req->cmd->arg >> 28) & 0x7); in sunxi_mmc_send_manual_stop()
471 dev_err(mmc_dev(host->mmc), "send stop command failed\n"); in sunxi_mmc_send_manual_stop()
472 if (req->stop) in sunxi_mmc_send_manual_stop()
473 req->stop->resp[0] = -ETIMEDOUT; in sunxi_mmc_send_manual_stop()
475 if (req->stop) in sunxi_mmc_send_manual_stop()
476 req->stop->resp[0] = mmc_readl(host, REG_RESP0); in sunxi_mmc_send_manual_stop()
484 struct mmc_command *cmd = host->mrq->cmd; in sunxi_mmc_dump_errinfo()
485 struct mmc_data *data = host->mrq->data; in sunxi_mmc_dump_errinfo()
488 if ((host->int_sum & SDXC_INTERRUPT_ERROR_BIT) == in sunxi_mmc_dump_errinfo()
489 SDXC_RESP_TIMEOUT && (cmd->opcode == SD_IO_SEND_OP_COND || in sunxi_mmc_dump_errinfo()
490 cmd->opcode == SD_IO_RW_DIRECT)) in sunxi_mmc_dump_errinfo()
493 dev_dbg(mmc_dev(host->mmc), in sunxi_mmc_dump_errinfo()
495 host->mmc->index, cmd->opcode, in sunxi_mmc_dump_errinfo()
496 data ? (data->flags & MMC_DATA_WRITE ? " WR" : " RD") : "", in sunxi_mmc_dump_errinfo()
497 host->int_sum & SDXC_RESP_ERROR ? " RE" : "", in sunxi_mmc_dump_errinfo()
498 host->int_sum & SDXC_RESP_CRC_ERROR ? " RCE" : "", in sunxi_mmc_dump_errinfo()
499 host->int_sum & SDXC_DATA_CRC_ERROR ? " DCE" : "", in sunxi_mmc_dump_errinfo()
500 host->int_sum & SDXC_RESP_TIMEOUT ? " RTO" : "", in sunxi_mmc_dump_errinfo()
501 host->int_sum & SDXC_DATA_TIMEOUT ? " DTO" : "", in sunxi_mmc_dump_errinfo()
502 host->int_sum & SDXC_FIFO_RUN_ERROR ? " FE" : "", in sunxi_mmc_dump_errinfo()
503 host->int_sum & SDXC_HARD_WARE_LOCKED ? " HL" : "", in sunxi_mmc_dump_errinfo()
504 host->int_sum & SDXC_START_BIT_ERROR ? " SBE" : "", in sunxi_mmc_dump_errinfo()
505 host->int_sum & SDXC_END_BIT_ERROR ? " EBE" : "" in sunxi_mmc_dump_errinfo()
512 struct mmc_request *mrq = host->mrq; in sunxi_mmc_finalize_request()
513 struct mmc_data *data = mrq->data; in sunxi_mmc_finalize_request()
516 mmc_writel(host, REG_IMASK, host->sdio_imask); in sunxi_mmc_finalize_request()
519 if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) { in sunxi_mmc_finalize_request()
521 mrq->cmd->error = -ETIMEDOUT; in sunxi_mmc_finalize_request()
524 data->error = -ETIMEDOUT; in sunxi_mmc_finalize_request()
525 host->manual_stop_mrq = mrq; in sunxi_mmc_finalize_request()
528 if (mrq->stop) in sunxi_mmc_finalize_request()
529 mrq->stop->error = -ETIMEDOUT; in sunxi_mmc_finalize_request()
531 if (mrq->cmd->flags & MMC_RSP_136) { in sunxi_mmc_finalize_request()
532 mrq->cmd->resp[0] = mmc_readl(host, REG_RESP3); in sunxi_mmc_finalize_request()
533 mrq->cmd->resp[1] = mmc_readl(host, REG_RESP2); in sunxi_mmc_finalize_request()
534 mrq->cmd->resp[2] = mmc_readl(host, REG_RESP1); in sunxi_mmc_finalize_request()
535 mrq->cmd->resp[3] = mmc_readl(host, REG_RESP0); in sunxi_mmc_finalize_request()
537 mrq->cmd->resp[0] = mmc_readl(host, REG_RESP0); in sunxi_mmc_finalize_request()
541 data->bytes_xfered = data->blocks * data->blksz; in sunxi_mmc_finalize_request()
554 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, in sunxi_mmc_finalize_request()
560 host->mrq = NULL; in sunxi_mmc_finalize_request()
561 host->int_sum = 0; in sunxi_mmc_finalize_request()
562 host->wait_dma = false; in sunxi_mmc_finalize_request()
564 return host->manual_stop_mrq ? IRQ_WAKE_THREAD : IRQ_HANDLED; in sunxi_mmc_finalize_request()
576 spin_lock(&host->lock); in sunxi_mmc_irq()
581 dev_dbg(mmc_dev(host->mmc), "irq: rq %p mi %08x idi %08x\n", in sunxi_mmc_irq()
582 host->mrq, msk_int, idma_int); in sunxi_mmc_irq()
584 mrq = host->mrq; in sunxi_mmc_irq()
587 host->wait_dma = false; in sunxi_mmc_irq()
589 host->int_sum |= msk_int; in sunxi_mmc_irq()
592 if ((host->int_sum & SDXC_RESP_TIMEOUT) && in sunxi_mmc_irq()
593 !(host->int_sum & SDXC_COMMAND_DONE)) in sunxi_mmc_irq()
595 host->sdio_imask | SDXC_COMMAND_DONE); in sunxi_mmc_irq()
597 else if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) in sunxi_mmc_irq()
599 else if ((host->int_sum & SDXC_INTERRUPT_DONE_BIT) && in sunxi_mmc_irq()
600 !host->wait_dma) in sunxi_mmc_irq()
613 spin_unlock(&host->lock); in sunxi_mmc_irq()
616 mmc_request_done(host->mmc, mrq); in sunxi_mmc_irq()
619 mmc_signal_sdio_irq(host->mmc); in sunxi_mmc_irq()
630 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
631 mrq = host->manual_stop_mrq; in sunxi_mmc_handle_manual_stop()
632 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
635 dev_err(mmc_dev(host->mmc), "no request for manual stop\n"); in sunxi_mmc_handle_manual_stop()
639 dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); in sunxi_mmc_handle_manual_stop()
644 * we've cleared host->manual_stop_mrq so we do not need to in sunxi_mmc_handle_manual_stop()
651 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
652 host->manual_stop_mrq = NULL; in sunxi_mmc_handle_manual_stop()
653 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
655 mmc_request_done(host->mmc, mrq); in sunxi_mmc_handle_manual_stop()
665 dev_dbg(mmc_dev(host->mmc), "%sabling the clock\n", in sunxi_mmc_oclk_onoff()
673 if (host->cfg->mask_data0) in sunxi_mmc_oclk_onoff()
690 dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n"); in sunxi_mmc_oclk_onoff()
691 return -EIO; in sunxi_mmc_oclk_onoff()
694 if (host->cfg->mask_data0) { in sunxi_mmc_oclk_onoff()
704 if (!host->cfg->can_calibrate) in sunxi_mmc_calibrate()
716 writel(SDXC_CAL_DL_SW_EN, host->reg_base + reg_off); in sunxi_mmc_calibrate()
727 if (host->use_new_timings) in sunxi_mmc_clk_set_phase()
731 if (!host->cfg->clk_delays) in sunxi_mmc_clk_set_phase()
740 if (ios->timing != MMC_TIMING_UHS_DDR50 && in sunxi_mmc_clk_set_phase()
741 ios->timing != MMC_TIMING_MMC_DDR52) { in sunxi_mmc_clk_set_phase()
743 } else if (ios->bus_width == MMC_BUS_WIDTH_8) { in sunxi_mmc_clk_set_phase()
749 dev_dbg(mmc_dev(host->mmc), "Invalid clock... returning\n"); in sunxi_mmc_clk_set_phase()
750 return -EINVAL; in sunxi_mmc_clk_set_phase()
753 clk_set_phase(host->clk_sample, host->cfg->clk_delays[index].sample); in sunxi_mmc_clk_set_phase()
754 clk_set_phase(host->clk_output, host->cfg->clk_delays[index].output); in sunxi_mmc_clk_set_phase()
762 struct mmc_host *mmc = host->mmc; in sunxi_mmc_clk_set_rate()
764 u32 rval, clock = ios->clock, div = 1; in sunxi_mmc_clk_set_rate()
772 mmc->actual_clock = 0; in sunxi_mmc_clk_set_rate()
774 if (!ios->clock) in sunxi_mmc_clk_set_rate()
786 if (ios->timing == MMC_TIMING_MMC_DDR52 && in sunxi_mmc_clk_set_rate()
787 (host->use_new_timings || in sunxi_mmc_clk_set_rate()
788 ios->bus_width == MMC_BUS_WIDTH_8)) { in sunxi_mmc_clk_set_rate()
793 if (host->use_new_timings && host->cfg->ccu_has_timings_switch) { in sunxi_mmc_clk_set_rate()
794 ret = sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); in sunxi_mmc_clk_set_rate()
802 rate = clk_round_rate(host->clk_mmc, clock); in sunxi_mmc_clk_set_rate()
812 ret = clk_set_rate(host->clk_mmc, rate); in sunxi_mmc_clk_set_rate()
822 rval |= div - 1; in sunxi_mmc_clk_set_rate()
834 if (host->use_new_timings) { in sunxi_mmc_clk_set_rate()
863 mmc->actual_clock = rate; in sunxi_mmc_clk_set_rate()
890 if (ios->timing == MMC_TIMING_UHS_DDR50 || in sunxi_mmc_set_clk()
891 ios->timing == MMC_TIMING_MMC_DDR52) in sunxi_mmc_set_clk()
897 host->ferror = sunxi_mmc_clk_set_rate(host, ios); in sunxi_mmc_set_clk()
904 struct mmc_host *mmc = host->mmc; in sunxi_mmc_card_power()
906 switch (ios->power_mode) { in sunxi_mmc_card_power()
910 if (!IS_ERR(mmc->supply.vmmc)) { in sunxi_mmc_card_power()
911 host->ferror = mmc_regulator_set_ocr(mmc, in sunxi_mmc_card_power()
912 mmc->supply.vmmc, in sunxi_mmc_card_power()
913 ios->vdd); in sunxi_mmc_card_power()
914 if (host->ferror) in sunxi_mmc_card_power()
918 if (!IS_ERR(mmc->supply.vqmmc)) { in sunxi_mmc_card_power()
919 host->ferror = regulator_enable(mmc->supply.vqmmc); in sunxi_mmc_card_power()
920 if (host->ferror) { in sunxi_mmc_card_power()
925 host->vqmmc_enabled = true; in sunxi_mmc_card_power()
932 if (!IS_ERR(mmc->supply.vmmc)) in sunxi_mmc_card_power()
933 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); in sunxi_mmc_card_power()
935 if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) in sunxi_mmc_card_power()
936 regulator_disable(mmc->supply.vqmmc); in sunxi_mmc_card_power()
938 host->vqmmc_enabled = false; in sunxi_mmc_card_power()
952 sunxi_mmc_set_bus_width(host, ios->bus_width); in sunxi_mmc_set_ios()
961 if (!IS_ERR(mmc->supply.vqmmc)) { in sunxi_mmc_volt_switch()
967 if (mmc->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) in sunxi_mmc_volt_switch()
970 return -EINVAL; in sunxi_mmc_volt_switch()
980 pm_runtime_get_noresume(host->dev); in sunxi_mmc_enable_sdio_irq()
982 spin_lock_irqsave(&host->lock, flags); in sunxi_mmc_enable_sdio_irq()
986 host->sdio_imask = SDXC_SDIO_INTERRUPT; in sunxi_mmc_enable_sdio_irq()
989 host->sdio_imask = 0; in sunxi_mmc_enable_sdio_irq()
993 spin_unlock_irqrestore(&host->lock, flags); in sunxi_mmc_enable_sdio_irq()
996 pm_runtime_put_noidle(host->mmc->parent); in sunxi_mmc_enable_sdio_irq()
1011 struct mmc_command *cmd = mrq->cmd; in sunxi_mmc_request()
1012 struct mmc_data *data = mrq->data; in sunxi_mmc_request()
1015 u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); in sunxi_mmc_request()
1016 bool wait_dma = host->wait_dma; in sunxi_mmc_request()
1020 if (host->ferror) { in sunxi_mmc_request()
1021 mrq->cmd->error = host->ferror; in sunxi_mmc_request()
1030 cmd->error = ret; in sunxi_mmc_request()
1031 data->error = ret; in sunxi_mmc_request()
1037 if (cmd->opcode == MMC_GO_IDLE_STATE) { in sunxi_mmc_request()
1042 if (cmd->flags & MMC_RSP_PRESENT) { in sunxi_mmc_request()
1044 if (cmd->flags & MMC_RSP_136) in sunxi_mmc_request()
1046 if (cmd->flags & MMC_RSP_CRC) in sunxi_mmc_request()
1049 if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) { in sunxi_mmc_request()
1052 if (cmd->data->stop) { in sunxi_mmc_request()
1059 if (cmd->data->flags & MMC_DATA_WRITE) in sunxi_mmc_request()
1071 cmd_val & 0x3f, cmd_val, cmd->arg, imask, in sunxi_mmc_request()
1072 mrq->data ? mrq->data->blksz * mrq->data->blocks : 0); in sunxi_mmc_request()
1074 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_request()
1076 if (host->mrq || host->manual_stop_mrq) { in sunxi_mmc_request()
1077 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_request()
1080 dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, in sunxi_mmc_request()
1084 mrq->cmd->error = -EBUSY; in sunxi_mmc_request()
1090 mmc_writel(host, REG_BLKSZ, data->blksz); in sunxi_mmc_request()
1091 mmc_writel(host, REG_BCNTR, data->blksz * data->blocks); in sunxi_mmc_request()
1095 host->mrq = mrq; in sunxi_mmc_request()
1096 host->wait_dma = wait_dma; in sunxi_mmc_request()
1097 mmc_writel(host, REG_IMASK, host->sdio_imask | imask); in sunxi_mmc_request()
1098 mmc_writel(host, REG_CARG, cmd->arg); in sunxi_mmc_request()
1101 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_request()
1203 { .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
1204 { .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
1205 { .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg },
1206 { .compatible = "allwinner,sun8i-a83t-emmc", .data = &sun8i_a83t_emmc_cfg },
1207 { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg },
1208 { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg },
1209 { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
1210 { .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
1211 { .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
1220 if (!IS_ERR(host->reset)) { in sunxi_mmc_enable()
1221 ret = reset_control_reset(host->reset); in sunxi_mmc_enable()
1223 dev_err(host->dev, "Couldn't reset the MMC controller (%d)\n", in sunxi_mmc_enable()
1229 ret = clk_prepare_enable(host->clk_ahb); in sunxi_mmc_enable()
1231 dev_err(host->dev, "Couldn't enable the bus clocks (%d)\n", ret); in sunxi_mmc_enable()
1235 ret = clk_prepare_enable(host->clk_mmc); in sunxi_mmc_enable()
1237 dev_err(host->dev, "Enable mmc clk err %d\n", ret); in sunxi_mmc_enable()
1241 ret = clk_prepare_enable(host->clk_output); in sunxi_mmc_enable()
1243 dev_err(host->dev, "Enable output clk err %d\n", ret); in sunxi_mmc_enable()
1247 ret = clk_prepare_enable(host->clk_sample); in sunxi_mmc_enable()
1249 dev_err(host->dev, "Enable sample clk err %d\n", ret); in sunxi_mmc_enable()
1264 clk_disable_unprepare(host->clk_sample); in sunxi_mmc_enable()
1266 clk_disable_unprepare(host->clk_output); in sunxi_mmc_enable()
1268 clk_disable_unprepare(host->clk_mmc); in sunxi_mmc_enable()
1270 clk_disable_unprepare(host->clk_ahb); in sunxi_mmc_enable()
1272 if (!IS_ERR(host->reset)) in sunxi_mmc_enable()
1273 reset_control_assert(host->reset); in sunxi_mmc_enable()
1281 clk_disable_unprepare(host->clk_sample); in sunxi_mmc_disable()
1282 clk_disable_unprepare(host->clk_output); in sunxi_mmc_disable()
1283 clk_disable_unprepare(host->clk_mmc); in sunxi_mmc_disable()
1284 clk_disable_unprepare(host->clk_ahb); in sunxi_mmc_disable()
1286 if (!IS_ERR(host->reset)) in sunxi_mmc_disable()
1287 reset_control_assert(host->reset); in sunxi_mmc_disable()
1295 host->cfg = of_device_get_match_data(&pdev->dev); in sunxi_mmc_resource_request()
1296 if (!host->cfg) in sunxi_mmc_resource_request()
1297 return -EINVAL; in sunxi_mmc_resource_request()
1299 ret = mmc_regulator_get_supply(host->mmc); in sunxi_mmc_resource_request()
1303 host->reg_base = devm_platform_ioremap_resource(pdev, 0); in sunxi_mmc_resource_request()
1304 if (IS_ERR(host->reg_base)) in sunxi_mmc_resource_request()
1305 return PTR_ERR(host->reg_base); in sunxi_mmc_resource_request()
1307 host->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in sunxi_mmc_resource_request()
1308 if (IS_ERR(host->clk_ahb)) { in sunxi_mmc_resource_request()
1309 dev_err(&pdev->dev, "Could not get ahb clock\n"); in sunxi_mmc_resource_request()
1310 return PTR_ERR(host->clk_ahb); in sunxi_mmc_resource_request()
1313 host->clk_mmc = devm_clk_get(&pdev->dev, "mmc"); in sunxi_mmc_resource_request()
1314 if (IS_ERR(host->clk_mmc)) { in sunxi_mmc_resource_request()
1315 dev_err(&pdev->dev, "Could not get mmc clock\n"); in sunxi_mmc_resource_request()
1316 return PTR_ERR(host->clk_mmc); in sunxi_mmc_resource_request()
1319 if (host->cfg->clk_delays) { in sunxi_mmc_resource_request()
1320 host->clk_output = devm_clk_get(&pdev->dev, "output"); in sunxi_mmc_resource_request()
1321 if (IS_ERR(host->clk_output)) { in sunxi_mmc_resource_request()
1322 dev_err(&pdev->dev, "Could not get output clock\n"); in sunxi_mmc_resource_request()
1323 return PTR_ERR(host->clk_output); in sunxi_mmc_resource_request()
1326 host->clk_sample = devm_clk_get(&pdev->dev, "sample"); in sunxi_mmc_resource_request()
1327 if (IS_ERR(host->clk_sample)) { in sunxi_mmc_resource_request()
1328 dev_err(&pdev->dev, "Could not get sample clock\n"); in sunxi_mmc_resource_request()
1329 return PTR_ERR(host->clk_sample); in sunxi_mmc_resource_request()
1333 host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev, in sunxi_mmc_resource_request()
1335 if (PTR_ERR(host->reset) == -EPROBE_DEFER) in sunxi_mmc_resource_request()
1336 return PTR_ERR(host->reset); in sunxi_mmc_resource_request()
1342 host->irq = platform_get_irq(pdev, 0); in sunxi_mmc_resource_request()
1343 if (host->irq <= 0) { in sunxi_mmc_resource_request()
1344 ret = -EINVAL; in sunxi_mmc_resource_request()
1348 return devm_request_threaded_irq(&pdev->dev, host->irq, sunxi_mmc_irq, in sunxi_mmc_resource_request()
1349 sunxi_mmc_handle_manual_stop, 0, "sunxi-mmc", host); in sunxi_mmc_resource_request()
1362 mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev); in sunxi_mmc_probe()
1364 dev_err(&pdev->dev, "mmc alloc host failed\n"); in sunxi_mmc_probe()
1365 return -ENOMEM; in sunxi_mmc_probe()
1370 host->dev = &pdev->dev; in sunxi_mmc_probe()
1371 host->mmc = mmc; in sunxi_mmc_probe()
1372 spin_lock_init(&host->lock); in sunxi_mmc_probe()
1378 host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, in sunxi_mmc_probe()
1379 &host->sg_dma, GFP_KERNEL); in sunxi_mmc_probe()
1380 if (!host->sg_cpu) { in sunxi_mmc_probe()
1381 dev_err(&pdev->dev, "Failed to allocate DMA descriptor mem\n"); in sunxi_mmc_probe()
1382 ret = -ENOMEM; in sunxi_mmc_probe()
1386 if (host->cfg->ccu_has_timings_switch) { in sunxi_mmc_probe()
1391 sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); in sunxi_mmc_probe()
1394 ret = sunxi_ccu_get_mmc_timing_mode(host->clk_mmc); in sunxi_mmc_probe()
1400 dev_warn(&pdev->dev, "MMC clk timing mode unknown\n"); in sunxi_mmc_probe()
1401 host->use_new_timings = false; in sunxi_mmc_probe()
1403 host->use_new_timings = !!ret; in sunxi_mmc_probe()
1405 } else if (host->cfg->needs_new_timings) { in sunxi_mmc_probe()
1407 host->use_new_timings = true; in sunxi_mmc_probe()
1410 mmc->ops = &sunxi_mmc_ops; in sunxi_mmc_probe()
1411 mmc->max_blk_count = 8192; in sunxi_mmc_probe()
1412 mmc->max_blk_size = 4096; in sunxi_mmc_probe()
1413 mmc->max_segs = PAGE_SIZE / sizeof(struct sunxi_idma_des); in sunxi_mmc_probe()
1414 mmc->max_seg_size = (1 << host->cfg->idma_des_size_bits); in sunxi_mmc_probe()
1415 mmc->max_req_size = mmc->max_seg_size * mmc->max_segs; in sunxi_mmc_probe()
1417 mmc->f_min = 400000; in sunxi_mmc_probe()
1418 mmc->f_max = 52000000; in sunxi_mmc_probe()
1419 mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | in sunxi_mmc_probe()
1429 if ((host->cfg->clk_delays || host->use_new_timings) && in sunxi_mmc_probe()
1430 !of_device_is_compatible(pdev->dev.of_node, in sunxi_mmc_probe()
1431 "allwinner,sun50i-h5-emmc")) in sunxi_mmc_probe()
1432 mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; in sunxi_mmc_probe()
1444 if (!(host->cfg->clk_delays || host->use_new_timings)) { in sunxi_mmc_probe()
1445 mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR | in sunxi_mmc_probe()
1447 mmc->caps2 &= ~MMC_CAP2_HS200; in sunxi_mmc_probe()
1451 mmc->caps2 &= ~MMC_CAP2_HS400; in sunxi_mmc_probe()
1457 pm_runtime_set_active(&pdev->dev); in sunxi_mmc_probe()
1458 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sunxi_mmc_probe()
1459 pm_runtime_use_autosuspend(&pdev->dev); in sunxi_mmc_probe()
1460 pm_runtime_enable(&pdev->dev); in sunxi_mmc_probe()
1466 dev_info(&pdev->dev, "initialized, max. request size: %u KB%s\n", in sunxi_mmc_probe()
1467 mmc->max_req_size >> 10, in sunxi_mmc_probe()
1468 host->use_new_timings ? ", uses new timings mode" : ""); in sunxi_mmc_probe()
1473 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); in sunxi_mmc_probe()
1485 pm_runtime_force_suspend(&pdev->dev); in sunxi_mmc_remove()
1486 disable_irq(host->irq); in sunxi_mmc_remove()
1488 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); in sunxi_mmc_remove()
1506 sunxi_mmc_set_bus_width(host, mmc->ios.bus_width); in sunxi_mmc_runtime_resume()
1507 sunxi_mmc_set_clk(host, &mmc->ios); in sunxi_mmc_runtime_resume()
1508 enable_irq(host->irq); in sunxi_mmc_runtime_resume()
1523 disable_irq(host->irq); in sunxi_mmc_runtime_suspend()
1541 .name = "sunxi-mmc",
1554 MODULE_ALIAS("platform:sunxi-mmc");