Lines Matching refs:host
209 static void usdhi6_write(struct usdhi6_host *host, u32 reg, u32 data) in usdhi6_write() argument
211 iowrite32(data, host->base + reg); in usdhi6_write()
212 dev_vdbg(mmc_dev(host->mmc), "%s(0x%p + 0x%x) = 0x%x\n", __func__, in usdhi6_write()
213 host->base, reg, data); in usdhi6_write()
216 static void usdhi6_write16(struct usdhi6_host *host, u32 reg, u16 data) in usdhi6_write16() argument
218 iowrite16(data, host->base + reg); in usdhi6_write16()
219 dev_vdbg(mmc_dev(host->mmc), "%s(0x%p + 0x%x) = 0x%x\n", __func__, in usdhi6_write16()
220 host->base, reg, data); in usdhi6_write16()
223 static u32 usdhi6_read(struct usdhi6_host *host, u32 reg) in usdhi6_read() argument
225 u32 data = ioread32(host->base + reg); in usdhi6_read()
226 dev_vdbg(mmc_dev(host->mmc), "%s(0x%p + 0x%x) = 0x%x\n", __func__, in usdhi6_read()
227 host->base, reg, data); in usdhi6_read()
231 static u16 usdhi6_read16(struct usdhi6_host *host, u32 reg) in usdhi6_read16() argument
233 u16 data = ioread16(host->base + reg); in usdhi6_read16()
234 dev_vdbg(mmc_dev(host->mmc), "%s(0x%p + 0x%x) = 0x%x\n", __func__, in usdhi6_read16()
235 host->base, reg, data); in usdhi6_read16()
239 static void usdhi6_irq_enable(struct usdhi6_host *host, u32 info1, u32 info2) in usdhi6_irq_enable() argument
241 host->status_mask = USDHI6_SD_INFO1_IRQ & ~info1; in usdhi6_irq_enable()
242 host->status2_mask = USDHI6_SD_INFO2_IRQ & ~info2; in usdhi6_irq_enable()
243 usdhi6_write(host, USDHI6_SD_INFO1_MASK, host->status_mask); in usdhi6_irq_enable()
244 usdhi6_write(host, USDHI6_SD_INFO2_MASK, host->status2_mask); in usdhi6_irq_enable()
247 static void usdhi6_wait_for_resp(struct usdhi6_host *host) in usdhi6_wait_for_resp() argument
249 usdhi6_irq_enable(host, USDHI6_SD_INFO1_RSP_END | in usdhi6_wait_for_resp()
254 static void usdhi6_wait_for_brwe(struct usdhi6_host *host, bool read) in usdhi6_wait_for_brwe() argument
256 usdhi6_irq_enable(host, USDHI6_SD_INFO1_ACCESS_END | in usdhi6_wait_for_brwe()
261 static void usdhi6_only_cd(struct usdhi6_host *host) in usdhi6_only_cd() argument
264 usdhi6_irq_enable(host, USDHI6_SD_INFO1_CARD_CD, 0); in usdhi6_only_cd()
267 static void usdhi6_mask_all(struct usdhi6_host *host) in usdhi6_mask_all() argument
269 usdhi6_irq_enable(host, 0, 0); in usdhi6_mask_all()
272 static int usdhi6_error_code(struct usdhi6_host *host) in usdhi6_error_code() argument
276 usdhi6_write(host, USDHI6_SD_STOP, USDHI6_SD_STOP_STP); in usdhi6_error_code()
278 if (host->io_error & in usdhi6_error_code()
280 u32 rsp54 = usdhi6_read(host, USDHI6_SD_RSP54); in usdhi6_error_code()
281 int opc = host->mrq ? host->mrq->cmd->opcode : -1; in usdhi6_error_code()
283 err = usdhi6_read(host, USDHI6_SD_ERR_STS2); in usdhi6_error_code()
285 if (host->wait == USDHI6_WAIT_FOR_CMD) in usdhi6_error_code()
286 dev_dbg(mmc_dev(host->mmc), in usdhi6_error_code()
288 err, rsp54, host->wait, opc); in usdhi6_error_code()
290 dev_warn(mmc_dev(host->mmc), in usdhi6_error_code()
292 err, rsp54, host->wait, opc); in usdhi6_error_code()
296 err = usdhi6_read(host, USDHI6_SD_ERR_STS1); in usdhi6_error_code()
298 dev_warn(mmc_dev(host->mmc), "Err sts 0x%x, state %u, CMD%d\n", in usdhi6_error_code()
299 err, host->wait, host->mrq ? host->mrq->cmd->opcode : -1); in usdhi6_error_code()
300 if (host->io_error & USDHI6_SD_INFO2_ILA) in usdhi6_error_code()
314 static void usdhi6_blk_bounce(struct usdhi6_host *host, in usdhi6_blk_bounce() argument
317 struct mmc_data *data = host->mrq->data; in usdhi6_blk_bounce()
318 size_t blk_head = host->head_len; in usdhi6_blk_bounce()
320 dev_dbg(mmc_dev(host->mmc), "%s(): CMD%u of %u SG: %ux%u @ 0x%x\n", in usdhi6_blk_bounce()
321 __func__, host->mrq->cmd->opcode, data->sg_len, in usdhi6_blk_bounce()
324 host->head_pg.page = host->pg.page; in usdhi6_blk_bounce()
325 host->head_pg.mapped = host->pg.mapped; in usdhi6_blk_bounce()
326 host->pg.page = nth_page(host->pg.page, 1); in usdhi6_blk_bounce()
327 host->pg.mapped = kmap(host->pg.page); in usdhi6_blk_bounce()
329 host->blk_page = host->bounce_buf; in usdhi6_blk_bounce()
330 host->offset = 0; in usdhi6_blk_bounce()
335 memcpy(host->bounce_buf, host->head_pg.mapped + PAGE_SIZE - blk_head, in usdhi6_blk_bounce()
337 memcpy(host->bounce_buf + blk_head, host->pg.mapped, in usdhi6_blk_bounce()
342 static void usdhi6_sg_prep(struct usdhi6_host *host) in usdhi6_sg_prep() argument
344 struct mmc_request *mrq = host->mrq; in usdhi6_sg_prep()
347 usdhi6_write(host, USDHI6_SD_SECCNT, data->blocks); in usdhi6_sg_prep()
349 host->sg = data->sg; in usdhi6_sg_prep()
351 host->offset = host->sg->offset; in usdhi6_sg_prep()
355 static void *usdhi6_sg_map(struct usdhi6_host *host) in usdhi6_sg_map() argument
357 struct mmc_data *data = host->mrq->data; in usdhi6_sg_map()
358 struct scatterlist *sg = data->sg_len > 1 ? host->sg : data->sg; in usdhi6_sg_map()
362 WARN(host->pg.page, "%p not properly unmapped!\n", host->pg.page); in usdhi6_sg_map()
368 host->pg.page = sg_page(sg); in usdhi6_sg_map()
369 host->pg.mapped = kmap(host->pg.page); in usdhi6_sg_map()
370 host->offset = sg->offset; in usdhi6_sg_map()
376 host->head_len = blk_head; in usdhi6_sg_map()
383 usdhi6_blk_bounce(host, sg); in usdhi6_sg_map()
385 host->blk_page = host->pg.mapped; in usdhi6_sg_map()
387 dev_dbg(mmc_dev(host->mmc), "Mapped %p (%lx) at %p + %u for CMD%u @ 0x%p\n", in usdhi6_sg_map()
388 host->pg.page, page_to_pfn(host->pg.page), host->pg.mapped, in usdhi6_sg_map()
389 sg->offset, host->mrq->cmd->opcode, host->mrq); in usdhi6_sg_map()
391 return host->blk_page + host->offset; in usdhi6_sg_map()
395 static void usdhi6_sg_unmap(struct usdhi6_host *host, bool force) in usdhi6_sg_unmap() argument
397 struct mmc_data *data = host->mrq->data; in usdhi6_sg_unmap()
398 struct page *page = host->head_pg.page; in usdhi6_sg_unmap()
403 host->sg : data->sg; in usdhi6_sg_unmap()
404 size_t blk_head = host->head_len; in usdhi6_sg_unmap()
407 memcpy(host->head_pg.mapped + PAGE_SIZE - blk_head, in usdhi6_sg_unmap()
408 host->bounce_buf, blk_head); in usdhi6_sg_unmap()
409 memcpy(host->pg.mapped, host->bounce_buf + blk_head, in usdhi6_sg_unmap()
416 host->head_pg.page = NULL; in usdhi6_sg_unmap()
419 (host->page_idx << PAGE_SHIFT) + data->blksz - blk_head) in usdhi6_sg_unmap()
424 page = host->pg.page; in usdhi6_sg_unmap()
431 host->pg.page = NULL; in usdhi6_sg_unmap()
435 static void usdhi6_sg_advance(struct usdhi6_host *host) in usdhi6_sg_advance() argument
437 struct mmc_data *data = host->mrq->data; in usdhi6_sg_advance()
441 if (host->head_pg.page) { in usdhi6_sg_advance()
443 host->page_idx++; in usdhi6_sg_advance()
444 host->offset = data->blksz - host->head_len; in usdhi6_sg_advance()
445 host->blk_page = host->pg.mapped; in usdhi6_sg_advance()
446 usdhi6_sg_unmap(host, false); in usdhi6_sg_advance()
448 host->offset += data->blksz; in usdhi6_sg_advance()
450 if (host->offset == PAGE_SIZE) { in usdhi6_sg_advance()
452 host->offset = 0; in usdhi6_sg_advance()
453 host->page_idx++; in usdhi6_sg_advance()
463 done = (host->page_idx << PAGE_SHIFT) + host->offset; in usdhi6_sg_advance()
464 total = host->sg->offset + sg_dma_len(host->sg); in usdhi6_sg_advance()
466 dev_dbg(mmc_dev(host->mmc), "%s(): %zu of %zu @ %zu\n", __func__, in usdhi6_sg_advance()
467 done, total, host->offset); in usdhi6_sg_advance()
469 if (done < total && host->offset) { in usdhi6_sg_advance()
471 if (host->offset + data->blksz > PAGE_SIZE) in usdhi6_sg_advance()
473 usdhi6_blk_bounce(host, host->sg); in usdhi6_sg_advance()
479 usdhi6_sg_unmap(host, false); in usdhi6_sg_advance()
487 struct scatterlist *next = sg_next(host->sg); in usdhi6_sg_advance()
489 host->page_idx = 0; in usdhi6_sg_advance()
492 host->wait = USDHI6_WAIT_FOR_DATA_END; in usdhi6_sg_advance()
493 host->sg = next; in usdhi6_sg_advance()
506 host->pg.page = nth_page(sg_page(host->sg), host->page_idx); in usdhi6_sg_advance()
507 host->pg.mapped = kmap(host->pg.page); in usdhi6_sg_advance()
508 host->blk_page = host->pg.mapped; in usdhi6_sg_advance()
510 dev_dbg(mmc_dev(host->mmc), "Mapped %p (%lx) at %p for CMD%u @ 0x%p\n", in usdhi6_sg_advance()
511 host->pg.page, page_to_pfn(host->pg.page), host->pg.mapped, in usdhi6_sg_advance()
512 host->mrq->cmd->opcode, host->mrq); in usdhi6_sg_advance()
517 static void usdhi6_dma_release(struct usdhi6_host *host) in usdhi6_dma_release() argument
519 host->dma_active = false; in usdhi6_dma_release()
520 if (host->chan_tx) { in usdhi6_dma_release()
521 struct dma_chan *chan = host->chan_tx; in usdhi6_dma_release()
522 host->chan_tx = NULL; in usdhi6_dma_release()
525 if (host->chan_rx) { in usdhi6_dma_release()
526 struct dma_chan *chan = host->chan_rx; in usdhi6_dma_release()
527 host->chan_rx = NULL; in usdhi6_dma_release()
532 static void usdhi6_dma_stop_unmap(struct usdhi6_host *host) in usdhi6_dma_stop_unmap() argument
534 struct mmc_data *data = host->mrq->data; in usdhi6_dma_stop_unmap()
536 if (!host->dma_active) in usdhi6_dma_stop_unmap()
539 usdhi6_write(host, USDHI6_CC_EXT_MODE, 0); in usdhi6_dma_stop_unmap()
540 host->dma_active = false; in usdhi6_dma_stop_unmap()
543 dma_unmap_sg(host->chan_rx->device->dev, data->sg, in usdhi6_dma_stop_unmap()
546 dma_unmap_sg(host->chan_tx->device->dev, data->sg, in usdhi6_dma_stop_unmap()
552 struct usdhi6_host *host = arg; in usdhi6_dma_complete() local
553 struct mmc_request *mrq = host->mrq; in usdhi6_dma_complete()
556 dev_name(mmc_dev(host->mmc)), mrq)) in usdhi6_dma_complete()
559 dev_dbg(mmc_dev(host->mmc), "%s(): CMD%u DMA completed\n", __func__, in usdhi6_dma_complete()
562 usdhi6_dma_stop_unmap(host); in usdhi6_dma_complete()
563 usdhi6_wait_for_brwe(host, mrq->data->flags & MMC_DATA_READ); in usdhi6_dma_complete()
566 static int usdhi6_dma_setup(struct usdhi6_host *host, struct dma_chan *chan, in usdhi6_dma_setup() argument
569 struct mmc_data *data = host->mrq->data; in usdhi6_dma_setup()
589 host->dma_active = true; in usdhi6_dma_setup()
596 desc->callback_param = host; in usdhi6_dma_setup()
600 dev_dbg(mmc_dev(host->mmc), "%s(): mapped %d -> %d, cookie %d @ %p\n", in usdhi6_dma_setup()
607 usdhi6_dma_release(host); in usdhi6_dma_setup()
608 dev_warn(mmc_dev(host->mmc), in usdhi6_dma_setup()
615 static int usdhi6_dma_start(struct usdhi6_host *host) in usdhi6_dma_start() argument
617 if (!host->chan_rx || !host->chan_tx) in usdhi6_dma_start()
620 if (host->mrq->data->flags & MMC_DATA_READ) in usdhi6_dma_start()
621 return usdhi6_dma_setup(host, host->chan_rx, DMA_DEV_TO_MEM); in usdhi6_dma_start()
623 return usdhi6_dma_setup(host, host->chan_tx, DMA_MEM_TO_DEV); in usdhi6_dma_start()
626 static void usdhi6_dma_kill(struct usdhi6_host *host) in usdhi6_dma_kill() argument
628 struct mmc_data *data = host->mrq->data; in usdhi6_dma_kill()
630 dev_dbg(mmc_dev(host->mmc), "%s(): SG of %u: %ux%u\n", in usdhi6_dma_kill()
634 dmaengine_terminate_sync(host->chan_rx); in usdhi6_dma_kill()
636 dmaengine_terminate_sync(host->chan_tx); in usdhi6_dma_kill()
639 static void usdhi6_dma_check_error(struct usdhi6_host *host) in usdhi6_dma_check_error() argument
641 struct mmc_data *data = host->mrq->data; in usdhi6_dma_check_error()
643 dev_dbg(mmc_dev(host->mmc), "%s(): IO error %d, status 0x%x\n", in usdhi6_dma_check_error()
644 __func__, host->io_error, usdhi6_read(host, USDHI6_SD_INFO1)); in usdhi6_dma_check_error()
646 if (host->io_error) { in usdhi6_dma_check_error()
647 data->error = usdhi6_error_code(host); in usdhi6_dma_check_error()
649 usdhi6_dma_kill(host); in usdhi6_dma_check_error()
650 usdhi6_dma_release(host); in usdhi6_dma_check_error()
651 dev_warn(mmc_dev(host->mmc), in usdhi6_dma_check_error()
661 if (host->irq_status & USDHI6_SD_INFO1_RSP_END) in usdhi6_dma_check_error()
662 dev_warn(mmc_dev(host->mmc), "Unexpected response received!\n"); in usdhi6_dma_check_error()
665 static void usdhi6_dma_kick(struct usdhi6_host *host) in usdhi6_dma_kick() argument
667 if (host->mrq->data->flags & MMC_DATA_READ) in usdhi6_dma_kick()
668 dma_async_issue_pending(host->chan_rx); in usdhi6_dma_kick()
670 dma_async_issue_pending(host->chan_tx); in usdhi6_dma_kick()
673 static void usdhi6_dma_request(struct usdhi6_host *host, phys_addr_t start) in usdhi6_dma_request() argument
681 host->chan_tx = dma_request_chan(mmc_dev(host->mmc), "tx"); in usdhi6_dma_request()
682 dev_dbg(mmc_dev(host->mmc), "%s: TX: got channel %p\n", __func__, in usdhi6_dma_request()
683 host->chan_tx); in usdhi6_dma_request()
685 if (IS_ERR(host->chan_tx)) { in usdhi6_dma_request()
686 host->chan_tx = NULL; in usdhi6_dma_request()
694 ret = dmaengine_slave_config(host->chan_tx, &cfg); in usdhi6_dma_request()
698 host->chan_rx = dma_request_chan(mmc_dev(host->mmc), "rx"); in usdhi6_dma_request()
699 dev_dbg(mmc_dev(host->mmc), "%s: RX: got channel %p\n", __func__, in usdhi6_dma_request()
700 host->chan_rx); in usdhi6_dma_request()
702 if (IS_ERR(host->chan_rx)) { in usdhi6_dma_request()
703 host->chan_rx = NULL; in usdhi6_dma_request()
711 ret = dmaengine_slave_config(host->chan_rx, &cfg); in usdhi6_dma_request()
718 dma_release_channel(host->chan_rx); in usdhi6_dma_request()
719 host->chan_rx = NULL; in usdhi6_dma_request()
721 dma_release_channel(host->chan_tx); in usdhi6_dma_request()
722 host->chan_tx = NULL; in usdhi6_dma_request()
727 static void usdhi6_clk_set(struct usdhi6_host *host, struct mmc_ios *ios) in usdhi6_clk_set() argument
734 if (usdhi6_read(host, USDHI6_SD_INFO2) & USDHI6_SD_INFO2_SCLKDIVEN) in usdhi6_clk_set()
740 dev_err(mmc_dev(host->mmc), "SD bus busy, clock set aborted\n"); in usdhi6_clk_set()
744 val = usdhi6_read(host, USDHI6_SD_CLK_CTRL) & ~USDHI6_SD_CLK_CTRL_DIV_MASK; in usdhi6_clk_set()
749 if (host->imclk <= rate) { in usdhi6_clk_set()
752 new_rate = host->imclk; in usdhi6_clk_set()
755 new_rate = host->imclk / 2; in usdhi6_clk_set()
759 roundup_pow_of_two(DIV_ROUND_UP(host->imclk, rate)); in usdhi6_clk_set()
761 new_rate = host->imclk / div; in usdhi6_clk_set()
764 if (host->rate == new_rate) in usdhi6_clk_set()
767 host->rate = new_rate; in usdhi6_clk_set()
769 dev_dbg(mmc_dev(host->mmc), "target %lu, div %u, set %lu\n", in usdhi6_clk_set()
777 if (host->imclk == rate || host->imclk == host->rate || !rate) in usdhi6_clk_set()
778 usdhi6_write(host, USDHI6_SD_CLK_CTRL, in usdhi6_clk_set()
782 host->rate = 0; in usdhi6_clk_set()
786 usdhi6_write(host, USDHI6_SD_CLK_CTRL, val); in usdhi6_clk_set()
788 if (host->imclk == rate || host->imclk == host->rate || in usdhi6_clk_set()
790 usdhi6_write(host, USDHI6_SD_CLK_CTRL, in usdhi6_clk_set()
794 static void usdhi6_set_power(struct usdhi6_host *host, struct mmc_ios *ios) in usdhi6_set_power() argument
796 struct mmc_host *mmc = host->mmc; in usdhi6_set_power()
804 static int usdhi6_reset(struct usdhi6_host *host) in usdhi6_reset() argument
808 usdhi6_write(host, USDHI6_SOFT_RST, USDHI6_SOFT_RST_RESERVED); in usdhi6_reset()
810 usdhi6_write(host, USDHI6_SOFT_RST, USDHI6_SOFT_RST_RESERVED | USDHI6_SOFT_RST_RESET); in usdhi6_reset()
812 if (usdhi6_read(host, USDHI6_SOFT_RST) & USDHI6_SOFT_RST_RESET) in usdhi6_reset()
820 struct usdhi6_host *host = mmc_priv(mmc); in usdhi6_set_ios() local
829 usdhi6_set_power(host, ios); in usdhi6_set_ios()
830 usdhi6_only_cd(host); in usdhi6_set_ios()
837 ret = usdhi6_reset(host); in usdhi6_set_ios()
841 usdhi6_set_power(host, ios); in usdhi6_set_ios()
842 usdhi6_only_cd(host); in usdhi6_set_ios()
846 option = usdhi6_read(host, USDHI6_SD_OPTION); in usdhi6_set_ios()
862 usdhi6_write(host, USDHI6_SD_OPTION, option); in usdhi6_set_ios()
863 usdhi6_write(host, USDHI6_SDIF_MODE, mode); in usdhi6_set_ios()
867 if (host->rate != ios->clock) in usdhi6_set_ios()
868 usdhi6_clk_set(host, ios); in usdhi6_set_ios()
872 static void usdhi6_timeout_set(struct usdhi6_host *host) in usdhi6_timeout_set() argument
874 struct mmc_request *mrq = host->mrq; in usdhi6_timeout_set()
879 ticks = host->rate / 1000 * mrq->cmd->busy_timeout; in usdhi6_timeout_set()
881 ticks = host->rate / 1000000 * (mrq->data->timeout_ns / 1000) + in usdhi6_timeout_set()
893 dev_dbg(mmc_dev(host->mmc), "Set %s timeout %lu ticks @ %lu Hz\n", in usdhi6_timeout_set()
894 mrq->data ? "data" : "cmd", ticks, host->rate); in usdhi6_timeout_set()
897 usdhi6_write(host, USDHI6_SD_OPTION, (val << USDHI6_SD_OPTION_TIMEOUT_SHIFT) | in usdhi6_timeout_set()
898 (usdhi6_read(host, USDHI6_SD_OPTION) & ~USDHI6_SD_OPTION_TIMEOUT_MASK)); in usdhi6_timeout_set()
901 static void usdhi6_request_done(struct usdhi6_host *host) in usdhi6_request_done() argument
903 struct mmc_request *mrq = host->mrq; in usdhi6_request_done()
906 if (WARN(host->pg.page || host->head_pg.page, in usdhi6_request_done()
908 host->pg.page, host->head_pg.page, host->wait, mrq->cmd->opcode, in usdhi6_request_done()
910 data ? host->offset : 0, data ? data->blocks : 0, in usdhi6_request_done()
912 usdhi6_sg_unmap(host, true); in usdhi6_request_done()
917 dev_dbg(mmc_dev(host->mmc), "%s(CMD%d: %ux%u): err %d %d %d\n", in usdhi6_request_done()
925 usdhi6_write(host, USDHI6_CC_EXT_MODE, 0); in usdhi6_request_done()
926 host->wait = USDHI6_WAIT_FOR_REQUEST; in usdhi6_request_done()
927 host->mrq = NULL; in usdhi6_request_done()
929 mmc_request_done(host->mmc, mrq); in usdhi6_request_done()
932 static int usdhi6_cmd_flags(struct usdhi6_host *host) in usdhi6_cmd_flags() argument
934 struct mmc_request *mrq = host->mrq; in usdhi6_cmd_flags()
938 if (host->app_cmd) { in usdhi6_cmd_flags()
939 host->app_cmd = false; in usdhi6_cmd_flags()
975 dev_warn(mmc_dev(host->mmc), in usdhi6_cmd_flags()
985 static int usdhi6_rq_start(struct usdhi6_host *host) in usdhi6_rq_start() argument
987 struct mmc_request *mrq = host->mrq; in usdhi6_rq_start()
990 int opc = usdhi6_cmd_flags(host); in usdhi6_rq_start()
997 if (!(usdhi6_read(host, USDHI6_SD_INFO2) & USDHI6_SD_INFO2_CBSY)) in usdhi6_rq_start()
1003 dev_dbg(mmc_dev(host->mmc), "Command active, request aborted\n"); in usdhi6_rq_start()
1011 host->page_idx = 0; in usdhi6_rq_start()
1034 dev_warn(mmc_dev(host->mmc), "%s(): %u blocks of %u bytes\n", in usdhi6_rq_start()
1043 usdhi6_sg_prep(host); in usdhi6_rq_start()
1045 usdhi6_write(host, USDHI6_SD_SIZE, data->blksz); in usdhi6_rq_start()
1051 dev_dbg(mmc_dev(host->mmc), in usdhi6_rq_start()
1058 usdhi6_dma_start(host) >= DMA_MIN_COOKIE; in usdhi6_rq_start()
1061 usdhi6_write(host, USDHI6_CC_EXT_MODE, USDHI6_CC_EXT_MODE_SDRW); in usdhi6_rq_start()
1063 dev_dbg(mmc_dev(host->mmc), in usdhi6_rq_start()
1070 dev_dbg(mmc_dev(host->mmc), "%s(): request opcode %u\n", in usdhi6_rq_start()
1075 usdhi6_wait_for_resp(host); in usdhi6_rq_start()
1077 host->wait = USDHI6_WAIT_FOR_CMD; in usdhi6_rq_start()
1078 schedule_delayed_work(&host->timeout_work, host->timeout); in usdhi6_rq_start()
1081 usdhi6_write(host, USDHI6_SD_STOP, in usdhi6_rq_start()
1083 usdhi6_write(host, USDHI6_SD_ARG, cmd->arg); in usdhi6_rq_start()
1086 usdhi6_write(host, USDHI6_SD_CMD, opc); in usdhi6_rq_start()
1093 struct usdhi6_host *host = mmc_priv(mmc); in usdhi6_request() local
1096 cancel_delayed_work_sync(&host->timeout_work); in usdhi6_request()
1098 host->mrq = mrq; in usdhi6_request()
1099 host->sg = NULL; in usdhi6_request()
1101 usdhi6_timeout_set(host); in usdhi6_request()
1102 ret = usdhi6_rq_start(host); in usdhi6_request()
1105 usdhi6_request_done(host); in usdhi6_request()
1111 struct usdhi6_host *host = mmc_priv(mmc); in usdhi6_get_cd() local
1113 u32 status = usdhi6_read(host, USDHI6_SD_INFO1) & USDHI6_SD_INFO1_CD; in usdhi6_get_cd()
1127 struct usdhi6_host *host = mmc_priv(mmc); in usdhi6_get_ro() local
1129 u32 status = usdhi6_read(host, USDHI6_SD_INFO1) & USDHI6_SD_INFO1_WP; in usdhi6_get_ro()
1143 struct usdhi6_host *host = mmc_priv(mmc); in usdhi6_enable_sdio_irq() local
1148 host->sdio_mask = USDHI6_SDIO_INFO1_IRQ & ~USDHI6_SDIO_INFO1_IOIRQ; in usdhi6_enable_sdio_irq()
1149 usdhi6_write(host, USDHI6_SDIO_INFO1_MASK, host->sdio_mask); in usdhi6_enable_sdio_irq()
1150 usdhi6_write(host, USDHI6_SDIO_MODE, 1); in usdhi6_enable_sdio_irq()
1152 usdhi6_write(host, USDHI6_SDIO_MODE, 0); in usdhi6_enable_sdio_irq()
1153 usdhi6_write(host, USDHI6_SDIO_INFO1_MASK, USDHI6_SDIO_INFO1_IRQ); in usdhi6_enable_sdio_irq()
1154 host->sdio_mask = USDHI6_SDIO_INFO1_IRQ; in usdhi6_enable_sdio_irq()
1158 static int usdhi6_set_pinstates(struct usdhi6_host *host, int voltage) in usdhi6_set_pinstates() argument
1160 if (IS_ERR(host->pins_uhs)) in usdhi6_set_pinstates()
1166 return pinctrl_select_state(host->pinctrl, in usdhi6_set_pinstates()
1167 host->pins_uhs); in usdhi6_set_pinstates()
1170 return pinctrl_select_default_state(mmc_dev(host->mmc)); in usdhi6_set_pinstates()
1191 struct usdhi6_host *host = mmc_priv(mmc); in usdhi6_card_busy() local
1192 u32 tmp = usdhi6_read(host, USDHI6_SD_INFO2); in usdhi6_card_busy()
1210 static void usdhi6_resp_cmd12(struct usdhi6_host *host) in usdhi6_resp_cmd12() argument
1212 struct mmc_command *cmd = host->mrq->stop; in usdhi6_resp_cmd12()
1213 cmd->resp[0] = usdhi6_read(host, USDHI6_SD_RSP10); in usdhi6_resp_cmd12()
1216 static void usdhi6_resp_read(struct usdhi6_host *host) in usdhi6_resp_read() argument
1218 struct mmc_command *cmd = host->mrq->cmd; in usdhi6_resp_read()
1239 if (!(host->irq_status & USDHI6_SD_INFO1_RSP_END)) { in usdhi6_resp_read()
1240 dev_err(mmc_dev(host->mmc), in usdhi6_resp_read()
1249 tmp = usdhi6_read(host, USDHI6_SD_RSP10 + i * 8); in usdhi6_resp_read()
1255 rsp[0] = usdhi6_read(host, USDHI6_SD_RSP54); in usdhi6_resp_read()
1257 rsp[0] = usdhi6_read(host, USDHI6_SD_RSP10); in usdhi6_resp_read()
1259 dev_dbg(mmc_dev(host->mmc), "Response 0x%x\n", rsp[0]); in usdhi6_resp_read()
1262 static int usdhi6_blk_read(struct usdhi6_host *host) in usdhi6_blk_read() argument
1264 struct mmc_data *data = host->mrq->data; in usdhi6_blk_read()
1268 if (host->io_error) { in usdhi6_blk_read()
1269 data->error = usdhi6_error_code(host); in usdhi6_blk_read()
1273 if (host->pg.page) { in usdhi6_blk_read()
1274 p = host->blk_page + host->offset; in usdhi6_blk_read()
1276 p = usdhi6_sg_map(host); in usdhi6_blk_read()
1284 *p = usdhi6_read(host, USDHI6_SD_BUF0); in usdhi6_blk_read()
1288 u16 d = usdhi6_read16(host, USDHI6_SD_BUF0); in usdhi6_blk_read()
1297 dev_dbg(mmc_dev(host->mmc), "%s(): %d\n", __func__, data->error); in usdhi6_blk_read()
1298 host->wait = USDHI6_WAIT_FOR_REQUEST; in usdhi6_blk_read()
1302 static int usdhi6_blk_write(struct usdhi6_host *host) in usdhi6_blk_write() argument
1304 struct mmc_data *data = host->mrq->data; in usdhi6_blk_write()
1308 if (host->io_error) { in usdhi6_blk_write()
1309 data->error = usdhi6_error_code(host); in usdhi6_blk_write()
1313 if (host->pg.page) { in usdhi6_blk_write()
1314 p = host->blk_page + host->offset; in usdhi6_blk_write()
1316 p = usdhi6_sg_map(host); in usdhi6_blk_write()
1324 usdhi6_write(host, USDHI6_SD_BUF0, *p); in usdhi6_blk_write()
1334 usdhi6_write16(host, USDHI6_SD_BUF0, d); in usdhi6_blk_write()
1340 dev_dbg(mmc_dev(host->mmc), "%s(): %d\n", __func__, data->error); in usdhi6_blk_write()
1341 host->wait = USDHI6_WAIT_FOR_REQUEST; in usdhi6_blk_write()
1345 static int usdhi6_stop_cmd(struct usdhi6_host *host) in usdhi6_stop_cmd() argument
1347 struct mmc_request *mrq = host->mrq; in usdhi6_stop_cmd()
1353 host->wait = USDHI6_WAIT_FOR_STOP; in usdhi6_stop_cmd()
1358 dev_err(mmc_dev(host->mmc), in usdhi6_stop_cmd()
1367 static bool usdhi6_end_cmd(struct usdhi6_host *host) in usdhi6_end_cmd() argument
1369 struct mmc_request *mrq = host->mrq; in usdhi6_end_cmd()
1372 if (host->io_error) { in usdhi6_end_cmd()
1373 cmd->error = usdhi6_error_code(host); in usdhi6_end_cmd()
1377 usdhi6_resp_read(host); in usdhi6_end_cmd()
1382 if (host->dma_active) { in usdhi6_end_cmd()
1383 usdhi6_dma_kick(host); in usdhi6_end_cmd()
1385 host->wait = USDHI6_WAIT_FOR_DMA; in usdhi6_end_cmd()
1386 else if (usdhi6_stop_cmd(host) < 0) in usdhi6_end_cmd()
1392 host->wait = USDHI6_WAIT_FOR_MREAD; in usdhi6_end_cmd()
1394 host->wait = USDHI6_WAIT_FOR_READ; in usdhi6_end_cmd()
1399 host->wait = USDHI6_WAIT_FOR_MWRITE; in usdhi6_end_cmd()
1401 host->wait = USDHI6_WAIT_FOR_WRITE; in usdhi6_end_cmd()
1407 static bool usdhi6_read_block(struct usdhi6_host *host) in usdhi6_read_block() argument
1410 int ret = usdhi6_blk_read(host); in usdhi6_read_block()
1417 usdhi6_sg_unmap(host, true); in usdhi6_read_block()
1422 host->wait = USDHI6_WAIT_FOR_DATA_END; in usdhi6_read_block()
1426 static bool usdhi6_mread_block(struct usdhi6_host *host) in usdhi6_mread_block() argument
1428 int ret = usdhi6_blk_read(host); in usdhi6_mread_block()
1433 usdhi6_sg_advance(host); in usdhi6_mread_block()
1435 return !host->mrq->data->error && in usdhi6_mread_block()
1436 (host->wait != USDHI6_WAIT_FOR_DATA_END || !host->mrq->stop); in usdhi6_mread_block()
1439 static bool usdhi6_write_block(struct usdhi6_host *host) in usdhi6_write_block() argument
1441 int ret = usdhi6_blk_write(host); in usdhi6_write_block()
1444 usdhi6_sg_unmap(host, true); in usdhi6_write_block()
1449 host->wait = USDHI6_WAIT_FOR_DATA_END; in usdhi6_write_block()
1453 static bool usdhi6_mwrite_block(struct usdhi6_host *host) in usdhi6_mwrite_block() argument
1455 int ret = usdhi6_blk_write(host); in usdhi6_mwrite_block()
1460 usdhi6_sg_advance(host); in usdhi6_mwrite_block()
1462 return !host->mrq->data->error && in usdhi6_mwrite_block()
1463 (host->wait != USDHI6_WAIT_FOR_DATA_END || !host->mrq->stop); in usdhi6_mwrite_block()
1470 struct usdhi6_host *host = dev_id; in usdhi6_sd_bh() local
1476 cancel_delayed_work_sync(&host->timeout_work); in usdhi6_sd_bh()
1478 mrq = host->mrq; in usdhi6_sd_bh()
1485 switch (host->wait) { in usdhi6_sd_bh()
1491 io_wait = usdhi6_end_cmd(host); in usdhi6_sd_bh()
1495 io_wait = usdhi6_mread_block(host); in usdhi6_sd_bh()
1499 io_wait = usdhi6_read_block(host); in usdhi6_sd_bh()
1503 io_wait = usdhi6_mwrite_block(host); in usdhi6_sd_bh()
1507 io_wait = usdhi6_write_block(host); in usdhi6_sd_bh()
1510 usdhi6_dma_check_error(host); in usdhi6_sd_bh()
1513 usdhi6_write(host, USDHI6_SD_STOP, 0); in usdhi6_sd_bh()
1514 if (host->io_error) { in usdhi6_sd_bh()
1515 int ret = usdhi6_error_code(host); in usdhi6_sd_bh()
1520 dev_warn(mmc_dev(host->mmc), "%s(): %d\n", __func__, ret); in usdhi6_sd_bh()
1523 usdhi6_resp_cmd12(host); in usdhi6_sd_bh()
1527 if (host->io_error) { in usdhi6_sd_bh()
1528 mrq->data->error = usdhi6_error_code(host); in usdhi6_sd_bh()
1529 dev_warn(mmc_dev(host->mmc), "%s(): %d\n", __func__, in usdhi6_sd_bh()
1535 dev_err(mmc_dev(host->mmc), "Invalid state %u\n", host->wait); in usdhi6_sd_bh()
1536 usdhi6_request_done(host); in usdhi6_sd_bh()
1541 schedule_delayed_work(&host->timeout_work, host->timeout); in usdhi6_sd_bh()
1543 if (!host->dma_active) in usdhi6_sd_bh()
1544 usdhi6_wait_for_brwe(host, mrq->data->flags & MMC_DATA_READ); in usdhi6_sd_bh()
1551 if (host->wait != USDHI6_WAIT_FOR_STOP && in usdhi6_sd_bh()
1552 host->mrq->stop && in usdhi6_sd_bh()
1553 !host->mrq->stop->error && in usdhi6_sd_bh()
1554 !usdhi6_stop_cmd(host)) { in usdhi6_sd_bh()
1556 usdhi6_wait_for_resp(host); in usdhi6_sd_bh()
1558 schedule_delayed_work(&host->timeout_work, in usdhi6_sd_bh()
1559 host->timeout); in usdhi6_sd_bh()
1567 dev_warn(mmc_dev(host->mmc), "%s(): data error %d\n", in usdhi6_sd_bh()
1569 usdhi6_sg_unmap(host, true); in usdhi6_sd_bh()
1572 host->app_cmd = true; in usdhi6_sd_bh()
1576 usdhi6_request_done(host); in usdhi6_sd_bh()
1583 struct usdhi6_host *host = dev_id; in usdhi6_sd() local
1586 status = usdhi6_read(host, USDHI6_SD_INFO1) & ~host->status_mask & in usdhi6_sd()
1588 status2 = usdhi6_read(host, USDHI6_SD_INFO2) & ~host->status2_mask; in usdhi6_sd()
1590 usdhi6_only_cd(host); in usdhi6_sd()
1592 dev_dbg(mmc_dev(host->mmc), in usdhi6_sd()
1602 usdhi6_write(host, USDHI6_SD_INFO1, in usdhi6_sd()
1610 usdhi6_write(host, USDHI6_SD_INFO2, in usdhi6_sd()
1614 host->io_error = error; in usdhi6_sd()
1615 host->irq_status = status; in usdhi6_sd()
1619 if (host->wait != USDHI6_WAIT_FOR_CMD || in usdhi6_sd()
1621 dev_warn(mmc_dev(host->mmc), in usdhi6_sd()
1625 dev_dbg(mmc_dev(host->mmc), in usdhi6_sd()
1635 struct usdhi6_host *host = dev_id; in usdhi6_sdio() local
1636 u32 status = usdhi6_read(host, USDHI6_SDIO_INFO1) & ~host->sdio_mask; in usdhi6_sdio()
1638 dev_dbg(mmc_dev(host->mmc), "%s(): status 0x%x\n", __func__, status); in usdhi6_sdio()
1643 usdhi6_write(host, USDHI6_SDIO_INFO1, ~status); in usdhi6_sdio()
1645 mmc_signal_sdio_irq(host->mmc); in usdhi6_sdio()
1652 struct usdhi6_host *host = dev_id; in usdhi6_cd() local
1653 struct mmc_host *mmc = host->mmc; in usdhi6_cd()
1657 status = usdhi6_read(host, USDHI6_SD_INFO1) & ~host->status_mask & in usdhi6_cd()
1664 usdhi6_write(host, USDHI6_SD_INFO1, ~status); in usdhi6_cd()
1684 struct usdhi6_host *host = container_of(d, struct usdhi6_host, timeout_work); in usdhi6_timeout_work() local
1685 struct mmc_request *mrq = host->mrq; in usdhi6_timeout_work()
1689 dev_warn(mmc_dev(host->mmc), in usdhi6_timeout_work()
1691 host->dma_active ? "DMA" : "PIO", in usdhi6_timeout_work()
1692 host->wait, mrq ? mrq->cmd->opcode : -1, in usdhi6_timeout_work()
1693 usdhi6_read(host, USDHI6_SD_INFO1), in usdhi6_timeout_work()
1694 usdhi6_read(host, USDHI6_SD_INFO2), host->irq_status); in usdhi6_timeout_work()
1696 if (host->dma_active) { in usdhi6_timeout_work()
1697 usdhi6_dma_kill(host); in usdhi6_timeout_work()
1698 usdhi6_dma_stop_unmap(host); in usdhi6_timeout_work()
1701 switch (host->wait) { in usdhi6_timeout_work()
1703 dev_err(mmc_dev(host->mmc), "Invalid state %u\n", host->wait); in usdhi6_timeout_work()
1706 usdhi6_error_code(host); in usdhi6_timeout_work()
1711 usdhi6_error_code(host); in usdhi6_timeout_work()
1719 sg = host->sg ?: data->sg; in usdhi6_timeout_work()
1720 dev_dbg(mmc_dev(host->mmc), in usdhi6_timeout_work()
1722 data->flags & MMC_DATA_READ ? 'R' : 'W', host->page_idx, in usdhi6_timeout_work()
1723 host->offset, data->blocks, data->blksz, data->sg_len, in usdhi6_timeout_work()
1725 usdhi6_sg_unmap(host, true); in usdhi6_timeout_work()
1728 usdhi6_error_code(host); in usdhi6_timeout_work()
1733 usdhi6_request_done(host); in usdhi6_timeout_work()
1748 struct usdhi6_host *host; in usdhi6_probe() local
1775 host = mmc_priv(mmc); in usdhi6_probe()
1776 host->mmc = mmc; in usdhi6_probe()
1777 host->wait = USDHI6_WAIT_FOR_REQUEST; in usdhi6_probe()
1778 host->timeout = msecs_to_jiffies(USDHI6_REQ_TIMEOUT_MS); in usdhi6_probe()
1785 host->pinctrl = devm_pinctrl_get(&pdev->dev); in usdhi6_probe()
1786 if (IS_ERR(host->pinctrl)) { in usdhi6_probe()
1787 ret = PTR_ERR(host->pinctrl); in usdhi6_probe()
1791 host->pins_uhs = pinctrl_lookup_state(host->pinctrl, "state_uhs"); in usdhi6_probe()
1794 host->base = devm_ioremap_resource(dev, res); in usdhi6_probe()
1795 if (IS_ERR(host->base)) { in usdhi6_probe()
1796 ret = PTR_ERR(host->base); in usdhi6_probe()
1800 host->clk = devm_clk_get(dev, NULL); in usdhi6_probe()
1801 if (IS_ERR(host->clk)) { in usdhi6_probe()
1802 ret = PTR_ERR(host->clk); in usdhi6_probe()
1806 host->imclk = clk_get_rate(host->clk); in usdhi6_probe()
1808 ret = clk_prepare_enable(host->clk); in usdhi6_probe()
1812 version = usdhi6_read(host, USDHI6_VERSION); in usdhi6_probe()
1820 usdhi6_read(host, USDHI6_SD_PORT_SEL) >> USDHI6_SD_PORT_SEL_PORTS_SHIFT); in usdhi6_probe()
1822 usdhi6_mask_all(host); in usdhi6_probe()
1826 dev_name(dev), host); in usdhi6_probe()
1834 dev_name(dev), host); in usdhi6_probe()
1839 dev_name(dev), host); in usdhi6_probe()
1843 INIT_DELAYED_WORK(&host->timeout_work, usdhi6_timeout_work); in usdhi6_probe()
1845 usdhi6_dma_request(host, res->start); in usdhi6_probe()
1865 mmc->f_max = host->imclk; in usdhi6_probe()
1866 mmc->f_min = host->imclk / 512; in usdhi6_probe()
1868 platform_set_drvdata(pdev, host); in usdhi6_probe()
1877 usdhi6_dma_release(host); in usdhi6_probe()
1879 clk_disable_unprepare(host->clk); in usdhi6_probe()
1888 struct usdhi6_host *host = platform_get_drvdata(pdev); in usdhi6_remove() local
1890 mmc_remove_host(host->mmc); in usdhi6_remove()
1892 usdhi6_mask_all(host); in usdhi6_remove()
1893 cancel_delayed_work_sync(&host->timeout_work); in usdhi6_remove()
1894 usdhi6_dma_release(host); in usdhi6_remove()
1895 clk_disable_unprepare(host->clk); in usdhi6_remove()
1896 mmc_free_host(host->mmc); in usdhi6_remove()