sandbox: sdl: Add an option to double the screen size

On high-DPI displays U-Boot's LCD window can look very small. Add a
-K flag to expand it to make things easier to read, while still using
the existing resolution internally.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index 58a9cc8..6416cab 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -30,6 +30,8 @@
  *
  * @width: Width of simulated LCD display
  * @height: Height of simulated LCD display
+ * @vis_width: Visible width (may be larger to allow for scaling up)
+ * @vis_height: Visible height (may be larger to allow for scaling up)
  * @depth: Depth of the display in bits per pixel (16 or 32)
  * @pitch: Number of bytes per line of the display
  * @sample_rate: Current sample rate for audio
@@ -46,6 +48,8 @@
 static struct sdl_info {
 	int width;
 	int height;
+	int vis_width;
+	int vis_height;
 	int depth;
 	int pitch;
 	uint sample_rate;
@@ -94,7 +98,8 @@
 	return 0;
 }
 
-int sandbox_sdl_init_display(int width, int height, int log2_bpp)
+int sandbox_sdl_init_display(int width, int height, int log2_bpp,
+			     bool double_size)
 {
 	struct sandbox_state *state = state_get_current();
 	int err;
@@ -110,11 +115,19 @@
 	}
 	sdl.width = width;
 	sdl.height = height;
+	if (double_size) {
+		sdl.vis_width = sdl.width * 2;
+		sdl.vis_height = sdl.height * 2;
+	} else {
+		sdl.vis_width = sdl.width;
+		sdl.vis_height = sdl.height;
+	}
+
 	sdl.depth = 1 << log2_bpp;
 	sdl.pitch = sdl.width * sdl.depth / 8;
 	SDL_Window *screen = SDL_CreateWindow("U-Boot", SDL_WINDOWPOS_UNDEFINED,
 					      SDL_WINDOWPOS_UNDEFINED,
-					      sdl.width, sdl.height, 0);
+					      sdl.vis_width, sdl.vis_height, 0);
 	if (!screen) {
 		printf("Unable to initialise SDL screen: %s\n",
 		       SDL_GetError());
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 4760731..b6ff5c3 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -308,6 +308,16 @@
 SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0,
 			  "Show the sandbox LCD display");
 
+static int sandbox_cmdline_cb_double_lcd(struct sandbox_state *state,
+					 const char *arg)
+{
+	state->double_lcd = true;
+
+	return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(double_lcd, 'K', 0,
+			  "Double the LCD display size in each direction");
+
 static const char *term_args[STATE_TERM_COUNT] = {
 	"raw-with-sigs",
 	"raw",
diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h
index c45dbdd..47fc488 100644
--- a/arch/sandbox/include/asm/sdl.h
+++ b/arch/sandbox/include/asm/sdl.h
@@ -17,10 +17,13 @@
  * @height	Window height in pixels
  * @log2_bpp:	Log to base 2 of the number of bits per pixel. So a 32bpp
  *		display will pass 5, since 2*5 = 32
+ * @double_size: true to double the visible size in each direction for high-DPI
+ *		displays
  * @return 0 if OK, -ENODEV if no device, -EIO if SDL failed to initialize
  *		and -EPERM if the video failed to come up.
  */
-int sandbox_sdl_init_display(int width, int height, int log2_bpp);
+int sandbox_sdl_init_display(int width, int height, int log2_bpp,
+			     bool double_size);
 
 /**
  * sandbox_sdl_sync() - Sync current U-Boot LCD frame buffer to SDL
@@ -78,8 +81,8 @@
 int sandbox_sdl_sound_init(int rate, int channels);
 
 #else
-static inline int sandbox_sdl_init_display(int width, int height,
-					    int log2_bpp)
+static inline int sandbox_sdl_init_display(int width, int height, int log2_bpp,
+					   bool double_size)
 {
 	return -ENODEV;
 }
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index ad3e94b..705645d 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -83,6 +83,7 @@
 	bool write_state;		/* Write sandbox state on exit */
 	bool ignore_missing_state_on_read;	/* No error if state missing */
 	bool show_lcd;			/* Show LCD on start-up */
+	bool double_lcd;		/* Double display size for high-DPI */
 	enum sysreset_t last_sysreset;	/* Last system reset type */
 	bool sysreset_allowed[SYSRESET_COUNT];	/* Allowed system reset types */
 	enum state_terminal_raw term_raw;	/* Terminal raw/cooked */
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index 913651c..d1272d0 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -8,6 +8,7 @@
 #include <fdtdec.h>
 #include <video.h>
 #include <asm/sdl.h>
+#include <asm/state.h>
 #include <asm/u-boot-sandbox.h>
 #include <dm/test.h>
 
@@ -23,9 +24,11 @@
 {
 	struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
 	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct sandbox_state *state = state_get_current();
 	int ret;
 
-	ret = sandbox_sdl_init_display(plat->xres, plat->yres, plat->bpix);
+	ret = sandbox_sdl_init_display(plat->xres, plat->yres, plat->bpix,
+				       state->double_lcd);
 	if (ret) {
 		puts("LCD init failed\n");
 		return ret;