aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhangfei Gao <zhangfei.gao@linaro.org>2014-06-20 10:00:51 +0800
committerZhangfei Gao <zhangfei.gao@linaro.org>2014-06-20 11:09:48 +0800
commite1f104de2184f90e9f8718bd876451b1eac711c2 (patch)
treea4ffd12b2fa870fb645955c5474964e0a4b86055
parente16a391fa6b4dc68de80e60ea592fcc06075b850 (diff)
debugphy
-rw-r--r--arch/arm/boot/dts/hix5hd2-dkb.dts3
-rw-r--r--arch/arm/boot/dts/hix5hd2.dtsi2
-rw-r--r--drivers/phy/phy-hix5hd2-sata.c125
3 files changed, 61 insertions, 69 deletions
diff --git a/arch/arm/boot/dts/hix5hd2-dkb.dts b/arch/arm/boot/dts/hix5hd2-dkb.dts
index cf187846e57e..5c65392c529b 100644
--- a/arch/arm/boot/dts/hix5hd2-dkb.dts
+++ b/arch/arm/boot/dts/hix5hd2-dkb.dts
@@ -85,9 +85,8 @@
sata_phy:phy@f9900000 {
compatible = "hisilicon,hix5hd2-sata-phy";
reg = <0xf9900000 0x10000>;
- hisilicon,peri-syscon = <&peri_ctrl>;
+ hisilicon,peripheral-syscon = <&peripheral_ctrl>;
hisilicon,power-reg = <0x8 10>;
- hisilicon,reg-init = <0x148 0 32 0x345cb8>,<0x14c 0 32 0x20545>;
#phy-cells = <0>;
};
diff --git a/arch/arm/boot/dts/hix5hd2.dtsi b/arch/arm/boot/dts/hix5hd2.dtsi
index 619ed9f7d6fd..7b63be434768 100644
--- a/arch/arm/boot/dts/hix5hd2.dtsi
+++ b/arch/arm/boot/dts/hix5hd2.dtsi
@@ -202,7 +202,7 @@
reboot_reg = <0x4>;
};
- peri_ctrl:syscon@f8a20000 {
+ peripheral_ctrl:syscon@f8a20000 {
compatible = "syscon";
reg = <0xf8a20000 0x1000>;
};
diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/phy-hix5hd2-sata.c
index 107804b47ea0..4844bb7b2412 100644
--- a/drivers/phy/phy-hix5hd2-sata.c
+++ b/drivers/phy/phy-hix5hd2-sata.c
@@ -18,7 +18,7 @@
#define SATA_PHY0_CTLL 0xa0
#define MPLL_MULTIPLIER_SHIFT 1
-#define MPLL_MULTIPLIER_WIDTH 7
+#define MPLL_MULTIPLIER_MASK 0xfe
#define MPLL_MULTIPLIER_50M 0x3c
#define MPLL_MULTIPLIER_100M 0x1e
#define PHY_RESET BIT(0)
@@ -27,14 +27,28 @@
#define REF_USE_PAD BIT(23)
#define SATA_PORT_PHYCTL 0x174
+#define SPEED_MODE_MASK 0x6f0000
#define HALF_RATE_SHIFT 16
-#define HALF_RATE_WIDTH 2
#define PHY_CONFIG_SHIFT 18
-#define PHY_CONFIG_WIDTH 2
#define GEN2_EN_SHIFT 21
-#define GEN2_EN_WIDTH 2
#define SPEED_CTRL BIT(20)
+#define SATA_PORT_PHYCTL1 0x148
+#define AMPLITUDE_GEN3 0x68
+#define AMPLITUDE_GEN3_SHIFT 15
+#define AMPLITUDE_GEN2 0x56
+#define AMPLITUDE_GEN2_SHIFT 8
+#define AMPLITUDE_GEN1 0x56
+#define AMPLITUDE_GEN1_SHIFT 1
+
+#define SATA_PORT_PHYCTL2 0x14c
+#define PREEMPH_GEN3 0x20
+#define PREEMPH_GEN3_SHIFT 12
+#define PREEMPH_GEN2 0x15
+#define PREEMPH_GEN2_SHIFT 6
+#define PREEMPH_GEN1 0x5
+#define PREEMPH_GEN1_SHIFT 0
+
struct hix5hd2_priv {
void __iomem *base;
struct regmap *peri_ctrl;
@@ -43,39 +57,15 @@ struct hix5hd2_priv {
enum phy_speed_mode {
SPEED_MODE_GEN1 = 0,
- SPEED_MODE_GEN2 = 1,
- SPEED_MODE_GEN3 = 2,
+ SPEED_MODE_GEN2 = 1,
+ SPEED_MODE_GEN3 = 2,
};
-static void hix5hd2_sata_phy_write(void __iomem *addr, int shift,
- int width, int value)
-{
- int reg, mask;
-
- mask = BIT(width) - 1;
- reg = readl_relaxed(addr);
- reg &= ~(mask << shift);
- reg |= (value & mask) << shift;
- writel_relaxed(reg, addr);
-}
-
-static void hix5hd2_sata_phy_setspeed(struct hix5hd2_priv *priv,
- enum phy_speed_mode mode)
-{
- hix5hd2_sata_phy_write(priv->base + SATA_PORT_PHYCTL, HALF_RATE_SHIFT,
- HALF_RATE_WIDTH, mode);
- hix5hd2_sata_phy_write(priv->base + SATA_PORT_PHYCTL, PHY_CONFIG_SHIFT,
- PHY_CONFIG_WIDTH, mode);
- hix5hd2_sata_phy_write(priv->base + SATA_PORT_PHYCTL, GEN2_EN_SHIFT,
- GEN2_EN_WIDTH, mode);
-}
-
static int hix5hd2_sata_phy_init(struct phy *phy)
{
struct hix5hd2_priv *priv = phy_get_drvdata(phy);
- u32 offset, shift, width, value, data[2];
- const __be32 *paddr;
- int i, lenp, ret;
+ u32 val, data[2];
+ int ret;
if (priv->peri_ctrl) {
ret = of_property_read_u32_array(phy->dev.of_node,
@@ -89,42 +79,45 @@ static int hix5hd2_sata_phy_init(struct phy *phy)
}
/* reset phy */
- hix5hd2_sata_phy_write(priv->base + SATA_PHY0_CTLL,
- MPLL_MULTIPLIER_SHIFT, MPLL_MULTIPLIER_WIDTH,
- MPLL_MULTIPLIER_50M);
- value = readl_relaxed(priv->base + SATA_PHY0_CTLL);
- value &= ~(REF_USE_PAD);
- value |= (REF_SSP_EN | PHY_RESET);
- writel_relaxed(value, priv->base + SATA_PHY0_CTLL);
+ val = readl_relaxed(priv->base + SATA_PHY0_CTLL);
+ val &= ~(MPLL_MULTIPLIER_MASK | REF_USE_PAD);
+ val |= MPLL_MULTIPLIER_50M << MPLL_MULTIPLIER_SHIFT |
+ REF_SSP_EN | PHY_RESET;
+ writel_relaxed(val, priv->base + SATA_PHY0_CTLL);
msleep(20);
- value &= ~(PHY_RESET);
- writel_relaxed(value, priv->base + SATA_PHY0_CTLL);
-
- paddr = of_get_property(phy->dev.of_node, "hisilicon,reg-init", &lenp);
- if (!paddr || lenp < 4 * sizeof(*paddr))
- return 0;
-
- lenp /= sizeof(*paddr);
- for (i = 0; i < lenp - 3; i += 4) {
- offset = be32_to_cpup(paddr + i);
- shift = be32_to_cpup(paddr + i + 1);
- width = be32_to_cpup(paddr + i + 2);
- value = be32_to_cpup(paddr + i + 3);
- hix5hd2_sata_phy_write(priv->base + offset,
- shift, width, value);
- }
+ val &= ~(PHY_RESET);
+ writel_relaxed(val, priv->base + SATA_PHY0_CTLL);
+
+ val = AMPLITUDE_GEN3 << AMPLITUDE_GEN3_SHIFT |
+ AMPLITUDE_GEN2 << AMPLITUDE_GEN2_SHIFT |
+ AMPLITUDE_GEN1 << AMPLITUDE_GEN1_SHIFT;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL1);
+
+ val = PREEMPH_GEN3 << PREEMPH_GEN3_SHIFT |
+ PREEMPH_GEN2 << PREEMPH_GEN2_SHIFT |
+ PREEMPH_GEN1 << PREEMPH_GEN1_SHIFT;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL2);
+
+ /* ensure PHYCTRL setting takes effect */
+ val = readl_relaxed(priv->base + SATA_PORT_PHYCTL);
+ val &= ~(SPEED_MODE_MASK);
+ val |= SPEED_MODE_GEN1 << HALF_RATE_SHIFT |
+ SPEED_MODE_GEN1 << PHY_CONFIG_SHIFT |
+ SPEED_MODE_GEN1 << GEN2_EN_SHIFT | SPEED_CTRL;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
- /* ensure reg-init takes effect */
- value = readl_relaxed(priv->base + SATA_PORT_PHYCTL);
- value |= SPEED_CTRL;
- writel_relaxed(value, priv->base + SATA_PORT_PHYCTL);
- hix5hd2_sata_phy_setspeed(priv, SPEED_MODE_GEN1);
msleep(20);
- hix5hd2_sata_phy_setspeed(priv, SPEED_MODE_GEN3);
- value = readl_relaxed(priv->base + SATA_PORT_PHYCTL);
- value &= ~(SPEED_CTRL);
- writel_relaxed(value, priv->base + SATA_PORT_PHYCTL);
- hix5hd2_sata_phy_setspeed(priv, SPEED_MODE_GEN2);
+ val &= ~(SPEED_MODE_MASK);
+ val |= SPEED_MODE_GEN3 << HALF_RATE_SHIFT |
+ SPEED_MODE_GEN3 << PHY_CONFIG_SHIFT |
+ SPEED_MODE_GEN3 << GEN2_EN_SHIFT | SPEED_CTRL;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
+
+ val &= ~(SPEED_MODE_MASK | SPEED_CTRL);
+ val |= SPEED_MODE_GEN2 << HALF_RATE_SHIFT |
+ SPEED_MODE_GEN2 << PHY_CONFIG_SHIFT |
+ SPEED_MODE_GEN2 << GEN2_EN_SHIFT;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
return 0;
}
@@ -151,7 +144,7 @@ static int hix5hd2_sata_phy_probe(struct platform_device *pdev)
return -ENOMEM;
priv->peri_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
- "hisilicon,peri-syscon");
+ "hisilicon,peripheral-syscon");
if (IS_ERR(priv->peri_ctrl))
priv->peri_ctrl = NULL;