@ -185,7 +185,7 @@
* 0 : 4 bytes
* 0x1FFFFFC : 32 M bytes
*
* DMA length is from 1 byte to 32 MB ( AST2600 , AST10x0 )
* DMA length is from 1 byte to 32 MB ( AST2600 , AST10x0 and AST2700 )
* 0 : 1 byte
* 0x1FFFFFF : 32 M bytes
*/
@ -1938,6 +1938,234 @@ static const TypeInfo aspeed_1030_spi2_info = {
. class_init = aspeed_1030_spi2_class_init ,
} ;
/*
* The FMC Segment Registers of the AST2700 have a 64 KB unit .
* Only bits [ 31 : 16 ] are used for decoding .
*/
# define AST2700_SEG_ADDR_MASK 0xffff0000
static uint32_t aspeed_2700_smc_segment_to_reg ( const AspeedSMCState * s ,
const AspeedSegments * seg )
{
uint32_t reg = 0 ;
/* Disabled segments have a nil register */
if ( ! seg - > size ) {
return 0 ;
}
reg | = ( seg - > addr & AST2700_SEG_ADDR_MASK ) > > 16 ; /* start offset */
reg | = ( seg - > addr + seg - > size - 1 ) & AST2700_SEG_ADDR_MASK ; /* end offset */
return reg ;
}
static void aspeed_2700_smc_reg_to_segment ( const AspeedSMCState * s ,
uint32_t reg , AspeedSegments * seg )
{
uint32_t start_offset = ( reg < < 16 ) & AST2700_SEG_ADDR_MASK ;
uint32_t end_offset = reg & AST2700_SEG_ADDR_MASK ;
AspeedSMCClass * asc = ASPEED_SMC_GET_CLASS ( s ) ;
if ( reg ) {
seg - > addr = asc - > flash_window_base + start_offset ;
seg - > size = end_offset + ( 64 * KiB ) - start_offset ;
} else {
seg - > addr = asc - > flash_window_base ;
seg - > size = 0 ;
}
}
static const uint32_t aspeed_2700_fmc_resets [ ASPEED_SMC_R_MAX ] = {
[ R_CONF ] = ( CONF_FLASH_TYPE_SPI < < CONF_FLASH_TYPE0 |
CONF_FLASH_TYPE_SPI < < CONF_FLASH_TYPE1 ) ,
[ R_CE_CTRL ] = 0x0000aa00 ,
[ R_CTRL0 ] = 0x406b0641 ,
[ R_CTRL1 ] = 0x00000400 ,
[ R_CTRL2 ] = 0x00000400 ,
[ R_CTRL3 ] = 0x00000400 ,
[ R_SEG_ADDR0 ] = 0x08000000 ,
[ R_SEG_ADDR1 ] = 0x10000800 ,
[ R_SEG_ADDR2 ] = 0x00000000 ,
[ R_SEG_ADDR3 ] = 0x00000000 ,
[ R_DUMMY_DATA ] = 0x00010000 ,
[ R_DMA_DRAM_ADDR_HIGH ] = 0x00000000 ,
[ R_TIMINGS ] = 0x007b0000 ,
} ;
static const MemoryRegionOps aspeed_2700_smc_flash_ops = {
. read = aspeed_smc_flash_read ,
. write = aspeed_smc_flash_write ,
. endianness = DEVICE_LITTLE_ENDIAN ,
. valid = {
. min_access_size = 1 ,
. max_access_size = 8 ,
} ,
} ;
static const AspeedSegments aspeed_2700_fmc_segments [ ] = {
{ 0x0 , 128 * MiB } , /* start address is readonly */
{ 128 * MiB , 128 * MiB } , /* default is disabled but needed for -kernel */
{ 256 * MiB , 128 * MiB } , /* default is disabled but needed for -kernel */
{ 0x0 , 0 } , /* disabled */
} ;
static void aspeed_2700_fmc_class_init ( ObjectClass * klass , void * data )
{
DeviceClass * dc = DEVICE_CLASS ( klass ) ;
AspeedSMCClass * asc = ASPEED_SMC_CLASS ( klass ) ;
dc - > desc = " Aspeed 2700 FMC Controller " ;
asc - > r_conf = R_CONF ;
asc - > r_ce_ctrl = R_CE_CTRL ;
asc - > r_ctrl0 = R_CTRL0 ;
asc - > r_timings = R_TIMINGS ;
asc - > nregs_timings = 3 ;
asc - > conf_enable_w0 = CONF_ENABLE_W0 ;
asc - > cs_num_max = 3 ;
asc - > segments = aspeed_2700_fmc_segments ;
asc - > segment_addr_mask = 0xffffffff ;
asc - > resets = aspeed_2700_fmc_resets ;
asc - > flash_window_base = 0x100000000 ;
asc - > flash_window_size = 1 * GiB ;
asc - > features = ASPEED_SMC_FEATURE_DMA |
ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH ;
asc - > dma_flash_mask = 0x2FFFFFFC ;
asc - > dma_dram_mask = 0xFFFFFFFC ;
asc - > dma_start_length = 1 ;
asc - > nregs = ASPEED_SMC_R_MAX ;
asc - > segment_to_reg = aspeed_2700_smc_segment_to_reg ;
asc - > reg_to_segment = aspeed_2700_smc_reg_to_segment ;
asc - > dma_ctrl = aspeed_2600_smc_dma_ctrl ;
asc - > reg_ops = & aspeed_2700_smc_flash_ops ;
}
static const TypeInfo aspeed_2700_fmc_info = {
. name = " aspeed.fmc-ast2700 " ,
. parent = TYPE_ASPEED_SMC ,
. class_init = aspeed_2700_fmc_class_init ,
} ;
static const AspeedSegments aspeed_2700_spi0_segments [ ] = {
{ 0x0 , 128 * MiB } , /* start address is readonly */
{ 128 * MiB , 128 * MiB } , /* start address is readonly */
{ 0x0 , 0 } , /* disabled */
} ;
static void aspeed_2700_spi0_class_init ( ObjectClass * klass , void * data )
{
DeviceClass * dc = DEVICE_CLASS ( klass ) ;
AspeedSMCClass * asc = ASPEED_SMC_CLASS ( klass ) ;
dc - > desc = " Aspeed 2700 SPI0 Controller " ;
asc - > r_conf = R_CONF ;
asc - > r_ce_ctrl = R_CE_CTRL ;
asc - > r_ctrl0 = R_CTRL0 ;
asc - > r_timings = R_TIMINGS ;
asc - > nregs_timings = 2 ;
asc - > conf_enable_w0 = CONF_ENABLE_W0 ;
asc - > cs_num_max = 2 ;
asc - > segments = aspeed_2700_spi0_segments ;
asc - > segment_addr_mask = 0xffffffff ;
asc - > flash_window_base = 0x180000000 ;
asc - > flash_window_size = 1 * GiB ;
asc - > features = ASPEED_SMC_FEATURE_DMA |
ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH ;
asc - > dma_flash_mask = 0x2FFFFFFC ;
asc - > dma_dram_mask = 0xFFFFFFFC ;
asc - > dma_start_length = 1 ;
asc - > nregs = ASPEED_SMC_R_MAX ;
asc - > segment_to_reg = aspeed_2700_smc_segment_to_reg ;
asc - > reg_to_segment = aspeed_2700_smc_reg_to_segment ;
asc - > dma_ctrl = aspeed_2600_smc_dma_ctrl ;
asc - > reg_ops = & aspeed_2700_smc_flash_ops ;
}
static const TypeInfo aspeed_2700_spi0_info = {
. name = " aspeed.spi0-ast2700 " ,
. parent = TYPE_ASPEED_SMC ,
. class_init = aspeed_2700_spi0_class_init ,
} ;
static const AspeedSegments aspeed_2700_spi1_segments [ ] = {
{ 0x0 , 128 * MiB } , /* start address is readonly */
{ 0x0 , 0 } , /* disabled */
} ;
static void aspeed_2700_spi1_class_init ( ObjectClass * klass , void * data )
{
DeviceClass * dc = DEVICE_CLASS ( klass ) ;
AspeedSMCClass * asc = ASPEED_SMC_CLASS ( klass ) ;
dc - > desc = " Aspeed 2700 SPI1 Controller " ;
asc - > r_conf = R_CONF ;
asc - > r_ce_ctrl = R_CE_CTRL ;
asc - > r_ctrl0 = R_CTRL0 ;
asc - > r_timings = R_TIMINGS ;
asc - > nregs_timings = 2 ;
asc - > conf_enable_w0 = CONF_ENABLE_W0 ;
asc - > cs_num_max = 2 ;
asc - > segments = aspeed_2700_spi1_segments ;
asc - > segment_addr_mask = 0xffffffff ;
asc - > flash_window_base = 0x200000000 ;
asc - > flash_window_size = 1 * GiB ;
asc - > features = ASPEED_SMC_FEATURE_DMA |
ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH ;
asc - > dma_flash_mask = 0x2FFFFFFC ;
asc - > dma_dram_mask = 0xFFFFFFFC ;
asc - > dma_start_length = 1 ;
asc - > nregs = ASPEED_SMC_R_MAX ;
asc - > segment_to_reg = aspeed_2700_smc_segment_to_reg ;
asc - > reg_to_segment = aspeed_2700_smc_reg_to_segment ;
asc - > dma_ctrl = aspeed_2600_smc_dma_ctrl ;
asc - > reg_ops = & aspeed_2700_smc_flash_ops ;
}
static const TypeInfo aspeed_2700_spi1_info = {
. name = " aspeed.spi1-ast2700 " ,
. parent = TYPE_ASPEED_SMC ,
. class_init = aspeed_2700_spi1_class_init ,
} ;
static const AspeedSegments aspeed_2700_spi2_segments [ ] = {
{ 0x0 , 128 * MiB } , /* start address is readonly */
{ 0x0 , 0 } , /* disabled */
} ;
static void aspeed_2700_spi2_class_init ( ObjectClass * klass , void * data )
{
DeviceClass * dc = DEVICE_CLASS ( klass ) ;
AspeedSMCClass * asc = ASPEED_SMC_CLASS ( klass ) ;
dc - > desc = " Aspeed 2700 SPI2 Controller " ;
asc - > r_conf = R_CONF ;
asc - > r_ce_ctrl = R_CE_CTRL ;
asc - > r_ctrl0 = R_CTRL0 ;
asc - > r_timings = R_TIMINGS ;
asc - > nregs_timings = 2 ;
asc - > conf_enable_w0 = CONF_ENABLE_W0 ;
asc - > cs_num_max = 2 ;
asc - > segments = aspeed_2700_spi2_segments ;
asc - > segment_addr_mask = 0xffffffff ;
asc - > flash_window_base = 0x280000000 ;
asc - > flash_window_size = 1 * GiB ;
asc - > features = ASPEED_SMC_FEATURE_DMA |
ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH ;
asc - > dma_flash_mask = 0x0FFFFFFC ;
asc - > dma_dram_mask = 0xFFFFFFFC ;
asc - > dma_start_length = 1 ;
asc - > nregs = ASPEED_SMC_R_MAX ;
asc - > segment_to_reg = aspeed_2700_smc_segment_to_reg ;
asc - > reg_to_segment = aspeed_2700_smc_reg_to_segment ;
asc - > dma_ctrl = aspeed_2600_smc_dma_ctrl ;
asc - > reg_ops = & aspeed_2700_smc_flash_ops ;
}
static const TypeInfo aspeed_2700_spi2_info = {
. name = " aspeed.spi2-ast2700 " ,
. parent = TYPE_ASPEED_SMC ,
. class_init = aspeed_2700_spi2_class_init ,
} ;
static void aspeed_smc_register_types ( void )
{
type_register_static ( & aspeed_smc_flash_info ) ;
@ -1954,6 +2182,10 @@ static void aspeed_smc_register_types(void)
type_register_static ( & aspeed_1030_fmc_info ) ;
type_register_static ( & aspeed_1030_spi1_info ) ;
type_register_static ( & aspeed_1030_spi2_info ) ;
type_register_static ( & aspeed_2700_fmc_info ) ;
type_register_static ( & aspeed_2700_spi0_info ) ;
type_register_static ( & aspeed_2700_spi1_info ) ;
type_register_static ( & aspeed_2700_spi2_info ) ;
}
type_init ( aspeed_smc_register_types )