sb/intel/ibexpeak: Implement USB current settings

This is based on the sandybridge settings.
The current lookup table comes from the x201 vendor lookup table.

Tested: USB mouse and webcam still work and current registers are the
same as before. USB IR are not but the code follows EDS instead of the
register replay.

Change-Id: Icea9673623a62e7039d5700100a2ee238478abd1
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/35762
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Arthur Heymans 2019-10-02 17:13:02 +02:00
parent d9ceb9deb4
commit 39f8a1aaf9
5 changed files with 165 additions and 47 deletions

View File

@ -61,6 +61,24 @@ static void pch_enable_lpc(void)
pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR); pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR);
} }
const struct southbridge_usb_port mainboard_usb_ports[] = {
/* Enabled, Current table lookup index, OC map */
{ 1, IF1_557, 0 },
{ 1, IF1_55F, 1 },
{ 1, IF1_74B, 3 },
{ 1, IF1_74B, 3 },
{ 1, IF1_557, 3 },
{ 1, IF1_14B, 3 },
{ 1, IF1_74B, 3 },
{ 1, IF1_74B, 3 },
{ 1, IF1_74B, 4 },
{ 1, IF1_74B, 5 },
{ 1, IF1_55F, 7 },
{ 1, IF1_55F, 7 },
{ 1, IF1_557, 7 },
{ 1, IF1_55F, 7 },
};
static void rcba_config(void) static void rcba_config(void)
{ {
southbridge_configure_default_intmap(); southbridge_configure_default_intmap();
@ -73,29 +91,7 @@ static void rcba_config(void)
/* Set reserved bit to 1 */ /* Set reserved bit to 1 */
RCBA32(FD2) = 1; RCBA32(FD2) = 1;
static const u32 rcba_dump3[] = { early_usb_init(mainboard_usb_ports);
/* 3500 */ 0x20000557, 0x2000055f, 0x2000074b, 0x2000074b,
/* 3510 */ 0x20000557, 0x2000014b, 0x2000074b, 0x2000074b,
/* 3520 */ 0x2000074b, 0x2000074b, 0x2000055f, 0x2000055f,
/* 3530 */ 0x20000557, 0x2000055f, 0x00000000, 0x00000000,
/* 3540 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 3550 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 3560 */ 0x00000001, 0x000026a3, 0x00040002, 0x01000052,
/* 3570 */ 0x02000772, 0x16000f8f, 0x1800ff4f, 0x0001d630,
/* 3580 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 3590 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35a0 */ 0xfc000201, 0x3c000201, 0x00000000, 0x00000000,
/* 35b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
};
unsigned i;
for (i = 0; i < sizeof(rcba_dump3) / 4; i++) {
RCBA32(4 * i + 0x3500) = rcba_dump3[i];
(void)RCBA32(4 * i + 0x3500);
}
} }
static inline void write_acpi32(u32 addr, u32 val) static inline void write_acpi32(u32 addr, u32 val)

View File

@ -56,6 +56,25 @@ static void pch_enable_lpc(void)
pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR); pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR);
} }
/* Seems copied from Lenovo Thinkpad x201, might be wrong */
const struct southbridge_usb_port mainboard_usb_ports[] = {
/* Enabled, Current table lookup index, OC map */
{ 1, IF1_557, 0 },
{ 1, IF1_55F, 1 },
{ 1, IF1_74B, 3 },
{ 1, IF1_74B, 3 },
{ 1, IF1_557, 3 },
{ 1, IF1_14B, 3 },
{ 1, IF1_74B, 3 },
{ 1, IF1_74B, 3 },
{ 1, IF1_74B, 4 },
{ 1, IF1_74B, 5 },
{ 1, IF1_55F, 7 },
{ 1, IF1_55F, 7 },
{ 1, IF1_557, 7 },
{ 1, IF1_55F, 7 },
};
static void rcba_config(void) static void rcba_config(void)
{ {
southbridge_configure_default_intmap(); southbridge_configure_default_intmap();
@ -68,30 +87,7 @@ static void rcba_config(void)
/* Set reserved bit to 1 */ /* Set reserved bit to 1 */
RCBA32(FD2) = 1; RCBA32(FD2) = 1;
static const u32 rcba_dump3[] = { early_usb_init(mainboard_usb_ports);
/* 3500 */ 0x20000557, 0x2000055f, 0x2000074b, 0x2000074b,
/* 3510 */ 0x20000557, 0x2000014b, 0x2000074b, 0x2000074b,
/* 3520 */ 0x2000074b, 0x2000074b, 0x2000055f, 0x2000055f,
/* 3530 */ 0x20000557, 0x2000055f, 0x00000000, 0x00000000,
/* 3540 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 3550 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 3560 */ 0x00000001, 0x000026a3, 0x00040002, 0x01000052,
/* 3570 */ 0x02000772, 0x16000f8f, 0x1800ff4f, 0x0001d630,
/* 3580 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 3590 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35a0 */ 0xfc000201, 0x3c000201, 0x00000000, 0x00000000,
/* 35b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* 35f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
};
unsigned i;
for (i = 0; i < sizeof(rcba_dump3) / 4; i++) {
RCBA32(4 * i + 0x3500) = rcba_dump3[i];
(void)RCBA32(4 * i + 0x3500);
}
} }
static inline void write_acpi32(u32 addr, u32 val) static inline void write_acpi32(u32 addr, u32 val)

View File

@ -43,5 +43,6 @@ romstage-y +=../bd82x6x/me_status.c
romstage-y += early_thermal.c romstage-y += early_thermal.c
romstage-y += ../bd82x6x/early_rcba.c romstage-y += ../bd82x6x/early_rcba.c
romstage-y += early_cir.c romstage-y += early_cir.c
romstage-y += early_usb.c
endif endif

View File

@ -0,0 +1,71 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2014 Vladimir Serbinenko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <device/mmio.h>
#include <device/pci_ops.h>
#include <device/pci_def.h>
#include <northbridge/intel/sandybridge/sandybridge.h>
#include <southbridge/intel/common/rcba.h>
#include <southbridge/intel/common/pmbase.h>
#include "pch.h"
#define TOTAL_USB_PORTS 14
void early_usb_init(const struct southbridge_usb_port *portmap)
{
u32 reg32;
const u16 currents[] = { 0xf57, 0xf5f, 0x753, 0x75f, 0x14b, 0x74b,
0x557, 0x757, 0x55f, 0x54b
};
int i;
/* Unlock registers. */
write_pmbase16(UPRWC, read_pmbase16(UPRWC) | UPRWC_WR_EN);
for (i = 0; i < TOTAL_USB_PORTS; i++)
RCBA32_AND_OR(USBIR0 + 4 * i, ~0xfff, currents[portmap[i].current]);
/* USB Initialization Registers. We follow what EDS recommends here.
TODO maybe vendor firmware values are better? */
RCBA32(USBIRC) &= ~(1 << 8);
RCBA32_OR(USBIRA, (7 << 12) | (7 << 8) | (7 << 4) | (2 << 0));
RCBA32_AND_OR(USBIRB, ~0x617f0, (3 << 17) | (1 << 12) | (1 << 10)
| (1 << 8) | (4 << 4));
/* Set to Rate Matching Hub Mode to make PCI devices appear. */
RCBA32(0x3598) = 0;
reg32 = 0;
for (i = 0; i < TOTAL_USB_PORTS; i++)
if (!portmap[i].enabled)
reg32 |= (1 << i);
RCBA32(USBPDO) = reg32;
reg32 = 0;
/* The OC pins of the first 8 USB ports are mapped in USBOCM1 */
for (i = 0; i < 8; i++)
if (portmap[i].enabled && portmap[i].oc_pin >= 0)
reg32 |= (1 << (i + 8 * portmap[i].oc_pin));
RCBA32(USBOCM1) = reg32;
reg32 = 0;
/* The OC pins of the remainder 6 USB ports are mapped in USBOCM2 */
for (i = 8; i < TOTAL_USB_PORTS; i++)
if (portmap[i].enabled && portmap[i].oc_pin >= 4)
reg32 |= (1 << (i - 8 + 8 * (portmap[i].oc_pin - 4)));
RCBA32(USBOCM2) = reg32;
/* Relock registers. */
write_pmbase16(UPRWC, 0);
}

View File

@ -66,6 +66,26 @@ void early_thermal_init(void);
void southbridge_configure_default_intmap(void); void southbridge_configure_default_intmap(void);
void pch_setup_cir(int chipset_type); void pch_setup_cir(int chipset_type);
enum current_lookup_idx {
IF1_F57 = 0,
IF1_F5F,
IF1_753,
IF1_75F,
IF1_14B,
IF1_74B,
IF1_557,
IF1_757,
IF1_55F,
IF1_54B,
};
struct southbridge_usb_port {
int enabled;
enum current_lookup_idx current;
int oc_pin;
};
void early_usb_init(const struct southbridge_usb_port *portmap);
#ifndef __ROMCC__ #ifndef __ROMCC__
#include <device/device.h> #include <device/device.h>
void pch_enable(struct device *dev); void pch_enable(struct device *dev);
@ -75,6 +95,10 @@ void pch_enable(struct device *dev);
#define MAINBOARD_POWER_ON 1 #define MAINBOARD_POWER_ON 1
#define MAINBOARD_POWER_KEEP 2 #define MAINBOARD_POWER_KEEP 2
/* PM I/O Space */
#define UPRWC 0x3c
#define UPRWC_WR_EN (1 << 1) /* USB Per-Port Registers Write Enable */
/* PCI Configuration Space (D30:F0): PCI2PCI */ /* PCI Configuration Space (D30:F0): PCI2PCI */
#define PSTS 0x06 #define PSTS 0x06
#define SMLT 0x1b #define SMLT 0x1b
@ -401,6 +425,36 @@ void pch_enable(struct device *dev);
#define PCH_DISABLE_MEI1 (1 << 1) #define PCH_DISABLE_MEI1 (1 << 1)
#define PCH_ENABLE_DBDF (1 << 0) #define PCH_ENABLE_DBDF (1 << 0)
/* USB Initialization Registers[13:0] */
#define USBIR0 0x3500 /* 32bit */
#define USBIR1 0x3504 /* 32bit */
#define USBIR2 0x3508 /* 32bit */
#define USBIR3 0x350c /* 32bit */
#define USBIR4 0x3510 /* 32bit */
#define USBIR5 0x3514 /* 32bit */
#define USBIR6 0x3518 /* 32bit */
#define USBIR7 0x351c /* 32bit */
#define USBIR8 0x3520 /* 32bit */
#define USBIR9 0x3524 /* 32bit */
#define USBIR10 0x3528 /* 32bit */
#define USBIR11 0x352c /* 32bit */
#define USBIR12 0x3530 /* 32bit */
#define USBIR13 0x3534 /* 32bit */
#define USBIRC 0x3564 /* 32bit */
#define USBIRA 0x3570 /* 32bit */
#define USBIRB 0x357c /* 32bit */
/* Miscellaneous Control Register */
#define MISCCTL 0x3590 /* 32bit */
/* USB Port Disable Override */
#define USBPDO 0x359c /* 32bit */
/* USB Overcurrent MAP Register */
#define USBOCM1 0x35a0 /* 32bit */
#define USBOCM2 0x35a4 /* 32bit */
/* Rate Matching Hub Wake Control Register */
#define RMHWKCTL 0x35b0 /* 32bit */
/* ICH7 PMBASE */ /* ICH7 PMBASE */
#define PM1_STS 0x00 #define PM1_STS 0x00
#define WAK_STS (1 << 15) #define WAK_STS (1 << 15)