[PATCH 0/3] rockchip: rk3308: Fix two minor UART warnings

Two minor issues arise as warning during boot phases once log features and CONFIG_LOG_ERROR_RETURN are enabled:
- clk_get_rate() return err (SPL, pre relocation and U-Boot proper phases) - uclass_get_device_by_phandle_id() return err (pre relocation phase only)
Both issues are not fatal and do not cause any functional problem, anyway they are fixed with these patches. Moreover, the support added in RK3308 clock driver to get UARTs rate makes 'clock-frequency' property useless in RK3308 based boards *-u-boot.dtsi files: due to the fact that UART is inited by an external TPL, in other boot phases (SPL, U-Boot proper) there is no need to know UART clock from DT but get it just reading how external TPL has configured SoC registers.
<debug_uart> s() returning err=-2
U-Boot SPL 2023.07-00560-gf2090b144c (Jul 27 2023 - 16:27:11 +0200) Trying to boot from MMC1 INFO: Preloader serial: 0 NOTICE: BL31: v1.3(release):30f1405 NOTICE: BL31: Built : 17:08:28, Sep 23 2019 INFO: Lastlog: last=0x100000, realtime=0x102000, size=0x2000 INFO: ARM GICv2 driver initialized INFO: Using opteed sec cpu_context! INFO: boot cpu mask: 1 INFO: plat_rockchip_pmu_init: pd status 0xe b INFO: BL31: Initializing runtime services WARNING: No OPTEE provided by BL2 boot loader, Booting device without OPTEE initialization. SMC`s destined for OPTEE will return SMC_UNK ERROR: Error initializing runtime service opteed_fast INFO: BL31: Preparing for EL3 exit to normal world INFO: Entry point address = 0x600000 INFO: SPSR = 0x3c9
<debug_uart> clk_get_rate() returning err=-2 pinctrl_select_state_full() ns16550_serial serial@ff0a0000: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19 pinctrl_select_state_full() ns16550_serial serial@ff0a0000: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19 pinctrl_select_state_full() ns16550_serial serial@ff0a0000: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19
U-Boot 2023.07-00560-gf2090b144c (Jul 27 2023 - 16:27:11 +0200)
Model: Radxa ROCK Pi S DRAM: 512 MiB (effective 510 MiB) clk_get_rate() returning err=-2 Core: 287 devices, 23 uclasses, devicetree: separate MMC: mmc@ff480000: 1, mmc@ff490000: 0, mmc@ff4a0000: 2
Massimo Pegorer (3): clk: rockchip: rk3308: Fix ordering between masking and shifting clk: rockchip: rk3308: Support reading UART rate and clock registers dts: rockchip: rk3308: Avoid warning for serial probe on prereloc
arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi | 29 +++++++- arch/arm/include/asm/arch-rk3308/cru_rk3308.h | 15 ++++ drivers/clk/rockchip/clk_rk3308.c | 69 +++++++++++++++++-- 3 files changed, 106 insertions(+), 7 deletions(-)

As per definitions of masks and shift offsets in cru_rk3308.h, values read from registers must be first masked and then shifted. By the way, this fix is binary invariant, because in all of fixed cases the shift offset is zero.
Signed-off-by: Massimo Pegorer massimo.pegorer+oss@gmail.com --- drivers/clk/rockchip/clk_rk3308.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c index 64f33587e2..d27673c454 100644 --- a/drivers/clk/rockchip/clk_rk3308.c +++ b/drivers/clk/rockchip/clk_rk3308.c @@ -150,7 +150,7 @@ static ulong rk3308_i2c_get_clk(struct clk *clk) }
con = readl(&cru->clksel_con[con_id]); - div = con >> CLK_I2C_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; + div = (con & CLK_I2C_DIV_CON_MASK) >> CLK_I2C_DIV_CON_SHIFT;
return DIV_TO_RATE(priv->dpll_hz, div); } @@ -314,7 +314,7 @@ static ulong rk3308_saradc_get_clk(struct clk *clk) u32 div, con;
con = readl(&cru->clksel_con[34]); - div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK; + div = (con & CLK_SARADC_DIV_CON_MASK) >> CLK_SARADC_DIV_CON_SHIFT;
return DIV_TO_RATE(OSC_HZ, div); } @@ -342,7 +342,7 @@ static ulong rk3308_tsadc_get_clk(struct clk *clk) u32 div, con;
con = readl(&cru->clksel_con[33]); - div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK; + div = (con & CLK_SARADC_DIV_CON_MASK) >> CLK_SARADC_DIV_CON_SHIFT;
return DIV_TO_RATE(OSC_HZ, div); } @@ -385,7 +385,7 @@ static ulong rk3308_spi_get_clk(struct clk *clk) }
con = readl(&cru->clksel_con[con_id]); - div = con >> CLK_SPI_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK; + div = (con & CLK_SPI_DIV_CON_MASK) >> CLK_SPI_DIV_CON_SHIFT;
return DIV_TO_RATE(priv->dpll_hz, div); } @@ -429,7 +429,7 @@ static ulong rk3308_pwm_get_clk(struct clk *clk) u32 div, con;
con = readl(&cru->clksel_con[29]); - div = con >> CLK_PWM_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK; + div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT;
return DIV_TO_RATE(priv->dpll_hz, div); }

On 2023/8/3 19:08, Massimo Pegorer wrote:
As per definitions of masks and shift offsets in cru_rk3308.h, values read from registers must be first masked and then shifted. By the way, this fix is binary invariant, because in all of fixed cases the shift offset is zero.
Signed-off-by: Massimo Pegorer massimo.pegorer+oss@gmail.com
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
drivers/clk/rockchip/clk_rk3308.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c index 64f33587e2..d27673c454 100644 --- a/drivers/clk/rockchip/clk_rk3308.c +++ b/drivers/clk/rockchip/clk_rk3308.c @@ -150,7 +150,7 @@ static ulong rk3308_i2c_get_clk(struct clk *clk) }
con = readl(&cru->clksel_con[con_id]);
- div = con >> CLK_I2C_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
div = (con & CLK_I2C_DIV_CON_MASK) >> CLK_I2C_DIV_CON_SHIFT;
return DIV_TO_RATE(priv->dpll_hz, div); }
@@ -314,7 +314,7 @@ static ulong rk3308_saradc_get_clk(struct clk *clk) u32 div, con;
con = readl(&cru->clksel_con[34]);
- div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
div = (con & CLK_SARADC_DIV_CON_MASK) >> CLK_SARADC_DIV_CON_SHIFT;
return DIV_TO_RATE(OSC_HZ, div); }
@@ -342,7 +342,7 @@ static ulong rk3308_tsadc_get_clk(struct clk *clk) u32 div, con;
con = readl(&cru->clksel_con[33]);
- div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
div = (con & CLK_SARADC_DIV_CON_MASK) >> CLK_SARADC_DIV_CON_SHIFT;
return DIV_TO_RATE(OSC_HZ, div); }
@@ -385,7 +385,7 @@ static ulong rk3308_spi_get_clk(struct clk *clk) }
con = readl(&cru->clksel_con[con_id]);
- div = con >> CLK_SPI_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
div = (con & CLK_SPI_DIV_CON_MASK) >> CLK_SPI_DIV_CON_SHIFT;
return DIV_TO_RATE(priv->dpll_hz, div); }
@@ -429,7 +429,7 @@ static ulong rk3308_pwm_get_clk(struct clk *clk) u32 div, con;
con = readl(&cru->clksel_con[29]);
- div = con >> CLK_PWM_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT;
return DIV_TO_RATE(priv->dpll_hz, div); }

Add support to read RK3308 registers used to configure UART clocks, and thus to get UART rate and baudrate. This fixes clock_get_rate returning error on serial device probing. Moreover, there is no need anymore to use 'clock-frequency' property for UART nodes in *-u-boot.dtsi files for all cases where UART is not inited by U-Boot proper or by SPL o by TPL code but by a preliminary external boot phase (for Rock PI S, UART is inited by external TPL).
Signed-off-by: Massimo Pegorer massimo.pegorer+oss@gmail.com --- arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi | 2 - arch/arm/include/asm/arch-rk3308/cru_rk3308.h | 15 +++++ drivers/clk/rockchip/clk_rk3308.c | 59 +++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi index 09694b41e5..61415559b7 100644 --- a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi +++ b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi @@ -12,6 +12,4 @@
&uart0 { bootph-all; - clock-frequency = <24000000>; - status = "okay"; }; diff --git a/arch/arm/include/asm/arch-rk3308/cru_rk3308.h b/arch/arm/include/asm/arch-rk3308/cru_rk3308.h index 86c906bb0e..84b63e4d56 100644 --- a/arch/arm/include/asm/arch-rk3308/cru_rk3308.h +++ b/arch/arm/include/asm/arch-rk3308/cru_rk3308.h @@ -189,6 +189,21 @@ enum { DCLK_VOP_DIV_SHIFT = 0, DCLK_VOP_DIV_MASK = 0xff,
+ /* CRU_CLKSEL_CON10 */ + /* CRU_CLKSEL_CON13 */ + /* CRU_CLKSEL_CON16 */ + /* CRU_CLKSEL_CON19 */ + /* CRU_CLKSEL_CON22 */ + CLK_UART_PLL_SEL_SHIFT = 13, + CLK_UART_PLL_SEL_MASK = 0x7 << CLK_UART_PLL_SEL_SHIFT, + CLK_UART_PLL_SEL_DPLL = 0, + CLK_UART_PLL_SEL_VPLL0, + CLK_UART_PLL_SEL_VPLL1, + CLK_UART_PLL_SEL_480M, + CLK_UART_PLL_SEL_24M, + CLK_UART_DIV_CON_SHIFT = 0, + CLK_UART_DIV_CON_MASK = 0x1f << CLK_UART_DIV_CON_SHIFT, + /* CRU_CLK_SEL25_CON */ /* CRU_CLK_SEL26_CON */ /* CRU_CLK_SEL27_CON */ diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c index d27673c454..d0a3f65446 100644 --- a/drivers/clk/rockchip/clk_rk3308.c +++ b/drivers/clk/rockchip/clk_rk3308.c @@ -451,6 +451,58 @@ static ulong rk3308_pwm_set_clk(struct clk *clk, uint hz) return rk3308_pwm_get_clk(clk); }
+static ulong rk3308_uart_get_clk(struct clk *clk) +{ + struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3308_cru *cru = priv->cru; + u32 div, pll_sel, con, con_id, parent; + + switch (clk->id) { + case SCLK_UART0: + con_id = 10; + break; + case SCLK_UART1: + con_id = 13; + break; + case SCLK_UART2: + con_id = 16; + break; + case SCLK_UART3: + con_id = 19; + break; + case SCLK_UART4: + con_id = 22; + break; + default: + printf("do not support this uart interface\n"); + return -EINVAL; + } + + con = readl(&cru->clksel_con[con_id]); + pll_sel = (con & CLK_UART_PLL_SEL_MASK) >> CLK_UART_PLL_SEL_SHIFT; + div = (con & CLK_UART_DIV_CON_MASK) >> CLK_UART_DIV_CON_SHIFT; + + switch (pll_sel) { + case CLK_UART_PLL_SEL_DPLL: + parent = priv->dpll_hz; + break; + case CLK_UART_PLL_SEL_VPLL0: + parent = priv->vpll0_hz; + break; + case CLK_UART_PLL_SEL_VPLL1: + parent = priv->vpll0_hz; + break; + case CLK_UART_PLL_SEL_24M: + parent = OSC_HZ; + break; + default: + printf("do not support this uart pll sel\n"); + return -EINVAL; + } + + return DIV_TO_RATE(parent, div); +} + static ulong rk3308_vop_get_clk(struct clk *clk) { struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); @@ -813,6 +865,13 @@ static ulong rk3308_clk_get_rate(struct clk *clk) case SCLK_EMMC_SAMPLE: rate = rk3308_mmc_get_clk(clk); break; + case SCLK_UART0: + case SCLK_UART1: + case SCLK_UART2: + case SCLK_UART3: + case SCLK_UART4: + rate = rk3308_uart_get_clk(clk); + break; case SCLK_I2C0: case SCLK_I2C1: case SCLK_I2C2:

On 2023/8/3 19:08, Massimo Pegorer wrote:
Add support to read RK3308 registers used to configure UART clocks, and thus to get UART rate and baudrate. This fixes clock_get_rate returning error on serial device probing. Moreover, there is no need anymore to use 'clock-frequency' property for UART nodes in *-u-boot.dtsi files for all cases where UART is not inited by U-Boot proper or by SPL o by TPL code but by a preliminary external boot phase (for Rock PI S, UART is inited by external TPL).
Signed-off-by: Massimo Pegorer massimo.pegorer+oss@gmail.com
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi | 2 - arch/arm/include/asm/arch-rk3308/cru_rk3308.h | 15 +++++ drivers/clk/rockchip/clk_rk3308.c | 59 +++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi index 09694b41e5..61415559b7 100644 --- a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi +++ b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi @@ -12,6 +12,4 @@
&uart0 { bootph-all;
- clock-frequency = <24000000>;
- status = "okay"; };
diff --git a/arch/arm/include/asm/arch-rk3308/cru_rk3308.h b/arch/arm/include/asm/arch-rk3308/cru_rk3308.h index 86c906bb0e..84b63e4d56 100644 --- a/arch/arm/include/asm/arch-rk3308/cru_rk3308.h +++ b/arch/arm/include/asm/arch-rk3308/cru_rk3308.h @@ -189,6 +189,21 @@ enum { DCLK_VOP_DIV_SHIFT = 0, DCLK_VOP_DIV_MASK = 0xff,
- /* CRU_CLKSEL_CON10 */
- /* CRU_CLKSEL_CON13 */
- /* CRU_CLKSEL_CON16 */
- /* CRU_CLKSEL_CON19 */
- /* CRU_CLKSEL_CON22 */
- CLK_UART_PLL_SEL_SHIFT = 13,
- CLK_UART_PLL_SEL_MASK = 0x7 << CLK_UART_PLL_SEL_SHIFT,
- CLK_UART_PLL_SEL_DPLL = 0,
- CLK_UART_PLL_SEL_VPLL0,
- CLK_UART_PLL_SEL_VPLL1,
- CLK_UART_PLL_SEL_480M,
- CLK_UART_PLL_SEL_24M,
- CLK_UART_DIV_CON_SHIFT = 0,
- CLK_UART_DIV_CON_MASK = 0x1f << CLK_UART_DIV_CON_SHIFT,
- /* CRU_CLK_SEL25_CON */ /* CRU_CLK_SEL26_CON */ /* CRU_CLK_SEL27_CON */
diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c index d27673c454..d0a3f65446 100644 --- a/drivers/clk/rockchip/clk_rk3308.c +++ b/drivers/clk/rockchip/clk_rk3308.c @@ -451,6 +451,58 @@ static ulong rk3308_pwm_set_clk(struct clk *clk, uint hz) return rk3308_pwm_get_clk(clk); }
+static ulong rk3308_uart_get_clk(struct clk *clk) +{
- struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
- struct rk3308_cru *cru = priv->cru;
- u32 div, pll_sel, con, con_id, parent;
- switch (clk->id) {
- case SCLK_UART0:
con_id = 10;
break;
- case SCLK_UART1:
con_id = 13;
break;
- case SCLK_UART2:
con_id = 16;
break;
- case SCLK_UART3:
con_id = 19;
break;
- case SCLK_UART4:
con_id = 22;
break;
- default:
printf("do not support this uart interface\n");
return -EINVAL;
- }
- con = readl(&cru->clksel_con[con_id]);
- pll_sel = (con & CLK_UART_PLL_SEL_MASK) >> CLK_UART_PLL_SEL_SHIFT;
- div = (con & CLK_UART_DIV_CON_MASK) >> CLK_UART_DIV_CON_SHIFT;
- switch (pll_sel) {
- case CLK_UART_PLL_SEL_DPLL:
parent = priv->dpll_hz;
break;
- case CLK_UART_PLL_SEL_VPLL0:
parent = priv->vpll0_hz;
break;
- case CLK_UART_PLL_SEL_VPLL1:
parent = priv->vpll0_hz;
break;
- case CLK_UART_PLL_SEL_24M:
parent = OSC_HZ;
break;
- default:
printf("do not support this uart pll sel\n");
return -EINVAL;
- }
- return DIV_TO_RATE(parent, div);
+}
- static ulong rk3308_vop_get_clk(struct clk *clk) { struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
@@ -813,6 +865,13 @@ static ulong rk3308_clk_get_rate(struct clk *clk) case SCLK_EMMC_SAMPLE: rate = rk3308_mmc_get_clk(clk); break;
- case SCLK_UART0:
- case SCLK_UART1:
- case SCLK_UART2:
- case SCLK_UART3:
- case SCLK_UART4:
rate = rk3308_uart_get_clk(clk);
case SCLK_I2C0: case SCLK_I2C1: case SCLK_I2C2:break;

Make device tree complete and consistent for pre relocation phase. Some nodes are missing, causing warnings to be issued on serial port probing during pre relocation phase (uclass_get_device_by_phandle_id fails when called by pinctrl_select_state_full: none of these failures is fatal nor causing issues). Add to *-u-boot.dtsi all required nodes with the 'bootph-some-ram' attribute.
Signed-off-by: Massimo Pegorer massimo.pegorer+oss@gmail.com --- arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi index 61415559b7..d88dee8057 100644 --- a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi +++ b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi @@ -13,3 +13,30 @@ &uart0 { bootph-all; }; + +&pinctrl { + bootph-some-ram; + + uart0 { + bootph-some-ram; + }; + rtc { + bootph-some-ram; + }; +}; + +&uart0_xfer { + bootph-some-ram; +}; + +&uart0_cts { + bootph-some-ram; +}; + +&uart0_rts { + bootph-some-ram; +}; + +&rtc_32k { + bootph-some-ram; +};

On 2023/8/3 19:08, Massimo Pegorer wrote:
Make device tree complete and consistent for pre relocation phase. Some nodes are missing, causing warnings to be issued on serial port probing during pre relocation phase (uclass_get_device_by_phandle_id fails when called by pinctrl_select_state_full: none of these failures is fatal nor causing issues). Add to *-u-boot.dtsi all required nodes with the 'bootph-some-ram' attribute.
Signed-off-by: Massimo Pegorer massimo.pegorer+oss@gmail.com
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi index 61415559b7..d88dee8057 100644 --- a/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi +++ b/arch/arm/dts/rk3308-rock-pi-s-u-boot.dtsi @@ -13,3 +13,30 @@ &uart0 { bootph-all; };
+&pinctrl {
- bootph-some-ram;
- uart0 {
bootph-some-ram;
- };
- rtc {
bootph-some-ram;
- };
+};
+&uart0_xfer {
- bootph-some-ram;
+};
+&uart0_cts {
- bootph-some-ram;
+};
+&uart0_rts {
- bootph-some-ram;
+};
+&rtc_32k {
- bootph-some-ram;
+};
participants (2)
-
Kever Yang
-
Massimo Pegorer