Advertisement
Guest User

Untitled

a guest
Mar 3rd, 2018
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 48.77 KB | None | 0 0
  1. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  2. ---
  3. drivers/gpu/drm/drm_modes.c | 134 ++++++++++++++++++++++++++++++++++----------
  4. include/drm/drm_modes.h | 9 +++
  5. 2 files changed, 112 insertions(+), 31 deletions(-)
  6.  
  7. diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
  8. index 4a3f68a33844..8128dbb098be 100644
  9. --- a/drivers/gpu/drm/drm_modes.c
  10. +++ b/drivers/gpu/drm/drm_modes.c
  11. @@ -940,17 +940,68 @@ struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
  12. }
  13. EXPORT_SYMBOL(drm_mode_duplicate);
  14.  
  15. +static bool drm_mode_match_timings(const struct drm_display_mode *mode1,
  16. + const struct drm_display_mode *mode2)
  17. +{
  18. + return mode1->hdisplay == mode2->hdisplay &&
  19. + mode1->hsync_start == mode2->hsync_start &&
  20. + mode1->hsync_end == mode2->hsync_end &&
  21. + mode1->htotal == mode2->htotal &&
  22. + mode1->hskew == mode2->hskew &&
  23. + mode1->vdisplay == mode2->vdisplay &&
  24. + mode1->vsync_start == mode2->vsync_start &&
  25. + mode1->vsync_end == mode2->vsync_end &&
  26. + mode1->vtotal == mode2->vtotal &&
  27. + mode1->vscan == mode2->vscan;
  28. +}
  29. +
  30. +static bool drm_mode_match_clock(const struct drm_display_mode *mode1,
  31. + const struct drm_display_mode *mode2)
  32. +{
  33. + /*
  34. + * do clock check convert to PICOS
  35. + * so fb modes get matched the same
  36. + */
  37. + if (mode1->clock && mode2->clock)
  38. + return KHZ2PICOS(mode1->clock) == KHZ2PICOS(mode2->clock);
  39. + else
  40. + return mode1->clock == mode2->clock;
  41. +}
  42. +
  43. +static bool drm_mode_match_flags(const struct drm_display_mode *mode1,
  44. + const struct drm_display_mode *mode2)
  45. +{
  46. + return (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
  47. + (mode2->flags & ~DRM_MODE_FLAG_3D_MASK);
  48. +}
  49. +
  50. +static bool drm_mode_match_3d_flags(const struct drm_display_mode *mode1,
  51. + const struct drm_display_mode *mode2)
  52. +{
  53. + return (mode1->flags & DRM_MODE_FLAG_3D_MASK) ==
  54. + (mode2->flags & DRM_MODE_FLAG_3D_MASK);
  55. +}
  56. +
  57. +static bool drm_mode_match_aspect_ratio(const struct drm_display_mode *mode1,
  58. + const struct drm_display_mode *mode2)
  59. +{
  60. + return mode1->picture_aspect_ratio == mode2->picture_aspect_ratio;
  61. +}
  62. +
  63. /**
  64. - * drm_mode_equal - test modes for equality
  65. + * drm_mode_match - test modes for (partial) equality
  66. * @mode1: first mode
  67. * @mode2: second mode
  68. + * @match_flags: which parts need to match (DRM_MODE_MATCH_*)
  69. *
  70. * Check to see if @mode1 and @mode2 are equivalent.
  71. *
  72. * Returns:
  73. - * True if the modes are equal, false otherwise.
  74. + * True if the modes are (partially) equal, false otherwise.
  75. */
  76. -bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)
  77. +bool drm_mode_match(const struct drm_display_mode *mode1,
  78. + const struct drm_display_mode *mode2,
  79. + unsigned int match_flags)
  80. {
  81. if (!mode1 && !mode2)
  82. return true;
  83. @@ -958,15 +1009,48 @@ bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_displ
  84. if (!mode1 || !mode2)
  85. return false;
  86.  
  87. - /* do clock check convert to PICOS so fb modes get matched
  88. - * the same */
  89. - if (mode1->clock && mode2->clock) {
  90. - if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock))
  91. - return false;
  92. - } else if (mode1->clock != mode2->clock)
  93. + if (match_flags & DRM_MODE_MATCH_TIMINGS &&
  94. + !drm_mode_match_timings(mode1, mode2))
  95. + return false;
  96. +
  97. + if (match_flags & DRM_MODE_MATCH_CLOCK &&
  98. + !drm_mode_match_clock(mode1, mode2))
  99. + return false;
  100. +
  101. + if (match_flags & DRM_MODE_MATCH_FLAGS &&
  102. + !drm_mode_match_flags(mode1, mode2))
  103. + return false;
  104. +
  105. + if (match_flags & DRM_MODE_MATCH_3D_FLAGS &&
  106. + !drm_mode_match_3d_flags(mode1, mode2))
  107. return false;
  108.  
  109. - return drm_mode_equal_no_clocks(mode1, mode2);
  110. + if (match_flags & DRM_MODE_MATCH_ASPECT_RATIO &&
  111. + !drm_mode_match_aspect_ratio(mode1, mode2))
  112. + return false;
  113. +
  114. + return true;
  115. +}
  116. +EXPORT_SYMBOL(drm_mode_match);
  117. +
  118. +/**
  119. + * drm_mode_equal - test modes for equality
  120. + * @mode1: first mode
  121. + * @mode2: second mode
  122. + *
  123. + * Check to see if @mode1 and @mode2 are equivalent.
  124. + *
  125. + * Returns:
  126. + * True if the modes are equal, false otherwise.
  127. + */
  128. +bool drm_mode_equal(const struct drm_display_mode *mode1,
  129. + const struct drm_display_mode *mode2)
  130. +{
  131. + return drm_mode_match(mode1, mode2,
  132. + DRM_MODE_MATCH_TIMINGS |
  133. + DRM_MODE_MATCH_CLOCK |
  134. + DRM_MODE_MATCH_FLAGS |
  135. + DRM_MODE_MATCH_3D_FLAGS);
  136. }
  137. EXPORT_SYMBOL(drm_mode_equal);
  138.  
  139. @@ -981,13 +1065,13 @@ EXPORT_SYMBOL(drm_mode_equal);
  140. * Returns:
  141. * True if the modes are equal, false otherwise.
  142. */
  143. -bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)
  144. +bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
  145. + const struct drm_display_mode *mode2)
  146. {
  147. - if ((mode1->flags & DRM_MODE_FLAG_3D_MASK) !=
  148. - (mode2->flags & DRM_MODE_FLAG_3D_MASK))
  149. - return false;
  150. -
  151. - return drm_mode_equal_no_clocks_no_stereo(mode1, mode2);
  152. + return drm_mode_match(mode1, mode2,
  153. + DRM_MODE_MATCH_TIMINGS |
  154. + DRM_MODE_MATCH_FLAGS |
  155. + DRM_MODE_MATCH_3D_FLAGS);
  156. }
  157. EXPORT_SYMBOL(drm_mode_equal_no_clocks);
  158.  
  159. @@ -1005,21 +1089,9 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks);
  160. bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
  161. const struct drm_display_mode *mode2)
  162. {
  163. - if (mode1->hdisplay == mode2->hdisplay &&
  164. - mode1->hsync_start == mode2->hsync_start &&
  165. - mode1->hsync_end == mode2->hsync_end &&
  166. - mode1->htotal == mode2->htotal &&
  167. - mode1->hskew == mode2->hskew &&
  168. - mode1->vdisplay == mode2->vdisplay &&
  169. - mode1->vsync_start == mode2->vsync_start &&
  170. - mode1->vsync_end == mode2->vsync_end &&
  171. - mode1->vtotal == mode2->vtotal &&
  172. - mode1->vscan == mode2->vscan &&
  173. - (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
  174. - (mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
  175. - return true;
  176. -
  177. - return false;
  178. + return drm_mode_match(mode1, mode2,
  179. + DRM_MODE_MATCH_TIMINGS |
  180. + DRM_MODE_MATCH_FLAGS);
  181. }
  182. EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
  183.  
  184. diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
  185. index 9f3421c8efcd..839eb9c3a029 100644
  186. --- a/include/drm/drm_modes.h
  187. +++ b/include/drm/drm_modes.h
  188. @@ -150,6 +150,12 @@ enum drm_mode_status {
  189.  
  190. #define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
  191.  
  192. +#define DRM_MODE_MATCH_TIMINGS (1 << 0)
  193. +#define DRM_MODE_MATCH_CLOCK (1 << 1)
  194. +#define DRM_MODE_MATCH_FLAGS (1 << 2)
  195. +#define DRM_MODE_MATCH_3D_FLAGS (1 << 3)
  196. +#define DRM_MODE_MATCH_ASPECT_RATIO (1 << 4)
  197. +
  198. /**
  199. * struct drm_display_mode - DRM kernel-internal display mode structure
  200. * @hdisplay: horizontal display size
  201. @@ -493,6 +499,9 @@ void drm_mode_copy(struct drm_display_mode *dst,
  202. const struct drm_display_mode *src);
  203. struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
  204. const struct drm_display_mode *mode);
  205. +bool drm_mode_match(const struct drm_display_mode *mode1,
  206. + const struct drm_display_mode *mode2,
  207. + unsigned int match_flags);
  208. bool drm_mode_equal(const struct drm_display_mode *mode1,
  209. const struct drm_display_mode *mode2);
  210. bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
  211.  
  212. From patchwork Mon Nov 13 17:04:21 2017
  213. Content-Type: text/plain; charset="utf-8"
  214. MIME-Version: 1.0
  215. Content-Transfer-Encoding: 8bit
  216. Subject: [04/10] drm/edid: Use drm_mode_match_no_clocks_no_stereo() for
  217. consistentcy
  218. From: Ville Syrjala <ville.syrjala@linux.intel.com>
  219. X-Patchwork-Id: 188038
  220. Message-Id: <20171113170427.4150-5-ville.syrjala@linux.intel.com>
  221. To: dri-devel@lists.freedesktop.org
  222. Cc: intel-gfx@lists.freedesktop.org
  223. Date: Mon, 13 Nov 2017 19:04:21 +0200
  224.  
  225. From: Ville Syrjälä <ville.syrjala@linux.intel.com>
  226.  
  227. Use drm_mode_equal_no_clocks_no_stereo() in
  228. drm_match_hdmi_mode_clock_tolerance() for consistency as we
  229. also use it in drm_match_hdmi_mode() and the cea mode matching
  230. functions.
  231.  
  232. This doesn't actually change anything since the input mode
  233. comes from detailed timings and we match it against
  234. edid_4k_modes[] which. So none of those modes can have stereo
  235. flags set.
  236.  
  237. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  238. ---
  239. drivers/gpu/drm/drm_edid.c | 2 +-
  240. 1 file changed, 1 insertion(+), 1 deletion(-)
  241.  
  242. diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
  243. index 9ada0ccf50df..b575c4b5a313 100644
  244. --- a/drivers/gpu/drm/drm_edid.c
  245. +++ b/drivers/gpu/drm/drm_edid.c
  246. @@ -3020,7 +3020,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_
  247. abs(to_match->clock - clock2) > clock_tolerance)
  248. continue;
  249.  
  250. - if (drm_mode_equal_no_clocks(to_match, hdmi_mode))
  251. + if (drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode))
  252. return vic;
  253. }
  254.  
  255.  
  256. From patchwork Mon Nov 13 17:04:22 2017
  257. Content-Type: text/plain; charset="utf-8"
  258. MIME-Version: 1.0
  259. Content-Transfer-Encoding: 8bit
  260. Subject: [05/10] drm/edid: Fix up edid_cea_modes[] formatting
  261. From: Ville Syrjala <ville.syrjala@linux.intel.com>
  262. X-Patchwork-Id: 188039
  263. Message-Id: <20171113170427.4150-6-ville.syrjala@linux.intel.com>
  264. To: dri-devel@lists.freedesktop.org
  265. Cc: intel-gfx@lists.freedesktop.org
  266. Date: Mon, 13 Nov 2017 19:04:22 +0200
  267.  
  268. From: Ville Syrjälä <ville.syrjala@linux.intel.com>
  269.  
  270. Fix up a bunch of bad indentation and insconsistent comments
  271. in edid_cea_modes[].
  272.  
  273. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  274. ---
  275. drivers/gpu/drm/drm_edid.c | 84 +++++++++++++++++++++++-----------------------
  276. 1 file changed, 42 insertions(+), 42 deletions(-)
  277.  
  278. diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
  279. index b575c4b5a313..7220b8f9a7e8 100644
  280. --- a/drivers/gpu/drm/drm_edid.c
  281. +++ b/drivers/gpu/drm/drm_edid.c
  282. @@ -685,43 +685,43 @@ static const struct drm_display_mode edid_cea_modes[] = {
  283. { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
  284. 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
  285. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
  286. - DRM_MODE_FLAG_INTERLACE),
  287. + DRM_MODE_FLAG_INTERLACE),
  288. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  289. /* 6 - 720(1440)x480i@60Hz */
  290. { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
  291. 801, 858, 0, 480, 488, 494, 525, 0,
  292. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  293. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  294. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  295. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  296. /* 7 - 720(1440)x480i@60Hz */
  297. { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
  298. 801, 858, 0, 480, 488, 494, 525, 0,
  299. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  300. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  301. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  302. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  303. /* 8 - 720(1440)x240@60Hz */
  304. { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
  305. 801, 858, 0, 240, 244, 247, 262, 0,
  306. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  307. - DRM_MODE_FLAG_DBLCLK),
  308. + DRM_MODE_FLAG_DBLCLK),
  309. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  310. /* 9 - 720(1440)x240@60Hz */
  311. { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
  312. 801, 858, 0, 240, 244, 247, 262, 0,
  313. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  314. - DRM_MODE_FLAG_DBLCLK),
  315. + DRM_MODE_FLAG_DBLCLK),
  316. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  317. /* 10 - 2880x480i@60Hz */
  318. { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
  319. 3204, 3432, 0, 480, 488, 494, 525, 0,
  320. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  321. - DRM_MODE_FLAG_INTERLACE),
  322. + DRM_MODE_FLAG_INTERLACE),
  323. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  324. /* 11 - 2880x480i@60Hz */
  325. { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
  326. 3204, 3432, 0, 480, 488, 494, 525, 0,
  327. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  328. - DRM_MODE_FLAG_INTERLACE),
  329. + DRM_MODE_FLAG_INTERLACE),
  330. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  331. /* 12 - 2880x240@60Hz */
  332. { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
  333. @@ -767,43 +767,43 @@ static const struct drm_display_mode edid_cea_modes[] = {
  334. { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
  335. 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
  336. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
  337. - DRM_MODE_FLAG_INTERLACE),
  338. + DRM_MODE_FLAG_INTERLACE),
  339. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  340. /* 21 - 720(1440)x576i@50Hz */
  341. { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
  342. 795, 864, 0, 576, 580, 586, 625, 0,
  343. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  344. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  345. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  346. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  347. /* 22 - 720(1440)x576i@50Hz */
  348. { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
  349. 795, 864, 0, 576, 580, 586, 625, 0,
  350. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  351. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  352. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  353. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  354. /* 23 - 720(1440)x288@50Hz */
  355. { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
  356. 795, 864, 0, 288, 290, 293, 312, 0,
  357. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  358. - DRM_MODE_FLAG_DBLCLK),
  359. + DRM_MODE_FLAG_DBLCLK),
  360. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  361. /* 24 - 720(1440)x288@50Hz */
  362. { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732,
  363. 795, 864, 0, 288, 290, 293, 312, 0,
  364. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  365. - DRM_MODE_FLAG_DBLCLK),
  366. + DRM_MODE_FLAG_DBLCLK),
  367. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  368. /* 25 - 2880x576i@50Hz */
  369. { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
  370. 3180, 3456, 0, 576, 580, 586, 625, 0,
  371. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  372. - DRM_MODE_FLAG_INTERLACE),
  373. + DRM_MODE_FLAG_INTERLACE),
  374. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  375. /* 26 - 2880x576i@50Hz */
  376. { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
  377. 3180, 3456, 0, 576, 580, 586, 625, 0,
  378. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  379. - DRM_MODE_FLAG_INTERLACE),
  380. + DRM_MODE_FLAG_INTERLACE),
  381. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  382. /* 27 - 2880x288@50Hz */
  383. { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
  384. @@ -869,13 +869,13 @@ static const struct drm_display_mode edid_cea_modes[] = {
  385. { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
  386. 2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
  387. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
  388. - DRM_MODE_FLAG_INTERLACE),
  389. + DRM_MODE_FLAG_INTERLACE),
  390. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  391. /* 40 - 1920x1080i@100Hz */
  392. { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
  393. 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
  394. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
  395. - DRM_MODE_FLAG_INTERLACE),
  396. + DRM_MODE_FLAG_INTERLACE),
  397. .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  398. /* 41 - 1280x720@100Hz */
  399. { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
  400. @@ -896,19 +896,19 @@ static const struct drm_display_mode edid_cea_modes[] = {
  401. { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
  402. 795, 864, 0, 576, 580, 586, 625, 0,
  403. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  404. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  405. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  406. .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  407. /* 45 - 720(1440)x576i@100Hz */
  408. { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
  409. 795, 864, 0, 576, 580, 586, 625, 0,
  410. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  411. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  412. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  413. .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  414. /* 46 - 1920x1080i@120Hz */
  415. { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
  416. 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
  417. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
  418. - DRM_MODE_FLAG_INTERLACE),
  419. + DRM_MODE_FLAG_INTERLACE),
  420. .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  421. /* 47 - 1280x720@120Hz */
  422. { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
  423. @@ -929,13 +929,13 @@ static const struct drm_display_mode edid_cea_modes[] = {
  424. { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
  425. 801, 858, 0, 480, 488, 494, 525, 0,
  426. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  427. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  428. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  429. .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  430. /* 51 - 720(1440)x480i@120Hz */
  431. { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739,
  432. 801, 858, 0, 480, 488, 494, 525, 0,
  433. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  434. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  435. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  436. .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  437. /* 52 - 720x576@200Hz */
  438. { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
  439. @@ -951,13 +951,13 @@ static const struct drm_display_mode edid_cea_modes[] = {
  440. { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
  441. 795, 864, 0, 576, 580, 586, 625, 0,
  442. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  443. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  444. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  445. .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  446. /* 55 - 720(1440)x576i@200Hz */
  447. { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
  448. 795, 864, 0, 576, 580, 586, 625, 0,
  449. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  450. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  451. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  452. .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  453. /* 56 - 720x480@240Hz */
  454. { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
  455. @@ -973,13 +973,13 @@ static const struct drm_display_mode edid_cea_modes[] = {
  456. { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
  457. 801, 858, 0, 480, 488, 494, 525, 0,
  458. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  459. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  460. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  461. .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
  462. /* 59 - 720(1440)x480i@240Hz */
  463. { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
  464. 801, 858, 0, 480, 488, 494, 525, 0,
  465. DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
  466. - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  467. + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
  468. .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  469. /* 60 - 1280x720@24Hz */
  470. { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
  471. @@ -1000,12 +1000,12 @@ static const struct drm_display_mode edid_cea_modes[] = {
  472. { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
  473. 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
  474. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  475. - .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  476. + .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  477. /* 64 - 1920x1080@100Hz */
  478. { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
  479. 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
  480. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  481. - .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  482. + .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  483. /* 65 - 1280x720@24Hz */
  484. { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
  485. 3080, 3300, 0, 720, 725, 730, 750, 0,
  486. @@ -1146,77 +1146,77 @@ static const struct drm_display_mode edid_cea_modes[] = {
  487. 3152, 3300, 0, 1080, 1084, 1089, 1250, 0,
  488. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  489. .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
  490. - /* 93 - 3840x2160p@24Hz 16:9 */
  491. + /* 93 - 3840x2160@24Hz */
  492. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
  493. 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
  494. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  495. .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  496. - /* 94 - 3840x2160p@25Hz 16:9 */
  497. + /* 94 - 3840x2160@25Hz */
  498. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
  499. 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
  500. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  501. .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  502. - /* 95 - 3840x2160p@30Hz 16:9 */
  503. + /* 95 - 3840x2160@30Hz */
  504. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
  505. 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
  506. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  507. .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  508. - /* 96 - 3840x2160p@50Hz 16:9 */
  509. + /* 96 - 3840x2160@50Hz */
  510. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
  511. 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
  512. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  513. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  514. - /* 97 - 3840x2160p@60Hz 16:9 */
  515. + /* 97 - 3840x2160@60Hz */
  516. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
  517. 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
  518. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  519. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
  520. - /* 98 - 4096x2160p@24Hz 256:135 */
  521. + /* 98 - 4096x2160@24Hz */
  522. { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5116,
  523. 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
  524. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  525. .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
  526. - /* 99 - 4096x2160p@25Hz 256:135 */
  527. + /* 99 - 4096x2160@25Hz */
  528. { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5064,
  529. 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
  530. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  531. .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
  532. - /* 100 - 4096x2160p@30Hz 256:135 */
  533. + /* 100 - 4096x2160@30Hz */
  534. { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
  535. 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
  536. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  537. .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
  538. - /* 101 - 4096x2160p@50Hz 256:135 */
  539. + /* 101 - 4096x2160@50Hz */
  540. { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5064,
  541. 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
  542. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  543. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
  544. - /* 102 - 4096x2160p@60Hz 256:135 */
  545. + /* 102 - 4096x2160@60Hz */
  546. { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
  547. 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
  548. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  549. .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
  550. - /* 103 - 3840x2160p@24Hz 64:27 */
  551. + /* 103 - 3840x2160@24Hz */
  552. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
  553. 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
  554. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  555. .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
  556. - /* 104 - 3840x2160p@25Hz 64:27 */
  557. + /* 104 - 3840x2160@25Hz */
  558. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
  559. 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
  560. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  561. .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
  562. - /* 105 - 3840x2160p@30Hz 64:27 */
  563. + /* 105 - 3840x2160@30Hz */
  564. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
  565. 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
  566. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  567. .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
  568. - /* 106 - 3840x2160p@50Hz 64:27 */
  569. + /* 106 - 3840x2160@50Hz */
  570. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
  571. 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
  572. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  573. .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
  574. - /* 107 - 3840x2160p@60Hz 64:27 */
  575. + /* 107 - 3840x2160@60Hz */
  576. { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
  577. 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
  578. DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  579.  
  580. From patchwork Mon Nov 13 17:04:23 2017
  581. Content-Type: text/plain; charset="utf-8"
  582. MIME-Version: 1.0
  583. Content-Transfer-Encoding: 8bit
  584. Subject: [06/10] drm/edid: Fix cea mode aspect ratio handling
  585. From: Ville Syrjala <ville.syrjala@linux.intel.com>
  586. X-Patchwork-Id: 188044
  587. Message-Id: <20171113170427.4150-7-ville.syrjala@linux.intel.com>
  588. To: dri-devel@lists.freedesktop.org
  589. Cc: Jose Abreu <Jose.Abreu@synopsys.com>, "Lin, Jia" <lin.a.jia@intel.com>,
  590. intel-gfx@lists.freedesktop.org, Daniel Vetter <daniel.vetter@ffwll.ch>
  591. Date: Mon, 13 Nov 2017 19:04:23 +0200
  592.  
  593. From: Ville Syrjälä <ville.syrjala@linux.intel.com>
  594.  
  595. commit 6dffd431e229 ("drm: Add aspect ratio parsing in DRM layer")
  596. cause us to not send out any VICs in the AVI infoframes. That commit
  597. was since reverted, but if and when we add aspect ratio handing back
  598. we need to be more careful.
  599.  
  600. Let's handle this by considering the aspect ratio as a requirement
  601. for cea mode matching only if the passed in mode actually has a
  602. non-zero aspect ratio field. This will keep userspace that doesn't
  603. provide an aspect ratio working as before by matching it to the
  604. first otherwise equal cea mode. And once userspace starts to
  605. provide the aspect ratio it will be considerd a hard requirement
  606. for the match.
  607.  
  608. Also change the hdmi mode matching to use drm_mode_match() for
  609. consistency, but we don't match on aspect ratio there since the
  610. spec doesn't list a specific aspect ratio for those modes.
  611.  
  612. Cc: Shashank Sharma <shashank.sharma@intel.com>
  613. Cc: "Lin, Jia" <lin.a.jia@intel.com>
  614. Cc: Akashdeep Sharma <akashdeep.sharma@intel.com>
  615. Cc: Jim Bride <jim.bride@linux.intel.com>
  616. Cc: Jose Abreu <Jose.Abreu@synopsys.com>
  617. Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
  618. Cc: Emil Velikov <emil.l.velikov@gmail.com>
  619. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  620. ---
  621. drivers/gpu/drm/drm_edid.c | 18 ++++++++++++++----
  622. 1 file changed, 14 insertions(+), 4 deletions(-)
  623.  
  624. diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
  625. index 7220b8f9a7e8..00aa98f3e55d 100644
  626. --- a/drivers/gpu/drm/drm_edid.c
  627. +++ b/drivers/gpu/drm/drm_edid.c
  628. @@ -2903,11 +2903,15 @@ cea_mode_alternate_timings(u8 vic, struct drm_display_mode *mode)
  629. static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match,
  630. unsigned int clock_tolerance)
  631. {
  632. + unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
  633. u8 vic;
  634.  
  635. if (!to_match->clock)
  636. return 0;
  637.  
  638. + if (to_match->picture_aspect_ratio)
  639. + match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
  640. +
  641. for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
  642. struct drm_display_mode cea_mode = edid_cea_modes[vic];
  643. unsigned int clock1, clock2;
  644. @@ -2921,7 +2925,7 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m
  645. continue;
  646.  
  647. do {
  648. - if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode))
  649. + if (drm_mode_match(to_match, &cea_mode, match_flags))
  650. return vic;
  651. } while (cea_mode_alternate_timings(vic, &cea_mode));
  652. }
  653. @@ -2938,11 +2942,15 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m
  654. */
  655. u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
  656. {
  657. + unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
  658. u8 vic;
  659.  
  660. if (!to_match->clock)
  661. return 0;
  662.  
  663. + if (to_match->picture_aspect_ratio)
  664. + match_flags |= DRM_MODE_MATCH_ASPECT_RATIO;
  665. +
  666. for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
  667. struct drm_display_mode cea_mode = edid_cea_modes[vic];
  668. unsigned int clock1, clock2;
  669. @@ -2956,7 +2964,7 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
  670. continue;
  671.  
  672. do {
  673. - if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode))
  674. + if (drm_mode_match(to_match, &cea_mode, match_flags))
  675. return vic;
  676. } while (cea_mode_alternate_timings(vic, &cea_mode));
  677. }
  678. @@ -3003,6 +3011,7 @@ hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
  679. static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match,
  680. unsigned int clock_tolerance)
  681. {
  682. + unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
  683. u8 vic;
  684.  
  685. if (!to_match->clock)
  686. @@ -3020,7 +3029,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_
  687. abs(to_match->clock - clock2) > clock_tolerance)
  688. continue;
  689.  
  690. - if (drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode))
  691. + if (drm_mode_match(to_match, hdmi_mode, match_flags))
  692. return vic;
  693. }
  694.  
  695. @@ -3037,6 +3046,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_
  696. */
  697. static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
  698. {
  699. + unsigned int match_flags = DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_FLAGS;
  700. u8 vic;
  701.  
  702. if (!to_match->clock)
  703. @@ -3052,7 +3062,7 @@ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
  704.  
  705. if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
  706. KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
  707. - drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode))
  708. + drm_mode_match(to_match, hdmi_mode, match_flags))
  709. return vic;
  710. }
  711. return 0;
  712.  
  713. From patchwork Mon Nov 13 17:04:24 2017
  714. Content-Type: text/plain; charset="utf-8"
  715. MIME-Version: 1.0
  716. Content-Transfer-Encoding: 8bit
  717. Subject: [07/10] drm/edid: Don't send bogus aspect ratios in AVI infoframes
  718. From: Ville Syrjala <ville.syrjala@linux.intel.com>
  719. X-Patchwork-Id: 188049
  720. Message-Id: <20171113170427.4150-8-ville.syrjala@linux.intel.com>
  721. To: dri-devel@lists.freedesktop.org
  722. Cc: Jose Abreu <Jose.Abreu@synopsys.com>,
  723. Daniel Vetter <daniel.vetter@ffwll.ch>, intel-gfx@lists.freedesktop.org
  724. Date: Mon, 13 Nov 2017 19:04:24 +0200
  725.  
  726. From: Ville Syrjälä <ville.syrjala@linux.intel.com>
  727.  
  728. If the user mode would specify an aspect ratio other than 4:3 or 16:9
  729. we now silently ignore it. Maybe a better apporoach is to return an
  730. error? Let's try that.
  731.  
  732. Also we must be careful that we don't try to send illegal picture
  733. aspect in the infoframe as it's only capable of signalling none,
  734. 4:3, and 16:9. Currently we're sending these bogus infoframes
  735. whenever the cea mode specifies some other aspect ratio.
  736.  
  737. Cc: Shashank Sharma <shashank.sharma@intel.com>
  738. Cc: Sean Paul <seanpaul@chromium.org>
  739. Cc: Jose Abreu <Jose.Abreu@synopsys.com>
  740. Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
  741. Cc: Emil Velikov <emil.l.velikov@gmail.com>
  742. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  743. Reviewed-by: Shashank Sharma <shashank.sharma@intel.com>
  744. ---
  745. drivers/gpu/drm/drm_edid.c | 23 +++++++++++++++++------
  746. 1 file changed, 17 insertions(+), 6 deletions(-)
  747.  
  748. diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
  749. index 00aa98f3e55d..bafb3ee4ea97 100644
  750. --- a/drivers/gpu/drm/drm_edid.c
  751. +++ b/drivers/gpu/drm/drm_edid.c
  752. @@ -4786,6 +4786,7 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
  753. const struct drm_display_mode *mode,
  754. bool is_hdmi2_sink)
  755. {
  756. + enum hdmi_picture_aspect picture_aspect;
  757. int err;
  758.  
  759. if (!frame || !mode)
  760. @@ -4828,13 +4829,23 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
  761. * Populate picture aspect ratio from either
  762. * user input (if specified) or from the CEA mode list.
  763. */
  764. - if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 ||
  765. - mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9)
  766. - frame->picture_aspect = mode->picture_aspect_ratio;
  767. - else if (frame->video_code > 0)
  768. - frame->picture_aspect = drm_get_cea_aspect_ratio(
  769. - frame->video_code);
  770. + picture_aspect = mode->picture_aspect_ratio;
  771. + if (picture_aspect == HDMI_PICTURE_ASPECT_NONE)
  772. + picture_aspect = drm_get_cea_aspect_ratio(frame->video_code);
  773.  
  774. + /*
  775. + * The infoframe can't convey anything but none, 4:3
  776. + * and 16:9, so if the user has asked for anything else
  777. + * we can only satisfy it by specifying the right VIC.
  778. + */
  779. + if (picture_aspect > HDMI_PICTURE_ASPECT_16_9) {
  780. + if (picture_aspect !=
  781. + drm_get_cea_aspect_ratio(frame->video_code))
  782. + return -EINVAL;
  783. + picture_aspect = HDMI_PICTURE_ASPECT_NONE;
  784. + }
  785. +
  786. + frame->picture_aspect = picture_aspect;
  787. frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
  788. frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
  789.  
  790.  
  791. From patchwork Mon Nov 13 17:04:25 2017
  792. Content-Type: text/plain; charset="utf-8"
  793. MIME-Version: 1.0
  794. Content-Transfer-Encoding: 8bit
  795. Subject: [08/10] video/hdmi: Reject illegal picture aspect ratios
  796. From: Ville Syrjala <ville.syrjala@linux.intel.com>
  797. X-Patchwork-Id: 188051
  798. Message-Id: <20171113170427.4150-9-ville.syrjala@linux.intel.com>
  799. To: dri-devel@lists.freedesktop.org
  800. Cc: Jose Abreu <Jose.Abreu@synopsys.com>, "Lin, Jia" <lin.a.jia@intel.com>,
  801. intel-gfx@lists.freedesktop.org, Hans Verkuil <hans.verkuil@cisco.com>,
  802. Daniel Vetter <daniel.vetter@ffwll.ch>, linux-media@vger.kernel.org
  803. Date: Mon, 13 Nov 2017 19:04:25 +0200
  804.  
  805. From: Ville Syrjälä <ville.syrjala@linux.intel.com>
  806.  
  807. AVI infoframe can only carry none, 4:3, or 16:9 picture aspect
  808. ratios. Return an error if the user asked for something different.
  809.  
  810. Cc: Shashank Sharma <shashank.sharma@intel.com>
  811. Cc: "Lin, Jia" <lin.a.jia@intel.com>
  812. Cc: Akashdeep Sharma <akashdeep.sharma@intel.com>
  813. Cc: Jim Bride <jim.bride@linux.intel.com>
  814. Cc: Jose Abreu <Jose.Abreu@synopsys.com>
  815. Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
  816. Cc: Emil Velikov <emil.l.velikov@gmail.com>
  817. Cc: Thierry Reding <thierry.reding@gmail.com>
  818. Cc: Hans Verkuil <hans.verkuil@cisco.com>
  819. Cc: linux-media@vger.kernel.org
  820. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  821. Reviewed-by: Jose Abreu <joabreu@synopsys.com>
  822. ---
  823. drivers/video/hdmi.c | 3 +++
  824. 1 file changed, 3 insertions(+)
  825.  
  826. diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
  827. index 111a0ab6280a..38716eb50408 100644
  828. --- a/drivers/video/hdmi.c
  829. +++ b/drivers/video/hdmi.c
  830. @@ -93,6 +93,9 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
  831. if (size < length)
  832. return -ENOSPC;
  833.  
  834. + if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
  835. + return -EINVAL;
  836. +
  837. memset(buffer, 0, size);
  838.  
  839. ptr[0] = frame->type;
  840.  
  841. From patchwork Mon Nov 13 17:04:26 2017
  842. Content-Type: text/plain; charset="utf-8"
  843. MIME-Version: 1.0
  844. Content-Transfer-Encoding: 8bit
  845. Subject: [09/10] video/hdmi: Constify 'buffer' to the unpack functions
  846. From: Ville Syrjala <ville.syrjala@linux.intel.com>
  847. X-Patchwork-Id: 188048
  848. Message-Id: <20171113170427.4150-10-ville.syrjala@linux.intel.com>
  849. To: dri-devel@lists.freedesktop.org
  850. Cc: intel-gfx@lists.freedesktop.org, Hans Verkuil <hans.verkuil@cisco.com>,
  851. linux-media@vger.kernel.org
  852. Date: Mon, 13 Nov 2017 19:04:26 +0200
  853.  
  854. From: Ville Syrjälä <ville.syrjala@linux.intel.com>
  855.  
  856. The unpack functions just read from the passed in buffer,
  857. so make it const.
  858.  
  859. Cc: Thierry Reding <thierry.reding@gmail.com>
  860. Cc: Hans Verkuil <hans.verkuil@cisco.com>
  861. Cc: linux-media@vger.kernel.org
  862. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  863. ---
  864. drivers/video/hdmi.c | 23 ++++++++++++-----------
  865. include/linux/hdmi.h | 3 ++-
  866. 2 files changed, 14 insertions(+), 12 deletions(-)
  867.  
  868. diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
  869. index 38716eb50408..65b915ea4936 100644
  870. --- a/drivers/video/hdmi.c
  871. +++ b/drivers/video/hdmi.c
  872. @@ -31,7 +31,7 @@
  873.  
  874. #define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__)
  875.  
  876. -static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
  877. +static u8 hdmi_infoframe_checksum(const u8 *ptr, size_t size)
  878. {
  879. u8 csum = 0;
  880. size_t i;
  881. @@ -1016,9 +1016,9 @@ EXPORT_SYMBOL(hdmi_infoframe_log);
  882. * Returns 0 on success or a negative error code on failure.
  883. */
  884. static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
  885. - void *buffer)
  886. + const void *buffer)
  887. {
  888. - u8 *ptr = buffer;
  889. + const u8 *ptr = buffer;
  890. int ret;
  891.  
  892. if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
  893. @@ -1079,9 +1079,9 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
  894. * Returns 0 on success or a negative error code on failure.
  895. */
  896. static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
  897. - void *buffer)
  898. + const void *buffer)
  899. {
  900. - u8 *ptr = buffer;
  901. + const u8 *ptr = buffer;
  902. int ret;
  903.  
  904. if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD ||
  905. @@ -1117,9 +1117,9 @@ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
  906. * Returns 0 on success or a negative error code on failure.
  907. */
  908. static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
  909. - void *buffer)
  910. + const void *buffer)
  911. {
  912. - u8 *ptr = buffer;
  913. + const u8 *ptr = buffer;
  914. int ret;
  915.  
  916. if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO ||
  917. @@ -1163,9 +1163,9 @@ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
  918. */
  919. static int
  920. hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  921. - void *buffer)
  922. + const void *buffer)
  923. {
  924. - u8 *ptr = buffer;
  925. + const u8 *ptr = buffer;
  926. size_t length;
  927. int ret;
  928. u8 hdmi_video_format;
  929. @@ -1234,10 +1234,11 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  930. *
  931. * Returns 0 on success or a negative error code on failure.
  932. */
  933. -int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer)
  934. +int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
  935. + const void *buffer)
  936. {
  937. int ret;
  938. - u8 *ptr = buffer;
  939. + const u8 *ptr = buffer;
  940.  
  941. switch (ptr[0]) {
  942. case HDMI_INFOFRAME_TYPE_AVI:
  943. diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
  944. index d271ff23984f..d3816170c062 100644
  945. --- a/include/linux/hdmi.h
  946. +++ b/include/linux/hdmi.h
  947. @@ -332,7 +332,8 @@ union hdmi_infoframe {
  948.  
  949. ssize_t
  950. hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size);
  951. -int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer);
  952. +int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
  953. + const void *buffer);
  954. void hdmi_infoframe_log(const char *level, struct device *dev,
  955. union hdmi_infoframe *frame);
  956.  
  957.  
  958. From patchwork Mon Nov 13 17:04:27 2017
  959. Content-Type: text/plain; charset="utf-8"
  960. MIME-Version: 1.0
  961. Content-Transfer-Encoding: 8bit
  962. Subject: [10/10] video/hdmi: Pass buffer size to infoframe unpack functions
  963. From: Ville Syrjala <ville.syrjala@linux.intel.com>
  964. X-Patchwork-Id: 188053
  965. Message-Id: <20171113170427.4150-11-ville.syrjala@linux.intel.com>
  966. To: dri-devel@lists.freedesktop.org
  967. Cc: intel-gfx@lists.freedesktop.org, Hans Verkuil <hans.verkuil@cisco.com>,
  968. linux-media@vger.kernel.org
  969. Date: Mon, 13 Nov 2017 19:04:27 +0200
  970.  
  971. From: Ville Syrjälä <ville.syrjala@linux.intel.com>
  972.  
  973. To make sure the infoframe unpack functions don't end up examining
  974. stack garbage or oopsing, let's pass in the size of the buffer.
  975.  
  976. Cc: Thierry Reding <thierry.reding@gmail.com>
  977. Cc: Hans Verkuil <hans.verkuil@cisco.com>
  978. Cc: linux-media@vger.kernel.org
  979. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
  980. ---
  981. drivers/media/i2c/adv7511.c | 2 +-
  982. drivers/media/i2c/adv7604.c | 2 +-
  983. drivers/media/i2c/adv7842.c | 2 +-
  984. drivers/media/i2c/tc358743.c | 2 +-
  985. drivers/video/hdmi.c | 51 ++++++++++++++++++++++++++++++++------------
  986. include/linux/hdmi.h | 2 +-
  987. 6 files changed, 42 insertions(+), 19 deletions(-)
  988.  
  989. diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
  990. index 2817bafc67bf..dec09c18ea34 100644
  991. --- a/drivers/media/i2c/adv7511.c
  992. +++ b/drivers/media/i2c/adv7511.c
  993. @@ -562,7 +562,7 @@ static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_
  994. buffer[3] = 0;
  995. buffer[3] = hdmi_infoframe_checksum(buffer, len + 4);
  996.  
  997. - if (hdmi_infoframe_unpack(&frame, buffer) < 0) {
  998. + if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) {
  999. v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc);
  1000. return;
  1001. }
  1002. diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
  1003. index f289b8aca1da..8500438af0d3 100644
  1004. --- a/drivers/media/i2c/adv7604.c
  1005. +++ b/drivers/media/i2c/adv7604.c
  1006. @@ -2429,7 +2429,7 @@ static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index,
  1007. buffer[i + 3] = infoframe_read(sd,
  1008. adv76xx_cri[index].payload_addr + i);
  1009.  
  1010. - if (hdmi_infoframe_unpack(frame, buffer) < 0) {
  1011. + if (hdmi_infoframe_unpack(frame, buffer, sizeof(buffer)) < 0) {
  1012. v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__,
  1013. adv76xx_cri[index].desc);
  1014. return -ENOENT;
  1015. diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
  1016. index 65f34e7e146f..fd5d5e84dcbf 100644
  1017. --- a/drivers/media/i2c/adv7842.c
  1018. +++ b/drivers/media/i2c/adv7842.c
  1019. @@ -2576,7 +2576,7 @@ static void log_infoframe(struct v4l2_subdev *sd, struct adv7842_cfg_read_infofr
  1020. for (i = 0; i < len; i++)
  1021. buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i);
  1022.  
  1023. - if (hdmi_infoframe_unpack(&frame, buffer) < 0) {
  1024. + if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) {
  1025. v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc);
  1026. return;
  1027. }
  1028. diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
  1029. index e6f5c363ccab..f6a5ebffd9c6 100644
  1030. --- a/drivers/media/i2c/tc358743.c
  1031. +++ b/drivers/media/i2c/tc358743.c
  1032. @@ -453,7 +453,7 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
  1033.  
  1034. i2c_rd(sd, PK_AVI_0HEAD, buffer, HDMI_INFOFRAME_SIZE(AVI));
  1035.  
  1036. - if (hdmi_infoframe_unpack(&frame, buffer) < 0) {
  1037. + if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) {
  1038. v4l2_err(sd, "%s: unpack of AVI infoframe failed\n", __func__);
  1039. return;
  1040. }
  1041. diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
  1042. index 65b915ea4936..b5d491014b0b 100644
  1043. --- a/drivers/video/hdmi.c
  1044. +++ b/drivers/video/hdmi.c
  1045. @@ -1005,8 +1005,9 @@ EXPORT_SYMBOL(hdmi_infoframe_log);
  1046.  
  1047. /**
  1048. * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe
  1049. - * @buffer: source buffer
  1050. * @frame: HDMI AVI infoframe
  1051. + * @buffer: source buffer
  1052. + * @size: size of buffer
  1053. *
  1054. * Unpacks the information contained in binary @buffer into a structured
  1055. * @frame of the HDMI Auxiliary Video (AVI) information frame.
  1056. @@ -1016,11 +1017,14 @@ EXPORT_SYMBOL(hdmi_infoframe_log);
  1057. * Returns 0 on success or a negative error code on failure.
  1058. */
  1059. static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
  1060. - const void *buffer)
  1061. + const void *buffer, size_t size)
  1062. {
  1063. const u8 *ptr = buffer;
  1064. int ret;
  1065.  
  1066. + if (size < HDMI_INFOFRAME_SIZE(AVI))
  1067. + return -EINVAL;
  1068. +
  1069. if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
  1070. ptr[1] != 2 ||
  1071. ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
  1072. @@ -1068,8 +1072,9 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
  1073.  
  1074. /**
  1075. * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe
  1076. - * @buffer: source buffer
  1077. * @frame: HDMI SPD infoframe
  1078. + * @buffer: source buffer
  1079. + * @size: size of buffer
  1080. *
  1081. * Unpacks the information contained in binary @buffer into a structured
  1082. * @frame of the HDMI Source Product Description (SPD) information frame.
  1083. @@ -1079,11 +1084,14 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
  1084. * Returns 0 on success or a negative error code on failure.
  1085. */
  1086. static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
  1087. - const void *buffer)
  1088. + const void *buffer, size_t size)
  1089. {
  1090. const u8 *ptr = buffer;
  1091. int ret;
  1092.  
  1093. + if (size < HDMI_INFOFRAME_SIZE(SPD))
  1094. + return -EINVAL;
  1095. +
  1096. if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD ||
  1097. ptr[1] != 1 ||
  1098. ptr[2] != HDMI_SPD_INFOFRAME_SIZE) {
  1099. @@ -1106,8 +1114,9 @@ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
  1100.  
  1101. /**
  1102. * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe
  1103. - * @buffer: source buffer
  1104. * @frame: HDMI Audio infoframe
  1105. + * @buffer: source buffer
  1106. + * @size: size of buffer
  1107. *
  1108. * Unpacks the information contained in binary @buffer into a structured
  1109. * @frame of the HDMI Audio information frame.
  1110. @@ -1117,11 +1126,14 @@ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
  1111. * Returns 0 on success or a negative error code on failure.
  1112. */
  1113. static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
  1114. - const void *buffer)
  1115. + const void *buffer, size_t size)
  1116. {
  1117. const u8 *ptr = buffer;
  1118. int ret;
  1119.  
  1120. + if (size < HDMI_INFOFRAME_SIZE(AUDIO))
  1121. + return -EINVAL;
  1122. +
  1123. if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO ||
  1124. ptr[1] != 1 ||
  1125. ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) {
  1126. @@ -1151,8 +1163,9 @@ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
  1127.  
  1128. /**
  1129. * hdmi_vendor_infoframe_unpack() - unpack binary buffer to a HDMI vendor infoframe
  1130. - * @buffer: source buffer
  1131. * @frame: HDMI Vendor infoframe
  1132. + * @buffer: source buffer
  1133. + * @size: size of buffer
  1134. *
  1135. * Unpacks the information contained in binary @buffer into a structured
  1136. * @frame of the HDMI Vendor information frame.
  1137. @@ -1163,7 +1176,7 @@ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
  1138. */
  1139. static int
  1140. hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  1141. - const void *buffer)
  1142. + const void *buffer, size_t size)
  1143. {
  1144. const u8 *ptr = buffer;
  1145. size_t length;
  1146. @@ -1171,6 +1184,9 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  1147. u8 hdmi_video_format;
  1148. struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
  1149.  
  1150. + if (size < HDMI_INFOFRAME_HEADER_SIZE)
  1151. + return -EINVAL;
  1152. +
  1153. if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR ||
  1154. ptr[1] != 1 ||
  1155. (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6))
  1156. @@ -1178,6 +1194,9 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  1157.  
  1158. length = ptr[2];
  1159.  
  1160. + if (size < HDMI_INFOFRAME_HEADER_SIZE + length)
  1161. + return -EINVAL;
  1162. +
  1163. if (hdmi_infoframe_checksum(buffer,
  1164. HDMI_INFOFRAME_HEADER_SIZE + length) != 0)
  1165. return -EINVAL;
  1166. @@ -1224,8 +1243,9 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  1167.  
  1168. /**
  1169. * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
  1170. - * @buffer: source buffer
  1171. * @frame: HDMI infoframe
  1172. + * @buffer: source buffer
  1173. + * @size: size of buffer
  1174. *
  1175. * Unpacks the information contained in binary buffer @buffer into a structured
  1176. * @frame of a HDMI infoframe.
  1177. @@ -1235,23 +1255,26 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
  1178. * Returns 0 on success or a negative error code on failure.
  1179. */
  1180. int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
  1181. - const void *buffer)
  1182. + const void *buffer, size_t size)
  1183. {
  1184. int ret;
  1185. const u8 *ptr = buffer;
  1186.  
  1187. + if (size < HDMI_INFOFRAME_HEADER_SIZE)
  1188. + return -EINVAL;
  1189. +
  1190. switch (ptr[0]) {
  1191. case HDMI_INFOFRAME_TYPE_AVI:
  1192. - ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer);
  1193. + ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size);
  1194. break;
  1195. case HDMI_INFOFRAME_TYPE_SPD:
  1196. - ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer);
  1197. + ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size);
  1198. break;
  1199. case HDMI_INFOFRAME_TYPE_AUDIO:
  1200. - ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer);
  1201. + ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer, size);
  1202. break;
  1203. case HDMI_INFOFRAME_TYPE_VENDOR:
  1204. - ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer);
  1205. + ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size);
  1206. break;
  1207. default:
  1208. ret = -EINVAL;
  1209. diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
  1210. index d3816170c062..a577d4ae2570 100644
  1211. --- a/include/linux/hdmi.h
  1212. +++ b/include/linux/hdmi.h
  1213. @@ -333,7 +333,7 @@ union hdmi_infoframe {
  1214. ssize_t
  1215. hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size);
  1216. int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
  1217. - const void *buffer);
  1218. + const void *buffer, size_t size);
  1219. void hdmi_infoframe_log(const char *level, struct device *dev,
  1220. union hdmi_infoframe *frame);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement