diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2017-02-28 15:33:00 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-03-07 14:15:56 -0800 |
commit | ad089de4b0430e5d997b9f6d6f187daae1fb11dc (patch) | |
tree | bf6668423a37f7beba6f9c1b24765385cc6e6135 | |
parent | 5b8b06e976623ad52a1c4c558dfdac8b1c9d3dc7 (diff) | |
download | chrome-ec-ad089de4b0430e5d997b9f6d6f187daae1fb11dc.tar.gz |
pdcontrol: Suspend port individually
pdcontrol suspend command will be used to prevent tcpm from putting
the chip into sleep while firmware update is taking place. Currently
the command suspends or resumes port 0. This patch makes the command
apply to ports individually.
pd enable console command now takes a port number:
pd <port> enable/disable.
This patch also replaces CONFIG_USB_PD_COMM_ENABLED with _DISABLED.
When it's defined, PD communication is disabled at startup.
Plankton undefines CONFIG_USB_PD_COMM_ENABLED enable, intending to
disable PD communication at startup. Therefore, this patch defines
CONFIG_USB_PD_COMM_DISABLED in its board.h.
BUG=b:35586859
BRANCH=none
TEST=From AP console:
localhost # /tmp/ectool pdcontrol suspend 1
[600.188013 TCPC p1 suspended!]
> pd 1 state
Port C1 CC1, Dis - Role: SNK-UFP State: SUSPENDED, Flags: 0x0020
localhost # /tmp/ectool pdcontrol resume 1
[678.516613 TCPC p1 resumed!]
> pd 1 state
Port C1 CC1, Ena - Role: SNK-UFP State: DRP_AUTO_TOGGLE, Flags: 0x0020
From ec console:
> pd 1 disable
Port C1 disable
> pd 1 state
Port C1 CC1, Dis - Role: SNK-UFP State: DRP_AUTO_TOGGLE, Flags: 0x0020
> pd 1 enable
Port C1 enabled
> pd 1 state
Port C1 CC1, Ena - Role: SNK-UFP State: DRP_AUTO_TOGGLE, Flags: 0x0020
Change-Id: Ia0cc4904ac52adc4b89de20918968c8df78b9c80
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/447968
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | board/plankton/board.c | 6 | ||||
-rw-r--r-- | board/plankton/board.h | 2 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 126 | ||||
-rw-r--r-- | include/config.h | 4 | ||||
-rw-r--r-- | include/usb_pd.h | 3 | ||||
-rw-r--r-- | util/ectool.c | 11 |
6 files changed, 82 insertions, 70 deletions
diff --git a/board/plankton/board.c b/board/plankton/board.c index 5bc6b776a3..b725989047 100644 --- a/board/plankton/board.c +++ b/board/plankton/board.c @@ -203,14 +203,14 @@ static void detect_cc_cable(void) TYPEC_CABLE_SINGLE_CC; /* Flip back to original polarity and enable PD comms */ set_active_cc(!active_cc); - pd_comm_enable(1); + pd_comm_enable(0, 1); break; case TYPEC_CABLE_SINGLE_CC: case TYPEC_CABLE_DOUBLE_CC: /* Check for disconnection and disable PD comms */ if (!pd_is_connected(0)) { cable = TYPEC_CABLE_NONE; - pd_comm_enable(0); + pd_comm_enable(0, 0); } break; } @@ -269,7 +269,7 @@ static void update_usbc_dual_role(int dual_role) /* Need to make sure both CC lines are set for SNK or SRC. */ set_active_cc(host_mode); /* Ensure that PD communication is enabled. */ - pd_comm_enable(1); + pd_comm_enable(0, 1); } else { drp_enable = 0; /* diff --git a/board/plankton/board.h b/board/plankton/board.h index 994fb98c76..590c6ef7f3 100644 --- a/board/plankton/board.h +++ b/board/plankton/board.h @@ -19,7 +19,7 @@ #define CONFIG_STM_HWTIMER32 #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE -#undef CONFIG_USB_PD_COMM_ENABLED +#define CONFIG_USB_PD_COMM_DISABLED #define CONFIG_USB_PD_CUSTOM_VDM #define CONFIG_USB_PD_DUAL_ROLE #define CONFIG_USB_PD_DYNAMIC_SRC_CAP diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index b7b825dcb9..90db784d2c 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -54,16 +54,11 @@ static int debug_level; * detects source/sink connection and disconnection, and will still * provide VBUS, but never sends any PD communication. */ -#if !defined(CONFIG_USB_PD_COMM_ENABLED) || defined(CONFIG_USB_PD_COMM_LOCKED) -static uint8_t pd_comm_enabled; -#else -static uint8_t pd_comm_enabled = 1; -#endif +static uint8_t pd_comm_enabled[CONFIG_USB_PD_PORT_COUNT]; #else /* CONFIG_COMMON_RUNTIME */ #define CPRINTF(format, args...) #define CPRINTS(format, args...) static const int debug_level; -static const uint8_t pd_comm_enabled = 1; #endif #ifdef CONFIG_USB_PD_DUAL_ROLE @@ -204,6 +199,15 @@ BUILD_ASSERT(ARRAY_SIZE(pd_state_names) == PD_STATE_COUNT); static struct ec_params_usb_pd_rw_hash_entry rw_hash_table[RW_HASH_ENTRIES]; #endif +static inline int pd_comm_is_enabled(int port) +{ +#ifdef CONFIG_COMMON_RUNTIME + return pd_comm_enabled[port]; +#else + return 1; +#endif +} + static inline void set_state_timeout(int port, uint64_t timeout, enum pd_states timeout_state) @@ -393,7 +397,7 @@ static int pd_transmit(int port, enum tcpm_transmit_type type, int evt; /* If comms are disabled, do not transmit, return error */ - if (!pd_comm_enabled) + if (!pd_comm_is_enabled(port)) return -1; tcpm_transmit(port, type, header, data); @@ -1484,28 +1488,25 @@ int pd_get_partner_data_swap_capable(int port) } #ifdef CONFIG_COMMON_RUNTIME -void pd_comm_enable(int enable) +void pd_comm_enable(int port, int enable) { - int i; - - pd_comm_enabled = enable; + /* We don't check port >= CONFIG_USB_PD_PORT_COUNT deliberately */ + pd_comm_enabled[port] = enable; - for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) { - /* If type-C connection, then update the TCPC RX enable */ - if (pd_is_connected(i)) - tcpm_set_rx_enable(i, enable); + /* If type-C connection, then update the TCPC RX enable */ + if (pd_is_connected(port)) + tcpm_set_rx_enable(port, enable); #ifdef CONFIG_USB_PD_DUAL_ROLE - /* - * If communications are enabled, start hard reset timer for - * any port in PD_SNK_DISCOVERY. - */ - if (enable && pd[i].task_state == PD_STATE_SNK_DISCOVERY) - set_state_timeout(i, - get_time().val + PD_T_SINK_WAIT_CAP, - PD_STATE_HARD_RESET_SEND); + /* + * If communications are enabled, start hard reset timer for + * any port in PD_SNK_DISCOVERY. + */ + if (enable && pd[port].task_state == PD_STATE_SNK_DISCOVERY) + set_state_timeout(port, + get_time().val + PD_T_SINK_WAIT_CAP, + PD_STATE_HARD_RESET_SEND); #endif - } } #endif @@ -1597,6 +1598,8 @@ void pd_set_new_power_request(int port) static void pd_init_tasks(void) { static int initialized; + int enable = 1; + int i; /* Initialize globals once, for all PD tasks. */ if (initialized) @@ -1612,15 +1615,16 @@ static void pd_init_tasks(void) drp_state = PD_DRP_TOGGLE_ON; #endif -#if !defined(CONFIG_USB_PD_COMM_ENABLED) || defined(CONFIG_USB_PD_COMM_LOCKED) - /* Enable PD communication at init if we're in RW or unlocked. */ - if (system_get_image_copy() != SYSTEM_IMAGE_RW && system_is_locked()) { - pd_comm_enabled = 0; - ccprintf("[%T PD comm disabled]\n"); - } else { - pd_comm_enabled = 1; - } +#if defined(CONFIG_USB_PD_COMM_DISABLED) + enable = 0; +#elif defined(CONFIG_USB_PD_COMM_LOCKED) + /* Disable PD communication at init if we're in RO and locked. */ + if (system_get_image_copy() != SYSTEM_IMAGE_RW && system_is_locked()) + enable = 0; #endif + for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) + pd_comm_enabled[i] = enable; + CPRINTS("PD comm %sabled", enable ? "en" : "dis"); initialized = 1; } @@ -1917,7 +1921,7 @@ void pd_task(void) } #endif /* If PD comm is enabled, enable TCPC RX */ - if (pd_comm_enabled) + if (pd_comm_is_enabled(port)) tcpm_set_rx_enable(port, 1); #ifdef CONFIG_USBC_VCONN @@ -1994,7 +1998,7 @@ void pd_task(void) * to RECEIVE_DETECT register to enable * PD message passing. */ - if (pd_comm_enabled) + if (pd_comm_is_enabled(port)) tcpm_set_rx_enable(port, 1); #endif /* CONFIG_USB_PD_TCPM_TCPCI */ @@ -2418,7 +2422,7 @@ void pd_task(void) port, typec_curr, TYPE_C_VOLTAGE); #endif /* If PD comm is enabled, enable TCPC RX */ - if (pd_comm_enabled) + if (pd_comm_is_enabled(port)) tcpm_set_rx_enable(port, 1); /* DFP is attached */ @@ -2504,7 +2508,7 @@ defined(CONFIG_CASE_CLOSED_DEBUG_EXTERNAL) * to RECEIVE_MESSAGE register to enable * PD message passing. */ - if (pd_comm_enabled) + if (pd_comm_is_enabled(port)) tcpm_set_rx_enable(port, 1); #endif /* CONFIG_USB_PD_TCPM_TCPCI */ @@ -2522,7 +2526,7 @@ defined(CONFIG_CASE_CLOSED_DEBUG_EXTERNAL) case PD_STATE_SNK_DISCOVERY: /* Wait for source cap expired only if we are enabled */ if ((pd[port].last_state != pd[port].task_state) - && pd_comm_enabled) { + && pd_comm_is_enabled(port)) { /* * If VBUS has never been low, and we timeout * waiting for source cap, try a soft reset @@ -3315,19 +3319,6 @@ static int command_pd(int argc, char **argv) return EC_SUCCESS; } #ifdef CONFIG_CMD_PD - else if (!strcasecmp(argv[1], "enable")) { - int enable; - - if (argc < 3) - return EC_ERROR_PARAM_COUNT; - - enable = strtoi(argv[2], &e, 10); - if (*e) - return EC_ERROR_PARAM3; - pd_comm_enable(enable); - ccprintf("Ports %s\n", enable ? "enabled" : "disabled"); - return EC_SUCCESS; - } #ifdef CONFIG_CMD_PD_DEV_DUMP_INFO else if (!strncasecmp(argv[1], "rwhashtable", 3)) { int i; @@ -3390,6 +3381,14 @@ static int command_pd(int argc, char **argv) pd_request_source_voltage(port, max_volt); ccprintf("max req: %dmV\n", max_volt); + } else if (!strcasecmp(argv[2], "disable")) { + pd_comm_enable(port, 0); + ccprintf("Port C%d disable\n", port); + return EC_SUCCESS; + } else if (!strcasecmp(argv[2], "enable")) { + pd_comm_enable(port, 1); + ccprintf("Port C%d enabled\n", port); + return EC_SUCCESS; } else if (!strncasecmp(argv[2], "hard", 4)) { set_state(port, PD_STATE_HARD_RESET_SEND); task_wake(PD_PORT_TO_TASK_ID(port)); @@ -3462,7 +3461,7 @@ static int command_pd(int argc, char **argv) ccprintf("Port C%d CC%d, %s - Role: %s-%s%s " "State: %s, Flags: 0x%04x\n", port, pd[port].polarity + 1, - pd_comm_enabled ? "Ena" : "Dis", + pd_comm_is_enabled(port) ? "Ena" : "Dis", pd[port].power_role == PD_ROLE_SOURCE ? "SRC" : "SNK", pd[port].data_role == PD_ROLE_DFP ? "DFP" : "UFP", (pd[port].flags & PD_FLAGS_VCONN_ON) ? "-VC" : "", @@ -3475,9 +3474,9 @@ static int command_pd(int argc, char **argv) return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(pd, command_pd, - "dualrole|dump|enable [0|1]|rwhashtable" - "trysrc [0|1]\n\t<port> " - "[tx|bist_rx|bist_tx|charger|clock|dev" + "dualrole|dump|rwhashtable" + "|trysrc [0|1]\n\t<port> " + "[tx|bist_rx|bist_tx|charger|clock|dev|disable|enable" "|soft|hash|hard|ping|state|swap [power|data]|" "vdm [ping | curr | vers]]", "USB PD"); @@ -3550,14 +3549,15 @@ static int hc_usb_pd_control(struct host_cmd_handler_args *args) #endif if (args->version == 0) { - r->enabled = pd_comm_enabled; + r->enabled = pd_comm_is_enabled(p->port); r->role = pd[p->port].power_role; r->polarity = pd[p->port].polarity; r->state = pd[p->port].task_state; args->response_size = sizeof(*r); } else { r_v1->enabled = - (pd_comm_enabled ? PD_CTRL_RESP_ENABLED_COMMS : 0) | + (pd_comm_is_enabled(p->port) ? + PD_CTRL_RESP_ENABLED_COMMS : 0) | (pd_is_connected(p->port) ? PD_CTRL_RESP_ENABLED_CONNECTED : 0) | ((pd[p->port].flags & PD_FLAGS_PREVIOUS_PD_CONN) ? @@ -3800,13 +3800,14 @@ DECLARE_HOST_COMMAND(EC_CMD_USB_PD_SET_AMODE, #endif /* HAS_TASK_HOSTCMD */ #ifdef CONFIG_CMD_PD_CONTROL -static int pd_control_disabled; static int pd_control(struct host_cmd_handler_args *args) { + static int pd_control_disabled; const struct ec_params_pd_control *cmd = args->params; + int enable; - if (cmd->chip != 0) + if (cmd->chip >= CONFIG_USB_PD_PORT_COUNT) return EC_RES_INVALID_PARAM; /* Always allow disable command */ @@ -3819,11 +3820,9 @@ static int pd_control(struct host_cmd_handler_args *args) return EC_RES_ACCESS_DENIED; if (cmd->subcmd == PD_SUSPEND) { - pd_comm_enable(0); - pd_set_suspend(0, 1); + enable = 0; } else if (cmd->subcmd == PD_RESUME) { - pd_comm_enable(1); - pd_set_suspend(0, 0); + enable = 1; } else if (cmd->subcmd == PD_RESET) { #ifdef HAS_TASK_PDCMD board_reset_pd_mcu(); @@ -3834,6 +3833,9 @@ static int pd_control(struct host_cmd_handler_args *args) return EC_RES_INVALID_COMMAND; } + pd_comm_enable(cmd->chip, enable); + pd_set_suspend(cmd->chip, !enable); + return EC_RES_SUCCESS; } diff --git a/include/config.h b/include/config.h index 19a6653161..b998fde1ed 100644 --- a/include/config.h +++ b/include/config.h @@ -2158,8 +2158,8 @@ /* Check if max voltage request is allowed before each request */ #undef CONFIG_USB_PD_CHECK_MAX_REQUEST_ALLOWED -/* Default state of PD communication enabled flag */ -#define CONFIG_USB_PD_COMM_ENABLED +/* Default state of PD communication disabled flag */ +#undef CONFIG_USB_PD_COMM_DISABLED /* * Do not enable PD communication in RO as a security measure. diff --git a/include/usb_pd.h b/include/usb_pd.h index 23909e6ac7..01b4ed5358 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -1555,9 +1555,10 @@ void pd_request_data_swap(int port); * the port can still detect connection and source power but will not * send or respond to any PD communication. * + * @param port USB-C port number * @param enable Enable flag to set */ -void pd_comm_enable(int enable); +void pd_comm_enable(int port, int enable); /** * Set the PD pings enabled flag. When source has negotiated power over diff --git a/util/ectool.c b/util/ectool.c index 5180a1a85b..10a178c942 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -6870,7 +6870,16 @@ int cmd_pd_control(int argc, char *argv[]) return -1; } - p.chip = 0; + if (argc == 2) { + p.chip = 0; + } else { + char *e; + p.chip = strtol(argv[2], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad port number '%s'.\n", argv[2]); + return -1; + } + } rv = ec_command(EC_CMD_PD_CONTROL, 0, &p, sizeof(p), NULL, 0); return (rv < 0 ? rv : 0); |