bcwc_pcie: Implement DDR read data fifo delay calibration

Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
This commit is contained in:
Patrik Jakobsson
2014-08-29 23:37:12 +02:00
parent d9c187e0e2
commit df3952819f

144
bcwc_hw.c
View File

@@ -839,8 +839,150 @@ int bcwc_hw_verify_mem(struct bcwc_private *dev_priv, u32 base)
/* FIXME: Make some more sense out of this */
static int bcwc_hw_ddr_calibrate_rd_data_dly_fifo(struct bcwc_private *dev_priv)
{
u32 base = 0x2800;
u32 offset_1 = base + 0x200;
u32 offset_2 = base + 0x274;
u32 offset_3 = base + 0x314;
u32 delay_reg = base + 0x360;
u32 offset_5 = base + 0x390;
u32 offset_6 = base + 0x394;
u32 reg_saved_1, reg_saved_2, reg_saved_3;
return 0;
u32 a, b, c, d, r8, r12, r14, r15;
u32 var_2c, var_30, fifo_delay, var_38;
int ret;
/* Save current register values */
reg_saved_1 = BCWC_S2_REG_READ(offset_1);
reg_saved_2 = BCWC_S2_REG_READ(offset_2);
reg_saved_3 = BCWC_S2_REG_READ(offset_3);
BCWC_S2_REG_WRITE(0x30000, offset_1);
bcwc_hw_pci_post(dev_priv);
BCWC_S2_REG_WRITE(0x30100, offset_2);
bcwc_hw_pci_post(dev_priv);
BCWC_S2_REG_WRITE(0x30100, offset_3);
bcwc_hw_pci_post(dev_priv);
fifo_delay = 1;
a = 1000;
r15 = 0;
b = 0;
var_30 = 0;
var_2c = 0;
do {
var_38 = a;
BCWC_S2_REG_WRITE((fifo_delay & 0x7), delay_reg);
bcwc_hw_pci_post(dev_priv);
/*
* How do we know if verification was successful?
* OSX doesn't check any return values from it's verification so
* perhaps controller can detect this itself and set some regs.
*/
bcwc_hw_verify_mem(dev_priv, 0);
BCWC_S2_REG_WRITE(1, offset_6);
bcwc_hw_pci_post(dev_priv);
r8 = (b >= 57) ? b : (b + 7);
a = r15 + 7;
b = a;
if (b < 57)
b = r15;
if (b > 63) {
a = 1;
b = 0;
r8 = 0;
}
c = var_38 - 1;
r14 = (BCWC_S2_REG_READ(offset_5) & 0xf) | var_2c;
if (r14 == 0)
var_2c = fifo_delay;
if (var_2c == 0)
c = 1;
r12 = (BCWC_S2_REG_READ(offset_5) & 0xf0) | var_30;
if (r12 == 0)
var_30 = fifo_delay;
if (var_30 == 0)
d = 1;
a += fifo_delay;
if (a < 8) {
r15 = (c | d) ^ 1;
fifo_delay = a;
} else {
if (var_30 == 0)
var_30 = 7;
if (var_2c == 0)
var_2c = 7;
fifo_delay = 7;
r15 = 1;
}
BCWC_S2_REG_WRITE((r8 & 0x3f) | 0x30000, offset_1);
bcwc_hw_pci_post(dev_priv);
BCWC_S2_REG_WRITE((b & 0x3f) | 0x30100, offset_2);
bcwc_hw_pci_post(dev_priv);
BCWC_S2_REG_WRITE((b & 0x3f) | 0x30100, offset_3);
bcwc_hw_pci_post(dev_priv);
if (var_38 == 0)
break;
a = var_38 - 1;
if (r15 != 0)
break;
r15 = b;
} while(1);
if (var_38 == 0) {
dev_err(&dev_priv->pdev->dev, "rd_data_dly_fifo timed out\n\n");
ret = -EIO;
goto out;
}
dev_info(&dev_priv->pdev->dev, "rd_data_dly_fifo succeeded\n");
BCWC_S2_REG_WRITE(reg_saved_1, offset_1);
bcwc_hw_pci_post(dev_priv);
BCWC_S2_REG_WRITE(reg_saved_2, offset_2);
bcwc_hw_pci_post(dev_priv);
BCWC_S2_REG_WRITE(reg_saved_3, offset_3);
bcwc_hw_pci_post(dev_priv);
if (var_30 > var_2c)
var_2c = var_30;
var_2c++;
var_30 = 7;
if (var_2c <= 7)
var_30 = var_2c;
if (var_30 < 7)
var_30++;
BCWC_S2_REG_WRITE(var_30, delay_reg);
bcwc_hw_pci_post(dev_priv);
ret = 0;
out:
return ret;
}
static int bcwc_hw_ddr_calibrate_re_byte_fifo(struct bcwc_private *dev_priv)