Lines Matching +full:mmc +full:-

4  * SPDX-License-Identifier:    GPL-2.0+
11 #include <mmc.h>
16 static inline void *get_regbase(const struct mmc *mmc) in get_regbase() argument
18 struct meson_mmc_platdata *pdata = mmc->priv; in get_regbase()
20 return pdata->regbase; in get_regbase()
23 static inline uint32_t meson_read(struct mmc *mmc, int offset) in meson_read() argument
25 return readl(get_regbase(mmc) + offset); in meson_read()
28 static inline void meson_write(struct mmc *mmc, uint32_t val, int offset) in meson_write() argument
30 writel(val, get_regbase(mmc) + offset); in meson_write()
33 static void meson_mmc_config_clock(struct mmc *mmc) in meson_mmc_config_clock() argument
39 if (mmc->clock > 16000000) { in meson_mmc_config_clock()
46 clk_div = DIV_ROUND_UP(clk, mmc->clock); in meson_mmc_config_clock()
58 meson_write(mmc, meson_mmc_clk, MESON_SD_EMMC_CLOCK); in meson_mmc_config_clock()
63 struct mmc *mmc = mmc_get_mmc_dev(dev); in meson_dm_mmc_set_ios() local
66 meson_mmc_config_clock(mmc); in meson_dm_mmc_set_ios()
68 meson_mmc_cfg = meson_read(mmc, MESON_SD_EMMC_CFG); in meson_dm_mmc_set_ios()
71 if (mmc->bus_width == 1) in meson_dm_mmc_set_ios()
73 else if (mmc->bus_width == 4) in meson_dm_mmc_set_ios()
75 else if (mmc->bus_width == 8) in meson_dm_mmc_set_ios()
78 return -EINVAL; in meson_dm_mmc_set_ios()
88 /* Command-command gap 16 clk */ in meson_dm_mmc_set_ios()
92 meson_write(mmc, meson_mmc_cfg, MESON_SD_EMMC_CFG); in meson_dm_mmc_set_ios()
97 static void meson_mmc_setup_cmd(struct mmc *mmc, struct mmc_data *data, in meson_mmc_setup_cmd() argument
102 meson_mmc_cmd |= cmd->cmdidx << CMD_CFG_CMD_INDEX_SHIFT; in meson_mmc_setup_cmd()
104 if (cmd->resp_type & MMC_RSP_PRESENT) { in meson_mmc_setup_cmd()
105 if (cmd->resp_type & MMC_RSP_136) in meson_mmc_setup_cmd()
108 if (cmd->resp_type & MMC_RSP_BUSY) in meson_mmc_setup_cmd()
111 if (!(cmd->resp_type & MMC_RSP_CRC)) in meson_mmc_setup_cmd()
118 cfg = meson_read(mmc, MESON_SD_EMMC_CFG); in meson_mmc_setup_cmd()
120 cfg |= ilog2(data->blocksize) << CFG_BL_LEN_SHIFT; in meson_mmc_setup_cmd()
121 meson_write(mmc, cfg, MESON_SD_EMMC_CFG); in meson_mmc_setup_cmd()
123 if (data->flags == MMC_DATA_WRITE) in meson_mmc_setup_cmd()
127 data->blocks; in meson_mmc_setup_cmd()
133 meson_write(mmc, meson_mmc_cmd, MESON_SD_EMMC_CMD_CFG); in meson_mmc_setup_cmd()
136 static void meson_mmc_setup_addr(struct mmc *mmc, struct mmc_data *data) in meson_mmc_setup_addr() argument
138 struct meson_mmc_platdata *pdata = mmc->priv; in meson_mmc_setup_addr()
143 data_size = data->blocks * data->blocksize; in meson_mmc_setup_addr()
145 if (data->flags == MMC_DATA_READ) { in meson_mmc_setup_addr()
146 data_addr = (ulong) data->dest; in meson_mmc_setup_addr()
150 pdata->w_buf = calloc(data_size, sizeof(char)); in meson_mmc_setup_addr()
151 data_addr = (ulong) pdata->w_buf; in meson_mmc_setup_addr()
152 memcpy(pdata->w_buf, data->src, data_size); in meson_mmc_setup_addr()
157 meson_write(mmc, data_addr, MESON_SD_EMMC_CMD_DAT); in meson_mmc_setup_addr()
160 static void meson_mmc_read_response(struct mmc *mmc, struct mmc_cmd *cmd) in meson_mmc_read_response() argument
162 if (cmd->resp_type & MMC_RSP_136) { in meson_mmc_read_response()
163 cmd->response[0] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP3); in meson_mmc_read_response()
164 cmd->response[1] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP2); in meson_mmc_read_response()
165 cmd->response[2] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP1); in meson_mmc_read_response()
166 cmd->response[3] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP); in meson_mmc_read_response()
168 cmd->response[0] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP); in meson_mmc_read_response()
175 struct mmc *mmc = mmc_get_mmc_dev(dev); in meson_dm_mmc_send_cmd() local
176 struct meson_mmc_platdata *pdata = mmc->priv; in meson_dm_mmc_send_cmd()
182 if (data && data->blocksize > 512) in meson_dm_mmc_send_cmd()
183 return -EINVAL; in meson_dm_mmc_send_cmd()
185 meson_mmc_setup_cmd(mmc, data, cmd); in meson_dm_mmc_send_cmd()
186 meson_mmc_setup_addr(mmc, data); in meson_dm_mmc_send_cmd()
188 meson_write(mmc, cmd->cmdarg, MESON_SD_EMMC_CMD_ARG); in meson_dm_mmc_send_cmd()
193 status = meson_read(mmc, MESON_SD_EMMC_STATUS); in meson_dm_mmc_send_cmd()
197 ret = -ETIMEDOUT; in meson_dm_mmc_send_cmd()
199 ret = -ETIMEDOUT; in meson_dm_mmc_send_cmd()
201 ret = -EIO; in meson_dm_mmc_send_cmd()
203 meson_mmc_read_response(mmc, cmd); in meson_dm_mmc_send_cmd()
205 if (data && data->flags == MMC_DATA_WRITE) in meson_dm_mmc_send_cmd()
206 free(pdata->w_buf); in meson_dm_mmc_send_cmd()
209 meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS); in meson_dm_mmc_send_cmd()
226 return -EINVAL; in meson_mmc_ofdata_to_platdata()
228 pdata->regbase = (void *)addr; in meson_mmc_ofdata_to_platdata()
237 struct mmc *mmc = &pdata->mmc; in meson_mmc_probe() local
238 struct mmc_config *cfg = &pdata->cfg; in meson_mmc_probe()
241 cfg->voltages = MMC_VDD_33_34 | MMC_VDD_32_33 | in meson_mmc_probe()
243 cfg->host_caps = MMC_MODE_8BIT | MMC_MODE_4BIT | in meson_mmc_probe()
245 cfg->f_min = DIV_ROUND_UP(SD_EMMC_CLKSRC_24M, CLK_MAX_DIV); in meson_mmc_probe()
246 cfg->f_max = 100000000; /* 100 MHz */ in meson_mmc_probe()
247 cfg->b_max = 511; /* max 512 - 1 blocks */ in meson_mmc_probe()
248 cfg->name = dev->name; in meson_mmc_probe()
250 mmc->priv = pdata; in meson_mmc_probe()
251 upriv->mmc = mmc; in meson_mmc_probe()
253 mmc_set_clock(mmc, cfg->f_min); in meson_mmc_probe()
256 meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS); in meson_mmc_probe()
259 meson_write(mmc, 0, MESON_SD_EMMC_IRQ_EN); in meson_mmc_probe()
262 val = meson_read(mmc, MESON_SD_EMMC_CFG); in meson_mmc_probe()
265 meson_write(mmc, val, MESON_SD_EMMC_CFG); in meson_mmc_probe()
274 return mmc_bind(dev, &pdata->mmc, &pdata->cfg); in meson_mmc_bind()
278 { .compatible = "amlogic,meson-gx-mmc" },