[RFC 11/13] drm/dp: Add helper to dump DPCD

Jani Nikula jani.nikula at linux.intel.com
Mon Aug 17 00:02:04 PDT 2015


On Fri, 14 Aug 2015, Rafael Antognolli <rafael.antognolli at intel.com> wrote:
> On Fri, Aug 14, 2015 at 02:56:55PM +0300, Jani Nikula wrote:
>> On Wed, 12 Aug 2015, Thierry Reding <thierry.reding at gmail.com> wrote:
>> > From: Thierry Reding <treding at nvidia.com>
>> >
>> > The new drm_dp_dpcd_dump() helper dumps the contents of a DPCD to a
>> > seq_file and can be used to make the DPCD available via debugfs for
>> > example.
>> 
>> See i915/i915_debugfs.c for one DPCD dump implementation.
>> 
>> Around the time that was added, there was also some discussion (and
>> patches [1]) to expose a read/write debugfs interface to DPCD, letting
>> userspace access arbitrary DPCD registers.
>> 
>> Just this week there was some discussion about revisiting that. It was
>> about accessing some proprietary panel features, but there's also the
>> ease of debugging without having to keep updating the kernel to dump
>> more.
>> 
>> I think it would be great to agree on a common debugfs interface to
>> access DPCD arbitrarily. Last time I checked, the blocker to that was
>> access to the aux channel from generic code; it's always driver
>> specific. SMOP. ;)
>
> Do you mean it would require the generic code/interface to somehow route
> this to the driver specific code? I am not sure yet how this works (if
> there's something like it around), but I'll take a look.

Drivers can choose to support DP AUX any way they like, and they don't
have to use the common helpers to do so. It's pretty much an
implementation detail. I think we could require the use of the common
helpers to support generic DPCD access from debugfs, but we'd still have
to come up with a way to get hold of struct drm_dp_aux (again, driver
internals) given a drm_connector in generic debugfs code.

Thierry, do you see any problems with having a connector function to get
hold of its drm_dp_aux?

>> I could put some effort into this (maybe Rafael too?), as long as we
>> could agree on the interface. As I wrote in the referenced thread, I
>> wasn't thrilled about what was proposed.
>> 
>
> Yes, I'm willing to put effort into this, for sure. Any help pointing to
> which direction to follow is greatly appreciated.

Great!

BR,
Jani.


>
> Thanks,
> Rafael
>
>> 
>> 
>> [1] http://mid.gmane.org/1428493301-20293-1-git-send-email-durgadoss.r@intel.com
>> 
>> 
>> 
>> >
>> > Signed-off-by: Thierry Reding <treding at nvidia.com>
>> > ---
>> >  drivers/gpu/drm/drm_dp_helper.c | 146 ++++++++++++++++++++++++++++++++++++++++
>> >  include/drm/drm_dp_helper.h     |   2 +
>> >  2 files changed, 148 insertions(+)
>> >
>> > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
>> > index 8968201ea93c..ea74884c9cb3 100644
>> > --- a/drivers/gpu/drm/drm_dp_helper.c
>> > +++ b/drivers/gpu/drm/drm_dp_helper.c
>> > @@ -27,6 +27,7 @@
>> >  #include <linux/errno.h>
>> >  #include <linux/sched.h>
>> >  #include <linux/i2c.h>
>> > +#include <linux/seq_file.h>
>> >  #include <drm/drm_dp_helper.h>
>> >  #include <drm/drmP.h>
>> >  
>> > @@ -292,6 +293,151 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
>> >  }
>> >  EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
>> >  
>> > +/**
>> > + * drm_dp_dpcd_dump() - dump DPCD content
>> > + * @aux: DisplayPort AUX channel
>> > + * @s: destination for DPCD dump
>> > + *
>> > + * Reads registers from the DPCD via a DisplayPort AUX channel and dumps them
>> > + * to a seq_file.
>> > + */
>> > +void drm_dp_dpcd_dump(struct drm_dp_aux *aux, struct seq_file *s)
>> > +{
>> > +#define DUMP_REG(aux, offset) ({					\
>> > +		u8 value;						\
>> > +		int err;						\
>> > +		err = drm_dp_dpcd_readb(aux, offset, &value);		\
>> > +		if (err < 0) {						\
>> > +			dev_err((aux)->dev, "failed to read %s: %d\n",	\
>> > +				#offset, err);				\
>> > +			return;						\
>> > +		}							\
>> > +		seq_printf(s, "%-35s 0x%04x 0x%02x\n", #offset, offset,	\
>> > +			   value);					\
>> > +	})
>> > +
>> > +	DUMP_REG(aux, DP_DPCD_REV);
>> > +	DUMP_REG(aux, DP_MAX_LINK_RATE);
>> > +	DUMP_REG(aux, DP_MAX_LANE_COUNT);
>> > +	DUMP_REG(aux, DP_MAX_DOWNSPREAD);
>> > +	DUMP_REG(aux, DP_NORP);
>> > +	DUMP_REG(aux, DP_DOWNSTREAMPORT_PRESENT);
>> > +	DUMP_REG(aux, DP_MAIN_LINK_CHANNEL_CODING);
>> > +	DUMP_REG(aux, DP_DOWN_STREAM_PORT_COUNT);
>> > +	DUMP_REG(aux, DP_RECEIVE_PORT_0_CAP_0);
>> > +	DUMP_REG(aux, DP_RECEIVE_PORT_0_BUFFER_SIZE);
>> > +	DUMP_REG(aux, DP_RECEIVE_PORT_1_CAP_0);
>> > +	DUMP_REG(aux, DP_RECEIVE_PORT_1_BUFFER_SIZE);
>> > +	DUMP_REG(aux, DP_I2C_SPEED_CAP);
>> > +	DUMP_REG(aux, DP_EDP_CONFIGURATION_CAP);
>> > +	DUMP_REG(aux, DP_TRAINING_AUX_RD_INTERVAL);
>> > +	DUMP_REG(aux, DP_ADAPTER_CAP);
>> > +	DUMP_REG(aux, DP_SUPPORTED_LINK_RATES);
>> > +	DUMP_REG(aux, DP_FAUX_CAP);
>> > +	DUMP_REG(aux, DP_MSTM_CAP);
>> > +	DUMP_REG(aux, DP_NUMBER_OF_AUDIO_ENDPOINTS);
>> > +	DUMP_REG(aux, DP_AV_GRANULARITY);
>> > +	DUMP_REG(aux, DP_AUD_DEC_LAT0);
>> > +	DUMP_REG(aux, DP_AUD_DEC_LAT1);
>> > +	DUMP_REG(aux, DP_AUD_PP_LAT0);
>> > +	DUMP_REG(aux, DP_AUD_PP_LAT1);
>> > +	DUMP_REG(aux, DP_VID_INTER_LAT);
>> > +	DUMP_REG(aux, DP_VID_PROG_LAT);
>> > +	DUMP_REG(aux, DP_REP_LAT);
>> > +	DUMP_REG(aux, DP_AUD_DEL_INS0);
>> > +	DUMP_REG(aux, DP_AUD_DEL_INS1);
>> > +	DUMP_REG(aux, DP_AUD_DEL_INS2);
>> > +	DUMP_REG(aux, DP_RECEIVER_ALPM_CAP);
>> > +	DUMP_REG(aux, DP_AUD_DEL_INS0);
>> > +	DUMP_REG(aux, DP_GUID);
>> > +	DUMP_REG(aux, DP_PSR_SUPPORT);
>> > +	DUMP_REG(aux, DP_PSR_CAPS);
>> > +	DUMP_REG(aux, DP_DOWNSTREAM_PORT_0);
>> > +	DUMP_REG(aux, DP_LINK_BW_SET);
>> > +	DUMP_REG(aux, DP_LANE_COUNT_SET);
>> > +	DUMP_REG(aux, DP_TRAINING_PATTERN_SET);
>> > +	DUMP_REG(aux, DP_TRAINING_LANE0_SET);
>> > +	DUMP_REG(aux, DP_TRAINING_LANE1_SET);
>> > +	DUMP_REG(aux, DP_TRAINING_LANE2_SET);
>> > +	DUMP_REG(aux, DP_TRAINING_LANE3_SET);
>> > +	DUMP_REG(aux, DP_DOWNSPREAD_CTRL);
>> > +	DUMP_REG(aux, DP_MAIN_LINK_CHANNEL_CODING_SET);
>> > +	DUMP_REG(aux, DP_I2C_SPEED_CONTROL_STATUS);
>> > +	DUMP_REG(aux, DP_EDP_CONFIGURATION_SET);
>> > +	DUMP_REG(aux, DP_LINK_QUAL_LANE0_SET);
>> > +	DUMP_REG(aux, DP_LINK_QUAL_LANE1_SET);
>> > +	DUMP_REG(aux, DP_LINK_QUAL_LANE2_SET);
>> > +	DUMP_REG(aux, DP_LINK_QUAL_LANE3_SET);
>> > +	DUMP_REG(aux, DP_TRAINING_LANE0_1_SET2);
>> > +	DUMP_REG(aux, DP_TRAINING_LANE2_3_SET2);
>> > +	DUMP_REG(aux, DP_MSTM_CTRL);
>> > +	DUMP_REG(aux, DP_AUDIO_DELAY0);
>> > +	DUMP_REG(aux, DP_AUDIO_DELAY1);
>> > +	DUMP_REG(aux, DP_AUDIO_DELAY2);
>> > +	DUMP_REG(aux, DP_LINK_RATE_SET);
>> > +	DUMP_REG(aux, DP_RECEIVER_ALPM_CONFIG);
>> > +	DUMP_REG(aux, DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF);
>> > +	DUMP_REG(aux, DP_UPSTREAM_DEVICE_DP_PWR_NEED);
>> > +	DUMP_REG(aux, DP_AUX_FRAME_SYNC_VALUE);
>> > +	DUMP_REG(aux, DP_PSR_EN_CFG);
>> > +	DUMP_REG(aux, DP_ADAPTER_CTRL);
>> > +	DUMP_REG(aux, DP_BRANCH_DEVICE_CTRL);
>> > +	DUMP_REG(aux, DP_PAYLOAD_ALLOCATE_SET);
>> > +	DUMP_REG(aux, DP_PAYLOAD_ALLOCATE_START_TIME_SLOT);
>> > +	DUMP_REG(aux, DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT);
>> > +	DUMP_REG(aux, DP_SINK_COUNT);
>> > +	DUMP_REG(aux, DP_DEVICE_SERVICE_IRQ_VECTOR);
>> > +	DUMP_REG(aux, DP_LANE0_1_STATUS);
>> > +	DUMP_REG(aux, DP_LANE2_3_STATUS);
>> > +	DUMP_REG(aux, DP_LANE_ALIGN_STATUS_UPDATED);
>> > +	DUMP_REG(aux, DP_SINK_STATUS);
>> > +	DUMP_REG(aux, DP_ADJUST_REQUEST_LANE0_1);
>> > +	DUMP_REG(aux, DP_ADJUST_REQUEST_LANE2_3);
>> > +	DUMP_REG(aux, DP_TEST_REQUEST);
>> > +	DUMP_REG(aux, DP_TEST_LINK_RATE);
>> > +	DUMP_REG(aux, DP_TEST_LANE_COUNT);
>> > +	DUMP_REG(aux, DP_TEST_CRC_R_CR);
>> > +	DUMP_REG(aux, DP_TEST_CRC_G_Y);
>> > +	DUMP_REG(aux, DP_TEST_CRC_B_CB);
>> > +	DUMP_REG(aux, DP_TEST_SINK_MISC);
>> > +	DUMP_REG(aux, DP_TEST_RESPONSE);
>> > +	DUMP_REG(aux, DP_TEST_EDID_CHECKSUM);
>> > +	DUMP_REG(aux, DP_TEST_SINK);
>> > +	DUMP_REG(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS);
>> > +	DUMP_REG(aux, DP_VC_PAYLOAD_ID_SLOT_1);
>> > +	DUMP_REG(aux, DP_SOURCE_OUI);
>> > +	DUMP_REG(aux, DP_SINK_OUI);
>> > +	DUMP_REG(aux, DP_BRANCH_OUI);
>> > +	DUMP_REG(aux, DP_SET_POWER);
>> > +	DUMP_REG(aux, DP_EDP_DPCD_REV);
>> > +	DUMP_REG(aux, DP_EDP_GENERAL_CAP_1);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_ADJUSTMENT_CAP);
>> > +	DUMP_REG(aux, DP_EDP_GENERAL_CAP_2);
>> > +	DUMP_REG(aux, DP_EDP_GENERAL_CAP_3);
>> > +	DUMP_REG(aux, DP_EDP_DISPLAY_CONTROL_REGISTER);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_BRIGHTNESS_LSB);
>> > +	DUMP_REG(aux, DP_EDP_PWMGEN_BIT_COUNT);
>> > +	DUMP_REG(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN);
>> > +	DUMP_REG(aux, DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_CONTROL_STATUS);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_FREQ_SET);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_FREQ_CAP_MIN_MSB);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_FREQ_CAP_MIN_MID);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_FREQ_CAP_MIN_LSB);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_FREQ_CAP_MAX_MSB);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_FREQ_CAP_MAX_MID);
>> > +	DUMP_REG(aux, DP_EDP_BACKLIGHT_FREQ_CAP_MAX_LSB);
>> > +	DUMP_REG(aux, DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET);
>> > +	DUMP_REG(aux, DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET);
>> > +	DUMP_REG(aux, DP_EDP_REGIONAL_BACKLIGHT_BASE);
>> > +	DUMP_REG(aux, DP_EDP_REGIONAL_BACKLIGHT_0);
>> > +
>> > +#undef DUMP_REG
>> > +}
>> > +EXPORT_SYMBOL(drm_dp_dpcd_dump);
>> > +
>> >  static void drm_dp_link_reset(struct drm_dp_link *link)
>> >  {
>> >  	if (!link)
>> > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
>> > index d041bb00d6a0..089d274f857d 100644
>> > --- a/include/drm/drm_dp_helper.h
>> > +++ b/include/drm/drm_dp_helper.h
>> > @@ -754,6 +754,8 @@ static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux,
>> >  int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
>> >  				 u8 status[DP_LINK_STATUS_SIZE]);
>> >  
>> > +void drm_dp_dpcd_dump(struct drm_dp_aux *aux, struct seq_file *s);
>> > +
>> >  /**
>> >   * struct drm_dp_link_train_set - link training settings
>> >   * @voltage_swing: per-lane voltage swing
>> > -- 
>> > 2.4.5
>> >
>> > _______________________________________________
>> > dri-devel mailing list
>> > dri-devel at lists.freedesktop.org
>> > http://lists.freedesktop.org/mailman/listinfo/dri-devel
>> 
>> -- 
>> Jani Nikula, Intel Open Source Technology Center

-- 
Jani Nikula, Intel Open Source Technology Center


More information about the dri-devel mailing list