From 026457a98c2057dc5d6a8533cab0a8c5aea374d6 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 18 Feb 2012 18:12:14 +0100 Subject: [PATCH] Send SDRAM initialization sequence and answer PHY read/write requests. Obstinately refuses to work, unfortunately. --- milkymist/dfii/__init__.py | 7 +++- software/bios/ddrinit.c | 75 ++++++++++++++++++++++++++++++++++++-- top.py | 2 +- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/milkymist/dfii/__init__.py b/milkymist/dfii/__init__.py index 429262006..c8dfbbe81 100644 --- a/milkymist/dfii/__init__.py +++ b/milkymist/dfii/__init__.py @@ -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, diff --git a/software/bios/ddrinit.c b/software/bios/ddrinit.c index 24352a7c8..5edce2347 100644 --- a/software/bios/ddrinit.c +++ b/software/bios/ddrinit.c @@ -18,13 +18,65 @@ #include #include +#include #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 3e97119d8..473674060 100644 --- 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) #