Lines Matching refs:host
107 static bool dw_mci_reset(struct dw_mci *host);
108 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
121 spin_lock_bh(&slot->host->lock); in dw_mci_req_show()
147 spin_unlock_bh(&slot->host->lock); in dw_mci_req_show()
193 struct dw_mci *host = slot->host; in dw_mci_init_debugfs() local
201 node = debugfs_create_file("regs", S_IRUSR, root, host, in dw_mci_init_debugfs()
211 node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state); in dw_mci_init_debugfs()
216 (u32 *)&host->pending_events); in dw_mci_init_debugfs()
221 (u32 *)&host->completed_events); in dw_mci_init_debugfs()
238 struct dw_mci *host = slot->host; in dw_mci_prepare_command() local
239 const struct dw_mci_drv_data *drv_data = slot->host->drv_data; in dw_mci_prepare_command()
261 WARN_ON(slot->host->state != STATE_SENDING_CMD); in dw_mci_prepare_command()
262 slot->host->state = STATE_SENDING_CMD11; in dw_mci_prepare_command()
275 clk_en_a = mci_readl(host, CLKENA); in dw_mci_prepare_command()
277 mci_writel(host, CLKENA, clk_en_a); in dw_mci_prepare_command()
302 drv_data->prepare_command(slot->host, &cmdr); in dw_mci_prepare_command()
307 static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd) in dw_mci_prep_stop_abort() argument
315 stop = &host->stop_abort; in dw_mci_prep_stop_abort()
343 static void dw_mci_wait_while_busy(struct dw_mci *host, u32 cmd_flags) in dw_mci_wait_while_busy() argument
357 while (mci_readl(host, STATUS) & SDMMC_STATUS_BUSY) { in dw_mci_wait_while_busy()
360 dev_err(host->dev, "Busy; trying anyway\n"); in dw_mci_wait_while_busy()
368 static void dw_mci_start_command(struct dw_mci *host, in dw_mci_start_command() argument
371 host->cmd = cmd; in dw_mci_start_command()
372 dev_vdbg(host->dev, in dw_mci_start_command()
376 mci_writel(host, CMDARG, cmd->arg); in dw_mci_start_command()
378 dw_mci_wait_while_busy(host, cmd_flags); in dw_mci_start_command()
380 mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START); in dw_mci_start_command()
383 static inline void send_stop_abort(struct dw_mci *host, struct mmc_data *data) in send_stop_abort() argument
385 struct mmc_command *stop = data->stop ? data->stop : &host->stop_abort; in send_stop_abort()
386 dw_mci_start_command(host, stop, host->stop_cmdr); in send_stop_abort()
390 static void dw_mci_stop_dma(struct dw_mci *host) in dw_mci_stop_dma() argument
392 if (host->using_dma) { in dw_mci_stop_dma()
393 host->dma_ops->stop(host); in dw_mci_stop_dma()
394 host->dma_ops->cleanup(host); in dw_mci_stop_dma()
398 set_bit(EVENT_XFER_COMPLETE, &host->pending_events); in dw_mci_stop_dma()
410 static void dw_mci_dma_cleanup(struct dw_mci *host) in dw_mci_dma_cleanup() argument
412 struct mmc_data *data = host->data; in dw_mci_dma_cleanup()
416 dma_unmap_sg(host->dev, in dw_mci_dma_cleanup()
422 static void dw_mci_idmac_reset(struct dw_mci *host) in dw_mci_idmac_reset() argument
424 u32 bmod = mci_readl(host, BMOD); in dw_mci_idmac_reset()
427 mci_writel(host, BMOD, bmod); in dw_mci_idmac_reset()
430 static void dw_mci_idmac_stop_dma(struct dw_mci *host) in dw_mci_idmac_stop_dma() argument
435 temp = mci_readl(host, CTRL); in dw_mci_idmac_stop_dma()
438 mci_writel(host, CTRL, temp); in dw_mci_idmac_stop_dma()
441 temp = mci_readl(host, BMOD); in dw_mci_idmac_stop_dma()
444 mci_writel(host, BMOD, temp); in dw_mci_idmac_stop_dma()
447 static void dw_mci_idmac_complete_dma(struct dw_mci *host) in dw_mci_idmac_complete_dma() argument
449 struct mmc_data *data = host->data; in dw_mci_idmac_complete_dma()
451 dev_vdbg(host->dev, "DMA complete\n"); in dw_mci_idmac_complete_dma()
453 host->dma_ops->cleanup(host); in dw_mci_idmac_complete_dma()
460 set_bit(EVENT_XFER_COMPLETE, &host->pending_events); in dw_mci_idmac_complete_dma()
461 tasklet_schedule(&host->tasklet); in dw_mci_idmac_complete_dma()
465 static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, in dw_mci_translate_sglist() argument
470 if (host->dma_64bit_address == 1) { in dw_mci_translate_sglist()
473 desc_first = desc_last = desc = host->sg_cpu; in dw_mci_translate_sglist()
517 desc_first = desc_last = desc = host->sg_cpu; in dw_mci_translate_sglist()
563 static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) in dw_mci_idmac_start_dma() argument
567 dw_mci_translate_sglist(host, host->data, sg_len); in dw_mci_idmac_start_dma()
570 dw_mci_ctrl_reset(host, SDMMC_CTRL_DMA_RESET); in dw_mci_idmac_start_dma()
571 dw_mci_idmac_reset(host); in dw_mci_idmac_start_dma()
574 temp = mci_readl(host, CTRL); in dw_mci_idmac_start_dma()
576 mci_writel(host, CTRL, temp); in dw_mci_idmac_start_dma()
581 temp = mci_readl(host, BMOD); in dw_mci_idmac_start_dma()
583 mci_writel(host, BMOD, temp); in dw_mci_idmac_start_dma()
586 mci_writel(host, PLDMND, 1); in dw_mci_idmac_start_dma()
589 static int dw_mci_idmac_init(struct dw_mci *host) in dw_mci_idmac_init() argument
593 if (host->dma_64bit_address == 1) { in dw_mci_idmac_init()
596 host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc_64addr); in dw_mci_idmac_init()
599 for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; in dw_mci_idmac_init()
601 p->des6 = (host->sg_dma + in dw_mci_idmac_init()
605 p->des7 = (u64)(host->sg_dma + in dw_mci_idmac_init()
615 p->des6 = host->sg_dma & 0xffffffff; in dw_mci_idmac_init()
616 p->des7 = (u64)host->sg_dma >> 32; in dw_mci_idmac_init()
622 host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); in dw_mci_idmac_init()
625 for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) { in dw_mci_idmac_init()
626 p->des3 = cpu_to_le32(host->sg_dma + in dw_mci_idmac_init()
632 p->des3 = cpu_to_le32(host->sg_dma); in dw_mci_idmac_init()
636 dw_mci_idmac_reset(host); in dw_mci_idmac_init()
638 if (host->dma_64bit_address == 1) { in dw_mci_idmac_init()
640 mci_writel(host, IDSTS64, IDMAC_INT_CLR); in dw_mci_idmac_init()
641 mci_writel(host, IDINTEN64, SDMMC_IDMAC_INT_NI | in dw_mci_idmac_init()
645 mci_writel(host, DBADDRL, host->sg_dma & 0xffffffff); in dw_mci_idmac_init()
646 mci_writel(host, DBADDRU, (u64)host->sg_dma >> 32); in dw_mci_idmac_init()
650 mci_writel(host, IDSTS, IDMAC_INT_CLR); in dw_mci_idmac_init()
651 mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | in dw_mci_idmac_init()
655 mci_writel(host, DBADDR, host->sg_dma); in dw_mci_idmac_init()
670 static int dw_mci_pre_dma_transfer(struct dw_mci *host, in dw_mci_pre_dma_transfer() argument
696 sg_len = dma_map_sg(host->dev, in dw_mci_pre_dma_transfer()
716 if (!slot->host->use_dma || !data) in dw_mci_pre_req()
724 if (dw_mci_pre_dma_transfer(slot->host, mrq->data, 1) < 0) in dw_mci_pre_req()
735 if (!slot->host->use_dma || !data) in dw_mci_post_req()
739 dma_unmap_sg(slot->host->dev, in dw_mci_post_req()
746 static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data) in dw_mci_adjust_fifoth() argument
751 u32 fifo_width = 1 << host->data_shift; in dw_mci_adjust_fifoth()
756 tx_wmark = (host->fifo_depth) / 2; in dw_mci_adjust_fifoth()
757 tx_wmark_invers = host->fifo_depth - tx_wmark; in dw_mci_adjust_fifoth()
783 mci_writel(host, FIFOTH, fifoth_val); in dw_mci_adjust_fifoth()
787 static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data) in dw_mci_ctrl_rd_thld() argument
799 if (host->verid < DW_MMC_240A) in dw_mci_ctrl_rd_thld()
802 if (host->timing != MMC_TIMING_MMC_HS200 && in dw_mci_ctrl_rd_thld()
803 host->timing != MMC_TIMING_MMC_HS400 && in dw_mci_ctrl_rd_thld()
804 host->timing != MMC_TIMING_UHS_SDR104) in dw_mci_ctrl_rd_thld()
807 blksz_depth = blksz / (1 << host->data_shift); in dw_mci_ctrl_rd_thld()
808 fifo_depth = host->fifo_depth; in dw_mci_ctrl_rd_thld()
819 mci_writel(host, CDTHRCTL, SDMMC_SET_RD_THLD(thld_size, 1)); in dw_mci_ctrl_rd_thld()
823 mci_writel(host, CDTHRCTL, SDMMC_SET_RD_THLD(0, 0)); in dw_mci_ctrl_rd_thld()
826 static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) in dw_mci_submit_data_dma() argument
832 host->using_dma = 0; in dw_mci_submit_data_dma()
835 if (!host->use_dma) in dw_mci_submit_data_dma()
838 sg_len = dw_mci_pre_dma_transfer(host, data, 0); in dw_mci_submit_data_dma()
840 host->dma_ops->stop(host); in dw_mci_submit_data_dma()
844 host->using_dma = 1; in dw_mci_submit_data_dma()
846 dev_vdbg(host->dev, in dw_mci_submit_data_dma()
848 (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma, in dw_mci_submit_data_dma()
856 if (host->prev_blksz != data->blksz) in dw_mci_submit_data_dma()
857 dw_mci_adjust_fifoth(host, data); in dw_mci_submit_data_dma()
860 temp = mci_readl(host, CTRL); in dw_mci_submit_data_dma()
862 mci_writel(host, CTRL, temp); in dw_mci_submit_data_dma()
865 spin_lock_irqsave(&host->irq_lock, irqflags); in dw_mci_submit_data_dma()
866 temp = mci_readl(host, INTMASK); in dw_mci_submit_data_dma()
868 mci_writel(host, INTMASK, temp); in dw_mci_submit_data_dma()
869 spin_unlock_irqrestore(&host->irq_lock, irqflags); in dw_mci_submit_data_dma()
871 host->dma_ops->start(host, sg_len); in dw_mci_submit_data_dma()
876 static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) in dw_mci_submit_data() argument
883 WARN_ON(host->data); in dw_mci_submit_data()
884 host->sg = NULL; in dw_mci_submit_data()
885 host->data = data; in dw_mci_submit_data()
888 host->dir_status = DW_MCI_RECV_STATUS; in dw_mci_submit_data()
889 dw_mci_ctrl_rd_thld(host, data); in dw_mci_submit_data()
891 host->dir_status = DW_MCI_SEND_STATUS; in dw_mci_submit_data()
894 if (dw_mci_submit_data_dma(host, data)) { in dw_mci_submit_data()
896 if (host->data->flags & MMC_DATA_READ) in dw_mci_submit_data()
901 sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); in dw_mci_submit_data()
902 host->sg = data->sg; in dw_mci_submit_data()
903 host->part_buf_start = 0; in dw_mci_submit_data()
904 host->part_buf_count = 0; in dw_mci_submit_data()
906 mci_writel(host, RINTSTS, SDMMC_INT_TXDR | SDMMC_INT_RXDR); in dw_mci_submit_data()
908 spin_lock_irqsave(&host->irq_lock, irqflags); in dw_mci_submit_data()
909 temp = mci_readl(host, INTMASK); in dw_mci_submit_data()
911 mci_writel(host, INTMASK, temp); in dw_mci_submit_data()
912 spin_unlock_irqrestore(&host->irq_lock, irqflags); in dw_mci_submit_data()
914 temp = mci_readl(host, CTRL); in dw_mci_submit_data()
916 mci_writel(host, CTRL, temp); in dw_mci_submit_data()
923 mci_writel(host, FIFOTH, host->fifoth_val); in dw_mci_submit_data()
924 host->prev_blksz = 0; in dw_mci_submit_data()
931 host->prev_blksz = data->blksz; in dw_mci_submit_data()
937 struct dw_mci *host = slot->host; in mci_send_cmd() local
941 mci_writel(host, CMDARG, arg); in mci_send_cmd()
943 dw_mci_wait_while_busy(host, cmd); in mci_send_cmd()
944 mci_writel(host, CMD, SDMMC_CMD_START | cmd); in mci_send_cmd()
947 cmd_status = mci_readl(host, CMD); in mci_send_cmd()
958 struct dw_mci *host = slot->host; in dw_mci_setup_bus() local
965 if (host->state == STATE_WAITING_CMD11_DONE) in dw_mci_setup_bus()
969 mci_writel(host, CLKENA, 0); in dw_mci_setup_bus()
971 } else if (clock != host->current_speed || force_clkinit) { in dw_mci_setup_bus()
972 div = host->bus_hz / clock; in dw_mci_setup_bus()
973 if (host->bus_hz % clock && host->bus_hz > clock) in dw_mci_setup_bus()
980 div = (host->bus_hz != clock) ? DIV_ROUND_UP(div, 2) : 0; in dw_mci_setup_bus()
985 slot->id, host->bus_hz, clock, in dw_mci_setup_bus()
986 div ? ((host->bus_hz / div) >> 1) : in dw_mci_setup_bus()
987 host->bus_hz, div); in dw_mci_setup_bus()
990 mci_writel(host, CLKENA, 0); in dw_mci_setup_bus()
991 mci_writel(host, CLKSRC, 0); in dw_mci_setup_bus()
997 mci_writel(host, CLKDIV, div); in dw_mci_setup_bus()
1006 mci_writel(host, CLKENA, clk_en_a); in dw_mci_setup_bus()
1015 host->current_speed = clock; in dw_mci_setup_bus()
1018 mci_writel(host, CTYPE, (slot->ctype << slot->id)); in dw_mci_setup_bus()
1021 static void __dw_mci_start_request(struct dw_mci *host, in __dw_mci_start_request() argument
1031 host->cur_slot = slot; in __dw_mci_start_request()
1032 host->mrq = mrq; in __dw_mci_start_request()
1034 host->pending_events = 0; in __dw_mci_start_request()
1035 host->completed_events = 0; in __dw_mci_start_request()
1036 host->cmd_status = 0; in __dw_mci_start_request()
1037 host->data_status = 0; in __dw_mci_start_request()
1038 host->dir_status = 0; in __dw_mci_start_request()
1042 mci_writel(host, TMOUT, 0xFFFFFFFF); in __dw_mci_start_request()
1043 mci_writel(host, BYTCNT, data->blksz*data->blocks); in __dw_mci_start_request()
1044 mci_writel(host, BLKSIZ, data->blksz); in __dw_mci_start_request()
1054 dw_mci_submit_data(host, data); in __dw_mci_start_request()
1058 dw_mci_start_command(host, cmd, cmdflags); in __dw_mci_start_request()
1073 spin_lock_irqsave(&host->irq_lock, irqflags); in __dw_mci_start_request()
1074 if (!test_bit(EVENT_CMD_COMPLETE, &host->pending_events)) in __dw_mci_start_request()
1075 mod_timer(&host->cmd11_timer, in __dw_mci_start_request()
1077 spin_unlock_irqrestore(&host->irq_lock, irqflags); in __dw_mci_start_request()
1081 host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); in __dw_mci_start_request()
1083 host->stop_cmdr = dw_mci_prep_stop_abort(host, cmd); in __dw_mci_start_request()
1086 static void dw_mci_start_request(struct dw_mci *host, in dw_mci_start_request() argument
1093 __dw_mci_start_request(host, slot, cmd); in dw_mci_start_request()
1097 static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, in dw_mci_queue_request() argument
1101 host->state); in dw_mci_queue_request()
1105 if (host->state == STATE_WAITING_CMD11_DONE) { in dw_mci_queue_request()
1113 host->state = STATE_IDLE; in dw_mci_queue_request()
1116 if (host->state == STATE_IDLE) { in dw_mci_queue_request()
1117 host->state = STATE_SENDING_CMD; in dw_mci_queue_request()
1118 dw_mci_start_request(host, slot); in dw_mci_queue_request()
1120 list_add_tail(&slot->queue_node, &host->queue); in dw_mci_queue_request()
1127 struct dw_mci *host = slot->host; in dw_mci_request() local
1136 spin_lock_bh(&host->lock); in dw_mci_request()
1139 spin_unlock_bh(&host->lock); in dw_mci_request()
1145 dw_mci_queue_request(host, slot, mrq); in dw_mci_request()
1147 spin_unlock_bh(&host->lock); in dw_mci_request()
1153 const struct dw_mci_drv_data *drv_data = slot->host->drv_data; in dw_mci_set_ios()
1169 regs = mci_readl(slot->host, UHS_REG); in dw_mci_set_ios()
1178 mci_writel(slot->host, UHS_REG, regs); in dw_mci_set_ios()
1179 slot->host->timing = ios->timing; in dw_mci_set_ios()
1188 drv_data->set_ios(slot->host, ios); in dw_mci_set_ios()
1196 dev_err(slot->host->dev, in dw_mci_set_ios()
1203 regs = mci_readl(slot->host, PWREN); in dw_mci_set_ios()
1205 mci_writel(slot->host, PWREN, regs); in dw_mci_set_ios()
1208 if (!slot->host->vqmmc_enabled) { in dw_mci_set_ios()
1212 dev_err(slot->host->dev, in dw_mci_set_ios()
1215 slot->host->vqmmc_enabled = true; in dw_mci_set_ios()
1219 slot->host->vqmmc_enabled = true; in dw_mci_set_ios()
1223 dw_mci_ctrl_reset(slot->host, in dw_mci_set_ios()
1238 if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled) in dw_mci_set_ios()
1240 slot->host->vqmmc_enabled = false; in dw_mci_set_ios()
1242 regs = mci_readl(slot->host, PWREN); in dw_mci_set_ios()
1244 mci_writel(slot->host, PWREN, regs); in dw_mci_set_ios()
1250 if (slot->host->state == STATE_WAITING_CMD11_DONE && ios->clock != 0) in dw_mci_set_ios()
1251 slot->host->state = STATE_IDLE; in dw_mci_set_ios()
1263 status = mci_readl(slot->host, STATUS); in dw_mci_card_busy()
1271 struct dw_mci *host = slot->host; in dw_mci_switch_voltage() local
1282 uhs = mci_readl(host, UHS_REG); in dw_mci_switch_voltage()
1302 mci_writel(host, UHS_REG, uhs); in dw_mci_switch_voltage()
1315 (slot->host->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT)) in dw_mci_get_ro()
1321 mci_readl(slot->host, WRTPRT) & (1 << slot->id) ? 1 : 0; in dw_mci_get_ro()
1333 struct dw_mci_board *brd = slot->host->pdata; in dw_mci_get_cd()
1334 struct dw_mci *host = slot->host; in dw_mci_get_cd() local
1344 present = (mci_readl(slot->host, CDETECT) & (1 << slot->id)) in dw_mci_get_cd()
1347 spin_lock_bh(&host->lock); in dw_mci_get_cd()
1355 spin_unlock_bh(&host->lock); in dw_mci_get_cd()
1363 struct dw_mci *host = slot->host; in dw_mci_init_card() local
1375 clk_en_a_old = mci_readl(host, CLKENA); in dw_mci_init_card()
1387 mci_writel(host, CLKENA, clk_en_a); in dw_mci_init_card()
1397 struct dw_mci *host = slot->host; in dw_mci_enable_sdio_irq() local
1401 spin_lock_irqsave(&host->irq_lock, irqflags); in dw_mci_enable_sdio_irq()
1404 int_mask = mci_readl(host, INTMASK); in dw_mci_enable_sdio_irq()
1409 mci_writel(host, INTMASK, int_mask); in dw_mci_enable_sdio_irq()
1411 spin_unlock_irqrestore(&host->irq_lock, irqflags); in dw_mci_enable_sdio_irq()
1417 struct dw_mci *host = slot->host; in dw_mci_execute_tuning() local
1418 const struct dw_mci_drv_data *drv_data = host->drv_data; in dw_mci_execute_tuning()
1429 struct dw_mci *host = slot->host; in dw_mci_prepare_hs400_tuning() local
1430 const struct dw_mci_drv_data *drv_data = host->drv_data; in dw_mci_prepare_hs400_tuning()
1433 return drv_data->prepare_hs400_tuning(host, ios); in dw_mci_prepare_hs400_tuning()
1453 static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) in dw_mci_request_end() argument
1454 __releases(&host->lock) in dw_mci_request_end()
1455 __acquires(&host->lock) in dw_mci_request_end()
1458 struct mmc_host *prev_mmc = host->cur_slot->mmc; in dw_mci_request_end()
1460 WARN_ON(host->cmd || host->data); in dw_mci_request_end()
1462 host->cur_slot->mrq = NULL; in dw_mci_request_end()
1463 host->mrq = NULL; in dw_mci_request_end()
1464 if (!list_empty(&host->queue)) { in dw_mci_request_end()
1465 slot = list_entry(host->queue.next, in dw_mci_request_end()
1468 dev_vdbg(host->dev, "list not empty: %s is next\n", in dw_mci_request_end()
1470 host->state = STATE_SENDING_CMD; in dw_mci_request_end()
1471 dw_mci_start_request(host, slot); in dw_mci_request_end()
1473 dev_vdbg(host->dev, "list empty\n"); in dw_mci_request_end()
1475 if (host->state == STATE_SENDING_CMD11) in dw_mci_request_end()
1476 host->state = STATE_WAITING_CMD11_DONE; in dw_mci_request_end()
1478 host->state = STATE_IDLE; in dw_mci_request_end()
1481 spin_unlock(&host->lock); in dw_mci_request_end()
1483 spin_lock(&host->lock); in dw_mci_request_end()
1486 static int dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd) in dw_mci_command_complete() argument
1488 u32 status = host->cmd_status; in dw_mci_command_complete()
1490 host->cmd_status = 0; in dw_mci_command_complete()
1495 cmd->resp[3] = mci_readl(host, RESP0); in dw_mci_command_complete()
1496 cmd->resp[2] = mci_readl(host, RESP1); in dw_mci_command_complete()
1497 cmd->resp[1] = mci_readl(host, RESP2); in dw_mci_command_complete()
1498 cmd->resp[0] = mci_readl(host, RESP3); in dw_mci_command_complete()
1500 cmd->resp[0] = mci_readl(host, RESP0); in dw_mci_command_complete()
1518 if (host->quirks & DW_MCI_QUIRK_RETRY_DELAY) in dw_mci_command_complete()
1525 static int dw_mci_data_complete(struct dw_mci *host, struct mmc_data *data) in dw_mci_data_complete() argument
1527 u32 status = host->data_status; in dw_mci_data_complete()
1535 if (host->dir_status == in dw_mci_data_complete()
1544 } else if (host->dir_status == in dw_mci_data_complete()
1553 dev_dbg(host->dev, "data error, status 0x%08x\n", status); in dw_mci_data_complete()
1559 dw_mci_reset(host); in dw_mci_data_complete()
1570 struct dw_mci *host = (struct dw_mci *)priv; in dw_mci_tasklet_func() local
1578 spin_lock(&host->lock); in dw_mci_tasklet_func()
1580 state = host->state; in dw_mci_tasklet_func()
1581 data = host->data; in dw_mci_tasklet_func()
1582 mrq = host->mrq; in dw_mci_tasklet_func()
1595 &host->pending_events)) in dw_mci_tasklet_func()
1598 cmd = host->cmd; in dw_mci_tasklet_func()
1599 host->cmd = NULL; in dw_mci_tasklet_func()
1600 set_bit(EVENT_CMD_COMPLETE, &host->completed_events); in dw_mci_tasklet_func()
1601 err = dw_mci_command_complete(host, cmd); in dw_mci_tasklet_func()
1604 __dw_mci_start_request(host, host->cur_slot, in dw_mci_tasklet_func()
1610 dw_mci_stop_dma(host); in dw_mci_tasklet_func()
1611 send_stop_abort(host, data); in dw_mci_tasklet_func()
1617 dw_mci_request_end(host, mrq); in dw_mci_tasklet_func()
1634 &host->pending_events)) { in dw_mci_tasklet_func()
1635 dw_mci_stop_dma(host); in dw_mci_tasklet_func()
1637 !(host->data_status & (SDMMC_INT_DRTO | in dw_mci_tasklet_func()
1639 send_stop_abort(host, data); in dw_mci_tasklet_func()
1645 &host->pending_events)) in dw_mci_tasklet_func()
1648 set_bit(EVENT_XFER_COMPLETE, &host->completed_events); in dw_mci_tasklet_func()
1664 &host->pending_events)) { in dw_mci_tasklet_func()
1665 dw_mci_stop_dma(host); in dw_mci_tasklet_func()
1667 !(host->data_status & (SDMMC_INT_DRTO | in dw_mci_tasklet_func()
1669 send_stop_abort(host, data); in dw_mci_tasklet_func()
1679 &host->pending_events)) in dw_mci_tasklet_func()
1682 host->data = NULL; in dw_mci_tasklet_func()
1683 set_bit(EVENT_DATA_COMPLETE, &host->completed_events); in dw_mci_tasklet_func()
1684 err = dw_mci_data_complete(host, data); in dw_mci_tasklet_func()
1690 dw_mci_request_end(host, mrq); in dw_mci_tasklet_func()
1696 send_stop_abort(host, data); in dw_mci_tasklet_func()
1708 &host->pending_events)) { in dw_mci_tasklet_func()
1709 host->cmd = NULL; in dw_mci_tasklet_func()
1710 dw_mci_request_end(host, mrq); in dw_mci_tasklet_func()
1725 &host->pending_events)) in dw_mci_tasklet_func()
1730 dw_mci_reset(host); in dw_mci_tasklet_func()
1732 host->cmd = NULL; in dw_mci_tasklet_func()
1733 host->data = NULL; in dw_mci_tasklet_func()
1736 dw_mci_command_complete(host, mrq->stop); in dw_mci_tasklet_func()
1738 host->cmd_status = 0; in dw_mci_tasklet_func()
1740 dw_mci_request_end(host, mrq); in dw_mci_tasklet_func()
1745 &host->pending_events)) in dw_mci_tasklet_func()
1753 host->state = state; in dw_mci_tasklet_func()
1755 spin_unlock(&host->lock); in dw_mci_tasklet_func()
1760 static void dw_mci_set_part_bytes(struct dw_mci *host, void *buf, int cnt) in dw_mci_set_part_bytes() argument
1762 memcpy((void *)&host->part_buf, buf, cnt); in dw_mci_set_part_bytes()
1763 host->part_buf_count = cnt; in dw_mci_set_part_bytes()
1767 static int dw_mci_push_part_bytes(struct dw_mci *host, void *buf, int cnt) in dw_mci_push_part_bytes() argument
1769 cnt = min(cnt, (1 << host->data_shift) - host->part_buf_count); in dw_mci_push_part_bytes()
1770 memcpy((void *)&host->part_buf + host->part_buf_count, buf, cnt); in dw_mci_push_part_bytes()
1771 host->part_buf_count += cnt; in dw_mci_push_part_bytes()
1776 static int dw_mci_pull_part_bytes(struct dw_mci *host, void *buf, int cnt) in dw_mci_pull_part_bytes() argument
1778 cnt = min(cnt, (int)host->part_buf_count); in dw_mci_pull_part_bytes()
1780 memcpy(buf, (void *)&host->part_buf + host->part_buf_start, in dw_mci_pull_part_bytes()
1782 host->part_buf_count -= cnt; in dw_mci_pull_part_bytes()
1783 host->part_buf_start += cnt; in dw_mci_pull_part_bytes()
1789 static void dw_mci_pull_final_bytes(struct dw_mci *host, void *buf, int cnt) in dw_mci_pull_final_bytes() argument
1791 memcpy(buf, &host->part_buf, cnt); in dw_mci_pull_final_bytes()
1792 host->part_buf_start = cnt; in dw_mci_pull_final_bytes()
1793 host->part_buf_count = (1 << host->data_shift) - cnt; in dw_mci_pull_final_bytes()
1796 static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt) in dw_mci_push_data16() argument
1798 struct mmc_data *data = host->data; in dw_mci_push_data16()
1802 if (unlikely(host->part_buf_count)) { in dw_mci_push_data16()
1803 int len = dw_mci_push_part_bytes(host, buf, cnt); in dw_mci_push_data16()
1806 if (host->part_buf_count == 2) { in dw_mci_push_data16()
1807 mci_fifo_writew(host->fifo_reg, host->part_buf16); in dw_mci_push_data16()
1808 host->part_buf_count = 0; in dw_mci_push_data16()
1824 mci_fifo_writew(host->fifo_reg, aligned_buf[i]); in dw_mci_push_data16()
1831 mci_fifo_writew(host->fifo_reg, *pdata++); in dw_mci_push_data16()
1836 dw_mci_set_part_bytes(host, buf, cnt); in dw_mci_push_data16()
1840 mci_fifo_writew(host->fifo_reg, host->part_buf16); in dw_mci_push_data16()
1844 static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt) in dw_mci_pull_data16() argument
1855 aligned_buf[i] = mci_fifo_readw(host->fifo_reg); in dw_mci_pull_data16()
1866 *pdata++ = mci_fifo_readw(host->fifo_reg); in dw_mci_pull_data16()
1870 host->part_buf16 = mci_fifo_readw(host->fifo_reg); in dw_mci_pull_data16()
1871 dw_mci_pull_final_bytes(host, buf, cnt); in dw_mci_pull_data16()
1875 static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt) in dw_mci_push_data32() argument
1877 struct mmc_data *data = host->data; in dw_mci_push_data32()
1881 if (unlikely(host->part_buf_count)) { in dw_mci_push_data32()
1882 int len = dw_mci_push_part_bytes(host, buf, cnt); in dw_mci_push_data32()
1885 if (host->part_buf_count == 4) { in dw_mci_push_data32()
1886 mci_fifo_writel(host->fifo_reg, host->part_buf32); in dw_mci_push_data32()
1887 host->part_buf_count = 0; in dw_mci_push_data32()
1903 mci_fifo_writel(host->fifo_reg, aligned_buf[i]); in dw_mci_push_data32()
1910 mci_fifo_writel(host->fifo_reg, *pdata++); in dw_mci_push_data32()
1915 dw_mci_set_part_bytes(host, buf, cnt); in dw_mci_push_data32()
1919 mci_fifo_writel(host->fifo_reg, host->part_buf32); in dw_mci_push_data32()
1923 static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt) in dw_mci_pull_data32() argument
1934 aligned_buf[i] = mci_fifo_readl(host->fifo_reg); in dw_mci_pull_data32()
1945 *pdata++ = mci_fifo_readl(host->fifo_reg); in dw_mci_pull_data32()
1949 host->part_buf32 = mci_fifo_readl(host->fifo_reg); in dw_mci_pull_data32()
1950 dw_mci_pull_final_bytes(host, buf, cnt); in dw_mci_pull_data32()
1954 static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt) in dw_mci_push_data64() argument
1956 struct mmc_data *data = host->data; in dw_mci_push_data64()
1960 if (unlikely(host->part_buf_count)) { in dw_mci_push_data64()
1961 int len = dw_mci_push_part_bytes(host, buf, cnt); in dw_mci_push_data64()
1965 if (host->part_buf_count == 8) { in dw_mci_push_data64()
1966 mci_fifo_writeq(host->fifo_reg, host->part_buf); in dw_mci_push_data64()
1967 host->part_buf_count = 0; in dw_mci_push_data64()
1983 mci_fifo_writeq(host->fifo_reg, aligned_buf[i]); in dw_mci_push_data64()
1990 mci_fifo_writeq(host->fifo_reg, *pdata++); in dw_mci_push_data64()
1995 dw_mci_set_part_bytes(host, buf, cnt); in dw_mci_push_data64()
1999 mci_fifo_writeq(host->fifo_reg, host->part_buf); in dw_mci_push_data64()
2003 static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt) in dw_mci_pull_data64() argument
2014 aligned_buf[i] = mci_fifo_readq(host->fifo_reg); in dw_mci_pull_data64()
2026 *pdata++ = mci_fifo_readq(host->fifo_reg); in dw_mci_pull_data64()
2030 host->part_buf = mci_fifo_readq(host->fifo_reg); in dw_mci_pull_data64()
2031 dw_mci_pull_final_bytes(host, buf, cnt); in dw_mci_pull_data64()
2035 static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) in dw_mci_pull_data() argument
2040 len = dw_mci_pull_part_bytes(host, buf, cnt); in dw_mci_pull_data()
2047 host->pull_data(host, buf, cnt); in dw_mci_pull_data()
2050 static void dw_mci_read_data_pio(struct dw_mci *host, bool dto) in dw_mci_read_data_pio() argument
2052 struct sg_mapping_iter *sg_miter = &host->sg_miter; in dw_mci_read_data_pio()
2055 struct mmc_data *data = host->data; in dw_mci_read_data_pio()
2056 int shift = host->data_shift; in dw_mci_read_data_pio()
2065 host->sg = sg_miter->piter.sg; in dw_mci_read_data_pio()
2071 fcnt = (SDMMC_GET_FCNT(mci_readl(host, STATUS)) in dw_mci_read_data_pio()
2072 << shift) + host->part_buf_count; in dw_mci_read_data_pio()
2076 dw_mci_pull_data(host, (void *)(buf + offset), len); in dw_mci_read_data_pio()
2083 status = mci_readl(host, MINTSTS); in dw_mci_read_data_pio()
2084 mci_writel(host, RINTSTS, SDMMC_INT_RXDR); in dw_mci_read_data_pio()
2087 (dto && SDMMC_GET_FCNT(mci_readl(host, STATUS)))); in dw_mci_read_data_pio()
2099 host->sg = NULL; in dw_mci_read_data_pio()
2101 set_bit(EVENT_XFER_COMPLETE, &host->pending_events); in dw_mci_read_data_pio()
2104 static void dw_mci_write_data_pio(struct dw_mci *host) in dw_mci_write_data_pio() argument
2106 struct sg_mapping_iter *sg_miter = &host->sg_miter; in dw_mci_write_data_pio()
2109 struct mmc_data *data = host->data; in dw_mci_write_data_pio()
2110 int shift = host->data_shift; in dw_mci_write_data_pio()
2113 unsigned int fifo_depth = host->fifo_depth; in dw_mci_write_data_pio()
2120 host->sg = sg_miter->piter.sg; in dw_mci_write_data_pio()
2127 SDMMC_GET_FCNT(mci_readl(host, STATUS))) in dw_mci_write_data_pio()
2128 << shift) - host->part_buf_count; in dw_mci_write_data_pio()
2132 host->push_data(host, (void *)(buf + offset), len); in dw_mci_write_data_pio()
2139 status = mci_readl(host, MINTSTS); in dw_mci_write_data_pio()
2140 mci_writel(host, RINTSTS, SDMMC_INT_TXDR); in dw_mci_write_data_pio()
2153 host->sg = NULL; in dw_mci_write_data_pio()
2155 set_bit(EVENT_XFER_COMPLETE, &host->pending_events); in dw_mci_write_data_pio()
2158 static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) in dw_mci_cmd_interrupt() argument
2160 if (!host->cmd_status) in dw_mci_cmd_interrupt()
2161 host->cmd_status = status; in dw_mci_cmd_interrupt()
2165 set_bit(EVENT_CMD_COMPLETE, &host->pending_events); in dw_mci_cmd_interrupt()
2166 tasklet_schedule(&host->tasklet); in dw_mci_cmd_interrupt()
2169 static void dw_mci_handle_cd(struct dw_mci *host) in dw_mci_handle_cd() argument
2173 for (i = 0; i < host->num_slots; i++) { in dw_mci_handle_cd()
2174 struct dw_mci_slot *slot = host->slot[i]; in dw_mci_handle_cd()
2182 msecs_to_jiffies(host->pdata->detect_delay_ms)); in dw_mci_handle_cd()
2188 struct dw_mci *host = dev_id; in dw_mci_interrupt() local
2192 pending = mci_readl(host, MINTSTS); /* read-only mask reg */ in dw_mci_interrupt()
2198 if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) { in dw_mci_interrupt()
2200 ((mci_readl(host, STATUS) >> 17) & 0x1fff)) in dw_mci_interrupt()
2206 if ((host->state == STATE_SENDING_CMD11) && in dw_mci_interrupt()
2210 mci_writel(host, RINTSTS, SDMMC_INT_VOLT_SWITCH); in dw_mci_interrupt()
2217 spin_lock_irqsave(&host->irq_lock, irqflags); in dw_mci_interrupt()
2218 dw_mci_cmd_interrupt(host, pending); in dw_mci_interrupt()
2219 spin_unlock_irqrestore(&host->irq_lock, irqflags); in dw_mci_interrupt()
2221 del_timer(&host->cmd11_timer); in dw_mci_interrupt()
2225 mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); in dw_mci_interrupt()
2226 host->cmd_status = pending; in dw_mci_interrupt()
2228 set_bit(EVENT_CMD_COMPLETE, &host->pending_events); in dw_mci_interrupt()
2233 mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); in dw_mci_interrupt()
2234 host->data_status = pending; in dw_mci_interrupt()
2236 set_bit(EVENT_DATA_ERROR, &host->pending_events); in dw_mci_interrupt()
2237 tasklet_schedule(&host->tasklet); in dw_mci_interrupt()
2241 mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); in dw_mci_interrupt()
2242 if (!host->data_status) in dw_mci_interrupt()
2243 host->data_status = pending; in dw_mci_interrupt()
2245 if (host->dir_status == DW_MCI_RECV_STATUS) { in dw_mci_interrupt()
2246 if (host->sg != NULL) in dw_mci_interrupt()
2247 dw_mci_read_data_pio(host, true); in dw_mci_interrupt()
2249 set_bit(EVENT_DATA_COMPLETE, &host->pending_events); in dw_mci_interrupt()
2250 tasklet_schedule(&host->tasklet); in dw_mci_interrupt()
2254 mci_writel(host, RINTSTS, SDMMC_INT_RXDR); in dw_mci_interrupt()
2255 if (host->dir_status == DW_MCI_RECV_STATUS && host->sg) in dw_mci_interrupt()
2256 dw_mci_read_data_pio(host, false); in dw_mci_interrupt()
2260 mci_writel(host, RINTSTS, SDMMC_INT_TXDR); in dw_mci_interrupt()
2261 if (host->dir_status == DW_MCI_SEND_STATUS && host->sg) in dw_mci_interrupt()
2262 dw_mci_write_data_pio(host); in dw_mci_interrupt()
2266 mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); in dw_mci_interrupt()
2267 dw_mci_cmd_interrupt(host, pending); in dw_mci_interrupt()
2271 mci_writel(host, RINTSTS, SDMMC_INT_CD); in dw_mci_interrupt()
2272 dw_mci_handle_cd(host); in dw_mci_interrupt()
2276 for (i = 0; i < host->num_slots; i++) { in dw_mci_interrupt()
2277 struct dw_mci_slot *slot = host->slot[i]; in dw_mci_interrupt()
2283 mci_writel(host, RINTSTS, in dw_mci_interrupt()
2293 if (host->dma_64bit_address == 1) { in dw_mci_interrupt()
2294 pending = mci_readl(host, IDSTS64); in dw_mci_interrupt()
2296 mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI | in dw_mci_interrupt()
2298 mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI); in dw_mci_interrupt()
2299 host->dma_ops->complete(host); in dw_mci_interrupt()
2302 pending = mci_readl(host, IDSTS); in dw_mci_interrupt()
2304 mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | in dw_mci_interrupt()
2306 mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); in dw_mci_interrupt()
2307 host->dma_ops->complete(host); in dw_mci_interrupt()
2369 static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) in dw_mci_init_slot() argument
2373 const struct dw_mci_drv_data *drv_data = host->drv_data; in dw_mci_init_slot()
2377 mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev); in dw_mci_init_slot()
2383 slot->sdio_id = host->sdio_id0 + id; in dw_mci_init_slot()
2385 slot->host = host; in dw_mci_init_slot()
2386 host->slot[id] = slot; in dw_mci_init_slot()
2388 slot->quirks = dw_mci_of_get_slot_quirks(host->dev, slot->id); in dw_mci_init_slot()
2391 if (of_property_read_u32_array(host->dev->of_node, in dw_mci_init_slot()
2408 if (host->pdata->caps) in dw_mci_init_slot()
2409 mmc->caps = host->pdata->caps; in dw_mci_init_slot()
2411 if (host->pdata->pm_caps) in dw_mci_init_slot()
2412 mmc->pm_caps = host->pdata->pm_caps; in dw_mci_init_slot()
2414 if (host->dev->of_node) { in dw_mci_init_slot()
2415 ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); in dw_mci_init_slot()
2419 ctrl_id = to_platform_device(host->dev)->id; in dw_mci_init_slot()
2424 if (host->pdata->caps2) in dw_mci_init_slot()
2425 mmc->caps2 = host->pdata->caps2; in dw_mci_init_slot()
2431 if (host->pdata->blk_settings) { in dw_mci_init_slot()
2432 mmc->max_segs = host->pdata->blk_settings->max_segs; in dw_mci_init_slot()
2433 mmc->max_blk_size = host->pdata->blk_settings->max_blk_size; in dw_mci_init_slot()
2434 mmc->max_blk_count = host->pdata->blk_settings->max_blk_count; in dw_mci_init_slot()
2435 mmc->max_req_size = host->pdata->blk_settings->max_req_size; in dw_mci_init_slot()
2436 mmc->max_seg_size = host->pdata->blk_settings->max_seg_size; in dw_mci_init_slot()
2440 mmc->max_segs = host->ring_size; in dw_mci_init_slot()
2443 mmc->max_req_size = mmc->max_seg_size * host->ring_size; in dw_mci_init_slot()
2478 slot->host->slot[id] = NULL; in dw_mci_cleanup_slot()
2482 static void dw_mci_init_dma(struct dw_mci *host) in dw_mci_init_dma() argument
2486 addr_config = (mci_readl(host, HCON) >> 27) & 0x01; in dw_mci_init_dma()
2490 host->dma_64bit_address = 1; in dw_mci_init_dma()
2491 dev_info(host->dev, "IDMAC supports 64-bit address mode.\n"); in dw_mci_init_dma()
2492 if (!dma_set_mask(host->dev, DMA_BIT_MASK(64))) in dw_mci_init_dma()
2493 dma_set_coherent_mask(host->dev, DMA_BIT_MASK(64)); in dw_mci_init_dma()
2496 host->dma_64bit_address = 0; in dw_mci_init_dma()
2497 dev_info(host->dev, "IDMAC supports 32-bit address mode.\n"); in dw_mci_init_dma()
2501 host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE, in dw_mci_init_dma()
2502 &host->sg_dma, GFP_KERNEL); in dw_mci_init_dma()
2503 if (!host->sg_cpu) { in dw_mci_init_dma()
2504 dev_err(host->dev, "%s: could not alloc DMA memory\n", in dw_mci_init_dma()
2511 host->dma_ops = &dw_mci_idmac_ops; in dw_mci_init_dma()
2512 dev_info(host->dev, "Using internal DMA controller.\n"); in dw_mci_init_dma()
2515 if (!host->dma_ops) in dw_mci_init_dma()
2518 if (host->dma_ops->init && host->dma_ops->start && in dw_mci_init_dma()
2519 host->dma_ops->stop && host->dma_ops->cleanup) { in dw_mci_init_dma()
2520 if (host->dma_ops->init(host)) { in dw_mci_init_dma()
2521 dev_err(host->dev, "%s: Unable to initialize " in dw_mci_init_dma()
2526 dev_err(host->dev, "DMA initialization not found.\n"); in dw_mci_init_dma()
2530 host->use_dma = 1; in dw_mci_init_dma()
2534 dev_info(host->dev, "Using PIO mode.\n"); in dw_mci_init_dma()
2535 host->use_dma = 0; in dw_mci_init_dma()
2539 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset) in dw_mci_ctrl_reset() argument
2544 ctrl = mci_readl(host, CTRL); in dw_mci_ctrl_reset()
2546 mci_writel(host, CTRL, ctrl); in dw_mci_ctrl_reset()
2550 ctrl = mci_readl(host, CTRL); in dw_mci_ctrl_reset()
2555 dev_err(host->dev, in dw_mci_ctrl_reset()
2562 static bool dw_mci_reset(struct dw_mci *host) in dw_mci_reset() argument
2571 if (host->sg) { in dw_mci_reset()
2572 sg_miter_stop(&host->sg_miter); in dw_mci_reset()
2573 host->sg = NULL; in dw_mci_reset()
2576 if (host->use_dma) in dw_mci_reset()
2579 if (dw_mci_ctrl_reset(host, flags)) { in dw_mci_reset()
2584 mci_writel(host, RINTSTS, 0xFFFFFFFF); in dw_mci_reset()
2587 if (host->use_dma) { in dw_mci_reset()
2591 status = mci_readl(host, STATUS); in dw_mci_reset()
2598 dev_err(host->dev, in dw_mci_reset()
2605 if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_FIFO_RESET)) in dw_mci_reset()
2610 if (!(mci_readl(host, CTRL) & SDMMC_CTRL_RESET)) { in dw_mci_reset()
2611 dev_err(host->dev, "%s: fifo/dma reset bits didn't " in dw_mci_reset()
2620 dw_mci_idmac_reset(host); in dw_mci_reset()
2627 mci_send_cmd(host->cur_slot, SDMMC_CMD_UPD_CLK, 0); in dw_mci_reset()
2634 struct dw_mci *host = (struct dw_mci *)arg; in dw_mci_cmd11_timer() local
2636 if (host->state != STATE_SENDING_CMD11) { in dw_mci_cmd11_timer()
2637 dev_warn(host->dev, "Unexpected CMD11 timeout\n"); in dw_mci_cmd11_timer()
2641 host->cmd_status = SDMMC_INT_RTO; in dw_mci_cmd11_timer()
2642 set_bit(EVENT_CMD_COMPLETE, &host->pending_events); in dw_mci_cmd11_timer()
2643 tasklet_schedule(&host->tasklet); in dw_mci_cmd11_timer()
2660 static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) in dw_mci_parse_dt() argument
2663 struct device *dev = host->dev; in dw_mci_parse_dt()
2665 const struct dw_mci_drv_data *drv_data = host->drv_data; in dw_mci_parse_dt()
2696 ret = drv_data->parse_dt(host); in dw_mci_parse_dt()
2708 static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) in dw_mci_parse_dt() argument
2714 static void dw_mci_enable_cd(struct dw_mci *host) in dw_mci_enable_cd() argument
2716 struct dw_mci_board *brd = host->pdata; in dw_mci_enable_cd()
2726 for (i = 0; i < host->num_slots; i++) { in dw_mci_enable_cd()
2727 struct dw_mci_slot *slot = host->slot[i]; in dw_mci_enable_cd()
2732 if (i == host->num_slots) in dw_mci_enable_cd()
2735 spin_lock_irqsave(&host->irq_lock, irqflags); in dw_mci_enable_cd()
2736 temp = mci_readl(host, INTMASK); in dw_mci_enable_cd()
2738 mci_writel(host, INTMASK, temp); in dw_mci_enable_cd()
2739 spin_unlock_irqrestore(&host->irq_lock, irqflags); in dw_mci_enable_cd()
2742 int dw_mci_probe(struct dw_mci *host) in dw_mci_probe() argument
2744 const struct dw_mci_drv_data *drv_data = host->drv_data; in dw_mci_probe()
2749 if (!host->pdata) { in dw_mci_probe()
2750 host->pdata = dw_mci_parse_dt(host); in dw_mci_probe()
2751 if (IS_ERR(host->pdata)) { in dw_mci_probe()
2752 dev_err(host->dev, "platform data not available\n"); in dw_mci_probe()
2757 if (host->pdata->num_slots > 1) { in dw_mci_probe()
2758 dev_err(host->dev, in dw_mci_probe()
2763 host->biu_clk = devm_clk_get(host->dev, "biu"); in dw_mci_probe()
2764 if (IS_ERR(host->biu_clk)) { in dw_mci_probe()
2765 dev_dbg(host->dev, "biu clock not available\n"); in dw_mci_probe()
2767 ret = clk_prepare_enable(host->biu_clk); in dw_mci_probe()
2769 dev_err(host->dev, "failed to enable biu clock\n"); in dw_mci_probe()
2774 host->ciu_clk = devm_clk_get(host->dev, "ciu"); in dw_mci_probe()
2775 if (IS_ERR(host->ciu_clk)) { in dw_mci_probe()
2776 dev_dbg(host->dev, "ciu clock not available\n"); in dw_mci_probe()
2777 host->bus_hz = host->pdata->bus_hz; in dw_mci_probe()
2779 ret = clk_prepare_enable(host->ciu_clk); in dw_mci_probe()
2781 dev_err(host->dev, "failed to enable ciu clock\n"); in dw_mci_probe()
2785 if (host->pdata->bus_hz) { in dw_mci_probe()
2786 ret = clk_set_rate(host->ciu_clk, host->pdata->bus_hz); in dw_mci_probe()
2788 dev_warn(host->dev, in dw_mci_probe()
2790 host->pdata->bus_hz); in dw_mci_probe()
2792 host->bus_hz = clk_get_rate(host->ciu_clk); in dw_mci_probe()
2795 if (!host->bus_hz) { in dw_mci_probe()
2796 dev_err(host->dev, in dw_mci_probe()
2803 ret = drv_data->init(host); in dw_mci_probe()
2805 dev_err(host->dev, in dw_mci_probe()
2812 ret = drv_data->setup_clock(host); in dw_mci_probe()
2814 dev_err(host->dev, in dw_mci_probe()
2820 setup_timer(&host->cmd11_timer, in dw_mci_probe()
2821 dw_mci_cmd11_timer, (unsigned long)host); in dw_mci_probe()
2823 host->quirks = host->pdata->quirks; in dw_mci_probe()
2825 spin_lock_init(&host->lock); in dw_mci_probe()
2826 spin_lock_init(&host->irq_lock); in dw_mci_probe()
2827 INIT_LIST_HEAD(&host->queue); in dw_mci_probe()
2833 i = (mci_readl(host, HCON) >> 7) & 0x7; in dw_mci_probe()
2835 host->push_data = dw_mci_push_data16; in dw_mci_probe()
2836 host->pull_data = dw_mci_pull_data16; in dw_mci_probe()
2838 host->data_shift = 1; in dw_mci_probe()
2840 host->push_data = dw_mci_push_data64; in dw_mci_probe()
2841 host->pull_data = dw_mci_pull_data64; in dw_mci_probe()
2843 host->data_shift = 3; in dw_mci_probe()
2849 host->push_data = dw_mci_push_data32; in dw_mci_probe()
2850 host->pull_data = dw_mci_pull_data32; in dw_mci_probe()
2852 host->data_shift = 2; in dw_mci_probe()
2856 if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS)) in dw_mci_probe()
2859 host->dma_ops = host->pdata->dma_ops; in dw_mci_probe()
2860 dw_mci_init_dma(host); in dw_mci_probe()
2863 mci_writel(host, RINTSTS, 0xFFFFFFFF); in dw_mci_probe()
2864 mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */ in dw_mci_probe()
2867 mci_writel(host, TMOUT, 0xFFFFFFFF); in dw_mci_probe()
2873 if (!host->pdata->fifo_depth) { in dw_mci_probe()
2880 fifo_size = mci_readl(host, FIFOTH); in dw_mci_probe()
2883 fifo_size = host->pdata->fifo_depth; in dw_mci_probe()
2885 host->fifo_depth = fifo_size; in dw_mci_probe()
2886 host->fifoth_val = in dw_mci_probe()
2888 mci_writel(host, FIFOTH, host->fifoth_val); in dw_mci_probe()
2891 mci_writel(host, CLKENA, 0); in dw_mci_probe()
2892 mci_writel(host, CLKSRC, 0); in dw_mci_probe()
2898 host->verid = SDMMC_GET_VERID(mci_readl(host, VERID)); in dw_mci_probe()
2899 dev_info(host->dev, "Version ID is %04x\n", host->verid); in dw_mci_probe()
2901 if (host->verid < DW_MMC_240A) in dw_mci_probe()
2902 host->fifo_reg = host->regs + DATA_OFFSET; in dw_mci_probe()
2904 host->fifo_reg = host->regs + DATA_240A_OFFSET; in dw_mci_probe()
2906 tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host); in dw_mci_probe()
2907 ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt, in dw_mci_probe()
2908 host->irq_flags, "dw-mci", host); in dw_mci_probe()
2912 if (host->pdata->num_slots) in dw_mci_probe()
2913 host->num_slots = host->pdata->num_slots; in dw_mci_probe()
2915 host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; in dw_mci_probe()
2921 mci_writel(host, RINTSTS, 0xFFFFFFFF); in dw_mci_probe()
2922 mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | in dw_mci_probe()
2925 mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ in dw_mci_probe()
2927 dev_info(host->dev, "DW MMC controller at irq %d, " in dw_mci_probe()
2930 host->irq, width, fifo_size); in dw_mci_probe()
2933 for (i = 0; i < host->num_slots; i++) { in dw_mci_probe()
2934 ret = dw_mci_init_slot(host, i); in dw_mci_probe()
2936 dev_dbg(host->dev, "slot %d init failed\n", i); in dw_mci_probe()
2942 dev_info(host->dev, "%d slots initialized\n", init_slots); in dw_mci_probe()
2944 dev_dbg(host->dev, "attempted to initialize %d slots, " in dw_mci_probe()
2945 "but failed on all\n", host->num_slots); in dw_mci_probe()
2950 dw_mci_enable_cd(host); in dw_mci_probe()
2952 if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) in dw_mci_probe()
2953 dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); in dw_mci_probe()
2958 if (host->use_dma && host->dma_ops->exit) in dw_mci_probe()
2959 host->dma_ops->exit(host); in dw_mci_probe()
2962 if (!IS_ERR(host->ciu_clk)) in dw_mci_probe()
2963 clk_disable_unprepare(host->ciu_clk); in dw_mci_probe()
2966 if (!IS_ERR(host->biu_clk)) in dw_mci_probe()
2967 clk_disable_unprepare(host->biu_clk); in dw_mci_probe()
2973 void dw_mci_remove(struct dw_mci *host) in dw_mci_remove() argument
2977 mci_writel(host, RINTSTS, 0xFFFFFFFF); in dw_mci_remove()
2978 mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */ in dw_mci_remove()
2980 for (i = 0; i < host->num_slots; i++) { in dw_mci_remove()
2981 dev_dbg(host->dev, "remove slot %d\n", i); in dw_mci_remove()
2982 if (host->slot[i]) in dw_mci_remove()
2983 dw_mci_cleanup_slot(host->slot[i], i); in dw_mci_remove()
2987 mci_writel(host, CLKENA, 0); in dw_mci_remove()
2988 mci_writel(host, CLKSRC, 0); in dw_mci_remove()
2990 if (host->use_dma && host->dma_ops->exit) in dw_mci_remove()
2991 host->dma_ops->exit(host); in dw_mci_remove()
2993 if (!IS_ERR(host->ciu_clk)) in dw_mci_remove()
2994 clk_disable_unprepare(host->ciu_clk); in dw_mci_remove()
2996 if (!IS_ERR(host->biu_clk)) in dw_mci_remove()
2997 clk_disable_unprepare(host->biu_clk); in dw_mci_remove()
3007 int dw_mci_suspend(struct dw_mci *host) in dw_mci_suspend() argument
3013 int dw_mci_resume(struct dw_mci *host) in dw_mci_resume() argument
3017 if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS)) { in dw_mci_resume()
3022 if (host->use_dma && host->dma_ops->init) in dw_mci_resume()
3023 host->dma_ops->init(host); in dw_mci_resume()
3029 mci_writel(host, FIFOTH, host->fifoth_val); in dw_mci_resume()
3030 host->prev_blksz = 0; in dw_mci_resume()
3033 mci_writel(host, TMOUT, 0xFFFFFFFF); in dw_mci_resume()
3035 mci_writel(host, RINTSTS, 0xFFFFFFFF); in dw_mci_resume()
3036 mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | in dw_mci_resume()
3039 mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); in dw_mci_resume()
3041 for (i = 0; i < host->num_slots; i++) { in dw_mci_resume()
3042 struct dw_mci_slot *slot = host->slot[i]; in dw_mci_resume()
3052 dw_mci_enable_cd(host); in dw_mci_resume()