Nico Huber has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/39864 )
Change subject: [RFC] udelay: Relax clock_gettime() resolution expectations ......................................................................
[RFC] udelay: Relax clock_gettime() resolution expectations
Only few programmers actually want to delay by a single microsecond. So we can relax the expected mininum resolution by default and let indivi- dual programmers override as needed.
UNTESTED
Change-Id: Ia24f5c8440b7cb8abcc5a1509443d0c41fd2c559 Signed-off-by: Nico Huber nico.h@gmx.de --- M bitbang_spi.c M cli_classic.c M nicintel_eeprom.c M udelay.c 4 files changed, 15 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/64/39864/1
diff --git a/bitbang_spi.c b/bitbang_spi.c index 7c183c3..8e5b8f2 100644 --- a/bitbang_spi.c +++ b/bitbang_spi.c @@ -104,6 +104,8 @@ mst.data = master; register_spi_master(&mst);
+ myusec_calibrate_delay(100); + /* Only mess with the bus if we're sure nobody else uses it. */ bitbang_spi_request_bus(master); bitbang_spi_set_cs(master, 1); diff --git a/cli_classic.c b/cli_classic.c index 73cc417..2436351 100644 --- a/cli_classic.c +++ b/cli_classic.c @@ -454,7 +454,7 @@ }
/* FIXME: Delay calibration should happen in programmer code. */ - myusec_calibrate_delay(); + myusec_calibrate_delay(1000);
if (programmer_init(prog, pparam)) { msg_perr("Error: Programmer initialization failed.\n"); diff --git a/nicintel_eeprom.c b/nicintel_eeprom.c index 4d45f79..06284d4 100644 --- a/nicintel_eeprom.c +++ b/nicintel_eeprom.c @@ -449,6 +449,8 @@
int nicintel_ee_init(void) { + myusec_calibrate_delay(100); + if (rget_io_perms()) return 1;
diff --git a/udelay.c b/udelay.c index 6c0efc4..3f0b6d1 100644 --- a/udelay.c +++ b/udelay.c @@ -52,11 +52,11 @@ } while (now.tv_sec < end.tv_sec || (now.tv_sec == end.tv_sec && now.tv_nsec < end.tv_nsec)); }
-static int clock_check_res(void) +static int clock_check_res(const unsigned int resolution_ns) { struct timespec res; if (!clock_getres(clock_id, &res)) { - if (res.tv_sec == 0 && res.tv_nsec <= 100) { + if (res.tv_sec == 0 && res.tv_nsec <= resolution_ns) { msg_pinfo("Using clock_gettime for delay loops (clk_id: %d, resolution: %ldns).\n", (int)clock_id, res.tv_nsec); use_clock_gettime = true; @@ -65,7 +65,7 @@ } else if (clock_id != CLOCK_REALTIME && errno == EINVAL) { /* Try again with CLOCK_REALTIME. */ clock_id = CLOCK_REALTIME; - return clock_check_res(); + return clock_check_res(resolution_ns); } return 0; } @@ -77,7 +77,7 @@ #endif /* HAVE_CLOCK_GETTIME == 1 */
/* loops per microsecond */ -static unsigned long micro = 1; +static unsigned long micro;
__attribute__ ((noinline)) void myusec_delay(unsigned int usecs) { @@ -133,15 +133,19 @@ return timeusec; }
-void myusec_calibrate_delay(void) +void myusec_calibrate_delay(const unsigned int resolution_ns) { - if (clock_check_res()) + if (clock_check_res(resolution_ns)) return;
+ if (micro) + return; /* already calibrated */ + unsigned long count = 1000; unsigned long timeusec, resolution; int i, tries = 0;
+ micro = 1; msg_pinfo("Calibrating delay loop... "); resolution = measure_os_delay_resolution(); if (resolution) {