board: w400: Add thor progress bar
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Thu, 26 Nov 2020 19:55:47 +0000 (20:55 +0100)
committerSylwester Nawrocki <s.nawrocki@samsung.com>
Tue, 1 Dec 2020 09:10:44 +0000 (10:10 +0100)
On thor connection a text notification is shown on the video console
and then graphic progress bar is drawn notifying about thor flashing
progress.

Based on patch from tizen-tm4 u-boot tree
 "bbdd221168b5 enable simple THOR download progress display"
 Author: Marek Szyprowski <m.szyprowski@samsung.com>

Change-Id: Iba4945ae26358936de1e1847d0095f97e6ab3498
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
board/amlogic/w400/w400.c

index 1636415503fa4705e78ba77672b689e6907a078c..d8a04b9d5fd38b3dab06bd56a88bb9c8586dda76 100644 (file)
@@ -9,6 +9,9 @@
 #include <env_internal.h>
 #include <init.h>
 #include <net.h>
+#include <thor.h>
+#include <video.h>
+#include <video_console.h>
 #include <asm/io.h>
 #include <asm/arch/boot.h>
 #include <asm/arch/eth.h>
@@ -21,9 +24,87 @@ int mmc_get_env_dev(void)
        return 0;
 }
 
+#define PROGRESS_BAR_COLOR     0x00901000
+#define PROGRESS_FRAME_COLOR   0x00909090
+
+static struct udevice *vidcon_dev;
+
+static inline void pixel(struct video_priv *vid_priv, int x, int y,
+                        unsigned int colour)
+{
+       u32 *screen = vid_priv->fb;
+       screen[y * vid_priv->xsize + x] = colour;
+}
+
+static void draw_thor_progress(unsigned int progress_value)
+{
+       struct udevice *vid_dev = vidcon_dev->parent;
+       struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
+       static int xpos, ypos, bar_width, bar_height;
+       int x, y;
+
+       if (bar_width == 0) {
+               xpos = vid_priv->ysize / 8;
+               ypos = vid_priv->ysize * 7 / 8;
+               bar_width = vid_priv->xsize - 2 * xpos;
+               bar_height = vid_priv->ysize * 4 / 128;
+       }
+
+       if (progress_value > 100)
+               progress_value = 100;
+
+       for (y = ypos; y <= ypos + bar_height; y++) {
+               pixel(vid_priv, xpos, y, PROGRESS_FRAME_COLOR);
+               pixel(vid_priv, xpos + bar_width, y, PROGRESS_FRAME_COLOR);
+       }
+
+       for (x = xpos; x - xpos < bar_width; x++) {
+               pixel(vid_priv, x, ypos, PROGRESS_FRAME_COLOR);
+               pixel(vid_priv, x, ypos + bar_height, PROGRESS_FRAME_COLOR);
+       }
+
+       for (y = ypos + 1; y < ypos + bar_height; y++)
+               for (x = 1; x < (bar_width * progress_value / 100); x++)
+                       pixel(vid_priv, x + xpos, y, PROGRESS_BAR_COLOR);
+
+       video_sync(vid_dev, false);
+}
+
+static void thor_notify(enum thor_notify_type type, unsigned long long int arg0,
+                       unsigned long long int arg1)
+{
+       static const char *thor_conn_text = "\x1b[2,5f\x1b[31m THOR MODE" \
+               "\x1b[4,5f\x1b[31m WARNING: Do not power off the device\33[0m\n";
+       unsigned int total_size, current_size;
+
+       switch (type) {
+       case THOR_NOTIFY_CONNECTED:
+               vidconsole_put_string(vidcon_dev, thor_conn_text);
+               break;
+
+       case THOR_NOTIFY_PROGRESS:
+               /* Shift to prevent int overflow */
+               total_size = arg0 >> 6;
+               current_size = arg1 >> 6;
+               if (total_size)
+                       draw_thor_progress(current_size * 100 / total_size);
+               break;
+       default:
+               break;
+       }
+}
+
 int misc_init_r(void)
 {
+       int ret;
+
        meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
 
+       ret = uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &vidcon_dev);
+       if (ret)
+               return ret;
+
+       thor_register_notifier(thor_notify);
+
        return 0;
 }