[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <202008041617.iVubhWnE%lkp@intel.com>
Date: Tue, 4 Aug 2020 16:26:44 +0800
From: kernel test robot <lkp@...el.com>
To: Badhri Jagan Sridharan <badhri@...gle.com>,
Guenter Roeck <linux@...ck-us.net>,
Heikki Krogerus <heikki.krogerus@...ux.intel.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: kbuild-all@...ts.01.org, linux-usb@...r.kernel.org,
linux-kernel@...r.kernel.org, --validate@...gle.com,
Badhri Jagan Sridharan <badhri@...gle.com>
Subject: Re: [PATCH v1] tcpm: Honour pSnkStdby requirement during negotiation
Hi Badhri,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on next-20200803]
[cannot apply to v5.8]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Badhri-Jagan-Sridharan/tcpm-Honour-pSnkStdby-requirement-during-negotiation/20200804-145301
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nios2
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@...el.com>
All warnings (new ones prefixed by >>):
drivers/usb/typec/tcpm/tcpm.c: In function 'run_state_machine':
>> drivers/usb/typec/tcpm/tcpm.c:3339:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
3339 | if (port->psnkstdby_after_accept)
| ^
drivers/usb/typec/tcpm/tcpm.c:3343:2: note: here
3343 | case SNK_TRANSITION_SINK_VBUS:
| ^~~~
At top level:
drivers/usb/typec/tcpm/tcpm.c:1614:39: warning: 'tcpm_altmode_ops' defined but not used [-Wunused-const-variable=]
1614 | static const struct typec_altmode_ops tcpm_altmode_ops = {
| ^~~~~~~~~~~~~~~~
vim +3339 drivers/usb/typec/tcpm/tcpm.c
2943
2944 static void run_state_machine(struct tcpm_port *port)
2945 {
2946 int ret;
2947 enum typec_pwr_opmode opmode;
2948 unsigned int msecs;
2949
2950 port->enter_state = port->state;
2951 switch (port->state) {
2952 case TOGGLING:
2953 break;
2954 /* SRC states */
2955 case SRC_UNATTACHED:
2956 if (!port->non_pd_role_swap)
2957 tcpm_swap_complete(port, -ENOTCONN);
2958 tcpm_src_detach(port);
2959 if (tcpm_start_toggling(port, tcpm_rp_cc(port))) {
2960 tcpm_set_state(port, TOGGLING, 0);
2961 break;
2962 }
2963 tcpm_set_cc(port, tcpm_rp_cc(port));
2964 if (port->port_type == TYPEC_PORT_DRP)
2965 tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK);
2966 break;
2967 case SRC_ATTACH_WAIT:
2968 if (tcpm_port_is_debug(port))
2969 tcpm_set_state(port, DEBUG_ACC_ATTACHED,
2970 PD_T_CC_DEBOUNCE);
2971 else if (tcpm_port_is_audio(port))
2972 tcpm_set_state(port, AUDIO_ACC_ATTACHED,
2973 PD_T_CC_DEBOUNCE);
2974 else if (tcpm_port_is_source(port))
2975 tcpm_set_state(port,
2976 tcpm_try_snk(port) ? SNK_TRY
2977 : SRC_ATTACHED,
2978 PD_T_CC_DEBOUNCE);
2979 break;
2980
2981 case SNK_TRY:
2982 port->try_snk_count++;
2983 /*
2984 * Requirements:
2985 * - Do not drive vconn or vbus
2986 * - Terminate CC pins (both) to Rd
2987 * Action:
2988 * - Wait for tDRPTry (PD_T_DRP_TRY).
2989 * Until then, ignore any state changes.
2990 */
2991 tcpm_set_cc(port, TYPEC_CC_RD);
2992 tcpm_set_state(port, SNK_TRY_WAIT, PD_T_DRP_TRY);
2993 break;
2994 case SNK_TRY_WAIT:
2995 if (tcpm_port_is_sink(port)) {
2996 tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE, 0);
2997 } else {
2998 tcpm_set_state(port, SRC_TRYWAIT, 0);
2999 port->max_wait = 0;
3000 }
3001 break;
3002 case SNK_TRY_WAIT_DEBOUNCE:
3003 tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS,
3004 PD_T_PD_DEBOUNCE);
3005 break;
3006 case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS:
3007 if (port->vbus_present && tcpm_port_is_sink(port)) {
3008 tcpm_set_state(port, SNK_ATTACHED, 0);
3009 } else {
3010 tcpm_set_state(port, SRC_TRYWAIT, 0);
3011 port->max_wait = 0;
3012 }
3013 break;
3014 case SRC_TRYWAIT:
3015 tcpm_set_cc(port, tcpm_rp_cc(port));
3016 if (port->max_wait == 0) {
3017 port->max_wait = jiffies +
3018 msecs_to_jiffies(PD_T_DRP_TRY);
3019 tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
3020 PD_T_DRP_TRY);
3021 } else {
3022 if (time_is_after_jiffies(port->max_wait))
3023 tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
3024 jiffies_to_msecs(port->max_wait -
3025 jiffies));
3026 else
3027 tcpm_set_state(port, SNK_UNATTACHED, 0);
3028 }
3029 break;
3030 case SRC_TRYWAIT_DEBOUNCE:
3031 tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE);
3032 break;
3033 case SRC_TRYWAIT_UNATTACHED:
3034 tcpm_set_state(port, SNK_UNATTACHED, 0);
3035 break;
3036
3037 case SRC_ATTACHED:
3038 ret = tcpm_src_attach(port);
3039 tcpm_set_state(port, SRC_UNATTACHED,
3040 ret < 0 ? 0 : PD_T_PS_SOURCE_ON);
3041 break;
3042 case SRC_STARTUP:
3043 opmode = tcpm_get_pwr_opmode(tcpm_rp_cc(port));
3044 typec_set_pwr_opmode(port->typec_port, opmode);
3045 port->pwr_opmode = TYPEC_PWR_MODE_USB;
3046 port->caps_count = 0;
3047 port->negotiated_rev = PD_MAX_REV;
3048 port->message_id = 0;
3049 port->rx_msgid = -1;
3050 port->explicit_contract = false;
3051 tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
3052 break;
3053 case SRC_SEND_CAPABILITIES:
3054 port->caps_count++;
3055 if (port->caps_count > PD_N_CAPS_COUNT) {
3056 tcpm_set_state(port, SRC_READY, 0);
3057 break;
3058 }
3059 ret = tcpm_pd_send_source_caps(port);
3060 if (ret < 0) {
3061 tcpm_set_state(port, SRC_SEND_CAPABILITIES,
3062 PD_T_SEND_SOURCE_CAP);
3063 } else {
3064 /*
3065 * Per standard, we should clear the reset counter here.
3066 * However, that can result in state machine hang-ups.
3067 * Reset it only in READY state to improve stability.
3068 */
3069 /* port->hard_reset_count = 0; */
3070 port->caps_count = 0;
3071 port->pd_capable = true;
3072 tcpm_set_state_cond(port, SRC_SEND_CAPABILITIES_TIMEOUT,
3073 PD_T_SEND_SOURCE_CAP);
3074 }
3075 break;
3076 case SRC_SEND_CAPABILITIES_TIMEOUT:
3077 /*
3078 * Error recovery for a PD_DATA_SOURCE_CAP reply timeout.
3079 *
3080 * PD 2.0 sinks are supposed to accept src-capabilities with a
3081 * 3.0 header and simply ignore any src PDOs which the sink does
3082 * not understand such as PPS but some 2.0 sinks instead ignore
3083 * the entire PD_DATA_SOURCE_CAP message, causing contract
3084 * negotiation to fail.
3085 *
3086 * After PD_N_HARD_RESET_COUNT hard-reset attempts, we try
3087 * sending src-capabilities with a lower PD revision to
3088 * make these broken sinks work.
3089 */
3090 if (port->hard_reset_count < PD_N_HARD_RESET_COUNT) {
3091 tcpm_set_state(port, HARD_RESET_SEND, 0);
3092 } else if (port->negotiated_rev > PD_REV20) {
3093 port->negotiated_rev--;
3094 port->hard_reset_count = 0;
3095 tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
3096 } else {
3097 tcpm_set_state(port, hard_reset_state(port), 0);
3098 }
3099 break;
3100 case SRC_NEGOTIATE_CAPABILITIES:
3101 ret = tcpm_pd_check_request(port);
3102 if (ret < 0) {
3103 tcpm_pd_send_control(port, PD_CTRL_REJECT);
3104 if (!port->explicit_contract) {
3105 tcpm_set_state(port,
3106 SRC_WAIT_NEW_CAPABILITIES, 0);
3107 } else {
3108 tcpm_set_state(port, SRC_READY, 0);
3109 }
3110 } else {
3111 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
3112 tcpm_set_state(port, SRC_TRANSITION_SUPPLY,
3113 PD_T_SRC_TRANSITION);
3114 }
3115 break;
3116 case SRC_TRANSITION_SUPPLY:
3117 /* XXX: regulator_set_voltage(vbus, ...) */
3118 tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
3119 port->explicit_contract = true;
3120 typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_PD);
3121 port->pwr_opmode = TYPEC_PWR_MODE_PD;
3122 tcpm_set_state_cond(port, SRC_READY, 0);
3123 break;
3124 case SRC_READY:
3125 #if 1
3126 port->hard_reset_count = 0;
3127 #endif
3128 port->try_src_count = 0;
3129
3130 tcpm_swap_complete(port, 0);
3131 tcpm_typec_connect(port);
3132
3133 tcpm_check_send_discover(port);
3134 /*
3135 * 6.3.5
3136 * Sending ping messages is not necessary if
3137 * - the source operates at vSafe5V
3138 * or
3139 * - The system is not operating in PD mode
3140 * or
3141 * - Both partners are connected using a Type-C connector
3142 *
3143 * There is no actual need to send PD messages since the local
3144 * port type-c and the spec does not clearly say whether PD is
3145 * possible when type-c is connected to Type-A/B
3146 */
3147 break;
3148 case SRC_WAIT_NEW_CAPABILITIES:
3149 /* Nothing to do... */
3150 break;
3151
3152 /* SNK states */
3153 case SNK_UNATTACHED:
3154 if (!port->non_pd_role_swap)
3155 tcpm_swap_complete(port, -ENOTCONN);
3156 tcpm_pps_complete(port, -ENOTCONN);
3157 tcpm_snk_detach(port);
3158 if (tcpm_start_toggling(port, TYPEC_CC_RD)) {
3159 tcpm_set_state(port, TOGGLING, 0);
3160 break;
3161 }
3162 tcpm_set_cc(port, TYPEC_CC_RD);
3163 if (port->port_type == TYPEC_PORT_DRP)
3164 tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC);
3165 break;
3166 case SNK_ATTACH_WAIT:
3167 if ((port->cc1 == TYPEC_CC_OPEN &&
3168 port->cc2 != TYPEC_CC_OPEN) ||
3169 (port->cc1 != TYPEC_CC_OPEN &&
3170 port->cc2 == TYPEC_CC_OPEN))
3171 tcpm_set_state(port, SNK_DEBOUNCED,
3172 PD_T_CC_DEBOUNCE);
3173 else if (tcpm_port_is_disconnected(port))
3174 tcpm_set_state(port, SNK_UNATTACHED,
3175 PD_T_PD_DEBOUNCE);
3176 break;
3177 case SNK_DEBOUNCED:
3178 if (tcpm_port_is_disconnected(port))
3179 tcpm_set_state(port, SNK_UNATTACHED,
3180 PD_T_PD_DEBOUNCE);
3181 else if (port->vbus_present)
3182 tcpm_set_state(port,
3183 tcpm_try_src(port) ? SRC_TRY
3184 : SNK_ATTACHED,
3185 0);
3186 else
3187 /* Wait for VBUS, but not forever */
3188 tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON);
3189 break;
3190
3191 case SRC_TRY:
3192 port->try_src_count++;
3193 tcpm_set_cc(port, tcpm_rp_cc(port));
3194 port->max_wait = 0;
3195 tcpm_set_state(port, SRC_TRY_WAIT, 0);
3196 break;
3197 case SRC_TRY_WAIT:
3198 if (port->max_wait == 0) {
3199 port->max_wait = jiffies +
3200 msecs_to_jiffies(PD_T_DRP_TRY);
3201 msecs = PD_T_DRP_TRY;
3202 } else {
3203 if (time_is_after_jiffies(port->max_wait))
3204 msecs = jiffies_to_msecs(port->max_wait -
3205 jiffies);
3206 else
3207 msecs = 0;
3208 }
3209 tcpm_set_state(port, SNK_TRYWAIT, msecs);
3210 break;
3211 case SRC_TRY_DEBOUNCE:
3212 tcpm_set_state(port, SRC_ATTACHED, PD_T_PD_DEBOUNCE);
3213 break;
3214 case SNK_TRYWAIT:
3215 tcpm_set_cc(port, TYPEC_CC_RD);
3216 tcpm_set_state(port, SNK_TRYWAIT_VBUS, PD_T_CC_DEBOUNCE);
3217 break;
3218 case SNK_TRYWAIT_VBUS:
3219 /*
3220 * TCPM stays in this state indefinitely until VBUS
3221 * is detected as long as Rp is not detected for
3222 * more than a time period of tPDDebounce.
3223 */
3224 if (port->vbus_present && tcpm_port_is_sink(port)) {
3225 tcpm_set_state(port, SNK_ATTACHED, 0);
3226 break;
3227 }
3228 if (!tcpm_port_is_sink(port))
3229 tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0);
3230 break;
3231 case SNK_TRYWAIT_DEBOUNCE:
3232 tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE);
3233 break;
3234 case SNK_ATTACHED:
3235 ret = tcpm_snk_attach(port);
3236 if (ret < 0)
3237 tcpm_set_state(port, SNK_UNATTACHED, 0);
3238 else
3239 tcpm_set_state(port, SNK_STARTUP, 0);
3240 break;
3241 case SNK_STARTUP:
3242 opmode = tcpm_get_pwr_opmode(port->polarity ?
3243 port->cc2 : port->cc1);
3244 typec_set_pwr_opmode(port->typec_port, opmode);
3245 port->pwr_opmode = TYPEC_PWR_MODE_USB;
3246 port->negotiated_rev = PD_MAX_REV;
3247 port->message_id = 0;
3248 port->rx_msgid = -1;
3249 port->explicit_contract = false;
3250 tcpm_set_state(port, SNK_DISCOVERY, 0);
3251 break;
3252 case SNK_DISCOVERY:
3253 if (port->vbus_present) {
3254 if (port->psnkstdby_after_accept || tcpm_get_current_limit(port) <=
3255 PD_P_SNK_STDBY_5V)
3256 tcpm_set_current_limit(port, tcpm_get_current_limit(port), 5000);
3257 else
3258 tcpm_set_current_limit(port, PD_P_SNK_STDBY_5V, 5000);
3259 tcpm_set_charge(port, true);
3260 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
3261 break;
3262 }
3263 /*
3264 * For DRP, timeouts differ. Also, handling is supposed to be
3265 * different and much more complex (dead battery detection;
3266 * see USB power delivery specification, section 8.3.3.6.1.5.1).
3267 */
3268 tcpm_set_state(port, hard_reset_state(port),
3269 port->port_type == TYPEC_PORT_DRP ?
3270 PD_T_DB_DETECT : PD_T_NO_RESPONSE);
3271 break;
3272 case SNK_DISCOVERY_DEBOUNCE:
3273 tcpm_set_state(port, SNK_DISCOVERY_DEBOUNCE_DONE,
3274 PD_T_CC_DEBOUNCE);
3275 break;
3276 case SNK_DISCOVERY_DEBOUNCE_DONE:
3277 if (!tcpm_port_is_disconnected(port) &&
3278 tcpm_port_is_sink(port) &&
3279 time_is_after_jiffies(port->delayed_runtime)) {
3280 tcpm_set_state(port, SNK_DISCOVERY,
3281 jiffies_to_msecs(port->delayed_runtime -
3282 jiffies));
3283 break;
3284 }
3285 tcpm_set_state(port, unattached_state(port), 0);
3286 break;
3287 case SNK_WAIT_CAPABILITIES:
3288 ret = port->tcpc->set_pd_rx(port->tcpc, true);
3289 if (ret < 0) {
3290 tcpm_set_state(port, SNK_READY, 0);
3291 break;
3292 }
3293 /*
3294 * If VBUS has never been low, and we time out waiting
3295 * for source cap, try a soft reset first, in case we
3296 * were already in a stable contract before this boot.
3297 * Do this only once.
3298 */
3299 if (port->vbus_never_low) {
3300 port->vbus_never_low = false;
3301 tcpm_set_state(port, SOFT_RESET_SEND,
3302 PD_T_SINK_WAIT_CAP);
3303 } else {
3304 tcpm_set_state(port, hard_reset_state(port),
3305 PD_T_SINK_WAIT_CAP);
3306 }
3307 break;
3308 case SNK_NEGOTIATE_CAPABILITIES:
3309 port->pd_capable = true;
3310 port->hard_reset_count = 0;
3311 ret = tcpm_pd_send_request(port);
3312 if (ret < 0) {
3313 /* Let the Source send capabilities again. */
3314 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
3315 } else {
3316 tcpm_set_state_cond(port, hard_reset_state(port),
3317 PD_T_SENDER_RESPONSE);
3318 }
3319 break;
3320 case SNK_NEGOTIATE_PPS_CAPABILITIES:
3321 ret = tcpm_pd_send_pps_request(port);
3322 if (ret < 0) {
3323 port->pps_status = ret;
3324 /*
3325 * If this was called due to updates to sink
3326 * capabilities, and pps is no longer valid, we should
3327 * safely fall back to a standard PDO.
3328 */
3329 if (port->update_sink_caps)
3330 tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0);
3331 else
3332 tcpm_set_state(port, SNK_READY, 0);
3333 } else {
3334 tcpm_set_state_cond(port, hard_reset_state(port),
3335 PD_T_SENDER_RESPONSE);
3336 }
3337 break;
3338 case SNK_TRANSITION_SINK:
> 3339 if (port->psnkstdby_after_accept)
3340 tcpm_set_current_limit(port, tcpm_get_current_limit(port) >
3341 PD_P_SNK_STDBY_5V ? PD_P_SNK_STDBY_5V :
3342 tcpm_get_current_limit(port), 5000);
3343 case SNK_TRANSITION_SINK_VBUS:
3344 tcpm_set_state(port, hard_reset_state(port),
3345 PD_T_PS_TRANSITION);
3346 break;
3347 case SNK_READY:
3348 port->try_snk_count = 0;
3349 port->update_sink_caps = false;
3350 if (port->explicit_contract) {
3351 typec_set_pwr_opmode(port->typec_port,
3352 TYPEC_PWR_MODE_PD);
3353 port->pwr_opmode = TYPEC_PWR_MODE_PD;
3354 }
3355
3356 /* Set current limit for NON-PD link when psnkstdby_after_accept is not set*/
3357 if (!port->pd_capable && !port->psnkstdby_after_accept)
3358 tcpm_set_current_limit(port, tcpm_get_current_limit(port), 5000);
3359
3360 tcpm_swap_complete(port, 0);
3361 tcpm_typec_connect(port);
3362 tcpm_check_send_discover(port);
3363 tcpm_pps_complete(port, port->pps_status);
3364
3365 power_supply_changed(port->psy);
3366
3367 break;
3368
3369 /* Accessory states */
3370 case ACC_UNATTACHED:
3371 tcpm_acc_detach(port);
3372 tcpm_set_state(port, SRC_UNATTACHED, 0);
3373 break;
3374 case DEBUG_ACC_ATTACHED:
3375 case AUDIO_ACC_ATTACHED:
3376 ret = tcpm_acc_attach(port);
3377 if (ret < 0)
3378 tcpm_set_state(port, ACC_UNATTACHED, 0);
3379 break;
3380 case AUDIO_ACC_DEBOUNCE:
3381 tcpm_set_state(port, ACC_UNATTACHED, PD_T_CC_DEBOUNCE);
3382 break;
3383
3384 /* Hard_Reset states */
3385 case HARD_RESET_SEND:
3386 tcpm_pd_transmit(port, TCPC_TX_HARD_RESET, NULL);
3387 tcpm_set_state(port, HARD_RESET_START, 0);
3388 break;
3389 case HARD_RESET_START:
3390 port->hard_reset_count++;
3391 port->tcpc->set_pd_rx(port->tcpc, false);
3392 tcpm_unregister_altmodes(port);
3393 port->send_discover = true;
3394 if (port->pwr_role == TYPEC_SOURCE)
3395 tcpm_set_state(port, SRC_HARD_RESET_VBUS_OFF,
3396 PD_T_PS_HARD_RESET);
3397 else
3398 tcpm_set_state(port, SNK_HARD_RESET_SINK_OFF, 0);
3399 break;
3400 case SRC_HARD_RESET_VBUS_OFF:
3401 tcpm_set_vconn(port, true);
3402 tcpm_set_vbus(port, false);
3403 tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
3404 tcpm_data_role_for_source(port));
3405 tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
3406 break;
3407 case SRC_HARD_RESET_VBUS_ON:
3408 tcpm_set_vbus(port, true);
3409 port->tcpc->set_pd_rx(port->tcpc, true);
3410 tcpm_set_attached_state(port, true);
3411 tcpm_set_state(port, SRC_UNATTACHED, PD_T_PS_SOURCE_ON);
3412 break;
3413 case SNK_HARD_RESET_SINK_OFF:
3414 memset(&port->pps_data, 0, sizeof(port->pps_data));
3415 tcpm_set_vconn(port, false);
3416 if (port->pd_capable)
3417 tcpm_set_charge(port, false);
3418 tcpm_set_roles(port, port->self_powered, TYPEC_SINK,
3419 tcpm_data_role_for_sink(port));
3420 /*
3421 * VBUS may or may not toggle, depending on the adapter.
3422 * If it doesn't toggle, transition to SNK_HARD_RESET_SINK_ON
3423 * directly after timeout.
3424 */
3425 tcpm_set_state(port, SNK_HARD_RESET_SINK_ON, PD_T_SAFE_0V);
3426 break;
3427 case SNK_HARD_RESET_WAIT_VBUS:
3428 /* Assume we're disconnected if VBUS doesn't come back. */
3429 tcpm_set_state(port, SNK_UNATTACHED,
3430 PD_T_SRC_RECOVER_MAX + PD_T_SRC_TURN_ON);
3431 break;
3432 case SNK_HARD_RESET_SINK_ON:
3433 /* Note: There is no guarantee that VBUS is on in this state */
3434 /*
3435 * XXX:
3436 * The specification suggests that dual mode ports in sink
3437 * mode should transition to state PE_SRC_Transition_to_default.
3438 * See USB power delivery specification chapter 8.3.3.6.1.3.
3439 * This would mean to to
3440 * - turn off VCONN, reset power supply
3441 * - request hardware reset
3442 * - turn on VCONN
3443 * - Transition to state PE_Src_Startup
3444 * SNK only ports shall transition to state Snk_Startup
3445 * (see chapter 8.3.3.3.8).
3446 * Similar, dual-mode ports in source mode should transition
3447 * to PE_SNK_Transition_to_default.
3448 */
3449 if (port->pd_capable) {
3450 tcpm_set_current_limit(port,
3451 tcpm_get_current_limit(port),
3452 5000);
3453 tcpm_set_charge(port, true);
3454 }
3455 tcpm_set_attached_state(port, true);
3456 tcpm_set_state(port, SNK_STARTUP, 0);
3457 break;
3458
3459 /* Soft_Reset states */
3460 case SOFT_RESET:
3461 port->message_id = 0;
3462 port->rx_msgid = -1;
3463 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
3464 if (port->pwr_role == TYPEC_SOURCE)
3465 tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
3466 else
3467 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
3468 break;
3469 case SOFT_RESET_SEND:
3470 port->message_id = 0;
3471 port->rx_msgid = -1;
3472 if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET))
3473 tcpm_set_state_cond(port, hard_reset_state(port), 0);
3474 else
3475 tcpm_set_state_cond(port, hard_reset_state(port),
3476 PD_T_SENDER_RESPONSE);
3477 break;
3478
3479 /* DR_Swap states */
3480 case DR_SWAP_SEND:
3481 tcpm_pd_send_control(port, PD_CTRL_DR_SWAP);
3482 tcpm_set_state_cond(port, DR_SWAP_SEND_TIMEOUT,
3483 PD_T_SENDER_RESPONSE);
3484 break;
3485 case DR_SWAP_ACCEPT:
3486 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
3487 tcpm_set_state_cond(port, DR_SWAP_CHANGE_DR, 0);
3488 break;
3489 case DR_SWAP_SEND_TIMEOUT:
3490 tcpm_swap_complete(port, -ETIMEDOUT);
3491 tcpm_set_state(port, ready_state(port), 0);
3492 break;
3493 case DR_SWAP_CHANGE_DR:
3494 if (port->data_role == TYPEC_HOST) {
3495 tcpm_unregister_altmodes(port);
3496 tcpm_set_roles(port, true, port->pwr_role,
3497 TYPEC_DEVICE);
3498 } else {
3499 tcpm_set_roles(port, true, port->pwr_role,
3500 TYPEC_HOST);
3501 port->send_discover = true;
3502 }
3503 tcpm_set_state(port, ready_state(port), 0);
3504 break;
3505
3506 /* PR_Swap states */
3507 case PR_SWAP_ACCEPT:
3508 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
3509 tcpm_set_state(port, PR_SWAP_START, 0);
3510 break;
3511 case PR_SWAP_SEND:
3512 tcpm_pd_send_control(port, PD_CTRL_PR_SWAP);
3513 tcpm_set_state_cond(port, PR_SWAP_SEND_TIMEOUT,
3514 PD_T_SENDER_RESPONSE);
3515 break;
3516 case PR_SWAP_SEND_TIMEOUT:
3517 tcpm_swap_complete(port, -ETIMEDOUT);
3518 tcpm_set_state(port, ready_state(port), 0);
3519 break;
3520 case PR_SWAP_START:
3521 if (port->pwr_role == TYPEC_SOURCE)
3522 tcpm_set_state(port, PR_SWAP_SRC_SNK_TRANSITION_OFF,
3523 PD_T_SRC_TRANSITION);
3524 else
3525 tcpm_set_state(port, PR_SWAP_SNK_SRC_SINK_OFF, 0);
3526 break;
3527 case PR_SWAP_SRC_SNK_TRANSITION_OFF:
3528 tcpm_set_vbus(port, false);
3529 port->explicit_contract = false;
3530 /* allow time for Vbus discharge, must be < tSrcSwapStdby */
3531 tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF,
3532 PD_T_SRCSWAPSTDBY);
3533 break;
3534 case PR_SWAP_SRC_SNK_SOURCE_OFF:
3535 tcpm_set_cc(port, TYPEC_CC_RD);
3536 /* allow CC debounce */
3537 tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED,
3538 PD_T_CC_DEBOUNCE);
3539 break;
3540 case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED:
3541 /*
3542 * USB-PD standard, 6.2.1.4, Port Power Role:
3543 * "During the Power Role Swap Sequence, for the initial Source
3544 * Port, the Port Power Role field shall be set to Sink in the
3545 * PS_RDY Message indicating that the initial Source’s power
3546 * supply is turned off"
3547 */
3548 tcpm_set_pwr_role(port, TYPEC_SINK);
3549 if (tcpm_pd_send_control(port, PD_CTRL_PS_RDY)) {
3550 tcpm_set_state(port, ERROR_RECOVERY, 0);
3551 break;
3552 }
3553 tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
3554 break;
3555 case PR_SWAP_SRC_SNK_SINK_ON:
3556 tcpm_set_state(port, SNK_STARTUP, 0);
3557 break;
3558 case PR_SWAP_SNK_SRC_SINK_OFF:
3559 tcpm_set_charge(port, false);
3560 tcpm_set_state(port, hard_reset_state(port),
3561 PD_T_PS_SOURCE_OFF);
3562 break;
3563 case PR_SWAP_SNK_SRC_SOURCE_ON:
3564 tcpm_set_cc(port, tcpm_rp_cc(port));
3565 tcpm_set_vbus(port, true);
3566 /*
3567 * allow time VBUS ramp-up, must be < tNewSrc
3568 * Also, this window overlaps with CC debounce as well.
3569 * So, Wait for the max of two which is PD_T_NEWSRC
3570 */
3571 tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP,
3572 PD_T_NEWSRC);
3573 break;
3574 case PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP:
3575 /*
3576 * USB PD standard, 6.2.1.4:
3577 * "Subsequent Messages initiated by the Policy Engine,
3578 * such as the PS_RDY Message sent to indicate that Vbus
3579 * is ready, will have the Port Power Role field set to
3580 * Source."
3581 */
3582 tcpm_set_pwr_role(port, TYPEC_SOURCE);
3583 tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
3584 tcpm_set_state(port, SRC_STARTUP, 0);
3585 break;
3586
3587 case VCONN_SWAP_ACCEPT:
3588 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
3589 tcpm_set_state(port, VCONN_SWAP_START, 0);
3590 break;
3591 case VCONN_SWAP_SEND:
3592 tcpm_pd_send_control(port, PD_CTRL_VCONN_SWAP);
3593 tcpm_set_state(port, VCONN_SWAP_SEND_TIMEOUT,
3594 PD_T_SENDER_RESPONSE);
3595 break;
3596 case VCONN_SWAP_SEND_TIMEOUT:
3597 tcpm_swap_complete(port, -ETIMEDOUT);
3598 tcpm_set_state(port, ready_state(port), 0);
3599 break;
3600 case VCONN_SWAP_START:
3601 if (port->vconn_role == TYPEC_SOURCE)
3602 tcpm_set_state(port, VCONN_SWAP_WAIT_FOR_VCONN, 0);
3603 else
3604 tcpm_set_state(port, VCONN_SWAP_TURN_ON_VCONN, 0);
3605 break;
3606 case VCONN_SWAP_WAIT_FOR_VCONN:
3607 tcpm_set_state(port, hard_reset_state(port),
3608 PD_T_VCONN_SOURCE_ON);
3609 break;
3610 case VCONN_SWAP_TURN_ON_VCONN:
3611 tcpm_set_vconn(port, true);
3612 tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
3613 tcpm_set_state(port, ready_state(port), 0);
3614 break;
3615 case VCONN_SWAP_TURN_OFF_VCONN:
3616 tcpm_set_vconn(port, false);
3617 tcpm_set_state(port, ready_state(port), 0);
3618 break;
3619
3620 case DR_SWAP_CANCEL:
3621 case PR_SWAP_CANCEL:
3622 case VCONN_SWAP_CANCEL:
3623 tcpm_swap_complete(port, port->swap_status);
3624 if (port->pwr_role == TYPEC_SOURCE)
3625 tcpm_set_state(port, SRC_READY, 0);
3626 else
3627 tcpm_set_state(port, SNK_READY, 0);
3628 break;
3629
3630 case BIST_RX:
3631 switch (BDO_MODE_MASK(port->bist_request)) {
3632 case BDO_MODE_CARRIER2:
3633 tcpm_pd_transmit(port, TCPC_TX_BIST_MODE_2, NULL);
3634 tcpm_set_state(port, unattached_state(port),
3635 PD_T_BIST_CONT_MODE);
3636 break;
3637 case BDO_MODE_TESTDATA:
3638 if (port->tcpc->set_bist_data) {
3639 tcpm_log(port, "Enable BIST MODE TESTDATA");
3640 port->tcpc->set_bist_data(port->tcpc, true);
3641 }
3642 break;
3643 default:
3644 break;
3645 }
3646 break;
3647 case GET_STATUS_SEND:
3648 tcpm_pd_send_control(port, PD_CTRL_GET_STATUS);
3649 tcpm_set_state(port, GET_STATUS_SEND_TIMEOUT,
3650 PD_T_SENDER_RESPONSE);
3651 break;
3652 case GET_STATUS_SEND_TIMEOUT:
3653 tcpm_set_state(port, ready_state(port), 0);
3654 break;
3655 case GET_PPS_STATUS_SEND:
3656 tcpm_pd_send_control(port, PD_CTRL_GET_PPS_STATUS);
3657 tcpm_set_state(port, GET_PPS_STATUS_SEND_TIMEOUT,
3658 PD_T_SENDER_RESPONSE);
3659 break;
3660 case GET_PPS_STATUS_SEND_TIMEOUT:
3661 tcpm_set_state(port, ready_state(port), 0);
3662 break;
3663 case ERROR_RECOVERY:
3664 tcpm_swap_complete(port, -EPROTO);
3665 tcpm_pps_complete(port, -EPROTO);
3666 tcpm_set_state(port, PORT_RESET, 0);
3667 break;
3668 case PORT_RESET:
3669 tcpm_reset_port(port);
3670 tcpm_set_cc(port, TYPEC_CC_OPEN);
3671 tcpm_set_state(port, PORT_RESET_WAIT_OFF,
3672 PD_T_ERROR_RECOVERY);
3673 break;
3674 case PORT_RESET_WAIT_OFF:
3675 tcpm_set_state(port,
3676 tcpm_default_state(port),
3677 port->vbus_present ? PD_T_PS_SOURCE_OFF : 0);
3678 break;
3679 default:
3680 WARN(1, "Unexpected port state %d\n", port->state);
3681 break;
3682 }
3683 }
3684
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Download attachment ".config.gz" of type "application/gzip" (56581 bytes)
Powered by blists - more mailing lists