On 31 August 2018 at 11:38, Cédric Le Goater <c...@kaod.org> wrote: > 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 <c...@kaod.org> > --- > 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. > + */
Not entirely sure what you have in mind by "on the field" here? Not used by Linux? thanks -- PMM