diff --git a/bcwc_hw.c b/bcwc_hw.c index 0c6ce62..3519705 100644 --- a/bcwc_hw.c +++ b/bcwc_hw.c @@ -612,7 +612,64 @@ static int bcwc_hw_s2_init_ddr_controller_soc(struct bcwc_private *dev_priv) udelay(500); - /* FIXME: Unfinished */ + BCWC_S2_REG_WRITE(0, S2_DDR_2004); + bcwc_hw_pci_post(dev_priv); + + udelay(10000); + + BCWC_S2_REG_WRITE(0xab0a, S2_DDR_2014); + bcwc_hw_pci_post(dev_priv); + + /* Polling for BUSY */ + for (i = 0; i < 10000; i++) { + reg = BCWC_S2_REG_READ(S2_DDR_STATUS_2018); + if (!(reg & S2_DDR_STATUS_BUSY)) + break; + udelay(10); + } + + if (i >= 10000) { + dev_info(&dev_priv->pdev->dev, + "S2_DDR_STATUS_2018 still busy after %d us\n", i); + return -ENODEV; + } + + udelay(10000); + + BCWC_S2_REG_WRITE(0, S2_3204); + bcwc_hw_pci_post(dev_priv); + + /* Read DRAM mem address (FIXME: Need to mask a few bits here) */ + reg = BCWC_S2_REG_READ(S2_DDR40_STRAP_STATUS); + dev_info(&dev_priv->pdev->dev, + "S2 DRAM memory address: 0x%08x\n", reg); + + switch (dev_priv->ddr_model) { + case 4: + val = 0x1fffffff; + break; + case 2: + val = 0x0fffffff; + break; + default: + val = dev_priv->ddr_model; + } + + BCWC_S2_REG_WRITE(val, S2_3208); + bcwc_hw_pci_post(dev_priv); + + BCWC_S2_REG_WRITE(0x1040, S2_3200); + bcwc_hw_pci_post(dev_priv); + + /* FIXME: implement + * bcwc_hw_rewrite_mode_regs(dev_priv); + */ + + BCWC_S2_REG_WRITE(0x20000, S2_DDR_2014); + bcwc_hw_pci_post(dev_priv); + + BCWC_S2_REG_WRITE(1, S2_DDR_2008); + bcwc_hw_pci_post(dev_priv); return 0; } diff --git a/bcwc_reg.h b/bcwc_reg.h index 80a2007..072a2f7 100644 --- a/bcwc_reg.h +++ b/bcwc_reg.h @@ -48,6 +48,12 @@ #define S2_PLL_CTRL_510 0x0510 /* Probably DDR PHY PLL registers */ +#define S2_DDR_2004 0x2004 +#define S2_DDR_2008 0x2008 +#define S2_DDR_2014 0x2014 +#define S2_DDR_STATUS_2018 0x2018 +#define S2_DDR_STATUS_BUSY (1 << 0) + #define S2_DDR_20A0 0x20a0 #define S2_DDR_20A4 0x20a4 #define S2_DDR_20A8 0x20a8 @@ -101,6 +107,10 @@ #define S2_2BA0 0x2ba0 #define S2_2BAC 0x2bac +#define S2_3200 0x3200 +#define S2_3204 0x3204 +#define S2_3208 0x3208 + /* On iomem with pointer at 0x0ff0 (Bar 4: 1MB) */ #define IRQ_IPC_NUM_CHAN 0xc3000 #define IRQ_IPC_QUEUE_SIZE 0xc3004