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 at >> 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