* [PATCH] [RFC] drm/i915/dp: add support for load detect Apple DP->VGA dongles
@ 2014-06-06 2:56 Dave Airlie
2014-06-06 9:57 ` Jani Nikula
0 siblings, 1 reply; 3+ messages in thread
From: Dave Airlie @ 2014-06-06 2:56 UTC (permalink / raw)
To: dri-devel
From: Dave Airlie <airlied@redhat.com>
The DP1.2 spec has some bits for forced load sensing on VGA dongles,
however the apple dongle I have doesn't do DP 1.2 yet, so I dug into
its vendor specific area and found a register that seems to correspond
to load detected on the outputs.
The main reason I need this was at LCA this year the slide capture system
failed to provide EDID, but I realised OSX worked. Really need to add support
to nouveau, but hey i915 is a start.
The dongle also appears to use short IRQs to denote a plug/unplug event,
though something seems to be failing in reading back the dpcd values from it.
(also this is based on my MST work just because.)
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
drivers/gpu/drm/i915/intel_dp.c | 29 +++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_drv.h | 1 +
include/drm/drm_dp_helper.h | 19 +++++++++++++++++++
3 files changed, 49 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c500f63..49afd7d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3173,6 +3173,16 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
+ intel_dp->is_apple_vga = false;
+ if (drm_dp_branch_is_apple(buf)) {
+ u8 mybuf[8];
+ if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_BRANCH_OUI + 3, mybuf, 8)) {
+ if (drm_dp_apple_has_load_detect(mybuf)) {
+ DRM_DEBUG_KMS("detected Apple DP VGA dongle\n");
+ intel_dp->is_apple_vga = true;
+ }
+ }
+ }
edp_panel_vdd_off(intel_dp, false);
}
@@ -3404,6 +3414,21 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
if (drm_probe_ddc(&intel_dp->aux.ddc))
return connector_status_connected;
+ if (intel_dp->is_apple_vga) {
+ u8 detect_buf;
+ int ret;
+ ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_APPLE_LOAD_DETECT,
+ &detect_buf);
+
+ if (ret == 1) {
+ DRM_DEBUG_KMS("Apple VGA detect is 0x%x\n", detect_buf);
+ /* I suspect 4 == load, 8 == edid */
+ if (detect_buf)
+ return connector_status_connected;
+ else
+ return connector_status_disconnected;
+ }
+ }
/* Well we tried, say unknown for unreliable port types */
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
@@ -3854,6 +3879,10 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
* but for short hpds we should check it now
*/
intel_dp_check_link_status(intel_dp);
+
+ /* if we get a short hpd on apple vga - its a hotplug */
+ if (intel_dp->is_apple_vga)
+ return true;
}
}
return false;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1edb38a..23f767c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -549,6 +549,7 @@ struct intel_dp {
bool use_tps3;
bool can_mst; /* this port supports mst */
bool is_mst;
+ bool is_apple_vga;
int active_mst_links;
/* connector directly attached - won't be use for modeset in mst world */
struct intel_connector *attached_connector;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 517d6c1..c8ebd27 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -612,4 +612,23 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
int drm_dp_aux_register(struct drm_dp_aux *aux);
void drm_dp_aux_unregister(struct drm_dp_aux *aux);
+#define DP_APPLE_OUI 0x10fa
+
+#define DP_APPLE_LOAD_DETECT (DP_BRANCH_OUI + 12)
+
+static inline bool drm_dp_branch_is_apple(const u8 buf[3])
+{
+ if (buf[0] == ((DP_APPLE_OUI >> 16) & 0xff) &&
+ buf[1] == ((DP_APPLE_OUI >> 8) & 0xff) &&
+ buf[2] == ((DP_APPLE_OUI & 0xff)))
+ return true;
+ return false;
+}
+
+static inline bool drm_dp_apple_has_load_detect(const u8 buf[8])
+{
+ if (!memcmp((const char *)buf, "mVGAa", 5))
+ return true;
+ return false;
+}
#endif /* _DRM_DP_HELPER_H_ */
--
1.9.3
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] [RFC] drm/i915/dp: add support for load detect Apple DP->VGA dongles
2014-06-06 2:56 [PATCH] [RFC] drm/i915/dp: add support for load detect Apple DP->VGA dongles Dave Airlie
@ 2014-06-06 9:57 ` Jani Nikula
2014-06-19 20:48 ` Daniel Vetter
0 siblings, 1 reply; 3+ messages in thread
From: Jani Nikula @ 2014-06-06 9:57 UTC (permalink / raw)
To: Dave Airlie, dri-devel
On Fri, 06 Jun 2014, Dave Airlie <airlied@gmail.com> wrote:
> From: Dave Airlie <airlied@redhat.com>
>
> The DP1.2 spec has some bits for forced load sensing on VGA dongles,
> however the apple dongle I have doesn't do DP 1.2 yet, so I dug into
> its vendor specific area and found a register that seems to correspond
> to load detected on the outputs.
>
> The main reason I need this was at LCA this year the slide capture system
> failed to provide EDID, but I realised OSX worked. Really need to add support
> to nouveau, but hey i915 is a start.
>
> The dongle also appears to use short IRQs to denote a plug/unplug event,
> though something seems to be failing in reading back the dpcd values from it.
> (also this is based on my MST work just because.)
Good timing for making use of the OUI! See
http://mid.gmane.org/1401920981-3137-1-git-send-email-clinton.a.taylor@intel.com
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
> drivers/gpu/drm/i915/intel_dp.c | 29 +++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_drv.h | 1 +
> include/drm/drm_dp_helper.h | 19 +++++++++++++++++++
> 3 files changed, 49 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index c500f63..49afd7d 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3173,6 +3173,16 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
> DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
> buf[0], buf[1], buf[2]);
>
> + intel_dp->is_apple_vga = false;
> + if (drm_dp_branch_is_apple(buf)) {
> + u8 mybuf[8];
> + if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_BRANCH_OUI + 3, mybuf, 8)) {
That may return negative values for errors.
FWIW I've thought about reading the sink/branch device identification
strings unconditionally along with the OUI just for debug purposes. I
wouldn't be opposed to such a change here.
> + if (drm_dp_apple_has_load_detect(mybuf)) {
> + DRM_DEBUG_KMS("detected Apple DP VGA dongle\n");
> + intel_dp->is_apple_vga = true;
> + }
> + }
> + }
I think I'd like this abstracted to a dedicated function and doing:
intel_dp->is_apple_vga = is_apple_vga(intel_dp, buf);
or something.
> edp_panel_vdd_off(intel_dp, false);
> }
>
> @@ -3404,6 +3414,21 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
> if (drm_probe_ddc(&intel_dp->aux.ddc))
> return connector_status_connected;
>
> + if (intel_dp->is_apple_vga) {
> + u8 detect_buf;
> + int ret;
> + ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_APPLE_LOAD_DETECT,
> + &detect_buf);
> +
> + if (ret == 1) {
> + DRM_DEBUG_KMS("Apple VGA detect is 0x%x\n", detect_buf);
> + /* I suspect 4 == load, 8 == edid */
> + if (detect_buf)
> + return connector_status_connected;
> + else
> + return connector_status_disconnected;
> + }
> + }
> /* Well we tried, say unknown for unreliable port types */
> if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
> type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
> @@ -3854,6 +3879,10 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
> * but for short hpds we should check it now
> */
> intel_dp_check_link_status(intel_dp);
> +
> + /* if we get a short hpd on apple vga - its a hotplug */
> + if (intel_dp->is_apple_vga)
> + return true;
> }
> }
> return false;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 1edb38a..23f767c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -549,6 +549,7 @@ struct intel_dp {
> bool use_tps3;
> bool can_mst; /* this port supports mst */
> bool is_mst;
> + bool is_apple_vga;
> int active_mst_links;
> /* connector directly attached - won't be use for modeset in mst world */
> struct intel_connector *attached_connector;
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 517d6c1..c8ebd27 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -612,4 +612,23 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
> int drm_dp_aux_register(struct drm_dp_aux *aux);
> void drm_dp_aux_unregister(struct drm_dp_aux *aux);
>
> +#define DP_APPLE_OUI 0x10fa
> +
> +#define DP_APPLE_LOAD_DETECT (DP_BRANCH_OUI + 12)
> +
> +static inline bool drm_dp_branch_is_apple(const u8 buf[3])
Naming buf and its size similar to other drm_dp_* helpers use would be
nice.
> +{
> + if (buf[0] == ((DP_APPLE_OUI >> 16) & 0xff) &&
> + buf[1] == ((DP_APPLE_OUI >> 8) & 0xff) &&
> + buf[2] == ((DP_APPLE_OUI & 0xff)))
> + return true;
> + return false;
> +}
> +
> +static inline bool drm_dp_apple_has_load_detect(const u8 buf[8])
Ditto.
> +{
> + if (!memcmp((const char *)buf, "mVGAa", 5))
Why the cast?
BR,
Jani.
> + return true;
> + return false;
> +}
> #endif /* _DRM_DP_HELPER_H_ */
> --
> 1.9.3
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Jani Nikula, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] [RFC] drm/i915/dp: add support for load detect Apple DP->VGA dongles
2014-06-06 9:57 ` Jani Nikula
@ 2014-06-19 20:48 ` Daniel Vetter
0 siblings, 0 replies; 3+ messages in thread
From: Daniel Vetter @ 2014-06-19 20:48 UTC (permalink / raw)
To: Jani Nikula; +Cc: dri-devel
On Fri, Jun 06, 2014 at 12:57:46PM +0300, Jani Nikula wrote:
> On Fri, 06 Jun 2014, Dave Airlie <airlied@gmail.com> wrote:
> > From: Dave Airlie <airlied@redhat.com>
> >
> > The DP1.2 spec has some bits for forced load sensing on VGA dongles,
> > however the apple dongle I have doesn't do DP 1.2 yet, so I dug into
> > its vendor specific area and found a register that seems to correspond
> > to load detected on the outputs.
> >
> > The main reason I need this was at LCA this year the slide capture system
> > failed to provide EDID, but I realised OSX worked. Really need to add support
> > to nouveau, but hey i915 is a start.
> >
> > The dongle also appears to use short IRQs to denote a plug/unplug event,
> > though something seems to be failing in reading back the dpcd values from it.
> > (also this is based on my MST work just because.)
>
> Good timing for making use of the OUI! See
>
> http://mid.gmane.org/1401920981-3137-1-git-send-email-clinton.a.taylor@intel.com
>
> > Signed-off-by: Dave Airlie <airlied@redhat.com>
Just a high-level bikeshed: Now that we have this nice dp helper library
shouldn't we add a dp_detect function there which fills out a bunch of
sink state in the core dp struct and also implements tricks like this?
Maybe as the plain dp version of the relevant dp mst handler?
Definitely not much point in copy&pasting this for radeon, noveau, tegra
and all the others.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-06-19 20:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-06 2:56 [PATCH] [RFC] drm/i915/dp: add support for load detect Apple DP->VGA dongles Dave Airlie
2014-06-06 9:57 ` Jani Nikula
2014-06-19 20:48 ` Daniel Vetter
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.