summaryrefslogtreecommitdiff
path: root/board/aurash/board.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/aurash/board.c')
-rw-r--r--board/aurash/board.c296
1 files changed, 124 insertions, 172 deletions
diff --git a/board/aurash/board.c b/board/aurash/board.c
index 742cb97ad9..64a8ca6015 100644
--- a/board/aurash/board.c
+++ b/board/aurash/board.c
@@ -2,11 +2,13 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+
#include "adc.h"
#include "builtin/assert.h"
#include "button.h"
#include "charge_manager.h"
#include "charge_state_v2.h"
+#include "chipset.h"
#include "common.h"
#include "compile_time_macros.h"
#include "console.h"
@@ -31,6 +33,32 @@ static void power_monitor(void);
DECLARE_DEFERRED(power_monitor);
/******************************************************************************/
+/* Power on by HDMI/ DP monitor */
+struct monitor_config {
+ enum gpio_signal gpio;
+ uint8_t state;
+};
+
+static struct monitor_config monitors[MONITOR_COUNT] = {
+ [HDMI1_MONITOR] = {
+ .gpio = GPIO_HDMI1_MONITOR_ON,
+ .state = MONITOR_OFF,
+ },
+
+ [HDMI2_MONITOR] = {
+ .gpio = GPIO_HDMI2_MONITOR_ON,
+ .state = MONITOR_OFF,
+ },
+
+ [OPTION_MONITOR] = {
+ .gpio = GPIO_OPTION_MONITOR_ON,
+ .state = MONITOR_OFF,
+ },
+};
+
+/******************************************************************************/
+
+/******************************************************************************/
/* USB-A charging control */
const int usb_port_enable[USB_PORT_COUNT] = {
@@ -88,7 +116,6 @@ int board_set_active_charge_port(int port)
switch (port) {
case CHARGE_PORT_TYPEC0:
case CHARGE_PORT_TYPEC1:
- case CHARGE_PORT_TYPEC2:
gpio_set_level(GPIO_EN_PPVAR_BJ_ADP_L, 1);
break;
case CHARGE_PORT_BARRELJACK:
@@ -105,92 +132,6 @@ int board_set_active_charge_port(int port)
}
static uint8_t usbc_overcurrent;
-static int32_t base_5v_power_s5;
-static int32_t base_5v_power_z1;
-
-/*
- * Power usage for each port as measured or estimated.
- * Units are milliwatts (5v x ma current)
- */
-
-/* PP5000_S5 loads */
-#define PWR_S5_BASE_LOAD (5 * 1431)
-#define PWR_S5_FRONT_HIGH (5 * 1737)
-#define PWR_S5_FRONT_LOW (5 * 1055)
-#define PWR_S5_REAR_HIGH (5 * 1737)
-#define PWR_S5_REAR_LOW (5 * 1055)
-#define PWR_S5_HDMI (5 * 580)
-#define PWR_S5_MAX (5 * 10000)
-#define FRONT_DELTA (PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW)
-#define REAR_DELTA (PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW)
-
-/* PP5000_Z1 loads */
-#define PWR_Z1_BASE_LOAD (5 * 5)
-#define PWR_Z1_C_HIGH (5 * 3600)
-#define PWR_Z1_C_LOW (5 * 2000)
-#define PWR_Z1_MAX (5 * 9000)
-/*
- * Update the 5V power usage, assuming no throttling,
- * and invoke the power monitoring.
- */
-static void update_5v_usage(void)
-{
- int front_ports = 0;
- int rear_ports = 0;
-
- /*
- * Recalculate the 5V load, assuming no throttling.
- */
- base_5v_power_s5 = PWR_S5_BASE_LOAD;
- if (!gpio_get_level(GPIO_USB_A0_OC_ODL)) {
- front_ports++;
- base_5v_power_s5 += PWR_S5_FRONT_LOW;
- }
- if (!gpio_get_level(GPIO_USB_A1_OC_ODL)) {
- front_ports++;
- base_5v_power_s5 += PWR_S5_FRONT_LOW;
- }
- /*
- * Only 1 front port can run higher power at a time.
- */
- if (front_ports > 0)
- base_5v_power_s5 += PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW;
-
- if (!gpio_get_level(GPIO_USB_A2_OC_ODL)) {
- rear_ports++;
- base_5v_power_s5 += PWR_S5_REAR_LOW;
- }
- if (!gpio_get_level(GPIO_USB_A3_OC_ODL)) {
- rear_ports++;
- base_5v_power_s5 += PWR_S5_REAR_LOW;
- }
- /*
- * Only 1 rear port can run higher power at a time.
- */
- if (rear_ports > 0)
- base_5v_power_s5 += PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW;
- if (!gpio_get_level(GPIO_HDMI_CONN_OC_ODL))
- base_5v_power_s5 += PWR_S5_HDMI;
- base_5v_power_z1 = PWR_Z1_BASE_LOAD;
- if (usbc_overcurrent)
- base_5v_power_z1 += PWR_Z1_C_HIGH;
- /*
- * Invoke the power handler immediately.
- */
- hook_call_deferred(&power_monitor_data, 0);
-}
-DECLARE_DEFERRED(update_5v_usage);
-/*
- * Start power monitoring after ADCs have been initialised.
- */
-DECLARE_HOOK(HOOK_INIT, update_5v_usage, HOOK_PRIO_INIT_ADC + 1);
-
-static void port_ocp_interrupt(enum gpio_signal signal)
-{
- hook_call_deferred(&update_5v_usage_data, 0);
-}
-/* Must come after other header files and interrupt handler declarations */
-#include "gpio_list.h"
/******************************************************************************/
/*
@@ -216,6 +157,7 @@ static void adp_connect_deferred(void)
return;
if (connected)
ec_bj_power(&pi.voltage, &pi.current);
+
charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED,
DEDICATED_CHARGE_PORT, &pi);
adp_connected = connected;
@@ -247,12 +189,29 @@ DECLARE_HOOK(HOOK_INIT, adp_state_init, HOOK_PRIO_INIT_CHARGE_MANAGER + 1);
static void board_init(void)
{
+ int i;
+
gpio_enable_interrupt(GPIO_BJ_ADP_PRESENT_ODL);
gpio_enable_interrupt(GPIO_HDMI_CONN_OC_ODL);
- gpio_enable_interrupt(GPIO_USB_A0_OC_ODL);
gpio_enable_interrupt(GPIO_USB_A1_OC_ODL);
gpio_enable_interrupt(GPIO_USB_A2_OC_ODL);
gpio_enable_interrupt(GPIO_USB_A3_OC_ODL);
+ gpio_enable_interrupt(GPIO_USB_A4_OC_ODL);
+
+ if (ec_cfg_power_on_monitor() == POWER_ON_MONITOR_ENABLE) {
+ /*
+ * Only enable interrupt when fw_config set it as enable.
+ */
+ gpio_enable_interrupt(GPIO_HDMI1_MONITOR_ON);
+ gpio_enable_interrupt(GPIO_HDMI2_MONITOR_ON);
+ gpio_enable_interrupt(GPIO_OPTION_MONITOR_ON);
+
+ /*
+ * Initialize the monitor state to corresponding gpio state.
+ */
+ for (i = 0; i < MONITOR_COUNT; i++)
+ monitors[i].state = gpio_get_level(monitors[i].gpio);
+ }
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
@@ -262,7 +221,6 @@ void board_overcurrent_event(int port, int is_overcurrented)
if ((port < 0) || (port >= CONFIG_USB_PD_PORT_MAX_COUNT))
return;
usbc_overcurrent = is_overcurrented;
- update_5v_usage();
}
/*
* Power monitoring and management.
@@ -307,7 +265,6 @@ void board_overcurrent_event(int port, int is_overcurrented)
#define THROT_TYPE_A_REAR BIT(1)
#define THROT_TYPE_C0 BIT(2)
#define THROT_TYPE_C1 BIT(3)
-#define THROT_TYPE_C2 BIT(4)
#define THROT_PROCHOT BIT(5)
/*
@@ -324,6 +281,9 @@ void board_overcurrent_event(int port, int is_overcurrented)
#define POWER_DELAY_MS 2
#define POWER_READINGS (10 / POWER_DELAY_MS)
+/* Must come after other header files and interrupt handler declarations */
+#include "gpio_list.h"
+
static void power_monitor(void)
{
static uint32_t current_state;
@@ -331,8 +291,6 @@ static void power_monitor(void)
static uint8_t index;
int32_t delay;
uint32_t new_state = 0, diff;
- int32_t headroom_5v_s5 = PWR_S5_MAX - base_5v_power_s5;
- int32_t headroom_5v_z1 = PWR_Z1_MAX - base_5v_power_z1;
/*
* If CPU is off or suspended, no need to throttle
@@ -408,7 +366,6 @@ static void power_monitor(void)
*/
if (gap <= 0) {
new_state |= THROT_TYPE_A_REAR;
- headroom_5v_s5 += REAR_DELTA;
if (!(current_state & THROT_TYPE_A_REAR))
gap += POWER_GAIN_TYPE_A;
}
@@ -417,8 +374,7 @@ static void power_monitor(void)
*/
if (gap <= 0) {
new_state |= THROT_TYPE_A_FRONT;
- headroom_5v_s5 += FRONT_DELTA;
- if (!(current_state & THROT_TYPE_A_REAR))
+ if (!(current_state & THROT_TYPE_A_FRONT))
gap += POWER_GAIN_TYPE_A;
}
/*
@@ -427,7 +383,6 @@ static void power_monitor(void)
*/
if (ppc_is_sourcing_vbus(0) && gap <= 0) {
new_state |= THROT_TYPE_C0;
- headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
if (!(current_state & THROT_TYPE_C0))
gap += POWER_GAIN_TYPE_C;
}
@@ -437,21 +392,10 @@ static void power_monitor(void)
*/
if (ppc_is_sourcing_vbus(1) && gap <= 0) {
new_state |= THROT_TYPE_C1;
- headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
if (!(current_state & THROT_TYPE_C1))
gap += POWER_GAIN_TYPE_C;
}
/*
- * If the type-C port is sourcing power,
- * check whether it should be throttled.
- */
- if (ppc_is_sourcing_vbus(2) && gap <= 0) {
- new_state |= THROT_TYPE_C2;
- headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
- if (!(current_state & THROT_TYPE_C2))
- gap += POWER_GAIN_TYPE_C;
- }
- /*
* As a last resort, turn on PROCHOT to
* throttle the CPU.
*/
@@ -460,60 +404,6 @@ static void power_monitor(void)
}
}
/*
- * Check the 5v power usage and if necessary,
- * adjust the throttles in priority order.
- *
- * Either throttle may have already been activated by
- * the overall power control.
- *
- * We rely on the overcurrent detection to inform us
- * if the port is in use.
- *
- * - If type C not already throttled:
- * * If not overcurrent, prefer to limit type C [1].
- * * If in overcurrentuse:
- * - limit type A first [2]
- * - If necessary, limit type C [3].
- * - If type A not throttled, if necessary limit it [2].
- */
- if (headroom_5v_z1 < 0) {
- /*
- * Check whether type C is not throttled,
- * and is not overcurrent.
- */
- if (!((new_state & THROT_TYPE_C0) || usbc_overcurrent)) {
- /*
- * [1] Type C not in overcurrent, throttle it.
- */
- headroom_5v_z1 += PWR_Z1_C_HIGH - PWR_Z1_C_LOW;
- new_state |= THROT_TYPE_C0;
- }
- /*
- * [2] If still under-budget, limit type C.
- * No need to check if it is already throttled or not.
- */
- if (headroom_5v_z1 < 0)
- new_state |= THROT_TYPE_C0;
- }
- if (headroom_5v_s5 < 0) {
- /*
- * [1] If type A rear not already throttled, and power still
- * needed, limit type A rear.
- */
- if (!(new_state & THROT_TYPE_A_REAR) && headroom_5v_s5 < 0) {
- headroom_5v_s5 += PWR_S5_REAR_HIGH - PWR_S5_REAR_LOW;
- new_state |= THROT_TYPE_A_REAR;
- }
- /*
- * [2] If type A front not already throttled, and power still
- * needed, limit type A front.
- */
- if (!(new_state & THROT_TYPE_A_FRONT) && headroom_5v_s5 < 0) {
- headroom_5v_s5 += PWR_S5_FRONT_HIGH - PWR_S5_FRONT_LOW;
- new_state |= THROT_TYPE_A_FRONT;
- }
- }
- /*
* Turn the throttles on or off if they have changed.
*/
diff = new_state ^ current_state;
@@ -541,26 +431,88 @@ static void power_monitor(void)
tcpm_select_rp_value(1, rp);
pd_update_contract(1);
}
- if (diff & THROT_TYPE_C2) {
- enum tcpc_rp_value rp = (new_state & THROT_TYPE_C2) ?
- TYPEC_RP_1A5 :
- TYPEC_RP_3A0;
-
- ppc_set_vbus_source_current_limit(2, rp);
- tcpm_select_rp_value(2, rp);
- pd_update_contract(2);
- }
if (diff & THROT_TYPE_A_REAR) {
int typea_bc = (new_state & THROT_TYPE_A_REAR) ? 1 : 0;
- gpio_set_level(GPIO_USB_A_LOW_PWR0_OD, typea_bc);
gpio_set_level(GPIO_USB_A_LOW_PWR1_OD, typea_bc);
}
if (diff & THROT_TYPE_A_FRONT) {
int typea_bc = (new_state & THROT_TYPE_A_FRONT) ? 1 : 0;
gpio_set_level(GPIO_USB_A_LOW_PWR2_OD, typea_bc);
- gpio_set_level(GPIO_USB_A_LOW_PWR3_OD, typea_bc);
}
hook_call_deferred(&power_monitor_data, delay);
}
+/*
+ * Start power monitoring after ADCs have been initialised.
+ */
+DECLARE_HOOK(HOOK_INIT, power_monitor, HOOK_PRIO_INIT_ADC + 1);
+
+/******************************************************************************/
+/*
+ * System power on and wake up by monitor power button.
+ *
+ * After pressing power button of monitor for power on, monitor will send power
+ * on signal with 3.3V / 200ms to DT. If DT detect that pulse, there are three
+ * DT behavior:
+ *
+ * - Do nothing in state S0.
+ * - Wake up from state S0ix.
+ * - Power on from state S5 and G3.
+ */
+
+/* Debounce time for HDMI power button press */
+#define MONITOR_DEBOUNCE_MS 100
+
+static void monitor_irq_deferred(void);
+DECLARE_DEFERRED(monitor_irq_deferred);
+
+static void monitor_irq_deferred(void)
+{
+ int i;
+
+ for (i = 0; i < MONITOR_COUNT; i++) {
+ if (monitors[i].state && gpio_get_level(monitors[i].gpio)) {
+ /*
+ * System power on from state S5 and G3.
+ */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ chipset_power_on();
+ /*
+ * System wake up from state S0ix.
+ */
+ else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND))
+ power_button_simulate_press(200);
+ }
+ monitors[i].state = MONITOR_OFF;
+ }
+}
+
+/* Power on by HDMI/ DP monitor. */
+void monitor_interrupt(enum gpio_signal signal)
+{
+ /*
+ * Power on by HDMI/ DP monitor only works
+ * when system is not in S0.
+ */
+ if (chipset_in_state(CHIPSET_STATE_ON))
+ return;
+
+ if (ec_cfg_power_on_monitor() == POWER_ON_MONITOR_ENABLE) {
+ switch (signal) {
+ case GPIO_HDMI1_MONITOR_ON:
+ monitors[HDMI1_MONITOR].state = MONITOR_ON;
+ break;
+ case GPIO_HDMI2_MONITOR_ON:
+ monitors[HDMI2_MONITOR].state = MONITOR_ON;
+ break;
+ case GPIO_OPTION_MONITOR_ON:
+ monitors[OPTION_MONITOR].state = MONITOR_ON;
+ break;
+ default:
+ break;
+ }
+ hook_call_deferred(&monitor_irq_deferred_data,
+ MONITOR_DEBOUNCE_MS * MSEC);
+ }
+}