summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorSteffen Trumtrar <s.trumtrar@pengutronix.de>2022-01-18 15:04:50 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2022-01-20 09:30:06 +0100
commit5e87daebe0b53bf62998c9e500227456745fdc98 (patch)
treefa6caca37ffa84dc6c80476c54551439ad410c2f /drivers/ata
parentc3ed22389e8d7f2979592949b034af7807dd599b (diff)
downloadbarebox-5e87daebe0b53bf62998c9e500227456745fdc98.tar.gz
barebox-5e87daebe0b53bf62998c9e500227456745fdc98.tar.xz
ata: sata_mv: handle the phy errata
Copied from Linux v5.15 Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> Link: https://lore.barebox.org/20220118140453.1860909-4-s.trumtrar@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_mv.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index c94ad2ca36..b8d21525a7 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -52,6 +52,40 @@ static void ata_ioports_init(struct ata_ioports *io,
#define REG_SCONTROL__IPM__PARTIAL 0x00000100
#define REG_SCONTROL__IPM__SLUMBER 0x00000200
+#define PHY_MODE3 0x310
+#define PHY_MODE4 0x314 /* requires read-after-write */
+#define PHY_MODE9_GEN2 0x398
+#define PHY_MODE9_GEN1 0x39c
+
+static void mv_soc_65n_phy_errata(void __iomem *base)
+{
+ u32 reg;
+
+ reg = readl(base + PHY_MODE3);
+ reg &= ~(0x3 << 27); /* SELMUPF (bits 28:27) to 1 */
+ reg |= (0x1 << 27);
+ reg &= ~(0x3 << 29); /* SELMUPI (bits 30:29) to 1 */
+ reg |= (0x1 << 29);
+ writel(reg, base + PHY_MODE3);
+
+ reg = readl(base + PHY_MODE4);
+ reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
+ reg |= (0x1 << 16);
+ writel(reg, base + PHY_MODE4);
+
+ reg = readl(base + PHY_MODE9_GEN2);
+ reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
+ writel(reg, base + PHY_MODE9_GEN2);
+
+ reg = readl(base + PHY_MODE9_GEN1);
+ reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
+ writel(reg, base + PHY_MODE9_GEN1);
+}
+
static int mv_sata_probe(struct device_d *dev)
{
struct resource *iores;
@@ -90,6 +124,8 @@ static int mv_sata_probe(struct device_d *dev)
return ret;
}
+ mv_soc_65n_phy_errata(base);
+
writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0));
udelay(25);
writel(0x0, base + REG_EDMA_COMMAND(0));