question about SD_CARD

Hi,
We made a carrier board and have an SD card interface. This interface is not very stable when initializing some SD cards.
Through measurement, we found that our board still has a voltage of about 1V on the power supply pin of the SD card when the SD card power is off. This power supply does not meet the power requirements of the SD card, causing the SD card to sometimes not work properly.
We tested two cases:
1.SD card does not insert SD card socket
When SDCARD_PWR_EN is off, the power pin voltage of the SD card is 0.
2.SD card is inserted into the SD card socket
When SDCARD_PWR_EN is off, the power supply pin voltage of the SD card is more than 1V.
In addition, I measured that when SDCARD_PWR_EN is off, TX2’s D0, D1, D2, D3 signals, some of the outputs are 3.3V.I think because these signals have 3.3V voltage, the SD card power pin voltage is caused not 0V.
The difference between our SD card power circuit and the TX2 DEV KIT is that the load switch of the sd card we use does not have a power discharge function.
Our board cannot be redesigned for some reason. Is there a way to make TX2 SD card signal D0, D1, D2, D3, CMD, CLK output 0V when SDCARD_PWR_EN is off?

Hi, did you see same behavior on devkit? If not, it might be cause by your load switch, not sure how to solve it, maybe you can ask vendor for more help?

I don’t see the same behavior on devkit.
I am sure this problem was introduced by my load switch. My load switch has no power discharge function.
But my hardware can’t be changed now.
I want to solve this problem by making the IOs(SDCARD_CLK,SDCARD_CMD,SDCARD_D0~D3) output low when the load switch is turned off. I don’t know which register can control the IOs output low.
I am trying to change sdhci-tegra.c. But I don’t know which register should be operated.

Hi wwph,

Have you read the TX2 TRM for register information?

Yes, I read the document “TECHNICAL REFERENCE MANUAL NVIDIA Parker Series SoC”. But I haven’t seen how to set IOs to low. Please give me some help!
thank you very much!

Hi WayneWWW,
I still can’t make the IOs output low. Do you have any news or suggestions?

Please help.

For TX2, dynamic updating the pinmux registers to program the SD lines is not recomended.
Boot time programming for the lines are here
tegra186-mb1-bct-pinmux-quill-p3310-1000-c03.cfg

pinmux.0x02438000 = 0x00004464; # sdmmc1_clk_pd0: sdmmc1, pull-down, tristate-disable, input-enable, loopback-enable
pinmux.0x02438008 = 0x00004448; # sdmmc1_cmd_pd1: sdmmc1, pull-up, tristate-disable, input-enable
pinmux.0x0243802c = 0x00000448; # sdmmc1_dat0_pd2: sdmmc1, pull-up, tristate-disable, input-enable
pinmux.0x02438024 = 0x00004448; # sdmmc1_dat1_pd3: sdmmc1, pull-up, tristate-disable, input-enable
pinmux.0x0243801c = 0x00000448; # sdmmc1_dat2_pd4: sdmmc1, pull-up, tristate-disable, input-enable
pinmux.0x02438014 = 0x00004448; # sdmmc1_dat3_pd5: sdmmc1, pull-up, tristate-disable, input-enable

You can try playing with these configurations to make the pins as input to stop detection when card is not inserted?

The SD card is always in the SD card slot. Cannot be inserted or removed.
I use blow code for test.
#define SDMMC1_HV_BASE 0x02438000
struct sdmmc1_padctl
{
volatile unsigned int sdmmc1_clk;
volatile unsigned int sdmmc1_clk_cfg;
volatile unsigned int sdmmc1_cmd;
volatile unsigned int sdmmc1_cmd_cfg;
volatile unsigned int sdmmc1_comp;
volatile unsigned int sdmmc1_dat3;
volatile unsigned int sdmmc1_dat3_cfg;
volatile unsigned int sdmmc1_dat2;
volatile unsigned int sdmmc1_dat2_cfg;
volatile unsigned int sdmmc1_dat1;
volatile unsigned int sdmmc1_dat1_cfg;
volatile unsigned int sdmmc1_dat0;
volatile unsigned int sdmmc1_dat0_cfg;
};
#define SDHCI_IO_SET_INPUT 0x01
#define SDHCI_IO_SET_BACK 0x02
static int tegra_sdhci_configure_ios(struct sdhci_host *sdhci,u8 flag)
{
struct sdmmc1_padctl * sdmmc1_padctl_ptr;
u32 val[6];
if(strcmp(sdhci->hw_name,“3400000.sdhci”) != 0)
{
printk(“pww:name no match= %s\n”,sdhci->hw_name);
return -1;
}
switch(flag)
{
case SDHCI_IO_SET_INPUT:
sdmmc1_padctl_ptr = ioremap(SDMMC1_HV_BASE, sizeof(struct sdmmc1_padctl));
val[0] = readl(&(sdmmc1_padctl_ptr->sdmmc1_clk));
val[1] = readl(&(sdmmc1_padctl_ptr->sdmmc1_cmd));
val[2] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat3));
val[3] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat2));
val[4] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat1));
val[5] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat0));

		writel ((val[0] & 0xffffffe0 ) | ((0x01 << 4) | (0x01 << 2)),&(sdmmc1_padctl_ptr->sdmmc1_clk));
		writel ((val[1] & 0xffffffe0 ) | ((0x01 << 4) | (0x01 << 2)),&(sdmmc1_padctl_ptr->sdmmc1_cmd));
		writel ((val[2] & 0xffffffe0 ) | ((0x01 << 4) | (0x01 << 2)),&(sdmmc1_padctl_ptr->sdmmc1_dat3));
		writel ((val[3] & 0xffffffe0 ) | ((0x01 << 4) | (0x01 << 2)),&(sdmmc1_padctl_ptr->sdmmc1_dat2));
		writel ((val[4] & 0xffffffe0 ) | ((0x01 << 4) | (0x01 << 2)),&(sdmmc1_padctl_ptr->sdmmc1_dat1));
		writel ((val[5] & 0xffffffe0 ) | ((0x01 << 4) | (0x01 << 2)),&(sdmmc1_padctl_ptr->sdmmc1_dat0));
		iounmap(sdmmc1_padctl_ptr);
		release_mem_region(SDMMC1_HV_BASE, sizeof(struct sdmmc1_padctl));
	break;
	case SDHCI_IO_SET_BACK:
		sdmmc1_padctl_ptr = ioremap(SDMMC1_HV_BASE, sizeof(struct sdmmc1_padctl));
		val[0] = readl(&(sdmmc1_padctl_ptr->sdmmc1_clk));
		val[1] = readl(&(sdmmc1_padctl_ptr->sdmmc1_cmd));
		val[2] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat3));
		val[3] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat2));
		val[4] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat1));
		val[5] = readl(&(sdmmc1_padctl_ptr->sdmmc1_dat0));

		writel ((val[0] & 0xffffffe0 ) | (0x01 << 3),&(sdmmc1_padctl_ptr->sdmmc1_clk));
		writel ((val[1] & 0xffffffe0 ) | (0x01 << 3),&(sdmmc1_padctl_ptr->sdmmc1_cmd));
		writel ((val[2] & 0xffffffe0 ) | (0x01 << 3),&(sdmmc1_padctl_ptr->sdmmc1_dat3));
		writel ((val[3] & 0xffffffe0 ) | (0x01 << 3),&(sdmmc1_padctl_ptr->sdmmc1_dat2));
		writel ((val[4] & 0xffffffe0 ) | (0x01 << 3),&(sdmmc1_padctl_ptr->sdmmc1_dat1));
		writel ((val[5] & 0xffffffe0 ) | (0x01 << 3),&(sdmmc1_padctl_ptr->sdmmc1_dat0));
		iounmap(sdmmc1_padctl_ptr);
		release_mem_region(SDMMC1_HV_BASE, sizeof(struct sdmmc1_padctl));
	break;
	default:
	break;
}
return 0;

}

Called as follows:
static int tegra_sdhci_configure_regulators(struct sdhci_host *sdhci,
u8 option, int min_uV, int max_uV)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci);
struct sdhci_tegra *tegra_host = pltfm_host->priv;
int rc = 0;

switch (option) {
case CONFIG_REG_GET:
	if(strcmp(sdhci->hw_name,"3400000.sdhci") == 0)
	{
		tegra_sdhci_configure_ios(sdhci,SDHCI_IO_SET_INPUT);
		mdelay(1000);
		tegra_sdhci_configure_ios(sdhci,SDHCI_IO_SET_BACK);
	}

This will set the SD card ios to low. At the same time, the power supply can reach 0V. However, it cannot be set to high or low with the SD card power supply. Especially the power-on process. At power-on, the power supply will output 1V first, then output 3.3V.
Where can I set these IOs to be synchronized to the power supply?