Skip to content

Commit

Permalink
ata: ahci: ceva: Update the driver to support xilinx GT phy
Browse files Browse the repository at this point in the history
SATA controller used in Xilinx ZynqMP platform uses xilinx GT phy
which has 4 GT lanes and can be used by 4 peripherals at a time.
SATA controller uses 1 GT phy lane among the 4 GT lanes. To configure
the GT lane for the SATA controller, the below sequence is expected.

1. Assert the SATA controller reset.
2. Configure the xilinx GT phy lane for SATA controller (phy_init).
3. De-assert the SATA controller reset.
4. Wait for PLL of the GT lane used by SATA to be locked (phy_power_on).

The ahci_platform_enable_resources() by default does the phy_init()
and phy_power_on() but the default sequence doesn't work with Xilinx
platforms. Because of this reason, updated the driver to support the
new sequence.

Added cevapriv->rst check, for backward compatibility with the older
sequence. If the reset controller is not available, then the SATA
controller will configure with the older sequences.

Signed-off-by: Piyush Mehta <[email protected]>
Acked-by: Michal Simek <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Piyush Mehta authored and axboe committed Mar 12, 2021
1 parent 3c0198c commit 9a9d3ab
Showing 1 changed file with 40 additions and 3 deletions.
43 changes: 40 additions & 3 deletions drivers/ata/ahci_ceva.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include "ahci.h"

/* Vendor Specific Register Offsets */
Expand Down Expand Up @@ -87,6 +88,7 @@ struct ceva_ahci_priv {
u32 axicc;
bool is_cci_enabled;
int flags;
struct reset_control *rst;
};

static unsigned int ceva_ahci_read_id(struct ata_device *dev,
Expand Down Expand Up @@ -202,13 +204,48 @@ static int ceva_ahci_probe(struct platform_device *pdev)

cevapriv->ahci_pdev = pdev;

cevapriv->rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
NULL);
if (IS_ERR(cevapriv->rst)) {
if (PTR_ERR(cevapriv->rst) != -EPROBE_DEFER)
dev_err(&pdev->dev, "failed to get reset: %ld\n",
PTR_ERR(cevapriv->rst));
}

hpriv = ahci_platform_get_resources(pdev, 0);
if (IS_ERR(hpriv))
return PTR_ERR(hpriv);

rc = ahci_platform_enable_resources(hpriv);
if (rc)
return rc;
if (!cevapriv->rst) {
rc = ahci_platform_enable_resources(hpriv);
if (rc)
return rc;
} else {
int i;

rc = ahci_platform_enable_clks(hpriv);
if (rc)
return rc;
/* Assert the controller reset */
reset_control_assert(cevapriv->rst);

for (i = 0; i < hpriv->nports; i++) {
rc = phy_init(hpriv->phys[i]);
if (rc)
return rc;
}

/* De-assert the controller reset */
reset_control_deassert(cevapriv->rst);

for (i = 0; i < hpriv->nports; i++) {
rc = phy_power_on(hpriv->phys[i]);
if (rc) {
phy_exit(hpriv->phys[i]);
return rc;
}
}
}

if (of_property_read_bool(np, "ceva,broken-gen2"))
cevapriv->flags = CEVA_FLAG_BROKEN_GEN2;
Expand Down

0 comments on commit 9a9d3ab

Please sign in to comment.