From a0ab764519f70f524a77c6fb02bf56f29d4f9325 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Tue, 28 Nov 2017 14:15:51 -0800 Subject: 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 Reviewed-on: https://review.coreboot.org/22623 Reviewed-by: Aaron Durbin Tested-by: build bot (Jenkins) --- src/mainboard/google/fizz/mainboard.c | 107 +++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/mainboard/google/fizz/mainboard.c b/src/mainboard/google/fizz/mainboard.c index ce60283eaf..98c00782f7 100644 --- a/src/mainboard/google/fizz/mainboard.c +++ b/src/mainboard/google/fizz/mainboard.c @@ -37,9 +37,64 @@ */ #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_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 * @@ -50,25 +105,16 @@ static const char *oem_table_id = "FIZZ"; */ 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; u32 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 (rv != 0 || type != USB_CHG_TYPE_PD) { /* using the barrel jack, get PL2 based on sku id */ watts = FIZZ_PL2_OTHERS; - sku_id = gpio_base2_value(sku_id_gpios, - ARRAY_SIZE(sku_id_gpios)); - if (sku_id == FIZZ_SKU_ID_I7_U42) + if (board_sku_id() == FIZZ_SKU_ID_I7_U42) watts = FIZZ_PL2_I7_U42; } else watts = GET_TYPEC_PL2(watts); @@ -78,16 +124,15 @@ static u32 mainboard_get_pl2(void) static uint8_t board_oem_id(void) { - static int board_oem_id = -1; + static int id = -1; const gpio_t oem_id_gpios[] = { GPIO_OEM_ID1, GPIO_OEM_ID2, GPIO_OEM_ID3, }; - if (board_oem_id < 0) - board_oem_id = gpio_base2_value(oem_id_gpios, - ARRAY_SIZE(oem_id_gpios)); - return board_oem_id; + if (id < 0) + id = gpio_base2_value(oem_id_gpios, ARRAY_SIZE(oem_id_gpios)); + return id; } const char *smbios_mainboard_sku(void) @@ -130,6 +175,36 @@ static unsigned long mainboard_write_acpi_tables( 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) { device_t root = SA_DEV_ROOT; @@ -137,6 +212,8 @@ static void mainboard_enable(device_t dev) conf->tdp_pl2_override = mainboard_get_pl2(); + set_bj_adapter_limit(); + dev->ops->init = mainboard_init; dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator; dev->ops->write_acpi_tables = mainboard_write_acpi_tables; -- cgit v1.2.3