1 /* 2 * This program is distributed in the hope that it will be useful, 3 * but WITHOUT ANY WARRANTY; without even the implied warranty of 4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 5 * GNU General Public License for more details. 6 * 7 * You should have received a copy of the GNU General Public License 8 * along with this program; if not, write to the Free Software 9 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 10 */ 11 12 #include <common.h> 13 #include <console.h> 14 #include <bootretry.h> 15 #include <cli.h> 16 #include <command.h> 17 #include <console.h> 18 19 #include <inttypes.h> 20 #include <mapmem.h> 21 #include <asm/io.h> 22 #include <linux/compiler.h> 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 #define DRAM_BASE 0x80000000 27 #define TIMEOUT_DRAM 5000000 28 29 /* ------------------------------------------------------------------------- */ 30 int MMCTestBurst(unsigned int datagen) 31 { 32 unsigned int data; 33 unsigned int timeout = 0; 34 35 writel(0x00000000, 0x1E6E0070); 36 writel((0x000000C1 | (datagen << 3)), 0x1E6E0070); 37 38 do { 39 data = readl(0x1E6E0070) & 0x3000; 40 41 if( data & 0x2000 ) 42 return(0); 43 44 if( ++timeout > TIMEOUT_DRAM ) { 45 printf("Timeout!!\n"); 46 writel(0x00000000, 0x1E6E0070); 47 return(0); 48 } 49 } while (!data); 50 51 writel(0x00000000, 0x1E6E0070); 52 53 return(1); 54 } 55 56 /* ------------------------------------------------------------------------- */ 57 int MMCTestSingle(unsigned int datagen) 58 { 59 unsigned int data; 60 unsigned int timeout = 0; 61 62 writel(0x00000000, 0x1E6E0070); 63 writel((0x00000085 | (datagen << 3)), 0x1E6E0070); 64 65 do { 66 data = readl(0x1E6E0070) & 0x3000; 67 68 if( data & 0x2000 ) 69 return(0); 70 71 if( ++timeout > TIMEOUT_DRAM ){ 72 printf("Timeout!!\n"); 73 writel(0x00000000, 0x1E6E0070); 74 75 return(0); 76 } 77 } while ( !data ); 78 79 writel(0x00000000, 0x1E6E0070); 80 81 return(1); 82 } 83 84 /* ------------------------------------------------------------------------- */ 85 int MMCTest(void) 86 { 87 unsigned int pattern; 88 89 pattern = rand(); 90 writel(pattern, 0x1E6E007C); 91 printf("Pattern = %08X : ",pattern); 92 93 if(!MMCTestBurst(0)) return(0); 94 if(!MMCTestBurst(1)) return(0); 95 if(!MMCTestBurst(2)) return(0); 96 if(!MMCTestBurst(3)) return(0); 97 if(!MMCTestBurst(4)) return(0); 98 if(!MMCTestBurst(5)) return(0); 99 if(!MMCTestBurst(6)) return(0); 100 if(!MMCTestBurst(7)) return(0); 101 if(!MMCTestSingle(0)) return(0); 102 if(!MMCTestSingle(1)) return(0); 103 if(!MMCTestSingle(2)) return(0); 104 if(!MMCTestSingle(3)) return(0); 105 if(!MMCTestSingle(4)) return(0); 106 if(!MMCTestSingle(5)) return(0); 107 if(!MMCTestSingle(6)) return(0); 108 if(!MMCTestSingle(7)) return(0); 109 110 return(1); 111 } 112 113 /* ------------------------------------------------------------------------- */ 114 static void print_usage(void) 115 { 116 printf("\nASPEED DRAM BIST\n\n"); 117 printf("Usage: dramtest <count> <block> <length>\n\n"); 118 printf("count: how many iterations to run (mandatory, in decimal)\n"); 119 printf(" 0: infinite loop.\n"); 120 printf("block: index of the address block to test " 121 "(optional, in decimal, default: 0)\n"); 122 printf(" 0: [8000_0000, 8400_0000)\n"); 123 printf(" 1: [8400_0000, 8800_0000)\n"); 124 printf(" 2: [8800_0000, 8C00_0000)\n"); 125 printf(" n: [8000_0000 + n*64MB, 8000_0000 + (n+1)*64MB)\n"); 126 printf(" where n = [0, 31]\n"); 127 printf("length: size to test (optional, in hex, default: 0x10000)\n"); 128 printf(" 0x0: test the whole memory block 64MB\n"); 129 printf(" 0x1: test the first 16 Bytes of the memory block\n"); 130 printf(" 0x2: test the first 2*16 Bytes of the memory block\n"); 131 printf(" n : test the first n*16 Bytes of the memory block\n"); 132 printf(" where n = [0x00_0001, 0x3F_FFFF]\n"); 133 printf("\n\n"); 134 } 135 136 static int 137 do_ast_dramtest(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 138 { 139 u32 PassCnt = 0; 140 unsigned long Testcounter = 0; 141 unsigned long block = 0; 142 unsigned long length = 0x10000; 143 int ret; 144 145 if (argc < 2) { 146 ret = 0; 147 goto cmd_err; 148 } 149 150 ret = CMD_RET_USAGE; 151 switch (argc) { 152 case 4: 153 if (strict_strtoul(argv[3], 16, &length) < 0) 154 goto cmd_err; 155 case 3: 156 if (strict_strtoul(argv[2], 10, &block) < 0) 157 goto cmd_err; 158 case 2: 159 if (strict_strtoul(argv[1], 10, &Testcounter) < 0) 160 goto cmd_err; 161 break; 162 } 163 164 printf("Test range: 0x%08lx - 0x%08lx\n", DRAM_BASE + (block << 26), 165 DRAM_BASE + (block << 26) + (length << 4)); 166 167 ret = 1; 168 writel(0xFC600309, 0x1E6E0000); 169 while ((Testcounter > PassCnt) || (Testcounter == 0)) { 170 clrsetbits_le32(0x1E6E0074, GENMASK(30, 4), 171 (block << 26) | (length << 4)); 172 if (!MMCTest()) { 173 printf("FAIL %d/%ld (fail DQ 0x%08x)\n", PassCnt, 174 Testcounter, readl(0x1E6E0078)); 175 ret = 0; 176 break; 177 } else { 178 PassCnt++; 179 printf("Pass %d/%ld\n", PassCnt, Testcounter); 180 } 181 } 182 183 return (ret); 184 185 cmd_err: 186 print_usage(); 187 return (ret); 188 } 189 190 U_BOOT_CMD( 191 dramtest, 5, 0, do_ast_dramtest, 192 "ASPEED DRAM BIST", 193 "" 194 ); 195