mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
In order to ensure we are always meeting the deadlines for the IRQ_HPD pulse, increase the priority of the processing by moving the rising edge from the low-priority HOOK task (in a deferred function) to the caller task (which is the high-priority PD task). The downside is we are now sleeping in the PD task blocking the processing of the PD messages during this time. Changed HPD_DSTREAM_DEBOUNCE_IRQ to 500us instead of 750us. According to DP spec, the IRQ_HPD pulse width is between 500us and 1000us. Ensure there is a minimum of 2ms delay in between each IRQ_HPD as specified by the DP spec, by sleeping before sending the next pulse if needed. (in practice, this should not wait if we are not too off processing the messages) BUG=chromium:711334 BRANCH=glados strago reef oak TEST=manual, on SKL platform with kernel 3.18 and MST, verify display is functional on USB-C dock. Change-Id: Ib2e9dd608c5f1c671cc5a0fd979a5742101375ff Signed-off-by: Kevin K Wong <kevin.k.wong@intel.com> Signed-off-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/508629 Reviewed-by: Todd Broch <tbroch@chromium.org>
94 lines
2.2 KiB
C
94 lines
2.2 KiB
C
/* Copyright 2016 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
/* Type-C port manager for Parade PS8751 with integrated superspeed muxes */
|
|
|
|
#include "common.h"
|
|
#include "ps8751.h"
|
|
#include "tcpm.h"
|
|
#include "timer.h"
|
|
#include "usb_pd.h"
|
|
|
|
#if !defined(CONFIG_USB_PD_TCPM_TCPCI) || \
|
|
!defined(CONFIG_USB_PD_TCPM_MUX) || \
|
|
!defined(CONFIG_USBC_SS_MUX)
|
|
|
|
#error "PS8751 is using a standard TCPCI interface with integrated mux control"
|
|
#error "Please upgrade your board configuration"
|
|
|
|
#endif
|
|
|
|
/*
|
|
* timestamp of the next possible toggle to ensure the 2-ms spacing
|
|
* between IRQ_HPD.
|
|
*/
|
|
static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_COUNT];
|
|
|
|
static int dp_set_hpd(int port, int enable)
|
|
{
|
|
int reg;
|
|
int rv;
|
|
|
|
rv = tcpc_read(port, PS8751_REG_CTRL_1, ®);
|
|
if (rv)
|
|
return rv;
|
|
if (enable)
|
|
reg |= PS8751_REG_CTRL_1_HPD;
|
|
else
|
|
reg &= ~PS8751_REG_CTRL_1_HPD;
|
|
return tcpc_write(port, PS8751_REG_CTRL_1, reg);
|
|
}
|
|
|
|
static int dp_set_irq(int port, int enable)
|
|
{
|
|
|
|
int reg;
|
|
int rv;
|
|
|
|
rv = tcpc_read(port, PS8751_REG_CTRL_1, ®);
|
|
if (rv)
|
|
return rv;
|
|
if (enable)
|
|
reg |= PS8751_REG_CTRL_1_IRQ;
|
|
else
|
|
reg &= ~PS8751_REG_CTRL_1_IRQ;
|
|
return tcpc_write(port, PS8751_REG_CTRL_1, reg);
|
|
}
|
|
|
|
void ps8751_tcpc_update_hpd_status(int port, int hpd_lvl, int hpd_irq)
|
|
{
|
|
dp_set_hpd(port, hpd_lvl);
|
|
|
|
if (hpd_irq) {
|
|
uint64_t now = get_time().val;
|
|
/* wait for the minimum spacing between IRQ_HPD if needed */
|
|
if (now < hpd_deadline[port])
|
|
usleep(hpd_deadline[port] - now);
|
|
|
|
dp_set_irq(port, 0);
|
|
usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
|
|
dp_set_irq(port, hpd_irq);
|
|
}
|
|
/* enforce 2-ms delay between HPD pulses */
|
|
hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
|
|
}
|
|
|
|
int ps8751_tcpc_get_fw_version(int port, int *version)
|
|
{
|
|
return tcpc_read(port, PS8751_REG_VERSION, version);
|
|
}
|
|
|
|
#ifdef CONFIG_CMD_I2C_STRESS_TEST_TCPC
|
|
struct i2c_stress_test_dev ps8751_i2c_stress_test_dev = {
|
|
.reg_info = {
|
|
.read_reg = PS8751_REG_VENDOR_ID_L,
|
|
.read_val = PS8751_VENDOR_ID & 0xFF,
|
|
.write_reg = PS8751_REG_CTRL_1,
|
|
},
|
|
.i2c_read = &tcpc_i2c_read,
|
|
.i2c_write = &tcpc_i2c_write,
|
|
};
|
|
#endif /* CONFIG_CMD_I2C_STRESS_TEST_TCPC */
|