How to make gpio high-level in cboot?

Dear,
I do not find a function in cboot code to pull gpio output high level or low, is there any way can help me do this?
whether or not can i change the gpio level through writing gpio regs with some funs? I really need this way.

hello gaozejun,

please access cboot sources via download center.
you’ll need to check Tegra GPIO driver APIs for accessing GPIO pins.
for example,
$L4T_Sources/r32.4.2/Linux_for_Tegra/source/public/cboot/bootloader/partner/common/drivers/gpio/tegrabl_gpio.c

static tegrabl_error_t tegrabl_gpio_read(uint32_t gpio_num, gpio_pin_state_t *state, void *drv_data)
{...}

static tegrabl_error_t tegrabl_gpio_config(uint32_t gpio_num, gpio_pin_mode_t mode, void *drv_data)
{...}

I have seen tegrabl_gpio_read{} and tegrabl_gpio_config,but i want to change gpio levels through writing gpio regs,becasue functions(tegrabl_gpio_read{} and tegrabl_gpio_config) initialization are too late, i need to pull GPIO15 high as soon as possible.

hello gaozejun,

you may access pinmux spreadsheets through download center, please also check the documentation for Pinmux and GPIO Configuration to change the board configurations.
thanks

GPIO17 is a pin for feeding watchdog,i need to change its levels between 1s.So i need a function to writing gpio regs.
if there is no functions to read or write gpio regs ,is there any example to show me how wo can use tegrabl_gpio_read(write/config).

hi,
i use functions in tegrabl_gpio.c to pull GPIO17 high,but GPIO17 is still low,can you find something wrong in my codes?

static struct gpio_driver drv = {
{
.name = TEGRA_GPIO_MAIN_DRIVER_NAME,
.phandle = -1,
.ops = &tegra_gpio_ops,
.chip_id = TEGRA_GPIO_MAIN_CHIPID,
.driver_data = (void *)&tegra_gpio_id_main,
},
{
.name = TEGRA_GPIO_AON_DRIVER_NAME,
.phandle = -1,
.ops = &tegra_gpio_ops,
.chip_id = TEGRA_GPIO_AON_CHIPID,
.driver_data = (void *)&tegra_gpio_id_aon,
},
};

gpio_config(drv, 449, GPIO_PINMODE_OUTPUT);
gpio_write(drv,449, GPIO_PIN_STATE_HIGH);

hello gaozejun,

you may check pinmux spreadsheets, that GPIO17 (i.e. GPIO3_PQ.01) were configure as pull-down by default.
could you please customize that for updating board configuration.
thanks

I need to control GPIO17 to output high or low level to feed watchdog in cboot ,so I must use tegrabl_gpio_write and tegrabl_gpio_config.
If GPIO17 (i.e. GPIO3_PQ.01) were configure as pull-down by default, can i still control it to output different levels?

hello gaozejun,

I think you’re miscalculate GPIO number for controlling.
according to gpio header, GPIO3_PQ.01 should belong to main GPIO controller groups.
$L4T_Sources/r32.4.2/Linux_for_Tegra/source/public/kernel/nvidia/include/dt-bindings/gpio/tegra194-gpio.h

/* GPIOs implemented by main GPIO controller */
...
#define TEGRA194_MAIN_GPIO_PORT_Q 16

#define TEGRA194_MAIN_GPIO(port, offset) \
        ((TEGRA194_MAIN_GPIO_PORT_##port * 8) + offset)

you may also refer to GPIO offsets from the kernel booting messages,
for example,

[    0.877253] gpiochip_setup_dev: registered GPIOs 288 to 511 on device: gpiochip0 (tegra-gpio)
[    0.886001] gpiochip_setup_dev: registered GPIOs 248 to 287 on device: gpiochip1 (tegra-gpio-aon)

GPIO3_PQ.01 should have pin number as shown, (16*8) + 288 + 1 = 417.
please have a try to control that with APIs.
thanks

I still can not control the GPIO17 with code shown below.

static struct gpio_driver drv = {
{
.name = TEGRA_GPIO_MAIN_DRIVER_NAME,
.phandle = -1,
.ops = &tegra_gpio_ops,
.chip_id = TEGRA_GPIO_MAIN_CHIPID,
.driver_data = (void *)&tegra_gpio_id_main,
},
{
.name = TEGRA_GPIO_AON_DRIVER_NAME,
.phandle = -1,
.ops = &tegra_gpio_ops,
.chip_id = TEGRA_GPIO_AON_CHIPID,
.driver_data = (void *)&tegra_gpio_id_aon,
},
};
#define FEED_WDT 417
void feed_wdt(void)
{
tegrabl_gpio_write(FEED_WDT, GPIO_PIN_STATE_HIGH, drv[0].driver_data);
tegrabl_mdelay(100);
tegrabl_gpio_write(FEED_WDT, GPIO_PIN_STATE_LOW, drv[0].driver_data);
}

I run “feed_wdt()” in cboot_src_t19x/bootloader/partner/common/drivers/gpio/tegrabl_gpio.c.
My cboot_src_t19x code is running on Xavier platform.
Whether or not you have verified these functions
(
.read = &tegrabl_gpio_read,
.write = &tegrabl_gpio_write,
.config = &tegrabl_gpio_config
)?

I have check the hardware, gpio can output high/low level in driver of kernel, so hardware is ok.

hello gaozejun,

could you please also gather bootloader messages for checking,
you might add some debug prints to indicate you’d toggle GPIO17.
thanks

I add some debug prints.It shows that running code has enter this function gpio_config(),
error = gpio_config(gpio_drv, gpio_num, GPIO_PINMODE_OUTPUT);
if (error != TEGRABL_NO_ERROR) {
pr_error("%s: Error config gpio pin\n", func);
return error;
}
But gpio_config return error.

#define FEED_WDT 417
uint32_t gpio_wdt_out(void)
{
tegrabl_error_t error = TEGRABL_NO_ERROR;
struct gpio_driver *gpio_drv;
uint32_t chip_id;
uint32_t gpio_num;

chip_id = TEGRA_GPIO_MAIN_CHIPID;
gpio_num = FEED_WDT;
pr_info("Enabling gpio chip_id = %u, gpio pin = %u\n", chip_id, gpio_num);

	pr_info("\n----------gpio_wdt_out----------\n");

error = tegrabl_gpio_driver_get(chip_id, &gpio_drv);
if (error != TEGRABL_NO_ERROR) {
	pr_error("%s: Can't get gpio driver\n", __func__);
	return error;
}

error = gpio_config(gpio_drv, gpio_num, GPIO_PINMODE_OUTPUT);
if (error != TEGRABL_NO_ERROR) {
	pr_error("%s: Error config gpio pin\n", __func__);
	return error;
}

error = gpio_write(gpio_drv, gpio_num, GPIO_PIN_STATE_HIGH);
if (error != TEGRABL_NO_ERROR) {
	pr_error("%s: Error enabling gpio pin\n", __func__);
	return error;
}

 tegrabl_mdelay(20);

error = gpio_write(gpio_drv, gpio_num, GPIO_PIN_STATE_LOW);
if (error != TEGRABL_NO_ERROR) {
	pr_error("%s: Error enabling gpio pin\n", __func__);
	return error;
}

return 0;

}

I doubt the parameter of gpio_num is not the value of (group+(port*8)+pin).

hello gaozejun,

you’re right, above pin number calculation formula was based-on boot into linux kernel.
please using cboot marcos for writing GPIO pins,
for example,

static status_t tegra_gpio_write(uint32_t gpio_num, enum gpio_pin_state state, void *drv_data)
{
        ...
        GPIO_WRITE(GPIO_PORT_BASE(gpio_num), OUT, GPIO_PIN(gpio_num), reg_val);

I have solved this problem.
The parameter gpio_num is the value of (port*8)+pin, not include group.
SO in this function, GPIO17(GPIO3_PQ.01) will be 129.