• Home
  • Raw
  • Download

Lines Matching full:mmc

31 #include <linux/mmc/host.h>
32 #include <linux/mmc/mmc.h>
33 #include <linux/mmc/sdio.h>
34 #include <linux/mmc/slot-gpio.h>
44 #define DRIVER_NAME "meson-gx-mmc"
159 struct mmc_host *mmc; member
220 struct meson_mmc_phase *mmc = to_meson_mmc_phase(hw); in meson_mmc_clk_get_phase() local
221 unsigned int phase_num = 1 << hweight_long(mmc->phase_mask); in meson_mmc_clk_get_phase()
226 val = readl(mmc->reg); in meson_mmc_clk_get_phase()
227 p = (val & mmc->phase_mask) >> __ffs(mmc->phase_mask); in meson_mmc_clk_get_phase()
230 if (mmc->delay_mask) { in meson_mmc_clk_get_phase()
233 d = (val & mmc->delay_mask) >> __ffs(mmc->delay_mask); in meson_mmc_clk_get_phase()
234 degrees += d * mmc->delay_step_ps * 360 / period_ps; in meson_mmc_clk_get_phase()
241 static void meson_mmc_apply_phase_delay(struct meson_mmc_phase *mmc, in meson_mmc_apply_phase_delay() argument
247 val = readl(mmc->reg); in meson_mmc_apply_phase_delay()
248 val &= ~mmc->phase_mask; in meson_mmc_apply_phase_delay()
249 val |= phase << __ffs(mmc->phase_mask); in meson_mmc_apply_phase_delay()
251 if (mmc->delay_mask) { in meson_mmc_apply_phase_delay()
252 val &= ~mmc->delay_mask; in meson_mmc_apply_phase_delay()
253 val |= delay << __ffs(mmc->delay_mask); in meson_mmc_apply_phase_delay()
256 writel(val, mmc->reg); in meson_mmc_apply_phase_delay()
261 struct meson_mmc_phase *mmc = to_meson_mmc_phase(hw); in meson_mmc_clk_set_phase() local
262 unsigned int phase_num = 1 << hweight_long(mmc->phase_mask); in meson_mmc_clk_set_phase()
268 if (!mmc->delay_mask) { in meson_mmc_clk_set_phase()
279 360 * mmc->delay_step_ps); in meson_mmc_clk_set_phase()
280 d = min(d, mmc->delay_mask >> __ffs(mmc->delay_mask)); in meson_mmc_clk_set_phase()
283 meson_mmc_apply_phase_delay(mmc, p, d); in meson_mmc_clk_set_phase()
315 static void meson_mmc_get_transfer_mode(struct mmc_host *mmc, in meson_mmc_get_transfer_mode() argument
355 static void meson_mmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq) in meson_mmc_pre_req() argument
362 meson_mmc_get_transfer_mode(mmc, mrq); in meson_mmc_pre_req()
368 data->sg_count = dma_map_sg(mmc_dev(mmc), data->sg, data->sg_len, in meson_mmc_pre_req()
371 dev_err(mmc_dev(mmc), "dma_map_sg failed"); in meson_mmc_pre_req()
374 static void meson_mmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, in meson_mmc_post_req() argument
380 dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, in meson_mmc_post_req()
395 * Gating the clock on this controller is tricky. It seems the mmc clock
432 struct mmc_host *mmc = host->mmc; in meson_mmc_clk_set() local
450 mmc->actual_clock = 0; in meson_mmc_clk_set()
468 mmc->actual_clock = clk_get_rate(host->mmc_clk); in meson_mmc_clk_set()
472 mmc->actual_clock >>= 1; in meson_mmc_clk_set()
474 dev_dbg(host->dev, "clk rate: %u Hz\n", mmc->actual_clock); in meson_mmc_clk_set()
475 if (ios->clock != mmc->actual_clock) in meson_mmc_clk_set()
486 * generating the MMC clock. Use the clock framework to create and
568 /* create the mmc core clock */ in meson_mmc_clk_init()
589 /* create the mmc tx clock */ in meson_mmc_clk_init()
612 /* create the mmc rx clock */ in meson_mmc_clk_init()
636 host->mmc->f_min = clk_round_rate(host->mmc_clk, 400000); in meson_mmc_clk_init()
637 ret = clk_set_rate(host->mmc_clk, host->mmc->f_min); in meson_mmc_clk_init()
715 static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, in meson_mmc_clk_phase_tuning() argument
721 dev_dbg(mmc_dev(mmc), "%s phase/delay tunning...\n", in meson_mmc_clk_phase_tuning()
728 ret = mmc_send_tuning(mmc, opcode, NULL); in meson_mmc_clk_phase_tuning()
739 dev_dbg(mmc_dev(mmc), "success with phase: %d\n", in meson_mmc_clk_phase_tuning()
744 static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) in meson_mmc_execute_tuning() argument
746 struct meson_host *host = mmc_priv(mmc); in meson_mmc_execute_tuning()
748 return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); in meson_mmc_execute_tuning()
751 static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) in meson_mmc_set_ios() argument
753 struct meson_host *host = mmc_priv(mmc); in meson_mmc_set_ios()
763 if (!IS_ERR(mmc->supply.vmmc)) in meson_mmc_set_ios()
764 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); in meson_mmc_set_ios()
766 if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { in meson_mmc_set_ios()
767 regulator_disable(mmc->supply.vqmmc); in meson_mmc_set_ios()
774 if (!IS_ERR(mmc->supply.vmmc)) in meson_mmc_set_ios()
775 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); in meson_mmc_set_ios()
783 if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { in meson_mmc_set_ios()
784 int ret = regulator_enable(mmc->supply.vqmmc); in meson_mmc_set_ios()
833 static void meson_mmc_request_done(struct mmc_host *mmc, in meson_mmc_request_done() argument
836 struct meson_host *host = mmc_priv(mmc); in meson_mmc_request_done()
839 mmc_request_done(host->mmc, mrq); in meson_mmc_request_done()
842 static void meson_mmc_set_blksz(struct mmc_host *mmc, unsigned int blksz) in meson_mmc_set_blksz() argument
844 struct meson_host *host = mmc_priv(mmc); in meson_mmc_set_blksz()
884 static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg) in meson_mmc_desc_chain_transfer() argument
886 struct meson_host *host = mmc_priv(mmc); in meson_mmc_desc_chain_transfer()
898 meson_mmc_set_blksz(mmc, data->blksz); in meson_mmc_desc_chain_transfer()
922 static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) in meson_mmc_start_cmd() argument
924 struct meson_host *host = mmc_priv(mmc); in meson_mmc_start_cmd()
948 meson_mmc_desc_chain_transfer(mmc, cmd_cfg); in meson_mmc_start_cmd()
956 meson_mmc_set_blksz(mmc, data->blksz); in meson_mmc_start_cmd()
985 static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) in meson_mmc_request() argument
987 struct meson_host *host = mmc_priv(mmc); in meson_mmc_request()
992 meson_mmc_get_transfer_mode(mmc, mrq); in meson_mmc_request()
998 meson_mmc_pre_req(mmc, mrq); in meson_mmc_request()
1003 meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd); in meson_mmc_request()
1006 meson_mmc_post_req(mmc, mrq, 0); in meson_mmc_request()
1009 static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd) in meson_mmc_read_resp() argument
1011 struct meson_host *host = mmc_priv(mmc); in meson_mmc_read_resp()
1064 meson_mmc_read_resp(host->mmc, cmd); in meson_mmc_irq()
1094 meson_mmc_request_done(host->mmc, cmd->mrq); in meson_mmc_irq()
1140 meson_mmc_request_done(host->mmc, cmd->mrq); in meson_mmc_irq_thread()
1155 meson_mmc_start_cmd(host->mmc, next_cmd); in meson_mmc_irq_thread()
1157 meson_mmc_request_done(host->mmc, cmd->mrq); in meson_mmc_irq_thread()
1164 * interrupts. For now, the MMC core will use this for polling.
1166 static int meson_mmc_get_cd(struct mmc_host *mmc) in meson_mmc_get_cd() argument
1168 int status = mmc_gpio_get_cd(mmc); in meson_mmc_get_cd()
1191 static int meson_mmc_card_busy(struct mmc_host *mmc) in meson_mmc_card_busy() argument
1193 struct meson_host *host = mmc_priv(mmc); in meson_mmc_card_busy()
1202 static int meson_mmc_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) in meson_mmc_voltage_switch() argument
1205 if (!IS_ERR(mmc->supply.vqmmc)) { in meson_mmc_voltage_switch()
1213 return mmc_regulator_set_vqmmc(mmc, ios); in meson_mmc_voltage_switch()
1238 struct mmc_host *mmc; in meson_mmc_probe() local
1241 mmc = mmc_alloc_host(sizeof(struct meson_host), &pdev->dev); in meson_mmc_probe()
1242 if (!mmc) in meson_mmc_probe()
1244 host = mmc_priv(mmc); in meson_mmc_probe()
1245 host->mmc = mmc; in meson_mmc_probe()
1253 ret = mmc_regulator_get_supply(mmc); in meson_mmc_probe()
1257 ret = mmc_of_parse(mmc); in meson_mmc_probe()
1347 mmc->caps |= MMC_CAP_CMD23; in meson_mmc_probe()
1348 mmc->max_blk_count = CMD_CFG_LENGTH_MASK; in meson_mmc_probe()
1349 mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size; in meson_mmc_probe()
1350 mmc->max_segs = SD_EMMC_DESC_BUF_LEN / sizeof(struct sd_emmc_desc); in meson_mmc_probe()
1351 mmc->max_seg_size = mmc->max_req_size; in meson_mmc_probe()
1354 host->bounce_buf_size = mmc->max_req_size; in meson_mmc_probe()
1372 mmc->ops = &meson_mmc_ops; in meson_mmc_probe()
1373 mmc_add_host(mmc); in meson_mmc_probe()
1387 mmc_free_host(mmc); in meson_mmc_probe()
1395 mmc_remove_host(host->mmc); in meson_mmc_remove()
1409 mmc_free_host(host->mmc); in meson_mmc_remove()
1426 { .compatible = "amlogic,meson-gx-mmc", .data = &meson_gx_data },
1427 { .compatible = "amlogic,meson-gxbb-mmc", .data = &meson_gx_data },
1428 { .compatible = "amlogic,meson-gxl-mmc", .data = &meson_gx_data },
1429 { .compatible = "amlogic,meson-gxm-mmc", .data = &meson_gx_data },
1430 { .compatible = "amlogic,meson-axg-mmc", .data = &meson_axg_data },