linux/drivers/ata/ahci_imx.c
<<
>>
Prefs
   1/*
   2 * copyright (c) 2013 Freescale Semiconductor, Inc.
   3 * Freescale IMX AHCI SATA platform driver
   4 *
   5 * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms and conditions of the GNU General Public License,
   9 * version 2, as published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program. If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/platform_device.h>
  23#include <linux/regmap.h>
  24#include <linux/ahci_platform.h>
  25#include <linux/of_device.h>
  26#include <linux/mfd/syscon.h>
  27#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28#include <linux/libata.h>
  29#include "ahci.h"
  30
  31#define DRV_NAME "ahci-imx"
  32
  33enum {
  34        /* Timer 1-ms Register */
  35        IMX_TIMER1MS                            = 0x00e0,
  36        /* Port0 PHY Control Register */
  37        IMX_P0PHYCR                             = 0x0178,
  38        IMX_P0PHYCR_TEST_PDDQ                   = 1 << 20,
  39        IMX_P0PHYCR_CR_READ                     = 1 << 19,
  40        IMX_P0PHYCR_CR_WRITE                    = 1 << 18,
  41        IMX_P0PHYCR_CR_CAP_DATA                 = 1 << 17,
  42        IMX_P0PHYCR_CR_CAP_ADDR                 = 1 << 16,
  43        /* Port0 PHY Status Register */
  44        IMX_P0PHYSR                             = 0x017c,
  45        IMX_P0PHYSR_CR_ACK                      = 1 << 18,
  46        IMX_P0PHYSR_CR_DATA_OUT                 = 0xffff << 0,
  47        /* Lane0 Output Status Register */
  48        IMX_LANE0_OUT_STAT                      = 0x2003,
  49        IMX_LANE0_OUT_STAT_RX_PLL_STATE         = 1 << 1,
  50        /* Clock Reset Register */
  51        IMX_CLOCK_RESET                         = 0x7f3f,
  52        IMX_CLOCK_RESET_RESET                   = 1 << 0,
  53};
  54
  55enum ahci_imx_type {
  56        AHCI_IMX53,
  57        AHCI_IMX6Q,
  58};
  59
  60struct imx_ahci_priv {
  61        struct platform_device *ahci_pdev;
  62        enum ahci_imx_type type;
  63        struct clk *sata_clk;
  64        struct clk *sata_ref_clk;
  65        struct clk *ahb_clk;
  66        struct regmap *gpr;
  67        bool no_device;
  68        bool first_time;
  69        u32 phy_params;
  70};
  71
  72static int ahci_imx_hotplug;
  73module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
  74MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
  75
  76static void ahci_imx_host_stop(struct ata_host *host);
  77
  78static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert)
  79{
  80        int timeout = 10;
  81        u32 crval;
  82        u32 srval;
  83
  84        /* Assert or deassert the bit */
  85        crval = readl(mmio + IMX_P0PHYCR);
  86        if (assert)
  87                crval |= bit;
  88        else
  89                crval &= ~bit;
  90        writel(crval, mmio + IMX_P0PHYCR);
  91
  92        /* Wait for the cr_ack signal */
  93        do {
  94                srval = readl(mmio + IMX_P0PHYSR);
  95                if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK)
  96                        break;
  97                usleep_range(100, 200);
  98        } while (--timeout);
  99
 100        return timeout ? 0 : -ETIMEDOUT;
 101}
 102
 103static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio)
 104{
 105        u32 crval = addr;
 106        int ret;
 107
 108        /* Supply the address on cr_data_in */
 109        writel(crval, mmio + IMX_P0PHYCR);
 110
 111        /* Assert the cr_cap_addr signal */
 112        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true);
 113        if (ret)
 114                return ret;
 115
 116        /* Deassert cr_cap_addr */
 117        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false);
 118        if (ret)
 119                return ret;
 120
 121        return 0;
 122}
 123
 124static int imx_phy_reg_write(u16 val, void __iomem *mmio)
 125{
 126        u32 crval = val;
 127        int ret;
 128
 129        /* Supply the data on cr_data_in */
 130        writel(crval, mmio + IMX_P0PHYCR);
 131
 132        /* Assert the cr_cap_data signal */
 133        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true);
 134        if (ret)
 135                return ret;
 136
 137        /* Deassert cr_cap_data */
 138        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false);
 139        if (ret)
 140                return ret;
 141
 142        if (val & IMX_CLOCK_RESET_RESET) {
 143                /*
 144                 * In case we're resetting the phy, it's unable to acknowledge,
 145                 * so we return immediately here.
 146                 */
 147                crval |= IMX_P0PHYCR_CR_WRITE;
 148                writel(crval, mmio + IMX_P0PHYCR);
 149                goto out;
 150        }
 151
 152        /* Assert the cr_write signal */
 153        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true);
 154        if (ret)
 155                return ret;
 156
 157        /* Deassert cr_write */
 158        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false);
 159        if (ret)
 160                return ret;
 161
 162out:
 163        return 0;
 164}
 165
 166static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
 167{
 168        int ret;
 169
 170        /* Assert the cr_read signal */
 171        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true);
 172        if (ret)
 173                return ret;
 174
 175        /* Capture the data from cr_data_out[] */
 176        *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT;
 177
 178        /* Deassert cr_read */
 179        ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false);
 180        if (ret)
 181                return ret;
 182
 183        return 0;
 184}
 185
 186static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
 187{
 188        void __iomem *mmio = hpriv->mmio;
 189        int timeout = 10;
 190        u16 val;
 191        int ret;
 192
 193        /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
 194        ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
 195        if (ret)
 196                return ret;
 197        ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio);
 198        if (ret)
 199                return ret;
 200
 201        /* Wait for PHY RX_PLL to be stable */
 202        do {
 203                usleep_range(100, 200);
 204                ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio);
 205                if (ret)
 206                        return ret;
 207                ret = imx_phy_reg_read(&val, mmio);
 208                if (ret)
 209                        return ret;
 210                if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE)
 211                        break;
 212        } while (--timeout);
 213
 214        return timeout ? 0 : -ETIMEDOUT;
 215}
 216
 217static int imx_sata_enable(struct ahci_host_priv *hpriv)
 218{
 219        struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 220        struct device *dev = &imxpriv->ahci_pdev->dev;
 221        int ret;
 222
 223        if (imxpriv->no_device)
 224                return 0;
 225
 226        ret = ahci_platform_enable_regulators(hpriv);
 227        if (ret)
 228                return ret;
 229
 230        ret = clk_prepare_enable(imxpriv->sata_ref_clk);
 231        if (ret < 0)
 232                goto disable_regulator;
 233
 234        if (imxpriv->type == AHCI_IMX6Q) {
 235                /*
 236                 * set PHY Paremeters, two steps to configure the GPR13,
 237                 * one write for rest of parameters, mask of first write
 238                 * is 0x07ffffff, and the other one write for setting
 239                 * the mpll_clk_en.
 240                 */
 241                regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
 242                                   IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
 243                                   IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
 244                                   IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
 245                                   IMX6Q_GPR13_SATA_SPD_MODE_MASK |
 246                                   IMX6Q_GPR13_SATA_MPLL_SS_EN |
 247                                   IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
 248                                   IMX6Q_GPR13_SATA_TX_BOOST_MASK |
 249                                   IMX6Q_GPR13_SATA_TX_LVL_MASK |
 250                                   IMX6Q_GPR13_SATA_MPLL_CLK_EN |
 251                                   IMX6Q_GPR13_SATA_TX_EDGE_RATE,
 252                                   imxpriv->phy_params);
 253                regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
 254                                   IMX6Q_GPR13_SATA_MPLL_CLK_EN,
 255                                   IMX6Q_GPR13_SATA_MPLL_CLK_EN);
 256
 257                usleep_range(100, 200);
 258
 259                ret = imx_sata_phy_reset(hpriv);
 260                if (ret) {
 261                        dev_err(dev, "failed to reset phy: %d\n", ret);
 262                        goto disable_clk;
 263                }
 264        }
 265
 266        usleep_range(1000, 2000);
 267
 268        return 0;
 269
 270disable_clk:
 271        clk_disable_unprepare(imxpriv->sata_ref_clk);
 272disable_regulator:
 273        ahci_platform_disable_regulators(hpriv);
 274
 275        return ret;
 276}
 277
 278static void imx_sata_disable(struct ahci_host_priv *hpriv)
 279{
 280        struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 281
 282        if (imxpriv->no_device)
 283                return;
 284
 285        if (imxpriv->type == AHCI_IMX6Q) {
 286                regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
 287                                   IMX6Q_GPR13_SATA_MPLL_CLK_EN,
 288                                   !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
 289        }
 290
 291        clk_disable_unprepare(imxpriv->sata_ref_clk);
 292
 293        ahci_platform_disable_regulators(hpriv);
 294}
 295
 296static void ahci_imx_error_handler(struct ata_port *ap)
 297{
 298        u32 reg_val;
 299        struct ata_device *dev;
 300        struct ata_host *host = dev_get_drvdata(ap->dev);
 301        struct ahci_host_priv *hpriv = host->private_data;
 302        void __iomem *mmio = hpriv->mmio;
 303        struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 304
 305        ahci_error_handler(ap);
 306
 307        if (!(imxpriv->first_time) || ahci_imx_hotplug)
 308                return;
 309
 310        imxpriv->first_time = false;
 311
 312        ata_for_each_dev(dev, &ap->link, ENABLED)
 313                return;
 314        /*
 315         * Disable link to save power.  An imx ahci port can't be recovered
 316         * without full reset once the pddq mode is enabled making it
 317         * impossible to use as part of libata LPM.
 318         */
 319        reg_val = readl(mmio + IMX_P0PHYCR);
 320        writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR);
 321        imx_sata_disable(hpriv);
 322        imxpriv->no_device = true;
 323
 324        dev_info(ap->dev, "no device found, disabling link.\n");
 325        dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX ".hotplug=1 to enable hotplug\n");
 326}
 327
 328static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
 329                       unsigned long deadline)
 330{
 331        struct ata_port *ap = link->ap;
 332        struct ata_host *host = dev_get_drvdata(ap->dev);
 333        struct ahci_host_priv *hpriv = host->private_data;
 334        struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 335        int ret = -EIO;
 336
 337        if (imxpriv->type == AHCI_IMX53)
 338                ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline);
 339        else if (imxpriv->type == AHCI_IMX6Q)
 340                ret = ahci_ops.softreset(link, class, deadline);
 341
 342        return ret;
 343}
 344
 345static struct ata_port_operations ahci_imx_ops = {
 346        .inherits       = &ahci_ops,
 347        .host_stop      = ahci_imx_host_stop,
 348        .error_handler  = ahci_imx_error_handler,
 349        .softreset      = ahci_imx_softreset,
 350};
 351
 352static const struct ata_port_info ahci_imx_port_info = {
 353        .flags          = AHCI_FLAG_COMMON,
 354        .pio_mask       = ATA_PIO4,
 355        .udma_mask      = ATA_UDMA6,
 356        .port_ops       = &ahci_imx_ops,
 357};
 358
 359static const struct of_device_id imx_ahci_of_match[] = {
 360        { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
 361        { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
 362        {},
 363};
 364MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
 365
 366struct reg_value {
 367        u32 of_value;
 368        u32 reg_value;
 369};
 370
 371struct reg_property {
 372        const char *name;
 373        const struct reg_value *values;
 374        size_t num_values;
 375        u32 def_value;
 376        u32 set_value;
 377};
 378
 379static const struct reg_value gpr13_tx_level[] = {
 380        {  937, IMX6Q_GPR13_SATA_TX_LVL_0_937_V },
 381        {  947, IMX6Q_GPR13_SATA_TX_LVL_0_947_V },
 382        {  957, IMX6Q_GPR13_SATA_TX_LVL_0_957_V },
 383        {  966, IMX6Q_GPR13_SATA_TX_LVL_0_966_V },
 384        {  976, IMX6Q_GPR13_SATA_TX_LVL_0_976_V },
 385        {  986, IMX6Q_GPR13_SATA_TX_LVL_0_986_V },
 386        {  996, IMX6Q_GPR13_SATA_TX_LVL_0_996_V },
 387        { 1005, IMX6Q_GPR13_SATA_TX_LVL_1_005_V },
 388        { 1015, IMX6Q_GPR13_SATA_TX_LVL_1_015_V },
 389        { 1025, IMX6Q_GPR13_SATA_TX_LVL_1_025_V },
 390        { 1035, IMX6Q_GPR13_SATA_TX_LVL_1_035_V },
 391        { 1045, IMX6Q_GPR13_SATA_TX_LVL_1_045_V },
 392        { 1054, IMX6Q_GPR13_SATA_TX_LVL_1_054_V },
 393        { 1064, IMX6Q_GPR13_SATA_TX_LVL_1_064_V },
 394        { 1074, IMX6Q_GPR13_SATA_TX_LVL_1_074_V },
 395        { 1084, IMX6Q_GPR13_SATA_TX_LVL_1_084_V },
 396        { 1094, IMX6Q_GPR13_SATA_TX_LVL_1_094_V },
 397        { 1104, IMX6Q_GPR13_SATA_TX_LVL_1_104_V },
 398        { 1113, IMX6Q_GPR13_SATA_TX_LVL_1_113_V },
 399        { 1123, IMX6Q_GPR13_SATA_TX_LVL_1_123_V },
 400        { 1133, IMX6Q_GPR13_SATA_TX_LVL_1_133_V },
 401        { 1143, IMX6Q_GPR13_SATA_TX_LVL_1_143_V },
 402        { 1152, IMX6Q_GPR13_SATA_TX_LVL_1_152_V },
 403        { 1162, IMX6Q_GPR13_SATA_TX_LVL_1_162_V },
 404        { 1172, IMX6Q_GPR13_SATA_TX_LVL_1_172_V },
 405        { 1182, IMX6Q_GPR13_SATA_TX_LVL_1_182_V },
 406        { 1191, IMX6Q_GPR13_SATA_TX_LVL_1_191_V },
 407        { 1201, IMX6Q_GPR13_SATA_TX_LVL_1_201_V },
 408        { 1211, IMX6Q_GPR13_SATA_TX_LVL_1_211_V },
 409        { 1221, IMX6Q_GPR13_SATA_TX_LVL_1_221_V },
 410        { 1230, IMX6Q_GPR13_SATA_TX_LVL_1_230_V },
 411        { 1240, IMX6Q_GPR13_SATA_TX_LVL_1_240_V }
 412};
 413
 414static const struct reg_value gpr13_tx_boost[] = {
 415        {    0, IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB },
 416        {  370, IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB },
 417        {  740, IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB },
 418        { 1110, IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB },
 419        { 1480, IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB },
 420        { 1850, IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB },
 421        { 2220, IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB },
 422        { 2590, IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB },
 423        { 2960, IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB },
 424        { 3330, IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB },
 425        { 3700, IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB },
 426        { 4070, IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB },
 427        { 4440, IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB },
 428        { 4810, IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB },
 429        { 5280, IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB },
 430        { 5750, IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB }
 431};
 432
 433static const struct reg_value gpr13_tx_atten[] = {
 434        {  8, IMX6Q_GPR13_SATA_TX_ATTEN_8_16 },
 435        {  9, IMX6Q_GPR13_SATA_TX_ATTEN_9_16 },
 436        { 10, IMX6Q_GPR13_SATA_TX_ATTEN_10_16 },
 437        { 12, IMX6Q_GPR13_SATA_TX_ATTEN_12_16 },
 438        { 14, IMX6Q_GPR13_SATA_TX_ATTEN_14_16 },
 439        { 16, IMX6Q_GPR13_SATA_TX_ATTEN_16_16 },
 440};
 441
 442static const struct reg_value gpr13_rx_eq[] = {
 443        {  500, IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB },
 444        { 1000, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB },
 445        { 1500, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB },
 446        { 2000, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB },
 447        { 2500, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB },
 448        { 3000, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB },
 449        { 3500, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB },
 450        { 4000, IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB },
 451};
 452
 453static const struct reg_property gpr13_props[] = {
 454        {
 455                .name = "fsl,transmit-level-mV",
 456                .values = gpr13_tx_level,
 457                .num_values = ARRAY_SIZE(gpr13_tx_level),
 458                .def_value = IMX6Q_GPR13_SATA_TX_LVL_1_025_V,
 459        }, {
 460                .name = "fsl,transmit-boost-mdB",
 461                .values = gpr13_tx_boost,
 462                .num_values = ARRAY_SIZE(gpr13_tx_boost),
 463                .def_value = IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB,
 464        }, {
 465                .name = "fsl,transmit-atten-16ths",
 466                .values = gpr13_tx_atten,
 467                .num_values = ARRAY_SIZE(gpr13_tx_atten),
 468                .def_value = IMX6Q_GPR13_SATA_TX_ATTEN_9_16,
 469        }, {
 470                .name = "fsl,receive-eq-mdB",
 471                .values = gpr13_rx_eq,
 472                .num_values = ARRAY_SIZE(gpr13_rx_eq),
 473                .def_value = IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB,
 474        }, {
 475                .name = "fsl,no-spread-spectrum",
 476                .def_value = IMX6Q_GPR13_SATA_MPLL_SS_EN,
 477                .set_value = 0,
 478        },
 479};
 480
 481static u32 imx_ahci_parse_props(struct device *dev,
 482                                const struct reg_property *prop, size_t num)
 483{
 484        struct device_node *np = dev->of_node;
 485        u32 reg_value = 0;
 486        int i, j;
 487
 488        for (i = 0; i < num; i++, prop++) {
 489                u32 of_val;
 490
 491                if (prop->num_values == 0) {
 492                        if (of_property_read_bool(np, prop->name))
 493                                reg_value |= prop->set_value;
 494                        else
 495                                reg_value |= prop->def_value;
 496                        continue;
 497                }
 498
 499                if (of_property_read_u32(np, prop->name, &of_val)) {
 500                        dev_info(dev, "%s not specified, using %08x\n",
 501                                prop->name, prop->def_value);
 502                        reg_value |= prop->def_value;
 503                        continue;
 504                }
 505
 506                for (j = 0; j < prop->num_values; j++) {
 507                        if (prop->values[j].of_value == of_val) {
 508                                dev_info(dev, "%s value %u, using %08x\n",
 509                                        prop->name, of_val, prop->values[j].reg_value);
 510                                reg_value |= prop->values[j].reg_value;
 511                                break;
 512                        }
 513                }
 514
 515                if (j == prop->num_values) {
 516                        dev_err(dev, "DT property %s is not a valid value\n",
 517                                prop->name);
 518                        reg_value |= prop->def_value;
 519                }
 520        }
 521
 522        return reg_value;
 523}
 524
 525static struct scsi_host_template ahci_platform_sht = {
 526        AHCI_SHT(DRV_NAME),
 527};
 528
 529static int imx_ahci_probe(struct platform_device *pdev)
 530{
 531        struct device *dev = &pdev->dev;
 532        const struct of_device_id *of_id;
 533        struct ahci_host_priv *hpriv;
 534        struct imx_ahci_priv *imxpriv;
 535        unsigned int reg_val;
 536        int ret;
 537
 538        of_id = of_match_device(imx_ahci_of_match, dev);
 539        if (!of_id)
 540                return -EINVAL;
 541
 542        imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
 543        if (!imxpriv)
 544                return -ENOMEM;
 545
 546        imxpriv->ahci_pdev = pdev;
 547        imxpriv->no_device = false;
 548        imxpriv->first_time = true;
 549        imxpriv->type = (enum ahci_imx_type)of_id->data;
 550
 551        imxpriv->sata_clk = devm_clk_get(dev, "sata");
 552        if (IS_ERR(imxpriv->sata_clk)) {
 553                dev_err(dev, "can't get sata clock.\n");
 554                return PTR_ERR(imxpriv->sata_clk);
 555        }
 556
 557        imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
 558        if (IS_ERR(imxpriv->sata_ref_clk)) {
 559                dev_err(dev, "can't get sata_ref clock.\n");
 560                return PTR_ERR(imxpriv->sata_ref_clk);
 561        }
 562
 563        imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
 564        if (IS_ERR(imxpriv->ahb_clk)) {
 565                dev_err(dev, "can't get ahb clock.\n");
 566                return PTR_ERR(imxpriv->ahb_clk);
 567        }
 568
 569        if (imxpriv->type == AHCI_IMX6Q) {
 570                u32 reg_value;
 571
 572                imxpriv->gpr = syscon_regmap_lookup_by_compatible(
 573                                                        "fsl,imx6q-iomuxc-gpr");
 574                if (IS_ERR(imxpriv->gpr)) {
 575                        dev_err(dev,
 576                                "failed to find fsl,imx6q-iomux-gpr regmap\n");
 577                        return PTR_ERR(imxpriv->gpr);
 578                }
 579
 580                reg_value = imx_ahci_parse_props(dev, gpr13_props,
 581                                                 ARRAY_SIZE(gpr13_props));
 582
 583                imxpriv->phy_params =
 584                                   IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
 585                                   IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
 586                                   IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
 587                                   reg_value;
 588        }
 589
 590        hpriv = ahci_platform_get_resources(pdev);
 591        if (IS_ERR(hpriv))
 592                return PTR_ERR(hpriv);
 593
 594        hpriv->plat_data = imxpriv;
 595
 596        ret = clk_prepare_enable(imxpriv->sata_clk);
 597        if (ret)
 598                return ret;
 599
 600        ret = imx_sata_enable(hpriv);
 601        if (ret)
 602                goto disable_clk;
 603
 604        /*
 605         * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
 606         * and IP vendor specific register IMX_TIMER1MS.
 607         * Configure CAP_SSS (support stagered spin up).
 608         * Implement the port0.
 609         * Get the ahb clock rate, and configure the TIMER1MS register.
 610         */
 611        reg_val = readl(hpriv->mmio + HOST_CAP);
 612        if (!(reg_val & HOST_CAP_SSS)) {
 613                reg_val |= HOST_CAP_SSS;
 614                writel(reg_val, hpriv->mmio + HOST_CAP);
 615        }
 616        reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL);
 617        if (!(reg_val & 0x1)) {
 618                reg_val |= 0x1;
 619                writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
 620        }
 621
 622        reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
 623        writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
 624
 625        ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
 626                                      &ahci_platform_sht);
 627        if (ret)
 628                goto disable_sata;
 629
 630        return 0;
 631
 632disable_sata:
 633        imx_sata_disable(hpriv);
 634disable_clk:
 635        clk_disable_unprepare(imxpriv->sata_clk);
 636        return ret;
 637}
 638
 639static void ahci_imx_host_stop(struct ata_host *host)
 640{
 641        struct ahci_host_priv *hpriv = host->private_data;
 642        struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 643
 644        imx_sata_disable(hpriv);
 645        clk_disable_unprepare(imxpriv->sata_clk);
 646}
 647
 648#ifdef CONFIG_PM_SLEEP
 649static int imx_ahci_suspend(struct device *dev)
 650{
 651        struct ata_host *host = dev_get_drvdata(dev);
 652        struct ahci_host_priv *hpriv = host->private_data;
 653        int ret;
 654
 655        ret = ahci_platform_suspend_host(dev);
 656        if (ret)
 657                return ret;
 658
 659        imx_sata_disable(hpriv);
 660
 661        return 0;
 662}
 663
 664static int imx_ahci_resume(struct device *dev)
 665{
 666        struct ata_host *host = dev_get_drvdata(dev);
 667        struct ahci_host_priv *hpriv = host->private_data;
 668        int ret;
 669
 670        ret = imx_sata_enable(hpriv);
 671        if (ret)
 672                return ret;
 673
 674        return ahci_platform_resume_host(dev);
 675}
 676#endif
 677
 678static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
 679
 680static struct platform_driver imx_ahci_driver = {
 681        .probe = imx_ahci_probe,
 682        .remove = ata_platform_remove_one,
 683        .driver = {
 684                .name = DRV_NAME,
 685                .of_match_table = imx_ahci_of_match,
 686                .pm = &ahci_imx_pm_ops,
 687        },
 688};
 689module_platform_driver(imx_ahci_driver);
 690
 691MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver");
 692MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>");
 693MODULE_LICENSE("GPL");
 694MODULE_ALIAS("ahci:imx");
 695