sb/intel/bd82x6x: Allow actual USBIRx values for native USB config

For USB to work under native code path, the USB port config needs to
include a current setting for each port, which gets mapped to an
initialization value that gets programmed into the USBIRx register
for the respective port. This map resides in early_usb.c.

The need to update it, whenever we see a previously unaccounted for
initialization value, is getting out of hand.

Instead this patch will allow specifying those values, presumably
taken from an inteltool dump while running vendor firmware,
directly in the USB port map.

Because all USBIRx values are always in the 0x20000yyy form, we only
need the lowest 12 bits. We have more than enough space in the USB
port config structure for this.

As the lowest yyy value we saw so far is 0x53, a note is included to
limit the map to not more than 80 entries. Any value that is too big
to be an index into the map is programmed directly, + 0x20000000, into
the registers.

This opens the future possibility to use the map for a simpler
mapping for boards also using MRC, and remove the need for any
mapping at all for the rest.

Change-Id: I3d79b33bac742faa9bd4fc9852aff73fe326de4e
Signed-off-by: Keith Hui <buurin@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/82655
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com>
diff --git a/src/southbridge/intel/bd82x6x/early_usb.c b/src/southbridge/intel/bd82x6x/early_usb.c
index 6d3d096..6667d47 100644
--- a/src/southbridge/intel/bd82x6x/early_usb.c
+++ b/src/southbridge/intel/bd82x6x/early_usb.c
@@ -16,6 +16,8 @@
 		/* 3560 */ 0x024c8001, 0x000024a3, 0x00040002, 0x01000050,
 		/* 3570 */ 0x02000772, 0x16000f9f, 0x1800ff4f, 0x0001d630,
 	};
+	/* Care should be taken to limit this array to not more than 80 (0x50) entries.
+	 * See below. */
 	const u32 currents[] = { USBIR_TXRX_GAIN_MOBILE_LOW, USBIR_TXRX_GAIN_DEFAULT,
 				 USBIR_TXRX_GAIN_HIGH, 0x20000f51, 0x2000094a, 0x2000035f,
 				 USBIR_TXRX_GAIN_DESKTOP_LOW, 0x20000357, 0x20000353,
@@ -26,6 +28,14 @@
 	write_pmbase16(UPRWC, read_pmbase16(UPRWC) | UPRWC_WR_EN);
 
 	for (i = 0; i < 14; i++) {
+		/*
+		 * If the value from devicetree is beyond the highest possible current map
+		 * index, it is meant to go directly into (bottom 12 bits of) USBIRx.
+		 */
+		if (portmap[i].current >= ARRAY_SIZE(currents)) {
+			RCBA32(USBIR0 + 4 * i) = 0x20000000 | (portmap[i].current & 0xfff);
+			continue;
+		}
 		if (portmap[i].enabled && !pch_is_mobile() &&
 		    currents[portmap[i].current] == USBIR_TXRX_GAIN_MOBILE_LOW) {
 			/*