spi: bcm-qspi: choose sysclk setting based on requested speed

Check requested speed for a given transfer before setting
27MHz or 108Mhz sysclk on SoCs that support both. This way
for baud rates below 212Khz we can use 27Mhz clock.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Link: https://lore.kernel.org/r/20211124193353.32311-2-kdasu.kdev@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Kamal Dasu 2021-11-24 14:33:52 -05:00 коммит произвёл Mark Brown
Родитель b79332ef9d
Коммит c74526f947
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 24D68B725D5487D0
1 изменённых файлов: 26 добавлений и 6 удалений

Просмотреть файл

@ -287,6 +287,18 @@ static inline int bcm_qspi_spbr_min(struct bcm_qspi *qspi)
return 8;
}
static u32 bcm_qspi_calc_spbr(u32 clk_speed_hz,
const struct bcm_qspi_parms *xp)
{
u32 spbr = 0;
/* SPBR = System Clock/(2 * SCK Baud Rate) */
if (xp->speed_hz)
spbr = clk_speed_hz / (xp->speed_hz * 2);
return spbr;
}
/* Read qspi controller register*/
static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type,
unsigned int offset)
@ -621,10 +633,18 @@ static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi,
spcr |= MSPI_SPCR3_HALFDUPLEX | MSPI_SPCR3_HDOUTTYPE;
if (bcm_qspi_has_sysclk_108(qspi)) {
/* SYSCLK_108 */
/* check requested baud rate before moving to 108Mhz */
spbr = bcm_qspi_calc_spbr(MSPI_BASE_FREQ * 4, xp);
if (spbr > QSPI_SPBR_MAX) {
/* use SYSCLK_27Mhz for slower baud rates */
spcr &= ~MSPI_SPCR3_SYSCLKSEL_MASK;
qspi->base_clk = MSPI_BASE_FREQ;
} else {
/* SYSCLK_108Mhz */
spcr |= MSPI_SPCR3_SYSCLKSEL_108;
qspi->base_clk = MSPI_BASE_FREQ * 4;
}
}
if (xp->bits_per_word > 16) {
/* data_reg_size 1 (64bit) */
@ -649,9 +669,9 @@ static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi,
bcm_qspi_write(qspi, MSPI, MSPI_SPCR3, spcr);
}
if (xp->speed_hz)
spbr = qspi->base_clk / (2 * xp->speed_hz);
/* SCK Baud Rate = System Clock/(2 * SPBR) */
qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2);
spbr = bcm_qspi_calc_spbr(qspi->base_clk, xp);
spbr = clamp_val(spbr, bcm_qspi_spbr_min(qspi), QSPI_SPBR_MAX);
bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, spbr);