When the IMX8MQ SoC is powered on, the UBOOT initializes GPIO in the BOARD_EARLY_INIT_F function.However, GPIO is not controlled at the moment of power on, what should I do to achieve such control effect?thank you.
Hi,
in spl.c of i.mx8mq board , there is example code for GPIO opreations:
...
#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 12)
#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10)
#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19)
int board_mmc_getcd(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
int ret = 0;
switch (cfg->esdhc_base) {
case USDHC1_BASE_ADDR:
ret = 1;
break;
case USDHC2_BASE_ADDR:
ret = !gpio_get_value(USDHC2_CD_GPIO);
return ret;
}
return 1;
}
#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \
PAD_CTL_FSEL2)
#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1)
static iomux_v3_cfg_t const usdhc1_pads[] = {
IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
static iomux_v3_cfg_t const usdhc2_pads[] = {
IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0x16 */
IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
IMX8MQ_PAD_SD2_CD_B__GPIO2_IO12 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
};
static struct fsl_esdhc_cfg usdhc_cfg[2] = {
{USDHC1_BASE_ADDR, 0, 8},
{USDHC2_BASE_ADDR, 0, 4},
};
int board_mmc_init(bd_t *bis)
{
int i, ret;
/*
* According to the board_mmc_init() the following map is done:
* (U-Boot device node) (Physical Port)
* mmc0 USDHC1
* mmc1 USDHC2
*/
for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
switch (i) {
case 0:
init_clk_usdhc(0);
usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
imx_iomux_v3_setup_multiple_pads(usdhc1_pads,
ARRAY_SIZE(usdhc1_pads));
gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset");
gpio_direction_output(USDHC1_PWR_GPIO, 0);
udelay(500);
gpio_direction_output(USDHC1_PWR_GPIO, 1);
break;
case 1:
init_clk_usdhc(1);
usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
imx_iomux_v3_setup_multiple_pads(usdhc2_pads,
ARRAY_SIZE(usdhc2_pads));
gpio_request(USDHC2_PWR_GPIO, "usdhc2_reset");
gpio_direction_output(USDHC2_PWR_GPIO, 0);
udelay(500);
gpio_direction_output(USDHC2_PWR_GPIO, 1);
break;
default:
printf("Warning: you configured more USDHC controllers(%d) than supported by the board\n", i + 1);
return -EINVAL;
}
ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
if (ret)
return ret;
}
return 0;
}
....
You can refer to them.
weidong
Hi,
The API interface of dm-gpio is used in u-boot. There are already examples in imx8mq_evk.c:
struct gpio_desc type_sel_desc;
static iomux_v3_cfg_t ss_mux_gpio[] = {
IMX8MQ_PAD_NAND_RE_B__GPIO3_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
void ss_mux_select(enum typec_cc_polarity pol)
{
if (pol == TYPEC_POLARITY_CC1)
dm_gpio_set_value(&type_sel_desc, 1);
else
dm_gpio_set_value(&type_sel_desc, 0);
}
static int setup_typec(void)
{
int ret;
imx_iomux_v3_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio));
ret = dm_gpio_lookup_name("GPIO3_15", &type_sel_desc);
if (ret) {
printf("%s lookup GPIO3_15 failed ret = %d\n", __func__, ret);
return -ENODEV;
}
ret = dm_gpio_request(&type_sel_desc, "typec_sel");
if (ret) {
printf("%s request typec_sel failed ret = %d\n", __func__, ret);
return -ENODEV;
}
dm_gpio_set_dir_flags(&type_sel_desc, GPIOD_IS_OUT);
ret = tcpc_init(&port, port_config, &ss_mux_select);
if (ret) {
printf("%s: tcpc init failed, err=%d\n",
__func__, ret);
}
return ret;
}
so you can refer to above source code to configure your GPIO.
Have a nice day!
B.R,
weidong
I did GPIO initialization in the board_early_init_f () function, which should be earlier than the method initialization you mentioned, but it will take 200ms to run this function after power on.
If you want to use this GPIO early, you can also wire its code in spl.c. OK?
yes,I initialize the GPIO in spl_board_init(), and I still can't pull the GPIO up or down when I power it up.