google/fizz: Set BJ max current and voltage

This patch makes coreboot set the max current and voltage for barrel jack
adapters.

BUG=b:64442692
BRANCH=none
TEST=Boot Fizz. Use chgsup console command to verify the max current and
voltage are set as expected.

Change-Id: Ifebee09096e0935cc7d3e53920a251b0496d3c55
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://review.coreboot.org/22623
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Daisuke Nojiri 2017-11-28 14:15:51 -08:00 committed by Aaron Durbin
parent 93fd8fa40f
commit a0ab764519
1 changed files with 92 additions and 15 deletions

View File

@ -37,9 +37,64 @@
*/ */
#define GET_TYPEC_PL2(w) (9 * (w) / 10) #define GET_TYPEC_PL2(w) (9 * (w) / 10)
#define OEM_ID_COUNT 3
#define SKU_ID_COUNT 7
/* List of BJ adapters shipped with Fizz or its variants */
enum bj_adapter {
BJ_UNKNOWN,
BJ_65W_19V,
BJ_90W_19V,
BJ_65W_19P5V,
BJ_90W_19P5V,
BJ_COUNT,
};
/* BJ adapter specs */
static const struct {
uint16_t current_lim; /* in mA */
uint16_t voltage_lim; /* in mV */
} bj_adapters[] = {
[BJ_65W_19V] = { .current_lim = 3420, .voltage_lim = 19000 },
[BJ_90W_19V] = { .current_lim = 4740, .voltage_lim = 19000 },
[BJ_65W_19P5V] = { .current_lim = 3330, .voltage_lim = 19500 },
[BJ_90W_19P5V] = { .current_lim = 4620, .voltage_lim = 19500 },
};
/*
* The table showing which device is shipped with which BJ adapter.
*
* | SKU0 SKU1 ...
* OEM0 | AdapterX AdapterZ ...
* OEM1 | AdapterY ...
* ... |
*/
static const enum bj_adapter bj_adapter_table[OEM_ID_COUNT][SKU_ID_COUNT] = {
{ BJ_65W_19P5V, BJ_65W_19P5V, BJ_90W_19P5V, BJ_90W_19P5V,
BJ_90W_19P5V, BJ_90W_19P5V, BJ_65W_19P5V },
{ BJ_65W_19V, BJ_65W_19V, BJ_UNKNOWN, BJ_UNKNOWN,
BJ_90W_19V, BJ_90W_19V, BJ_UNKNOWN },
{ BJ_65W_19V, BJ_65W_19V, BJ_90W_19V, BJ_90W_19V,
BJ_90W_19V, BJ_90W_19V, BJ_65W_19V },
};
static const char *oem_id = "GOOGLE"; static const char *oem_id = "GOOGLE";
static const char *oem_table_id = "FIZZ"; static const char *oem_table_id = "FIZZ";
static uint8_t board_sku_id(void)
{
static int id = -1;
const gpio_t sku_id_gpios[] = {
GPIO_SKU_ID0,
GPIO_SKU_ID1,
GPIO_SKU_ID2,
GPIO_SKU_ID3,
};
if (id < 0)
id = gpio_base2_value(sku_id_gpios, ARRAY_SIZE(sku_id_gpios));
return id;
}
/* /*
* mainboard_get_pl2 * mainboard_get_pl2
* *
@ -50,25 +105,16 @@ static const char *oem_table_id = "FIZZ";
*/ */
static u32 mainboard_get_pl2(void) static u32 mainboard_get_pl2(void)
{ {
const gpio_t sku_id_gpios[] = {
GPIO_SKU_ID0,
GPIO_SKU_ID1,
GPIO_SKU_ID2,
GPIO_SKU_ID3,
};
enum usb_chg_type type; enum usb_chg_type type;
u32 watts; u32 watts;
int rv = google_chromeec_get_usb_pd_power_info(&type, &watts); int rv = google_chromeec_get_usb_pd_power_info(&type, &watts);
int sku_id;
/* If we can't get charger info or not PD charger, assume barrel jack */ /* If we can't get charger info or not PD charger, assume barrel jack */
if (rv != 0 || type != USB_CHG_TYPE_PD) { if (rv != 0 || type != USB_CHG_TYPE_PD) {
/* using the barrel jack, get PL2 based on sku id */ /* using the barrel jack, get PL2 based on sku id */
watts = FIZZ_PL2_OTHERS; watts = FIZZ_PL2_OTHERS;
sku_id = gpio_base2_value(sku_id_gpios, if (board_sku_id() == FIZZ_SKU_ID_I7_U42)
ARRAY_SIZE(sku_id_gpios));
if (sku_id == FIZZ_SKU_ID_I7_U42)
watts = FIZZ_PL2_I7_U42; watts = FIZZ_PL2_I7_U42;
} else } else
watts = GET_TYPEC_PL2(watts); watts = GET_TYPEC_PL2(watts);
@ -78,16 +124,15 @@ static u32 mainboard_get_pl2(void)
static uint8_t board_oem_id(void) static uint8_t board_oem_id(void)
{ {
static int board_oem_id = -1; static int id = -1;
const gpio_t oem_id_gpios[] = { const gpio_t oem_id_gpios[] = {
GPIO_OEM_ID1, GPIO_OEM_ID1,
GPIO_OEM_ID2, GPIO_OEM_ID2,
GPIO_OEM_ID3, GPIO_OEM_ID3,
}; };
if (board_oem_id < 0) if (id < 0)
board_oem_id = gpio_base2_value(oem_id_gpios, id = gpio_base2_value(oem_id_gpios, ARRAY_SIZE(oem_id_gpios));
ARRAY_SIZE(oem_id_gpios)); return id;
return board_oem_id;
} }
const char *smbios_mainboard_sku(void) const char *smbios_mainboard_sku(void)
@ -130,6 +175,36 @@ static unsigned long mainboard_write_acpi_tables(
return end_addr; return end_addr;
} }
/*
* Set max current and voltage for a barrel jack adapter based on {OEM, SKU}.
* If this fails, the limit will remain unchanged = default values, which make
* the system run under safe but under-rated power.
* If a BJ adapter isn't plugged, this is a no-op.
*/
static void set_bj_adapter_limit(void)
{
uint8_t oem = board_oem_id();
uint8_t sku = board_sku_id();
enum bj_adapter bj;
if (oem >= OEM_ID_COUNT || sku >= SKU_ID_COUNT) {
printk(BIOS_ERR, "Unrecognized OEM or SKU: %d/%d\n", oem, sku);
return;
}
bj = bj_adapter_table[oem][sku];
if (bj <= BJ_UNKNOWN || BJ_COUNT <= bj) {
printk(BIOS_ERR, "Invalid BJ adapter ID: %d\n", bj);
return;
}
printk(BIOS_INFO, "Setting BJ limit: %dmA/%dmV\n",
bj_adapters[bj].current_lim, bj_adapters[bj].voltage_lim);
if (google_chromeec_override_dedicated_charger_limit(
bj_adapters[bj].current_lim,
bj_adapters[bj].voltage_lim))
printk(BIOS_ERR, "Failed to set BJ limit\n");
}
static void mainboard_enable(device_t dev) static void mainboard_enable(device_t dev)
{ {
device_t root = SA_DEV_ROOT; device_t root = SA_DEV_ROOT;
@ -137,6 +212,8 @@ static void mainboard_enable(device_t dev)
conf->tdp_pl2_override = mainboard_get_pl2(); conf->tdp_pl2_override = mainboard_get_pl2();
set_bj_adapter_limit();
dev->ops->init = mainboard_init; dev->ops->init = mainboard_init;
dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator; dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator;
dev->ops->write_acpi_tables = mainboard_write_acpi_tables; dev->ops->write_acpi_tables = mainboard_write_acpi_tables;