You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
770 lines
15 KiB
770 lines
15 KiB
/************************
|
|
function PROBE_DIMM changed by cxk on 09/26/2010
|
|
Single CHIP & USE_SB_I2C mode & DDR2 DIMM can work normal
|
|
DDR3 SDRAM need to be finished!!
|
|
************************/
|
|
|
|
#define BONITO_HTIO_BASE_VA 0x90000efdfc000000
|
|
#define CHIP1_BASE_ADDRESS 0x0000100000000000
|
|
#define CHIP2_BASE_ADDRESS 0x0000200000000000
|
|
#define CHIP3_BASE_ADDRESS 0x0000300000000000
|
|
|
|
#ifndef MULTI_CHIP
|
|
|
|
#ifdef USE_SB_I2C
|
|
LEAF(i2cread)
|
|
/***************
|
|
use register:
|
|
v0, v1
|
|
a0, a1
|
|
***************/
|
|
ori a0,a0,1
|
|
/* set device address */
|
|
//li v0, 0xbfd00000 + SMBUS_HOST_ADDRESS
|
|
dli v0, BONITO_HTIO_BASE_VA + SMBUS_HOST_ADDRESS
|
|
|
|
sb a0, 0(v0);
|
|
|
|
/* store register offset */
|
|
//li v0, 0xbfd00000 + SMBUS_HOST_COMMAND
|
|
dli v0, BONITO_HTIO_BASE_VA + SMBUS_HOST_COMMAND
|
|
sb a1, 0(v0);
|
|
|
|
/* read byte data protocol */
|
|
li v0, 0x08
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_CONTROL
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_CONTROL
|
|
sb v0, 0(v1);
|
|
|
|
/* make sure SMB host ready to start, important!--zfx */
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_STATUS
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_STATUS
|
|
lbu v0, 0(v1)
|
|
andi v0,v0, 0x1f
|
|
beqz v0,1f
|
|
nop
|
|
sb v0, 0(v1)
|
|
lbu v0, 0(v1) #flush the write
|
|
1:
|
|
/* start */
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_CONTROL
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_CONTROL
|
|
lbu v0, 0(v1)
|
|
ori v0, v0, 0x40
|
|
sb v0, 0(v1);
|
|
|
|
/* wait */
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_STATUS
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_STATUS
|
|
1:
|
|
|
|
#if 0
|
|
/* delay */
|
|
li a0, 0x1000
|
|
2:
|
|
bnez a0,2b
|
|
addiu a0, -1
|
|
#endif
|
|
|
|
lbu v0, 0(v1)
|
|
andi v0, SMBUS_HOST_STATUS_BUSY
|
|
bnez v0, 1b #IDEL ?
|
|
nop
|
|
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_STATUS
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_STATUS
|
|
lbu v0, 0(v1)
|
|
andi v0,v0, 0x1f
|
|
beqz v0,1f
|
|
nop
|
|
sb v0, 0(v1) #reset
|
|
lbu v0, 0(v1) #flush the write
|
|
1:
|
|
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_DATA0
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_DATA0
|
|
lbu v0, 0(v1)
|
|
|
|
jr ra
|
|
nop
|
|
END(i2cread)
|
|
#else
|
|
|
|
#ifdef USE_GPIO_I2C
|
|
#include "i2c_firewall.S"
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/*************************
|
|
PROBE_DIMM:
|
|
function: probe the given slot(I2C device id is given in a0),
|
|
if there is no DIMM in this slot, clear SDRAM_TYPE to 0,
|
|
else read the DIMM infor from the SPD and store the infor in s1(CS_MAP at [17:16],
|
|
MEMSIZE at [11:8]).
|
|
use register:
|
|
a0,a1,a2,a3
|
|
v0, v1
|
|
t5, t6
|
|
|
|
t7: store ra
|
|
a0: input, i2c device id(don't change it).
|
|
a1: register offset of i2c device
|
|
*************************/
|
|
#if 0 //debug code, used in PROBE_DIMM, after read i2c, print v0
|
|
//debug------------
|
|
move t5, a0
|
|
move t6, v0
|
|
TTYDBG("\r\nBanks: ")
|
|
move a0, t6
|
|
bal hexserial
|
|
nop
|
|
TTYDBG("\r\n")
|
|
move a0, t5
|
|
move v0, t6
|
|
//------------debug
|
|
|
|
//Test whether i2cread will dead loop
|
|
move t5, a0
|
|
TTYDBG("\r\nIn Probe_DIMM, before i2cread!")
|
|
move a0, t5
|
|
dli a1, 0
|
|
bal i2cread
|
|
nop
|
|
move t5, a0
|
|
TTYDBG("\r\nIn Probe_DIMM, after i2cread!")
|
|
move a0, t5
|
|
#endif
|
|
LEAF(PROBE_DIMM)
|
|
move t7, ra
|
|
|
|
//read the i2c spd for learn,read data is abandon
|
|
dli a1, 0
|
|
bal i2cread
|
|
nop
|
|
|
|
//probe SDRAM type, if SDRAM type error, repeat t6 times.
|
|
dli t6, 8 //max probing times(t6)
|
|
1:
|
|
//delay some time
|
|
dli t5, 0xfff
|
|
2:
|
|
daddiu t5, t5, -1
|
|
bnez t5, 2b
|
|
nop
|
|
|
|
daddiu t6, t6, -1
|
|
|
|
dli a1, 2
|
|
bal i2cread
|
|
nop
|
|
//only bit[7:0] used
|
|
andi v0, v0, 0xff
|
|
/* v0 should be 0xb or 0x8,else error DIMM type */
|
|
dli t5, 0x08
|
|
beq v0, t5, DDR2
|
|
nop
|
|
dli t5, 0x0B
|
|
beq v0, t5, DDR3
|
|
nop
|
|
//this time probe error
|
|
bnez t6, 1b
|
|
nop
|
|
3:
|
|
TTYDBG("\r\nNO DIMM in this slot.\r\n")
|
|
b ERROR_TYPE
|
|
nop
|
|
DDR2:
|
|
dli t5, 0x2
|
|
dsll t5, t5, SDRAM_TYPE_OFFSET
|
|
or s1, s1, t5
|
|
//probe DIMM_TYPE
|
|
dli a1, 20
|
|
bal i2cread
|
|
nop
|
|
//only bit[5:0] used
|
|
andi v0, v0, 0x3f
|
|
//here just recognize RDIMM and UDIMM
|
|
dli t5, 0x01
|
|
beq v0, t5, 1f
|
|
nop
|
|
dli t5, 0x02
|
|
beq v0, t5, 2f
|
|
nop
|
|
TTYDBG("\r\nERROR: DIMM type is not in support range(UDIMM or RDIMM).\r\n")
|
|
b ERROR_TYPE
|
|
nop
|
|
1: //RDIMM
|
|
dli t5, 0x1
|
|
dsll t5, t5, DIMM_TYPE_OFFSET
|
|
or s1, s1, t5
|
|
b 3f
|
|
nop
|
|
2: //UDIMM
|
|
|
|
3:
|
|
//probe DIMM ECC
|
|
dli a1, 11
|
|
bal i2cread
|
|
nop
|
|
//only bit[2:0] used
|
|
andi v0, v0, 0x07
|
|
//here just recognize ECC or not
|
|
andi t5, v0, 0x2
|
|
dsrl t5, t5, 1
|
|
dsll t5, t5, DIMM_ECC_OFFSET
|
|
or s1, s1, t5
|
|
//probe SDRAM_ROW_SIZE
|
|
dli a1, 3
|
|
bal i2cread
|
|
nop
|
|
//only bit[7:0] used
|
|
andi v0, v0, 0xff
|
|
//v0 should < 15
|
|
andi v0, v0, 0x0f
|
|
dli t5, 15
|
|
subu t5, t5, v0
|
|
dsll t5, t5, ROW_SIZE_OFFSET
|
|
or s1, s1, t5
|
|
//probe SDRAM_COL_SIZE
|
|
dli a1, 4
|
|
bal i2cread
|
|
nop
|
|
//only bit[7:0] used
|
|
andi v0, v0, 0xff
|
|
//v0 should < 14
|
|
andi v0, v0, 0x0f
|
|
dli t5, 14
|
|
subu t5, t5, v0
|
|
dsll t5, t5, COL_SIZE_OFFSET
|
|
or s1, s1, t5
|
|
//probe SDRAM BANK number
|
|
dli a1, 17
|
|
bal i2cread
|
|
nop
|
|
//bit[7:0] used
|
|
andi v0, v0, 0xff
|
|
//here just recognize 4 banks or 8 banks
|
|
dli t5, 0x08
|
|
beq v0, t5, 1f
|
|
nop
|
|
dli t5, 0x04
|
|
beq v0, t5, 2f
|
|
nop
|
|
TTYDBG("\r\nERROR: SDRAM Banks number is not in support range(4 or 8).\r\n")
|
|
b ERROR_TYPE
|
|
nop
|
|
1: //8 banks
|
|
dli t5, 0x1
|
|
dsll t5, t5, EIGHT_BANK_OFFSET
|
|
or s1, s1, t5
|
|
b 3f
|
|
nop
|
|
2: //4 banks
|
|
|
|
3:
|
|
//probe DIMM Ranks
|
|
dli a1, 5
|
|
bal i2cread
|
|
nop
|
|
//only bit[2:0] used
|
|
andi v0, v0, 0x7
|
|
//here just recognize 1 ranks or 2 ranks
|
|
dli t5, 0x0
|
|
beq v0, t5, 1f
|
|
nop
|
|
dli t5, 0x1
|
|
beq v0, t5, 2f
|
|
nop
|
|
TTYDBG("\r\nERROR: DIMM Ranks number is not in support range(1 or 2).\r\n")
|
|
b ERROR_TYPE
|
|
nop
|
|
1: //1 rank
|
|
dli t5, 0x1
|
|
b 3f
|
|
nop
|
|
2: //2 ranks
|
|
dli t5, 0x3
|
|
3:
|
|
dsll t5, t5, MC_CS_MAP_OFFSET
|
|
or s1, s1, t5
|
|
//probe DIMM Memory SIZE
|
|
dli a1, 31
|
|
bal i2cread
|
|
nop
|
|
//only bit[7:0] used
|
|
andi v0, v0, 0xff
|
|
//currently only support 1 rank >= 512M & 2 ranks <= 4G, else assume there is NO DIMM
|
|
move t5, v0
|
|
dli t6, 0xe0
|
|
and t5, t5, t6
|
|
beqz t5, 1f
|
|
nop
|
|
//1 rank<= 512M
|
|
dsrl t5, t5, 7
|
|
beqz t5, 2f //1 rank < 512M, error
|
|
nop
|
|
//1 rank = 512M, double the MEMSIZE if there are 2 ranks
|
|
GET_MC_CS_MAP
|
|
dsrl a1, a1, 1 //test the cs 1
|
|
beqz a1, 5f
|
|
nop
|
|
//double the size
|
|
dsll t5, t5, 1
|
|
5:
|
|
dsll t5, t5, DIMM_MEMSIZE_OFFSET
|
|
or s1, s1, t5
|
|
b 3f
|
|
nop
|
|
1: //1 rank >= 1G
|
|
//double the MEMSIZE if there are 2 ranks
|
|
GET_MC_CS_MAP
|
|
dsrl a1, a1, 1 //test the cs 1
|
|
beqz a1, 5f
|
|
nop
|
|
//double the size
|
|
dsll v0, v0, 1
|
|
5:
|
|
dli t5, 0x7
|
|
and t5, t5, v0
|
|
beqz t5, 2f //DIMM SIZE > 4G
|
|
nop
|
|
dsll t5, v0, 1 //MEMSIZE is 512M/unit, v0 is 1G/unit
|
|
dsll t5, t5, DIMM_MEMSIZE_OFFSET
|
|
or s1, s1, t5
|
|
b 3f
|
|
nop
|
|
2:
|
|
//1 rank < 512M or DIMM SIZE > 4G, errors(clear SDRAM_TYPE, assume there is NO DIMM in this slot)
|
|
dli t5, 0x3
|
|
dsll t5, t5, SDRAM_TYPE_OFFSET
|
|
not t5, t5
|
|
and s1, s1, t5
|
|
TTYDBG("\r\nERROR: DIMM size is not in support range(512M~4G).\r\n")
|
|
b ERROR_TYPE
|
|
nop
|
|
3:
|
|
//DDR2 probe finished
|
|
b end
|
|
nop
|
|
DDR3: //DDR3 SDRAM
|
|
dli t5, 0x3
|
|
dsll t5, t5, SDRAM_TYPE_OFFSET
|
|
or s1, s1, t5
|
|
//!!!!!!need to be completed
|
|
b end
|
|
nop
|
|
|
|
ERROR_TYPE:
|
|
//no DIMM or unrecognized DIMM in this slot
|
|
dli t5, 0x3
|
|
dsll t5, t5, SDRAM_TYPE_OFFSET
|
|
not t5, t5
|
|
and s1, s1, t5
|
|
end:
|
|
jr t7
|
|
nop
|
|
END(PROBE_DIMM)
|
|
|
|
#else //Multi chips
|
|
//not checked now!!!!!!!!!!1
|
|
/****************************************************/
|
|
/* for multi-chip mode */
|
|
/****************************************************/
|
|
|
|
/* input: a0,a1,a2
|
|
a0: device ID
|
|
a1: register offset
|
|
a2: chip ID (0,1,2,3)
|
|
changed registers: v0,v1,t3
|
|
*/
|
|
LEAF(i2cread)
|
|
ori a0,a0,1
|
|
|
|
/* added address offset according chip ID */
|
|
beqz a2,88f
|
|
nop
|
|
beq a2,0x1, 81f
|
|
nop
|
|
beq a2,0x2, 82f
|
|
nop
|
|
|
|
dli t3, CHIP3_BASE_ADDRESS
|
|
b 88f
|
|
|
|
81: dli t3, CHIP1_BASE_ADDRESS
|
|
b 88f
|
|
nop
|
|
82: dli t3, CHIP2_BASE_ADDRESS
|
|
b 88f
|
|
nop
|
|
88:
|
|
/* set device address */
|
|
//li v0, 0xbfd00000 + SMBUS_HOST_ADDRESS
|
|
dli v0, BONITO_HTIO_BASE_VA + SMBUS_HOST_ADDRESS
|
|
dadd v0,v0,t3
|
|
sb a0, 0(v0);
|
|
|
|
/* store register offset */
|
|
//li v0, 0xbfd00000 + SMBUS_HOST_COMMAND
|
|
dli v0, BONITO_HTIO_BASE_VA + SMBUS_HOST_COMMAND
|
|
dadd v0,v0,t3
|
|
sb a1, 0(v0);
|
|
|
|
/* read byte data protocol */
|
|
li v0, 0x08
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_CONTROL
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_CONTROL
|
|
dadd v1,v1,t3
|
|
sb v0, 0(v1);
|
|
|
|
/* make sure SMB host ready to start, important!--zfx */
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_STATUS
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_STATUS
|
|
dadd v1,v1,t3
|
|
lbu v0, 0(v1)
|
|
andi v0,v0, 0x1f
|
|
beqz v0,1f
|
|
nop
|
|
sb v0, 0(v1)
|
|
lbu v0, 0(v1) #flush the write
|
|
1:
|
|
|
|
/* start */
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_CONTROL
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_CONTROL
|
|
dadd v1,v1,t3
|
|
lbu v0, 0(v1)
|
|
ori v0, v0, 0x40
|
|
sb v0, 0(v1);
|
|
|
|
/* wait */
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_STATUS
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_STATUS
|
|
dadd v1,v1,t3
|
|
1:
|
|
|
|
#if 0
|
|
/* delay */
|
|
li a0, 0x1000
|
|
2:
|
|
bnez a0,2b
|
|
addiu a0, -1
|
|
#endif
|
|
|
|
lbu v0, 0(v1)
|
|
andi v0, SMBUS_HOST_STATUS_BUSY
|
|
bnez v0, 1b #IDEL ?
|
|
nop
|
|
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_STATUS
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_STATUS
|
|
dadd v1,v1,t3
|
|
lbu v0, 0(v1)
|
|
andi v0,v0, 0x1f
|
|
beqz v0,1f
|
|
nop
|
|
sb v0, 0(v1) #reset
|
|
lbu v0, 0(v1) #flush the write
|
|
1:
|
|
|
|
//li v1, 0xbfd00000 + SMBUS_HOST_DATA0
|
|
dli v1, BONITO_HTIO_BASE_VA + SMBUS_HOST_DATA0
|
|
dadd v1,v1,t3
|
|
lbu v0, 0(v1)
|
|
|
|
jr ra
|
|
nop
|
|
END(i2cread)
|
|
|
|
/* input: a0,a1,a2
|
|
a0: I2C device ID
|
|
a1: register offset in the device
|
|
a2: CHIP id (0,1,2,3)
|
|
output: not set
|
|
*/
|
|
LEAF(PROBE_DIMM)
|
|
move a3,ra;
|
|
move s2,a0; //store a0: i2C DEVICE id
|
|
move s3,a1; //store a1: REG offset in i2c dev
|
|
|
|
li a1, 2;
|
|
bal i2cread;
|
|
nop;
|
|
beq v0,SPD_NODEVICE, out;
|
|
nop;
|
|
|
|
|
|
/* set DDR type @ s1[7:7] */
|
|
/* assumed here v0 should be 0xc or 0x8 */
|
|
//bne v0,SPD_TYPEDDR3, ddr2
|
|
andi v0,0x4;
|
|
srl v0,0x2;
|
|
sll v0,DDRTYPE_MASK ;
|
|
or s1,v0;
|
|
|
|
|
|
/* set CONTROLLER_SELECT@ s1[3:2] */
|
|
/* a1 should set to be MC0_USED or MC1_USD */
|
|
/* Firt check whether BOTH MC0 and MC1 used, if
|
|
true,set s1[3:2] = 2b'00
|
|
*/
|
|
or s1,s3;
|
|
andi t1,s1,0xc;
|
|
bne t1,0xc,10f;
|
|
nop
|
|
subu s1,0xc
|
|
|
|
10:
|
|
/* set SIZE_PER_CONTROLLE @ s1[6:4] */
|
|
/* step 1: read out number of DIMMS Ranks(CS) */
|
|
move a0, s2; //store a1: REG offset in i2c dev
|
|
li a1, 5;
|
|
bal i2cread;
|
|
nop;
|
|
andi v0,0x3; // MASK for DIMMS Ranks(CS)
|
|
move t2,v0;
|
|
|
|
//bez t2,out
|
|
nop
|
|
addi t2,0x1
|
|
|
|
/* step 2: read out DIMMS size */
|
|
move a0,s2;
|
|
li a1, 31;
|
|
bal i2cread;
|
|
nop;
|
|
bne v0,SPD_DDR2SIZE_512M, 11f;
|
|
nop;
|
|
//ori s1,DDR2SIZE_512M_MASK;
|
|
li v0, 0x20000000
|
|
b 1f;
|
|
nop;
|
|
11:
|
|
bne v0,SPD_DDR2SIZE_1G, 12f;
|
|
nop;
|
|
//ori s1,DDR2SIZE_1G_MASK;
|
|
li v0, 0x40000000
|
|
b 1f;
|
|
nop;
|
|
12:
|
|
bne v0,SPD_DDR2SIZE_2G, 1f;
|
|
nop;
|
|
//ori s1,DDR2SIZE_2G_MASK; // v0: 0x80 means 1G
|
|
li v0, 0x80000000;
|
|
1:
|
|
/* step 3: calculate each mem SIZE of one slot*/
|
|
beq t2,0x1,21f;
|
|
nop
|
|
sll v0,0x1
|
|
//multu v0,t2;
|
|
|
|
21:
|
|
bne v0,0x20000000, 13f
|
|
nop;
|
|
|
|
/* check whther this channel is smaller than others
|
|
if smller: remove other bits,and set DDRPERSZ_512M
|
|
else: do nothing, don't set PERSIZE_BIT
|
|
// defalut setting 512M leaset MEM size
|
|
*/
|
|
|
|
andi t1,s1,DDR2SIZE_MASK;
|
|
beqz t1,211f;
|
|
nop
|
|
bleu t1,DDR2SIZE_512M_MASK, 15f;
|
|
nop
|
|
li t1,DDR2SIZE_MASK;
|
|
not t2,t1;
|
|
and s1,t2;
|
|
|
|
211:
|
|
ori s1,DDRPERSZ_512M ;
|
|
b 15f;
|
|
nop
|
|
13:
|
|
bne v0,0x40000000, 14f
|
|
nop
|
|
|
|
/* check whther this channel is smaller than others
|
|
if smller: remove other bits,and set DDRPERSZ_1G
|
|
else: do nothing, don't set PERSIZE_BIT
|
|
*/
|
|
andi t1,s1,DDR2SIZE_MASK;
|
|
beqz t1,131f;
|
|
nop
|
|
bleu t1, DDR2SIZE_1G_MASK,15f
|
|
nop
|
|
li t1,DDR2SIZE_MASK;
|
|
not t2,t1;
|
|
and s1,t2;
|
|
|
|
131:
|
|
ori s1,DDRPERSZ_1G;
|
|
b 15f;
|
|
nop
|
|
|
|
14:/* only support 512M,1G,2G per DIMM now */
|
|
bne v0,0x80000000, 15f
|
|
nop
|
|
|
|
/* check whther this channel is smaller than others
|
|
if smller: remove other bits,and set DDRPERSZ_2G
|
|
else: do nothing, don't set PERSIZE_BIT
|
|
*/
|
|
andi t1,s1,DDR2SIZE_MASK;
|
|
beqz t1,141f;
|
|
nop
|
|
bleu t1, DDR2SIZE_2G_MASK,15f
|
|
nop
|
|
li t1,DDR2SIZE_MASK;
|
|
not t2,t1;
|
|
and s1,t2;
|
|
|
|
141:
|
|
ori s1,DDRPERSZ_2G;
|
|
|
|
|
|
15:
|
|
/* check whether MC0 or MC1 used to set CS_MAP */
|
|
bne s3, MC0_USED, 2f;
|
|
nop;
|
|
/* set DDR MC0_CS_MAP @s1[11:8] */
|
|
ori s1, 0x400 // at leaset one bit is selected
|
|
move a0,s2;
|
|
li a1, 5;
|
|
bal i2cread;
|
|
nop;
|
|
andi v0,0x1;
|
|
beq v0,0x0,16f;
|
|
nop;
|
|
ori s1,0x800;
|
|
|
|
16:
|
|
/* set DDR MC0_COL_SIZE @s1[18:16] */
|
|
move a0,s2;
|
|
li a1, 4;
|
|
bal i2cread;
|
|
nop;
|
|
li t0,14;
|
|
sub t0,v0;
|
|
sll t0,0x10;
|
|
or s1,t0;
|
|
|
|
/* set MC0_EIGHT_BANK @s1[19] */
|
|
move a0,s2;
|
|
li a1, 17;
|
|
bal i2cread;
|
|
nop;
|
|
andi v0,0x8;
|
|
srl v0,0x3;
|
|
sll v0,0x13; //MC0_EIGHT_BANK shift
|
|
or s1,v0;
|
|
|
|
/* set DDR MC0_ROW_SIZE @s1[22:20] */
|
|
move a0,s2;
|
|
li a1, 3;
|
|
bal i2cread;
|
|
nop;
|
|
li t0,15;
|
|
sub t0,v0;
|
|
sll t0,0x14;
|
|
or s1,t0;
|
|
|
|
/* set MC0_ECC bit @s1[32] */
|
|
move a0,s2;
|
|
li a1, 11;
|
|
bal i2cread;
|
|
li t0,0x2;
|
|
andi v0,0x2;
|
|
srl v0,0x1;
|
|
dsll v0,32;
|
|
//dli v0,0x100000000 // for test
|
|
or s1,v0;
|
|
|
|
/* set DIMM Type information @s1[33:33] */
|
|
move a0,s2;
|
|
li a1, 20;
|
|
bal i2cread;
|
|
nop;
|
|
andi v0,0x1; // only to check whether in Register Dual In_line memory module
|
|
dsll v0,33;
|
|
or s1,v0;
|
|
|
|
|
|
b out;
|
|
nop;
|
|
|
|
2: /* MC1_USED */
|
|
#if 1
|
|
|
|
/* set DDR MC1_CS_MAP @s1[15:12] ? */
|
|
ori s1, 0x4000 // at leaset one bit is selected
|
|
move a0,s2;
|
|
li a1, 5;
|
|
bal i2cread;
|
|
nop;
|
|
andi v0,0x1;
|
|
beq v0,0x0, 26f
|
|
nop
|
|
ori s1,0x8000
|
|
26:
|
|
|
|
/* set DDR MC1_COL_SIZE @s1[26:24] */
|
|
move a0,s2;
|
|
li a1, 4;
|
|
bal i2cread;
|
|
nop;
|
|
li t0,14;
|
|
sub t0,v0;
|
|
sll t0,0x18;
|
|
or s1,t0;
|
|
|
|
/* set MC1_EIGHT_BANK @s1[27] ? */
|
|
move a0,s2
|
|
li a1, 17;
|
|
bal i2cread;
|
|
nop;
|
|
andi v0,0x8;
|
|
srl v0,0x3;
|
|
sll v0,27; //MC0_EIGHT_BANK shift
|
|
or s1,v0;
|
|
|
|
/* set DDR MC1_ROW_SIZE @s1[30:28] */
|
|
move a0,s2;
|
|
li a1, 3;
|
|
bal i2cread;
|
|
nop;
|
|
li t0,15;
|
|
sub t0,v0;
|
|
sll t0,0x1c;
|
|
or s1,t0;
|
|
|
|
/* set MC1_ECC bit @s1[34] */
|
|
move a0,s2;
|
|
li a1, 11;
|
|
bal i2cread;
|
|
li t0,0x2;
|
|
andi v0,0x2;
|
|
srl v0,0x1;
|
|
dsll v0,34;
|
|
or s1,v0;
|
|
|
|
/* set DIMM Type information @s1[35:35] */
|
|
move a0,s2;
|
|
li a1, 20;
|
|
bal i2cread;
|
|
nop;
|
|
and v0,0x1;// only to check whether in Register Dual In_line memory module
|
|
dsll v0,35;
|
|
or s1,v0;
|
|
|
|
#endif
|
|
|
|
out:/* out of MC0_CS_MAP or MC1_CS_MAP */
|
|
//jr ra
|
|
jr a3
|
|
nop
|
|
END(PROBE_DIMM)
|
|
|
|
#endif
|
|
|