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.
Changes in v2: - Added VID_MODE_VPG_MODE - Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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; +} + +int 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 +1052,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
Hello Angelo,
Tested OK on STM32F769i-DISCO, DSI v1.30, on next-20200406. I guess there is no horizontal for BER.
Regards, Adrian
On Mon, Apr 6, 2020 at 4:49 PM Angelo Ribeiro Angelo.Ribeiro@synopsys.com 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.
Changes in v2:
- Added VID_MODE_VPG_MODE
- Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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
Tested-by: Adrian Pop pop.adrian61@gmail.com Tested OK on STM32F769i-DISCO, DSI v1.30, on next-20200406.
On Mon, Apr 6, 2020 at 8:45 PM Adrian Pop pop.adrian61@gmail.com wrote:
Hello Angelo,
Tested OK on STM32F769i-DISCO, DSI v1.30, on next-20200406. I guess there is no horizontal for BER.
Regards, Adrian
On Mon, Apr 6, 2020 at 4:49 PM Angelo Ribeiro Angelo.Ribeiro@synopsys.com 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.
Changes in v2:
- Added VID_MODE_VPG_MODE
- Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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
Hi Adrian,
-----Original Message----- From: Adrian Pop pop.adrian61@gmail.com Sent: Tuesday, April 7, 2020 7:58 AM To: Angelo Ribeiro angelor@synopsys.com Cc: yannick.fertre@st.com; philippe.cornu@st.com; benjamin.gaignard@st.com; airlied@linux.ie; Daniel Vetter daniel@ffwll.ch; mcoquelin.stm32@gmail.com; alexandre.torgue@st.com; dri-devel@lists.freedesktop.org; linux-stm32@st-md-mailman.stormreply.com; linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org; Gustavo Pimentel gustavo@synopsys.com; Joao Pinto jpinto@synopsys.com; Jose Abreu joabreu@synopsys.com Subject: Re: [PATCH v2] drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs
Tested-by: Adrian Pop pop.adrian61@gmail.com Tested OK on STM32F769i-DISCO, DSI v1.30, on next-20200406.
On Mon, Apr 6, 2020 at 8:45 PM Adrian Pop pop.adrian61@gmail.com wrote:
Hello Angelo,
Tested OK on STM32F769i-DISCO, DSI v1.30, on next-20200406. I guess there is no horizontal for BER.
Yes, there is no horizontal for BER. Thank you for testing the patch.
Regards, Adrian
On Mon, Apr 6, 2020 at 4:49 PM Angelo Ribeiro Angelo.Ribeiro@synopsys.com 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.
Changes in v2:
- Added VID_MODE_VPG_MODE
- Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98
++++++++++++++++++++++++---
1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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 +982,68 @@ static const struct drm_bridge_funcs
dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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
Thanks, Angelo
Hello Angelo, thanks for the patch. Tested-by: Yannick Fertre yannick.fertre@st.com Tested OK on STM32MP1-DISCO, DSI v1.31
Best regards
On 4/6/20 3:49 PM, Angelo Ribeiro 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.
Changes in v2:
- Added VID_MODE_VPG_MODE
- Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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;
} #endif /* CONFIG_DEBUG_FS */val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
@@ -961,6 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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
Hi,
Is this patch good to go? @daniel@ffwll.ch, @Philippe CORNU
Was already tested by @Yannick FERTRE and @Adrian Pop on https://lkml.org/lkml/2020/4/6/691 .
Thanks, Angelo
From: Yannick FERTRE yannick.fertre@st.com Date: Wed, Jun 24, 2020 at 16:35:04
Hello Angelo, thanks for the patch. Tested-by: Yannick Fertre yannick.fertre@st.com Tested OK on STM32MP1-DISCO, DSI v1.31
Best regards
On 4/6/20 3:49 PM, Angelo Ribeiro 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.
Changes in v2:
- Added VID_MODE_VPG_MODE
- Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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;
} #endif /* CONFIG_DEBUG_FS */val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
@@ -961,6 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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
dri-devel mailing list dri-devel@lists.freedesktop.org https://urldefense.com/v3/__https://lists.freedesktop.org/mailman/listinfo/d...
Hi,
Le 08/07/2020 à 19:08, Angelo Ribeiro a écrit :
Hi,
Is this patch good to go? @daniel@ffwll.ch, @Philippe CORNU
Was already tested by @Yannick FERTRE and @Adrian Pop on https://lkml.org/lkml/2020/4/6/691 .
It would be great to have a review or an ack before applying.
Neil
Thanks, Angelo
From: Yannick FERTRE yannick.fertre@st.com Date: Wed, Jun 24, 2020 at 16:35:04
Hello Angelo, thanks for the patch. Tested-by: Yannick Fertre yannick.fertre@st.com Tested OK on STM32MP1-DISCO, DSI v1.31
Best regards
On 4/6/20 3:49 PM, Angelo Ribeiro 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.
Changes in v2:
- Added VID_MODE_VPG_MODE
- Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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;
} #endif /* CONFIG_DEBUG_FS */val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
@@ -961,6 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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
dri-devel mailing list dri-devel@lists.freedesktop.org https://urldefense.com/v3/__https://lists.freedesktop.org/mailman/listinfo/d...
linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On 7/8/20 7:08 PM, Angelo Ribeiro wrote:
Hi,
Is this patch good to go? @daniel@ffwll.ch, @Philippe CORNU
Was already tested by @Yannick FERTRE and @Adrian Pop on https://lkml.org/lkml/2020/4/6/691 .
Thanks, Angelo
From: Yannick FERTRE yannick.fertre@st.com Date: Wed, Jun 24, 2020 at 16:35:04
Hello Angelo, thanks for the patch. Tested-by: Yannick Fertre yannick.fertre@st.com Tested OK on STM32MP1-DISCO, DSI v1.31
Best regards
On 4/6/20 3:49 PM, Angelo Ribeiro 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.
Changes in v2: - Added VID_MODE_VPG_MODE - Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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;
} #endif /* CONFIG_DEBUG_FS */val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
@@ -961,6 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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);
Hi Angelo, And thank you for your patch. Could you please explain why you have "so many lines" for adding the ber pattern, instead of these 4 lines :
+#define VID_MODE_VPG_MODE BIT(20) +bool vpg_ber_pattern; +val |= dsi->vpg_ber_pattern ? VID_MODE_VPG_MODE : 0; +debugfs_create_bool("vpg_ber_pattern", 0660, dsi->debugfs, &dsi->vpg_ber_pattern);
Many thanks Philippe :-)
}
static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) { debugfs_remove_recursive(dsi->debugfs);
kfree(dsi->debugfs_vpg); }
#else
dri-devel mailing list dri-devel@lists.freedesktop.org https://urldefense.com/v3/__https://lists.freedesktop.org/mailman/listinfo/d...
Hi Philippe,
From: Philippe CORNU philippe.cornu@st.com Date: Thu, Jul 09, 2020 at 08:56:10
On 7/8/20 7:08 PM, Angelo Ribeiro wrote:
Hi,
Is this patch good to go? @daniel@ffwll.ch, @Philippe CORNU
Was already tested by @Yannick FERTRE and @Adrian Pop on https://urldefense.com/v3/__https://lkml.org/lkml/2020/4/6/691__;!!A4F2R9G_p... .
Thanks, Angelo
From: Yannick FERTRE yannick.fertre@st.com Date: Wed, Jun 24, 2020 at 16:35:04
Hello Angelo, thanks for the patch. Tested-by: Yannick Fertre yannick.fertre@st.com Tested OK on STM32MP1-DISCO, DSI v1.31
Best regards
On 4/6/20 3:49 PM, Angelo Ribeiro 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.
Changes in v2: - Added VID_MODE_VPG_MODE - Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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;
} #endif /* CONFIG_DEBUG_FS */val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
@@ -961,6 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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);
Hi Angelo, And thank you for your patch. Could you please explain why you have "so many lines" for adding the ber pattern, instead of these 4 lines :
+#define VID_MODE_VPG_MODE BIT(20) +bool vpg_ber_pattern; +val |= dsi->vpg_ber_pattern ? VID_MODE_VPG_MODE : 0; +debugfs_create_bool("vpg_ber_pattern", 0660, dsi->debugfs, &dsi->vpg_ber_pattern);
Many thanks Philippe :-)
Thank you for the review.
With this implementation you only need to set the debugfs file to control the VPG. Since the internal VPG is used for debug purposes it eases the use during your development.
Thanks, Angelo
}
static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) { debugfs_remove_recursive(dsi->debugfs);
kfree(dsi->debugfs_vpg); }
#else
dri-devel mailing list dri-devel@lists.freedesktop.org https://urldefense.com/v3/__https://lists.freedesktop.org/mailman/listinfo/d...
dri-devel mailing list dri-devel@lists.freedesktop.org https://urldefense.com/v3/__https://lists.freedesktop.org/mailman/listinfo/d...
Hi,
On 06/04/2020 15:49, Angelo Ribeiro 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.
Changes in v2:
- Added VID_MODE_VPG_MODE
- Solved incompatible return type on __get and __set
Reported-by: kbuild test robot lkp@intel.com Reported-by: Adrian Pop pop.adrian61@gmail.com Cc: Gustavo Pimentel gustavo.pimentel@synopsys.com Cc: Joao Pinto jpinto@synopsys.com Cc: Jose Abreu jose.abreu@synopsys.com Signed-off-by: Angelo Ribeiro angelo.ribeiro@synopsys.com
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- 1 file changed, 90 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..9de3645 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -91,6 +91,7 @@ #define VID_MODE_TYPE_BURST 0x2 #define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_VPG_ENABLE BIT(16) +#define VID_MODE_VPG_MODE BIT(20) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c @@ -221,6 +222,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 +254,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 +549,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 +982,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS
+int 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;
+}
+int 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 +1052,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
Acked-by: Neil Armstrong narmstrong@baylibre.com
Applying to drm-misc-next
Thanks, Neil
dri-devel@lists.freedesktop.org