Lines Matching +full:sun5i +full:- +full:a13 +full:- +full:mmc
2 * Driver for sunxi SD/MMC host controllers
3 * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd.
4 * (C) Copyright 2007-2011 Aaron Maoye <leafy.myeh@reuuimllatech.com>
5 * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch>
6 * (C) Copyright 2013-2014 David Lanzendörfer <david.lanzendoerfer@o2s.ch>
7 * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com>
17 #include <linux/clk/sunxi-ng.h>
20 #include <linux/dma-mapping.h>
26 #include <linux/mmc/card.h>
27 #include <linux/mmc/core.h>
28 #include <linux/mmc/host.h>
29 #include <linux/mmc/mmc.h>
30 #include <linux/mmc/sd.h>
31 #include <linux/mmc/sdio.h>
32 #include <linux/mmc/slot-gpio.h>
83 readl((host)->reg_base + SDXC_##reg)
85 writel((value), (host)->reg_base + SDXC_##reg)
208 * If the idma-des-size-bits of property is ie 13, bufsize bits are:
209 * Bits 0-12: buf1 size
210 * Bits 13-25: buf2 size
211 * Bits 26-31: not used
220 #define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */
270 struct mmc_host *mmc; member
316 dev_err(mmc_dev(host->mmc), "fatal err reset timeout\n"); in sunxi_mmc_reset_host()
317 return -EIO; in sunxi_mmc_reset_host()
328 return -EIO; in sunxi_mmc_init_host()
339 mmc_writel(host, REG_IMASK, host->sdio_imask); in sunxi_mmc_init_host()
347 mmc_writel(host, REG_DLBA, host->sg_dma); in sunxi_mmc_init_host()
361 struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu; in sunxi_mmc_init_idma_des()
362 dma_addr_t next_desc = host->sg_dma; in sunxi_mmc_init_idma_des()
363 int i, max_len = (1 << host->cfg->idma_des_size_bits); in sunxi_mmc_init_idma_des()
365 for (i = 0; i < data->sg_len; i++) { in sunxi_mmc_init_idma_des()
370 if (data->sg[i].length == max_len) in sunxi_mmc_init_idma_des()
373 pdes[i].buf_size = cpu_to_le32(data->sg[i].length); in sunxi_mmc_init_idma_des()
377 cpu_to_le32(sg_dma_address(&data->sg[i])); in sunxi_mmc_init_idma_des()
382 pdes[i - 1].config |= cpu_to_le32(SDXC_IDMAC_DES0_LD | in sunxi_mmc_init_idma_des()
384 pdes[i - 1].config &= cpu_to_le32(~SDXC_IDMAC_DES0_DIC); in sunxi_mmc_init_idma_des()
385 pdes[i - 1].buf_addr_ptr2 = 0; in sunxi_mmc_init_idma_des()
388 * Avoid the io-store starting the idmac hitting io-mem before the in sunxi_mmc_init_idma_des()
389 * descriptors hit the main-mem. in sunxi_mmc_init_idma_des()
400 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, in sunxi_mmc_map_dma()
403 dev_err(mmc_dev(host->mmc), "dma_map_sg failed\n"); in sunxi_mmc_map_dma()
404 return -ENOMEM; in sunxi_mmc_map_dma()
407 for_each_sg(data->sg, sg, data->sg_len, i) { in sunxi_mmc_map_dma()
408 if (sg->offset & 3 || sg->length & 3) { in sunxi_mmc_map_dma()
409 dev_err(mmc_dev(host->mmc), in sunxi_mmc_map_dma()
411 sg->offset, sg->length); in sunxi_mmc_map_dma()
412 return -EINVAL; in sunxi_mmc_map_dma()
434 if (!(data->flags & MMC_DATA_WRITE)) in sunxi_mmc_start_dma()
450 if (req->cmd->opcode == SD_IO_RW_EXTENDED) { in sunxi_mmc_send_manual_stop()
453 ((req->cmd->arg >> 28) & 0x7); in sunxi_mmc_send_manual_stop()
468 dev_err(mmc_dev(host->mmc), "send stop command failed\n"); in sunxi_mmc_send_manual_stop()
469 if (req->stop) in sunxi_mmc_send_manual_stop()
470 req->stop->resp[0] = -ETIMEDOUT; in sunxi_mmc_send_manual_stop()
472 if (req->stop) in sunxi_mmc_send_manual_stop()
473 req->stop->resp[0] = mmc_readl(host, REG_RESP0); in sunxi_mmc_send_manual_stop()
481 struct mmc_command *cmd = host->mrq->cmd; in sunxi_mmc_dump_errinfo()
482 struct mmc_data *data = host->mrq->data; in sunxi_mmc_dump_errinfo()
484 /* For some cmds timeout is normal with sd/mmc cards */ in sunxi_mmc_dump_errinfo()
485 if ((host->int_sum & SDXC_INTERRUPT_ERROR_BIT) == in sunxi_mmc_dump_errinfo()
486 SDXC_RESP_TIMEOUT && (cmd->opcode == SD_IO_SEND_OP_COND || in sunxi_mmc_dump_errinfo()
487 cmd->opcode == SD_IO_RW_DIRECT)) in sunxi_mmc_dump_errinfo()
490 dev_dbg(mmc_dev(host->mmc), in sunxi_mmc_dump_errinfo()
492 host->mmc->index, cmd->opcode, in sunxi_mmc_dump_errinfo()
493 data ? (data->flags & MMC_DATA_WRITE ? " WR" : " RD") : "", in sunxi_mmc_dump_errinfo()
494 host->int_sum & SDXC_RESP_ERROR ? " RE" : "", in sunxi_mmc_dump_errinfo()
495 host->int_sum & SDXC_RESP_CRC_ERROR ? " RCE" : "", in sunxi_mmc_dump_errinfo()
496 host->int_sum & SDXC_DATA_CRC_ERROR ? " DCE" : "", in sunxi_mmc_dump_errinfo()
497 host->int_sum & SDXC_RESP_TIMEOUT ? " RTO" : "", in sunxi_mmc_dump_errinfo()
498 host->int_sum & SDXC_DATA_TIMEOUT ? " DTO" : "", in sunxi_mmc_dump_errinfo()
499 host->int_sum & SDXC_FIFO_RUN_ERROR ? " FE" : "", in sunxi_mmc_dump_errinfo()
500 host->int_sum & SDXC_HARD_WARE_LOCKED ? " HL" : "", in sunxi_mmc_dump_errinfo()
501 host->int_sum & SDXC_START_BIT_ERROR ? " SBE" : "", in sunxi_mmc_dump_errinfo()
502 host->int_sum & SDXC_END_BIT_ERROR ? " EBE" : "" in sunxi_mmc_dump_errinfo()
509 struct mmc_request *mrq = host->mrq; in sunxi_mmc_finalize_request()
510 struct mmc_data *data = mrq->data; in sunxi_mmc_finalize_request()
513 mmc_writel(host, REG_IMASK, host->sdio_imask); in sunxi_mmc_finalize_request()
516 if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) { in sunxi_mmc_finalize_request()
518 mrq->cmd->error = -ETIMEDOUT; in sunxi_mmc_finalize_request()
521 data->error = -ETIMEDOUT; in sunxi_mmc_finalize_request()
522 host->manual_stop_mrq = mrq; in sunxi_mmc_finalize_request()
525 if (mrq->stop) in sunxi_mmc_finalize_request()
526 mrq->stop->error = -ETIMEDOUT; in sunxi_mmc_finalize_request()
528 if (mrq->cmd->flags & MMC_RSP_136) { in sunxi_mmc_finalize_request()
529 mrq->cmd->resp[0] = mmc_readl(host, REG_RESP3); in sunxi_mmc_finalize_request()
530 mrq->cmd->resp[1] = mmc_readl(host, REG_RESP2); in sunxi_mmc_finalize_request()
531 mrq->cmd->resp[2] = mmc_readl(host, REG_RESP1); in sunxi_mmc_finalize_request()
532 mrq->cmd->resp[3] = mmc_readl(host, REG_RESP0); in sunxi_mmc_finalize_request()
534 mrq->cmd->resp[0] = mmc_readl(host, REG_RESP0); in sunxi_mmc_finalize_request()
538 data->bytes_xfered = data->blocks * data->blksz; in sunxi_mmc_finalize_request()
551 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, in sunxi_mmc_finalize_request()
557 host->mrq = NULL; in sunxi_mmc_finalize_request()
558 host->int_sum = 0; in sunxi_mmc_finalize_request()
559 host->wait_dma = false; in sunxi_mmc_finalize_request()
561 return host->manual_stop_mrq ? IRQ_WAKE_THREAD : IRQ_HANDLED; in sunxi_mmc_finalize_request()
573 spin_lock(&host->lock); in sunxi_mmc_irq()
578 dev_dbg(mmc_dev(host->mmc), "irq: rq %p mi %08x idi %08x\n", in sunxi_mmc_irq()
579 host->mrq, msk_int, idma_int); in sunxi_mmc_irq()
581 mrq = host->mrq; in sunxi_mmc_irq()
584 host->wait_dma = false; in sunxi_mmc_irq()
586 host->int_sum |= msk_int; in sunxi_mmc_irq()
589 if ((host->int_sum & SDXC_RESP_TIMEOUT) && in sunxi_mmc_irq()
590 !(host->int_sum & SDXC_COMMAND_DONE)) in sunxi_mmc_irq()
592 host->sdio_imask | SDXC_COMMAND_DONE); in sunxi_mmc_irq()
594 else if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) in sunxi_mmc_irq()
596 else if ((host->int_sum & SDXC_INTERRUPT_DONE_BIT) && in sunxi_mmc_irq()
597 !host->wait_dma) in sunxi_mmc_irq()
610 spin_unlock(&host->lock); in sunxi_mmc_irq()
613 mmc_request_done(host->mmc, mrq); in sunxi_mmc_irq()
616 mmc_signal_sdio_irq(host->mmc); in sunxi_mmc_irq()
627 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
628 mrq = host->manual_stop_mrq; in sunxi_mmc_handle_manual_stop()
629 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
632 dev_err(mmc_dev(host->mmc), "no request for manual stop\n"); in sunxi_mmc_handle_manual_stop()
636 dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); in sunxi_mmc_handle_manual_stop()
641 * we've cleared host->manual_stop_mrq so we do not need to in sunxi_mmc_handle_manual_stop()
648 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
649 host->manual_stop_mrq = NULL; in sunxi_mmc_handle_manual_stop()
650 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
652 mmc_request_done(host->mmc, mrq); in sunxi_mmc_handle_manual_stop()
662 dev_dbg(mmc_dev(host->mmc), "%sabling the clock\n", in sunxi_mmc_oclk_onoff()
670 if (host->cfg->mask_data0) in sunxi_mmc_oclk_onoff()
687 dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n"); in sunxi_mmc_oclk_onoff()
688 return -EIO; in sunxi_mmc_oclk_onoff()
691 if (host->cfg->mask_data0) { in sunxi_mmc_oclk_onoff()
701 if (!host->cfg->can_calibrate) in sunxi_mmc_calibrate()
713 writel(SDXC_CAL_DL_SW_EN, host->reg_base + reg_off); in sunxi_mmc_calibrate()
724 if (host->use_new_timings) in sunxi_mmc_clk_set_phase()
728 if (!host->cfg->clk_delays) in sunxi_mmc_clk_set_phase()
737 if (ios->timing != MMC_TIMING_UHS_DDR50 && in sunxi_mmc_clk_set_phase()
738 ios->timing != MMC_TIMING_MMC_DDR52) { in sunxi_mmc_clk_set_phase()
740 } else if (ios->bus_width == MMC_BUS_WIDTH_8) { in sunxi_mmc_clk_set_phase()
746 dev_dbg(mmc_dev(host->mmc), "Invalid clock... returning\n"); in sunxi_mmc_clk_set_phase()
747 return -EINVAL; in sunxi_mmc_clk_set_phase()
750 clk_set_phase(host->clk_sample, host->cfg->clk_delays[index].sample); in sunxi_mmc_clk_set_phase()
751 clk_set_phase(host->clk_output, host->cfg->clk_delays[index].output); in sunxi_mmc_clk_set_phase()
759 struct mmc_host *mmc = host->mmc; in sunxi_mmc_clk_set_rate() local
761 u32 rval, clock = ios->clock, div = 1; in sunxi_mmc_clk_set_rate()
769 mmc->actual_clock = 0; in sunxi_mmc_clk_set_rate()
771 if (!ios->clock) in sunxi_mmc_clk_set_rate()
779 * We currently only support the standard MMC DDR52 mode. in sunxi_mmc_clk_set_rate()
783 if (ios->timing == MMC_TIMING_MMC_DDR52 && in sunxi_mmc_clk_set_rate()
784 (host->use_new_timings || in sunxi_mmc_clk_set_rate()
785 ios->bus_width == MMC_BUS_WIDTH_8)) { in sunxi_mmc_clk_set_rate()
790 if (host->use_new_timings && host->cfg->has_timings_switch) { in sunxi_mmc_clk_set_rate()
791 ret = sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); in sunxi_mmc_clk_set_rate()
793 dev_err(mmc_dev(mmc), in sunxi_mmc_clk_set_rate()
799 rate = clk_round_rate(host->clk_mmc, clock); in sunxi_mmc_clk_set_rate()
801 dev_err(mmc_dev(mmc), "error rounding clk to %d: %ld\n", in sunxi_mmc_clk_set_rate()
805 dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n", in sunxi_mmc_clk_set_rate()
809 ret = clk_set_rate(host->clk_mmc, rate); in sunxi_mmc_clk_set_rate()
811 dev_err(mmc_dev(mmc), "error setting clk to %ld: %d\n", in sunxi_mmc_clk_set_rate()
819 rval |= div - 1; in sunxi_mmc_clk_set_rate()
825 if (host->use_new_timings) { in sunxi_mmc_clk_set_rate()
854 mmc->actual_clock = rate; in sunxi_mmc_clk_set_rate()
881 if (ios->timing == MMC_TIMING_UHS_DDR50 || in sunxi_mmc_set_clk()
882 ios->timing == MMC_TIMING_MMC_DDR52) in sunxi_mmc_set_clk()
888 host->ferror = sunxi_mmc_clk_set_rate(host, ios); in sunxi_mmc_set_clk()
895 struct mmc_host *mmc = host->mmc; in sunxi_mmc_card_power() local
897 switch (ios->power_mode) { in sunxi_mmc_card_power()
899 dev_dbg(mmc_dev(mmc), "Powering card up\n"); in sunxi_mmc_card_power()
901 if (!IS_ERR(mmc->supply.vmmc)) { in sunxi_mmc_card_power()
902 host->ferror = mmc_regulator_set_ocr(mmc, in sunxi_mmc_card_power()
903 mmc->supply.vmmc, in sunxi_mmc_card_power()
904 ios->vdd); in sunxi_mmc_card_power()
905 if (host->ferror) in sunxi_mmc_card_power()
909 if (!IS_ERR(mmc->supply.vqmmc)) { in sunxi_mmc_card_power()
910 host->ferror = regulator_enable(mmc->supply.vqmmc); in sunxi_mmc_card_power()
911 if (host->ferror) { in sunxi_mmc_card_power()
912 dev_err(mmc_dev(mmc), in sunxi_mmc_card_power()
916 host->vqmmc_enabled = true; in sunxi_mmc_card_power()
921 dev_dbg(mmc_dev(mmc), "Powering card off\n"); in sunxi_mmc_card_power()
923 if (!IS_ERR(mmc->supply.vmmc)) in sunxi_mmc_card_power()
924 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); in sunxi_mmc_card_power()
926 if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) in sunxi_mmc_card_power()
927 regulator_disable(mmc->supply.vqmmc); in sunxi_mmc_card_power()
929 host->vqmmc_enabled = false; in sunxi_mmc_card_power()
933 dev_dbg(mmc_dev(mmc), "Ignoring unknown card power state\n"); in sunxi_mmc_card_power()
938 static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) in sunxi_mmc_set_ios() argument
940 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_set_ios()
943 sunxi_mmc_set_bus_width(host, ios->bus_width); in sunxi_mmc_set_ios()
947 static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) in sunxi_mmc_volt_switch() argument
950 if (!IS_ERR(mmc->supply.vqmmc)) in sunxi_mmc_volt_switch()
951 return mmc_regulator_set_vqmmc(mmc, ios); in sunxi_mmc_volt_switch()
954 if (mmc->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) in sunxi_mmc_volt_switch()
957 return -EINVAL; in sunxi_mmc_volt_switch()
960 static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) in sunxi_mmc_enable_sdio_irq() argument
962 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_enable_sdio_irq()
967 pm_runtime_get_noresume(host->dev); in sunxi_mmc_enable_sdio_irq()
969 spin_lock_irqsave(&host->lock, flags); in sunxi_mmc_enable_sdio_irq()
973 host->sdio_imask = SDXC_SDIO_INTERRUPT; in sunxi_mmc_enable_sdio_irq()
976 host->sdio_imask = 0; in sunxi_mmc_enable_sdio_irq()
980 spin_unlock_irqrestore(&host->lock, flags); in sunxi_mmc_enable_sdio_irq()
983 pm_runtime_put_noidle(host->mmc->parent); in sunxi_mmc_enable_sdio_irq()
986 static void sunxi_mmc_hw_reset(struct mmc_host *mmc) in sunxi_mmc_hw_reset() argument
988 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_hw_reset()
995 static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) in sunxi_mmc_request() argument
997 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_request()
998 struct mmc_command *cmd = mrq->cmd; in sunxi_mmc_request()
999 struct mmc_data *data = mrq->data; in sunxi_mmc_request()
1002 u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); in sunxi_mmc_request()
1003 bool wait_dma = host->wait_dma; in sunxi_mmc_request()
1007 if (host->ferror) { in sunxi_mmc_request()
1008 mrq->cmd->error = host->ferror; in sunxi_mmc_request()
1009 mmc_request_done(mmc, mrq); in sunxi_mmc_request()
1016 dev_err(mmc_dev(mmc), "map DMA failed\n"); in sunxi_mmc_request()
1017 cmd->error = ret; in sunxi_mmc_request()
1018 data->error = ret; in sunxi_mmc_request()
1019 mmc_request_done(mmc, mrq); in sunxi_mmc_request()
1024 if (cmd->opcode == MMC_GO_IDLE_STATE) { in sunxi_mmc_request()
1029 if (cmd->flags & MMC_RSP_PRESENT) { in sunxi_mmc_request()
1031 if (cmd->flags & MMC_RSP_136) in sunxi_mmc_request()
1033 if (cmd->flags & MMC_RSP_CRC) in sunxi_mmc_request()
1036 if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) { in sunxi_mmc_request()
1039 if (cmd->data->stop) { in sunxi_mmc_request()
1046 if (cmd->data->flags & MMC_DATA_WRITE) in sunxi_mmc_request()
1057 dev_dbg(mmc_dev(mmc), "cmd %d(%08x) arg %x ie 0x%08x len %d\n", in sunxi_mmc_request()
1058 cmd_val & 0x3f, cmd_val, cmd->arg, imask, in sunxi_mmc_request()
1059 mrq->data ? mrq->data->blksz * mrq->data->blocks : 0); in sunxi_mmc_request()
1061 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_request()
1063 if (host->mrq || host->manual_stop_mrq) { in sunxi_mmc_request()
1064 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_request()
1067 dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, in sunxi_mmc_request()
1070 dev_err(mmc_dev(mmc), "request already pending\n"); in sunxi_mmc_request()
1071 mrq->cmd->error = -EBUSY; in sunxi_mmc_request()
1072 mmc_request_done(mmc, mrq); in sunxi_mmc_request()
1077 mmc_writel(host, REG_BLKSZ, data->blksz); in sunxi_mmc_request()
1078 mmc_writel(host, REG_BCNTR, data->blksz * data->blocks); in sunxi_mmc_request()
1082 host->mrq = mrq; in sunxi_mmc_request()
1083 host->wait_dma = wait_dma; in sunxi_mmc_request()
1084 mmc_writel(host, REG_IMASK, host->sdio_imask | imask); in sunxi_mmc_request()
1085 mmc_writel(host, REG_CARG, cmd->arg); in sunxi_mmc_request()
1088 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_request()
1091 static int sunxi_mmc_card_busy(struct mmc_host *mmc) in sunxi_mmc_card_busy() argument
1093 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_card_busy()
1172 { .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
1173 { .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
1174 { .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg },
1175 { .compatible = "allwinner,sun8i-a83t-emmc", .data = &sun8i_a83t_emmc_cfg },
1176 { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg },
1177 { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg },
1178 { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
1187 if (!IS_ERR(host->reset)) { in sunxi_mmc_enable()
1188 ret = reset_control_reset(host->reset); in sunxi_mmc_enable()
1190 dev_err(host->dev, "Couldn't reset the MMC controller (%d)\n", in sunxi_mmc_enable()
1196 ret = clk_prepare_enable(host->clk_ahb); in sunxi_mmc_enable()
1198 dev_err(host->dev, "Couldn't enable the bus clocks (%d)\n", ret); in sunxi_mmc_enable()
1202 ret = clk_prepare_enable(host->clk_mmc); in sunxi_mmc_enable()
1204 dev_err(host->dev, "Enable mmc clk err %d\n", ret); in sunxi_mmc_enable()
1208 ret = clk_prepare_enable(host->clk_output); in sunxi_mmc_enable()
1210 dev_err(host->dev, "Enable output clk err %d\n", ret); in sunxi_mmc_enable()
1214 ret = clk_prepare_enable(host->clk_sample); in sunxi_mmc_enable()
1216 dev_err(host->dev, "Enable sample clk err %d\n", ret); in sunxi_mmc_enable()
1231 clk_disable_unprepare(host->clk_sample); in sunxi_mmc_enable()
1233 clk_disable_unprepare(host->clk_output); in sunxi_mmc_enable()
1235 clk_disable_unprepare(host->clk_mmc); in sunxi_mmc_enable()
1237 clk_disable_unprepare(host->clk_ahb); in sunxi_mmc_enable()
1239 if (!IS_ERR(host->reset)) in sunxi_mmc_enable()
1240 reset_control_assert(host->reset); in sunxi_mmc_enable()
1248 clk_disable_unprepare(host->clk_sample); in sunxi_mmc_disable()
1249 clk_disable_unprepare(host->clk_output); in sunxi_mmc_disable()
1250 clk_disable_unprepare(host->clk_mmc); in sunxi_mmc_disable()
1251 clk_disable_unprepare(host->clk_ahb); in sunxi_mmc_disable()
1253 if (!IS_ERR(host->reset)) in sunxi_mmc_disable()
1254 reset_control_assert(host->reset); in sunxi_mmc_disable()
1262 host->cfg = of_device_get_match_data(&pdev->dev); in sunxi_mmc_resource_request()
1263 if (!host->cfg) in sunxi_mmc_resource_request()
1264 return -EINVAL; in sunxi_mmc_resource_request()
1266 ret = mmc_regulator_get_supply(host->mmc); in sunxi_mmc_resource_request()
1270 host->reg_base = devm_ioremap_resource(&pdev->dev, in sunxi_mmc_resource_request()
1272 if (IS_ERR(host->reg_base)) in sunxi_mmc_resource_request()
1273 return PTR_ERR(host->reg_base); in sunxi_mmc_resource_request()
1275 host->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in sunxi_mmc_resource_request()
1276 if (IS_ERR(host->clk_ahb)) { in sunxi_mmc_resource_request()
1277 dev_err(&pdev->dev, "Could not get ahb clock\n"); in sunxi_mmc_resource_request()
1278 return PTR_ERR(host->clk_ahb); in sunxi_mmc_resource_request()
1281 host->clk_mmc = devm_clk_get(&pdev->dev, "mmc"); in sunxi_mmc_resource_request()
1282 if (IS_ERR(host->clk_mmc)) { in sunxi_mmc_resource_request()
1283 dev_err(&pdev->dev, "Could not get mmc clock\n"); in sunxi_mmc_resource_request()
1284 return PTR_ERR(host->clk_mmc); in sunxi_mmc_resource_request()
1287 if (host->cfg->clk_delays) { in sunxi_mmc_resource_request()
1288 host->clk_output = devm_clk_get(&pdev->dev, "output"); in sunxi_mmc_resource_request()
1289 if (IS_ERR(host->clk_output)) { in sunxi_mmc_resource_request()
1290 dev_err(&pdev->dev, "Could not get output clock\n"); in sunxi_mmc_resource_request()
1291 return PTR_ERR(host->clk_output); in sunxi_mmc_resource_request()
1294 host->clk_sample = devm_clk_get(&pdev->dev, "sample"); in sunxi_mmc_resource_request()
1295 if (IS_ERR(host->clk_sample)) { in sunxi_mmc_resource_request()
1296 dev_err(&pdev->dev, "Could not get sample clock\n"); in sunxi_mmc_resource_request()
1297 return PTR_ERR(host->clk_sample); in sunxi_mmc_resource_request()
1301 host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev, in sunxi_mmc_resource_request()
1303 if (PTR_ERR(host->reset) == -EPROBE_DEFER) in sunxi_mmc_resource_request()
1304 return PTR_ERR(host->reset); in sunxi_mmc_resource_request()
1310 host->irq = platform_get_irq(pdev, 0); in sunxi_mmc_resource_request()
1311 if (host->irq <= 0) { in sunxi_mmc_resource_request()
1312 ret = -EINVAL; in sunxi_mmc_resource_request()
1316 return devm_request_threaded_irq(&pdev->dev, host->irq, sunxi_mmc_irq, in sunxi_mmc_resource_request()
1317 sunxi_mmc_handle_manual_stop, 0, "sunxi-mmc", host); in sunxi_mmc_resource_request()
1327 struct mmc_host *mmc; in sunxi_mmc_probe() local
1330 mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev); in sunxi_mmc_probe()
1331 if (!mmc) { in sunxi_mmc_probe()
1332 dev_err(&pdev->dev, "mmc alloc host failed\n"); in sunxi_mmc_probe()
1333 return -ENOMEM; in sunxi_mmc_probe()
1335 platform_set_drvdata(pdev, mmc); in sunxi_mmc_probe()
1337 host = mmc_priv(mmc); in sunxi_mmc_probe()
1338 host->dev = &pdev->dev; in sunxi_mmc_probe()
1339 host->mmc = mmc; in sunxi_mmc_probe()
1340 spin_lock_init(&host->lock); in sunxi_mmc_probe()
1346 host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, in sunxi_mmc_probe()
1347 &host->sg_dma, GFP_KERNEL); in sunxi_mmc_probe()
1348 if (!host->sg_cpu) { in sunxi_mmc_probe()
1349 dev_err(&pdev->dev, "Failed to allocate DMA descriptor mem\n"); in sunxi_mmc_probe()
1350 ret = -ENOMEM; in sunxi_mmc_probe()
1354 if (host->cfg->has_timings_switch) { in sunxi_mmc_probe()
1359 sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); in sunxi_mmc_probe()
1362 ret = sunxi_ccu_get_mmc_timing_mode(host->clk_mmc); in sunxi_mmc_probe()
1368 dev_warn(&pdev->dev, "MMC clk timing mode unknown\n"); in sunxi_mmc_probe()
1369 host->use_new_timings = false; in sunxi_mmc_probe()
1371 host->use_new_timings = !!ret; in sunxi_mmc_probe()
1373 } else if (host->cfg->needs_new_timings) { in sunxi_mmc_probe()
1375 host->use_new_timings = true; in sunxi_mmc_probe()
1378 mmc->ops = &sunxi_mmc_ops; in sunxi_mmc_probe()
1379 mmc->max_blk_count = 8192; in sunxi_mmc_probe()
1380 mmc->max_blk_size = 4096; in sunxi_mmc_probe()
1381 mmc->max_segs = PAGE_SIZE / sizeof(struct sunxi_idma_des); in sunxi_mmc_probe()
1382 mmc->max_seg_size = (1 << host->cfg->idma_des_size_bits); in sunxi_mmc_probe()
1383 mmc->max_req_size = mmc->max_seg_size * mmc->max_segs; in sunxi_mmc_probe()
1385 mmc->f_min = 400000; in sunxi_mmc_probe()
1386 mmc->f_max = 52000000; in sunxi_mmc_probe()
1387 mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | in sunxi_mmc_probe()
1390 if (host->cfg->clk_delays || host->use_new_timings) in sunxi_mmc_probe()
1391 mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; in sunxi_mmc_probe()
1393 ret = mmc_of_parse(mmc); in sunxi_mmc_probe()
1403 if (!(host->cfg->clk_delays || host->use_new_timings)) { in sunxi_mmc_probe()
1404 mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR | in sunxi_mmc_probe()
1406 mmc->caps2 &= ~MMC_CAP2_HS200; in sunxi_mmc_probe()
1410 mmc->caps2 &= ~MMC_CAP2_HS400; in sunxi_mmc_probe()
1416 pm_runtime_set_active(&pdev->dev); in sunxi_mmc_probe()
1417 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sunxi_mmc_probe()
1418 pm_runtime_use_autosuspend(&pdev->dev); in sunxi_mmc_probe()
1419 pm_runtime_enable(&pdev->dev); in sunxi_mmc_probe()
1421 ret = mmc_add_host(mmc); in sunxi_mmc_probe()
1425 dev_info(&pdev->dev, "initialized, max. request size: %u KB%s\n", in sunxi_mmc_probe()
1426 mmc->max_req_size >> 10, in sunxi_mmc_probe()
1427 host->use_new_timings ? ", uses new timings mode" : ""); in sunxi_mmc_probe()
1432 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); in sunxi_mmc_probe()
1434 mmc_free_host(mmc); in sunxi_mmc_probe()
1440 struct mmc_host *mmc = platform_get_drvdata(pdev); in sunxi_mmc_remove() local
1441 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_remove()
1443 mmc_remove_host(mmc); in sunxi_mmc_remove()
1444 pm_runtime_force_suspend(&pdev->dev); in sunxi_mmc_remove()
1445 disable_irq(host->irq); in sunxi_mmc_remove()
1447 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); in sunxi_mmc_remove()
1448 mmc_free_host(mmc); in sunxi_mmc_remove()
1456 struct mmc_host *mmc = dev_get_drvdata(dev); in sunxi_mmc_runtime_resume() local
1457 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_runtime_resume()
1465 sunxi_mmc_set_bus_width(host, mmc->ios.bus_width); in sunxi_mmc_runtime_resume()
1466 sunxi_mmc_set_clk(host, &mmc->ios); in sunxi_mmc_runtime_resume()
1467 enable_irq(host->irq); in sunxi_mmc_runtime_resume()
1474 struct mmc_host *mmc = dev_get_drvdata(dev); in sunxi_mmc_runtime_suspend() local
1475 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_runtime_suspend()
1482 disable_irq(host->irq); in sunxi_mmc_runtime_suspend()
1498 .name = "sunxi-mmc",
1507 MODULE_DESCRIPTION("Allwinner's SD/MMC Card Controller Driver");
1510 MODULE_ALIAS("platform:sunxi-mmc");