Skip to content

Commit e587873

Browse files
Richard Zhuhtejun
authored andcommitted
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 <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 34d232e commit e587873

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

Documentation/devicetree/bindings/ata/imx-sata.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Required properties:
77
- compatible : should be one of the following:
88
- "fsl,imx53-ahci" for i.MX53 SATA controller
99
- "fsl,imx6q-ahci" for i.MX6Q SATA controller
10+
- "fsl,imx6qp-ahci" for i.MX6QP SATA controller
1011
- interrupts : interrupt mapping for SATA IRQ
1112
- reg : registers mapping
1213
- clocks : list of clock specifiers, must contain an entry for each

drivers/ata/ahci_imx.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ enum {
5858
enum ahci_imx_type {
5959
AHCI_IMX53,
6060
AHCI_IMX6Q,
61+
AHCI_IMX6QP,
6162
};
6263

6364
struct imx_ahci_priv {
@@ -188,11 +189,26 @@ static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
188189

189190
static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
190191
{
192+
struct imx_ahci_priv *imxpriv = hpriv->plat_data;
191193
void __iomem *mmio = hpriv->mmio;
192194
int timeout = 10;
193195
u16 val;
194196
int ret;
195197

198+
if (imxpriv->type == AHCI_IMX6QP) {
199+
/* 6qp adds the sata reset mechanism, use it for 6qp sata */
200+
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
201+
IMX6Q_GPR5_SATA_SW_PD, 0);
202+
203+
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
204+
IMX6Q_GPR5_SATA_SW_RST, 0);
205+
udelay(50);
206+
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
207+
IMX6Q_GPR5_SATA_SW_RST,
208+
IMX6Q_GPR5_SATA_SW_RST);
209+
return 0;
210+
}
211+
196212
/* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
197213
ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
198214
if (ret)
@@ -408,7 +424,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
408424
if (ret < 0)
409425
goto disable_regulator;
410426

411-
if (imxpriv->type == AHCI_IMX6Q) {
427+
if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
412428
/*
413429
* set PHY Paremeters, two steps to configure the GPR13,
414430
* one write for rest of parameters, mask of first write
@@ -459,10 +475,21 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv)
459475
if (imxpriv->no_device)
460476
return;
461477

462-
if (imxpriv->type == AHCI_IMX6Q) {
478+
switch (imxpriv->type) {
479+
case AHCI_IMX6QP:
480+
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
481+
IMX6Q_GPR5_SATA_SW_PD,
482+
IMX6Q_GPR5_SATA_SW_PD);
463483
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
464484
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
465485
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
486+
break;
487+
488+
case AHCI_IMX6Q:
489+
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
490+
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
491+
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
492+
break;
466493
}
467494

468495
clk_disable_unprepare(imxpriv->sata_ref_clk);
@@ -513,7 +540,7 @@ static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
513540

514541
if (imxpriv->type == AHCI_IMX53)
515542
ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline);
516-
else if (imxpriv->type == AHCI_IMX6Q)
543+
else
517544
ret = ahci_ops.softreset(link, class, deadline);
518545

519546
return ret;
@@ -536,6 +563,7 @@ static const struct ata_port_info ahci_imx_port_info = {
536563
static const struct of_device_id imx_ahci_of_match[] = {
537564
{ .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
538565
{ .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
566+
{ .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP },
539567
{},
540568
};
541569
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
@@ -743,7 +771,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
743771
return PTR_ERR(imxpriv->ahb_clk);
744772
}
745773

746-
if (imxpriv->type == AHCI_IMX6Q) {
774+
if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
747775
u32 reg_value;
748776

749777
imxpriv->gpr = syscon_regmap_lookup_by_compatible(

include/linux/mfd/syscon/imx6q-iomuxc-gpr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@
243243
#define IMX6Q_GPR4_IPU_RD_CACHE_CTL BIT(0)
244244

245245
#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)
246248

247249
#define IMX6Q_GPR6_IPU1_ID00_WR_QOS_MASK (0xf << 0)
248250
#define IMX6Q_GPR6_IPU1_ID01_WR_QOS_MASK (0xf << 4)

0 commit comments

Comments
 (0)