* [PATCH] sata_mv: use new sata phy register settings for new devices
@ 2009-04-11 16:08 Martin Michlmayr
2009-04-11 22:02 ` Grant Grundler
0 siblings, 1 reply; 8+ messages in thread
From: Martin Michlmayr @ 2009-04-11 16:08 UTC (permalink / raw)
To: Mark Lord; +Cc: Saeed Bishara, linux-ide
From: Saeed Bishara <saeed@marvell.com>
Marvell's new SoC (65 nano) needs different modification for its SATA
PHY registers.
Tested-by: Martin Michlmayr <tbm@cyrius.com>
Signed-off-by: Saeed Bishara <saeed@marvell.com>
Signed-off-by: Martin Michlmayr <tbm@cyrius.com>
---
This fixes the SATA problems I saw on the Kirkwood-based QNAP TS-219.
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 37ae5dc..f19f2e3 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -293,6 +293,10 @@ enum {
FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
+ PHY_MODE9_GEN2 = 0x398,
+ PHY_MODE9_GEN1 = 0x39c,
+ PHYCFG_OFS = 0x3a0, /* only in 65n devices */
+
MV5_PHY_MODE = 0x74,
MV5_LTMODE = 0x30,
MV5_PHY_CTL = 0x0C,
@@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
@@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = {
.reset_bus = mv_soc_reset_bus,
};
+static const struct mv_hw_ops mv_soc_65n_ops = {
+ .phy_errata = mv_soc_65n_phy_errata,
+ .enable_leds = mv_soc_enable_leds,
+ .reset_hc = mv_soc_reset_hc,
+ .reset_flash = mv_soc_reset_flash,
+ .reset_bus = mv_soc_reset_bus,
+};
+
/*
* Functions
*/
@@ -3359,6 +3373,53 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
return;
}
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+ u32 reg;
+
+ reg = readl(port_mmio + PHY_MODE3);
+ reg &= ~(0x3 << 27); /* bits 28:27 to 0x1 */
+ reg |= (0x1 << 27);
+ reg &= ~(0x3 << 29); /* bits 30:29 to 0x1 */
+ reg |= (0x1 << 29);
+ writel(reg, port_mmio + PHY_MODE3);
+
+ reg = readl(port_mmio + PHY_MODE4);
+ reg &= ~0x1; /* bit 0 to 0x0, bit 16 must be set */
+ reg |= (0x1 << 16);
+ writel(reg, port_mmio + PHY_MODE4);
+
+ reg = readl(port_mmio + PHY_MODE9_GEN2);
+ reg &= ~0xf; /* bits 3:0 to 0x8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* bit 14 to 0 */
+ writel(reg, port_mmio + PHY_MODE9_GEN2);
+
+ reg = readl(port_mmio + PHY_MODE9_GEN1);
+ reg &= ~0xf; /* bits 3:0 to 0x8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* bit 14 to 0 */
+ writel(reg, port_mmio + PHY_MODE9_GEN1);
+}
+
+/**
+ * soc_is_65 - check if the soc is 65 nano device
+ *
+ * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
+ * register, this register should contain non-zero value and it exists only
+ * in the 65 nano devices, when reading it from older devices we get 0.
+ */
+static bool soc_is_65n(struct mv_host_priv *hpriv)
+{
+ void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
+
+ if (readl(port0_mmio + PHYCFG_OFS))
+ return true;
+ return false;
+}
+
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
u32 ifcfg = readl(port_mmio + SATA_IFCFG);
@@ -3699,7 +3760,10 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
}
break;
case chip_soc:
- hpriv->ops = &mv_soc_ops;
+ if (soc_is_65n(hpriv))
+ hpriv->ops = &mv_soc_65n_ops;
+ else
+ hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
MV_HP_ERRATA_60X1C0;
break;
@@ -3762,7 +3826,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
n_hc = mv_get_hc_count(host->ports[0]->flags);
for (port = 0; port < host->n_ports; port++)
- hpriv->ops->read_preamp(hpriv, port, mmio);
+ if (hpriv->ops->read_preamp)
+ hpriv->ops->read_preamp(hpriv, port, mmio);
rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
if (rc)
--
Martin Michlmayr
http://www.cyrius.com/
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] sata_mv: use new sata phy register settings for new devices
2009-04-11 16:08 [PATCH] sata_mv: use new sata phy register settings for new devices Martin Michlmayr
@ 2009-04-11 22:02 ` Grant Grundler
2009-04-13 7:26 ` saeed bishara
0 siblings, 1 reply; 8+ messages in thread
From: Grant Grundler @ 2009-04-11 22:02 UTC (permalink / raw)
To: Saeed Bishara; +Cc: Mark Lord, linux-ide, Martin Michlmayr
On Sat, Apr 11, 2009 at 9:08 AM, Martin Michlmayr <tbm@cyrius.com> wrote:
> From: Saeed Bishara <saeed@marvell.com>
>
> Marvell's new SoC (65 nano) needs different modification for its SATA
> PHY registers.
>
> Tested-by: Martin Michlmayr <tbm@cyrius.com>
> Signed-off-by: Saeed Bishara <saeed@marvell.com>
> Signed-off-by: Martin Michlmayr <tbm@cyrius.com>
>
> ---
> This fixes the SATA problems I saw on the Kirkwood-based QNAP TS-219.
>
> diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
> index 37ae5dc..f19f2e3 100644
> --- a/drivers/ata/sata_mv.c
> +++ b/drivers/ata/sata_mv.c
> @@ -293,6 +293,10 @@ enum {
> FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
> FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
>
> + PHY_MODE9_GEN2 = 0x398,
> + PHY_MODE9_GEN1 = 0x39c,
> + PHYCFG_OFS = 0x3a0, /* only in 65n devices */
> +
> MV5_PHY_MODE = 0x74,
> MV5_LTMODE = 0x30,
> MV5_PHY_CTL = 0x0C,
> @@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
> static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
> void __iomem *mmio);
> static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
> +static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
> + void __iomem *mmio, unsigned int port);
> static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
> static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
> unsigned int port_no);
> @@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = {
> .reset_bus = mv_soc_reset_bus,
> };
>
> +static const struct mv_hw_ops mv_soc_65n_ops = {
> + .phy_errata = mv_soc_65n_phy_errata,
> + .enable_leds = mv_soc_enable_leds,
> + .reset_hc = mv_soc_reset_hc,
> + .reset_flash = mv_soc_reset_flash,
> + .reset_bus = mv_soc_reset_bus,
> +};
> +
> /*
> * Functions
> */
> @@ -3359,6 +3373,53 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
> return;
> }
>
> +static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
> + void __iomem *mmio, unsigned int port)
> +{
> + void __iomem *port_mmio = mv_port_base(mmio, port);
> + u32 reg;
> +
> + reg = readl(port_mmio + PHY_MODE3);
> + reg &= ~(0x3 << 27); /* bits 28:27 to 0x1 */
> + reg |= (0x1 << 27);
> + reg &= ~(0x3 << 29); /* bits 30:29 to 0x1 */
> + reg |= (0x1 << 29);
Saeed,
Any chance these magic numbers can be documented?
No objection to this patch and I would prefer a follow on
patch to document the bits if that's possible.
thanks,
grant
> + writel(reg, port_mmio + PHY_MODE3);
> +
> + reg = readl(port_mmio + PHY_MODE4);
> + reg &= ~0x1; /* bit 0 to 0x0, bit 16 must be set */
> + reg |= (0x1 << 16);
> + writel(reg, port_mmio + PHY_MODE4);
> +
> + reg = readl(port_mmio + PHY_MODE9_GEN2);
> + reg &= ~0xf; /* bits 3:0 to 0x8 */
> + reg |= 0x8;
> + reg &= ~(0x1 << 14); /* bit 14 to 0 */
> + writel(reg, port_mmio + PHY_MODE9_GEN2);
> +
> + reg = readl(port_mmio + PHY_MODE9_GEN1);
> + reg &= ~0xf; /* bits 3:0 to 0x8 */
> + reg |= 0x8;
> + reg &= ~(0x1 << 14); /* bit 14 to 0 */
> + writel(reg, port_mmio + PHY_MODE9_GEN1);
> +}
> +
> +/**
> + * soc_is_65 - check if the soc is 65 nano device
> + *
> + * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
> + * register, this register should contain non-zero value and it exists only
> + * in the 65 nano devices, when reading it from older devices we get 0.
> + */
> +static bool soc_is_65n(struct mv_host_priv *hpriv)
> +{
> + void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
> +
> + if (readl(port0_mmio + PHYCFG_OFS))
> + return true;
> + return false;
> +}
> +
> static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
> {
> u32 ifcfg = readl(port_mmio + SATA_IFCFG);
> @@ -3699,7 +3760,10 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
> }
> break;
> case chip_soc:
> - hpriv->ops = &mv_soc_ops;
> + if (soc_is_65n(hpriv))
> + hpriv->ops = &mv_soc_65n_ops;
> + else
> + hpriv->ops = &mv_soc_ops;
> hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
> MV_HP_ERRATA_60X1C0;
> break;
> @@ -3762,7 +3826,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
> n_hc = mv_get_hc_count(host->ports[0]->flags);
>
> for (port = 0; port < host->n_ports; port++)
> - hpriv->ops->read_preamp(hpriv, port, mmio);
> + if (hpriv->ops->read_preamp)
> + hpriv->ops->read_preamp(hpriv, port, mmio);
>
> rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
> if (rc)
>
> --
> Martin Michlmayr
> http://www.cyrius.com/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ide" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sata_mv: use new sata phy register settings for new devices
2009-04-11 22:02 ` Grant Grundler
@ 2009-04-13 7:26 ` saeed bishara
2009-04-13 7:34 ` Jeff Garzik
0 siblings, 1 reply; 8+ messages in thread
From: saeed bishara @ 2009-04-13 7:26 UTC (permalink / raw)
To: Grant Grundler; +Cc: Saeed Bishara, Mark Lord, linux-ide, Martin Michlmayr
> Any chance these magic numbers can be documented?
>
> No objection to this patch and I would prefer a follow on
> patch to document the bits if that's possible.
Grant,
those bits control analog/electrical settings of the sata phy
module, the functional spec uses acronyms to name it, and without much
documentation for it.
saeed
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sata_mv: use new sata phy register settings for new devices
2009-04-13 7:26 ` saeed bishara
@ 2009-04-13 7:34 ` Jeff Garzik
2009-04-22 10:44 ` saeed bishara
0 siblings, 1 reply; 8+ messages in thread
From: Jeff Garzik @ 2009-04-13 7:34 UTC (permalink / raw)
To: saeed bishara
Cc: Grant Grundler, Saeed Bishara, Mark Lord, linux-ide,
Martin Michlmayr
saeed bishara wrote:
>> Any chance these magic numbers can be documented?
>>
>> No objection to this patch and I would prefer a follow on
>> patch to document the bits if that's possible.
> Grant,
> those bits control analog/electrical settings of the sata phy
> module, the functional spec uses acronyms to name it, and without much
> documentation for it.
Named constants based on acronyms are preferable to numeric constants.
A little information and disambiguation is better than none at all.
Jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sata_mv: use new sata phy register settings for new devices
2009-04-13 7:34 ` Jeff Garzik
@ 2009-04-22 10:44 ` saeed bishara
2009-05-04 18:58 ` Martin Michlmayr
0 siblings, 1 reply; 8+ messages in thread
From: saeed bishara @ 2009-04-22 10:44 UTC (permalink / raw)
To: Jeff Garzik
Cc: Grant Grundler, Saeed Bishara, Mark Lord, linux-ide,
Martin Michlmayr
Here the patch with names constants:
To: Mark Lord <liml@rtr.ca>
Cc: Martin Michlmayr <tbm@cyrius.com>, linux-ide@vger.kernel.org
Subject: [PATCH] sata_mv: use new sata phy register settings for new devices
Marvell's new SoC (65 nano) needs different settings for its SATA
PHY registers.
Tested-by: Martin Michlmayr <tbm@cyrius.com>
Signed-off-by: Saeed Bishara <saeed@marvell.com>
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -293,6 +293,10 @@ enum {
FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
+ PHY_MODE9_GEN2 = 0x398,
+ PHY_MODE9_GEN1 = 0x39c,
+ PHYCFG_OFS = 0x3a0, /* only in 65n devices */
+
MV5_PHY_MODE = 0x74,
MV5_LTMODE = 0x30,
MV5_PHY_CTL = 0x0C,
@@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
@@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = {
.reset_bus = mv_soc_reset_bus,
};
+static const struct mv_hw_ops mv_soc_65n_ops = {
+ .phy_errata = mv_soc_65n_phy_errata,
+ .enable_leds = mv_soc_enable_leds,
+ .reset_hc = mv_soc_reset_hc,
+ .reset_flash = mv_soc_reset_flash,
+ .reset_bus = mv_soc_reset_bus,
+};
+
/*
* Functions
*/
@@ -3359,6 +3373,53 @@ static void mv_soc_reset_bus(struct ata_host
*host, void __iomem *mmio)
return;
}
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+ u32 reg;
+
+ reg = readl(port_mmio + 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, port_mmio + PHY_MODE3);
+
+ reg = readl(port_mmio + PHY_MODE4);
+ reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
+ reg |= (0x1 << 16);
+ writel(reg, port_mmio + PHY_MODE4);
+
+ reg = readl(port_mmio + 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, port_mmio + PHY_MODE9_GEN2);
+
+ reg = readl(port_mmio + 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, port_mmio + PHY_MODE9_GEN1);
+}
+
+/**
+ * soc_is_65 - check if the soc is 65 nano device
+ *
+ * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
+ * register, this register should contain non-zero value and it exists only
+ * in the 65 nano devices, when reading it from older devices we get 0.
+ */
+static bool soc_is_65n(struct mv_host_priv *hpriv)
+{
+ void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
+
+ if (readl(port0_mmio + PHYCFG_OFS))
+ return true;
+ return false;
+}
+
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
u32 ifcfg = readl(port_mmio + SATA_IFCFG);
@@ -3699,7 +3760,10 @@ static int mv_chip_id(struct ata_host *host,
unsigned int board_idx)
}
break;
case chip_soc:
- hpriv->ops = &mv_soc_ops;
+ if (soc_is_65n(hpriv))
+ hpriv->ops = &mv_soc_65n_ops;
+ else
+ hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
MV_HP_ERRATA_60X1C0;
break;
@@ -3762,7 +3826,8 @@ static int mv_init_host(struct ata_host *host,
unsigned int board_idx)
n_hc = mv_get_hc_count(host->ports[0]->flags);
for (port = 0; port < host->n_ports; port++)
- hpriv->ops->read_preamp(hpriv, port, mmio);
+ if (hpriv->ops->read_preamp)
+ hpriv->ops->read_preamp(hpriv, port, mmio);
rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
if (rc)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sata_mv: use new sata phy register settings for new devices
2009-04-22 10:44 ` saeed bishara
@ 2009-05-04 18:58 ` Martin Michlmayr
2009-05-04 23:43 ` Mark Lord
2009-05-11 18:34 ` Jeff Garzik
0 siblings, 2 replies; 8+ messages in thread
From: Martin Michlmayr @ 2009-05-04 18:58 UTC (permalink / raw)
To: Mark Lord; +Cc: Jeff Garzik, Grant Grundler, Saeed Bishara, linux-ide
Mark, can this patch go in now? It's needed to make SATA operational
on my Kirkwood-based QNAP TS-219 with a Maxtor drive.
Subject: [PATCH] sata_mv: use new sata phy register settings for new devices
From: Saeed Bishara <saeed@marvell.com>
Marvell's new SoC (65 nano) needs different settings for its SATA
PHY registers.
Tested-by: Martin Michlmayr <tbm@cyrius.com>
Signed-off-by: Saeed Bishara <saeed@marvell.com>
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -293,6 +293,10 @@ enum {
FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
+ PHY_MODE9_GEN2 = 0x398,
+ PHY_MODE9_GEN1 = 0x39c,
+ PHYCFG_OFS = 0x3a0, /* only in 65n devices */
+
MV5_PHY_MODE = 0x74,
MV5_LTMODE = 0x30,
MV5_PHY_CTL = 0x0C,
@@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
@@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = {
.reset_bus = mv_soc_reset_bus,
};
+static const struct mv_hw_ops mv_soc_65n_ops = {
+ .phy_errata = mv_soc_65n_phy_errata,
+ .enable_leds = mv_soc_enable_leds,
+ .reset_hc = mv_soc_reset_hc,
+ .reset_flash = mv_soc_reset_flash,
+ .reset_bus = mv_soc_reset_bus,
+};
+
/*
* Functions
*/
@@ -3397,6 +3411,53 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
return;
}
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+ u32 reg;
+
+ reg = readl(port_mmio + 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, port_mmio + PHY_MODE3);
+
+ reg = readl(port_mmio + PHY_MODE4);
+ reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
+ reg |= (0x1 << 16);
+ writel(reg, port_mmio + PHY_MODE4);
+
+ reg = readl(port_mmio + 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, port_mmio + PHY_MODE9_GEN2);
+
+ reg = readl(port_mmio + 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, port_mmio + PHY_MODE9_GEN1);
+}
+
+/**
+ * soc_is_65 - check if the soc is 65 nano device
+ *
+ * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
+ * register, this register should contain non-zero value and it exists only
+ * in the 65 nano devices, when reading it from older devices we get 0.
+ */
+static bool soc_is_65n(struct mv_host_priv *hpriv)
+{
+ void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
+
+ if (readl(port0_mmio + PHYCFG_OFS))
+ return true;
+ return false;
+}
+
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
u32 ifcfg = readl(port_mmio + SATA_IFCFG);
@@ -3737,7 +3798,10 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
}
break;
case chip_soc:
- hpriv->ops = &mv_soc_ops;
+ if (soc_is_65n(hpriv))
+ hpriv->ops = &mv_soc_65n_ops;
+ else
+ hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
MV_HP_ERRATA_60X1C0;
break;
@@ -3800,7 +3864,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
n_hc = mv_get_hc_count(host->ports[0]->flags);
for (port = 0; port < host->n_ports; port++)
- hpriv->ops->read_preamp(hpriv, port, mmio);
+ if (hpriv->ops->read_preamp)
+ hpriv->ops->read_preamp(hpriv, port, mmio);
rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
if (rc)
--
Martin Michlmayr
http://www.cyrius.com/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sata_mv: use new sata phy register settings for new devices
2009-05-04 18:58 ` Martin Michlmayr
@ 2009-05-04 23:43 ` Mark Lord
2009-05-11 18:34 ` Jeff Garzik
1 sibling, 0 replies; 8+ messages in thread
From: Mark Lord @ 2009-05-04 23:43 UTC (permalink / raw)
To: Martin Michlmayr; +Cc: Jeff Garzik, Grant Grundler, Saeed Bishara, linux-ide
Martin Michlmayr wrote:
> Mark, can this patch go in now? It's needed to make SATA operational
> on my Kirkwood-based QNAP TS-219 with a Maxtor drive.
..
No comment from me on this one. I don't know if this patch has been tested
on more than a single device type or not. Eg. does it break CF or ATAPI ?
It *looks* harmless on the non-SOC chips though,
so even if it's not perfect it shouldn't do much harm.
Jeff: pick it up if you feel comfortable with the submitter's track record.
Cheers
-ml
..
> Subject: [PATCH] sata_mv: use new sata phy register settings for new devices
> From: Saeed Bishara <saeed@marvell.com>
>
> Marvell's new SoC (65 nano) needs different settings for its SATA
> PHY registers.
>
> Tested-by: Martin Michlmayr <tbm@cyrius.com>
> Signed-off-by: Saeed Bishara <saeed@marvell.com>
>
> --- a/drivers/ata/sata_mv.c
> +++ b/drivers/ata/sata_mv.c
> @@ -293,6 +293,10 @@ enum {
> FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
> FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
>
> + PHY_MODE9_GEN2 = 0x398,
> + PHY_MODE9_GEN1 = 0x39c,
> + PHYCFG_OFS = 0x3a0, /* only in 65n devices */
> +
> MV5_PHY_MODE = 0x74,
> MV5_LTMODE = 0x30,
> MV5_PHY_CTL = 0x0C,
> @@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
> static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
> void __iomem *mmio);
> static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
> +static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
> + void __iomem *mmio, unsigned int port);
> static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
> static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
> unsigned int port_no);
> @@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = {
> .reset_bus = mv_soc_reset_bus,
> };
>
> +static const struct mv_hw_ops mv_soc_65n_ops = {
> + .phy_errata = mv_soc_65n_phy_errata,
> + .enable_leds = mv_soc_enable_leds,
> + .reset_hc = mv_soc_reset_hc,
> + .reset_flash = mv_soc_reset_flash,
> + .reset_bus = mv_soc_reset_bus,
> +};
> +
> /*
> * Functions
> */
> @@ -3397,6 +3411,53 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
> return;
> }
>
> +static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
> + void __iomem *mmio, unsigned int port)
> +{
> + void __iomem *port_mmio = mv_port_base(mmio, port);
> + u32 reg;
> +
> + reg = readl(port_mmio + 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, port_mmio + PHY_MODE3);
> +
> + reg = readl(port_mmio + PHY_MODE4);
> + reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
> + reg |= (0x1 << 16);
> + writel(reg, port_mmio + PHY_MODE4);
> +
> + reg = readl(port_mmio + 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, port_mmio + PHY_MODE9_GEN2);
> +
> + reg = readl(port_mmio + 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, port_mmio + PHY_MODE9_GEN1);
> +}
> +
> +/**
> + * soc_is_65 - check if the soc is 65 nano device
> + *
> + * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
> + * register, this register should contain non-zero value and it exists only
> + * in the 65 nano devices, when reading it from older devices we get 0.
> + */
> +static bool soc_is_65n(struct mv_host_priv *hpriv)
> +{
> + void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
> +
> + if (readl(port0_mmio + PHYCFG_OFS))
> + return true;
> + return false;
> +}
> +
> static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
> {
> u32 ifcfg = readl(port_mmio + SATA_IFCFG);
> @@ -3737,7 +3798,10 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
> }
> break;
> case chip_soc:
> - hpriv->ops = &mv_soc_ops;
> + if (soc_is_65n(hpriv))
> + hpriv->ops = &mv_soc_65n_ops;
> + else
> + hpriv->ops = &mv_soc_ops;
> hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
> MV_HP_ERRATA_60X1C0;
> break;
> @@ -3800,7 +3864,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
> n_hc = mv_get_hc_count(host->ports[0]->flags);
>
> for (port = 0; port < host->n_ports; port++)
> - hpriv->ops->read_preamp(hpriv, port, mmio);
> + if (hpriv->ops->read_preamp)
> + hpriv->ops->read_preamp(hpriv, port, mmio);
>
> rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
> if (rc)
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] sata_mv: use new sata phy register settings for new devices
2009-05-04 18:58 ` Martin Michlmayr
2009-05-04 23:43 ` Mark Lord
@ 2009-05-11 18:34 ` Jeff Garzik
1 sibling, 0 replies; 8+ messages in thread
From: Jeff Garzik @ 2009-05-11 18:34 UTC (permalink / raw)
To: Martin Michlmayr; +Cc: Mark Lord, Grant Grundler, Saeed Bishara, linux-ide
Martin Michlmayr wrote:
> Mark, can this patch go in now? It's needed to make SATA operational
> on my Kirkwood-based QNAP TS-219 with a Maxtor drive.
>
>
> Subject: [PATCH] sata_mv: use new sata phy register settings for new devices
> From: Saeed Bishara <saeed@marvell.com>
>
> Marvell's new SoC (65 nano) needs different settings for its SATA
> PHY registers.
>
> Tested-by: Martin Michlmayr <tbm@cyrius.com>
> Signed-off-by: Saeed Bishara <saeed@marvell.com>
applied -- though I still await answers to maintainer Mark Lord's
questions: was this tested with ATAPI and other features?
(rhetorical question... if not... test it!)
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-05-11 18:34 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-11 16:08 [PATCH] sata_mv: use new sata phy register settings for new devices Martin Michlmayr
2009-04-11 22:02 ` Grant Grundler
2009-04-13 7:26 ` saeed bishara
2009-04-13 7:34 ` Jeff Garzik
2009-04-22 10:44 ` saeed bishara
2009-05-04 18:58 ` Martin Michlmayr
2009-05-04 23:43 ` Mark Lord
2009-05-11 18:34 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).