From: KuanLim.Lee <kuanlim.lee@starfivetech.com>
To: "u-boot@lists.denx.de" <u-boot@lists.denx.de>
Cc: Yuklin Soo <yuklin.soo@starfivetech.com>,
WeiLiang Lim <weiliang.lim@starfivetech.com>,
Kuan Lim Lee <kuanlim.lee@linux.starfivetech.com>
Subject: RE: [PATCH] mmc: sdhci-cadence: Add support for Cadence sdmmc v6
Date: Tue, 10 Oct 2023 08:18:35 +0000 [thread overview]
Message-ID: <bc3993e1ba28418db4c552198dfd1ad0@EXMBX066.cuchost.com> (raw)
In-Reply-To: <20231003072320.2008-1-kuanlim.lee@starfivetech.com>
Hi there,
May I know that these patches has any issue?
> -----Original Message-----
> From: KuanLim.Lee <kuanlim.lee@starfivetech.com>
> Sent: Tuesday, October 3, 2023 3:23 PM
> To: u-boot@lists.denx.de
> Cc: Yuklin Soo <yuklin.soo@starfivetech.com>; WeiLiang Lim
> <weiliang.lim@starfivetech.com>; Kuan Lim Lee
> <kuanlim.lee@linux.starfivetech.com>; KuanLim.Lee
> <kuanlim.lee@starfivetech.com>
> Subject: [PATCH] mmc: sdhci-cadence: Add support for Cadence sdmmc v6
>
> From: Kuan Lim Lee <kuanlim.lee@linux.starfivetech.com>
>
> Cadence SDMMC v6 controller has a lot of changes on initialize compared to v4
> controller. PHY is needed by v6 controller.
>
> Signed-off-by: Kuan Lim Lee <kuanlim.lee@starfivetech.com>
> Reviewed-by: Alex Soo <yuklin.soo@starfivetech.com>
> Reviewed-by: Wei Liang Lim <weiliang.lim@starfivetech.com>
> ---
> drivers/mmc/Kconfig | 13 ++
> drivers/mmc/Makefile | 1 +
> drivers/mmc/sdhci-cadence.c | 63 ++-----
> drivers/mmc/sdhci-cadence.h | 68 +++++++
> drivers/mmc/sdhci-cadence6-phy.c | 302
> +++++++++++++++++++++++++++++++
> 5 files changed, 396 insertions(+), 51 deletions(-) create mode 100644
> drivers/mmc/sdhci-cadence.h create mode 100644 drivers/mmc/sdhci-
> cadence6-phy.c
>
> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index
> de01b9687b..cec881d862 100644
> --- a/drivers/mmc/Kconfig
> +++ b/drivers/mmc/Kconfig
> @@ -573,6 +573,19 @@ config MMC_SDHCI_CADENCE
>
> If unsure, say N.
>
> +config MMC_SDHCI_CADENCE_V6
> + bool "SDHCI support for the Cadence SD/SDIO/eMMC controller &
> driver version 6"
> + depends on BLK && DM_MMC
> + depends on MMC_SDHCI
> + depends on OF_CONTROL
> + select MMC_SDHCI_CADENCE
> + help
> + This selects the Cadence SD/SDIO/eMMC driver version 6.
> +
> + If you have a controller with this interface, say Y here.
> +
> + If unsure, say N.
> +
> config MMC_SDHCI_AM654
> bool "SDHCI Controller on TI's Am654 devices"
> depends on ARCH_K3
> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index
> 2c65c4765a..cdcce55b8b 100644
> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -61,6 +61,7 @@ obj-$(CONFIG_MMC_SDHCI_ATMEL) +=
> atmel_sdhci.o
> obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o
> obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o
> obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o
> +obj-$(CONFIG_MMC_SDHCI_CADENCE_V6) += sdhci-cadence6-phy.o
> obj-$(CONFIG_MMC_SDHCI_AM654) += am654_sdhci.o
> obj-$(CONFIG_MMC_SDHCI_IPROC) += iproc_sdhci.o
> obj-$(CONFIG_MMC_SDHCI_KONA) += kona_sdhci.o
> diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c index
> 327a05ad11..d7a270e74c 100644
> --- a/drivers/mmc/sdhci-cadence.c
> +++ b/drivers/mmc/sdhci-cadence.c
> @@ -17,56 +17,7 @@
> #include <linux/libfdt.h>
> #include <mmc.h>
> #include <sdhci.h>
> -
> -/* HRS - Host Register Set (specific to Cadence) */
> -#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */
> -#define SDHCI_CDNS_HRS04_ACK BIT(26)
> -#define SDHCI_CDNS_HRS04_RD BIT(25)
> -#define SDHCI_CDNS_HRS04_WR BIT(24)
> -#define SDHCI_CDNS_HRS04_RDATA GENMASK(23, 16)
> -#define SDHCI_CDNS_HRS04_WDATA GENMASK(15, 8)
> -#define SDHCI_CDNS_HRS04_ADDR GENMASK(5, 0)
> -
> -#define SDHCI_CDNS_HRS06 0x18 /* eMMC control */
> -#define SDHCI_CDNS_HRS06_TUNE_UP BIT(15)
> -#define SDHCI_CDNS_HRS06_TUNE GENMASK(13, 8)
> -#define SDHCI_CDNS_HRS06_MODE GENMASK(2, 0)
> -#define SDHCI_CDNS_HRS06_MODE_SD 0x0
> -#define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2
> -#define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3
> -#define SDHCI_CDNS_HRS06_MODE_MMC_HS200 0x4
> -#define SDHCI_CDNS_HRS06_MODE_MMC_HS400 0x5
> -#define SDHCI_CDNS_HRS06_MODE_MMC_HS400ES 0x6
> -
> -/* SRS - Slot Register Set (SDHCI-compatible) */
> -#define SDHCI_CDNS_SRS_BASE 0x200
> -
> -/* PHY */
> -#define SDHCI_CDNS_PHY_DLY_SD_HS 0x00
> -#define SDHCI_CDNS_PHY_DLY_SD_DEFAULT 0x01
> -#define SDHCI_CDNS_PHY_DLY_UHS_SDR12 0x02
> -#define SDHCI_CDNS_PHY_DLY_UHS_SDR25 0x03
> -#define SDHCI_CDNS_PHY_DLY_UHS_SDR50 0x04
> -#define SDHCI_CDNS_PHY_DLY_UHS_DDR50 0x05
> -#define SDHCI_CDNS_PHY_DLY_EMMC_LEGACY 0x06
> -#define SDHCI_CDNS_PHY_DLY_EMMC_SDR 0x07
> -#define SDHCI_CDNS_PHY_DLY_EMMC_DDR 0x08
> -#define SDHCI_CDNS_PHY_DLY_SDCLK 0x0b
> -#define SDHCI_CDNS_PHY_DLY_HSMMC 0x0c
> -#define SDHCI_CDNS_PHY_DLY_STROBE 0x0d
> -
> -/*
> - * The tuned val register is 6 bit-wide, but not the whole of the range is
> - * available. The range 0-42 seems to be available (then 43 wraps around to 0)
> - * but I am not quite sure if it is official. Use only 0 to 39 for safety.
> - */
> -#define SDHCI_CDNS_MAX_TUNING_LOOP 40
> -
> -struct sdhci_cdns_plat {
> - struct mmc_config cfg;
> - struct mmc mmc;
> - void __iomem *hrs_addr;
> -};
> +#include "sdhci-cadence.h"
>
> struct sdhci_cdns_phy_cfg {
> const char *property;
> @@ -112,8 +63,11 @@ static int sdhci_cdns_write_phy_reg(struct
> sdhci_cdns_plat *plat, }
>
> static int sdhci_cdns_phy_init(struct sdhci_cdns_plat *plat,
> - const void *fdt, int nodeoffset)
> + const void *fdt, int nodeoffset)
> {
> + if (IS_ENABLED(CONFIG_MMC_SDHCI_CADENCE_V6))
> + return sdhci_cdns6_phy_init(plat,
> SDHCI_CDNS_HRS06_MODE_SD);
> +
> const fdt32_t *prop;
> int ret, i;
>
> @@ -163,6 +117,9 @@ static void sdhci_cdns_set_control_reg(struct
> sdhci_host *host)
> tmp &= ~SDHCI_CDNS_HRS06_MODE;
> tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_MODE, mode);
> writel(tmp, plat->hrs_addr + SDHCI_CDNS_HRS06);
> +
> + if (IS_ENABLED(CONFIG_MMC_SDHCI_CADENCE_V6))
> + sdhci_cdns6_phy_init(plat, mode);
> }
>
> static const struct sdhci_ops sdhci_cdns_ops = { @@ -172,6 +129,9 @@ static
> const struct sdhci_ops sdhci_cdns_ops = { static int
> sdhci_cdns_set_tune_val(struct sdhci_cdns_plat *plat,
> unsigned int val)
> {
> + if (IS_ENABLED(CONFIG_MMC_SDHCI_CADENCE_V6))
> + return sdhci_cdns6_set_tune_val(plat, val);
> +
> void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS06;
> u32 tmp;
> int i, ret;
> @@ -301,6 +261,7 @@ static int sdhci_cdns_probe(struct udevice *dev) static
> const struct udevice_id sdhci_cdns_match[] = {
> { .compatible = "socionext,uniphier-sd4hc" },
> { .compatible = "cdns,sd4hc" },
> + { .compatible = "cdns,sd6hc" },
> { /* sentinel */ }
> };
>
> diff --git a/drivers/mmc/sdhci-cadence.h b/drivers/mmc/sdhci-cadence.h new
> file mode 100644 index 0000000000..2c42cff2f3
> --- /dev/null
> +++ b/drivers/mmc/sdhci-cadence.h
> @@ -0,0 +1,68 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2022 Starfive.
> + * Author: Kuan Lim Lee <kuanlim.lee@starfivetech.com>
> + */
> +
> +#ifndef SDHCI_CADENCE_H_
> +#define SDHCI_CADENCE_H_
> +
> +/* HRS - Host Register Set (specific to Cadence) */
> +/* PHY access port */
> +#define SDHCI_CDNS_HRS04 0x10
> +/* Cadence V4 HRS04 Description*/
> +#define SDHCI_CDNS_HRS04_ACK BIT(26)
> +#define SDHCI_CDNS_HRS04_RD BIT(25)
> +#define SDHCI_CDNS_HRS04_WR BIT(24)
> +#define SDHCI_CDNS_HRS04_RDATA GENMASK(23, 16)
> +#define SDHCI_CDNS_HRS04_WDATA GENMASK(15, 8)
> +#define SDHCI_CDNS_HRS04_ADDR GENMASK(5, 0)
> +
> +#define SDHCI_CDNS_HRS05 0x14
> +
> +/* eMMC control */
> +#define SDHCI_CDNS_HRS06 0x18
> +#define SDHCI_CDNS_HRS06_TUNE_UP BIT(15)
> +#define SDHCI_CDNS_HRS06_TUNE GENMASK(13, 8)
> +#define SDHCI_CDNS_HRS06_MODE GENMASK(2, 0)
> +#define SDHCI_CDNS_HRS06_MODE_SD 0x0
> +#define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2
> +#define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3
> +#define SDHCI_CDNS_HRS06_MODE_MMC_HS200 0x4
> +#define SDHCI_CDNS_HRS06_MODE_MMC_HS400 0x5
> +#define SDHCI_CDNS_HRS06_MODE_MMC_HS400ES 0x6
> +
> +/* SRS - Slot Register Set (SDHCI-compatible) */
> +#define SDHCI_CDNS_SRS_BASE 0x200
> +
> +/* Cadence V4 PHY Setting*/
> +#define SDHCI_CDNS_PHY_DLY_SD_HS 0x00
> +#define SDHCI_CDNS_PHY_DLY_SD_DEFAULT 0x01
> +#define SDHCI_CDNS_PHY_DLY_UHS_SDR12 0x02
> +#define SDHCI_CDNS_PHY_DLY_UHS_SDR25 0x03
> +#define SDHCI_CDNS_PHY_DLY_UHS_SDR50 0x04
> +#define SDHCI_CDNS_PHY_DLY_UHS_DDR50 0x05
> +#define SDHCI_CDNS_PHY_DLY_EMMC_LEGACY 0x06
> +#define SDHCI_CDNS_PHY_DLY_EMMC_SDR 0x07
> +#define SDHCI_CDNS_PHY_DLY_EMMC_DDR 0x08
> +#define SDHCI_CDNS_PHY_DLY_SDCLK 0x0b
> +#define SDHCI_CDNS_PHY_DLY_HSMMC 0x0c
> +#define SDHCI_CDNS_PHY_DLY_STROBE 0x0d
> +
> +/*
> + * The tuned val register is 6 bit-wide, but not the whole of the range
> +is
> + * available. The range 0-42 seems to be available (then 43 wraps
> +around to 0)
> + * but I am not quite sure if it is official. Use only 0 to 39 for safety.
> + */
> +#define SDHCI_CDNS_MAX_TUNING_LOOP 40
> +
> +struct sdhci_cdns_plat {
> + struct mmc_config cfg;
> + struct mmc mmc;
> + void __iomem *hrs_addr;
> +};
> +
> +int sdhci_cdns6_phy_init(struct sdhci_cdns_plat *plat, u32 mode); int
> +sdhci_cdns6_set_tune_val(struct sdhci_cdns_plat *plat, unsigned int
> +val);
> +
> +#endif
> diff --git a/drivers/mmc/sdhci-cadence6-phy.c b/drivers/mmc/sdhci-cadence6-
> phy.c
> new file mode 100644
> index 0000000000..dd3df27dc8
> --- /dev/null
> +++ b/drivers/mmc/sdhci-cadence6-phy.c
> @@ -0,0 +1,302 @@
> +// SPDX-License-Identifier: GPL-2.0-or-platform_driver
> +/*
> + * Copyright (C) 2022 Starfive.
> + * Author: Kuan Lim Lee <kuanlim.lee@starfivetech.com>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <asm/global_data.h>
> +#include <dm/device_compat.h>
> +#include <linux/bitfield.h>
> +#include <linux/bitops.h>
> +#include <linux/bug.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/sizes.h>
> +#include <linux/libfdt.h>
> +#include <mmc.h>
> +#include <sdhci.h>
> +#include "sdhci-cadence.h"
> +
> +/* IO Delay Information */
> +#define SDHCI_CDNS_HRS07 0X1C
> +#define SDHCI_CDNS_HRS07_RW_COMPENSATE GENMASK(20,
> 16)
> +#define SDHCI_CDNS_HRS07_IDELAY_VAL GENMASK(4,
> 0)
> +
> +#define SDHCI_CDNS_HRS09 0x24 /* PHY Control and
> Status */
> +#define SDHCI_CDNS_HRS09_RDDATA_EN BIT(16)
> +#define SDHCI_CDNS_HRS09_RDCMD_EN BIT(15)
> +#define SDHCI_CDNS_HRS09_EXTENDED_WR_MODE BIT(3)
> +#define SDHCI_CDNS_HRS09_EXTENDED_RD_MODE BIT(2)
> +#define SDHCI_CDNS_HRS09_PHY_INIT_COMPLETE BIT(1)
> +#define SDHCI_CDNS_HRS09_PHY_SW_RESET BIT(0)
> +
> +#define SDHCI_CDNS_HRS10 0x28 /* SDCLK adjustment
> */
> +#define SDHCI_CDNS_HRS10_HCSDCLKADJ GENMASK(19, 16)
> +
> +#define SDHCI_CDNS_HRS16 0x40 /* CMD/DAT output
> delay */
> +
> +/* PHY Special Function Registers */
> +//#define DLL_PHY_REG_BASE 0x2000
> +
> +/* register to control the DQ related timing */
> +#define PHY_DQ_TIMING_REG_ADDR 0x2000
> +
> +/* register to control the DQS related timing */
> +#define PHY_DQS_TIMING_REG_ADDR 0x2004
> +
> +/* register to control the gate and loopback control related timing */
> +#define PHY_GATE_LPBK_CTRL_REG_ADDR 0x2008
> +
> +/* register to control the Master DLL logic */
> +#define PHY_DLL_MASTER_CTRL_REG_ADDR 0x200C
> +
> +/* register to control the Slave DLL logic */
> +#define PHY_DLL_SLAVE_CTRL_REG_ADDR 0x2010
> +#define PHY_DLL_SLAVE_CTRL_REG_READ_DQS_CMD_DELAY GENMASK(31,
> 24)
> +#define PHY_DLL_SLAVE_CTRL_REG_READ_DQS_DELAY
> GENMASK(7, 0)
> +
> +/* register to control the global settings for PHY */
> +#define PHY_CTRL_REG_ADDR 0x2080
> +
> +struct phy_reg {
> + u32 phy_dqs_timing;
> + u32 phy_gate_lpbk_ctrl;
> + //u32 phy_dll_master_ctrl;
> + u32 phy_dll_slave_ctrl;
> + //u32 phy_ctrl;
> + u32 phy_dq_timing;
> + //cp_sw_half_cycle_shift; ASIC
> +};
> +
> +struct controller_reg {
> + u32 hrs07;
> + u32 hrs09;
> + u32 hrs10;
> + u32 hrs16;
> +};
> +
> +static struct phy_reg sd_ds_phy_cfg = {
> + 0x00380004,
> + 0x01A00040,
> + 0x00000000,
> + 0x00000001,
> +};
> +
> +static struct phy_reg emmc_sdr_phy_cfg = {
> + 0x00380004,
> + 0x01A00040,
> + 0x00000000,
> + 0x00000001,
> +};
> +
> +static struct phy_reg emmc_ddr_phy_cfg = {
> + 0x00380004,
> + 0x01A00040,
> + 0x00000000,
> + 0x10000001,
> +};
> +
> +static struct phy_reg emmc_hs200_phy_cfg = {
> + 0x00380004,
> + 0x01A00040,
> + 0x00DADA00,
> + 0x00000001,
> +};
> +
> +static struct phy_reg emmc_hs400_phy_cfg = {
> + 0x00280004,
> + 0x01A00040,
> + 0x00DAD800,
> + 0x00000001,
> +};
> +
> +static struct controller_reg sd_ds_ctrl_cfg = {
> + 0x00080000,
> + 0x0001800C,
> + 0x00020000,
> + 0x00000000,
> +};
> +
> +static struct controller_reg emmc_sdr_ctrl_cfg = {
> + 0x00080000,
> + 0x0001800C,
> + 0x00030000,
> + 0x00000000,
> +};
> +
> +static struct controller_reg emmc_ddr_ctrl_cfg = {
> + 0x00090001,
> + 0x0001800C,
> + 0x00020000,
> + 0x11000001,
> +};
> +
> +static struct controller_reg emmc_hs200_ctrl_cfg = {
> + 0x00090000,
> + 0x00018000,
> + 0x00080000,
> + 0x00000000,
> +};
> +
> +static struct controller_reg emmc_hs400_ctrl_cfg = {
> + 0x00080000,
> + 0x00018000,
> + 0x00080000,
> + 0x11000000,
> +};
> +
> +static unsigned int sdhci_cdns6_read_phy_reg(struct sdhci_cdns_plat *plat,
> + u32 addr)
> +{
> + u32 data = 0;
> +
> + writel(addr, plat->hrs_addr + SDHCI_CDNS_HRS04);
> + data = readl(plat->hrs_addr + SDHCI_CDNS_HRS05);
> + return data;
> +}
> +
> +static void sdhci_cdns6_write_phy_reg(struct sdhci_cdns_plat *plat,
> + u32 addr, u32 data)
> +{
> + u32 readdat = 0;
> +
> + writel(addr, plat->hrs_addr + SDHCI_CDNS_HRS04);
> + writel(data, plat->hrs_addr + SDHCI_CDNS_HRS05);
> + readdat = readl(plat->hrs_addr + SDHCI_CDNS_HRS05);
> +
> + if (readdat != data) {
> + pr_err("Error, %s: Writing failed!: address: 0x%x, value : 0x%x,
> + readval: 0x%x\n", __func__, addr, data, readdat);
> + }
> +}
> +
> +static int sdhci_cdns6_reset_phy_dll(struct sdhci_cdns_plat *plat,
> + unsigned int reset)
> +{
> + void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS09;
> + u32 tmp;
> + int ret;
> +
> + tmp = readl(reg);
> + tmp &= ~SDHCI_CDNS_HRS09_PHY_SW_RESET;
> +
> + if (reset) /* Switch On DLL Reset */
> + tmp |= FIELD_PREP(SDHCI_CDNS_HRS09_PHY_SW_RESET, 0);
> + else /* Switch Off DLL Reset */
> + tmp |= FIELD_PREP(SDHCI_CDNS_HRS09_PHY_SW_RESET, 1);
> +
> + writel(tmp, reg);
> +
> + if (!reset) {
> + ret = readl_poll_timeout(reg, tmp,
> + (tmp &
> SDHCI_CDNS_HRS09_PHY_INIT_COMPLETE),
> + 3000);
> + }
> +
> + return ret;
> +}
> +
> +int sdhci_cdns6_phy_init(struct sdhci_cdns_plat *plat, u32 mode) {
> + struct phy_reg *phy_cfgs;
> + struct controller_reg *ctrl_cfgs;
> + void __iomem *reg = NULL;
> + u32 tmp;
> + int ret;
> +
> + switch (mode) {
> + case SDHCI_CDNS_HRS06_MODE_SD:
> + phy_cfgs = &sd_ds_phy_cfg;
> + ctrl_cfgs = &sd_ds_ctrl_cfg;
> + break;
> +
> + case SDHCI_CDNS_HRS06_MODE_MMC_SDR:
> + phy_cfgs = &emmc_sdr_phy_cfg;
> + ctrl_cfgs = &emmc_sdr_ctrl_cfg;
> + break;
> +
> + case SDHCI_CDNS_HRS06_MODE_MMC_DDR:
> + phy_cfgs = &emmc_ddr_phy_cfg;
> + ctrl_cfgs = &emmc_ddr_ctrl_cfg;
> + break;
> +
> + case SDHCI_CDNS_HRS06_MODE_MMC_HS200:
> + phy_cfgs = &emmc_hs200_phy_cfg;
> + ctrl_cfgs = &emmc_hs200_ctrl_cfg;
> + break;
> +
> + case SDHCI_CDNS_HRS06_MODE_MMC_HS400:
> + phy_cfgs = &emmc_hs400_phy_cfg;
> + ctrl_cfgs = &emmc_hs400_ctrl_cfg;
> + break;
> + }
> +
> + /* Switch On the DLL Reset */
> + sdhci_cdns6_reset_phy_dll(plat, 1);
> +
> + sdhci_cdns6_write_phy_reg(plat, PHY_DQS_TIMING_REG_ADDR,
> + phy_cfgs->phy_dqs_timing);
> + sdhci_cdns6_write_phy_reg(plat, PHY_GATE_LPBK_CTRL_REG_ADDR,
> + phy_cfgs->phy_gate_lpbk_ctrl);
> + sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR,
> + phy_cfgs->phy_dll_slave_ctrl);
> +
> + /* Switch Off the DLL Reset */
> + ret = sdhci_cdns6_reset_phy_dll(plat, 0);
> + if (ret) {
> + printf("sdhci_cdns6_reset_phy is not completed\n");
> + return ret;
> + }
> +
> + /* Set PHY DQ TIMING control register */
> + sdhci_cdns6_write_phy_reg(plat, PHY_DQ_TIMING_REG_ADDR,
> + phy_cfgs->phy_dq_timing);
> +
> + /* Set HRS09 register */
> + reg = plat->hrs_addr + SDHCI_CDNS_HRS09;
> + tmp = readl(reg);
> + tmp &= ~(SDHCI_CDNS_HRS09_EXTENDED_WR_MODE |
> + SDHCI_CDNS_HRS09_EXTENDED_RD_MODE |
> + SDHCI_CDNS_HRS09_RDDATA_EN |
> + SDHCI_CDNS_HRS09_RDCMD_EN);
> + tmp |= ctrl_cfgs->hrs09;
> + writel(tmp, reg);
> +
> + /* Set HRS10 register */
> + reg = plat->hrs_addr + SDHCI_CDNS_HRS10;
> + tmp = readl(reg);
> + tmp &= ~SDHCI_CDNS_HRS10_HCSDCLKADJ;
> + tmp |= ctrl_cfgs->hrs10;
> + writel(tmp, reg);
> +
> + /* Set HRS16 register */
> + reg = plat->hrs_addr + SDHCI_CDNS_HRS16;
> + tmp = ctrl_cfgs->hrs16;
> + writel(tmp, reg);
> +
> + /* Set HRS07 register */
> + reg = plat->hrs_addr + SDHCI_CDNS_HRS07;
> + tmp = ctrl_cfgs->hrs07;
> + writel(tmp, reg);
> +
> + return 0;
> +}
> +
> +int sdhci_cdns6_set_tune_val(struct sdhci_cdns_plat *plat,
> + unsigned int val)
> +{
> + u32 tmp, tuneval;
> +
> + tuneval = (val * 256) / SDHCI_CDNS_MAX_TUNING_LOOP;
> +
> + tmp = sdhci_cdns6_read_phy_reg(plat,
> PHY_DLL_SLAVE_CTRL_REG_ADDR);
> + tmp &= ~(PHY_DLL_SLAVE_CTRL_REG_READ_DQS_CMD_DELAY |
> + PHY_DLL_SLAVE_CTRL_REG_READ_DQS_DELAY);
> + tmp |=
> FIELD_PREP(PHY_DLL_SLAVE_CTRL_REG_READ_DQS_CMD_DELAY, tuneval) |
> + FIELD_PREP(PHY_DLL_SLAVE_CTRL_REG_READ_DQS_DELAY,
> tuneval);
> + sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR,
> tmp);
> +
> + return 0;
> +}
> --
> 2.34.1
next prev parent reply other threads:[~2023-10-10 8:18 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20231101001948epcas1p21f7980fd9ab6a99e884eeb08409b1f48@epcas1p2.samsung.com>
2023-10-03 7:22 ` [PATCH] mmc: sdhci-cadence: Add support for Cadence sdmmc v6 Kuan Lim Lee
2023-10-10 8:18 ` KuanLim.Lee [this message]
2023-10-17 4:53 ` KuanLim.Lee
2023-11-01 0:19 ` Jaehoon Chung
2023-11-07 6:23 ` KuanLim.Lee
2023-11-15 3:36 ` KuanLim.Lee
2023-11-15 12:16 ` Jaehoon Chung
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=bc3993e1ba28418db4c552198dfd1ad0@EXMBX066.cuchost.com \
--to=kuanlim.lee@starfivetech.com \
--cc=kuanlim.lee@linux.starfivetech.com \
--cc=u-boot@lists.denx.de \
--cc=weiliang.lim@starfivetech.com \
--cc=yuklin.soo@starfivetech.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.