unplugged-kernel/drivers/mmc/host/mediatek/ComboA/mt6885/msdc_fpga_io.c

146 lines
3.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#ifdef pr_fmt
#undef pr_fmt
#endif
#define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt
#include <linux/io.h>
#include "mtk_sd.h"
#include <mt-plat/mtk_boot.h>
#define FPGA_PWR_GPIO (0x10001E84)
#define FPGA_PWR_GPIO_EO (0x10001E88)
static void __iomem *fpga_pwr_gpio;
static void __iomem *fpga_pwr_gpio_eo;
#define PWR_GPIO (fpga_pwr_gpio)
#define PWR_GPIO_EO (fpga_pwr_gpio_eo)
#define PWR_MASK_VOL_33 (1 << 10)
#define PWR_MASK_VOL_18 (1 << 9)
#define PWR_MASK_CARD (1 << 8)
#define PWR_MASK_VOL_33_MASK (~(1 << 10))
#define PWR_MASK_CARD_MASK (~(1 << 8))
#define PWR_MASK_VOL_18_MASK (~(1 << 9))
void msdc_set_pwr_gpio_dir(void __iomem *fpga_pwr_gpio,
void __iomem *fpga_pwr_gpio_eo)
{
u16 l_val;
l_val = MSDC_READ16(PWR_GPIO_EO);
MSDC_WRITE16(PWR_GPIO_EO,
(l_val | /* PWR_GPIO_L4_DIR | */
PWR_MASK_CARD | PWR_MASK_VOL_33 | PWR_MASK_VOL_18));
l_val = MSDC_READ16(PWR_GPIO_EO);
pr_debug("[%s]: pwr gpio dir = 0x%x\n", __func__, l_val);
}
void msdc_fpga_pwr_init(void)
{
if (fpga_pwr_gpio == NULL) {
fpga_pwr_gpio = ioremap(FPGA_PWR_GPIO, 8);
if (fpga_pwr_gpio == NULL) {
pr_notice("[%s] msdc ioremap error\n", __func__);
WARN_ON(1);
}
fpga_pwr_gpio_eo = fpga_pwr_gpio + 0x4;
pr_notice("FPGA PWR_GPIO, PWR_GPIO_EO address 0x%p, 0x%p\n",
fpga_pwr_gpio, fpga_pwr_gpio_eo);
}
msdc_set_pwr_gpio_dir(fpga_pwr_gpio, fpga_pwr_gpio_eo);
}
bool hwPowerOn_fpga(void)
{
u16 l_val;
int boot_type;
l_val = MSDC_READ16(PWR_GPIO);
boot_type = get_boot_type();
if (boot_type == BOOTDEV_SDMMC) {
MSDC_WRITE16(PWR_GPIO,
(l_val | PWR_MASK_VOL_18 | PWR_MASK_CARD));
} else {
MSDC_WRITE16(PWR_GPIO,
(l_val | PWR_MASK_VOL_33 | PWR_MASK_CARD));
}
l_val = MSDC_READ16(PWR_GPIO);
pr_debug("[%s]: pwr gpio = 0x%x\n", __func__, l_val);
return true;
}
EXPORT_SYMBOL(hwPowerOn_fpga);
bool hwPowerSwitch_fpga(void)
{
u16 l_val;
l_val = MSDC_READ16(PWR_GPIO);
MSDC_WRITE16(PWR_GPIO, (l_val & ~(PWR_MASK_VOL_33)));
l_val = MSDC_READ16(PWR_GPIO);
MSDC_WRITE16(PWR_GPIO, (l_val | PWR_MASK_VOL_18));
l_val = MSDC_READ16(PWR_GPIO);
pr_debug("[%s]: pwr gpio = 0x%x\n", __func__, l_val);
return true;
}
EXPORT_SYMBOL(hwPowerSwitch_fpga);
bool hwPowerDown_fpga(void)
{
u16 l_val;
int boot_type;
l_val = MSDC_READ16(PWR_GPIO);
boot_type = get_boot_type();
if (boot_type == BOOTDEV_SDMMC) {
MSDC_WRITE16(PWR_GPIO,
(l_val & ~(PWR_MASK_VOL_18 | PWR_MASK_CARD)));
} else {
MSDC_WRITE16(PWR_GPIO,
(l_val & ~(PWR_MASK_VOL_18 |
PWR_MASK_VOL_33 | PWR_MASK_CARD)));
}
l_val = MSDC_READ16(PWR_GPIO);
pr_debug("[%s]: pwr gpio = 0x%x\n", __func__, l_val);
return true;
}
EXPORT_SYMBOL(hwPowerDown_fpga);
void msdc_fpga_power(struct msdc_host *host, u32 on)
{
if (on)
hwPowerOn_fpga();
else
hwPowerDown_fpga();
}
void msdc_sd_power_switch(struct msdc_host *host, u32 on)
{
if (on)
hwPowerSwitch_fpga();
}
void msdc_select_clksrc(struct msdc_host *host, int clksrc)
{
host->hclk = msdc_get_hclk(host->id, clksrc);
host->hw->clk_src = clksrc;
pr_notice("[%s]: msdc%d select clk_src as %d(%dKHz)\n", __func__,
host->id, clksrc, host->hclk/1000);
}
/* do we need sync object or not */
void msdc_clk_status(int *status)
{
}