Hello Patrick Rudolph, Jonathan Zhang, Johnny Lin, Rocky Phagura, Morgan Jang,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/43005
to look at the new patch set (#8).
Change subject: mb/ocp/deltalake: Send OEM IPMI command for CMOS clear on RTC failure
......................................................................
mb/ocp/deltalake: Send OEM IPMI command for CMOS clear on RTC failure
When RTC failure is detected, send IPMI OEM command to issue CMOS clear.
This is to let the payload (LinuxBoot) do some handling.
Tested on OCP Delta Lake
Signed-off-by: Jingle Hsu <jingle_hsu(a)wiwynn.com>
Change-Id: I27428c02e99040754e15e07782ec1ad8524def2f
---
M src/mainboard/ocp/deltalake/ipmi.c
M src/mainboard/ocp/deltalake/ipmi.h
M src/mainboard/ocp/deltalake/romstage.c
3 files changed, 73 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/05/43005/8
--
To view, visit https://review.coreboot.org/c/coreboot/+/43005
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I27428c02e99040754e15e07782ec1ad8524def2f
Gerrit-Change-Number: 43005
Gerrit-PatchSet: 8
Gerrit-Owner: Jingle Hsu <jingle_hsu(a)wiwynn.com>
Gerrit-Reviewer: Johnny Lin <Johnny_Lin(a)wiwynn.com>
Gerrit-Reviewer: Jonathan Zhang <jonzhang(a)fb.com>
Gerrit-Reviewer: Morgan Jang
Gerrit-Reviewer: Patrick Rudolph <patrick.rudolph(a)9elements.com>
Gerrit-Reviewer: Rocky Phagura
Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-MessageType: newpatchset
Julius Werner has submitted this change. ( https://review.coreboot.org/c/coreboot/+/42792 )
Change subject: libpayload: cbgfx: Replace bilinear resampling with Lanczos
......................................................................
libpayload: cbgfx: Replace bilinear resampling with Lanczos
This patch improves the image resampling (scaling) code in CBGFX to use
the Lanczos algorithm that is widely considered the "best" resampling
algorithm (e.g. also the first choice in Python's PIL library). It is of
course much more elaborate and therefore slower than bilinear
resampling, but a lot of the difference can be made up with
optimizations, and the resulting code was found to still produce
acceptable speeds for existing Chrome OS UI use cases (on an Arm
Cortex-A55 device, time to scale an image to 1101x593 went from ~88ms to
~275ms, a little over 3x slowdown). Nevertheless, if this should be too
slow for anyone there's also an option to tune it down a little, but
still much better than bilinear (same operation was ~170ms with this).
Example images (scaled up by a factor of 7):
Old (bilinear): https://i.imgur.com/ytr2n4Z.png
New (Lanczos a=3): https://i.imgur.com/f0vKluM.png
Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Change-Id: Idde6f61865bfac2801ee4fff40ac64e4ebddff1a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42792
Tested-by: build bot (Jenkins) <no-reply(a)coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso(a)google.com>
Reviewed-by: Hung-Te Lin <hungte(a)chromium.org>
---
M payloads/libpayload/Kconfig
M payloads/libpayload/drivers/video/graphics.c
2 files changed, 303 insertions(+), 85 deletions(-)
Approvals:
build bot (Jenkins): Verified
Hung-Te Lin: Looks good to me, approved
Yu-Ping Wu: Looks good to me, but someone else must approve
diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig
index 7e506d9..b5dc9a3 100644
--- a/payloads/libpayload/Kconfig
+++ b/payloads/libpayload/Kconfig
@@ -334,6 +334,19 @@
By default (value of 0), the scale factor is automatically
calculated to ensure at least 130 columns (when possible).
+config CBGFX_FAST_RESAMPLE
+ bool "CBGFX: use faster (less pretty) image scaling"
+ default n
+ help
+ When payloads use the CBGFX library to draw .BMPs on the screen,
+ they will be resampled with an anti-aliasing filter to scale to the
+ requested output size. The default implementation should normally be
+ fast enough, but if desired this option can make it about 50-100%
+ faster at the cost of quality. (It changes the 'a' parameter in the
+ Lanczos resampling algorithm from 3 to 2.)
+
+ Only affects .BMPs that aren't already provided at the right size.
+
config PC_I8042
bool "A common PC i8042 driver"
default y if PC_KEYBOARD || PC_MOUSE
diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c
index fa72c9b..bb8467b 100644
--- a/payloads/libpayload/drivers/video/graphics.c
+++ b/payloads/libpayload/drivers/video/graphics.c
@@ -28,6 +28,7 @@
#include <libpayload.h>
#include <cbfs.h>
+#include <fpmath.h>
#include <sysinfo.h>
#include "bitmap.h"
@@ -468,33 +469,116 @@
return CBGFX_SUCCESS;
}
-/*
- * Bi-linear Interpolation
- *
- * It estimates the value of a middle point (tx, ty) using the values from four
- * adjacent points (q00, q01, q10, q11).
- */
-static uint32_t bli(uint32_t q00, uint32_t q10, uint32_t q01, uint32_t q11,
- struct fraction *tx, struct fraction *ty)
+static int pal_to_rgb(uint8_t index, const struct bitmap_palette_element_v3 *pal,
+ size_t palcount, struct rgb_color *out)
{
- uint32_t r0 = (tx->n * q10 + (tx->d - tx->n) * q00) / tx->d;
- uint32_t r1 = (tx->n * q11 + (tx->d - tx->n) * q01) / tx->d;
- uint32_t p = (ty->n * r1 + (ty->d - ty->n) * r0) / ty->d;
- return p;
+ if (index >= palcount) {
+ LOG("Color index %d exceeds palette boundary\n", index);
+ return CBGFX_ERROR_BITMAP_DATA;
+ }
+
+ out->red = pal[index].red;
+ out->green = pal[index].green;
+ out->blue = pal[index].blue;
+ return CBGFX_SUCCESS;
+}
+
+/*
+ * We're using the Lanczos resampling algorithm to rescale images to a new size.
+ * Since output size is often not cleanly divisible by input size, an output
+ * pixel (ox,oy) corresponds to a point that lies in the middle between several
+ * input pixels (ix,iy), meaning that if you transformed the coordinates of the
+ * output pixel into the input image space, they would be fractional. To sample
+ * the color of this "virtual" pixel with fractional coordinates, we gather the
+ * 6x6 grid of nearest real input pixels in a sample array. Then we multiply the
+ * color values for each of those pixels (separately for red, green and blue)
+ * with a "weight" value that was calculated from the distance between that
+ * input pixel and the fractional output pixel coordinates. This is done for
+ * both X and Y dimensions separately. The combined weights for all 36 sample
+ * pixels add up to 1.0, so by adding up the multiplied color values we get the
+ * interpolated color for the output pixel.
+ *
+ * The CONFIG_LP_CBGFX_FAST_RESAMPLE option let's the user change the 'a'
+ * parameter from the Lanczos weight formula from 3 to 2, which effectively
+ * reduces the size of the sample array from 6x6 to 4x4. This is a bit faster
+ * but doesn't look as good. Most use cases should be fine without it.
+ */
+#if CONFIG(LP_CBGFX_FAST_RESAMPLE)
+#define LNCZ_A 2
+#else
+#define LNCZ_A 3
+#endif
+
+/*
+ * When walking the sample array we often need to start at a pixel close to our
+ * fractional output pixel (for convenience we choose the pixel on the top-left
+ * which corresponds to the integer parts of the output pixel coordinates) and
+ * then work our way outwards in both directions from there. Arrays in C must
+ * start at 0 but we'd really prefer indexes to go from -2 to 3 (for 6x6)
+ * instead, so that this "start pixel" could be 0. Since we cannot do that,
+ * define a constant for the index of that "0th" pixel instead.
+ */
+#define S0 (LNCZ_A - 1)
+
+/* The size of the sample array, which we need a lot. */
+#define SSZ (LNCZ_A * 2)
+
+/*
+ * This is implementing the Lanczos kernel according to:
+ * https://en.wikipedia.org/wiki/Lanczos_resampling
+ *
+ * / 1 if x = 0
+ * L(x) = < a * sin(pi * x) * sin(pi * x / a) / (pi^2 * x^2) if -a < x <= a
+ * \ 0 otherwise
+ */
+static fpmath_t lanczos_weight(fpmath_t in, int off)
+{
+ /*
+ * |in| is the output pixel coordinate scaled into the input pixel
+ * space. |off| is the offset in the sample array for the pixel whose
+ * weight we're calculating. (off - S0) is the distance from that
+ * sample pixel to the S0 pixel, and the fractional part of |in|
+ * (in - floor(in)) is by definition the distance between S0 and the
+ * output pixel.
+ *
+ * So (off - S0) - (in - floor(in)) is the distance from the sample
+ * pixel to S0 minus the distance from S0 to the output pixel, aka
+ * the distance from the sample pixel to the output pixel.
+ */
+ fpmath_t x = fpisub(off - S0, fpsubi(in, fpfloor(in)));
+
+ if (fpequals(x, fp(0)))
+ return fp(1);
+
+ /* x * 2 / a can save some instructions if a == 2 */
+ fpmath_t x2a = x;
+ if (LNCZ_A != 2)
+ x2a = fpmul(x, fpfrac(2, LNCZ_A));
+
+ fpmath_t x_times_pi = fpmul(x, fppi());
+
+ /*
+ * Rather than using sinr(pi*x), we leverage the "one-based" sine
+ * function (see <fpmath.h>) with sin1(2*x) so that the pi is eliminated
+ * since multiplication by an integer is a slightly faster operation.
+ */
+ fpmath_t tmp = fpmuli(fpdiv(fpsin1(fpmuli(x, 2)), x_times_pi), LNCZ_A);
+ return fpdiv(fpmul(tmp, fpsin1(x2a)), x_times_pi);
}
static int draw_bitmap_v3(const struct vector *top_left,
- const struct scale *scale,
const struct vector *dim,
const struct vector *dim_org,
const struct bitmap_header_v3 *header,
const struct bitmap_palette_element_v3 *pal,
- const uint8_t *pixel_array,
- uint8_t invert)
+ const uint8_t *pixel_array, uint8_t invert)
{
const int bpp = header->bits_per_pixel;
int32_t dir;
struct vector p;
+ int32_t ox, oy; /* output (resampled) pixel coordinates */
+ int32_t ix, iy; /* input (source image) pixel coordinates */
+ int sx, sy; /* index into |sample| (not ringbuffer adjusted) */
if (header->compression) {
LOG("Compressed bitmaps are not supported\n");
@@ -508,10 +592,6 @@
LOG("Unsupported bits per pixel: %d\n", bpp);
return CBGFX_ERROR_BITMAP_FORMAT;
}
- if (scale->x.n == 0 || scale->y.n == 0) {
- LOG("Scaling out of range\n");
- return CBGFX_ERROR_SCALE_OUT_OF_RANGE;
- }
const int32_t y_stride = ROUNDUP(dim_org->width * bpp / 8, 4);
/*
@@ -530,63 +610,202 @@
p.y += dim->height - 1;
dir = -1;
}
- /*
- * Plot pixels scaled by the bilinear interpolation. We scan over the
- * image on canvas (using d) and find the corresponding pixel in the
- * bitmap data (using s0, s1).
- *
- * When d hits the right bottom corner, s0 also hits the right bottom
- * corner of the pixel array because that's how scale->x and scale->y
- * have been set. Since the pixel array size is already validated in
- * parse_bitmap_header_v3, s0 is guaranteed not to exceed pixel array
- * boundary.
- */
- struct vector s0, s1, d;
- struct fraction tx, ty;
- for (d.y = 0; d.y < dim->height; d.y++, p.y += dir) {
- s0.y = d.y * scale->y.d / scale->y.n;
- s1.y = s0.y;
- if (s1.y + 1 < dim_org->height)
- s1.y++;
- ty.d = scale->y.n;
- ty.n = (d.y * scale->y.d) % scale->y.n;
- const uint8_t *data0 = pixel_array + s0.y * y_stride;
- const uint8_t *data1 = pixel_array + s1.y * y_stride;
- p.x = top_left->x;
- for (d.x = 0; d.x < dim->width; d.x++, p.x++) {
- s0.x = d.x * scale->x.d / scale->x.n;
- s1.x = s0.x;
- if (s1.x + 1 < dim_org->width)
- s1.x++;
- tx.d = scale->x.n;
- tx.n = (d.x * scale->x.d) % scale->x.n;
- uint8_t c00 = data0[s0.x];
- uint8_t c10 = data0[s1.x];
- uint8_t c01 = data1[s0.x];
- uint8_t c11 = data1[s1.x];
- if (c00 >= header->colors_used
- || c10 >= header->colors_used
- || c01 >= header->colors_used
- || c11 >= header->colors_used) {
- LOG("Color index exceeds palette boundary\n");
- return CBGFX_ERROR_BITMAP_DATA;
+
+ /* Don't waste time resampling when the scale is 1:1. */
+ if (dim_org->width == dim->width && dim_org->height == dim->height) {
+ for (oy = 0; oy < dim->height; oy++, p.y += dir) {
+ p.x = top_left->x;
+ for (ox = 0; ox < dim->width; ox++, p.x++) {
+ struct rgb_color rgb;
+ if (pal_to_rgb(pixel_array[oy * y_stride + ox],
+ pal, header->colors_used, &rgb))
+ return CBGFX_ERROR_BITMAP_DATA;
+ set_pixel(&p, calculate_color(&rgb, invert));
}
- const struct rgb_color rgb = {
- .red = bli(pal[c00].red, pal[c10].red,
- pal[c01].red, pal[c11].red,
- &tx, &ty),
- .green = bli(pal[c00].green, pal[c10].green,
- pal[c01].green, pal[c11].green,
- &tx, &ty),
- .blue = bli(pal[c00].blue, pal[c10].blue,
- pal[c01].blue, pal[c11].blue,
- &tx, &ty),
+ }
+ return CBGFX_SUCCESS;
+ }
+
+ /* Precalculate the X-weights for every possible ox so that we only have
+ to multiply weights together in the end. */
+ fpmath_t (*weight_x)[SSZ] = malloc(sizeof(fpmath_t) * SSZ * dim->width);
+ if (!weight_x)
+ return CBGFX_ERROR_UNKNOWN;
+ for (ox = 0; ox < dim->width; ox++) {
+ for (sx = 0; sx < SSZ; sx++) {
+ fpmath_t ixfp = fpfrac(ox * dim_org->width, dim->width);
+ weight_x[ox][sx] = lanczos_weight(ixfp, sx);
+ }
+ }
+
+ /*
+ * For every sy in the sample array, we directly cache a pointer into
+ * the .BMP pixel array for the start of the corresponding line. On the
+ * edges of the image (where we don't have any real pixels to fill all
+ * lines in the sample array), we just reuse the last valid lines inside
+ * the image for all lines that would lie outside.
+ */
+ const uint8_t *ypix[SSZ];
+ for (sy = 0; sy < SSZ; sy++) {
+ if (sy <= S0)
+ ypix[sy] = pixel_array;
+ else if (sy - S0 >= dim_org->height)
+ ypix[sy] = ypix[sy - 1];
+ else
+ ypix[sy] = &pixel_array[y_stride * (sy - S0)];
+ }
+
+ /* iy and ix track the input pixel corresponding to sample[S0][S0]. */
+ iy = 0;
+ for (oy = 0; oy < dim->height; oy++, p.y += dir) {
+ struct rgb_color sample[SSZ][SSZ];
+
+ /* Like with X weights, we also cache all Y weights. */
+ fpmath_t iyfp = fpfrac(oy * dim_org->height, dim->height);
+ fpmath_t weight_y[SSZ];
+ for (sy = 0; sy < SSZ; sy++)
+ weight_y[sy] = lanczos_weight(iyfp, sy);
+
+ /*
+ * If we have a new input pixel line between the last oy and
+ * this one, we have to adjust iy forward. When upscaling, this
+ * is not always the case for each new output line. When
+ * downscaling, we may even cross more than one line per output
+ * pixel.
+ */
+ while (fpfloor(iyfp) > iy) {
+ iy++;
+
+ /* Shift ypix array up to center around next iy line. */
+ for (sy = 0; sy < SSZ - 1; sy++)
+ ypix[sy] = ypix[sy + 1];
+
+ /* Calculate the last ypix that is being shifted in,
+ but beware of reaching the end of the input image. */
+ if (iy + LNCZ_A < dim_org->height)
+ ypix[SSZ - 1] = &pixel_array[y_stride *
+ (iy + LNCZ_A)];
+ }
+
+ /*
+ * Initialize the sample array for this line. For pixels to the
+ * left of S0 there are no corresponding input pixels so just
+ * copy the S0 values over.
+ *
+ * Also initialize the equals counter, which counts how many of
+ * the latest pixels were exactly equal. We know the columns
+ * left of S0 must be equal to S0, so start with that number.
+ */
+ int equals = S0 * SSZ;
+ uint8_t last_equal = ypix[0][0];
+ for (sy = 0; sy < SSZ; sy++) {
+ for (sx = S0; sx < SSZ; sx++) {
+ if (sx >= dim_org->width) {
+ sample[sx][sy] = sample[sx - 1][sy];
+ equals++;
+ continue;
+ }
+ uint8_t i = ypix[sy][sx - S0];
+ if (pal_to_rgb(i, pal, header->colors_used,
+ &sample[sx][sy]))
+ goto bitmap_error;
+ if (i == last_equal) {
+ equals++;
+ } else {
+ last_equal = i;
+ equals = 1;
+ }
+ }
+ for (sx = S0 - 1; sx >= 0; sx--)
+ sample[sx][sy] = sample[S0][sy];
+ }
+
+ ix = 0;
+ p.x = top_left->x;
+ for (ox = 0; ox < dim->width; ox++, p.x++) {
+ /* Adjust ix forward, same as iy above. */
+ fpmath_t ixfp = fpfrac(ox * dim_org->width, dim->width);
+ while (fpfloor(ixfp) > ix) {
+ ix++;
+
+ /*
+ * We want to reuse the sample columns we
+ * already have, but we don't want to copy them
+ * all around for every new column either.
+ * Instead, treat the X dimension of the sample
+ * array like a ring buffer indexed by ix. rx is
+ * the ringbuffer-adjusted offset of the new
+ * column in sample (the rightmost one) we're
+ * trying to fill.
+ */
+ int rx = (SSZ - 1 + ix) % SSZ;
+ for (sy = 0; sy < SSZ; sy++) {
+ if (ix + LNCZ_A >= dim_org->width) {
+ sample[rx][sy] = sample[(SSZ - 2
+ + ix) % SSZ][sy];
+ equals++;
+ continue;
+ }
+ uint8_t i = ypix[sy][ix + LNCZ_A];
+ if (i == last_equal) {
+ if (equals++ >= (SSZ * SSZ))
+ continue;
+ } else {
+ last_equal = i;
+ equals = 1;
+ }
+ if (pal_to_rgb(i, pal,
+ header->colors_used,
+ &sample[rx][sy]))
+ goto bitmap_error;
+ }
+ }
+
+ /* If all pixels in sample are equal, fast path. */
+ if (equals >= (SSZ * SSZ)) {
+ set_pixel(&p, calculate_color(&sample[0][0],
+ invert));
+ continue;
+ }
+
+ fpmath_t red = fp(0);
+ fpmath_t green = fp(0);
+ fpmath_t blue = fp(0);
+ for (sy = 0; sy < SSZ; sy++) {
+ for (sx = 0; sx < SSZ; sx++) {
+ int rx = (sx + ix) % SSZ;
+ fpmath_t weight = fpmul(weight_x[ox][sx],
+ weight_y[sy]);
+ red = fpadd(red, fpmuli(weight,
+ sample[rx][sy].red));
+ green = fpadd(green, fpmuli(weight,
+ sample[rx][sy].green));
+ blue = fpadd(blue, fpmuli(weight,
+ sample[rx][sy].blue));
+ }
+ }
+
+ /*
+ * Weights *should* sum up to 1.0 (making this not
+ * necessary) but just to hedge against rounding errors
+ * we should clamp color values to their legal limits.
+ */
+ struct rgb_color rgb = {
+ .red = MAX(0, MIN(UINT8_MAX, fpround(red))),
+ .green = MAX(0, MIN(UINT8_MAX, fpround(green))),
+ .blue = MAX(0, MIN(UINT8_MAX, fpround(blue))),
};
+
set_pixel(&p, calculate_color(&rgb, invert));
}
}
+ free(weight_x);
return CBGFX_SUCCESS;
+
+bitmap_error:
+ free(weight_x);
+ return CBGFX_ERROR_BITMAP_DATA;
}
static int get_bitmap_file_header(const void *bitmap, size_t size,
@@ -780,7 +999,6 @@
const struct bitmap_palette_element_v3 *palette;
const uint8_t *pixel_array;
struct vector top_left, dim, dim_org;
- struct scale scale;
int rv;
const uint8_t pivot = flags & PIVOT_MASK;
const uint8_t invert = (flags & INVERT_COLORS) >> INVERT_SHIFT;
@@ -799,12 +1017,6 @@
if (rv)
return rv;
- /* Calculate self scale */
- scale.x.n = dim.width;
- scale.x.d = dim_org.width;
- scale.y.n = dim.height;
- scale.y.d = dim_org.height;
-
/* Calculate coordinate */
rv = calculate_position(&dim, pos_rel, pivot, &top_left);
if (rv)
@@ -816,7 +1028,7 @@
return rv;
}
- return draw_bitmap_v3(&top_left, &scale, &dim, &dim_org,
+ return draw_bitmap_v3(&top_left, &dim, &dim_org,
&header, palette, pixel_array, invert);
}
@@ -827,7 +1039,6 @@
const struct bitmap_palette_element_v3 *palette;
const uint8_t *pixel_array;
struct vector dim;
- struct scale scale;
int rv;
if (cbgfx_init())
@@ -839,19 +1050,13 @@
if (rv)
return rv;
- /* Calculate self scale */
- scale.x.n = 1;
- scale.x.d = 1;
- scale.y.n = 1;
- scale.y.d = 1;
-
rv = check_boundary(top_left, &dim, &screen);
if (rv) {
LOG("Bitmap image exceeds screen boundary\n");
return rv;
}
- return draw_bitmap_v3(top_left, &scale, &dim, &dim,
+ return draw_bitmap_v3(top_left, &dim, &dim,
&header, palette, pixel_array, 0);
}
--
To view, visit https://review.coreboot.org/c/coreboot/+/42792
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Idde6f61865bfac2801ee4fff40ac64e4ebddff1a
Gerrit-Change-Number: 42792
Gerrit-PatchSet: 17
Gerrit-Owner: Julius Werner <jwerner(a)chromium.org>
Gerrit-Reviewer: Hung-Te Lin <hungte(a)chromium.org>
Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org>
Gerrit-Reviewer: Shelley Chen <shchen(a)google.com>
Gerrit-Reviewer: Yu-Ping Wu <yupingso(a)google.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-MessageType: merged
Hello Shelley Chen, Hung-Te Lin, Yu-Ping Wu,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/42993
to review the following change.
Change subject: libpayload: Add simple 32.32 fixed-point math API
......................................................................
libpayload: Add simple 32.32 fixed-point math API
struct fraction is slooooooooooow. This patch adds a simple 64-bit
(32-bits integral, 32-bits fractional) fixed-point math API that is
*much* faster when doing intensive graphics operations. It is optimized
for speed over accuracy so some operations may lose a bit more precision
than expected, but overall it's still plenty of bits for most use cases.
Also includes support for basic trigonometric functions with a small
lookup table.
Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Change-Id: Id0f9c23980e36ce0ac0b7c5cd0bc66153bca1fd0
---
A payloads/libpayload/include/fpmath.h
M payloads/libpayload/libc/Makefile.inc
A payloads/libpayload/libc/fpmath.c
3 files changed, 384 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/93/42993/1
diff --git a/payloads/libpayload/include/fpmath.h b/payloads/libpayload/include/fpmath.h
new file mode 100644
index 0000000..db7cc21
--- /dev/null
+++ b/payloads/libpayload/include/fpmath.h
@@ -0,0 +1,234 @@
+/*
+ *
+ * Copyright (C) 2020 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+
+/*
+ * This file implements operations for a simple 32.32 fixed-point math type.
+ * This is intended for speed-critical stuff (e.g. graphics) so there are
+ * intentionally no overflow checks or assertions, and operations are written
+ * to prefer speed over precision (e.g. multiplying by 1 may lose precision).
+ * For best results, only use for applications where 16.16 would fit.
+ */
+
+typedef struct { /* wrap in struct to prevent direct access */
+ int64_t v;
+} fpmath_t;
+
+#define FPMATH_SHIFT 32 /* define where to place the decimal point */
+
+/* Turn an integer into an fpmath_t. */
+static inline fpmath_t fp(int32_t a)
+{
+ return (fpmath_t){ .v = (int64_t)a << FPMATH_SHIFT };
+}
+
+/* Create an fpmath_t from a fraction. (numerator / denominator) */
+static inline fpmath_t fpfrac(int32_t numerator, int32_t denominator)
+{
+ return (fpmath_t){ .v = ((int64_t)numerator << FPMATH_SHIFT) / denominator };
+}
+
+/* Turn an fpmath_t back into an integer, rounding towards -INF. */
+static inline int32_t fpfloor(fpmath_t a)
+{
+ return a.v >> FPMATH_SHIFT;
+}
+
+/* Turn an fpmath_t back into an integer, rounding towards nearest. */
+static inline int32_t fpround(fpmath_t a)
+{
+ return (a.v + ((int64_t)1 << (FPMATH_SHIFT - 1))) >> FPMATH_SHIFT;
+}
+
+/* Turn an fpmath_t back into an integer, rounding towards +INF. */
+static inline int32_t fpceil(fpmath_t a)
+{
+ return (a.v + ((int64_t)1 << FPMATH_SHIFT) - 1) >> FPMATH_SHIFT;
+}
+
+/* Add two fpmath_t. (a + b) */
+static inline fpmath_t fpadd(fpmath_t a, fpmath_t b)
+{
+ return (fpmath_t){ .v = a.v + b.v };
+}
+
+/* Add an fpmath_t and an integer. (a + b) */
+static inline fpmath_t fpaddi(fpmath_t a, int32_t b)
+{
+ return (fpmath_t){ .v = a.v + ((int64_t)b << FPMATH_SHIFT) };
+}
+
+/* Subtract one fpmath_t from another. (a + b) */
+static inline fpmath_t fpsub(fpmath_t a, fpmath_t b)
+{
+ return (fpmath_t){ .v = a.v - b.v };
+}
+
+/* Subtract an integer from an fpmath_t. (a - b) */
+static inline fpmath_t fpsubi(fpmath_t a, int32_t b)
+{
+ return (fpmath_t){ .v = a.v - ((int64_t)b << FPMATH_SHIFT) };
+}
+
+/* Subtract an fpmath_t from an integer. (a - b) */
+static inline fpmath_t fpisub(int32_t a, fpmath_t b)
+{
+ return (fpmath_t){ .v = ((int64_t)a << FPMATH_SHIFT) - b.v };
+}
+
+/* Multiply two fpmath_t. (a * b)
+ Looses 16 bits fractional precision on each. */
+static inline fpmath_t fpmul(fpmath_t a, fpmath_t b)
+{
+ return (fpmath_t){ .v = (a.v >> (FPMATH_SHIFT/2)) * (b.v >> (FPMATH_SHIFT/2)) };
+}
+
+/* Multiply an fpmath_t and an integer. (a * b) */
+static inline fpmath_t fpmuli(fpmath_t a, int32_t b)
+{
+ return (fpmath_t){ .v = a.v * b };
+}
+
+/* Divide an fpmath_t by another. (a / b)
+ Looses 16 bits integral precision on each! Careful with this one! */
+static inline fpmath_t fpdiv(fpmath_t a, fpmath_t b)
+{
+ return (fpmath_t){ .v = (a.v << (FPMATH_SHIFT/2)) / (b.v >> (FPMATH_SHIFT/2)) };
+}
+
+/* Divide an fpmath_t by an integer. (a / b) */
+static inline fpmath_t fpdivi(fpmath_t a, int32_t b)
+{
+ return (fpmath_t){ .v = a.v / b };
+}
+
+/* Calculate absolute value of an fpmath_t. (ABS(a)) */
+static inline fpmath_t fpabs(fpmath_t a)
+{
+ return (fpmath_t){ .v = (a.v < 0 ? -a.v : a.v) };
+}
+
+/* Return true iff two fpmath_t are exactly equal. (a == b)
+ Like with floats, you probably don't want to use this most of the time. */
+static inline int fpequals(fpmath_t a, fpmath_t b)
+{
+ return a.v == b.v;
+}
+
+/* Return true iff one fpmath_t is less than another. (a < b) */
+static inline int fpless(fpmath_t a, fpmath_t b)
+{
+ return a.v < b.v;
+}
+
+/* Return true iff one fpmath_t is more than another. (a > b) */
+static inline int fpmore(fpmath_t a, fpmath_t b)
+{
+ return a.v > b.v;
+}
+
+/* Return the smaller of two fpmath_t. (MIN(a, b)) */
+static inline fpmath_t fpmin(fpmath_t a, fpmath_t b)
+{
+ if (a.v < b.v)
+ return a;
+ else
+ return b;
+}
+
+/* Return the larger of two fpmath_t. (MAX(a, b)) */
+static inline fpmath_t fpmax(fpmath_t a, fpmath_t b)
+{
+ if (a.v > b.v)
+ return a;
+ else
+ return b;
+}
+
+/* Return the constant PI as an fpmath_t (to as much precision as I was willing to bother). */
+static inline fpmath_t fppi(void)
+{
+ /* Can have one more digit when dividing unsigned, will be small enough to fit after. */
+ return (fpmath_t){ .v = ((uint64_t)3141592654 << FPMATH_SHIFT) / 1000000000 };
+}
+
+/*
+ * Returns the "one-based" sine of an fpmath_t, meaning the input is interpreted as if the range
+ * 0.0-1.0 corresponded to 0.0-PI/2 for radians. This is mostly here as the base primitives for
+ * the other trig stuff, but it may be useful to use directly if your input value already needs
+ * to be multiplied by some factor of PI and you want to save the instructions (and precision)
+ * for multiplying it in just so that the trig functions can divide it right out again.
+ */
+fpmath_t fpsin1(fpmath_t x);
+
+/* Returns the "one-based" cosine of an fpmath_t (analogous definition to fpsin1()). */
+static inline fpmath_t fpcos1(fpmath_t x)
+{
+ return fpsin1(fpaddi(x, 1));
+}
+
+/* Returns the sine of an fpmath_t interpreted as radians. */
+static inline fpmath_t fpsinr(fpmath_t radians)
+{
+ return fpsin1(fpdiv(radians, fpdivi(fppi(), 2)));
+}
+
+/* Returns the sine of an fpmath_t interpreted as degrees. */
+static inline fpmath_t fpsind(fpmath_t degrees)
+{
+ return fpsin1(fpdivi(degrees, 90));
+}
+
+/* Returns the cosine of an fpmath_t interpreted as radians. */
+static inline fpmath_t fpcosr(fpmath_t radians)
+{
+ return fpcos1(fpdiv(radians, fpdivi(fppi(), 2)));
+}
+
+/* Returns the cosine of an fpmath_t interpreted as degrees. */
+static inline fpmath_t fpcosd(fpmath_t degrees)
+{
+ return fpcos1(fpdivi(degrees, 90));
+}
+
+/* Returns the tangent of an fpmath_t interpreted as radians.
+ No safety rails, don't call this at the poles! */
+static inline fpmath_t fptanr(fpmath_t radians)
+{
+ fpmath_t one_based = fpdiv(radians, fpdivi(fppi(), 2));
+ return fpdiv(fpsin1(one_based), fpcos1(one_based));
+}
+
+/* Returns the tangent of an fpmath_t interpreted as degrees.
+ No safety rails, don't call this at the poles! */
+static inline fpmath_t fptand(fpmath_t degrees)
+{
+ fpmath_t one_based = fpdivi(degrees, 90);
+ return fpdiv(fpsin1(one_based), fpcos1(one_based));
+}
diff --git a/payloads/libpayload/libc/Makefile.inc b/payloads/libpayload/libc/Makefile.inc
index 2999023..f9006ae 100644
--- a/payloads/libpayload/libc/Makefile.inc
+++ b/payloads/libpayload/libc/Makefile.inc
@@ -38,3 +38,4 @@
libc-$(CONFIG_LP_LIBC) += die.c
libc-$(CONFIG_LP_LIBC) += coreboot.c
libc-$(CONFIG_LP_LIBC) += fmap.c
+libc-$(CONFIG_LP_LIBC) += fpmath.c
diff --git a/payloads/libpayload/libc/fpmath.c b/payloads/libpayload/libc/fpmath.c
new file mode 100644
index 0000000..4c2a6ac
--- /dev/null
+++ b/payloads/libpayload/libc/fpmath.c
@@ -0,0 +1,149 @@
+/*
+ *
+ * Copyright (C) 2020 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <fpmath.h>
+
+/*
+ * This table represents one ascending arc of the sine curve, i.e. the values sin(x) for
+ * 0.0 <= x < PI/2. We divide that range into 256 equidistant points and store the corresponding
+ * sine values for those points. Since the values lie in the range 0.0 <= sin(x) < 1.0, in order
+ * to make the most use of the bytes we store, we map them to the range from 0 to UINT16_MAX.
+ *
+ * Generated with:
+ *
+ * for (i = 0; i < 256; i++) {
+ * double s = sin((double)i * M_PI / 2 / 256);
+ * uint16_t u = fmin(round(s * (1 << 16)), (1 << 16));
+ * printf("0x%04x,%s", u, i % 8 == 7 ? "\n" : " ");
+ * }
+ *
+ * In order to make sure the second access for linear interpolation (see below) cannot overrun
+ * the array, we stick a final 257th value 0xffff at the end. (It should really be 0x10000,
+ * but... this is good enough.)
+ */
+
+/* Table size as power of two. If we ever want to change the table size, updating this value
+ should make everything else fall back into place again (hopefully). */
+#define TP2 8
+
+static const uint16_t fpsin_table[(1 << TP2) + 1] = {
+ 0x0000, 0x0192, 0x0324, 0x04b6, 0x0648, 0x07da, 0x096c, 0x0afe,
+ 0x0c90, 0x0e21, 0x0fb3, 0x1144, 0x12d5, 0x1466, 0x15f7, 0x1787,
+ 0x1918, 0x1aa8, 0x1c38, 0x1dc7, 0x1f56, 0x20e5, 0x2274, 0x2402,
+ 0x2590, 0x271e, 0x28ab, 0x2a38, 0x2bc4, 0x2d50, 0x2edc, 0x3067,
+ 0x31f1, 0x337c, 0x3505, 0x368e, 0x3817, 0x399f, 0x3b27, 0x3cae,
+ 0x3e34, 0x3fba, 0x413f, 0x42c3, 0x4447, 0x45cb, 0x474d, 0x48cf,
+ 0x4a50, 0x4bd1, 0x4d50, 0x4ecf, 0x504d, 0x51cb, 0x5348, 0x54c3,
+ 0x563e, 0x57b9, 0x5932, 0x5aaa, 0x5c22, 0x5d99, 0x5f0f, 0x6084,
+ 0x61f8, 0x636b, 0x64dd, 0x664e, 0x67be, 0x692d, 0x6a9b, 0x6c08,
+ 0x6d74, 0x6edf, 0x7049, 0x71b2, 0x731a, 0x7480, 0x75e6, 0x774a,
+ 0x78ad, 0x7a10, 0x7b70, 0x7cd0, 0x7e2f, 0x7f8c, 0x80e8, 0x8243,
+ 0x839c, 0x84f5, 0x864c, 0x87a1, 0x88f6, 0x8a49, 0x8b9a, 0x8ceb,
+ 0x8e3a, 0x8f88, 0x90d4, 0x921f, 0x9368, 0x94b0, 0x95f7, 0x973c,
+ 0x9880, 0x99c2, 0x9b03, 0x9c42, 0x9d80, 0x9ebc, 0x9ff7, 0xa130,
+ 0xa268, 0xa39e, 0xa4d2, 0xa605, 0xa736, 0xa866, 0xa994, 0xaac1,
+ 0xabeb, 0xad14, 0xae3c, 0xaf62, 0xb086, 0xb1a8, 0xb2c9, 0xb3e8,
+ 0xb505, 0xb620, 0xb73a, 0xb852, 0xb968, 0xba7d, 0xbb8f, 0xbca0,
+ 0xbdaf, 0xbebc, 0xbfc7, 0xc0d1, 0xc1d8, 0xc2de, 0xc3e2, 0xc4e4,
+ 0xc5e4, 0xc6e2, 0xc7de, 0xc8d9, 0xc9d1, 0xcac7, 0xcbbc, 0xccae,
+ 0xcd9f, 0xce8e, 0xcf7a, 0xd065, 0xd14d, 0xd234, 0xd318, 0xd3fb,
+ 0xd4db, 0xd5ba, 0xd696, 0xd770, 0xd848, 0xd91e, 0xd9f2, 0xdac4,
+ 0xdb94, 0xdc62, 0xdd2d, 0xddf7, 0xdebe, 0xdf83, 0xe046, 0xe107,
+ 0xe1c6, 0xe282, 0xe33c, 0xe3f4, 0xe4aa, 0xe55e, 0xe610, 0xe6bf,
+ 0xe76c, 0xe817, 0xe8bf, 0xe966, 0xea0a, 0xeaab, 0xeb4b, 0xebe8,
+ 0xec83, 0xed1c, 0xedb3, 0xee47, 0xeed9, 0xef68, 0xeff5, 0xf080,
+ 0xf109, 0xf18f, 0xf213, 0xf295, 0xf314, 0xf391, 0xf40c, 0xf484,
+ 0xf4fa, 0xf56e, 0xf5df, 0xf64e, 0xf6ba, 0xf724, 0xf78c, 0xf7f1,
+ 0xf854, 0xf8b4, 0xf913, 0xf96e, 0xf9c8, 0xfa1f, 0xfa73, 0xfac5,
+ 0xfb15, 0xfb62, 0xfbad, 0xfbf5, 0xfc3b, 0xfc7f, 0xfcc0, 0xfcfe,
+ 0xfd3b, 0xfd74, 0xfdac, 0xfde1, 0xfe13, 0xfe43, 0xfe71, 0xfe9c,
+ 0xfec4, 0xfeeb, 0xff0e, 0xff30, 0xff4e, 0xff6b, 0xff85, 0xff9c,
+ 0xffb1, 0xffc4, 0xffd4, 0xffe1, 0xffec, 0xfff5, 0xfffb, 0xffff,
+ 0xffff,
+};
+
+/* x is in the "one-based" scale, so x == 1.0 is the top of the curve (PI/2 in radians). */
+fpmath_t fpsin1(fpmath_t x)
+{
+ /*
+ * When doing things like sin(x)/x, tiny errors can quickly become big problems, so just
+ * returning the nearest table value we have is not good enough (our fpmath_t has four
+ * times as much fractional precision as the sine table). A good and fast enough remedy
+ * is to linearly interpolate between the two nearest table values v1 and v2.
+ * (There are better but slower interpolations so we intentionally choose this one.)
+ *
+ * Most of this math can be done in 32 bits (because we're just operating on fractional
+ * parts in the 0.0-1.0 range anyway), so to help our 32-bit platforms a bit we keep it
+ * there as long as possible and only go back to an int64_t at the end.
+ */
+ uint32_t v1, v2;
+
+ /*
+ * Since x is "one-based" the part that maps to our curve (0.0 to PI/2 in radians) just
+ * happens to be exactly the fractional part of the fpmath_t, easy to extract.
+ */
+ int index = (x.v >> (FPMATH_SHIFT - TP2)) & ((1 << TP2) - 1);
+
+ /*
+ * In our one-based input domain, the period of the sine function is exactly 4.0. By
+ * extracting the first bit of the integral part of the fpmath_t we can check if it is
+ * odd-numbered (1.0-2.0, 3.0-4.0, etc.) or even numbered (0.0-1.0, 2.0-3.0, etc.), and
+ * that tells us whether we are in a "rising" (away from 0) or "falling" (towards 0)
+ * part of the sine curve. Our table curve is rising, so for the falling parts we have
+ * to mirror the curve horizontally by using the complement of our input index.
+ */
+ if (x.v & ((int64_t)1 << FPMATH_SHIFT)) {
+ v1 = fpsin_table[(1 << TP2) - index];
+ v2 = fpsin_table[(1 << TP2) - index - 1];
+ } else {
+ v1 = fpsin_table[index];
+ v2 = fpsin_table[index + 1];
+ }
+
+ /*
+ * Linear interpolation: sin(x) is interpolated as the closest number sin(x0) to the
+ * left of x we have in our table, plus the distance of that value to the closest number
+ * to the right of x (sin(x1)) times the fractional distance of x to x0. Since the table
+ * is conveniently exactly 256 values, x0 is exactly the upper 8 bits of the fractional
+ * part of x, meaning all fractional bits below that represent exactly the distance we
+ * need to interpolate over. (There are 24 of them but we need to multiply them with
+ * 16-bit table values to fit exactly 32 bits, so we discard the lowest 8 bits.)
+ */
+ uint32_t val = (v1 << (FPMATH_SHIFT - 16)) +
+ (v2 - v1) * ((x.v >> (16 - TP2)) & 0xffff);
+
+ /*
+ * Just like the first integral bit told us whether we need to mirror horizontally, the
+ * second can tell us to mirror vertically. In 2.0-4.0, 6.0-8.0, etc. of the input range
+ * the sine is negative, and in 0.0-2.0, 4.0-6.0, etc. it is positive.
+ */
+ if (x.v & ((int64_t)2 << FPMATH_SHIFT))
+ return (fpmath_t){ .v = -(int64_t)val };
+ else
+ return (fpmath_t){ .v = val };
+}
--
To view, visit https://review.coreboot.org/c/coreboot/+/42993
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Id0f9c23980e36ce0ac0b7c5cd0bc66153bca1fd0
Gerrit-Change-Number: 42993
Gerrit-PatchSet: 1
Gerrit-Owner: Julius Werner <jwerner(a)chromium.org>
Gerrit-Reviewer: Hung-Te Lin <hungte(a)chromium.org>
Gerrit-Reviewer: Shelley Chen <shchen(a)google.com>
Gerrit-Reviewer: Yu-Ping Wu <yupingso(a)google.com>
Gerrit-MessageType: newchange
Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/43225 )
Change subject: mb/google/zork: Do not select VARIANT_SUPPORTS_PRE_V3_SCHEMATICS for Vilboz
......................................................................
mb/google/zork: Do not select VARIANT_SUPPORTS_PRE_V3_SCHEMATICS for Vilboz
This change drops the selection of VARIANT_SUPPORTS_PRE_V3_SCHEMATICS
for Vilboz since it did not have any build with pre-v3 schematics.
Change-Id: I3919ad43e1dae95a4fa71073e83865e92f30dfec
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
M src/mainboard/google/zork/Kconfig
1 file changed, 0 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/25/43225/1
diff --git a/src/mainboard/google/zork/Kconfig b/src/mainboard/google/zork/Kconfig
index 185303f..9abfc64 100644
--- a/src/mainboard/google/zork/Kconfig
+++ b/src/mainboard/google/zork/Kconfig
@@ -142,7 +142,6 @@
default y if BOARD_GOOGLE_MORPHIUS
default y if BOARD_GOOGLE_BERKNIP
default y if BOARD_GOOGLE_DALBOZ
- default y if BOARD_GOOGLE_VILBOZ
default n
help
Whether this variant supports pre-v3 version of schematics.
@@ -158,7 +157,6 @@
default 3 if BOARD_GOOGLE_MORPHIUS
default 2 if BOARD_GOOGLE_BERKNIP
default 3 if BOARD_GOOGLE_DALBOZ
- default 1 if BOARD_GOOGLE_VILBOZ
default 256
help
Minimum board version where the variant starts supporting
--
To view, visit https://review.coreboot.org/c/coreboot/+/43225
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I3919ad43e1dae95a4fa71073e83865e92f30dfec
Gerrit-Change-Number: 43225
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan(a)google.com>
Gerrit-MessageType: newchange
Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/43224 )
Change subject: mb/google/zork: Add helpers for v3 schematics and wifi power enable
......................................................................
mb/google/zork: Add helpers for v3 schematics and wifi power enable
This change adds following two helper functions:
1. variant_uses_v3_schematics() - Check whether the variant is using
v3 version of schematics.
2. variant_has_active_low_wifi_power() - Check whether the variant is
using active low power enable for WiFi.
In addition to this, Kconfig options are reorganized to add two new
configs - VARIANT_SUPPORTS_PRE_V3_SCHEMATICS and
VARIANT_SUPPORTS_WIFI_POWER_ACTIVE_HIGH. This allows the helper
functions to return `true` early without checking for board version.
Eventually, when a variant decides to drop support for pre-v3
schematics, it can be dropped from selecting
VARIANT_SUPPORTS_PRE_V3_SCHEMATICS. Similarly, when the variant
decides to drop support for active high power enable for WiFi, it can
be dropped from selecting VARIANT_SUPPORTS_WIFI_POWER_ACTIVE_HIGH.
Change-Id: I62851299e8dd7929a8e1e9a287389abd71c7706c
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
M src/mainboard/google/zork/Kconfig
M src/mainboard/google/zork/variants/baseboard/Makefile.inc
M src/mainboard/google/zork/variants/baseboard/gpio_baseboard_dalboz.c
M src/mainboard/google/zork/variants/baseboard/gpio_baseboard_trembyle.c
M src/mainboard/google/zork/variants/baseboard/helpers.c
M src/mainboard/google/zork/variants/baseboard/include/baseboard/variants.h
M src/mainboard/google/zork/variants/baseboard/ramstage_common.c
7 files changed, 90 insertions(+), 25 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/24/43224/1
diff --git a/src/mainboard/google/zork/Kconfig b/src/mainboard/google/zork/Kconfig
index 19225d7..185303f 100644
--- a/src/mainboard/google/zork/Kconfig
+++ b/src/mainboard/google/zork/Kconfig
@@ -135,8 +135,24 @@
help
Which board version did FW_CONFIG become valid in CBI.
+config VARIANT_SUPPORTS_PRE_V3_SCHEMATICS
+ bool
+ default y if BOARD_GOOGLE_TREMBYLE
+ default y if BOARD_GOOGLE_EZKINIL
+ default y if BOARD_GOOGLE_MORPHIUS
+ default y if BOARD_GOOGLE_BERKNIP
+ default y if BOARD_GOOGLE_DALBOZ
+ default y if BOARD_GOOGLE_VILBOZ
+ default n
+ help
+ Whether this variant supports pre-v3 version of schematics.
+ Eventually, when a variant moves to a point where it no
+ longer has to support pre-v3 schematics, `default y` entry
+ for it can be dropped.
+
config VARIANT_MIN_BOARD_ID_V3_SCHEMATICS
int
+ depends on VARIANT_SUPPORTS_PRE_V3_SCHEMATICS
default 4 if BOARD_GOOGLE_TREMBYLE
default 3 if BOARD_GOOGLE_EZKINIL
default 3 if BOARD_GOOGLE_MORPHIUS
@@ -144,11 +160,34 @@
default 3 if BOARD_GOOGLE_DALBOZ
default 1 if BOARD_GOOGLE_VILBOZ
default 256
+ help
+ Minimum board version where the variant starts supporting
+ v3 version of reference schematics.
+
+config VARIANT_SUPPORTS_WIFI_POWER_ACTIVE_HIGH
+ bool
+ default y if VARIANT_SUPPORTS_PRE_V3_SCHEMATICS
+ default y if BOARD_GOOGLE_BERKNIP
+ default y if BOARD_GOOGLE_VILBOZ
+ default n
+ help
+ Whether this variant supports active high power enable for
+ WiFi. For pre-v3 schematics, this is always true. There are
+ some variants which used v3 schematics, but did not pick up
+ the change for active low WiFi power enable. Those variants
+ will have to set this config to true. Eventually, when a
+ variant needs to only support v3 schematics with active low
+ power enable for WiFi, `default y` entry for it can be
+ dropped.
config VARIANT_MIN_BOARD_ID_WIFI_POWER_ACTIVE_LOW
int
+ depends on VARIANT_SUPPORTS_WIFI_POWER_ACTIVE_HIGH
default 3 if BOARD_GOOGLE_BERKNIP
default 2 if BOARD_GOOGLE_VILBOZ
default VARIANT_MIN_BOARD_ID_V3_SCHEMATICS
+ help
+ Minimum board version where the variant starts supporting
+ active low power enable for WiFi.
endif # BOARD_GOOGLE_BASEBOARD_TREMBYLE || BOARD_GOOGLE_BASEBOARD_DALBOZ
diff --git a/src/mainboard/google/zork/variants/baseboard/Makefile.inc b/src/mainboard/google/zork/variants/baseboard/Makefile.inc
index 2b0ee3c..c9e3657 100644
--- a/src/mainboard/google/zork/variants/baseboard/Makefile.inc
+++ b/src/mainboard/google/zork/variants/baseboard/Makefile.inc
@@ -1,10 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-or-later
bootblock-y += gpio_baseboard_common.c
+bootblock-y += helpers.c
bootblock-$(CONFIG_BOARD_GOOGLE_BASEBOARD_TREMBYLE) += gpio_baseboard_trembyle.c
bootblock-$(CONFIG_BOARD_GOOGLE_BASEBOARD_DALBOZ) += gpio_baseboard_dalboz.c
verstage-y += gpio_baseboard_common.c
+verstage-y += helpers.c
ifeq ($(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK),y)
verstage-$(CONFIG_BOARD_GOOGLE_BASEBOARD_TREMBYLE) += gpio_baseboard_trembyle.c
verstage-$(CONFIG_BOARD_GOOGLE_BASEBOARD_DALBOZ) += gpio_baseboard_dalboz.c
@@ -12,6 +14,7 @@
verstage-y += tpm_tis.c
romstage-y += gpio_baseboard_common.c
+romstage-y += helpers.c
romstage-$(CONFIG_BOARD_GOOGLE_BASEBOARD_TREMBYLE) += gpio_baseboard_trembyle.c
romstage-$(CONFIG_BOARD_GOOGLE_BASEBOARD_DALBOZ) += gpio_baseboard_dalboz.c
romstage-y += tpm_tis.c
diff --git a/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_dalboz.c b/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_dalboz.c
index 8e6124c..cdce5d3 100644
--- a/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_dalboz.c
+++ b/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_dalboz.c
@@ -181,10 +181,7 @@
const __weak
struct soc_amd_gpio *variant_romstage_gpio_table(size_t *size)
{
- uint32_t board_version;
-
- if (!google_chromeec_cbi_get_board_version(&board_version) &&
- (board_version >= CONFIG_VARIANT_MIN_BOARD_ID_V3_SCHEMATICS)) {
+ if (variant_uses_v3_schematics()) {
*size = ARRAY_SIZE(gpio_set_stage_rom_v3);
return gpio_set_stage_rom_v3;
}
@@ -260,9 +257,9 @@
gpio_set(GPIO_29, 0);
}
-static void wifi_power_reset_configure_v3(uint32_t board_version)
+static void wifi_power_reset_configure_v3(void)
{
- if (board_version >= CONFIG_VARIANT_MIN_BOARD_ID_WIFI_POWER_ACTIVE_LOW)
+ if (variant_has_active_low_wifi_power())
wifi_power_reset_configure_active_low_power();
else
wifi_power_reset_configure_active_high_power();
@@ -296,14 +293,11 @@
__weak void variant_pcie_power_reset_configure(void)
{
- uint32_t board_version;
-
/* Deassert PCIE_RST1_L */
gpio_set(GPIO_27, 1);
- if (!google_chromeec_cbi_get_board_version(&board_version) &&
- (board_version >= CONFIG_VARIANT_MIN_BOARD_ID_V3_SCHEMATICS))
- wifi_power_reset_configure_v3(board_version);
+ if (variant_uses_v3_schematics())
+ wifi_power_reset_configure_v3();
else
wifi_power_reset_configure_pre_v3();
}
diff --git a/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_trembyle.c b/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_trembyle.c
index 77a3212d..a0d3854 100644
--- a/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_trembyle.c
+++ b/src/mainboard/google/zork/variants/baseboard/gpio_baseboard_trembyle.c
@@ -171,10 +171,7 @@
const __weak
struct soc_amd_gpio *variant_romstage_gpio_table(size_t *size)
{
- uint32_t board_version;
-
- if (!google_chromeec_cbi_get_board_version(&board_version) &&
- (board_version >= CONFIG_VARIANT_MIN_BOARD_ID_V3_SCHEMATICS)) {
+ if (variant_uses_v3_schematics()) {
*size = ARRAY_SIZE(gpio_set_stage_rom_v3);
return gpio_set_stage_rom_v3;
}
@@ -250,9 +247,9 @@
gpio_set(GPIO_86, 1);
}
-static void wifi_power_reset_configure_v3(uint32_t board_version)
+static void wifi_power_reset_configure_v3(void)
{
- if (board_version >= CONFIG_VARIANT_MIN_BOARD_ID_WIFI_POWER_ACTIVE_LOW)
+ if (variant_has_active_low_wifi_power())
wifi_power_reset_configure_active_low_power();
else
wifi_power_reset_configure_active_high_power();
@@ -286,11 +283,8 @@
__weak void variant_pcie_power_reset_configure(void)
{
- uint32_t board_version;
-
- if (!google_chromeec_cbi_get_board_version(&board_version) &&
- (board_version >= CONFIG_VARIANT_MIN_BOARD_ID_V3_SCHEMATICS))
- wifi_power_reset_configure_v3(board_version);
+ if (variant_uses_v3_schematics())
+ wifi_power_reset_configure_v3();
else
wifi_power_reset_configure_pre_v3();
}
diff --git a/src/mainboard/google/zork/variants/baseboard/helpers.c b/src/mainboard/google/zork/variants/baseboard/helpers.c
index 06cc9ad..0a1cf5c 100644
--- a/src/mainboard/google/zork/variants/baseboard/helpers.c
+++ b/src/mainboard/google/zork/variants/baseboard/helpers.c
@@ -113,3 +113,35 @@
{
return !!extract_field(FW_CONFIG_MASK_NVME, FW_CONFIG_SHIFT_NVME);
}
+
+bool variant_uses_v3_schematics(void)
+{
+ uint32_t board_version;
+
+ if (!CONFIG(VARIANT_SUPPORTS_PRE_V3_SCHEMATICS))
+ return true;
+
+ if (google_chromeec_cbi_get_board_version(&board_version))
+ return false;
+
+ if ((int)board_version < CONFIG_VARIANT_MIN_BOARD_ID_V3_SCHEMATICS)
+ return false;
+
+ return true;
+}
+
+bool variant_has_active_low_wifi_power(void)
+{
+ uint32_t board_version;
+
+ if (!CONFIG(VARIANT_SUPPORTS_WIFI_POWER_ACTIVE_HIGH))
+ return true;
+
+ if (google_chromeec_cbi_get_board_version(&board_version))
+ return false;
+
+ if ((int)board_version < CONFIG_VARIANT_MIN_BOARD_ID_WIFI_POWER_ACTIVE_LOW)
+ return false;
+
+ return true;
+}
diff --git a/src/mainboard/google/zork/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/zork/variants/baseboard/include/baseboard/variants.h
index ac29b92..14123d5 100644
--- a/src/mainboard/google/zork/variants/baseboard/include/baseboard/variants.h
+++ b/src/mainboard/google/zork/variants/baseboard/include/baseboard/variants.h
@@ -63,4 +63,9 @@
/* Determine if booting in factory by using CROS_SKU_UNPROVISIONED. */
int boot_is_factory_unprovisioned(void);
+/* Return true if variant uses v3 version of reference schematics. */
+bool variant_uses_v3_schematics(void);
+/* Return true if variant has active low power enable fow WiFi. */
+bool variant_has_active_low_wifi_power(void);
+
#endif /* __BASEBOARD_VARIANTS_H__ */
diff --git a/src/mainboard/google/zork/variants/baseboard/ramstage_common.c b/src/mainboard/google/zork/variants/baseboard/ramstage_common.c
index 6372af6..143c1b4 100644
--- a/src/mainboard/google/zork/variants/baseboard/ramstage_common.c
+++ b/src/mainboard/google/zork/variants/baseboard/ramstage_common.c
@@ -8,11 +8,9 @@
void variant_audio_update(void)
{
struct soc_amd_picasso_config *cfg = config_of_soc();
- uint32_t board_version;
struct acpi_gpio *gpio = &cfg->dmic_select_gpio;
- if (!google_chromeec_cbi_get_board_version(&board_version) &&
- (board_version >= CONFIG_VARIANT_MIN_BOARD_ID_V3_SCHEMATICS))
+ if (!variant_uses_v3_schematics())
return;
if (CONFIG(BOARD_GOOGLE_BASEBOARD_TREMBYLE))
--
To view, visit https://review.coreboot.org/c/coreboot/+/43224
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I62851299e8dd7929a8e1e9a287389abd71c7706c
Gerrit-Change-Number: 43224
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan(a)google.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-MessageType: newchange
Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/43222 )
Change subject: mb/google/zork: Do not share "write protect" information with depthcharge
......................................................................
mb/google/zork: Do not share "write protect" information with depthcharge
This change removes "write protect" entry from the list of GPIOs
shared with depthcharge as done for other Chrome OS boards in CB:39318.
Change-Id: Ibd39e8d6835e465b2ab5eebcc245e45db5d84deb
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
M src/mainboard/google/zork/chromeos.c
1 file changed, 0 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/22/43222/1
diff --git a/src/mainboard/google/zork/chromeos.c b/src/mainboard/google/zork/chromeos.c
index 2256ef2..b581b90 100644
--- a/src/mainboard/google/zork/chromeos.c
+++ b/src/mainboard/google/zork/chromeos.c
@@ -8,7 +8,6 @@
void fill_lb_gpios(struct lb_gpios *gpios)
{
struct lb_gpio chromeos_gpios[] = {
- {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"},
{-1, ACTIVE_HIGH, get_lid_switch(), "lid"},
{-1, ACTIVE_HIGH, 0, "power"},
{GPIO_EC_IN_RW, ACTIVE_HIGH, gpio_get(GPIO_EC_IN_RW),
--
To view, visit https://review.coreboot.org/c/coreboot/+/43222
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ibd39e8d6835e465b2ab5eebcc245e45db5d84deb
Gerrit-Change-Number: 43222
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan(a)google.com>
Gerrit-MessageType: newchange