blob: 895cb6fc403c43a0ff59fd0e00fce7d934c9b77e [file] [log] [blame]
#include "tests.h"
#include <diags.h>
#include <common.h>
#include <asm/io.h>
#include <mach/comcerto-2000.h>
#include <mach/gpio.h>
#include <mach/clkcore.h>
#include "common_func.h"
#include "serdes_common.h"
#include "sata_common.h"
#define GPIO_BASE 0x90470000
int Comcerto_sata0_test (void)
{
U32 rd_data, ret = -1, offset;
int i;
//bootstrap overwriting
reg_wr(GPIO_BASE + 0x44,0x30000);
//PLL programming to get different clks
reg_wr(0x904B0004,0x0);
reg_wr(0x904B0008,0x0);
reg_wr(0x904B0160,0x3);
reg_wr(0x904B0164,0x3);
reg_wr(0x904B0174,0x6);
// SATA, Port#0 Initialization
// sbphy_init_wait_lane_rdy(bool forPCIE, bool forSATA, bool forSGMII, int PCIE_num, int SATA_num, bool sata_p0_gen1, bool sata_p1_gen1, bool debug)
sbphy_init_wait_lane_rdy(false, true, false, 0, 0, false, false, false);
// sata_oob_detect(bool both_ports, int port_num, bool port0_gen1, bool port1_gen1, bool debug)
//sata_oob_detect(false, 0, false, false, false);
// printf("\nStart SATA BIST Far End Retransmit Test...\n\n");
// Set the Command-List Base Address in the Port#0 Command-List Base Address Register(P0CLB) for SATA Controller
// printf("Set P0.CLB:Command-List Base Address on Port0\n");
// reg_wr(P0CLB, P0_CMD_BASE); //P0_CMD_BASE, 0x83010000
// Set the FIS Base Address in the Port#0 FIS Base Address Register(P0FB) for SATA Controller
// printf("Set P0.FIS:FIS Base Address in the Port0\n");
// reg_wr(P0FIS, P0_FIS_BASE); //P0_FIS_BASE, 0x8301A000
// Clear all the bits for the detected Interface errors on Port0
//printf("Clear P0.SERR\n");
//offset = 0x130;
//reg_wr((SATA_CFG_BASE + offset), 0xFFFFFFFF);
reg_wr(P0SERR, 0xFFFFFFFF);
// Configure the Port0 Command Register to Spin-Up Device, Enable FIS Receive & Start processing the command-list
//printf("Set P0.CMD\n");
//offset = 0x118;
//reg_wr((SATA_CFG_BASE + offset), 0x00000013);
reg_wr(P0CMD, 0x00000013);
// Clear all the Interrupts in the Interrupt Status(IS) Register
//printf("Clear IS :Clear all the Interrupts in the Interrupt Status(IS) Register\n");
//offset = 0x008;
//reg_wr((SATA_CFG_BASE + offset), 0xFFFFFFFF);
reg_wr(IS, 0xFFFFFFFF);
// Read the AHCI Enable bit set in the Global HBA Control Register(GHC)
//offset = 0x004;
//rd_data = reg_rd((SATA_CFG_BASE + offset));
rd_data = reg_rd(GHC);
//printf("GHC = 0x%x\n", rd_data);
//printf("Set P0.GHC:Enable the IRQ in the Global HBA Control Register\n");
//reg_wr((SATA_CFG_BASE + offset), 0x80000002);
reg_wr(GHC, 0x80000002);
// Read the Port0 Command Issue Register(P0CI)
//offset = 0x138;
//rd_data = reg_rd((SATA_CFG_BASE + offset));
rd_data = reg_rd(P0CI);
// printf("P0.CI = 0x%x\n", rd_data);
//// SATA 0
// Start bist loopback initiator
// select the port1 for BIST operation TESTR.PSEL
//offset = 0x0F4;
//reg_wr((SATA_CFG_BASE + offset), 0x0);
reg_wr(TESTR, 0x0);
// select the bist pattern from BISTCR[3:0], currently selecting Low frequency test pattern (LFTP)
//offset = 0x0A4;
//reg_wr((SATA_CFG_BASE + offset), 0x00000008);
reg_wr(BISTCR, 0x00000007);
// Builds a BIST FIS
// Backdoor Load the Command-List for port1 into IRAM (to be replaced with DDR Address Backddor or backdoor in TB)
// printf("Set up CMD for BIST\n");
reg_wr((P0_CMD_BASE), 0x00000205); //[31:16] PRDTL = 0x0001, [4:0] CFL = 5'b01001
reg_wr((P0_CMD_BASE + 0x4), 0x00000000); //PRD Byte Count
reg_wr((P0_CMD_BASE + 0x8), P0_CMD_TABLE); //Command table base
reg_wr((P0_CMD_BASE + 0xC), 0x00000000); //Command table base upper
// Backdoor Load the Command Register FIS words for port1 to Device into IRAM (to be replaced with DDR Address Backddor or backdoor in TB)
//printf("Set up CMD Table for BIST FIS\n");
reg_wr((P0_CMD_TABLE), 0x00100058); // BIST Activate FIS with Far-end retimed
reg_wr((P0_CMD_TABLE + 0x4), 0x33221100); //Dev/Head,CycHigh,CycLow,SectorNum
reg_wr((P0_CMD_TABLE + 0x8), 0x77665544); //Dev/Head,CycHigh,CycLow,SectorNum
reg_wr((P0_CMD_TABLE + 0xC), 0x00000000); //Control,REVD,SectorCnt,SectorCnt
reg_wr((P0_CMD_TABLE + 0x10), 0x00000000); //REVD
reg_wr((P0_CMD_TABLE + 0x14), 0x00000000); //REVD ??
// Backdoor Load the PRDT/PRDT pointer at offset P0_CMD_TABLE + 0x80
reg_wr((P0_CMD_TABLE + 0x80), P0_DAT_BUFF); //Data base address for TX
reg_wr((P0_CMD_TABLE + 0x84), 0x00000000); //Data base address upper
reg_wr((P0_CMD_TABLE + 0x88), 0x00000000); //REVD
reg_wr((P0_CMD_TABLE + 0x8C), 0x800001FF); //ByteCnt
//printf("BIST CMD Kickoff\n");
//offset = 0x138;
//reg_wr((SATA_CFG_BASE + offset), 0x00000001);
reg_wr(P0CI, 0x00000001);
// Waiting until PxSSTS.DET return 4h, when read. it mean is in BIST mode
//offset = 0x128;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(P0SSTS);
// printf("P0.SSTS = 0x%x\n", rd_data);
while((rd_data & 0x00000004) != 0x4)
{
rd_data = reg_rd(P0SSTS);
//printf("P0.SSTS = 0x%x\n", rd_data);
}
// Read BIST FIS Count Register (BISTFCTR)
//offset = 0x0A8;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(BISTFCTR);
//printf("BISTFCTR = 0x%x\n", rd_data);
// Read BIST Status Register (BISTSR)
//offset = 0x0AC;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(BISTSR);
// printf("BISTSR = 0x%x\n", rd_data);
// Read BIST DWORD Error Count Register (BISTDECR)
//offset = 0x0B0;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(BISTDECR);
// printf("BISTDECR = 0x%x\n", rd_data);
if(rd_data == 0x00000000)
{
printf("SATA0 BIST Far End Retransmit Test Passed!\n");
ret = 0;
}
else
printf("SATA0 BIST Far End Retransmit Test Failed!\n");
//pass_ctl();
reg_wr(P0CMD, 0x00000012);
rd_data = reg_rd(P0CI);
printf("P0.CI = 0x%x\n", rd_data);
// Apply COMRESET
reg_wr(P0SCTL,0x1);
printf("Port Reset P0.SCTL = 0x%x\n",0x1);
rd_data = reg_rd(P0SSTS);
printf("P0.SSTS = 0x%x\n", rd_data);
return ret;
}
//// SATA 1
int Comcerto_sata1_test (void)
{
U32 rd_data, ret = -1, offset;
int i;
//bootstrap overwriting
reg_wr(GPIO_BASE + 0x44,0x30000);
//PLL programming to get different clks
reg_wr(0x904B0004,0x0);
reg_wr(0x904B0008,0x0);
reg_wr(0x904B0160,0x3);
reg_wr(0x904B0164,0x3);
reg_wr(0x904B0174,0x6);
// SATA, Port#1 Initialization
// sbphy_init_wait_lane_rdy(bool forPCIE, bool forSATA, bool forSGMII, int PCIE_num, int SATA_num, bool sata_p0_gen1, bool sata_p1_gen1, bool debug)
sbphy_init_wait_lane_rdy(false, true, false, 0, 1, false, false, false);
// sata_oob_detect(bool both_ports, int port_num, bool port0_gen1, bool port1_gen1, bool debug)
//sata_oob_detect(false, 1, false, false, false);
// Clear all the bits for the detected Interface errors on Port1
//printf("Clear P1.SERR\n");
reg_wr(P1SERR, 0xFFFFFFFF);
// Configure the Port1 Command Register to Spin-Up Device, Enable FIS Receive & Start processing the command-list
//printf("Set P1.CMD\n");
reg_wr(P1CMD, 0x00000013);
// Clear all the Interrupts in the Interrupt Status(IS) Register
//printf("Clear IS :Clear all the Interrupts in the Interrupt Status(IS) Register\n");
reg_wr(IS, 0xFFFFFFFF);
// Read the AHCI Enable bit set in the Global HBA Control Register(GHC)
rd_data = reg_rd(GHC);
//printf("GHC = 0x%x\n", rd_data);
// Enable the Interrupts in the Global HBA Control Register
// printf("Set GHC\n");
reg_wr(GHC, 0x80000002);
// Read the Port1 Command Issue Register(P1CI)
rd_data = reg_rd(P1CI);
// Start bist loopback initiator
// printf("Select the port1 for BIST operation TESTR.PSEL\n");
//offset = 0x0F4;
//reg_wr((SATA_CFG_BASE + offset), 0x0);
reg_wr(TESTR, 0x10000);
// select the bist pattern from BISTCR[3:0], currently selecting Low frequency test pattern (LFTP)
//offset = 0x0A4;
//reg_wr((SATA_CFG_BASE + offset), 0x00000008);
reg_wr(BISTCR, 0x00000007);
// Builds a BIST FIS
// Backdoor Load the Command-List for port1 into IRAM (to be replaced with DDR Address Backddor or backdoor in TB)
// printf("Set up CMD for BIST\n");
reg_wr((P1_CMD_BASE), 0x00000205); //[31:16] PRDTL = 0x0001, [4:0] CFL = 5'b01001
reg_wr((P1_CMD_BASE + 0x4), 0x00000000); //PRD Byte Count
reg_wr((P1_CMD_BASE + 0x8), P1_CMD_TABLE); //Command table base
reg_wr((P1_CMD_BASE + 0xC), 0x00000000); //Command table base upper
// Backdoor Load the Command Register FIS words for port1 to Device into IRAM (to be replaced with DDR Address Backddor or backdoor in TB)
//printf("Set up CMD Table for BIST FIS\n");
reg_wr((P1_CMD_TABLE), 0x00100058); // BIST Activate FIS with Far-end retimed
reg_wr((P1_CMD_TABLE + 0x4), 0x33221100); //Dev/Head,CycHigh,CycLow,SectorNum
reg_wr((P1_CMD_TABLE + 0x8), 0x77665544); //Dev/Head,CycHigh,CycLow,SectorNum
reg_wr((P1_CMD_TABLE + 0xC), 0x00000000); //Control,REVD,SectorCnt,SectorCnt
reg_wr((P1_CMD_TABLE + 0x10), 0x00000000); //REVD
reg_wr((P1_CMD_TABLE + 0x14), 0x00000000); //REVD ??
// Backdoor Load the PRDT/PRDT pointer at offset P1_CMD_TABLE + 0x80
reg_wr((P1_CMD_TABLE + 0x80), P1_DAT_BUFF); //Data base address for TX
reg_wr((P1_CMD_TABLE + 0x84), 0x00000000); //Data base address upper
reg_wr((P1_CMD_TABLE + 0x88), 0x00000000); //REVD
reg_wr((P1_CMD_TABLE + 0x8C), 0x800001FF); //ByteCnt
//printf("BIST CMD Kickoff\n");
//offset = 0x138;
//reg_wr((SATA_CFG_BASE + offset), 0x00000001);
reg_wr(P1CI, 0x00000001);
// Waiting until PxSSTS.DET return 4h, when read. it mean is in BIST mode
//offset = 0x128;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(P1SSTS);
// printf("P1.SSTS = 0x%x\n", rd_data);
while((rd_data & 0x00000004) != 0x4)
{
rd_data = reg_rd(P1SSTS);
//printf("P1.SSTS = 0x%x\n", rd_data);
}
// Read BIST FIS Count Register (BISTFCTR)
//offset = 0x0A8;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(BISTFCTR);
//printf("BISTFCTR = 0x%x\n", rd_data);
// Read BIST Status Register (BISTSR)
//offset = 0x0AC;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(BISTSR);
// printf("BISTSR = 0x%x\n", rd_data);
// Read BIST DWORD Error Count Register (BISTDECR)
//offset = 0x0B0;
//rd_data = (SATA_CFG_BASE + offset);
rd_data = reg_rd(BISTDECR);
// printf("BISTDECR = 0x%x\n", rd_data);
if(rd_data == 0x00000000)
{
printf("SATA1 BIST Far End Retransmit Test Passed!\n");
ret = 0;
}
else
printf("SATA1 BIST Far End Retransmit Test Failed!\n");
//pass_ctl();
reg_wr(P1CMD, 0x00000012);
rd_data = reg_rd(P1CI);
printf("P1.CI = 0x%x\n", rd_data);
// Apply COMRESET
reg_wr(P1SCTL,0x1);
printf("Port Reset P1.SCTL = 0x%x\n",0x1);
rd_data = reg_rd(P1SSTS);
printf("P1.SSTS = 0x%x\n", rd_data);
return ret;
}
int Comcerto_sata_test (struct diags_test_param *p)
{
int ret = 0;
ret = Comcerto_sata0_test ();
ret = Comcerto_sata1_test ();
return ret;
}