soc/intel/apollolake: Implement reset_prepare()

At first boot CSE spends long time preparing media for use. As result
it may not be able to deal with a CPU reset. Add reset_prepare()
callback that polls CSE readiness.

BUG=chrome-os-partner:55055
TEST=build with release version of fsp, reboot, observe polling for
CSE, then proper reboot happening

Change-Id: I639ef900b97132f1a7f269bb864d70009df9fdfe
Signed-off-by: Andrey Petrov <andrey.petrov@intel.com>
Reviewed-on: https://review.coreboot.org/15721
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Andrey Petrov 2016-07-15 14:44:48 -07:00 committed by Aaron Durbin
parent 6401188024
commit 91ef21df62
1 changed files with 36 additions and 0 deletions

View File

@ -13,11 +13,47 @@
* GNU General Public License for more details.
*/
#include <console/console.h>
#include <delay.h>
#include <reset.h>
#include <soc/heci.h>
#include <soc/pm.h>
#include <timer.h>
#define CSE_WAIT_MAX_MS 1000
void global_reset(void)
{
global_reset_enable(1);
hard_reset();
}
void reset_prepare(void)
{
struct stopwatch sw;
/*
* If CSE state is something else than 'normal', it is probably in some
* recovery state. In this case there is no point in waiting for it to
* get ready so we cross fingers and reset.
*/
if (!heci_cse_normal()) {
printk(BIOS_DEBUG, "CSE is not in normal state, resetting\n");
return;
}
/* Reset if CSE is ready */
if (heci_cse_done())
return;
printk(BIOS_SPEW, "CSE is not yet ready, waiting\n");
stopwatch_init_msecs_expire(&sw, CSE_WAIT_MAX_MS);
while (!heci_cse_done()) {
if (stopwatch_expired(&sw)) {
printk(BIOS_SPEW, "CSE timed out. Resetting\n");
return;
}
mdelay(1);
}
printk(BIOS_SPEW, "CSE took %lu ms\n", stopwatch_duration_msecs(&sw));
}