[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 09/11] aspeed/smc: add DMA calibration settings
From: |
Cédric Le Goater |
Subject: |
[Qemu-devel] [PATCH 09/11] aspeed/smc: add DMA calibration settings |
Date: |
Fri, 31 Aug 2018 12:38:16 +0200 |
When doing calibration, the SPI clock rate in the CE0 Control Register
and the read delay cycles in the Read Timing Compensation Register are
replaced by bit[11:4] of the DMA Control Register.
Signed-off-by: Cédric Le Goater <address@hidden>
---
hw/ssi/aspeed_smc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 534faec4c111..983066f5ad1d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -695,6 +695,56 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr,
unsigned int size)
}
}
+static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
+{
+ /* HCLK/1 .. HCLK/16 */
+ const uint8_t hclk_divisors[] = {
+ 15, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hclk_divisors); i++) {
+ if (hclk_mask == hclk_divisors[i]) {
+ return i + 1;
+ }
+ }
+
+ qemu_log_mask(LOG_GUEST_ERROR, "invalid HCLK mask %x", hclk_mask);
+ return 0;
+}
+
+/*
+ * When doing calibration, the SPI clock rate in the CE0 Control
+ * Register and the read delay cycles in the Read Timing
+ * Compensation Register are replaced by bit[11:4] of the DMA
+ * Control Register.
+ */
+static void aspeed_smc_dma_calibration(AspeedSMCState *s)
+{
+ uint8_t delay =
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
+ uint8_t hclk_mask =
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
+ uint8_t hclk_div = aspeed_smc_hclk_divisor(hclk_mask);
+ uint32_t hclk_shift = (hclk_div - 1) << 2;
+ uint8_t cs;
+
+ /* Only HCLK/1 - HCLK/5 have tunable delays */
+ if (hclk_div && hclk_div < 6) {
+ s->regs[s->r_timings] &= ~(0xf << hclk_shift);
+ s->regs[s->r_timings] |= delay << hclk_shift;
+ }
+
+ /*
+ * TODO: choose CS depending on the DMA address. This is not used
+ * on the field.
+ */
+ cs = 0;
+ s->regs[s->r_ctrl0 + cs] &=
+ ~(CE_CTRL_CLOCK_FREQ_MASK << CE_CTRL_CLOCK_FREQ_SHIFT);
+ s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
+}
+
/*
* Accumulate the result of the reads to provide a checksum that will
* be used to validate the read timing settings.
@@ -709,6 +759,10 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
return;
}
+ if (s->regs[R_DMA_CTRL] & DMA_CTRL_CALIB) {
+ aspeed_smc_dma_calibration(s);
+ }
+
while (s->regs[R_DMA_LEN]) {
cpu_physical_memory_read(s->regs[R_DMA_FLASH_ADDR], &data, 4);
--
2.17.1
- [Qemu-devel] [PATCH 00/11] aspeed: misc fixes and enhancements (SMC), Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 01/11] aspeed/timer: fix compile breakage with clang 3.4.2, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 02/11] hw/arm/aspeed: change the FMC flash model of the AST2500 evb, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 03/11] hw/arm/aspeed: Add an Aspeed machine class, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 04/11] hw/arm/aspeed: add a 'mmio-exec' property to boot from the FMC flash module, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 05/11] aspeed/smc: fix some alignment issues, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 06/11] aspeed/smc: fix default read value, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 07/11] aspeed/smc: add a 'sdram_base' and 'max-ram-size' properties, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 08/11] aspeed/smc: add support for DMAs, Cédric Le Goater, 2018/08/31
- [Qemu-devel] [PATCH 09/11] aspeed/smc: add DMA calibration settings,
Cédric Le Goater <=
- [Qemu-devel] [PATCH 10/11] aspeed/smc: inject errors in DMA checksum, Cédric Le Goater, 2018/08/31
- Re: [Qemu-devel] [PATCH 00/11] aspeed: misc fixes and enhancements (SMC), Joel Stanley, 2018/08/31