drm_modes.c 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150
  1. /*
  2. * Copyright © 1997-2003 by The XFree86 Project, Inc.
  3. * Copyright © 2007 Dave Airlie
  4. * Copyright © 2007-2008 Intel Corporation
  5. * Jesse Barnes <[email protected]>
  6. * Copyright 2005-2006 Luc Verhaegen
  7. * Copyright (c) 2001, Andy Ritger [email protected]
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a
  10. * copy of this software and associated documentation files (the "Software"),
  11. * to deal in the Software without restriction, including without limitation
  12. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13. * and/or sell copies of the Software, and to permit persons to whom the
  14. * Software is furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25. * OTHER DEALINGS IN THE SOFTWARE.
  26. *
  27. * Except as contained in this notice, the name of the copyright holder(s)
  28. * and author(s) shall not be used in advertising or otherwise to promote
  29. * the sale, use or other dealings in this Software without prior written
  30. * authorization from the copyright holder(s) and author(s).
  31. */
  32. #include <linux/ctype.h>
  33. #include <linux/list.h>
  34. #include <linux/list_sort.h>
  35. #include <linux/export.h>
  36. #include <linux/fb.h>
  37. #include <video/of_display_timing.h>
  38. #include <video/of_videomode.h>
  39. #include <video/videomode.h>
  40. #include <drm/drm_crtc.h>
  41. #include <drm/drm_device.h>
  42. #include <drm/drm_edid.h>
  43. #include <drm/drm_modes.h>
  44. #include <drm/drm_print.h>
  45. #include "drm_crtc_internal.h"
  46. /**
  47. * drm_mode_debug_printmodeline - print a mode to dmesg
  48. * @mode: mode to print
  49. *
  50. * Describe @mode using DRM_DEBUG.
  51. */
  52. void drm_mode_debug_printmodeline(const struct drm_display_mode *mode)
  53. {
  54. DRM_DEBUG_KMS("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
  55. }
  56. EXPORT_SYMBOL(drm_mode_debug_printmodeline);
  57. /**
  58. * drm_mode_create - create a new display mode
  59. * @dev: DRM device
  60. *
  61. * Create a new, cleared drm_display_mode with kzalloc, allocate an ID for it
  62. * and return it.
  63. *
  64. * Returns:
  65. * Pointer to new mode on success, NULL on error.
  66. */
  67. struct drm_display_mode *drm_mode_create(struct drm_device *dev)
  68. {
  69. struct drm_display_mode *nmode;
  70. nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
  71. if (!nmode)
  72. return NULL;
  73. return nmode;
  74. }
  75. EXPORT_SYMBOL(drm_mode_create);
  76. /**
  77. * drm_mode_destroy - remove a mode
  78. * @dev: DRM device
  79. * @mode: mode to remove
  80. *
  81. * Release @mode's unique ID, then free it @mode structure itself using kfree.
  82. */
  83. void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
  84. {
  85. if (!mode)
  86. return;
  87. kfree(mode);
  88. }
  89. EXPORT_SYMBOL(drm_mode_destroy);
  90. /**
  91. * drm_mode_probed_add - add a mode to a connector's probed_mode list
  92. * @connector: connector the new mode
  93. * @mode: mode data
  94. *
  95. * Add @mode to @connector's probed_mode list for later use. This list should
  96. * then in a second step get filtered and all the modes actually supported by
  97. * the hardware moved to the @connector's modes list.
  98. */
  99. void drm_mode_probed_add(struct drm_connector *connector,
  100. struct drm_display_mode *mode)
  101. {
  102. WARN_ON(!mutex_is_locked(&connector->dev->mode_config.mutex));
  103. list_add_tail(&mode->head, &connector->probed_modes);
  104. }
  105. EXPORT_SYMBOL(drm_mode_probed_add);
  106. /**
  107. * drm_cvt_mode -create a modeline based on the CVT algorithm
  108. * @dev: drm device
  109. * @hdisplay: hdisplay size
  110. * @vdisplay: vdisplay size
  111. * @vrefresh: vrefresh rate
  112. * @reduced: whether to use reduced blanking
  113. * @interlaced: whether to compute an interlaced mode
  114. * @margins: whether to add margins (borders)
  115. *
  116. * This function is called to generate the modeline based on CVT algorithm
  117. * according to the hdisplay, vdisplay, vrefresh.
  118. * It is based from the VESA(TM) Coordinated Video Timing Generator by
  119. * Graham Loveridge April 9, 2003 available at
  120. * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls
  121. *
  122. * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c.
  123. * What I have done is to translate it by using integer calculation.
  124. *
  125. * Returns:
  126. * The modeline based on the CVT algorithm stored in a drm_display_mode object.
  127. * The display mode object is allocated with drm_mode_create(). Returns NULL
  128. * when no mode could be allocated.
  129. */
  130. struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
  131. int vdisplay, int vrefresh,
  132. bool reduced, bool interlaced, bool margins)
  133. {
  134. #define HV_FACTOR 1000
  135. /* 1) top/bottom margin size (% of height) - default: 1.8, */
  136. #define CVT_MARGIN_PERCENTAGE 18
  137. /* 2) character cell horizontal granularity (pixels) - default 8 */
  138. #define CVT_H_GRANULARITY 8
  139. /* 3) Minimum vertical porch (lines) - default 3 */
  140. #define CVT_MIN_V_PORCH 3
  141. /* 4) Minimum number of vertical back porch lines - default 6 */
  142. #define CVT_MIN_V_BPORCH 6
  143. /* Pixel Clock step (kHz) */
  144. #define CVT_CLOCK_STEP 250
  145. struct drm_display_mode *drm_mode;
  146. unsigned int vfieldrate, hperiod;
  147. int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync;
  148. int interlace;
  149. u64 tmp;
  150. if (!hdisplay || !vdisplay)
  151. return NULL;
  152. /* allocate the drm_display_mode structure. If failure, we will
  153. * return directly
  154. */
  155. drm_mode = drm_mode_create(dev);
  156. if (!drm_mode)
  157. return NULL;
  158. /* the CVT default refresh rate is 60Hz */
  159. if (!vrefresh)
  160. vrefresh = 60;
  161. /* the required field fresh rate */
  162. if (interlaced)
  163. vfieldrate = vrefresh * 2;
  164. else
  165. vfieldrate = vrefresh;
  166. /* horizontal pixels */
  167. hdisplay_rnd = hdisplay - (hdisplay % CVT_H_GRANULARITY);
  168. /* determine the left&right borders */
  169. hmargin = 0;
  170. if (margins) {
  171. hmargin = hdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000;
  172. hmargin -= hmargin % CVT_H_GRANULARITY;
  173. }
  174. /* find the total active pixels */
  175. drm_mode->hdisplay = hdisplay_rnd + 2 * hmargin;
  176. /* find the number of lines per field */
  177. if (interlaced)
  178. vdisplay_rnd = vdisplay / 2;
  179. else
  180. vdisplay_rnd = vdisplay;
  181. /* find the top & bottom borders */
  182. vmargin = 0;
  183. if (margins)
  184. vmargin = vdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000;
  185. drm_mode->vdisplay = vdisplay + 2 * vmargin;
  186. /* Interlaced */
  187. if (interlaced)
  188. interlace = 1;
  189. else
  190. interlace = 0;
  191. /* Determine VSync Width from aspect ratio */
  192. if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay))
  193. vsync = 4;
  194. else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay))
  195. vsync = 5;
  196. else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay))
  197. vsync = 6;
  198. else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay))
  199. vsync = 7;
  200. else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay))
  201. vsync = 7;
  202. else /* custom */
  203. vsync = 10;
  204. if (!reduced) {
  205. /* simplify the GTF calculation */
  206. /* 4) Minimum time of vertical sync + back porch interval (µs)
  207. * default 550.0
  208. */
  209. int tmp1, tmp2;
  210. #define CVT_MIN_VSYNC_BP 550
  211. /* 3) Nominal HSync width (% of line period) - default 8 */
  212. #define CVT_HSYNC_PERCENTAGE 8
  213. unsigned int hblank_percentage;
  214. int vsyncandback_porch, __maybe_unused vback_porch, hblank;
  215. /* estimated the horizontal period */
  216. tmp1 = HV_FACTOR * 1000000 -
  217. CVT_MIN_VSYNC_BP * HV_FACTOR * vfieldrate;
  218. tmp2 = (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH) * 2 +
  219. interlace;
  220. hperiod = tmp1 * 2 / (tmp2 * vfieldrate);
  221. tmp1 = CVT_MIN_VSYNC_BP * HV_FACTOR / hperiod + 1;
  222. /* 9. Find number of lines in sync + backporch */
  223. if (tmp1 < (vsync + CVT_MIN_V_PORCH))
  224. vsyncandback_porch = vsync + CVT_MIN_V_PORCH;
  225. else
  226. vsyncandback_porch = tmp1;
  227. /* 10. Find number of lines in back porch */
  228. vback_porch = vsyncandback_porch - vsync;
  229. drm_mode->vtotal = vdisplay_rnd + 2 * vmargin +
  230. vsyncandback_porch + CVT_MIN_V_PORCH;
  231. /* 5) Definition of Horizontal blanking time limitation */
  232. /* Gradient (%/kHz) - default 600 */
  233. #define CVT_M_FACTOR 600
  234. /* Offset (%) - default 40 */
  235. #define CVT_C_FACTOR 40
  236. /* Blanking time scaling factor - default 128 */
  237. #define CVT_K_FACTOR 128
  238. /* Scaling factor weighting - default 20 */
  239. #define CVT_J_FACTOR 20
  240. #define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256)
  241. #define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
  242. CVT_J_FACTOR)
  243. /* 12. Find ideal blanking duty cycle from formula */
  244. hblank_percentage = CVT_C_PRIME * HV_FACTOR - CVT_M_PRIME *
  245. hperiod / 1000;
  246. /* 13. Blanking time */
  247. if (hblank_percentage < 20 * HV_FACTOR)
  248. hblank_percentage = 20 * HV_FACTOR;
  249. hblank = drm_mode->hdisplay * hblank_percentage /
  250. (100 * HV_FACTOR - hblank_percentage);
  251. hblank -= hblank % (2 * CVT_H_GRANULARITY);
  252. /* 14. find the total pixels per line */
  253. drm_mode->htotal = drm_mode->hdisplay + hblank;
  254. drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2;
  255. drm_mode->hsync_start = drm_mode->hsync_end -
  256. (drm_mode->htotal * CVT_HSYNC_PERCENTAGE) / 100;
  257. drm_mode->hsync_start += CVT_H_GRANULARITY -
  258. drm_mode->hsync_start % CVT_H_GRANULARITY;
  259. /* fill the Vsync values */
  260. drm_mode->vsync_start = drm_mode->vdisplay + CVT_MIN_V_PORCH;
  261. drm_mode->vsync_end = drm_mode->vsync_start + vsync;
  262. } else {
  263. /* Reduced blanking */
  264. /* Minimum vertical blanking interval time (µs)- default 460 */
  265. #define CVT_RB_MIN_VBLANK 460
  266. /* Fixed number of clocks for horizontal sync */
  267. #define CVT_RB_H_SYNC 32
  268. /* Fixed number of clocks for horizontal blanking */
  269. #define CVT_RB_H_BLANK 160
  270. /* Fixed number of lines for vertical front porch - default 3*/
  271. #define CVT_RB_VFPORCH 3
  272. int vbilines;
  273. int tmp1, tmp2;
  274. /* 8. Estimate Horizontal period. */
  275. tmp1 = HV_FACTOR * 1000000 -
  276. CVT_RB_MIN_VBLANK * HV_FACTOR * vfieldrate;
  277. tmp2 = vdisplay_rnd + 2 * vmargin;
  278. hperiod = tmp1 / (tmp2 * vfieldrate);
  279. /* 9. Find number of lines in vertical blanking */
  280. vbilines = CVT_RB_MIN_VBLANK * HV_FACTOR / hperiod + 1;
  281. /* 10. Check if vertical blanking is sufficient */
  282. if (vbilines < (CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH))
  283. vbilines = CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH;
  284. /* 11. Find total number of lines in vertical field */
  285. drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines;
  286. /* 12. Find total number of pixels in a line */
  287. drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK;
  288. /* Fill in HSync values */
  289. drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2;
  290. drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC;
  291. /* Fill in VSync values */
  292. drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH;
  293. drm_mode->vsync_end = drm_mode->vsync_start + vsync;
  294. }
  295. /* 15/13. Find pixel clock frequency (kHz for xf86) */
  296. tmp = drm_mode->htotal; /* perform intermediate calcs in u64 */
  297. tmp *= HV_FACTOR * 1000;
  298. do_div(tmp, hperiod);
  299. tmp -= drm_mode->clock % CVT_CLOCK_STEP;
  300. drm_mode->clock = tmp;
  301. /* 18/16. Find actual vertical frame frequency */
  302. /* ignore - just set the mode flag for interlaced */
  303. if (interlaced) {
  304. drm_mode->vtotal *= 2;
  305. drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
  306. }
  307. /* Fill the mode line name */
  308. drm_mode_set_name(drm_mode);
  309. if (reduced)
  310. drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
  311. DRM_MODE_FLAG_NVSYNC);
  312. else
  313. drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC |
  314. DRM_MODE_FLAG_NHSYNC);
  315. return drm_mode;
  316. }
  317. EXPORT_SYMBOL(drm_cvt_mode);
  318. /**
  319. * drm_gtf_mode_complex - create the modeline based on the full GTF algorithm
  320. * @dev: drm device
  321. * @hdisplay: hdisplay size
  322. * @vdisplay: vdisplay size
  323. * @vrefresh: vrefresh rate.
  324. * @interlaced: whether to compute an interlaced mode
  325. * @margins: desired margin (borders) size
  326. * @GTF_M: extended GTF formula parameters
  327. * @GTF_2C: extended GTF formula parameters
  328. * @GTF_K: extended GTF formula parameters
  329. * @GTF_2J: extended GTF formula parameters
  330. *
  331. * GTF feature blocks specify C and J in multiples of 0.5, so we pass them
  332. * in here multiplied by two. For a C of 40, pass in 80.
  333. *
  334. * Returns:
  335. * The modeline based on the full GTF algorithm stored in a drm_display_mode object.
  336. * The display mode object is allocated with drm_mode_create(). Returns NULL
  337. * when no mode could be allocated.
  338. */
  339. struct drm_display_mode *
  340. drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay,
  341. int vrefresh, bool interlaced, int margins,
  342. int GTF_M, int GTF_2C, int GTF_K, int GTF_2J)
  343. { /* 1) top/bottom margin size (% of height) - default: 1.8, */
  344. #define GTF_MARGIN_PERCENTAGE 18
  345. /* 2) character cell horizontal granularity (pixels) - default 8 */
  346. #define GTF_CELL_GRAN 8
  347. /* 3) Minimum vertical porch (lines) - default 3 */
  348. #define GTF_MIN_V_PORCH 1
  349. /* width of vsync in lines */
  350. #define V_SYNC_RQD 3
  351. /* width of hsync as % of total line */
  352. #define H_SYNC_PERCENT 8
  353. /* min time of vsync + back porch (microsec) */
  354. #define MIN_VSYNC_PLUS_BP 550
  355. /* C' and M' are part of the Blanking Duty Cycle computation */
  356. #define GTF_C_PRIME ((((GTF_2C - GTF_2J) * GTF_K / 256) + GTF_2J) / 2)
  357. #define GTF_M_PRIME (GTF_K * GTF_M / 256)
  358. struct drm_display_mode *drm_mode;
  359. unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd;
  360. int top_margin, bottom_margin;
  361. int interlace;
  362. unsigned int hfreq_est;
  363. int vsync_plus_bp, __maybe_unused vback_porch;
  364. unsigned int vtotal_lines, __maybe_unused vfieldrate_est;
  365. unsigned int __maybe_unused hperiod;
  366. unsigned int vfield_rate, __maybe_unused vframe_rate;
  367. int left_margin, right_margin;
  368. unsigned int total_active_pixels, ideal_duty_cycle;
  369. unsigned int hblank, total_pixels, pixel_freq;
  370. int hsync, hfront_porch, vodd_front_porch_lines;
  371. unsigned int tmp1, tmp2;
  372. if (!hdisplay || !vdisplay)
  373. return NULL;
  374. drm_mode = drm_mode_create(dev);
  375. if (!drm_mode)
  376. return NULL;
  377. /* 1. In order to give correct results, the number of horizontal
  378. * pixels requested is first processed to ensure that it is divisible
  379. * by the character size, by rounding it to the nearest character
  380. * cell boundary:
  381. */
  382. hdisplay_rnd = (hdisplay + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN;
  383. hdisplay_rnd = hdisplay_rnd * GTF_CELL_GRAN;
  384. /* 2. If interlace is requested, the number of vertical lines assumed
  385. * by the calculation must be halved, as the computation calculates
  386. * the number of vertical lines per field.
  387. */
  388. if (interlaced)
  389. vdisplay_rnd = vdisplay / 2;
  390. else
  391. vdisplay_rnd = vdisplay;
  392. /* 3. Find the frame rate required: */
  393. if (interlaced)
  394. vfieldrate_rqd = vrefresh * 2;
  395. else
  396. vfieldrate_rqd = vrefresh;
  397. /* 4. Find number of lines in Top margin: */
  398. top_margin = 0;
  399. if (margins)
  400. top_margin = (vdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) /
  401. 1000;
  402. /* 5. Find number of lines in bottom margin: */
  403. bottom_margin = top_margin;
  404. /* 6. If interlace is required, then set variable interlace: */
  405. if (interlaced)
  406. interlace = 1;
  407. else
  408. interlace = 0;
  409. /* 7. Estimate the Horizontal frequency */
  410. {
  411. tmp1 = (1000000 - MIN_VSYNC_PLUS_BP * vfieldrate_rqd) / 500;
  412. tmp2 = (vdisplay_rnd + 2 * top_margin + GTF_MIN_V_PORCH) *
  413. 2 + interlace;
  414. hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1;
  415. }
  416. /* 8. Find the number of lines in V sync + back porch */
  417. /* [V SYNC+BP] = RINT(([MIN VSYNC+BP] * hfreq_est / 1000000)) */
  418. vsync_plus_bp = MIN_VSYNC_PLUS_BP * hfreq_est / 1000;
  419. vsync_plus_bp = (vsync_plus_bp + 500) / 1000;
  420. /* 9. Find the number of lines in V back porch alone: */
  421. vback_porch = vsync_plus_bp - V_SYNC_RQD;
  422. /* 10. Find the total number of lines in Vertical field period: */
  423. vtotal_lines = vdisplay_rnd + top_margin + bottom_margin +
  424. vsync_plus_bp + GTF_MIN_V_PORCH;
  425. /* 11. Estimate the Vertical field frequency: */
  426. vfieldrate_est = hfreq_est / vtotal_lines;
  427. /* 12. Find the actual horizontal period: */
  428. hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines);
  429. /* 13. Find the actual Vertical field frequency: */
  430. vfield_rate = hfreq_est / vtotal_lines;
  431. /* 14. Find the Vertical frame frequency: */
  432. if (interlaced)
  433. vframe_rate = vfield_rate / 2;
  434. else
  435. vframe_rate = vfield_rate;
  436. /* 15. Find number of pixels in left margin: */
  437. if (margins)
  438. left_margin = (hdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) /
  439. 1000;
  440. else
  441. left_margin = 0;
  442. /* 16.Find number of pixels in right margin: */
  443. right_margin = left_margin;
  444. /* 17.Find total number of active pixels in image and left and right */
  445. total_active_pixels = hdisplay_rnd + left_margin + right_margin;
  446. /* 18.Find the ideal blanking duty cycle from blanking duty cycle */
  447. ideal_duty_cycle = GTF_C_PRIME * 1000 -
  448. (GTF_M_PRIME * 1000000 / hfreq_est);
  449. /* 19.Find the number of pixels in the blanking time to the nearest
  450. * double character cell: */
  451. hblank = total_active_pixels * ideal_duty_cycle /
  452. (100000 - ideal_duty_cycle);
  453. hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN);
  454. hblank = hblank * 2 * GTF_CELL_GRAN;
  455. /* 20.Find total number of pixels: */
  456. total_pixels = total_active_pixels + hblank;
  457. /* 21.Find pixel clock frequency: */
  458. pixel_freq = total_pixels * hfreq_est / 1000;
  459. /* Stage 1 computations are now complete; I should really pass
  460. * the results to another function and do the Stage 2 computations,
  461. * but I only need a few more values so I'll just append the
  462. * computations here for now */
  463. /* 17. Find the number of pixels in the horizontal sync period: */
  464. hsync = H_SYNC_PERCENT * total_pixels / 100;
  465. hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN;
  466. hsync = hsync * GTF_CELL_GRAN;
  467. /* 18. Find the number of pixels in horizontal front porch period */
  468. hfront_porch = hblank / 2 - hsync;
  469. /* 36. Find the number of lines in the odd front porch period: */
  470. vodd_front_porch_lines = GTF_MIN_V_PORCH ;
  471. /* finally, pack the results in the mode struct */
  472. drm_mode->hdisplay = hdisplay_rnd;
  473. drm_mode->hsync_start = hdisplay_rnd + hfront_porch;
  474. drm_mode->hsync_end = drm_mode->hsync_start + hsync;
  475. drm_mode->htotal = total_pixels;
  476. drm_mode->vdisplay = vdisplay_rnd;
  477. drm_mode->vsync_start = vdisplay_rnd + vodd_front_porch_lines;
  478. drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD;
  479. drm_mode->vtotal = vtotal_lines;
  480. drm_mode->clock = pixel_freq;
  481. if (interlaced) {
  482. drm_mode->vtotal *= 2;
  483. drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
  484. }
  485. drm_mode_set_name(drm_mode);
  486. if (GTF_M == 600 && GTF_2C == 80 && GTF_K == 128 && GTF_2J == 40)
  487. drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC;
  488. else
  489. drm_mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC;
  490. return drm_mode;
  491. }
  492. EXPORT_SYMBOL(drm_gtf_mode_complex);
  493. /**
  494. * drm_gtf_mode - create the modeline based on the GTF algorithm
  495. * @dev: drm device
  496. * @hdisplay: hdisplay size
  497. * @vdisplay: vdisplay size
  498. * @vrefresh: vrefresh rate.
  499. * @interlaced: whether to compute an interlaced mode
  500. * @margins: desired margin (borders) size
  501. *
  502. * return the modeline based on GTF algorithm
  503. *
  504. * This function is to create the modeline based on the GTF algorithm.
  505. * Generalized Timing Formula is derived from:
  506. *
  507. * GTF Spreadsheet by Andy Morrish (1/5/97)
  508. * available at https://www.vesa.org
  509. *
  510. * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c.
  511. * What I have done is to translate it by using integer calculation.
  512. * I also refer to the function of fb_get_mode in the file of
  513. * drivers/video/fbmon.c
  514. *
  515. * Standard GTF parameters::
  516. *
  517. * M = 600
  518. * C = 40
  519. * K = 128
  520. * J = 20
  521. *
  522. * Returns:
  523. * The modeline based on the GTF algorithm stored in a drm_display_mode object.
  524. * The display mode object is allocated with drm_mode_create(). Returns NULL
  525. * when no mode could be allocated.
  526. */
  527. struct drm_display_mode *
  528. drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh,
  529. bool interlaced, int margins)
  530. {
  531. return drm_gtf_mode_complex(dev, hdisplay, vdisplay, vrefresh,
  532. interlaced, margins,
  533. 600, 40 * 2, 128, 20 * 2);
  534. }
  535. EXPORT_SYMBOL(drm_gtf_mode);
  536. #ifdef CONFIG_VIDEOMODE_HELPERS
  537. /**
  538. * drm_display_mode_from_videomode - fill in @dmode using @vm,
  539. * @vm: videomode structure to use as source
  540. * @dmode: drm_display_mode structure to use as destination
  541. *
  542. * Fills out @dmode using the display mode specified in @vm.
  543. */
  544. void drm_display_mode_from_videomode(const struct videomode *vm,
  545. struct drm_display_mode *dmode)
  546. {
  547. dmode->hdisplay = vm->hactive;
  548. dmode->hsync_start = dmode->hdisplay + vm->hfront_porch;
  549. dmode->hsync_end = dmode->hsync_start + vm->hsync_len;
  550. dmode->htotal = dmode->hsync_end + vm->hback_porch;
  551. dmode->vdisplay = vm->vactive;
  552. dmode->vsync_start = dmode->vdisplay + vm->vfront_porch;
  553. dmode->vsync_end = dmode->vsync_start + vm->vsync_len;
  554. dmode->vtotal = dmode->vsync_end + vm->vback_porch;
  555. dmode->clock = vm->pixelclock / 1000;
  556. dmode->flags = 0;
  557. if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH)
  558. dmode->flags |= DRM_MODE_FLAG_PHSYNC;
  559. else if (vm->flags & DISPLAY_FLAGS_HSYNC_LOW)
  560. dmode->flags |= DRM_MODE_FLAG_NHSYNC;
  561. if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
  562. dmode->flags |= DRM_MODE_FLAG_PVSYNC;
  563. else if (vm->flags & DISPLAY_FLAGS_VSYNC_LOW)
  564. dmode->flags |= DRM_MODE_FLAG_NVSYNC;
  565. if (vm->flags & DISPLAY_FLAGS_INTERLACED)
  566. dmode->flags |= DRM_MODE_FLAG_INTERLACE;
  567. if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
  568. dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
  569. if (vm->flags & DISPLAY_FLAGS_DOUBLECLK)
  570. dmode->flags |= DRM_MODE_FLAG_DBLCLK;
  571. drm_mode_set_name(dmode);
  572. }
  573. EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
  574. /**
  575. * drm_display_mode_to_videomode - fill in @vm using @dmode,
  576. * @dmode: drm_display_mode structure to use as source
  577. * @vm: videomode structure to use as destination
  578. *
  579. * Fills out @vm using the display mode specified in @dmode.
  580. */
  581. void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
  582. struct videomode *vm)
  583. {
  584. vm->hactive = dmode->hdisplay;
  585. vm->hfront_porch = dmode->hsync_start - dmode->hdisplay;
  586. vm->hsync_len = dmode->hsync_end - dmode->hsync_start;
  587. vm->hback_porch = dmode->htotal - dmode->hsync_end;
  588. vm->vactive = dmode->vdisplay;
  589. vm->vfront_porch = dmode->vsync_start - dmode->vdisplay;
  590. vm->vsync_len = dmode->vsync_end - dmode->vsync_start;
  591. vm->vback_porch = dmode->vtotal - dmode->vsync_end;
  592. vm->pixelclock = dmode->clock * 1000;
  593. vm->flags = 0;
  594. if (dmode->flags & DRM_MODE_FLAG_PHSYNC)
  595. vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
  596. else if (dmode->flags & DRM_MODE_FLAG_NHSYNC)
  597. vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
  598. if (dmode->flags & DRM_MODE_FLAG_PVSYNC)
  599. vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
  600. else if (dmode->flags & DRM_MODE_FLAG_NVSYNC)
  601. vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
  602. if (dmode->flags & DRM_MODE_FLAG_INTERLACE)
  603. vm->flags |= DISPLAY_FLAGS_INTERLACED;
  604. if (dmode->flags & DRM_MODE_FLAG_DBLSCAN)
  605. vm->flags |= DISPLAY_FLAGS_DOUBLESCAN;
  606. if (dmode->flags & DRM_MODE_FLAG_DBLCLK)
  607. vm->flags |= DISPLAY_FLAGS_DOUBLECLK;
  608. }
  609. EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
  610. /**
  611. * drm_bus_flags_from_videomode - extract information about pixelclk and
  612. * DE polarity from videomode and store it in a separate variable
  613. * @vm: videomode structure to use
  614. * @bus_flags: information about pixelclk, sync and DE polarity will be stored
  615. * here
  616. *
  617. * Sets DRM_BUS_FLAG_DE_(LOW|HIGH), DRM_BUS_FLAG_PIXDATA_DRIVE_(POS|NEG)EDGE
  618. * and DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to DISPLAY_FLAGS
  619. * found in @vm
  620. */
  621. void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags)
  622. {
  623. *bus_flags = 0;
  624. if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
  625. *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
  626. if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
  627. *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
  628. if (vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE)
  629. *bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE;
  630. if (vm->flags & DISPLAY_FLAGS_SYNC_NEGEDGE)
  631. *bus_flags |= DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;
  632. if (vm->flags & DISPLAY_FLAGS_DE_LOW)
  633. *bus_flags |= DRM_BUS_FLAG_DE_LOW;
  634. if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
  635. *bus_flags |= DRM_BUS_FLAG_DE_HIGH;
  636. }
  637. EXPORT_SYMBOL_GPL(drm_bus_flags_from_videomode);
  638. #ifdef CONFIG_OF
  639. /**
  640. * of_get_drm_display_mode - get a drm_display_mode from devicetree
  641. * @np: device_node with the timing specification
  642. * @dmode: will be set to the return value
  643. * @bus_flags: information about pixelclk, sync and DE polarity
  644. * @index: index into the list of display timings in devicetree
  645. *
  646. * This function is expensive and should only be used, if only one mode is to be
  647. * read from DT. To get multiple modes start with of_get_display_timings and
  648. * work with that instead.
  649. *
  650. * Returns:
  651. * 0 on success, a negative errno code when no of videomode node was found.
  652. */
  653. int of_get_drm_display_mode(struct device_node *np,
  654. struct drm_display_mode *dmode, u32 *bus_flags,
  655. int index)
  656. {
  657. struct videomode vm;
  658. int ret;
  659. ret = of_get_videomode(np, &vm, index);
  660. if (ret)
  661. return ret;
  662. drm_display_mode_from_videomode(&vm, dmode);
  663. if (bus_flags)
  664. drm_bus_flags_from_videomode(&vm, bus_flags);
  665. pr_debug("%pOF: got %dx%d display mode\n",
  666. np, vm.hactive, vm.vactive);
  667. drm_mode_debug_printmodeline(dmode);
  668. return 0;
  669. }
  670. EXPORT_SYMBOL_GPL(of_get_drm_display_mode);
  671. /**
  672. * of_get_drm_panel_display_mode - get a panel-timing drm_display_mode from devicetree
  673. * @np: device_node with the panel-timing specification
  674. * @dmode: will be set to the return value
  675. * @bus_flags: information about pixelclk, sync and DE polarity
  676. *
  677. * The mandatory Device Tree properties width-mm and height-mm
  678. * are read and set on the display mode.
  679. *
  680. * Returns:
  681. * Zero on success, negative error code on failure.
  682. */
  683. int of_get_drm_panel_display_mode(struct device_node *np,
  684. struct drm_display_mode *dmode, u32 *bus_flags)
  685. {
  686. u32 width_mm = 0, height_mm = 0;
  687. struct display_timing timing;
  688. struct videomode vm;
  689. int ret;
  690. ret = of_get_display_timing(np, "panel-timing", &timing);
  691. if (ret)
  692. return ret;
  693. videomode_from_timing(&timing, &vm);
  694. memset(dmode, 0, sizeof(*dmode));
  695. drm_display_mode_from_videomode(&vm, dmode);
  696. if (bus_flags)
  697. drm_bus_flags_from_videomode(&vm, bus_flags);
  698. ret = of_property_read_u32(np, "width-mm", &width_mm);
  699. if (ret)
  700. return ret;
  701. ret = of_property_read_u32(np, "height-mm", &height_mm);
  702. if (ret)
  703. return ret;
  704. dmode->width_mm = width_mm;
  705. dmode->height_mm = height_mm;
  706. drm_mode_debug_printmodeline(dmode);
  707. return 0;
  708. }
  709. EXPORT_SYMBOL_GPL(of_get_drm_panel_display_mode);
  710. #endif /* CONFIG_OF */
  711. #endif /* CONFIG_VIDEOMODE_HELPERS */
  712. /**
  713. * drm_mode_set_name - set the name on a mode
  714. * @mode: name will be set in this mode
  715. *
  716. * Set the name of @mode to a standard format which is <hdisplay>x<vdisplay>
  717. * with an optional 'i' suffix for interlaced modes.
  718. */
  719. void drm_mode_set_name(struct drm_display_mode *mode)
  720. {
  721. bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
  722. snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d%s",
  723. mode->hdisplay, mode->vdisplay,
  724. interlaced ? "i" : "");
  725. }
  726. EXPORT_SYMBOL(drm_mode_set_name);
  727. /**
  728. * drm_mode_vrefresh - get the vrefresh of a mode
  729. * @mode: mode
  730. *
  731. * Returns:
  732. * @modes's vrefresh rate in Hz, rounded to the nearest integer. Calculates the
  733. * value first if it is not yet set.
  734. */
  735. int drm_mode_vrefresh(const struct drm_display_mode *mode)
  736. {
  737. unsigned int num, den;
  738. if (mode->htotal == 0 || mode->vtotal == 0)
  739. return 0;
  740. num = mode->clock;
  741. den = mode->htotal * mode->vtotal;
  742. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  743. num *= 2;
  744. if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
  745. den *= 2;
  746. if (mode->vscan > 1)
  747. den *= mode->vscan;
  748. return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(num, 1000), den);
  749. }
  750. EXPORT_SYMBOL(drm_mode_vrefresh);
  751. /**
  752. * drm_mode_get_hv_timing - Fetches hdisplay/vdisplay for given mode
  753. * @mode: mode to query
  754. * @hdisplay: hdisplay value to fill in
  755. * @vdisplay: vdisplay value to fill in
  756. *
  757. * The vdisplay value will be doubled if the specified mode is a stereo mode of
  758. * the appropriate layout.
  759. */
  760. void drm_mode_get_hv_timing(const struct drm_display_mode *mode,
  761. int *hdisplay, int *vdisplay)
  762. {
  763. struct drm_display_mode adjusted;
  764. drm_mode_init(&adjusted, mode);
  765. drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
  766. *hdisplay = adjusted.crtc_hdisplay;
  767. *vdisplay = adjusted.crtc_vdisplay;
  768. }
  769. EXPORT_SYMBOL(drm_mode_get_hv_timing);
  770. /**
  771. * drm_mode_set_crtcinfo - set CRTC modesetting timing parameters
  772. * @p: mode
  773. * @adjust_flags: a combination of adjustment flags
  774. *
  775. * Setup the CRTC modesetting timing parameters for @p, adjusting if necessary.
  776. *
  777. * - The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of
  778. * interlaced modes.
  779. * - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for
  780. * buffers containing two eyes (only adjust the timings when needed, eg. for
  781. * "frame packing" or "side by side full").
  782. * - The CRTC_NO_DBLSCAN and CRTC_NO_VSCAN flags request that adjustment *not*
  783. * be performed for doublescan and vscan > 1 modes respectively.
  784. */
  785. void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
  786. {
  787. if (!p)
  788. return;
  789. p->crtc_clock = p->clock;
  790. p->crtc_hdisplay = p->hdisplay;
  791. p->crtc_hsync_start = p->hsync_start;
  792. p->crtc_hsync_end = p->hsync_end;
  793. p->crtc_htotal = p->htotal;
  794. p->crtc_hskew = p->hskew;
  795. p->crtc_vdisplay = p->vdisplay;
  796. p->crtc_vsync_start = p->vsync_start;
  797. p->crtc_vsync_end = p->vsync_end;
  798. p->crtc_vtotal = p->vtotal;
  799. if (p->flags & DRM_MODE_FLAG_INTERLACE) {
  800. if (adjust_flags & CRTC_INTERLACE_HALVE_V) {
  801. p->crtc_vdisplay /= 2;
  802. p->crtc_vsync_start /= 2;
  803. p->crtc_vsync_end /= 2;
  804. p->crtc_vtotal /= 2;
  805. }
  806. }
  807. if (!(adjust_flags & CRTC_NO_DBLSCAN)) {
  808. if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
  809. p->crtc_vdisplay *= 2;
  810. p->crtc_vsync_start *= 2;
  811. p->crtc_vsync_end *= 2;
  812. p->crtc_vtotal *= 2;
  813. }
  814. }
  815. if (!(adjust_flags & CRTC_NO_VSCAN)) {
  816. if (p->vscan > 1) {
  817. p->crtc_vdisplay *= p->vscan;
  818. p->crtc_vsync_start *= p->vscan;
  819. p->crtc_vsync_end *= p->vscan;
  820. p->crtc_vtotal *= p->vscan;
  821. }
  822. }
  823. if (adjust_flags & CRTC_STEREO_DOUBLE) {
  824. unsigned int layout = p->flags & DRM_MODE_FLAG_3D_MASK;
  825. switch (layout) {
  826. case DRM_MODE_FLAG_3D_FRAME_PACKING:
  827. p->crtc_clock *= 2;
  828. p->crtc_vdisplay += p->crtc_vtotal;
  829. p->crtc_vsync_start += p->crtc_vtotal;
  830. p->crtc_vsync_end += p->crtc_vtotal;
  831. p->crtc_vtotal += p->crtc_vtotal;
  832. break;
  833. }
  834. }
  835. p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay);
  836. p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal);
  837. p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay);
  838. p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal);
  839. }
  840. EXPORT_SYMBOL(drm_mode_set_crtcinfo);
  841. /**
  842. * drm_mode_copy - copy the mode
  843. * @dst: mode to overwrite
  844. * @src: mode to copy
  845. *
  846. * Copy an existing mode into another mode, preserving the
  847. * list head of the destination mode.
  848. */
  849. void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src)
  850. {
  851. struct list_head head = dst->head;
  852. *dst = *src;
  853. dst->head = head;
  854. }
  855. EXPORT_SYMBOL(drm_mode_copy);
  856. /**
  857. * drm_mode_init - initialize the mode from another mode
  858. * @dst: mode to overwrite
  859. * @src: mode to copy
  860. *
  861. * Copy an existing mode into another mode, zeroing the
  862. * list head of the destination mode. Typically used
  863. * to guarantee the list head is not left with stack
  864. * garbage in on-stack modes.
  865. */
  866. void drm_mode_init(struct drm_display_mode *dst, const struct drm_display_mode *src)
  867. {
  868. memset(dst, 0, sizeof(*dst));
  869. drm_mode_copy(dst, src);
  870. }
  871. EXPORT_SYMBOL(drm_mode_init);
  872. /**
  873. * drm_mode_duplicate - allocate and duplicate an existing mode
  874. * @dev: drm_device to allocate the duplicated mode for
  875. * @mode: mode to duplicate
  876. *
  877. * Just allocate a new mode, copy the existing mode into it, and return
  878. * a pointer to it. Used to create new instances of established modes.
  879. *
  880. * Returns:
  881. * Pointer to duplicated mode on success, NULL on error.
  882. */
  883. struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
  884. const struct drm_display_mode *mode)
  885. {
  886. struct drm_display_mode *nmode;
  887. nmode = drm_mode_create(dev);
  888. if (!nmode)
  889. return NULL;
  890. drm_mode_copy(nmode, mode);
  891. return nmode;
  892. }
  893. EXPORT_SYMBOL(drm_mode_duplicate);
  894. static bool drm_mode_match_timings(const struct drm_display_mode *mode1,
  895. const struct drm_display_mode *mode2)
  896. {
  897. return mode1->hdisplay == mode2->hdisplay &&
  898. mode1->hsync_start == mode2->hsync_start &&
  899. mode1->hsync_end == mode2->hsync_end &&
  900. mode1->htotal == mode2->htotal &&
  901. mode1->hskew == mode2->hskew &&
  902. mode1->vdisplay == mode2->vdisplay &&
  903. mode1->vsync_start == mode2->vsync_start &&
  904. mode1->vsync_end == mode2->vsync_end &&
  905. mode1->vtotal == mode2->vtotal &&
  906. mode1->vscan == mode2->vscan;
  907. }
  908. static bool drm_mode_match_clock(const struct drm_display_mode *mode1,
  909. const struct drm_display_mode *mode2)
  910. {
  911. /*
  912. * do clock check convert to PICOS
  913. * so fb modes get matched the same
  914. */
  915. if (mode1->clock && mode2->clock)
  916. return KHZ2PICOS(mode1->clock) == KHZ2PICOS(mode2->clock);
  917. else
  918. return mode1->clock == mode2->clock;
  919. }
  920. static bool drm_mode_match_flags(const struct drm_display_mode *mode1,
  921. const struct drm_display_mode *mode2)
  922. {
  923. return (mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
  924. (mode2->flags & ~DRM_MODE_FLAG_3D_MASK);
  925. }
  926. static bool drm_mode_match_3d_flags(const struct drm_display_mode *mode1,
  927. const struct drm_display_mode *mode2)
  928. {
  929. return (mode1->flags & DRM_MODE_FLAG_3D_MASK) ==
  930. (mode2->flags & DRM_MODE_FLAG_3D_MASK);
  931. }
  932. static bool drm_mode_match_aspect_ratio(const struct drm_display_mode *mode1,
  933. const struct drm_display_mode *mode2)
  934. {
  935. return mode1->picture_aspect_ratio == mode2->picture_aspect_ratio;
  936. }
  937. /**
  938. * drm_mode_match - test modes for (partial) equality
  939. * @mode1: first mode
  940. * @mode2: second mode
  941. * @match_flags: which parts need to match (DRM_MODE_MATCH_*)
  942. *
  943. * Check to see if @mode1 and @mode2 are equivalent.
  944. *
  945. * Returns:
  946. * True if the modes are (partially) equal, false otherwise.
  947. */
  948. bool drm_mode_match(const struct drm_display_mode *mode1,
  949. const struct drm_display_mode *mode2,
  950. unsigned int match_flags)
  951. {
  952. if (!mode1 && !mode2)
  953. return true;
  954. if (!mode1 || !mode2)
  955. return false;
  956. if (match_flags & DRM_MODE_MATCH_TIMINGS &&
  957. !drm_mode_match_timings(mode1, mode2))
  958. return false;
  959. if (match_flags & DRM_MODE_MATCH_CLOCK &&
  960. !drm_mode_match_clock(mode1, mode2))
  961. return false;
  962. if (match_flags & DRM_MODE_MATCH_FLAGS &&
  963. !drm_mode_match_flags(mode1, mode2))
  964. return false;
  965. if (match_flags & DRM_MODE_MATCH_3D_FLAGS &&
  966. !drm_mode_match_3d_flags(mode1, mode2))
  967. return false;
  968. if (match_flags & DRM_MODE_MATCH_ASPECT_RATIO &&
  969. !drm_mode_match_aspect_ratio(mode1, mode2))
  970. return false;
  971. return true;
  972. }
  973. EXPORT_SYMBOL(drm_mode_match);
  974. /**
  975. * drm_mode_equal - test modes for equality
  976. * @mode1: first mode
  977. * @mode2: second mode
  978. *
  979. * Check to see if @mode1 and @mode2 are equivalent.
  980. *
  981. * Returns:
  982. * True if the modes are equal, false otherwise.
  983. */
  984. bool drm_mode_equal(const struct drm_display_mode *mode1,
  985. const struct drm_display_mode *mode2)
  986. {
  987. return drm_mode_match(mode1, mode2,
  988. DRM_MODE_MATCH_TIMINGS |
  989. DRM_MODE_MATCH_CLOCK |
  990. DRM_MODE_MATCH_FLAGS |
  991. DRM_MODE_MATCH_3D_FLAGS|
  992. DRM_MODE_MATCH_ASPECT_RATIO);
  993. }
  994. EXPORT_SYMBOL(drm_mode_equal);
  995. /**
  996. * drm_mode_equal_no_clocks - test modes for equality
  997. * @mode1: first mode
  998. * @mode2: second mode
  999. *
  1000. * Check to see if @mode1 and @mode2 are equivalent, but
  1001. * don't check the pixel clocks.
  1002. *
  1003. * Returns:
  1004. * True if the modes are equal, false otherwise.
  1005. */
  1006. bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
  1007. const struct drm_display_mode *mode2)
  1008. {
  1009. return drm_mode_match(mode1, mode2,
  1010. DRM_MODE_MATCH_TIMINGS |
  1011. DRM_MODE_MATCH_FLAGS |
  1012. DRM_MODE_MATCH_3D_FLAGS);
  1013. }
  1014. EXPORT_SYMBOL(drm_mode_equal_no_clocks);
  1015. /**
  1016. * drm_mode_equal_no_clocks_no_stereo - test modes for equality
  1017. * @mode1: first mode
  1018. * @mode2: second mode
  1019. *
  1020. * Check to see if @mode1 and @mode2 are equivalent, but
  1021. * don't check the pixel clocks nor the stereo layout.
  1022. *
  1023. * Returns:
  1024. * True if the modes are equal, false otherwise.
  1025. */
  1026. bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
  1027. const struct drm_display_mode *mode2)
  1028. {
  1029. return drm_mode_match(mode1, mode2,
  1030. DRM_MODE_MATCH_TIMINGS |
  1031. DRM_MODE_MATCH_FLAGS);
  1032. }
  1033. EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
  1034. static enum drm_mode_status
  1035. drm_mode_validate_basic(const struct drm_display_mode *mode)
  1036. {
  1037. if (mode->type & ~DRM_MODE_TYPE_ALL)
  1038. return MODE_BAD;
  1039. if (mode->flags & ~DRM_MODE_FLAG_ALL)
  1040. return MODE_BAD;
  1041. if ((mode->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX)
  1042. return MODE_BAD;
  1043. if (mode->clock == 0)
  1044. return MODE_CLOCK_LOW;
  1045. if (mode->hdisplay == 0 ||
  1046. mode->hsync_start < mode->hdisplay ||
  1047. mode->hsync_end < mode->hsync_start ||
  1048. mode->htotal < mode->hsync_end)
  1049. return MODE_H_ILLEGAL;
  1050. if (mode->vdisplay == 0 ||
  1051. mode->vsync_start < mode->vdisplay ||
  1052. mode->vsync_end < mode->vsync_start ||
  1053. mode->vtotal < mode->vsync_end)
  1054. return MODE_V_ILLEGAL;
  1055. return MODE_OK;
  1056. }
  1057. /**
  1058. * drm_mode_validate_driver - make sure the mode is somewhat sane
  1059. * @dev: drm device
  1060. * @mode: mode to check
  1061. *
  1062. * First do basic validation on the mode, and then allow the driver
  1063. * to check for device/driver specific limitations via the optional
  1064. * &drm_mode_config_helper_funcs.mode_valid hook.
  1065. *
  1066. * Returns:
  1067. * The mode status
  1068. */
  1069. enum drm_mode_status
  1070. drm_mode_validate_driver(struct drm_device *dev,
  1071. const struct drm_display_mode *mode)
  1072. {
  1073. enum drm_mode_status status;
  1074. status = drm_mode_validate_basic(mode);
  1075. if (status != MODE_OK)
  1076. return status;
  1077. if (dev->mode_config.funcs->mode_valid)
  1078. return dev->mode_config.funcs->mode_valid(dev, mode);
  1079. else
  1080. return MODE_OK;
  1081. }
  1082. EXPORT_SYMBOL(drm_mode_validate_driver);
  1083. /**
  1084. * drm_mode_validate_size - make sure modes adhere to size constraints
  1085. * @mode: mode to check
  1086. * @maxX: maximum width
  1087. * @maxY: maximum height
  1088. *
  1089. * This function is a helper which can be used to validate modes against size
  1090. * limitations of the DRM device/connector. If a mode is too big its status
  1091. * member is updated with the appropriate validation failure code. The list
  1092. * itself is not changed.
  1093. *
  1094. * Returns:
  1095. * The mode status
  1096. */
  1097. enum drm_mode_status
  1098. drm_mode_validate_size(const struct drm_display_mode *mode,
  1099. int maxX, int maxY)
  1100. {
  1101. if (maxX > 0 && mode->hdisplay > maxX)
  1102. return MODE_VIRTUAL_X;
  1103. if (maxY > 0 && mode->vdisplay > maxY)
  1104. return MODE_VIRTUAL_Y;
  1105. return MODE_OK;
  1106. }
  1107. EXPORT_SYMBOL(drm_mode_validate_size);
  1108. /**
  1109. * drm_mode_validate_ycbcr420 - add 'ycbcr420-only' modes only when allowed
  1110. * @mode: mode to check
  1111. * @connector: drm connector under action
  1112. *
  1113. * This function is a helper which can be used to filter out any YCBCR420
  1114. * only mode, when the source doesn't support it.
  1115. *
  1116. * Returns:
  1117. * The mode status
  1118. */
  1119. enum drm_mode_status
  1120. drm_mode_validate_ycbcr420(const struct drm_display_mode *mode,
  1121. struct drm_connector *connector)
  1122. {
  1123. if (!connector->ycbcr_420_allowed &&
  1124. drm_mode_is_420_only(&connector->display_info, mode))
  1125. return MODE_NO_420;
  1126. return MODE_OK;
  1127. }
  1128. EXPORT_SYMBOL(drm_mode_validate_ycbcr420);
  1129. #define MODE_STATUS(status) [MODE_ ## status + 3] = #status
  1130. static const char * const drm_mode_status_names[] = {
  1131. MODE_STATUS(OK),
  1132. MODE_STATUS(HSYNC),
  1133. MODE_STATUS(VSYNC),
  1134. MODE_STATUS(H_ILLEGAL),
  1135. MODE_STATUS(V_ILLEGAL),
  1136. MODE_STATUS(BAD_WIDTH),
  1137. MODE_STATUS(NOMODE),
  1138. MODE_STATUS(NO_INTERLACE),
  1139. MODE_STATUS(NO_DBLESCAN),
  1140. MODE_STATUS(NO_VSCAN),
  1141. MODE_STATUS(MEM),
  1142. MODE_STATUS(VIRTUAL_X),
  1143. MODE_STATUS(VIRTUAL_Y),
  1144. MODE_STATUS(MEM_VIRT),
  1145. MODE_STATUS(NOCLOCK),
  1146. MODE_STATUS(CLOCK_HIGH),
  1147. MODE_STATUS(CLOCK_LOW),
  1148. MODE_STATUS(CLOCK_RANGE),
  1149. MODE_STATUS(BAD_HVALUE),
  1150. MODE_STATUS(BAD_VVALUE),
  1151. MODE_STATUS(BAD_VSCAN),
  1152. MODE_STATUS(HSYNC_NARROW),
  1153. MODE_STATUS(HSYNC_WIDE),
  1154. MODE_STATUS(HBLANK_NARROW),
  1155. MODE_STATUS(HBLANK_WIDE),
  1156. MODE_STATUS(VSYNC_NARROW),
  1157. MODE_STATUS(VSYNC_WIDE),
  1158. MODE_STATUS(VBLANK_NARROW),
  1159. MODE_STATUS(VBLANK_WIDE),
  1160. MODE_STATUS(PANEL),
  1161. MODE_STATUS(INTERLACE_WIDTH),
  1162. MODE_STATUS(ONE_WIDTH),
  1163. MODE_STATUS(ONE_HEIGHT),
  1164. MODE_STATUS(ONE_SIZE),
  1165. MODE_STATUS(NO_REDUCED),
  1166. MODE_STATUS(NO_STEREO),
  1167. MODE_STATUS(NO_420),
  1168. MODE_STATUS(STALE),
  1169. MODE_STATUS(BAD),
  1170. MODE_STATUS(ERROR),
  1171. };
  1172. #undef MODE_STATUS
  1173. const char *drm_get_mode_status_name(enum drm_mode_status status)
  1174. {
  1175. int index = status + 3;
  1176. if (WARN_ON(index < 0 || index >= ARRAY_SIZE(drm_mode_status_names)))
  1177. return "";
  1178. return drm_mode_status_names[index];
  1179. }
  1180. /**
  1181. * drm_mode_prune_invalid - remove invalid modes from mode list
  1182. * @dev: DRM device
  1183. * @mode_list: list of modes to check
  1184. * @verbose: be verbose about it
  1185. *
  1186. * This helper function can be used to prune a display mode list after
  1187. * validation has been completed. All modes whose status is not MODE_OK will be
  1188. * removed from the list, and if @verbose the status code and mode name is also
  1189. * printed to dmesg.
  1190. */
  1191. void drm_mode_prune_invalid(struct drm_device *dev,
  1192. struct list_head *mode_list, bool verbose)
  1193. {
  1194. struct drm_display_mode *mode, *t;
  1195. list_for_each_entry_safe(mode, t, mode_list, head) {
  1196. if (mode->status != MODE_OK) {
  1197. list_del(&mode->head);
  1198. if (mode->type & DRM_MODE_TYPE_USERDEF) {
  1199. drm_warn(dev, "User-defined mode not supported: "
  1200. DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
  1201. }
  1202. if (verbose) {
  1203. drm_mode_debug_printmodeline(mode);
  1204. DRM_DEBUG_KMS("Not using %s mode: %s\n",
  1205. mode->name,
  1206. drm_get_mode_status_name(mode->status));
  1207. }
  1208. drm_mode_destroy(dev, mode);
  1209. }
  1210. }
  1211. }
  1212. EXPORT_SYMBOL(drm_mode_prune_invalid);
  1213. /**
  1214. * drm_mode_compare - compare modes for favorability
  1215. * @priv: unused
  1216. * @lh_a: list_head for first mode
  1217. * @lh_b: list_head for second mode
  1218. *
  1219. * Compare two modes, given by @lh_a and @lh_b, returning a value indicating
  1220. * which is better.
  1221. *
  1222. * Returns:
  1223. * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or
  1224. * positive if @lh_b is better than @lh_a.
  1225. */
  1226. static int drm_mode_compare(void *priv, const struct list_head *lh_a,
  1227. const struct list_head *lh_b)
  1228. {
  1229. struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head);
  1230. struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head);
  1231. int diff;
  1232. diff = ((b->type & DRM_MODE_TYPE_PREFERRED) != 0) -
  1233. ((a->type & DRM_MODE_TYPE_PREFERRED) != 0);
  1234. if (diff)
  1235. return diff;
  1236. diff = b->hdisplay * b->vdisplay - a->hdisplay * a->vdisplay;
  1237. if (diff)
  1238. return diff;
  1239. diff = drm_mode_vrefresh(b) - drm_mode_vrefresh(a);
  1240. if (diff)
  1241. return diff;
  1242. diff = b->clock - a->clock;
  1243. return diff;
  1244. }
  1245. /**
  1246. * drm_mode_sort - sort mode list
  1247. * @mode_list: list of drm_display_mode structures to sort
  1248. *
  1249. * Sort @mode_list by favorability, moving good modes to the head of the list.
  1250. */
  1251. void drm_mode_sort(struct list_head *mode_list)
  1252. {
  1253. list_sort(NULL, mode_list, drm_mode_compare);
  1254. }
  1255. EXPORT_SYMBOL(drm_mode_sort);
  1256. /**
  1257. * drm_connector_list_update - update the mode list for the connector
  1258. * @connector: the connector to update
  1259. *
  1260. * This moves the modes from the @connector probed_modes list
  1261. * to the actual mode list. It compares the probed mode against the current
  1262. * list and only adds different/new modes.
  1263. *
  1264. * This is just a helper functions doesn't validate any modes itself and also
  1265. * doesn't prune any invalid modes. Callers need to do that themselves.
  1266. */
  1267. void drm_connector_list_update(struct drm_connector *connector)
  1268. {
  1269. struct drm_display_mode *pmode, *pt;
  1270. WARN_ON(!mutex_is_locked(&connector->dev->mode_config.mutex));
  1271. list_for_each_entry_safe(pmode, pt, &connector->probed_modes, head) {
  1272. struct drm_display_mode *mode;
  1273. bool found_it = false;
  1274. /* go through current modes checking for the new probed mode */
  1275. list_for_each_entry(mode, &connector->modes, head) {
  1276. if (!drm_mode_equal(pmode, mode))
  1277. continue;
  1278. found_it = true;
  1279. /*
  1280. * If the old matching mode is stale (ie. left over
  1281. * from a previous probe) just replace it outright.
  1282. * Otherwise just merge the type bits between all
  1283. * equal probed modes.
  1284. *
  1285. * If two probed modes are considered equal, pick the
  1286. * actual timings from the one that's marked as
  1287. * preferred (in case the match isn't 100%). If
  1288. * multiple or zero preferred modes are present, favor
  1289. * the mode added to the probed_modes list first.
  1290. */
  1291. if (mode->status == MODE_STALE) {
  1292. drm_mode_copy(mode, pmode);
  1293. } else if ((mode->type & DRM_MODE_TYPE_PREFERRED) == 0 &&
  1294. (pmode->type & DRM_MODE_TYPE_PREFERRED) != 0) {
  1295. pmode->type |= mode->type;
  1296. drm_mode_copy(mode, pmode);
  1297. } else {
  1298. mode->type |= pmode->type;
  1299. }
  1300. list_del(&pmode->head);
  1301. drm_mode_destroy(connector->dev, pmode);
  1302. break;
  1303. }
  1304. if (!found_it) {
  1305. list_move_tail(&pmode->head, &connector->modes);
  1306. }
  1307. }
  1308. }
  1309. EXPORT_SYMBOL(drm_connector_list_update);
  1310. static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr,
  1311. struct drm_cmdline_mode *mode)
  1312. {
  1313. unsigned int bpp;
  1314. if (str[0] != '-')
  1315. return -EINVAL;
  1316. str++;
  1317. bpp = simple_strtol(str, end_ptr, 10);
  1318. if (*end_ptr == str)
  1319. return -EINVAL;
  1320. mode->bpp = bpp;
  1321. mode->bpp_specified = true;
  1322. return 0;
  1323. }
  1324. static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr,
  1325. struct drm_cmdline_mode *mode)
  1326. {
  1327. unsigned int refresh;
  1328. if (str[0] != '@')
  1329. return -EINVAL;
  1330. str++;
  1331. refresh = simple_strtol(str, end_ptr, 10);
  1332. if (*end_ptr == str)
  1333. return -EINVAL;
  1334. mode->refresh = refresh;
  1335. mode->refresh_specified = true;
  1336. return 0;
  1337. }
  1338. static int drm_mode_parse_cmdline_extra(const char *str, int length,
  1339. bool freestanding,
  1340. const struct drm_connector *connector,
  1341. struct drm_cmdline_mode *mode)
  1342. {
  1343. int i;
  1344. for (i = 0; i < length; i++) {
  1345. switch (str[i]) {
  1346. case 'i':
  1347. if (freestanding)
  1348. return -EINVAL;
  1349. mode->interlace = true;
  1350. break;
  1351. case 'm':
  1352. if (freestanding)
  1353. return -EINVAL;
  1354. mode->margins = true;
  1355. break;
  1356. case 'D':
  1357. if (mode->force != DRM_FORCE_UNSPECIFIED)
  1358. return -EINVAL;
  1359. if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
  1360. (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
  1361. mode->force = DRM_FORCE_ON;
  1362. else
  1363. mode->force = DRM_FORCE_ON_DIGITAL;
  1364. break;
  1365. case 'd':
  1366. if (mode->force != DRM_FORCE_UNSPECIFIED)
  1367. return -EINVAL;
  1368. mode->force = DRM_FORCE_OFF;
  1369. break;
  1370. case 'e':
  1371. if (mode->force != DRM_FORCE_UNSPECIFIED)
  1372. return -EINVAL;
  1373. mode->force = DRM_FORCE_ON;
  1374. break;
  1375. default:
  1376. return -EINVAL;
  1377. }
  1378. }
  1379. return 0;
  1380. }
  1381. static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length,
  1382. bool extras,
  1383. const struct drm_connector *connector,
  1384. struct drm_cmdline_mode *mode)
  1385. {
  1386. const char *str_start = str;
  1387. bool rb = false, cvt = false;
  1388. int xres = 0, yres = 0;
  1389. int remaining, i;
  1390. char *end_ptr;
  1391. xres = simple_strtol(str, &end_ptr, 10);
  1392. if (end_ptr == str)
  1393. return -EINVAL;
  1394. if (end_ptr[0] != 'x')
  1395. return -EINVAL;
  1396. end_ptr++;
  1397. str = end_ptr;
  1398. yres = simple_strtol(str, &end_ptr, 10);
  1399. if (end_ptr == str)
  1400. return -EINVAL;
  1401. remaining = length - (end_ptr - str_start);
  1402. if (remaining < 0)
  1403. return -EINVAL;
  1404. for (i = 0; i < remaining; i++) {
  1405. switch (end_ptr[i]) {
  1406. case 'M':
  1407. cvt = true;
  1408. break;
  1409. case 'R':
  1410. rb = true;
  1411. break;
  1412. default:
  1413. /*
  1414. * Try to pass that to our extras parsing
  1415. * function to handle the case where the
  1416. * extras are directly after the resolution
  1417. */
  1418. if (extras) {
  1419. int ret = drm_mode_parse_cmdline_extra(end_ptr + i,
  1420. 1,
  1421. false,
  1422. connector,
  1423. mode);
  1424. if (ret)
  1425. return ret;
  1426. } else {
  1427. return -EINVAL;
  1428. }
  1429. }
  1430. }
  1431. mode->xres = xres;
  1432. mode->yres = yres;
  1433. mode->cvt = cvt;
  1434. mode->rb = rb;
  1435. return 0;
  1436. }
  1437. static int drm_mode_parse_cmdline_int(const char *delim, unsigned int *int_ret)
  1438. {
  1439. const char *value;
  1440. char *endp;
  1441. /*
  1442. * delim must point to the '=', otherwise it is a syntax error and
  1443. * if delim points to the terminating zero, then delim + 1 will point
  1444. * past the end of the string.
  1445. */
  1446. if (*delim != '=')
  1447. return -EINVAL;
  1448. value = delim + 1;
  1449. *int_ret = simple_strtol(value, &endp, 10);
  1450. /* Make sure we have parsed something */
  1451. if (endp == value)
  1452. return -EINVAL;
  1453. return 0;
  1454. }
  1455. static int drm_mode_parse_panel_orientation(const char *delim,
  1456. struct drm_cmdline_mode *mode)
  1457. {
  1458. const char *value;
  1459. if (*delim != '=')
  1460. return -EINVAL;
  1461. value = delim + 1;
  1462. delim = strchr(value, ',');
  1463. if (!delim)
  1464. delim = value + strlen(value);
  1465. if (!strncmp(value, "normal", delim - value))
  1466. mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
  1467. else if (!strncmp(value, "upside_down", delim - value))
  1468. mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
  1469. else if (!strncmp(value, "left_side_up", delim - value))
  1470. mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
  1471. else if (!strncmp(value, "right_side_up", delim - value))
  1472. mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
  1473. else
  1474. return -EINVAL;
  1475. return 0;
  1476. }
  1477. static int drm_mode_parse_cmdline_options(const char *str,
  1478. bool freestanding,
  1479. const struct drm_connector *connector,
  1480. struct drm_cmdline_mode *mode)
  1481. {
  1482. unsigned int deg, margin, rotation = 0;
  1483. const char *delim, *option, *sep;
  1484. option = str;
  1485. do {
  1486. delim = strchr(option, '=');
  1487. if (!delim) {
  1488. delim = strchr(option, ',');
  1489. if (!delim)
  1490. delim = option + strlen(option);
  1491. }
  1492. if (!strncmp(option, "rotate", delim - option)) {
  1493. if (drm_mode_parse_cmdline_int(delim, &deg))
  1494. return -EINVAL;
  1495. switch (deg) {
  1496. case 0:
  1497. rotation |= DRM_MODE_ROTATE_0;
  1498. break;
  1499. case 90:
  1500. rotation |= DRM_MODE_ROTATE_90;
  1501. break;
  1502. case 180:
  1503. rotation |= DRM_MODE_ROTATE_180;
  1504. break;
  1505. case 270:
  1506. rotation |= DRM_MODE_ROTATE_270;
  1507. break;
  1508. default:
  1509. return -EINVAL;
  1510. }
  1511. } else if (!strncmp(option, "reflect_x", delim - option)) {
  1512. rotation |= DRM_MODE_REFLECT_X;
  1513. } else if (!strncmp(option, "reflect_y", delim - option)) {
  1514. rotation |= DRM_MODE_REFLECT_Y;
  1515. } else if (!strncmp(option, "margin_right", delim - option)) {
  1516. if (drm_mode_parse_cmdline_int(delim, &margin))
  1517. return -EINVAL;
  1518. mode->tv_margins.right = margin;
  1519. } else if (!strncmp(option, "margin_left", delim - option)) {
  1520. if (drm_mode_parse_cmdline_int(delim, &margin))
  1521. return -EINVAL;
  1522. mode->tv_margins.left = margin;
  1523. } else if (!strncmp(option, "margin_top", delim - option)) {
  1524. if (drm_mode_parse_cmdline_int(delim, &margin))
  1525. return -EINVAL;
  1526. mode->tv_margins.top = margin;
  1527. } else if (!strncmp(option, "margin_bottom", delim - option)) {
  1528. if (drm_mode_parse_cmdline_int(delim, &margin))
  1529. return -EINVAL;
  1530. mode->tv_margins.bottom = margin;
  1531. } else if (!strncmp(option, "panel_orientation", delim - option)) {
  1532. if (drm_mode_parse_panel_orientation(delim, mode))
  1533. return -EINVAL;
  1534. } else {
  1535. return -EINVAL;
  1536. }
  1537. sep = strchr(delim, ',');
  1538. option = sep + 1;
  1539. } while (sep);
  1540. if (rotation && freestanding)
  1541. return -EINVAL;
  1542. if (!(rotation & DRM_MODE_ROTATE_MASK))
  1543. rotation |= DRM_MODE_ROTATE_0;
  1544. /* Make sure there is exactly one rotation defined */
  1545. if (!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK))
  1546. return -EINVAL;
  1547. mode->rotation_reflection = rotation;
  1548. return 0;
  1549. }
  1550. static const char * const drm_named_modes_whitelist[] = {
  1551. "NTSC",
  1552. "PAL",
  1553. };
  1554. /**
  1555. * drm_mode_parse_command_line_for_connector - parse command line modeline for connector
  1556. * @mode_option: optional per connector mode option
  1557. * @connector: connector to parse modeline for
  1558. * @mode: preallocated drm_cmdline_mode structure to fill out
  1559. *
  1560. * This parses @mode_option command line modeline for modes and options to
  1561. * configure the connector. If @mode_option is NULL the default command line
  1562. * modeline in fb_mode_option will be parsed instead.
  1563. *
  1564. * This uses the same parameters as the fb modedb.c, except for an extra
  1565. * force-enable, force-enable-digital and force-disable bit at the end::
  1566. *
  1567. * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
  1568. *
  1569. * Additionals options can be provided following the mode, using a comma to
  1570. * separate each option. Valid options can be found in
  1571. * Documentation/fb/modedb.rst.
  1572. *
  1573. * The intermediate drm_cmdline_mode structure is required to store additional
  1574. * options from the command line modline like the force-enable/disable flag.
  1575. *
  1576. * Returns:
  1577. * True if a valid modeline has been parsed, false otherwise.
  1578. */
  1579. bool drm_mode_parse_command_line_for_connector(const char *mode_option,
  1580. const struct drm_connector *connector,
  1581. struct drm_cmdline_mode *mode)
  1582. {
  1583. const char *name;
  1584. bool freestanding = false, parse_extras = false;
  1585. unsigned int bpp_off = 0, refresh_off = 0, options_off = 0;
  1586. unsigned int mode_end = 0;
  1587. const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
  1588. const char *options_ptr = NULL;
  1589. char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL;
  1590. int i, len, ret;
  1591. memset(mode, 0, sizeof(*mode));
  1592. mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
  1593. if (!mode_option)
  1594. return false;
  1595. name = mode_option;
  1596. /* Try to locate the bpp and refresh specifiers, if any */
  1597. bpp_ptr = strchr(name, '-');
  1598. if (bpp_ptr)
  1599. bpp_off = bpp_ptr - name;
  1600. refresh_ptr = strchr(name, '@');
  1601. if (refresh_ptr)
  1602. refresh_off = refresh_ptr - name;
  1603. /* Locate the start of named options */
  1604. options_ptr = strchr(name, ',');
  1605. if (options_ptr)
  1606. options_off = options_ptr - name;
  1607. /* Locate the end of the name / resolution, and parse it */
  1608. if (bpp_ptr) {
  1609. mode_end = bpp_off;
  1610. } else if (refresh_ptr) {
  1611. mode_end = refresh_off;
  1612. } else if (options_ptr) {
  1613. mode_end = options_off;
  1614. parse_extras = true;
  1615. } else {
  1616. mode_end = strlen(name);
  1617. parse_extras = true;
  1618. }
  1619. /* First check for a named mode */
  1620. for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
  1621. ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
  1622. if (ret == mode_end) {
  1623. if (refresh_ptr)
  1624. return false; /* named + refresh is invalid */
  1625. strcpy(mode->name, drm_named_modes_whitelist[i]);
  1626. mode->specified = true;
  1627. break;
  1628. }
  1629. }
  1630. /* No named mode? Check for a normal mode argument, e.g. 1024x768 */
  1631. if (!mode->specified && isdigit(name[0])) {
  1632. ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
  1633. parse_extras,
  1634. connector,
  1635. mode);
  1636. if (ret)
  1637. return false;
  1638. mode->specified = true;
  1639. }
  1640. /* No mode? Check for freestanding extras and/or options */
  1641. if (!mode->specified) {
  1642. unsigned int len = strlen(mode_option);
  1643. if (bpp_ptr || refresh_ptr)
  1644. return false; /* syntax error */
  1645. if (len == 1 || (len >= 2 && mode_option[1] == ','))
  1646. extra_ptr = mode_option;
  1647. else
  1648. options_ptr = mode_option - 1;
  1649. freestanding = true;
  1650. }
  1651. if (bpp_ptr) {
  1652. ret = drm_mode_parse_cmdline_bpp(bpp_ptr, &bpp_end_ptr, mode);
  1653. if (ret)
  1654. return false;
  1655. mode->bpp_specified = true;
  1656. }
  1657. if (refresh_ptr) {
  1658. ret = drm_mode_parse_cmdline_refresh(refresh_ptr,
  1659. &refresh_end_ptr, mode);
  1660. if (ret)
  1661. return false;
  1662. mode->refresh_specified = true;
  1663. }
  1664. /*
  1665. * Locate the end of the bpp / refresh, and parse the extras
  1666. * if relevant
  1667. */
  1668. if (bpp_ptr && refresh_ptr)
  1669. extra_ptr = max(bpp_end_ptr, refresh_end_ptr);
  1670. else if (bpp_ptr)
  1671. extra_ptr = bpp_end_ptr;
  1672. else if (refresh_ptr)
  1673. extra_ptr = refresh_end_ptr;
  1674. if (extra_ptr) {
  1675. if (options_ptr)
  1676. len = options_ptr - extra_ptr;
  1677. else
  1678. len = strlen(extra_ptr);
  1679. ret = drm_mode_parse_cmdline_extra(extra_ptr, len, freestanding,
  1680. connector, mode);
  1681. if (ret)
  1682. return false;
  1683. }
  1684. if (options_ptr) {
  1685. ret = drm_mode_parse_cmdline_options(options_ptr + 1,
  1686. freestanding,
  1687. connector, mode);
  1688. if (ret)
  1689. return false;
  1690. }
  1691. return true;
  1692. }
  1693. EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
  1694. /**
  1695. * drm_mode_create_from_cmdline_mode - convert a command line modeline into a DRM display mode
  1696. * @dev: DRM device to create the new mode for
  1697. * @cmd: input command line modeline
  1698. *
  1699. * Returns:
  1700. * Pointer to converted mode on success, NULL on error.
  1701. */
  1702. struct drm_display_mode *
  1703. drm_mode_create_from_cmdline_mode(struct drm_device *dev,
  1704. struct drm_cmdline_mode *cmd)
  1705. {
  1706. struct drm_display_mode *mode;
  1707. if (cmd->xres == 0 || cmd->yres == 0)
  1708. return NULL;
  1709. if (cmd->cvt)
  1710. mode = drm_cvt_mode(dev,
  1711. cmd->xres, cmd->yres,
  1712. cmd->refresh_specified ? cmd->refresh : 60,
  1713. cmd->rb, cmd->interlace,
  1714. cmd->margins);
  1715. else
  1716. mode = drm_gtf_mode(dev,
  1717. cmd->xres, cmd->yres,
  1718. cmd->refresh_specified ? cmd->refresh : 60,
  1719. cmd->interlace,
  1720. cmd->margins);
  1721. if (!mode)
  1722. return NULL;
  1723. mode->type |= DRM_MODE_TYPE_USERDEF;
  1724. /* fix up 1368x768: GFT/CVT can't express 1366 width due to alignment */
  1725. if (cmd->xres == 1366)
  1726. drm_mode_fixup_1366x768(mode);
  1727. drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  1728. return mode;
  1729. }
  1730. EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode);
  1731. /**
  1732. * drm_mode_convert_to_umode - convert a drm_display_mode into a modeinfo
  1733. * @out: drm_mode_modeinfo struct to return to the user
  1734. * @in: drm_display_mode to use
  1735. *
  1736. * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
  1737. * the user.
  1738. */
  1739. void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
  1740. const struct drm_display_mode *in)
  1741. {
  1742. out->clock = in->clock;
  1743. out->hdisplay = in->hdisplay;
  1744. out->hsync_start = in->hsync_start;
  1745. out->hsync_end = in->hsync_end;
  1746. out->htotal = in->htotal;
  1747. out->hskew = in->hskew;
  1748. out->vdisplay = in->vdisplay;
  1749. out->vsync_start = in->vsync_start;
  1750. out->vsync_end = in->vsync_end;
  1751. out->vtotal = in->vtotal;
  1752. out->vscan = in->vscan;
  1753. out->vrefresh = drm_mode_vrefresh(in);
  1754. out->flags = in->flags;
  1755. out->type = in->type;
  1756. switch (in->picture_aspect_ratio) {
  1757. case HDMI_PICTURE_ASPECT_4_3:
  1758. out->flags |= DRM_MODE_FLAG_PIC_AR_4_3;
  1759. break;
  1760. case HDMI_PICTURE_ASPECT_16_9:
  1761. out->flags |= DRM_MODE_FLAG_PIC_AR_16_9;
  1762. break;
  1763. case HDMI_PICTURE_ASPECT_64_27:
  1764. out->flags |= DRM_MODE_FLAG_PIC_AR_64_27;
  1765. break;
  1766. case HDMI_PICTURE_ASPECT_256_135:
  1767. out->flags |= DRM_MODE_FLAG_PIC_AR_256_135;
  1768. break;
  1769. default:
  1770. WARN(1, "Invalid aspect ratio (0%x) on mode\n",
  1771. in->picture_aspect_ratio);
  1772. fallthrough;
  1773. case HDMI_PICTURE_ASPECT_NONE:
  1774. out->flags |= DRM_MODE_FLAG_PIC_AR_NONE;
  1775. break;
  1776. }
  1777. strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  1778. out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  1779. }
  1780. EXPORT_SYMBOL_GPL(drm_mode_convert_to_umode);
  1781. /**
  1782. * drm_mode_convert_umode - convert a modeinfo into a drm_display_mode
  1783. * @dev: drm device
  1784. * @out: drm_display_mode to return to the user
  1785. * @in: drm_mode_modeinfo to use
  1786. *
  1787. * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
  1788. * the caller.
  1789. *
  1790. * Returns:
  1791. * Zero on success, negative errno on failure.
  1792. */
  1793. int drm_mode_convert_umode(struct drm_device *dev,
  1794. struct drm_display_mode *out,
  1795. const struct drm_mode_modeinfo *in)
  1796. {
  1797. if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
  1798. return -ERANGE;
  1799. out->clock = in->clock;
  1800. out->hdisplay = in->hdisplay;
  1801. out->hsync_start = in->hsync_start;
  1802. out->hsync_end = in->hsync_end;
  1803. out->htotal = in->htotal;
  1804. out->hskew = in->hskew;
  1805. out->vdisplay = in->vdisplay;
  1806. out->vsync_start = in->vsync_start;
  1807. out->vsync_end = in->vsync_end;
  1808. out->vtotal = in->vtotal;
  1809. out->vscan = in->vscan;
  1810. out->flags = in->flags;
  1811. /*
  1812. * Old xf86-video-vmware (possibly others too) used to
  1813. * leave 'type' uninitialized. Just ignore any bits we
  1814. * don't like. It's a just hint after all, and more
  1815. * useful for the kernel->userspace direction anyway.
  1816. */
  1817. out->type = in->type & DRM_MODE_TYPE_ALL;
  1818. strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
  1819. out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
  1820. /* Clearing picture aspect ratio bits from out flags,
  1821. * as the aspect-ratio information is not stored in
  1822. * flags for kernel-mode, but in picture_aspect_ratio.
  1823. */
  1824. out->flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
  1825. switch (in->flags & DRM_MODE_FLAG_PIC_AR_MASK) {
  1826. case DRM_MODE_FLAG_PIC_AR_4_3:
  1827. out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
  1828. break;
  1829. case DRM_MODE_FLAG_PIC_AR_16_9:
  1830. out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
  1831. break;
  1832. case DRM_MODE_FLAG_PIC_AR_64_27:
  1833. out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27;
  1834. break;
  1835. case DRM_MODE_FLAG_PIC_AR_256_135:
  1836. out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135;
  1837. break;
  1838. case DRM_MODE_FLAG_PIC_AR_NONE:
  1839. out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
  1840. break;
  1841. default:
  1842. return -EINVAL;
  1843. }
  1844. out->status = drm_mode_validate_driver(dev, out);
  1845. if (out->status != MODE_OK)
  1846. return -EINVAL;
  1847. drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
  1848. return 0;
  1849. }
  1850. EXPORT_SYMBOL_GPL(drm_mode_convert_umode);
  1851. /**
  1852. * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
  1853. * output format
  1854. *
  1855. * @display: display under action
  1856. * @mode: video mode to be tested.
  1857. *
  1858. * Returns:
  1859. * true if the mode can be supported in YCBCR420 format
  1860. * false if not.
  1861. */
  1862. bool drm_mode_is_420_only(const struct drm_display_info *display,
  1863. const struct drm_display_mode *mode)
  1864. {
  1865. u8 vic = drm_match_cea_mode(mode);
  1866. return test_bit(vic, display->hdmi.y420_vdb_modes);
  1867. }
  1868. EXPORT_SYMBOL(drm_mode_is_420_only);
  1869. /**
  1870. * drm_mode_is_420_also - if a given videomode can be supported in YCBCR420
  1871. * output format also (along with RGB/YCBCR444/422)
  1872. *
  1873. * @display: display under action.
  1874. * @mode: video mode to be tested.
  1875. *
  1876. * Returns:
  1877. * true if the mode can be support YCBCR420 format
  1878. * false if not.
  1879. */
  1880. bool drm_mode_is_420_also(const struct drm_display_info *display,
  1881. const struct drm_display_mode *mode)
  1882. {
  1883. u8 vic = drm_match_cea_mode(mode);
  1884. return test_bit(vic, display->hdmi.y420_cmdb_modes);
  1885. }
  1886. EXPORT_SYMBOL(drm_mode_is_420_also);
  1887. /**
  1888. * drm_mode_is_420 - if a given videomode can be supported in YCBCR420
  1889. * output format
  1890. *
  1891. * @display: display under action.
  1892. * @mode: video mode to be tested.
  1893. *
  1894. * Returns:
  1895. * true if the mode can be supported in YCBCR420 format
  1896. * false if not.
  1897. */
  1898. bool drm_mode_is_420(const struct drm_display_info *display,
  1899. const struct drm_display_mode *mode)
  1900. {
  1901. return drm_mode_is_420_only(display, mode) ||
  1902. drm_mode_is_420_also(display, mode);
  1903. }
  1904. EXPORT_SYMBOL(drm_mode_is_420);