Daisuke Nojiri has uploaded this change for review. ( https://review.coreboot.org/22620
Change subject: Fizz: Set BJ adapter limit ......................................................................
Fizz: Set BJ adapter limit
This patch makes coreboot set the max current and voltage for a barrel jack adapter.
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: I9b70725c7e2b37aab1e874e2969ea83324abfb42 Signed-off-by: Daisuke Nojiri dnojiri@chromium.org --- M src/ec/google/chromeec/ec.c M src/ec/google/chromeec/ec.h M src/ec/google/chromeec/ec_commands.h M src/mainboard/google/fizz/mainboard.c 4 files changed, 135 insertions(+), 10 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/22620/1
diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index 3d053b6..9bdf702 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -638,6 +638,26 @@ return 0; }
+int google_chromeec_override_dedicated_charger_limit(u16 current_lim, + u16 voltage_lim) +{ + struct ec_params_dedicated_charger_limit p = { + .current_lim = current_lim, + .voltage_lim = voltage_lim, + }; + struct chromeec_command cmd = { + .cmd_code = EC_CMD_OVERRIDE_DEDICATED_CHARGER_LIMIT, + .cmd_version = 0, + .cmd_data_in = &p, + .cmd_size_in = sizeof(p), + .cmd_data_out = NULL, + .cmd_size_out = 0, + .cmd_dev_index = 0, + }; + + return google_chromeec_command(&cmd); +} + int google_chromeec_set_usb_pd_role(u8 port, enum usb_pd_control_role role) { struct ec_params_usb_pd_control req = { diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 25a90d7..59f48d8 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -91,6 +91,16 @@ int google_chromeec_get_usb_pd_power_info(enum usb_chg_type *type, u32 *max_watts);
+/* + * Set max current and voltage of a dedicated charger. + * + * @param current_lim Max current in mA + * @param voltage_lim Max voltage in mV + * @return non-zero for error, otherwise 0. + */ +int google_chromeec_override_dedicated_charger_limit(u16 current_lim, + u16 voltage_lim); + /* internal structure to send a command to the EC and wait for response. */ struct chromeec_command { uint16_t cmd_code; /* command code in, status out */ diff --git a/src/ec/google/chromeec/ec_commands.h b/src/ec/google/chromeec/ec_commands.h index c4e4e31..17ac51e 100644 --- a/src/ec/google/chromeec/ec_commands.h +++ b/src/ec/google/chromeec/ec_commands.h @@ -3533,6 +3533,16 @@
#define EC_POWER_LIMIT_NONE 0xffff
+/* + * Set maximum voltage & current of a dedicated charge port + */ +#define EC_CMD_OVERRIDE_DEDICATED_CHARGER_LIMIT 0x00A3 + +struct __ec_align2 ec_params_dedicated_charger_limit { + uint16_t current_lim; /* in mA */ + uint16_t voltage_lim; /* in mV */ +}; + /*****************************************************************************/ /* Hibernate/Deep Sleep Commands */
diff --git a/src/mainboard/google/fizz/mainboard.c b/src/mainboard/google/fizz/mainboard.c index ae37675..319b1ed 100644 --- a/src/mainboard/google/fizz/mainboard.c +++ b/src/mainboard/google/fizz/mainboard.c @@ -35,8 +35,71 @@ */ #define GET_TYPEC_PL2(w) (9 * (w) / 10)
+/* Dev, Asus, HP, Acer, CfM */ +#define OEM_ID_COUNT 5 +/* Celeron-1, Celeron-2, i3, i5-2, i5-4, i7-2, i7-4 */ +#define SKU_ID_COUNT 7 + +/* List of BJ adapters shipped with Fizz or its variants */ +enum bj_adapter { + BJ_UNKNOWN, + BJ_PPP012C_S, + BJ_ADP_65HB_HCE, + BJ_PA_1650_30, + BJ_PA_1900_92, + BJ_COUNT, +}; + +/* BJ adapter specs */ +static const struct { + uint16_t current_lim; /* in mA */ + uint16_t voltage_lim; /* in mV */ +} bj_adapters[] = { + [BJ_PPP012C_S] = {4620, 19500}, + [BJ_ADP_65HB_HCE] = {3330, 19500}, + [BJ_PA_1650_30] = {3420, 19000}, + [BJ_PA_1900_92] = {4740, 19000}, +}; + +/* + * 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_PPP012C_S, BJ_ADP_65HB_HCE, BJ_PA_1650_30, BJ_PA_1900_92, + BJ_PA_1900_92, BJ_PA_1900_92, BJ_UNKNOWN}, + {BJ_PPP012C_S, BJ_ADP_65HB_HCE, BJ_PA_1650_30, BJ_PA_1900_92, + BJ_PA_1900_92, BJ_PA_1900_92, BJ_UNKNOWN}, + {BJ_PPP012C_S, BJ_ADP_65HB_HCE, BJ_PA_1650_30, BJ_PA_1900_92, + BJ_PA_1900_92, BJ_PA_1900_92, BJ_UNKNOWN}, + {BJ_PPP012C_S, BJ_ADP_65HB_HCE, BJ_PA_1650_30, BJ_PA_1900_92, + BJ_PA_1900_92, BJ_PA_1900_92, BJ_UNKNOWN}, + {BJ_PPP012C_S, BJ_ADP_65HB_HCE, BJ_PA_1650_30, BJ_PA_1900_92, + BJ_PA_1900_92, BJ_PA_1900_92, BJ_UNKNOWN}, +}; + static const char *oem_id = "GOOGLE"; static const char *oem_table_id = "FIZZ"; + + +static uint8_t board_sku_id(void) +{ + static int sku_id = -1; + const gpio_t sku_id_gpios[] = { + GPIO_SKU_ID0, + GPIO_SKU_ID1, + GPIO_SKU_ID2, + GPIO_SKU_ID3, + }; + if (sku_id < 0) + sku_id = gpio_base2_value(sku_id_gpios, + ARRAY_SIZE(sku_id_gpios)); + return sku_id; +}
/* * mainboard_get_pl2 @@ -48,25 +111,16 @@ */ 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); @@ -105,6 +159,35 @@ 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); + google_chromeec_override_dedicated_charger_limit( + bj_adapters[bj].current_lim, + bj_adapters[bj].voltage_lim); +} + static void mainboard_enable(device_t dev) { device_t tpm; @@ -113,6 +196,8 @@
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;