[PATCH] board: rockchip: Add Support for RG353PS and Panel Auto Detection

Chris Morgan macromorgan at hotmail.com
Mon May 15 17:17:18 CEST 2023


On Mon, May 15, 2023 at 10:49:43AM +0800, Kever Yang wrote:
> Hi Chris,
> 
>     Please split this patch into a series with:

Thanks, sorry. I probably should have done it this way to begin with.

> 
> - driver update
> 
> - dts update
> 
> - config update.
> 
> 
> Thanks,
> 
> - Kever
> 
> On 2023/5/13 00:34, Chris Morgan wrote:
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Add support for panel auto detection for the Anbernic RGxx3 series.
> > This requires us to probe the DSI and DSI-DPHY controllers so that
> > we may send a MIPI_DCS_GET_DISPLAY_ID command to the panel to find
> > out which panel we are running. This requires creating a kind of
> > "skeleton" driver for the panel so we have just enough information
> > about it to issue the necessary command.
> > 
> > Once the panel type is determined the panel type is saved as an
> > environment variable, and additionally the panel compatible string
> > is automatically fixed-up in the devicetree if it is found to be
> > incompatible. There is a table of panel IDs and compatible strings,
> > support for a new panel only requires knowing the ID and the string.
> > 
> > Additionally, the device auto detection was changed so that it
> > mimicks the panel auto detection, requiring only defining a few
> > new values to add support for a new compatible board. This is done
> > while also adding a new board, the RG353PS.
> > 
> > Tested the auto detection on an RG353P, RG353PS (2nd revision panel),
> > RG353V, RG353V (2nd revision panel), RG353M, and RG503. As long as
> > the correct devicetrees were located in ${boot}/rockchip/. U-Boot
> > was able to automatically detect the correct board and panel and
> > boot each device correctly.
> > 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> > ---
> >   .../arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi |  10 +
> >   board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c    | 322 +++++++++++++++---
> >   configs/anbernic-rgxx3_defconfig              |  15 +
> >   3 files changed, 307 insertions(+), 40 deletions(-)
> > 
> > diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi
> > index a18e5d1cf7..f986e1941e 100644
> > --- a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi
> > +++ b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi
> > @@ -46,7 +46,17 @@
> >   			<&pmucru CLK_RTC32K_FRAC>;
> >   };
> > +&dsi_dphy0 {
> > +	status = "okay";
> > +};
> > +
> > +&dsi0 {
> > +	status = "okay";
> > +};
> > +
> >   &i2c2 {
> > +	pinctrl-0 = <&i2c2m1_xfer>;
> > +	pinctrl-names = "default";
> >   	status = "okay";
> >   };
> > diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c
> > index decc46db78..027f4872bb 100644
> > --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c
> > +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c
> > @@ -6,25 +6,37 @@
> >   #include <abuf.h>
> >   #include <adc.h>
> >   #include <asm/io.h>
> > +#include <display.h>
> >   #include <dm.h>
> > +#include <dm/lists.h>
> > +#include <env.h>
> > +#include <fdt_support.h>
> >   #include <linux/delay.h>
> > +#include <mipi_dsi.h>
> > +#include <mmc.h>
> > +#include <panel.h>
> >   #include <pwm.h>
> >   #include <rng.h>
> >   #include <stdlib.h>
> > -#include <mmc.h>
> > -#include <env.h>
> > +#include <video_bridge.h>
> >   #define GPIO0_BASE		0xfdd60000
> > +#define GPIO4_BASE		0xfe770000
> > +#define GPIO_SWPORT_DR_L	0x0000
> >   #define GPIO_SWPORT_DR_H	0x0004
> > +#define GPIO_SWPORT_DDR_L	0x0008
> >   #define GPIO_SWPORT_DDR_H	0x000c
> > -#define GPIO_A5			BIT(5)
> > -#define GPIO_A6			BIT(6)
> > +#define GPIO_A0			BIT(0)
> > +#define GPIO_C5			BIT(5)
> > +#define GPIO_C6			BIT(6)
> > +#define GPIO_C7			BIT(7)
> >   #define GPIO_WRITEMASK(bits)	((bits) << 16)
> >   #define DTB_DIR			"rockchip/"
> >   struct rg3xx_model {
> > +	const u16 adc_value;
> >   	const char *board;
> >   	const char *board_name;
> >   	const char *fdtfile;
> > @@ -34,49 +46,74 @@ enum rgxx3_device_id {
> >   	RG353M,
> >   	RG353P,
> >   	RG353V,
> > -	RG353VS,
> >   	RG503,
> > +	/* Devices with duplicate ADC value */
> > +	RG353PS,
> > +	RG353VS,
> >   };
> >   static const struct rg3xx_model rg3xx_model_details[] = {
> >   	[RG353M] = {
> > +		517, /* Observed average from device */
> >   		"rk3566-anbernic-rg353m",
> >   		"RG353M",
> > -		DTB_DIR "rk3566-anbernic-rg353m.dtb",
> > +		DTB_DIR "rk3566-anbernic-rg353p.dtb", /* Identical devices */
> >   	},
> >   	[RG353P] = {
> > +		860, /* Documented value of 860 */
> >   		"rk3566-anbernic-rg353p",
> >   		"RG353P",
> >   		DTB_DIR "rk3566-anbernic-rg353p.dtb",
> >   	},
> >   	[RG353V] = {
> > +		695, /* Observed average from device */
> >   		"rk3566-anbernic-rg353v",
> >   		"RG353V",
> >   		DTB_DIR "rk3566-anbernic-rg353v.dtb",
> >   	},
> > -	[RG353VS] = {
> > -		"rk3566-anbernic-rg353vs",
> > -		"RG353VS",
> > -		DTB_DIR "rk3566-anbernic-rg353vs.dtb",
> > -	},
> >   	[RG503] = {
> > +		1023, /* Observed average from device */
> >   		"rk3566-anbernic-rg503",
> >   		"RG503",
> >   		DTB_DIR "rk3566-anbernic-rg503.dtb",
> >   	},
> > +	/* Devices with duplicate ADC value */
> > +	[RG353PS] = {
> > +		860, /* Gathered from second hand information */
> > +		"rk3566-anbernic-rg353ps",
> > +		"RG353PS",
> > +		DTB_DIR "rk3566-anbernic-rg353ps.dtb",
> > +	},
> > +	[RG353VS] = {
> > +		695, /* Gathered from second hand information */
> > +		"rk3566-anbernic-rg353vs",
> > +		"RG353VS",
> > +		DTB_DIR "rk3566-anbernic-rg353vs.dtb",
> > +	},
> > +};
> > +
> > +struct rg353_panel {
> > +	const u16 id;
> > +	const char *panel_compat;
> > +};
> > +
> > +static const struct rg353_panel rg353_panel_details[] = {
> > +	{ .id = 0x3052, .panel_compat = "newvision,nv3051d"},
> > +	{ .id = 0x3821, .panel_compat = "anbernic,rg353v-panel-v2"},
> >   };
> >   /*
> >    * Start LED very early so user knows device is on. Set color
> > - * to amber.
> > + * to red.
> >    */
> >   void spl_board_init(void)
> >   {
> > -	/* Set GPIO0_A5 and GPIO0_A6 to output. */
> > -	writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | (GPIO_A6 | GPIO_A5),
> > +	/* Set GPIO0_C5, GPIO0_C6, and GPIO0_C7 to output. */
> > +	writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | \
> > +	       (GPIO_C7 | GPIO_C6 | GPIO_C5),
> >   	       (GPIO0_BASE + GPIO_SWPORT_DDR_H));
> > -	/* Set GPIO0_A5 to 0 and GPIO0_A6 to 1. */
> > -	writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | GPIO_A6,
> > +	/* Set GPIO0_C5 and GPIO_C6 to 0 and GPIO0_C7 to 1. */
> > +	writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | GPIO_C7,
> >   	       (GPIO0_BASE + GPIO_SWPORT_DR_H));
> >   }
> > @@ -126,15 +163,159 @@ void __maybe_unused startup_buzz(void)
> >   	pwm_set_enable(dev, 0, 0);
> >   }
> > +/*
> > + * Provide the bare minimum to identify the panel for the RG353
> > + * series. Since we don't have a working framebuffer device, no
> > + * need to init the panel; just identify it and provide the
> > + * clocks so we know what to set the different clock values to.
> > + */
> > +
> > +static const struct display_timing rg353_default_timing = {
> > +	.pixelclock.typ		= 24150000,
> > +	.hactive.typ		= 640,
> > +	.hfront_porch.typ	= 40,
> > +	.hback_porch.typ	= 80,
> > +	.hsync_len.typ		= 2,
> > +	.vactive.typ		= 480,
> > +	.vfront_porch.typ	= 18,
> > +	.vback_porch.typ	= 28,
> > +	.vsync_len.typ		= 2,
> > +	.flags			= DISPLAY_FLAGS_HSYNC_HIGH |
> > +				  DISPLAY_FLAGS_VSYNC_HIGH,
> > +};
> > +
> > +static int anbernic_rg353_panel_get_timing(struct udevice *dev,
> > +					   struct display_timing *timings)
> > +{
> > +	memcpy(timings, &rg353_default_timing, sizeof(*timings));
> > +
> > +	return 0;
> > +}
> > +
> > +static int anbernic_rg353_panel_probe(struct udevice *dev)
> > +{
> > +	struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
> > +
> > +	plat->lanes = 4;
> > +	plat->format = MIPI_DSI_FMT_RGB888;
> > +	plat->mode_flags = MIPI_DSI_MODE_VIDEO |
> > +			   MIPI_DSI_MODE_VIDEO_BURST |
> > +			   MIPI_DSI_MODE_EOT_PACKET |
> > +			   MIPI_DSI_MODE_LPM;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct panel_ops anbernic_rg353_panel_ops = {
> > +	.get_display_timing = anbernic_rg353_panel_get_timing,
> > +};
> > +
> > +U_BOOT_DRIVER(anbernic_rg353_panel) = {
> > +	.name		= "anbernic_rg353_panel",
> > +	.id		= UCLASS_PANEL,
> > +	.ops		= &anbernic_rg353_panel_ops,
> > +	.probe		= anbernic_rg353_panel_probe,
> > +	.plat_auto	= sizeof(struct mipi_dsi_panel_plat),
> > +};
> > +
> > +int rgxx3_detect_display(void)
> > +{
> > +	struct udevice *dev;
> > +	struct mipi_dsi_device *dsi;
> > +	struct mipi_dsi_panel_plat *mplat;
> > +	const struct rg353_panel *panel;
> > +	int ret = 0;
> > +	int i;
> > +	u8 panel_id[2];
> > +
> > +	/*
> > +	 * Take panel out of reset status.
> > +	 * Set GPIO4_A0 to output.
> > +	 */
> > +	writel(GPIO_WRITEMASK(GPIO_A0) | GPIO_A0,
> > +	       (GPIO4_BASE + GPIO_SWPORT_DDR_L));
> > +	/* Set GPIO4_A0 to 1. */
> > +	writel(GPIO_WRITEMASK(GPIO_A0) | GPIO_A0,
> > +	       (GPIO4_BASE + GPIO_SWPORT_DR_L));
> > +
> > +	/* Probe the DSI controller. */
> > +	ret = uclass_get_device_by_name(UCLASS_VIDEO_BRIDGE,
> > +					"dsi at fe060000", &dev);
> > +	if (ret) {
> > +		printf("DSI host not probed: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* Probe the DSI panel. */
> > +	ret = device_bind_driver_to_node(dev, "anbernic_rg353_panel",
> > +					 "anbernic_rg353_panel",
> > +					 dev_ofnode(dev), NULL);
> > +	if (ret) {
> > +		printf("Failed to probe RG353 panel: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/*
> > +	 * Attach the DSI controller which will also probe and attach
> > +	 * the DSIDPHY.
> > +	 */
> > +	ret = video_bridge_attach(dev);
> > +	if (ret) {
> > +		printf("Failed to attach DSI controller: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/*
> > +	 * Get the panel which should have already been probed by the
> > +	 * video_bridge_attach() function.
> > +	 */
> > +	ret = uclass_first_device_err(UCLASS_PANEL, &dev);
> > +	if (ret) {
> > +		printf("Panel device error: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* Now call the panel via DSI commands to get the panel ID. */
> > +	mplat = dev_get_plat(dev);
> > +	dsi = mplat->device;
> > +	mipi_dsi_set_maximum_return_packet_size(dsi, sizeof(panel_id));
> > +	ret = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_ID, &panel_id,
> > +				sizeof(panel_id));
> > +	if (ret < 0) {
> > +		printf("Unable to read panel ID: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* Get the correct panel compatible from the table. */
> > +	for (i = 0; i < ARRAY_SIZE(rg353_panel_details); i++) {
> > +		if (rg353_panel_details[i].id == ((panel_id[0] << 8) |
> > +						 panel_id[1])) {
> > +			panel = &rg353_panel_details[i];
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (!panel) {
> > +		printf("Unable to identify panel_id %x\n",
> > +		       (panel_id[0] << 8) | panel_id[1]);
> > +		env_set("panel", "unknown");
> > +		return -EINVAL;
> > +	}
> > +
> > +	env_set("panel", panel->panel_compat);
> > +
> > +	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 (TODO).
> > + * presence of an eMMC on mmc0, and querying the DSI panel.
> >    */
> >   int rgxx3_detect_device(void)
> >   {
> >   	u32 adc_info;
> > -	int ret;
> > +	int ret, i;
> >   	int board_id = -ENXIO;
> >   	struct mmc *mmc;
> > @@ -144,30 +325,37 @@ int rgxx3_detect_device(void)
> >   		return ret;
> >   	}
> > -	/* Observed value 517. */
> > -	if (adc_info > 505 && adc_info < 530)
> > -		board_id = RG353M;
> > -	/* Observed value 695. */
> > -	if (adc_info > 680 && adc_info < 710)
> > -		board_id = RG353V;
> > -	/* Documented value 860. */
> > -	if (adc_info > 850 && adc_info < 870)
> > -		board_id = RG353P;
> > -	/* Observed value 1023. */
> > -	if (adc_info > 1010)
> > -		board_id = RG503;
> > +	/*
> > +	 * Get the correct device from the table. The ADC value is
> > +	 * determined by a resistor on ADC channel 0. The hardware
> > +	 * 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++) {
> > +		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;
> > +		}
> > +	}
> >   	/*
> > -	 * Try to access the eMMC on an RG353V. If it's missing, it's
> > -	 * an RG353VS. Note we could also check for a touchscreen at
> > -	 * 0x1a on i2c2.
> > +	 * Try to access the eMMC on an RG353V or RG353P. If it's
> > +	 * missing, it's an RG353VS or RG353PS. Note we could also
> > +	 * check for a touchscreen at 0x1a on i2c2.
> >   	 */
> > -	if (board_id == RG353V) {
> > +	if (board_id == RG353V || board_id == RG353P) {
> >   		mmc = find_mmc_device(0);
> >   		if (mmc) {
> >   			ret = mmc_init(mmc);
> > -			if (ret)
> > -				board_id = RG353VS;
> > +			if (ret) {
> > +				if (board_id == RG353V)
> > +					board_id = RG353VS;
> > +				else
> > +					board_id = RG353PS;
> > +			}
> >   		}
> >   	}
> > @@ -179,6 +367,14 @@ int rgxx3_detect_device(void)
> >   		rg3xx_model_details[board_id].board_name);
> >   	env_set("fdtfile", rg3xx_model_details[board_id].fdtfile);
> > +	/* Detect the panel type for any device that isn't a 503. */
> > +	if (board_id == RG503)
> > +		return 0;
> > +
> > +	ret = rgxx3_detect_display();
> > +	if (ret)
> > +		return ret;
> > +
> >   	return 0;
> >   }
> > @@ -186,18 +382,64 @@ int rk_board_late_init(void)
> >   {
> >   	int ret;
> > -	/* Turn off orange LED and turn on green LED. */
> > -	writel(GPIO_WRITEMASK(GPIO_A6 | GPIO_A5) | GPIO_A5,
> > -	       (GPIO0_BASE + GPIO_SWPORT_DR_H));
> > -
> >   	ret = rgxx3_detect_device();
> >   	if (ret) {
> >   		printf("Unable to detect device type: %d\n", ret);
> >   		return ret;
> >   	}
> > +	/* 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();
> >   	return 0;
> >   }
> > +
> > +int ft_board_setup(void *blob, struct bd_info *bd)
> > +{
> > +	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));
> > +
> > +	/*
> > +	 * Check if the environment variable doesn't equal the panel.
> > +	 * If it doesn't, update the devicetree to the correct panel.
> > +	 */
> > +	node = fdt_path_offset(blob, "/dsi at fe060000/panel at 0");
> > +	if (!(node > 0)) {
> > +		printf("Can't find the DSI node\n");
> > +		return -ENODEV;
> > +	}
> > +
> > +	env = env_get("panel");
> > +	if (!env) {
> > +		printf("Can't get panel env\n");
> > +		return -ENODEV;
> > +	}
> > +
> > +	ret = fdt_node_check_compatible(blob, node, env);
> > +	if (ret < 0)
> > +		return -ENODEV;
> > +
> > +	/* Panels match, return 0. */
> > +	if (!ret)
> > +		return 0;
> > +
> > +	do_fixup_by_path_string(blob, "/dsi at fe060000/panel at 0",
> > +				"compatible", env);
> > +
> > +	return 0;
> > +}
> > diff --git a/configs/anbernic-rgxx3_defconfig b/configs/anbernic-rgxx3_defconfig
> > index b17e917914..ed6643d9d4 100644
> > --- a/configs/anbernic-rgxx3_defconfig
> > +++ b/configs/anbernic-rgxx3_defconfig
> > @@ -12,6 +12,7 @@ CONFIG_DEFAULT_DEVICE_TREE="rk3566-anbernic-rgxx3"
> >   CONFIG_ROCKCHIP_RK3568=y
> >   CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
> >   CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
> > +CONFIG_ROCKCHIP_RK8XX_DISABLE_BOOT_ON_POWERON=y
> >   CONFIG_SPL_MMC=y
> >   CONFIG_SPL_SERIAL=y
> >   CONFIG_SPL_STACK_R_ADDR=0x600000
> > @@ -24,9 +25,13 @@ CONFIG_DEBUG_UART=y
> >   CONFIG_FIT=y
> >   CONFIG_FIT_VERBOSE=y
> >   CONFIG_SPL_LOAD_FIT=y
> > +CONFIG_OF_BOARD_SETUP=y
> > +CONFIG_OF_STDOUT_VIA_ALIAS=y
> >   CONFIG_DEFAULT_FDT_FILE="rockchip/rk3566-anbernic-rgxx3.dtb"
> > +# CONFIG_CONSOLE_MUX is not set
> >   # CONFIG_DISPLAY_CPUINFO is not set
> >   CONFIG_DISPLAY_BOARDINFO_LATE=y
> > +CONFIG_BOARD_RNG_SEED=y
> >   CONFIG_SPL_MAX_SIZE=0x20000
> >   CONFIG_SPL_PAD_TO=0x7f8000
> >   CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
> > @@ -41,6 +46,7 @@ CONFIG_CMD_PWM=y
> >   CONFIG_CMD_GPT=y
> >   CONFIG_CMD_MMC=y
> >   # CONFIG_CMD_SETEXPR is not set
> > +# CONFIG_CMD_CLS is not set
> >   # CONFIG_SPL_DOS_PARTITION is not set
> >   CONFIG_SPL_OF_CONTROL=y
> >   CONFIG_OF_LIVE=y
> > @@ -60,6 +66,7 @@ CONFIG_MMC_DW_ROCKCHIP=y
> >   CONFIG_MMC_SDHCI=y
> >   CONFIG_MMC_SDHCI_SDMA=y
> >   CONFIG_MMC_SDHCI_ROCKCHIP=y
> > +CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=y
> >   CONFIG_DM_PMIC=y
> >   CONFIG_DM_PMIC_FAN53555=y
> >   CONFIG_PMIC_RK8XX=y
> > @@ -69,10 +76,18 @@ CONFIG_REGULATOR_RK8XX=y
> >   CONFIG_DM_REGULATOR_SCMI=y
> >   CONFIG_PWM_ROCKCHIP=y
> >   CONFIG_SPL_RAM=y
> > +# CONFIG_RAM_ROCKCHIP_DEBUG is not set
> > +CONFIG_DM_RNG=y
> > +CONFIG_RNG_ROCKCHIP=y
> > +# CONFIG_RNG_SMCCC_TRNG is not set
> >   CONFIG_BAUDRATE=1500000
> >   CONFIG_DEBUG_UART_SHIFT=2
> >   CONFIG_SYS_NS16550_MEM32=y
> >   CONFIG_SYSRESET=y
> > +CONFIG_VIDEO=y
> > +CONFIG_VIDEO_ROCKCHIP=y
> > +CONFIG_DISPLAY_ROCKCHIP_DW_MIPI=y
> > +CONFIG_VIDEO_BRIDGE=y
> >   CONFIG_REGEX=y
> >   CONFIG_ERRNO_STR=y
> >   # CONFIG_EFI_LOADER is not set


More information about the U-Boot mailing list