mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
34d232eb2d
commit
e5878732a5
|
@ -7,6 +7,7 @@ Required properties:
|
||||||
- compatible : should be one of the following:
|
- compatible : should be one of the following:
|
||||||
- "fsl,imx53-ahci" for i.MX53 SATA controller
|
- "fsl,imx53-ahci" for i.MX53 SATA controller
|
||||||
- "fsl,imx6q-ahci" for i.MX6Q SATA controller
|
- "fsl,imx6q-ahci" for i.MX6Q SATA controller
|
||||||
|
- "fsl,imx6qp-ahci" for i.MX6QP SATA controller
|
||||||
- interrupts : interrupt mapping for SATA IRQ
|
- interrupts : interrupt mapping for SATA IRQ
|
||||||
- reg : registers mapping
|
- reg : registers mapping
|
||||||
- clocks : list of clock specifiers, must contain an entry for each
|
- clocks : list of clock specifiers, must contain an entry for each
|
||||||
|
|
|
@ -58,6 +58,7 @@ enum {
|
||||||
enum ahci_imx_type {
|
enum ahci_imx_type {
|
||||||
AHCI_IMX53,
|
AHCI_IMX53,
|
||||||
AHCI_IMX6Q,
|
AHCI_IMX6Q,
|
||||||
|
AHCI_IMX6QP,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct imx_ahci_priv {
|
struct imx_ahci_priv {
|
||||||
|
@ -188,11 +189,26 @@ static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
|
||||||
|
|
||||||
static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
|
static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
|
||||||
{
|
{
|
||||||
|
struct imx_ahci_priv *imxpriv = hpriv->plat_data;
|
||||||
void __iomem *mmio = hpriv->mmio;
|
void __iomem *mmio = hpriv->mmio;
|
||||||
int timeout = 10;
|
int timeout = 10;
|
||||||
u16 val;
|
u16 val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (imxpriv->type == AHCI_IMX6QP) {
|
||||||
|
/* 6qp adds the sata reset mechanism, use it for 6qp sata */
|
||||||
|
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
|
||||||
|
IMX6Q_GPR5_SATA_SW_PD, 0);
|
||||||
|
|
||||||
|
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
|
||||||
|
IMX6Q_GPR5_SATA_SW_RST, 0);
|
||||||
|
udelay(50);
|
||||||
|
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
|
||||||
|
IMX6Q_GPR5_SATA_SW_RST,
|
||||||
|
IMX6Q_GPR5_SATA_SW_RST);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
|
/* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
|
||||||
ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
|
ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -408,7 +424,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto disable_regulator;
|
goto disable_regulator;
|
||||||
|
|
||||||
if (imxpriv->type == AHCI_IMX6Q) {
|
if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
|
||||||
/*
|
/*
|
||||||
* set PHY Paremeters, two steps to configure the GPR13,
|
* set PHY Paremeters, two steps to configure the GPR13,
|
||||||
* one write for rest of parameters, mask of first write
|
* one write for rest of parameters, mask of first write
|
||||||
|
@ -459,10 +475,21 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv)
|
||||||
if (imxpriv->no_device)
|
if (imxpriv->no_device)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (imxpriv->type == AHCI_IMX6Q) {
|
switch (imxpriv->type) {
|
||||||
|
case AHCI_IMX6QP:
|
||||||
|
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR5,
|
||||||
|
IMX6Q_GPR5_SATA_SW_PD,
|
||||||
|
IMX6Q_GPR5_SATA_SW_PD);
|
||||||
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
|
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
|
||||||
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
|
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
|
||||||
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
|
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AHCI_IMX6Q:
|
||||||
|
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
|
||||||
|
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
|
||||||
|
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_disable_unprepare(imxpriv->sata_ref_clk);
|
clk_disable_unprepare(imxpriv->sata_ref_clk);
|
||||||
|
@ -513,7 +540,7 @@ static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
|
||||||
|
|
||||||
if (imxpriv->type == AHCI_IMX53)
|
if (imxpriv->type == AHCI_IMX53)
|
||||||
ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline);
|
ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline);
|
||||||
else if (imxpriv->type == AHCI_IMX6Q)
|
else
|
||||||
ret = ahci_ops.softreset(link, class, deadline);
|
ret = ahci_ops.softreset(link, class, deadline);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -536,6 +563,7 @@ static const struct ata_port_info ahci_imx_port_info = {
|
||||||
static const struct of_device_id imx_ahci_of_match[] = {
|
static const struct of_device_id imx_ahci_of_match[] = {
|
||||||
{ .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
|
{ .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
|
||||||
{ .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
|
{ .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
|
||||||
|
{ .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
|
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
|
||||||
|
@ -743,7 +771,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
|
||||||
return PTR_ERR(imxpriv->ahb_clk);
|
return PTR_ERR(imxpriv->ahb_clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imxpriv->type == AHCI_IMX6Q) {
|
if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
|
||||||
u32 reg_value;
|
u32 reg_value;
|
||||||
|
|
||||||
imxpriv->gpr = syscon_regmap_lookup_by_compatible(
|
imxpriv->gpr = syscon_regmap_lookup_by_compatible(
|
||||||
|
|
|
@ -243,6 +243,8 @@
|
||||||
#define IMX6Q_GPR4_IPU_RD_CACHE_CTL BIT(0)
|
#define IMX6Q_GPR4_IPU_RD_CACHE_CTL BIT(0)
|
||||||
|
|
||||||
#define IMX6Q_GPR5_L2_CLK_STOP BIT(8)
|
#define IMX6Q_GPR5_L2_CLK_STOP BIT(8)
|
||||||
|
#define IMX6Q_GPR5_SATA_SW_PD BIT(10)
|
||||||
|
#define IMX6Q_GPR5_SATA_SW_RST BIT(11)
|
||||||
|
|
||||||
#define IMX6Q_GPR6_IPU1_ID00_WR_QOS_MASK (0xf << 0)
|
#define IMX6Q_GPR6_IPU1_ID00_WR_QOS_MASK (0xf << 0)
|
||||||
#define IMX6Q_GPR6_IPU1_ID01_WR_QOS_MASK (0xf << 4)
|
#define IMX6Q_GPR6_IPU1_ID01_WR_QOS_MASK (0xf << 4)
|
||||||
|
|
Loading…
Reference in New Issue