Skip to content

Commit a779e37

Browse files
committed
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 <[email protected]>
1 parent 71255c4 commit a779e37

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

hw/ssi/aspeed_smc.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,6 @@
196196
* controller. These can be changed when board is initialized with the
197197
* Segment Address Registers.
198198
*/
199-
static const AspeedSegments aspeed_2400_spi1_segments[];
200199
static const AspeedSegments aspeed_2500_spi1_segments[];
201200
static const AspeedSegments aspeed_2500_spi2_segments[];
202201

@@ -382,15 +381,15 @@ static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
382381
return cmd;
383382
}
384383

385-
static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
384+
static inline int aspeed_smc_flash_addr_width(const AspeedSMCFlash *fl)
386385
{
387386
const AspeedSMCState *s = fl->controller;
388387
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
389388

390-
if (asc->segments == aspeed_2400_spi1_segments) {
391-
return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
389+
if (asc->addr_width) {
390+
return asc->addr_width(s);
392391
} else {
393-
return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs));
392+
return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs)) ? 4 : 3;
394393
}
395394
}
396395

@@ -450,7 +449,7 @@ static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
450449
{
451450
const AspeedSMCState *s = fl->controller;
452451
uint8_t cmd = aspeed_smc_flash_cmd(fl);
453-
int i = aspeed_smc_flash_is_4byte(fl) ? 4 : 3;
452+
int i = aspeed_smc_flash_addr_width(fl);
454453

455454
/* Flash access can not exceed CS segment */
456455
addr = aspeed_smc_check_segment_addr(fl, addr);
@@ -558,7 +557,7 @@ static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl, uint64_t data,
558557
unsigned size)
559558
{
560559
AspeedSMCState *s = fl->controller;
561-
uint8_t addr_width = aspeed_smc_flash_is_4byte(fl) ? 4 : 3;
560+
uint8_t addr_width = aspeed_smc_flash_addr_width(fl);
562561

563562
trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies,
564563
(uint8_t) data & 0xff);
@@ -1384,6 +1383,11 @@ static const AspeedSegments aspeed_2400_spi1_segments[] = {
13841383
{ 0x30000000, 64 * MiB },
13851384
};
13861385

1386+
static int aspeed_2400_spi1_addr_width(const AspeedSMCState *s)
1387+
{
1388+
return s->regs[R_SPI_CTRL0] & CTRL_AST2400_SPI_4BYTE ? 4 : 3;
1389+
}
1390+
13871391
static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
13881392
{
13891393
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1405,6 +1409,7 @@ static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
14051409
asc->segment_to_reg = aspeed_smc_segment_to_reg;
14061410
asc->reg_to_segment = aspeed_smc_reg_to_segment;
14071411
asc->dma_ctrl = aspeed_smc_dma_ctrl;
1412+
asc->addr_width = aspeed_2400_spi1_addr_width;
14081413
}
14091414

14101415
static const TypeInfo aspeed_2400_spi1_info = {

include/hw/ssi/aspeed_smc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct AspeedSMCClass {
111111
void (*reg_to_segment)(const AspeedSMCState *s, uint32_t reg,
112112
AspeedSegments *seg);
113113
void (*dma_ctrl)(AspeedSMCState *s, uint32_t value);
114+
int (*addr_width)(const AspeedSMCState *s);
114115
};
115116

116117
#endif /* ASPEED_SMC_H */

0 commit comments

Comments
 (0)