Skip to content

Commit 1e19ec6

Browse files
committed
Merge tag 'drm-misc-fixes-2019-09-05' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
drm-misc-fixes for v5.3 final: - Make ingenic panel type DPI insteado f unknown. - Fixes for command line parser modes. Signed-off-by: Dave Airlie <[email protected]> From: Maarten Lankhorst <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 7610bb0 + 424c38a commit 1e19ec6

File tree

4 files changed

+187
-9
lines changed

4 files changed

+187
-9
lines changed

drivers/gpu/drm/drm_modes.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,7 @@ static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr,
14541454
}
14551455

14561456
static int drm_mode_parse_cmdline_extra(const char *str, int length,
1457+
bool freestanding,
14571458
const struct drm_connector *connector,
14581459
struct drm_cmdline_mode *mode)
14591460
{
@@ -1462,9 +1463,15 @@ static int drm_mode_parse_cmdline_extra(const char *str, int length,
14621463
for (i = 0; i < length; i++) {
14631464
switch (str[i]) {
14641465
case 'i':
1466+
if (freestanding)
1467+
return -EINVAL;
1468+
14651469
mode->interlace = true;
14661470
break;
14671471
case 'm':
1472+
if (freestanding)
1473+
return -EINVAL;
1474+
14681475
mode->margins = true;
14691476
break;
14701477
case 'D':
@@ -1542,6 +1549,7 @@ static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length,
15421549
if (extras) {
15431550
int ret = drm_mode_parse_cmdline_extra(end_ptr + i,
15441551
1,
1552+
false,
15451553
connector,
15461554
mode);
15471555
if (ret)
@@ -1669,6 +1677,22 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len,
16691677
return 0;
16701678
}
16711679

1680+
static const char *drm_named_modes_whitelist[] = {
1681+
"NTSC",
1682+
"PAL",
1683+
};
1684+
1685+
static bool drm_named_mode_is_in_whitelist(const char *mode, unsigned int size)
1686+
{
1687+
int i;
1688+
1689+
for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++)
1690+
if (!strncmp(mode, drm_named_modes_whitelist[i], size))
1691+
return true;
1692+
1693+
return false;
1694+
}
1695+
16721696
/**
16731697
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector
16741698
* @mode_option: optional per connector mode option
@@ -1725,16 +1749,30 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
17251749
* bunch of things:
17261750
* - We need to make sure that the first character (which
17271751
* would be our resolution in X) is a digit.
1728-
* - However, if the X resolution is missing, then we end up
1729-
* with something like x<yres>, with our first character
1730-
* being an alpha-numerical character, which would be
1731-
* considered a named mode.
1752+
* - If not, then it's either a named mode or a force on/off.
1753+
* To distinguish between the two, we need to run the
1754+
* extra parsing function, and if not, then we consider it
1755+
* a named mode.
17321756
*
17331757
* If this isn't enough, we should add more heuristics here,
17341758
* and matching unit-tests.
17351759
*/
1736-
if (!isdigit(name[0]) && name[0] != 'x')
1760+
if (!isdigit(name[0]) && name[0] != 'x') {
1761+
unsigned int namelen = strlen(name);
1762+
1763+
/*
1764+
* Only the force on/off options can be in that case,
1765+
* and they all take a single character.
1766+
*/
1767+
if (namelen == 1) {
1768+
ret = drm_mode_parse_cmdline_extra(name, namelen, true,
1769+
connector, mode);
1770+
if (!ret)
1771+
return true;
1772+
}
1773+
17371774
named_mode = true;
1775+
}
17381776

17391777
/* Try to locate the bpp and refresh specifiers, if any */
17401778
bpp_ptr = strchr(name, '-');
@@ -1772,6 +1810,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
17721810
if (named_mode) {
17731811
if (mode_end + 1 > DRM_DISPLAY_MODE_LEN)
17741812
return false;
1813+
1814+
if (!drm_named_mode_is_in_whitelist(name, mode_end))
1815+
return false;
1816+
17751817
strscpy(mode->name, name, mode_end + 1);
17761818
} else {
17771819
ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
@@ -1811,7 +1853,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
18111853
extra_ptr != options_ptr) {
18121854
int len = strlen(name) - (extra_ptr - name);
18131855

1814-
ret = drm_mode_parse_cmdline_extra(extra_ptr, len,
1856+
ret = drm_mode_parse_cmdline_extra(extra_ptr, len, false,
18151857
connector, mode);
18161858
if (ret)
18171859
return false;

drivers/gpu/drm/ingenic/ingenic-drm.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -656,10 +656,9 @@ static int ingenic_drm_probe(struct platform_device *pdev)
656656
return ret;
657657
}
658658

659-
if (panel) {
659+
if (panel)
660660
bridge = devm_drm_panel_bridge_add(dev, panel,
661-
DRM_MODE_CONNECTOR_Unknown);
662-
}
661+
DRM_MODE_CONNECTOR_DPI);
663662

664663
priv->dma_hwdesc = dma_alloc_coherent(dev, sizeof(*priv->dma_hwdesc),
665664
&priv->dma_hwdesc_phys,

drivers/gpu/drm/selftests/drm_cmdline_selftests.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99

1010
#define cmdline_test(test) selftest(test, test)
1111

12+
cmdline_test(drm_cmdline_test_force_d_only)
13+
cmdline_test(drm_cmdline_test_force_D_only_dvi)
14+
cmdline_test(drm_cmdline_test_force_D_only_hdmi)
15+
cmdline_test(drm_cmdline_test_force_D_only_not_digital)
16+
cmdline_test(drm_cmdline_test_force_e_only)
17+
cmdline_test(drm_cmdline_test_margin_only)
18+
cmdline_test(drm_cmdline_test_interlace_only)
1219
cmdline_test(drm_cmdline_test_res)
1320
cmdline_test(drm_cmdline_test_res_missing_x)
1421
cmdline_test(drm_cmdline_test_res_missing_y)

drivers/gpu/drm/selftests/test-drm_cmdline_parser.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,136 @@
1717

1818
static const struct drm_connector no_connector = {};
1919

20+
static int drm_cmdline_test_force_e_only(void *ignored)
21+
{
22+
struct drm_cmdline_mode mode = { };
23+
24+
FAIL_ON(!drm_mode_parse_command_line_for_connector("e",
25+
&no_connector,
26+
&mode));
27+
FAIL_ON(mode.specified);
28+
FAIL_ON(mode.refresh_specified);
29+
FAIL_ON(mode.bpp_specified);
30+
31+
FAIL_ON(mode.rb);
32+
FAIL_ON(mode.cvt);
33+
FAIL_ON(mode.interlace);
34+
FAIL_ON(mode.margins);
35+
FAIL_ON(mode.force != DRM_FORCE_ON);
36+
37+
return 0;
38+
}
39+
40+
static int drm_cmdline_test_force_D_only_not_digital(void *ignored)
41+
{
42+
struct drm_cmdline_mode mode = { };
43+
44+
FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
45+
&no_connector,
46+
&mode));
47+
FAIL_ON(mode.specified);
48+
FAIL_ON(mode.refresh_specified);
49+
FAIL_ON(mode.bpp_specified);
50+
51+
FAIL_ON(mode.rb);
52+
FAIL_ON(mode.cvt);
53+
FAIL_ON(mode.interlace);
54+
FAIL_ON(mode.margins);
55+
FAIL_ON(mode.force != DRM_FORCE_ON);
56+
57+
return 0;
58+
}
59+
60+
static const struct drm_connector connector_hdmi = {
61+
.connector_type = DRM_MODE_CONNECTOR_HDMIB,
62+
};
63+
64+
static int drm_cmdline_test_force_D_only_hdmi(void *ignored)
65+
{
66+
struct drm_cmdline_mode mode = { };
67+
68+
FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
69+
&connector_hdmi,
70+
&mode));
71+
FAIL_ON(mode.specified);
72+
FAIL_ON(mode.refresh_specified);
73+
FAIL_ON(mode.bpp_specified);
74+
75+
FAIL_ON(mode.rb);
76+
FAIL_ON(mode.cvt);
77+
FAIL_ON(mode.interlace);
78+
FAIL_ON(mode.margins);
79+
FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
80+
81+
return 0;
82+
}
83+
84+
static const struct drm_connector connector_dvi = {
85+
.connector_type = DRM_MODE_CONNECTOR_DVII,
86+
};
87+
88+
static int drm_cmdline_test_force_D_only_dvi(void *ignored)
89+
{
90+
struct drm_cmdline_mode mode = { };
91+
92+
FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
93+
&connector_dvi,
94+
&mode));
95+
FAIL_ON(mode.specified);
96+
FAIL_ON(mode.refresh_specified);
97+
FAIL_ON(mode.bpp_specified);
98+
99+
FAIL_ON(mode.rb);
100+
FAIL_ON(mode.cvt);
101+
FAIL_ON(mode.interlace);
102+
FAIL_ON(mode.margins);
103+
FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
104+
105+
return 0;
106+
}
107+
108+
static int drm_cmdline_test_force_d_only(void *ignored)
109+
{
110+
struct drm_cmdline_mode mode = { };
111+
112+
FAIL_ON(!drm_mode_parse_command_line_for_connector("d",
113+
&no_connector,
114+
&mode));
115+
FAIL_ON(mode.specified);
116+
FAIL_ON(mode.refresh_specified);
117+
FAIL_ON(mode.bpp_specified);
118+
119+
FAIL_ON(mode.rb);
120+
FAIL_ON(mode.cvt);
121+
FAIL_ON(mode.interlace);
122+
FAIL_ON(mode.margins);
123+
FAIL_ON(mode.force != DRM_FORCE_OFF);
124+
125+
return 0;
126+
}
127+
128+
static int drm_cmdline_test_margin_only(void *ignored)
129+
{
130+
struct drm_cmdline_mode mode = { };
131+
132+
FAIL_ON(drm_mode_parse_command_line_for_connector("m",
133+
&no_connector,
134+
&mode));
135+
136+
return 0;
137+
}
138+
139+
static int drm_cmdline_test_interlace_only(void *ignored)
140+
{
141+
struct drm_cmdline_mode mode = { };
142+
143+
FAIL_ON(drm_mode_parse_command_line_for_connector("i",
144+
&no_connector,
145+
&mode));
146+
147+
return 0;
148+
}
149+
20150
static int drm_cmdline_test_res(void *ignored)
21151
{
22152
struct drm_cmdline_mode mode = { };

0 commit comments

Comments
 (0)