aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
authorMartin Michlmayr <tbm@cyrius.com>2009-05-04 14:58:50 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-05-11 14:29:41 -0400
commit29b7e43c310bdc20d240c7674d9073f6c1c12a3f (patch)
tree94272c2eb5e38b3bf103de1042193a67745ac640 /drivers/ata/sata_mv.c
parent842faa6c1a1d6faddf3377948e5cf214812c6c90 (diff)
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> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r--drivers/ata/sata_mv.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 870dcfd82357..23714aefb825 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -293,6 +293,10 @@ enum {
293 FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */ 293 FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
294 FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */ 294 FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
295 295
296 PHY_MODE9_GEN2 = 0x398,
297 PHY_MODE9_GEN1 = 0x39c,
298 PHYCFG_OFS = 0x3a0, /* only in 65n devices */
299
296 MV5_PHY_MODE = 0x74, 300 MV5_PHY_MODE = 0x74,
297 MV5_LTMODE = 0x30, 301 MV5_LTMODE = 0x30,
298 MV5_PHY_CTL = 0x0C, 302 MV5_PHY_CTL = 0x0C,
@@ -609,6 +613,8 @@ static int mv_soc_reset_hc(struct mv_host_priv *hpriv,
609static void mv_soc_reset_flash(struct mv_host_priv *hpriv, 613static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
610 void __iomem *mmio); 614 void __iomem *mmio);
611static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio); 615static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
616static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
617 void __iomem *mmio, unsigned int port);
612static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio); 618static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
613static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, 619static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
614 unsigned int port_no); 620 unsigned int port_no);
@@ -807,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops = {
807 .reset_bus = mv_soc_reset_bus, 813 .reset_bus = mv_soc_reset_bus,
808}; 814};
809 815
816static const struct mv_hw_ops mv_soc_65n_ops = {
817 .phy_errata = mv_soc_65n_phy_errata,
818 .enable_leds = mv_soc_enable_leds,
819 .reset_hc = mv_soc_reset_hc,
820 .reset_flash = mv_soc_reset_flash,
821 .reset_bus = mv_soc_reset_bus,
822};
823
810/* 824/*
811 * Functions 825 * Functions
812 */ 826 */
@@ -3397,6 +3411,53 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
3397 return; 3411 return;
3398} 3412}
3399 3413
3414static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
3415 void __iomem *mmio, unsigned int port)
3416{
3417 void __iomem *port_mmio = mv_port_base(mmio, port);
3418 u32 reg;
3419
3420 reg = readl(port_mmio + PHY_MODE3);
3421 reg &= ~(0x3 << 27); /* SELMUPF (bits 28:27) to 1 */
3422 reg |= (0x1 << 27);
3423 reg &= ~(0x3 << 29); /* SELMUPI (bits 30:29) to 1 */
3424 reg |= (0x1 << 29);
3425 writel(reg, port_mmio + PHY_MODE3);
3426
3427 reg = readl(port_mmio + PHY_MODE4);
3428 reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
3429 reg |= (0x1 << 16);
3430 writel(reg, port_mmio + PHY_MODE4);
3431
3432 reg = readl(port_mmio + PHY_MODE9_GEN2);
3433 reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
3434 reg |= 0x8;
3435 reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
3436 writel(reg, port_mmio + PHY_MODE9_GEN2);
3437
3438 reg = readl(port_mmio + PHY_MODE9_GEN1);
3439 reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
3440 reg |= 0x8;
3441 reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
3442 writel(reg, port_mmio + PHY_MODE9_GEN1);
3443}
3444
3445/**
3446 * soc_is_65 - check if the soc is 65 nano device
3447 *
3448 * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
3449 * register, this register should contain non-zero value and it exists only
3450 * in the 65 nano devices, when reading it from older devices we get 0.
3451 */
3452static bool soc_is_65n(struct mv_host_priv *hpriv)
3453{
3454 void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
3455
3456 if (readl(port0_mmio + PHYCFG_OFS))
3457 return true;
3458 return false;
3459}
3460
3400static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i) 3461static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
3401{ 3462{
3402 u32 ifcfg = readl(port_mmio + SATA_IFCFG); 3463 u32 ifcfg = readl(port_mmio + SATA_IFCFG);
@@ -3737,7 +3798,10 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
3737 } 3798 }
3738 break; 3799 break;
3739 case chip_soc: 3800 case chip_soc:
3740 hpriv->ops = &mv_soc_ops; 3801 if (soc_is_65n(hpriv))
3802 hpriv->ops = &mv_soc_65n_ops;
3803 else
3804 hpriv->ops = &mv_soc_ops;
3741 hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE | 3805 hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
3742 MV_HP_ERRATA_60X1C0; 3806 MV_HP_ERRATA_60X1C0;
3743 break; 3807 break;
@@ -3800,7 +3864,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
3800 n_hc = mv_get_hc_count(host->ports[0]->flags); 3864 n_hc = mv_get_hc_count(host->ports[0]->flags);
3801 3865
3802 for (port = 0; port < host->n_ports; port++) 3866 for (port = 0; port < host->n_ports; port++)
3803 hpriv->ops->read_preamp(hpriv, port, mmio); 3867 if (hpriv->ops->read_preamp)
3868 hpriv->ops->read_preamp(hpriv, port, mmio);
3804 3869
3805 rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); 3870 rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
3806 if (rc) 3871 if (rc)