sata_mv: move SOC_FLAG to hpriv
PATCH 1/3 sata_mv: move SOC_FLAG to hpriv
Convert the System-on-Chip flag from a host flag to an hpriv flag, for better consistency with other chip-rev flags, and for easier use in errata fixes etc.
Also change the related "HAS_PCI()" into "!IS_SOC()" for better consistency of naming/use (everything else SOC-related already uses "SOC").
There are no functionality changes in this patch.
---
This is the first of three patches aimed at fixing/completing various PHY_MODEx register errata workarounds.
drivers/ata/sata_mv.c +0 -0
@@ -122,8 +122,6 @@
/* Host Flags */ MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
- /* SoC integrated controllers, no PCI interface */
- MV_FLAG_SOC = (1 << 28),
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
@@ -362,6 +360,7 @@
MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
+ MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */
/* Port private flags (pp_flags) */ MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
@@ -374,7 +373,7 @@
#define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) #define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE) -#define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) +#define IS_SOC(hpriv) ((hpriv)->hp_flags & MV_HP_FLAG_SOC)
#define WINDOW_CTRL(i) (0x20030 + ((i) << 4))
#define WINDOW_BASE(i) (0x20034 + ((i) << 4))
@@ -652,7 +651,7 @@
.port_ops = &mv_iie_ops,
},
{ /* chip_soc */
- .flags = MV_GENIIE_FLAGS | MV_FLAG_SOC,
+ .flags = MV_GENIIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,@@ -1254,7 +1253,7 @@
cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */
cfg |= (1 << 22); /* enab 4-entry host queue cache */
- if (HAS_PCI(ap->host))
+ if (!IS_SOC(hpriv))
cfg |= (1 << 18); /* enab early completion */
if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
@@ -2225,7 +2224,7 @@
* a bogus register value which can indicate HW removal or PCI fault.
*/
if (pending_irqs && main_irq_cause != 0xffffffffU) {
- if (unlikely((pending_irqs & PCI_ERR) && HAS_PCI(host)))
+ if (unlikely((pending_irqs & PCI_ERR) && !IS_SOC(hpriv)))
handled = mv_pci_error(host, hpriv->base);
else
handled = mv_host_intr(host, pending_irqs);
@@ -2876,7 +2875,7 @@
void __iomem *mmio = hpriv->base;
u32 reg;- if (!HAS_PCI(host) || !IS_PCIE(hpriv))
+ if (IS_SOC(hpriv) || !IS_PCIE(hpriv))
return 0; /* not PCI-X capable */ reg = readl(mmio + MV_PCI_MODE_OFS); if ((reg & MV_PCI_MODE_MASK) == 0) @@ -3018,7 +3017,7 @@ break; case chip_soc: hpriv->ops = &mv_soc_ops; - hp_flags |= MV_HP_ERRATA_60X1C0; + hp_flags |= MV_HP_FLAG_SOC | MV_HP_ERRATA_60X1C0; break; default: @@ -3062,12 +3061,12 @@ if (rc) goto done;
- if (HAS_PCI(host)) {
- hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS;
- hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
- } else {
+ if (IS_SOC(hpriv)) {
hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE_OFS;
hpriv->main_irq_mask_addr = mmio + SOC_HC_MAIN_IRQ_MASK_OFS;
+ } else {
+ hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS;
+ hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
}
/* global interrupt mask: 0 == mask everything */
@@ -3093,7 +3092,7 @@
mv_port_init(&ap->ioaddr, port_mmio);#ifdef CONFIG_PCI
- if (HAS_PCI(host)) {
+ if (!IS_SOC(hpriv)) {
unsigned int offset = port_mmio - mmio;
ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
@@ -3113,7 +3112,7 @@
writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
}- if (HAS_PCI(host)) {
+ if (!IS_SOC(hpriv)) {
/* Clear any currently outstanding host interrupt conditions */
writelfl(0, mmio + hpriv->irq_cause_ofs);PATCH 2/3 sata_mv: PHY_MODEx errata fixes
Fix and update the errata handling for the PHY_MODEx registers. This improves receiver noise tolerance, among other things.
drivers/ata/sata_mv.c +0 -0
@@ -2546,7 +2546,7 @@
hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); int fix_phy_mode4 = hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0);
- u32 m2, tmp;
+ u32 m2, m3;
if (fix_phy_mode2) {
m2 = readl(port_mmio + PHY_MODE2);
@@ -2563,27 +2563,27 @@
udelay(200);
}- /* who knows what this magic does */
- tmp = readl(port_mmio + PHY_MODE3);
- tmp &= ~0x7F800000;
- tmp |= 0x2A800000;
- writel(tmp, port_mmio + PHY_MODE3);
+ /*
+ * Gen-II/IIe PHY_MODE3 errata RM#2:
+ * Achieves better receiver noise performance than the h/w default:
+ */
+ m3 = readl(port_mmio + PHY_MODE3);
+ m3 = (m3 & 0x1f) | (0x5555601 << 5);
+ writel(m3, port_mmio + PHY_MODE3);
if (fix_phy_mode4) {
u32 m4;
m4 = readl(port_mmio + PHY_MODE4);- if (hp_flags & MV_HP_ERRATA_60X1B2)
- tmp = readl(port_mmio + PHY_MODE3);
-
/* workaround for errata FEr SATA#10 (part 1) */ m4 = (m4 & ~(1 << 1)) | (1 << 0);
- writel(m4, port_mmio + PHY_MODE4);
+ /* enforce bit restrictions on GenIIe devices */
+ if (IS_GEN_IIE(hpriv))
+ m4 = (m4 & ~0x5DE3FFFC) | (1 << 2);
- if (hp_flags & MV_HP_ERRATA_60X1B2)
- writel(tmp, port_mmio + PHY_MODE3);
+ writel(m4, port_mmio + PHY_MODE4); } /* Revert values of pre-emphasis and signal amps to the saved ones */
PATCH 3/3 sata_mv: nuke unreleased GenIIe revisions
The only public release of the 6042/7042 chips was/is revision "B0". Remove code that attempted to deal with earlier, non-released revs. This matches the logic of the current Marvell "proprietary" driver.
Also, bump up the sata_mv version number, to reflect this batch of erratas.
---
This update was specifically requested by Marvell.
drivers/ata/sata_mv.c +0 -0
@@ -72,7 +72,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.21"
+#define DRV_VERSION "1.22"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -354,7 +354,6 @@
MV_HP_ERRATA_50XXB2 = (1 << 2),
MV_HP_ERRATA_60X1B2 = (1 << 3),
MV_HP_ERRATA_60X1C0 = (1 << 4),
- MV_HP_ERRATA_XX42A0 = (1 << 5),
MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */
MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */
MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */
@@ -811,12 +810,7 @@
writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index,
port_mmio + EDMA_REQ_Q_IN_PTR_OFS);-
- if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
- writelfl((pp->crqb_dma & 0xffffffff) | index,
- port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
- else
- writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+ writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
/* * initialize response queue
@@ -826,13 +820,7 @@
WARN_ON(pp->crpb_dma & 0xff); writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
-
- if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
- writelfl((pp->crpb_dma & 0xffffffff) | index,
- port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
- else
- writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
-
+ writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index,
port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
}
@@ -3002,10 +2990,7 @@
hp_flags |= MV_HP_CUT_THROUGH;
switch (pdev->revision) {- case 0x0:
- hp_flags |= MV_HP_ERRATA_XX42A0;
- break;
- case 0x1:
+ case 0x2: /* Rev.B0: the first/only public release */
hp_flags |= MV_HP_ERRATA_60X1C0; break; default:
PATCH 4/4 sata_mv: workaround for 60x1 errata sata13
The "B2" variant of the 6041/6081 (genII) chips requires that the PHY_MODE3 register be rewritten after any write to PHY_MODE4.
This fixes a regression introduced by an earlier patch.
drivers/ata/sata_mv.c +0 -0
@@ -72,7 +72,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.22"
+#define DRV_VERSION "1.23"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -2557,7 +2557,6 @@
*/
m3 = readl(port_mmio + PHY_MODE3);
m3 = (m3 & 0x1f) | (0x5555601 << 5);- writel(m3, port_mmio + PHY_MODE3);
if (fix_phy_mode4) {
u32 m4;@@ -2573,6 +2572,12 @@
writel(m4, port_mmio + PHY_MODE4); }
+ /*
+ * Workaround for 60x1-B2 errata SATA#13:
+ * Any write to PHY_MODE4 (above) may corrupt PHY_MODE3,
+ * so we must always rewrite PHY_MODE3 after PHY_MODE4.
+ */
+ writel(m3, port_mmio + PHY_MODE3);
/* Revert values of pre-emphasis and signal amps to the saved ones */ m2 = readl(port_mmio + PHY_MODE2);
PATCH 5/5 sata_mv: implement SoC guideline SATA_S11
The 5182 System-On-Chip (SOC) variant wants certain lower bits to be cleared on any write to the PHY_MODE3 register.
If/when support is added for other SOC variants, we'll need some way to uniquely identify the 5182, and not perform this workaround for the others.
But for now, it is the only SOC variant we support here.
---
Another extension to the patch series.
This concludes the errata fixes I know of
for the various PHY_MODE registers.
drivers/ata/sata_mv.c +0 -0
@@ -72,7 +72,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.23"
+#define DRV_VERSION "1.24"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -2558,6 +2558,10 @@
m3 = readl(port_mmio + PHY_MODE3);
m3 = (m3 & 0x1f) | (0x5555601 << 5);+ /* Guideline 88F5182 (GL# SATA-S11) */
+ if (IS_SOC(hpriv))
+ m3 &= ~0x1c;
+
if (fix_phy_mode4) {
u32 m4;Re: [PATCH 02/03] sata_mv: PHY_MODEx errata fixes
In reply to Mark LordQuoted 38 lines · Mark Lord
Fix and update the errata handling for the
PHY_MODExregisters. This improves receiver noise tolerance, among other things.Signed-off-by Mark Lord <[email protected]>drivers/ata/sata_mv.c 2008-05-27 12:01:25.000000000 -0400 renamed from drivers/ata/sata_mv.c 2008-05-27 11:53:01.000000000 -0400 +8
-6@@ -2546,7 +2546,7 @@ hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); int fix_phy_mode4 = hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); - u32 m2, tmp; + u32 m2, m3; if (fix_phy_mode2) { m2 = readl(port_mmio + PHY_MODE2);@@ -2563,27 +2563,27 @@ udelay(200); } - /* who knows what this magic does */ - tmp = readl(port_mmio + PHY_MODE3); - tmp &= ~0x7F800000; - tmp |= 0x2A800000; - writel(tmp, port_mmio + PHY_MODE3); + /* + * Gen-II/IIe PHY_MODE3 errata RM#2: + * Achieves better receiver noise performance than the h/w default: + */ + m3 = readl(port_mmio + PHY_MODE3); + m3 = (m3 & 0x1f) | (0x5555601 << 5); + writel(m3, port_mmio + PHY_MODE3); if (fix_phy_mode4) { u32 m4; m4 = readl(port_mmio + PHY_MODE4);
drivers/ata/sata_mv.c 2008-05-27 12:01:25.000000000 -0400 line 2584
Quoted 10 lines
drivers/ata/sata_mv.c 2008-05-27 12:01:25.000000000 -0400 renamed from drivers/ata/sata_mv.c 2008-05-27 11:53:01.000000000 -0400 +3
-4- if (hp_flags & MV_HP_ERRATA_60X1B2) - tmp = readl(port_mmio + PHY_MODE3); - /* workaround for errata FEr SATA#10 (part 1) */ m4 = (m4 & ~(1 << 1)) | (1 << 0); - writel(m4, port_mmio + PHY_MODE4); + /* enforce bit restrictions on GenIIe devices */ + if (IS_GEN_IIE(hpriv)) + m4 = (m4 & ~0x5DE3FFFC) | (1 << 2);
can this magic number become a named constant? do we know the bits, can they be broken out and enumerated?
Re: [PATCH 02/03] sata_mv: PHY_MODEx errata fixes
Quoted 3 lines · Jeff Garzik
Quoted 2 lines · Mark Lord
Fix and update the errata handling for the
PHY_MODExregisters. This improves receiver noise tolerance, among other things.
..
Quoted 5 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+ /* enforce bit restrictions on GenIIe devices */ + if (IS_GEN_IIE(hpriv)) + m4 = (m4 & ~0x5DE3FFFC) | (1 << 2);can this magic number become a named constant? do we know the bits, can they be broken out and enumerated?
..
Heh..
I simply copied it over from the Marvell driver, and the folks at Marvell ack'd it without responding to my request for a pointer to an errata doc somewhere.
But as it turns out, I do have something here that describes it. The code seems to be just masking away all of the reserved bits, which need to be written as zeros on every access.
Except for reserved bit2, which has to be written as 1 on every write.
I'll break that up into a pair of suitable constants. So it will look something like this, after passing it by Marvell:
if (IS_GEN_IIE(hpriv)) m4 = (m4 & ~PHY_MODE4_RSVD_ZEROS) | PHY_MODE4_RSVD_ONES;
How's that look to you?
Cheers
PATCH 1/1 sata_mv: PHY_MODE4 cleanups
In reply to Jeff GarzikThe handling for PHY_MODE4 was originally just cloned from the Marvell proprietary driver (with their blessing). But we can do better than that.
Tidy things up with some judicious mask definitions, to improve maintainability.
---
As requested..
drivers/ata/sata_mv.c +0 -0
@@ -224,6 +224,11 @@
PHY_MODE3 = 0x310, PHY_MODE4 = 0x314,
+ PHY_MODE4_CFG_MASK = 0x00000003, /* phy internal config field */
+ PHY_MODE4_CFG_VALUE = 0x00000001, /* phy internal config field */
+ PHY_MODE4_RSVD_ZEROS = 0x5de3fffa, /* Gen2e always write zeros */
+ PHY_MODE4_RSVD_ONES = 0x00000005, /* Gen2e always write ones */
+
PHY_MODE2 = 0x330,
SATA_IFCTL_OFS = 0x344,
SATA_TESTCTL_OFS = 0x348,
@@ -2563,17 +2568,16 @@
m3 &= ~0x1c;
if (fix_phy_mode4) {- u32 m4;
-
- m4 = readl(port_mmio + PHY_MODE4);
-
- /* workaround for errata FEr SATA#10 (part 1) */
- m4 = (m4 & ~(1 << 1)) | (1 << 0);
-
- /* enforce bit restrictions on GenIIe devices */
+ u32 m4 = readl(port_mmio + PHY_MODE4);
+ /*
+ * Enforce reserved-bit restrictions on GenIIe devices only.
+ * For earlier chipsets, force only the internal config field
+ * (workaround for errata FEr SATA#10 part 1).
+ */
if (IS_GEN_IIE(hpriv))
- m4 = (m4 & ~0x5DE3FFFC) | (1 << 2);
-
+ m4 = (m4 & ~PHY_MODE4_RSVD_ZEROS) | PHY_MODE4_RSVD_ONES;
+ else
+ m4 = (m4 & ~PHY_MODE4_CFG_MASK) | PHY_MODE4_CFG_VALUE; writel(m4, port_mmio + PHY_MODE4); } /*
Jeff Garzik
AppliedRe: [PATCH 01/01] sata_mv: PHY_MODE4 cleanups
Quoted 40 lines · Mark Lord
The handling for
PHY_MODE4was originally just cloned from the Marvell proprietary driver (with their blessing). But we can do better than that.Tidy things up with some judicious mask definitions, to improve maintainability.
Signed-off-by Mark Lord <[email protected]>---
As requested..
drivers/ata/sata_mv.c 2008-05-30 19:36:52.000000000 -0400 renamed from drivers/ata/sata_mv.c 2008-05-28 12:20:05.000000000 -0400 +2
-0@@ -224,6 +224,11 @@ PHY_MODE3 = 0x310, PHY_MODE4 = 0x314, + PHY_MODE4_CFG_MASK = 0x00000003, /* phy internal config field */ + PHY_MODE4_CFG_VALUE = 0x00000001, /* phy internal configfield */
+PHY_MODE4_RSVD_ZEROS=0x5de3fffa, /* Gen2e always write
zeros */drivers/ata/sata_mv.c 2008-05-30 19:36:52.000000000 -0400 renamed from drivers/ata/sata_mv.c 2008-05-28 12:20:05.000000000 -0400 +3
-8+ PHY_MODE4_RSVD_ONES = 0x00000005, /* Gen2e always write ones */ + PHY_MODE2 = 0x330, SATA_IFCTL_OFS = 0x344, SATA_TESTCTL_OFS = 0x348,@@ -2563,17 +2568,16 @@ m3 &= ~0x1c; if (fix_phy_mode4) { - u32 m4; - - m4 = readl(port_mmio + PHY_MODE4); - - /* workaround for errata FEr SATA#10 (part 1) */ - m4 = (m4 & ~(1 << 1)) | (1 << 0); - - /* enforce bit restrictions on GenIIe devices */ + u32 m4 = readl(port_mmio + PHY_MODE4);
drivers/ata/sata_mv.c 2008-05-30 19:36:52.000000000 -0400 line 2579
Quoted 10 lines
drivers/ata/sata_mv.c 2008-05-30 19:36:52.000000000 -0400 renamed from drivers/ata/sata_mv.c 2008-05-28 12:20:05.000000000 -0400 +7
-2+ /* + * Enforce reserved-bit restrictions on GenIIe devices only. + * For earlier chipsets, force only the internal config field + * (workaround for errata FEr SATA#10 part 1). + */ if (IS_GEN_IIE(hpriv)) - m4 = (m4 & ~0x5DE3FFFC) | (1 << 2); - + m4 = (m4 & ~PHY_MODE4_RSVD_ZEROS) | PHY_MODE4_RSVD_ONES; + else
applied, thanks
Quoted 7 lines · Mark Lord
Convert the System-on-Chip flag from a host flag to an hpriv flag, for better consistency with other chip-rev flags, and for easier use in errata fixes etc.
Also change the related "
HAS_PCI()" into "!IS_SOC()" for better consistency of naming/use (everything else SOC-related already uses "SOC").
Quoted 7 lines
There are no functionality changes in this patch.
Signed-off-by Mark Lord <[email protected]>---
This is the first of three patches aimed at fixing/completing variousPHY_MODExregister errata workarounds.
applied 1-5