Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ahci: imx: add the imx6qp ahci sata support

- Regarding to imx6q ahci sata, imx6qp ahci sata
has the reset mechanism. Add the imx6qp ahci sata
support in this commit.
- Use the specific reset callback for imx53 sata,
and use the default ahci_ops.softreset for the others.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Richard Zhu and committed by
Tejun Heo
e5878732 34d232eb

+35 -4
+1
Documentation/devicetree/bindings/ata/imx-sata.txt
··· 7 7 - compatible : should be one of the following: 8 8 - "fsl,imx53-ahci" for i.MX53 SATA controller 9 9 - "fsl,imx6q-ahci" for i.MX6Q SATA controller 10 + - "fsl,imx6qp-ahci" for i.MX6QP SATA controller 10 11 - interrupts : interrupt mapping for SATA IRQ 11 12 - reg : registers mapping 12 13 - clocks : list of clock specifiers, must contain an entry for each
+32 -4
drivers/ata/ahci_imx.c
··· 58 58 enum ahci_imx_type { 59 59 AHCI_IMX53, 60 60 AHCI_IMX6Q, 61 + AHCI_IMX6QP, 61 62 }; 62 63 63 64 struct imx_ahci_priv { ··· 189 188 190 189 static int imx_sata_phy_reset(struct ahci_host_priv *hpriv) 191 190 { 191 + struct imx_ahci_priv *imxpriv = hpriv->plat_data; 192 192 void __iomem *mmio = hpriv->mmio; 193 193 int timeout = 10; 194 194 u16 val; 195 195 int ret; 196 + 197 + if (imxpriv->type == AHCI_IMX6QP) { 198 + /* 6qp adds the sata reset mechanism, use it for 6qp sata */ 199 + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5, 200 + IMX6Q_GPR5_SATA_SW_PD, 0); 201 + 202 + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5, 203 + IMX6Q_GPR5_SATA_SW_RST, 0); 204 + udelay(50); 205 + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5, 206 + IMX6Q_GPR5_SATA_SW_RST, 207 + IMX6Q_GPR5_SATA_SW_RST); 208 + return 0; 209 + } 196 210 197 211 /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */ 198 212 ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio); ··· 424 408 if (ret < 0) 425 409 goto disable_regulator; 426 410 427 - if (imxpriv->type == AHCI_IMX6Q) { 411 + if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) { 428 412 /* 429 413 * set PHY Paremeters, two steps to configure the GPR13, 430 414 * one write for rest of parameters, mask of first write ··· 475 459 if (imxpriv->no_device) 476 460 return; 477 461 478 - if (imxpriv->type == AHCI_IMX6Q) { 462 + switch (imxpriv->type) { 463 + case AHCI_IMX6QP: 464 + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5, 465 + IMX6Q_GPR5_SATA_SW_PD, 466 + IMX6Q_GPR5_SATA_SW_PD); 479 467 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 480 468 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 481 469 !IMX6Q_GPR13_SATA_MPLL_CLK_EN); 470 + break; 471 + 472 + case AHCI_IMX6Q: 473 + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 474 + IMX6Q_GPR13_SATA_MPLL_CLK_EN, 475 + !IMX6Q_GPR13_SATA_MPLL_CLK_EN); 476 + break; 482 477 } 483 478 484 479 clk_disable_unprepare(imxpriv->sata_ref_clk); ··· 540 513 541 514 if (imxpriv->type == AHCI_IMX53) 542 515 ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline); 543 - else if (imxpriv->type == AHCI_IMX6Q) 516 + else 544 517 ret = ahci_ops.softreset(link, class, deadline); 545 518 546 519 return ret; ··· 563 536 static const struct of_device_id imx_ahci_of_match[] = { 564 537 { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 }, 565 538 { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q }, 539 + { .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP }, 566 540 {}, 567 541 }; 568 542 MODULE_DEVICE_TABLE(of, imx_ahci_of_match); ··· 771 743 return PTR_ERR(imxpriv->ahb_clk); 772 744 } 773 745 774 - if (imxpriv->type == AHCI_IMX6Q) { 746 + if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) { 775 747 u32 reg_value; 776 748 777 749 imxpriv->gpr = syscon_regmap_lookup_by_compatible(
+2
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
··· 243 243 #define IMX6Q_GPR4_IPU_RD_CACHE_CTL BIT(0) 244 244 245 245 #define IMX6Q_GPR5_L2_CLK_STOP BIT(8) 246 + #define IMX6Q_GPR5_SATA_SW_PD BIT(10) 247 + #define IMX6Q_GPR5_SATA_SW_RST BIT(11) 246 248 247 249 #define IMX6Q_GPR6_IPU1_ID00_WR_QOS_MASK (0xf << 0) 248 250 #define IMX6Q_GPR6_IPU1_ID01_WR_QOS_MASK (0xf << 4)