diff --git a/bcwc_hw.c b/bcwc_hw.c index 8598ac2..0b7a7e1 100644 --- a/bcwc_hw.c +++ b/bcwc_hw.c @@ -254,7 +254,7 @@ static int bcwc_hw_s2_init_ddr_controller_soc(struct bcwc_private *dev_priv) { u32 cmd; u32 reg; - int ret; + int ret, i; /* Read PCI config command register */ ret = pci_read_config_dword(dev_priv->pdev, 4, &cmd); @@ -283,6 +283,77 @@ static int bcwc_hw_s2_init_ddr_controller_soc(struct bcwc_private *dev_priv) bcwc_hw_ddr_phy_soft_reset(dev_priv); + /* Not sure what this is yet (perhaps safe/slow DDR PLL settings) */ + BCWC_S2_REG_WRITE(0x2, S2_2BA4); + bcwc_hw_pci_post(dev_priv); + + BCWC_S2_REG_WRITE(0x2, S2_2BA8); + bcwc_hw_pci_post(dev_priv); + + /* Disable the hardware frequency change function */ + BCWC_S2_REG_WRITE(0x3f4, S2_20F8); + bcwc_hw_pci_post(dev_priv); + + /* Setup the PLL */ + BCWC_S2_REG_WRITE(0x40, S2_2434); + bcwc_hw_pci_post(dev_priv); + + BCWC_S2_REG_WRITE(0x10000000, S2_2438); + bcwc_hw_pci_post(dev_priv); + + /* Wait for DDR PLL to lock */ + for (i = 0; i <= 10000; i++) { + reg = BCWC_S2_REG_READ(S2_DDR_PLL_STATUS_2444); + if (reg & S2_DDR_PLL_STATUS_2444_LOCKED) + break; + udelay(10); + } + + if (i > 10000) { + dev_err(&dev_priv->pdev->dev, + "Failed to lock DDR PHY PLL in stage 1\n"); + return -EIO; + } + + BCWC_S2_REG_WRITE(0x1f37205, S2_2430); + bcwc_hw_pci_post(dev_priv); + + for (i = 0; i <= 10000; i++) { + reg = BCWC_S2_REG_READ(S2_DDR_PLL_STATUS_241C); + if (reg & S2_DDR_PLL_STATUS_241C_LOCKED) + break; + udelay(10); + } + + if (i > 10000) { + dev_err(&dev_priv->pdev->dev, + "Failed to lock DDR PHY PLL in stage 2\n"); + return -EIO; + } + + udelay(10000); + + BCWC_S2_REG_WRITE(0x0c10, S2_281C); + bcwc_hw_pci_post(dev_priv); + + BCWC_S2_REG_WRITE(0x0010, S2_2814); + bcwc_hw_pci_post(dev_priv); + + for (i = 0; i <= 10000; i++) { + reg = BCWC_S2_REG_READ(S2_DDR_PLL_STATUS_2810); + if (reg & S2_DDR_PLL_STATUS_2810_LOCKED) + break; + udelay(10); + } + + if (i > 10000) { + dev_err(&dev_priv->pdev->dev, + "Failed to lock DDR PHY PLL in stage 3\n"); + return -EIO; + } + + dev_info(&dev_priv->pdev->dev, "DDR PHY PLL locked on safe settings\n"); + /* FIXME: Unfinished */ return 0; diff --git a/bcwc_reg.h b/bcwc_reg.h index bf2e795..c4bf375 100644 --- a/bcwc_reg.h +++ b/bcwc_reg.h @@ -14,7 +14,6 @@ #define _BCWC_REG_H /* S2 IO reg */ - #define S2_PCIE_LINK_D000 0xd000 #define S2_PCIE_LINK_D120 0xd120 #define S2_PCIE_LINK_D124 0xd124 @@ -31,9 +30,6 @@ #define S2_DDR_REG_1118 0x1118 #define S2_DDR_REG_111C 0x111c -#define DDR_PHY_REG_BASE 0x2800 -#define DDR_PHY_NUM_REGS 127 /* Found in AppleCamIn::Start() */ - #define S2_PLL_STATUS_04 0x04 #define S2_PLL_REFCLK (1 << 3) /* 1 = 25MHz, 0 = 24MHz */ @@ -51,6 +47,29 @@ #define S2_PLL_CTRL_100 0x0100 #define S2_PLL_CTRL_510 0x0510 +/* Probably DDR PHY PLL registers */ +#define S2_20F8 0x20f8 +#define S2_2430 0x2430 +#define S2_2434 0x2434 +#define S2_2438 0x2438 + +#define S2_DDR_PLL_STATUS_241C 0x241c +#define S2_DDR_PLL_STATUS_241C_LOCKED 0x0400 + +#define S2_DDR_PLL_STATUS_2444 0x2444 +#define S2_DDR_PLL_STATUS_2444_LOCKED 0x2000 + +#define DDR_PHY_REG_BASE 0x2800 +#define DDR_PHY_NUM_REGS 127 /* Found in AppleCamIn::Start() */ + +#define S2_DDR_PLL_STATUS_2810 0x2810 +#define S2_DDR_PLL_STATUS_2810_LOCKED 0x1 +#define S2_2814 0x2814 +#define S2_281C 0x281c + +#define S2_2BA4 0x2ba4 +#define S2_2BA8 0x2ba8 + /* On iomem with pointer at 0x0ff0 (Bar 4: 1MB) */ #define IRQ_IPC_NUM_CHAN 0xc3000 #define IRQ_IPC_QUEUE_SIZE 0xc3004