@@ -95,7 +95,7 @@ static void cypd_update_port_state(int controller, int port);
9595static void cypd_pdo_reset_deferred (void );
9696static void cypd_set_prepare_pdo (int controller , int port );
9797
98- int cypd_write_reg_block (int controller , int reg , void * data , int len )
98+ int cypd_write_reg_block (int controller , int reg , const void * data , int len )
9999{
100100 int rv ;
101101 uint16_t i2c_port = pd_chip_config [controller ].i2c_port ;
@@ -199,15 +199,16 @@ int cypd_clear_int(int controller, int mask)
199199
200200int cypd_wait_for_ack (int controller , int timeout_ms )
201201{
202- int timeout ;
203202 const struct gpio_dt_spec * intr = gpio_get_dt_spec (pd_chip_config [controller ].gpio );
203+ timestamp_t start = get_time ();
204204
205205 /* wait for interrupt ack to be asserted */
206- for ( timeout = 0 ; timeout < timeout_ms ; timeout ++ ) {
206+ do {
207207 if (gpio_pin_get_dt (intr ) == 0 )
208208 break ;
209- usleep (MSEC );
210- }
209+ usleep (100 );
210+ } while (time_since32 (start ) < (timeout_ms * MSEC ));
211+
211212 /* make sure response is ok */
212213 if (gpio_pin_get_dt (intr ) != 0 ) {
213214 CPRINTS ("%s timeout on interrupt" , __func__ );
@@ -221,8 +222,35 @@ static int cypd_write_reg8_wait_ack(int controller, int reg, int data)
221222 int rv = EC_SUCCESS ;
222223 int intr_status ;
223224 int event ;
224- int cmd_port = reg & 0x2000 ? 1 : 0 ;
225+ int cmd_port = -1 ;
225226 int ack_mask = 0 ;
227+ int expected_ack_mask = 0 ;
228+ const struct gpio_dt_spec * intr = gpio_get_dt_spec (pd_chip_config [controller ].gpio );
229+
230+ if (reg < 0x1000 ) {
231+ expected_ack_mask = CCG_DEV_INTR ;
232+ cmd_port = -1 ;
233+ } else if (reg < 0x2000 ) {
234+ expected_ack_mask = CCG_PORT0_INTR ;
235+ cmd_port = 0 ;
236+ } else {
237+ expected_ack_mask = CCG_PORT1_INTR ;
238+ cmd_port = 1 ;
239+ }
240+
241+ if (gpio_pin_get_dt (intr ) == 0 ) {
242+ /* we may have a pending interrupt */
243+ rv = cypd_get_int (controller , & intr_status );
244+ CPRINTS ("%s pre 0x%x " , __func__ , intr_status );
245+ if (intr_status & CCG_DEV_INTR ) {
246+ rv = cypd_read_reg16 (controller , CCG_RESPONSE_REG , & event );
247+ if (event < 0x80 ) {
248+ cypd_clear_int (controller , CCG_DEV_INTR );
249+ }
250+ usleep (50 );
251+ }
252+ }
253+
226254
227255 rv = cypd_write_reg8 (controller , reg , data );
228256 if (rv != EC_SUCCESS )
@@ -236,27 +264,40 @@ static int cypd_write_reg8_wait_ack(int controller, int reg, int data)
236264 if (rv != EC_SUCCESS )
237265 CPRINTS ("Get INT Fail" );
238266
239- if (intr_status & CCG_DEV_INTR ) {
267+ if (intr_status & CCG_DEV_INTR && cmd_port == -1 ) {
240268 rv = cypd_read_reg16 (controller , CCG_RESPONSE_REG , & event );
241269 if (rv != EC_SUCCESS )
242270 CPRINTS ("fail to read DEV response" );
243271 ack_mask = CCG_DEV_INTR ;
244- } else if (intr_status & CCG_PORT0_INTR && ! cmd_port ) {
272+ } else if (intr_status & CCG_PORT0_INTR && cmd_port == 0 ) {
245273 rv = cypd_read_reg16 (controller , CCG_PORT_PD_RESPONSE_REG (0 ), & event );
246274 if (rv != EC_SUCCESS )
247275 CPRINTS ("fail to read P0 response" );
248276 ack_mask = CCG_PORT0_INTR ;
249- } else if (intr_status & CCG_PORT1_INTR && cmd_port ) {
277+ } else if (intr_status & CCG_PORT1_INTR && cmd_port == 1 ) {
250278 rv = cypd_read_reg16 (controller , CCG_PORT_PD_RESPONSE_REG (1 ), & event );
251279 if (rv != EC_SUCCESS )
252280 CPRINTS ("fail to read P1 response" );
253281 ack_mask = CCG_PORT1_INTR ;
282+ } else {
283+ CPRINTS ("%s C:%d Unexpected response 0x%x to reg 0x%x" ,
284+ __func__ , controller , intr_status , reg );
285+ rv = cypd_read_reg16 (controller , CCG_RESPONSE_REG , & event );
286+ CPRINTS ("Dev 0x%x" , event );
287+ rv = cypd_read_reg16 (controller , CCG_PORT_PD_RESPONSE_REG (0 ), & event );
288+ CPRINTS ("P0 0x%x" , event );
289+ rv = cypd_read_reg16 (controller , CCG_PORT_PD_RESPONSE_REG (1 ), & event );
290+ CPRINTS ("P1 0x%x" , event );
254291 }
255292
256293 /* only clear response code let main task handle event code */
257294 if (event < 0x80 ) {
258295 cypd_clear_int (controller , ack_mask );
259- rv = event & CCG_RESPONSE_SUCCESS ? EC_SUCCESS : EC_ERROR_INVAL ;
296+ if (event != CCG_RESPONSE_SUCCESS ) {
297+ CPRINTS ("%s C:%d 0x%x response 0x%x" ,
298+ __func__ , controller , reg , event );
299+ }
300+ rv = (event == CCG_RESPONSE_SUCCESS ) ? EC_SUCCESS : EC_ERROR_INVAL ;
260301 }
261302
262303 usleep (50 );
@@ -1224,22 +1265,22 @@ static void perform_error_recovery(int controller)
12241265 if (controller < 2 )
12251266 for (i = 0 ; i < 2 ; i ++ ) {
12261267 if (!((controller * 2 + i ) == prev_charge_port &&
1227- battery_get_disconnect_state () != BATTERY_NOT_DISCONNECTED ) &&
1228- ( pd_port_states [ i ]. c_state != CCG_STATUS_NOTHING ))
1268+ battery_get_disconnect_state () != BATTERY_NOT_DISCONNECTED )) {
1269+
12291270 data [0 ] = PORT_TO_CONTROLLER_PORT (i );
12301271 cypd_write_reg_block (PORT_TO_CONTROLLER (i ),
12311272 CCG_DPM_CMD_REG ,
12321273 data , 2 );
1274+ }
12331275 }
12341276 else {
12351277 /* Hard reset all ports that are not supplying power in dead battery mode */
12361278 for (i = 0 ; i < PD_PORT_COUNT ; i ++ ) {
12371279 if (!(i == prev_charge_port &&
1238- battery_get_disconnect_state () != BATTERY_NOT_DISCONNECTED ) &&
1239- ((pd_port_states [i ].c_state != CCG_STATUS_NOTHING ))) {
1280+ battery_get_disconnect_state () != BATTERY_NOT_DISCONNECTED )) {
12401281
12411282 if ((pd_port_states [i ].c_state == CCG_STATUS_SOURCE ) &&
1242- (batt_os_percentage < 30 ) && (i == prev_charge_port ))
1283+ (batt_os_percentage < 3 ) && (i == prev_charge_port ))
12431284 continue ;
12441285
12451286 CPRINTS ("Hard reset %d" , i );
@@ -1264,21 +1305,17 @@ static void port_to_safe_mode(int port)
12641305
12651306}
12661307
1267- enum power_state pd_prev_power_state = POWER_G3 ;
12681308void update_system_power_state (int controller )
12691309{
12701310 enum power_state ps = power_get_state ();
1271-
12721311 switch (ps ) {
12731312 case POWER_G3 :
12741313 case POWER_S5G3 :
1275- pd_prev_power_state = POWER_G3 ;
12761314 cypd_set_power_state (CCG_POWERSTATE_G3 , controller );
12771315 break ;
12781316 case POWER_S5 :
12791317 case POWER_S3S5 :
12801318 case POWER_S4S5 :
1281- pd_prev_power_state = POWER_S5 ;
12821319 cypd_set_power_state (CCG_POWERSTATE_S5 , controller );
12831320 break ;
12841321 case POWER_S3 :
@@ -1287,19 +1324,11 @@ void update_system_power_state(int controller)
12871324 case POWER_S0S3 :
12881325 case POWER_S0ixS3 : /* S0ix -> S3 */
12891326 cypd_set_power_state (CCG_POWERSTATE_S3 , controller );
1290- if (pd_prev_power_state < POWER_S3 ) {
1291- perform_error_recovery (controller );
1292- pd_prev_power_state = ps ;
1293- }
12941327 break ;
12951328 case POWER_S0 :
12961329 case POWER_S3S0 :
12971330 case POWER_S0ixS0 : /* S0ix -> S0 */
12981331 cypd_set_power_state (CCG_POWERSTATE_S0 , controller );
1299- if (pd_prev_power_state < POWER_S3 ) {
1300- perform_error_recovery (controller );
1301- pd_prev_power_state = ps ;
1302- }
13031332 break ;
13041333 case POWER_S0ix :
13051334 case POWER_S3S0ix : /* S3 -> S0ix */
@@ -1318,6 +1347,13 @@ void cypd_set_power_active(void)
13181347 task_set_event (TASK_ID_CYPD , CCG_EVT_S_CHANGE );
13191348}
13201349
1350+ void cypd_port_reset (void )
1351+ {
1352+ task_set_event (TASK_ID_CYPD , CCG_EVT_PLT_RESET );
1353+ }
1354+
1355+
1356+
13211357#define CYPD_SETUP_CMDS_LEN 2
13221358static int cypd_setup (int controller )
13231359{
@@ -1422,6 +1458,7 @@ static void cypd_handle_state(int controller)
14221458 cypd_update_power_status (controller );
14231459
14241460 update_system_power_state (controller );
1461+
14251462 cypd_setup (controller );
14261463
14271464 /* After initial complete, update the type-c port state */
@@ -1612,7 +1649,7 @@ void cypd_handle_vdm(int controller, int port, uint8_t *data, int len)
16121649
16131650 }
16141651 if (trigger_deferred_update ) {
1615- hook_call_deferred (& poweroff_dp_deferred_data , 5000 * MSEC );
1652+ hook_call_deferred (& poweroff_dp_deferred_data , 10000 * MSEC );
16161653 }
16171654
16181655}
@@ -1636,10 +1673,15 @@ void cypd_port_int(int controller, int port)
16361673 switch (data2 [0 ]) {
16371674 case CCG_RESPONSE_PORT_DISCONNECT :
16381675 record_ucsi_connector_change_event (controller , port );
1676+ CPRINTS ("PORT_DISCONNECT" );
16391677 __fallthrough ;
16401678 case CCG_RESPONSE_HARD_RESET_RX :
16411679 case CCG_RESPONSE_TYPE_C_ERROR_RECOVERY :
1642- CPRINTS ("TYPE_C_ERROR_RECOVERY" );
1680+ if (data2 [0 ] == CCG_RESPONSE_HARD_RESET_RX )
1681+ CPRINTS ("HARD_RESET_RX" );
1682+ if (data2 [0 ] == CCG_RESPONSE_TYPE_C_ERROR_RECOVERY )
1683+ CPRINTS ("TYPE_C_ERROR_RECOVERY" );
1684+
16431685 cypd_update_port_state (controller , port );
16441686 cypd_release_port (controller , port );
16451687 /* make sure the type-c state is cleared */
@@ -1854,6 +1896,11 @@ void cypd_interrupt_handler_task(void *p)
18541896 if (evt & CCG_EVT_UPDATE_PWRSTAT )
18551897 cypd_update_power_status (2 );
18561898
1899+ if (evt & CCG_EVT_PLT_RESET ) {
1900+ CPRINTS ("PD Platform reset" );
1901+ perform_error_recovery (2 );
1902+ }
1903+
18571904
18581905 if (evt & (CCG_EVT_INT_CTRL_0 | CCG_EVT_INT_CTRL_1 |
18591906 CCG_EVT_STATE_CTRL_0 | CCG_EVT_STATE_CTRL_1 )) {
@@ -2067,6 +2114,10 @@ static int cmd_cypd_get_status(int argc, const char **argv)
20672114 port_status [(data >> 2 ) & 0x7 ],
20682115 data & 0x20 ? "Ra" : "NoRa" ,
20692116 current_level [(data >> 6 ) & 0x03 ]);
2117+ cypd_read_reg8 (i , CCG_PORT_VBUS_FET_CONTROL (p ), & data );
2118+ CPRINTS (" VBUS_FET : %s %s" ,
2119+ data & 0x1 ? "EC" : "Auto" ,
2120+ data & 0x2 ? "On" : "Off" );
20702121 cypd_read_reg_block (i , CCG_CURRENT_RDO_REG (p ), data16 , 4 );
20712122 CPRINTS (" RDO : Current:%dmA MaxCurrent%dmA 0x%08x" ,
20722123 ((data16 [0 ] + (data16 [1 ]<<8 )) & 0x3FF )* 10 ,
@@ -2080,10 +2131,10 @@ static int cmd_cypd_get_status(int argc, const char **argv)
20802131 * (uint32_t * )data16 );
20812132 cypd_read_reg8 (i , CCG_TYPE_C_VOLTAGE_REG (p ), & data );
20822133 CPRINTS (" TYPE_C_VOLTAGE : %dmV" , data * 100 );
2083- cypd_read_reg16 (i , CCG_PORT_INTR_STATUS_REG (p ), & data );
2084- CPRINTS (" INTR_STATUS_REG0: 0x%02x " , data );
2085- cypd_read_reg16 (i , CCG_PORT_INTR_STATUS_REG (p )+ 2 , & data );
2086- CPRINTS (" INTR_STATUS_REG1: 0x%02x " , data );
2134+ cypd_read_reg8 (i , CCG_PORT_CURRENT_REG (p ), & data );
2135+ CPRINTS (" TYPE_C_CURRENT : %dmA " , data * 50 );
2136+ cypd_read_reg_block (i , CCG_PORT_INTR_STATUS_REG (p ), data16 , 4 );
2137+ cypd_print_buff (" INTR_STATUS: " , data16 , 4 );
20872138 cypd_read_reg16 (i , SELECT_SINK_PDO_EPR_MASK (p ), & data );
20882139 CPRINTS (" SINK PDO EPR MASK: 0x%02x" , data );
20892140 /* Flush console to avoid truncating output */
0 commit comments