@samitouri / QOSamiQemu / commits / 0da192c45b

hw/ssi: aspeed_smc: Fix direct-read dummy bytes

m25p80 now consumes fast-read dummy phases as byte counts. The ASPEED SMC direct-read path still treated the CEx dummy field as raw cycles and emitted field * 8 SSI transfers. Convert the ASPEED dummy field to SSI byte transfers using the selected direct-read data width. Fixes: ac2810defa9d ("aspeed/smc: handle dummy bytes when doing fast reads in command mode") Signed-off-by: Bin Meng <bin.meng@processmission.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Tested-by: Cédric Le Goater <clg@redhat.com> Message-ID: <20260707083431.219671-8-bin.meng@processmission.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

Bin Meng committed Jul 7, 2026 at 16:34 UTC 0da192c45b9b2820dc2b89ad5bd518be375fb9b3
1 file changed +15 -6
hw/ssi/aspeed_smc.c
+15 -6
@@ -449,19 +449,28 @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
449 return addr;
450 }
451
452 -static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
452 +static int aspeed_smc_flash_dummy_bytes(const AspeedSMCFlash *fl)
453 {
454 const AspeedSMCState *s = fl->controller;
455 uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->cs];
456 uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
457 uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
458 - uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;
458 + uint32_t dummy_bytes = (dummy_high << 2) | dummy_low;
459
460 - if (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA) {
461 - dummies /= 2;
460 + /*
461 + * Scale the controller dummy field to SSI byte transfers using the
462 + * direct-read dummy/address bus width.
463 + */
464 + if ((r_ctrl0 & CTRL_IO_QPI) ||
465 + ((r_ctrl0 & CTRL_IO_QUAD_DATA) &&
466 + (r_ctrl0 & CTRL_IO_QUAD_ADDR_DATA))) {
467 + dummy_bytes *= 4;
468 + } else if ((r_ctrl0 & CTRL_IO_DUAL_DATA) &&
469 + (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA)) {
470 + dummy_bytes *= 2;
471 }
472
464 - return dummies;
473 + return dummy_bytes;
474 }
475
476 static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
@@ -487,7 +496,7 @@ static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
496 * settings, let's check for fast read mode.
497 */
498 if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
490 - for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
499 + for (i = 0; i < aspeed_smc_flash_dummy_bytes(fl); i++) {
500 ssi_transfer(fl->controller->spi, s->regs[R_DUMMY_DATA] & 0xff);
501 }
502 }