+// SPDX-License-Identifier: GPL-2.0+
/*
* Allwinner DE2 display driver
*
* (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <display.h>
#include <dm.h>
#include <edid.h>
+#include <efi_loader.h>
+#include <fdtdec.h>
+#include <fdt_support.h>
#include <video.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/arch/display2.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
+#include "simplefb_common.h"
DECLARE_GLOBAL_DATA_PTR;
uc_priv->bpix = l2bpp;
debug("fb=%lx, size=%d %d\n", fbbase, uc_priv->xsize, uc_priv->ysize);
+#ifdef CONFIG_EFI_LOADER
+ efi_add_memory_map(fbbase,
+ ALIGN(timing.hactive.typ * timing.vactive.typ *
+ (1 << l2bpp) / 8, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+ EFI_RESERVED_MEMORY_TYPE, false);
+#endif
+
return 0;
}
if (!(gd->flags & GD_FLG_RELOC))
return 0;
+ ret = uclass_find_device_by_name(UCLASS_DISPLAY,
+ "sunxi_lcd", &disp);
+ if (!ret) {
+ int mux;
+
+ mux = 0;
+
+ ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux,
+ false);
+ if (!ret) {
+ video_set_flush_dcache(dev, 1);
+ return 0;
+ }
+ }
+
+ debug("%s: lcd display not found (ret=%d)\n", __func__, ret);
+
ret = uclass_find_device_by_name(UCLASS_DISPLAY,
"sunxi_dw_hdmi", &disp);
if (!ret) {
U_BOOT_DEVICE(sunxi_de2) = {
.name = "sunxi_de2"
};
+
+/*
+ * Simplefb support.
+ */
+#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
+int sunxi_simplefb_setup(void *blob)
+{
+ struct udevice *de2, *hdmi, *lcd;
+ struct video_priv *de2_priv;
+ struct video_uc_platdata *de2_plat;
+ int mux;
+ int offset, ret;
+ u64 start, size;
+ const char *pipeline = NULL;
+
+ debug("Setting up simplefb\n");
+
+ if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
+ mux = 0;
+ else
+ mux = 1;
+
+ /* Skip simplefb setting if DE2 / HDMI is not present */
+ ret = uclass_find_device_by_name(UCLASS_VIDEO,
+ "sunxi_de2", &de2);
+ if (ret) {
+ debug("DE2 not present\n");
+ return 0;
+ }
+
+ ret = uclass_find_device_by_name(UCLASS_DISPLAY,
+ "sunxi_dw_hdmi", &hdmi);
+ if (ret) {
+ debug("HDMI not present\n");
+ } else if (device_active(hdmi)) {
+ if (mux == 0)
+ pipeline = "mixer0-lcd0-hdmi";
+ else
+ pipeline = "mixer1-lcd1-hdmi";
+ } else {
+ debug("HDMI present but not probed\n");
+ }
+
+ ret = uclass_find_device_by_name(UCLASS_DISPLAY,
+ "sunxi_lcd", &lcd);
+ if (ret)
+ debug("LCD not present\n");
+ else if (device_active(lcd))
+ pipeline = "mixer0-lcd0";
+ else
+ debug("LCD present but not probed\n");
+
+ if (!pipeline) {
+ debug("No active display present\n");
+ return 0;
+ }
+
+ de2_priv = dev_get_uclass_priv(de2);
+ de2_plat = dev_get_uclass_platdata(de2);
+
+ offset = sunxi_simplefb_fdt_match(blob, pipeline);
+ if (offset < 0) {
+ eprintf("Cannot setup simplefb: node not found\n");
+ return 0; /* Keep older kernels working */
+ }
+
+ start = gd->bd->bi_dram[0].start;
+ size = de2_plat->base - start;
+ ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
+ if (ret) {
+ eprintf("Cannot setup simplefb: Error reserving memory\n");
+ return ret;
+ }
+
+ ret = fdt_setup_simplefb_node(blob, offset, de2_plat->base,
+ de2_priv->xsize, de2_priv->ysize,
+ VNBYTES(de2_priv->bpix) * de2_priv->xsize,
+ "x8r8g8b8");
+ if (ret)
+ eprintf("Cannot setup simplefb: Error setting properties\n");
+
+ return ret;
+}
+#endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */