From 6a71c1947c90ea055e0beaaefb47a804110a00b5 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Sun, 22 Feb 2015 22:59:35 +0100 Subject: [PATCH] bcwc_pcie: Implement bcwc_ddr_generic_rd_dqs Signed-off-by: Patrik Jakobsson --- bcwc_ddr.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++- bcwc_reg.h | 9 ++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/bcwc_ddr.c b/bcwc_ddr.c index 4149b2d..55fad45 100644 --- a/bcwc_ddr.c +++ b/bcwc_ddr.c @@ -420,9 +420,73 @@ static int bcwc_ddr_calibrate_re_byte_fifo(struct bcwc_private *dev_priv) return 0; } +/* Set default/generic read data strobe */ static int bcwc_ddr_generic_rd_dqs(struct bcwc_private *dev_priv) { - return 0; + u32 retries, locked, reg_val, tmp, offset; + u32 bytes[S2_DDR40_NUM_BYTE_LANES]; + int i, j, ret; + + /* Save the current byte lanes */ + for (i = 0; i < S2_DDR40_NUM_BYTE_LANES; i++) { + tmp = BCWC_S2_REG_READ(S2_DDR40_RDEN_BYTE0 + + (i * S2_DDR40_BYTE_LANE_SIZE)); + bytes[i] = tmp & 0x3f; + } + + /* Clear all byte lanes */ + for (i = 0; i < S2_DDR40_NUM_BYTE_LANES; i++) { + for (j = 0; j < 8; j++) { + offset = S2_DDR40_2A38 + (i * 0xa0) + (j * 8); + + BCWC_S2_REG_WRITE(0x30000, offset - 4); + BCWC_S2_REG_WRITE(0x30000, offset); + } + } + + reg_val = (BCWC_S2_REG_READ(S2_DDR40_2850) >> 20) & 0x3f; + + locked = 0; + retries = 1000; + + while (retries > 0 && !locked) { + ret = bcwc_ddr_verify_mem(dev_priv, 0); + if (!ret) + break; + + retries--; + + reg_val++; + tmp = (reg_val & 0x3f) | 0x30100; + + BCWC_S2_REG_WRITE(tmp, S2_DDR40_2A08); + BCWC_S2_REG_WRITE(tmp, S2_DDR40_2A0C); + BCWC_S2_REG_WRITE(tmp, S2_DDR40_2AA8); + BCWC_S2_REG_WRITE(tmp, S2_DDR40_2AAC); + + locked = reg_val > 0x3e; + offset = S2_DDR40_RDEN_BYTE0; + + /* Write byte lane settings */ + for (i = 0; i < 2; i++) { + bytes[i]++; + BCWC_S2_REG_WRITE((bytes[i] & 0x3f) | 0x30100, offset); + + if (bytes[i] > 0x3e) + locked = 1; + + offset += 0xa0; + } + } + + if (retries == 0) { + dev_err(&dev_priv->pdev->dev, "Generic RD DQS timeout\n"); + ret = -EIO; + } + + dev_info(&dev_priv->pdev->dev, "Generic RD DQS succeeded\n"); + + return ret; } static int bcwc_ddr_wr_dqs_setting(struct bcwc_private *dev_priv) diff --git a/bcwc_reg.h b/bcwc_reg.h index 356da88..f138f9f 100644 --- a/bcwc_reg.h +++ b/bcwc_reg.h @@ -90,6 +90,7 @@ #define S2_DDR40_PHY_VDL_CTL 0x2848 #define S2_DDR40_PHY_VDL_STATUS 0x284c +#define S2_DDR40_2850 0x2850 #define S2_DDR40_PHY_VDL_CHAN_STATUS 0x2854 #define S2_DDR40_PHY_VTT_CTL 0x285c @@ -101,8 +102,16 @@ #define S2_DDR40_STRAP_CTL_2 0x28b4 #define S2_DDR40_STRAP_STATUS 0x28b8 +#define S2_DDR40_NUM_BYTE_LANES 2 +#define S2_DDR40_BYTE_LANE_SIZE 0xa0 + #define S2_DDR40_RDEN_BYTE 0x2a00 +#define S2_DDR40_2A08 0x2a08 +#define S2_DDR40_2A0C 0x2a0c +#define S2_DDR40_2A38 0x2a38 #define S2_DDR40_RDEN_BYTE0 0x2a74 +#define S2_DDR40_2AA8 0x2aa8 +#define S2_DDR40_2AAC 0x2aac #define S2_DDR40_RDEN_BYTE1 0x2b14 #define S2_DDR40_RD_DATA_DLY_FIFO 0x2b60