uboot/drivers/mmc/meson_gx_mmc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2016 Carlo Caione <carlo@caione.org>
   4 */
   5
   6#include <common.h>
   7#include <clk.h>
   8#include <cpu_func.h>
   9#include <dm.h>
  10#include <fdtdec.h>
  11#include <malloc.h>
  12#include <pwrseq.h>
  13#include <mmc.h>
  14#include <asm/io.h>
  15#include <asm/gpio.h>
  16#include <linux/delay.h>
  17#include <linux/log2.h>
  18#include "meson_gx_mmc.h"
  19
  20bool meson_gx_mmc_is_compatible(struct udevice *dev,
  21                                enum meson_gx_mmc_compatible family)
  22{
  23        enum meson_gx_mmc_compatible compat = dev_get_driver_data(dev);
  24
  25        return compat == family;
  26}
  27
  28static inline void *get_regbase(const struct mmc *mmc)
  29{
  30        struct meson_mmc_plat *pdata = mmc->priv;
  31
  32        return pdata->regbase;
  33}
  34
  35static inline uint32_t meson_read(struct mmc *mmc, int offset)
  36{
  37        return readl(get_regbase(mmc) + offset);
  38}
  39
  40static inline void meson_write(struct mmc *mmc, uint32_t val, int offset)
  41{
  42        writel(val, get_regbase(mmc) + offset);
  43}
  44
  45static void meson_mmc_config_clock(struct mmc *mmc)
  46{
  47        uint32_t meson_mmc_clk = 0;
  48        unsigned int clk, clk_src, clk_div;
  49
  50        if (!mmc->clock)
  51                return;
  52
  53        /* TOFIX This should use the proper clock taken from DT */
  54
  55        /* 1GHz / CLK_MAX_DIV = 15,9 MHz */
  56        if (mmc->clock > 16000000) {
  57                clk = SD_EMMC_CLKSRC_DIV2;
  58                clk_src = CLK_SRC_DIV2;
  59        } else {
  60                clk = SD_EMMC_CLKSRC_24M;
  61                clk_src = CLK_SRC_24M;
  62        }
  63        clk_div = DIV_ROUND_UP(clk, mmc->clock);
  64
  65        /*
  66         * SM1 SoCs doesn't work fine over 50MHz with CLK_CO_PHASE_180
  67         * If CLK_CO_PHASE_270 is used, it's more stable than other.
  68         * Other SoCs use CLK_CO_PHASE_180 by default.
  69         * It needs to find what is a proper value about each SoCs.
  70         */
  71        if (meson_gx_mmc_is_compatible(mmc->dev, MMC_COMPATIBLE_SM1))
  72                meson_mmc_clk |= CLK_CO_PHASE_270;
  73        else
  74                meson_mmc_clk |= CLK_CO_PHASE_180;
  75
  76        /* 180 phase tx clock */
  77        meson_mmc_clk |= CLK_TX_PHASE_000;
  78
  79        /* clock settings */
  80        meson_mmc_clk |= clk_src;
  81        meson_mmc_clk |= clk_div;
  82
  83        meson_write(mmc, meson_mmc_clk, MESON_SD_EMMC_CLOCK);
  84}
  85
  86static int meson_dm_mmc_set_ios(struct udevice *dev)
  87{
  88        struct mmc *mmc = mmc_get_mmc_dev(dev);
  89        uint32_t meson_mmc_cfg;
  90
  91        meson_mmc_config_clock(mmc);
  92
  93        meson_mmc_cfg = meson_read(mmc, MESON_SD_EMMC_CFG);
  94
  95        meson_mmc_cfg &= ~CFG_BUS_WIDTH_MASK;
  96        if (mmc->bus_width == 1)
  97                meson_mmc_cfg |= CFG_BUS_WIDTH_1;
  98        else if (mmc->bus_width == 4)
  99                meson_mmc_cfg |= CFG_BUS_WIDTH_4;
 100        else if (mmc->bus_width == 8)
 101                meson_mmc_cfg |= CFG_BUS_WIDTH_8;
 102        else
 103                return -EINVAL;
 104
 105        /* 512 bytes block length */
 106        meson_mmc_cfg &= ~CFG_BL_LEN_MASK;
 107        meson_mmc_cfg |= CFG_BL_LEN_512;
 108
 109        /* Response timeout 256 clk */
 110        meson_mmc_cfg &= ~CFG_RESP_TIMEOUT_MASK;
 111        meson_mmc_cfg |= CFG_RESP_TIMEOUT_256;
 112
 113        /* Command-command gap 16 clk */
 114        meson_mmc_cfg &= ~CFG_RC_CC_MASK;
 115        meson_mmc_cfg |= CFG_RC_CC_16;
 116
 117        meson_write(mmc, meson_mmc_cfg, MESON_SD_EMMC_CFG);
 118
 119        return 0;
 120}
 121
 122static void meson_mmc_setup_cmd(struct mmc *mmc, struct mmc_data *data,
 123                                struct mmc_cmd *cmd)
 124{
 125        uint32_t meson_mmc_cmd = 0, cfg;
 126
 127        meson_mmc_cmd |= cmd->cmdidx << CMD_CFG_CMD_INDEX_SHIFT;
 128
 129        if (cmd->resp_type & MMC_RSP_PRESENT) {
 130                if (cmd->resp_type & MMC_RSP_136)
 131                        meson_mmc_cmd |= CMD_CFG_RESP_128;
 132
 133                if (cmd->resp_type & MMC_RSP_BUSY)
 134                        meson_mmc_cmd |= CMD_CFG_R1B;
 135
 136                if (!(cmd->resp_type & MMC_RSP_CRC))
 137                        meson_mmc_cmd |= CMD_CFG_RESP_NOCRC;
 138        } else {
 139                meson_mmc_cmd |= CMD_CFG_NO_RESP;
 140        }
 141
 142        if (data) {
 143                cfg = meson_read(mmc, MESON_SD_EMMC_CFG);
 144                cfg &= ~CFG_BL_LEN_MASK;
 145                cfg |= ilog2(data->blocksize) << CFG_BL_LEN_SHIFT;
 146                meson_write(mmc, cfg, MESON_SD_EMMC_CFG);
 147
 148                if (data->flags == MMC_DATA_WRITE)
 149                        meson_mmc_cmd |= CMD_CFG_DATA_WR;
 150
 151                meson_mmc_cmd |= CMD_CFG_DATA_IO | CMD_CFG_BLOCK_MODE |
 152                                 data->blocks;
 153        }
 154
 155        meson_mmc_cmd |= CMD_CFG_TIMEOUT_4S | CMD_CFG_OWNER |
 156                         CMD_CFG_END_OF_CHAIN;
 157
 158        meson_write(mmc, meson_mmc_cmd, MESON_SD_EMMC_CMD_CFG);
 159}
 160
 161static void meson_mmc_setup_addr(struct mmc *mmc, struct mmc_data *data)
 162{
 163        struct meson_mmc_plat *pdata = mmc->priv;
 164        unsigned int data_size;
 165        uint32_t data_addr = 0;
 166
 167        if (data) {
 168                data_size = data->blocks * data->blocksize;
 169
 170                if (data->flags == MMC_DATA_READ) {
 171                        data_addr = (ulong) data->dest;
 172                        invalidate_dcache_range(data_addr,
 173                                                data_addr + data_size);
 174                } else {
 175                        pdata->w_buf = calloc(data_size, sizeof(char));
 176                        data_addr = (ulong) pdata->w_buf;
 177                        memcpy(pdata->w_buf, data->src, data_size);
 178                        flush_dcache_range(data_addr, data_addr + data_size);
 179                }
 180        }
 181
 182        meson_write(mmc, data_addr, MESON_SD_EMMC_CMD_DAT);
 183}
 184
 185static void meson_mmc_read_response(struct mmc *mmc, struct mmc_cmd *cmd)
 186{
 187        if (cmd->resp_type & MMC_RSP_136) {
 188                cmd->response[0] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP3);
 189                cmd->response[1] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP2);
 190                cmd->response[2] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP1);
 191                cmd->response[3] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP);
 192        } else {
 193                cmd->response[0] = meson_read(mmc, MESON_SD_EMMC_CMD_RSP);
 194        }
 195}
 196
 197static int meson_dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
 198                                 struct mmc_data *data)
 199{
 200        struct mmc *mmc = mmc_get_mmc_dev(dev);
 201        struct meson_mmc_plat *pdata = mmc->priv;
 202        uint32_t status;
 203        ulong start;
 204        int ret = 0;
 205
 206        /* max block size supported by chip is 512 byte */
 207        if (data && data->blocksize > 512)
 208                return -EINVAL;
 209
 210        meson_mmc_setup_cmd(mmc, data, cmd);
 211        meson_mmc_setup_addr(mmc, data);
 212
 213        meson_write(mmc, cmd->cmdarg, MESON_SD_EMMC_CMD_ARG);
 214
 215        /* use 10s timeout */
 216        start = get_timer(0);
 217        do {
 218                status = meson_read(mmc, MESON_SD_EMMC_STATUS);
 219        } while(!(status & STATUS_END_OF_CHAIN) && get_timer(start) < 10000);
 220
 221        if (!(status & STATUS_END_OF_CHAIN))
 222                ret = -ETIMEDOUT;
 223        else if (status & STATUS_RESP_TIMEOUT)
 224                ret = -ETIMEDOUT;
 225        else if (status & STATUS_ERR_MASK)
 226                ret = -EIO;
 227
 228        meson_mmc_read_response(mmc, cmd);
 229
 230        if (data && data->flags == MMC_DATA_WRITE)
 231                free(pdata->w_buf);
 232
 233        /* reset status bits */
 234        meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS);
 235
 236        return ret;
 237}
 238
 239static const struct dm_mmc_ops meson_dm_mmc_ops = {
 240        .send_cmd = meson_dm_mmc_send_cmd,
 241        .set_ios = meson_dm_mmc_set_ios,
 242};
 243
 244static int meson_mmc_of_to_plat(struct udevice *dev)
 245{
 246        struct meson_mmc_plat *pdata = dev_get_plat(dev);
 247        fdt_addr_t addr;
 248
 249        addr = dev_read_addr(dev);
 250        if (addr == FDT_ADDR_T_NONE)
 251                return -EINVAL;
 252
 253        pdata->regbase = (void *)addr;
 254
 255        return 0;
 256}
 257
 258static int meson_mmc_probe(struct udevice *dev)
 259{
 260        struct meson_mmc_plat *pdata = dev_get_plat(dev);
 261        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 262        struct mmc *mmc = &pdata->mmc;
 263        struct mmc_config *cfg = &pdata->cfg;
 264        struct clk_bulk clocks;
 265        uint32_t val;
 266        int ret;
 267
 268        /* Enable the clocks feeding the MMC controller */
 269        ret = clk_get_bulk(dev, &clocks);
 270        if (ret)
 271                return ret;
 272
 273        ret = clk_enable_bulk(&clocks);
 274        if (ret)
 275                return ret;
 276
 277        cfg->voltages = MMC_VDD_33_34 | MMC_VDD_32_33 |
 278                        MMC_VDD_31_32 | MMC_VDD_165_195;
 279        cfg->host_caps = MMC_MODE_8BIT | MMC_MODE_4BIT |
 280                        MMC_MODE_HS_52MHz | MMC_MODE_HS;
 281        cfg->f_min = DIV_ROUND_UP(SD_EMMC_CLKSRC_24M, CLK_MAX_DIV);
 282        cfg->f_max = 100000000; /* 100 MHz */
 283        cfg->b_max = 511; /* max 512 - 1 blocks */
 284        cfg->name = dev->name;
 285
 286        mmc->priv = pdata;
 287        upriv->mmc = mmc;
 288
 289        mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE);
 290
 291#ifdef CONFIG_MMC_PWRSEQ
 292        /* Enable power if needed */
 293        ret = mmc_pwrseq_get_power(dev, cfg);
 294        if (!ret) {
 295                ret = pwrseq_set_power(cfg->pwr_dev, true);
 296                if (ret)
 297                        return ret;
 298        }
 299#endif
 300
 301        /* reset all status bits */
 302        meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS);
 303
 304        /* disable interrupts */
 305        meson_write(mmc, 0, MESON_SD_EMMC_IRQ_EN);
 306
 307        /* enable auto clock mode */
 308        val = meson_read(mmc, MESON_SD_EMMC_CFG);
 309        val &= ~CFG_SDCLK_ALWAYS_ON;
 310        val |= CFG_AUTO_CLK;
 311        meson_write(mmc, val, MESON_SD_EMMC_CFG);
 312
 313        return 0;
 314}
 315
 316int meson_mmc_bind(struct udevice *dev)
 317{
 318        struct meson_mmc_plat *pdata = dev_get_plat(dev);
 319
 320        return mmc_bind(dev, &pdata->mmc, &pdata->cfg);
 321}
 322
 323static const struct udevice_id meson_mmc_match[] = {
 324        { .compatible = "amlogic,meson-gx-mmc", .data = MMC_COMPATIBLE_GX },
 325        { .compatible = "amlogic,meson-axg-mmc", .data = MMC_COMPATIBLE_GX },
 326        { .compatible = "amlogic,meson-sm1-mmc", .data = MMC_COMPATIBLE_SM1 },
 327        { /* sentinel */ }
 328};
 329
 330U_BOOT_DRIVER(meson_mmc) = {
 331        .name = "meson_gx_mmc",
 332        .id = UCLASS_MMC,
 333        .of_match = meson_mmc_match,
 334        .ops = &meson_dm_mmc_ops,
 335        .probe = meson_mmc_probe,
 336        .bind = meson_mmc_bind,
 337        .of_to_plat = meson_mmc_of_to_plat,
 338        .plat_auto      = sizeof(struct meson_mmc_plat),
 339};
 340