On Fri, 14 Aug 2015, Rafael Antognolli rafael.antognolli@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@gmail.com wrote:
From: Thierry Reding treding@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@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@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
-- Jani Nikula, Intel Open Source Technology Center