linux/drivers/mmc/host/sdhci-of-arasan.c
<<
>>
Prefs
   1/*
   2 * Arasan Secure Digital Host Controller Interface.
   3 * Copyright (C) 2011 - 2012 Michal Simek <monstr@monstr.eu>
   4 * Copyright (c) 2012 Wind River Systems, Inc.
   5 * Copyright (C) 2013 Pengutronix e.K.
   6 * Copyright (C) 2013 Xilinx Inc.
   7 *
   8 * Based on sdhci-of-esdhc.c
   9 *
  10 * Copyright (c) 2007 Freescale Semiconductor, Inc.
  11 * Copyright (c) 2009 MontaVista Software, Inc.
  12 *
  13 * Authors: Xiaobo Xie <X.Xie@freescale.com>
  14 *          Anton Vorontsov <avorontsov@ru.mvista.com>
  15 *
  16 * This program is free software; you can redistribute it and/or modify
  17 * it under the terms of the GNU General Public License as published by
  18 * the Free Software Foundation; either version 2 of the License, or (at
  19 * your option) any later version.
  20 */
  21
  22#include <linux/clk-provider.h>
  23#include <linux/mfd/syscon.h>
  24#include <linux/module.h>
  25#include <linux/of_device.h>
  26#include <linux/phy/phy.h>
  27#include <linux/regmap.h>
  28#include "sdhci-pltfm.h"
  29#include <linux/of.h>
  30
  31#define SDHCI_ARASAN_VENDOR_REGISTER    0x78
  32
  33#define VENDOR_ENHANCED_STROBE          BIT(0)
  34
  35#define PHY_CLK_TOO_SLOW_HZ             400000
  36
  37/*
  38 * On some SoCs the syscon area has a feature where the upper 16-bits of
  39 * each 32-bit register act as a write mask for the lower 16-bits.  This allows
  40 * atomic updates of the register without locking.  This macro is used on SoCs
  41 * that have that feature.
  42 */
  43#define HIWORD_UPDATE(val, mask, shift) \
  44                ((val) << (shift) | (mask) << ((shift) + 16))
  45
  46/**
  47 * struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map
  48 *
  49 * @reg:        Offset within the syscon of the register containing this field
  50 * @width:      Number of bits for this field
  51 * @shift:      Bit offset within @reg of this field (or -1 if not avail)
  52 */
  53struct sdhci_arasan_soc_ctl_field {
  54        u32 reg;
  55        u16 width;
  56        s16 shift;
  57};
  58
  59/**
  60 * struct sdhci_arasan_soc_ctl_map - Map in syscon to corecfg registers
  61 *
  62 * It's up to the licensee of the Arsan IP block to make these available
  63 * somewhere if needed.  Presumably these will be scattered somewhere that's
  64 * accessible via the syscon API.
  65 *
  66 * @baseclkfreq:        Where to find corecfg_baseclkfreq
  67 * @clockmultiplier:    Where to find corecfg_clockmultiplier
  68 * @hiword_update:      If true, use HIWORD_UPDATE to access the syscon
  69 */
  70struct sdhci_arasan_soc_ctl_map {
  71        struct sdhci_arasan_soc_ctl_field       baseclkfreq;
  72        struct sdhci_arasan_soc_ctl_field       clockmultiplier;
  73        bool                                    hiword_update;
  74};
  75
  76/**
  77 * struct sdhci_arasan_data
  78 * @host:               Pointer to the main SDHCI host structure.
  79 * @clk_ahb:            Pointer to the AHB clock
  80 * @phy:                Pointer to the generic phy
  81 * @is_phy_on:          True if the PHY is on; false if not.
  82 * @sdcardclk_hw:       Struct for the clock we might provide to a PHY.
  83 * @sdcardclk:          Pointer to normal 'struct clock' for sdcardclk_hw.
  84 * @soc_ctl_base:       Pointer to regmap for syscon for soc_ctl registers.
  85 * @soc_ctl_map:        Map to get offsets into soc_ctl registers.
  86 */
  87struct sdhci_arasan_data {
  88        struct sdhci_host *host;
  89        struct clk      *clk_ahb;
  90        struct phy      *phy;
  91        bool            is_phy_on;
  92
  93        struct clk_hw   sdcardclk_hw;
  94        struct clk      *sdcardclk;
  95
  96        struct regmap   *soc_ctl_base;
  97        const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
  98        unsigned int    quirks; /* Arasan deviations from spec */
  99
 100/* Controller does not have CD wired and will not function normally without */
 101#define SDHCI_ARASAN_QUIRK_FORCE_CDTEST BIT(0)
 102};
 103
 104static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = {
 105        .baseclkfreq = { .reg = 0xf000, .width = 8, .shift = 8 },
 106        .clockmultiplier = { .reg = 0xf02c, .width = 8, .shift = 0},
 107        .hiword_update = true,
 108};
 109
 110/**
 111 * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers
 112 *
 113 * This function allows writing to fields in sdhci_arasan_soc_ctl_map.
 114 * Note that if a field is specified as not available (shift < 0) then
 115 * this function will silently return an error code.  It will be noisy
 116 * and print errors for any other (unexpected) errors.
 117 *
 118 * @host:       The sdhci_host
 119 * @fld:        The field to write to
 120 * @val:        The value to write
 121 */
 122static int sdhci_arasan_syscon_write(struct sdhci_host *host,
 123                                   const struct sdhci_arasan_soc_ctl_field *fld,
 124                                   u32 val)
 125{
 126        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 127        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 128        struct regmap *soc_ctl_base = sdhci_arasan->soc_ctl_base;
 129        u32 reg = fld->reg;
 130        u16 width = fld->width;
 131        s16 shift = fld->shift;
 132        int ret;
 133
 134        /*
 135         * Silently return errors for shift < 0 so caller doesn't have
 136         * to check for fields which are optional.  For fields that
 137         * are required then caller needs to do something special
 138         * anyway.
 139         */
 140        if (shift < 0)
 141                return -EINVAL;
 142
 143        if (sdhci_arasan->soc_ctl_map->hiword_update)
 144                ret = regmap_write(soc_ctl_base, reg,
 145                                   HIWORD_UPDATE(val, GENMASK(width, 0),
 146                                                 shift));
 147        else
 148                ret = regmap_update_bits(soc_ctl_base, reg,
 149                                         GENMASK(shift + width, shift),
 150                                         val << shift);
 151
 152        /* Yell about (unexpected) regmap errors */
 153        if (ret)
 154                pr_warn("%s: Regmap write fail: %d\n",
 155                         mmc_hostname(host->mmc), ret);
 156
 157        return ret;
 158}
 159
 160static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock)
 161{
 162        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 163        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 164        bool ctrl_phy = false;
 165
 166        if (!IS_ERR(sdhci_arasan->phy)) {
 167                if (!sdhci_arasan->is_phy_on && clock <= PHY_CLK_TOO_SLOW_HZ) {
 168                        /*
 169                         * If PHY off, set clock to max speed and power PHY on.
 170                         *
 171                         * Although PHY docs apparently suggest power cycling
 172                         * when changing the clock the PHY doesn't like to be
 173                         * powered on while at low speeds like those used in ID
 174                         * mode.  Even worse is powering the PHY on while the
 175                         * clock is off.
 176                         *
 177                         * To workaround the PHY limitations, the best we can
 178                         * do is to power it on at a faster speed and then slam
 179                         * through low speeds without power cycling.
 180                         */
 181                        sdhci_set_clock(host, host->max_clk);
 182                        phy_power_on(sdhci_arasan->phy);
 183                        sdhci_arasan->is_phy_on = true;
 184
 185                        /*
 186                         * We'll now fall through to the below case with
 187                         * ctrl_phy = false (so we won't turn off/on).  The
 188                         * sdhci_set_clock() will set the real clock.
 189                         */
 190                } else if (clock > PHY_CLK_TOO_SLOW_HZ) {
 191                        /*
 192                         * At higher clock speeds the PHY is fine being power
 193                         * cycled and docs say you _should_ power cycle when
 194                         * changing clock speeds.
 195                         */
 196                        ctrl_phy = true;
 197                }
 198        }
 199
 200        if (ctrl_phy && sdhci_arasan->is_phy_on) {
 201                phy_power_off(sdhci_arasan->phy);
 202                sdhci_arasan->is_phy_on = false;
 203        }
 204
 205        sdhci_set_clock(host, clock);
 206
 207        if (ctrl_phy) {
 208                phy_power_on(sdhci_arasan->phy);
 209                sdhci_arasan->is_phy_on = true;
 210        }
 211}
 212
 213static void sdhci_arasan_hs400_enhanced_strobe(struct mmc_host *mmc,
 214                                        struct mmc_ios *ios)
 215{
 216        u32 vendor;
 217        struct sdhci_host *host = mmc_priv(mmc);
 218
 219        vendor = readl(host->ioaddr + SDHCI_ARASAN_VENDOR_REGISTER);
 220        if (ios->enhanced_strobe)
 221                vendor |= VENDOR_ENHANCED_STROBE;
 222        else
 223                vendor &= ~VENDOR_ENHANCED_STROBE;
 224
 225        writel(vendor, host->ioaddr + SDHCI_ARASAN_VENDOR_REGISTER);
 226}
 227
 228static void sdhci_arasan_reset(struct sdhci_host *host, u8 mask)
 229{
 230        u8 ctrl;
 231        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 232        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 233
 234        sdhci_reset(host, mask);
 235
 236        if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) {
 237                ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 238                ctrl |= SDHCI_CTRL_CDTEST_INS | SDHCI_CTRL_CDTEST_EN;
 239                sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 240        }
 241}
 242
 243static int sdhci_arasan_voltage_switch(struct mmc_host *mmc,
 244                                       struct mmc_ios *ios)
 245{
 246        switch (ios->signal_voltage) {
 247        case MMC_SIGNAL_VOLTAGE_180:
 248                /*
 249                 * Plese don't switch to 1V8 as arasan,5.1 doesn't
 250                 * actually refer to this setting to indicate the
 251                 * signal voltage and the state machine will be broken
 252                 * actually if we force to enable 1V8. That's something
 253                 * like broken quirk but we could work around here.
 254                 */
 255                return 0;
 256        case MMC_SIGNAL_VOLTAGE_330:
 257        case MMC_SIGNAL_VOLTAGE_120:
 258                /* We don't support 3V3 and 1V2 */
 259                break;
 260        }
 261
 262        return -EINVAL;
 263}
 264
 265static struct sdhci_ops sdhci_arasan_ops = {
 266        .set_clock = sdhci_arasan_set_clock,
 267        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
 268        .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
 269        .set_bus_width = sdhci_set_bus_width,
 270        .reset = sdhci_arasan_reset,
 271        .set_uhs_signaling = sdhci_set_uhs_signaling,
 272};
 273
 274static struct sdhci_pltfm_data sdhci_arasan_pdata = {
 275        .ops = &sdhci_arasan_ops,
 276        .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
 277        .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
 278                        SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
 279};
 280
 281#ifdef CONFIG_PM_SLEEP
 282/**
 283 * sdhci_arasan_suspend - Suspend method for the driver
 284 * @dev:        Address of the device structure
 285 * Returns 0 on success and error value on error
 286 *
 287 * Put the device in a low power state.
 288 */
 289static int sdhci_arasan_suspend(struct device *dev)
 290{
 291        struct platform_device *pdev = to_platform_device(dev);
 292        struct sdhci_host *host = platform_get_drvdata(pdev);
 293        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 294        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 295        int ret;
 296
 297        if (host->tuning_mode != SDHCI_TUNING_MODE_3)
 298                mmc_retune_needed(host->mmc);
 299
 300        ret = sdhci_suspend_host(host);
 301        if (ret)
 302                return ret;
 303
 304        if (!IS_ERR(sdhci_arasan->phy) && sdhci_arasan->is_phy_on) {
 305                ret = phy_power_off(sdhci_arasan->phy);
 306                if (ret) {
 307                        dev_err(dev, "Cannot power off phy.\n");
 308                        sdhci_resume_host(host);
 309                        return ret;
 310                }
 311                sdhci_arasan->is_phy_on = false;
 312        }
 313
 314        clk_disable(pltfm_host->clk);
 315        clk_disable(sdhci_arasan->clk_ahb);
 316
 317        return 0;
 318}
 319
 320/**
 321 * sdhci_arasan_resume - Resume method for the driver
 322 * @dev:        Address of the device structure
 323 * Returns 0 on success and error value on error
 324 *
 325 * Resume operation after suspend
 326 */
 327static int sdhci_arasan_resume(struct device *dev)
 328{
 329        struct platform_device *pdev = to_platform_device(dev);
 330        struct sdhci_host *host = platform_get_drvdata(pdev);
 331        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 332        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 333        int ret;
 334
 335        ret = clk_enable(sdhci_arasan->clk_ahb);
 336        if (ret) {
 337                dev_err(dev, "Cannot enable AHB clock.\n");
 338                return ret;
 339        }
 340
 341        ret = clk_enable(pltfm_host->clk);
 342        if (ret) {
 343                dev_err(dev, "Cannot enable SD clock.\n");
 344                return ret;
 345        }
 346
 347        if (!IS_ERR(sdhci_arasan->phy) && host->mmc->actual_clock) {
 348                ret = phy_power_on(sdhci_arasan->phy);
 349                if (ret) {
 350                        dev_err(dev, "Cannot power on phy.\n");
 351                        return ret;
 352                }
 353                sdhci_arasan->is_phy_on = true;
 354        }
 355
 356        return sdhci_resume_host(host);
 357}
 358#endif /* ! CONFIG_PM_SLEEP */
 359
 360static SIMPLE_DEV_PM_OPS(sdhci_arasan_dev_pm_ops, sdhci_arasan_suspend,
 361                         sdhci_arasan_resume);
 362
 363static const struct of_device_id sdhci_arasan_of_match[] = {
 364        /* SoC-specific compatible strings w/ soc_ctl_map */
 365        {
 366                .compatible = "rockchip,rk3399-sdhci-5.1",
 367                .data = &rk3399_soc_ctl_map,
 368        },
 369
 370        /* Generic compatible below here */
 371        { .compatible = "arasan,sdhci-8.9a" },
 372        { .compatible = "arasan,sdhci-5.1" },
 373        { .compatible = "arasan,sdhci-4.9a" },
 374
 375        { /* sentinel */ }
 376};
 377MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
 378
 379/**
 380 * sdhci_arasan_sdcardclk_recalc_rate - Return the card clock rate
 381 *
 382 * Return the current actual rate of the SD card clock.  This can be used
 383 * to communicate with out PHY.
 384 *
 385 * @hw:                 Pointer to the hardware clock structure.
 386 * @parent_rate         The parent rate (should be rate of clk_xin).
 387 * Returns the card clock rate.
 388 */
 389static unsigned long sdhci_arasan_sdcardclk_recalc_rate(struct clk_hw *hw,
 390                                                      unsigned long parent_rate)
 391
 392{
 393        struct sdhci_arasan_data *sdhci_arasan =
 394                container_of(hw, struct sdhci_arasan_data, sdcardclk_hw);
 395        struct sdhci_host *host = sdhci_arasan->host;
 396
 397        return host->mmc->actual_clock;
 398}
 399
 400static const struct clk_ops arasan_sdcardclk_ops = {
 401        .recalc_rate = sdhci_arasan_sdcardclk_recalc_rate,
 402};
 403
 404/**
 405 * sdhci_arasan_update_clockmultiplier - Set corecfg_clockmultiplier
 406 *
 407 * The corecfg_clockmultiplier is supposed to contain clock multiplier
 408 * value of programmable clock generator.
 409 *
 410 * NOTES:
 411 * - Many existing devices don't seem to do this and work fine.  To keep
 412 *   compatibility for old hardware where the device tree doesn't provide a
 413 *   register map, this function is a noop if a soc_ctl_map hasn't been provided
 414 *   for this platform.
 415 * - The value of corecfg_clockmultiplier should sync with that of corresponding
 416 *   value reading from sdhci_capability_register. So this function is called
 417 *   once at probe time and never called again.
 418 *
 419 * @host:               The sdhci_host
 420 */
 421static void sdhci_arasan_update_clockmultiplier(struct sdhci_host *host,
 422                                                u32 value)
 423{
 424        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 425        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 426        const struct sdhci_arasan_soc_ctl_map *soc_ctl_map =
 427                sdhci_arasan->soc_ctl_map;
 428
 429        /* Having a map is optional */
 430        if (!soc_ctl_map)
 431                return;
 432
 433        /* If we have a map, we expect to have a syscon */
 434        if (!sdhci_arasan->soc_ctl_base) {
 435                pr_warn("%s: Have regmap, but no soc-ctl-syscon\n",
 436                        mmc_hostname(host->mmc));
 437                return;
 438        }
 439
 440        sdhci_arasan_syscon_write(host, &soc_ctl_map->clockmultiplier, value);
 441}
 442
 443/**
 444 * sdhci_arasan_update_baseclkfreq - Set corecfg_baseclkfreq
 445 *
 446 * The corecfg_baseclkfreq is supposed to contain the MHz of clk_xin.  This
 447 * function can be used to make that happen.
 448 *
 449 * NOTES:
 450 * - Many existing devices don't seem to do this and work fine.  To keep
 451 *   compatibility for old hardware where the device tree doesn't provide a
 452 *   register map, this function is a noop if a soc_ctl_map hasn't been provided
 453 *   for this platform.
 454 * - It's assumed that clk_xin is not dynamic and that we use the SDHCI divider
 455 *   to achieve lower clock rates.  That means that this function is called once
 456 *   at probe time and never called again.
 457 *
 458 * @host:               The sdhci_host
 459 */
 460static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host)
 461{
 462        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 463        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 464        const struct sdhci_arasan_soc_ctl_map *soc_ctl_map =
 465                sdhci_arasan->soc_ctl_map;
 466        u32 mhz = DIV_ROUND_CLOSEST(clk_get_rate(pltfm_host->clk), 1000000);
 467
 468        /* Having a map is optional */
 469        if (!soc_ctl_map)
 470                return;
 471
 472        /* If we have a map, we expect to have a syscon */
 473        if (!sdhci_arasan->soc_ctl_base) {
 474                pr_warn("%s: Have regmap, but no soc-ctl-syscon\n",
 475                        mmc_hostname(host->mmc));
 476                return;
 477        }
 478
 479        sdhci_arasan_syscon_write(host, &soc_ctl_map->baseclkfreq, mhz);
 480}
 481
 482/**
 483 * sdhci_arasan_register_sdclk - Register the sdclk for a PHY to use
 484 *
 485 * Some PHY devices need to know what the actual card clock is.  In order for
 486 * them to find out, we'll provide a clock through the common clock framework
 487 * for them to query.
 488 *
 489 * Note: without seriously re-architecting SDHCI's clock code and testing on
 490 * all platforms, there's no way to create a totally beautiful clock here
 491 * with all clock ops implemented.  Instead, we'll just create a clock that can
 492 * be queried and set the CLK_GET_RATE_NOCACHE attribute to tell common clock
 493 * framework that we're doing things behind its back.  This should be sufficient
 494 * to create nice clean device tree bindings and later (if needed) we can try
 495 * re-architecting SDHCI if we see some benefit to it.
 496 *
 497 * @sdhci_arasan:       Our private data structure.
 498 * @clk_xin:            Pointer to the functional clock
 499 * @dev:                Pointer to our struct device.
 500 * Returns 0 on success and error value on error
 501 */
 502static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan,
 503                                       struct clk *clk_xin,
 504                                       struct device *dev)
 505{
 506        struct device_node *np = dev->of_node;
 507        struct clk_init_data sdcardclk_init;
 508        const char *parent_clk_name;
 509        int ret;
 510
 511        /* Providing a clock to the PHY is optional; no error if missing */
 512        if (!of_find_property(np, "#clock-cells", NULL))
 513                return 0;
 514
 515        ret = of_property_read_string_index(np, "clock-output-names", 0,
 516                                            &sdcardclk_init.name);
 517        if (ret) {
 518                dev_err(dev, "DT has #clock-cells but no clock-output-names\n");
 519                return ret;
 520        }
 521
 522        parent_clk_name = __clk_get_name(clk_xin);
 523        sdcardclk_init.parent_names = &parent_clk_name;
 524        sdcardclk_init.num_parents = 1;
 525        sdcardclk_init.flags = CLK_GET_RATE_NOCACHE;
 526        sdcardclk_init.ops = &arasan_sdcardclk_ops;
 527
 528        sdhci_arasan->sdcardclk_hw.init = &sdcardclk_init;
 529        sdhci_arasan->sdcardclk =
 530                devm_clk_register(dev, &sdhci_arasan->sdcardclk_hw);
 531        sdhci_arasan->sdcardclk_hw.init = NULL;
 532
 533        ret = of_clk_add_provider(np, of_clk_src_simple_get,
 534                                  sdhci_arasan->sdcardclk);
 535        if (ret)
 536                dev_err(dev, "Failed to add clock provider\n");
 537
 538        return ret;
 539}
 540
 541/**
 542 * sdhci_arasan_unregister_sdclk - Undoes sdhci_arasan_register_sdclk()
 543 *
 544 * Should be called any time we're exiting and sdhci_arasan_register_sdclk()
 545 * returned success.
 546 *
 547 * @dev:                Pointer to our struct device.
 548 */
 549static void sdhci_arasan_unregister_sdclk(struct device *dev)
 550{
 551        struct device_node *np = dev->of_node;
 552
 553        if (!of_find_property(np, "#clock-cells", NULL))
 554                return;
 555
 556        of_clk_del_provider(dev->of_node);
 557}
 558
 559static int sdhci_arasan_probe(struct platform_device *pdev)
 560{
 561        int ret;
 562        const struct of_device_id *match;
 563        struct device_node *node;
 564        struct clk *clk_xin;
 565        struct sdhci_host *host;
 566        struct sdhci_pltfm_host *pltfm_host;
 567        struct sdhci_arasan_data *sdhci_arasan;
 568        struct device_node *np = pdev->dev.of_node;
 569
 570        host = sdhci_pltfm_init(pdev, &sdhci_arasan_pdata,
 571                                sizeof(*sdhci_arasan));
 572        if (IS_ERR(host))
 573                return PTR_ERR(host);
 574
 575        pltfm_host = sdhci_priv(host);
 576        sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 577        sdhci_arasan->host = host;
 578
 579        match = of_match_node(sdhci_arasan_of_match, pdev->dev.of_node);
 580        sdhci_arasan->soc_ctl_map = match->data;
 581
 582        node = of_parse_phandle(pdev->dev.of_node, "arasan,soc-ctl-syscon", 0);
 583        if (node) {
 584                sdhci_arasan->soc_ctl_base = syscon_node_to_regmap(node);
 585                of_node_put(node);
 586
 587                if (IS_ERR(sdhci_arasan->soc_ctl_base)) {
 588                        ret = PTR_ERR(sdhci_arasan->soc_ctl_base);
 589                        if (ret != -EPROBE_DEFER)
 590                                dev_err(&pdev->dev, "Can't get syscon: %d\n",
 591                                        ret);
 592                        goto err_pltfm_free;
 593                }
 594        }
 595
 596        sdhci_arasan->clk_ahb = devm_clk_get(&pdev->dev, "clk_ahb");
 597        if (IS_ERR(sdhci_arasan->clk_ahb)) {
 598                dev_err(&pdev->dev, "clk_ahb clock not found.\n");
 599                ret = PTR_ERR(sdhci_arasan->clk_ahb);
 600                goto err_pltfm_free;
 601        }
 602
 603        clk_xin = devm_clk_get(&pdev->dev, "clk_xin");
 604        if (IS_ERR(clk_xin)) {
 605                dev_err(&pdev->dev, "clk_xin clock not found.\n");
 606                ret = PTR_ERR(clk_xin);
 607                goto err_pltfm_free;
 608        }
 609
 610        ret = clk_prepare_enable(sdhci_arasan->clk_ahb);
 611        if (ret) {
 612                dev_err(&pdev->dev, "Unable to enable AHB clock.\n");
 613                goto err_pltfm_free;
 614        }
 615
 616        ret = clk_prepare_enable(clk_xin);
 617        if (ret) {
 618                dev_err(&pdev->dev, "Unable to enable SD clock.\n");
 619                goto clk_dis_ahb;
 620        }
 621
 622        sdhci_get_of_property(pdev);
 623
 624        if (of_property_read_bool(np, "xlnx,fails-without-test-cd"))
 625                sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_FORCE_CDTEST;
 626
 627        pltfm_host->clk = clk_xin;
 628
 629        if (of_device_is_compatible(pdev->dev.of_node,
 630                                    "rockchip,rk3399-sdhci-5.1"))
 631                sdhci_arasan_update_clockmultiplier(host, 0x0);
 632
 633        sdhci_arasan_update_baseclkfreq(host);
 634
 635        ret = sdhci_arasan_register_sdclk(sdhci_arasan, clk_xin, &pdev->dev);
 636        if (ret)
 637                goto clk_disable_all;
 638
 639        ret = mmc_of_parse(host->mmc);
 640        if (ret) {
 641                dev_err(&pdev->dev, "parsing dt failed (%d)\n", ret);
 642                goto unreg_clk;
 643        }
 644
 645        sdhci_arasan->phy = ERR_PTR(-ENODEV);
 646        if (of_device_is_compatible(pdev->dev.of_node,
 647                                    "arasan,sdhci-5.1")) {
 648                sdhci_arasan->phy = devm_phy_get(&pdev->dev,
 649                                                 "phy_arasan");
 650                if (IS_ERR(sdhci_arasan->phy)) {
 651                        ret = PTR_ERR(sdhci_arasan->phy);
 652                        dev_err(&pdev->dev, "No phy for arasan,sdhci-5.1.\n");
 653                        goto unreg_clk;
 654                }
 655
 656                ret = phy_init(sdhci_arasan->phy);
 657                if (ret < 0) {
 658                        dev_err(&pdev->dev, "phy_init err.\n");
 659                        goto unreg_clk;
 660                }
 661
 662                host->mmc_host_ops.hs400_enhanced_strobe =
 663                                        sdhci_arasan_hs400_enhanced_strobe;
 664                host->mmc_host_ops.start_signal_voltage_switch =
 665                                        sdhci_arasan_voltage_switch;
 666        }
 667
 668        ret = sdhci_add_host(host);
 669        if (ret)
 670                goto err_add_host;
 671
 672        return 0;
 673
 674err_add_host:
 675        if (!IS_ERR(sdhci_arasan->phy))
 676                phy_exit(sdhci_arasan->phy);
 677unreg_clk:
 678        sdhci_arasan_unregister_sdclk(&pdev->dev);
 679clk_disable_all:
 680        clk_disable_unprepare(clk_xin);
 681clk_dis_ahb:
 682        clk_disable_unprepare(sdhci_arasan->clk_ahb);
 683err_pltfm_free:
 684        sdhci_pltfm_free(pdev);
 685        return ret;
 686}
 687
 688static int sdhci_arasan_remove(struct platform_device *pdev)
 689{
 690        int ret;
 691        struct sdhci_host *host = platform_get_drvdata(pdev);
 692        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 693        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
 694        struct clk *clk_ahb = sdhci_arasan->clk_ahb;
 695
 696        if (!IS_ERR(sdhci_arasan->phy)) {
 697                if (sdhci_arasan->is_phy_on)
 698                        phy_power_off(sdhci_arasan->phy);
 699                phy_exit(sdhci_arasan->phy);
 700        }
 701
 702        sdhci_arasan_unregister_sdclk(&pdev->dev);
 703
 704        ret = sdhci_pltfm_unregister(pdev);
 705
 706        clk_disable_unprepare(clk_ahb);
 707
 708        return ret;
 709}
 710
 711static struct platform_driver sdhci_arasan_driver = {
 712        .driver = {
 713                .name = "sdhci-arasan",
 714                .of_match_table = sdhci_arasan_of_match,
 715                .pm = &sdhci_arasan_dev_pm_ops,
 716        },
 717        .probe = sdhci_arasan_probe,
 718        .remove = sdhci_arasan_remove,
 719};
 720
 721module_platform_driver(sdhci_arasan_driver);
 722
 723MODULE_DESCRIPTION("Driver for the Arasan SDHCI Controller");
 724MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com>");
 725MODULE_LICENSE("GPL");
 726