[PATCH 09/17] drm/i915: Add config parsing utilities in debugfs for Displayport compliance

Todd Previte
2014-12-10T23:54:11Z

This patch was previously part of "[PATCH 05/10] drm/i915: Add debugfs
interface for Displayport debug and compliance testing". This patch adds two
functions to handle parsing of Displayport configuration information as it
formatted in the debugfs file. It is used to process incoming configuration
changes from the userspace compliance application during testing.

Signed-off-by: Todd Previte <tprevite@gmail.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 128 ++++++++++++++++++++++++++++++++++++
1 file changed, 128 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 184797d..55b6da5 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3792,6 +3792,134 @@ int value_for_config_param(enum dp_config_param param,
return status;
}

+int tokenize_dp_config(char *input_buffer, char *output[])
+{
+ char *base = input_buffer, *index, *end;
+ int line_count = 0;
+ int i = 0, len = 0;
+ int done = 0;
+
+ if (!input_buffer)
+ return 0;
+
+ while (!done) {
+ index = strpbrk(base, ":");
+ if (index) {
+ len = index - base;
+ *index = '\0';
+ index++;
+ /* Save the type string */
+ output[i] = base;
+ i++;
+ line_count++;
+ end = strpbrk(index, "\n\0");
+ if (end) {
+ *end = '\0';
+ /* Eat up whitespace */
+ while (*index <= 0x20)
+ index++;
+ output[i] = index;
+ i++;
+ line_count++;
+ } else
+ done = 1;
+ /* Move to the next section of the string */
+ base = end + 1;
+ } else
+ done = 1;
+ }
+ return line_count;
+}
+
+static int displayport_parse_config(char *input_buffer,
+ ssize_t buffer_size,
+ struct intel_dp *intel_dp)
+{
+ int status = 0;
+ char *lines[MAX_DP_CONFIG_LINE_COUNT];
+ int i = 0;
+ struct dp_config parms[DP_PARAMETER_COUNT];
+ int line_count = 0;
+ char *buffer = input_buffer;
+ enum dp_config_param parm_type;
+ unsigned long parm_value;
+
+ line_count = tokenize_dp_config(buffer, lines);
+
+ if (line_count == 0) {
+ DRM_DEBUG_DRIVER("No lines to process\n");
+ return 0;
+ }
+
+ for (i = 0; i < line_count; i += 2) {
+ parm_type = displayport_get_config_param_type(lines[i]);
+ if (parm_type != DP_CONFIG_PARAM_INVALID) {
+ status = value_for_config_param(parm_type,
+ lines[i+1],
+ &parm_value);
+ if (status == 0) {
+ parms[parm_type].type = parm_type;
+ parms[parm_type].value = parm_value;
+ }
+ }
+ }
+
+ if (parms[DP_CONFIG_PARAM_LINK_RATE].value == 0x06 ||
+ parms[DP_CONFIG_PARAM_LINK_RATE].value == 0x0a ||
+ parms[DP_CONFIG_PARAM_LINK_RATE].value == 0x14) {
+ intel_dp->compliance_config.link_rate =
+ parms[DP_CONFIG_PARAM_LINK_RATE].value;
+ } else
+ return -EINVAL;
+
+ if (parms[DP_CONFIG_PARAM_LANE_COUNT].value == 0x01 ||
+ parms[DP_CONFIG_PARAM_LANE_COUNT].value == 0x02 ||
+ parms[DP_CONFIG_PARAM_LANE_COUNT].value == 0x04) {
+ intel_dp->compliance_config.lane_count =
+ parms[DP_CONFIG_PARAM_LANE_COUNT].value;
+ } else
+ return -EINVAL;
+
+ if (parms[DP_CONFIG_PARAM_VOLTAGE_SWING].value <= 0x03 &&
+ parms[DP_CONFIG_PARAM_VOLTAGE_SWING].value >= 0x00) {
+ intel_dp->compliance_config.vswing_level =
+ parms[DP_CONFIG_PARAM_VOLTAGE_SWING].value;
+ } else
+ return -EINVAL;
+
+ if (parms[DP_CONFIG_PARAM_PREEMPHASIS].value <= 0x03 &&
+ parms[DP_CONFIG_PARAM_PREEMPHASIS].value >= 0x00) {
+ intel_dp->compliance_config.preemp_level =
+ parms[DP_CONFIG_PARAM_PREEMPHASIS].value;
+ } else
+ return -EINVAL;
+
+ if (parms[DP_CONFIG_PARAM_BPP].value == 18 ||
+ parms[DP_CONFIG_PARAM_BPP].value == 24 ||
+ parms[DP_CONFIG_PARAM_BPP].value == 30 ||
+ parms[DP_CONFIG_PARAM_BPP].value == 36) {
+ intel_dp->compliance_config.bits_per_pixel =
+ parms[DP_CONFIG_PARAM_PREEMPHASIS].value;
+ } else
+ return -EINVAL;
+
+ if (parms[DP_CONFIG_PARAM_HRES].value > 0 &&
+ parms[DP_CONFIG_PARAM_HRES].value <= 8192) {
+ intel_dp->compliance_config.hres =
+ parms[DP_CONFIG_PARAM_HRES].value;
+ } else
+ return -EINVAL;
+
+ if (parms[DP_CONFIG_PARAM_VRES].value > 0 &&
+ parms[DP_CONFIG_PARAM_VRES].value <= 8192) {
+ intel_dp->compliance_config.vres =
+ parms[DP_CONFIG_PARAM_VRES].value;
+ } else
+ return -EINVAL;
+
+ return status;
+}
+
static int displayport_config_ctl_show(struct seq_file *m, void *data)
{
struct drm_device *dev = m->private;
--
1.9.1