Send SDRAM initialization sequence and answer PHY read/write requests. Obstinately...
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 18 Feb 2012 17:12:14 +0000 (18:12 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 18 Feb 2012 17:12:14 +0000 (18:12 +0100)
milkymist/dfii/__init__.py
software/bios/ddrinit.c
top.py

index 429262006872fb024762642a55cc36ea9273456f..c8dfbbe81d5c7e84677eff4ed346d818f3feed3c 100644 (file)
@@ -83,7 +83,6 @@ class DFIInjector:
                                phase.we_n.eq(1),
                                phase.cas_n.eq(1),
                                phase.ras_n.eq(1)
-                               
                        ]
                
                # commands
@@ -101,6 +100,12 @@ class DFIInjector:
                        )
                ]
                
+               # addresses
+               comb += [
+                       cmdphase.address.eq(self._address.field.r),
+                       cmdphase.bank.eq(self._baddress.field.r)
+               ]
+               
                # data enables
                sync += _data_en(self._command.re & self._rddata.r,
                        rddata_en,
index 24352a7c8165f683a5fc420d4ba7fc587fc2c74c..5edce2347809f1048c3b33f632c8ae9b00502158 100644 (file)
 #include <stdio.h>
 
 #include <hw/s6ddrphy.h>
+#include <hw/dfii.h>
 
 #include "ddrinit.h"
 
+static void cdelay(int i)
+{
+       while(i > 0) {
+               __asm__ volatile("nop");
+               i--;
+       }
+}
+
+static void setaddr(int a)
+{
+       CSR_DFII_AH = (a & 0x1fe0) >> 5;
+       CSR_DFII_AL = a & 0x001f;
+}
+
 static void init_sequence(void)
 {
+       int i;
+       
        printf("Sending initialization sequence...\n");
-       // TODO
+       
+       /* Bring CKE high */
+       setaddr(0x0000);
+       CSR_DFII_BA = 0;
+       CSR_DFII_CONTROL = DFII_CONTROL_CKE;
+       
+       /* Precharge All */
+       setaddr(0x0400);
+       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+       
+       /* Load Extended Mode Register */
+       CSR_DFII_BA = 1;
+       setaddr(0x0000);
+       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+       CSR_DFII_BA = 0;
+       
+       /* Load Mode Register */
+       setaddr(0x0132); /* Reset DLL, CL=3, BL=4 */
+       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+       cdelay(200);
+       
+       /* Precharge All */
+       setaddr(0x0400);
+       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+       
+       /* 2x Auto Refresh */
+       for(i=0;i<2;i++) {
+               setaddr(0);
+               CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS;
+               cdelay(4);
+       }
+       
+       /* Load Mode Register */
+       setaddr(0x0032); /* CL=3, BL=4 */
+       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+       cdelay(200);
 }
 
 static void calibrate_phy(void)
@@ -33,21 +85,38 @@ static void calibrate_phy(void)
        int addr;
        
        printf("Calibrating PHY...\n");
+       
+       CSR_DFII_WRDELAY = 4;
+       CSR_DFII_WRDURATION = 1;
+       CSR_DFII_RDDELAY = 7;
+       CSR_DFII_RDDURATION = 1;
+       
+       /* Use bank 0, activate row 0 */
+       CSR_DFII_BA = 0;
+       setaddr(0x0000);
+       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CS;
+       
        while(!(CSR_DDRPHY_STATUS & DDRPHY_STATUS_PHY_CAL_DONE)) {
+               cdelay(20);
                requests = CSR_DDRPHY_REQUESTS;
                addr = CSR_DDRPHY_REQADDR;
                
+               setaddr(addr << 2);
                if(requests & DDRPHY_REQUEST_READ) {
                        printf("R %d\n", addr);
-                       // TODO
+                       CSR_DFII_COMMAND = DFII_COMMAND_RDDATA|DFII_COMMAND_CAS|DFII_COMMAND_CS;
                }
                if(requests & DDRPHY_REQUEST_WRITE) {
                        printf("W %d\n", addr);
-                       // TODO
+                       CSR_DFII_COMMAND = DFII_COMMAND_WRDATA|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
                }
                
                CSR_DDRPHY_REQUESTS = requests;
        }
+       
+       /* Precharge All */
+       setaddr(0x0400);
+       CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
 }
 
 int ddrinit(void)
diff --git a/top.py b/top.py
index 3e97119d828fcedeffca952c38b9a45cacdd9817..473674060639c8b94e4d77fb7df47511606af139 100644 (file)
--- a/top.py
+++ b/top.py
@@ -43,7 +43,7 @@ def get():
        # DFI
        #
        ddrphy0 = s6ddrphy.S6DDRPHY(1, dfi_a, dfi_ba, dfi_d)
-       dfii0 = dfii.DFIInjector(2, dfi_a, dfi_ba, dfi_d, 2)
+       dfii0 = dfii.DFIInjector(2, dfi_a, dfi_ba, dfi_d, 1)
        dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
 
        #