92e1863542a3d519f5ade1dfd94437c4c80b2b3c
[litex.git] / software / bios / sdram.c
1 #include <generated/csr.h>
2 #ifdef DFII_BASE
3
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include <generated/sdram_phy.h>
8 #include <generated/mem.h>
9 #include <hw/flags.h>
10
11 #include "sdram.h"
12
13 static void cdelay(int i)
14 {
15 while(i > 0) {
16 __asm__ volatile("nop");
17 i--;
18 }
19 }
20
21 void ddrsw(void)
22 {
23 dfii_control_write(DFII_CONTROL_CKE);
24 printf("DDR now under software control\n");
25 }
26
27 void ddrhw(void)
28 {
29 dfii_control_write(DFII_CONTROL_SEL|DFII_CONTROL_CKE);
30 printf("DDR now under hardware control\n");
31 }
32
33 void ddrrow(char *_row)
34 {
35 char *c;
36 unsigned int row;
37
38 if(*_row == 0) {
39 dfii_pi0_address_write(0x0000);
40 dfii_pi0_baddress_write(0);
41 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
42 cdelay(15);
43 printf("Precharged\n");
44 } else {
45 row = strtoul(_row, &c, 0);
46 if(*c != 0) {
47 printf("incorrect row\n");
48 return;
49 }
50 dfii_pi0_address_write(row);
51 dfii_pi0_baddress_write(0);
52 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
53 cdelay(15);
54 printf("Activated row %d\n", row);
55 }
56 }
57
58 void ddrrd(char *startaddr)
59 {
60 char *c;
61 unsigned int addr;
62 int i;
63
64 if(*startaddr == 0) {
65 printf("ddrrd <address>\n");
66 return;
67 }
68 addr = strtoul(startaddr, &c, 0);
69 if(*c != 0) {
70 printf("incorrect address\n");
71 return;
72 }
73
74 dfii_pird_address_write(addr);
75 dfii_pird_baddress_write(0);
76 command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
77 cdelay(15);
78
79 for(i=0;i<8;i++)
80 printf("%02x", MMPTR(0xe0001038+4*i));
81 for(i=0;i<8;i++)
82 printf("%02x", MMPTR(0xe000108c+4*i));
83 printf("\n");
84 }
85
86 void ddrwr(char *startaddr)
87 {
88 char *c;
89 unsigned int addr;
90 int i;
91
92 if(*startaddr == 0) {
93 printf("ddrrd <address>\n");
94 return;
95 }
96 addr = strtoul(startaddr, &c, 0);
97 if(*c != 0) {
98 printf("incorrect address\n");
99 return;
100 }
101
102 for(i=0;i<8;i++) {
103 MMPTR(0xe0001018+4*i) = i;
104 MMPTR(0xe000106c+4*i) = 0xf0 + i;
105 }
106
107 dfii_piwr_address_write(addr);
108 dfii_piwr_baddress_write(0);
109 command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
110 }
111
112 #define TEST_SIZE (4*1024*1024)
113
114 int memtest_silent(void)
115 {
116 volatile unsigned int *array = (unsigned int *)SDRAM_BASE;
117 int i;
118 unsigned int prv;
119 unsigned int error_cnt;
120
121 prv = 0;
122 for(i=0;i<TEST_SIZE/4;i++) {
123 prv = 1664525*prv + 1013904223;
124 array[i] = prv;
125 }
126
127 prv = 0;
128 error_cnt = 0;
129 for(i=0;i<TEST_SIZE/4;i++) {
130 prv = 1664525*prv + 1013904223;
131 if(array[i] != prv)
132 error_cnt++;
133 }
134 return error_cnt;
135 }
136
137 int memtest(void)
138 {
139 unsigned int e;
140
141 e = memtest_silent();
142 if(e != 0) {
143 printf("Memtest failed: %d/%d words incorrect\n", e, TEST_SIZE/4);
144 return 0;
145 } else {
146 printf("Memtest OK\n");
147 return 1;
148 }
149 }
150
151 int ddrinit(void)
152 {
153 printf("Initializing DDR SDRAM...\n");
154
155 init_sequence();
156 dfii_control_write(DFII_CONTROL_SEL|DFII_CONTROL_CKE);
157 if(!memtest())
158 return 0;
159
160 return 1;
161 }
162
163 #endif