^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2008 Embedded Alley Solutions, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2009-2011 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/dmaengine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/dma/mxs-dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/mmc/host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mmc/mmc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/mmc/sdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/mmc/slot-gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/stmp_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/spi/mxs-spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DRIVER_NAME "mxs-mmc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MXS_MMC_IRQ_BITS (BM_SSP_CTRL1_SDIO_IRQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) BM_SSP_CTRL1_RESP_ERR_IRQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) BM_SSP_CTRL1_RESP_TIMEOUT_IRQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) BM_SSP_CTRL1_DATA_TIMEOUT_IRQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) BM_SSP_CTRL1_DATA_CRC_IRQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) BM_SSP_CTRL1_RECV_TIMEOUT_IRQ | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* card detect polling timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MXS_MMC_DETECT_TIMEOUT (HZ/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct mxs_mmc_host {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct mxs_ssp ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct mmc_host *mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct mmc_request *mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct mmc_command *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct mmc_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned char bus_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int sdio_irq_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bool broken_cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int mxs_mmc_get_cd(struct mmc_host *mmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct mxs_mmc_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int present, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (host->broken_cd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ret = mmc_gpio_get_cd(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) present = mmc->caps & MMC_CAP_NEEDS_POLL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) !(readl(ssp->base + HW_SSP_STATUS(ssp)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) BM_SSP_STATUS_CARD_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) present = !present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int mxs_mmc_reset(struct mxs_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u32 ctrl0, ctrl1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ret = stmp_reset_block(ssp->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) BF_SSP(0x7, CTRL1_WORD_LENGTH) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) BM_SSP_CTRL1_DMA_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) BM_SSP_CTRL1_POLARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) BM_SSP_CTRL1_DATA_CRC_IRQ_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) BM_SSP_CTRL1_RESP_ERR_IRQ_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) BF_SSP(2, TIMING_CLOCK_DIVIDE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) BF_SSP(0, TIMING_CLOCK_RATE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ssp->base + HW_SSP_TIMING(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (host->sdio_irq_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) writel(ctrl0, ssp->base + HW_SSP_CTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) writel(ctrl1, ssp->base + HW_SSP_CTRL1(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct mmc_command *cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void mxs_mmc_request_done(struct mxs_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct mmc_command *cmd = host->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct mmc_data *data = host->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct mmc_request *mrq = host->mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (mmc_resp_type(cmd) & MMC_RSP_136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (cmd == mrq->sbc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Finished CMD23, now send actual command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) mxs_mmc_start_cmd(host, mrq->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) } else if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dma_unmap_sg(mmc_dev(host->mmc), data->sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) data->sg_len, ssp->dma_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * If there was an error on any block, we mark all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * data blocks as being in error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!data->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) data->bytes_xfered = data->blocks * data->blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) data->bytes_xfered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) host->data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (data->stop && (data->error || !mrq->sbc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mxs_mmc_start_cmd(host, mrq->stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) host->mrq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) mmc_request_done(host->mmc, mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static void mxs_mmc_dma_irq_callback(void *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct mxs_mmc_host *host = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mxs_mmc_request_done(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct mxs_mmc_host *host = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct mmc_command *cmd = host->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct mmc_data *data = host->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u32 stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) spin_lock(&host->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) stat = readl(ssp->base + HW_SSP_CTRL1(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) writel(stat & MXS_MMC_IRQ_BITS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) spin_unlock(&host->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mmc_signal_sdio_irq(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) cmd->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cmd->error = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (stat & (BM_SSP_CTRL1_DATA_TIMEOUT_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) data->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else if (stat & BM_SSP_CTRL1_DATA_CRC_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) data->error = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) else if (stat & (BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) BM_SSP_CTRL1_FIFO_OVERRUN_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) data->error = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct mxs_mmc_host *host, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct dma_async_tx_descriptor *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct mmc_data *data = host->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct scatterlist * sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned int sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dma_map_sg(mmc_dev(host->mmc), data->sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) data->sg_len, ssp->dma_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sgl = data->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sg_len = data->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* pio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) sgl = (struct scatterlist *) ssp->ssp_pio_words;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) sg_len = SSP_PIO_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) desc = dmaengine_prep_slave_sg(ssp->dmach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sgl, sg_len, ssp->slave_dirn, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) desc->callback = mxs_mmc_dma_irq_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) desc->callback_param = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dma_unmap_sg(mmc_dev(host->mmc), data->sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) data->sg_len, ssp->dma_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static void mxs_mmc_bc(struct mxs_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct mmc_command *cmd = host->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct dma_async_tx_descriptor *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u32 ctrl0, cmd0, cmd1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ctrl0 = BM_SSP_CTRL0_ENABLE | BM_SSP_CTRL0_IGNORE_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) cmd0 = BF_SSP(cmd->opcode, CMD0_CMD) | BM_SSP_CMD0_APPEND_8CYC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) cmd1 = cmd->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (host->sdio_irq_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ssp->ssp_pio_words[0] = ctrl0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ssp->ssp_pio_words[1] = cmd0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ssp->ssp_pio_words[2] = cmd1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ssp->dma_dir = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ssp->slave_dirn = DMA_TRANS_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) desc = mxs_mmc_prep_dma(host, MXS_DMA_CTRL_WAIT4END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dmaengine_submit(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) dma_async_issue_pending(ssp->dmach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) dev_warn(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) "%s: failed to prep dma\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static void mxs_mmc_ac(struct mxs_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct mmc_command *cmd = host->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct dma_async_tx_descriptor *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) u32 ignore_crc, get_resp, long_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u32 ctrl0, cmd0, cmd1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ignore_crc = (mmc_resp_type(cmd) & MMC_RSP_CRC) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 0 : BM_SSP_CTRL0_IGNORE_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) get_resp = (mmc_resp_type(cmd) & MMC_RSP_PRESENT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) BM_SSP_CTRL0_GET_RESP : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) long_resp = (mmc_resp_type(cmd) & MMC_RSP_136) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) BM_SSP_CTRL0_LONG_RESP : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ctrl0 = BM_SSP_CTRL0_ENABLE | ignore_crc | get_resp | long_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) cmd1 = cmd->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (cmd->opcode == MMC_STOP_TRANSMISSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (host->sdio_irq_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ssp->ssp_pio_words[0] = ctrl0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ssp->ssp_pio_words[1] = cmd0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ssp->ssp_pio_words[2] = cmd1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ssp->dma_dir = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ssp->slave_dirn = DMA_TRANS_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) desc = mxs_mmc_prep_dma(host, MXS_DMA_CTRL_WAIT4END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) dmaengine_submit(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dma_async_issue_pending(ssp->dmach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) dev_warn(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) "%s: failed to prep dma\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static unsigned short mxs_ns_to_ssp_ticks(unsigned clock_rate, unsigned ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) const unsigned int ssp_timeout_mul = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * Calculate ticks in ms since ns are large numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * and might overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) const unsigned int clock_per_ms = clock_rate / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) const unsigned int ms = ns / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) const unsigned int ticks = ms * clock_per_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) const unsigned int ssp_ticks = ticks / ssp_timeout_mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) WARN_ON(ssp_ticks == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return ssp_ticks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void mxs_mmc_adtc(struct mxs_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct mmc_command *cmd = host->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct mmc_data *data = cmd->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct dma_async_tx_descriptor *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct scatterlist *sgl = data->sg, *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned int sg_len = data->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned short dma_data_dir, timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) enum dma_transfer_direction slave_dirn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) unsigned int data_size = 0, log2_blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) unsigned int blocks = data->blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) u32 ignore_crc, get_resp, long_resp, read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) u32 ctrl0, cmd0, cmd1, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ignore_crc = (mmc_resp_type(cmd) & MMC_RSP_CRC) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 0 : BM_SSP_CTRL0_IGNORE_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) get_resp = (mmc_resp_type(cmd) & MMC_RSP_PRESENT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) BM_SSP_CTRL0_GET_RESP : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) long_resp = (mmc_resp_type(cmd) & MMC_RSP_136) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) BM_SSP_CTRL0_LONG_RESP : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (data->flags & MMC_DATA_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dma_data_dir = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) slave_dirn = DMA_MEM_TO_DEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) dma_data_dir = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) slave_dirn = DMA_DEV_TO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) read = BM_SSP_CTRL0_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ctrl0 = BF_SSP(host->bus_width, CTRL0_BUS_WIDTH) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ignore_crc | get_resp | long_resp |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) BM_SSP_CTRL0_DATA_XFER | read |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) BM_SSP_CTRL0_WAIT_FOR_IRQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) BM_SSP_CTRL0_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* get logarithm to base 2 of block size for setting register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) log2_blksz = ilog2(data->blksz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * take special care of the case that data size from data->sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * is not equal to blocks x blksz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) for_each_sg(sgl, sg, sg_len, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) data_size += sg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (data_size != data->blocks * data->blksz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) blocks = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* xfer count, block size and count need to be set differently */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (ssp_is_old(ssp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) writel(data_size, ssp->base + HW_SSP_XFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ssp->base + HW_SSP_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (cmd->opcode == SD_IO_RW_EXTENDED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) cmd1 = cmd->arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (host->sdio_irq_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* set the timeout count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) timeout = mxs_ns_to_ssp_ticks(ssp->clk_rate, data->timeout_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) val = readl(ssp->base + HW_SSP_TIMING(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) val &= ~(BM_SSP_TIMING_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) val |= BF_SSP(timeout, TIMING_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) writel(val, ssp->base + HW_SSP_TIMING(ssp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* pio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ssp->ssp_pio_words[0] = ctrl0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ssp->ssp_pio_words[1] = cmd0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ssp->ssp_pio_words[2] = cmd1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ssp->dma_dir = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ssp->slave_dirn = DMA_TRANS_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) desc = mxs_mmc_prep_dma(host, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* append data sg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) WARN_ON(host->data != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) host->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ssp->dma_dir = dma_data_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ssp->slave_dirn = slave_dirn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) dmaengine_submit(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dma_async_issue_pending(ssp->dmach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) dev_warn(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) "%s: failed to prep dma\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct mmc_command *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) host->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) switch (mmc_cmd_type(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case MMC_CMD_BC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) mxs_mmc_bc(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case MMC_CMD_BCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) mxs_mmc_ac(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case MMC_CMD_AC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) mxs_mmc_ac(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case MMC_CMD_ADTC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) mxs_mmc_adtc(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dev_warn(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) "%s: unknown MMC command\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct mxs_mmc_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) WARN_ON(host->mrq != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) host->mrq = mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (mrq->sbc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) mxs_mmc_start_cmd(host, mrq->sbc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) mxs_mmc_start_cmd(host, mrq->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct mxs_mmc_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (ios->bus_width == MMC_BUS_WIDTH_8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) host->bus_width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) else if (ios->bus_width == MMC_BUS_WIDTH_4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) host->bus_width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) host->bus_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (ios->clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) mxs_ssp_set_clk_rate(&host->ssp, ios->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct mxs_mmc_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) host->sdio_irq_en = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (enable && readl(ssp->base + HW_SSP_STATUS(ssp)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) BM_SSP_STATUS_SDIO_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) mmc_signal_sdio_irq(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static const struct mmc_host_ops mxs_mmc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .request = mxs_mmc_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .get_ro = mmc_gpio_get_ro,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .get_cd = mxs_mmc_get_cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .set_ios = mxs_mmc_set_ios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .enable_sdio_irq = mxs_mmc_enable_sdio_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static const struct platform_device_id mxs_ssp_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .name = "imx23-mmc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .driver_data = IMX23_SSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .name = "imx28-mmc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .driver_data = IMX28_SSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) MODULE_DEVICE_TABLE(platform, mxs_ssp_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static const struct of_device_id mxs_mmc_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_SSP, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_SSP, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static void mxs_mmc_regulator_disable(void *regulator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) regulator_disable(regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int mxs_mmc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) const struct of_device_id *of_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) of_match_device(mxs_mmc_dt_ids, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct mxs_mmc_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct mmc_host *mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int ret = 0, irq_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct regulator *reg_vmmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct mxs_ssp *ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) irq_err = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (irq_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return irq_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (!mmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ssp->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ssp->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (IS_ERR(ssp->base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ret = PTR_ERR(ssp->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) goto out_mmc_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ssp->devid = (enum mxs_ssp_id) of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) host->mmc = mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) host->sdio_irq_en = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) reg_vmmc = devm_regulator_get(&pdev->dev, "vmmc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (!IS_ERR(reg_vmmc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ret = regulator_enable(reg_vmmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) "Failed to enable vmmc regulator: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) goto out_mmc_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ret = devm_add_action_or_reset(&pdev->dev, mxs_mmc_regulator_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) reg_vmmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) goto out_mmc_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ssp->clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (IS_ERR(ssp->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ret = PTR_ERR(ssp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto out_mmc_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = clk_prepare_enable(ssp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) goto out_mmc_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ret = mxs_mmc_reset(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dev_err(&pdev->dev, "Failed to reset mmc: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) goto out_clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ssp->dmach = dma_request_chan(&pdev->dev, "rx-tx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (IS_ERR(ssp->dmach)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dev_err(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) "%s: failed to request dma\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = PTR_ERR(ssp->dmach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto out_clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /* set mmc core parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) mmc->ops = &mxs_mmc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL | MMC_CAP_CMD23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) host->broken_cd = of_property_read_bool(np, "broken-cd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) mmc->f_min = 400000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) mmc->f_max = 288000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ret = mmc_of_parse(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) goto out_free_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) mmc->max_segs = 52;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) mmc->max_blk_size = 1 << 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) platform_set_drvdata(pdev, mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) spin_lock_init(&host->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) dev_name(&pdev->dev), host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) goto out_free_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ret = mmc_add_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) goto out_free_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) dev_info(mmc_dev(host->mmc), "initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) out_free_dma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) dma_release_channel(ssp->dmach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) out_clk_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) clk_disable_unprepare(ssp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) out_mmc_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) mmc_free_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int mxs_mmc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct mmc_host *mmc = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct mxs_mmc_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mmc_remove_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (ssp->dmach)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dma_release_channel(ssp->dmach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) clk_disable_unprepare(ssp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) mmc_free_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int mxs_mmc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct mmc_host *mmc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct mxs_mmc_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) clk_disable_unprepare(ssp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static int mxs_mmc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct mmc_host *mmc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct mxs_mmc_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct mxs_ssp *ssp = &host->ssp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return clk_prepare_enable(ssp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static SIMPLE_DEV_PM_OPS(mxs_mmc_pm_ops, mxs_mmc_suspend, mxs_mmc_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static struct platform_driver mxs_mmc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .probe = mxs_mmc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .remove = mxs_mmc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) .id_table = mxs_ssp_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) .name = DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .probe_type = PROBE_PREFER_ASYNCHRONOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .pm = &mxs_mmc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .of_match_table = mxs_mmc_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) module_platform_driver(mxs_mmc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) MODULE_AUTHOR("Freescale Semiconductor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) MODULE_ALIAS("platform:" DRIVER_NAME);