Skip to content

Commit 553827c

Browse files
Josh-Tsaikiram9
andauthored
fwk: power off the retimer if the DP/HDMI expansion card does not connect the device (#1025)
* fwk: power off the retimer if the DP/HDMI expansion card does not connect the device Signed-off-by: Josh-Tsai <[email protected]> * add support for tgl retimer power off Requires TGL PD firmware 2576 Signed-off-by: Kieran Levin <[email protected]> --------- Signed-off-by: Josh-Tsai <[email protected]> Signed-off-by: Kieran Levin <[email protected]> Co-authored-by: Kieran Levin <[email protected]>
1 parent a29b80c commit 553827c

File tree

5 files changed

+350
-37
lines changed

5 files changed

+350
-37
lines changed

.github/labeler.yml

+39-17
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,57 @@
11
# Add 'repo' label to any root file changes
22
repo:
3-
- ./*
3+
- changed-files:
4+
- any-glob-to-any-file:
5+
- ./*
46

57
hx20:
6-
- board/hx20/*
7-
- board/hx20/**/*
8+
- changed-files:
9+
- any-glob-to-any-file:
10+
- board/hx20/*
11+
- board/hx20/**/*
812

913
hx30:
10-
- board/hx30/*
11-
- board/hx30/**/*
14+
- changed-files:
15+
- any-glob-to-any-file:
16+
- board/hx30/*
17+
- board/hx30/**/*
1218

1319
board-mistake:
14-
- any: ['board/**/*', '!board/hx20/*', '!board/hx30/*']
20+
- changed-files:
21+
- any-glob-to-any-file:
22+
- board/**/*
23+
- all-globs-to-all-files: ['!board/hx20/*', '!board/hx30/*']
1524

1625
mchp:
17-
- chip/mchp/**/*
26+
- changed-files:
27+
- any-glob-to-any-file:
28+
- chip/mchp/**/*
1829

1930
chip-mistake:
20-
- any: ['chip/**/*', '!chip/mchp/*']
31+
- changed-files:
32+
- any-glob-to-any-file:
33+
- chip/**/*
34+
- all-globs-to-all-files: '!chip/mchp/*'
2135

2236
common:
23-
- common/*
24-
- common/**/*
37+
- changed-files:
38+
- any-glob-to-any-file:
39+
- common/*
40+
- common/**/*
2541

2642
baseboard:
27-
- baseboard/*
28-
- baseboard/**/*
43+
- changed-files:
44+
- any-glob-to-any-file:
45+
- baseboard/*
46+
- baseboard/**/*
2947

3048
workflow:
31-
- .github/*
32-
- .github/**/*
33-
34-
project:
35-
- .vscode/*
49+
- changed-files:
50+
- any-glob-to-any-file:
51+
- .github/*
52+
- .github/**/*
53+
54+
project:
55+
- changed-files:
56+
- any-glob-to-any-file:
57+
- .vscode/*

board/hx20/cypress5525.c

+132-1
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,16 @@ int cypd_update_power_status(void)
387387
return rv;
388388
}
389389

390+
static void port_to_safe_mode(int port)
391+
{
392+
uint8_t data[2] = {0x00, CCG_PD_USER_MUX_CONFIG_SAFE};
393+
394+
data[0] = PORT_TO_CONTROLLER_PORT(port);
395+
cypd_write_reg_block(PORT_TO_CONTROLLER(port), CYP5225_MUX_CFG_REG, data, 2);
396+
cypd_write_reg_block(PORT_TO_CONTROLLER(port), CYP5225_DEINIT_PORT_REG, data, 1);
397+
CPRINTS("P%d: Safe", port);
398+
}
399+
390400
void enable_compliance_mode(int controller)
391401
{
392402
int rv;
@@ -553,6 +563,120 @@ int cyp5525_setup(int controller)
553563
}
554564

555565

566+
static bool pending_dp_poweroff[PD_PORT_COUNT];
567+
static void poweroff_dp_check(void)
568+
{
569+
int i;
570+
int alt_active = 0;
571+
572+
for (i = 0; i < PD_PORT_COUNT; i++) {
573+
if (pending_dp_poweroff[i]) {
574+
/* see if alt mode is active */
575+
cypd_read_reg8(PORT_TO_CONTROLLER(i),
576+
CYP5525_DP_ALT_MODE_CONFIG_REG(PORT_TO_CONTROLLER_PORT(i)),
577+
&alt_active);
578+
/*
579+
* DP_ALT should be on bit 1 always, but there is a bug
580+
* in the PD stack that if a port does not have TBT mode
581+
* enabled, it will shift the DP alt mode enable bit to
582+
* bit 0. Since we only whitelist DP alt mode cards, just
583+
* mask on both as a workaround.
584+
*/
585+
if ((alt_active & (BIT(1) + BIT(0))) == 0)
586+
port_to_safe_mode(i);
587+
588+
pending_dp_poweroff[i] = 0;
589+
}
590+
}
591+
}
592+
static void poweroff_dp_deferred(void)
593+
{
594+
task_set_event(TASK_ID_CYPD, CYPD_EVT_DPALT_DISABLE, 0);
595+
596+
}
597+
DECLARE_DEFERRED(poweroff_dp_deferred);
598+
599+
struct framework_dp_ids {
600+
uint16_t vid;
601+
uint16_t pid;
602+
} const cypd_altmode_ids[] = {
603+
{0x32AC, 0x0002},
604+
{0x32AC, 0x0003},
605+
{0x32AC, 0x000E},
606+
};
607+
struct match_vdm_header {
608+
uint8_t idx;
609+
uint8_t val;
610+
} const framework_vdm_hdr_match[] = {
611+
{0, 0x8f},
612+
/*{1, 0x52},*/
613+
{2, 0},
614+
{4, 0x41},
615+
/*{5, 0xa0},*/
616+
{6, 0x00},
617+
{7, 0xFF},
618+
/*{8, 0xAC}, Framework VID */
619+
/*{9, 0x32}, */
620+
/*{10, 0x00},*/
621+
/*{11, 0x6C}*/
622+
};
623+
624+
void cypd_handle_vdm(int controller, int port, uint8_t *data, int len)
625+
{
626+
/* parse vdm
627+
* if we get a DP alt mode VDM that matches our
628+
* HDMI or DP VID/PID we will start a timer
629+
* to set the port mux to safe/isolate
630+
* if we get a enter alt mode later on,
631+
* we will cancel the timer so that PD can
632+
* properly enter the alt mode
633+
*
634+
* ID HDR ProductVDO
635+
* hdr SOP R VDMHDR VDO VDO VDO
636+
* HDMI
637+
* 0x8f52 00 00 41a000ff ac32006c 00000000 00000200 18000000
638+
* DP
639+
* 0x8f52 00 00 41a000ff ac32006c 00000000 00000300 18000000
640+
* 0 1 2 3 4 8 12 16
641+
* 180W Power Adapter
642+
* 0x8f59 00 00 41a800ff ac32c001 00000000 00000e00 01008020
643+
*/
644+
int i;
645+
uint16_t vid, pid;
646+
bool trigger_deferred_update = false;
647+
648+
for (i = 0; i < sizeof(framework_vdm_hdr_match)/sizeof(struct match_vdm_header); i++) {
649+
if (framework_vdm_hdr_match[i].idx >= len)
650+
continue;
651+
652+
if (data[framework_vdm_hdr_match[i].idx] !=
653+
framework_vdm_hdr_match[i].val) {
654+
return;
655+
}
656+
}
657+
658+
for (i = 0; i < sizeof(cypd_altmode_ids)/sizeof(struct framework_dp_ids); i++) {
659+
vid = cypd_altmode_ids[i].vid;
660+
pid = cypd_altmode_ids[i].pid;
661+
if ((vid & 0xFF) == data[8] &&
662+
((vid>>8) & 0xFF) == data[9] &&
663+
(pid & 0xFF) == data[18] &&
664+
((pid>>8) & 0xFF) == data[19]
665+
) {
666+
pending_dp_poweroff[port + (controller<<1)] = true;
667+
trigger_deferred_update = true;
668+
CPRINTS(" vdm vidpid match");
669+
670+
}
671+
672+
}
673+
if (trigger_deferred_update) {
674+
hook_call_deferred(&poweroff_dp_deferred_data, 30000 * MSEC);
675+
}
676+
677+
}
678+
679+
556680
void cypd_set_source_pdo_mask(int enabled_mask)
557681
{
558682
int i;
@@ -1008,6 +1132,11 @@ void cyp5525_port_int(int controller, int port)
10081132
cypd_handle_extend_msg(controller, port, response_len, sop_type);
10091133
CPRINTS("CYP_RESPONSE_RX_EXT_MSG");
10101134
break;
1135+
case CYPD_RESPONSE_VDM_RX:
1136+
i2c_read_offset16_block(i2c_port, addr_flags,
1137+
CYP5525_READ_DATA_MEMORY_REG(port, 0), data2, MIN(response_len, 32));
1138+
cypd_handle_vdm(controller, port, data2, response_len);
1139+
CPRINTS("CYPD_RESPONSE_VDM_RX");
10111140
default:
10121141
if (response_len && verbose_msg_logging) {
10131142
CPRINTF("Port:%d Data:0x", port_idx);
@@ -1087,7 +1216,6 @@ void cypd_handle_state(int controller)
10871216
case CYP5525_STATE_APP_SETUP:
10881217
gpio_disable_interrupt(pd_chip_config[controller].gpio);
10891218
cyp5525_get_version(controller);
1090-
cypd_write_reg8_wait_ack(controller, CYP5225_USER_MAINBOARD_VERSION, board_get_version());
10911219

10921220
/*for(i=0; i < 50;i++) {
10931221
if (gpio_get_level(GPIO_PWR_3V5V_PG) &&
@@ -1332,6 +1460,9 @@ void cypd_interrupt_handler_task(void *p)
13321460
if (evt & CYPD_EVT_INT_CTRL_1) {
13331461
cyp5525_interrupt(1);
13341462
}
1463+
if (evt & CYPD_EVT_DPALT_DISABLE) {
1464+
poweroff_dp_check();
1465+
}
13351466
if (evt & CYPD_EVT_STATE_CTRL_0) {
13361467
cypd_handle_state(0);
13371468
task_wait_event_mask(TASK_EVENT_TIMER,10);

board/hx20/cypress5525.h

+26-4
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@
3131
#define CYP5525_ICL_STS_REG 0x0042
3232
#define CYP5525_ICL_BB_RETIMER_CMD_REG 0x0046
3333
#define CYP5525_ICL_BB_RETIMER_DAT_REG 0x0048
34-
#define CYP5225_USER_MAINBOARD_VERSION 0x004F
35-
#define CYP5225_USER_BB_POWER_EVT 0x004E
36-
#define CYP5225_USER_DISABLE_LOCKOUT 0x004D
34+
#define CYP5225_USER_DISABLE_LOCKOUT 0x004A
35+
#define CYP5225_USER_BB_POWER_EVT 0x004B
36+
/* Hx30 uses to control mux and bbretimer */
37+
#define CYP5225_MUX_CFG_REG 0x004D
38+
#define CYP5225_DEINIT_PORT_REG 0x004E
39+
40+
3741

3842
#define CYP5525_RESPONSE_REG 0x007E
3943
#define CYP5525_DATA_MEM_REG 0x1404
@@ -129,6 +133,11 @@
129133
#define CYP5525_POWERSTATE_S4 0x02
130134
#define CYP5525_POWERSTATE_S5 0x03
131135

136+
/************************************************/
137+
/* HELPER FUNCTIONS */
138+
/************************************************/
139+
#define PORT_TO_CONTROLLER(x) ((x) >> 1)
140+
#define PORT_TO_CONTROLLER_PORT(x) ((x) & 0x01)
132141

133142
/************************************************
134143
* PD COMMAND DEFINITION
@@ -153,6 +162,18 @@ enum cypd_pd_command {
153162
CYPD_PD_CMD_CHANGE_PD_PORT_PARAMS = 0x14,
154163
};
155164

165+
/************************************************
166+
* USER MUXCFG for register 0x0041
167+
* This allows us to override the PD mux
168+
* configuration for a specific port.
169+
************************************************/
170+
enum ccg_usermux_configuration {
171+
CCG_PD_USER_MUX_CONFIG_ISOLATE = 0,
172+
CCG_PD_USER_MUX_CONFIG_SAFE,
173+
CCG_PD_USER_MUX_CONFIG_SS_ONLY,
174+
CCG_PD_USER_MUX_CONFIG_DEBUG_ACCESSORY = 0x0A
175+
};
176+
156177
/************************************************
157178
* RESPONSE DEFINITION
158179
* See 001-97863_0N_V.pdf from cypress for the HPI
@@ -393,7 +414,8 @@ enum pd_task_evt {
393414
CYPD_EVT_UCSI_POLL_CTRL_0 = BIT(7),
394415
CYPD_EVT_UCSI_POLL_CTRL_1 = BIT(8),
395416
CYPD_EVT_RETIMER_PWR = BIT(9),
396-
CYPD_EVT_UPDATE_PWRSTAT = BIT(10)
417+
CYPD_EVT_UPDATE_PWRSTAT = BIT(10),
418+
CYPD_EVT_DPALT_DISABLE = BIT(16),
397419
};
398420

399421
/* PD CHIP */

0 commit comments

Comments
 (0)