mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 02:24:58 -06:00
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>
This commit is contained in:
parent
71255c48e7
commit
a779e37c68
2 changed files with 13 additions and 7 deletions
|
@ -196,7 +196,6 @@
|
||||||
* controller. These can be changed when board is initialized with the
|
* controller. These can be changed when board is initialized with the
|
||||||
* Segment Address Registers.
|
* Segment Address Registers.
|
||||||
*/
|
*/
|
||||||
static const AspeedSegments aspeed_2400_spi1_segments[];
|
|
||||||
static const AspeedSegments aspeed_2500_spi1_segments[];
|
static const AspeedSegments aspeed_2500_spi1_segments[];
|
||||||
static const AspeedSegments aspeed_2500_spi2_segments[];
|
static const AspeedSegments aspeed_2500_spi2_segments[];
|
||||||
|
|
||||||
|
@ -382,15 +381,15 @@ static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
|
||||||
return cmd;
|
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;
|
const AspeedSMCState *s = fl->controller;
|
||||||
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
|
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
|
||||||
|
|
||||||
if (asc->segments == aspeed_2400_spi1_segments) {
|
if (asc->addr_width) {
|
||||||
return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
|
return asc->addr_width(s);
|
||||||
} else {
|
} 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;
|
const AspeedSMCState *s = fl->controller;
|
||||||
uint8_t cmd = aspeed_smc_flash_cmd(fl);
|
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 */
|
/* Flash access can not exceed CS segment */
|
||||||
addr = aspeed_smc_check_segment_addr(fl, addr);
|
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)
|
unsigned size)
|
||||||
{
|
{
|
||||||
AspeedSMCState *s = fl->controller;
|
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,
|
trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies,
|
||||||
(uint8_t) data & 0xff);
|
(uint8_t) data & 0xff);
|
||||||
|
@ -1384,6 +1383,11 @@ static const AspeedSegments aspeed_2400_spi1_segments[] = {
|
||||||
{ 0x30000000, 64 * MiB },
|
{ 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)
|
static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
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->segment_to_reg = aspeed_smc_segment_to_reg;
|
||||||
asc->reg_to_segment = aspeed_smc_reg_to_segment;
|
asc->reg_to_segment = aspeed_smc_reg_to_segment;
|
||||||
asc->dma_ctrl = aspeed_smc_dma_ctrl;
|
asc->dma_ctrl = aspeed_smc_dma_ctrl;
|
||||||
|
asc->addr_width = aspeed_2400_spi1_addr_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo aspeed_2400_spi1_info = {
|
static const TypeInfo aspeed_2400_spi1_info = {
|
||||||
|
|
|
@ -111,6 +111,7 @@ struct AspeedSMCClass {
|
||||||
void (*reg_to_segment)(const AspeedSMCState *s, uint32_t reg,
|
void (*reg_to_segment)(const AspeedSMCState *s, uint32_t reg,
|
||||||
AspeedSegments *seg);
|
AspeedSegments *seg);
|
||||||
void (*dma_ctrl)(AspeedSMCState *s, uint32_t value);
|
void (*dma_ctrl)(AspeedSMCState *s, uint32_t value);
|
||||||
|
int (*addr_width)(const AspeedSMCState *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ASPEED_SMC_H */
|
#endif /* ASPEED_SMC_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue