Message ID | 1470661230-15988-2-git-send-email-mika.kahola@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Aug 08, 2016 at 04:00:26PM +0300, Mika Kahola wrote: > HW revision is mandatory field for DisplayPort branch > devices. This is defined in DPCD register field 0x509. But what do we want to do with it? Me, I don't see a point in parsing a bunch of stuff from the DPCD unless there's a real use case for it. /dev/drm_dp_aux will provide all the debug aid we need if we need to check random pieces of data from the DPCD, so even exposing this sort of stuff via debugfs is IMO pretty pointless. If there's a good reason for a debug print, then I think we could parse something and dump it out so that it's always in the dmesg. But so far I'm not aware of any bug that would have required to deal with different hw revisions of things and whatnot. > > v2: move drm_dp_ds_revision structure to be part of > drm_dp_link structure (Daniel) > > Signed-off-by: Mika Kahola <mika.kahola@intel.com> > --- > drivers/gpu/drm/drm_dp_helper.c | 27 +++++++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_drv.h | 1 + > include/drm/drm_dp_helper.h | 9 +++++++++ > 3 files changed, 37 insertions(+) > > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c > index 75b2873..5fecdc1 100644 > --- a/drivers/gpu/drm/drm_dp_helper.c > +++ b/drivers/gpu/drm/drm_dp_helper.c > @@ -514,6 +514,33 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > EXPORT_SYMBOL(drm_dp_downstream_max_bpc); > > /** > + * drm_dp_downstream_hw_rev() - read DP branch device HW revision > + * @aux: DisplayPort AUX channel > + * > + * Returns 0 on succes or negative error code on failure > + */ > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > + struct drm_dp_aux *aux, struct drm_dp_link *link) > +{ > + uint8_t tmp; > + int err; > + > + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) > + return -EINVAL; > + > + err = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1); > + > + if (err < 0) > + return err; > + > + link->ds_hw_rev.major = (tmp & 0xf0) >> 4; > + link->ds_hw_rev.minor = tmp & 0xf; > + > + return 0; > +} > +EXPORT_SYMBOL(drm_dp_downstream_hw_rev); > + > +/** > * drm_dp_downstream_id() - identify branch device > * @aux: DisplayPort AUX channel > * > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index e74d851..a6eccf5 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -865,6 +865,7 @@ struct intel_dp { > uint8_t num_sink_rates; > int sink_rates[DP_MAX_SUPPORTED_RATES]; > struct drm_dp_aux aux; > + struct drm_dp_link link; > uint8_t train_set[4]; > int panel_power_up_delay; > int panel_power_down_delay; > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > index 8e1fe58..1127948 100644 > --- a/include/drm/drm_dp_helper.h > +++ b/include/drm/drm_dp_helper.h > @@ -446,6 +446,7 @@ > #define DP_SINK_OUI 0x400 > #define DP_BRANCH_OUI 0x500 > #define DP_BRANCH_ID 0x503 > +#define DP_BRANCH_HW_REV 0x509 > > #define DP_SET_POWER 0x600 > # define DP_SET_POWER_D0 0x1 > @@ -803,11 +804,17 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, > */ > #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0) > > +struct drm_dp_ds_revision { > + int major; > + int minor; > +}; > + > struct drm_dp_link { > unsigned char revision; > unsigned int rate; > unsigned int num_lanes; > unsigned long capabilities; > + struct drm_dp_ds_revision ds_hw_rev; > }; > > int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); > @@ -819,6 +826,8 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > const u8 port_cap[4]); > int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]); > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > + struct drm_dp_aux *aux, struct drm_dp_link *link); > > void drm_dp_aux_init(struct drm_dp_aux *aux); > int drm_dp_aux_register(struct drm_dp_aux *aux); > -- > 1.9.1
On Thu, 2016-08-11 at 10:10 +0300, Ville Syrjälä wrote: > On Mon, Aug 08, 2016 at 04:00:26PM +0300, Mika Kahola wrote: > > HW revision is mandatory field for DisplayPort branch > > devices. This is defined in DPCD register field 0x509. > > But what do we want to do with it? Me, I don't see a point in parsing a > bunch of stuff from the DPCD unless there's a real use case for it. > /dev/drm_dp_aux will provide all the debug aid we need if we need to > check random pieces of data from the DPCD, so even exposing this sort > of stuff via debugfs is IMO pretty pointless. > > If there's a good reason for a debug print, then I think we could parse > something and dump it out so that it's always in the dmesg. But so far > I'm not aware of any bug that would have required to deal with different > hw revisions of things and whatnot. > Digging up the HW and SW revisions are just for debugging purposes. My idea here was that it would be handy if this information would be available if we face a problem let's say with VGA dongle for example. It is true that at the moment we don't have a single bug that would require HW/SW revision information but maybe in the future we have one. So, if we don't want to have this stuff in drm_dp_helpers and/or debugfs I could make a change and print this info on dmesg when DP branch device is plugged in. Cheers, Mika > > > > v2: move drm_dp_ds_revision structure to be part of > > drm_dp_link structure (Daniel) > > > > Signed-off-by: Mika Kahola <mika.kahola@intel.com> > > --- > > drivers/gpu/drm/drm_dp_helper.c | 27 +++++++++++++++++++++++++++ > > drivers/gpu/drm/i915/intel_drv.h | 1 + > > include/drm/drm_dp_helper.h | 9 +++++++++ > > 3 files changed, 37 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c > > index 75b2873..5fecdc1 100644 > > --- a/drivers/gpu/drm/drm_dp_helper.c > > +++ b/drivers/gpu/drm/drm_dp_helper.c > > @@ -514,6 +514,33 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > EXPORT_SYMBOL(drm_dp_downstream_max_bpc); > > > > /** > > + * drm_dp_downstream_hw_rev() - read DP branch device HW revision > > + * @aux: DisplayPort AUX channel > > + * > > + * Returns 0 on succes or negative error code on failure > > + */ > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > + struct drm_dp_aux *aux, struct drm_dp_link *link) > > +{ > > + uint8_t tmp; > > + int err; > > + > > + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) > > + return -EINVAL; > > + > > + err = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1); > > + > > + if (err < 0) > > + return err; > > + > > + link->ds_hw_rev.major = (tmp & 0xf0) >> 4; > > + link->ds_hw_rev.minor = tmp & 0xf; > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(drm_dp_downstream_hw_rev); > > + > > +/** > > * drm_dp_downstream_id() - identify branch device > > * @aux: DisplayPort AUX channel > > * > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > index e74d851..a6eccf5 100644 > > --- a/drivers/gpu/drm/i915/intel_drv.h > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > @@ -865,6 +865,7 @@ struct intel_dp { > > uint8_t num_sink_rates; > > int sink_rates[DP_MAX_SUPPORTED_RATES]; > > struct drm_dp_aux aux; > > + struct drm_dp_link link; > > uint8_t train_set[4]; > > int panel_power_up_delay; > > int panel_power_down_delay; > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > > index 8e1fe58..1127948 100644 > > --- a/include/drm/drm_dp_helper.h > > +++ b/include/drm/drm_dp_helper.h > > @@ -446,6 +446,7 @@ > > #define DP_SINK_OUI 0x400 > > #define DP_BRANCH_OUI 0x500 > > #define DP_BRANCH_ID 0x503 > > +#define DP_BRANCH_HW_REV 0x509 > > > > #define DP_SET_POWER 0x600 > > # define DP_SET_POWER_D0 0x1 > > @@ -803,11 +804,17 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, > > */ > > #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0) > > > > +struct drm_dp_ds_revision { > > + int major; > > + int minor; > > +}; > > + > > struct drm_dp_link { > > unsigned char revision; > > unsigned int rate; > > unsigned int num_lanes; > > unsigned long capabilities; > > + struct drm_dp_ds_revision ds_hw_rev; > > }; > > > > int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); > > @@ -819,6 +826,8 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > const u8 port_cap[4]); > > int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]); > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > + struct drm_dp_aux *aux, struct drm_dp_link *link); > > > > void drm_dp_aux_init(struct drm_dp_aux *aux); > > int drm_dp_aux_register(struct drm_dp_aux *aux); > > -- > > 1.9.1 >
On Thu, Aug 11, 2016 at 11:14:43AM +0300, Mika Kahola wrote: > On Thu, 2016-08-11 at 10:10 +0300, Ville Syrjälä wrote: > > On Mon, Aug 08, 2016 at 04:00:26PM +0300, Mika Kahola wrote: > > > HW revision is mandatory field for DisplayPort branch > > > devices. This is defined in DPCD register field 0x509. > > > > But what do we want to do with it? Me, I don't see a point in parsing a > > bunch of stuff from the DPCD unless there's a real use case for it. > > /dev/drm_dp_aux will provide all the debug aid we need if we need to > > check random pieces of data from the DPCD, so even exposing this sort > > of stuff via debugfs is IMO pretty pointless. > > > > If there's a good reason for a debug print, then I think we could parse > > something and dump it out so that it's always in the dmesg. But so far > > I'm not aware of any bug that would have required to deal with different > > hw revisions of things and whatnot. > > > Digging up the HW and SW revisions are just for debugging purposes. My > idea here was that it would be handy if this information would be > available if we face a problem let's say with VGA dongle for example. It > is true that at the moment we don't have a single bug that would require > HW/SW revision information but maybe in the future we have one. > > So, if we don't want to have this stuff in drm_dp_helpers and/or debugfs > I could make a change and print this info on dmesg when DP branch device > is plugged in. Perhaps. We do print out the OUI as well, so there is some precedent. > > Cheers, > Mika > > > > > > > v2: move drm_dp_ds_revision structure to be part of > > > drm_dp_link structure (Daniel) > > > > > > Signed-off-by: Mika Kahola <mika.kahola@intel.com> > > > --- > > > drivers/gpu/drm/drm_dp_helper.c | 27 +++++++++++++++++++++++++++ > > > drivers/gpu/drm/i915/intel_drv.h | 1 + > > > include/drm/drm_dp_helper.h | 9 +++++++++ > > > 3 files changed, 37 insertions(+) > > > > > > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c > > > index 75b2873..5fecdc1 100644 > > > --- a/drivers/gpu/drm/drm_dp_helper.c > > > +++ b/drivers/gpu/drm/drm_dp_helper.c > > > @@ -514,6 +514,33 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > EXPORT_SYMBOL(drm_dp_downstream_max_bpc); > > > > > > /** > > > + * drm_dp_downstream_hw_rev() - read DP branch device HW revision > > > + * @aux: DisplayPort AUX channel > > > + * > > > + * Returns 0 on succes or negative error code on failure > > > + */ > > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > + struct drm_dp_aux *aux, struct drm_dp_link *link) > > > +{ > > > + uint8_t tmp; > > > + int err; > > > + > > > + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) > > > + return -EINVAL; > > > + > > > + err = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1); > > > + > > > + if (err < 0) > > > + return err; > > > + > > > + link->ds_hw_rev.major = (tmp & 0xf0) >> 4; > > > + link->ds_hw_rev.minor = tmp & 0xf; > > > + > > > + return 0; > > > +} > > > +EXPORT_SYMBOL(drm_dp_downstream_hw_rev); > > > + > > > +/** > > > * drm_dp_downstream_id() - identify branch device > > > * @aux: DisplayPort AUX channel > > > * > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > > index e74d851..a6eccf5 100644 > > > --- a/drivers/gpu/drm/i915/intel_drv.h > > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > > @@ -865,6 +865,7 @@ struct intel_dp { > > > uint8_t num_sink_rates; > > > int sink_rates[DP_MAX_SUPPORTED_RATES]; > > > struct drm_dp_aux aux; > > > + struct drm_dp_link link; > > > uint8_t train_set[4]; > > > int panel_power_up_delay; > > > int panel_power_down_delay; > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > > > index 8e1fe58..1127948 100644 > > > --- a/include/drm/drm_dp_helper.h > > > +++ b/include/drm/drm_dp_helper.h > > > @@ -446,6 +446,7 @@ > > > #define DP_SINK_OUI 0x400 > > > #define DP_BRANCH_OUI 0x500 > > > #define DP_BRANCH_ID 0x503 > > > +#define DP_BRANCH_HW_REV 0x509 > > > > > > #define DP_SET_POWER 0x600 > > > # define DP_SET_POWER_D0 0x1 > > > @@ -803,11 +804,17 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, > > > */ > > > #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0) > > > > > > +struct drm_dp_ds_revision { > > > + int major; > > > + int minor; > > > +}; > > > + > > > struct drm_dp_link { > > > unsigned char revision; > > > unsigned int rate; > > > unsigned int num_lanes; > > > unsigned long capabilities; > > > + struct drm_dp_ds_revision ds_hw_rev; > > > }; > > > > > > int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); > > > @@ -819,6 +826,8 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > const u8 port_cap[4]); > > > int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]); > > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > + struct drm_dp_aux *aux, struct drm_dp_link *link); > > > > > > void drm_dp_aux_init(struct drm_dp_aux *aux); > > > int drm_dp_aux_register(struct drm_dp_aux *aux); > > > -- > > > 1.9.1 > > >
On Thu, Aug 11, 2016 at 11:22:15AM +0300, Ville Syrjälä wrote: > On Thu, Aug 11, 2016 at 11:14:43AM +0300, Mika Kahola wrote: > > On Thu, 2016-08-11 at 10:10 +0300, Ville Syrjälä wrote: > > > On Mon, Aug 08, 2016 at 04:00:26PM +0300, Mika Kahola wrote: > > > > HW revision is mandatory field for DisplayPort branch > > > > devices. This is defined in DPCD register field 0x509. > > > > > > But what do we want to do with it? Me, I don't see a point in parsing a > > > bunch of stuff from the DPCD unless there's a real use case for it. > > > /dev/drm_dp_aux will provide all the debug aid we need if we need to > > > check random pieces of data from the DPCD, so even exposing this sort > > > of stuff via debugfs is IMO pretty pointless. > > > > > > If there's a good reason for a debug print, then I think we could parse > > > something and dump it out so that it's always in the dmesg. But so far > > > I'm not aware of any bug that would have required to deal with different > > > hw revisions of things and whatnot. > > > > > Digging up the HW and SW revisions are just for debugging purposes. My > > idea here was that it would be handy if this information would be > > available if we face a problem let's say with VGA dongle for example. It > > is true that at the moment we don't have a single bug that would require > > HW/SW revision information but maybe in the future we have one. > > > > So, if we don't want to have this stuff in drm_dp_helpers and/or debugfs > > I could make a change and print this info on dmesg when DP branch device > > is plugged in. > > Perhaps. We do print out the OUI as well, so there is some precedent. Even if we don't dump stuff out to dmesg, I'd like to see this information in the mst_info debugfs file or someplace similar. As has been pointed out, having this information available in the event that we need to work with a vendor on a problem would be a help. Jim > > > > > Cheers, > > Mika > > > > > > > > > > v2: move drm_dp_ds_revision structure to be part of > > > > drm_dp_link structure (Daniel) > > > > > > > > Signed-off-by: Mika Kahola <mika.kahola@intel.com> > > > > --- > > > > drivers/gpu/drm/drm_dp_helper.c | 27 +++++++++++++++++++++++++++ > > > > drivers/gpu/drm/i915/intel_drv.h | 1 + > > > > include/drm/drm_dp_helper.h | 9 +++++++++ > > > > 3 files changed, 37 insertions(+) > > > > > > > > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c > > > > index 75b2873..5fecdc1 100644 > > > > --- a/drivers/gpu/drm/drm_dp_helper.c > > > > +++ b/drivers/gpu/drm/drm_dp_helper.c > > > > @@ -514,6 +514,33 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > EXPORT_SYMBOL(drm_dp_downstream_max_bpc); > > > > > > > > /** > > > > + * drm_dp_downstream_hw_rev() - read DP branch device HW revision > > > > + * @aux: DisplayPort AUX channel > > > > + * > > > > + * Returns 0 on succes or negative error code on failure > > > > + */ > > > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > + struct drm_dp_aux *aux, struct drm_dp_link *link) > > > > +{ > > > > + uint8_t tmp; > > > > + int err; > > > > + > > > > + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) > > > > + return -EINVAL; > > > > + > > > > + err = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1); > > > > + > > > > + if (err < 0) > > > > + return err; > > > > + > > > > + link->ds_hw_rev.major = (tmp & 0xf0) >> 4; > > > > + link->ds_hw_rev.minor = tmp & 0xf; > > > > + > > > > + return 0; > > > > +} > > > > +EXPORT_SYMBOL(drm_dp_downstream_hw_rev); > > > > + > > > > +/** > > > > * drm_dp_downstream_id() - identify branch device > > > > * @aux: DisplayPort AUX channel > > > > * > > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > > > index e74d851..a6eccf5 100644 > > > > --- a/drivers/gpu/drm/i915/intel_drv.h > > > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > > > @@ -865,6 +865,7 @@ struct intel_dp { > > > > uint8_t num_sink_rates; > > > > int sink_rates[DP_MAX_SUPPORTED_RATES]; > > > > struct drm_dp_aux aux; > > > > + struct drm_dp_link link; > > > > uint8_t train_set[4]; > > > > int panel_power_up_delay; > > > > int panel_power_down_delay; > > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > > > > index 8e1fe58..1127948 100644 > > > > --- a/include/drm/drm_dp_helper.h > > > > +++ b/include/drm/drm_dp_helper.h > > > > @@ -446,6 +446,7 @@ > > > > #define DP_SINK_OUI 0x400 > > > > #define DP_BRANCH_OUI 0x500 > > > > #define DP_BRANCH_ID 0x503 > > > > +#define DP_BRANCH_HW_REV 0x509 > > > > > > > > #define DP_SET_POWER 0x600 > > > > # define DP_SET_POWER_D0 0x1 > > > > @@ -803,11 +804,17 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, > > > > */ > > > > #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0) > > > > > > > > +struct drm_dp_ds_revision { > > > > + int major; > > > > + int minor; > > > > +}; > > > > + > > > > struct drm_dp_link { > > > > unsigned char revision; > > > > unsigned int rate; > > > > unsigned int num_lanes; > > > > unsigned long capabilities; > > > > + struct drm_dp_ds_revision ds_hw_rev; > > > > }; > > > > > > > > int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); > > > > @@ -819,6 +826,8 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > const u8 port_cap[4]); > > > > int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]); > > > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > + struct drm_dp_aux *aux, struct drm_dp_link *link); > > > > > > > > void drm_dp_aux_init(struct drm_dp_aux *aux); > > > > int drm_dp_aux_register(struct drm_dp_aux *aux); > > > > -- > > > > 1.9.1 > > > > > > > -- > Ville Syrjälä > Intel OTC
On Thu, Aug 11, 2016 at 10:21:36AM -0700, Jim Bride wrote: > On Thu, Aug 11, 2016 at 11:22:15AM +0300, Ville Syrjälä wrote: > > On Thu, Aug 11, 2016 at 11:14:43AM +0300, Mika Kahola wrote: > > > On Thu, 2016-08-11 at 10:10 +0300, Ville Syrjälä wrote: > > > > On Mon, Aug 08, 2016 at 04:00:26PM +0300, Mika Kahola wrote: > > > > > HW revision is mandatory field for DisplayPort branch > > > > > devices. This is defined in DPCD register field 0x509. > > > > > > > > But what do we want to do with it? Me, I don't see a point in parsing a > > > > bunch of stuff from the DPCD unless there's a real use case for it. > > > > /dev/drm_dp_aux will provide all the debug aid we need if we need to > > > > check random pieces of data from the DPCD, so even exposing this sort > > > > of stuff via debugfs is IMO pretty pointless. > > > > > > > > If there's a good reason for a debug print, then I think we could parse > > > > something and dump it out so that it's always in the dmesg. But so far > > > > I'm not aware of any bug that would have required to deal with different > > > > hw revisions of things and whatnot. > > > > > > > Digging up the HW and SW revisions are just for debugging purposes. My > > > idea here was that it would be handy if this information would be > > > available if we face a problem let's say with VGA dongle for example. It > > > is true that at the moment we don't have a single bug that would require > > > HW/SW revision information but maybe in the future we have one. > > > > > > So, if we don't want to have this stuff in drm_dp_helpers and/or debugfs > > > I could make a change and print this info on dmesg when DP branch device > > > is plugged in. > > > > Perhaps. We do print out the OUI as well, so there is some precedent. > > Even if we don't dump stuff out to dmesg, I'd like to see this information > in the mst_info debugfs file or someplace similar. As has been pointed out, > having this information available in the event that we need to work with a > vendor on a problem would be a help. Just dump the whole thing via /dev/drm_dp_aux<n>. The problem with getting parsed data for debugging is that the parser itself might be buggy or just incomplete. So IMO it's always much better to get the raw data. This way you can be sure that it's not affected by the parser, and that you get all of the data and don't have to back asking for more all the time. I really hate it when someone attaches a parsed VBT dump to a bug for instance. It's pretty much useless. I've been waiting for someone to step up and write a userspace tool for pretty printing the entire DPCD dumps. So far no one has volunteered. > Jim > > > > > > > > > > Cheers, > > > Mika > > > > > > > > > > > > > v2: move drm_dp_ds_revision structure to be part of > > > > > drm_dp_link structure (Daniel) > > > > > > > > > > Signed-off-by: Mika Kahola <mika.kahola@intel.com> > > > > > --- > > > > > drivers/gpu/drm/drm_dp_helper.c | 27 +++++++++++++++++++++++++++ > > > > > drivers/gpu/drm/i915/intel_drv.h | 1 + > > > > > include/drm/drm_dp_helper.h | 9 +++++++++ > > > > > 3 files changed, 37 insertions(+) > > > > > > > > > > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c > > > > > index 75b2873..5fecdc1 100644 > > > > > --- a/drivers/gpu/drm/drm_dp_helper.c > > > > > +++ b/drivers/gpu/drm/drm_dp_helper.c > > > > > @@ -514,6 +514,33 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > > EXPORT_SYMBOL(drm_dp_downstream_max_bpc); > > > > > > > > > > /** > > > > > + * drm_dp_downstream_hw_rev() - read DP branch device HW revision > > > > > + * @aux: DisplayPort AUX channel > > > > > + * > > > > > + * Returns 0 on succes or negative error code on failure > > > > > + */ > > > > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > > + struct drm_dp_aux *aux, struct drm_dp_link *link) > > > > > +{ > > > > > + uint8_t tmp; > > > > > + int err; > > > > > + > > > > > + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) > > > > > + return -EINVAL; > > > > > + > > > > > + err = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1); > > > > > + > > > > > + if (err < 0) > > > > > + return err; > > > > > + > > > > > + link->ds_hw_rev.major = (tmp & 0xf0) >> 4; > > > > > + link->ds_hw_rev.minor = tmp & 0xf; > > > > > + > > > > > + return 0; > > > > > +} > > > > > +EXPORT_SYMBOL(drm_dp_downstream_hw_rev); > > > > > + > > > > > +/** > > > > > * drm_dp_downstream_id() - identify branch device > > > > > * @aux: DisplayPort AUX channel > > > > > * > > > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > > > > index e74d851..a6eccf5 100644 > > > > > --- a/drivers/gpu/drm/i915/intel_drv.h > > > > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > > > > @@ -865,6 +865,7 @@ struct intel_dp { > > > > > uint8_t num_sink_rates; > > > > > int sink_rates[DP_MAX_SUPPORTED_RATES]; > > > > > struct drm_dp_aux aux; > > > > > + struct drm_dp_link link; > > > > > uint8_t train_set[4]; > > > > > int panel_power_up_delay; > > > > > int panel_power_down_delay; > > > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > > > > > index 8e1fe58..1127948 100644 > > > > > --- a/include/drm/drm_dp_helper.h > > > > > +++ b/include/drm/drm_dp_helper.h > > > > > @@ -446,6 +446,7 @@ > > > > > #define DP_SINK_OUI 0x400 > > > > > #define DP_BRANCH_OUI 0x500 > > > > > #define DP_BRANCH_ID 0x503 > > > > > +#define DP_BRANCH_HW_REV 0x509 > > > > > > > > > > #define DP_SET_POWER 0x600 > > > > > # define DP_SET_POWER_D0 0x1 > > > > > @@ -803,11 +804,17 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, > > > > > */ > > > > > #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0) > > > > > > > > > > +struct drm_dp_ds_revision { > > > > > + int major; > > > > > + int minor; > > > > > +}; > > > > > + > > > > > struct drm_dp_link { > > > > > unsigned char revision; > > > > > unsigned int rate; > > > > > unsigned int num_lanes; > > > > > unsigned long capabilities; > > > > > + struct drm_dp_ds_revision ds_hw_rev; > > > > > }; > > > > > > > > > > int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); > > > > > @@ -819,6 +826,8 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > > int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > > const u8 port_cap[4]); > > > > > int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]); > > > > > +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], > > > > > + struct drm_dp_aux *aux, struct drm_dp_link *link); > > > > > > > > > > void drm_dp_aux_init(struct drm_dp_aux *aux); > > > > > int drm_dp_aux_register(struct drm_dp_aux *aux); > > > > > -- > > > > > 1.9.1 > > > > > > > > > > > -- > > Ville Syrjälä > > Intel OTC
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 75b2873..5fecdc1 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -514,6 +514,33 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], EXPORT_SYMBOL(drm_dp_downstream_max_bpc); /** + * drm_dp_downstream_hw_rev() - read DP branch device HW revision + * @aux: DisplayPort AUX channel + * + * Returns 0 on succes or negative error code on failure + */ +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + struct drm_dp_aux *aux, struct drm_dp_link *link) +{ + uint8_t tmp; + int err; + + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) + return -EINVAL; + + err = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1); + + if (err < 0) + return err; + + link->ds_hw_rev.major = (tmp & 0xf0) >> 4; + link->ds_hw_rev.minor = tmp & 0xf; + + return 0; +} +EXPORT_SYMBOL(drm_dp_downstream_hw_rev); + +/** * drm_dp_downstream_id() - identify branch device * @aux: DisplayPort AUX channel * diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e74d851..a6eccf5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -865,6 +865,7 @@ struct intel_dp { uint8_t num_sink_rates; int sink_rates[DP_MAX_SUPPORTED_RATES]; struct drm_dp_aux aux; + struct drm_dp_link link; uint8_t train_set[4]; int panel_power_up_delay; int panel_power_down_delay; diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 8e1fe58..1127948 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -446,6 +446,7 @@ #define DP_SINK_OUI 0x400 #define DP_BRANCH_OUI 0x500 #define DP_BRANCH_ID 0x503 +#define DP_BRANCH_HW_REV 0x509 #define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 @@ -803,11 +804,17 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, */ #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0) +struct drm_dp_ds_revision { + int major; + int minor; +}; + struct drm_dp_link { unsigned char revision; unsigned int rate; unsigned int num_lanes; unsigned long capabilities; + struct drm_dp_ds_revision ds_hw_rev; }; int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); @@ -819,6 +826,8 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4]); int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]); +int drm_dp_downstream_hw_rev(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + struct drm_dp_aux *aux, struct drm_dp_link *link); void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux);
HW revision is mandatory field for DisplayPort branch devices. This is defined in DPCD register field 0x509. v2: move drm_dp_ds_revision structure to be part of drm_dp_link structure (Daniel) Signed-off-by: Mika Kahola <mika.kahola@intel.com> --- drivers/gpu/drm/drm_dp_helper.c | 27 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + include/drm/drm_dp_helper.h | 9 +++++++++ 3 files changed, 37 insertions(+)