Lines Matching full:host

15 #include <linux/mmc/host.h>
176 static inline int spmmc_wait_finish(struct spmmc_host *host) in spmmc_wait_finish() argument
180 return readl_poll_timeout(host->base + SPMMC_SD_STATE_REG, state, in spmmc_wait_finish()
185 static inline int spmmc_wait_sdstatus(struct spmmc_host *host, unsigned int status_bit) in spmmc_wait_sdstatus() argument
189 return readl_poll_timeout(host->base + SPMMC_SD_STATUS_REG, status, in spmmc_wait_sdstatus()
194 #define spmmc_wait_rspbuf_full(host) spmmc_wait_sdstatus(host, SPMMC_SDSTATUS_RSP_BUF_FULL) argument
195 #define spmmc_wait_rxbuf_full(host) spmmc_wait_sdstatus(host, SPMMC_SDSTATUS_RX_DATA_BUF_FULL) argument
196 #define spmmc_wait_txbuf_empty(host) spmmc_wait_sdstatus(host, SPMMC_SDSTATUS_TX_DATA_BUF_EMPTY) argument
198 static void spmmc_get_rsp(struct spmmc_host *host, struct mmc_command *cmd) in spmmc_get_rsp() argument
205 if (spmmc_wait_rspbuf_full(host)) in spmmc_get_rsp()
207 value0_3 = readl(host->base + SPMMC_SD_RSPBUF0_3_REG); in spmmc_get_rsp()
208 value4_5 = readl(host->base + SPMMC_SD_RSPBUF4_5_REG) & 0xffff; in spmmc_get_rsp()
211 value0_3 = readl(host->base + SPMMC_SD_RSPBUF0_3_REG); in spmmc_get_rsp()
212 value4_5 = readl(host->base + SPMMC_SD_RSPBUF4_5_REG) & 0xffff; in spmmc_get_rsp()
216 value0_3 = readl(host->base + SPMMC_SD_RSPBUF0_3_REG); in spmmc_get_rsp()
217 value4_5 = readl(host->base + SPMMC_SD_RSPBUF4_5_REG) & 0xffff; in spmmc_get_rsp()
222 if (spmmc_wait_rspbuf_full(host)) in spmmc_get_rsp()
224 value0_3 = readl(host->base + SPMMC_SD_RSPBUF0_3_REG); in spmmc_get_rsp()
225 value4_5 = readl(host->base + SPMMC_SD_RSPBUF4_5_REG) & 0xffff; in spmmc_get_rsp()
231 static void spmmc_set_bus_clk(struct spmmc_host *host, int clk) in spmmc_set_bus_clk() argument
234 int f_min = host->mmc->f_min; in spmmc_set_bus_clk()
235 int f_max = host->mmc->f_max; in spmmc_set_bus_clk()
236 u32 value = readl(host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_clk()
243 clkdiv = (clk_get_rate(host->clk) + clk) / clk - 1; in spmmc_set_bus_clk()
248 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_clk()
251 static void spmmc_set_bus_timing(struct spmmc_host *host, unsigned int timing) in spmmc_set_bus_timing() argument
253 u32 value = readl(host->base + SPMMC_SD_CONFIG1_REG); in spmmc_set_bus_timing()
254 int clkdiv = FIELD_GET(SPMMC_CLOCK_DIVISION, readl(host->base + SPMMC_SD_CONFIG0_REG)); in spmmc_set_bus_timing()
282 writel(value, host->base + SPMMC_SD_CONFIG1_REG); in spmmc_set_bus_timing()
283 value = readl(host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_set_bus_timing()
288 writel(value, host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_set_bus_timing()
291 writel(value, host->base + SPMMC_SD_CONFIG1_REG); in spmmc_set_bus_timing()
294 value = readl(host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_timing()
296 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_timing()
298 value = readl(host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_timing()
300 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_timing()
304 static void spmmc_set_bus_width(struct spmmc_host *host, int width) in spmmc_set_bus_width() argument
306 u32 value = readl(host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_width()
322 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_bus_width()
328 static void spmmc_set_sdmmc_mode(struct spmmc_host *host) in spmmc_set_sdmmc_mode() argument
330 u32 value = readl(host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_sdmmc_mode()
334 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_set_sdmmc_mode()
337 static void spmmc_sw_reset(struct spmmc_host *host) in spmmc_sw_reset() argument
346 value = readl(host->base + SPMMC_HW_DMA_CTRL_REG); in spmmc_sw_reset()
348 writel(value, host->base + SPMMC_HW_DMA_CTRL_REG); in spmmc_sw_reset()
350 writel(value, host->base + SPMMC_HW_DMA_CTRL_REG); in spmmc_sw_reset()
351 value = readl(host->base + SPMMC_HW_DMA_CTRL_REG); in spmmc_sw_reset()
353 writel(value, host->base + SPMMC_HW_DMA_CTRL_REG); in spmmc_sw_reset()
354 writel(0x7, host->base + SPMMC_SD_RST_REG); in spmmc_sw_reset()
355 readl_poll_timeout_atomic(host->base + SPMMC_SD_HW_STATE_REG, value, in spmmc_sw_reset()
359 static void spmmc_prepare_cmd(struct spmmc_host *host, struct mmc_command *cmd) in spmmc_prepare_cmd() argument
365 writel(value, host->base + SPMMC_SD_CMDBUF0_3_REG); in spmmc_prepare_cmd()
366 writeb(cmd->arg & 0xff, host->base + SPMMC_SD_CMDBUF4_REG); in spmmc_prepare_cmd()
369 value = readl(host->base + SPMMC_SD_INT_REG); in spmmc_prepare_cmd()
372 writel(value, host->base + SPMMC_SD_INT_REG); in spmmc_prepare_cmd()
374 value = readl(host->base + SPMMC_SD_CONFIG0_REG); in spmmc_prepare_cmd()
381 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_prepare_cmd()
386 * Currently, host is not capable of checking R2's CRC7, in spmmc_prepare_cmd()
398 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_prepare_cmd()
401 static void spmmc_prepare_data(struct spmmc_host *host, struct mmc_data *data) in spmmc_prepare_data() argument
405 writel(data->blocks - 1, host->base + SPMMC_SD_PAGE_NUM_REG); in spmmc_prepare_data()
406 writel(data->blksz - 1, host->base + SPMMC_SD_BLOCKSIZE_REG); in spmmc_prepare_data()
407 value = readl(host->base + SPMMC_SD_CONFIG0_REG); in spmmc_prepare_data()
413 srcdst = readl(host->base + SPMMC_CARD_MEDIATYPE_SRCDST_REG); in spmmc_prepare_data()
418 writel(srcdst, host->base + SPMMC_CARD_MEDIATYPE_SRCDST_REG); in spmmc_prepare_data()
422 srcdst = readl(host->base + SPMMC_CARD_MEDIATYPE_SRCDST_REG); in spmmc_prepare_data()
427 writel(srcdst, host->base + SPMMC_CARD_MEDIATYPE_SRCDST_REG); in spmmc_prepare_data()
431 if (host->dmapio_mode == SPMMC_DMA_MODE) { in spmmc_prepare_data()
437 count = dma_map_sg(host->mmc->parent, data->sg, data->sg_len, in spmmc_prepare_data()
448 writel(dma_addr, host->base + SPMMC_DMA_BASE_ADDR_REG); in spmmc_prepare_data()
449 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_0_SIZE_REG); in spmmc_prepare_data()
451 writel(dma_addr, host->base + SPMMC_SDRAM_SECTOR_1_ADDR_REG); in spmmc_prepare_data()
452 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_1_LENG_REG); in spmmc_prepare_data()
454 writel(dma_addr, host->base + SPMMC_SDRAM_SECTOR_2_ADDR_REG); in spmmc_prepare_data()
455 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_2_LENG_REG); in spmmc_prepare_data()
457 writel(dma_addr, host->base + SPMMC_SDRAM_SECTOR_3_ADDR_REG); in spmmc_prepare_data()
458 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_3_LENG_REG); in spmmc_prepare_data()
460 writel(dma_addr, host->base + SPMMC_SDRAM_SECTOR_4_ADDR_REG); in spmmc_prepare_data()
461 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_4_LENG_REG); in spmmc_prepare_data()
463 writel(dma_addr, host->base + SPMMC_SDRAM_SECTOR_5_ADDR_REG); in spmmc_prepare_data()
464 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_5_LENG_REG); in spmmc_prepare_data()
466 writel(dma_addr, host->base + SPMMC_SDRAM_SECTOR_6_ADDR_REG); in spmmc_prepare_data()
467 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_6_LENG_REG); in spmmc_prepare_data()
469 writel(dma_addr, host->base + SPMMC_SDRAM_SECTOR_7_ADDR_REG); in spmmc_prepare_data()
470 writel(dma_size, host->base + SPMMC_SDRAM_SECTOR_7_LENG_REG); in spmmc_prepare_data()
474 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_prepare_data()
476 if (data->blksz * data->blocks > host->dma_int_threshold) { in spmmc_prepare_data()
477 host->dma_use_int = 1; in spmmc_prepare_data()
478 value = readl(host->base + SPMMC_SD_INT_REG); in spmmc_prepare_data()
481 writel(value, host->base + SPMMC_SD_INT_REG); in spmmc_prepare_data()
486 writel(value, host->base + SPMMC_SD_CONFIG0_REG); in spmmc_prepare_data()
490 static inline void spmmc_trigger_transaction(struct spmmc_host *host) in spmmc_trigger_transaction() argument
492 u32 value = readl(host->base + SPMMC_SD_CTRL_REG); in spmmc_trigger_transaction()
495 writel(value, host->base + SPMMC_SD_CTRL_REG); in spmmc_trigger_transaction()
498 static void spmmc_send_stop_cmd(struct spmmc_host *host) in spmmc_send_stop_cmd() argument
506 spmmc_prepare_cmd(host, &stop); in spmmc_send_stop_cmd()
507 value = readl(host->base + SPMMC_SD_INT_REG); in spmmc_send_stop_cmd()
510 writel(value, host->base + SPMMC_SD_INT_REG); in spmmc_send_stop_cmd()
511 spmmc_trigger_transaction(host); in spmmc_send_stop_cmd()
512 readl_poll_timeout(host->base + SPMMC_SD_STATE_REG, value, in spmmc_send_stop_cmd()
516 static int spmmc_check_error(struct spmmc_host *host, struct mmc_request *mrq) in spmmc_check_error() argument
522 u32 value = readl(host->base + SPMMC_SD_STATE_REG); in spmmc_check_error()
528 value = readl(host->base + SPMMC_SD_STATUS_REG); in spmmc_check_error()
530 if (host->tuning_info.enable_tuning) { in spmmc_check_error()
531 timing_cfg0 = readl(host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_check_error()
532 host->tuning_info.rd_crc_dly = FIELD_GET(SPMMC_SD_READ_CRC_DELAY, in spmmc_check_error()
534 host->tuning_info.rd_dat_dly = FIELD_GET(SPMMC_SD_READ_DATA_DELAY, in spmmc_check_error()
536 host->tuning_info.rd_rsp_dly = FIELD_GET(SPMMC_SD_READ_RESPONSE_DELAY, in spmmc_check_error()
538 host->tuning_info.wr_cmd_dly = FIELD_GET(SPMMC_SD_WRITE_COMMAND_DELAY, in spmmc_check_error()
540 host->tuning_info.wr_dat_dly = FIELD_GET(SPMMC_SD_WRITE_DATA_DELAY, in spmmc_check_error()
546 host->tuning_info.wr_cmd_dly++; in spmmc_check_error()
549 host->tuning_info.rd_rsp_dly++; in spmmc_check_error()
553 host->tuning_info.rd_dat_dly++; in spmmc_check_error()
556 host->tuning_info.rd_dat_dly++; in spmmc_check_error()
559 host->tuning_info.rd_crc_dly++; in spmmc_check_error()
563 host->tuning_info.wr_dat_dly++; in spmmc_check_error()
565 host->tuning_info.rd_crc_dly++; in spmmc_check_error()
573 if (!host->tuning_info.need_tuning && host->tuning_info.enable_tuning) in spmmc_check_error()
575 spmmc_sw_reset(host); in spmmc_check_error()
577 if (host->tuning_info.enable_tuning) { in spmmc_check_error()
580 host->tuning_info.rd_crc_dly); in spmmc_check_error()
583 host->tuning_info.rd_dat_dly); in spmmc_check_error()
586 host->tuning_info.rd_rsp_dly); in spmmc_check_error()
589 host->tuning_info.wr_cmd_dly); in spmmc_check_error()
592 host->tuning_info.wr_dat_dly); in spmmc_check_error()
593 writel(timing_cfg0, host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_check_error()
599 host->tuning_info.need_tuning = ret; in spmmc_check_error()
624 static void spmmc_xfer_data_pio(struct spmmc_host *host, struct mmc_data *data) in spmmc_xfer_data_pio() argument
646 if (spmmc_wait_txbuf_empty(host)) in spmmc_xfer_data_pio()
648 writel(*buf, host->base + SPMMC_SD_PIODATATX_REG); in spmmc_xfer_data_pio()
650 if (spmmc_wait_rxbuf_full(host)) in spmmc_xfer_data_pio()
652 *buf = readl(host->base + SPMMC_SD_PIODATARX_REG); in spmmc_xfer_data_pio()
666 static void spmmc_controller_init(struct spmmc_host *host) in spmmc_controller_init() argument
669 int ret = reset_control_assert(host->rstc); in spmmc_controller_init()
673 ret = reset_control_deassert(host->rstc); in spmmc_controller_init()
676 value = readl(host->base + SPMMC_CARD_MEDIATYPE_SRCDST_REG); in spmmc_controller_init()
679 writel(value, host->base + SPMMC_CARD_MEDIATYPE_SRCDST_REG); in spmmc_controller_init()
687 static void spmmc_finish_request(struct spmmc_host *host, struct mmc_request *mrq) in spmmc_finish_request() argument
698 if (data && SPMMC_DMA_MODE == host->dmapio_mode) { in spmmc_finish_request()
699 dma_unmap_sg(host->mmc->parent, data->sg, data->sg_len, mmc_get_dma_dir(data)); in spmmc_finish_request()
700 host->dma_use_int = 0; in spmmc_finish_request()
703 spmmc_get_rsp(host, cmd); in spmmc_finish_request()
704 spmmc_check_error(host, mrq); in spmmc_finish_request()
706 spmmc_send_stop_cmd(host); in spmmc_finish_request()
708 host->mrq = NULL; in spmmc_finish_request()
709 mmc_request_done(host->mmc, mrq); in spmmc_finish_request()
715 struct spmmc_host *host = dev_id; in spmmc_irq() local
716 u32 value = readl(host->base + SPMMC_SD_INT_REG); in spmmc_irq()
721 writel(value, host->base + SPMMC_SD_INT_REG); in spmmc_irq()
729 struct spmmc_host *host = mmc_priv(mmc); in spmmc_request() local
733 host->mrq = mrq; in spmmc_request()
737 spmmc_prepare_cmd(host, cmd); in spmmc_request()
740 spmmc_trigger_transaction(host); in spmmc_request()
741 spmmc_get_rsp(host, cmd); in spmmc_request()
742 spmmc_wait_finish(host); in spmmc_request()
743 spmmc_check_error(host, mrq); in spmmc_request()
744 host->mrq = NULL; in spmmc_request()
745 mmc_request_done(host->mmc, mrq); in spmmc_request()
748 spmmc_prepare_data(host, data); in spmmc_request()
750 if (host->dmapio_mode == SPMMC_PIO_MODE && data) { in spmmc_request()
753 value = readl(host->base + SPMMC_SD_INT_REG); in spmmc_request()
755 writel(value, host->base + SPMMC_SD_INT_REG); in spmmc_request()
756 spmmc_trigger_transaction(host); in spmmc_request()
757 spmmc_xfer_data_pio(host, data); in spmmc_request()
758 spmmc_wait_finish(host); in spmmc_request()
759 spmmc_finish_request(host, mrq); in spmmc_request()
761 if (host->dma_use_int) { in spmmc_request()
762 spmmc_trigger_transaction(host); in spmmc_request()
764 spmmc_trigger_transaction(host); in spmmc_request()
765 spmmc_wait_finish(host); in spmmc_request()
766 spmmc_finish_request(host, mrq); in spmmc_request()
774 struct spmmc_host *host = (struct spmmc_host *)mmc_priv(mmc); in spmmc_set_ios() local
776 spmmc_set_bus_clk(host, ios->clock); in spmmc_set_ios()
777 spmmc_set_bus_timing(host, ios->timing); in spmmc_set_ios()
778 spmmc_set_bus_width(host, ios->bus_width); in spmmc_set_ios()
780 spmmc_set_sdmmc_mode(host); in spmmc_set_ios()
805 struct spmmc_host *host = mmc_priv(mmc); in spmmc_execute_tuning() local
809 host->tuning_info.enable_tuning = 0; in spmmc_execute_tuning()
811 value = readl(host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_execute_tuning()
818 writel(value, host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_execute_tuning()
825 host->tuning_info.enable_tuning = 1; in spmmc_execute_tuning()
829 value = readl(host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_execute_tuning()
836 writel(value, host->base + SPMMC_SD_TIMING_CONFIG0_REG); in spmmc_execute_tuning()
852 struct spmmc_host *host = dev_id; in spmmc_func_finish_req() local
854 spmmc_finish_request(host, host->mrq); in spmmc_func_finish_req()
863 struct spmmc_host *host; in spmmc_drv_probe() local
870 host = mmc_priv(mmc); in spmmc_drv_probe()
871 host->mmc = mmc; in spmmc_drv_probe()
872 host->dmapio_mode = SPMMC_DMA_MODE; in spmmc_drv_probe()
873 host->dma_int_threshold = 1024; in spmmc_drv_probe()
875 host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in spmmc_drv_probe()
876 if (IS_ERR(host->base)) in spmmc_drv_probe()
877 return PTR_ERR(host->base); in spmmc_drv_probe()
879 host->clk = devm_clk_get(&pdev->dev, NULL); in spmmc_drv_probe()
880 if (IS_ERR(host->clk)) in spmmc_drv_probe()
881 return dev_err_probe(&pdev->dev, PTR_ERR(host->clk), "clk get fail\n"); in spmmc_drv_probe()
883 host->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); in spmmc_drv_probe()
884 if (IS_ERR(host->rstc)) in spmmc_drv_probe()
885 return dev_err_probe(&pdev->dev, PTR_ERR(host->rstc), "rst get fail\n"); in spmmc_drv_probe()
887 host->irq = platform_get_irq(pdev, 0); in spmmc_drv_probe()
888 if (host->irq < 0) in spmmc_drv_probe()
889 return host->irq; in spmmc_drv_probe()
891 ret = devm_request_threaded_irq(&pdev->dev, host->irq, in spmmc_drv_probe()
893 NULL, host); in spmmc_drv_probe()
897 ret = clk_prepare_enable(host->clk); in spmmc_drv_probe()
922 dev_set_drvdata(&pdev->dev, host); in spmmc_drv_probe()
923 spmmc_controller_init(host); in spmmc_drv_probe()
924 spmmc_set_sdmmc_mode(host); in spmmc_drv_probe()
925 host->tuning_info.enable_tuning = 1; in spmmc_drv_probe()
938 clk_disable_unprepare(host->clk); in spmmc_drv_probe()
944 struct spmmc_host *host = platform_get_drvdata(dev); in spmmc_drv_remove() local
946 mmc_remove_host(host->mmc); in spmmc_drv_remove()
948 clk_disable_unprepare(host->clk); in spmmc_drv_remove()
955 struct spmmc_host *host; in spmmc_pm_runtime_suspend() local
957 host = dev_get_drvdata(dev); in spmmc_pm_runtime_suspend()
958 clk_disable_unprepare(host->clk); in spmmc_pm_runtime_suspend()
965 struct spmmc_host *host; in spmmc_pm_runtime_resume() local
967 host = dev_get_drvdata(dev); in spmmc_pm_runtime_resume()
969 return clk_prepare_enable(host->clk); in spmmc_pm_runtime_resume()