[PATCH 0/3] Anbernic RGxx3 Bootloader Fixes

From: Chris Morgan macromorgan@hotmail.com
Update the Anbernic RGxx3 "device" to use upstream device-trees, add logic to detect a different vdd_cpu regulator, and implement a fix to allow the panel auto-detection to run when using mainline A-TF.
Note that *Linux* still cannot use mainline A-TF because of the missing SCMI clock and reset functionality, but this patch series at least ensures that this board can once Linux is ready.
Chris Morgan (3): board: rockchip: Convert Anbernic RGxx3 to OF_UPSTREAM board: rockchip: Add vdd_cpu reg fixup for RGXX3 Series board: rockchip: Fix panel detection for mainline A-TF
.../dts/rk3566-anbernic-rg353p-u-boot.dtsi | 34 ++ .../arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi | 52 --- arch/arm/dts/rk3566-anbernic-rgxx3.dts | 28 -- board/anbernic/rgxx3_rk3566/MAINTAINERS | 4 +- board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 372 +++++++++++++++--- configs/anbernic-rgxx3-rk3566_defconfig | 12 +- 6 files changed, 354 insertions(+), 148 deletions(-) create mode 100644 arch/arm/dts/rk3566-anbernic-rg353p-u-boot.dtsi delete mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi delete mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3.dts

From: Chris Morgan macromorgan@hotmail.com
Refactor the board detection logic (again) to make it compatible with the upstream device-trees, and switch to OF_UPSTREAM.
Now the device boots with the device-tree for the 353P, and then loads the correct device tree (of 10) in the later stages of SPL.
Signed-off-by: Chris Morgan macromorgan@hotmail.com --- .../dts/rk3566-anbernic-rg353p-u-boot.dtsi | 34 +++ .../arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi | 52 ----- arch/arm/dts/rk3566-anbernic-rgxx3.dts | 28 --- board/anbernic/rgxx3_rk3566/MAINTAINERS | 4 +- board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 214 +++++++++++++----- configs/anbernic-rgxx3-rk3566_defconfig | 10 +- 6 files changed, 195 insertions(+), 147 deletions(-) create mode 100644 arch/arm/dts/rk3566-anbernic-rg353p-u-boot.dtsi delete mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi delete mode 100644 arch/arm/dts/rk3566-anbernic-rgxx3.dts
diff --git a/arch/arm/dts/rk3566-anbernic-rg353p-u-boot.dtsi b/arch/arm/dts/rk3566-anbernic-rg353p-u-boot.dtsi new file mode 100644 index 00000000000..fa3fbe6c810 --- /dev/null +++ b/arch/arm/dts/rk3566-anbernic-rg353p-u-boot.dtsi @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk356x-u-boot.dtsi" + +/ { + chosen { + u-boot,spl-boot-order = &sdmmc0, &sdhci; + }; + + /* + * Adding fixed regulator to work around driver regulator + * requirements. Note that the correct regulator is on by + * default at boot and that saradc regulator gets corrected + * when proper device-tree is loaded. + */ + vcc_1v8_dummy: vcc-1v8-dummy { + bootph-pre-ram; + bootph-some-ram; + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_dummy"; + status = "okay"; + }; +}; + +&saradc { + bootph-pre-ram; + bootph-some-ram; + vref-supply = <&vcc_1v8_dummy>; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi deleted file mode 100644 index c7e849816a6..00000000000 --- a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) - -#include "rk356x-u-boot.dtsi" - -/ { - chosen { - u-boot,spl-boot-order = &sdmmc0, &sdhci; - }; -}; - -&dsi_dphy0 { - status = "okay"; -}; - -&dsi0 { - status = "okay"; -}; - -&i2c2 { - pinctrl-0 = <&i2c2m1_xfer>; - pinctrl-names = "default"; - status = "okay"; -}; - -&pmucru { - assigned-clocks = <&pmucru SCLK_32K_IOE>; - assigned-clock-parents = <&pmucru CLK_RTC_32K>; -}; - -/* - * We don't need the clocks, but if they are present they may cause - * probing to fail so we remove them for U-Boot. - */ -&rk817 { - /delete-property/ assigned-clocks; - /delete-property/ assigned-clock-parents; - /delete-property/ clocks; - /delete-property/ clock-names; -}; - -&sdhci { - pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>, - <&emmc_datastrobe>, <&emmc_rstnout>; - pinctrl-names = "default"; - bus-width = <8>; - max-frequency = <200000000>; - mmc-hs200-1_8v; - non-removable; - vmmc-supply = <&vcc_3v3>; - vqmmc-supply = <&vcc_1v8>; - status = "okay"; -}; diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3.dts b/arch/arm/dts/rk3566-anbernic-rgxx3.dts deleted file mode 100644 index c393c8d07af..00000000000 --- a/arch/arm/dts/rk3566-anbernic-rgxx3.dts +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) - -/dts-v1/; - -#include "rk3566-anbernic-rgxx3.dtsi" - -/ { - -/* - * Note this is a pseudo-model that doesn't exist in mainline Linux. - * This model is used for all RGXX3 devices and the board.c file will - * set the correct dtb name for loading mainline Linux automatically. - */ - model = "RGXX3"; - compatible = "anbernic,rg-arc-d", "anbernic,rg-arc-s", - "anbernic,rg353m", "anbernic,rg353p", - "anbernic,rg353ps", "anbernic,rg353v", - "anbernic,rg353vs", "anbernic,rg503", - "powkiddy,rgb10max3", "powkiddy,rgb30", - "powkiddy,rk2023", "rockchip,rk3566"; -}; - -&cru { - assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>, - <&pmucru PLL_PPLL>, <&cru PLL_VPLL>; - assigned-clock-rates = <32768>, <1200000000>, - <200000000>, <241500000>; -}; diff --git a/board/anbernic/rgxx3_rk3566/MAINTAINERS b/board/anbernic/rgxx3_rk3566/MAINTAINERS index 7970e5a4aad..75a1e8076ca 100644 --- a/board/anbernic/rgxx3_rk3566/MAINTAINERS +++ b/board/anbernic/rgxx3_rk3566/MAINTAINERS @@ -4,6 +4,4 @@ S: Maintained F: board/anbernic/rgxx3_rk3566 F: include/configs/anbernic-rgxx3-rk3566.h F: configs/anbernic-rgxx3-rk3566_defconfig -F: arch/arm/dts/rk3566-anbernic-rgxx3.dts -F: arch/arm/dts/rk3566-anbernic-rgxx3.dtsi -F: arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi +F: arch/arm/dts/rk3566-anbernic-rg353p-u-boot.dtsi diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index 5c57b902d14..224019f9ba3 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -11,6 +11,7 @@ #include <dm/lists.h> #include <env.h> #include <fdt_support.h> +#include <i2c.h> #include <linux/delay.h> #include <mipi_dsi.h> #include <mmc.h> @@ -19,6 +20,8 @@ #include <stdlib.h> #include <video_bridge.h>
+DECLARE_GLOBAL_DATA_PTR; + #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000 @@ -40,10 +43,11 @@ struct rg3xx_model { const char *board_name; const char *fdtfile; const bool detect_panel; + const bool uart_con; };
enum rgxx3_device_id { - RG353M, + RG353M = 1, RG353P, RG353V, RG503, @@ -61,45 +65,51 @@ static const struct rg3xx_model rg3xx_model_details[] = { [RG353M] = { .adc_value = 517, /* Observed average from device */ .board = "rk3566-anbernic-rg353m", - .board_name = "RG353M", + .board_name = "Anbernic RG353M", /* Device is identical to RG353P. */ .fdtfile = DTB_DIR "rk3566-anbernic-rg353p.dtb", .detect_panel = 1, + .uart_con = 1, }, [RG353P] = { .adc_value = 860, /* Documented value of 860 */ .board = "rk3566-anbernic-rg353p", - .board_name = "RG353P", + .board_name = "Anbernic RG353P", .fdtfile = DTB_DIR "rk3566-anbernic-rg353p.dtb", .detect_panel = 1, + .uart_con = 1, }, [RG353V] = { .adc_value = 695, /* Observed average from device */ .board = "rk3566-anbernic-rg353v", - .board_name = "RG353V", + .board_name = "Anbernic RG353V", .fdtfile = DTB_DIR "rk3566-anbernic-rg353v.dtb", .detect_panel = 1, + .uart_con = 1, }, [RG503] = { .adc_value = 1023, /* Observed average from device */ .board = "rk3566-anbernic-rg503", - .board_name = "RG503", + .board_name = "Anbernic RG503", .fdtfile = DTB_DIR "rk3566-anbernic-rg503.dtb", .detect_panel = 0, + .uart_con = 1, }, [RGB30] = { .adc_value = 383, /* Gathered from second hand information */ .board = "rk3566-powkiddy-rgb30", - .board_name = "RGB30", + .board_name = "Powkiddy RGB30", .fdtfile = DTB_DIR "rk3566-powkiddy-rgb30.dtb", .detect_panel = 0, + .uart_con = 0, }, [RK2023] = { .adc_value = 635, /* Observed average from device */ .board = "rk3566-powkiddy-rk2023", - .board_name = "RK2023", + .board_name = "Powkiddy RK2023", .fdtfile = DTB_DIR "rk3566-powkiddy-rk2023.dtb", .detect_panel = 0, + .uart_con = 0, }, [RGARCD] = { .adc_value = 183, /* Observed average from device */ @@ -107,6 +117,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG ARC-D", .fdtfile = DTB_DIR "rk3566-anbernic-rg-arc-d.dtb", .detect_panel = 0, + .uart_con = 1, }, [RGB10MAX3] = { .adc_value = 765, /* Observed average from device */ @@ -114,21 +125,24 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Powkiddy RGB10MAX3", .fdtfile = DTB_DIR "rk3566-powkiddy-rgb10max3.dtb", .detect_panel = 0, + .uart_con = 0, }, /* Devices with duplicate ADC value */ [RG353PS] = { .adc_value = 860, /* Observed average from device */ .board = "rk3566-anbernic-rg353ps", - .board_name = "RG353PS", + .board_name = "Anbernic RG353PS", .fdtfile = DTB_DIR "rk3566-anbernic-rg353ps.dtb", .detect_panel = 1, + .uart_con = 1, }, [RG353VS] = { .adc_value = 695, /* Gathered from second hand information */ .board = "rk3566-anbernic-rg353vs", - .board_name = "RG353VS", + .board_name = "Anbernic RG353VS", .fdtfile = DTB_DIR "rk3566-anbernic-rg353vs.dtb", .detect_panel = 1, + .uart_con = 1, }, [RGARCS] = { .adc_value = 183, /* Observed average from device */ @@ -136,6 +150,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG ARC-S", .fdtfile = DTB_DIR "rk3566-anbernic-rg-arc-s.dtb", .detect_panel = 0, + .uart_con = 1, }, };
@@ -164,7 +179,7 @@ static const struct rg353_panel rg353_panel_details[] = { void spl_board_init(void) { /* Set GPIO0_C5, GPIO0_C6, and GPIO0_C7 to output. */ - writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | \ + writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | (GPIO_C7 | GPIO_C6 | GPIO_C5), (GPIO0_BASE + GPIO_SWPORT_DDR_H)); /* Set GPIO0_C5 and GPIO_C6 to 0 and GPIO0_C7 to 1. */ @@ -174,16 +189,22 @@ void spl_board_init(void)
/* * Buzz the buzzer so the user knows something is going on. Make it - * optional in case PWM is disabled. + * optional in case PWM is disabled or if CONFIG_DM_PWM is not + * enabled. */ void __maybe_unused startup_buzz(void) { struct udevice *dev; int err;
- err = uclass_get_device(UCLASS_PWM, 0, &dev); + if (!IS_ENABLED(CONFIG_DM_PWM)) + return; + + /* Probe the PWM controller. */ + err = uclass_get_device_by_name(UCLASS_PWM, + "pwm@fe6e0010", &dev); if (err) - printf("pwm not found\n"); + return;
pwm_set_enable(dev, 0, 1); mdelay(200); @@ -245,6 +266,13 @@ U_BOOT_DRIVER(anbernic_rg353_panel) = { .plat_auto = sizeof(struct mipi_dsi_panel_plat), };
+/* + * The Anbernic 353 series shipped with 2 distinct displays requiring + * 2 distinct drivers, with no way for a user to know which panel is + * which. This function queries the DSI panel for the panel ID to + * determine which panel is present so the device-tree can be corrected + * automatically. + */ int rgxx3_detect_display(void) { struct udevice *dev; @@ -333,17 +361,10 @@ int rgxx3_detect_display(void) return 0; }
-/* Detect which Anbernic RGXX3 device we are using so as to load the - * correct devicetree for Linux. Set an environment variable once - * found. The detection depends on the value of ADC channel 1, the - * presence of an eMMC on mmc0, and querying the DSI panel. - */ -int rgxx3_detect_device(void) +int rgxx3_read_board_id(void) { u32 adc_info; - int ret, i; - int board_id = -ENXIO; - struct mmc *mmc; + int ret;
ret = adc_channel_single_shot("saradc@fe720000", 1, &adc_info); if (ret) { @@ -357,16 +378,32 @@ int rgxx3_detect_device(void) * design calls for no more than a 1% variance on the * resistor, so assume a +- value of 15 should be enough. */ - for (i = 0; i < ARRAY_SIZE(rg3xx_model_details); i++) { + for (int i = 0; i < ARRAY_SIZE(rg3xx_model_details); i++) { u32 adc_min = rg3xx_model_details[i].adc_value - 15; u32 adc_max = rg3xx_model_details[i].adc_value + 15;
- if (adc_min < adc_info && adc_max > adc_info) { - board_id = i; - break; - } + if (adc_min < adc_info && adc_max > adc_info) + return i; }
+ return -ENODEV; +} + +/* Detect which Anbernic RGXX3 device we are using so as to load the + * correct devicetree for Linux. Set an environment variable once + * found. The detection depends on the value of ADC channel 1 and the + * presence of an eMMC on mmc0. + */ +int rgxx3_detect_device(void) +{ + int ret; + int board_id; + struct mmc *mmc; + + board_id = rgxx3_read_board_id(); + if (board_id < 0) + return board_id; + /* * Try to access the eMMC on an RG353V, RG353P, or RG Arc D. * If it's missing, it's an RG353VS, RG353PS, or RG Arc S. @@ -387,67 +424,87 @@ int rgxx3_detect_device(void) } }
- if (board_id < 0) - return board_id; + return board_id; +}
- env_set("board", rg3xx_model_details[board_id].board); - env_set("board_name", - rg3xx_model_details[board_id].board_name); - env_set("fdtfile", rg3xx_model_details[board_id].fdtfile); +/* + * Check the loaded device tree to set the correct gd->board_type. + * Disable the console if the board doesn't support a console. + */ +int set_gd_value(void) +{ + const char *model;
- /* Skip panel detection for when it is not needed. */ - if (!rg3xx_model_details[board_id].detect_panel) - return 0; + model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
- /* Warn but don't fail for errors in auto-detection of the panel. */ - ret = rgxx3_detect_display(); - if (ret) - printf("Failed to detect panel type\n"); + for (int i = 0; i < ARRAY_SIZE(rg3xx_model_details); i++) { + if (strcmp(rg3xx_model_details[i].board_name, model) == 0) { + gd->board_type = i; + if (!rg3xx_model_details[i].uart_con) + gd->flags |= GD_FLG_SILENT | + GD_FLG_DISABLE_CONSOLE; + return 0; + } + }
- return 0; + return -ENODEV; }
int rk_board_late_init(void) { int ret;
- ret = rgxx3_detect_device(); + ret = set_gd_value(); if (ret) { - printf("Unable to detect device type: %d\n", ret); - return ret; + printf("Unable to auto-detect device\n"); + goto end; }
+ /* + * Change the model number on the RG353M since it uses the same + * tree as the RG353P. + */ + if (gd->board_type == RG353P) { + ret = rgxx3_read_board_id(); + if (ret > 0) + gd->board_type = ret; + } + + env_set("board", rg3xx_model_details[gd->board_type].board); + env_set("board_name", + rg3xx_model_details[gd->board_type].board_name); + env_set("fdtfile", rg3xx_model_details[gd->board_type].fdtfile); + + /* + * Skip panel detection if not needed. Warn but don't fail for + * errors in auto-detection of the panel. + */ + if (rg3xx_model_details[gd->board_type].detect_panel) { + ret = rgxx3_detect_display(); + if (ret) + printf("Failed to detect panel type\n"); + } + +end: /* Turn off red LED and turn on orange LED. */ writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | GPIO_C6, (GPIO0_BASE + GPIO_SWPORT_DR_H));
- if (IS_ENABLED(CONFIG_DM_PWM)) - startup_buzz(); + startup_buzz();
return 0; }
-int ft_board_setup(void *blob, struct bd_info *bd) +int rgxx3_panel_fixup(void *blob) { const struct rg353_panel *panel = NULL; - int node, ret, i; + int node, ret; char *env;
- /* No fixups necessary for the RG503 */ - env = env_get("board_name"); - if (env && (!strcmp(env, rg3xx_model_details[RG503].board_name))) - return 0; - - /* Change the model name of the RG353M */ - if (env && (!strcmp(env, rg3xx_model_details[RG353M].board_name))) - fdt_setprop(blob, 0, "model", - rg3xx_model_details[RG353M].board_name, - sizeof(rg3xx_model_details[RG353M].board_name)); - env = env_get("panel"); if (!env) { printf("Can't get panel env\n"); - return 0; + return -EINVAL; }
/* @@ -469,7 +526,7 @@ int ft_board_setup(void *blob, struct bd_info *bd) return 0;
/* Panels don't match, search by first compatible value. */ - for (i = 0; i < ARRAY_SIZE(rg353_panel_details); i++) { + for (int i = 0; i < ARRAY_SIZE(rg353_panel_details); i++) { if (!strcmp(env, rg353_panel_details[i].panel_compat[0])) { panel = &rg353_panel_details[i]; break; @@ -489,3 +546,38 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0; } + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + int ret; + + if (gd->board_type == RG353M) + fdt_setprop(blob, 0, "model", + rg3xx_model_details[RG353M].board_name, + sizeof(rg3xx_model_details[RG353M].board_name)); + + if (rg3xx_model_details[gd->board_type].detect_panel) { + ret = rgxx3_panel_fixup(blob); + if (ret) + printf("Unable to update panel compat\n"); + } + + return 0; +} + +int board_fit_config_name_match(const char *name) +{ + int ret; + + if (gd->board_type == 0) { + ret = rgxx3_detect_device(); + if (ret < 0) + return ret; + gd->board_type = ret; + } + + if (strcmp(name, rg3xx_model_details[gd->board_type].fdtfile) == 0) + return 0; + + return -ENXIO; +} diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index a03509bf467..f5e5470df8c 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -3,7 +3,7 @@ CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=24000000 CONFIG_ARCH_ROCKCHIP=y CONFIG_SPL_GPIO=y -CONFIG_DEFAULT_DEVICE_TREE="rk3566-anbernic-rgxx3" +CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3566-anbernic-rg353p" CONFIG_ROCKCHIP_RK3568=y CONFIG_ROCKCHIP_RK8XX_DISABLE_BOOT_ON_POWERON=y CONFIG_SPL_SERIAL=y @@ -19,8 +19,10 @@ CONFIG_SPL_LOAD_FIT=y CONFIG_LEGACY_IMAGE_FORMAT=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_DEFAULT_FDT_FILE="rockchip/rk3566-anbernic-rgxx3.dtb" +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3566-anbernic-rg353p.dtb" +CONFIG_DISABLE_CONSOLE=y # CONFIG_CONSOLE_MUX is not set +CONFIG_BOARD_TYPES=y # CONFIG_DISPLAY_CPUINFO is not set CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_BOARD_RNG_SEED=y @@ -38,13 +40,14 @@ CONFIG_CMD_MMC=y # CONFIG_SPL_DOS_PARTITION is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_LIVE=y -# CONFIG_OF_UPSTREAM is not set +CONFIG_OF_LIST="rockchip/rk3566-anbernic-rg353p rockchip/rk3566-anbernic-rg353v rockchip/rk3566-anbernic-rg503 rockchip/rk3566-anbernic-rg-arc-d rockchip/rk3566-anbernic-rg353ps rockchip/rk3566-anbernic-rg353vs rockchip/rk3566-anbernic-rg-arc-s rockchip/rk3566-powkiddy-rgb30 rockchip/rk3566-powkiddy-rk2023 rockchip/rk3566-powkiddy-rgb10max3" CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y # CONFIG_NET is not set CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y +CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y CONFIG_ARM_SMCCC_FEATURES=y CONFIG_SCMI_FIRMWARE=y @@ -70,6 +73,7 @@ CONFIG_SPL_RAM=y # CONFIG_RAM_ROCKCHIP_DEBUG is not set # CONFIG_RNG_SMCCC_TRNG is not set CONFIG_BAUDRATE=1500000 +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550_MEM32=y CONFIG_SYSRESET=y

From: Chris Morgan macromorgan@hotmail.com
Some of the Powkiddy devices switched to using a different vendor for the vdd_cpu regulator. Unfortunately the device does not have a new revision to denote this, so users have no way of knowing in advance.
Add code to detect if a device is present at addresses 0x1c or 0x40 on the i2c0 bus and update the devicetree if needed.
Signed-off-by: Chris Morgan macromorgan@hotmail.com --- board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 147 +++++++++++++++++++++ 1 file changed, 147 insertions(+)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index 224019f9ba3..c1d1826fd14 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -43,6 +43,7 @@ struct rg3xx_model { const char *board_name; const char *fdtfile; const bool detect_panel; + const bool detect_regulator; const bool uart_con; };
@@ -69,6 +70,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { /* Device is identical to RG353P. */ .fdtfile = DTB_DIR "rk3566-anbernic-rg353p.dtb", .detect_panel = 1, + .detect_regulator = 0, .uart_con = 1, }, [RG353P] = { @@ -77,6 +79,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG353P", .fdtfile = DTB_DIR "rk3566-anbernic-rg353p.dtb", .detect_panel = 1, + .detect_regulator = 0, .uart_con = 1, }, [RG353V] = { @@ -85,6 +88,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG353V", .fdtfile = DTB_DIR "rk3566-anbernic-rg353v.dtb", .detect_panel = 1, + .detect_regulator = 0, .uart_con = 1, }, [RG503] = { @@ -93,6 +97,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG503", .fdtfile = DTB_DIR "rk3566-anbernic-rg503.dtb", .detect_panel = 0, + .detect_regulator = 0, .uart_con = 1, }, [RGB30] = { @@ -101,6 +106,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Powkiddy RGB30", .fdtfile = DTB_DIR "rk3566-powkiddy-rgb30.dtb", .detect_panel = 0, + .detect_regulator = 1, .uart_con = 0, }, [RK2023] = { @@ -109,6 +115,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Powkiddy RK2023", .fdtfile = DTB_DIR "rk3566-powkiddy-rk2023.dtb", .detect_panel = 0, + .detect_regulator = 1, .uart_con = 0, }, [RGARCD] = { @@ -117,6 +124,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG ARC-D", .fdtfile = DTB_DIR "rk3566-anbernic-rg-arc-d.dtb", .detect_panel = 0, + .detect_regulator = 0, .uart_con = 1, }, [RGB10MAX3] = { @@ -125,6 +133,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Powkiddy RGB10MAX3", .fdtfile = DTB_DIR "rk3566-powkiddy-rgb10max3.dtb", .detect_panel = 0, + .detect_regulator = 1, .uart_con = 0, }, /* Devices with duplicate ADC value */ @@ -134,6 +143,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG353PS", .fdtfile = DTB_DIR "rk3566-anbernic-rg353ps.dtb", .detect_panel = 1, + .detect_regulator = 0, .uart_con = 1, }, [RG353VS] = { @@ -142,6 +152,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG353VS", .fdtfile = DTB_DIR "rk3566-anbernic-rg353vs.dtb", .detect_panel = 1, + .detect_regulator = 0, .uart_con = 1, }, [RGARCS] = { @@ -150,6 +161,7 @@ static const struct rg3xx_model rg3xx_model_details[] = { .board_name = "Anbernic RG ARC-S", .fdtfile = DTB_DIR "rk3566-anbernic-rg-arc-s.dtb", .detect_panel = 0, + .detect_regulator = 0, .uart_con = 1, }, }; @@ -172,6 +184,22 @@ static const struct rg353_panel rg353_panel_details[] = { }, };
+struct powkiddy_regulators { + const u8 addr; + const char *regulator_compat; +}; + +static const struct powkiddy_regulators regulator_details[] = { + { + .addr = 0x1c, + .regulator_compat = "tcs,tcs4525", + }, + { + .addr = 0x40, + .regulator_compat = "fcs,fan53555", + }, +}; + /* * Start LED very early so user knows device is on. Set color * to red. @@ -361,6 +389,44 @@ int rgxx3_detect_display(void) return 0; }
+/* + * Some of the Powkiddy devices switched the CPU regulator, but users + * are not able to determine this by looking at their hardware. + * Attempt to auto-detect this situation and fixup the device-tree. + */ +int rgxx3_detect_regulator(void) +{ + struct udevice *bus; + struct udevice *chip; + u8 val; + int ret; + + /* Get the correct i2c bus (i2c0). */ + ret = uclass_get_device_by_name(UCLASS_I2C, + "i2c@fdd40000", &bus); + if (ret) + return ret; + + /* + * Check for all vdd_cpu regulators and read an arbitrary + * register to confirm it's present. + */ + for (int i = 0; i < ARRAY_SIZE(regulator_details); i++) { + ret = i2c_get_chip(bus, regulator_details[i].addr, + 1, &chip); + if (ret) + return ret; + + ret = dm_i2c_read(chip, 0, &val, 1); + if (!ret) { + env_set("vdd_cpu", regulator_details[i].regulator_compat); + break; + } + } + + return 0; +} + int rgxx3_read_board_id(void) { u32 adc_info; @@ -485,6 +551,16 @@ int rk_board_late_init(void) printf("Failed to detect panel type\n"); }
+ /* + * Skip vdd_cpu regulator detection if not needed. Warn but + * don't fail for errors in auto-detection of regulator. + */ + if (rg3xx_model_details[gd->board_type].detect_regulator) { + ret = rgxx3_detect_regulator(); + if (ret) + printf("Unable to detect vdd_cpu regulator\n"); + } + end: /* Turn off red LED and turn on orange LED. */ writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | GPIO_C6, @@ -547,6 +623,71 @@ int rgxx3_panel_fixup(void *blob) return 0; }
+int rgxx3_regulator_fixup(void *blob) +{ + const struct powkiddy_regulators *vdd_cpu = NULL; + int node, ret, i; + char path[] = "/i2c@fdd40000/regulator@00"; + char name[] = "regulator@00"; + char *env; + + env = env_get("vdd_cpu"); + if (!env) { + printf("Can't get vdd_cpu env\n"); + return -EINVAL; + } + + /* + * Find the device we have in our tree, which may or may not + * be present. + */ + for (i = 0; i < ARRAY_SIZE(regulator_details); i++) { + sprintf(path, "/i2c@fdd40000/regulator@%02x", + regulator_details[i].addr); + node = fdt_path_offset(blob, path); + if (node > 0) + break; + + printf("Unable to find vdd_cpu\n"); + return -ENODEV; + } + + node = fdt_path_offset(blob, path); + if (!(node > 0)) { + printf("Can't find the vdd_cpu node\n"); + return -ENODEV; + } + + ret = fdt_node_check_compatible(blob, node, env); + if (ret < 0) + return -ENODEV; + + /* vdd_cpu regulators match, return 0. */ + if (!ret) + return 0; + + /* Regulators don't match, search by first compatible value. */ + for (i = 0; i < ARRAY_SIZE(regulator_details); i++) { + if (!strcmp(env, regulator_details[i].regulator_compat)) { + vdd_cpu = ®ulator_details[i]; + break; + } + } + + if (!vdd_cpu) { + printf("Unable to identify vdd_cpu by compat string\n"); + return -ENODEV; + } + + /* Set the compatible and reg with the auto-detected values */ + fdt_setprop_string(blob, node, "compatible", vdd_cpu->regulator_compat); + fdt_setprop_u32(blob, node, "reg", vdd_cpu->addr); + sprintf(name, "regulator@%02x", vdd_cpu->addr); + fdt_set_name(blob, node, name); + + return 0; +} + int ft_board_setup(void *blob, struct bd_info *bd) { int ret; @@ -562,6 +703,12 @@ int ft_board_setup(void *blob, struct bd_info *bd) printf("Unable to update panel compat\n"); }
+ if (rg3xx_model_details[gd->board_type].detect_regulator) { + ret = rgxx3_regulator_fixup(blob); + if (ret) + printf("Unable to update vdd_cpu compat\n"); + } + return 0; }

From: Chris Morgan macromorgan@hotmail.com
The current panel detection logic crashes when the device boots with mainline A-TF, causing a reboot loop. It turns out mainline A-TF doesn't enable the VO power domain like the BSP A-TF did.
Set the VO domain on and use a memory barrier to ensure it is powered up before we attempt to do the panel detection.
Signed-off-by: Chris Morgan macromorgan@hotmail.com --- board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 13 +++++++++++++ configs/anbernic-rgxx3-rk3566_defconfig | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index c1d1826fd14..f4e7c1ab360 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -22,6 +22,10 @@
DECLARE_GLOBAL_DATA_PTR;
+#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_PWR_GATE_SFTCON 0xa0 +#define PMU_PD_VO_DWN_ENA BIT(7) + #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000 @@ -311,6 +315,15 @@ int rgxx3_detect_display(void) int i; u8 panel_id[2];
+ /* Disable VO power domain power-down */ + writel((PMU_PD_VO_DWN_ENA << 16), + PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON); + /* + * System will crash if the power domain isn't enabled before + * we start trying to talk to the DSI panel. + */ + wmb(); + /* * Take panel out of reset status. * Set GPIO4_A0 to output. diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index f5e5470df8c..49d3766613e 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -49,8 +49,6 @@ CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y -CONFIG_ARM_SMCCC_FEATURES=y -CONFIG_SCMI_FIRMWARE=y CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y

Hi Chris,
Please update the subject with something like "Enable the VO PD before driver access",
and the commit message for the change reason is enough.
and the config is more soc level, I think you can add this to arch_cpu_init() for we don't have a power domain driver.
On 2024/9/17 05:01, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The current panel detection logic crashes when the device boots with mainline A-TF, causing a reboot loop. It turns out mainline A-TF doesn't enable the VO power domain like the BSP A-TF did.
Set the VO domain on and use a memory barrier to ensure it is powered up before we attempt to do the panel detection.
Signed-off-by: Chris Morgan macromorgan@hotmail.com
board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 13 +++++++++++++ configs/anbernic-rgxx3-rk3566_defconfig | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index c1d1826fd14..f4e7c1ab360 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -22,6 +22,10 @@
DECLARE_GLOBAL_DATA_PTR;
+#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_PWR_GATE_SFTCON 0xa0 +#define PMU_PD_VO_DWN_ENA BIT(7)
- #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000
@@ -311,6 +315,15 @@ int rgxx3_detect_display(void) int i; u8 panel_id[2];
- /* Disable VO power domain power-down */
Disable?
- writel((PMU_PD_VO_DWN_ENA << 16),
PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON);
- /*
* System will crash if the power domain isn't enabled before
* we start trying to talk to the DSI panel.
*/
- wmb();
- /*
- Take panel out of reset status.
- Set GPIO4_A0 to output.
diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index f5e5470df8c..49d3766613e 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -49,8 +49,6 @@ CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y -CONFIG_ARM_SMCCC_FEATURES=y -CONFIG_SCMI_FIRMWARE=y
This should be a separate patch, and what's the change?
Thanks,
- Kever
CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y

On Wed, Sep 18, 2024 at 11:06:34AM +0800, Kever Yang wrote:
Hi Chris,
Please update the subject with something like "Enable the VO PD before driver access",
and the commit message for the change reason is enough.
and the config is more soc level, I think you can add this to arch_cpu_init() for we don't have a power domain driver.
To my knowledge I'm the only board trying to access the video before Linux proper. Do you want me to add this for all rk3568 boards then (from within rk3568.c under arch_cpu_init() as you say)? I'm thinking if I do though I can at least get rid of the memory barrier.
On 2024/9/17 05:01, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The current panel detection logic crashes when the device boots with mainline A-TF, causing a reboot loop. It turns out mainline A-TF doesn't enable the VO power domain like the BSP A-TF did.
Set the VO domain on and use a memory barrier to ensure it is powered up before we attempt to do the panel detection.
Signed-off-by: Chris Morgan macromorgan@hotmail.com
board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 13 +++++++++++++ configs/anbernic-rgxx3-rk3566_defconfig | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index c1d1826fd14..f4e7c1ab360 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -22,6 +22,10 @@ DECLARE_GLOBAL_DATA_PTR; +#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_PWR_GATE_SFTCON 0xa0 +#define PMU_PD_VO_DWN_ENA BIT(7)
- #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000
@@ -311,6 +315,15 @@ int rgxx3_detect_display(void) int i; u8 panel_id[2];
- /* Disable VO power domain power-down */
Disable?
It's weird verbiage but the data sheet says "Enable power down PD_VO" by writing a 1, so I figure I'm disabling it by writing a 0.
- writel((PMU_PD_VO_DWN_ENA << 16),
PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON);
- /*
* System will crash if the power domain isn't enabled before
* we start trying to talk to the DSI panel.
*/
- wmb();
- /*
- Take panel out of reset status.
- Set GPIO4_A0 to output.
diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index f5e5470df8c..49d3766613e 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -49,8 +49,6 @@ CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y -CONFIG_ARM_SMCCC_FEATURES=y -CONFIG_SCMI_FIRMWARE=y
This should be a separate patch, and what's the change?
Mainline A-TF seems to get angry with U-Boot when these are enabled. By angry I mean it freezes. It's all a related change to allowing mainline A-TF, though I should probably call it out better as a required change. Again I also specify though in the commit message that mainline A-TF still doesn't work with Linux proper because of the missing psci clk and psci reset bits, but at least with this change U-Boot won't be contributing to the problem (for this board).
Thanks,
- Kever
CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y
Thank you, Chris

Hi Chris,
On 2024/9/18 21:38, Chris Morgan wrote:
On Wed, Sep 18, 2024 at 11:06:34AM +0800, Kever Yang wrote:
Hi Chris,
Please update the subject with something like "Enable the VO PD before driver access",
and the commit message for the change reason is enough.
and the config is more soc level, I think you can add this to arch_cpu_init() for we don't have a power domain driver.
To my knowledge I'm the only board trying to access the video before Linux proper. Do you want me to add this for all rk3568 boards then (from within rk3568.c under arch_cpu_init() as you say)?
Yes, please move it to rk3568.c in case other board need it.
I'm thinking if I do though I can at least get rid of the memory barrier.
On 2024/9/17 05:01, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The current panel detection logic crashes when the device boots with mainline A-TF, causing a reboot loop. It turns out mainline A-TF doesn't enable the VO power domain like the BSP A-TF did.
Set the VO domain on and use a memory barrier to ensure it is powered up before we attempt to do the panel detection.
Signed-off-by: Chris Morgan macromorgan@hotmail.com
board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 13 +++++++++++++ configs/anbernic-rgxx3-rk3566_defconfig | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index c1d1826fd14..f4e7c1ab360 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -22,6 +22,10 @@ DECLARE_GLOBAL_DATA_PTR; +#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_PWR_GATE_SFTCON 0xa0 +#define PMU_PD_VO_DWN_ENA BIT(7)
- #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000
@@ -311,6 +315,15 @@ int rgxx3_detect_display(void) int i; u8 panel_id[2];
- /* Disable VO power domain power-down */
Disable?
It's weird verbiage but the data sheet says "Enable power down PD_VO" by writing a 1, so I figure I'm disabling it by writing a 0.
OK, understand now.
To make it simple and clear, could you just say "Enable PD_VO for display"?
- writel((PMU_PD_VO_DWN_ENA << 16),
PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON);
- /*
* System will crash if the power domain isn't enabled before
* we start trying to talk to the DSI panel.
*/
- wmb();
- /*
- Take panel out of reset status.
- Set GPIO4_A0 to output.
diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index f5e5470df8c..49d3766613e 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -49,8 +49,6 @@ CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y -CONFIG_ARM_SMCCC_FEATURES=y -CONFIG_SCMI_FIRMWARE=y
This should be a separate patch, and what's the change?
Mainline A-TF seems to get angry with U-Boot when these are enabled. By angry I mean it freezes. It's all a related change to allowing mainline A-TF, though I should probably call it out better as a required change. Again I also specify though in the commit message that mainline A-TF still doesn't work with Linux proper because of the missing psci clk and psci reset bits, but at least with this change U-Boot won't be contributing to the problem (for this board).
The scmi clock is missing on rk3568 mainline A-TF now, but it should return error with something like
NOT SUPPORT instead of hang inside.
Any way, this is a separate change, we don't need it if the ATF supports scmi clock later.
Thanks,
- Kever
Thanks,
- Kever
CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y
Thank you, Chris

On Thu, Sep 19, 2024 at 09:48:58AM +0800, Kever Yang wrote:
Hi Chris,
On 2024/9/18 21:38, Chris Morgan wrote:
On Wed, Sep 18, 2024 at 11:06:34AM +0800, Kever Yang wrote:
Hi Chris,
Please update the subject with something like "Enable the VO PD before driver access",
and the commit message for the change reason is enough.
and the config is more soc level, I think you can add this to arch_cpu_init() for we don't have a power domain driver.
To my knowledge I'm the only board trying to access the video before Linux proper. Do you want me to add this for all rk3568 boards then (from within rk3568.c under arch_cpu_init() as you say)?
Yes, please move it to rk3568.c in case other board need it.
I'm thinking if I do though I can at least get rid of the memory barrier.
On 2024/9/17 05:01, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The current panel detection logic crashes when the device boots with mainline A-TF, causing a reboot loop. It turns out mainline A-TF doesn't enable the VO power domain like the BSP A-TF did.
Set the VO domain on and use a memory barrier to ensure it is powered up before we attempt to do the panel detection.
Signed-off-by: Chris Morgan macromorgan@hotmail.com
board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 13 +++++++++++++ configs/anbernic-rgxx3-rk3566_defconfig | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index c1d1826fd14..f4e7c1ab360 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -22,6 +22,10 @@ DECLARE_GLOBAL_DATA_PTR; +#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_PWR_GATE_SFTCON 0xa0 +#define PMU_PD_VO_DWN_ENA BIT(7)
- #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000
@@ -311,6 +315,15 @@ int rgxx3_detect_display(void) int i; u8 panel_id[2];
- /* Disable VO power domain power-down */
Disable?
It's weird verbiage but the data sheet says "Enable power down PD_VO" by writing a 1, so I figure I'm disabling it by writing a 0.
OK, understand now.
To make it simple and clear, could you just say "Enable PD_VO for display"?
- writel((PMU_PD_VO_DWN_ENA << 16),
PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON);
- /*
* System will crash if the power domain isn't enabled before
* we start trying to talk to the DSI panel.
*/
- wmb();
- /*
- Take panel out of reset status.
- Set GPIO4_A0 to output.
diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index f5e5470df8c..49d3766613e 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -49,8 +49,6 @@ CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y -CONFIG_ARM_SMCCC_FEATURES=y -CONFIG_SCMI_FIRMWARE=y
This should be a separate patch, and what's the change?
Mainline A-TF seems to get angry with U-Boot when these are enabled. By angry I mean it freezes. It's all a related change to allowing mainline A-TF, though I should probably call it out better as a required change. Again I also specify though in the commit message that mainline A-TF still doesn't work with Linux proper because of the missing psci clk and psci reset bits, but at least with this change U-Boot won't be contributing to the problem (for this board).
The scmi clock is missing on rk3568 mainline A-TF now, but it should return error with something like
NOT SUPPORT instead of hang inside.
Any way, this is a separate change, we don't need it if the ATF supports scmi clock later.
Thanks,
- Kever
I'll opt to disable this for now anyway (but in a commit by itself), if that's okay. It makes no difference for booting when using binary A-TF, but it does make a difference when using the *current* mainline A-TF, even if we do get SCMI later.
Thank you, Chris
Thanks,
- Kever
CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y
Thank you, Chris

On 2024/9/19 21:15, Chris Morgan wrote:
On Thu, Sep 19, 2024 at 09:48:58AM +0800, Kever Yang wrote:
Hi Chris,
On 2024/9/18 21:38, Chris Morgan wrote:
On Wed, Sep 18, 2024 at 11:06:34AM +0800, Kever Yang wrote:
Hi Chris,
Please update the subject with something like "Enable the VO PD before driver access",
and the commit message for the change reason is enough.
and the config is more soc level, I think you can add this to arch_cpu_init() for we don't have a power domain driver.
To my knowledge I'm the only board trying to access the video before Linux proper. Do you want me to add this for all rk3568 boards then (from within rk3568.c under arch_cpu_init() as you say)?
Yes, please move it to rk3568.c in case other board need it.
I'm thinking if I do though I can at least get rid of the memory barrier.
On 2024/9/17 05:01, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The current panel detection logic crashes when the device boots with mainline A-TF, causing a reboot loop. It turns out mainline A-TF doesn't enable the VO power domain like the BSP A-TF did.
Set the VO domain on and use a memory barrier to ensure it is powered up before we attempt to do the panel detection.
Signed-off-by: Chris Morgan macromorgan@hotmail.com
board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 13 +++++++++++++ configs/anbernic-rgxx3-rk3566_defconfig | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index c1d1826fd14..f4e7c1ab360 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -22,6 +22,10 @@ DECLARE_GLOBAL_DATA_PTR; +#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_PWR_GATE_SFTCON 0xa0 +#define PMU_PD_VO_DWN_ENA BIT(7)
- #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000
@@ -311,6 +315,15 @@ int rgxx3_detect_display(void) int i; u8 panel_id[2];
- /* Disable VO power domain power-down */
Disable?
It's weird verbiage but the data sheet says "Enable power down PD_VO" by writing a 1, so I figure I'm disabling it by writing a 0.
OK, understand now.
To make it simple and clear, could you just say "Enable PD_VO for display"?
- writel((PMU_PD_VO_DWN_ENA << 16),
PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON);
- /*
* System will crash if the power domain isn't enabled before
* we start trying to talk to the DSI panel.
*/
- wmb();
/* * Take panel out of reset status. * Set GPIO4_A0 to output.
diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index f5e5470df8c..49d3766613e 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -49,8 +49,6 @@ CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y -CONFIG_ARM_SMCCC_FEATURES=y -CONFIG_SCMI_FIRMWARE=y
This should be a separate patch, and what's the change?
Mainline A-TF seems to get angry with U-Boot when these are enabled. By angry I mean it freezes. It's all a related change to allowing mainline A-TF, though I should probably call it out better as a required change. Again I also specify though in the commit message that mainline A-TF still doesn't work with Linux proper because of the missing psci clk and psci reset bits, but at least with this change U-Boot won't be contributing to the problem (for this board).
The scmi clock is missing on rk3568 mainline A-TF now, but it should return error with something like
NOT SUPPORT instead of hang inside.
Any way, this is a separate change, we don't need it if the ATF supports scmi clock later.
Thanks,
- Kever
I'll opt to disable this for now anyway (but in a commit by itself), if that's okay. It makes no difference for booting when using binary A-TF, but it does make a difference when using the *current* mainline A-TF, even if we do get SCMI later.
Could you try with below patch for rk3568 SCMI support:
https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/31265
Thanks,
- Kever
Thank you, Chris
Thanks,
- Kever
CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y
Thank you, Chris

On Mon, Sep 30, 2024 at 04:59:41PM +0800, Kever Yang wrote:
On 2024/9/19 21:15, Chris Morgan wrote:
On Thu, Sep 19, 2024 at 09:48:58AM +0800, Kever Yang wrote:
Hi Chris,
On 2024/9/18 21:38, Chris Morgan wrote:
On Wed, Sep 18, 2024 at 11:06:34AM +0800, Kever Yang wrote:
Hi Chris,
Please update the subject with something like "Enable the VO PD before driver access",
and the commit message for the change reason is enough.
and the config is more soc level, I think you can add this to arch_cpu_init() for we don't have a power domain driver.
To my knowledge I'm the only board trying to access the video before Linux proper. Do you want me to add this for all rk3568 boards then (from within rk3568.c under arch_cpu_init() as you say)?
Yes, please move it to rk3568.c in case other board need it.
I'm thinking if I do though I can at least get rid of the memory barrier.
On 2024/9/17 05:01, Chris Morgan wrote:
From: Chris Morgan macromorgan@hotmail.com
The current panel detection logic crashes when the device boots with mainline A-TF, causing a reboot loop. It turns out mainline A-TF doesn't enable the VO power domain like the BSP A-TF did.
Set the VO domain on and use a memory barrier to ensure it is powered up before we attempt to do the panel detection.
Signed-off-by: Chris Morgan macromorgan@hotmail.com
board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 13 +++++++++++++ configs/anbernic-rgxx3-rk3566_defconfig | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index c1d1826fd14..f4e7c1ab360 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -22,6 +22,10 @@ DECLARE_GLOBAL_DATA_PTR; +#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_PWR_GATE_SFTCON 0xa0 +#define PMU_PD_VO_DWN_ENA BIT(7)
- #define GPIO0_BASE 0xfdd60000 #define GPIO4_BASE 0xfe770000 #define GPIO_SWPORT_DR_L 0x0000
@@ -311,6 +315,15 @@ int rgxx3_detect_display(void) int i; u8 panel_id[2];
- /* Disable VO power domain power-down */
Disable?
It's weird verbiage but the data sheet says "Enable power down PD_VO" by writing a 1, so I figure I'm disabling it by writing a 0.
OK, understand now.
To make it simple and clear, could you just say "Enable PD_VO for display"?
- writel((PMU_PD_VO_DWN_ENA << 16),
PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON);
- /*
* System will crash if the power domain isn't enabled before
* we start trying to talk to the DSI panel.
*/
- wmb();
/* * Take panel out of reset status. * Set GPIO4_A0 to output.
diff --git a/configs/anbernic-rgxx3-rk3566_defconfig b/configs/anbernic-rgxx3-rk3566_defconfig index f5e5470df8c..49d3766613e 100644 --- a/configs/anbernic-rgxx3-rk3566_defconfig +++ b/configs/anbernic-rgxx3-rk3566_defconfig @@ -49,8 +49,6 @@ CONFIG_SPL_REGMAP=y CONFIG_SPL_SYSCON=y CONFIG_SPL_ADC=y CONFIG_SPL_CLK=y -CONFIG_ARM_SMCCC_FEATURES=y -CONFIG_SCMI_FIRMWARE=y
This should be a separate patch, and what's the change?
Mainline A-TF seems to get angry with U-Boot when these are enabled. By angry I mean it freezes. It's all a related change to allowing mainline A-TF, though I should probably call it out better as a required change. Again I also specify though in the commit message that mainline A-TF still doesn't work with Linux proper because of the missing psci clk and psci reset bits, but at least with this change U-Boot won't be contributing to the problem (for this board).
The scmi clock is missing on rk3568 mainline A-TF now, but it should return error with something like
NOT SUPPORT instead of hang inside.
Any way, this is a separate change, we don't need it if the ATF supports scmi clock later.
Thanks,
- Kever
I'll opt to disable this for now anyway (but in a commit by itself), if that's okay. It makes no difference for booting when using binary A-TF, but it does make a difference when using the *current* mainline A-TF, even if we do get SCMI later.
Could you try with below patch for rk3568 SCMI support:
https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/31265
I did. We still need this specific patch to call the panel in U-Boot (so I can detect it and fix-up the device tree). I noted a few issues I identified on that commit; they may or may not be related to the specific commit at hand though since it was the first time I could boot my devices with mainline A-TF.
Thank you, Chris
Thanks,
- Kever
Thank you, Chris
Thanks,
- Kever
CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y
Thank you, Chris
participants (3)
-
Chris Morgan
-
Chris Morgan
-
Kever Yang