@@ -308,24 +308,46 @@ int board_set_active_charge_port(int charge_port)
308308#endif /* CONFIG_PD_COMMON_VBUS_CONTROL */
309309
310310#ifdef CONFIG_PD_CCG6_ERROR_RECOVERY
311-
312311/*****************************************************************
313312 * Error Recovery Functions
314313 ****************************************************************/
315314
316- static bool reconnect_flag ;
317- void cypd_set_error_recovery (void )
315+ static void perform_error_recovery (int controller )
318316{
319317 int i ;
320-
321- for (i = 0 ; i < PD_CHIP_COUNT ; i ++ ) {
322- /* We use port reconnect (0x2C) to replace error recovery (0xC1) for GRL issue.
323- * GRL FV 3.1.2.3.
324- * 0xC0 means no recovery.
325- */
326- cypd_write_reg8_wait_ack (i , CCG_SYS_PWR_STATE , 0xC0 );
318+ uint8_t data [2 ] = {0x00 , CCG_PD_USER_CMD_TYPEC_ERR_RECOVERY };
319+ uint32_t batt_os_percentage = get_system_percentage ();
320+
321+ if (controller < 2 )
322+ for (i = 0 ; i < 2 ; i ++ ) {
323+ if (!((controller * 2 + i ) == get_active_charge_pd_port () &&
324+ battery_get_disconnect_state () != BATTERY_NOT_DISCONNECTED )) {
325+
326+ data [0 ] = PORT_TO_CONTROLLER_PORT (i );
327+ cypd_write_reg_block (PORT_TO_CONTROLLER (i ),
328+ CCG_DPM_CMD_REG ,
329+ data , 2 );
330+ }
331+ }
332+ else {
333+ /* Hard reset all ports that are not supplying power in dead battery mode */
334+ for (i = 0 ; i < PD_PORT_COUNT ; i ++ ) {
335+ if (!(i == get_active_charge_pd_port () &&
336+ battery_get_disconnect_state () != BATTERY_NOT_DISCONNECTED )) {
337+
338+ if ((pd_port_states [i ].c_state == CCG_STATUS_SOURCE ) &&
339+ (batt_os_percentage < 3 ) && (i == get_active_charge_pd_port ()))
340+ continue ;
341+
342+ data [0 ] = PORT_TO_CONTROLLER_PORT (i );
343+ cypd_write_reg_block (PORT_TO_CONTROLLER (i ),
344+ CCG_DPM_CMD_REG ,
345+ data , 2 );
346+ }
347+ }
327348 }
328349}
350+ #endif /* CONFIG_PD_CCG6_ERROR_RECOVERY */
329351
330352void update_system_power_state (int controller )
331353{
@@ -342,16 +364,12 @@ void update_system_power_state(int controller)
342364 /* Do not update the same state again */
343365 if (pre_state != CCG_POWERSTATE_S5 )
344366 cypd_set_power_state (CCG_POWERSTATE_S5 , controller );
345-
346367 pre_state = CCG_POWERSTATE_S5 ;
347- reconnect_flag = true;
348368 break ;
349369 case POWER_S3 :
350370 case POWER_S4S3 :
351371 case POWER_S5S3 :
352372 case POWER_S0S3 :
353- case POWER_S0ix :
354- case POWER_S0S0ix : /* S0 -> S0ix */
355373 /* Do not update the same state again */
356374 if (pre_state != CCG_POWERSTATE_S3 )
357375 cypd_set_power_state (CCG_POWERSTATE_S3 , controller );
@@ -361,132 +379,27 @@ void update_system_power_state(int controller)
361379 case POWER_S3S0 :
362380 case POWER_S0ixS0 : /* S0ix -> S0 */
363381 if (pre_state != CCG_POWERSTATE_S0 ) {
364- cypd_set_error_recovery ();
365382 cypd_set_power_state (CCG_POWERSTATE_S0 , controller );
383+ #ifdef CONFIG_PD_CCG6_ERROR_RECOVERY
384+ /* only execute the error recovery when the system power on */
385+ if (pre_state != CCG_POWERSTATE_S0ix )
386+ perform_error_recovery (controller );
387+ #endif
366388 }
367389 pre_state = CCG_POWERSTATE_S0 ;
368-
369- if (reconnect_flag ) {
370- CPRINTS ("CYPD reconnect" );
371- cypd_reconnect ();
372- reconnect_flag = false;
373- }
374- break ;
375- default :
376390 break ;
377- }
378- }
379-
380- int cypd_reconnect_port_disable (int controller )
381- {
382- int rv ;
383- uint8_t pd_status_reg [4 ];
384- int port_power_role ;
385- int portEnable = 0 ; /* default disable all port*/
386- bool battery_can_discharge = (battery_is_present () == BP_YES ) &
387- battery_get_disconnect_state ();
388-
389- /* check the first port's status */
390- rv = cypd_read_reg_block (controller , CCG_PD_STATUS_REG (0 ), pd_status_reg , 4 );
391- if (rv != EC_SUCCESS )
392- CPRINTS ("CCG_PD_STATUS_REG failed" );
393-
394- port_power_role = pd_status_reg [1 ] & BIT (0 );
395- /* Does not disable the source port */
396- if (port_power_role == PD_ROLE_SINK && (pd_status_reg [1 ] & BIT (2 )) == BIT (2 ))
397- portEnable |= BIT (0 );
398-
399- /* check the second port's status */
400- rv = cypd_read_reg_block (controller , CCG_PD_STATUS_REG (1 ), pd_status_reg , 4 );
401- if (rv != EC_SUCCESS )
402- CPRINTS ("CCG_PD_STATUS_REG failed" );
403-
404- port_power_role = pd_status_reg [1 ] & BIT (0 );
405- /* Does not disable the source port */
406- if (port_power_role == PD_ROLE_SINK && (pd_status_reg [1 ] & BIT (2 )) == BIT (2 ))
407- portEnable |= BIT (1 );
408-
409- /* If there is DC, just force reconnect port. */
410- if (battery_can_discharge )
411- portEnable = 0x0 ;
412-
413- rv = cypd_write_reg8 (controller , CCG_PDPORT_ENABLE_REG , portEnable );
414- if (rv != EC_SUCCESS )
415- return rv ;
416-
417- CPRINTS ("disable controller: %d, Port: 0x%02x" , controller , portEnable );
418-
419- return rv ;
420- }
421-
422- int cypd_reconnect_port_enable (int controller )
423- {
424- int rv ;
425-
426- rv = cypd_write_reg8 (controller , CCG_PDPORT_ENABLE_REG , 3 );
427- if (rv != EC_SUCCESS )
428- return rv ;
429-
430- CPRINTS ("enable controller: %d" , controller );
431-
432- return rv ;
433- }
434-
435- void cypd_reconnect (void )
436- {
437- int events ;
438-
439- /* trigger port reconnect, will check ac status while disable port */
440- events = task_wait_event_mask (TASK_EVENT_TIMER , 100 * MSEC );
441- if (events & TASK_EVENT_TIMER )
442- task_set_event (TASK_ID_CYPD , CCG_EVT_PORT_DISABLE );
443- }
444- #else
445-
446- void update_system_power_state (int controller )
447- {
448- enum power_state ps = power_get_state ();
449- /* CCG6 does not support power state G3, just for initial state */
450- static uint8_t pre_state = CCG_POWERSTATE_G3 ;
451-
452- switch (ps ) {
453- case POWER_G3 :
454- case POWER_S5G3 :
455- case POWER_S5 :
456- case POWER_S3S5 :
457- case POWER_S4S5 :
458- /* Do not update the same state again */
459- if (pre_state != CCG_POWERSTATE_S5 )
460- cypd_set_power_state (CCG_POWERSTATE_S5 , controller );
461- pre_state = CCG_POWERSTATE_S5 ;
462- break ;
463- case POWER_S3 :
464- case POWER_S4S3 :
465- case POWER_S5S3 :
466- case POWER_S0S3 :
467391 case POWER_S0ix :
468392 case POWER_S0S0ix : /* S0 -> S0ix */
469393 /* Do not update the same state again */
470- if (pre_state != CCG_POWERSTATE_S3 )
394+ if (pre_state != CCG_POWERSTATE_S0ix )
471395 cypd_set_power_state (CCG_POWERSTATE_S3 , controller );
472- pre_state = CCG_POWERSTATE_S3 ;
473- break ;
474- case POWER_S0 :
475- case POWER_S3S0 :
476- case POWER_S0ixS0 : /* S0ix -> S0 */
477- if (pre_state != CCG_POWERSTATE_S0 )
478- cypd_set_power_state (CCG_POWERSTATE_S0 , controller );
479- pre_state = CCG_POWERSTATE_S0 ;
396+ pre_state = CCG_POWERSTATE_S0ix ;
480397 break ;
481398 default :
482399 break ;
483400 }
484-
485401}
486402
487- #endif /* PD_CCG6_ERROR_RECOVERY */
488-
489-
490403/*****************************************************************
491404 * BB Retimer Functions
492405 ****************************************************************/
0 commit comments