From 19977502bd62afa177e86f8bdc03d55f76508ee4 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Tue, 1 Jul 2014 00:39:48 +0200 Subject: [PATCH] bcwc_pcie: Add DDR40 VDL stuff Signed-off-by: Patrik Jakobsson --- bcwc_drv.h | 1 + bcwc_hw.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++- bcwc_reg.h | 5 +++ 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/bcwc_drv.h b/bcwc_drv.h index a8cb68e..892593e 100644 --- a/bcwc_drv.h +++ b/bcwc_drv.h @@ -40,6 +40,7 @@ struct bcwc_private { u32 core_clk; u32 ddr_model; u32 ddr_speed; + u32 vdl_step_size; /* DDR_PHY saved registers. Offsets need to be initialized somewhere */ u32 ddr_phy_num_regs; diff --git a/bcwc_hw.c b/bcwc_hw.c index 0f806c6..f30f9cc 100644 --- a/bcwc_hw.c +++ b/bcwc_hw.c @@ -255,6 +255,7 @@ static int bcwc_hw_s2_init_ddr_controller_soc(struct bcwc_private *dev_priv) u32 cmd; u32 val; u32 reg; + u32 step_size, vdl_fine, vdl_coarse; int ret, i; /* Set DDR speed (450 MHz for now) */ @@ -356,7 +357,8 @@ static int bcwc_hw_s2_init_ddr_controller_soc(struct bcwc_private *dev_priv) return -EIO; } - dev_info(&dev_priv->pdev->dev, "DDR40 PHY PLL locked on safe settings\n"); + dev_info(&dev_priv->pdev->dev, + "DDR40 PHY PLL locked on safe settings\n"); /* Default is DDR model 4 */ if (dev_priv->ddr_model == 2) @@ -462,6 +464,103 @@ static int bcwc_hw_s2_init_ddr_controller_soc(struct bcwc_private *dev_priv) dev_info(&dev_priv->pdev->dev, "DDR40 PLL is locked after %d us\n", i); + BCWC_S2_REG_WRITE(0, S2_DDR40_PHY_VDL_CTL); + bcwc_hw_pci_post(dev_priv); + + BCWC_S2_REG_WRITE(0x103, S2_DDR40_PHY_VDL_CTL); + bcwc_hw_pci_post(dev_priv); + + /* Poll for VDL calibration */ + for (i = 0; i < 100; i++) { + reg = BCWC_S2_REG_READ(S2_DDR40_PHY_VDL_STATUS); + if (reg & 0x1) + break; + udelay(1); + } + + if (reg & 0x1) { + dev_info(&dev_priv->pdev->dev, + "First DDR40 VDL calibration completed after %d us", + i); + + if (!(reg & 0x2)) { + dev_info(&dev_priv->pdev->dev, + "...but failed to lock\n"); + } + + } else { + dev_err(&dev_priv->pdev->dev, + "First DDR40 VDL calibration failed\n"); + } + + BCWC_S2_REG_WRITE(0, S2_DDR40_PHY_VDL_CTL); + bcwc_hw_pci_post(dev_priv); + + BCWC_S2_REG_WRITE(0x200, S2_DDR40_PHY_VDL_CTL); + bcwc_hw_pci_post(dev_priv); + + for (i = 0; i < 1000; i++) { + reg = BCWC_S2_REG_READ(S2_DDR40_PHY_VDL_STATUS); + if (reg & 0x1) + break; + udelay(1); + } + + step_size = 0; + + if (reg & 0x1) { + dev_info(&dev_priv->pdev->dev, + "Second DDR40 VDL calibration completed after %d us\n", + i); + + if (!(reg & 0x2)) { + step_size = (reg >> 2) & 0x3ff; + dev_info(&dev_priv->pdev->dev, "Using step size %u\n", + step_size); + } + } else { + dev_info(&dev_priv->pdev->dev, + "Second DDR40 VDL calibration failed, using default step size\n"); + } + + val = 1000000 % dev_priv->ddr_speed; + + if (step_size == 0) { + step_size = (val * 0x4ec4ec4f) >> 22; + dev_info(&dev_priv->pdev->dev, "Using default step size (%u)\n", + step_size); + } + + dev_priv->vdl_step_size = step_size; + + vdl_fine = BCWC_S2_REG_READ(S2_DDR40_PHY_VDL_CHAN_STATUS); + if (!(vdl_fine & 2)) { + vdl_fine = (vdl_fine >> 8) & 0x3f; + vdl_fine |= 0x10100; + + BCWC_S2_REG_WRITE(vdl_fine, S2_DDR40_PHY_VDL_OVR_FINE); + bcwc_hw_pci_post(dev_priv); + + vdl_coarse = 0x10000; + + step_size >>= 4; + step_size += step_size * 2; + + if (step_size > 10) { + step_size = (step_size + 118) >> 1; + step_size &= 0x3f; + step_size |= 0x10000; + vdl_coarse = step_size; + } + + BCWC_S2_REG_WRITE(vdl_coarse, S2_DDR40_PHY_VDL_OVR_COARSE); + bcwc_hw_pci_post(dev_priv); + + dev_info(&dev_priv->pdev->dev, + "VDL set to: coarse=0x%x, fine=0x%x\n", + vdl_coarse, vdl_fine); + } + /* FIXME: Unfinished */ return 0; diff --git a/bcwc_reg.h b/bcwc_reg.h index 63203f8..f7fb7bc 100644 --- a/bcwc_reg.h +++ b/bcwc_reg.h @@ -74,6 +74,11 @@ #define S2_DDR40_PHY_PLL_CFG 0x2814 #define S2_DDR40_PHY_PLL_DIV 0x281c #define S2_DDR40_AUX_CTL 0x2820 +#define S2_DDR40_PHY_VDL_OVR_COARSE 0x2830 +#define S2_DDR40_PHY_VDL_OVR_FINE 0x2834 +#define S2_DDR40_PHY_VDL_CTL 0x2848 +#define S2_DDR40_PHY_VDL_STATUS 0x284c +#define S2_DDR40_PHY_VDL_CHAN_STATUS 0x2854 #define S2_DDR40_STRAP_CTL 0x28b0 #define S2_DDR40_STRAP_CTL_2 0x28b4 #define S2_DDR40_STRAP_STATUS 0x28b8