Hello all,
The FSBL can read information regarding the Device name, SOM, revision number and Ethernet mac address
as shown below.
--------------------------------------------------------------------------------
Xilinx First Stage Boot Loader (TE modified)
Release 2020.2 Apr 29 2021-13:46:07
Device IDCODE: 23727093
Device Name: 7z020 (7)
Device Revision: 2
--------------------------------------------------------------------------------
TE0720 TE_FsblHookBeforeHandoff_Custom
SoM: TE0720-03-1C R SC REV:05
MAC: D8 80 39 4A 40 DE
--------------------------------------------------------------------------------
Is it possible to access the above information using register space using devmem as shown below for a example address?
If not, how can I have the above information accessible to the PS side.
root@dev:~# devmem 0xFFFFFC00
0xCAFEBABE
Hi,
depends on which of the content you mean....
QuoteDevice IDCODE: 23727093
Device Name: 7z020 (7)
Device Revision: 2
This information comes from Zynq register...see our FSBL code or Zynq TRM
QuoteSoM: TE0720-03-1C R SC REV:05
MAC: D8 80 39 4A 40 DE
This information comes from our CPLD over MDIO interface. You can also read them with PHY tools in linux.
We have also a new CPLD Revision online and some more documentation how you get this infos with the new CPLD version:
https://wiki.trenz-electronic.de/display/PD/TE0720+CPLD
br
John
Thanks a lot John. That was useful information.
Just a couple more question.
I am currently having TE0720-03-1QF module and when I use phytool to inspect the register 3 and register 4
root@dev:/opt# ./phytool read eth0/0x1A/3
0x0c10
root@dev:/opt# ./phytool read eth0/0x1A/4
0x7005
and then decode the SOM, REV, pcb_rev, speed_grade, temp_grade, model based on the above value using the example code given in zynq_fsbl/te_fsbl_hooks.c
// register 3
int rval3= 0x0c10;
int pcb_rev, speed_grade, temp_grade, model;
pcb_rev = (rval3 >>10) & 0x7;
// register 4
int rval4= 0x7005;
/* 0=C, 1=E, 2=I, 3=A */
speed_grade = (rval4 >> 12) & 3;
temp_grade = 0x43;
if ((rval4 & 0x3000)==0x1000) { temp_grade = 0x45; }
if ((rval4 & 0x3000)==0x2000) { temp_grade = 0x49; }
if ((rval4 & 0x3000)==0x3000) { temp_grade = 0x41; }
model = ((rval4 & 0xF00)==0) ? 0x46 : 0x52;
printf("\n\rSoM: TE0720-0%d-%d%c%c SC REV:%02x", pcb_rev, speed_grade, temp_grade, model, rval4 & 0xFF);
I get the following result
SoM: TE0720-03-3AF SC REV:05
Which seems to mis-match with the original Vendor Part number that is TE0720-03-1QF.
The temperature grade and the model seems to mismatch. Moreover, there is no entry for the device with a temperature grade Q,
the code only seems to have C,E,I,A . Unless A -> Automotive maps to Q ?
Can you please clarify the above.
Thanks,
Neels
Hi,
yes for old modules A --> automotive for Q Variant.
you can rename it to Q if you want, but we have updated our CPLD Firmware. And for Systemcontroller CPLD Firmware Revision 07 or newer. Now new encoding is used --> We have changed our article name style and old encoding was not longer possible for CPLD ---> to much variants of CPLD files only to change the name...new FSBL which also encodes new cpld firmware will be released with the next reference design update.
All changes, see: https://wiki.trenz-electronic.de/display/PD/TE0720+CPLD#TE0720CPLD-RevisionChanges
br
John
Thanks John,
I shall look forward to the next release and possibly reprogram the CPLD once it is available.
regards,
Neels
Hi,
CPLD is public:
https://wiki.trenz-electronic.de/display/PD/TE0720+CPLD
https://shop.trenz-electronic.de/de/Download/?path=Trenz_Electronic/Modules_and_Module_Carriers/4x5/TE0720/REV04/Firmware
FSBL code will be updated in one of the next releases.
TE0720 specific part of the FSBL to encode new content:
/*
* Decode SoM model and version information!
*/
// Read register 3
Status = XEmacPs_PhyRead(&Emac, 0x1A, 3, &rval16); if(Status != XST_SUCCESS){ return XST_FAILURE; }
pcb_rev = (rval16 >>10) & 0x7;
// Read register 4
Status = XEmacPs_PhyRead(&Emac, 0x1A, 4, &rval16); if(Status != XST_SUCCESS){ return XST_FAILURE; }
cpld_rev = (rval16 & 0x00FF);
if (cpld_rev <= 6)
{
speed_grade = (rval16 >> 14) & 3;
/* 0=C, 1=E, 2=I, 3=A */
if ((rval16 & 0x3000)==0x0000) { temp_grade = 0x43; }
else if ((rval16 & 0x3000)==0x1000) { temp_grade = 0x45; }
else if ((rval16 & 0x3000)==0x2000) { temp_grade = 0x49; }
else if ((rval16 & 0x3000)==0x3000) { temp_grade = 0x41; }
else { temp_grade = 0x20; }
if ((rval16 & 0x0F00)==0x000) { model1 = 0x20;model2 = 0x20;model3 = 0x46; }
else if ((rval16 & 0x0F00)==0x100) { model1 = 0x20;model2 = 0x20;model3 = 0x52; }
else if ((rval16 & 0x0F00)==0x200) { model1 = 0x20;model2 = 0x4C;model3 = 0x46; }
else if ((rval16 & 0x0F00)==0x300) { model1 = 0x31;model2 = 0x34;model3 = 0x53; }
else { model1 = 0x31;model2 = 0x31;model3 = 0x31; }
xil_printf("\n\rSoM: TE0720-0%d-%d%c%c%c%c SC REV:%02x", pcb_rev, speed_grade, temp_grade, model1, model2, model3, rval16 & 0xFF);
xil_printf("\n\rMAC: ");
for(i = 0; i < 6; i++) {
xil_printf("%02x ", mac_addr[i]);
}
xil_printf("\n\r");
}
else
{
Status = XEmacPs_PhyRead(&Emac, 0x1A, 4, &rval16); if(Status != XST_SUCCESS){ return XST_FAILURE; }
wdt = (rval16 >> 14) & 0x3;
if (wdt == 0b00)
{
wdt_status = "Deactive";
}else if (wdt == 0b01)
{
wdt_status = "Hardware_WDT";
}else if (wdt == 0b10)
{
wdt_status = "Software_WDT";
}else if (wdt == 0b11)
{
wdt_status = "No WDT chip on the board. SOftware_WDT with PL clock";
}
boot_gen = (rval16 >> 12) & 0x3;
if (boot_gen == 0b00)
{
bootmode_gen = "QSPI/SD";
}else if (boot_gen == 0b01)
{
bootmode_gen = "QSPI/JTAG";
}else if (boot_gen == 0b10)
{
bootmode_gen = "JTAG/SD";
}else if (boot_gen == 0b11)
{
bootmode_gen = "default QSPI/JTAG/SD";
}else
{
bootmode_gen = "undefined";
}
pudc = (rval16 >> 11) & 0x1;
if (pudc==1)
{
pudc_mode = "Pulldown";
} else
{
pudc_mode = "Pullup";
}
Status = XEmacPs_PhyRead(&Emac, 0x1A, 4, &rval16); if(Status != XST_SUCCESS){ return XST_FAILURE; }
cpld_bm = (rval16 >> 10)& 0x01;
if (cpld_bm == 0)
{
cpld_bootmode = "Deactive";
// Read register 4
Status = XEmacPs_PhyRead(&Emac, 0x1A, 4, &rval16); if(Status != XST_SUCCESS){ return XST_FAILURE; }
boot = (rval16 >> 8) & 0x3;
if (boot == 0b00)
{
boot_mode = "JTAG";
}
else if (boot == 0b10)
{
boot_mode = "QSPI";
}
else if (boot == 0b11)
{
boot_mode = "SD Card";
}
else if (boot == 0b01)
{
boot_mode = "undefined";
}
// xil_printf("\n\rSoM: TE0720 CPLD_BM=%s(%x) BOOTMOD_GEN=%x(%s) PUDC_MODE=%s(%d) BOOT_MODE=%s(%x) CPLD_REV=%02x", cpld_bootmode, cpld_bm, boot_gen, bootmode_gen, pudc_mode, pudc, boot_mode, boot, cpld_rev);
// xil_printf("\n\rSoM: TE0720 WDT_STATUS=%s(%x) CPLD_BM=%s(%x) BOOTMOD_GEN=%x(%s) PUDC_MODE=%s(%d) BOOT_MODE=%s(%x) CPLD_REV=%02x", wdt_status, wdt, cpld_bootmode, cpld_bm, boot_gen, bootmode_gen, pudc_mode, pudc, boot_mode, boot, cpld_rev);
xil_printf("\n\rCPLD_REV=%02x\n\r",cpld_rev);
xil_printf("\n\rWDT_STATUS=%s(%x)\n\r", wdt_status,wdt);
xil_printf("\n\rCPLD_BM=%s(%x)\n\r",cpld_bootmode, cpld_bm);
xil_printf("\n\rBOOTMOD_GEN=%x(%s)\n\r", boot_gen, bootmode_gen);
xil_printf("\n\rPUDC_MODE=%s(%d)\n\r", pudc_mode, pudc);
xil_printf("\n\rBOOT_MODE=%s(%x)\n\r", boot_mode, boot);
} else
{
cpld_bootmode="Active";
// Read register 12 (CR4[15:8])
Status = XEmacPs_PhyRead(&Emac, 0x1A, 12, &rval16); if(Status != XST_SUCCESS){ return XST_FAILURE; }
boot = (rval16 >> 8) & 0x3;
if (boot == 0b01)
{
boot_mode = "JTAG";
}
else if (boot == 0b10)
{
boot_mode = "QSPI";
}
else if (boot == 0b11)
{
boot_mode = "SD Card";
}
else if (boot == 0b00)
{
boot_mode = "undefined";
}
// xil_printf("\n\rSoM: TE0720 CPLD_BM=%s(%x) BOOTMOD_GEN=%x(%s) PUDC_MODE=%s(%d) BOOT_MODE=%s(%x) CPLD_REV=%02x", cpld_bootmode, cpld_bm, boot_gen, bootmode_gen, pudc_mode, pudc, boot_mode, boot, cpld_rev);
// xil_printf("\n\rSoM: TE0720 WDT_STATUS=%s(%x) CPLD_BM=%s(%x) BOOTMOD_GEN=%x(%s) PUDC_MODE=%s(%d) BOOT_MODE=%s(%x) CPLD_REV=%02x", wdt_status, wdt, cpld_bootmode, cpld_bm, boot_gen, bootmode_gen, pudc_mode, pudc, boot_mode, boot, cpld_rev);
xil_printf("\n\rCPLD_REV=%02x\n\r",cpld_rev);
xil_printf("\n\rWDT_STATUS=%s(%x)\n\r", wdt_status,wdt);
xil_printf("\n\rCPLD_BM=%s(%x)\n\r",cpld_bootmode, cpld_bm);
xil_printf("\n\rBOOTMOD_GEN=%x(%s)\n\r", boot_gen, bootmode_gen);
xil_printf("\n\rPUDC_MODE=%s(%d)\n\r", pudc_mode, pudc);
xil_printf("\n\rBOOT_MODE=%s(%x)\n\r", boot_mode, boot);
}
xil_printf("\n\rMAC: ");
for(i = 0; i < 6; i++) {
xil_printf("%02x ", mac_addr[i]);
}
xil_printf("\n\r");
}
br
John