40hdr - SPI1 gpio padctl register bit[10] effect by gpiod tools in JP6

Hi Nvidia Teams.

We are trying to use 40pin hdr gpio (PZ.03~PZ.07) , and there is something weird on GPIO behavier.

Here is our step :

  1. use same pinmux setting as devkit does ( gpio input)

  2. check register status after system boot-up (all pin is input )
    register show bit[10]=0 , bit[6,4]=1 , same as online document requried.

  1. use gpioget to get pin status.
    all these pins can reflect current pin status
    image

  2. re-check register status of PZ.03~07
    we found all register bit[10] was changed to 1
    image

  3. To set PZ.03~07 as output pin
    set register value to 0x1 by devmem tool. and read back register status
    **

  4. set PZ.03~07 as output low , and check register value after use gpioset

  5. to measure PZ.03~07 by multimeter
    all this pin status is H , can not be set to low , until we reset all register to 0x1

As on-line document shows : bit[10] should be [0] , but it was always modified when gpiod(gpioget/gpioset) tools called.

We also do the same test on JP5 BSP , gpiod(gpioget/gpioset) won’t make register bit 10 value from 0 to 1.

Need nvidia teams to help us to clarify how to test gpio pin in userspace in JP6 bsp.

Regards

Hi yi-chia.lan,

Are you using the devkit or custom board for AGX Orin?

We’ve found that gpiod tool (gpioget/gpioset) may modify the pinmux register.
Those pins are configured as Input/Int PD in pinmux spreadsheet by default.
Could you try to configure them as Bidirectional/NA instead?

Please also let us know what’s your use case for those pins. (SPI or GPIO? Input/Output? HIgh/Low?)

Hi KevinFFF,

we do set pinmux as what you mentrioned, but still the same sitution. (both on devkit and customize board)
I think register bit 10 is the key.
would like to know what is the difference between JP5 and JP6, because JP5 register bit 10 won’t be changed after gpiod tools been use.

we also download/test gpiod version 1.4.1 as JP5 used on JP6 environment, we found registser 10 still been modified after gpioset/gpioget called.

we also set register bit 10 on JP5 by devmem tool. once the bit was set , the gpio status is same as JP6 shows.

Please help to provide the way to use userspace gpio on JP6 bsp.

Regards

Bit 10 should be 0 for GPIO usage.

Would you still hit the issue after configuring it as Bidirectional/NA in pinmux spreadsheet?

Hi KevinFFF,

Yes, still hit the issue.

Regards

Could you share the result of the following command on your board? (before and after you run gpiod command)

$ sudo busybox devmem 0x0243d028

Hi KevinFFF,

The bit 10 should be change to 1 after gpioget.
Is the issue specific to PZ.03?
How about you run gpioget for other GPIO?

Hi Kevin,

  1. Not only PZ.03 bit 10 been changed, all PZ03~PZ07 bit 10 changed to 1.

  2. If bit 10 should be changed to 1 after gpiod been called as you mentioned.
    How do user access gpio pin on userspace ??

  3. bit 10 only changed from 0 to 1 after gpiod been called on JP6 BSP, the same access didn’t happen on JP5.
    So , what is different between JP5 and JP6?

Regards

We checked this issue with our engineers and it seems that when starting gpioget and gpioset, the SFIO bit is disabled by the pinctrl driver. Once gpioset and gpioget exit, the SFIO is enabled by the pinctrl driver. So basically when the command is running, the pins are configured to GPIO and turned into SFIO when the command exits.

this means that gpioget behaviour is correct as it reflects the current pin status.

For gpioset, we can look at the manual
gpioset(1) — gpiod — Debian bullseye — Debian Manpages

It says
Set GPIO line values of a GPIO chip and maintain the state until the process exits
so that means the state of GPIO line is not guaranteed to be the same once the process exits.

Therefore, you can do something like
gpioset -m wait gpiochip0 133=0

then it will be zero until you press enter. There are also other modes you can use if you look in the manual

1 Like

Hi @yi-chia.lan,

Please apply the following patch and check if it could help for your case.

diff --git a/drivers/pinctrl/tegra/pinctrl-tegra234.c b/drivers/pinctrl/tegra/pinctrl-tegra234.c
index fd7072539216..61baee288671 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra234.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra234.c
@@ -1812,7 +1812,7 @@ static const struct tegra_pinctrl_soc_data tegra234_pinctrl = {
 	.hsm_in_mux = false,
 	.schmitt_in_mux = true,
 	.drvtype_in_mux = true,
-	.sfsel_in_mux = true,
+	.sfsel_in_mux = false,
 };
 
 static const struct pinctrl_pin_desc tegra234_aon_pins[] = {
@@ -1929,7 +1929,7 @@ static const struct tegra_pinctrl_soc_data tegra234_pinctrl_aon = {
 	.hsm_in_mux = false,
 	.schmitt_in_mux = true,
 	.drvtype_in_mux = true,
-	.sfsel_in_mux = true,
+	.sfsel_in_mux = false,
 };
 
 static int tegra234_pinctrl_probe(struct platform_device *pdev)
1 Like

Have you tried that patch? Any result can be shared?

Hi Kayccc,

yes, this patch can fix SFIP be modified by gpiod tools issue.

Regards

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

This issue may affect to control GPIO in JP6.
We have an official patch to fix this issue as following:

diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
index 953a3a650a9e..7022faa2a7ce 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
@@ -281,7 +281,7 @@ static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
 
 
 static const struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev *pctldev,
-                                                       unsigned int offset)
+					unsigned int offset, struct tegra_pingroup_config **config)
 {
 		struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 		unsigned int group, num_pins, j;
@@ -293,9 +293,12 @@ static const struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev *
 			if (ret < 0)
 				continue;
 			for (j = 0; j < num_pins; j++) {
-				if (offset == pins[j])
+				if (offset == pins[j]) {
+					if (config)
+						*config = &pmx->pingroup_configs[group];
 
 				return &pmx->soc->groups[group];
+				}
 			}
 		}
 
@@ -309,12 +312,14 @@ static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
 {
 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 	const struct tegra_pingroup *group;
+	struct tegra_pingroup_config *config;
 	u32 value;
 
 	if (!pmx->soc->sfsel_in_mux)
 		return 0;
 
-	group = tegra_pinctrl_get_group(pctldev, offset);
+	group = tegra_pinctrl_get_group(pctldev, offset, &config);
+
 	if (!group)
 		return -EINVAL;
 
@@ -323,6 +328,7 @@ static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
 		return -EINVAL;
 
 	value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
+	config->is_sfsel = (value & BIT(group->sfsel_bit)) != 0;
 	value &= ~BIT(group->sfsel_bit);
 	pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
 
@@ -335,12 +341,14 @@ static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
 {
 	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 	const struct tegra_pingroup *group;
+	struct tegra_pingroup_config *config;
 	u32 value;
 
 	if (!pmx->soc->sfsel_in_mux)
 		return;
 
-	group = tegra_pinctrl_get_group(pctldev, offset);
+	group = tegra_pinctrl_get_group(pctldev, offset, &config);
+
 	if (!group)
 		return;
 
@@ -348,7 +356,8 @@ static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
 		return;
 
 	value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
-	value |= BIT(group->sfsel_bit);
+	if (config->is_sfsel)
+		value |= BIT(group->sfsel_bit);
 	pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
 }
 
@@ -801,6 +810,11 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
 	pmx->dev = &pdev->dev;
 	pmx->soc = soc_data;
 
+	pmx->pingroup_configs = devm_kcalloc(&pdev->dev,
+		pmx->soc->ngroups, sizeof(*pmx->pingroup_configs), GFP_KERNEL);
+	if (!pmx->pingroup_configs)
+		return -ENOMEM;
+
 	/*
 	 * Each mux group will appear in 4 functions' list of groups.
 	 * This over-allocates slightly, since not all groups are mux groups.

diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.h b/drivers/pinctrl/tegra/pinctrl-tegra.h
index 216cc59b62b4..a47ac519f3ec 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.h
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.h
@@ -8,6 +8,10 @@
 #ifndef __PINMUX_TEGRA_H__
 #define __PINMUX_TEGRA_H__
 
+struct tegra_pingroup_config {
+	bool is_sfsel;
+};
+
 struct tegra_pmx {
 	struct device *dev;
 	struct pinctrl_dev *pctl;
@@ -21,6 +25,8 @@ struct tegra_pmx {
 	int nbanks;
 	void __iomem **regs;
 	u32 *backup_regs;
+	/* Array of size soc->ngroups */
+	struct tegra_pingroup_config *pingroup_configs;
 };
 
 enum tegra_pinconf_param {
-- 
3 Likes