Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Driver for Synopsys DesignWare Cores Mobile Storage Host Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2018 Synaptics Incorporated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Jisheng Zhang <jszhang@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "sdhci-pltfm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define SDHCI_DWCMSHC_ARG2_STUFF	GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /* DWCMSHC specific Mode Select value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DWCMSHC_CTRL_HS400		0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define DWCMSHC_VER_ID			0x500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define DWCMSHC_VER_TYPE		0x504
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define DWCMSHC_HOST_CTRL3		0x508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define DWCMSHC_EMMC_CONTROL		0x52c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define DWCMSHC_EMMC_ATCTRL		0x540
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /* Rockchip specific Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define DWCMSHC_EMMC_DLL_CTRL		0x800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define DWCMSHC_EMMC_DLL_RXCLK		0x804
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define DWCMSHC_EMMC_DLL_TXCLK		0x808
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define DWCMSHC_EMMC_DLL_STRBIN		0x80c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define DECMSHC_EMMC_DLL_CMDOUT		0x810
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define DWCMSHC_EMMC_DLL_STATUS0	0x840
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define DWCMSHC_EMMC_DLL_START		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define DWCMSHC_EMMC_DLL_LOCKED		BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define DWCMSHC_EMMC_DLL_TIMEOUT	BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define DWCMSHC_EMMC_DLL_START_POINT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define DWCMSHC_EMMC_DLL_INC		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define DWCMSHC_EMMC_DLL_DLYENA		BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define DLL_TXCLK_TAPNUM_DEFAULT	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define DLL_TXCLK_TAPNUM_90_DEGREES	0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define DLL_TXCLK_TAPNUM_FROM_SW	BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define DLL_TXCLK_NO_INVERTER		BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define DLL_STRBIN_TAPNUM_DEFAULT	0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define DLL_STRBIN_TAPNUM_FROM_SW	BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define DLL_STRBIN_DELAY_NUM_SEL	BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define DLL_STRBIN_DELAY_NUM_OFFSET	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define DLL_STRBIN_DELAY_NUM_DEFAULT	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define DLL_RXCLK_NO_INVERTER		BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define DWCMSHC_CARD_IS_EMMC		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define DWCMSHC_ENHANCED_STROBE		BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define DLL_CMDOUT_TAPNUM_90_DEGREES	0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define DLL_CMDOUT_TAPNUM_FROM_SW	BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define DLL_CMDOUT_SRC_CLK_NEG		BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define DLL_CMDOUT_EN_SRC_CLK_NEG	BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define DLL_LOCK_WO_TMOUT(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	(((x) & DWCMSHC_EMMC_DLL_TIMEOUT) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define ROCKCHIP_MAX_CLKS		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define BOUNDARY_OK(addr, len) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) struct dwcmshc_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct clk	*bus_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	u32 cclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/* Rockchip specified optional clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct clk_bulk_data rockchip_clks[ROCKCHIP_MAX_CLKS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct reset_control *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	int txclk_tapnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	unsigned int actual_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	u32 acpi_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) struct dwcmshc_driver_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	const struct sdhci_pltfm_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define RK_PLATFROM		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define RK_DLL_CMD_OUT		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define RK_RXCLK_NO_INVERTER	BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * If DMA addr spans 128MB boundary, we split the DMA transfer into two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * so that each DMA transfer doesn't exceed the boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void dwcmshc_adma_write_desc(struct sdhci_host *host, void **desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				    dma_addr_t addr, int len, unsigned int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	int tmplen, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (likely(!len || BOUNDARY_OK(addr, len))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		sdhci_adma_write_desc(host, desc, addr, len, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	offset = addr & (SZ_128M - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	tmplen = SZ_128M - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	sdhci_adma_write_desc(host, desc, addr, tmplen, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	addr += tmplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	len -= tmplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	sdhci_adma_write_desc(host, desc, addr, len, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				     struct mmc_request *mrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct sdhci_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 * block count register which doesn't support stuff bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 * CMD23 argument on dwcmsch host controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		host->flags &= ~SDHCI_AUTO_CMD23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		host->flags |= SDHCI_AUTO_CMD23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	dwcmshc_check_auto_cmd23(mmc, mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	sdhci_request(mmc, mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 				      unsigned int timing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	u16 ctrl_2, ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	/* Select Bus Speed Mode for host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if ((timing == MMC_TIMING_MMC_HS200) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	    (timing == MMC_TIMING_UHS_SDR104))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	else if (timing == MMC_TIMING_UHS_SDR12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	else if ((timing == MMC_TIMING_UHS_SDR25) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		 (timing == MMC_TIMING_MMC_HS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	else if (timing == MMC_TIMING_UHS_SDR50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	else if ((timing == MMC_TIMING_UHS_DDR50) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		 (timing == MMC_TIMING_MMC_DDR52))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	else if (timing == MMC_TIMING_MMC_HS400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		/* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		ctrl = sdhci_readw(host, DWCMSHC_EMMC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		ctrl |= DWCMSHC_CARD_IS_EMMC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		sdhci_writew(host, ctrl, DWCMSHC_EMMC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		ctrl_2 |= DWCMSHC_CTRL_HS400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void dwcmshc_hs400_enhanced_strobe(struct mmc_host *mmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 					  struct mmc_ios *ios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	u32 vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	struct sdhci_host *host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	vendor = sdhci_readl(host, DWCMSHC_EMMC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (ios->enhanced_strobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		vendor |= DWCMSHC_ENHANCED_STROBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		vendor &= ~DWCMSHC_ENHANCED_STROBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	sdhci_writel(host, vendor, DWCMSHC_EMMC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void dwcmshc_rk_set_clock(struct sdhci_host *host, unsigned int clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	u32 txclk_tapnum, extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	host->mmc->actual_clock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	if (clock == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		/* Disable interface clock at initial state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		sdhci_set_clock(host, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	/* Rockchip platform only support 375KHz for identify mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (clock <= 400000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		clock = 375000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (priv->acpi_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		union acpi_object params[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		struct acpi_object_list param_objects;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		params[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		params[0].integer.value  = clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		param_objects.count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		param_objects.pointer = params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		acpi_evaluate_object(ACPI_HANDLE(mmc_dev(host->mmc)), "SCLK", &param_objects, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		err = clk_set_rate(pltfm_host->clk, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	sdhci_set_clock(host, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	/* Disable cmd conflict check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	extra = sdhci_readl(host, DWCMSHC_HOST_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	extra &= ~BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	sdhci_writel(host, extra, DWCMSHC_HOST_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (clock <= 52000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		/* Disable DLL and reset both of sample and drive clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_RXCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		 * Before switching to hs400es mode, the driver will enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		 * enhanced strobe first. PHY needs to configure the parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		 * of enhanced strobe first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		extra = DWCMSHC_EMMC_DLL_DLYENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			DLL_STRBIN_DELAY_NUM_SEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			DLL_STRBIN_DELAY_NUM_DEFAULT << DLL_STRBIN_DELAY_NUM_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	/* Reset DLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	sdhci_writel(host, BIT(1), DWCMSHC_EMMC_DLL_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	sdhci_writel(host, 0x0, DWCMSHC_EMMC_DLL_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	 * We shouldn't set DLL_RXCLK_NO_INVERTER for identify mode but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 * we must set it in higher speed mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	extra = DWCMSHC_EMMC_DLL_DLYENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	if (priv->flags & RK_RXCLK_NO_INVERTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		extra |= DLL_RXCLK_NO_INVERTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	/* Init DLL settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	extra = 0x5 << DWCMSHC_EMMC_DLL_START_POINT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		0x2 << DWCMSHC_EMMC_DLL_INC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		DWCMSHC_EMMC_DLL_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				 extra, DLL_LOCK_WO_TMOUT(extra), 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				 500 * USEC_PER_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	extra = 0x1 << 16 | /* tune clock stop en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		0x2 << 17 | /* pre-change delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		0x3 << 19;  /* post-change delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	sdhci_writel(host, extra, DWCMSHC_EMMC_ATCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	txclk_tapnum = priv->txclk_tapnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if ((priv->flags & RK_DLL_CMD_OUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	    host->mmc->ios.timing == MMC_TIMING_MMC_HS400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		extra = DLL_CMDOUT_SRC_CLK_NEG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			DLL_CMDOUT_EN_SRC_CLK_NEG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			DWCMSHC_EMMC_DLL_DLYENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			DLL_CMDOUT_TAPNUM_90_DEGREES |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			DLL_CMDOUT_TAPNUM_FROM_SW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	extra = DWCMSHC_EMMC_DLL_DLYENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		DLL_TXCLK_TAPNUM_FROM_SW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		DLL_RXCLK_NO_INVERTER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		txclk_tapnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	extra = DWCMSHC_EMMC_DLL_DLYENA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		DLL_STRBIN_TAPNUM_DEFAULT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		DLL_STRBIN_TAPNUM_FROM_SW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static void rockchip_sdhci_reset(struct sdhci_host *host, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	struct sdhci_pltfm_host *pltfm_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct dwcmshc_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (mask & SDHCI_RESET_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		priv = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		if (!IS_ERR_OR_NULL(priv->reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			reset_control_assert(priv->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			reset_control_deassert(priv->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	sdhci_reset(host, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static const struct sdhci_ops sdhci_dwcmshc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	.set_clock		= sdhci_set_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	.set_bus_width		= sdhci_set_bus_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	.set_uhs_signaling	= dwcmshc_set_uhs_signaling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	.get_max_clock		= sdhci_pltfm_clk_get_max_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	.reset			= sdhci_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	.adma_write_desc	= dwcmshc_adma_write_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static const struct sdhci_ops sdhci_dwcmshc_rk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	.set_clock		= dwcmshc_rk_set_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	.set_bus_width		= sdhci_set_bus_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	.set_uhs_signaling	= dwcmshc_set_uhs_signaling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	.get_max_clock		= sdhci_pltfm_clk_get_max_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	.reset			= rockchip_sdhci_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	.adma_write_desc	= dwcmshc_adma_write_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	.ops = &sdhci_dwcmshc_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const struct sdhci_pltfm_data sdhci_dwcmshc_rk_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	.ops = &sdhci_dwcmshc_rk_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		   SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static const struct dwcmshc_driver_data dwcmshc_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	.pdata = &sdhci_dwcmshc_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static const struct dwcmshc_driver_data rk3568_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	.pdata = &sdhci_dwcmshc_rk_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	.flags = RK_PLATFROM | RK_RXCLK_NO_INVERTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static const struct dwcmshc_driver_data rk3588_drvdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	.pdata = &sdhci_dwcmshc_rk_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	.flags = RK_PLATFROM | RK_DLL_CMD_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static int rockchip_pltf_init(struct sdhci_host *host, struct dwcmshc_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	priv->rockchip_clks[0].id = "axi";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	priv->rockchip_clks[1].id = "block";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	priv->rockchip_clks[2].id = "timer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), ROCKCHIP_MAX_CLKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 					 priv->rockchip_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	err = clk_bulk_prepare_enable(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	if (of_property_read_u32(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				 &priv->txclk_tapnum))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	/* Disable cmd conflict check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	sdhci_writel(host, 0x0, DWCMSHC_HOST_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	/* Reset previous settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_STRBIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	 * Don't support highspeed bus mode with low clk speed as we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	 * cannot use DLL for this condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (host->mmc->f_max <= 52000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static const struct of_device_id sdhci_dwcmshc_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		.compatible = "snps,dwcmshc-sdhci",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		.data = &dwcmshc_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		.compatible = "rockchip,dwcmshc-sdhci",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		.data = &rk3568_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		.compatible = "rockchip,rk3588-dwcmshc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		.data = &rk3588_drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int dwcmshc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct sdhci_pltfm_host *pltfm_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	struct sdhci_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	struct dwcmshc_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	const struct dwcmshc_driver_data *drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	u32 extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	drv_data = device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (!drv_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		dev_err(&pdev->dev, "Error: No device match data found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	host = sdhci_pltfm_init(pdev, drv_data->pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 				sizeof(struct dwcmshc_priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	if (IS_ERR(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		return PTR_ERR(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	 * extra adma table cnt for cross 128M boundary handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	extra = DIV_ROUND_UP_ULL(dma_get_required_mask(&pdev->dev), SZ_128M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	if (extra > SDHCI_MAX_SEGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		extra = SDHCI_MAX_SEGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	host->adma_table_cnt += extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	priv = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	priv->acpi_en = has_acpi_companion(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (!priv->acpi_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		priv->reset = devm_reset_control_array_get_exclusive(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		pltfm_host->clk = devm_clk_get(&pdev->dev, "core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		if (IS_ERR(pltfm_host->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			err = PTR_ERR(pltfm_host->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			dev_err(&pdev->dev, "failed to get core clk: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			goto free_pltfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		err = clk_prepare_enable(pltfm_host->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			goto free_pltfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		priv->bus_clk = devm_clk_get(&pdev->dev, "bus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		if (!IS_ERR(priv->bus_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			clk_prepare_enable(priv->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	err = mmc_of_parse(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	sdhci_get_of_property(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	host->mmc_host_ops.request = dwcmshc_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	err = sdhci_add_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	priv->flags = drv_data->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	if (drv_data->flags & RK_PLATFROM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		err = rockchip_pltf_init(host, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 			goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	if (!priv->acpi_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		pm_runtime_get_noresume(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		pm_runtime_set_active(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		pm_runtime_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		pm_runtime_put_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) err_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	clk_disable_unprepare(pltfm_host->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	clk_disable_unprepare(priv->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) free_pltfm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	sdhci_pltfm_free(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static int dwcmshc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	struct sdhci_host *host = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	sdhci_remove_host(host, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	clk_disable_unprepare(pltfm_host->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	clk_disable_unprepare(priv->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	sdhci_pltfm_free(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int dwcmshc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	ret = sdhci_suspend_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	clk_disable_unprepare(pltfm_host->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	if (!IS_ERR(priv->bus_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		clk_disable_unprepare(priv->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	clk_bulk_disable_unprepare(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int dwcmshc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	ret = clk_prepare_enable(pltfm_host->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	if (!IS_ERR(priv->bus_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		ret = clk_prepare_enable(priv->bus_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	ret = clk_bulk_prepare_enable(ROCKCHIP_MAX_CLKS, priv->rockchip_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	return sdhci_resume_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static int dwcmshc_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	data = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	data &= ~SDHCI_CLOCK_CARD_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	sdhci_writew(host, data, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int dwcmshc_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	data = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	data |= SDHCI_CLOCK_CARD_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	sdhci_writew(host, data, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static const struct dev_pm_ops dwcmshc_pmops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	SET_SYSTEM_SLEEP_PM_OPS(dwcmshc_suspend, dwcmshc_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	SET_RUNTIME_PM_OPS(dwcmshc_runtime_suspend, dwcmshc_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) MODULE_DEVICE_TABLE(of, sdhci_dwcmshc_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static struct platform_driver sdhci_dwcmshc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	.driver	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		.name	= "sdhci-dwcmshc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		.of_match_table = sdhci_dwcmshc_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		.pm = &dwcmshc_pmops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	.probe	= dwcmshc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	.remove	= dwcmshc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) module_platform_driver(sdhci_dwcmshc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) MODULE_DESCRIPTION("SDHCI platform driver for Synopsys DWC MSHC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) MODULE_LICENSE("GPL v2");