Prep work for DP branch device handling
This series of patches reads DPCD register 0x80h for receiver capabilities for DP branch devices. The branch device types are converters for the following standards
- DP to VGA - DP to DVI - DP to HDMI - DP++ dual mode - Wireless WiGig
DPCD register defines max pixel rate for VGA dongles. This check is carried out during mode validation.
What's new in the series: - Readout of branch device ID, HW, and SW revisions from DPCD register - branch device info on debugfs
v2: DPCD register read outs moved to drm (Ville, Daniel) v3: Max pixel rate computation moved to drm (Daniel) v4: Use of drm_dp_helper routines to collect data (Ville) v5: Remove duplicate code and unnecessary functions from drm_dp_helper (Ville) v6: Rebase and i915_debugfs cleanup
Mika Kahola (10): drm: Add missing DP downstream port types drm: Drop VGA from bpc definitions drm: Helper to read max clock rate drm: Helper to read max bits per component drm: Read DP branch device id drm: Read DP branch device HW revision drm: Read DP branch device SW revision drm/i915: Check pixel rate for DP to VGA dongle drm/i915: Update bits per component for display info drm/i915: Add DP branch device info on debugfs
drivers/gpu/drm/drm_dp_helper.c | 129 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_debugfs.c | 75 +++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 35 ++++++++++ include/drm/drm_dp_helper.h | 27 ++++++-- 4 files changed, 261 insertions(+), 5 deletions(-)
Add missing DisplayPort downstream port types. The introduced new port types are DP++ and Wireless.
Signed-off-by: Mika Kahola mika.kahola@intel.com --- include/drm/drm_dp_helper.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 4d85cf2..6e8b92e 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -211,6 +211,8 @@ # define DP_DS_PORT_TYPE_DVI 2 # define DP_DS_PORT_TYPE_HDMI 3 # define DP_DS_PORT_TYPE_NON_EDID 4 +# define DP_DS_PORT_TYPE_DP_DUALMODE 5 +# define DP_DS_PORT_TYPE_WIRELESS 6 # define DP_DS_PORT_HPD (1 << 3) /* offset 1 for VGA is maximum megapixels per second / 8 */ /* offset 2 */
On Wed, Jul 06, 2016 at 02:04:45PM +0300, Mika Kahola wrote:
Add missing DisplayPort downstream port types. The introduced new port types are DP++ and Wireless.
Looks good relative to the DP spec.
Reviewed-by: Jim Bride jim.bride@linux.intel.com
Signed-off-by: Mika Kahola mika.kahola@intel.com
include/drm/drm_dp_helper.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 4d85cf2..6e8b92e 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -211,6 +211,8 @@ # define DP_DS_PORT_TYPE_DVI 2 # define DP_DS_PORT_TYPE_HDMI 3 # define DP_DS_PORT_TYPE_NON_EDID 4 +# define DP_DS_PORT_TYPE_DP_DUALMODE 5 +# define DP_DS_PORT_TYPE_WIRELESS 6 # define DP_DS_PORT_HPD (1 << 3) /* offset 1 for VGA is maximum megapixels per second / 8 */ /* offset 2 */ -- 1.9.1
Drop "VGA" from bits per component definitions as these are also used by other standards such as DVI, HDMI, DP++.
Signed-off-by: Mika Kahola mika.kahola@intel.com --- include/drm/drm_dp_helper.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 6e8b92e..336d742 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -216,11 +216,11 @@ # define DP_DS_PORT_HPD (1 << 3) /* offset 1 for VGA is maximum megapixels per second / 8 */ /* offset 2 */ -# define DP_DS_VGA_MAX_BPC_MASK (3 << 0) -# define DP_DS_VGA_8BPC 0 -# define DP_DS_VGA_10BPC 1 -# define DP_DS_VGA_12BPC 2 -# define DP_DS_VGA_16BPC 3 +# define DP_DS_MAX_BPC_MASK (3 << 0) +# define DP_DS_8BPC 0 +# define DP_DS_10BPC 1 +# define DP_DS_12BPC 2 +# define DP_DS_16BPC 3
/* link configuration */ #define DP_LINK_BW_SET 0x100
On Wed, Jul 06, 2016 at 02:04:46PM +0300, Mika Kahola wrote:
Drop "VGA" from bits per component definitions as these are also used by other standards such as DVI, HDMI, DP++.
Reviewed-by: Jim Bride jim.bride@linux.intel.com
Signed-off-by: Mika Kahola mika.kahola@intel.com
include/drm/drm_dp_helper.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 6e8b92e..336d742 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -216,11 +216,11 @@ # define DP_DS_PORT_HPD (1 << 3) /* offset 1 for VGA is maximum megapixels per second / 8 */ /* offset 2 */ -# define DP_DS_VGA_MAX_BPC_MASK (3 << 0) -# define DP_DS_VGA_8BPC 0 -# define DP_DS_VGA_10BPC 1 -# define DP_DS_VGA_12BPC 2 -# define DP_DS_VGA_16BPC 3 +# define DP_DS_MAX_BPC_MASK (3 << 0) +# define DP_DS_8BPC 0 +# define DP_DS_10BPC 1 +# define DP_DS_12BPC 2 +# define DP_DS_16BPC 3
/* link configuration */
#define DP_LINK_BW_SET 0x100
1.9.1
Helper routine to read out maximum supported pixel rate for DisplayPort legay VGA converter or TMDS clock rate for other digital legacy converters. The helper returns clock rate in kHz.
v2: Return early if detailed port cap info is not available. Replace if-else ladder with switch-case (Ville)
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 33 +++++++++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 091053e..0d4117c 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -438,6 +438,39 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link) } EXPORT_SYMBOL(drm_dp_link_configure);
+/** + * drm_dp_downstream_max_clock() - extract branch device max + * pixel rate for legacy VGA + * converter or max TMDS clock + * rate for others + * @dpcd: DisplayPort configuration data + * @port_cap: port capabilities + * + * Returns max clock in kHz on success or 0 if max clock not defined + */ +int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]) +{ + int type = port_cap[0] & DP_DS_PORT_TYPE_MASK; + bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DETAILED_CAP_INFO_AVAILABLE; + + if (!detailed_cap_info) + return 0; + + switch (type) { + case DP_DS_PORT_TYPE_VGA: + return port_cap[1] * 8 * 1000; + case DP_DS_PORT_TYPE_DVI: + case DP_DS_PORT_TYPE_HDMI: + case DP_DS_PORT_TYPE_DP_DUALMODE: + return port_cap[1] * 2500; + default: + return 0; + } +} +EXPORT_SYMBOL(drm_dp_downstream_max_clock); + /* * I2C-over-AUX implementation */ diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 336d742..de8e9ae 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -806,6 +806,8 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); +int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux);
On Wed, Jul 06, 2016 at 02:04:47PM +0300, Mika Kahola wrote:
Helper routine to read out maximum supported pixel rate for DisplayPort legay VGA converter or TMDS clock rate for other digital legacy converters. The helper returns clock rate in kHz.
v2: Return early if detailed port cap info is not available. Replace if-else ladder with switch-case (Ville)
Reviewed-by: Jim Bride jim.bride@linux.intel.com
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/drm_dp_helper.c | 33 +++++++++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 091053e..0d4117c 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -438,6 +438,39 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link) } EXPORT_SYMBOL(drm_dp_link_configure);
+/**
- drm_dp_downstream_max_clock() - extract branch device max
pixel rate for legacy VGA
converter or max TMDS clock
rate for others
- @dpcd: DisplayPort configuration data
- @port_cap: port capabilities
- Returns max clock in kHz on success or 0 if max clock not defined
- */
+int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4])
+{
- int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
- bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
DP_DETAILED_CAP_INFO_AVAILABLE;
- if (!detailed_cap_info)
return 0;
- switch (type) {
- case DP_DS_PORT_TYPE_VGA:
return port_cap[1] * 8 * 1000;
- case DP_DS_PORT_TYPE_DVI:
- case DP_DS_PORT_TYPE_HDMI:
- case DP_DS_PORT_TYPE_DP_DUALMODE:
return port_cap[1] * 2500;
- default:
return 0;
- }
+} +EXPORT_SYMBOL(drm_dp_downstream_max_clock);
/*
- I2C-over-AUX implementation
*/ diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 336d742..de8e9ae 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -806,6 +806,8 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); +int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4]);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); -- 1.9.1
Helper routine to read out maximum supported bits per component for DisplayPort legay converters.
v2: Return early if detailed port cap info is not available. Replace if-else ladder with switch-case (Ville)
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 42 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 44 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 0d4117c..95d624a 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -471,6 +471,48 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], } EXPORT_SYMBOL(drm_dp_downstream_max_clock);
+/** + * drm_dp_downstream_max_bpc() - extract branch device max + * bits per component + * @dpcd: DisplayPort configuration data + * @port_cap: port capabilities + * + * Returns max bpc on success or 0 if max bpc not defined + */ +int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]) +{ + int type = port_cap[0] & DP_DS_PORT_TYPE_MASK; + bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DETAILED_CAP_INFO_AVAILABLE; + int bpc; + + if (!detailed_cap_info) + return 0; + + switch (type) { + case DP_DS_PORT_TYPE_VGA: + case DP_DS_PORT_TYPE_DVI: + case DP_DS_PORT_TYPE_HDMI: + case DP_DS_PORT_TYPE_DP_DUALMODE: + bpc = port_cap[2] & DP_DS_MAX_BPC_MASK; + + switch (bpc) { + case DP_DS_8BPC: + return 8; + case DP_DS_10BPC: + return 10; + case DP_DS_12BPC: + return 12; + case DP_DS_16BPC: + return 16; + } + default: + return 0; + } +} +EXPORT_SYMBOL(drm_dp_downstream_max_bpc); + /* * I2C-over-AUX implementation */ diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index de8e9ae..47ae8ed 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -808,6 +808,8 @@ int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4]); +int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], + const u8 port_cap[4]);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux);
On Wed, Jul 06, 2016 at 02:04:48PM +0300, Mika Kahola wrote:
Helper routine to read out maximum supported bits per component for DisplayPort legay converters.
v2: Return early if detailed port cap info is not available. Replace if-else ladder with switch-case (Ville)
Reviewed-by: Jim Bride jim.bride@linux.intel.com
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/drm_dp_helper.c | 42 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 44 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 0d4117c..95d624a 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -471,6 +471,48 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], } EXPORT_SYMBOL(drm_dp_downstream_max_clock);
+/**
- drm_dp_downstream_max_bpc() - extract branch device max
bits per component
- @dpcd: DisplayPort configuration data
- @port_cap: port capabilities
- Returns max bpc on success or 0 if max bpc not defined
- */
+int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4])
+{
- int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
- bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
DP_DETAILED_CAP_INFO_AVAILABLE;
- int bpc;
- if (!detailed_cap_info)
return 0;
- switch (type) {
- case DP_DS_PORT_TYPE_VGA:
- case DP_DS_PORT_TYPE_DVI:
- case DP_DS_PORT_TYPE_HDMI:
- case DP_DS_PORT_TYPE_DP_DUALMODE:
bpc = port_cap[2] & DP_DS_MAX_BPC_MASK;
switch (bpc) {
case DP_DS_8BPC:
return 8;
case DP_DS_10BPC:
return 10;
case DP_DS_12BPC:
return 12;
case DP_DS_16BPC:
return 16;
}
- default:
return 0;
- }
+} +EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
/*
- I2C-over-AUX implementation
*/ diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index de8e9ae..47ae8ed 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -808,6 +808,8 @@ int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4]); +int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4]);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); -- 1.9.1
Read DisplayPort branch device id string.
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 12 ++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 95d624a..4003464 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -513,6 +513,18 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], } EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
+/** + * drm_dp_downstream_id() - identify branch device + * @aux: DisplayPort AUX channel + * + * Returns branch device id on success or NULL on failure + */ +int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]) +{ + return drm_dp_dpcd_read(aux, DP_BRANCH_ID, id, 6); +} +EXPORT_SYMBOL(drm_dp_downstream_id); + /* * I2C-over-AUX implementation */ diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 47ae8ed..8264d54 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -445,6 +445,7 @@ #define DP_SOURCE_OUI 0x300 #define DP_SINK_OUI 0x400 #define DP_BRANCH_OUI 0x500 +#define DP_BRANCH_ID 0x503
#define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 @@ -810,6 +811,7 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4]); 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]);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux);
On Wed, Jul 06, 2016 at 02:04:49PM +0300, Mika Kahola wrote:
Read DisplayPort branch device id string.
Reviewed-by: Jim Bride jim.bride@linux.intel.com
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/drm_dp_helper.c | 12 ++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 95d624a..4003464 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -513,6 +513,18 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE], } EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
+/**
- drm_dp_downstream_id() - identify branch device
- @aux: DisplayPort AUX channel
- Returns branch device id on success or NULL on failure
- */
+int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]) +{
- return drm_dp_dpcd_read(aux, DP_BRANCH_ID, id, 6);
+} +EXPORT_SYMBOL(drm_dp_downstream_id);
/*
- I2C-over-AUX implementation
*/ diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 47ae8ed..8264d54 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -445,6 +445,7 @@ #define DP_SOURCE_OUI 0x300 #define DP_SINK_OUI 0x400 #define DP_BRANCH_OUI 0x500 +#define DP_BRANCH_ID 0x503
#define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 @@ -810,6 +811,7 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4]); 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]);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); -- 1.9.1
HW revision is mandatory field for DisplayPort branch devices. This is defined in DPCD register field 0x509.
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 21 +++++++++++++++++++++ include/drm/drm_dp_helper.h | 7 +++++++ 2 files changed, 28 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 4003464..cfd75df 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -514,6 +514,27 @@ 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 HW revision on succes or negative error code on failure + */ +struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux) +{ + uint8_t tmp; + struct drm_dp_revision rev = { .major = -EINVAL, .minor = -EINVAL }; + + if (drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1) != 1) + return rev; + + rev.major = (tmp & 0xf0) >> 4; + rev.minor = tmp & 0xf; + + return rev; +} +EXPORT_SYMBOL(drm_dp_downstream_hw_rev); + +/** * drm_dp_downstream_id() - identify branch device * @aux: DisplayPort AUX channel * diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 8264d54..5f577e4 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,6 +804,11 @@ struct drm_dp_link { unsigned long capabilities; };
+struct drm_dp_revision { + int major; + int minor; +}; + int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); @@ -812,6 +818,7 @@ 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]); +struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux);
On Wed, Jul 06, 2016 at 02:04:50PM +0300, Mika Kahola wrote:
HW revision is mandatory field for DisplayPort branch devices. This is defined in DPCD register field 0x509.
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/drm_dp_helper.c | 21 +++++++++++++++++++++ include/drm/drm_dp_helper.h | 7 +++++++ 2 files changed, 28 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 4003464..cfd75df 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -514,6 +514,27 @@ 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 HW revision on succes or negative error code on failure
- */
+struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux) +{
- uint8_t tmp;
- struct drm_dp_revision rev = { .major = -EINVAL, .minor = -EINVAL };
- if (drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1) != 1)
return rev;
- rev.major = (tmp & 0xf0) >> 4;
- rev.minor = tmp & 0xf;
- return rev;
+} +EXPORT_SYMBOL(drm_dp_downstream_hw_rev);
+/**
- drm_dp_downstream_id() - identify branch device
- @aux: DisplayPort AUX channel
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 8264d54..5f577e4 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,6 +804,11 @@ struct drm_dp_link { unsigned long capabilities; };
+struct drm_dp_revision {
int major;
int minor;
+};
Atm we have two styles of helpers: - The ones that put decoded values into struct drm_dp_link - A pile of functions that return individual values.
This seems to add a third one. I guess it'd be better to just move everything over to putting parsed values into drm_dp_link and fill that out for everything ... -Daniel
int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); @@ -812,6 +818,7 @@ 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]); +struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); -- 1.9.1
On Tue, 2016-07-12 at 15:54 +0200, Daniel Vetter wrote:
On Wed, Jul 06, 2016 at 02:04:50PM +0300, Mika Kahola wrote:
HW revision is mandatory field for DisplayPort branch devices. This is defined in DPCD register field 0x509.
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/drm_dp_helper.c | 21 +++++++++++++++++++++ include/drm/drm_dp_helper.h | 7 +++++++ 2 files changed, 28 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 4003464..cfd75df 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -514,6 +514,27 @@ 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 HW revision on succes or negative error code on failure
- */
+struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux) +{
- uint8_t tmp;
- struct drm_dp_revision rev = { .major = -EINVAL, .minor = -EINVAL };
- if (drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &tmp, 1) != 1)
return rev;
- rev.major = (tmp & 0xf0) >> 4;
- rev.minor = tmp & 0xf;
- return rev;
+} +EXPORT_SYMBOL(drm_dp_downstream_hw_rev);
+/**
- drm_dp_downstream_id() - identify branch device
- @aux: DisplayPort AUX channel
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 8264d54..5f577e4 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,6 +804,11 @@ struct drm_dp_link { unsigned long capabilities; };
+struct drm_dp_revision {
int major;
int minor;
+};
Atm we have two styles of helpers:
- The ones that put decoded values into struct drm_dp_link
- A pile of functions that return individual values.
This seems to add a third one. I guess it'd be better to just move everything over to putting parsed values into drm_dp_link and fill that out for everything ... -Daniel
Ok. Let's move all this information to drm_dp_link. I'll revise the patch.
Cheers, Mika
int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); @@ -812,6 +818,7 @@ 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]); +struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); -- 1.9.1
SW revision is mandatory field for DisplayPort branch devices. This is defined in DPCD register field 0x50A.
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 21 +++++++++++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index cfd75df..19e06a0 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -535,6 +535,27 @@ struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux) EXPORT_SYMBOL(drm_dp_downstream_hw_rev);
/** + * drm_dp_downstream_sw_rev() - read DP branch device SW revision + * @aux: DisplayPort AUX channel + * + * Returns SW revision on success or negative error code on failure + */ +struct drm_dp_revision drm_dp_downstream_sw_rev(struct drm_dp_aux *aux) +{ + uint8_t tmp[2]; + struct drm_dp_revision rev = { .major = -EINVAL, .minor = -EINVAL }; + + if (drm_dp_dpcd_read(aux, DP_BRANCH_SW_REV, tmp, 2) != 2) + return rev; + + rev.major = tmp[0]; + rev.minor = tmp[1]; + + return rev; +} +EXPORT_SYMBOL(drm_dp_downstream_sw_rev); + +/** * drm_dp_downstream_id() - identify branch device * @aux: DisplayPort AUX channel * diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 5f577e4..764a309 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -447,6 +447,7 @@ #define DP_BRANCH_OUI 0x500 #define DP_BRANCH_ID 0x503 #define DP_BRANCH_HW_REV 0x509 +#define DP_BRANCH_SW_REV 0x50A
#define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 @@ -819,6 +820,7 @@ 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]); struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux); +struct drm_dp_revision drm_dp_downstream_sw_rev(struct drm_dp_aux *aux);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux);
On Wed, Jul 06, 2016 at 02:04:51PM +0300, Mika Kahola wrote:
SW revision is mandatory field for DisplayPort branch devices. This is defined in DPCD register field 0x50A.
Reviewed-by: Jim Bride jim.bride@linux.intel.com
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/drm_dp_helper.c | 21 +++++++++++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index cfd75df..19e06a0 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -535,6 +535,27 @@ struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux) EXPORT_SYMBOL(drm_dp_downstream_hw_rev);
/**
- drm_dp_downstream_sw_rev() - read DP branch device SW revision
- @aux: DisplayPort AUX channel
- Returns SW revision on success or negative error code on failure
- */
+struct drm_dp_revision drm_dp_downstream_sw_rev(struct drm_dp_aux *aux) +{
- uint8_t tmp[2];
- struct drm_dp_revision rev = { .major = -EINVAL, .minor = -EINVAL };
- if (drm_dp_dpcd_read(aux, DP_BRANCH_SW_REV, tmp, 2) != 2)
return rev;
- rev.major = tmp[0];
- rev.minor = tmp[1];
- return rev;
+} +EXPORT_SYMBOL(drm_dp_downstream_sw_rev);
+/**
- drm_dp_downstream_id() - identify branch device
- @aux: DisplayPort AUX channel
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 5f577e4..764a309 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -447,6 +447,7 @@ #define DP_BRANCH_OUI 0x500 #define DP_BRANCH_ID 0x503 #define DP_BRANCH_HW_REV 0x509 +#define DP_BRANCH_SW_REV 0x50A
#define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 @@ -819,6 +820,7 @@ 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]); struct drm_dp_revision drm_dp_downstream_hw_rev(struct drm_dp_aux *aux); +struct drm_dp_revision drm_dp_downstream_sw_rev(struct drm_dp_aux *aux);
void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); -- 1.9.1
Filter out a mode that exceeds the max pixel rate setting for DP to VGA dongle. This is defined in DPCD register 0x81 if detailed cap info i.e. info field is 4 bytes long and it is available for DP downstream port.
The register defines the pixel rate divided by 8 in MP/s.
v2: DPCD read outs and computation moved to drm (Ville, Daniel) v3: Sink pixel rate computation moved to drm_dp_max_sink_dotclock() function (Daniel) v4: Use of drm_dp_helper.c routines to compute max pixel clock (Ville) v5: Use of intel_dp->downstream_ports to read out port capabilities. Code restructuring (Ville)
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ffa43ec..76a654e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -190,6 +190,20 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) return (max_link_clock * max_lanes * 8) / 10; }
+static int +intel_dp_downstream_max_clock(struct intel_dp *intel_dp, int clock) +{ + int dp_ds_clk; + + dp_ds_clk = drm_dp_downstream_max_clock(intel_dp->dpcd, + intel_dp->downstream_ports); + + if (dp_ds_clk == 0) + return clock; + + return min(clock, dp_ds_clk); +} + static enum drm_mode_status intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -201,6 +215,18 @@ intel_dp_mode_valid(struct drm_connector *connector, int max_rate, mode_rate, max_lanes, max_link_clock; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+ bool is_branch_device = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DWN_STRM_PORT_PRESENT; + int type; + + if (is_branch_device) { + type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK; + + if (type == DP_DS_PORT_TYPE_VGA) + max_dotclk = intel_dp_downstream_max_clock(intel_dp, + max_dotclk); + } + if (is_edp(intel_dp) && fixed_mode) { if (mode->hdisplay > fixed_mode->hdisplay) return MODE_PANEL;
On Wed, Jul 06, 2016 at 02:04:52PM +0300, Mika Kahola wrote:
Filter out a mode that exceeds the max pixel rate setting for DP to VGA dongle. This is defined in DPCD register 0x81 if detailed cap info i.e. info field is 4 bytes long and it is available for DP downstream port.
The register defines the pixel rate divided by 8 in MP/s.
v2: DPCD read outs and computation moved to drm (Ville, Daniel) v3: Sink pixel rate computation moved to drm_dp_max_sink_dotclock() function (Daniel) v4: Use of drm_dp_helper.c routines to compute max pixel clock (Ville) v5: Use of intel_dp->downstream_ports to read out port capabilities. Code restructuring (Ville)
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/i915/intel_dp.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ffa43ec..76a654e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -190,6 +190,20 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) return (max_link_clock * max_lanes * 8) / 10; }
+static int +intel_dp_downstream_max_clock(struct intel_dp *intel_dp, int clock) +{
- int dp_ds_clk;
- dp_ds_clk = drm_dp_downstream_max_clock(intel_dp->dpcd,
intel_dp->downstream_ports);
- if (dp_ds_clk == 0)
return clock;
- return min(clock, dp_ds_clk);
+}
static enum drm_mode_status intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -201,6 +215,18 @@ intel_dp_mode_valid(struct drm_connector *connector, int max_rate, mode_rate, max_lanes, max_link_clock; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
- bool is_branch_device = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
DP_DWN_STRM_PORT_PRESENT;
- int type;
- if (is_branch_device) {
Shouldn't we move this check into the drm dp helper? It can always return 0 for "no downstream port restrictions".
type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
if (type == DP_DS_PORT_TYPE_VGA)
Same here. -Daniel
max_dotclk = intel_dp_downstream_max_clock(intel_dp,
max_dotclk);
- }
- if (is_edp(intel_dp) && fixed_mode) { if (mode->hdisplay > fixed_mode->hdisplay) return MODE_PANEL;
-- 1.9.1
On Tue, 2016-07-12 at 15:50 +0200, Daniel Vetter wrote:
On Wed, Jul 06, 2016 at 02:04:52PM +0300, Mika Kahola wrote:
Filter out a mode that exceeds the max pixel rate setting for DP to VGA dongle. This is defined in DPCD register 0x81 if detailed cap info i.e. info field is 4 bytes long and it is available for DP downstream port.
The register defines the pixel rate divided by 8 in MP/s.
v2: DPCD read outs and computation moved to drm (Ville, Daniel) v3: Sink pixel rate computation moved to drm_dp_max_sink_dotclock() function (Daniel) v4: Use of drm_dp_helper.c routines to compute max pixel clock (Ville) v5: Use of intel_dp->downstream_ports to read out port capabilities. Code restructuring (Ville)
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/i915/intel_dp.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ffa43ec..76a654e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -190,6 +190,20 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) return (max_link_clock * max_lanes * 8) / 10; }
+static int +intel_dp_downstream_max_clock(struct intel_dp *intel_dp, int clock) +{
- int dp_ds_clk;
- dp_ds_clk = drm_dp_downstream_max_clock(intel_dp->dpcd,
intel_dp->downstream_ports);
- if (dp_ds_clk == 0)
return clock;
- return min(clock, dp_ds_clk);
+}
static enum drm_mode_status intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -201,6 +215,18 @@ intel_dp_mode_valid(struct drm_connector *connector, int max_rate, mode_rate, max_lanes, max_link_clock; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
- bool is_branch_device = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
DP_DWN_STRM_PORT_PRESENT;
- int type;
- if (is_branch_device) {
Shouldn't we move this check into the drm dp helper? It can always return 0 for "no downstream port restrictions".
I guess we can do that. It probably looks cleaner that way.
Cheers, Mika
type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
if (type == DP_DS_PORT_TYPE_VGA)
Same here. -Daniel
max_dotclk = intel_dp_downstream_max_clock(intel_dp,
max_dotclk);
- }
- if (is_edp(intel_dp) && fixed_mode) { if (mode->hdisplay > fixed_mode->hdisplay) return MODE_PANEL;
-- 1.9.1
DisplayPort branch device may define max supported bits per component. Update display info based on this value if bpc is defined.
v2: cleanup to match the drm_dp_helper.c patches introduced earlier in this series
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 76a654e..53ec844 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3932,6 +3932,14 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) uint8_t *dpcd = intel_dp->dpcd; uint8_t type;
+ if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) { + int bpc = drm_dp_downstream_max_bpc(dpcd, + intel_dp->downstream_ports); + + if (bpc > 0) + intel_dp->attached_connector->base.display_info.bpc = bpc; + } + if (!intel_dp_get_dpcd(intel_dp)) return connector_status_disconnected;
@@ -3968,6 +3976,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) return connector_status_unknown; }
+ /* Anything else is out of spec, warn and ignore */ DRM_DEBUG_KMS("Broken DP branch device, ignoring\n"); return connector_status_disconnected;
On Wed, Jul 06, 2016 at 02:04:53PM +0300, Mika Kahola wrote:
DisplayPort branch device may define max supported bits per component. Update display info based on this value if bpc is defined.
v2: cleanup to match the drm_dp_helper.c patches introduced earlier in this series
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/i915/intel_dp.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 76a654e..53ec844 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3932,6 +3932,14 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) uint8_t *dpcd = intel_dp->dpcd; uint8_t type;
- if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) {
int bpc = drm_dp_downstream_max_bpc(dpcd,
intel_dp->downstream_ports);
if (bpc > 0)
intel_dp->attached_connector->base.display_info.bpc = bpc;
- }
I think a function in the dp helpers to correctly fill out the connector's display info would be neater. -Daniel
- if (!intel_dp_get_dpcd(intel_dp)) return connector_status_disconnected;
@@ -3968,6 +3976,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) return connector_status_unknown; }
- /* Anything else is out of spec, warn and ignore */ DRM_DEBUG_KMS("Broken DP branch device, ignoring\n"); return connector_status_disconnected;
-- 1.9.1
On Tue, 2016-07-12 at 15:51 +0200, Daniel Vetter wrote:
On Wed, Jul 06, 2016 at 02:04:53PM +0300, Mika Kahola wrote:
DisplayPort branch device may define max supported bits per component. Update display info based on this value if bpc is defined.
v2: cleanup to match the drm_dp_helper.c patches introduced earlier in this series
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/i915/intel_dp.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 76a654e..53ec844 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3932,6 +3932,14 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) uint8_t *dpcd = intel_dp->dpcd; uint8_t type;
- if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) {
int bpc = drm_dp_downstream_max_bpc(dpcd,
intel_dp->downstream_ports);
if (bpc > 0)
intel_dp->attached_connector->base.display_info.bpc = bpc;
- }
I think a function in the dp helpers to correctly fill out the connector's display info would be neater. -Daniel
Ok. I can move this stuff to be part of dp helper routine. Cheers, Mika
- if (!intel_dp_get_dpcd(intel_dp)) return connector_status_disconnected;
@@ -3968,6 +3976,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) return connector_status_unknown; }
- /* Anything else is out of spec, warn and ignore */ DRM_DEBUG_KMS("Broken DP branch device, ignoring\n"); return connector_status_disconnected;
-- 1.9.1
On Tue, Aug 02, 2016 at 02:23:13PM +0300, Mika Kahola wrote:
On Tue, 2016-07-12 at 15:51 +0200, Daniel Vetter wrote:
On Wed, Jul 06, 2016 at 02:04:53PM +0300, Mika Kahola wrote:
DisplayPort branch device may define max supported bits per component. Update display info based on this value if bpc is defined.
v2: cleanup to match the drm_dp_helper.c patches introduced earlier in this series
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/i915/intel_dp.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 76a654e..53ec844 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3932,6 +3932,14 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) uint8_t *dpcd = intel_dp->dpcd; uint8_t type;
- if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) {
int bpc = drm_dp_downstream_max_bpc(dpcd,
intel_dp->downstream_ports);
if (bpc > 0)
intel_dp->attached_connector->base.display_info.bpc = bpc;
- }
I think a function in the dp helpers to correctly fill out the connector's display info would be neater. -Daniel
Ok. I can move this stuff to be part of dp helper routine.
I'm not sure frobbing with display_info is a good idea here since that that one has so far been the EDID parsers domain. The ordering between all this stuff is already very poorly defined/buggy, so some bigger cleanup is probably needed. I have some patches to the EDID parser that I should send out that at least make it a bit clearer where it fills out the display_info stuff.
Cheers, Mika
- if (!intel_dp_get_dpcd(intel_dp)) return connector_status_disconnected;
@@ -3968,6 +3976,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) return connector_status_unknown; }
- /* Anything else is out of spec, warn and ignore */ DRM_DEBUG_KMS("Broken DP branch device, ignoring\n"); return connector_status_disconnected;
-- 1.9.1
-- Mika Kahola - Intel OTC
On Tue, Aug 02, 2016 at 02:41:25PM +0300, Ville Syrjälä wrote:
On Tue, Aug 02, 2016 at 02:23:13PM +0300, Mika Kahola wrote:
On Tue, 2016-07-12 at 15:51 +0200, Daniel Vetter wrote:
On Wed, Jul 06, 2016 at 02:04:53PM +0300, Mika Kahola wrote:
DisplayPort branch device may define max supported bits per component. Update display info based on this value if bpc is defined.
v2: cleanup to match the drm_dp_helper.c patches introduced earlier in this series
Signed-off-by: Mika Kahola mika.kahola@intel.com
drivers/gpu/drm/i915/intel_dp.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 76a654e..53ec844 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3932,6 +3932,14 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) uint8_t *dpcd = intel_dp->dpcd; uint8_t type;
- if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) {
int bpc = drm_dp_downstream_max_bpc(dpcd,
intel_dp->downstream_ports);
if (bpc > 0)
intel_dp->attached_connector->base.display_info.bpc = bpc;
- }
I think a function in the dp helpers to correctly fill out the connector's display info would be neater. -Daniel
Ok. I can move this stuff to be part of dp helper routine.
I'm not sure frobbing with display_info is a good idea here since that that one has so far been the EDID parsers domain. The ordering between all this stuff is already very poorly defined/buggy, so some bigger cleanup is probably needed. I have some patches to the EDID parser that I should send out that at least make it a bit clearer where it fills out the display_info stuff.
+1 for bigger cleanup. A helper which does all the dp sink detection (grabs edid, dpcd and everything else and then computes restrictions) would be _real_ awesome I think. Even better if you can trick some other driver into using it too.
Tomeu from collabora just volunteered himself to clean up the analogix dp support and switch over to the helpers. He's rather active on irc, so great guinea-pig to volutneer for this and work together with. -Daniel
Cheers, Mika
- if (!intel_dp_get_dpcd(intel_dp)) return connector_status_disconnected;
@@ -3968,6 +3976,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) return connector_status_unknown; }
- /* Anything else is out of spec, warn and ignore */ DRM_DEBUG_KMS("Broken DP branch device, ignoring\n"); return connector_status_disconnected;
-- 1.9.1
-- Mika Kahola - Intel OTC
-- Ville Syrjälä Intel OTC
Read DisplayPort branch device info from through debugfs interface.
v2: use drm_dp_helper routines to collect data v3: cleanup to match the drm_dp_helper.c patches introduced earlier in this series v4: move DP branch device info to function 'intel_dp_branch_device_info()'
Signed-off-by: Mika Kahola mika.kahola@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9989b6a..7f57b3c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2942,16 +2942,91 @@ static void intel_panel_info(struct seq_file *m, struct intel_panel *panel) intel_seq_print_mode(m, 2, mode); }
+static void intel_dp_branch_device_info(struct seq_file *m, struct intel_dp *intel_dp) +{ + struct drm_dp_revision rev; + bool detailed_cap_info = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DETAILED_CAP_INFO_AVAILABLE; + int type; + int clk; + int bpc; + char id[6]; + + type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK; + + switch (type) { + case DP_DS_PORT_TYPE_DP: + seq_printf(m, "\ttype: DisplayPort\n"); + break; + case DP_DS_PORT_TYPE_VGA: + seq_printf(m, "\ttype: VGA\n"); + break; + case DP_DS_PORT_TYPE_DVI: + seq_printf(m, "\ttype: DVI\n"); + break; + case DP_DS_PORT_TYPE_HDMI: + seq_printf(m, "\ttype: HDMI\n"); + break; + case DP_DS_PORT_TYPE_NON_EDID: + seq_printf(m, "\ttype: others without EDID support\n"); + break; + case DP_DS_PORT_TYPE_DP_DUALMODE: + seq_printf(m, "\ttype: DP++\n"); + break; + case DP_DS_PORT_TYPE_WIRELESS: + seq_printf(m, "\ttype: Wireless\n"); + break; + default: + seq_printf(m, "\ttype: N/A\n"); + } + + drm_dp_downstream_id(&intel_dp->aux, id); + seq_printf(m, "\tDevice id: %s\n", id); + + rev = drm_dp_downstream_hw_rev(&intel_dp->aux); + seq_printf(m, "\tHW revision: %.2d.%.2d\n", rev.major, rev.minor); + + rev = drm_dp_downstream_sw_rev(&intel_dp->aux); + seq_printf(m, "\tSW revision: %.2d.%.2d\n", rev.major, rev.minor); + + if (detailed_cap_info) { + clk = drm_dp_downstream_max_clock(intel_dp->dpcd, + intel_dp->downstream_ports); + + if (clk > 0) { + if (type == DP_DS_PORT_TYPE_VGA) + seq_printf(m, "\tMax dot clock: %d kHz\n", clk); + else + seq_printf(m, "\tMax TMDS clock: %d kHz\n", clk); + } + + bpc = drm_dp_downstream_max_bpc(intel_dp->dpcd, + intel_dp->downstream_ports); + + if (bpc > 0) + seq_printf(m, "\tMax bpc: %d\n", bpc); + } +} + static void intel_dp_info(struct seq_file *m, struct intel_connector *intel_connector) { struct intel_encoder *intel_encoder = intel_connector->encoder; struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); + bool is_branch_device;
seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]); seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio)); + if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) intel_panel_info(m, &intel_connector->panel); + + is_branch_device = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DWN_STRM_PORT_PRESENT; + seq_printf(m, "\tbranch device: %s\n", yesno(is_branch_device)); + + if (is_branch_device) + intel_dp_branch_device_info(m, intel_dp); }
static void intel_hdmi_info(struct seq_file *m,
On Wed, Jul 06, 2016 at 02:04:54PM +0300, Mika Kahola wrote:
Read DisplayPort branch device info from through debugfs interface.
v2: use drm_dp_helper routines to collect data v3: cleanup to match the drm_dp_helper.c patches introduced earlier in this series v4: move DP branch device info to function 'intel_dp_branch_device_info()'
Signed-off-by: Mika Kahola mika.kahola@intel.com
Shouldn't we do any additional debugfs support at the dp helper level too? That way the parsing and debug code are all in the same place. Driver's shouldn't even need to register the debugfs files themselves imo. -Daniel
drivers/gpu/drm/i915/i915_debugfs.c | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9989b6a..7f57b3c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2942,16 +2942,91 @@ static void intel_panel_info(struct seq_file *m, struct intel_panel *panel) intel_seq_print_mode(m, 2, mode); }
+static void intel_dp_branch_device_info(struct seq_file *m, struct intel_dp *intel_dp) +{
- struct drm_dp_revision rev;
- bool detailed_cap_info = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
DP_DETAILED_CAP_INFO_AVAILABLE;
- int type;
- int clk;
- int bpc;
- char id[6];
- type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
- switch (type) {
- case DP_DS_PORT_TYPE_DP:
seq_printf(m, "\ttype: DisplayPort\n");
break;
- case DP_DS_PORT_TYPE_VGA:
seq_printf(m, "\ttype: VGA\n");
break;
- case DP_DS_PORT_TYPE_DVI:
seq_printf(m, "\ttype: DVI\n");
break;
- case DP_DS_PORT_TYPE_HDMI:
seq_printf(m, "\ttype: HDMI\n");
break;
- case DP_DS_PORT_TYPE_NON_EDID:
seq_printf(m, "\ttype: others without EDID support\n");
break;
- case DP_DS_PORT_TYPE_DP_DUALMODE:
seq_printf(m, "\ttype: DP++\n");
break;
- case DP_DS_PORT_TYPE_WIRELESS:
seq_printf(m, "\ttype: Wireless\n");
break;
- default:
seq_printf(m, "\ttype: N/A\n");
- }
- drm_dp_downstream_id(&intel_dp->aux, id);
- seq_printf(m, "\tDevice id: %s\n", id);
- rev = drm_dp_downstream_hw_rev(&intel_dp->aux);
- seq_printf(m, "\tHW revision: %.2d.%.2d\n", rev.major, rev.minor);
- rev = drm_dp_downstream_sw_rev(&intel_dp->aux);
- seq_printf(m, "\tSW revision: %.2d.%.2d\n", rev.major, rev.minor);
- if (detailed_cap_info) {
clk = drm_dp_downstream_max_clock(intel_dp->dpcd,
intel_dp->downstream_ports);
if (clk > 0) {
if (type == DP_DS_PORT_TYPE_VGA)
seq_printf(m, "\tMax dot clock: %d kHz\n", clk);
else
seq_printf(m, "\tMax TMDS clock: %d kHz\n", clk);
}
bpc = drm_dp_downstream_max_bpc(intel_dp->dpcd,
intel_dp->downstream_ports);
if (bpc > 0)
seq_printf(m, "\tMax bpc: %d\n", bpc);
- }
+}
static void intel_dp_info(struct seq_file *m, struct intel_connector *intel_connector) { struct intel_encoder *intel_encoder = intel_connector->encoder; struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
bool is_branch_device;
seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]); seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio));
if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) intel_panel_info(m, &intel_connector->panel);
is_branch_device = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
DP_DWN_STRM_PORT_PRESENT;
seq_printf(m, "\tbranch device: %s\n", yesno(is_branch_device));
if (is_branch_device)
intel_dp_branch_device_info(m, intel_dp);
}
static void intel_hdmi_info(struct seq_file *m,
1.9.1
dri-devel@lists.freedesktop.org