2020-04-03 15:38:36

by Angelo Ribeiro

[permalink] [raw]
Subject: [PATCH] drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs

Add support for the video pattern generator (VPG) BER pattern mode and
configuration in runtime.

This enables using the debugfs interface to manipulate the VPG after
the pipeline is set.
Also, enables the usage of the VPG BER pattern.

Cc: Gustavo Pimentel <[email protected]>
Cc: Joao Pinto <[email protected]>
Cc: Jose Abreu <[email protected]>
Signed-off-by: Angelo Ribeiro <[email protected]>
---
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 97 ++++++++++++++++++++++++---
1 file changed, 89 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index b18351b..512c922 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -221,6 +221,21 @@
#define PHY_STATUS_TIMEOUT_US 10000
#define CMD_PKT_STATUS_TIMEOUT_US 20000

+#ifdef CONFIG_DEBUG_FS
+#define VPG_DEFS(name, dsi) \
+ ((void __force *)&((*dsi).vpg_defs.name))
+
+#define REGISTER(name, mask, dsi) \
+ { #name, VPG_DEFS(name, dsi), mask, dsi }
+
+struct debugfs_entries {
+ const char *name;
+ bool *reg;
+ u32 mask;
+ struct dw_mipi_dsi *dsi;
+};
+#endif /* CONFIG_DEBUG_FS */
+
struct dw_mipi_dsi {
struct drm_bridge bridge;
struct mipi_dsi_host dsi_host;
@@ -238,9 +253,12 @@ struct dw_mipi_dsi {

#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
-
- bool vpg;
- bool vpg_horizontal;
+ struct debugfs_entries *debugfs_vpg;
+ struct {
+ bool vpg;
+ bool vpg_horizontal;
+ bool vpg_ber_pattern;
+ } vpg_defs;
#endif /* CONFIG_DEBUG_FS */

struct dw_mipi_dsi *master; /* dual-dsi master ptr */
@@ -530,9 +548,11 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;

#ifdef CONFIG_DEBUG_FS
- if (dsi->vpg) {
+ if (dsi->vpg_defs.vpg) {
val |= VID_MODE_VPG_ENABLE;
- val |= dsi->vpg_horizontal ? VID_MODE_VPG_HORIZONTAL : 0;
+ val |= dsi->vpg_defs.vpg_horizontal ?
+ VID_MODE_VPG_HORIZONTAL : 0;
+ val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
}
#endif /* CONFIG_DEBUG_FS */

@@ -961,6 +981,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {

#ifdef CONFIG_DEBUG_FS

+ssize_t dw_mipi_dsi_debugfs_write(void *data, u64 val)
+{
+ struct debugfs_entries *vpg = data;
+ struct dw_mipi_dsi *dsi;
+ u32 mode_cfg;
+
+ if (!vpg)
+ return -ENODEV;
+
+ dsi = vpg->dsi;
+
+ *vpg->reg = (bool)val;
+
+ mode_cfg = dsi_read(dsi, DSI_VID_MODE_CFG);
+
+ if (*vpg->reg)
+ mode_cfg |= vpg->mask;
+ else
+ mode_cfg &= ~vpg->mask;
+
+ dsi_write(dsi, DSI_VID_MODE_CFG, mode_cfg);
+
+ return 0;
+}
+
+ssize_t dw_mipi_dsi_debugfs_show(void *data, u64 *val)
+{
+ struct debugfs_entries *vpg = data;
+
+ if (!vpg)
+ return -ENODEV;
+
+ *val = *vpg->reg;
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_mipi_dsi_debugfs_show,
+ dw_mipi_dsi_debugfs_write, "%llu\n");
+
+static void debugfs_create_files(void *data)
+{
+ struct dw_mipi_dsi *dsi = data;
+ struct debugfs_entries debugfs[] = {
+ REGISTER(vpg, VID_MODE_VPG_ENABLE, dsi),
+ REGISTER(vpg_horizontal, VID_MODE_VPG_HORIZONTAL, dsi),
+ REGISTER(vpg_ber_pattern, VID_MODE_VPG_MODE, dsi),
+ };
+ int i;
+
+ dsi->debugfs_vpg = kmalloc(sizeof(debugfs), GFP_KERNEL);
+ if (!dsi->debugfs_vpg)
+ return;
+
+ memcpy(dsi->debugfs_vpg, debugfs, sizeof(debugfs));
+
+ for (i = 0; i < ARRAY_SIZE(debugfs); i++)
+ debugfs_create_file(dsi->debugfs_vpg[i].name, 0644,
+ dsi->debugfs, &dsi->debugfs_vpg[i],
+ &fops_x32);
+}
+
static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
{
dsi->debugfs = debugfs_create_dir(dev_name(dsi->dev), NULL);
@@ -969,14 +1051,13 @@ static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
return;
}

- debugfs_create_bool("vpg", 0660, dsi->debugfs, &dsi->vpg);
- debugfs_create_bool("vpg_horizontal", 0660, dsi->debugfs,
- &dsi->vpg_horizontal);
+ debugfs_create_files(dsi);
}

static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi)
{
debugfs_remove_recursive(dsi->debugfs);
+ kfree(dsi->debugfs_vpg);
}

#else
--
2.7.4


2020-04-04 10:57:34

by Adrian Pop

[permalink] [raw]
Subject: Re: [PATCH] drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs

Hello Angelo,

I get a compile error: error: ‘VID_MODE_VPG_MODE’ undeclared. I am
quite new to the mailing list, maybe I misapplied the patch.

Regards,
Adrian


On Fri, Apr 3, 2020 at 6:37 PM Angelo Ribeiro
<[email protected]> wrote:
>
> Add support for the video pattern generator (VPG) BER pattern mode and
> configuration in runtime.
>
> This enables using the debugfs interface to manipulate the VPG after
> the pipeline is set.
> Also, enables the usage of the VPG BER pattern.
>
> Cc: Gustavo Pimentel <[email protected]>
> Cc: Joao Pinto <[email protected]>
> Cc: Jose Abreu <[email protected]>
> Signed-off-by: Angelo Ribeiro <[email protected]>
> ---
> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 97 ++++++++++++++++++++++++---
> 1 file changed, 89 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index b18351b..512c922 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -221,6 +221,21 @@
> #define PHY_STATUS_TIMEOUT_US 10000
> #define CMD_PKT_STATUS_TIMEOUT_US 20000
>
> +#ifdef CONFIG_DEBUG_FS
> +#define VPG_DEFS(name, dsi) \
> + ((void __force *)&((*dsi).vpg_defs.name))
> +
> +#define REGISTER(name, mask, dsi) \
> + { #name, VPG_DEFS(name, dsi), mask, dsi }
> +
> +struct debugfs_entries {
> + const char *name;
> + bool *reg;
> + u32 mask;
> + struct dw_mipi_dsi *dsi;
> +};
> +#endif /* CONFIG_DEBUG_FS */
> +
> struct dw_mipi_dsi {
> struct drm_bridge bridge;
> struct mipi_dsi_host dsi_host;
> @@ -238,9 +253,12 @@ struct dw_mipi_dsi {
>
> #ifdef CONFIG_DEBUG_FS
> struct dentry *debugfs;
> -
> - bool vpg;
> - bool vpg_horizontal;
> + struct debugfs_entries *debugfs_vpg;
> + struct {
> + bool vpg;
> + bool vpg_horizontal;
> + bool vpg_ber_pattern;
> + } vpg_defs;
> #endif /* CONFIG_DEBUG_FS */
>
> struct dw_mipi_dsi *master; /* dual-dsi master ptr */
> @@ -530,9 +548,11 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
> val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
>
> #ifdef CONFIG_DEBUG_FS
> - if (dsi->vpg) {
> + if (dsi->vpg_defs.vpg) {
> val |= VID_MODE_VPG_ENABLE;
> - val |= dsi->vpg_horizontal ? VID_MODE_VPG_HORIZONTAL : 0;
> + val |= dsi->vpg_defs.vpg_horizontal ?
> + VID_MODE_VPG_HORIZONTAL : 0;
> + val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
> }
> #endif /* CONFIG_DEBUG_FS */
>
> @@ -961,6 +981,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
>
> #ifdef CONFIG_DEBUG_FS
>
> +ssize_t dw_mipi_dsi_debugfs_write(void *data, u64 val)
> +{
> + struct debugfs_entries *vpg = data;
> + struct dw_mipi_dsi *dsi;
> + u32 mode_cfg;
> +
> + if (!vpg)
> + return -ENODEV;
> +
> + dsi = vpg->dsi;
> +
> + *vpg->reg = (bool)val;
> +
> + mode_cfg = dsi_read(dsi, DSI_VID_MODE_CFG);
> +
> + if (*vpg->reg)
> + mode_cfg |= vpg->mask;
> + else
> + mode_cfg &= ~vpg->mask;
> +
> + dsi_write(dsi, DSI_VID_MODE_CFG, mode_cfg);
> +
> + return 0;
> +}
> +
> +ssize_t dw_mipi_dsi_debugfs_show(void *data, u64 *val)
> +{
> + struct debugfs_entries *vpg = data;
> +
> + if (!vpg)
> + return -ENODEV;
> +
> + *val = *vpg->reg;
> +
> + return 0;
> +}
> +
> +DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_mipi_dsi_debugfs_show,
> + dw_mipi_dsi_debugfs_write, "%llu\n");
> +
> +static void debugfs_create_files(void *data)
> +{
> + struct dw_mipi_dsi *dsi = data;
> + struct debugfs_entries debugfs[] = {
> + REGISTER(vpg, VID_MODE_VPG_ENABLE, dsi),
> + REGISTER(vpg_horizontal, VID_MODE_VPG_HORIZONTAL, dsi),
> + REGISTER(vpg_ber_pattern, VID_MODE_VPG_MODE, dsi),
> + };
> + int i;
> +
> + dsi->debugfs_vpg = kmalloc(sizeof(debugfs), GFP_KERNEL);
> + if (!dsi->debugfs_vpg)
> + return;
> +
> + memcpy(dsi->debugfs_vpg, debugfs, sizeof(debugfs));
> +
> + for (i = 0; i < ARRAY_SIZE(debugfs); i++)
> + debugfs_create_file(dsi->debugfs_vpg[i].name, 0644,
> + dsi->debugfs, &dsi->debugfs_vpg[i],
> + &fops_x32);
> +}
> +
> static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
> {
> dsi->debugfs = debugfs_create_dir(dev_name(dsi->dev), NULL);
> @@ -969,14 +1051,13 @@ static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
> return;
> }
>
> - debugfs_create_bool("vpg", 0660, dsi->debugfs, &dsi->vpg);
> - debugfs_create_bool("vpg_horizontal", 0660, dsi->debugfs,
> - &dsi->vpg_horizontal);
> + debugfs_create_files(dsi);
> }
>
> static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi)
> {
> debugfs_remove_recursive(dsi->debugfs);
> + kfree(dsi->debugfs_vpg);
> }
>
> #else
> --
> 2.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

2020-04-04 23:39:37

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs

Hi Angelo,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.6 next-20200404]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/Angelo-Ribeiro/drm-bridge-dw-mipi-dsi-c-Add-VPG-runtime-config-through-debugfs/20200405-032129
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 83eb69f3b80f7cf2ca6357fb9c23adc48632a0e3
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=9.3.0 make.cross ARCH=arm64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <[email protected]>

All errors (new ones prefixed by >>):

drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c: In function 'dw_mipi_dsi_video_mode_config':
>> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:555:42: error: 'VID_MODE_VPG_MODE' undeclared (first use in this function); did you mean 'VID_MODE_VPG_ENABLE'?
555 | val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
| ^~~~~~~~~~~~~~~~~
| VID_MODE_VPG_ENABLE
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:555:42: note: each undeclared identifier is reported only once for each function it appears in
In file included from drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:13:
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c: In function 'fops_x32_open':
>> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:1024:36: error: passing argument 3 of 'simple_attr_open' from incompatible pointer type [-Werror=incompatible-pointer-types]
1024 | DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_mipi_dsi_debugfs_show,
| ^~~~~~~~~~~~~~~~~~~~~~~~
| |
| ssize_t (*)(void *, u64 *) {aka long int (*)(void *, long long unsigned int *)}
include/linux/debugfs.h:47:39: note: in definition of macro 'DEFINE_DEBUGFS_ATTRIBUTE'
47 | return simple_attr_open(inode, file, __get, __set, __fmt); \
| ^~~~~
In file included from include/linux/debugfs.h:15,
from drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:13:
include/linux/fs.h:3529:14: note: expected 'int (*)(void *, u64 *)' {aka 'int (*)(void *, long long unsigned int *)'} but argument is of type 'ssize_t (*)(void *, u64 *)' {aka 'long int (*)(void *, long long unsigned int *)'}
3529 | int (*get)(void *, u64 *), int (*set)(void *, u64),
| ~~~~~~^~~~~~~~~~~~~~~~~~~
In file included from drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:13:
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:1025:5: error: passing argument 4 of 'simple_attr_open' from incompatible pointer type [-Werror=incompatible-pointer-types]
1025 | dw_mipi_dsi_debugfs_write, "%llu\n");
| ^~~~~~~~~~~~~~~~~~~~~~~~~
| |
| ssize_t (*)(void *, u64) {aka long int (*)(void *, long long unsigned int)}
include/linux/debugfs.h:47:46: note: in definition of macro 'DEFINE_DEBUGFS_ATTRIBUTE'
47 | return simple_attr_open(inode, file, __get, __set, __fmt); \
| ^~~~~
In file included from include/linux/debugfs.h:15,
from drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:13:
include/linux/fs.h:3529:41: note: expected 'int (*)(void *, u64)' {aka 'int (*)(void *, long long unsigned int)'} but argument is of type 'ssize_t (*)(void *, u64)' {aka 'long int (*)(void *, long long unsigned int)'}
3529 | int (*get)(void *, u64 *), int (*set)(void *, u64),
| ~~~~~~^~~~~~~~~~~~~~~~~
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c: In function 'debugfs_create_files':
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:1033:29: error: 'VID_MODE_VPG_MODE' undeclared (first use in this function); did you mean 'VID_MODE_VPG_ENABLE'?
1033 | REGISTER(vpg_ber_pattern, VID_MODE_VPG_MODE, dsi),
| ^~~~~~~~~~~~~~~~~
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c:229:32: note: in definition of macro 'REGISTER'
229 | { #name, VPG_DEFS(name, dsi), mask, dsi }
| ^~~~
cc1: some warnings being treated as errors

vim +555 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c

531
532 static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
533 {
534 u32 val;
535
536 /*
537 * TODO dw drv improvements
538 * enabling low power is panel-dependent, we should use the
539 * panel configuration here...
540 */
541 val = ENABLE_LOW_POWER;
542
543 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
544 val |= VID_MODE_TYPE_BURST;
545 else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
546 val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
547 else
548 val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
549
550 #ifdef CONFIG_DEBUG_FS
551 if (dsi->vpg_defs.vpg) {
552 val |= VID_MODE_VPG_ENABLE;
553 val |= dsi->vpg_defs.vpg_horizontal ?
554 VID_MODE_VPG_HORIZONTAL : 0;
> 555 val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
556 }
557 #endif /* CONFIG_DEBUG_FS */
558
559 dsi_write(dsi, DSI_VID_MODE_CFG, val);
560 }
561

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (5.99 kB)
.config.gz (47.82 kB)
Download all attachments

2020-04-06 08:27:20

by Angelo Ribeiro

[permalink] [raw]
Subject: RE: [PATCH] drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs

Hi Adrian,

You are right!

Thanks for the help,
Angelo Ribeiro

From: Adrian Pop <[email protected]>
Date: Sat, Apr 04, 2020 at 11:56:11

> Hello Angelo,
>
> I get a compile error: error: ‘VID_MODE_VPG_MODE’ undeclared. I am
> quite new to the mailing list, maybe I misapplied the patch.
>
> Regards,
> Adrian
>
>
> On Fri, Apr 3, 2020 at 6:37 PM Angelo Ribeiro
> <[email protected]> wrote:
> >
> > Add support for the video pattern generator (VPG) BER pattern mode and
> > configuration in runtime.
> >
> > This enables using the debugfs interface to manipulate the VPG after
> > the pipeline is set.
> > Also, enables the usage of the VPG BER pattern.
> >
> > Cc: Gustavo Pimentel <[email protected]>
> > Cc: Joao Pinto <[email protected]>
> > Cc: Jose Abreu <[email protected]>
> > Signed-off-by: Angelo Ribeiro <[email protected]>
> > ---
> > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 97 ++++++++++++++++++++++++---
> > 1 file changed, 89 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > index b18351b..512c922 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > @@ -221,6 +221,21 @@
> > #define PHY_STATUS_TIMEOUT_US 10000
> > #define CMD_PKT_STATUS_TIMEOUT_US 20000
> >
> > +#ifdef CONFIG_DEBUG_FS
> > +#define VPG_DEFS(name, dsi) \
> > + ((void __force *)&((*dsi).vpg_defs.name))
> > +
> > +#define REGISTER(name, mask, dsi) \
> > + { #name, VPG_DEFS(name, dsi), mask, dsi }
> > +
> > +struct debugfs_entries {
> > + const char *name;
> > + bool *reg;
> > + u32 mask;
> > + struct dw_mipi_dsi *dsi;
> > +};
> > +#endif /* CONFIG_DEBUG_FS */
> > +
> > struct dw_mipi_dsi {
> > struct drm_bridge bridge;
> > struct mipi_dsi_host dsi_host;
> > @@ -238,9 +253,12 @@ struct dw_mipi_dsi {
> >
> > #ifdef CONFIG_DEBUG_FS
> > struct dentry *debugfs;
> > -
> > - bool vpg;
> > - bool vpg_horizontal;
> > + struct debugfs_entries *debugfs_vpg;
> > + struct {
> > + bool vpg;
> > + bool vpg_horizontal;
> > + bool vpg_ber_pattern;
> > + } vpg_defs;
> > #endif /* CONFIG_DEBUG_FS */
> >
> > struct dw_mipi_dsi *master; /* dual-dsi master ptr */
> > @@ -530,9 +548,11 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
> > val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
> >
> > #ifdef CONFIG_DEBUG_FS
> > - if (dsi->vpg) {
> > + if (dsi->vpg_defs.vpg) {
> > val |= VID_MODE_VPG_ENABLE;
> > - val |= dsi->vpg_horizontal ? VID_MODE_VPG_HORIZONTAL : 0;
> > + val |= dsi->vpg_defs.vpg_horizontal ?
> > + VID_MODE_VPG_HORIZONTAL : 0;
> > + val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
> > }
> > #endif /* CONFIG_DEBUG_FS */
> >
> > @@ -961,6 +981,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
> >
> > #ifdef CONFIG_DEBUG_FS
> >
> > +ssize_t dw_mipi_dsi_debugfs_write(void *data, u64 val)
> > +{
> > + struct debugfs_entries *vpg = data;
> > + struct dw_mipi_dsi *dsi;
> > + u32 mode_cfg;
> > +
> > + if (!vpg)
> > + return -ENODEV;
> > +
> > + dsi = vpg->dsi;
> > +
> > + *vpg->reg = (bool)val;
> > +
> > + mode_cfg = dsi_read(dsi, DSI_VID_MODE_CFG);
> > +
> > + if (*vpg->reg)
> > + mode_cfg |= vpg->mask;
> > + else
> > + mode_cfg &= ~vpg->mask;
> > +
> > + dsi_write(dsi, DSI_VID_MODE_CFG, mode_cfg);
> > +
> > + return 0;
> > +}
> > +
> > +ssize_t dw_mipi_dsi_debugfs_show(void *data, u64 *val)
> > +{
> > + struct debugfs_entries *vpg = data;
> > +
> > + if (!vpg)
> > + return -ENODEV;
> > +
> > + *val = *vpg->reg;
> > +
> > + return 0;
> > +}
> > +
> > +DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_mipi_dsi_debugfs_show,
> > + dw_mipi_dsi_debugfs_write, "%llu\n");
> > +
> > +static void debugfs_create_files(void *data)
> > +{
> > + struct dw_mipi_dsi *dsi = data;
> > + struct debugfs_entries debugfs[] = {
> > + REGISTER(vpg, VID_MODE_VPG_ENABLE, dsi),
> > + REGISTER(vpg_horizontal, VID_MODE_VPG_HORIZONTAL, dsi),
> > + REGISTER(vpg_ber_pattern, VID_MODE_VPG_MODE, dsi),
> > + };
> > + int i;
> > +
> > + dsi->debugfs_vpg = kmalloc(sizeof(debugfs), GFP_KERNEL);
> > + if (!dsi->debugfs_vpg)
> > + return;
> > +
> > + memcpy(dsi->debugfs_vpg, debugfs, sizeof(debugfs));
> > +
> > + for (i = 0; i < ARRAY_SIZE(debugfs); i++)
> > + debugfs_create_file(dsi->debugfs_vpg[i].name, 0644,
> > + dsi->debugfs, &dsi->debugfs_vpg[i],
> > + &fops_x32);
> > +}
> > +
> > static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
> > {
> > dsi->debugfs = debugfs_create_dir(dev_name(dsi->dev), NULL);
> > @@ -969,14 +1051,13 @@ static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
> > return;
> > }
> >
> > - debugfs_create_bool("vpg", 0660, dsi->debugfs, &dsi->vpg);
> > - debugfs_create_bool("vpg_horizontal", 0660, dsi->debugfs,
> > - &dsi->vpg_horizontal);
> > + debugfs_create_files(dsi);
> > }
> >
> > static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi)
> > {
> > debugfs_remove_recursive(dsi->debugfs);
> > + kfree(dsi->debugfs_vpg);
> > }
> >
> > #else
> > --
> > 2.7.4
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > [email protected]
> > https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.infradead.org_mailman_listinfo_linux-2Darm-2Dkernel&d=DwIFaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=-1lJkMi2j8IE8jpsNWO99o9zJFwyv1Mbjj3vJBR__i0&m=RVkzeuU9Ybr4sDavJDQlDQQNISVU7OADwa4H5svdMQI&s=Tz0W4ilX0ssp-RWLwnDjK_J0Ujjqj9TyjW4cVWK8TEM&e=