@ -116,8 +116,6 @@ static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
value = - 1 ;
break ;
}
value = extract64 ( bus - > dma_dram_offset , 0 , 32 ) ;
break ;
case A_I2CD_DMA_LEN :
if ( ! aic - > has_dma ) {
@ -221,6 +219,64 @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
return SHARED_ARRAY_FIELD_EX32 ( bus - > regs , R_I2CD_CMD , TX_STATE ) ;
}
/*
* The AST2700 support the maximum DRAM size is 8 GB .
* The DRAM offset range is from 0x0 _0000_0000 to
* 0x1 _FFFF_FFFF and it is enough to use bits [ 33 : 0 ]
* saving the dram offset .
* Therefore , save the high part physical address bit [ 1 : 0 ]
* of Tx / Rx buffer address as dma_dram_offset bit [ 33 : 32 ] .
*/
static void aspeed_i2c_set_tx_dma_dram_offset ( AspeedI2CBus * bus )
{
AspeedI2CClass * aic = ASPEED_I2C_GET_CLASS ( bus - > controller ) ;
uint32_t value ;
assert ( aic - > has_dma ) ;
if ( aspeed_i2c_is_new_mode ( bus - > controller ) ) {
value = bus - > regs [ R_I2CM_DMA_TX_ADDR ] ;
bus - > dma_dram_offset =
deposit64 ( bus - > dma_dram_offset , 0 , 32 ,
FIELD_EX32 ( value , I2CM_DMA_TX_ADDR , ADDR ) ) ;
if ( ! aic - > has_dma64 ) {
value = bus - > regs [ R_I2CM_DMA_TX_ADDR_HI ] ;
bus - > dma_dram_offset =
deposit64 ( bus - > dma_dram_offset , 32 , 32 ,
extract32 ( value , 0 , 2 ) ) ;
}
} else {
value = bus - > regs [ R_I2CD_DMA_ADDR ] ;
bus - > dma_dram_offset = deposit64 ( bus - > dma_dram_offset , 0 , 32 ,
value & 0x3ffffffc ) ;
}
}
static void aspeed_i2c_set_rx_dma_dram_offset ( AspeedI2CBus * bus )
{
AspeedI2CClass * aic = ASPEED_I2C_GET_CLASS ( bus - > controller ) ;
uint32_t value ;
assert ( aic - > has_dma ) ;
if ( aspeed_i2c_is_new_mode ( bus - > controller ) ) {
value = bus - > regs [ R_I2CM_DMA_RX_ADDR ] ;
bus - > dma_dram_offset =
deposit64 ( bus - > dma_dram_offset , 0 , 32 ,
FIELD_EX32 ( value , I2CM_DMA_RX_ADDR , ADDR ) ) ;
if ( ! aic - > has_dma64 ) {
value = bus - > regs [ R_I2CM_DMA_RX_ADDR_HI ] ;
bus - > dma_dram_offset =
deposit64 ( bus - > dma_dram_offset , 32 , 32 ,
extract32 ( value , 0 , 2 ) ) ;
}
} else {
value = bus - > regs [ R_I2CD_DMA_ADDR ] ;
bus - > dma_dram_offset = deposit64 ( bus - > dma_dram_offset , 0 , 32 ,
value & 0x3ffffffc ) ;
}
}
static int aspeed_i2c_dma_read ( AspeedI2CBus * bus , uint8_t * data )
{
MemTxResult result ;
@ -270,6 +326,7 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus)
if ( aspeed_i2c_is_new_mode ( bus - > controller ) ) {
ARRAY_FIELD_DP32 ( bus - > regs , I2CM_DMA_LEN_STS , TX_LEN , 0 ) ;
}
aspeed_i2c_set_tx_dma_dram_offset ( bus ) ;
while ( bus - > regs [ reg_dma_len ] ) {
uint8_t data ;
ret = aspeed_i2c_dma_read ( bus , & data ) ;
@ -335,6 +392,7 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
ARRAY_FIELD_DP32 ( bus - > regs , I2CM_DMA_LEN_STS , RX_LEN , 0 ) ;
}
aspeed_i2c_set_rx_dma_dram_offset ( bus ) ;
while ( bus - > regs [ reg_dma_len ] ) {
MemTxResult result ;
@ -401,6 +459,7 @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
} else if ( SHARED_ARRAY_FIELD_EX32 ( bus - > regs , reg_cmd , TX_DMA_EN ) ) {
uint8_t data ;
aspeed_i2c_set_tx_dma_dram_offset ( bus ) ;
aspeed_i2c_dma_read ( bus , & data ) ;
return data ;
} else {
@ -657,16 +716,10 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
case A_I2CM_DMA_TX_ADDR :
bus - > regs [ R_I2CM_DMA_TX_ADDR ] = FIELD_EX32 ( value , I2CM_DMA_TX_ADDR ,
ADDR ) ;
bus - > dma_dram_offset =
deposit64 ( bus - > dma_dram_offset , 0 , 32 ,
FIELD_EX32 ( value , I2CM_DMA_TX_ADDR , ADDR ) ) ;
break ;
case A_I2CM_DMA_RX_ADDR :
bus - > regs [ R_I2CM_DMA_RX_ADDR ] = FIELD_EX32 ( value , I2CM_DMA_RX_ADDR ,
ADDR ) ;
bus - > dma_dram_offset =
deposit64 ( bus - > dma_dram_offset , 0 , 32 ,
FIELD_EX32 ( value , I2CM_DMA_RX_ADDR , ADDR ) ) ;
break ;
case A_I2CM_DMA_LEN :
w1t = FIELD_EX32 ( value , I2CM_DMA_LEN , RX_BUF_LEN_W1T ) | |
@ -748,15 +801,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
qemu_log_mask ( LOG_UNIMP , " %s: Slave mode DMA TX is not implemented \n " ,
__func__ ) ;
break ;
/*
* The AST2700 support the maximum DRAM size is 8 GB .
* The DRAM offset range is from 0x0 _0000_0000 to
* 0x1 _FFFF_FFFF and it is enough to use bits [ 33 : 0 ]
* saving the dram offset .
* Therefore , save the high part physical address bit [ 1 : 0 ]
* of Tx / Rx buffer address as dma_dram_offset bit [ 33 : 32 ] .
*/
case A_I2CM_DMA_TX_ADDR_HI :
if ( ! aic - > has_dma64 ) {
qemu_log_mask ( LOG_GUEST_ERROR , " %s: No DMA 64 bits support \n " ,
@ -766,8 +810,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
bus - > regs [ R_I2CM_DMA_TX_ADDR_HI ] = FIELD_EX32 ( value ,
I2CM_DMA_TX_ADDR_HI ,
ADDR_HI ) ;
bus - > dma_dram_offset = deposit64 ( bus - > dma_dram_offset , 32 , 32 ,
extract32 ( value , 0 , 2 ) ) ;
break ;
case A_I2CM_DMA_RX_ADDR_HI :
if ( ! aic - > has_dma64 ) {
@ -778,8 +820,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
bus - > regs [ R_I2CM_DMA_RX_ADDR_HI ] = FIELD_EX32 ( value ,
I2CM_DMA_RX_ADDR_HI ,
ADDR_HI ) ;
bus - > dma_dram_offset = deposit64 ( bus - > dma_dram_offset , 32 , 32 ,
extract32 ( value , 0 , 2 ) ) ;
break ;
case A_I2CS_DMA_TX_ADDR_HI :
qemu_log_mask ( LOG_UNIMP ,
@ -795,8 +835,6 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
bus - > regs [ R_I2CS_DMA_RX_ADDR_HI ] = FIELD_EX32 ( value ,
I2CS_DMA_RX_ADDR_HI ,
ADDR_HI ) ;
bus - > dma_dram_offset = deposit64 ( bus - > dma_dram_offset , 32 , 32 ,
extract32 ( value , 0 , 2 ) ) ;
break ;
default :
qemu_log_mask ( LOG_GUEST_ERROR , " %s: Bad offset 0x% " HWADDR_PRIx " \n " ,
@ -887,9 +925,6 @@ static void aspeed_i2c_bus_old_write(AspeedI2CBus *bus, hwaddr offset,
qemu_log_mask ( LOG_GUEST_ERROR , " %s: No DMA support \n " , __func__ ) ;
break ;
}
bus - > dma_dram_offset = deposit64 ( bus - > dma_dram_offset , 0 , 32 ,
value & 0x3ffffffc ) ;
break ;
case A_I2CD_DMA_LEN :