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: Jouni Högander <jouni.hogander@intel.com> Acked-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Luca Coelho <luciano.coelho@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231024124109.384973-2-jouni.hogander@intel.com
This commit is contained in:
parent
bc725dc1a8
commit
8015bee0bf
10 changed files with 311 additions and 0 deletions
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
drivers/gpu/drm/i915/display/intel_display_debugfs_params.c
Normal file
176
drivers/gpu/drm/i915/display/intel_display_debugfs_params.c
Normal file
|
@ -0,0 +1,176 @@
|
|||
// 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
drivers/gpu/drm/i915/display/intel_display_debugfs_params.h
Normal file
13
drivers/gpu/drm/i915/display/intel_display_debugfs_params.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* 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__ */
|
|
@ -12,6 +12,7 @@
|
|||
#include "intel_de.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_device.h"
|
||||
#include "intel_display_params.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
#include "intel_fbc.h"
|
||||
|
@ -937,6 +938,13 @@ void intel_display_device_probe(struct drm_i915_private *i915)
|
|||
DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
|
||||
DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
|
||||
}
|
||||
|
||||
intel_display_params_copy(&i915->display.params);
|
||||
}
|
||||
|
||||
void intel_display_device_remove(struct drm_i915_private *i915)
|
||||
{
|
||||
intel_display_params_free(&i915->display.params);
|
||||
}
|
||||
|
||||
static void __intel_display_device_info_runtime_init(struct drm_i915_private *i915)
|
||||
|
|
|
@ -161,6 +161,7 @@ struct intel_display_device_info {
|
|||
|
||||
bool intel_display_device_enabled(struct drm_i915_private *i915);
|
||||
void intel_display_device_probe(struct drm_i915_private *i915);
|
||||
void intel_display_device_remove(struct drm_i915_private *i915);
|
||||
void intel_display_device_info_runtime_init(struct drm_i915_private *i915);
|
||||
|
||||
void intel_display_device_info_print(const struct intel_display_device_info *info,
|
||||
|
|
71
drivers/gpu/drm/i915/display/intel_display_params.c
Normal file
71
drivers/gpu/drm/i915/display/intel_display_params.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "intel_display_params.h"
|
||||
#include "i915_drv.h"
|
||||
|
||||
#define intel_display_param_named(name, T, perm, desc) \
|
||||
module_param_named(name, intel_display_modparams.name, T, perm); \
|
||||
MODULE_PARM_DESC(name, desc)
|
||||
#define intel_display_param_named_unsafe(name, T, perm, desc) \
|
||||
module_param_named_unsafe(name, intel_display_modparams.name, T, perm); \
|
||||
MODULE_PARM_DESC(name, desc)
|
||||
|
||||
static struct intel_display_params intel_display_modparams __read_mostly = {
|
||||
#define MEMBER(T, member, value, ...) .member = (value),
|
||||
INTEL_DISPLAY_PARAMS_FOR_EACH(MEMBER)
|
||||
#undef MEMBER
|
||||
};
|
||||
/*
|
||||
* Note: As a rule, keep module parameter sysfs permissions read-only
|
||||
* 0400. Runtime changes are only supported through i915 debugfs.
|
||||
*
|
||||
* For any exceptions requiring write access and runtime changes through module
|
||||
* parameter sysfs, prevent debugfs file creation by setting the parameter's
|
||||
* debugfs mode to 0.
|
||||
*/
|
||||
|
||||
__maybe_unused static void _param_dup_charp(char **valp)
|
||||
{
|
||||
*valp = kstrdup(*valp ? *valp : "", GFP_ATOMIC);
|
||||
}
|
||||
|
||||
__maybe_unused static void _param_nop(void *valp)
|
||||
{
|
||||
}
|
||||
|
||||
#define _param_dup(valp) \
|
||||
_Generic(valp, \
|
||||
char ** : _param_dup_charp, \
|
||||
default : _param_nop) \
|
||||
(valp)
|
||||
|
||||
void intel_display_params_copy(struct intel_display_params *dest)
|
||||
{
|
||||
*dest = intel_display_modparams;
|
||||
#define DUP(T, x, ...) _param_dup(&dest->x);
|
||||
INTEL_DISPLAY_PARAMS_FOR_EACH(DUP);
|
||||
#undef DUP
|
||||
}
|
||||
|
||||
__maybe_unused static void _param_free_charp(char **valp)
|
||||
{
|
||||
kfree(*valp);
|
||||
*valp = NULL;
|
||||
}
|
||||
|
||||
#define _param_free(valp) \
|
||||
_Generic(valp, \
|
||||
char ** : _param_free_charp, \
|
||||
default : _param_nop) \
|
||||
(valp)
|
||||
|
||||
/* free the allocated members, *not* the passed in params itself */
|
||||
void intel_display_params_free(struct intel_display_params *params)
|
||||
{
|
||||
#define FREE(T, x, ...) _param_free(¶ms->x);
|
||||
INTEL_DISPLAY_PARAMS_FOR_EACH(FREE);
|
||||
#undef FREE
|
||||
}
|
34
drivers/gpu/drm/i915/display/intel_display_params.h
Normal file
34
drivers/gpu/drm/i915/display/intel_display_params.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _INTEL_DISPLAY_PARAMS_H_
|
||||
#define _INTEL_DISPLAY_PARAMS_H_
|
||||
|
||||
struct drm_printer;
|
||||
|
||||
/*
|
||||
* Invoke param, a function-like macro, for each intel display param, with
|
||||
* arguments:
|
||||
*
|
||||
* param(type, name, value, mode)
|
||||
*
|
||||
* type: parameter type, one of {bool, int, unsigned int, unsigned long, char *}
|
||||
* name: name of the parameter
|
||||
* value: initial/default value of the parameter
|
||||
* mode: debugfs file permissions, one of {0400, 0600, 0}, use 0 to not create
|
||||
* debugfs file
|
||||
*/
|
||||
#define INTEL_DISPLAY_PARAMS_FOR_EACH(param) /* empty define to avoid build failure */
|
||||
|
||||
#define MEMBER(T, member, ...) T member;
|
||||
struct intel_display_params {
|
||||
INTEL_DISPLAY_PARAMS_FOR_EACH(MEMBER);
|
||||
};
|
||||
#undef MEMBER
|
||||
|
||||
void intel_display_params_copy(struct intel_display_params *dest);
|
||||
void intel_display_params_free(struct intel_display_params *params);
|
||||
|
||||
#endif
|
|
@ -908,6 +908,8 @@ static void i915_driver_release(struct drm_device *dev)
|
|||
intel_runtime_pm_driver_release(rpm);
|
||||
|
||||
i915_driver_late_release(dev_priv);
|
||||
|
||||
intel_display_device_remove(dev_priv);
|
||||
}
|
||||
|
||||
static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
|
||||
|
|
Loading…
Add table
Reference in a new issue