1 /*
2 * Copyright (c) 2006-2014, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
34 function d2h(d) {return ("00000000" + (d).toString(16)).slice(-8);}
36 // helper function to create decimal numbers in ascii format
37 function d2d(d) {return ((+d).toString());}
39 function printRegisterValue(ds, name, addr)
40 {
41 value = debugSessionDAP.memory.readWord(0,addr,false);
42 value_string = d2h(value);
43 file.write(name + " = 0x" + value_string + "\n");
44 return value; // return the register value for interrogation
45 }
47 function getRegisterValue(debug, addr)
48 {
49 return debug.memory.readWord(0,addr,false);
50 }
52 function interpret_cmd_phy_macro(value, index)
53 {
54 WD1 = (value >> (21+index)) & 1;
55 WD0 = (value >> (10+index)) & 1;
56 WD = (WD1 << 1) | WD0;
57 if (WD == 0) return_string = "Pullup/Pulldown disabled\n";
58 if (WD == 1) return_string = "Weak pullup enabled\n";
59 if (WD == 2) return_string = "Weak pulldown enabled\n";
60 if (WD == 3) return_string = "Weak keeper enabled\n";
61 return return_string;
62 }
64 function interpret_data_phy_macro(value, index)
65 {
66 WD1 = (value >> (20+index)) & 1;
67 WD0 = (value >> (10+index)) & 1;
68 WD = (WD1 << 1) | WD0;
69 if (WD == 0) return_string = "Pullup/Pulldown disabled\n";
70 if (WD == 1) return_string = "Weak pullup enabled\n";
71 if (WD == 2) return_string = "Weak pulldown enabled\n";
72 if (WD == 3) return_string = "Weak keeper enabled\n";
73 return return_string;
74 }
76 // Inputs:
77 // Data - 32-bit register value
78 // Upper - Highest bit to keep
79 // Lower - Lowest bit to keep
80 // (bit 0 refers to LSB, bit 31 to MSB)
81 // Return: right aligned data
82 function bits32(data, upper, lower)
83 {
84 data = data >>> lower; // unsigned right-shift
85 upper = upper - lower;
86 bitmask = 0xFFFFFFFF >>> (31 - upper);
87 return (data & bitmask);
88 }
90 // Build a filename that includes date/time
91 var today = new Date();
92 var year4digit = today.getFullYear();
93 var month2digit = ("0" + (today.getMonth()+1)).slice(-2);
94 var day2digit = ("0" + today.getDate()).slice(-2);
95 var hour2digit = ("0" + today.getHours()).slice(-2);
96 var minutes2digit = ("0" + today.getMinutes()).slice(-2);
97 var seconds2digit = ("0" + today.getSeconds()).slice(-2);
98 var filename_date = '_' + year4digit + '-' + month2digit + '-' + day2digit + '_' + hour2digit + minutes2digit + seconds2digit;
99 var userHomeFolder = System.getProperty("user.home");
100 var filename = userHomeFolder + '/Desktop/' + 'am335x-ddr-analysis' + filename_date + '.txt';
101 file = new java.io.FileWriter(filename);
102 var newline = "\n";
104 debugSessionDAP = ds.openSession("*","CS_DAP_M3");
105 use_dap_m3 = 1;
107 try {
108 debugSessionDAP.target.connect();
109 } catch (ex) {
110 print("\n ERROR: Could not connect to DAP_M3.\n");
111 }
113 // Do a test read of Device_ID register at 0x44e10600
114 value = debugSessionDAP.memory.readWord(0,0x44e10600,false);
116 // If it is zero, switch to CS_DAP_DebugSS
117 if (value == 0)
118 {
119 debugSessionDAP.target.disconnect();
120 debugSessionDAP = ds.openSession("*","CS_DAP_DebugSS");
121 debugSessionDAP.target.connect();
122 use_dap_m3 = 0;
123 file.write("Switched to DAP_DebugSS" + newline);
124 value = debugSessionDAP.memory.readWord(0,0x44e10600,false);
125 file.write("Read value of " + d2h(value) + " from Device_ID register." + newline);
126 }
128 var original_CM_WKUP_DEBUGSS_CLKCTRL = debugSessionDAP.memory.readWord(0,0x44e00414,false);
129 var original_CM_PER_L3_CLKSTCTRL = debugSessionDAP.memory.readWord(0,0x44E0000C,false);
131 // Only try to read EMIF registers if EMIF clock is enabled
132 if (original_CM_PER_L3_CLKSTCTRL & 1<<2) {
134 // CM_WKUP_DEBUGSS_CLKCTRL[MODULEMODE] = ENABLED
135 debugSessionDAP.expression.evaluate(
136 "*((unsigned int*) 0x44e00414 ) |= 0x2;");
138 debugSessionDAP.target.disconnect(); // disconnect from DAP_M3
140 // Connect to DAP_DebugSS for L3 visibility (EMIF regs)
141 debugSessionDAP = ds.openSession("*","CS_DAP_DebugSS");
142 debugSessionDAP.target.connect();
144 var reg_val;
146 // CONTROL: device_id
147 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: device_id", 0x44E10600);
148 if ( (reg_val & 0x0FFFFFFF) == 0xb94402e ) {file.write(" * AM335x family" + newline);}
149 if ( (reg_val & 0xF0000000) == (0 << 28) ) {file.write(" * Silicon Revision 1.0" + newline);}
150 if ( (reg_val & 0xF0000000) == (1 << 28) ) {file.write(" * Silicon Revision 2.0" + newline);}
151 if ( (reg_val & 0xF0000000) == (2 << 28) ) {file.write(" * Silicon Revision 2.1" + newline);}
153 // CONTROL: control_status
154 file.write(newline);
155 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: control_status", 0x44E10040);
156 speedselect_pins = bits32(reg_val, 23, 22);
157 switch (speedselect_pins) {
158 case 0:
159 file.write(" * SYSBOOT[15:14] = 00b (19.2 MHz)" + newline);
160 input_clock = 19.2;
161 break;
162 case 1:
163 file.write(" * SYSBOOT[15:14] = 01b (24 MHz)" + newline);
164 input_clock = 24;
165 break;
166 case 2:
167 file.write(" * SYSBOOT[15:14] = 10b (25 MHz)" + newline);
168 input_clock = 25;
169 break;
170 case 3:
171 file.write(" * SYSBOOT[15:14] = 11b (26 MHz)" + newline);
172 input_clock = 26;
173 break;
174 }
176 // CM_CLKSEL_DPLL_DDR
177 reg_val = printRegisterValue(debugSessionDAP, "CM_CLKSEL_DPLL_DDR", 0x44E00440);
178 dpll_mult = bits32(reg_val, 18, 8);
179 file.write(" * DPLL_MULT = " + d2d(dpll_mult) + " (x" + d2d(dpll_mult) + ")" + newline);
180 dpll_div = bits32(reg_val, 6, 0);
181 file.write(" * DPLL_DIV = " + d2d(dpll_div) + " (/" + d2d(dpll_div+1) + ")" + newline);
182 f_dpll_ddr = input_clock*2*dpll_mult/(dpll_div+1);
184 // CM_DIV_M2_DPLL_DDR
185 reg_val = printRegisterValue(debugSessionDAP, "CM_DIV_M2_DPLL_DDR", 0x44E004A0);
186 if (reg_val & (1<<9)) // CLKST = 1
187 file.write(" * CLKST = 1: M2 output clock enabled" + newline);
188 else
189 file.write(" * CLKST = 0: M2 output clock disabled" + newline);;
190 div_m2 = reg_val & 0x1F;
191 file.write(" * DIVHS = " + d2d(div_m2) + " (/" + d2d(div_m2) + ")" + newline);
193 file.write(newline + "DPLL_DDR Summary" + newline);
194 file.write(" -> F_input = " + d2d(input_clock) + " MHz" + newline);
195 file.write(" -> CLKOUT_M2 = DDR_PLL_CLKOUT = " + f_dpll_ddr / 2 / div_m2 + " MHz" + newline);
197 // EMIF: SDRAM_CONFIG
198 file.write(newline);
199 reg_val = printRegisterValue(debugSessionDAP, "EMIF: SDRAM_CONFIG", 0x4C000008);
200 reg_sdram_type = bits32(reg_val, 31, 29);
201 reg_ibank_pos = bits32(reg_val, 28, 27);
202 reg_ddr_term = bits32(reg_val, 26, 24);
203 reg_ddr2_ddqs = bits32(reg_val, 23, 23);
204 reg_dyn_odt = bits32(reg_val, 22, 21);
205 reg_ddr_disable_dll = bits32(reg_val, 20, 20);
206 reg_sdram_drive = bits32(reg_val, 19, 18);
207 reg_cwl = bits32(reg_val, 17, 16);
208 reg_narrow_mode = bits32(reg_val, 15, 14);
209 reg_cl = bits32(reg_val, 13, 10);
210 reg_rowsize = bits32(reg_val, 9, 7);
211 reg_ibank = bits32(reg_val, 6, 4);
212 reg_ebank = bits32(reg_val, 3, 3);
213 reg_pagesize = bits32(reg_val, 2, 0);
215 var is_ddr3=0;
216 var is_ddr2=0;
217 var is_lpddr=0;
219 switch (reg_sdram_type) {
220 case 0:
221 file.write(" * ERROR! Unsupported memory type (DDR1)" + newline);
222 break;
223 case 1:
224 file.write(" * Bits 31:29 (reg_sdram_type) set for LPDDR" + newline);
225 is_lpddr=1;
226 break;
227 case 2:
228 file.write(" * Bits 31:29 (reg_sdram_type) set for DDR2" + newline);
229 is_ddr2=1;
230 break;
231 case 3:
232 file.write(" * Bits 31:29 (reg_sdram_type) set for DDR3" + newline);
233 is_ddr3=1;
234 break;
235 default:
236 file.write(" * Bits 31:29 (reg_sdram_type) set to invalid selection!" + newline);
237 }
238 file.write(" * Bits 28:27 (reg_ibank_pos) set to " + d2d(reg_ibank_pos) + newline);
239 if (is_ddr3 == 1) {
240 file.write(" * Bits 26:24 (reg_ddr_term) set for ");
241 if ( reg_ddr_term == 0 ) {file.write("termination disabled (000b)\n");}
242 if ( reg_ddr_term == 1 ) {file.write("RZQ/4 (001b)\n");}
243 if ( reg_ddr_term == 2 ) {file.write("RZQ/2 (010b)\n");}
244 if ( reg_ddr_term == 3 ) {file.write("RZQ/6 (011b)\n");}
245 if ( reg_ddr_term == 4 ) {file.write("RZQ/12 (100b)\n");}
246 if ( reg_ddr_term == 5 ) {file.write("RZQ/8 (101b)\n");}
247 if ( reg_ddr_term == 6 ) {file.write("ERROR\n");}
248 if ( reg_ddr_term == 7 ) {file.write("ERROR\n");}
249 }
250 if (is_ddr2 == 1) {
251 file.write(" * Bits 26:24 (reg_ddr_term) set for ");
252 if ( reg_ddr_term == 0 ) {file.write("termination disabled (000b)\n");}
253 if ( reg_ddr_term == 1 ) {file.write("75 Ohm (001b)\n");}
254 if ( reg_ddr_term == 2 ) {file.write("150 Ohm (010b)\n");}
255 if ( reg_ddr_term == 3 ) {file.write("50 Ohm (011b)\n");}
256 if ( reg_ddr_term == 4 ) {file.write("ERROR\n");}
257 if ( reg_ddr_term == 5 ) {file.write("ERROR\n");}
258 if ( reg_ddr_term == 6 ) {file.write("ERROR\n");}
259 if ( reg_ddr_term == 7 ) {file.write("ERROR\n");}
260 }
261 if (is_ddr2 == 1) {
262 file.write(" * Bit 23 (reg_ddr2_ddqs) set to ");
263 if ( bits32(reg_val, 23, 23) == 0 ) {
264 file.write("single ended DQS." + newline);
265 } else {
266 file.write("differential DQS." + newline);
267 }
268 }
269 if (is_ddr3 == 1) {
270 file.write(" * Bits 22:21 (reg_dyn_odt) DDR3 dynamic ODT ");
271 if (reg_dyn_odt == 0)
272 file.write("disabled" + newline);
273 else if (reg_dyn_odt == 1)
274 file.write("set to RZQ / 4" + newline);
275 else if (reg_dyn_odt == 2)
276 file.write("set to RZQ / 2" + newline);
277 else
278 file.write("ERROR (illegal value)" + newline);
279 if (reg_ddr_disable_dll == 0)
280 file.write(" * Bit 20 (reg_ddr_disable_dll) set to 0, DDR3 DLL enabled" + newline);
281 else
282 file.write(" * Bit 20 (reg_ddr_disable_dll) set to 1, DDR3 DLL disabled" + newline);
283 file.write(" * Bits 19:18 (reg_sdram_drive) set for ");
284 if ( reg_sdram_drive == 0 ) {file.write("RZQ/6 (00b)\n");}
285 if ( reg_sdram_drive == 1 ) {file.write("RZQ/7 (01b)\n");}
286 if ( reg_sdram_drive == 2 ) {file.write("ERROR (10b)\n");}
287 if ( reg_sdram_drive == 3 ) {file.write("ERROR (11b)\n");}
288 }
289 if (is_lpddr == 1) {
290 file.write(" * Bits 19:18 (reg_sdram_drive) set for ");
291 if ( reg_sdram_drive == 0 ) {file.write("full strength (00b)\n");}
292 if ( reg_sdram_drive == 1 ) {file.write("half strength (01b)\n");}
293 if ( reg_sdram_drive == 2 ) {file.write("quarter strength (10b)\n");}
294 if ( reg_sdram_drive == 3 ) {file.write("eighth strength (11b)\n");}
295 }
296 if (is_ddr2 == 1) {
297 file.write(" * Bits 19:18 (reg_sdram_drive) set for ");
298 if ( reg_sdram_drive == 0 ) {file.write("normal drive (00b)\n");}
299 if ( reg_sdram_drive == 1 ) {file.write("weak drive (01b)\n");}
300 if ( reg_sdram_drive == 2 ) {file.write("ERROR (10b)\n");}
301 if ( reg_sdram_drive == 3 ) {file.write("ERROR (11b)\n");}
302 }
303 if (is_ddr3 == 1) {
304 file.write(" * Bits 17:16 (reg_cwl) set for " + d2d(reg_cwl) + ", CWL = " + d2d(reg_cwl+5) + newline);
305 }
306 if (reg_narrow_mode == 1)
307 file.write(" * Bits 15:14 (reg_narrow_mode) set to 1 -> 16-bit EMIF interface" + newline);
308 else
309 file.write(" * Bits 15:14 (reg_narrow_mode) set to ILLEGAL VALUE" + newline);
310 file.write(" * Bits 13:10 (reg_cl) set to " + d2d(reg_cl) + " -> CL = ");
311 decoded_CL = 0;
312 if (is_ddr2 == 1) {
313 switch (reg_cl) {
314 case 2:
315 case 3:
316 case 4:
317 case 5:
318 decoded_CL = reg_cl;
319 file.write(d2d(decoded_CL) + newline);
320 break;
321 default:
322 file.write("ILLEGAL VALUE" + newline);
323 break;
324 }
325 }
326 if (is_ddr3 == 1) {
327 switch (reg_cl) {
328 case 2:
329 case 4:
330 case 6:
331 case 8:
332 case 10:
333 case 12:
334 case 14:
335 decoded_CL = reg_cl/2 + 4;
336 file.write(d2d(decoded_CL) + newline);
337 break;
338 default:
339 file.write("ILLEGAL VALUE" + newline);
340 break;
341 }
342 }
343 if (is_lpddr == 1) {
344 switch (reg_cl) {
345 case 2:
346 case 3:
347 decoded_CL = reg_cl;
348 file.write(d2d(decoded_CL) + newline);
349 break;
350 default:
351 file.write("ILLEGAL VALUE" + newline);
352 break;
353 }
354 }
355 file.write(" * Bits 09:07 (reg_rowsize) set to " + d2d(reg_rowsize) + " -> " + d2d(reg_rowsize+9) + " row bits" + newline);
356 file.write(" * Bits 06:04 (reg_ibank) set to " + d2d(reg_ibank) + " -> ");
357 switch (reg_ibank) {
358 case 0:
359 case 1:
360 case 2:
361 case 3:
362 file.write(d2d(Math.pow(2,reg_ibank)) + " banks" + newline);
363 break;
364 default:
365 file.write("ILLEGAL VALUE" + newline);
366 break;
367 }
368 if (reg_ebank == 1)
369 file.write(" * Bit 03 ERROR, only 1 chip select allowed!" + newline);
370 file.write(" * Bits 02:00 (reg_pagesize) set to " + d2d(reg_pagesize) + " -> ");
371 switch (reg_pagesize) {
372 case 0:
373 case 1:
374 case 2:
375 case 3:
376 file.write(d2d(reg_pagesize+8) + " column bits" + newline);
377 break;
378 default:
379 file.write("ILLEGAL VALUE" + newline);
380 break;
381 }
383 // EMIF: PWR_MGMT_CTRL
384 file.write(newline);
385 reg_val = printRegisterValue(debugSessionDAP, "EMIF: PWR_MGMT_CTRL", 0x4C000038);
386 reg_lp_mode = bits32(reg_val, 10, 8);
387 switch (reg_lp_mode) {
388 case 1:
389 file.write(" * Bits 10:8 reg_lp_mode set to 1, clock stop mode (WARNING!)" + newline);
390 break;
391 case 2:
392 file.write(" * Bits 10:8 reg_lp_mode set to 2, self refresh (WARNING!)" + newline);
393 break;
394 case 4:
395 file.write(" * Bits 10:8 reg_lp_mode set to 4, power down (WARNING!)" + newline);
396 break;
397 default:
398 file.write(" * Bits 10:8 reg_lp_mode set to " + d2d(reg_lp_mode) + ", auto power management disabled" + newline);
399 break;
400 }
401 reg_sr_tim = bits32(reg_val, 7, 4);
402 if ( (reg_sr_tim < 9) & (reg_lp_mode != 2) ) {
403 file.write(" * Warning: Bits 7:4 (reg_sr_tim) are in violation of Maximum Self-Refresh Command Limit" + newline);
404 file.write(" -> Please see the silicon errata (DDR3: JEDEC Compliance for Maximum Self-Refresh Command Limit) for more details." + newline);
405 file.write(" -> This is only an issue if used in conjunction with reg_lp_mode=2." + newline)
406 } else if ( (reg_sr_tim < 9) & (reg_lp_mode == 2) ) {
407 file.write(" * ERROR: Bits 7:4 (reg_sr_tim) are in violation of Maximum Self-Refresh Command Limit" + newline);
408 }
410 // DDR PHY: DDR_PHY_CTRL_1
411 file.write(newline);
412 reg_val = printRegisterValue(debugSessionDAP, "DDR PHY: DDR_PHY_CTRL_1", 0x4C0000E4);
413 if ( (reg_val & 1<<20) == 0 ) {file.write(" * WARNING: reg_phy_enable_dynamic_pwrdn disabled.\n");}
414 reg_phy_rd_local_odt = bits32(reg_val, 9, 8);
415 file.write(" * Bits 9:8 (reg_phy_rd_local_odt) to " + d2d(reg_phy_rd_local_odt) + " -> ");
416 switch (reg_phy_rd_local_odt) {
417 case 0:
418 case 1:
419 file.write("no termination" + newline);
420 if (is_ddr3 == 1)
421 file.write(" -> Read termination is highly recommended in general for best DDR3 signal integrity" + newline);
422 break;
423 case 2:
424 file.write("full thevenin termination\n");
425 break;
426 case 3:
427 file.write("half thevenin termination\n");
428 break;
429 default:
430 file.write("ILLEGAL VALUE" + newline);
431 break;
432 }
433 reg_read_latency = bits32(reg_val, 4, 0);
434 if( reg_read_latency < decoded_CL+1 )
435 file.write(" * Bits 4:0 (reg_read_latency) set to " + d2d(reg_read_latency) + " -> ERROR: TOO SMALL" + newline);
436 else if (reg_read_latency == decoded_CL+1) {
437 file.write(" * Bits 4:0 (reg_read_latency) set to " + d2d(reg_read_latency) + newline);
438 file.write(" -> If PHY_INVERT_CLKOUT=0, this is an appropriate value." + newline);
439 file.write(" -> If PHY_INVERT_CLKOUT=1, this is too small." + newline);
440 file.write(" -> PHY_INVERT_CLKOUT is a write-only register, so this needs to be" + newline);
441 file.write(" -> inspected closely in the code and RatioSeed spreadsheet." + newline);
442 } else
443 file.write(" * Bits 4:0 (reg_read_latency) set to " + d2d(reg_read_latency) + " -> Ok: CL+2 is typical with PHY_INVERT_CLKOUT=1." + newline);
445 file.write("\n");
446 file.write("*********************\n");
447 file.write("*** Register Dump ***\n")
448 file.write("*********************\n\n");
450 var ddr_config_regs = [
451 0x4C000000,
452 0x4C000004,
453 0x4C000008,
454 0x4C00000C,
455 0x4C000010,
456 0x4C000014,
457 0x4C000018,
458 0x4C00001C,
459 0x4C000020,
460 0x4C000024,
461 0x4C000028,
462 0x4C00002C,
463 0x4C000038,
464 0x4C00003C,
465 0x4C000054,
466 0x4C000058,
467 0x4C00005C,
468 0x4C000080,
469 0x4C000084,
470 0x4C000088,
471 0x4C00008C,
472 0x4C000090,
473 0x4C000098,
474 0x4C00009C,
475 0x4C0000A4,
476 0x4C0000AC,
477 0x4C0000B4,
478 0x4C0000BC,
479 0x4C0000C8,
480 0x4C0000D4,
481 0x4C0000D8,
482 0x4C0000DC,
483 0x4C0000E4,
484 0x4C0000E8,
485 0x4C000100,
486 0x4C000104,
487 0x4C000108,
488 0x4C000120];
490 for (i=0; i<ddr_config_regs.length; i++)
491 {
492 reg_val = getRegisterValue(debugSessionDAP, ddr_config_regs[i]);
493 file.write("*(0x" + d2h(ddr_config_regs[i]) + ")"); // Address
494 file.write(" = 0x" + d2h(reg_val) + "\n"); // Raw Reg Val
495 }
497 if ( use_dap_m3 == 1 ) {
498 // Close (Main) DAP session and use M3 DAP to view Control Registers
499 debugSessionDAP.target.disconnect();
500 debugSessionDAP = ds.openSession("*","CS_DAP_M3");
501 debugSessionDAP.target.connect();
502 }
504 // Restore CM_WKUP_DEBUGSS_CLKCTRL[MODULEMODE]
505 if ( (original_CM_WKUP_DEBUGSS_CLKCTRL & 3) == 0 ) {
506 debugSessionDAP.memory.writeWord(0,0x44e00414,original_CM_WKUP_DEBUGSS_CLKCTRL);
507 }
508 } else {
509 file.write("Skipping read of EMIF registers since EMIF clock disabled.\n");
510 file.write(" * EMIF registers are not readable when in DS0 state\n");
511 file.write(" * If you are attempting to enter DS0 this is normal.\n");
512 file.write(" * CM_PER_L3_CLKSTCTRL = " + d2h(original_CM_PER_L3_CLKSTCTRL) + newline);
513 }
515 file.write("\n");
516 file.write("************************\n");
517 file.write("*** IOCTRL Registers ***\n")
518 file.write("************************\n\n");
520 // CONTROL: DDR_CMD0_IOCTRL
521 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD0_IOCTRL", 0x44E11404);
522 file.write(" * ddr_ba2 " + interpret_cmd_phy_macro(reg_val, 0));
523 file.write(" * ddr_wen " + interpret_cmd_phy_macro(reg_val, 1));
524 file.write(" * ddr_ba0 " + interpret_cmd_phy_macro(reg_val, 2));
525 file.write(" * ddr_a5 " + interpret_cmd_phy_macro(reg_val, 3));
526 file.write(" * ddr_ck " + interpret_cmd_phy_macro(reg_val, 4));
527 file.write(" * ddr_ckn " + interpret_cmd_phy_macro(reg_val, 5));
528 file.write(" * ddr_a3 " + interpret_cmd_phy_macro(reg_val, 6));
529 file.write(" * ddr_a4 " + interpret_cmd_phy_macro(reg_val, 7));
530 file.write(" * ddr_a8 " + interpret_cmd_phy_macro(reg_val, 8));
531 file.write(" * ddr_a9 " + interpret_cmd_phy_macro(reg_val, 9));
532 file.write(" * ddr_a6 " + interpret_cmd_phy_macro(reg_val, 10));
533 file.write(" * Bits 9:5 control ddr_ck and ddr_ckn\n");
534 file.write(" - Slew ");
535 if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}
536 if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}
537 if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}
538 if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}
539 var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;
540 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
541 file.write(" * Bits 4:0 control ddr_ba0, ddr_ba2, ddr_wen, ddr_a[9:8], ddr_a[6:3]\n");
542 file.write(" - Slew ");
543 if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
544 if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
545 if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
546 if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
547 var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
548 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
550 // CONTROL: DDR_CMD1_IOCTRL
551 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD1_IOCTRL", 0x44E11408);
552 file.write(" * ddr_a15 " + interpret_cmd_phy_macro(reg_val, 1));
553 file.write(" * ddr_a2 " + interpret_cmd_phy_macro(reg_val, 2));
554 file.write(" * ddr_a12 " + interpret_cmd_phy_macro(reg_val, 3));
555 file.write(" * ddr_a7 " + interpret_cmd_phy_macro(reg_val, 4));
556 file.write(" * ddr_ba1 " + interpret_cmd_phy_macro(reg_val, 5));
557 file.write(" * ddr_a10 " + interpret_cmd_phy_macro(reg_val, 6));
558 file.write(" * ddr_a0 " + interpret_cmd_phy_macro(reg_val, 7));
559 file.write(" * ddr_a11 " + interpret_cmd_phy_macro(reg_val, 8));
560 file.write(" * ddr_casn " + interpret_cmd_phy_macro(reg_val, 9));
561 file.write(" * ddr_rasn " + interpret_cmd_phy_macro(reg_val, 10));
562 file.write(" * Bits 4:0 control ddr_15, ddr_a[12:10], ddr_a7, ddr_a2, ddr_a0, ddr_ba1, ddr_casn, ddr_rasn\n");
563 file.write(" - Slew ");
564 if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
565 if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
566 if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
567 if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
568 var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
569 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
571 // CONTROL: DDR_CMD2_IOCTRL
572 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD2_IOCTRL", 0x44E1140C);
573 file.write(" * ddr_cke " + interpret_cmd_phy_macro(reg_val, 0));
574 file.write(" * ddr_resetn " + interpret_cmd_phy_macro(reg_val, 1));
575 file.write(" * ddr_odt " + interpret_cmd_phy_macro(reg_val, 2));
576 file.write(" * ddr_a14 " + interpret_cmd_phy_macro(reg_val, 4));
577 file.write(" * ddr_a13 " + interpret_cmd_phy_macro(reg_val, 5));
578 file.write(" * ddr_csn0 " + interpret_cmd_phy_macro(reg_val, 6));
579 file.write(" * ddr_a1 " + interpret_cmd_phy_macro(reg_val, 8));
580 file.write(" * Bits 4:0 control ddr_cke, ddr_resetn, ddr_odt, ddr_csn0, ddr_[a14:13], ddr_a1\n");
581 file.write(" - Slew ");
582 if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
583 if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
584 if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
585 if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
586 var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
587 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
589 // CONTROL: DDR_DATA0_IOCTRL
590 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_DATA0_IOCTRL", 0x44E11440);
591 file.write(" * ddr_d8 " + interpret_data_phy_macro(reg_val, 0));
592 file.write(" * ddr_d9 " + interpret_data_phy_macro(reg_val, 1));
593 file.write(" * ddr_d10 " + interpret_data_phy_macro(reg_val, 2));
594 file.write(" * ddr_d11 " + interpret_data_phy_macro(reg_val, 3));
595 file.write(" * ddr_d12 " + interpret_data_phy_macro(reg_val, 4));
596 file.write(" * ddr_d13 " + interpret_data_phy_macro(reg_val, 5));
597 file.write(" * ddr_d14 " + interpret_data_phy_macro(reg_val, 6));
598 file.write(" * ddr_d15 " + interpret_data_phy_macro(reg_val, 7));
599 file.write(" * ddr_dqm1 " + interpret_data_phy_macro(reg_val, 8));
600 file.write(" * ddr_dqs1 and ddr_dqsn1 " + interpret_data_phy_macro(reg_val, 9));
601 file.write(" * Bits 9:5 control ddr_dqs1, ddr_dqsn1\n");
602 file.write(" - Slew ");
603 if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}
604 if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}
605 if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}
606 if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}
607 var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;
608 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
609 file.write(" * Bits 4:0 control ddr_d[15:8], ddr_dqm1\n");
610 file.write(" - Slew ");
611 if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
612 if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
613 if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
614 if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
615 var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
616 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
618 // CONTROL: DDR_DATA1_IOCTRL
619 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_DATA1_IOCTRL", 0x44E11444);
620 file.write(" * ddr_d0 " + interpret_data_phy_macro(reg_val, 0));
621 file.write(" * ddr_d1 " + interpret_data_phy_macro(reg_val, 1));
622 file.write(" * ddr_d2 " + interpret_data_phy_macro(reg_val, 2));
623 file.write(" * ddr_d3 " + interpret_data_phy_macro(reg_val, 3));
624 file.write(" * ddr_d4 " + interpret_data_phy_macro(reg_val, 4));
625 file.write(" * ddr_d5 " + interpret_data_phy_macro(reg_val, 5));
626 file.write(" * ddr_d6 " + interpret_data_phy_macro(reg_val, 6));
627 file.write(" * ddr_d7 " + interpret_data_phy_macro(reg_val, 7));
628 file.write(" * ddr_dqm0 " + interpret_data_phy_macro(reg_val, 8));
629 file.write(" * ddr_dqs0 and ddr_dqsn0 " + interpret_data_phy_macro(reg_val, 9));
630 file.write(" * Bits 9:5 control ddr_dqs0, ddr_dqsn0\n");
631 file.write(" - Slew ");
632 if ( (reg_val & 0x300) == (0 << 8) ) {file.write("fastest\n");}
633 if ( (reg_val & 0x300) == (1 << 8) ) {file.write("slow\n");}
634 if ( (reg_val & 0x300) == (2 << 8) ) {file.write("fast\n");}
635 if ( (reg_val & 0x300) == (3 << 8) ) {file.write("slowest\n");}
636 var drive_strength_mA = ((reg_val & 0xE0) >> 5) + 5;
637 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
638 file.write(" * Bits 4:0 control ddr_d[7:0], dqm0\n");
639 file.write(" - Slew ");
640 if ( (reg_val & 0x18) == (0 << 3) ) {file.write("fastest\n");}
641 if ( (reg_val & 0x18) == (1 << 3) ) {file.write("slow\n");}
642 if ( (reg_val & 0x18) == (2 << 3) ) {file.write("fast\n");}
643 if ( (reg_val & 0x18) == (3 << 3) ) {file.write("slowest\n");}
644 var drive_strength_mA = ((reg_val & 0x07) >> 0) + 5;
645 file.write(" - Drive Strength " + drive_strength_mA + " mA\n");
647 // CONTROL: DDR_IO_CTRL
648 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_IO_CTRL", 0x44E10E04);
649 if ( (reg_val & (1 << 31)) == (1<<31) ) {
650 file.write(" * Bit 31: Overriding DDR_RESETn (expected for DS0).\n");
651 } else {
652 file.write(" * Bit 31: DDR_RESETn controlled by EMIF.\n");
653 }
654 if ( (reg_val & (1 << 28)) == 0) {
655 file.write(" * Bit 28 (mddr_sel) configured for SSTL, i.e. DDR2/DDR3/DDR3L operation.\n");
656 if (is_lpddr == 1) {file.write("ERROR! Mismatch with SDRAM_CONFIG.\n");}
657 }
658 else {
659 file.write(" * Bit 28 (mddr_sel) configured for LVCMOS, i.e. LPDDR/mDDR operation.\n");
660 if (is_ddr2 == 1) {file.write("ERROR! Mismatch with SDRAM_CONFIG.\n");}
661 if (is_ddr3 == 1) {file.write("ERROR! Mismatch with SDRAM_CONFIG.\n");}
662 }
664 // CONTROL: VTP_CTRL
665 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: VTP_CTRL", 0x44E10E0C);
666 if ( reg_val == 0 ) {
667 file.write(" * VTP disabled (expected in DS0).\n");
668 } else {
669 file.write(" * VTP not disabled (expected in normal operation, but not DS0).\n");
670 }
672 // CONTROL: VREF_CTRL
673 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: VREF_CTRL", 0x44E10E14);
674 if ( (reg_val & 1) == 0 ) {
675 file.write(" * VREF supplied externally (typical).\n");
676 } else {
677 file.write(" * Internal VREF (unusual).\n");
678 }
680 // CONTROL: DDR_CKE_CTRL
681 reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CKE_CTRL", 0x44E1131C);
682 if ( (reg_val & 1) == 0 ) {
683 file.write(" * CKE gated (forces pin low).\n");
684 } else {
685 file.write(" * CKE controlled by EMIF (normal/ungated operation).\n");
686 }
688 file.close();
689 print("Created file " + filename);
690 debugSessionDAP.target.disconnect();
694 //****************************************************************************
695 // getErrorCode
696 //****************************************************************************
697 function getErrorCode(exception)
698 {
699 var ex2 = exception.javaException;
700 if (ex2 instanceof Packages.com.ti.ccstudio.scripting.environment.ScriptingException)
701 {
702 return ex2.getErrorID();
703 }
704 return 0;
705 }