All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukasz Majewski <lukma@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [v3, 4/5] mmc: fsl_esdhc: drop i.MX code
Date: Wed, 29 May 2019 08:40:19 +0200	[thread overview]
Message-ID: <20190529084019.1b97bdd2@jawa> (raw)
In-Reply-To: <20190521085215.6263-5-yangbo.lu@nxp.com>

On Tue, 21 May 2019 08:52:44 +0000
"Y.b. Lu" <yangbo.lu@nxp.com> wrote:

> Dropped i.MX code which couldn't be reused.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> ---
> Changes for v2:
> 	- Added this patch.
> Changes for v3:
> 	- Rebased.
> ---
>  drivers/mmc/fsl_esdhc.c | 609
> ++-------------------------------------- include/fsl_esdhc.h     |
> 57 ---- 2 files changed, 21 insertions(+), 645 deletions(-)
> 
> diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
> index 1b7de74a72..3f4f75ae4c 100644
> --- a/drivers/mmc/fsl_esdhc.c
> +++ b/drivers/mmc/fsl_esdhc.c
> @@ -16,14 +16,11 @@
>  #include <hwconfig.h>
>  #include <mmc.h>
>  #include <part.h>
> -#include <power/regulator.h>
>  #include <malloc.h>
>  #include <fsl_esdhc.h>
>  #include <fdt_support.h>
>  #include <asm/io.h>
>  #include <dm.h>
> -#include <asm-generic/gpio.h>
> -#include <dm/pinctrl.h>
>  
>  DECLARE_GLOBAL_DATA_PTR;
>  
> @@ -33,8 +30,6 @@ DECLARE_GLOBAL_DATA_PTR;
>  				IRQSTATEN_CIE | IRQSTATEN_DTOE |
> IRQSTATEN_DCE | \ IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \
>  				IRQSTATEN_DINT)
> -#define MAX_TUNING_LOOP 40
> -
>  struct fsl_esdhc {
>  	uint    dsaddr;		/* SDMA system address
> register */ uint    blkattr;	/* Block attributes register */
> @@ -54,37 +49,20 @@ struct fsl_esdhc {
>  	uint    autoc12err;	/* Auto CMD error status register
> */ uint    hostcapblt;	/* Host controller capabilities
> register */ uint    wml;		/* Watermark level register */
> -	uint    mixctrl;	/* For USDHC */
> -	char    reserved1[4];	/* reserved */
> +	char    reserved1[8];	/* reserved */
>  	uint    fevt;		/* Force event register */
>  	uint    admaes;		/* ADMA error status register
> */ uint    adsaddr;	/* ADMA system address register */
> -	char    reserved2[4];
> -	uint    dllctrl;
> -	uint    dllstat;
> -	uint    clktunectrlstatus;
> -	char    reserved3[4];
> -	uint	strobe_dllctrl;
> -	uint	strobe_dllstat;
> -	char    reserved4[72];
> -	uint    vendorspec;
> -	uint    mmcboot;
> -	uint    vendorspec2;
> -	uint    tuning_ctrl;	/* on i.MX6/7/8 */
> -	char	reserved5[44];
> +	char    reserved2[160];
>  	uint    hostver;	/* Host controller version register
> */
> -	char    reserved6[4];	/* reserved */
> +	char    reserved3[4];	/* reserved */
>  	uint    dmaerraddr;	/* DMA error address register */
> -	char    reserved7[4];	/* reserved */
> +	char    reserved4[4];	/* reserved */
>  	uint    dmaerrattr;	/* DMA error attribute register */
> -	char    reserved8[4];	/* reserved */
> +	char    reserved5[4];	/* reserved */
>  	uint    hostcapblt2;	/* Host controller capabilities
> register 2 */
> -	char    reserved9[8];	/* reserved */
> -	uint    tcr;		/* Tuning control register */
> -	char    reserved10[28];	/* reserved */
> -	uint    sddirctl;	/* SD direction control register */
> -	char    reserved11[712];/* reserved */
> -	uint    scr;		/* eSDHC control register */
> +	char    reserved6[756];	/* reserved */
> +	uint    esdhcctl;	/* eSDHC control register */
>  };
>  
>  struct fsl_esdhc_plat {
> @@ -92,11 +70,6 @@ struct fsl_esdhc_plat {
>  	struct mmc mmc;
>  };
>  
> -struct esdhc_soc_data {
> -	u32 flags;
> -	u32 caps;
> -};
> -
>  /**
>   * struct fsl_esdhc_priv
>   *
> @@ -109,13 +82,6 @@ struct esdhc_soc_data {
>   * @dev: pointer for the device
>   * @non_removable: 0: removable; 1: non-removable
>   * @wp_enable: 1: enable checking wp; 0: no check
> - * @vs18_enable: 1: use 1.8V voltage; 0: use 3.3V
> - * @flags: ESDHC_FLAG_xx in include/fsl_esdhc.h
> - * @caps: controller capabilities
> - * @tuning_step: tuning step setting in tuning_ctrl register
> - * @start_tuning_tap: the start point for tuning in tuning_ctrl
> register
> - * @strobe_dll_delay_target: settings in strobe_dllctrl
> - * @signal_voltage: indicating the current voltage
>   * @cd_gpio: gpio for card detection
>   * @wp_gpio: gpio for write protection
>   */
> @@ -124,7 +90,6 @@ struct fsl_esdhc_priv {
>  	unsigned int sdhc_clk;
>  	struct clk per_clk;
>  	unsigned int clock;
> -	unsigned int mode;
>  	unsigned int bus_width;
>  #if !CONFIG_IS_ENABLED(BLK)
>  	struct mmc *mmc;
> @@ -132,21 +97,6 @@ struct fsl_esdhc_priv {
>  	struct udevice *dev;
>  	int non_removable;
>  	int wp_enable;
> -	int vs18_enable;
> -	u32 flags;
> -	u32 caps;
> -	u32 tuning_step;
> -	u32 tuning_start_tap;
> -	u32 strobe_dll_delay_target;
> -	u32 signal_voltage;
> -#if IS_ENABLED(CONFIG_DM_REGULATOR)
> -	struct udevice *vqmmc_dev;
> -	struct udevice *vmmc_dev;
> -#endif
> -#ifdef CONFIG_DM_GPIO
> -	struct gpio_desc cd_gpio;
> -	struct gpio_desc wp_gpio;
> -#endif

I suppose that _all_ 85xx and layerscape/OorIQ boards are not converted
to DM and they are not using card detect and write protect pins?

IIRC the 85xx gained recently the support for DM/DTS. Maybe it would be
worth to re-check if this code would be used?

>  };
>  
>  /* Return the XFERTYP flags for a given command and data packet */
> @@ -258,8 +208,7 @@ static int esdhc_setup_data(struct fsl_esdhc_priv
> *priv, struct mmc *mmc, {
>  	int timeout;
>  	struct fsl_esdhc *regs = priv->esdhc_regs;
> -#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
> -	defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
> +#if defined(CONFIG_FSL_LAYERSCAPE)
>  	dma_addr_t addr;
>  #endif
>  	uint wml_value;
> @@ -272,8 +221,7 @@ static int esdhc_setup_data(struct fsl_esdhc_priv
> *priv, struct mmc *mmc, 
>  		esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK,
> wml_value); #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
> -#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
> -	defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
> +#if defined(CONFIG_FSL_LAYERSCAPE)
>  		addr = virt_to_phys((void *)(data->dest));
>  		if (upper_32_bits(addr))
>  			printf("Error found for upper 32 bits\n");
> @@ -297,20 +245,12 @@ static int esdhc_setup_data(struct
> fsl_esdhc_priv *priv, struct mmc *mmc, printf("\nThe SD card is
> locked. Can not write to a locked card.\n\n"); return -ETIMEDOUT;
>  			}
> -		} else {
> -#ifdef CONFIG_DM_GPIO
> -			if (dm_gpio_is_valid(&priv->wp_gpio) &&
> dm_gpio_get_value(&priv->wp_gpio)) {
> -				printf("\nThe SD card is locked. Can
> not write to a locked card.\n\n");
> -				return -ETIMEDOUT;
> -			}
> -#endif
>  		}
>  
>  		esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
>  					wml_value << 16);
>  #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
> -#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
> -	defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
> +#if defined(CONFIG_FSL_LAYERSCAPE)
>  		addr = virt_to_phys((void *)(data->src));
>  		if (upper_32_bits(addr))
>  			printf("Error found for upper 32 bits\n");
> @@ -375,8 +315,7 @@ static void check_and_invalidate_dcache_range
>  	unsigned end = 0;
>  	unsigned size = roundup(ARCH_DMA_MINALIGN,
>  				data->blocks*data->blocksize);
> -#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
> -	defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
> +#if defined(CONFIG_FSL_LAYERSCAPE)
>  	dma_addr_t addr;
>  
>  	addr = virt_to_phys((void *)(data->dest));
> @@ -466,14 +405,7 @@ static int esdhc_send_cmd_common(struct
> fsl_esdhc_priv *priv, struct mmc *mmc, 
>  	/* Send the command */
>  	esdhc_write32(&regs->cmdarg, cmd->cmdarg);
> -#if defined(CONFIG_FSL_USDHC)
> -	esdhc_write32(&regs->mixctrl,
> -	(esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp &
> 0x7F)
> -			| (mmc->ddr_mode ? XFERTYP_DDREN : 0));
> -	esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
> -#else
>  	esdhc_write32(&regs->xfertyp, xfertyp);
> -#endif
>  
>  	if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) ||
>  	    (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200))
> @@ -500,15 +432,6 @@ static int esdhc_send_cmd_common(struct
> fsl_esdhc_priv *priv, struct mmc *mmc, goto out;
>  	}
>  
> -	/* Switch voltage to 1.8V if CMD11 succeeded */
> -	if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) {
> -		esdhc_setbits32(&regs->vendorspec,
> ESDHC_VENDORSPEC_VSELECT); -
> -		printf("Run CMD11 1.8V switch\n");
> -		/* Sleep for 5 ms - max time for card to switch to
> 1.8V */
> -		udelay(5000);
> -	}
> -
>  	/* Workaround for ESDHC errata ENGcm03648 */
>  	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
>  		int timeout = 6000;
> @@ -596,10 +519,6 @@ out:
>  			while ((esdhc_read32(&regs->sysctl) &
> SYSCTL_RSTD)) ;
>  		}
> -
> -		/* If this was CMD11, then notify that power cycle
> is needed */
> -		if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V)
> -			printf("CMD11 to switch to 1.8V mode failed,
> card requires power cycle.\n"); }
>  
>  	esdhc_write32(&regs->irqstat, -1);
> @@ -611,62 +530,32 @@ static void set_sysctl(struct fsl_esdhc_priv
> *priv, struct mmc *mmc, uint clock) {
>  	struct fsl_esdhc *regs = priv->esdhc_regs;
>  	int div = 1;
> -#ifdef ARCH_MXC
> -#ifdef CONFIG_MX53
> -	/* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */
> -	int pre_div = (regs == (struct fsl_esdhc
> *)MMC_SDHC3_BASE_ADDR) ? 2 : 1; -#else
> -	int pre_div = 1;
> -#endif
> -#else
>  	int pre_div = 2;
> -#endif
> +	int ddr_pre_div = mmc->ddr_mode ? 2 : 1;
>  	int sdhc_clk = priv->sdhc_clk;
>  	uint clk;
>  
> -	/*
> -	 * For ddr mode, usdhc need to enable DDR mode first, after
> select
> -	 * this DDR mode, usdhc will automatically divide the usdhc
> clock
> -	 */
> -	if (mmc->ddr_mode) {
> -		writel(readl(&regs->mixctrl) | MIX_CTRL_DDREN,
> &regs->mixctrl);
> -		sdhc_clk >>= 1;
> -	}
> -
>  	if (clock < mmc->cfg->f_min)
>  		clock = mmc->cfg->f_min;
>  
> -	if (sdhc_clk / 16 > clock) {
> -		for (; pre_div < 256; pre_div *= 2)
> -			if ((sdhc_clk / pre_div) <= (clock * 16))
> -				break;
> -	} else
> -		pre_div = 1;
> +	while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock &&
> pre_div < 256)
> +		pre_div *= 2;
>  
> -	for (div = 1; div <= 16; div++)
> -		if ((sdhc_clk / (div * pre_div)) <= clock)
> -			break;
> +	while (sdhc_clk / (div * pre_div * ddr_pre_div) > clock &&
> div < 16)
> +		div++;
>  

Have you updated your series to be on top of newest mainline? The above
code looks like the one, which has been recently reverted as it breaks
i.MX53 devices.


>  	pre_div >>= 1;
>  	div -= 1;
>  
>  	clk = (pre_div << 8) | (div << 4);
>  
> -#ifdef CONFIG_FSL_USDHC
> -	esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_CKEN);
> -#else
>  	esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
> -#endif
>  
>  	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
>  
>  	udelay(10000);
>  
> -#ifdef CONFIG_FSL_USDHC
> -	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
> VENDORSPEC_CKEN); -#else
>  	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
> -#endif
>  
>  	priv->clock = clock;
>  }
> @@ -700,317 +589,20 @@ static void esdhc_clock_control(struct
> fsl_esdhc_priv *priv, bool enable) }
>  #endif
>  
> -#ifdef MMC_SUPPORTS_TUNING
> -static int esdhc_change_pinstate(struct udevice *dev)
> -{
> -	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
> -	int ret;
> -
> -	switch (priv->mode) {
> -	case UHS_SDR50:
> -	case UHS_DDR50:
> -		ret = pinctrl_select_state(dev, "state_100mhz");
> -		break;
> -	case UHS_SDR104:
> -	case MMC_HS_200:
> -	case MMC_HS_400:
> -		ret = pinctrl_select_state(dev, "state_200mhz");
> -		break;
> -	default:
> -		ret = pinctrl_select_state(dev, "default");
> -		break;
> -	}
> -
> -	if (ret)
> -		printf("%s %d error\n", __func__, priv->mode);
> -
> -	return ret;
> -}
> -
> -static void esdhc_reset_tuning(struct mmc *mmc)
> -{
> -	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
> -	struct fsl_esdhc *regs = priv->esdhc_regs;
> -
> -	if (priv->flags & ESDHC_FLAG_USDHC) {
> -		if (priv->flags & ESDHC_FLAG_STD_TUNING) {
> -			esdhc_clrbits32(&regs->autoc12err,
> -					MIX_CTRL_SMPCLK_SEL |
> -					MIX_CTRL_EXE_TUNE);
> -		}
> -	}
> -}
> -
> -static void esdhc_set_strobe_dll(struct mmc *mmc)
> -{
> -	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
> -	struct fsl_esdhc *regs = priv->esdhc_regs;
> -	u32 val;
> -
> -	if (priv->clock > ESDHC_STROBE_DLL_CLK_FREQ) {
> -		writel(ESDHC_STROBE_DLL_CTRL_RESET,
> &regs->strobe_dllctrl); -
> -		/*
> -		 * enable strobe dll ctrl and adjust the delay target
> -		 * for the uSDHC loopback read clock
> -		 */
> -		val = ESDHC_STROBE_DLL_CTRL_ENABLE |
> -			(priv->strobe_dll_delay_target <<
> -			 ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> -		writel(val, &regs->strobe_dllctrl);
> -		/* wait 1us to make sure strobe dll status register
> stable */
> -		mdelay(1);
> -		val = readl(&regs->strobe_dllstat);
> -		if (!(val & ESDHC_STROBE_DLL_STS_REF_LOCK))
> -			pr_warn("HS400 strobe DLL status REF not
> lock!\n");
> -		if (!(val & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> -			pr_warn("HS400 strobe DLL status SLV not
> lock!\n");
> -	}
> -}
> -
> -static int esdhc_set_timing(struct mmc *mmc)
> -{
> -	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
> -	struct fsl_esdhc *regs = priv->esdhc_regs;
> -	u32 mixctrl;
> -
> -	mixctrl = readl(&regs->mixctrl);
> -	mixctrl &= ~(MIX_CTRL_DDREN | MIX_CTRL_HS400_EN);
> -
> -	switch (mmc->selected_mode) {
> -	case MMC_LEGACY:
> -	case SD_LEGACY:
> -		esdhc_reset_tuning(mmc);
> -		writel(mixctrl, &regs->mixctrl);
> -		break;
> -	case MMC_HS_400:
> -		mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
> -		writel(mixctrl, &regs->mixctrl);
> -		esdhc_set_strobe_dll(mmc);
> -		break;
> -	case MMC_HS:
> -	case MMC_HS_52:
> -	case MMC_HS_200:
> -	case SD_HS:
> -	case UHS_SDR12:
> -	case UHS_SDR25:
> -	case UHS_SDR50:
> -	case UHS_SDR104:
> -		writel(mixctrl, &regs->mixctrl);
> -		break;
> -	case UHS_DDR50:
> -	case MMC_DDR_52:
> -		mixctrl |= MIX_CTRL_DDREN;
> -		writel(mixctrl, &regs->mixctrl);
> -		break;
> -	default:
> -		printf("Not supported %d\n", mmc->selected_mode);
> -		return -EINVAL;
> -	}
> -
> -	priv->mode = mmc->selected_mode;
> -
> -	return esdhc_change_pinstate(mmc->dev);
> -}
> -
> -static int esdhc_set_voltage(struct mmc *mmc)
> -{
> -	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
> -	struct fsl_esdhc *regs = priv->esdhc_regs;
> -	int ret;
> -
> -	priv->signal_voltage = mmc->signal_voltage;
> -	switch (mmc->signal_voltage) {
> -	case MMC_SIGNAL_VOLTAGE_330:
> -		if (priv->vs18_enable)
> -			return -EIO;
> -#if CONFIG_IS_ENABLED(DM_REGULATOR)
> -		if (!IS_ERR_OR_NULL(priv->vqmmc_dev)) {
> -			ret = regulator_set_value(priv->vqmmc_dev,
> 3300000);
> -			if (ret) {
> -				printf("Setting to 3.3V error");
> -				return -EIO;
> -			}
> -			/* Wait for 5ms */
> -			mdelay(5);
> -		}
> -#endif
> -
> -		esdhc_clrbits32(&regs->vendorspec,
> ESDHC_VENDORSPEC_VSELECT);
> -		if (!(esdhc_read32(&regs->vendorspec) &
> -		    ESDHC_VENDORSPEC_VSELECT))
> -			return 0;
> -
> -		return -EAGAIN;
> -	case MMC_SIGNAL_VOLTAGE_180:
> -#if CONFIG_IS_ENABLED(DM_REGULATOR)
> -		if (!IS_ERR_OR_NULL(priv->vqmmc_dev)) {
> -			ret = regulator_set_value(priv->vqmmc_dev,
> 1800000);
> -			if (ret) {
> -				printf("Setting to 1.8V error");
> -				return -EIO;
> -			}
> -		}
> -#endif
> -		esdhc_setbits32(&regs->vendorspec,
> ESDHC_VENDORSPEC_VSELECT);
> -		if (esdhc_read32(&regs->vendorspec) &
> ESDHC_VENDORSPEC_VSELECT)
> -			return 0;
> -
> -		return -EAGAIN;
> -	case MMC_SIGNAL_VOLTAGE_120:
> -		return -ENOTSUPP;
> -	default:
> -		return 0;
> -	}
> -}
> -
> -static void esdhc_stop_tuning(struct mmc *mmc)
> -{
> -	struct mmc_cmd cmd;
> -
> -	cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
> -	cmd.cmdarg = 0;
> -	cmd.resp_type = MMC_RSP_R1b;
> -
> -	dm_mmc_send_cmd(mmc->dev, &cmd, NULL);
> -}
> -
> -static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t
> opcode) -{
> -	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
> -	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
> -	struct fsl_esdhc *regs = priv->esdhc_regs;
> -	struct mmc *mmc = &plat->mmc;
> -	u32 irqstaten = readl(&regs->irqstaten);
> -	u32 irqsigen = readl(&regs->irqsigen);
> -	int i, ret = -ETIMEDOUT;
> -	u32 val, mixctrl;
> -
> -	/* clock tuning is not needed for upto 52MHz */
> -	if (mmc->clock <= 52000000)
> -		return 0;
> -
> -	/* This is readw/writew SDHCI_HOST_CONTROL2 when tuning */
> -	if (priv->flags & ESDHC_FLAG_STD_TUNING) {
> -		val = readl(&regs->autoc12err);
> -		mixctrl = readl(&regs->mixctrl);
> -		val &= ~MIX_CTRL_SMPCLK_SEL;
> -		mixctrl &= ~(MIX_CTRL_FBCLK_SEL |
> MIX_CTRL_AUTO_TUNE_EN); -
> -		val |= MIX_CTRL_EXE_TUNE;
> -		mixctrl |= MIX_CTRL_FBCLK_SEL |
> MIX_CTRL_AUTO_TUNE_EN; -
> -		writel(val, &regs->autoc12err);
> -		writel(mixctrl, &regs->mixctrl);
> -	}
> -
> -	/* sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
> */
> -	mixctrl = readl(&regs->mixctrl);
> -	mixctrl = MIX_CTRL_DTDSEL_READ | (mixctrl &
> ~MIX_CTRL_SDHCI_MASK);
> -	writel(mixctrl, &regs->mixctrl);
> -
> -	writel(IRQSTATEN_BRR, &regs->irqstaten);
> -	writel(IRQSTATEN_BRR, &regs->irqsigen);
> -
> -	/*
> -	 * Issue opcode repeatedly till Execute Tuning is set to 0
> or the number
> -	 * of loops reaches 40 times.
> -	 */
> -	for (i = 0; i < MAX_TUNING_LOOP; i++) {
> -		u32 ctrl;
> -
> -		if (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200) {
> -			if (mmc->bus_width == 8)
> -				writel(0x7080, &regs->blkattr);
> -			else if (mmc->bus_width == 4)
> -				writel(0x7040, &regs->blkattr);
> -		} else {
> -			writel(0x7040, &regs->blkattr);
> -		}
> -
> -		/* sdhci_writew(host, SDHCI_TRNS_READ,
> SDHCI_TRANSFER_MODE) */
> -		val = readl(&regs->mixctrl);
> -		val = MIX_CTRL_DTDSEL_READ | (val &
> ~MIX_CTRL_SDHCI_MASK);
> -		writel(val, &regs->mixctrl);
> -
> -		/* We are using STD tuning, no need to check return
> value */
> -		mmc_send_tuning(mmc, opcode, NULL);
> -
> -		ctrl = readl(&regs->autoc12err);
> -		if ((!(ctrl & MIX_CTRL_EXE_TUNE)) &&
> -		    (ctrl & MIX_CTRL_SMPCLK_SEL)) {
> -			/*
> -			 * need to wait some time, make sure sd/mmc
> fininsh
> -			 * send out tuning data, otherwise, the
> sd/mmc can't
> -			 * response to any command when the card
> still out
> -			 * put the tuning data.
> -			 */
> -			mdelay(1);
> -			ret = 0;
> -			break;
> -		}
> -
> -		/* Add 1ms delay for SD and eMMC */
> -		mdelay(1);
> -	}
> -
> -	writel(irqstaten, &regs->irqstaten);
> -	writel(irqsigen, &regs->irqsigen);
> -
> -	esdhc_stop_tuning(mmc);
> -
> -	return ret;
> -}
> -#endif
> -
>  static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct
> mmc *mmc) {
>  	struct fsl_esdhc *regs = priv->esdhc_regs;
> -	int ret __maybe_unused;
>  
>  #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
>  	/* Select to use peripheral clock */
>  	esdhc_clock_control(priv, false);
> -	esdhc_setbits32(&regs->scr, ESDHCCTL_PCS);
> +	esdhc_setbits32(&regs->esdhcctl, ESDHCCTL_PCS);
>  	esdhc_clock_control(priv, true);
>  #endif
>  	/* Set the clock speed */
>  	if (priv->clock != mmc->clock)
>  		set_sysctl(priv, mmc, mmc->clock);
>  
> -#ifdef MMC_SUPPORTS_TUNING
> -	if (mmc->clk_disable) {
> -#ifdef CONFIG_FSL_USDHC
> -		esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_CKEN);
> -#else
> -		esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
> -#endif
> -	} else {
> -#ifdef CONFIG_FSL_USDHC
> -		esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
> -				VENDORSPEC_CKEN);
> -#else
> -		esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN |
> SYSCTL_CKEN); -#endif
> -	}
> -
> -	if (priv->mode != mmc->selected_mode) {
> -		ret = esdhc_set_timing(mmc);
> -		if (ret) {
> -			printf("esdhc_set_timing error %d\n", ret);
> -			return ret;
> -		}
> -	}
> -
> -	if (priv->signal_voltage != mmc->signal_voltage) {
> -		ret = esdhc_set_voltage(mmc);
> -		if (ret) {
> -			printf("esdhc_set_voltage error %d\n", ret);
> -			return ret;
> -		}
> -	}
> -#endif
> -
>  	/* Set the bus width */
>  	esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
>  
> @@ -1037,34 +629,10 @@ static int esdhc_init_common(struct
> fsl_esdhc_priv *priv, struct mmc *mmc) return -ETIMEDOUT;
>  	}
>  
> -#if defined(CONFIG_FSL_USDHC)
> -	/* RSTA doesn't reset MMC_BOOT register, so manually reset
> it */
> -	esdhc_write32(&regs->mmcboot, 0x0);
> -	/* Reset MIX_CTRL and CLK_TUNE_CTRL_STATUS regs to 0 */
> -	esdhc_write32(&regs->mixctrl, 0x0);
> -	esdhc_write32(&regs->clktunectrlstatus, 0x0);
> -
> -	/* Put VEND_SPEC to default value */
> -	if (priv->vs18_enable)
> -		esdhc_write32(&regs->vendorspec, (VENDORSPEC_INIT |
> -			      ESDHC_VENDORSPEC_VSELECT));
> -	else
> -		esdhc_write32(&regs->vendorspec, VENDORSPEC_INIT);
> -
> -	/* Disable DLL_CTRL delay line */
> -	esdhc_write32(&regs->dllctrl, 0x0);
> -#endif
> -
> -#ifndef ARCH_MXC
>  	/* Enable cache snooping */
> -	esdhc_write32(&regs->scr, 0x00000040);
> -#endif
> +	esdhc_write32(&regs->esdhcctl, 0x00000040);
>  
> -#ifndef CONFIG_FSL_USDHC
>  	esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
> -#else
> -	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_HCKEN |
> VENDORSPEC_IPGEN); -#endif
>  
>  	/* Set the initial clock speed */
>  	mmc_set_clock(mmc, 400000, MMC_CLK_ENABLE);
> @@ -1098,10 +666,6 @@ static int esdhc_getcd_common(struct
> fsl_esdhc_priv *priv) #if CONFIG_IS_ENABLED(DM_MMC)
>  	if (priv->non_removable)
>  		return 1;
> -#ifdef CONFIG_DM_GPIO
> -	if (dm_gpio_is_valid(&priv->cd_gpio))
> -		return dm_gpio_get_value(&priv->cd_gpio);
> -#endif
>  #endif
>  
>  	while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) &&
> --timeout) @@ -1190,20 +754,8 @@ static int fsl_esdhc_init(struct
> fsl_esdhc_priv *priv, esdhc_write32(&regs->proctl, PROCTL_INIT |
> PROCTL_D3CD); #endif
>  
> -#ifndef CONFIG_FSL_USDHC
> -	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
> -				| SYSCTL_IPGEN | SYSCTL_CKEN);
> -	/* Clearing tuning bits in case ROM has set it already */
> -	esdhc_write32(&regs->mixctrl, 0);
> -	esdhc_write32(&regs->autoc12err, 0);
> -	esdhc_write32(&regs->clktunectrlstatus, 0);
> -#else
> -	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
> -			VENDORSPEC_HCKEN | VENDORSPEC_IPGEN |
> VENDORSPEC_CKEN); -#endif
> -
> -	if (priv->vs18_enable)
> -		esdhc_setbits32(&regs->vendorspec,
> ESDHC_VENDORSPEC_VSELECT);
> +	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN |
> +				       SYSCTL_IPGEN | SYSCTL_CKEN);
>  
>  	writel(SDHCI_IRQ_EN_BITS, &regs->irqstaten);
>  	cfg = &plat->cfg;
> @@ -1279,27 +831,11 @@ static int fsl_esdhc_init(struct
> fsl_esdhc_priv *priv, cfg->host_caps &= ~MMC_MODE_8BIT;
>  #endif
>  
> -	cfg->host_caps |= priv->caps;
> -
>  	cfg->f_min = 400000;
>  	cfg->f_max = min(priv->sdhc_clk, (u32)200000000);
>  
>  	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
>  
> -	writel(0, &regs->dllctrl);
> -	if (priv->flags & ESDHC_FLAG_USDHC) {
> -		if (priv->flags & ESDHC_FLAG_STD_TUNING) {
> -			u32 val = readl(&regs->tuning_ctrl);
> -
> -			val |= ESDHC_STD_TUNING_EN;
> -			val &= ~ESDHC_TUNING_START_TAP_MASK;
> -			val |= priv->tuning_start_tap;
> -			val &= ~ESDHC_TUNING_STEP_MASK;
> -			val |= (priv->tuning_step) <<
> ESDHC_TUNING_STEP_SHIFT;
> -			writel(val, &regs->tuning_ctrl);
> -		}
> -	}
> -
>  	return 0;
>  }
>  
> @@ -1314,7 +850,6 @@ static int fsl_esdhc_cfg_to_priv(struct
> fsl_esdhc_cfg *cfg, priv->bus_width = cfg->max_bus_width;
>  	priv->sdhc_clk = cfg->sdhc_clk;
>  	priv->wp_enable  = cfg->wp_enable;
> -	priv->vs18_enable  = cfg->vs18_enable;
>  
>  	return 0;
>  };
> @@ -1449,22 +984,11 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
>  
>  #if CONFIG_IS_ENABLED(DM_MMC)
>  #include <asm/arch/clock.h>
> -__weak void init_clk_usdhc(u32 index)
> -{
> -}
> -
>  static int fsl_esdhc_probe(struct udevice *dev)
>  {
>  	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>  	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
>  	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
> -	const void *fdt = gd->fdt_blob;
> -	int node = dev_of_offset(dev);
> -	struct esdhc_soc_data *data =
> -		(struct esdhc_soc_data *)dev_get_driver_data(dev);
> -#if CONFIG_IS_ENABLED(DM_REGULATOR)
> -	struct udevice *vqmmc_dev;
> -#endif
>  	fdt_addr_t addr;
>  	unsigned int val;
>  	struct mmc *mmc;
> @@ -1476,11 +1000,6 @@ static int fsl_esdhc_probe(struct udevice *dev)
>  
>  	priv->esdhc_regs = (struct fsl_esdhc *)addr;
>  	priv->dev = dev;
> -	priv->mode = -1;
> -	if (data) {
> -		priv->flags = data->flags;
> -		priv->caps = data->caps;
> -	}
>  
>  	val = dev_read_u32_default(dev, "bus-width", -1);
>  	if (val == 8)
> @@ -1490,81 +1009,13 @@ static int fsl_esdhc_probe(struct udevice
> *dev) else
>  		priv->bus_width = 1;
>  
> -	val = fdtdec_get_int(fdt, node, "fsl,tuning-step", 1);
> -	priv->tuning_step = val;
> -	val = fdtdec_get_int(fdt, node, "fsl,tuning-start-tap",
> -			     ESDHC_TUNING_START_TAP_DEFAULT);
> -	priv->tuning_start_tap = val;
> -	val = fdtdec_get_int(fdt, node,
> "fsl,strobe-dll-delay-target",
> -
> ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT);
> -	priv->strobe_dll_delay_target = val;
> -
>  	if (dev_read_bool(dev, "non-removable")) {
>  		priv->non_removable = 1;
>  	 } else {
>  		priv->non_removable = 0;
> -#ifdef CONFIG_DM_GPIO
> -		gpio_request_by_name(dev, "cd-gpios", 0,
> &priv->cd_gpio,
> -				     GPIOD_IS_IN);
> -#endif
>  	}
>  
> -	if (dev_read_prop(dev, "fsl,wp-controller", NULL)) {
> -		priv->wp_enable = 1;
> -	} else {
> -		priv->wp_enable = 0;
> -#ifdef CONFIG_DM_GPIO
> -		gpio_request_by_name(dev, "wp-gpios", 0,
> &priv->wp_gpio,
> -				   GPIOD_IS_IN);
> -#endif
> -	}
> -
> -	priv->vs18_enable = 0;
> -
> -#if CONFIG_IS_ENABLED(DM_REGULATOR)
> -	/*
> -	 * If emmc I/O has a fixed voltage at 1.8V, this must be
> provided,
> -	 * otherwise, emmc will work abnormally.
> -	 */
> -	ret = device_get_supply_regulator(dev, "vqmmc-supply",
> &vqmmc_dev);
> -	if (ret) {
> -		dev_dbg(dev, "no vqmmc-supply\n");
> -	} else {
> -		ret = regulator_set_enable(vqmmc_dev, true);
> -		if (ret) {
> -			dev_err(dev, "fail to enable
> vqmmc-supply\n");
> -			return ret;
> -		}
> -
> -		if (regulator_get_value(vqmmc_dev) == 1800000)
> -			priv->vs18_enable = 1;
> -	}
> -#endif
> -
> -	if (fdt_get_property(fdt, node, "no-1-8-v", NULL))
> -		priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200 |
> MMC_MODE_HS400); -
> -	/*
> -	 * TODO:
> -	 * Because lack of clk driver, if SDHC clk is not enabled,
> -	 * need to enable it first before this driver is invoked.
> -	 *
> -	 * we use MXC_ESDHC_CLK to get clk freq.
> -	 * If one would like to make this function work,
> -	 * the aliases should be provided in dts as this:
> -	 *
> -	 *  aliases {
> -	 *	mmc0 = &usdhc1;
> -	 *	mmc1 = &usdhc2;
> -	 *	mmc2 = &usdhc3;
> -	 *	mmc3 = &usdhc4;
> -	 *	};
> -	 * Then if your board only supports mmc2 and mmc3, but we can
> -	 * correctly get the seq as 2 and 3, then let mxc_get_clock
> -	 * work as expected.
> -	 */
> -
> -	init_clk_usdhc(dev->seq);
> +	priv->wp_enable = 1;
>  
>  	if (IS_ENABLED(CONFIG_CLK)) {
>  		/* Assigned clock already set clock */
> @@ -1631,28 +1082,10 @@ static const struct dm_mmc_ops fsl_esdhc_ops
> = { .get_cd		= fsl_esdhc_get_cd,
>  	.send_cmd	= fsl_esdhc_send_cmd,
>  	.set_ios	= fsl_esdhc_set_ios,
> -#ifdef MMC_SUPPORTS_TUNING
> -	.execute_tuning	= fsl_esdhc_execute_tuning,
> -#endif
>  };
>  #endif
>  
> -static struct esdhc_soc_data usdhc_imx7d_data = {
> -	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> -			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> -			| ESDHC_FLAG_HS400,
> -	.caps = UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_DDR_52MHz |
> -		MMC_MODE_HS_52MHz | MMC_MODE_HS,
> -};
> -
>  static const struct udevice_id fsl_esdhc_ids[] = {
> -	{ .compatible = "fsl,imx53-esdhc", },
> -	{ .compatible = "fsl,imx6ul-usdhc", },
> -	{ .compatible = "fsl,imx6sx-usdhc", },
> -	{ .compatible = "fsl,imx6sl-usdhc", },
> -	{ .compatible = "fsl,imx6q-usdhc", },
> -	{ .compatible = "fsl,imx7d-usdhc", .data =
> (ulong)&usdhc_imx7d_data,},
> -	{ .compatible = "fsl,imx7ulp-usdhc", },
>  	{ .compatible = "fsl,esdhc", },
>  	{ /* sentinel */ }
>  };
> diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
> index 8dbd5249a7..7d7e946ab3 100644
> --- a/include/fsl_esdhc.h
> +++ b/include/fsl_esdhc.h
> @@ -9,7 +9,6 @@
>  #ifndef  __FSL_ESDHC_H__
>  #define	__FSL_ESDHC_H__
>  
> -#include <linux/bitops.h>
>  #include <linux/errno.h>
>  #include <asm/byteorder.h>
>  
> @@ -25,22 +24,14 @@
>  #define SYSCTL_INITA		0x08000000
>  #define SYSCTL_TIMEOUT_MASK	0x000f0000
>  #define SYSCTL_CLOCK_MASK	0x0000fff0
> -#if !defined(CONFIG_FSL_USDHC)
>  #define SYSCTL_CKEN		0x00000008
>  #define SYSCTL_PEREN		0x00000004
>  #define SYSCTL_HCKEN		0x00000002
>  #define SYSCTL_IPGEN		0x00000001
> -#endif
>  #define SYSCTL_RSTA		0x01000000
>  #define SYSCTL_RSTC		0x02000000
>  #define SYSCTL_RSTD		0x04000000
>  
> -#define VENDORSPEC_CKEN		0x00004000
> -#define VENDORSPEC_PEREN	0x00002000
> -#define VENDORSPEC_HCKEN	0x00001000
> -#define VENDORSPEC_IPGEN	0x00000800
> -#define VENDORSPEC_INIT		0x20007809
> -
>  #define IRQSTAT			0x0002e030
>  #define IRQSTAT_DMAE		(0x10000000)
>  #define IRQSTAT_AC12E		(0x01000000)
> @@ -172,54 +163,6 @@
>  #define ESDHC_HOSTCAPBLT_DMAS	0x00400000
>  #define ESDHC_HOSTCAPBLT_HSS	0x00200000
>  
> -#define ESDHC_VENDORSPEC_VSELECT 0x00000002 /* Use 1.8V */
> -
> -/* Imported from Linux Kernel drivers/mmc/host/sdhci-esdhc-imx.c */
> -#define	MIX_CTRL_DDREN		BIT(3)
> -#define MIX_CTRL_DTDSEL_READ	BIT(4)
> -#define	MIX_CTRL_AC23EN		BIT(7)
> -#define	MIX_CTRL_EXE_TUNE	BIT(22)
> -#define	MIX_CTRL_SMPCLK_SEL	BIT(23)
> -#define	MIX_CTRL_AUTO_TUNE_EN	BIT(24)
> -#define	MIX_CTRL_FBCLK_SEL	BIT(25)
> -#define	MIX_CTRL_HS400_EN	BIT(26)
> -#define	MIX_CTRL_HS400_ES	BIT(27)
> -/* Bits 3 and 6 are not SDHCI standard definitions */
> -#define	MIX_CTRL_SDHCI_MASK	0xb7
> -/* Tuning bits */
> -#define	MIX_CTRL_TUNING_MASK	0x03c00000
> -
> -/* strobe dll register */
> -#define ESDHC_STROBE_DLL_CTRL		0x70
> -#define ESDHC_STROBE_DLL_CTRL_ENABLE	BIT(0)
> -#define ESDHC_STROBE_DLL_CTRL_RESET	BIT(1)
> -#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT	0x7
> -#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> -
> -#define ESDHC_STROBE_DLL_STATUS		0x74
> -#define ESDHC_STROBE_DLL_STS_REF_LOCK	BIT(1)
> -#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> -#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
> -
> -#define ESDHC_STD_TUNING_EN             BIT(24)
> -/* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
> -#define ESDHC_TUNING_START_TAP_DEFAULT	0x1
> -#define ESDHC_TUNING_START_TAP_MASK	0xff
> -#define ESDHC_TUNING_STEP_MASK		0x00070000
> -#define ESDHC_TUNING_STEP_SHIFT		16
> -
> -#define	ESDHC_FLAG_MULTIBLK_NO_INT	BIT(1)
> -#define	ESDHC_FLAG_ENGCM07207		BIT(2)
> -#define	ESDHC_FLAG_USDHC		BIT(3)
> -#define	ESDHC_FLAG_MAN_TUNING		BIT(4)
> -#define	ESDHC_FLAG_STD_TUNING		BIT(5)
> -#define	ESDHC_FLAG_HAVE_CAP1		BIT(6)
> -#define	ESDHC_FLAG_ERR004536		BIT(7)
> -#define	ESDHC_FLAG_HS200		BIT(8)
> -#define	ESDHC_FLAG_HS400		BIT(9)
> -#define	ESDHC_FLAG_ERR010450		BIT(10)
> -#define	ESDHC_FLAG_HS400_ES		BIT(11)
> -
>  struct fsl_esdhc_cfg {
>  	phys_addr_t esdhc_base;
>  	u32	sdhc_clk;




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190529/b739adc0/attachment.sig>

  parent reply	other threads:[~2019-05-29  6:40 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-21  8:51 [U-Boot] [v3, 0/5] Split fsl_esdhc driver for i.MX Y.b. Lu
2019-05-21  8:51 ` [U-Boot] [v3, 1/5] Move CONFIG_FSL_ESDHC to defconfig Y.b. Lu
2019-05-29  1:34   ` Peng Fan
2019-05-29  1:46   ` Jason Liu
2019-05-29  6:23   ` Lukasz Majewski
2019-05-21  8:52 ` [U-Boot] [v3, 2/5] mmc: split fsl_esdhc driver for i.MX Y.b. Lu
2019-05-29  1:42   ` Peng Fan
2019-05-29  6:29   ` Lukasz Majewski
2019-05-29  7:10     ` Y.b. Lu
2019-05-29 12:22       ` Y.b. Lu
2019-05-21  8:52 ` [U-Boot] [v3, 3/5] Convert to use fsl_esdhc_imx for i.MX platforms Y.b. Lu
2019-05-29  1:46   ` Peng Fan
2019-05-29  1:47   ` Jason Liu
2019-05-29  6:31   ` Lukasz Majewski
2019-05-21  8:52 ` [U-Boot] [v3, 4/5] mmc: fsl_esdhc: drop i.MX code Y.b. Lu
2019-05-29  1:47   ` Peng Fan
2019-05-29  6:40   ` Lukasz Majewski [this message]
2019-05-29  7:34     ` Y.b. Lu
2019-05-21  8:53 ` [U-Boot] [v3, 5/5] mmc: fsl_esdhc_imx: drop useless code Y.b. Lu
2019-05-29  1:53   ` Peng Fan
2019-05-29  6:09     ` Y.b. Lu
2019-05-29  6:16       ` Peng Fan
2019-05-29  6:42   ` Lukasz Majewski
2019-05-29  7:37     ` Y.b. Lu
2019-05-30 18:23   ` Angelo Dureghello
2019-05-31  5:58     ` Peng Fan
2019-05-31  6:12     ` Y.b. Lu
2019-05-31  7:15       ` Angelo Dureghello
2019-06-03  4:28         ` Y.b. Lu
2019-06-22 21:42           ` Angelo Dureghello
2019-06-24  1:23             ` Y.b. Lu
2019-06-24  9:26               ` Angelo Dureghello
2019-06-24  2:05       ` Marek Vasut
2019-05-23  8:36 ` [U-Boot] [v3, 0/5] Split fsl_esdhc driver for i.MX linux-kernel-dev
2019-05-23  9:15   ` Lukasz Majewski
2019-05-29  6:21 ` Lukasz Majewski

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=20190529084019.1b97bdd2@jawa \
    --to=lukma@denx.de \
    --cc=u-boot@lists.denx.de \
    /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.