firmware/lib/ec_sync_all: Refactor the EC SW Sync flow

Perform all the operations regarding EC AUX FW update once the EC update
is applied and EC has jumped to the updated image. This way the
information regarding the devices that require EC AUX FW update can be
probed and obtained from EC consistently.

BUG=b:128820536,b:119046668
BRANCH=None
TEST=Ensure that the device boots to ChromeOS. Ensure that the Aux FW
update is handled after EC update is applied and jumped to the updated
EC image.

Casta:
sync_one_ec: jumping to EC-RW
send_packet: CrosEC result code 12
EC returned from reboot after 53061us
ps8751.0: vendor 0x1da0 product 0x8751 device 0x0001 fw_rev 0x39
ps8751.1: vendor 0x1da0 product 0x8751 device 0x0001 fw_rev 0x39

Bobba:
sync_one_ec: jumping to EC-RW
send_packet: CrosEC result code 12
EC returned from reboot after 52271us
ps8751.1: vendor 0x1da0 product 0x8751 device 0x0001 fw_rev 0x39

Ampton:
sync_one_ec: jumping to EC-RW
EC returned from reboot after 43019us
vb2_developer_ui: Entering
vboot_draw_screen: screen=0x101 locale=0

Change-Id: I28956543dfe1e059e15212dceada8bc517c0e7fc
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1592472
Commit-Ready: Karthikeyan Ramasubramanian <kramasub@chromium.org>
Tested-by: Karthikeyan Ramasubramanian <kramasub@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
diff --git a/firmware/lib/ec_sync_all.c b/firmware/lib/ec_sync_all.c
index fca9f9b..b250677 100644
--- a/firmware/lib/ec_sync_all.c
+++ b/firmware/lib/ec_sync_all.c
@@ -37,45 +37,49 @@
 	return VBERROR_SUCCESS;
 }
 
+static int check_reboot_for_display(struct vb2_context *ctx,
+					struct vb2_shared_data *sd)
+{
+	if (!(sd->flags & VB2_SD_FLAG_DISPLAY_AVAILABLE)) {
+		VB2_DEBUG("Reboot to initialize display\n");
+		vb2_nv_set(ctx, VB2_NV_DISPLAY_REQUEST, 1);
+		return 1;
+	}
+	return 0;
+}
+
+static void display_wait_screen(struct vb2_context *ctx, const char *fw_name)
+{
+	VB2_DEBUG("%s update is slow. Show WAIT screen.\n", fw_name);
+	VbDisplayScreen(ctx, VB_SCREEN_WAIT, 0, NULL);
+}
+
 VbError_t ec_sync_all(struct vb2_context *ctx)
 {
 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
-	VbAuxFwUpdateSeverity_t fw_update;
+	VbAuxFwUpdateSeverity_t fw_update = VB_AUX_FW_NO_UPDATE;
 	VbError_t rv;
 
-	rv = ec_sync_check_aux_fw(ctx, &fw_update);
-	if (rv)
-		return rv;
-
 	/* Phase 1; this determines if we need an update */
 	VbError_t phase1_rv = ec_sync_phase1(ctx);
-	int need_wait_screen = ec_will_update_slowly(ctx) ||
-		(fw_update == VB_AUX_FW_SLOW_UPDATE);
+	int need_wait_screen = ec_will_update_slowly(ctx);
 
-	/*
-	 * Check if we need to reboot to initialize the display before we can
-	 * display the WAIT screen.
-	 *
-	 * Do this before we check if ec_sync_phase1() requires a reboot for
-	 * some other reason, since there's no reason to reboot twice.
-	 */
-	int reboot_for_display = (need_wait_screen &&
-				  !(sd->flags & VB2_SD_FLAG_DISPLAY_AVAILABLE));
-	if (reboot_for_display) {
-		VB2_DEBUG("Reboot to initialize display\n");
-		vb2_nv_set(ctx, VB2_NV_DISPLAY_REQUEST, 1);
+	/* Check if EC SW Sync Phase1 needs reboot */
+	if (phase1_rv) {
+		ec_sync_check_aux_fw(ctx, &fw_update);
+		/* It does -- speculatively check if we need display as well */
+		if (need_wait_screen || fw_update == VB_AUX_FW_SLOW_UPDATE)
+			check_reboot_for_display(ctx, sd);
+		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
 	}
 
-	/* Reboot if phase 1 needed it, or if we need to initialize display */
-	if (phase1_rv)
-		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
-	if (reboot_for_display)
-		return VBERROR_REBOOT_REQUIRED;
-
-	/* Display the wait screen if we need it */
+	/* Is EC already in RO and needs slow update? */
 	if (need_wait_screen) {
-		VB2_DEBUG("EC is slow. Show WAIT screen.\n");
-		VbDisplayScreen(ctx, VB_SCREEN_WAIT, 0, NULL);
+		/* Might still need display in that case */
+		if (check_reboot_for_display(ctx, sd))
+			return VBERROR_REBOOT_REQUIRED;
+		/* Display is available, so pop up the wait screen */
+		display_wait_screen(ctx, "EC FW");
 	}
 
 	/* Phase 2; Applies update and/or jumps to the correct EC image */
@@ -83,6 +87,20 @@
 	if (rv)
 		return rv;
 
+	/* EC in RW, now we can check the severity of the AUX FW update */
+	rv = ec_sync_check_aux_fw(ctx, &fw_update);
+	if (rv)
+		return rv;
+
+	/* If AUX FW update is slow display the wait screen */
+	if (fw_update == VB_AUX_FW_SLOW_UPDATE) {
+		need_wait_screen = 1;
+		/* Display should be available, but better check again */
+		if (check_reboot_for_display(ctx, sd))
+			return VBERROR_REBOOT_REQUIRED;
+		display_wait_screen(ctx, "AUX FW");
+	}
+
 	/*
 	 * Do Aux FW software sync and protect devices tunneled through the EC.
 	 * Aux FW update may request RO reboot to force EC cold reset so also