soc/intel/common/tcss: Optimize USB-C DP flow and code structure
HPD event may not be ready when configuring TCSS mux for DP, check if any DP device is connected and wait for HPD ready before TCSS configuration. Remove unnecessary dependency on mainboard functions, use generic interface which provides USB-C mux operations. BUG=b:192947843 TEST=select ENABLE_TCSS_DISPLAY_DETECTION in Kconfig.name for Brya. Build coreboot and update your Brya. Boot Brya with USB-C display connected, you should find `HPD ready after %lu ms` and `Port C%zd is configured to DP mode!` in coreboot log. Display should show screen in developer mode or recovery mode. Signed-off-by: Derek Huang <derek.huang@intel.corp-partner.google.com> Change-Id: Ia7e6dd952d3183ecb76de6d4887ee573ef89bb50 Reviewed-on: https://review.coreboot.org/c/coreboot/+/57139 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
parent
7c6d673c26
commit
7f22bc4659
|
@ -4,6 +4,7 @@
|
|||
#define _TCSS_H_
|
||||
|
||||
#include <intelblocks/gpio.h>
|
||||
#include <device/usbc_mux.h>
|
||||
|
||||
/* PMC IPC related offsets and commands */
|
||||
#define PMC_IPC_USBC_CMD_ID 0xA7
|
||||
|
@ -126,19 +127,6 @@ enum pmc_ipc_command_type {
|
|||
#define MODE_DP_PIN_E BIT(4)
|
||||
#define MODE_DP_PIN_F BIT(5)
|
||||
|
||||
/* struct to hold all tcss_mux related variables */
|
||||
struct tcss_mux_info {
|
||||
bool dp; /* DP connected */
|
||||
bool usb; /* USB connected */
|
||||
bool cable; /* Active/Passive Cable */
|
||||
bool polarity; /* polarity of connected device */
|
||||
bool hpd_lvl; /* HPD Level assert */
|
||||
bool hpd_irq; /* HPD IRQ assert */
|
||||
bool ufp;
|
||||
bool acc;
|
||||
uint8_t dp_mode; /* DP Operation Mode */
|
||||
};
|
||||
|
||||
struct tcss_port_map {
|
||||
uint8_t usb2_port; /* USB2 Port Number */
|
||||
uint8_t usb3_port; /* USB3 Port Number */
|
||||
|
@ -156,20 +144,10 @@ struct typec_aux_bias_pads {
|
|||
*/
|
||||
void tcss_configure(const struct typec_aux_bias_pads pads[MAX_TYPE_C_PORTS]);
|
||||
|
||||
/*
|
||||
* Mainboard method to setup any mux config needed for TCSS display operations.
|
||||
* This function will need to obtain any mux data needed to forward to IOM/PMC
|
||||
* Since the mux data may be stored differently by different mainboards this
|
||||
* function must be defined by mainboard with its specific mux data stored in a
|
||||
* tcss_mux_info struct as defined above.
|
||||
* Returns completed tcss_mux_info structure for the specified port
|
||||
*/
|
||||
const struct tcss_mux_info *mainboard_tcss_get_mux_info(int port);
|
||||
|
||||
/*
|
||||
* Method to get only the port information to initialize the muxes to
|
||||
* disconnect mode during boot.
|
||||
* returns tscc_port_map of all ports on system
|
||||
* Returns tcss_port_map of all ports on system
|
||||
*/
|
||||
const struct tcss_port_map *tcss_get_port_info(size_t *num_ports);
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#define BIAS_CTRL_VW_INDEX_SHIFT 16
|
||||
#define BIAS_CTRL_BIT_POS_SHIFT 8
|
||||
#define WAIT_FOR_DISPLAYPORT_TIMEOUT_MS 1000
|
||||
#define WAIT_FOR_HPD_TIMEOUT_MS 3000
|
||||
|
||||
static uint32_t tcss_make_conn_cmd(int u, int u3, int u2, int ufp, int hsl,
|
||||
int sbu, int acc)
|
||||
|
@ -130,7 +132,7 @@ static int send_pmc_disconnect_request(int port, const struct tcss_port_map *por
|
|||
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,
|
||||
static int send_pmc_connect_request(int port, const struct usbc_mux_info *mux_data,
|
||||
const struct tcss_port_map *port_map)
|
||||
{
|
||||
uint32_t cmd;
|
||||
|
@ -144,7 +146,7 @@ static int send_pmc_connect_request(int port, const struct tcss_mux_info *mux_da
|
|||
mux_data->ufp,
|
||||
mux_data->polarity,
|
||||
mux_data->polarity,
|
||||
mux_data->acc);
|
||||
mux_data->dbg_acc);
|
||||
|
||||
req.buf[0] = cmd;
|
||||
|
||||
|
@ -162,7 +164,7 @@ static int send_pmc_connect_request(int port, const struct tcss_mux_info *mux_da
|
|||
return send_pmc_req(CONNECT_REQ, &req, &rsp, PMC_IPC_CONN_REQ_SIZE);
|
||||
}
|
||||
|
||||
static int send_pmc_safe_mode_request(int port, const struct tcss_mux_info *mux_data,
|
||||
static int send_pmc_safe_mode_request(int port, const struct usbc_mux_info *mux_data,
|
||||
const struct tcss_port_map *port_map)
|
||||
{
|
||||
uint32_t cmd;
|
||||
|
@ -181,7 +183,7 @@ static int send_pmc_safe_mode_request(int port, const struct tcss_mux_info *mux_
|
|||
return send_pmc_req(SAFE_REQ, &req, &rsp, PMC_IPC_SAFE_REQ_SIZE);
|
||||
}
|
||||
|
||||
static int send_pmc_dp_hpd_request(int port, const struct tcss_mux_info *mux_data,
|
||||
static int send_pmc_dp_hpd_request(int port, const struct usbc_mux_info *mux_data,
|
||||
const struct tcss_port_map *port_map)
|
||||
{
|
||||
struct pmc_ipc_buffer req = { 0 };
|
||||
|
@ -200,7 +202,7 @@ static int send_pmc_dp_hpd_request(int port, const struct tcss_mux_info *mux_dat
|
|||
|
||||
}
|
||||
|
||||
static int send_pmc_dp_mode_request(int port, const struct tcss_mux_info *mux_data,
|
||||
static int send_pmc_dp_mode_request(int port, const struct usbc_mux_info *mux_data,
|
||||
const struct tcss_port_map *port_map)
|
||||
{
|
||||
uint32_t cmd;
|
||||
|
@ -223,7 +225,7 @@ static int send_pmc_dp_mode_request(int port, const struct tcss_mux_info *mux_da
|
|||
GET_TCSS_ALT_FIELD(USB3, cmd),
|
||||
GET_TCSS_ALT_FIELD(MODE, cmd));
|
||||
|
||||
switch (mux_data->dp_mode) {
|
||||
switch (mux_data->dp_pin_mode) {
|
||||
case MODE_DP_PIN_A:
|
||||
dp_mode = 1;
|
||||
break;
|
||||
|
@ -282,35 +284,59 @@ static void tcss_init_mux(int port, const struct tcss_port_map *port_map)
|
|||
|
||||
static void tcss_configure_dp_mode(const struct tcss_port_map *port_map, size_t num_ports)
|
||||
{
|
||||
int ret;
|
||||
int ret, port_bitmask;
|
||||
size_t i;
|
||||
const struct tcss_mux_info *mux_info;
|
||||
const struct usbc_ops *ops;
|
||||
struct usbc_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];
|
||||
ops = usbc_get_ops();
|
||||
if (ops == NULL)
|
||||
return;
|
||||
|
||||
if (!mux_info->dp)
|
||||
port_bitmask = ops->dp_ops.wait_for_connection(WAIT_FOR_DISPLAYPORT_TIMEOUT_MS);
|
||||
if (!port_bitmask) /* No DP device is connected */
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_ports; i++) {
|
||||
if (!(port_bitmask & BIT(i)))
|
||||
continue;
|
||||
|
||||
ret = send_pmc_connect_request(i, mux_info, port_info);
|
||||
ret = ops->dp_ops.enter_dp_mode(i);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
|
||||
ret = ops->dp_ops.wait_for_hpd(i, WAIT_FOR_HPD_TIMEOUT_MS);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
|
||||
ret = ops->mux_ops.get_mux_info(i, &mux_info);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
|
||||
port_info = &port_map[i];
|
||||
|
||||
ret = send_pmc_connect_request(i, &mux_info, port_info);
|
||||
if (ret) {
|
||||
printk(BIOS_ERR, "Port %zd connect request failed\n", i);
|
||||
continue;
|
||||
}
|
||||
ret = send_pmc_safe_mode_request(i, mux_info, port_info);
|
||||
ret = send_pmc_safe_mode_request(i, &mux_info, port_info);
|
||||
if (ret) {
|
||||
printk(BIOS_ERR, "Port %zd safe mode request failed\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = send_pmc_dp_mode_request(i, mux_info, port_info);
|
||||
if (ret)
|
||||
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);
|
||||
} else {
|
||||
printk(BIOS_INFO, "Port C%zd is configured to DP mode!\n", i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue