Commit e2435d69 authored by Angelo Ribeiro's avatar Angelo Ribeiro Committed by Neil Armstrong

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.

Changes in v2:
  - Added VID_MODE_VPG_MODE
  - Solved incompatible return type on __get and __set
Reported-by: default avatarkbuild test robot <lkp@intel.com>
Reported-by: default avatarAdrian Pop <pop.adrian61@gmail.com>
Signed-off-by: default avatarAngelo Ribeiro <angelo.ribeiro@synopsys.com>
Tested-by: default avatarYannick Fertre <yannick.fertre@st.com>
Tested-by: default avatarAdrian Pop <pop.adrian61@gmail.com>
Acked-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Jose Abreu <jose.abreu@synopsys.com>
Signed-off-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/a809feb7d7153a92e323416f744f1565e995da01.1586180592.git.angelo.ribeiro@synopsys.com
parent c6d94e37
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
#define VID_MODE_TYPE_MASK 0x3 #define VID_MODE_TYPE_MASK 0x3
#define ENABLE_LOW_POWER_CMD BIT(15) #define ENABLE_LOW_POWER_CMD BIT(15)
#define VID_MODE_VPG_ENABLE BIT(16) #define VID_MODE_VPG_ENABLE BIT(16)
#define VID_MODE_VPG_MODE BIT(20)
#define VID_MODE_VPG_HORIZONTAL BIT(24) #define VID_MODE_VPG_HORIZONTAL BIT(24)
#define DSI_VID_PKT_SIZE 0x3c #define DSI_VID_PKT_SIZE 0x3c
...@@ -221,6 +222,21 @@ ...@@ -221,6 +222,21 @@
#define PHY_STATUS_TIMEOUT_US 10000 #define PHY_STATUS_TIMEOUT_US 10000
#define CMD_PKT_STATUS_TIMEOUT_US 20000 #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 dw_mipi_dsi {
struct drm_bridge bridge; struct drm_bridge bridge;
struct mipi_dsi_host dsi_host; struct mipi_dsi_host dsi_host;
...@@ -238,9 +254,12 @@ struct dw_mipi_dsi { ...@@ -238,9 +254,12 @@ struct dw_mipi_dsi {
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *debugfs; struct dentry *debugfs;
struct debugfs_entries *debugfs_vpg;
struct {
bool vpg; bool vpg;
bool vpg_horizontal; bool vpg_horizontal;
bool vpg_ber_pattern;
} vpg_defs;
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */
struct dw_mipi_dsi *master; /* dual-dsi master ptr */ struct dw_mipi_dsi *master; /* dual-dsi master ptr */
...@@ -545,9 +564,11 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) ...@@ -545,9 +564,11 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS; val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
if (dsi->vpg) { if (dsi->vpg_defs.vpg) {
val |= VID_MODE_VPG_ENABLE; 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 */ #endif /* CONFIG_DEBUG_FS */
...@@ -978,6 +999,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { ...@@ -978,6 +999,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
#ifdef CONFIG_DEBUG_FS #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) static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
{ {
dsi->debugfs = debugfs_create_dir(dev_name(dsi->dev), NULL); dsi->debugfs = debugfs_create_dir(dev_name(dsi->dev), NULL);
...@@ -986,14 +1069,13 @@ static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi) ...@@ -986,14 +1069,13 @@ static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi)
return; return;
} }
debugfs_create_bool("vpg", 0660, dsi->debugfs, &dsi->vpg); debugfs_create_files(dsi);
debugfs_create_bool("vpg_horizontal", 0660, dsi->debugfs,
&dsi->vpg_horizontal);
} }
static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi)
{ {
debugfs_remove_recursive(dsi->debugfs); debugfs_remove_recursive(dsi->debugfs);
kfree(dsi->debugfs_vpg);
} }
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment