[imx8mn ddr3l evk] error during uart3 init on u-boot
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
here is part of arch/arm/dts/imx8mn-evk.dtsi for uart3(original source).
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
assigned-clocks = <&clk IMX8MN_CLK_UART3>;
assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_80M>;
u-boot,dm-spl;
uart-has-rtscts;
status = "okay";
};
with this dts, run uart_test. it show error message like below.
error is "could not get parent clock pointer, id 111"
I haven't touch any dts for clock.
I tried to remove "assigned-clock-parents item", then it works without error.
So, I got a question,
how to fix this issue ? Is it ok if removing "assigned-clock-parents " in dts file ? any impact ?
u-boot=> uart_test uart3 9600 48656C6C6F2C2055415254210A
trying to uclass_get_device_by_name: serial@30880000...
device_probe: udevice->name: serial@30880000
device_probe: udevice->name: spba-bus@30800000
device_probe: udevice->name: uart3grp
device_probe: udevice->name: pinctrl@30330000
clk_set_defaults(uart3grp)
clk_set_default_parents: could not read assigned-clock-parents for 000000007df08f70
clk_set_defaults(serial@30880000)
clk_get_by_indexed_prop(dev=000000007df09f30, index=0, clk=000000007def9af8)
device_probe: udevice->name: clock-controller@30380000
clk_of_xlate_default(clk=000000007def9af8)
clk_request(dev=000000007df09510, clk=000000007def9af8)
clk_get_by_indexed_prop(dev=000000007df09f30, index=0, clk=000000007def9ad0)
device_probe: udevice->name: clock-controller@30380000
clk_of_xlate_default(clk=000000007def9ad0)
clk_request(dev=000000007df09510, clk=000000007def9ad0)
clk_set_default_get_by_id(): could not get parent clock pointer, id 111
clk_set_parent(clk=000000007def9ad0, parent=000000007df0ea80)
clk_set_default_parents: failed to reparent clock 0 for serial@30880000
u-boot=>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for your reply.
so far, it works well.
but I got a question. So, how to find source clock for uart3 including uart 1,2,4 as well?
I tryed to call clk dump, but uart clock doesn't show up.
Could you guide me how to find the clock source for each uart port ?
=================================================
u-boot=> clk dump
Rate Usecnt Name
------------------------------------------
32768 0 |-- clock-osc-32k
24000000 4 |-- clock-osc-24m
24000000 0 | |-- video_pll1_ref_sel
594000000 0 | | `-- video_pll1
594000000 0 | | `-- video_pll1_bypass
594000000 0 | | `-- video_pll1_out
27000000 0 | | `-- dsi_phy_ref
24000000 0 | |-- dram_pll_ref_sel
400000000 0 | | `-- dram_pll
400000000 0 | | `-- dram_pll_bypass
400000000 0 | | `-- dram_pll_out
24000000 0 | |-- arm_pll_ref_sel
1200000000 0 | | `-- arm_pll
1200000000 0 | | `-- arm_pll_bypass
1200000000 0 | | `-- arm_pll_out
24000000 1 | |-- sys_pll1_ref_sel
800000000 1 | | `-- sys_pll1
800000000 1 | | `-- sys_pll1_bypass
800000000 3 | | `-- sys_pll1_out
40000000 0 | | |-- sys_pll1_40m
80000000 0 | | |-- sys_pll1_80m
100000000 0 | | |-- sys_pll1_100m
100000000 0 | | | `-- usb_phy_ref
133333333 1 | | |-- sys_pll1_133m
133333333 2 | | | `-- ahb
66666667 3 | | | `-- ipg_root
66666667 0 | | | `-- ocotp_root_clk
160000000 0 | | |-- sys_pll1_160m
200000000 0 | | |-- sys_pll1_200m
266666666 3 | | |-- sys_pll1_266m
266666666 3 | | | |-- nand_usdhc_bus
266666666 0 | | | | `-- nand_usdhc_rawnand_clk
266666666 0 | | | |-- dsi_core
266666666 2 | | | `-- enet_axi
266666666 3 | | | `-- enet1_root_clk
400000000 2 | | |-- sys_pll1_400m
200000000 0 | | | |-- usdhc1
200000000 0 | | | | `-- usdhc1_root_clk
400000000 0 | | | |-- qspi
400000000 0 | | | | `-- qspi_root_clk
400000000 2 | | | |-- usdhc2
400000000 2 | | | | `-- usdhc2_root_clk
400000000 2 | | | `-- usdhc3
400000000 2 | | | `-- usdhc3_root_clk
800000000 0 | | `-- sys_pll1_800m
200000000 0 | | `-- disp_apb
200000000 0 | | `-- disp_apb_root_clk
24000000 1 | |-- sys_pll2_ref_sel
1000000000 1 | | `-- sys_pll2
1000000000 1 | | `-- sys_pll2_bypass
1000000000 3 | | `-- sys_pll2_out
50000000 2 | | |-- sys_pll2_50m
50000000 2 | | | `-- enet_phy
100000000 2 | | |-- sys_pll2_100m
100000000 2 | | | `-- enet_timer
125000000 2 | | |-- sys_pll2_125m
125000000 2 | | | `-- enet_ref
166666666 0 | | |-- sys_pll2_166m
200000000 0 | | |-- sys_pll2_200m
50000000 0 | | | |-- ecspi1
50000000 0 | | | | `-- ecspi1_root_clk
50000000 0 | | | |-- ecspi2
50000000 0 | | | | `-- ecspi2_root_clk
50000000 0 | | | `-- ecspi3
50000000 0 | | | `-- ecspi3_root_clk
250000000 0 | | |-- sys_pll2_250m
333333333 0 | | |-- sys_pll2_333m
500000000 0 | | |-- sys_pll2_500m
500000000 0 | | | |-- arm_a53_src
500000000 0 | | | | `-- arm_a53_cg
500000000 0 | | | | `-- arm_a53_div
500000000 0 | | | |-- usb_bus
500000000 0 | | | | `-- usb1_ctrl_root_clk
500000000 0 | | | `-- nand
500000000 0 | | | `-- nand_root_clk
1000000000 0 | | `-- sys_pll2_1000m
500000000 0 | | `-- disp_axi
500000000 0 | | `-- disp_axi_root_clk
24000000 0 | |-- sys_pll3_ref_sel
600000000 0 | | `-- sys_pll3
600000000 0 | | `-- sys_pll3_bypass
600000000 0 | | `-- sys_pll3_out
24000000 2 | |-- i2c1
24000000 2 | | `-- i2c1_root_clk
24000000 2 | |-- i2c2
24000000 2 | | `-- i2c2_root_clk
24000000 0 | |-- i2c3
24000000 0 | | `-- i2c3_root_clk
24000000 0 | |-- i2c4
24000000 0 | | `-- i2c4_root_clk
24000000 0 | |-- wdog
24000000 0 | | |-- wdog1_root_clk
24000000 0 | | |-- wdog2_root_clk
24000000 0 | | `-- wdog3_root_clk
24000000 0 | |-- usb_core_ref
24000000 0 | |-- disp_pixel
24000000 0 | | `-- disp_pixel_clk
24000000 0 | |-- dsi_dbi
24000000 0 | `-- camera_pixel
24000000 0 | `-- camera_pixel_clk
133000000 0 |-- clock-ext1
133000000 0 |-- clock-ext2
133000000 0 |-- clock-ext3
133000000 0 |-- clock-ext4
u-boot=>

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
All UART, at least in our BSP, uses SYS_PLL1_80M
Best regards/Saludos,
Aldo.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your reply.
you mean uart clock is hardwired with SYS_PLL1_80M, or configured.
if it's hardwired, Could you let me know how to check it with register ?
-Best Regards-

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
It is configured that way, even one could check the root clock on the CCM register, by reading the register 3038_44B0 (CCM_CCGR75).
Best regards/Saludos,
Aldo.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
u-boot=> md 0x303844b0 1
303844b0: 00000003 ....
u-boot=>
I can't catch the meaning of 0x00000003 for address 303844b0.
could you guide me how to find the clock of uart3 with this ?
-Best Regards-
Justin-Inno

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Please do accept my apologize for the confusion it is a different register, it should be:
3038_A580 Target Register (CCM_TARGET_ROOT75)
Best regards/Saludos,
Aldo.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Could you share the Uboot version that you are working with?
Also, could you share the logs of a working test?
Best regards/Saludos,
Aldo.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
my dev environment: imx-6.1.55-2.2.1
(repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-mickledore -m imx-6.1.55-2.2.1.xml)
<< u-boot log >>
U-Boot SPL 2023.04-lf_v2023.04+g49b102d9888 (Nov 21 2023 - 07:28:53 +0000)
DDR Initialization
DDRINFO: start DRAM init...
DDRINFO: DRAM rate 1600MTS
DDRINFO:ddrphy calibration done
DDRINFO: ddrmix config done
DDRINFO: end DRAM init...
SEC0: RNG instantiated
Normal Boot
Trying to boot from BOOTROM
Boot Stage: Primary boot
image offset 0x0, pagesize 0x200, ivt offset 0x0
NOTICE: Do not release JR0 to NS as it can be used by HAB
NOTICE: BL31: v2.8(release):lf-6.1.55-2.2.1-rc1-0-g08e9d4eef-dirty
NOTICE: BL31: Built : 06:43:30, Nov 21 2023
U-Boot 2023.04-lf_v2023.04+g49b102d9888 (Nov 21 2023 - 07:28:53 +0000)
CPU: i.MX8MNano UltraLite Quad rev1.0 1400 MHz (running at 1200 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 30C
Reset cause: POR
Model: NXP i.MX8MNano DDR3L EVK board
DRAM: 992 MiB
tcpc_init: Can't find device id=0x52
setup_typec: tcpc port2 init failed, err=-19
tcpc_init: Can't find device id=0x50
setup_typec: tcpc port1 init failed, err=-19
Core: 199 devices, 27 uclasses, devicetree: separate
MMC: FSL_SDHC: 1, FSL_SDHC: 2
Loading Environment from MMC... Select HS400ES failed -5
Select HS400 failed -5
OK
In: serial
Out: serial
Err: serial
SEC0: RNG instantiated
Select HS400ES failed -5
Select HS400 failed -5
switch to partitions #0, OK
mmc2(part 0) is current device
flash target is MMC:2
Select HS400ES failed -5
Select HS400 failed -5
Net: ksz-switch switch@5f: ksz_i2c_probe switch@5f master:ethernet@30be0000
ksz-switch switch@5f: ksz_i2c_probe id=0x00989600
KSZ9896CS: eth0: ethernet@30be0000
Fastboot: Normal
Normal Boot
Hit any key to stop autoboot: 0
u-boot=>
<< u-boot, arch/arm/dts/imx8mn-evk.dtsi >>
&uart1 { /* console */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
u-boot,dm-spl;
status = "okay";
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
status = "okay";
};
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
assigned-clocks = <&clk IMX8MN_CLK_UART3>;
assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_80M>;
u-boot,dm-spl;
uart-has-rtscts;
status = "okay";
};
<< u-boot, board/freescale/imx8mn_evk/imx8mn_evk.c>>
static iomux_v3_cfg_t const uart_pads[] = {
IMX8MN_PAD_UART1_RXD__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
IMX8MN_PAD_UART1_TXD__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
IMX8MN_PAD_UART2_RXD__UART2_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
IMX8MN_PAD_UART2_TXD__UART2_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
IMX8MN_PAD_ECSPI1_SCLK__UART3_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
IMX8MN_PAD_ECSPI1_MOSI__UART3_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
IMX8MN_PAD_ECSPI1_MISO__UART3_DCE_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
IMX8MN_PAD_ECSPI1_SS0__UART3_DCE_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
};
int board_early_init_f(void)
{
struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
set_wdog_reset(wdog);
imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
init_uart_clk(0);
init_uart_clk(1);
init_uart_clk(2);
#ifdef CONFIG_NAND_MXS
setup_gpmi_nand(); /* SPL will call the board_early_init_f */
#endif
return 0;
}
<< u-boot, cmd/uart_test.c>>
abc@dev:~/yocto/build/tmp/work/imx8mnul_ddr3l_evk-poky-linux/u-boot-imx/2023.04-r0/git/cmd (lf_v2023.04)$ cat uart_test.c
#include <common.h>
#include <command.h>
#include <dm.h>
#include <serial.h>
#include <dm/device.h>
#include <dm/uclass.h>
#include <dm/device-internal.h> // device_probe()
#include <dm/uclass-internal.h> // uclass_first_device(), uclass_next_device()
static const struct {
const char *alias;
const char *device_name;
} uart_aliases[] = {
{ "uart2", "serial@30890000" },
{ "uart3", "serial@30880000" },
{ "uart4", "serial@308a0000" }
};
static const char *get_uart_device_name(const char *alias) {
for (int i = 0; i < ARRAY_SIZE(uart_aliases); i++) {
if (strcmp(alias, uart_aliases[i].alias) == 0) {
return uart_aliases[i].device_name;
}
}
return alias;
}
static int do_uart_test(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
const char *uart_name;
const char *device_name;
struct udevice *dev;
struct udevice *iter_dev;
const struct dm_serial_ops *ops;
const char *baudrate_str;
const char *hex_message;
int baudrate;
int ret;
bool found = false;
if (argc != 4) {
printf("Usage: uart_test <uart_name> <baudrate> <hex message>\n");
return CMD_RET_USAGE;
}
uart_name = argv[1];
baudrate_str = argv[2];
hex_message = argv[3];
baudrate = simple_strtoul(baudrate_str, NULL, 10);
device_name = get_uart_device_name(uart_name);
if (!gd->dm_root) {
ret = dm_scan_fdt(gd->fdt_blob, false);
if (ret) {
printf("Failed to scan FDT (error: %d)\n", ret);
return CMD_RET_FAILURE;
}
}
printf("trying to uclass_get_device_by_name: %s...\n", device_name);
ret = uclass_get_device_by_name(UCLASS_SERIAL, device_name, &dev);
if (ret) {
printf("UART device %s not found, trying to probe...\n", device_name);
ret = device_probe(dev);
if (ret) {
printf("Error: Unable to probe UART device %s (ret=%d)\n", device_name, ret);
return CMD_RET_FAILURE;
}
printf("devcie probe finished: %s ...\n", device_name);
printf("trying to uclass_get_device_by_name: %s...\n", device_name);
ret = uclass_get_device_by_name(UCLASS_SERIAL, device_name, &dev);
if (ret) {
printf("Still failed to find UART device: %s (error: %d)\n", device_name, ret);
return CMD_RET_FAILURE;
}
}
printf("UART device %s found...\n", device_name);
#if 0
if (!dev) {
printf("Error: Device not found!\n");
return CMD_RET_FAILURE;
}
ret = device_probe(dev);
if (ret) {
printf("Error: Unable to probe UART device %s (ret=%d)\n", device_name, ret);
return CMD_RET_FAILURE;
}
printf("UART device %s probed successfully.\n", device_name);
#endif
/* Set baudrate */
ops = serial_get_ops(dev);
if (!ops || !ops->putc || !ops->setbrg) {
printf("UART device does not support putc, setbrg operation\n");
return CMD_RET_FAILURE;
}
/* Get DM serial operations */
/* Set baudrate */
ret = ops->setbrg(dev, baudrate);
if (ret) {
printf("Failed to set baudrate %d on %s (error: %d)\n", baudrate, device_name, ret);
return CMD_RET_FAILURE;
}
printf("UART device: %s\n", device_name);
printf("BaudRate: %d\n", baudrate);
/* Convert hex string to binary and send */
while (*hex_message && *(hex_message + 1)) {
char hex_byte[3] = {hex_message[0], hex_message[1], '\0'};
char byte = (char) simple_strtoul(hex_byte, NULL, 16);
ops->putc(dev, byte);
hex_message += 2;
}
printf("Message sent successfully.\n");
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
uart_test, 4, 1, do_uart_test,
"Send hex message over UART",
"<uart_name> <baudrate> <hex_message>\n"
" - Send <hex_message> (hex format) to specified UART device.\n"
" example) - uart2, 115200, Hello, UART! \n => uart_test uart2 115200 48656C6C6F2C2055415254210A\n"
" example) - uart3, 9600, Hello, UART! \n => uart_test uart3 9600 48656C6C6F2C2055415254210A\n"
" example) - uart4, 9600, Hello, 1122aabb\n => uart_test uart4 9600 1122aabb\n"
);
abc@dev:~/yocto/build/tmp/work/imx8mnul_ddr3l_evk-poky-linux/u-boot-imx/2023.04-r0/git/cmd (lf_v2023.04)$

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Thank you for sharing, I do not think that removing assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_80M> is enough, is just that it skips the api that checks this is enabled correctly.
https://github.com/nxp-imx/uboot-imx/blob/lf_v2023.04/drivers/clk/clk-uclass.c#L214
num_parents = dev_count_phandle_with_args(dev, "assigned-clock-parents",
"#clock-cells", 0);
if (num_parents < 0) {
debug("%s: could not read assigned-clock-parents for %p\n",
__func__, dev);
return 0;
}
https://github.com/nxp-imx/uboot-imx/blob/lf_v2022.04/include/dm/read.h#L438
/**
* dev_count_phandle_with_args() - Return phandle number in a list
*
* This function is usefull to get phandle number contained in a property list.
* For example, this allows to allocate the right amount of memory to keep
* clock's reference contained into the "clocks" property.
*
* @Dev: device whose node containing a list
* @list_name: property name that contains a list
* @cells_name: property name that specifies phandles' arguments count
* @cell_count: Cell count to use if @cells_name is NULL
* Return: number of phandle found on success, on error returns appropriate
* errno value.
*/
For some reason I see that its returning failure, in your test you were able to test UART3 correctly with that change?
Removing assigned-clock-parents
Best regards/Saludos,
Aldo.
