summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-10-13 17:50:33 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-25 08:14:10 +0000
commitcadce20c1ac866833d15ad7d8360cda17ea344e2 (patch)
treee9d27e61d9bb1583f7768a2c11da041cfbced5a2 /board
parentbf8335a0a329f8d40fe3c4e911c9f9bb144ca2ad (diff)
downloadchrome-ec-cadce20c1ac866833d15ad7d8360cda17ea344e2.tar.gz
pd: Add DFP parsing for alternate mode status & attention.
Once alternate mode is entered the DFP will make an initial status request to the UFP. Future status changes on the UFP are then sent to the DFP via the attention command. This VDM consists of the VDM header plus another VDO containing mode specific information. CL adds ability of DFP to consume the attention VDMs status message and in the case of DisplayPort SID toggle the necessary HPD gpio accordingly. BRANCH=samus BUG=chrome-os-partner:30645 TEST=manual, for DFP w/ HPD over CC see HPD toggle correctly without manually driving it providing cable connected when AMA is inserted. Change-Id: Ifef60b5d0170cbcc1b518e3b13e84bac99a17e32 Signed-off-by: Todd Broch <tbroch@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/224769 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'board')
-rw-r--r--board/dingdong/usb_pd_policy.c46
-rw-r--r--board/fruitpie/usb_pd_policy.c7
-rw-r--r--board/hoho/usb_pd_policy.c46
-rw-r--r--board/samus_pd/usb_pd_policy.c42
4 files changed, 92 insertions, 49 deletions
diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c
index fa0894e509..97504a1cbf 100644
--- a/board/dingdong/usb_pd_policy.c
+++ b/board/dingdong/usb_pd_policy.c
@@ -124,7 +124,14 @@ static int svdm_response_svids(int port, uint32_t *payload)
return 2;
}
-const uint32_t vdo_dp_mode[1] = {
+/* Will only ever be a single mode for this UFP_D device as it has no USB
+ * support (2.0 or 3.0) making it only PIN_E configureable nor does it have any
+ * source functionality.
+ */
+#define MODE_CNT 1
+#define OPOS 1
+
+const uint32_t vdo_dp_mode[MODE_CNT] = {
VDO_MODE_DP(0, /* UFP pin cfg supported : none */
MODE_DP_PIN_E, /* DFP pin cfg supported */
1, /* no usb2.0 signalling in AMode */
@@ -135,57 +142,46 @@ const uint32_t vdo_dp_mode[1] = {
static int svdm_response_modes(int port, uint32_t *payload)
{
- int mode_cnt = ARRAY_SIZE(vdo_dp_mode);
-
if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) {
/* TODO(tbroch) USB billboard enabled here then */
return 1; /* will generate a NAK */
}
memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode));
- return mode_cnt + 1;
-}
-
-static int hpd_get_irq(int port)
-{
- /* TODO(tbroch) FIXME */
- return 0;
-}
-
-static enum hpd_level hpd_get_level(int port)
-{
- /* TODO(tbroch) FIXME: needs debounce */
- return gpio_get_level(GPIO_DP_HPD);
+ return MODE_CNT + 1;
}
static int dp_status(int port, uint32_t *payload)
{
- uint32_t ufp_dp_sts = payload[1] & 0x3;
- payload[1] = VDO_DP_STATUS(hpd_get_irq(port), /* IRQ_HPD */
- hpd_get_level(port), /* HPD_HI|LOW */
+ int opos = PD_VDO_OPOS(payload[0]);
+ int hpd = gpio_get_level(GPIO_DP_HPD);
+ if (opos != OPOS)
+ return 0; /* nak */
+
+ payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */
+ (hpd == 1), /* HPD_HI|LOW */
0, /* request exit DP */
0, /* request exit USB */
0, /* MF pref */
gpio_get_level(GPIO_PD_SBU_ENABLE),
0, /* power low */
- (ufp_dp_sts | 0x2));
+ 0x2);
return 2;
}
static int dp_config(int port, uint32_t *payload)
{
- if (PD_DP_CFG_DPON(payload[1])) {
+ if (PD_DP_CFG_DPON(payload[1]))
gpio_set_level(GPIO_PD_SBU_ENABLE, 1);
- payload[1] = 0;
- }
- return 2;
+
+ return 1;
}
static int svdm_enter_mode(int port, uint32_t *payload)
{
/* SID & mode request is valid */
if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
- (PD_VDO_OPOS(payload[0]) != 1))
+ (PD_VDO_OPOS(payload[0]) != OPOS))
return 0; /* will generate NAK */
return 1;
}
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c
index 6caea5692f..aa63911cc9 100644
--- a/board/fruitpie/usb_pd_policy.c
+++ b/board/fruitpie/usb_pd_policy.c
@@ -224,6 +224,12 @@ static int svdm_dp_config(int port, uint32_t *payload)
return 2;
};
+static int svdm_dp_attention(int port, uint32_t *payload)
+{
+ CPRINTF("dp sts:%08x\n", payload[1]);
+ return 1; /* ack */
+}
+
static void svdm_exit_dp_mode(int port)
{
CPRINTF("Exiting mode\n");
@@ -236,6 +242,7 @@ const struct svdm_amode_fx supported_modes[] = {
.enter = &svdm_enter_dp_mode,
.status = &svdm_dp_status,
.config = &svdm_dp_config,
+ .attention = &svdm_dp_attention,
.exit = &svdm_exit_dp_mode,
},
};
diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c
index 61457d3d6c..b747766aa9 100644
--- a/board/hoho/usb_pd_policy.c
+++ b/board/hoho/usb_pd_policy.c
@@ -124,7 +124,14 @@ static int svdm_response_svids(int port, uint32_t *payload)
return 2;
}
-const uint32_t vdo_dp_mode[1] = {
+/* Will only ever be a single mode for this UFP_D device as it has no USB
+ * support (2.0 or 3.0) making it only PIN_E configureable nor does it have any
+ * source functionality.
+ */
+#define MODE_CNT 1
+#define OPOS 1
+
+const uint32_t vdo_dp_mode[MODE_CNT] = {
VDO_MODE_DP(0, /* UFP pin cfg supported : none */
MODE_DP_PIN_C, /* DFP pin cfg supported */
1, /* no usb2.0 signalling in AMode */
@@ -135,39 +142,30 @@ const uint32_t vdo_dp_mode[1] = {
static int svdm_response_modes(int port, uint32_t *payload)
{
- int mode_cnt = ARRAY_SIZE(vdo_dp_mode);
-
if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) {
/* TODO(tbroch) USB billboard enabled here then */
return 1; /* will generate a NAK */
}
memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode));
- return mode_cnt + 1;
-}
-
-static int hpd_get_irq(int port)
-{
- /* TODO(tbroch) FIXME */
- return 0;
-}
-
-static enum hpd_level hpd_get_level(int port)
-{
- return gpio_get_level(GPIO_DP_HPD);
+ return MODE_CNT + 1;
}
static int dp_status(int port, uint32_t *payload)
{
- uint32_t ufp_dp_sts = payload[1] & 0x3;
- payload[1] = VDO_DP_STATUS(hpd_get_irq(port), /* IRQ_HPD */
- hpd_get_level(port), /* HPD_HI|LOW */
- 0, /* request exit DP */
- 0, /* request exit USB */
- 0, /* MF pref */
+ int opos = PD_VDO_OPOS(payload[0]);
+ int hpd = gpio_get_level(GPIO_DP_HPD);
+ if (opos != OPOS)
+ return 0; /* nak */
+
+ payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */
+ (hpd == 1), /* HPD_HI|LOW */
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ 0, /* MF pref */
gpio_get_level(GPIO_PD_SBU_ENABLE),
- 0, /* power low */
- (ufp_dp_sts | 0x2));
+ 0, /* power low */
+ 0x2);
return 2;
}
@@ -182,7 +180,7 @@ static int svdm_enter_mode(int port, uint32_t *payload)
{
/* SID & mode request is valid */
if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
- (PD_VDO_OPOS(payload[0]) != 1))
+ (PD_VDO_OPOS(payload[0]) != OPOS))
return 0; /* will generate a NAK */
return 1;
}
diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c
index e8ffd2a886..507c6d3bce 100644
--- a/board/samus_pd/usb_pd_policy.c
+++ b/board/samus_pd/usb_pd_policy.c
@@ -7,6 +7,7 @@
#include "common.h"
#include "console.h"
#include "gpio.h"
+#include "hooks.h"
#include "host_command.h"
#include "registers.h"
#include "task.h"
@@ -275,9 +276,49 @@ static int svdm_dp_config(int port, uint32_t *payload)
return 2;
};
+static void hpd0_irq_deferred(void)
+{
+ gpio_set_level(GPIO_USB_C0_DP_HPD, 1);
+}
+
+static void hpd1_irq_deferred(void)
+{
+ gpio_set_level(GPIO_USB_C1_DP_HPD, 1);
+}
+
+DECLARE_DEFERRED(hpd0_irq_deferred);
+DECLARE_DEFERRED(hpd1_irq_deferred);
+
+#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD)
+
+static int svdm_dp_attention(int port, uint32_t *payload)
+{
+ int cur_lvl;
+ int lvl = PD_VDO_HPD_LVL(payload[1]);
+ int irq = PD_VDO_HPD_IRQ(payload[1]);
+ enum gpio_signal hpd = PORT_TO_HPD(port);
+ cur_lvl = gpio_get_level(hpd);
+ if (irq & cur_lvl) {
+ gpio_set_level(hpd, 0);
+ /* 250 usecs is minimum, 2msec is max */
+ if (port)
+ hook_call_deferred(hpd1_irq_deferred, 300);
+ else
+ hook_call_deferred(hpd0_irq_deferred, 300);
+ } else if (irq & !cur_lvl) {
+ CPRINTF("PE ERR: IRQ_HPD w/ HPD_LOW\n");
+ return 0; /* nak */
+ } else {
+ gpio_set_level(hpd, lvl);
+ }
+ /* ack */
+ return 1;
+}
+
static void svdm_exit_dp_mode(int port)
{
svdm_safe_dp_mode(port);
+ gpio_set_level(PORT_TO_HPD(port), 0);
}
const struct svdm_amode_fx supported_modes[] = {
@@ -286,6 +327,7 @@ const struct svdm_amode_fx supported_modes[] = {
.enter = &svdm_enter_dp_mode,
.status = &svdm_dp_status,
.config = &svdm_dp_config,
+ .attention = &svdm_dp_attention,
.exit = &svdm_exit_dp_mode,
},
};