Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7001
-gerrit
commit 62383213530806a20d4250a80e810dfba8b40e56
Author: Shawn Nematbakhsh <shawnn(a)chromium.org>
Date: Mon Mar 10 14:12:29 2014 -0700
libpayload: usb: Remove generic roothub reset port function
The generic roothub reset port function is overly broad and does some
things which may be undesirable, such as issuing multiple resets to a
port if the reset is deemed to have finished too quickly. Remove the
generic function and replace it with a controller-specific function,
currently only implemented for xhci.
Change-Id: Id46f73ea3341d4d01d2b517c6bf687402022d272
Signed-off-by: Shawn Nematbakhsh <shawnn(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/189495
Reviewed-by: Julius Werner <jwerner(a)chromium.org>
(cherry picked from commit 54e1da075b0106b0a1f736641fa52c39401d349d)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
payloads/libpayload/drivers/usb/generic_hub.c | 34 +--------------------------
payloads/libpayload/drivers/usb/generic_hub.h | 5 +++-
payloads/libpayload/drivers/usb/xhci_rh.c | 16 ++++++++++---
3 files changed, 18 insertions(+), 37 deletions(-)
diff --git a/payloads/libpayload/drivers/usb/generic_hub.c b/payloads/libpayload/drivers/usb/generic_hub.c
index fa95969..9f86705 100644
--- a/payloads/libpayload/drivers/usb/generic_hub.c
+++ b/payloads/libpayload/drivers/usb/generic_hub.c
@@ -93,7 +93,7 @@ generic_hub_debounce(usbdev_t *const dev, const int port)
return 0; /* ignore timeouts, try to always go on */
}
-static int
+int
generic_hub_wait_for_port(usbdev_t *const dev, const int port,
const int wait_for,
int (*const port_op)(usbdev_t *, int),
@@ -135,38 +135,6 @@ generic_hub_resetport(usbdev_t *const dev, const int port)
return 0; /* ignore timeouts, try to always go on */
}
-int
-generic_hub_rh_resetport(usbdev_t *const dev, const int port)
-{
- generic_hub_t *const hub = GEN_HUB(dev);
-
- /*
- * Resetting a root hub port should hold 50ms with pulses of at
- * least 10ms and gaps of at most 3ms (usb20 spec 7.1.7.5).
- * After reset, the port will be enabled automatically.
- */
- int total = 500; /* 500 * 100us = 50ms */
- while (total > 0) {
- if (hub->ops->start_port_reset(dev, port) < 0)
- return -1;
-
- /* wait 100ms for the hub to finish the reset pulse */
- const int timeout = generic_hub_wait_for_port(
- /* time out after 1000 * 100us = 100ms */
- dev, port, 0, hub->ops->port_in_reset, 1000, 100);
- const int reset_time = 1000 - timeout;
- if (timeout < 0)
- return -1;
- else if (!timeout)
- usb_debug("generic_hub: Reset timed out at port %d\n",
- port);
- else if (reset_time < 100) /* i.e. < 100 * 100us */
- usb_debug("generic_hub: Port reset too short\n");
- total -= reset_time;
- }
- return 0; /* ignore timeouts, try to always go on */
-}
-
static int
generic_hub_detach_dev(usbdev_t *const dev, const int port)
{
diff --git a/payloads/libpayload/drivers/usb/generic_hub.h b/payloads/libpayload/drivers/usb/generic_hub.h
index cd4ebb6..21536c0 100644
--- a/payloads/libpayload/drivers/usb/generic_hub.h
+++ b/payloads/libpayload/drivers/usb/generic_hub.h
@@ -72,8 +72,11 @@ typedef struct generic_hub {
} generic_hub_t;
void generic_hub_destroy(usbdev_t *);
+int generic_hub_wait_for_port(usbdev_t *const dev, const int port,
+ const int wait_for,
+ int (*const port_op)(usbdev_t *, int),
+ int timeout_steps, const int step_us);
int generic_hub_resetport(usbdev_t *, int port);
-int generic_hub_rh_resetport(usbdev_t *, int port); /* root hubs have different timing requirements */
int generic_hub_scanport(usbdev_t *, int port);
/* the provided generic_hub_ops struct has to be static */
int generic_hub_init(usbdev_t *, int num_ports, const generic_hub_ops_t *);
diff --git a/payloads/libpayload/drivers/usb/xhci_rh.c b/payloads/libpayload/drivers/usb/xhci_rh.c
index c4cbeea..26bb4f9 100644
--- a/payloads/libpayload/drivers/usb/xhci_rh.c
+++ b/payloads/libpayload/drivers/usb/xhci_rh.c
@@ -100,12 +100,22 @@ xhci_rh_port_speed(usbdev_t *const dev, const int port)
}
static int
-xhci_rh_start_port_reset(usbdev_t *const dev, const int port)
+xhci_rh_reset_port(usbdev_t *const dev, const int port)
{
xhci_t *const xhci = XHCI_INST(dev->controller);
volatile u32 *const portsc = &xhci->opreg->prs[port - 1].portsc;
+ /* Trigger port reset. */
*portsc = (*portsc & PORTSC_RW_MASK) | PORTSC_PR;
+
+ /* Wait for port_in_reset == 0, up to 150 * 1000us = 150ms */
+ if (generic_hub_wait_for_port(dev, port, 0, xhci_rh_port_in_reset,
+ 150, 1000) == 0)
+ usb_debug("xhci_rh: Reset timed out at port %d\n", port);
+ else
+ /* Clear reset status bits, since port is out of reset. */
+ *portsc = (*portsc & PORTSC_RW_MASK) | PORTSC_PRC | PORTSC_WRC;
+
return 0;
}
@@ -118,8 +128,8 @@ static const generic_hub_ops_t xhci_rh_ops = {
.port_speed = xhci_rh_port_speed,
.enable_port = NULL,
.disable_port = NULL,
- .start_port_reset = xhci_rh_start_port_reset,
- .reset_port = generic_hub_rh_resetport,
+ .start_port_reset = NULL,
+ .reset_port = xhci_rh_reset_port,
};
void
Paul Menzel (paulepanter(a)users.sourceforge.net) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6995
-gerrit
commit 52559a3989718502f71e2336ed0a2702db8d1844
Author: Hung-Te Lin <hungte(a)chromium.org>
Date: Thu Apr 3 18:35:58 2014 +0800
edid: Fix extension parsing when EDID blob does not have any extensions.
When parsing "extensions", we should skip the first EDID (main) block and start
from offset 128 (EDID may have only main block, so an EDID without any
extension is fine) because the header format for main block and extensions are
different.
Without this we will see "Unknown extension block" on all EDIDs, and seeing an
error (1) return value for EDIDs without extension.
Also, after the first "unknown" error is fixed, we can now collect all return
values from parse_extension, and return an error when any of the extensions are
wrong (not just last one).
Change-Id: I0ee029ac8ec6800687cd7749e23989399e721109
Signed-off-by: Hung-Te Lin <hungte(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/193011
(cherry picked from commit fdf0cc2e9573c19b550fa2b5e4e06337b114f864)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
src/lib/edid.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/lib/edid.c b/src/lib/edid.c
index 0dc86d5..6bd471a 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -1261,8 +1261,14 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
printk(BIOS_SPEW, "Checksum\n");
do_checksum(edid);
- for(i = 0; i < size; i += 128)
- nonconformant_extension = parse_extension(out, &edid[i]);
+
+ /* EDID v2.0 has a larger blob (256 bytes) and may have some problem in
+ * the extension parsing loop below. Since v2.0 was quickly deprecated
+ * by v1.3 and we are unlikely to use any EDID 2.0 panels, we ignore
+ * that case now and can fix it when we need to use a real 2.0 panel.
+ */
+ for(i = 128; i < size; i += 128)
+ nonconformant_extension += parse_extension(out, &edid[i]);
/*
* x = edid;
* for (edid_lines /= 8; edid_lines > 1; edid_lines--) {
Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6998
-gerrit
commit b1186c60aaa0314436f276654ce47281f1ebc41f
Author: Hung-Te Lin <hungte(a)chromium.org>
Date: Thu Apr 3 21:13:11 2014 +0800
edid: Support EDID 1.4.
EDID v1.4 has changed some fields (0xfc - Monitor Name, 0xfd - Monitor Range
Limits) to optional so we need to list the requirements explicitly instead of
sharing v1.3 requirements.
Change-Id: I5c7ca06893bd20e178bc35164c4ca639c881e00b
Signed-off-by: Hung-Te Lin <hungte(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/193013
(cherry picked from commit 2ad598b8bd620117e70e13347365d74a7c6b87ef)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
src/lib/edid.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/src/lib/edid.c b/src/lib/edid.c
index b171c8b..6efe6a9 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -1251,7 +1251,24 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
* }
*/
- if (claims_one_point_three) {
+ if (claims_one_point_four) {
+ if (nonconformant_digital_display ||
+ !has_valid_string_termination ||
+ !has_valid_descriptor_pad ||
+ !has_preferred_timing)
+ conformant = 0;
+ if (!conformant)
+ printk(BIOS_ERR, "EDID block does NOT conform to EDID 1.4!\n");
+ if (nonconformant_digital_display)
+ printk(BIOS_ERR, "\tDigital display field contains garbage: %x\n",
+ nonconformant_digital_display);
+ if (!has_valid_string_termination)
+ printk(BIOS_ERR, "\tDetailed block string not properly terminated\n");
+ if (!has_valid_descriptor_pad)
+ printk(BIOS_ERR, "\tInvalid descriptor block padding\n");
+ if (!has_preferred_timing)
+ printk(BIOS_ERR, "\tMissing preferred timing\n");
+ } else if (claims_one_point_three) {
if (nonconformant_digital_display ||
!has_valid_string_termination ||
!has_valid_descriptor_pad ||
Isaac Christensen (isaac.christensen(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6995
-gerrit
commit 095c784f66bb12647ea0eefe96782a3777d62088
Author: Hung-Te Lin <hungte(a)chromium.org>
Date: Thu Apr 3 18:35:58 2014 +0800
edid: Fix extension parsing when EDID blob does not have any extensions.
When parsing "extensions", we should skip the first EDID (main) block and start
from offset 128 (EDID may have only main block, so an EDID without any
extension is fine) because the header format for main block and extensions are
different.
Without this we will see "Unknown extension block" on all EDIDs, and seeing a
error (1) return value for EDIDs without extension.
Also, after the first "unknown" error is fixed, we can now collect all return
values from parse_extension, and give error when any of the extensions are wrong
(not just last one).
Change-Id: I0ee029ac8ec6800687cd7749e23989399e721109
Signed-off-by: Hung-Te Lin <hungte(a)chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/193011
(cherry picked from commit fdf0cc2e9573c19b550fa2b5e4e06337b114f864)
Signed-off-by: Isaac Christensen <isaac.christensen(a)se-eng.com>
---
src/lib/edid.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/lib/edid.c b/src/lib/edid.c
index 0dc86d5..6bd471a 100644
--- a/src/lib/edid.c
+++ b/src/lib/edid.c
@@ -1261,8 +1261,14 @@ int decode_edid(unsigned char *edid, int size, struct edid *out)
printk(BIOS_SPEW, "Checksum\n");
do_checksum(edid);
- for(i = 0; i < size; i += 128)
- nonconformant_extension = parse_extension(out, &edid[i]);
+
+ /* EDID v2.0 has a larger blob (256 bytes) and may have some problem in
+ * the extension parsing loop below. Since v2.0 was quickly deprecated
+ * by v1.3 and we are unlikely to use any EDID 2.0 panels, we ignore
+ * that case now and can fix it when we need to use a real 2.0 panel.
+ */
+ for(i = 128; i < size; i += 128)
+ nonconformant_extension += parse_extension(out, &edid[i]);
/*
* x = edid;
* for (edid_lines /= 8; edid_lines > 1; edid_lines--) {