Source
* If Vqmmc is fixed on platform, vqmmc regulator should be unavailable.
// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for Marvell Xenon SDHC as a platform device
*
* Copyright (C) 2016 Marvell, All Rights Reserved.
*
* Author: Hu Ziji <huziji@marvell.com>
* Date: 2016-8-24
*
* Inspired by Jisheng Zhang <jszhang@marvell.com>
* Special thanks to Video BG4 project team.
*/
static int xenon_enable_internal_clk(struct sdhci_host *host)
{
u32 reg;
ktime_t timeout;
reg = sdhci_readl(host, SDHCI_CLOCK_CONTROL);
reg |= SDHCI_CLOCK_INT_EN;
sdhci_writel(host, reg, SDHCI_CLOCK_CONTROL);
/* Wait max 20 ms */
timeout = ktime_add_ms(ktime_get(), 20);
while (1) {
bool timedout = ktime_after(ktime_get(), timeout);
reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
if (reg & SDHCI_CLOCK_INT_STABLE)
break;
if (timedout) {
dev_err(mmc_dev(host->mmc), "Internal clock never stabilised.\n");
return -ETIMEDOUT;
}
usleep_range(900, 1100);
}
return 0;
}
/* Set SDCLK-off-while-idle */
static void xenon_set_sdclk_off_idle(struct sdhci_host *host,
unsigned char sdhc_id, bool enable)
{
u32 reg;
u32 mask;
reg = sdhci_readl(host, XENON_SYS_OP_CTRL);
/* Get the bit shift basing on the SDHC index */
mask = (0x1 << (XENON_SDCLK_IDLEOFF_ENABLE_SHIFT + sdhc_id));
if (enable)
reg |= mask;
else
reg &= ~mask;