index a1950231ea18c45bc163e6c7f6bc98032aacc0a2..48cf00adcc7284675547abca1424c96a67677421 100644 (file)
--- a/am335x-ddr-analysis.dss
+++ b/am335x-ddr-analysis.dss
function d2h(d) {return ("00000000" + (d).toString(16)).slice(-8);}
+// helper function to create decimal numbers in ascii format
+function d2d(d) {return ((+d).toString());}
+
function printRegisterValue(ds, name, addr)
{
value = debugSessionDAP.memory.readWord(0,addr,false);
return value; // return the register value for interrogation
}
+function getRegisterValue(debug, addr)
+{
+ return debug.memory.readWord(0,addr,false);
+}
+
function interpret_cmd_phy_macro(value, index)
{
WD1 = (value >> (21+index)) & 1;
return return_string;
}
+// Inputs:
+// Data - 32-bit register value
+// Upper - Highest bit to keep
+// Lower - Lowest bit to keep
+// (bit 0 refers to LSB, bit 31 to MSB)
+// Return: right aligned data
+function bits32(data, upper, lower)
+{
+ data = data >>> lower; // unsigned right-shift
+ upper = upper - lower;
+ bitmask = 0xFFFFFFFF >>> (31 - upper);
+ return (data & bitmask);
+}
+
// Build a filename that includes date/time
var today = new Date();
var year4digit = today.getFullYear();
var filename = userHomeFolder + '/Desktop/' + 'am335x-ddr-analysis' + filename_date + '.txt';
debugSessionDAP = ds.openSession("*","CS_DAP_M3");
+use_dap_m3 = 1;
try {
debugSessionDAP.target.connect();
print("\n ERROR: Could not connect to DAP_M3.\n");
}
+// Do a test read of Device_ID register at 0x44e10600
+value = debugSessionDAP.memory.readWord(0,0x44e10600,false);
+
+// If it is zero, switch to CS_DAP_DebugSS
+if (value == 0)
+{
+ debugSessionDAP.target.disconnect();
+ debugSessionDAP = ds.openSession("*","CS_DAP_DebugSS");
+ debugSessionDAP.target.connect();
+ use_dap_m3 = 0;
+}
+
var original_CM_WKUP_DEBUGSS_CLKCTRL = debugSessionDAP.memory.readWord(0,0x44e00414,false);
var original_CM_PER_L3_CLKSTCTRL = debugSessionDAP.memory.readWord(0,0x44E0000C,false);
+var newline = "\n";
file = new java.io.FileWriter(filename);
debugSessionDAP.target.connect();
var reg_val;
+
+ // CONTROL: device_id
+ reg_val = printRegisterValue(debugSessionDAP, "CONTROL: device_id", 0x44E10600);
+ if ( (reg_val & 0x0FFFFFFF) == 0xb94402e ) {file.write(" * AM335x family" + newline);}
+ if ( (reg_val & 0xF0000000) == (0 << 28) ) {file.write(" * Silicon Revision 1.0" + newline);}
+ if ( (reg_val & 0xF0000000) == (1 << 28) ) {file.write(" * Silicon Revision 2.0" + newline);}
+ if ( (reg_val & 0xF0000000) == (2 << 28) ) {file.write(" * Silicon Revision 2.1" + newline);}
+
+ // CONTROL: control_status
+ file.write(newline);
+ reg_val = printRegisterValue(debugSessionDAP, "CONTROL: control_status", 0x44E10040);
+ speedselect_pins = bits32(reg_val, 23, 22);
+ switch (speedselect_pins) {
+ case 0:
+ file.write(" * SYSBOOT[15:14] = 00b (19.2 MHz)" + newline);
+ input_clock = 19.2;
+ break;
+ case 1:
+ file.write(" * SYSBOOT[15:14] = 01b (24 MHz)" + newline);
+ input_clock = 24;
+ break;
+ case 2:
+ file.write(" * SYSBOOT[15:14] = 10b (25 MHz)" + newline);
+ input_clock = 25;
+ break;
+ case 3:
+ file.write(" * SYSBOOT[15:14] = 11b (26 MHz)" + newline);
+ input_clock = 26;
+ break;
+ }
+ // CM_CLKSEL_DPLL_DDR
+ reg_val = printRegisterValue(debugSessionDAP, "CM_CLKSEL_DPLL_DDR", 0x44E00440);
+ dpll_mult = bits32(reg_val, 18, 8);
+ file.write(" * DPLL_MULT = " + d2d(dpll_mult) + " (x" + d2d(dpll_mult) + ")" + newline);
+ dpll_div = bits32(reg_val, 6, 0);
+ file.write(" * DPLL_DIV = " + d2d(dpll_div) + " (/" + d2d(dpll_div+1) + ")" + newline);
+ f_dpll_ddr = input_clock*2*dpll_mult/(dpll_div+1);
+
+ // CM_DIV_M2_DPLL_DDR
+ reg_val = printRegisterValue(debugSessionDAP, "CM_DIV_M2_DPLL_DDR", 0x44E004A0);
+ if (reg_val & (1<<9)) // CLKST = 1
+ file.write(" * CLKST = 1: M2 output clock enabled" + newline);
+ else
+ file.write(" * CLKST = 0: M2 output clock disabled" + newline);;
+ div_m2 = reg_val & 0x1F;
+ file.write(" * DIVHS = " + d2d(div_m2) + " (/" + d2d(div_m2) + ")" + newline);
+
+ file.write(newline + "DPLL_DDR Summary" + newline);
+ file.write(" -> F_input = " + d2d(input_clock) + " MHz" + newline);
+ file.write(" -> CLKOUT_M2 = DDR_PLL_CLKOUT = " + f_dpll_ddr / 2 / div_m2 + " MHz" + newline);
+
// EMIF: SDRAM_CONFIG
+ file.write(newline);
reg_val = printRegisterValue(debugSessionDAP, "EMIF: SDRAM_CONFIG", 0x4C000008);
+ reg_sdram_type = bits32(reg_val, 31, 29);
+ reg_ibank_pos = bits32(reg_val, 28, 27);
+ reg_ddr_term = bits32(reg_val, 26, 24);
+ reg_ddr2_ddqs = bits32(reg_val, 23, 23);
+ reg_dyn_odt = bits32(reg_val, 22, 21);
+ reg_ddr_disable_dll = bits32(reg_val, 20, 20);
+ reg_sdram_drive = bits32(reg_val, 19, 18);
+ reg_cwl = bits32(reg_val, 17, 16);
+ reg_narrow_mode = bits32(reg_val, 15, 14);
+ reg_cl = bits32(reg_val, 13, 10);
+ reg_rowsize = bits32(reg_val, 9, 7);
+ reg_ibank = bits32(reg_val, 6, 4);
+ reg_ebank = bits32(reg_val, 3, 3);
+ reg_pagesize = bits32(reg_val, 2, 0);
var is_ddr3=0;
var is_ddr2=0;
var is_lpddr=0;
- if ( (reg_val & 0xE0000000) == (0 << 29) ) {file.write(" * ERROR! Unsupported memory type (DDR1)\n");}
- if ( (reg_val & 0xE0000000) == (1 << 29) ) {is_lpddr=1;}
- if ( (reg_val & 0xE0000000) == (2 << 29) ) {is_ddr2=1;}
- if ( (reg_val & 0xE0000000) == (3 << 29) ) {is_ddr3=1;}
+
+ switch (reg_sdram_type) {
+ case 0:
+ file.write(" * ERROR! Unsupported memory type (DDR1)" + newline);
+ break;
+ case 1:
+ file.write(" * Bits 31:29 (reg_sdram_type) set for LPDDR" + newline);
+ is_lpddr=1;
+ break;
+ case 2:
+ file.write(" * Bits 31:29 (reg_sdram_type) set for DDR2" + newline);
+ is_ddr2=1;
+ break;
+ case 3:
+ file.write(" * Bits 31:29 (reg_sdram_type) set for DDR3" + newline);
+ is_ddr3=1;
+ break;
+ default:
+ file.write(" * Bits 31:29 (reg_sdram_type) set to invalid selection!" + newline);
+ }
+ file.write(" * Bits 28:27 (reg_ibank_pos) set to " + d2d(reg_ibank_pos) + newline);
if (is_ddr3 == 1) {
file.write(" * Bits 26:24 (reg_ddr_term) set for ");
- if ( (reg_val & 0x07000000) == (0 << 24) ) {file.write("termination disabled (000b)\n");}
- if ( (reg_val & 0x07000000) == (1 << 24) ) {file.write("RZQ/4 (001b)\n");}
- if ( (reg_val & 0x07000000) == (2 << 24) ) {file.write("RZQ/2 (010b)\n");}
- if ( (reg_val & 0x07000000) == (3 << 24) ) {file.write("RZQ/6 (011b)\n");}
- if ( (reg_val & 0x07000000) == (4 << 24) ) {file.write("RZQ/12 (100b)\n");}
- if ( (reg_val & 0x07000000) == (5 << 24) ) {file.write("RZQ/8 (101b)\n");}
- if ( (reg_val & 0x07000000) == (6 << 24) ) {file.write("ERROR\n");}
- if ( (reg_val & 0x07000000) == (7 << 24) ) {file.write("ERROR\n");}
+ if ( reg_ddr_term == 0 ) {file.write("termination disabled (000b)\n");}
+ if ( reg_ddr_term == 1 ) {file.write("RZQ/4 (001b)\n");}
+ if ( reg_ddr_term == 2 ) {file.write("RZQ/2 (010b)\n");}
+ if ( reg_ddr_term == 3 ) {file.write("RZQ/6 (011b)\n");}
+ if ( reg_ddr_term == 4 ) {file.write("RZQ/12 (100b)\n");}
+ if ( reg_ddr_term == 5 ) {file.write("RZQ/8 (101b)\n");}
+ if ( reg_ddr_term == 6 ) {file.write("ERROR\n");}
+ if ( reg_ddr_term == 7 ) {file.write("ERROR\n");}
}
if (is_ddr2 == 1) {
file.write(" * Bits 26:24 (reg_ddr_term) set for ");
- if ( (reg_val & 0x07000000) == (0 << 24) ) {file.write("termination disabled (000b)\n");}
- if ( (reg_val & 0x07000000) == (1 << 24) ) {file.write("75 Ohm (001b)\n");}
- if ( (reg_val & 0x07000000) == (2 << 24) ) {file.write("150 Ohm (010b)\n");}
- if ( (reg_val & 0x07000000) == (3 << 24) ) {file.write("50 Ohm (011b)\n");}
- if ( (reg_val & 0x07000000) == (4 << 24) ) {file.write("ERROR\n");}
- if ( (reg_val & 0x07000000) == (5 << 24) ) {file.write("ERROR\n");}
- if ( (reg_val & 0x07000000) == (6 << 24) ) {file.write("ERROR\n");}
- if ( (reg_val & 0x07000000) == (7 << 24) ) {file.write("ERROR\n");}
+ if ( reg_ddr_term == 0 ) {file.write("termination disabled (000b)\n");}
+ if ( reg_ddr_term == 1 ) {file.write("75 Ohm (001b)\n");}
+ if ( reg_ddr_term == 2 ) {file.write("150 Ohm (010b)\n");}
+ if ( reg_ddr_term == 3 ) {file.write("50 Ohm (011b)\n");}
+ if ( reg_ddr_term == 4 ) {file.write("ERROR\n");}
+ if ( reg_ddr_term == 5 ) {file.write("ERROR\n");}
+ if ( reg_ddr_term == 6 ) {file.write("ERROR\n");}
+ if ( reg_ddr_term == 7 ) {file.write("ERROR\n");}
+ }
+ if (is_ddr2 == 1) {
+ file.write(" * Bit 23 (reg_ddr2_ddqs) set to ");
+ if ( bits32(reg_val, 23, 23) == 0 ) {
+ file.write("single ended DQS." + newline);
+ } else {
+ file.write("differential DQS." + newline);
+ }
}
if (is_ddr3 == 1) {
+ file.write(" * Bits 22:21 (reg_dyn_odt) DDR3 dynamic ODT ");
+ if (reg_dyn_odt == 0)
+ file.write("disabled" + newline);
+ else if (reg_dyn_odt == 1)
+ file.write("set to RZQ / 4" + newline);
+ else if (reg_dyn_odt == 2)
+ file.write("set to RZQ / 2" + newline);
+ else
+ file.write("ERROR (illegal value)" + newline);
+ if (reg_ddr_disable_dll == 0)
+ file.write(" * Bit 20 (reg_ddr_disable_dll) set to 0, DDR3 DLL enabled" + newline);
+ else
+ file.write(" * Bit 20 (reg_ddr_disable_dll) set to 1, DDR3 DLL disabled" + newline);
file.write(" * Bits 19:18 (reg_sdram_drive) set for ");
- if ( (reg_val & 0x000C0000) == (0 << 18) ) {file.write("RZQ/6 (00b)\n");}
- if ( (reg_val & 0x000C0000) == (1 << 18) ) {file.write("RZQ/7 (01b)\n");}
- if ( (reg_val & 0x000C0000) == (2 << 18) ) {file.write("ERROR (10b)\n");}
- if ( (reg_val & 0x000C0000) == (3 << 18) ) {file.write("ERROR (11b)\n");}
+ if ( reg_sdram_drive == 0 ) {file.write("RZQ/6 (00b)\n");}
+ if ( reg_sdram_drive == 1 ) {file.write("RZQ/7 (01b)\n");}
+ if ( reg_sdram_drive == 2 ) {file.write("ERROR (10b)\n");}
+ if ( reg_sdram_drive == 3 ) {file.write("ERROR (11b)\n");}
+ }
+ if (is_lpddr == 1) {
+ file.write(" * Bits 19:18 (reg_sdram_drive) set for ");
+ if ( reg_sdram_drive == 0 ) {file.write("full strength (00b)\n");}
+ if ( reg_sdram_drive == 1 ) {file.write("half strength (01b)\n");}
+ if ( reg_sdram_drive == 2 ) {file.write("quarter strength (10b)\n");}
+ if ( reg_sdram_drive == 3 ) {file.write("eighth strength (11b)\n");}
}
if (is_ddr2 == 1) {
file.write(" * Bits 19:18 (reg_sdram_drive) set for ");
- if ( (reg_val & 0x000C0000) == (0 << 18) ) {file.write("normal drive (00b)\n");}
- if ( (reg_val & 0x000C0000) == (1 << 18) ) {file.write("weak drive (01b)\n");}
- if ( (reg_val & 0x000C0000) == (2 << 18) ) {file.write("ERROR (10b)\n");}
- if ( (reg_val & 0x000C0000) == (3 << 18) ) {file.write("ERROR (11b)\n");}
+ if ( reg_sdram_drive == 0 ) {file.write("normal drive (00b)\n");}
+ if ( reg_sdram_drive == 1 ) {file.write("weak drive (01b)\n");}
+ if ( reg_sdram_drive == 2 ) {file.write("ERROR (10b)\n");}
+ if ( reg_sdram_drive == 3 ) {file.write("ERROR (11b)\n");}
+ }
+ if (is_ddr3 == 1) {
+ file.write(" * Bits 17:16 (reg_cwl) set for " + d2d(reg_cwl) + ", CWL = " + d2d(reg_cwl+5) + newline);
+ }
+ if (reg_narrow_mode == 1)
+ file.write(" * Bits 15:14 (reg_narrow_mode) set to 1 -> 16-bit EMIF interface" + newline);
+ else
+ file.write(" * Bits 15:14 (reg_narrow_mode) set to ILLEGAL VALUE" + newline);
+ file.write(" * Bits 13:10 (reg_cl) set to " + d2d(reg_cl) + " -> CL = ");
+ decoded_CL = 0;
+ if (is_ddr2 == 1) {
+ switch (reg_cl) {
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ decoded_CL = reg_cl;
+ file.write(d2d(decoded_CL) + newline);
+ break;
+ default:
+ file.write("ILLEGAL VALUE" + newline);
+ break;
+ }
+ }
+ if (is_ddr3 == 1) {
+ switch (reg_cl) {
+ case 2:
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ case 12:
+ case 14:
+ decoded_CL = reg_cl/2 + 4;
+ file.write(d2d(decoded_CL) + newline);
+ break;
+ default:
+ file.write("ILLEGAL VALUE" + newline);
+ break;
+ }
}
if (is_lpddr == 1) {
- file.write(" * Bits 19:18 (reg_sdram_drive) set for ");
- if ( (reg_val & 0x000C0000) == (0 << 18) ) {file.write("full strength (00b)\n");}
- if ( (reg_val & 0x000C0000) == (1 << 18) ) {file.write("half strength (01b)\n");}
- if ( (reg_val & 0x000C0000) == (2 << 18) ) {file.write("quarter strength (10b)\n");}
- if ( (reg_val & 0x000C0000) == (3 << 18) ) {file.write("eighth strength (11b)\n");}
+ switch (reg_cl) {
+ case 2:
+ case 3:
+ decoded_CL = reg_cl;
+ file.write(d2d(decoded_CL) + newline);
+ break;
+ default:
+ file.write("ILLEGAL VALUE" + newline);
+ break;
+ }
}
-
+ file.write(" * Bits 09:07 (reg_rowsize) set to " + d2d(reg_rowsize) + " -> " + d2d(reg_rowsize+9) + " row bits" + newline);
+ file.write(" * Bits 06:04 (reg_ibank) set to " + d2d(reg_ibank) + " -> ");
+ switch (reg_ibank) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ file.write(d2d(Math.pow(2,reg_ibank)) + " banks" + newline);
+ break;
+ default:
+ file.write("ILLEGAL VALUE" + newline);
+ break;
+ }
+ if (reg_ebank == 1)
+ file.write(" * Bit 03 ERROR, only 1 chip select allowed!" + newline);
+ file.write(" * Bits 02:00 (reg_pagesize) set to " + d2d(reg_pagesize) + " -> ");
+ switch (reg_pagesize) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ file.write(d2d(reg_pagesize+8) + " column bits" + newline);
+ break;
+ default:
+ file.write("ILLEGAL VALUE" + newline);
+ break;
+ }
+
// EMIF: PWR_MGMT_CTRL
reg_val = printRegisterValue(debugSessionDAP, "EMIF: PWR_MGMT_CTRL", 0x4C000038);
if ( (reg_val & 0xF0) < 0x90 ) {
if ( (reg_val & 0x300) == (1 << 8) ) {file.write("no termination (01b)\n");}
if ( (reg_val & 0x300) == (2 << 8) ) {file.write("full thevenin termination\n");}
if ( (reg_val & 0x300) == (3 << 8) ) {file.write("half thevenin termination\n");}
-
- // Close (Main) DAP session and use M3 DAP to view Control Registers
- debugSessionDAP.target.disconnect();
- debugSessionDAP = ds.openSession("*","CS_DAP_M3");
- debugSessionDAP.target.connect();
+
+ file.write("\n");
+ file.write("*********************\n");
+ file.write("*** Register Dump ***\n")
+ file.write("*********************\n\n");
+
+ var ddr_config_regs = [
+ 0x4C000000,
+ 0x4C000004,
+ 0x4C000008,
+ 0x4C00000C,
+ 0x4C000010,
+ 0x4C000014,
+ 0x4C000018,
+ 0x4C00001C,
+ 0x4C000020,
+ 0x4C000024,
+ 0x4C000028,
+ 0x4C00002C,
+ 0x4C000038,
+ 0x4C00003C,
+ 0x4C000054,
+ 0x4C000058,
+ 0x4C00005C,
+ 0x4C000080,
+ 0x4C000084,
+ 0x4C000088,
+ 0x4C00008C,
+ 0x4C000090,
+ 0x4C000098,
+ 0x4C00009C,
+ 0x4C0000A4,
+ 0x4C0000AC,
+ 0x4C0000B4,
+ 0x4C0000BC,
+ 0x4C0000C8,
+ 0x4C0000D4,
+ 0x4C0000D8,
+ 0x4C0000DC,
+ 0x4C0000E4,
+ 0x4C0000E8,
+ 0x4C000100,
+ 0x4C000104,
+ 0x4C000108,
+ 0x4C000120];
+
+ for (i=0; i<ddr_config_regs.length; i++)
+ {
+ reg_val = getRegisterValue(debugSessionDAP, ddr_config_regs[i]);
+ file.write("*(0x" + d2h(ddr_config_regs[i]) + ")"); // Address
+ file.write(" = 0x" + d2h(reg_val) + "\n"); // Raw Reg Val
+ }
+
+ if ( use_dap_m3 == 1 ) {
+ // Close (Main) DAP session and use M3 DAP to view Control Registers
+ debugSessionDAP.target.disconnect();
+ debugSessionDAP = ds.openSession("*","CS_DAP_M3");
+ debugSessionDAP.target.connect();
+ }
// Restore CM_WKUP_DEBUGSS_CLKCTRL[MODULEMODE]
if ( (original_CM_WKUP_DEBUGSS_CLKCTRL & 3) == 0 ) {
file.write(" * If you are attempting to enter DS0 this is normal.\n");
}
+file.write("\n");
+file.write("************************\n");
+file.write("*** IOCTRL Registers ***\n")
+file.write("************************\n\n");
+
// CONTROL: DDR_CMD0_IOCTRL
reg_val = printRegisterValue(debugSessionDAP, "CONTROL: DDR_CMD0_IOCTRL", 0x44E11404);
file.write(" * ddr_ba2 " + interpret_cmd_phy_macro(reg_val, 0));