diff options
author | Brandon Breitenstein <brandon.breitenstein@intel.com> | 2021-03-03 14:09:22 -0800 |
---|---|---|
committer | Furquan Shaikh <furquan@google.com> | 2021-03-05 17:02:20 +0000 |
commit | d8774f6899ac2468c1a4e1787597ba2c22ecbae8 (patch) | |
tree | e1baf36fe14c03c2658d1b57990840099a76bb03 /src/soc/intel/tigerlake/early_tcss.c | |
parent | 54d59ef7b772374ae9e30826a2e85b9fccafa2e4 (diff) |
soc/intel/tigerlake: Enable TCSS Muxes to disconnect mode during boot
TCSS muxes being left uninitialized during boot is causing some USB3
devices to downgrade to USB2 speed. To properly configure the Type C ports
the muxes should be set to disconnected state during boot so that the port
mapping of USB2/3 devices is properly setup prior to Kernel initializing
devices.
BUG=b:180426950
BRANCH=firmware-volteer-13672.B
TEST= Connected USB3 storage device and rebooted the system multiple
times to verify that devices were no longer downgrading to USB2 speed.
Change-Id: I4352072a4a7d6ccb1364b38377831f3c22ae8fb4
Signed-off-by: Brandon Breitenstein <brandon.breitenstein@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51194
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/soc/intel/tigerlake/early_tcss.c')
-rw-r--r-- | src/soc/intel/tigerlake/early_tcss.c | 124 |
1 files changed, 85 insertions, 39 deletions
diff --git a/src/soc/intel/tigerlake/early_tcss.c b/src/soc/intel/tigerlake/early_tcss.c index cdc90ad813..e32c29fc1b 100644 --- a/src/soc/intel/tigerlake/early_tcss.c +++ b/src/soc/intel/tigerlake/early_tcss.c @@ -104,7 +104,28 @@ static int send_pmc_req(int cmd_type, const struct pmc_ipc_buffer *req, return -1; } -static int send_pmc_connect_request(int port, struct tcss_mux mux_data) +static int send_pmc_disconnect_request(int port, const struct tcss_port_map *port_map) +{ + uint32_t cmd; + struct pmc_ipc_buffer req = { 0 }; + struct pmc_ipc_buffer rsp; + + cmd = tcss_make_conn_cmd(PMC_IPC_TCSS_DISC_REQ_RES, port_map->usb3_port, + port_map->usb2_port, 0, 0, 0, 0); + + req.buf[0] = cmd; + + printk(BIOS_DEBUG, "port C%d DISC req: usage %d usb3 %d usb2 %d\n", + port, + GET_TCSS_CD_FIELD(USAGE, cmd), + GET_TCSS_CD_FIELD(USB3, cmd), + GET_TCSS_CD_FIELD(USB2, cmd)); + + return send_pmc_req(CONNECT_REQ, &req, &rsp, PMC_IPC_DISC_REQ_SIZE); +} + +static int send_pmc_connect_request(int port, const struct tcss_mux_info *mux_data, + const struct tcss_port_map *port_map) { uint32_t cmd; struct pmc_ipc_buffer req = { 0 }; @@ -112,12 +133,12 @@ static int send_pmc_connect_request(int port, struct tcss_mux mux_data) cmd = tcss_make_conn_cmd( PMC_IPC_TCSS_CONN_REQ_RES, - mux_data.usb3_port, - mux_data.usb2_port, - mux_data.ufp, - mux_data.polarity, - mux_data.polarity, - mux_data.acc); + port_map->usb3_port, + port_map->usb2_port, + mux_data->ufp, + mux_data->polarity, + mux_data->polarity, + mux_data->acc); req.buf[0] = cmd; @@ -135,13 +156,14 @@ static int send_pmc_connect_request(int port, struct tcss_mux mux_data) return send_pmc_req(CONNECT_REQ, &req, &rsp, PMC_IPC_CONN_REQ_SIZE); } -static int send_pmc_safe_mode_request(int port, struct tcss_mux mux_data) +static int send_pmc_safe_mode_request(int port, const struct tcss_mux_info *mux_data, + const struct tcss_port_map *port_map) { uint32_t cmd; struct pmc_ipc_buffer req = { 0 }; struct pmc_ipc_buffer rsp; - cmd = tcss_make_safe_mode_cmd(PMC_IPC_TCSS_SAFE_MODE_REQ_RES, mux_data.usb3_port); + cmd = tcss_make_safe_mode_cmd(PMC_IPC_TCSS_SAFE_MODE_REQ_RES, port_map->usb3_port); req.buf[0] = cmd; @@ -153,7 +175,8 @@ static int send_pmc_safe_mode_request(int port, struct tcss_mux mux_data) return send_pmc_req(SAFE_REQ, &req, &rsp, PMC_IPC_SAFE_REQ_SIZE); } -static int send_pmc_dp_hpd_request(int port, struct tcss_mux mux_data) +static int send_pmc_dp_hpd_request(int port, const struct tcss_mux_info *mux_data, + const struct tcss_port_map *port_map) { struct pmc_ipc_buffer req = { 0 }; struct pmc_ipc_buffer rsp; @@ -161,26 +184,29 @@ static int send_pmc_dp_hpd_request(int port, struct tcss_mux mux_data) cmd = tcss_make_hpd_mode_cmd( PMC_IPC_TCSS_HPD_REQ_RES, - mux_data.usb3_port, - mux_data.hpd_lvl, - mux_data.hpd_irq); + port_map->usb3_port, + mux_data->hpd_lvl, + mux_data->hpd_irq); req.buf[0] = cmd; return send_pmc_req(HPD_REQ, &req, &rsp, PMC_IPC_HPD_REQ_SIZE); + } -static int send_pmc_dp_mode_request(int port, struct tcss_mux mux_data) +static int send_pmc_dp_mode_request(int port, const struct tcss_mux_info *mux_data, + const struct tcss_port_map *port_map) { uint32_t cmd; uint8_t dp_mode; int ret; + struct pmc_ipc_buffer req = { 0 }; struct pmc_ipc_buffer rsp; cmd = tcss_make_alt_mode_cmd_buf_0( PMC_IPC_TCSS_ALTMODE_REQ_RES, - mux_data.usb3_port, + port_map->usb3_port, PMC_IPC_DP_MODE); req.buf[0] = cmd; @@ -191,7 +217,7 @@ static int send_pmc_dp_mode_request(int port, struct tcss_mux mux_data) GET_TCSS_ALT_FIELD(USB3, cmd), GET_TCSS_ALT_FIELD(MODE, cmd)); - switch (mux_data.dp_mode) { + switch (mux_data->dp_mode) { case MODE_DP_PIN_A: dp_mode = 1; break; @@ -216,8 +242,8 @@ static int send_pmc_dp_mode_request(int port, struct tcss_mux mux_data) } cmd = tcss_make_alt_mode_cmd_buf_1( - mux_data.polarity, - mux_data.cable, + mux_data->polarity, + mux_data->cable, 0, /* ufp is not supported in DP ALT Mode request */ dp_mode); @@ -235,46 +261,66 @@ static int send_pmc_dp_mode_request(int port, struct tcss_mux mux_data) if (ret) return ret; - send_pmc_dp_hpd_request(port, mux_data); + send_pmc_dp_hpd_request(port, mux_data, port_map); return 0; } -static void update_tcss_mux(int port, struct tcss_mux mux_data) +static void tcss_init_mux(int port, const struct tcss_port_map *port_map) { - int ret = 0; + int ret; - /* check if mux has a DP device */ - if (mux_data.dp) { - ret = send_pmc_connect_request(port, mux_data); + ret = send_pmc_disconnect_request(port, port_map); + if (ret) + printk(BIOS_ERR, "Failed to setup port:%d to initial state\n", port); +} + +static void tcss_configure_dp_mode(const struct tcss_port_map *port_map, size_t num_ports) +{ + int ret; + size_t i; + const struct tcss_mux_info *mux_info; + const struct tcss_port_map *port_info; + + if (!display_init_required()) + return; + + for (i = 0; i < num_ports; i++) { + mux_info = mainboard_tcss_get_mux_info(i); + port_info = &port_map[i]; + + if (!mux_info->dp) + continue; + + ret = send_pmc_connect_request(i, mux_info, port_info); if (ret) { - printk(BIOS_ERR, "Port %d connect request failed\n", port); - return; + printk(BIOS_ERR, "Port %zd connect request failed\n", i); + continue; } - ret = send_pmc_safe_mode_request(port, mux_data); + ret = send_pmc_safe_mode_request(i, mux_info, port_info); if (ret) { - printk(BIOS_ERR, "Port %d safe mode request failed\n", port); - return; + printk(BIOS_ERR, "Port %zd safe mode request failed\n", i); + continue; } - ret = send_pmc_dp_mode_request(port, mux_data); + ret = send_pmc_dp_mode_request(i, mux_info, port_info); + if (ret) + printk(BIOS_ERR, "Port C%zd mux set failed with error %d\n", i, ret); } - - if (ret) - printk(BIOS_ERR, "Port C%d mux set failed with error %d\n", port, ret); } void tcss_early_configure(void) { - const struct tcss_mux *mux_info; + const struct tcss_port_map *port_map; size_t num_ports; - int i; + size_t i; - if (!display_init_required()) + port_map = mainboard_tcss_get_port_info(&num_ports); + if (port_map == NULL) return; - mux_info = mainboard_tcss_fill_mux_info(&num_ports); - for (i = 0; i < num_ports; i++) - update_tcss_mux(i, mux_info[i]); + tcss_init_mux(i, &port_map[i]); + if (CONFIG(EARLY_TCSS_DISPLAY)) + tcss_configure_dp_mode(port_map, num_ports); } |