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 enum { 32 /* Timer 1-ms Register */ 33 IMX_TIMER1MS = 0x00e0, 34 /* Port0 PHY Control Register */ 35 IMX_P0PHYCR = 0x0178, 36 IMX_P0PHYCR_TEST_PDDQ = 1 << 20, 37 IMX_P0PHYCR_CR_READ = 1 << 19, 38 IMX_P0PHYCR_CR_WRITE = 1 << 18, 39 IMX_P0PHYCR_CR_CAP_DATA = 1 << 17, 40 IMX_P0PHYCR_CR_CAP_ADDR = 1 << 16, 41 /* Port0 PHY Status Register */ 42 IMX_P0PHYSR = 0x017c, 43 IMX_P0PHYSR_CR_ACK = 1 << 18, 44 IMX_P0PHYSR_CR_DATA_OUT = 0xffff << 0, 45 /* Lane0 Output Status Register */ 46 IMX_LANE0_OUT_STAT = 0x2003, 47 IMX_LANE0_OUT_STAT_RX_PLL_STATE = 1 << 1, 48 /* Clock Reset Register */ 49 IMX_CLOCK_RESET = 0x7f3f, 50 IMX_CLOCK_RESET_RESET = 1 << 0, 51 }; 52 53 enum ahci_imx_type { 54 AHCI_IMX53, 55 AHCI_IMX6Q, 56 }; 57 58 struct imx_ahci_priv { 59 struct platform_device *ahci_pdev; 60 enum ahci_imx_type type; 61 struct clk *sata_clk; 62 struct clk *sata_ref_clk; 63 struct clk *ahb_clk; 64 struct regmap *gpr; 65 bool no_device; 66 bool first_time; 67 }; 68 69 static int ahci_imx_hotplug; 70 module_param_named(hotplug, ahci_imx_hotplug, int, 0644); 71 MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)"); 72 73 static void ahci_imx_host_stop(struct ata_host *host); 74 75 static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert) 76 { 77 int timeout = 10; 78 u32 crval; 79 u32 srval; 80 81 /* Assert or deassert the bit */ 82 crval = readl(mmio + IMX_P0PHYCR); 83 if (assert) 84 crval |= bit; 85 else 86 crval &= ~bit; 87 writel(crval, mmio + IMX_P0PHYCR); 88 89 /* Wait for the cr_ack signal */ 90 do { 91 srval = readl(mmio + IMX_P0PHYSR); 92 if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK) 93 break; 94 usleep_range(100, 200); 95 } while (--timeout); 96 97 return timeout ? 0 : -ETIMEDOUT; 98 } 99 100 static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio) 101 { 102 u32 crval = addr; 103 int ret; 104 105 /* Supply the address on cr_data_in */ 106 writel(crval, mmio + IMX_P0PHYCR); 107 108 /* Assert the cr_cap_addr signal */ 109 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true); 110 if (ret) 111 return ret; 112 113 /* Deassert cr_cap_addr */ 114 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false); 115 if (ret) 116 return ret; 117 118 return 0; 119 } 120 121 static int imx_phy_reg_write(u16 val, void __iomem *mmio) 122 { 123 u32 crval = val; 124 int ret; 125 126 /* Supply the data on cr_data_in */ 127 writel(crval, mmio + IMX_P0PHYCR); 128 129 /* Assert the cr_cap_data signal */ 130 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true); 131 if (ret) 132 return ret; 133 134 /* Deassert cr_cap_data */ 135 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false); 136 if (ret) 137 return ret; 138 139 if (val & IMX_CLOCK_RESET_RESET) { 140 /* 141 * In case we're resetting the phy, it's unable to acknowledge, 142 * so we return immediately here. 143 */ 144 crval |= IMX_P0PHYCR_CR_WRITE; 145 writel(crval, mmio + IMX_P0PHYCR); 146 goto out; 147 } 148 149 /* Assert the cr_write signal */ 150 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true); 151 if (ret) 152 return ret; 153 154 /* Deassert cr_write */ 155 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false); 156 if (ret) 157 return ret; 158 159 out: 160 return 0; 161 } 162 163 static int imx_phy_reg_read(u16 *val, void __iomem *mmio) 164 { 165 int ret; 166 167 /* Assert the cr_read signal */ 168 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true); 169 if (ret) 170 return ret; 171 172 /* Capture the data from cr_data_out[] */ 173 *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT; 174 175 /* Deassert cr_read */ 176 ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false); 177 if (ret) 178 return ret; 179 180 return 0; 181 } 182 183 static int imx_sata_phy_reset(struct ahci_host_priv *hpriv) 184 { 185 void __iomem *mmio = hpriv->mmio; 186 int timeout = 10; 187 u16 val; 188 int ret; 189 190 /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */ 191 ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio); 192 if (ret) 193 return ret; 194 ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio); 195 if (ret) 196 return ret; 197 198 /* Wait for PHY RX_PLL to be stable */ 199 do { 200 usleep_range(100, 200); 201 ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio); 202 if (ret) 203 return ret; 204 ret = imx_phy_reg_read(&val, mmio); 205 if (ret) 206 return ret; 207 if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE) 208 break; 209 } while (--timeout); 210 211 return timeout ? 0 : -ETIMEDOUT; 212 } 213 214 static int imx_sata_enable(struct ahci_host_priv *hpriv) 215 { 216 struct imx_ahci_priv *imxpriv = hpriv->plat_data; 217 struct device *dev = &imxpriv->ahci_pdev->dev; 218 int ret; 219 220 if (imxpriv->no_device) 221 return 0; 222 223 if (hpriv->target_pwr) { 224 ret = regulator_enable(hpriv->target_pwr); 225 if (ret) 226 return ret; 227 } 228 229 ret = clk_prepare_enable(imxpriv->sata_ref_clk); 230 if (ret < 0) 231 goto disable_regulator; 232 233 if (imxpriv->type == AHCI_IMX6Q) { 234 /* 235 * set PHY Paremeters, two steps to configure the GPR13, 236 * one write for rest of parameters, mask of first write 237 * is 0x07ffffff, and the other one write for setting 238 * the mpll_clk_en. 239 */ 240 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 241 IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK | 242 IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK | 243 IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK | 244 IMX6Q_GPR13_SATA_SPD_MODE_MASK | 245 IMX6Q_GPR13_SATA_MPLL_SS_EN | 246 IMX6Q_GPR13_SATA_TX_ATTEN_MASK | 247 IMX6Q_GPR13_SATA_TX_BOOST_MASK | 248 IMX6Q_GPR13_SATA_TX_LVL_MASK | 249 IMX6Q_GPR13_SATA_MPLL_CLK_EN | 250 IMX6Q_GPR13_SATA_TX_EDGE_RATE, 251 IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB | 252 IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M | 253 IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F | 254 IMX6Q_GPR13_SATA_SPD_MODE_3P0G | 255 IMX6Q_GPR13_SATA_MPLL_SS_EN | 256 IMX6Q_GPR13_SATA_TX_ATTEN_9_16 | 257 IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB | 258 IMX6Q_GPR13_SATA_TX_LVL_1_025_V); 259 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 260 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 261 IMX6Q_GPR13_SATA_MPLL_CLK_EN); 262 263 usleep_range(100, 200); 264 265 ret = imx_sata_phy_reset(hpriv); 266 if (ret) { 267 dev_err(dev, "failed to reset phy: %d\n", ret); 268 goto disable_regulator; 269 } 270 } 271 272 usleep_range(1000, 2000); 273 274 return 0; 275 276 disable_regulator: 277 if (hpriv->target_pwr) 278 regulator_disable(hpriv->target_pwr); 279 280 return ret; 281 } 282 283 static void imx_sata_disable(struct ahci_host_priv *hpriv) 284 { 285 struct imx_ahci_priv *imxpriv = hpriv->plat_data; 286 287 if (imxpriv->no_device) 288 return; 289 290 if (imxpriv->type == AHCI_IMX6Q) { 291 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 292 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 293 !IMX6Q_GPR13_SATA_MPLL_CLK_EN); 294 } 295 296 clk_disable_unprepare(imxpriv->sata_ref_clk); 297 298 if (hpriv->target_pwr) 299 regulator_disable(hpriv->target_pwr); 300 } 301 302 static void ahci_imx_error_handler(struct ata_port *ap) 303 { 304 u32 reg_val; 305 struct ata_device *dev; 306 struct ata_host *host = dev_get_drvdata(ap->dev); 307 struct ahci_host_priv *hpriv = host->private_data; 308 void __iomem *mmio = hpriv->mmio; 309 struct imx_ahci_priv *imxpriv = hpriv->plat_data; 310 311 ahci_error_handler(ap); 312 313 if (!(imxpriv->first_time) || ahci_imx_hotplug) 314 return; 315 316 imxpriv->first_time = false; 317 318 ata_for_each_dev(dev, &ap->link, ENABLED) 319 return; 320 /* 321 * Disable link to save power. An imx ahci port can't be recovered 322 * without full reset once the pddq mode is enabled making it 323 * impossible to use as part of libata LPM. 324 */ 325 reg_val = readl(mmio + IMX_P0PHYCR); 326 writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR); 327 imx_sata_disable(hpriv); 328 imxpriv->no_device = true; 329 330 dev_info(ap->dev, "no device found, disabling link.\n"); 331 dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX ".hotplug=1 to enable hotplug\n"); 332 } 333 334 static int ahci_imx_softreset(struct ata_link *link, unsigned int *class, 335 unsigned long deadline) 336 { 337 struct ata_port *ap = link->ap; 338 struct ata_host *host = dev_get_drvdata(ap->dev); 339 struct ahci_host_priv *hpriv = host->private_data; 340 struct imx_ahci_priv *imxpriv = hpriv->plat_data; 341 int ret = -EIO; 342 343 if (imxpriv->type == AHCI_IMX53) 344 ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline); 345 else if (imxpriv->type == AHCI_IMX6Q) 346 ret = ahci_ops.softreset(link, class, deadline); 347 348 return ret; 349 } 350 351 static struct ata_port_operations ahci_imx_ops = { 352 .inherits = &ahci_ops, 353 .host_stop = ahci_imx_host_stop, 354 .error_handler = ahci_imx_error_handler, 355 .softreset = ahci_imx_softreset, 356 }; 357 358 static const struct ata_port_info ahci_imx_port_info = { 359 .flags = AHCI_FLAG_COMMON, 360 .pio_mask = ATA_PIO4, 361 .udma_mask = ATA_UDMA6, 362 .port_ops = &ahci_imx_ops, 363 }; 364 365 static const struct of_device_id imx_ahci_of_match[] = { 366 { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 }, 367 { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q }, 368 {}, 369 }; 370 MODULE_DEVICE_TABLE(of, imx_ahci_of_match); 371 372 static int imx_ahci_probe(struct platform_device *pdev) 373 { 374 struct device *dev = &pdev->dev; 375 const struct of_device_id *of_id; 376 struct ahci_host_priv *hpriv; 377 struct imx_ahci_priv *imxpriv; 378 unsigned int reg_val; 379 int ret; 380 381 of_id = of_match_device(imx_ahci_of_match, dev); 382 if (!of_id) 383 return -EINVAL; 384 385 imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL); 386 if (!imxpriv) 387 return -ENOMEM; 388 389 imxpriv->ahci_pdev = pdev; 390 imxpriv->no_device = false; 391 imxpriv->first_time = true; 392 imxpriv->type = (enum ahci_imx_type)of_id->data; 393 394 imxpriv->sata_clk = devm_clk_get(dev, "sata"); 395 if (IS_ERR(imxpriv->sata_clk)) { 396 dev_err(dev, "can't get sata clock.\n"); 397 return PTR_ERR(imxpriv->sata_clk); 398 } 399 400 imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref"); 401 if (IS_ERR(imxpriv->sata_ref_clk)) { 402 dev_err(dev, "can't get sata_ref clock.\n"); 403 return PTR_ERR(imxpriv->sata_ref_clk); 404 } 405 406 imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); 407 if (IS_ERR(imxpriv->ahb_clk)) { 408 dev_err(dev, "can't get ahb clock.\n"); 409 return PTR_ERR(imxpriv->ahb_clk); 410 } 411 412 if (imxpriv->type == AHCI_IMX6Q) { 413 imxpriv->gpr = syscon_regmap_lookup_by_compatible( 414 "fsl,imx6q-iomuxc-gpr"); 415 if (IS_ERR(imxpriv->gpr)) { 416 dev_err(dev, 417 "failed to find fsl,imx6q-iomux-gpr regmap\n"); 418 return PTR_ERR(imxpriv->gpr); 419 } 420 } 421 422 hpriv = ahci_platform_get_resources(pdev); 423 if (IS_ERR(hpriv)) 424 return PTR_ERR(hpriv); 425 426 hpriv->plat_data = imxpriv; 427 428 ret = clk_prepare_enable(imxpriv->sata_clk); 429 if (ret) 430 return ret; 431 432 ret = imx_sata_enable(hpriv); 433 if (ret) 434 goto disable_clk; 435 436 /* 437 * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, 438 * and IP vendor specific register IMX_TIMER1MS. 439 * Configure CAP_SSS (support stagered spin up). 440 * Implement the port0. 441 * Get the ahb clock rate, and configure the TIMER1MS register. 442 */ 443 reg_val = readl(hpriv->mmio + HOST_CAP); 444 if (!(reg_val & HOST_CAP_SSS)) { 445 reg_val |= HOST_CAP_SSS; 446 writel(reg_val, hpriv->mmio + HOST_CAP); 447 } 448 reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL); 449 if (!(reg_val & 0x1)) { 450 reg_val |= 0x1; 451 writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL); 452 } 453 454 reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; 455 writel(reg_val, hpriv->mmio + IMX_TIMER1MS); 456 457 ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 458 0, 0, 0); 459 if (ret) 460 goto disable_sata; 461 462 return 0; 463 464 disable_sata: 465 imx_sata_disable(hpriv); 466 disable_clk: 467 clk_disable_unprepare(imxpriv->sata_clk); 468 return ret; 469 } 470 471 static void ahci_imx_host_stop(struct ata_host *host) 472 { 473 struct ahci_host_priv *hpriv = host->private_data; 474 struct imx_ahci_priv *imxpriv = hpriv->plat_data; 475 476 imx_sata_disable(hpriv); 477 clk_disable_unprepare(imxpriv->sata_clk); 478 } 479 480 #ifdef CONFIG_PM_SLEEP 481 static int imx_ahci_suspend(struct device *dev) 482 { 483 struct ata_host *host = dev_get_drvdata(dev); 484 struct ahci_host_priv *hpriv = host->private_data; 485 int ret; 486 487 ret = ahci_platform_suspend_host(dev); 488 if (ret) 489 return ret; 490 491 imx_sata_disable(hpriv); 492 493 return 0; 494 } 495 496 static int imx_ahci_resume(struct device *dev) 497 { 498 struct ata_host *host = dev_get_drvdata(dev); 499 struct ahci_host_priv *hpriv = host->private_data; 500 int ret; 501 502 ret = imx_sata_enable(hpriv); 503 if (ret) 504 return ret; 505 506 return ahci_platform_resume_host(dev); 507 } 508 #endif 509 510 static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume); 511 512 static struct platform_driver imx_ahci_driver = { 513 .probe = imx_ahci_probe, 514 .remove = ata_platform_remove_one, 515 .driver = { 516 .name = "ahci-imx", 517 .owner = THIS_MODULE, 518 .of_match_table = imx_ahci_of_match, 519 .pm = &ahci_imx_pm_ops, 520 }, 521 }; 522 module_platform_driver(imx_ahci_driver); 523 524 MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver"); 525 MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>"); 526 MODULE_LICENSE("GPL"); 527 MODULE_ALIAS("ahci:imx"); 528