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