Commit 8015bee0 authored by Jouni Högander's avatar Jouni Högander
Browse files

drm/i915/display: Add framework to add parameters specific to display



Currently all module parameters are handled by i915_param.c/h. This
is a problem for display parameters when Xe driver is used. Add
a mechanism to add parameters specific to the display. This is mainly
copied from i915_[debugfs]_params.[ch]. Parameters are not yet moved. This
is done by subsequent patches.

v2:
  - Drop unused predefinition (dentry)
  - Clarify need for empty INTEL_DISPLAY_PARAMS_FOR_EACH in comment

Signed-off-by: default avatarJouni Högander <jouni.hogander@intel.com>
Acked-by: default avatarJani Nikula <jani.nikula@intel.com>
Reviewed-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231024124109.384973-2-jouni.hogander@intel.com
parent bc725dc1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ i915-$(CONFIG_DEBUG_FS) += \
	i915_debugfs.o \
	i915_debugfs_params.o \
	display/intel_display_debugfs.o \
	display/intel_display_debugfs_params.o \
	display/intel_pipe_crc.o
i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o

@@ -257,6 +258,7 @@ i915-y += \
	display/intel_display.o \
	display/intel_display_driver.o \
	display/intel_display_irq.o \
	display/intel_display_params.o \
	display/intel_display_power.o \
	display/intel_display_power_map.o \
	display/intel_display_power_well.o \
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "intel_cdclk.h"
#include "intel_display_device.h"
#include "intel_display_limits.h"
#include "intel_display_params.h"
#include "intel_display_power.h"
#include "intel_dpll_mgr.h"
#include "intel_fbc.h"
@@ -517,6 +518,7 @@ struct intel_display {
	struct intel_hotplug hotplug;
	struct intel_opregion opregion;
	struct intel_overlay *overlay;
	struct intel_display_params params;
	struct intel_vbt_data vbt;
	struct intel_wm wm;
};
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "intel_de.h"
#include "intel_crtc_state_dump.h"
#include "intel_display_debugfs.h"
#include "intel_display_debugfs_params.h"
#include "intel_display_power.h"
#include "intel_display_power_well.h"
#include "intel_display_types.h"
@@ -1111,6 +1112,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
	intel_hpd_debugfs_register(i915);
	intel_psr_debugfs_register(i915);
	intel_wm_debugfs_register(i915);
	intel_display_debugfs_params(i915);
}

static int i915_panel_show(struct seq_file *m, void *data)
+176 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */

#include <linux/kernel.h>

#include <drm/drm_drv.h>

#include "intel_display_debugfs_params.h"
#include "i915_drv.h"
#include "intel_display_params.h"

/* int param */
static int intel_display_param_int_show(struct seq_file *m, void *data)
{
	int *value = m->private;

	seq_printf(m, "%d\n", *value);

	return 0;
}

static int intel_display_param_int_open(struct inode *inode, struct file *file)
{
	return single_open(file, intel_display_param_int_show, inode->i_private);
}

static ssize_t intel_display_param_int_write(struct file *file,
					     const char __user *ubuf, size_t len,
					     loff_t *offp)
{
	struct seq_file *m = file->private_data;
	int *value = m->private;
	int ret;

	ret = kstrtoint_from_user(ubuf, len, 0, value);
	if (ret) {
		/* support boolean values too */
		bool b;

		ret = kstrtobool_from_user(ubuf, len, &b);
		if (!ret)
			*value = b;
	}

	return ret ?: len;
}

static const struct file_operations intel_display_param_int_fops = {
	.owner = THIS_MODULE,
	.open = intel_display_param_int_open,
	.read = seq_read,
	.write = intel_display_param_int_write,
	.llseek = default_llseek,
	.release = single_release,
};

static const struct file_operations intel_display_param_int_fops_ro = {
	.owner = THIS_MODULE,
	.open = intel_display_param_int_open,
	.read = seq_read,
	.llseek = default_llseek,
	.release = single_release,
};

/* unsigned int param */
static int intel_display_param_uint_show(struct seq_file *m, void *data)
{
	unsigned int *value = m->private;

	seq_printf(m, "%u\n", *value);

	return 0;
}

static int intel_display_param_uint_open(struct inode *inode, struct file *file)
{
	return single_open(file, intel_display_param_uint_show, inode->i_private);
}

static ssize_t intel_display_param_uint_write(struct file *file,
					      const char __user *ubuf, size_t len,
					      loff_t *offp)
{
	struct seq_file *m = file->private_data;
	unsigned int *value = m->private;
	int ret;

	ret = kstrtouint_from_user(ubuf, len, 0, value);
	if (ret) {
		/* support boolean values too */
		bool b;

		ret = kstrtobool_from_user(ubuf, len, &b);
		if (!ret)
			*value = b;
	}

	return ret ?: len;
}

static const struct file_operations intel_display_param_uint_fops = {
	.owner = THIS_MODULE,
	.open = intel_display_param_uint_open,
	.read = seq_read,
	.write = intel_display_param_uint_write,
	.llseek = default_llseek,
	.release = single_release,
};

static const struct file_operations intel_display_param_uint_fops_ro = {
	.owner = THIS_MODULE,
	.open = intel_display_param_uint_open,
	.read = seq_read,
	.llseek = default_llseek,
	.release = single_release,
};

#define RO(mode) (((mode) & 0222) == 0)

__maybe_unused static struct dentry *
intel_display_debugfs_create_int(const char *name, umode_t mode,
			struct dentry *parent, int *value)
{
	return debugfs_create_file_unsafe(name, mode, parent, value,
					  RO(mode) ? &intel_display_param_int_fops_ro :
					  &intel_display_param_int_fops);
}

__maybe_unused static struct dentry *
intel_display_debugfs_create_uint(const char *name, umode_t mode,
			 struct dentry *parent, unsigned int *value)
{
	return debugfs_create_file_unsafe(name, mode, parent, value,
					  RO(mode) ? &intel_display_param_uint_fops_ro :
					  &intel_display_param_uint_fops);
}

#define _intel_display_param_create_file(parent, name, mode, valp)	\
	do {								\
		if (mode)						\
			_Generic(valp,					\
				 bool * : debugfs_create_bool,		\
				 int * : intel_display_debugfs_create_int, \
				 unsigned int * : intel_display_debugfs_create_uint, \
				 unsigned long * : debugfs_create_ulong, \
				 char ** : debugfs_create_str) \
				(name, mode, parent, valp);		\
	} while (0)

/* add a subdirectory with files for each intel display param */
void intel_display_debugfs_params(struct drm_i915_private *i915)
{
	struct drm_minor *minor = i915->drm.primary;
	struct dentry *dir;
	char dirname[16];

	snprintf(dirname, sizeof(dirname), "%s_params", i915->drm.driver->name);
	dir = debugfs_lookup(dirname, minor->debugfs_root);
	if (!dir)
		dir = debugfs_create_dir(dirname, minor->debugfs_root);
	if (IS_ERR(dir))
		return;

	/*
	 * Note: We could create files for params needing special handling
	 * here. Set mode in params to 0 to skip the generic create file, or
	 * just let the generic create file fail silently with -EEXIST.
	 */

#define REGISTER(T, x, unused, mode, ...) _intel_display_param_create_file( \
		dir, #x, mode, &i915->display.params.x);
	INTEL_DISPLAY_PARAMS_FOR_EACH(REGISTER);
#undef REGISTER
}
+13 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2023 Intel Corporation
 */

#ifndef __INTEL_DISPLAY_DEBUGFS_PARAMS__
#define __INTEL_DISPLAY_DEBUGFS_PARAMS__

struct drm_i915_private;

void intel_display_debugfs_params(struct drm_i915_private *i915);

#endif /* __INTEL_DISPLAY_DEBUGFS_PARAMS__ */
Loading