diff options
author | Cédric Le Goater <clg@kaod.org> | 2021-10-12 08:20:08 +0200 |
---|---|---|
committer | Cédric Le Goater <clg@kaod.org> | 2021-10-12 08:20:08 +0200 |
commit | a779e37c681f17f83e1d31a68c030731ebc8c998 (patch) | |
tree | 3931a0714e1dad7be2d132ace6421ab840e56fe4 /hw/ssi | |
parent | 71255c48e7b902483b94862f4882ddd050fe8ad8 (diff) |
aspeed/smc: Introduce a new addr_width() class handler
The AST2400 SPI controller has a transitional HW interface and it
stores the address width currently in use in a different register than
all the other SMC controllers. It needs special handling when working
in 4B mode.
Make it clear through a class handler. This also removes another use
of the segments array.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'hw/ssi')
-rw-r--r-- | hw/ssi/aspeed_smc.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index 8cc7ccf455..7129341c12 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -196,7 +196,6 @@ * controller. These can be changed when board is initialized with the * Segment Address Registers. */ -static const AspeedSegments aspeed_2400_spi1_segments[]; static const AspeedSegments aspeed_2500_spi1_segments[]; static const AspeedSegments aspeed_2500_spi2_segments[]; @@ -382,15 +381,15 @@ static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl) return cmd; } -static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl) +static inline int aspeed_smc_flash_addr_width(const AspeedSMCFlash *fl) { const AspeedSMCState *s = fl->controller; AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s); - if (asc->segments == aspeed_2400_spi1_segments) { - return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE; + if (asc->addr_width) { + return asc->addr_width(s); } else { - return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs)); + return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs)) ? 4 : 3; } } @@ -450,7 +449,7 @@ static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr) { const AspeedSMCState *s = fl->controller; uint8_t cmd = aspeed_smc_flash_cmd(fl); - int i = aspeed_smc_flash_is_4byte(fl) ? 4 : 3; + int i = aspeed_smc_flash_addr_width(fl); /* Flash access can not exceed CS segment */ addr = aspeed_smc_check_segment_addr(fl, addr); @@ -558,7 +557,7 @@ static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl, uint64_t data, unsigned size) { AspeedSMCState *s = fl->controller; - uint8_t addr_width = aspeed_smc_flash_is_4byte(fl) ? 4 : 3; + uint8_t addr_width = aspeed_smc_flash_addr_width(fl); trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies, (uint8_t) data & 0xff); @@ -1384,6 +1383,11 @@ static const AspeedSegments aspeed_2400_spi1_segments[] = { { 0x30000000, 64 * MiB }, }; +static int aspeed_2400_spi1_addr_width(const AspeedSMCState *s) +{ + return s->regs[R_SPI_CTRL0] & CTRL_AST2400_SPI_4BYTE ? 4 : 3; +} + static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1405,6 +1409,7 @@ static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data) asc->segment_to_reg = aspeed_smc_segment_to_reg; asc->reg_to_segment = aspeed_smc_reg_to_segment; asc->dma_ctrl = aspeed_smc_dma_ctrl; + asc->addr_width = aspeed_2400_spi1_addr_width; } static const TypeInfo aspeed_2400_spi1_info = { |