All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@arm.com>
To: u-boot@lists.denx.de
Subject: [PATCH v3] video: sunxi_display: Convert to DM_VIDEO
Date: Fri,  5 Feb 2021 01:07:48 +0000	[thread overview]
Message-ID: <20210205010748.2646-1-andre.przywara@arm.com> (raw)

From: Jagan Teki <jagan@amarulasolutions.com>

DM_VIDEO migration deadline is already expired, but around
80 Allwinner boards are still using video in a legacy way.

===================== WARNING ======================
This board does not use CONFIG_DM_VIDEO Please update
the board to use CONFIG_DM_VIDEO before the v2019.07 release.
Failure to update by the deadline may result in board removal.
See doc/driver-model/migration.rst for more info.
====================================================

Convert the legacy video driver over to the DM_VIDEO framework. This is
a minimal conversion: it doesn't use the DT for finding its resources,
nor does it use DM clocks or DM devices for the outputs (LCD, HDMI, CVBS).

Tested in Bananapi M1+ Plus 1920x1200 HDMI out. (Jagan)

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
[Andre: rebase and smaller fixes]
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
Hi,

I picked this one up to get rid of the warnings. I dropped the BMP
support for now (v2 1/3 and v2 2/3), I need to have a closer look, as
I am not convinced this was the right solution.

Cheers,
Andre

Changelog v2 .. v3:
- rebase against master, fixing up renamed variables and structs
- replace enum with #define
- remove BMP from Kconfig
- fix memory node size calculation in simplefb setup

 arch/arm/mach-sunxi/Kconfig         |   9 +-
 drivers/video/sunxi/sunxi_display.c | 262 ++++++++++++++++------------
 include/configs/sunxi-common.h      |  17 --
 scripts/config_whitelist.txt        |   1 -
 4 files changed, 157 insertions(+), 132 deletions(-)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 0135575ca1e..a29d11505aa 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -816,13 +816,14 @@ config VIDEO_SUNXI
 	depends on !MACH_SUN9I
 	depends on !MACH_SUN50I
 	depends on !SUN50I_GEN_H6
-	select VIDEO
+	select DM_VIDEO
+	select DISPLAY
 	imply VIDEO_DT_SIMPLEFB
 	default y
 	---help---
-	Say Y here to add support for using a cfb console on the HDMI, LCD
-	or VGA output found on most sunxi devices. See doc/README.video for
-	info on how to select the video output and mode.
+	Say Y here to add support for using a graphical console on the HDMI,
+	LCD or VGA output found on older sunxi devices. This will also provide
+	a simple_framebuffer device for Linux.
 
 config VIDEO_HDMI
 	bool "HDMI output support"
diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
index f52aba4d21c..61498d1642f 100644
--- a/drivers/video/sunxi/sunxi_display.c
+++ b/drivers/video/sunxi/sunxi_display.c
@@ -7,6 +7,8 @@
  */
 
 #include <common.h>
+#include <display.h>
+#include <dm.h>
 #include <cpu_func.h>
 #include <efi_loader.h>
 #include <init.h>
@@ -28,7 +30,9 @@
 #include <fdt_support.h>
 #include <i2c.h>
 #include <malloc.h>
+#include <video.h>
 #include <video_fb.h>
+#include <dm/uclass-internal.h>
 #include "../videomodes.h"
 #include "../anx9804.h"
 #include "../hitachi_tx18d42vm_lcd.h"
@@ -45,6 +49,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* Maximum LCD size we support */
+#define LCD_MAX_WIDTH		3840
+#define LCD_MAX_HEIGHT		2160
+#define LCD_MAX_LOG2_BPP	VIDEO_BPP32
+
 enum sunxi_monitor {
 	sunxi_monitor_none,
 	sunxi_monitor_dvi,
@@ -59,12 +68,11 @@ enum sunxi_monitor {
 #define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
 
 struct sunxi_display {
-	GraphicDevice graphic_device;
 	enum sunxi_monitor monitor;
 	unsigned int depth;
 	unsigned int fb_addr;
 	unsigned int fb_size;
-} sunxi_display;
+};
 
 const struct ctfb_res_modes composite_video_modes[2] = {
 	/*  x     y  hz  pixclk ps/kHz   le   ri  up  lo   hs vs  s  vmode */
@@ -214,7 +222,8 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
 	return r;
 }
 
-static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode,
+static int sunxi_hdmi_edid_get_mode(struct sunxi_display *sunxi_display,
+				    struct ctfb_res_modes *mode,
 				    bool verbose_mode)
 {
 	struct edid1_info edid1;
@@ -291,14 +300,14 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode,
 	}
 
 	/* Check for basic audio support, if found enable hdmi output */
-	sunxi_display.monitor = sunxi_monitor_dvi;
+	sunxi_display->monitor = sunxi_monitor_dvi;
 	for (i = 0; i < ext_blocks; i++) {
 		if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG ||
 		    cea681[i].revision < 2)
 			continue;
 
 		if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i]))
-			sunxi_display.monitor = sunxi_monitor_hdmi;
+			sunxi_display->monitor = sunxi_monitor_hdmi;
 	}
 
 	return 0;
@@ -414,9 +423,9 @@ static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
 static void sunxi_frontend_enable(void) {}
 #endif
 
-static bool sunxi_is_composite(void)
+static bool sunxi_is_composite(enum sunxi_monitor monitor)
 {
-	switch (sunxi_display.monitor) {
+	switch (monitor) {
 	case sunxi_monitor_none:
 	case sunxi_monitor_dvi:
 	case sunxi_monitor_hdmi:
@@ -473,7 +482,8 @@ static const u32 sunxi_rgb2yuv_coef[12] = {
 };
 
 static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
-				    unsigned int address)
+				    unsigned int address,
+				    enum sunxi_monitor monitor)
 {
 	struct sunxi_de_be_reg * const de_be =
 		(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
@@ -502,7 +512,7 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
 #endif
 			     SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
 
-	if (sunxi_is_composite()) {
+	if (sunxi_is_composite(monitor)) {
 		writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
 		       &de_be->output_color_ctrl);
 		for (i = 0; i < 12; i++)
@@ -616,7 +626,8 @@ static void sunxi_lcdc_backlight_enable(void)
 		gpio_direction_output(pin, PWM_ON);
 }
 
-static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
+static void sunxi_lcdc_tcon0_mode_set(struct sunxi_display *sunxi_display,
+				      const struct ctfb_res_modes *mode,
 				      bool for_ext_vga_dac)
 {
 	struct sunxi_lcdc_reg * const lcdc =
@@ -643,17 +654,18 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
 	}
 
 	lcdc_pll_set(ccm, 0, mode->pixclock_khz, &clk_div, &clk_double,
-		     sunxi_is_composite());
+		     sunxi_is_composite(sunxi_display->monitor));
 
 	video_ctfb_mode_to_display_timing(mode, &timing);
 	lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
-			    sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
+			    sunxi_display->depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
 }
 
 #if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
 static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 				      int *clk_div, int *clk_double,
-				      bool use_portd_hvsync)
+				      bool use_portd_hvsync,
+				      enum sunxi_monitor monitor)
 {
 	struct sunxi_lcdc_reg * const lcdc =
 		(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
@@ -663,7 +675,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 
 	video_ctfb_mode_to_display_timing(mode, &timing);
 	lcdc_tcon1_mode_set(lcdc, &timing, use_portd_hvsync,
-			    sunxi_is_composite());
+			    sunxi_is_composite(monitor));
 
 	if (use_portd_hvsync) {
 		sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
@@ -671,7 +683,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
 	}
 
 	lcdc_pll_set(ccm, 1, mode->pixclock_khz, clk_div, clk_double,
-		     sunxi_is_composite());
+		     sunxi_is_composite(monitor));
 }
 #endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
 
@@ -725,7 +737,8 @@ static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode)
 }
 
 static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
-				int clk_div, int clk_double)
+				int clk_div, int clk_double,
+				enum sunxi_monitor monitor)
 {
 	struct sunxi_hdmi_reg * const hdmi =
 		(struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
@@ -734,7 +747,7 @@ static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
 	/* Write clear interrupt status bits */
 	writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
 
-	if (sunxi_display.monitor == sunxi_monitor_hdmi)
+	if (monitor == sunxi_monitor_hdmi)
 		sunxi_hdmi_setup_info_frames(mode);
 
 	/* Set input sync enable */
@@ -789,7 +802,7 @@ static void sunxi_hdmi_enable(void)
 
 #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
 
-static void sunxi_tvencoder_mode_set(void)
+static void sunxi_tvencoder_mode_set(enum sunxi_monitor monitor)
 {
 	struct sunxi_ccm_reg * const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
@@ -801,7 +814,7 @@ static void sunxi_tvencoder_mode_set(void)
 	/* Clock on */
 	setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
 
-	switch (sunxi_display.monitor) {
+	switch (monitor) {
 	case sunxi_monitor_vga:
 		tvencoder_mode_set(tve, tve_mode_vga);
 		break;
@@ -896,26 +909,28 @@ static void sunxi_engines_init(void)
 	sunxi_drc_init();
 }
 
-static void sunxi_mode_set(const struct ctfb_res_modes *mode,
+static void sunxi_mode_set(struct sunxi_display *sunxi_display,
+			   const struct ctfb_res_modes *mode,
 			   unsigned int address)
 {
+	enum sunxi_monitor monitor = sunxi_display->monitor;
 	int __maybe_unused clk_div, clk_double;
 	struct sunxi_lcdc_reg * const lcdc =
 		(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
 	struct sunxi_tve_reg * __maybe_unused const tve =
 		(struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
 
-	switch (sunxi_display.monitor) {
+	switch (sunxi_display->monitor) {
 	case sunxi_monitor_none:
 		break;
 	case sunxi_monitor_dvi:
 	case sunxi_monitor_hdmi:
 #ifdef CONFIG_VIDEO_HDMI
-		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
-		sunxi_hdmi_mode_set(mode, clk_div, clk_double);
+		sunxi_composer_mode_set(mode, address, monitor);
+		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0, monitor);
+		sunxi_hdmi_mode_set(mode, clk_div, clk_double, monitor);
 		sunxi_composer_enable();
-		lcdc_enable(lcdc, sunxi_display.depth);
+		lcdc_enable(lcdc, sunxi_display->depth);
 		sunxi_hdmi_enable();
 #endif
 		break;
@@ -930,7 +945,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 			axp_set_eldo(3, 1800);
 			anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
 				     ANX9804_DATA_RATE_1620M,
-				     sunxi_display.depth);
+				     sunxi_display->depth);
 		}
 		if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
 			mdelay(50); /* Wait for lcd controller power on */
@@ -942,10 +957,10 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 			i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
 			i2c_set_bus_num(orig_i2c_bus);
 		}
-		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon0_mode_set(mode, false);
+		sunxi_composer_mode_set(mode, address, monitor);
+		sunxi_lcdc_tcon0_mode_set(sunxi_display, mode, false);
 		sunxi_composer_enable();
-		lcdc_enable(lcdc, sunxi_display.depth);
+		lcdc_enable(lcdc, sunxi_display->depth);
 #ifdef CONFIG_VIDEO_LCD_SSD2828
 		sunxi_ssd2828_init(mode);
 #endif
@@ -953,17 +968,17 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 		break;
 	case sunxi_monitor_vga:
 #ifdef CONFIG_VIDEO_VGA
-		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
-		sunxi_tvencoder_mode_set();
+		sunxi_composer_mode_set(mode, address, monitor);
+		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1, monitor);
+		sunxi_tvencoder_mode_set(monitor);
 		sunxi_composer_enable();
-		lcdc_enable(lcdc, sunxi_display.depth);
+		lcdc_enable(lcdc, sunxi_display->depth);
 		tvencoder_enable(tve);
 #elif defined CONFIG_VIDEO_VGA_VIA_LCD
-		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon0_mode_set(mode, true);
+		sunxi_composer_mode_set(mode, address, monitor);
+		sunxi_lcdc_tcon0_mode_set(sunxi_display, mode, true);
 		sunxi_composer_enable();
-		lcdc_enable(lcdc, sunxi_display.depth);
+		lcdc_enable(lcdc, sunxi_display->depth);
 		sunxi_vga_external_dac_enable();
 #endif
 		break;
@@ -972,11 +987,11 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
 	case sunxi_monitor_composite_pal_m:
 	case sunxi_monitor_composite_pal_nc:
 #ifdef CONFIG_VIDEO_COMPOSITE
-		sunxi_composer_mode_set(mode, address);
-		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
-		sunxi_tvencoder_mode_set();
+		sunxi_composer_mode_set(mode, address, monitor);
+		sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0, monitor);
+		sunxi_tvencoder_mode_set(monitor);
 		sunxi_composer_enable();
-		lcdc_enable(lcdc, sunxi_display.depth);
+		lcdc_enable(lcdc, sunxi_display->depth);
 		tvencoder_enable(tve);
 #endif
 		break;
@@ -999,11 +1014,6 @@ static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
 	}
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
-{
-	return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
-}
-
 static bool sunxi_has_hdmi(void)
 {
 #ifdef CONFIG_VIDEO_HDMI
@@ -1052,9 +1062,11 @@ static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
 		return sunxi_monitor_none;
 }
 
-void *video_hw_init(void)
+static int sunxi_de_probe(struct udevice *dev)
 {
-	static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+	struct sunxi_display *sunxi_display = dev_get_priv(dev);
 	const struct ctfb_res_modes *mode;
 	struct ctfb_res_modes custom;
 	const char *options;
@@ -1067,10 +1079,8 @@ void *video_hw_init(void)
 	char mon[16];
 	char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
 
-	memset(&sunxi_display, 0, sizeof(struct sunxi_display));
-
 	video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
-				 &sunxi_display.depth, &options);
+				 &sunxi_display->depth, &options);
 #ifdef CONFIG_VIDEO_HDMI
 	hpd = video_get_option_int(options, "hpd", 1);
 	hpd_delay = video_get_option_int(options, "hpd_delay", 500);
@@ -1078,35 +1088,35 @@ void *video_hw_init(void)
 #endif
 	overscan_x = video_get_option_int(options, "overscan_x", -1);
 	overscan_y = video_get_option_int(options, "overscan_y", -1);
-	sunxi_display.monitor = sunxi_get_default_mon(true);
+	sunxi_display->monitor = sunxi_get_default_mon(true);
 	video_get_option_string(options, "monitor", mon, sizeof(mon),
-				sunxi_get_mon_desc(sunxi_display.monitor));
+				sunxi_get_mon_desc(sunxi_display->monitor));
 	for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
 		if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) {
-			sunxi_display.monitor = i;
+			sunxi_display->monitor = i;
 			break;
 		}
 	}
 	if (i > SUNXI_MONITOR_LAST)
 		printf("Unknown monitor: '%s', falling back to '%s'\n",
-		       mon, sunxi_get_mon_desc(sunxi_display.monitor));
+		       mon, sunxi_get_mon_desc(sunxi_display->monitor));
 
 #ifdef CONFIG_VIDEO_HDMI
 	/* If HDMI/DVI is selected do HPD & EDID, and handle fallback */
-	if (sunxi_display.monitor == sunxi_monitor_dvi ||
-	    sunxi_display.monitor == sunxi_monitor_hdmi) {
+	if (sunxi_display->monitor == sunxi_monitor_dvi ||
+	    sunxi_display->monitor == sunxi_monitor_hdmi) {
 		/* Always call hdp_detect, as it also enables clocks, etc. */
 		hdmi_present = (sunxi_hdmi_hpd_detect(hpd_delay) == 1);
 		if (hdmi_present && edid) {
 			printf("HDMI connected: ");
-			if (sunxi_hdmi_edid_get_mode(&custom, true) == 0)
+			if (sunxi_hdmi_edid_get_mode(sunxi_display, &custom, true) == 0)
 				mode = &custom;
 			else
 				hdmi_present = false;
 		}
 		/* Fall back to EDID in case HPD failed */
 		if (edid && !hdmi_present) {
-			if (sunxi_hdmi_edid_get_mode(&custom, false) == 0) {
+			if (sunxi_hdmi_edid_get_mode(sunxi_display, &custom, false) == 0) {
 				mode = &custom;
 				hdmi_present = true;
 			}
@@ -1114,38 +1124,39 @@ void *video_hw_init(void)
 		/* Shut down when display was not found */
 		if ((hpd || edid) && !hdmi_present) {
 			sunxi_hdmi_shutdown();
-			sunxi_display.monitor = sunxi_get_default_mon(false);
+			sunxi_display->monitor = sunxi_get_default_mon(false);
 		} /* else continue with hdmi/dvi without a cable connected */
 	}
 #endif
 
-	switch (sunxi_display.monitor) {
+	switch (sunxi_display->monitor) {
 	case sunxi_monitor_none:
-		return NULL;
+		printf("Unknown monitor\n");
+		return -EINVAL;
 	case sunxi_monitor_dvi:
 	case sunxi_monitor_hdmi:
 		if (!sunxi_has_hdmi()) {
 			printf("HDMI/DVI not supported on this board\n");
-			sunxi_display.monitor = sunxi_monitor_none;
-			return NULL;
+			sunxi_display->monitor = sunxi_monitor_none;
+			return -EINVAL;
 		}
 		break;
 	case sunxi_monitor_lcd:
 		if (!sunxi_has_lcd()) {
 			printf("LCD not supported on this board\n");
-			sunxi_display.monitor = sunxi_monitor_none;
-			return NULL;
+			sunxi_display->monitor = sunxi_monitor_none;
+			return -EINVAL;
 		}
-		sunxi_display.depth = video_get_params(&custom, lcd_mode);
+		sunxi_display->depth = video_get_params(&custom, lcd_mode);
 		mode = &custom;
 		break;
 	case sunxi_monitor_vga:
 		if (!sunxi_has_vga()) {
 			printf("VGA not supported on this board\n");
-			sunxi_display.monitor = sunxi_monitor_none;
-			return NULL;
+			sunxi_display->monitor = sunxi_monitor_none;
+			return -EINVAL;
 		}
-		sunxi_display.depth = 18;
+		sunxi_display->depth = 18;
 		break;
 	case sunxi_monitor_composite_pal:
 	case sunxi_monitor_composite_ntsc:
@@ -1153,85 +1164,103 @@ void *video_hw_init(void)
 	case sunxi_monitor_composite_pal_nc:
 		if (!sunxi_has_composite()) {
 			printf("Composite video not supported on this board\n");
-			sunxi_display.monitor = sunxi_monitor_none;
-			return NULL;
+			sunxi_display->monitor = sunxi_monitor_none;
+			return -EINVAL;
 		}
-		if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
-		    sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
+		if (sunxi_display->monitor == sunxi_monitor_composite_pal ||
+		    sunxi_display->monitor == sunxi_monitor_composite_pal_nc)
 			mode = &composite_video_modes[0];
 		else
 			mode = &composite_video_modes[1];
-		sunxi_display.depth = 24;
+		sunxi_display->depth = 24;
 		break;
 	}
 
 	/* Yes these defaults are quite high, overscan on composite sucks... */
 	if (overscan_x == -1)
-		overscan_x = sunxi_is_composite() ? 32 : 0;
+		overscan_x = sunxi_is_composite(sunxi_display->monitor) ? 32 : 0;
 	if (overscan_y == -1)
-		overscan_y = sunxi_is_composite() ? 20 : 0;
+		overscan_y = sunxi_is_composite(sunxi_display->monitor) ? 20 : 0;
 
-	sunxi_display.fb_size =
-		(mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
+	sunxi_display->fb_size = plat->size;
 	overscan_offset = (overscan_y * mode->xres + overscan_x) * 4;
 	/* We want to keep the fb_base for simplefb page aligned, where as
 	 * the sunxi dma engines will happily accept an unaligned address. */
 	if (overscan_offset)
-		sunxi_display.fb_size += 0x1000;
-
-	if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
-		printf("Error need %dkB for fb, but only %dkB is reserved\n",
-		       sunxi_display.fb_size >> 10,
-		       CONFIG_SUNXI_MAX_FB_SIZE >> 10);
-		return NULL;
-	}
+		sunxi_display->fb_size += 0x1000;
 
 	printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n",
 	       mode->xres, mode->yres,
 	       (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
-	       sunxi_get_mon_desc(sunxi_display.monitor),
+	       sunxi_get_mon_desc(sunxi_display->monitor),
 	       overscan_x, overscan_y);
 
-	gd->fb_base = gd->bd->bi_dram[0].start +
-		      gd->bd->bi_dram[0].size - sunxi_display.fb_size;
+	sunxi_display->fb_addr = plat->base;
 	sunxi_engines_init();
 
 #ifdef CONFIG_EFI_LOADER
-	efi_add_memory_map(gd->fb_base, sunxi_display.fb_size,
+	efi_add_memory_map(sunxi_display->fb_addr, sunxi_display->fb_size,
 			   EFI_RESERVED_MEMORY_TYPE);
 #endif
 
-	fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE;
-	sunxi_display.fb_addr = gd->fb_base;
+	fb_dma_addr = sunxi_display->fb_addr - CONFIG_SYS_SDRAM_BASE;
 	if (overscan_offset) {
 		fb_dma_addr += 0x1000 - (overscan_offset & 0xfff);
-		sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff;
-		memset((void *)gd->fb_base, 0, sunxi_display.fb_size);
-		flush_cache(gd->fb_base, sunxi_display.fb_size);
+		sunxi_display->fb_addr += (overscan_offset + 0xfff) & ~0xfff;
+		memset((void *)sunxi_display->fb_addr, 0, sunxi_display->fb_size);
+		flush_cache(sunxi_display->fb_addr, sunxi_display->fb_size);
 	}
-	sunxi_mode_set(mode, fb_dma_addr);
+	sunxi_mode_set(sunxi_display, mode, fb_dma_addr);
 
 	/*
 	 * These are the only members of this structure that are used. All the
 	 * others are driver specific. The pitch is stored in plnSizeX.
 	 */
-	graphic_device->frameAdrs = sunxi_display.fb_addr;
-	graphic_device->gdfIndex = GDF_32BIT_X888RGB;
-	graphic_device->gdfBytesPP = 4;
-	graphic_device->winSizeX = mode->xres - 2 * overscan_x;
-	graphic_device->winSizeY = mode->yres - 2 * overscan_y;
-	graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP;
-
-	return graphic_device;
+	uc_priv->bpix = VIDEO_BPP32;
+	uc_priv->xsize = mode->xres;
+	uc_priv->ysize = mode->yres;
+
+	video_set_flush_dcache(dev, 1);
+
+	return 0;
 }
 
+static int sunxi_de_bind(struct udevice *dev)
+{
+	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+
+	plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
+		     (1 << LCD_MAX_LOG2_BPP) / 8;
+
+	return 0;
+}
+
+static const struct video_ops sunxi_de_ops = {
+};
+
+U_BOOT_DRIVER(sunxi_de) = {
+	.name	= "sunxi_de",
+	.id	= UCLASS_VIDEO,
+	.ops	= &sunxi_de_ops,
+	.bind	= sunxi_de_bind,
+	.probe	= sunxi_de_probe,
+	.priv_auto = sizeof(struct sunxi_display),
+	.flags	= DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRVINFO(sunxi_de) = {
+	.name = "sunxi_de"
+};
+
 /*
  * Simplefb support.
  */
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
 int sunxi_simplefb_setup(void *blob)
 {
-	static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
+	struct sunxi_display *sunxi_display;
+	struct video_priv *uc_priv;
+	struct udevice *de;
 	int offset, ret;
 	u64 start, size;
 	const char *pipeline = NULL;
@@ -1242,7 +1271,19 @@ int sunxi_simplefb_setup(void *blob)
 #define PIPELINE_PREFIX
 #endif
 
-	switch (sunxi_display.monitor) {
+	ret = uclass_find_device_by_name(UCLASS_VIDEO, "sunxi_de", &de);
+	if (ret) {
+		printf("DE not present\n");
+		return 0;
+	} else if (!device_active(de)) {
+		printf("DE is present but not probed\n");
+		return 0;
+	}
+
+	uc_priv = dev_get_uclass_priv(de);
+	sunxi_display = dev_get_priv(de);
+
+	switch (sunxi_display->monitor) {
 	case sunxi_monitor_none:
 		return 0;
 	case sunxi_monitor_dvi:
@@ -1280,16 +1321,17 @@ int sunxi_simplefb_setup(void *blob)
 	 * linux/arch/arm/mm/ioremap.c around line 301.
 	 */
 	start = gd->bd->bi_dram[0].start;
-	size = gd->bd->bi_dram[0].size - sunxi_display.fb_size;
+	size = sunxi_display->fb_addr - 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, sunxi_display.fb_addr,
-			graphic_device->winSizeX, graphic_device->winSizeY,
-			graphic_device->plnSizeX, "x8r8g8b8");
+	ret = fdt_setup_simplefb_node(blob, offset, sunxi_display->fb_addr,
+				      uc_priv->xsize, uc_priv->ysize,
+				      VNBYTES(uc_priv->bpix) * uc_priv->xsize,
+				      "x8r8g8b8");
 	if (ret)
 		eprintf("Cannot setup simplefb: Error setting properties\n");
 
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 000f3864702..97661329ba4 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -256,23 +256,6 @@ extern int soft_i2c_gpio_scl;
 #endif
 #endif /* ifdef CONFIG_REQUIRE_SERIAL_CONSOLE */
 
-#ifdef CONFIG_VIDEO_SUNXI
-/*
- * The amount of RAM to keep free at the top of RAM when relocating u-boot,
- * to use as framebuffer. This must be a multiple of 4096.
- */
-#define CONFIG_SUNXI_MAX_FB_SIZE (16 << 20)
-
-#define CONFIG_VIDEO_LOGO
-#define CONFIG_VIDEO_STD_TIMINGS
-#define CONFIG_I2C_EDID
-#define VIDEO_LINE_LEN (pGD->plnSizeX)
-
-/* allow both serial and cfb console. */
-/* stop x86 thinking in cfbconsole from trying to init a pc keyboard */
-
-#endif /* CONFIG_VIDEO_SUNXI */
-
 /* Ethernet support */
 
 #ifdef CONFIG_USB_EHCI_HCD
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index c6a83124956..ed469f74034 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1661,7 +1661,6 @@ CONFIG_STV0991
 CONFIG_STV0991_HZ
 CONFIG_STV0991_HZ_CLOCK
 CONFIG_ST_SMI
-CONFIG_SUNXI_MAX_FB_SIZE
 CONFIG_SXNI855T
 CONFIG_SYSFLAGS_ADDR
 CONFIG_SYSFS
-- 
2.17.5

             reply	other threads:[~2021-02-05  1:07 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-05  1:07 Andre Przywara [this message]
2021-02-05 16:04 ` [PATCH v3] video: sunxi_display: Convert to DM_VIDEO Maxime Ripard
2021-02-05 16:27 ` Jernej Škrabec
2021-02-05 19:31   ` Andre Przywara
2021-02-07 14:37 ` Simon Glass
2021-02-08  1:36   ` Andre Przywara
2021-02-08  4:21     ` Simon Glass
2021-02-21  0:07   ` Andre Przywara
2021-02-21  0:45     ` Tom Rini
2021-02-21 16:47       ` Anatolij Gustschin
2021-02-22  0:17         ` Andre Przywara
2021-02-22  7:37           ` Anatolij Gustschin
2021-02-21 16:24     ` Simon Glass
2021-02-22  9:02       ` Maxime Ripard
2021-02-22  8:59     ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210205010748.2646-1-andre.przywara@arm.com \
    --to=andre.przywara@arm.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.