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 PORT_PHY_CTL = 0x178, /* Port0 PHY Control */ 33 PORT_PHY_CTL_PDDQ_LOC = 0x100000, /* PORT_PHY_CTL bits */ 34 HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ 35 }; 36 37 enum ahci_imx_type { 38 AHCI_IMX53, 39 AHCI_IMX6Q, 40 }; 41 42 struct imx_ahci_priv { 43 struct platform_device *ahci_pdev; 44 enum ahci_imx_type type; 45 46 /* i.MX53 clock */ 47 struct clk *sata_gate_clk; 48 /* Common clock */ 49 struct clk *sata_ref_clk; 50 struct clk *ahb_clk; 51 52 struct regmap *gpr; 53 bool no_device; 54 bool first_time; 55 }; 56 57 static int ahci_imx_hotplug; 58 module_param_named(hotplug, ahci_imx_hotplug, int, 0644); 59 MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)"); 60 61 static int imx_sata_clock_enable(struct device *dev) 62 { 63 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); 64 int ret; 65 66 if (imxpriv->type == AHCI_IMX53) { 67 ret = clk_prepare_enable(imxpriv->sata_gate_clk); 68 if (ret < 0) { 69 dev_err(dev, "prepare-enable sata_gate clock err:%d\n", 70 ret); 71 return ret; 72 } 73 } 74 75 ret = clk_prepare_enable(imxpriv->sata_ref_clk); 76 if (ret < 0) { 77 dev_err(dev, "prepare-enable sata_ref clock err:%d\n", 78 ret); 79 goto clk_err; 80 } 81 82 if (imxpriv->type == AHCI_IMX6Q) { 83 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 84 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 85 IMX6Q_GPR13_SATA_MPLL_CLK_EN); 86 } 87 88 usleep_range(1000, 2000); 89 90 return 0; 91 92 clk_err: 93 if (imxpriv->type == AHCI_IMX53) 94 clk_disable_unprepare(imxpriv->sata_gate_clk); 95 return ret; 96 } 97 98 static void imx_sata_clock_disable(struct device *dev) 99 { 100 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); 101 102 if (imxpriv->type == AHCI_IMX6Q) { 103 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 104 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 105 !IMX6Q_GPR13_SATA_MPLL_CLK_EN); 106 } 107 108 clk_disable_unprepare(imxpriv->sata_ref_clk); 109 110 if (imxpriv->type == AHCI_IMX53) 111 clk_disable_unprepare(imxpriv->sata_gate_clk); 112 } 113 114 static void ahci_imx_error_handler(struct ata_port *ap) 115 { 116 u32 reg_val; 117 struct ata_device *dev; 118 struct ata_host *host = dev_get_drvdata(ap->dev); 119 struct ahci_host_priv *hpriv = host->private_data; 120 void __iomem *mmio = hpriv->mmio; 121 struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent); 122 123 ahci_error_handler(ap); 124 125 if (!(imxpriv->first_time) || ahci_imx_hotplug) 126 return; 127 128 imxpriv->first_time = false; 129 130 ata_for_each_dev(dev, &ap->link, ENABLED) 131 return; 132 /* 133 * Disable link to save power. An imx ahci port can't be recovered 134 * without full reset once the pddq mode is enabled making it 135 * impossible to use as part of libata LPM. 136 */ 137 reg_val = readl(mmio + PORT_PHY_CTL); 138 writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL); 139 imx_sata_clock_disable(ap->dev); 140 imxpriv->no_device = true; 141 } 142 143 static int ahci_imx_softreset(struct ata_link *link, unsigned int *class, 144 unsigned long deadline) 145 { 146 struct ata_port *ap = link->ap; 147 struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent); 148 int ret = -EIO; 149 150 if (imxpriv->type == AHCI_IMX53) 151 ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline); 152 else if (imxpriv->type == AHCI_IMX6Q) 153 ret = ahci_ops.softreset(link, class, deadline); 154 155 return ret; 156 } 157 158 static struct ata_port_operations ahci_imx_ops = { 159 .inherits = &ahci_platform_ops, 160 .error_handler = ahci_imx_error_handler, 161 .softreset = ahci_imx_softreset, 162 }; 163 164 static const struct ata_port_info ahci_imx_port_info = { 165 .flags = AHCI_FLAG_COMMON, 166 .pio_mask = ATA_PIO4, 167 .udma_mask = ATA_UDMA6, 168 .port_ops = &ahci_imx_ops, 169 }; 170 171 static int imx_sata_init(struct device *dev, void __iomem *mmio) 172 { 173 int ret = 0; 174 unsigned int reg_val; 175 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); 176 177 ret = imx_sata_clock_enable(dev); 178 if (ret < 0) 179 return ret; 180 181 /* 182 * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, 183 * and IP vendor specific register HOST_TIMER1MS. 184 * Configure CAP_SSS (support stagered spin up). 185 * Implement the port0. 186 * Get the ahb clock rate, and configure the TIMER1MS register. 187 */ 188 reg_val = readl(mmio + HOST_CAP); 189 if (!(reg_val & HOST_CAP_SSS)) { 190 reg_val |= HOST_CAP_SSS; 191 writel(reg_val, mmio + HOST_CAP); 192 } 193 reg_val = readl(mmio + HOST_PORTS_IMPL); 194 if (!(reg_val & 0x1)) { 195 reg_val |= 0x1; 196 writel(reg_val, mmio + HOST_PORTS_IMPL); 197 } 198 199 reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; 200 writel(reg_val, mmio + HOST_TIMER1MS); 201 202 return 0; 203 } 204 205 static void imx_sata_exit(struct device *dev) 206 { 207 imx_sata_clock_disable(dev); 208 } 209 210 static int imx_ahci_suspend(struct device *dev) 211 { 212 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); 213 214 /* 215 * If no_device is set, The CLKs had been gated off in the 216 * initialization so don't do it again here. 217 */ 218 if (!imxpriv->no_device) 219 imx_sata_clock_disable(dev); 220 221 return 0; 222 } 223 224 static int imx_ahci_resume(struct device *dev) 225 { 226 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); 227 int ret = 0; 228 229 if (!imxpriv->no_device) 230 ret = imx_sata_clock_enable(dev); 231 232 return ret; 233 } 234 235 static struct ahci_platform_data imx_sata_pdata = { 236 .init = imx_sata_init, 237 .exit = imx_sata_exit, 238 .ata_port_info = &ahci_imx_port_info, 239 .suspend = imx_ahci_suspend, 240 .resume = imx_ahci_resume, 241 242 }; 243 244 static const struct of_device_id imx_ahci_of_match[] = { 245 { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 }, 246 { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q }, 247 {}, 248 }; 249 MODULE_DEVICE_TABLE(of, imx_ahci_of_match); 250 251 static int imx_ahci_probe(struct platform_device *pdev) 252 { 253 struct device *dev = &pdev->dev; 254 struct resource *mem, *irq, res[2]; 255 const struct of_device_id *of_id; 256 enum ahci_imx_type type; 257 const struct ahci_platform_data *pdata = NULL; 258 struct imx_ahci_priv *imxpriv; 259 struct device *ahci_dev; 260 struct platform_device *ahci_pdev; 261 int ret; 262 263 of_id = of_match_device(imx_ahci_of_match, dev); 264 if (!of_id) 265 return -EINVAL; 266 267 type = (enum ahci_imx_type)of_id->data; 268 pdata = &imx_sata_pdata; 269 270 imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL); 271 if (!imxpriv) { 272 dev_err(dev, "can't alloc ahci_host_priv\n"); 273 return -ENOMEM; 274 } 275 276 ahci_pdev = platform_device_alloc("ahci", -1); 277 if (!ahci_pdev) 278 return -ENODEV; 279 280 ahci_dev = &ahci_pdev->dev; 281 ahci_dev->parent = dev; 282 283 imxpriv->no_device = false; 284 imxpriv->first_time = true; 285 imxpriv->type = type; 286 287 imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); 288 if (IS_ERR(imxpriv->ahb_clk)) { 289 dev_err(dev, "can't get ahb clock.\n"); 290 ret = PTR_ERR(imxpriv->ahb_clk); 291 goto err_out; 292 } 293 294 if (type == AHCI_IMX53) { 295 imxpriv->sata_gate_clk = devm_clk_get(dev, "sata_gate"); 296 if (IS_ERR(imxpriv->sata_gate_clk)) { 297 dev_err(dev, "can't get sata_gate clock.\n"); 298 ret = PTR_ERR(imxpriv->sata_gate_clk); 299 goto err_out; 300 } 301 } 302 303 imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref"); 304 if (IS_ERR(imxpriv->sata_ref_clk)) { 305 dev_err(dev, "can't get sata_ref clock.\n"); 306 ret = PTR_ERR(imxpriv->sata_ref_clk); 307 goto err_out; 308 } 309 310 imxpriv->ahci_pdev = ahci_pdev; 311 platform_set_drvdata(pdev, imxpriv); 312 313 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 314 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 315 if (!mem || !irq) { 316 dev_err(dev, "no mmio/irq resource\n"); 317 ret = -ENOMEM; 318 goto err_out; 319 } 320 321 res[0] = *mem; 322 res[1] = *irq; 323 324 ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32); 325 ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask; 326 ahci_dev->of_node = dev->of_node; 327 328 if (type == AHCI_IMX6Q) { 329 imxpriv->gpr = syscon_regmap_lookup_by_compatible( 330 "fsl,imx6q-iomuxc-gpr"); 331 if (IS_ERR(imxpriv->gpr)) { 332 dev_err(dev, 333 "failed to find fsl,imx6q-iomux-gpr regmap\n"); 334 ret = PTR_ERR(imxpriv->gpr); 335 goto err_out; 336 } 337 338 /* 339 * Set PHY Paremeters, two steps to configure the GPR13, 340 * one write for rest of parameters, mask of first write 341 * is 0x07fffffe, and the other one write for setting 342 * the mpll_clk_en happens in imx_sata_clock_enable(). 343 */ 344 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 345 IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK | 346 IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK | 347 IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK | 348 IMX6Q_GPR13_SATA_SPD_MODE_MASK | 349 IMX6Q_GPR13_SATA_MPLL_SS_EN | 350 IMX6Q_GPR13_SATA_TX_ATTEN_MASK | 351 IMX6Q_GPR13_SATA_TX_BOOST_MASK | 352 IMX6Q_GPR13_SATA_TX_LVL_MASK | 353 IMX6Q_GPR13_SATA_MPLL_CLK_EN | 354 IMX6Q_GPR13_SATA_TX_EDGE_RATE, 355 IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB | 356 IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M | 357 IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F | 358 IMX6Q_GPR13_SATA_SPD_MODE_3P0G | 359 IMX6Q_GPR13_SATA_MPLL_SS_EN | 360 IMX6Q_GPR13_SATA_TX_ATTEN_9_16 | 361 IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB | 362 IMX6Q_GPR13_SATA_TX_LVL_1_025_V); 363 } 364 365 ret = platform_device_add_resources(ahci_pdev, res, 2); 366 if (ret) 367 goto err_out; 368 369 ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata)); 370 if (ret) 371 goto err_out; 372 373 ret = platform_device_add(ahci_pdev); 374 if (ret) { 375 err_out: 376 platform_device_put(ahci_pdev); 377 return ret; 378 } 379 380 return 0; 381 } 382 383 static int imx_ahci_remove(struct platform_device *pdev) 384 { 385 struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev); 386 struct platform_device *ahci_pdev = imxpriv->ahci_pdev; 387 388 platform_device_unregister(ahci_pdev); 389 return 0; 390 } 391 392 static struct platform_driver imx_ahci_driver = { 393 .probe = imx_ahci_probe, 394 .remove = imx_ahci_remove, 395 .driver = { 396 .name = "ahci-imx", 397 .owner = THIS_MODULE, 398 .of_match_table = imx_ahci_of_match, 399 }, 400 }; 401 module_platform_driver(imx_ahci_driver); 402 403 MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver"); 404 MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>"); 405 MODULE_LICENSE("GPL"); 406 MODULE_ALIAS("ahci:imx"); 407