From: Peng Fan <peng.fan@oss.nxp.com>
To: Raymond Mao <raymondmaoca@gmail.com>
Cc: u-boot@lists.denx.de, uboot@riscstar.com,
u-boot-spacemit@groups.io, raymond.mao@riscstar.com,
rick@andestech.com, ycliang@andestech.com, trini@konsulko.com,
lukma@denx.de, hs@nabladev.com, jh80.chung@samsung.com,
peng.fan@nxp.com, xypron.glpk@gmx.de, randolph@andestech.com,
dlan@gentoo.org, junhui.liu@pigmoral.tech,
neil.armstrong@linaro.org, quentin.schulz@cherry.de,
samuel@sholland.org, Guodong Xu <guodong@riscstar.com>
Subject: Re: [PATCH 2/8] mmc: k1: add sdhci platform driver
Date: Wed, 24 Jun 2026 16:15:57 +0800 [thread overview]
Message-ID: <ajuSPftsQnAQdzBD@shlinux89> (raw)
In-Reply-To: <20260612201901.73657-3-raymondmaoca@gmail.com>
On Fri, Jun 12, 2026 at 04:18:55PM -0400, Raymond Mao wrote:
>From: Guodong Xu <guodong@riscstar.com>
>
>Add SDHCI platform driver support for SpacemiT K1 SoC. This driver
>implements the necessary platform-specific operations for the SDHCI
>controller, enabling MMC/SD card functionality on K1-based platforms.
>
>Signed-off-by: Guodong Xu <guodong@riscstar.com>
>Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
>---
>+
>+#define LOG_CATEGORY UCLASS_MMC
>+
>+#include <clk.h>
>+#include <dm.h>
>+#include <dm/pinctrl.h>
>+#include <fdtdec.h>
>+#include <linux/libfdt.h>
>+#include <linux/delay.h>
>+#include <log.h>
>+#include <malloc.h>
>+#include <sdhci.h>
>+#include <reset-uclass.h>
>+#include <power/regulator.h>
>+#include <mapmem.h>
See doc/develop/codingstyle.rst regarding "Include files"
>+
>+/* SDH register definitions */
>+#define SDHC_OP_EXT_REG 0x108
>+#define OVRRD_CLK_OEN 0x0800
>+#define FORCE_CLK_ON 0x1000
>+
>+#define SDHC_LEGACY_CTRL_REG 0x10C
Not used.
>+#define GEN_PAD_CLK_ON 0x0040
>+
>+#define SDHC_MMC_CTRL_REG 0x114
>+#define MISC_INT_EN 0x0002
>+#define MISC_INT 0x0004
>+#define ENHANCE_STROBE_EN 0x0100
>+#define MMC_HS400 0x0200
>+#define MMC_HS200 0x0400
>+#define MMC_CARD_MODE 0x1000
Use BIT(x) and GENMASK for register bits, and other places.
>+
>+#define SDHC_RX_CFG_REG 0x118
>+#define RX_SDCLK_SEL0_MASK 0x03
>+#define RX_SDCLK_SEL0_SHIFT 0x00
>+#define RX_SDCLK_SEL0 0x02
>+#define RX_SDCLK_SEL1_MASK 0x03
>+#define RX_SDCLK_SEL1_SHIFT 0x02
>+#define RX_SDCLK_SEL1 0x01
>+
>+#define SDHC_TX_CFG_REG 0x11C
>+#define TX_INT_CLK_SEL 0x40000000
>+#define TX_MUX_SEL 0x80000000
>+
>+#define SDHC_DLINE_CTRL_REG 0x130
>+#define DLINE_PU 0x01
>+#define RX_DLINE_CODE_MASK 0xFF
>+#define RX_DLINE_CODE_SHIFT 0x10
>+#define TX_DLINE_CODE_MASK 0xFF
>+#define TX_DLINE_CODE_SHIFT 0x18
>+
>+#define SDHC_DLINE_CFG_REG 0x134
>+#define RX_DLINE_REG_MASK 0xFF
>+#define RX_DLINE_REG_SHIFT 0x00
>+#define RX_DLINE_GAIN_MASK 0x1
>+#define RX_DLINE_GAIN_SHIFT 0x8
>+#define RX_DLINE_GAIN 0x1
>+#define TX_DLINE_REG_MASK 0xFF
>+#define TX_DLINE_REG_SHIFT 0x10
>+
>+#define SDHC_PHY_CTRL_REG 0x160
>+#define PHY_FUNC_EN 0x0001
>+#define PHY_PLL_LOCK 0x0002
>+#define HOST_LEGACY_MODE 0x80000000
>+
>+#define SDHC_PHY_FUNC_REG 0x164
>+#define PHY_TEST_EN 0x0080
>+#define HS200_USE_RFIFO 0x8000
>+
>+#define SDHC_PHY_DLLCFG 0x168
>+#define DLL_PREDLY_NUM 0x04
>+#define DLL_FULLDLY_RANGE 0x10
>+#define DLL_VREG_CTRL 0x40
>+#define DLL_ENABLE 0x80000000
>+#define DLL_REFRESH_SWEN_SHIFT 0x1C
>+#define DLL_REFRESH_SW_SHIFT 0x1D
>+
>+#define SDHC_PHY_DLLCFG1 0x16C
>+#define DLL_REG2_CTRL 0x0C
>+#define DLL_REG3_CTRL_MASK 0xFF
>+#define DLL_REG3_CTRL_SHIFT 0x10
>+#define DLL_REG2_CTRL_MASK 0xFF
>+#define DLL_REG2_CTRL_SHIFT 0x08
>+#define DLL_REG1_CTRL 0x92
>+#define DLL_REG1_CTRL_MASK 0xFF
>+#define DLL_REG1_CTRL_SHIFT 0x00
>+
>+#define SDHC_PHY_DLLSTS 0x170
>+#define DLL_LOCK_STATE 0x01
>+
>+#define SDHC_PHY_DLLSTS1 0x174
>+#define DLL_MASTER_DELAY_MASK 0xFF
>+#define DLL_MASTER_DELAY_SHIFT 0x10
>+
>+#define SDHC_PHY_PADCFG_REG 0x178
>+#define RX_BIAS_CTRL_SHIFT 0x5
>+#define PHY_DRIVE_SEL_SHIFT 0x0
>+#define PHY_DRIVE_SEL_MASK 0x7
>+#define PHY_DRIVE_SEL_DEFAULT 0x4
>+
>+#define MMC1_IO_V18EN 0x04
>+#define AKEY_ASFAR 0xBABA
>+#define AKEY_ASSAR 0xEB10
>+
>+#define SDHC_RX_TUNE_DELAY_MIN 0x0
>+#define SDHC_RX_TUNE_DELAY_MAX 0xFF
>+#define SDHC_RX_TUNE_DELAY_STEP 0x1
>+
>+#define CANDIDATE_WIN_NUM 3
>+#define SELECT_DELAY_NUM 9
>+#define WINDOW_1ST 0
>+#define WINDOW_2ND 1
>+#define WINDOW_3RD 2
>+
>+#define RX_TUNING_WINDOW_THRESHOLD 80
>+#define RX_TUNING_DLINE_REG 0x09
>+#define TX_TUNING_DLINE_REG 0x00
>+#define TX_TUNING_DELAYCODE 127
...
>+
>+static int spacemit_sdhci_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
>+{
>+ int err = 0;
>+
>+ err = spacemit_sdhci_send_tuning(host, opcode, NULL);
>+ if (err) {
>+ log_warning("%s: send tuning err:%d\n", host->name, err);
>+ return err;
>+ }
>+
>+ err = spacemit_sdhci_tuning_pattern_check(host);
>+ return err;
return spacemit_sdhci_tuning_pattern_check(host);
>+}
>+
>+static void spacemit_sdhci_clear_tuned_clk(struct sdhci_host *host)
>+{
>+ u16 ctrl;
>+
>+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
>+ ctrl &= ~(SDHCI_CTRL_TUNED_CLK | SDHCI_CTRL_EXEC_TUNING);
>+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
>+}
>+
...
>+
>+
>+ /* Enable DLL */
>+ reg = sdhci_readl(host, SDHC_PHY_DLLCFG);
>+ reg |= DLL_ENABLE;
>+ sdhci_writel(host, reg, SDHC_PHY_DLLCFG);
>+
>+ /* Wait for DLL lock */
>+ i = 0;
>+ while (i++ < 100) {
>+ if (sdhci_readl(host, SDHC_PHY_DLLSTS) & DLL_LOCK_STATE)
>+ break;
>+ udelay(10);
>+ }
Use readx_poll_sleep_timeout?
>+ if (i == 100) {
>+ log_err("%s: phy dll lock timeout\n", host->name);
>+ return -ETIMEDOUT;
>+ }
>+
>+ return 0;
>+}
>+
>+static int spacemit_sdhci_hs400_enhanced_strobe(struct sdhci_host *host)
>+{
>+ u32 reg;
>+
>+ reg = sdhci_readl(host, SDHC_MMC_CTRL_REG);
>+ reg |= ENHANCE_STROBE_EN;
>+ sdhci_writel(host, reg, SDHC_MMC_CTRL_REG);
>+
>+ return spacemit_sdhci_phy_dll_init(host);
>+}
>+#endif
>+
>+const struct sdhci_ops spacemit_sdhci_ops = {
>+ .set_control_reg = spacemit_sdhci_set_control_reg,
>+ .platform_execute_tuning = spacemit_sdhci_execute_tuning,
>+#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
>+ .set_enhanced_strobe = spacemit_sdhci_hs400_enhanced_strobe,
>+#endif
>+};
>+
>+static struct dm_mmc_ops spacemit_mmc_ops;
>+
>+static int spacemit_sdhci_probe(struct udevice *dev)
>+{
>+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>+ struct spacemit_sdhci_priv *priv = dev_get_priv(dev);
>+ struct spacemit_sdhci_plat *plat = dev_get_plat(dev);
>+ struct sdhci_host *host = &priv->host;
>+ struct clk clk;
>+ int ret = 0;
>+
>+ host->mmc = &plat->mmc;
>+ host->mmc->priv = host;
>+ host->mmc->dev = dev;
>+ upriv->mmc = host->mmc;
>+
>+ spacemit_mmc_ops = sdhci_ops;
>+ spacemit_mmc_ops.wait_dat0 = spacemit_sdhci_wait_dat0;
>+
>+ ret = clk_get_bulk(dev, &plat->clks);
>+ if (ret) {
>+ log_err("Can't get clk: %d\n", ret);
>+ return ret;
>+ }
>+
>+ ret = clk_enable_bulk(&plat->clks);
>+ if (ret) {
>+ log_err("Failed to enable clk: %d\n", ret);
>+ return ret;
>+ }
>+
>+ ret = reset_get_bulk(dev, &plat->resets);
>+ if (ret) {
>+ log_err("Can't get reset: %d\n", ret);
>+ return ret;
>+ }
>+
>+ ret = reset_deassert_bulk(&plat->resets);
>+ if (ret) {
>+ log_err("Failed to reset: %d\n", ret);
>+ return ret;
>+ }
>+
>+ ret = clk_get_by_index(dev, 1, &clk);
>+ if (ret) {
>+ log_err("Can't get io clk: %d\n", ret);
>+ return ret;
>+ }
>+
>+ ret = clk_set_rate(&clk, plat->cfg.f_max);
>+ if (ret) {
>+ log_err("Failed to set io clk: %d\n", ret);
>+ return ret;
>+ }
>+
>+ /* Set quirks */
>+ if (IS_ENABLED(CONFIG_SPL_BUILD))
CONFIG_XPL_BUILD
>+ host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD;
>+ else
>+ host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
>+ SDHCI_QUIRK_32BIT_DMA_ADDR;
Regards
Peng
next prev parent reply other threads:[~2026-06-24 8:12 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-12 20:18 [PATCH 0/8] Add SD card and eMMC support for SpacemiT K1 Raymond Mao
2026-06-12 20:18 ` [PATCH 1/8] spacemit: k1: select boot device via config registers Raymond Mao
2026-06-13 3:50 ` Yao Zi
2026-06-24 0:46 ` Eric Chung
2026-06-24 4:35 ` Yao Zi
2026-06-24 7:25 ` Eric Chung
2026-06-12 20:18 ` [PATCH 2/8] mmc: k1: add sdhci platform driver Raymond Mao
2026-06-13 6:43 ` Yao Zi
2026-06-24 2:23 ` Eric Chung
2026-06-24 4:46 ` Yao Zi
2026-06-24 7:34 ` Eric Chung
2026-06-24 8:15 ` Peng Fan [this message]
2026-06-12 20:18 ` [PATCH 3/8] dts: k1: add SD card support in u-boot overlay Raymond Mao
2026-06-12 20:18 ` [PATCH 4/8] configs: k1: enable SD and eMMC support Raymond Mao
2026-06-12 20:18 ` [PATCH 5/8] doc: spacemit: flash on K1 SoC based boards Raymond Mao
2026-06-12 20:18 ` [PATCH 6/8] cmd: meminfo: widen memory map addresses to phys_addr_t Raymond Mao
2026-06-12 20:19 ` [PATCH 7/8] cmd: meminfo: fix the lmb info for large DRAM Raymond Mao
2026-06-12 20:19 ` [PATCH 8/8] cmd: tlv_eeprom: fix accessing invalid parameter Raymond Mao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ajuSPftsQnAQdzBD@shlinux89 \
--to=peng.fan@oss.nxp.com \
--cc=dlan@gentoo.org \
--cc=guodong@riscstar.com \
--cc=hs@nabladev.com \
--cc=jh80.chung@samsung.com \
--cc=junhui.liu@pigmoral.tech \
--cc=lukma@denx.de \
--cc=neil.armstrong@linaro.org \
--cc=peng.fan@nxp.com \
--cc=quentin.schulz@cherry.de \
--cc=randolph@andestech.com \
--cc=raymond.mao@riscstar.com \
--cc=raymondmaoca@gmail.com \
--cc=rick@andestech.com \
--cc=samuel@sholland.org \
--cc=trini@konsulko.com \
--cc=u-boot-spacemit@groups.io \
--cc=u-boot@lists.denx.de \
--cc=uboot@riscstar.com \
--cc=xypron.glpk@gmx.de \
--cc=ycliang@andestech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.