linux/drivers/mmc/host/sdhci-msm.c
<<
>>
Prefs
   1/*
   2 * drivers/mmc/host/sdhci-msm.c - Qualcomm SDHCI Platform driver
   3 *
   4 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 and
   8 * only version 2 as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 */
  16
  17#include <linux/module.h>
  18#include <linux/of_device.h>
  19#include <linux/regulator/consumer.h>
  20#include <linux/delay.h>
  21#include <linux/mmc/mmc.h>
  22#include <linux/slab.h>
  23
  24#include "sdhci-pltfm.h"
  25
  26#define CORE_HC_MODE            0x78
  27#define HC_MODE_EN              0x1
  28#define CORE_POWER              0x0
  29#define CORE_SW_RST             BIT(7)
  30
  31#define MAX_PHASES              16
  32#define CORE_DLL_LOCK           BIT(7)
  33#define CORE_DLL_EN             BIT(16)
  34#define CORE_CDR_EN             BIT(17)
  35#define CORE_CK_OUT_EN          BIT(18)
  36#define CORE_CDR_EXT_EN         BIT(19)
  37#define CORE_DLL_PDN            BIT(29)
  38#define CORE_DLL_RST            BIT(30)
  39#define CORE_DLL_CONFIG         0x100
  40#define CORE_DLL_STATUS         0x108
  41
  42#define CORE_VENDOR_SPEC        0x10c
  43#define CORE_CLK_PWRSAVE        BIT(1)
  44
  45#define CDR_SELEXT_SHIFT        20
  46#define CDR_SELEXT_MASK         (0xf << CDR_SELEXT_SHIFT)
  47#define CMUX_SHIFT_PHASE_SHIFT  24
  48#define CMUX_SHIFT_PHASE_MASK   (7 << CMUX_SHIFT_PHASE_SHIFT)
  49
  50static const u32 tuning_block_64[] = {
  51        0x00ff0fff, 0xccc3ccff, 0xffcc3cc3, 0xeffefffe,
  52        0xddffdfff, 0xfbfffbff, 0xff7fffbf, 0xefbdf777,
  53        0xf0fff0ff, 0x3cccfc0f, 0xcfcc33cc, 0xeeffefff,
  54        0xfdfffdff, 0xffbfffdf, 0xfff7ffbb, 0xde7b7ff7
  55};
  56
  57static const u32 tuning_block_128[] = {
  58        0xff00ffff, 0x0000ffff, 0xccccffff, 0xcccc33cc,
  59        0xcc3333cc, 0xffffcccc, 0xffffeeff, 0xffeeeeff,
  60        0xffddffff, 0xddddffff, 0xbbffffff, 0xbbffffff,
  61        0xffffffbb, 0xffffff77, 0x77ff7777, 0xffeeddbb,
  62        0x00ffffff, 0x00ffffff, 0xccffff00, 0xcc33cccc,
  63        0x3333cccc, 0xffcccccc, 0xffeeffff, 0xeeeeffff,
  64        0xddffffff, 0xddffffff, 0xffffffdd, 0xffffffbb,
  65        0xffffbbbb, 0xffff77ff, 0xff7777ff, 0xeeddbb77
  66};
  67
  68struct sdhci_msm_host {
  69        struct platform_device *pdev;
  70        void __iomem *core_mem; /* MSM SDCC mapped address */
  71        struct clk *clk;        /* main SD/MMC bus clock */
  72        struct clk *pclk;       /* SDHC peripheral bus clock */
  73        struct clk *bus_clk;    /* SDHC bus voter clock */
  74        struct mmc_host *mmc;
  75        struct sdhci_pltfm_data sdhci_msm_pdata;
  76};
  77
  78/* Platform specific tuning */
  79static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll)
  80{
  81        u32 wait_cnt = 50;
  82        u8 ck_out_en;
  83        struct mmc_host *mmc = host->mmc;
  84
  85        /* Poll for CK_OUT_EN bit.  max. poll time = 50us */
  86        ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) &
  87                        CORE_CK_OUT_EN);
  88
  89        while (ck_out_en != poll) {
  90                if (--wait_cnt == 0) {
  91                        dev_err(mmc_dev(mmc), "%s: CK_OUT_EN bit is not %d\n",
  92                               mmc_hostname(mmc), poll);
  93                        return -ETIMEDOUT;
  94                }
  95                udelay(1);
  96
  97                ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) &
  98                                CORE_CK_OUT_EN);
  99        }
 100
 101        return 0;
 102}
 103
 104static int msm_config_cm_dll_phase(struct sdhci_host *host, u8 phase)
 105{
 106        int rc;
 107        static const u8 grey_coded_phase_table[] = {
 108                0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4,
 109                0xc, 0xd, 0xf, 0xe, 0xa, 0xb, 0x9, 0x8
 110        };
 111        unsigned long flags;
 112        u32 config;
 113        struct mmc_host *mmc = host->mmc;
 114
 115        spin_lock_irqsave(&host->lock, flags);
 116
 117        config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
 118        config &= ~(CORE_CDR_EN | CORE_CK_OUT_EN);
 119        config |= (CORE_CDR_EXT_EN | CORE_DLL_EN);
 120        writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
 121
 122        /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '0' */
 123        rc = msm_dll_poll_ck_out_en(host, 0);
 124        if (rc)
 125                goto err_out;
 126
 127        /*
 128         * Write the selected DLL clock output phase (0 ... 15)
 129         * to CDR_SELEXT bit field of DLL_CONFIG register.
 130         */
 131        config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
 132        config &= ~CDR_SELEXT_MASK;
 133        config |= grey_coded_phase_table[phase] << CDR_SELEXT_SHIFT;
 134        writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
 135
 136        /* Set CK_OUT_EN bit of DLL_CONFIG register to 1. */
 137        writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
 138                        | CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG);
 139
 140        /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '1' */
 141        rc = msm_dll_poll_ck_out_en(host, 1);
 142        if (rc)
 143                goto err_out;
 144
 145        config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
 146        config |= CORE_CDR_EN;
 147        config &= ~CORE_CDR_EXT_EN;
 148        writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
 149        goto out;
 150
 151err_out:
 152        dev_err(mmc_dev(mmc), "%s: Failed to set DLL phase: %d\n",
 153               mmc_hostname(mmc), phase);
 154out:
 155        spin_unlock_irqrestore(&host->lock, flags);
 156        return rc;
 157}
 158
 159/*
 160 * Find out the greatest range of consecuitive selected
 161 * DLL clock output phases that can be used as sampling
 162 * setting for SD3.0 UHS-I card read operation (in SDR104
 163 * timing mode) or for eMMC4.5 card read operation (in HS200
 164 * timing mode).
 165 * Select the 3/4 of the range and configure the DLL with the
 166 * selected DLL clock output phase.
 167 */
 168
 169static int msm_find_most_appropriate_phase(struct sdhci_host *host,
 170                                           u8 *phase_table, u8 total_phases)
 171{
 172        int ret;
 173        u8 ranges[MAX_PHASES][MAX_PHASES] = { {0}, {0} };
 174        u8 phases_per_row[MAX_PHASES] = { 0 };
 175        int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0;
 176        int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0;
 177        bool phase_0_found = false, phase_15_found = false;
 178        struct mmc_host *mmc = host->mmc;
 179
 180        if (!total_phases || (total_phases > MAX_PHASES)) {
 181                dev_err(mmc_dev(mmc), "%s: Invalid argument: total_phases=%d\n",
 182                       mmc_hostname(mmc), total_phases);
 183                return -EINVAL;
 184        }
 185
 186        for (cnt = 0; cnt < total_phases; cnt++) {
 187                ranges[row_index][col_index] = phase_table[cnt];
 188                phases_per_row[row_index] += 1;
 189                col_index++;
 190
 191                if ((cnt + 1) == total_phases) {
 192                        continue;
 193                /* check if next phase in phase_table is consecutive or not */
 194                } else if ((phase_table[cnt] + 1) != phase_table[cnt + 1]) {
 195                        row_index++;
 196                        col_index = 0;
 197                }
 198        }
 199
 200        if (row_index >= MAX_PHASES)
 201                return -EINVAL;
 202
 203        /* Check if phase-0 is present in first valid window? */
 204        if (!ranges[0][0]) {
 205                phase_0_found = true;
 206                phase_0_raw_index = 0;
 207                /* Check if cycle exist between 2 valid windows */
 208                for (cnt = 1; cnt <= row_index; cnt++) {
 209                        if (phases_per_row[cnt]) {
 210                                for (i = 0; i < phases_per_row[cnt]; i++) {
 211                                        if (ranges[cnt][i] == 15) {
 212                                                phase_15_found = true;
 213                                                phase_15_raw_index = cnt;
 214                                                break;
 215                                        }
 216                                }
 217                        }
 218                }
 219        }
 220
 221        /* If 2 valid windows form cycle then merge them as single window */
 222        if (phase_0_found && phase_15_found) {
 223                /* number of phases in raw where phase 0 is present */
 224                u8 phases_0 = phases_per_row[phase_0_raw_index];
 225                /* number of phases in raw where phase 15 is present */
 226                u8 phases_15 = phases_per_row[phase_15_raw_index];
 227
 228                if (phases_0 + phases_15 >= MAX_PHASES)
 229                        /*
 230                         * If there are more than 1 phase windows then total
 231                         * number of phases in both the windows should not be
 232                         * more than or equal to MAX_PHASES.
 233                         */
 234                        return -EINVAL;
 235
 236                /* Merge 2 cyclic windows */
 237                i = phases_15;
 238                for (cnt = 0; cnt < phases_0; cnt++) {
 239                        ranges[phase_15_raw_index][i] =
 240                            ranges[phase_0_raw_index][cnt];
 241                        if (++i >= MAX_PHASES)
 242                                break;
 243                }
 244
 245                phases_per_row[phase_0_raw_index] = 0;
 246                phases_per_row[phase_15_raw_index] = phases_15 + phases_0;
 247        }
 248
 249        for (cnt = 0; cnt <= row_index; cnt++) {
 250                if (phases_per_row[cnt] > curr_max) {
 251                        curr_max = phases_per_row[cnt];
 252                        selected_row_index = cnt;
 253                }
 254        }
 255
 256        i = (curr_max * 3) / 4;
 257        if (i)
 258                i--;
 259
 260        ret = ranges[selected_row_index][i];
 261
 262        if (ret >= MAX_PHASES) {
 263                ret = -EINVAL;
 264                dev_err(mmc_dev(mmc), "%s: Invalid phase selected=%d\n",
 265                       mmc_hostname(mmc), ret);
 266        }
 267
 268        return ret;
 269}
 270
 271static inline void msm_cm_dll_set_freq(struct sdhci_host *host)
 272{
 273        u32 mclk_freq = 0, config;
 274
 275        /* Program the MCLK value to MCLK_FREQ bit field */
 276        if (host->clock <= 112000000)
 277                mclk_freq = 0;
 278        else if (host->clock <= 125000000)
 279                mclk_freq = 1;
 280        else if (host->clock <= 137000000)
 281                mclk_freq = 2;
 282        else if (host->clock <= 150000000)
 283                mclk_freq = 3;
 284        else if (host->clock <= 162000000)
 285                mclk_freq = 4;
 286        else if (host->clock <= 175000000)
 287                mclk_freq = 5;
 288        else if (host->clock <= 187000000)
 289                mclk_freq = 6;
 290        else if (host->clock <= 200000000)
 291                mclk_freq = 7;
 292
 293        config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
 294        config &= ~CMUX_SHIFT_PHASE_MASK;
 295        config |= mclk_freq << CMUX_SHIFT_PHASE_SHIFT;
 296        writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
 297}
 298
 299/* Initialize the DLL (Programmable Delay Line) */
 300static int msm_init_cm_dll(struct sdhci_host *host)
 301{
 302        struct mmc_host *mmc = host->mmc;
 303        int wait_cnt = 50;
 304        unsigned long flags;
 305
 306        spin_lock_irqsave(&host->lock, flags);
 307
 308        /*
 309         * Make sure that clock is always enabled when DLL
 310         * tuning is in progress. Keeping PWRSAVE ON may
 311         * turn off the clock.
 312         */
 313        writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC)
 314                        & ~CORE_CLK_PWRSAVE), host->ioaddr + CORE_VENDOR_SPEC);
 315
 316        /* Write 1 to DLL_RST bit of DLL_CONFIG register */
 317        writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
 318                        | CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
 319
 320        /* Write 1 to DLL_PDN bit of DLL_CONFIG register */
 321        writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
 322                        | CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);
 323        msm_cm_dll_set_freq(host);
 324
 325        /* Write 0 to DLL_RST bit of DLL_CONFIG register */
 326        writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
 327                        & ~CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
 328
 329        /* Write 0 to DLL_PDN bit of DLL_CONFIG register */
 330        writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
 331                        & ~CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);
 332
 333        /* Set DLL_EN bit to 1. */
 334        writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
 335                        | CORE_DLL_EN), host->ioaddr + CORE_DLL_CONFIG);
 336
 337        /* Set CK_OUT_EN bit to 1. */
 338        writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
 339                        | CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG);
 340
 341        /* Wait until DLL_LOCK bit of DLL_STATUS register becomes '1' */
 342        while (!(readl_relaxed(host->ioaddr + CORE_DLL_STATUS) &
 343                 CORE_DLL_LOCK)) {
 344                /* max. wait for 50us sec for LOCK bit to be set */
 345                if (--wait_cnt == 0) {
 346                        dev_err(mmc_dev(mmc), "%s: DLL failed to LOCK\n",
 347                               mmc_hostname(mmc));
 348                        spin_unlock_irqrestore(&host->lock, flags);
 349                        return -ETIMEDOUT;
 350                }
 351                udelay(1);
 352        }
 353
 354        spin_unlock_irqrestore(&host->lock, flags);
 355        return 0;
 356}
 357
 358static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
 359{
 360        int tuning_seq_cnt = 3;
 361        u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0;
 362        const u32 *tuning_block_pattern = tuning_block_64;
 363        int size = sizeof(tuning_block_64);     /* Pattern size in bytes */
 364        int rc;
 365        struct mmc_host *mmc = host->mmc;
 366        struct mmc_ios ios = host->mmc->ios;
 367
 368        /*
 369         * Tuning is required for SDR104, HS200 and HS400 cards and
 370         * if clock frequency is greater than 100MHz in these modes.
 371         */
 372        if (host->clock <= 100 * 1000 * 1000 ||
 373            !((ios.timing == MMC_TIMING_MMC_HS200) ||
 374              (ios.timing == MMC_TIMING_UHS_SDR104)))
 375                return 0;
 376
 377        if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) &&
 378            (mmc->ios.bus_width == MMC_BUS_WIDTH_8)) {
 379                tuning_block_pattern = tuning_block_128;
 380                size = sizeof(tuning_block_128);
 381        }
 382
 383        data_buf = kmalloc(size, GFP_KERNEL);
 384        if (!data_buf)
 385                return -ENOMEM;
 386
 387retry:
 388        /* First of all reset the tuning block */
 389        rc = msm_init_cm_dll(host);
 390        if (rc)
 391                goto out;
 392
 393        phase = 0;
 394        do {
 395                struct mmc_command cmd = { 0 };
 396                struct mmc_data data = { 0 };
 397                struct mmc_request mrq = {
 398                        .cmd = &cmd,
 399                        .data = &data
 400                };
 401                struct scatterlist sg;
 402
 403                /* Set the phase in delay line hw block */
 404                rc = msm_config_cm_dll_phase(host, phase);
 405                if (rc)
 406                        goto out;
 407
 408                cmd.opcode = opcode;
 409                cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 410
 411                data.blksz = size;
 412                data.blocks = 1;
 413                data.flags = MMC_DATA_READ;
 414                data.timeout_ns = NSEC_PER_SEC; /* 1 second */
 415
 416                data.sg = &sg;
 417                data.sg_len = 1;
 418                sg_init_one(&sg, data_buf, size);
 419                memset(data_buf, 0, size);
 420                mmc_wait_for_req(mmc, &mrq);
 421
 422                if (!cmd.error && !data.error &&
 423                    !memcmp(data_buf, tuning_block_pattern, size)) {
 424                        /* Tuning is successful at this tuning point */
 425                        tuned_phases[tuned_phase_cnt++] = phase;
 426                        dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n",
 427                                 mmc_hostname(mmc), phase);
 428                }
 429        } while (++phase < ARRAY_SIZE(tuned_phases));
 430
 431        if (tuned_phase_cnt) {
 432                rc = msm_find_most_appropriate_phase(host, tuned_phases,
 433                                                     tuned_phase_cnt);
 434                if (rc < 0)
 435                        goto out;
 436                else
 437                        phase = rc;
 438
 439                /*
 440                 * Finally set the selected phase in delay
 441                 * line hw block.
 442                 */
 443                rc = msm_config_cm_dll_phase(host, phase);
 444                if (rc)
 445                        goto out;
 446                dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n",
 447                         mmc_hostname(mmc), phase);
 448        } else {
 449                if (--tuning_seq_cnt)
 450                        goto retry;
 451                /* Tuning failed */
 452                dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n",
 453                       mmc_hostname(mmc));
 454                rc = -EIO;
 455        }
 456
 457out:
 458        kfree(data_buf);
 459        return rc;
 460}
 461
 462static const struct of_device_id sdhci_msm_dt_match[] = {
 463        { .compatible = "qcom,sdhci-msm-v4" },
 464        {},
 465};
 466
 467MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match);
 468
 469static struct sdhci_ops sdhci_msm_ops = {
 470        .platform_execute_tuning = sdhci_msm_execute_tuning,
 471        .reset = sdhci_reset,
 472        .set_clock = sdhci_set_clock,
 473        .set_bus_width = sdhci_set_bus_width,
 474        .set_uhs_signaling = sdhci_set_uhs_signaling,
 475};
 476
 477static int sdhci_msm_probe(struct platform_device *pdev)
 478{
 479        struct sdhci_host *host;
 480        struct sdhci_pltfm_host *pltfm_host;
 481        struct sdhci_msm_host *msm_host;
 482        struct resource *core_memres;
 483        int ret;
 484        u16 host_version;
 485
 486        msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
 487        if (!msm_host)
 488                return -ENOMEM;
 489
 490        msm_host->sdhci_msm_pdata.ops = &sdhci_msm_ops;
 491        host = sdhci_pltfm_init(pdev, &msm_host->sdhci_msm_pdata, 0);
 492        if (IS_ERR(host))
 493                return PTR_ERR(host);
 494
 495        pltfm_host = sdhci_priv(host);
 496        pltfm_host->priv = msm_host;
 497        msm_host->mmc = host->mmc;
 498        msm_host->pdev = pdev;
 499
 500        ret = mmc_of_parse(host->mmc);
 501        if (ret)
 502                goto pltfm_free;
 503
 504        sdhci_get_of_property(pdev);
 505
 506        /* Setup SDCC bus voter clock. */
 507        msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus");
 508        if (!IS_ERR(msm_host->bus_clk)) {
 509                /* Vote for max. clk rate for max. performance */
 510                ret = clk_set_rate(msm_host->bus_clk, INT_MAX);
 511                if (ret)
 512                        goto pltfm_free;
 513                ret = clk_prepare_enable(msm_host->bus_clk);
 514                if (ret)
 515                        goto pltfm_free;
 516        }
 517
 518        /* Setup main peripheral bus clock */
 519        msm_host->pclk = devm_clk_get(&pdev->dev, "iface");
 520        if (IS_ERR(msm_host->pclk)) {
 521                ret = PTR_ERR(msm_host->pclk);
 522                dev_err(&pdev->dev, "Perpheral clk setup failed (%d)\n", ret);
 523                goto bus_clk_disable;
 524        }
 525
 526        ret = clk_prepare_enable(msm_host->pclk);
 527        if (ret)
 528                goto bus_clk_disable;
 529
 530        /* Setup SDC MMC clock */
 531        msm_host->clk = devm_clk_get(&pdev->dev, "core");
 532        if (IS_ERR(msm_host->clk)) {
 533                ret = PTR_ERR(msm_host->clk);
 534                dev_err(&pdev->dev, "SDC MMC clk setup failed (%d)\n", ret);
 535                goto pclk_disable;
 536        }
 537
 538        ret = clk_prepare_enable(msm_host->clk);
 539        if (ret)
 540                goto pclk_disable;
 541
 542        core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 543        msm_host->core_mem = devm_ioremap_resource(&pdev->dev, core_memres);
 544
 545        if (IS_ERR(msm_host->core_mem)) {
 546                dev_err(&pdev->dev, "Failed to remap registers\n");
 547                ret = PTR_ERR(msm_host->core_mem);
 548                goto clk_disable;
 549        }
 550
 551        /* Reset the core and Enable SDHC mode */
 552        writel_relaxed(readl_relaxed(msm_host->core_mem + CORE_POWER) |
 553                       CORE_SW_RST, msm_host->core_mem + CORE_POWER);
 554
 555        /* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */
 556        usleep_range(1000, 5000);
 557        if (readl(msm_host->core_mem + CORE_POWER) & CORE_SW_RST) {
 558                dev_err(&pdev->dev, "Stuck in reset\n");
 559                ret = -ETIMEDOUT;
 560                goto clk_disable;
 561        }
 562
 563        /* Set HC_MODE_EN bit in HC_MODE register */
 564        writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE));
 565
 566        host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
 567        host->quirks |= SDHCI_QUIRK_SINGLE_POWER_WRITE;
 568
 569        host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
 570        dev_dbg(&pdev->dev, "Host Version: 0x%x Vendor Version 0x%x\n",
 571                host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >>
 572                               SDHCI_VENDOR_VER_SHIFT));
 573
 574        ret = sdhci_add_host(host);
 575        if (ret)
 576                goto clk_disable;
 577
 578        return 0;
 579
 580clk_disable:
 581        clk_disable_unprepare(msm_host->clk);
 582pclk_disable:
 583        clk_disable_unprepare(msm_host->pclk);
 584bus_clk_disable:
 585        if (!IS_ERR(msm_host->bus_clk))
 586                clk_disable_unprepare(msm_host->bus_clk);
 587pltfm_free:
 588        sdhci_pltfm_free(pdev);
 589        return ret;
 590}
 591
 592static int sdhci_msm_remove(struct platform_device *pdev)
 593{
 594        struct sdhci_host *host = platform_get_drvdata(pdev);
 595        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 596        struct sdhci_msm_host *msm_host = pltfm_host->priv;
 597        int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) ==
 598                    0xffffffff);
 599
 600        sdhci_remove_host(host, dead);
 601        sdhci_pltfm_free(pdev);
 602        clk_disable_unprepare(msm_host->clk);
 603        clk_disable_unprepare(msm_host->pclk);
 604        if (!IS_ERR(msm_host->bus_clk))
 605                clk_disable_unprepare(msm_host->bus_clk);
 606        return 0;
 607}
 608
 609static struct platform_driver sdhci_msm_driver = {
 610        .probe = sdhci_msm_probe,
 611        .remove = sdhci_msm_remove,
 612        .driver = {
 613                   .name = "sdhci_msm",
 614                   .owner = THIS_MODULE,
 615                   .of_match_table = sdhci_msm_dt_match,
 616        },
 617};
 618
 619module_platform_driver(sdhci_msm_driver);
 620
 621MODULE_DESCRIPTION("Qualcomm Secure Digital Host Controller Interface driver");
 622MODULE_LICENSE("GPL v2");
 623