Skip to content

Commit c34bb44

Browse files
authored
Merge pull request #811 from FrameworkComputer/fwk.hang_issue
Fwk.hang issue
2 parents b950ae6 + 526d6c9 commit c34bb44

File tree

3 files changed

+100
-34
lines changed

3 files changed

+100
-34
lines changed

zephyr/program/lotus/include/cypress_pd_common.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@
8585
(0x1010 + ((x) * 0x1000))
8686
#define CCG_CURRENT_RDO_REG(x) \
8787
(0x1014 + ((x) * 0x1000))
88+
#define CCG_ALT_MODE_CMD_REG(x) \
89+
(0x101C + ((x) * 0x1000))
90+
#define CCG_APP_HW_CMD_REG(x) \
91+
(0x1020 + ((x) * 0x1000))
8892
#define CCG_EVENT_MASK_REG(x) \
8993
(0x1024 + ((x) * 0x1000))
9094
#define CCG_VDM_EC_CONTROL_REG(x) \
@@ -95,6 +99,12 @@
9599
(0x1032 + ((x) * 0x1000))
96100
#define CCG_PORT_INTR_STATUS_REG(x) \
97101
(0x1034 + ((x) * 0x1000))
102+
#define CCG_PORT_CURRENT_REG(x) \
103+
(0x1058 + ((x) * 0x1000))
104+
#define CCG_PORT_HOST_CAP_REG(x) \
105+
(0x105C + ((x) * 0x1000))
106+
#define CCG_ALT_MODE_MASK_REG(x) \
107+
(0x1060 + ((x) * 0x1000))
98108
#define SELECT_SINK_PDO_EPR_MASK(x) \
99109
(0x1065 + ((x) * 0x1000))
100110
#define CCG_SINK_PPS_AVS_CTRL_REG(x) \
@@ -289,6 +299,7 @@ enum ccg_usermux_configuration {
289299
CCG_PD_USER_MUX_CONFIG_ISOLATE = 0,
290300
CCG_PD_USER_MUX_CONFIG_SAFE,
291301
CCG_PD_USER_MUX_CONFIG_SS_ONLY,
302+
CCG_PD_USER_MUX_CONFIG_DEINIT = 0x09,
292303
CCG_PD_USER_MUX_CONFIG_DEBUG_ACCESSORY = 0x0A
293304
};
294305

@@ -475,7 +486,7 @@ struct pd_chip_ucsi_info_t {
475486

476487
int cypd_write_reg8(int controller, int reg, int data);
477488

478-
int cypd_write_reg_block(int controller, int reg, void *data, int len);
489+
int cypd_write_reg_block(int controller, int reg, const void *data, int len);
479490

480491
int cypd_read_reg_block(int controller, int reg, void *data, int len);
481492

@@ -550,4 +561,6 @@ int cypd_get_ac_power(void);
550561
*/
551562
void force_disable_epr_mode(void);
552563

564+
void cypd_port_reset(void);
565+
553566
#endif /* __CROS_EC_CYPRESS_PD_COMMON_H */

zephyr/program/lotus/src/board_host_command.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ static enum ec_status enter_non_acpi_mode(struct host_cmd_handler_args *args)
173173

174174
update_apu_ready(1);
175175

176+
cypd_port_reset();
177+
176178
/**
177179
* Even though the protocol returns EC_SUCCESS,
178180
* the system still does not update the power limit.

zephyr/program/lotus/src/cypress_pd_common.c

Lines changed: 84 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static void cypd_update_port_state(int controller, int port);
9595
static void cypd_pdo_reset_deferred(void);
9696
static 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

200200
int 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;
12681308
void 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
13221358
static 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

Comments
 (0)