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