Skip to content

Commit 1deb6ed

Browse files
AngeloGioacchino Del RegnoChun-Kuang Hu
authored andcommitted
drm/mediatek: mtk_dpi: Add support for Pattern Generator in debugfs
This IP includes a Pattern Generator which is useful for debugging and testing purposes: add the relevant register and bits to the mtk_dpi_regs.h header, and implement support for it in mtk_dpi. Adding this required to introduce a .debugfs_init() callback for the DPI bridge, which creates a "dpi_test_pattern" file in the directory of the appropriate connector. The pattern generator can generate various internal patterns and this submission includes support for: - 256 or 1024 shades of gray in a Vertical or Horizontal Pattern - Vertical Color Bars - Frame border - Dot Moire This generator also supports filling the entire screen with one custom color, but support for that is not included in this commit. Enabling and disabling this generator can be done by sending a string to the dpi_test_pattern debugfs file; the pattern is expected to be formatted as follows: <enable (1) or disable (0)> <pattern number> where the pattern number can be a number from 0 to 7, excluding 5. Of course 5 is excluded because that activates custom color fill which, again, is not supported in this commit. Reviewed-by: CK Hu <[email protected]> Signed-off-by: AngeloGioacchino Del Regno <[email protected]> Link: https://patchwork.kernel.org/project/dri-devel/patch/[email protected]/ Signed-off-by: Chun-Kuang Hu <[email protected]>
1 parent 4104622 commit 1deb6ed

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

drivers/gpu/drm/mediatek/mtk_dpi.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
* Author: Jie Qiu <[email protected]>
55
*/
66

7+
#include <linux/bitfield.h>
78
#include <linux/clk.h>
89
#include <linux/component.h>
10+
#include <linux/debugfs.h>
911
#include <linux/interrupt.h>
1012
#include <linux/kernel.h>
1113
#include <linux/media-bus-format.h>
@@ -166,6 +168,18 @@ static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
166168
writel(tmp, dpi->regs + offset);
167169
}
168170

171+
static void mtk_dpi_test_pattern_en(struct mtk_dpi *dpi, u8 type, bool enable)
172+
{
173+
u32 val;
174+
175+
if (enable)
176+
val = FIELD_PREP(DPI_PAT_SEL, type) | DPI_PAT_EN;
177+
else
178+
val = 0;
179+
180+
mtk_dpi_mask(dpi, DPI_PATTERN0, val, DPI_PAT_SEL | DPI_PAT_EN);
181+
}
182+
169183
static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
170184
{
171185
mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
@@ -767,6 +781,99 @@ mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
767781
return MODE_OK;
768782
}
769783

784+
static int mtk_dpi_debug_tp_show(struct seq_file *m, void *arg)
785+
{
786+
struct mtk_dpi *dpi = m->private;
787+
bool en;
788+
u32 val;
789+
790+
if (!dpi)
791+
return -EINVAL;
792+
793+
val = readl(dpi->regs + DPI_PATTERN0);
794+
en = val & DPI_PAT_EN;
795+
val = FIELD_GET(DPI_PAT_SEL, val);
796+
797+
seq_printf(m, "DPI Test Pattern: %s\n", en ? "Enabled" : "Disabled");
798+
799+
if (en) {
800+
seq_printf(m, "Internal pattern %d: ", val);
801+
switch (val) {
802+
case 0:
803+
seq_puts(m, "256 Vertical Gray\n");
804+
break;
805+
case 1:
806+
seq_puts(m, "1024 Vertical Gray\n");
807+
break;
808+
case 2:
809+
seq_puts(m, "256 Horizontal Gray\n");
810+
break;
811+
case 3:
812+
seq_puts(m, "1024 Horizontal Gray\n");
813+
break;
814+
case 4:
815+
seq_puts(m, "Vertical Color bars\n");
816+
break;
817+
case 6:
818+
seq_puts(m, "Frame border\n");
819+
break;
820+
case 7:
821+
seq_puts(m, "Dot moire\n");
822+
break;
823+
default:
824+
seq_puts(m, "Invalid selection\n");
825+
break;
826+
}
827+
}
828+
829+
return 0;
830+
}
831+
832+
static ssize_t mtk_dpi_debug_tp_write(struct file *file, const char __user *ubuf,
833+
size_t len, loff_t *offp)
834+
{
835+
struct seq_file *m = file->private_data;
836+
u32 en, type;
837+
char buf[6];
838+
839+
if (!m || !m->private || *offp || len > sizeof(buf) - 1)
840+
return -EINVAL;
841+
842+
memset(buf, 0, sizeof(buf));
843+
if (copy_from_user(buf, ubuf, len))
844+
return -EFAULT;
845+
846+
if (sscanf(buf, "%u %u", &en, &type) != 2)
847+
return -EINVAL;
848+
849+
if (en < 0 || en > 1 || type < 0 || type > 7)
850+
return -EINVAL;
851+
852+
mtk_dpi_test_pattern_en((struct mtk_dpi *)m->private, type, en);
853+
return len;
854+
}
855+
856+
static int mtk_dpi_debug_tp_open(struct inode *inode, struct file *file)
857+
{
858+
return single_open(file, mtk_dpi_debug_tp_show, inode->i_private);
859+
}
860+
861+
static const struct file_operations mtk_dpi_debug_tp_fops = {
862+
.owner = THIS_MODULE,
863+
.open = mtk_dpi_debug_tp_open,
864+
.read = seq_read,
865+
.write = mtk_dpi_debug_tp_write,
866+
.llseek = seq_lseek,
867+
.release = single_release,
868+
};
869+
870+
static void mtk_dpi_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
871+
{
872+
struct mtk_dpi *dpi = bridge_to_dpi(bridge);
873+
874+
debugfs_create_file("dpi_test_pattern", 0640, root, dpi, &mtk_dpi_debug_tp_fops);
875+
}
876+
770877
static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
771878
.attach = mtk_dpi_bridge_attach,
772879
.mode_set = mtk_dpi_bridge_mode_set,
@@ -779,6 +886,7 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
779886
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
780887
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
781888
.atomic_reset = drm_atomic_helper_bridge_reset,
889+
.debugfs_init = mtk_dpi_debugfs_init,
782890
};
783891

784892
void mtk_dpi_start(struct device *dev)

drivers/gpu/drm/mediatek/mtk_dpi_regs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,8 @@
235235
#define MATRIX_SEL_RGB_TO_JPEG 0
236236
#define MATRIX_SEL_RGB_TO_BT601 2
237237

238+
#define DPI_PATTERN0 0xf00
239+
#define DPI_PAT_EN BIT(0)
240+
#define DPI_PAT_SEL GENMASK(6, 4)
241+
238242
#endif /* __MTK_DPI_REGS_H */

0 commit comments

Comments
 (0)