Lines Matching refs:host
74 #define mmc_readl(host, reg) \ argument
75 readl((host)->reg_base + SDXC_##reg)
76 #define mmc_writel(host, reg, value) \ argument
77 writel((value), (host)->reg_base + SDXC_##reg)
261 static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host) in sunxi_mmc_reset_host() argument
266 mmc_writel(host, REG_GCTRL, SDXC_HARDWARE_RESET); in sunxi_mmc_reset_host()
268 rval = mmc_readl(host, REG_GCTRL); in sunxi_mmc_reset_host()
272 dev_err(mmc_dev(host->mmc), "fatal err reset timeout\n"); in sunxi_mmc_reset_host()
282 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_init_host() local
284 if (sunxi_mmc_reset_host(host)) in sunxi_mmc_init_host()
287 mmc_writel(host, REG_FTRGL, 0x20070008); in sunxi_mmc_init_host()
288 mmc_writel(host, REG_TMOUT, 0xffffffff); in sunxi_mmc_init_host()
289 mmc_writel(host, REG_IMASK, host->sdio_imask); in sunxi_mmc_init_host()
290 mmc_writel(host, REG_RINTR, 0xffffffff); in sunxi_mmc_init_host()
291 mmc_writel(host, REG_DBGC, 0xdeb); in sunxi_mmc_init_host()
292 mmc_writel(host, REG_FUNS, SDXC_CEATA_ON); in sunxi_mmc_init_host()
293 mmc_writel(host, REG_DLBA, host->sg_dma); in sunxi_mmc_init_host()
295 rval = mmc_readl(host, REG_GCTRL); in sunxi_mmc_init_host()
298 mmc_writel(host, REG_GCTRL, rval); in sunxi_mmc_init_host()
303 static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host, in sunxi_mmc_init_idma_des() argument
306 struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu; in sunxi_mmc_init_idma_des()
307 dma_addr_t next_desc = host->sg_dma; in sunxi_mmc_init_idma_des()
308 int i, max_len = (1 << host->idma_des_size_bits); in sunxi_mmc_init_idma_des()
344 static int sunxi_mmc_map_dma(struct sunxi_mmc_host *host, in sunxi_mmc_map_dma() argument
350 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, in sunxi_mmc_map_dma()
353 dev_err(mmc_dev(host->mmc), "dma_map_sg failed\n"); in sunxi_mmc_map_dma()
359 dev_err(mmc_dev(host->mmc), in sunxi_mmc_map_dma()
369 static void sunxi_mmc_start_dma(struct sunxi_mmc_host *host, in sunxi_mmc_start_dma() argument
374 sunxi_mmc_init_idma_des(host, data); in sunxi_mmc_start_dma()
376 rval = mmc_readl(host, REG_GCTRL); in sunxi_mmc_start_dma()
378 mmc_writel(host, REG_GCTRL, rval); in sunxi_mmc_start_dma()
380 mmc_writel(host, REG_GCTRL, rval); in sunxi_mmc_start_dma()
382 mmc_writel(host, REG_DMAC, SDXC_IDMAC_SOFT_RESET); in sunxi_mmc_start_dma()
385 mmc_writel(host, REG_IDIE, SDXC_IDMAC_RECEIVE_INTERRUPT); in sunxi_mmc_start_dma()
387 mmc_writel(host, REG_DMAC, in sunxi_mmc_start_dma()
391 static void sunxi_mmc_send_manual_stop(struct sunxi_mmc_host *host, in sunxi_mmc_send_manual_stop() argument
409 mmc_writel(host, REG_CARG, arg); in sunxi_mmc_send_manual_stop()
410 mmc_writel(host, REG_CMDR, cmd_val); in sunxi_mmc_send_manual_stop()
413 ri = mmc_readl(host, REG_RINTR); in sunxi_mmc_send_manual_stop()
418 dev_err(mmc_dev(host->mmc), "send stop command failed\n"); in sunxi_mmc_send_manual_stop()
423 req->stop->resp[0] = mmc_readl(host, REG_RESP0); in sunxi_mmc_send_manual_stop()
426 mmc_writel(host, REG_RINTR, 0xffff); in sunxi_mmc_send_manual_stop()
429 static void sunxi_mmc_dump_errinfo(struct sunxi_mmc_host *host) in sunxi_mmc_dump_errinfo() argument
431 struct mmc_command *cmd = host->mrq->cmd; in sunxi_mmc_dump_errinfo()
432 struct mmc_data *data = host->mrq->data; in sunxi_mmc_dump_errinfo()
435 if ((host->int_sum & SDXC_INTERRUPT_ERROR_BIT) == in sunxi_mmc_dump_errinfo()
440 dev_err(mmc_dev(host->mmc), in sunxi_mmc_dump_errinfo()
442 host->mmc->index, cmd->opcode, in sunxi_mmc_dump_errinfo()
444 host->int_sum & SDXC_RESP_ERROR ? " RE" : "", in sunxi_mmc_dump_errinfo()
445 host->int_sum & SDXC_RESP_CRC_ERROR ? " RCE" : "", in sunxi_mmc_dump_errinfo()
446 host->int_sum & SDXC_DATA_CRC_ERROR ? " DCE" : "", in sunxi_mmc_dump_errinfo()
447 host->int_sum & SDXC_RESP_TIMEOUT ? " RTO" : "", in sunxi_mmc_dump_errinfo()
448 host->int_sum & SDXC_DATA_TIMEOUT ? " DTO" : "", in sunxi_mmc_dump_errinfo()
449 host->int_sum & SDXC_FIFO_RUN_ERROR ? " FE" : "", in sunxi_mmc_dump_errinfo()
450 host->int_sum & SDXC_HARD_WARE_LOCKED ? " HL" : "", in sunxi_mmc_dump_errinfo()
451 host->int_sum & SDXC_START_BIT_ERROR ? " SBE" : "", in sunxi_mmc_dump_errinfo()
452 host->int_sum & SDXC_END_BIT_ERROR ? " EBE" : "" in sunxi_mmc_dump_errinfo()
457 static irqreturn_t sunxi_mmc_finalize_request(struct sunxi_mmc_host *host) in sunxi_mmc_finalize_request() argument
459 struct mmc_request *mrq = host->mrq; in sunxi_mmc_finalize_request()
463 mmc_writel(host, REG_IMASK, host->sdio_imask); in sunxi_mmc_finalize_request()
464 mmc_writel(host, REG_IDIE, 0); in sunxi_mmc_finalize_request()
466 if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) { in sunxi_mmc_finalize_request()
467 sunxi_mmc_dump_errinfo(host); in sunxi_mmc_finalize_request()
472 host->manual_stop_mrq = mrq; in sunxi_mmc_finalize_request()
479 mrq->cmd->resp[0] = mmc_readl(host, REG_RESP3); in sunxi_mmc_finalize_request()
480 mrq->cmd->resp[1] = mmc_readl(host, REG_RESP2); in sunxi_mmc_finalize_request()
481 mrq->cmd->resp[2] = mmc_readl(host, REG_RESP1); in sunxi_mmc_finalize_request()
482 mrq->cmd->resp[3] = mmc_readl(host, REG_RESP0); in sunxi_mmc_finalize_request()
484 mrq->cmd->resp[0] = mmc_readl(host, REG_RESP0); in sunxi_mmc_finalize_request()
492 mmc_writel(host, REG_IDST, 0x337); in sunxi_mmc_finalize_request()
493 mmc_writel(host, REG_DMAC, 0); in sunxi_mmc_finalize_request()
494 rval = mmc_readl(host, REG_GCTRL); in sunxi_mmc_finalize_request()
496 mmc_writel(host, REG_GCTRL, rval); in sunxi_mmc_finalize_request()
498 mmc_writel(host, REG_GCTRL, rval); in sunxi_mmc_finalize_request()
500 mmc_writel(host, REG_GCTRL, rval); in sunxi_mmc_finalize_request()
501 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, in sunxi_mmc_finalize_request()
505 mmc_writel(host, REG_RINTR, 0xffff); in sunxi_mmc_finalize_request()
507 host->mrq = NULL; in sunxi_mmc_finalize_request()
508 host->int_sum = 0; in sunxi_mmc_finalize_request()
509 host->wait_dma = false; in sunxi_mmc_finalize_request()
511 return host->manual_stop_mrq ? IRQ_WAKE_THREAD : IRQ_HANDLED; in sunxi_mmc_finalize_request()
516 struct sunxi_mmc_host *host = dev_id; in sunxi_mmc_irq() local
523 spin_lock(&host->lock); in sunxi_mmc_irq()
525 idma_int = mmc_readl(host, REG_IDST); in sunxi_mmc_irq()
526 msk_int = mmc_readl(host, REG_MISTA); in sunxi_mmc_irq()
528 dev_dbg(mmc_dev(host->mmc), "irq: rq %p mi %08x idi %08x\n", in sunxi_mmc_irq()
529 host->mrq, msk_int, idma_int); in sunxi_mmc_irq()
531 mrq = host->mrq; in sunxi_mmc_irq()
534 host->wait_dma = false; in sunxi_mmc_irq()
536 host->int_sum |= msk_int; in sunxi_mmc_irq()
539 if ((host->int_sum & SDXC_RESP_TIMEOUT) && in sunxi_mmc_irq()
540 !(host->int_sum & SDXC_COMMAND_DONE)) in sunxi_mmc_irq()
541 mmc_writel(host, REG_IMASK, in sunxi_mmc_irq()
542 host->sdio_imask | SDXC_COMMAND_DONE); in sunxi_mmc_irq()
544 else if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) in sunxi_mmc_irq()
546 else if ((host->int_sum & SDXC_INTERRUPT_DONE_BIT) && in sunxi_mmc_irq()
547 !host->wait_dma) in sunxi_mmc_irq()
554 mmc_writel(host, REG_RINTR, msk_int); in sunxi_mmc_irq()
555 mmc_writel(host, REG_IDST, idma_int); in sunxi_mmc_irq()
558 ret = sunxi_mmc_finalize_request(host); in sunxi_mmc_irq()
560 spin_unlock(&host->lock); in sunxi_mmc_irq()
563 mmc_request_done(host->mmc, mrq); in sunxi_mmc_irq()
566 mmc_signal_sdio_irq(host->mmc); in sunxi_mmc_irq()
573 struct sunxi_mmc_host *host = dev_id; in sunxi_mmc_handle_manual_stop() local
577 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
578 mrq = host->manual_stop_mrq; in sunxi_mmc_handle_manual_stop()
579 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
582 dev_err(mmc_dev(host->mmc), "no request for manual stop\n"); in sunxi_mmc_handle_manual_stop()
586 dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); in sunxi_mmc_handle_manual_stop()
596 sunxi_mmc_send_manual_stop(host, mrq); in sunxi_mmc_handle_manual_stop()
598 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
599 host->manual_stop_mrq = NULL; in sunxi_mmc_handle_manual_stop()
600 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_handle_manual_stop()
602 mmc_request_done(host->mmc, mrq); in sunxi_mmc_handle_manual_stop()
607 static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) in sunxi_mmc_oclk_onoff() argument
612 rval = mmc_readl(host, REG_CLKCR); in sunxi_mmc_oclk_onoff()
618 mmc_writel(host, REG_CLKCR, rval); in sunxi_mmc_oclk_onoff()
621 mmc_writel(host, REG_CMDR, rval); in sunxi_mmc_oclk_onoff()
624 rval = mmc_readl(host, REG_CMDR); in sunxi_mmc_oclk_onoff()
628 mmc_writel(host, REG_RINTR, in sunxi_mmc_oclk_onoff()
629 mmc_readl(host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT); in sunxi_mmc_oclk_onoff()
632 dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n"); in sunxi_mmc_oclk_onoff()
639 static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, in sunxi_mmc_clk_set_rate() argument
645 rate = clk_round_rate(host->clk_mmc, ios->clock); in sunxi_mmc_clk_set_rate()
646 dev_dbg(mmc_dev(host->mmc), "setting clk to %d, rounded %d\n", in sunxi_mmc_clk_set_rate()
650 ret = clk_set_rate(host->clk_mmc, rate); in sunxi_mmc_clk_set_rate()
652 dev_err(mmc_dev(host->mmc), "error setting clk to %d: %d\n", in sunxi_mmc_clk_set_rate()
657 ret = sunxi_mmc_oclk_onoff(host, 0); in sunxi_mmc_clk_set_rate()
662 rval = mmc_readl(host, REG_CLKCR); in sunxi_mmc_clk_set_rate()
664 mmc_writel(host, REG_CLKCR, rval); in sunxi_mmc_clk_set_rate()
668 oclk_dly = host->clk_delays[SDXC_CLK_400K].output; in sunxi_mmc_clk_set_rate()
669 sclk_dly = host->clk_delays[SDXC_CLK_400K].sample; in sunxi_mmc_clk_set_rate()
671 oclk_dly = host->clk_delays[SDXC_CLK_25M].output; in sunxi_mmc_clk_set_rate()
672 sclk_dly = host->clk_delays[SDXC_CLK_25M].sample; in sunxi_mmc_clk_set_rate()
675 oclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].output; in sunxi_mmc_clk_set_rate()
676 sclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].sample; in sunxi_mmc_clk_set_rate()
678 oclk_dly = host->clk_delays[SDXC_CLK_50M].output; in sunxi_mmc_clk_set_rate()
679 sclk_dly = host->clk_delays[SDXC_CLK_50M].sample; in sunxi_mmc_clk_set_rate()
685 clk_set_phase(host->clk_sample, sclk_dly); in sunxi_mmc_clk_set_rate()
686 clk_set_phase(host->clk_output, oclk_dly); in sunxi_mmc_clk_set_rate()
688 return sunxi_mmc_oclk_onoff(host, 1); in sunxi_mmc_clk_set_rate()
693 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_set_ios() local
704 host->ferror = sunxi_mmc_init_host(mmc); in sunxi_mmc_set_ios()
705 if (host->ferror) in sunxi_mmc_set_ios()
713 sunxi_mmc_reset_host(host); in sunxi_mmc_set_ios()
721 mmc_writel(host, REG_WIDTH, SDXC_WIDTH1); in sunxi_mmc_set_ios()
724 mmc_writel(host, REG_WIDTH, SDXC_WIDTH4); in sunxi_mmc_set_ios()
727 mmc_writel(host, REG_WIDTH, SDXC_WIDTH8); in sunxi_mmc_set_ios()
732 rval = mmc_readl(host, REG_GCTRL); in sunxi_mmc_set_ios()
737 mmc_writel(host, REG_GCTRL, rval); in sunxi_mmc_set_ios()
741 host->ferror = sunxi_mmc_clk_set_rate(host, ios); in sunxi_mmc_set_ios()
748 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_enable_sdio_irq() local
752 spin_lock_irqsave(&host->lock, flags); in sunxi_mmc_enable_sdio_irq()
754 imask = mmc_readl(host, REG_IMASK); in sunxi_mmc_enable_sdio_irq()
756 host->sdio_imask = SDXC_SDIO_INTERRUPT; in sunxi_mmc_enable_sdio_irq()
759 host->sdio_imask = 0; in sunxi_mmc_enable_sdio_irq()
762 mmc_writel(host, REG_IMASK, imask); in sunxi_mmc_enable_sdio_irq()
763 spin_unlock_irqrestore(&host->lock, flags); in sunxi_mmc_enable_sdio_irq()
768 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_hw_reset() local
769 mmc_writel(host, REG_HWRST, 0); in sunxi_mmc_hw_reset()
771 mmc_writel(host, REG_HWRST, 1); in sunxi_mmc_hw_reset()
777 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_request() local
783 bool wait_dma = host->wait_dma; in sunxi_mmc_request()
787 if (host->ferror) { in sunxi_mmc_request()
788 mrq->cmd->error = host->ferror; in sunxi_mmc_request()
794 ret = sunxi_mmc_map_dma(host, data); in sunxi_mmc_request()
846 spin_lock_irqsave(&host->lock, iflags); in sunxi_mmc_request()
848 if (host->mrq || host->manual_stop_mrq) { in sunxi_mmc_request()
849 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_request()
862 mmc_writel(host, REG_BLKSZ, data->blksz); in sunxi_mmc_request()
863 mmc_writel(host, REG_BCNTR, data->blksz * data->blocks); in sunxi_mmc_request()
864 sunxi_mmc_start_dma(host, data); in sunxi_mmc_request()
867 host->mrq = mrq; in sunxi_mmc_request()
868 host->wait_dma = wait_dma; in sunxi_mmc_request()
869 mmc_writel(host, REG_IMASK, host->sdio_imask | imask); in sunxi_mmc_request()
870 mmc_writel(host, REG_CARG, cmd->arg); in sunxi_mmc_request()
871 mmc_writel(host, REG_CMDR, cmd_val); in sunxi_mmc_request()
873 spin_unlock_irqrestore(&host->lock, iflags); in sunxi_mmc_request()
878 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_card_busy() local
880 return !!(mmc_readl(host, REG_STAS) & SDXC_CARD_DATA_BUSY); in sunxi_mmc_card_busy()
915 static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, in sunxi_mmc_resource_request() argument
922 host->idma_des_size_bits = 13; in sunxi_mmc_resource_request()
924 host->idma_des_size_bits = 16; in sunxi_mmc_resource_request()
927 host->clk_delays = sun9i_mmc_clk_delays; in sunxi_mmc_resource_request()
929 host->clk_delays = sunxi_mmc_clk_delays; in sunxi_mmc_resource_request()
931 ret = mmc_regulator_get_supply(host->mmc); in sunxi_mmc_resource_request()
938 host->reg_base = devm_ioremap_resource(&pdev->dev, in sunxi_mmc_resource_request()
940 if (IS_ERR(host->reg_base)) in sunxi_mmc_resource_request()
941 return PTR_ERR(host->reg_base); in sunxi_mmc_resource_request()
943 host->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); in sunxi_mmc_resource_request()
944 if (IS_ERR(host->clk_ahb)) { in sunxi_mmc_resource_request()
946 return PTR_ERR(host->clk_ahb); in sunxi_mmc_resource_request()
949 host->clk_mmc = devm_clk_get(&pdev->dev, "mmc"); in sunxi_mmc_resource_request()
950 if (IS_ERR(host->clk_mmc)) { in sunxi_mmc_resource_request()
952 return PTR_ERR(host->clk_mmc); in sunxi_mmc_resource_request()
955 host->clk_output = devm_clk_get(&pdev->dev, "output"); in sunxi_mmc_resource_request()
956 if (IS_ERR(host->clk_output)) { in sunxi_mmc_resource_request()
958 return PTR_ERR(host->clk_output); in sunxi_mmc_resource_request()
961 host->clk_sample = devm_clk_get(&pdev->dev, "sample"); in sunxi_mmc_resource_request()
962 if (IS_ERR(host->clk_sample)) { in sunxi_mmc_resource_request()
964 return PTR_ERR(host->clk_sample); in sunxi_mmc_resource_request()
967 host->reset = devm_reset_control_get_optional(&pdev->dev, "ahb"); in sunxi_mmc_resource_request()
968 if (PTR_ERR(host->reset) == -EPROBE_DEFER) in sunxi_mmc_resource_request()
969 return PTR_ERR(host->reset); in sunxi_mmc_resource_request()
971 ret = clk_prepare_enable(host->clk_ahb); in sunxi_mmc_resource_request()
977 ret = clk_prepare_enable(host->clk_mmc); in sunxi_mmc_resource_request()
983 ret = clk_prepare_enable(host->clk_output); in sunxi_mmc_resource_request()
989 ret = clk_prepare_enable(host->clk_sample); in sunxi_mmc_resource_request()
995 if (!IS_ERR(host->reset)) { in sunxi_mmc_resource_request()
996 ret = reset_control_deassert(host->reset); in sunxi_mmc_resource_request()
1007 ret = sunxi_mmc_reset_host(host); in sunxi_mmc_resource_request()
1011 host->irq = platform_get_irq(pdev, 0); in sunxi_mmc_resource_request()
1012 return devm_request_threaded_irq(&pdev->dev, host->irq, sunxi_mmc_irq, in sunxi_mmc_resource_request()
1013 sunxi_mmc_handle_manual_stop, 0, "sunxi-mmc", host); in sunxi_mmc_resource_request()
1016 if (!IS_ERR(host->reset)) in sunxi_mmc_resource_request()
1017 reset_control_assert(host->reset); in sunxi_mmc_resource_request()
1019 clk_disable_unprepare(host->clk_sample); in sunxi_mmc_resource_request()
1021 clk_disable_unprepare(host->clk_output); in sunxi_mmc_resource_request()
1023 clk_disable_unprepare(host->clk_mmc); in sunxi_mmc_resource_request()
1025 clk_disable_unprepare(host->clk_ahb); in sunxi_mmc_resource_request()
1031 struct sunxi_mmc_host *host; in sunxi_mmc_probe() local
1041 host = mmc_priv(mmc); in sunxi_mmc_probe()
1042 host->mmc = mmc; in sunxi_mmc_probe()
1043 spin_lock_init(&host->lock); in sunxi_mmc_probe()
1045 ret = sunxi_mmc_resource_request(host, pdev); in sunxi_mmc_probe()
1049 host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, in sunxi_mmc_probe()
1050 &host->sg_dma, GFP_KERNEL); in sunxi_mmc_probe()
1051 if (!host->sg_cpu) { in sunxi_mmc_probe()
1061 mmc->max_seg_size = (1 << host->idma_des_size_bits); in sunxi_mmc_probe()
1077 dev_info(&pdev->dev, "base:0x%p irq:%u\n", host->reg_base, host->irq); in sunxi_mmc_probe()
1082 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); in sunxi_mmc_probe()
1091 struct sunxi_mmc_host *host = mmc_priv(mmc); in sunxi_mmc_remove() local
1094 disable_irq(host->irq); in sunxi_mmc_remove()
1095 sunxi_mmc_reset_host(host); in sunxi_mmc_remove()
1097 if (!IS_ERR(host->reset)) in sunxi_mmc_remove()
1098 reset_control_assert(host->reset); in sunxi_mmc_remove()
1100 clk_disable_unprepare(host->clk_mmc); in sunxi_mmc_remove()
1101 clk_disable_unprepare(host->clk_ahb); in sunxi_mmc_remove()
1103 dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); in sunxi_mmc_remove()