fbmon.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599
  1. /*
  2. * linux/drivers/video/fbmon.c
  3. *
  4. * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net>
  5. *
  6. * Credits:
  7. *
  8. * The EDID Parser is a conglomeration from the following sources:
  9. *
  10. * 1. SciTech SNAP Graphics Architecture
  11. * Copyright (C) 1991-2002 SciTech Software, Inc. All rights reserved.
  12. *
  13. * 2. XFree86 4.3.0, interpret_edid.c
  14. * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
  15. *
  16. * 3. John Fremlin <vii@users.sourceforge.net> and
  17. * Ani Joshi <ajoshi@unixbox.com>
  18. *
  19. * Generalized Timing Formula is derived from:
  20. *
  21. * GTF Spreadsheet by Andy Morrish (1/5/97)
  22. * available at http://www.vesa.org
  23. *
  24. * This file is subject to the terms and conditions of the GNU General Public
  25. * License. See the file COPYING in the main directory of this archive
  26. * for more details.
  27. *
  28. */
  29. #include <linux/fb.h>
  30. #include <linux/module.h>
  31. #include <linux/pci.h>
  32. #include <linux/slab.h>
  33. #include <video/edid.h>
  34. #include <video/of_videomode.h>
  35. #include <video/videomode.h>
  36. #ifdef CONFIG_PPC_OF
  37. #include <asm/prom.h>
  38. #include <asm/pci-bridge.h>
  39. #endif
  40. #include "../edid.h"
  41. /*
  42. * EDID parser
  43. */
  44. #undef DEBUG /* define this for verbose EDID parsing output */
  45. #ifdef DEBUG
  46. #define DPRINTK(fmt, args...) printk(fmt,## args)
  47. #else
  48. #define DPRINTK(fmt, args...)
  49. #endif
  50. #define FBMON_FIX_HEADER 1
  51. #define FBMON_FIX_INPUT 2
  52. #define FBMON_FIX_TIMINGS 3
  53. #ifdef CONFIG_FB_MODE_HELPERS
  54. struct broken_edid {
  55. u8 manufacturer[4];
  56. u32 model;
  57. u32 fix;
  58. };
  59. static const struct broken_edid brokendb[] = {
  60. /* DEC FR-PCXAV-YZ */
  61. {
  62. .manufacturer = "DEC",
  63. .model = 0x073a,
  64. .fix = FBMON_FIX_HEADER,
  65. },
  66. /* ViewSonic PF775a */
  67. {
  68. .manufacturer = "VSC",
  69. .model = 0x5a44,
  70. .fix = FBMON_FIX_INPUT,
  71. },
  72. /* Sharp UXGA? */
  73. {
  74. .manufacturer = "SHP",
  75. .model = 0x138e,
  76. .fix = FBMON_FIX_TIMINGS,
  77. },
  78. };
  79. static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff,
  80. 0xff, 0xff, 0xff, 0x00
  81. };
  82. static void copy_string(unsigned char *c, unsigned char *s)
  83. {
  84. int i;
  85. c = c + 5;
  86. for (i = 0; (i < 13 && *c != 0x0A); i++)
  87. *(s++) = *(c++);
  88. *s = 0;
  89. while (i-- && (*--s == 0x20)) *s = 0;
  90. }
  91. static int edid_is_serial_block(unsigned char *block)
  92. {
  93. if ((block[0] == 0x00) && (block[1] == 0x00) &&
  94. (block[2] == 0x00) && (block[3] == 0xff) &&
  95. (block[4] == 0x00))
  96. return 1;
  97. else
  98. return 0;
  99. }
  100. static int edid_is_ascii_block(unsigned char *block)
  101. {
  102. if ((block[0] == 0x00) && (block[1] == 0x00) &&
  103. (block[2] == 0x00) && (block[3] == 0xfe) &&
  104. (block[4] == 0x00))
  105. return 1;
  106. else
  107. return 0;
  108. }
  109. static int edid_is_limits_block(unsigned char *block)
  110. {
  111. if ((block[0] == 0x00) && (block[1] == 0x00) &&
  112. (block[2] == 0x00) && (block[3] == 0xfd) &&
  113. (block[4] == 0x00))
  114. return 1;
  115. else
  116. return 0;
  117. }
  118. static int edid_is_monitor_block(unsigned char *block)
  119. {
  120. if ((block[0] == 0x00) && (block[1] == 0x00) &&
  121. (block[2] == 0x00) && (block[3] == 0xfc) &&
  122. (block[4] == 0x00))
  123. return 1;
  124. else
  125. return 0;
  126. }
  127. static int edid_is_timing_block(unsigned char *block)
  128. {
  129. if ((block[0] != 0x00) || (block[1] != 0x00) ||
  130. (block[2] != 0x00) || (block[4] != 0x00))
  131. return 1;
  132. else
  133. return 0;
  134. }
  135. static int check_edid(unsigned char *edid)
  136. {
  137. unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
  138. unsigned char *b;
  139. u32 model;
  140. int i, fix = 0, ret = 0;
  141. manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
  142. manufacturer[1] = ((block[0] & 0x03) << 3) +
  143. ((block[1] & 0xe0) >> 5) + '@';
  144. manufacturer[2] = (block[1] & 0x1f) + '@';
  145. manufacturer[3] = 0;
  146. model = block[2] + (block[3] << 8);
  147. for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
  148. if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
  149. brokendb[i].model == model) {
  150. fix = brokendb[i].fix;
  151. break;
  152. }
  153. }
  154. switch (fix) {
  155. case FBMON_FIX_HEADER:
  156. for (i = 0; i < 8; i++) {
  157. if (edid[i] != edid_v1_header[i]) {
  158. ret = fix;
  159. break;
  160. }
  161. }
  162. break;
  163. case FBMON_FIX_INPUT:
  164. b = edid + EDID_STRUCT_DISPLAY;
  165. /* Only if display is GTF capable will
  166. the input type be reset to analog */
  167. if (b[4] & 0x01 && b[0] & 0x80)
  168. ret = fix;
  169. break;
  170. case FBMON_FIX_TIMINGS:
  171. b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
  172. ret = fix;
  173. for (i = 0; i < 4; i++) {
  174. if (edid_is_limits_block(b)) {
  175. ret = 0;
  176. break;
  177. }
  178. b += DETAILED_TIMING_DESCRIPTION_SIZE;
  179. }
  180. break;
  181. }
  182. if (ret)
  183. printk("fbmon: The EDID Block of "
  184. "Manufacturer: %s Model: 0x%x is known to "
  185. "be broken,\n", manufacturer, model);
  186. return ret;
  187. }
  188. static void fix_edid(unsigned char *edid, int fix)
  189. {
  190. int i;
  191. unsigned char *b, csum = 0;
  192. switch (fix) {
  193. case FBMON_FIX_HEADER:
  194. printk("fbmon: trying a header reconstruct\n");
  195. memcpy(edid, edid_v1_header, 8);
  196. break;
  197. case FBMON_FIX_INPUT:
  198. printk("fbmon: trying to fix input type\n");
  199. b = edid + EDID_STRUCT_DISPLAY;
  200. b[0] &= ~0x80;
  201. edid[127] += 0x80;
  202. break;
  203. case FBMON_FIX_TIMINGS:
  204. printk("fbmon: trying to fix monitor timings\n");
  205. b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
  206. for (i = 0; i < 4; i++) {
  207. if (!(edid_is_serial_block(b) ||
  208. edid_is_ascii_block(b) ||
  209. edid_is_monitor_block(b) ||
  210. edid_is_timing_block(b))) {
  211. b[0] = 0x00;
  212. b[1] = 0x00;
  213. b[2] = 0x00;
  214. b[3] = 0xfd;
  215. b[4] = 0x00;
  216. b[5] = 60; /* vfmin */
  217. b[6] = 60; /* vfmax */
  218. b[7] = 30; /* hfmin */
  219. b[8] = 75; /* hfmax */
  220. b[9] = 17; /* pixclock - 170 MHz*/
  221. b[10] = 0; /* GTF */
  222. break;
  223. }
  224. b += DETAILED_TIMING_DESCRIPTION_SIZE;
  225. }
  226. for (i = 0; i < EDID_LENGTH - 1; i++)
  227. csum += edid[i];
  228. edid[127] = 256 - csum;
  229. break;
  230. }
  231. }
  232. static int edid_checksum(unsigned char *edid)
  233. {
  234. unsigned char csum = 0, all_null = 0;
  235. int i, err = 0, fix = check_edid(edid);
  236. if (fix)
  237. fix_edid(edid, fix);
  238. for (i = 0; i < EDID_LENGTH; i++) {
  239. csum += edid[i];
  240. all_null |= edid[i];
  241. }
  242. if (csum == 0x00 && all_null) {
  243. /* checksum passed, everything's good */
  244. err = 1;
  245. }
  246. return err;
  247. }
  248. static int edid_check_header(unsigned char *edid)
  249. {
  250. int i, err = 1, fix = check_edid(edid);
  251. if (fix)
  252. fix_edid(edid, fix);
  253. for (i = 0; i < 8; i++) {
  254. if (edid[i] != edid_v1_header[i])
  255. err = 0;
  256. }
  257. return err;
  258. }
  259. static void parse_vendor_block(unsigned char *block, struct fb_monspecs *specs)
  260. {
  261. specs->manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
  262. specs->manufacturer[1] = ((block[0] & 0x03) << 3) +
  263. ((block[1] & 0xe0) >> 5) + '@';
  264. specs->manufacturer[2] = (block[1] & 0x1f) + '@';
  265. specs->manufacturer[3] = 0;
  266. specs->model = block[2] + (block[3] << 8);
  267. specs->serial = block[4] + (block[5] << 8) +
  268. (block[6] << 16) + (block[7] << 24);
  269. specs->year = block[9] + 1990;
  270. specs->week = block[8];
  271. DPRINTK(" Manufacturer: %s\n", specs->manufacturer);
  272. DPRINTK(" Model: %x\n", specs->model);
  273. DPRINTK(" Serial#: %u\n", specs->serial);
  274. DPRINTK(" Year: %u Week %u\n", specs->year, specs->week);
  275. }
  276. static void get_dpms_capabilities(unsigned char flags,
  277. struct fb_monspecs *specs)
  278. {
  279. specs->dpms = 0;
  280. if (flags & DPMS_ACTIVE_OFF)
  281. specs->dpms |= FB_DPMS_ACTIVE_OFF;
  282. if (flags & DPMS_SUSPEND)
  283. specs->dpms |= FB_DPMS_SUSPEND;
  284. if (flags & DPMS_STANDBY)
  285. specs->dpms |= FB_DPMS_STANDBY;
  286. DPRINTK(" DPMS: Active %s, Suspend %s, Standby %s\n",
  287. (flags & DPMS_ACTIVE_OFF) ? "yes" : "no",
  288. (flags & DPMS_SUSPEND) ? "yes" : "no",
  289. (flags & DPMS_STANDBY) ? "yes" : "no");
  290. }
  291. static void get_chroma(unsigned char *block, struct fb_monspecs *specs)
  292. {
  293. int tmp;
  294. DPRINTK(" Chroma\n");
  295. /* Chromaticity data */
  296. tmp = ((block[5] & (3 << 6)) >> 6) | (block[0x7] << 2);
  297. tmp *= 1000;
  298. tmp += 512;
  299. specs->chroma.redx = tmp/1024;
  300. DPRINTK(" RedX: 0.%03d ", specs->chroma.redx);
  301. tmp = ((block[5] & (3 << 4)) >> 4) | (block[0x8] << 2);
  302. tmp *= 1000;
  303. tmp += 512;
  304. specs->chroma.redy = tmp/1024;
  305. DPRINTK("RedY: 0.%03d\n", specs->chroma.redy);
  306. tmp = ((block[5] & (3 << 2)) >> 2) | (block[0x9] << 2);
  307. tmp *= 1000;
  308. tmp += 512;
  309. specs->chroma.greenx = tmp/1024;
  310. DPRINTK(" GreenX: 0.%03d ", specs->chroma.greenx);
  311. tmp = (block[5] & 3) | (block[0xa] << 2);
  312. tmp *= 1000;
  313. tmp += 512;
  314. specs->chroma.greeny = tmp/1024;
  315. DPRINTK("GreenY: 0.%03d\n", specs->chroma.greeny);
  316. tmp = ((block[6] & (3 << 6)) >> 6) | (block[0xb] << 2);
  317. tmp *= 1000;
  318. tmp += 512;
  319. specs->chroma.bluex = tmp/1024;
  320. DPRINTK(" BlueX: 0.%03d ", specs->chroma.bluex);
  321. tmp = ((block[6] & (3 << 4)) >> 4) | (block[0xc] << 2);
  322. tmp *= 1000;
  323. tmp += 512;
  324. specs->chroma.bluey = tmp/1024;
  325. DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey);
  326. tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2);
  327. tmp *= 1000;
  328. tmp += 512;
  329. specs->chroma.whitex = tmp/1024;
  330. DPRINTK(" WhiteX: 0.%03d ", specs->chroma.whitex);
  331. tmp = (block[6] & 3) | (block[0xe] << 2);
  332. tmp *= 1000;
  333. tmp += 512;
  334. specs->chroma.whitey = tmp/1024;
  335. DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey);
  336. }
  337. static void calc_mode_timings(int xres, int yres, int refresh,
  338. struct fb_videomode *mode)
  339. {
  340. struct fb_var_screeninfo *var;
  341. var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL);
  342. if (var) {
  343. var->xres = xres;
  344. var->yres = yres;
  345. fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON,
  346. refresh, var, NULL);
  347. mode->xres = xres;
  348. mode->yres = yres;
  349. mode->pixclock = var->pixclock;
  350. mode->refresh = refresh;
  351. mode->left_margin = var->left_margin;
  352. mode->right_margin = var->right_margin;
  353. mode->upper_margin = var->upper_margin;
  354. mode->lower_margin = var->lower_margin;
  355. mode->hsync_len = var->hsync_len;
  356. mode->vsync_len = var->vsync_len;
  357. mode->vmode = 0;
  358. mode->sync = 0;
  359. kfree(var);
  360. }
  361. }
  362. static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
  363. {
  364. int num = 0;
  365. unsigned char c;
  366. c = block[0];
  367. if (c&0x80) {
  368. calc_mode_timings(720, 400, 70, &mode[num]);
  369. mode[num++].flag = FB_MODE_IS_CALCULATED;
  370. DPRINTK(" 720x400@70Hz\n");
  371. }
  372. if (c&0x40) {
  373. calc_mode_timings(720, 400, 88, &mode[num]);
  374. mode[num++].flag = FB_MODE_IS_CALCULATED;
  375. DPRINTK(" 720x400@88Hz\n");
  376. }
  377. if (c&0x20) {
  378. mode[num++] = vesa_modes[3];
  379. DPRINTK(" 640x480@60Hz\n");
  380. }
  381. if (c&0x10) {
  382. calc_mode_timings(640, 480, 67, &mode[num]);
  383. mode[num++].flag = FB_MODE_IS_CALCULATED;
  384. DPRINTK(" 640x480@67Hz\n");
  385. }
  386. if (c&0x08) {
  387. mode[num++] = vesa_modes[4];
  388. DPRINTK(" 640x480@72Hz\n");
  389. }
  390. if (c&0x04) {
  391. mode[num++] = vesa_modes[5];
  392. DPRINTK(" 640x480@75Hz\n");
  393. }
  394. if (c&0x02) {
  395. mode[num++] = vesa_modes[7];
  396. DPRINTK(" 800x600@56Hz\n");
  397. }
  398. if (c&0x01) {
  399. mode[num++] = vesa_modes[8];
  400. DPRINTK(" 800x600@60Hz\n");
  401. }
  402. c = block[1];
  403. if (c&0x80) {
  404. mode[num++] = vesa_modes[9];
  405. DPRINTK(" 800x600@72Hz\n");
  406. }
  407. if (c&0x40) {
  408. mode[num++] = vesa_modes[10];
  409. DPRINTK(" 800x600@75Hz\n");
  410. }
  411. if (c&0x20) {
  412. calc_mode_timings(832, 624, 75, &mode[num]);
  413. mode[num++].flag = FB_MODE_IS_CALCULATED;
  414. DPRINTK(" 832x624@75Hz\n");
  415. }
  416. if (c&0x10) {
  417. mode[num++] = vesa_modes[12];
  418. DPRINTK(" 1024x768@87Hz Interlaced\n");
  419. }
  420. if (c&0x08) {
  421. mode[num++] = vesa_modes[13];
  422. DPRINTK(" 1024x768@60Hz\n");
  423. }
  424. if (c&0x04) {
  425. mode[num++] = vesa_modes[14];
  426. DPRINTK(" 1024x768@70Hz\n");
  427. }
  428. if (c&0x02) {
  429. mode[num++] = vesa_modes[15];
  430. DPRINTK(" 1024x768@75Hz\n");
  431. }
  432. if (c&0x01) {
  433. mode[num++] = vesa_modes[21];
  434. DPRINTK(" 1280x1024@75Hz\n");
  435. }
  436. c = block[2];
  437. if (c&0x80) {
  438. mode[num++] = vesa_modes[17];
  439. DPRINTK(" 1152x870@75Hz\n");
  440. }
  441. DPRINTK(" Manufacturer's mask: %x\n",c&0x7F);
  442. return num;
  443. }
  444. static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
  445. int ver, int rev)
  446. {
  447. int xres, yres = 0, refresh, ratio, i;
  448. xres = (block[0] + 31) * 8;
  449. if (xres <= 256)
  450. return 0;
  451. ratio = (block[1] & 0xc0) >> 6;
  452. switch (ratio) {
  453. case 0:
  454. /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
  455. if (ver < 1 || (ver == 1 && rev < 3))
  456. yres = xres;
  457. else
  458. yres = (xres * 10)/16;
  459. break;
  460. case 1:
  461. yres = (xres * 3)/4;
  462. break;
  463. case 2:
  464. yres = (xres * 4)/5;
  465. break;
  466. case 3:
  467. yres = (xres * 9)/16;
  468. break;
  469. }
  470. refresh = (block[1] & 0x3f) + 60;
  471. DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh);
  472. for (i = 0; i < VESA_MODEDB_SIZE; i++) {
  473. if (vesa_modes[i].xres == xres &&
  474. vesa_modes[i].yres == yres &&
  475. vesa_modes[i].refresh == refresh) {
  476. *mode = vesa_modes[i];
  477. mode->flag |= FB_MODE_IS_STANDARD;
  478. return 1;
  479. }
  480. }
  481. calc_mode_timings(xres, yres, refresh, mode);
  482. return 1;
  483. }
  484. static int get_dst_timing(unsigned char *block,
  485. struct fb_videomode *mode, int ver, int rev)
  486. {
  487. int j, num = 0;
  488. for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
  489. num += get_std_timing(block, &mode[num], ver, rev);
  490. return num;
  491. }
  492. static void get_detailed_timing(unsigned char *block,
  493. struct fb_videomode *mode)
  494. {
  495. mode->xres = H_ACTIVE;
  496. mode->yres = V_ACTIVE;
  497. mode->pixclock = PIXEL_CLOCK;
  498. mode->pixclock /= 1000;
  499. mode->pixclock = KHZ2PICOS(mode->pixclock);
  500. mode->right_margin = H_SYNC_OFFSET;
  501. mode->left_margin = (H_ACTIVE + H_BLANKING) -
  502. (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
  503. mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
  504. V_SYNC_WIDTH;
  505. mode->lower_margin = V_SYNC_OFFSET;
  506. mode->hsync_len = H_SYNC_WIDTH;
  507. mode->vsync_len = V_SYNC_WIDTH;
  508. if (HSYNC_POSITIVE)
  509. mode->sync |= FB_SYNC_HOR_HIGH_ACT;
  510. if (VSYNC_POSITIVE)
  511. mode->sync |= FB_SYNC_VERT_HIGH_ACT;
  512. mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
  513. (V_ACTIVE + V_BLANKING));
  514. if (INTERLACED) {
  515. mode->yres *= 2;
  516. mode->upper_margin *= 2;
  517. mode->lower_margin *= 2;
  518. mode->vsync_len *= 2;
  519. mode->vmode |= FB_VMODE_INTERLACED;
  520. }
  521. mode->flag = FB_MODE_IS_DETAILED;
  522. DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
  523. DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
  524. H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
  525. DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
  526. V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
  527. DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
  528. (VSYNC_POSITIVE) ? "+" : "-");
  529. }
  530. /**
  531. * fb_create_modedb - create video mode database
  532. * @edid: EDID data
  533. * @dbsize: database size
  534. *
  535. * RETURNS: struct fb_videomode, @dbsize contains length of database
  536. *
  537. * DESCRIPTION:
  538. * This function builds a mode database using the contents of the EDID
  539. * data
  540. */
  541. static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
  542. {
  543. struct fb_videomode *mode, *m;
  544. unsigned char *block;
  545. int num = 0, i, first = 1;
  546. int ver, rev;
  547. ver = edid[EDID_STRUCT_VERSION];
  548. rev = edid[EDID_STRUCT_REVISION];
  549. mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
  550. if (mode == NULL)
  551. return NULL;
  552. if (edid == NULL || !edid_checksum(edid) ||
  553. !edid_check_header(edid)) {
  554. kfree(mode);
  555. return NULL;
  556. }
  557. *dbsize = 0;
  558. DPRINTK(" Detailed Timings\n");
  559. block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
  560. for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
  561. if (!(block[0] == 0x00 && block[1] == 0x00)) {
  562. get_detailed_timing(block, &mode[num]);
  563. if (first) {
  564. mode[num].flag |= FB_MODE_IS_FIRST;
  565. first = 0;
  566. }
  567. num++;
  568. }
  569. }
  570. DPRINTK(" Supported VESA Modes\n");
  571. block = edid + ESTABLISHED_TIMING_1;
  572. num += get_est_timing(block, &mode[num]);
  573. DPRINTK(" Standard Timings\n");
  574. block = edid + STD_TIMING_DESCRIPTIONS_START;
  575. for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
  576. num += get_std_timing(block, &mode[num], ver, rev);
  577. block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
  578. for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
  579. if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
  580. num += get_dst_timing(block + 5, &mode[num], ver, rev);
  581. }
  582. /* Yikes, EDID data is totally useless */
  583. if (!num) {
  584. kfree(mode);
  585. return NULL;
  586. }
  587. *dbsize = num;
  588. m = kmalloc(num * sizeof(struct fb_videomode), GFP_KERNEL);
  589. if (!m)
  590. return mode;
  591. memmove(m, mode, num * sizeof(struct fb_videomode));
  592. kfree(mode);
  593. return m;
  594. }
  595. /**
  596. * fb_destroy_modedb - destroys mode database
  597. * @modedb: mode database to destroy
  598. *
  599. * DESCRIPTION:
  600. * Destroy mode database created by fb_create_modedb
  601. */
  602. void fb_destroy_modedb(struct fb_videomode *modedb)
  603. {
  604. kfree(modedb);
  605. }
  606. static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
  607. {
  608. int i, retval = 1;
  609. unsigned char *block;
  610. block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
  611. DPRINTK(" Monitor Operating Limits: ");
  612. for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
  613. if (edid_is_limits_block(block)) {
  614. specs->hfmin = H_MIN_RATE * 1000;
  615. specs->hfmax = H_MAX_RATE * 1000;
  616. specs->vfmin = V_MIN_RATE;
  617. specs->vfmax = V_MAX_RATE;
  618. specs->dclkmax = MAX_PIXEL_CLOCK * 1000000;
  619. specs->gtf = (GTF_SUPPORT) ? 1 : 0;
  620. retval = 0;
  621. DPRINTK("From EDID\n");
  622. break;
  623. }
  624. }
  625. /* estimate monitor limits based on modes supported */
  626. if (retval) {
  627. struct fb_videomode *modes, *mode;
  628. int num_modes, hz, hscan, pixclock;
  629. int vtotal, htotal;
  630. modes = fb_create_modedb(edid, &num_modes);
  631. if (!modes) {
  632. DPRINTK("None Available\n");
  633. return 1;
  634. }
  635. retval = 0;
  636. for (i = 0; i < num_modes; i++) {
  637. mode = &modes[i];
  638. pixclock = PICOS2KHZ(modes[i].pixclock) * 1000;
  639. htotal = mode->xres + mode->right_margin + mode->hsync_len
  640. + mode->left_margin;
  641. vtotal = mode->yres + mode->lower_margin + mode->vsync_len
  642. + mode->upper_margin;
  643. if (mode->vmode & FB_VMODE_INTERLACED)
  644. vtotal /= 2;
  645. if (mode->vmode & FB_VMODE_DOUBLE)
  646. vtotal *= 2;
  647. hscan = (pixclock + htotal / 2) / htotal;
  648. hscan = (hscan + 500) / 1000 * 1000;
  649. hz = (hscan + vtotal / 2) / vtotal;
  650. if (specs->dclkmax == 0 || specs->dclkmax < pixclock)
  651. specs->dclkmax = pixclock;
  652. if (specs->dclkmin == 0 || specs->dclkmin > pixclock)
  653. specs->dclkmin = pixclock;
  654. if (specs->hfmax == 0 || specs->hfmax < hscan)
  655. specs->hfmax = hscan;
  656. if (specs->hfmin == 0 || specs->hfmin > hscan)
  657. specs->hfmin = hscan;
  658. if (specs->vfmax == 0 || specs->vfmax < hz)
  659. specs->vfmax = hz;
  660. if (specs->vfmin == 0 || specs->vfmin > hz)
  661. specs->vfmin = hz;
  662. }
  663. DPRINTK("Extrapolated\n");
  664. fb_destroy_modedb(modes);
  665. }
  666. DPRINTK(" H: %d-%dKHz V: %d-%dHz DCLK: %dMHz\n",
  667. specs->hfmin/1000, specs->hfmax/1000, specs->vfmin,
  668. specs->vfmax, specs->dclkmax/1000000);
  669. return retval;
  670. }
  671. static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs)
  672. {
  673. unsigned char c, *block;
  674. block = edid + EDID_STRUCT_DISPLAY;
  675. fb_get_monitor_limits(edid, specs);
  676. c = block[0] & 0x80;
  677. specs->input = 0;
  678. if (c) {
  679. specs->input |= FB_DISP_DDI;
  680. DPRINTK(" Digital Display Input");
  681. } else {
  682. DPRINTK(" Analog Display Input: Input Voltage - ");
  683. switch ((block[0] & 0x60) >> 5) {
  684. case 0:
  685. DPRINTK("0.700V/0.300V");
  686. specs->input |= FB_DISP_ANA_700_300;
  687. break;
  688. case 1:
  689. DPRINTK("0.714V/0.286V");
  690. specs->input |= FB_DISP_ANA_714_286;
  691. break;
  692. case 2:
  693. DPRINTK("1.000V/0.400V");
  694. specs->input |= FB_DISP_ANA_1000_400;
  695. break;
  696. case 3:
  697. DPRINTK("0.700V/0.000V");
  698. specs->input |= FB_DISP_ANA_700_000;
  699. break;
  700. }
  701. }
  702. DPRINTK("\n Sync: ");
  703. c = block[0] & 0x10;
  704. if (c)
  705. DPRINTK(" Configurable signal level\n");
  706. c = block[0] & 0x0f;
  707. specs->signal = 0;
  708. if (c & 0x10) {
  709. DPRINTK("Blank to Blank ");
  710. specs->signal |= FB_SIGNAL_BLANK_BLANK;
  711. }
  712. if (c & 0x08) {
  713. DPRINTK("Separate ");
  714. specs->signal |= FB_SIGNAL_SEPARATE;
  715. }
  716. if (c & 0x04) {
  717. DPRINTK("Composite ");
  718. specs->signal |= FB_SIGNAL_COMPOSITE;
  719. }
  720. if (c & 0x02) {
  721. DPRINTK("Sync on Green ");
  722. specs->signal |= FB_SIGNAL_SYNC_ON_GREEN;
  723. }
  724. if (c & 0x01) {
  725. DPRINTK("Serration on ");
  726. specs->signal |= FB_SIGNAL_SERRATION_ON;
  727. }
  728. DPRINTK("\n");
  729. specs->max_x = block[1];
  730. specs->max_y = block[2];
  731. DPRINTK(" Max H-size in cm: ");
  732. if (specs->max_x)
  733. DPRINTK("%d\n", specs->max_x);
  734. else
  735. DPRINTK("variable\n");
  736. DPRINTK(" Max V-size in cm: ");
  737. if (specs->max_y)
  738. DPRINTK("%d\n", specs->max_y);
  739. else
  740. DPRINTK("variable\n");
  741. c = block[3];
  742. specs->gamma = c+100;
  743. DPRINTK(" Gamma: ");
  744. DPRINTK("%d.%d\n", specs->gamma/100, specs->gamma % 100);
  745. get_dpms_capabilities(block[4], specs);
  746. switch ((block[4] & 0x18) >> 3) {
  747. case 0:
  748. DPRINTK(" Monochrome/Grayscale\n");
  749. specs->input |= FB_DISP_MONO;
  750. break;
  751. case 1:
  752. DPRINTK(" RGB Color Display\n");
  753. specs->input |= FB_DISP_RGB;
  754. break;
  755. case 2:
  756. DPRINTK(" Non-RGB Multicolor Display\n");
  757. specs->input |= FB_DISP_MULTI;
  758. break;
  759. default:
  760. DPRINTK(" Unknown\n");
  761. specs->input |= FB_DISP_UNKNOWN;
  762. break;
  763. }
  764. get_chroma(block, specs);
  765. specs->misc = 0;
  766. c = block[4] & 0x7;
  767. if (c & 0x04) {
  768. DPRINTK(" Default color format is primary\n");
  769. specs->misc |= FB_MISC_PRIM_COLOR;
  770. }
  771. if (c & 0x02) {
  772. DPRINTK(" First DETAILED Timing is preferred\n");
  773. specs->misc |= FB_MISC_1ST_DETAIL;
  774. }
  775. if (c & 0x01) {
  776. printk(" Display is GTF capable\n");
  777. specs->gtf = 1;
  778. }
  779. }
  780. int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
  781. {
  782. int i;
  783. unsigned char *block;
  784. if (edid == NULL || var == NULL)
  785. return 1;
  786. if (!(edid_checksum(edid)))
  787. return 1;
  788. if (!(edid_check_header(edid)))
  789. return 1;
  790. block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
  791. for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
  792. if (edid_is_timing_block(block)) {
  793. var->xres = var->xres_virtual = H_ACTIVE;
  794. var->yres = var->yres_virtual = V_ACTIVE;
  795. var->height = var->width = 0;
  796. var->right_margin = H_SYNC_OFFSET;
  797. var->left_margin = (H_ACTIVE + H_BLANKING) -
  798. (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
  799. var->upper_margin = V_BLANKING - V_SYNC_OFFSET -
  800. V_SYNC_WIDTH;
  801. var->lower_margin = V_SYNC_OFFSET;
  802. var->hsync_len = H_SYNC_WIDTH;
  803. var->vsync_len = V_SYNC_WIDTH;
  804. var->pixclock = PIXEL_CLOCK;
  805. var->pixclock /= 1000;
  806. var->pixclock = KHZ2PICOS(var->pixclock);
  807. if (HSYNC_POSITIVE)
  808. var->sync |= FB_SYNC_HOR_HIGH_ACT;
  809. if (VSYNC_POSITIVE)
  810. var->sync |= FB_SYNC_VERT_HIGH_ACT;
  811. return 0;
  812. }
  813. }
  814. return 1;
  815. }
  816. void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
  817. {
  818. unsigned char *block;
  819. int i, found = 0;
  820. if (edid == NULL)
  821. return;
  822. if (!(edid_checksum(edid)))
  823. return;
  824. if (!(edid_check_header(edid)))
  825. return;
  826. memset(specs, 0, sizeof(struct fb_monspecs));
  827. specs->version = edid[EDID_STRUCT_VERSION];
  828. specs->revision = edid[EDID_STRUCT_REVISION];
  829. DPRINTK("========================================\n");
  830. DPRINTK("Display Information (EDID)\n");
  831. DPRINTK("========================================\n");
  832. DPRINTK(" EDID Version %d.%d\n", (int) specs->version,
  833. (int) specs->revision);
  834. parse_vendor_block(edid + ID_MANUFACTURER_NAME, specs);
  835. block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
  836. for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
  837. if (edid_is_serial_block(block)) {
  838. copy_string(block, specs->serial_no);
  839. DPRINTK(" Serial Number: %s\n", specs->serial_no);
  840. } else if (edid_is_ascii_block(block)) {
  841. copy_string(block, specs->ascii);
  842. DPRINTK(" ASCII Block: %s\n", specs->ascii);
  843. } else if (edid_is_monitor_block(block)) {
  844. copy_string(block, specs->monitor);
  845. DPRINTK(" Monitor Name: %s\n", specs->monitor);
  846. }
  847. }
  848. DPRINTK(" Display Characteristics:\n");
  849. get_monspecs(edid, specs);
  850. specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
  851. /*
  852. * Workaround for buggy EDIDs that sets that the first
  853. * detailed timing is preferred but has not detailed
  854. * timing specified
  855. */
  856. for (i = 0; i < specs->modedb_len; i++) {
  857. if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) {
  858. found = 1;
  859. break;
  860. }
  861. }
  862. if (!found)
  863. specs->misc &= ~FB_MISC_1ST_DETAIL;
  864. DPRINTK("========================================\n");
  865. }
  866. /**
  867. * fb_edid_add_monspecs() - add monitor video modes from E-EDID data
  868. * @edid: 128 byte array with an E-EDID block
  869. * @spacs: monitor specs to be extended
  870. */
  871. void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
  872. {
  873. unsigned char *block;
  874. struct fb_videomode *m;
  875. int num = 0, i;
  876. u8 svd[64], edt[(128 - 4) / DETAILED_TIMING_DESCRIPTION_SIZE];
  877. u8 pos = 4, svd_n = 0;
  878. if (!edid)
  879. return;
  880. if (!edid_checksum(edid))
  881. return;
  882. if (edid[0] != 0x2 ||
  883. edid[2] < 4 || edid[2] > 128 - DETAILED_TIMING_DESCRIPTION_SIZE)
  884. return;
  885. DPRINTK(" Short Video Descriptors\n");
  886. while (pos < edid[2]) {
  887. u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7;
  888. pr_debug("Data block %u of %u bytes\n", type, len);
  889. if (type == 2) {
  890. for (i = pos; i < pos + len; i++) {
  891. u8 idx = edid[pos + i] & 0x7f;
  892. svd[svd_n++] = idx;
  893. pr_debug("N%sative mode #%d\n",
  894. edid[pos + i] & 0x80 ? "" : "on-n", idx);
  895. }
  896. } else if (type == 3 && len >= 3) {
  897. /* Check Vendor Specific Data Block. For HDMI,
  898. it is always 00-0C-03 for HDMI Licensing, LLC. */
  899. if (edid[pos + 1] == 3 && edid[pos + 2] == 0xc &&
  900. edid[pos + 3] == 0)
  901. specs->misc |= FB_MISC_HDMI;
  902. }
  903. pos += len + 1;
  904. }
  905. block = edid + edid[2];
  906. DPRINTK(" Extended Detailed Timings\n");
  907. for (i = 0; i < (128 - edid[2]) / DETAILED_TIMING_DESCRIPTION_SIZE;
  908. i++, block += DETAILED_TIMING_DESCRIPTION_SIZE)
  909. if (PIXEL_CLOCK)
  910. edt[num++] = block - edid;
  911. /* Yikes, EDID data is totally useless */
  912. if (!(num + svd_n))
  913. return;
  914. m = kzalloc((specs->modedb_len + num + svd_n) *
  915. sizeof(struct fb_videomode), GFP_KERNEL);
  916. if (!m)
  917. return;
  918. memcpy(m, specs->modedb, specs->modedb_len * sizeof(struct fb_videomode));
  919. for (i = specs->modedb_len; i < specs->modedb_len + num; i++) {
  920. get_detailed_timing(edid + edt[i - specs->modedb_len], &m[i]);
  921. if (i == specs->modedb_len)
  922. m[i].flag |= FB_MODE_IS_FIRST;
  923. pr_debug("Adding %ux%u@%u\n", m[i].xres, m[i].yres, m[i].refresh);
  924. }
  925. for (i = specs->modedb_len + num; i < specs->modedb_len + num + svd_n; i++) {
  926. int idx = svd[i - specs->modedb_len - num];
  927. if (!idx || idx > 63) {
  928. pr_warning("Reserved SVD code %d\n", idx);
  929. } else if (idx > ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) {
  930. pr_warning("Unimplemented SVD code %d\n", idx);
  931. } else {
  932. memcpy(&m[i], cea_modes + idx, sizeof(m[i]));
  933. pr_debug("Adding SVD #%d: %ux%u@%u\n", idx,
  934. m[i].xres, m[i].yres, m[i].refresh);
  935. }
  936. }
  937. kfree(specs->modedb);
  938. specs->modedb = m;
  939. specs->modedb_len = specs->modedb_len + num + svd_n;
  940. }
  941. /*
  942. * VESA Generalized Timing Formula (GTF)
  943. */
  944. #define FLYBACK 550
  945. #define V_FRONTPORCH 1
  946. #define H_OFFSET 40
  947. #define H_SCALEFACTOR 20
  948. #define H_BLANKSCALE 128
  949. #define H_GRADIENT 600
  950. #define C_VAL 30
  951. #define M_VAL 300
  952. struct __fb_timings {
  953. u32 dclk;
  954. u32 hfreq;
  955. u32 vfreq;
  956. u32 hactive;
  957. u32 vactive;
  958. u32 hblank;
  959. u32 vblank;
  960. u32 htotal;
  961. u32 vtotal;
  962. };
  963. /**
  964. * fb_get_vblank - get vertical blank time
  965. * @hfreq: horizontal freq
  966. *
  967. * DESCRIPTION:
  968. * vblank = right_margin + vsync_len + left_margin
  969. *
  970. * given: right_margin = 1 (V_FRONTPORCH)
  971. * vsync_len = 3
  972. * flyback = 550
  973. *
  974. * flyback * hfreq
  975. * left_margin = --------------- - vsync_len
  976. * 1000000
  977. */
  978. static u32 fb_get_vblank(u32 hfreq)
  979. {
  980. u32 vblank;
  981. vblank = (hfreq * FLYBACK)/1000;
  982. vblank = (vblank + 500)/1000;
  983. return (vblank + V_FRONTPORCH);
  984. }
  985. /**
  986. * fb_get_hblank_by_freq - get horizontal blank time given hfreq
  987. * @hfreq: horizontal freq
  988. * @xres: horizontal resolution in pixels
  989. *
  990. * DESCRIPTION:
  991. *
  992. * xres * duty_cycle
  993. * hblank = ------------------
  994. * 100 - duty_cycle
  995. *
  996. * duty cycle = percent of htotal assigned to inactive display
  997. * duty cycle = C - (M/Hfreq)
  998. *
  999. * where: C = ((offset - scale factor) * blank_scale)
  1000. * -------------------------------------- + scale factor
  1001. * 256
  1002. * M = blank_scale * gradient
  1003. *
  1004. */
  1005. static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres)
  1006. {
  1007. u32 c_val, m_val, duty_cycle, hblank;
  1008. c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 +
  1009. H_SCALEFACTOR) * 1000;
  1010. m_val = (H_BLANKSCALE * H_GRADIENT)/256;
  1011. m_val = (m_val * 1000000)/hfreq;
  1012. duty_cycle = c_val - m_val;
  1013. hblank = (xres * duty_cycle)/(100000 - duty_cycle);
  1014. return (hblank);
  1015. }
  1016. /**
  1017. * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock
  1018. * @dclk: pixelclock in Hz
  1019. * @xres: horizontal resolution in pixels
  1020. *
  1021. * DESCRIPTION:
  1022. *
  1023. * xres * duty_cycle
  1024. * hblank = ------------------
  1025. * 100 - duty_cycle
  1026. *
  1027. * duty cycle = percent of htotal assigned to inactive display
  1028. * duty cycle = C - (M * h_period)
  1029. *
  1030. * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100
  1031. * -----------------------------------------------
  1032. * 2 * M
  1033. * M = 300;
  1034. * C = 30;
  1035. */
  1036. static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
  1037. {
  1038. u32 duty_cycle, h_period, hblank;
  1039. dclk /= 1000;
  1040. h_period = 100 - C_VAL;
  1041. h_period *= h_period;
  1042. h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk);
  1043. h_period *= 10000;
  1044. h_period = int_sqrt(h_period);
  1045. h_period -= (100 - C_VAL) * 100;
  1046. h_period *= 1000;
  1047. h_period /= 2 * M_VAL;
  1048. duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100;
  1049. hblank = (xres * duty_cycle)/(100000 - duty_cycle) + 8;
  1050. hblank &= ~15;
  1051. return (hblank);
  1052. }
  1053. /**
  1054. * fb_get_hfreq - estimate hsync
  1055. * @vfreq: vertical refresh rate
  1056. * @yres: vertical resolution
  1057. *
  1058. * DESCRIPTION:
  1059. *
  1060. * (yres + front_port) * vfreq * 1000000
  1061. * hfreq = -------------------------------------
  1062. * (1000000 - (vfreq * FLYBACK)
  1063. *
  1064. */
  1065. static u32 fb_get_hfreq(u32 vfreq, u32 yres)
  1066. {
  1067. u32 divisor, hfreq;
  1068. divisor = (1000000 - (vfreq * FLYBACK))/1000;
  1069. hfreq = (yres + V_FRONTPORCH) * vfreq * 1000;
  1070. return (hfreq/divisor);
  1071. }
  1072. static void fb_timings_vfreq(struct __fb_timings *timings)
  1073. {
  1074. timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive);
  1075. timings->vblank = fb_get_vblank(timings->hfreq);
  1076. timings->vtotal = timings->vactive + timings->vblank;
  1077. timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq,
  1078. timings->hactive);
  1079. timings->htotal = timings->hactive + timings->hblank;
  1080. timings->dclk = timings->htotal * timings->hfreq;
  1081. }
  1082. static void fb_timings_hfreq(struct __fb_timings *timings)
  1083. {
  1084. timings->vblank = fb_get_vblank(timings->hfreq);
  1085. timings->vtotal = timings->vactive + timings->vblank;
  1086. timings->vfreq = timings->hfreq/timings->vtotal;
  1087. timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq,
  1088. timings->hactive);
  1089. timings->htotal = timings->hactive + timings->hblank;
  1090. timings->dclk = timings->htotal * timings->hfreq;
  1091. }
  1092. static void fb_timings_dclk(struct __fb_timings *timings)
  1093. {
  1094. timings->hblank = fb_get_hblank_by_dclk(timings->dclk,
  1095. timings->hactive);
  1096. timings->htotal = timings->hactive + timings->hblank;
  1097. timings->hfreq = timings->dclk/timings->htotal;
  1098. timings->vblank = fb_get_vblank(timings->hfreq);
  1099. timings->vtotal = timings->vactive + timings->vblank;
  1100. timings->vfreq = timings->hfreq/timings->vtotal;
  1101. }
  1102. /*
  1103. * fb_get_mode - calculates video mode using VESA GTF
  1104. * @flags: if: 0 - maximize vertical refresh rate
  1105. * 1 - vrefresh-driven calculation;
  1106. * 2 - hscan-driven calculation;
  1107. * 3 - pixelclock-driven calculation;
  1108. * @val: depending on @flags, ignored, vrefresh, hsync or pixelclock
  1109. * @var: pointer to fb_var_screeninfo
  1110. * @info: pointer to fb_info
  1111. *
  1112. * DESCRIPTION:
  1113. * Calculates video mode based on monitor specs using VESA GTF.
  1114. * The GTF is best for VESA GTF compliant monitors but is
  1115. * specifically formulated to work for older monitors as well.
  1116. *
  1117. * If @flag==0, the function will attempt to maximize the
  1118. * refresh rate. Otherwise, it will calculate timings based on
  1119. * the flag and accompanying value.
  1120. *
  1121. * If FB_IGNOREMON bit is set in @flags, monitor specs will be
  1122. * ignored and @var will be filled with the calculated timings.
  1123. *
  1124. * All calculations are based on the VESA GTF Spreadsheet
  1125. * available at VESA's public ftp (http://www.vesa.org).
  1126. *
  1127. * NOTES:
  1128. * The timings generated by the GTF will be different from VESA
  1129. * DMT. It might be a good idea to keep a table of standard
  1130. * VESA modes as well. The GTF may also not work for some displays,
  1131. * such as, and especially, analog TV.
  1132. *
  1133. * REQUIRES:
  1134. * A valid info->monspecs, otherwise 'safe numbers' will be used.
  1135. */
  1136. int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info)
  1137. {
  1138. struct __fb_timings *timings;
  1139. u32 interlace = 1, dscan = 1;
  1140. u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax, err = 0;
  1141. timings = kzalloc(sizeof(struct __fb_timings), GFP_KERNEL);
  1142. if (!timings)
  1143. return -ENOMEM;
  1144. /*
  1145. * If monspecs are invalid, use values that are enough
  1146. * for 640x480@60
  1147. */
  1148. if (!info || !info->monspecs.hfmax || !info->monspecs.vfmax ||
  1149. !info->monspecs.dclkmax ||
  1150. info->monspecs.hfmax < info->monspecs.hfmin ||
  1151. info->monspecs.vfmax < info->monspecs.vfmin ||
  1152. info->monspecs.dclkmax < info->monspecs.dclkmin) {
  1153. hfmin = 29000; hfmax = 30000;
  1154. vfmin = 60; vfmax = 60;
  1155. dclkmin = 0; dclkmax = 25000000;
  1156. } else {
  1157. hfmin = info->monspecs.hfmin;
  1158. hfmax = info->monspecs.hfmax;
  1159. vfmin = info->monspecs.vfmin;
  1160. vfmax = info->monspecs.vfmax;
  1161. dclkmin = info->monspecs.dclkmin;
  1162. dclkmax = info->monspecs.dclkmax;
  1163. }
  1164. timings->hactive = var->xres;
  1165. timings->vactive = var->yres;
  1166. if (var->vmode & FB_VMODE_INTERLACED) {
  1167. timings->vactive /= 2;
  1168. interlace = 2;
  1169. }
  1170. if (var->vmode & FB_VMODE_DOUBLE) {
  1171. timings->vactive *= 2;
  1172. dscan = 2;
  1173. }
  1174. switch (flags & ~FB_IGNOREMON) {
  1175. case FB_MAXTIMINGS: /* maximize refresh rate */
  1176. timings->hfreq = hfmax;
  1177. fb_timings_hfreq(timings);
  1178. if (timings->vfreq > vfmax) {
  1179. timings->vfreq = vfmax;
  1180. fb_timings_vfreq(timings);
  1181. }
  1182. if (timings->dclk > dclkmax) {
  1183. timings->dclk = dclkmax;
  1184. fb_timings_dclk(timings);
  1185. }
  1186. break;
  1187. case FB_VSYNCTIMINGS: /* vrefresh driven */
  1188. timings->vfreq = val;
  1189. fb_timings_vfreq(timings);
  1190. break;
  1191. case FB_HSYNCTIMINGS: /* hsync driven */
  1192. timings->hfreq = val;
  1193. fb_timings_hfreq(timings);
  1194. break;
  1195. case FB_DCLKTIMINGS: /* pixelclock driven */
  1196. timings->dclk = PICOS2KHZ(val) * 1000;
  1197. fb_timings_dclk(timings);
  1198. break;
  1199. default:
  1200. err = -EINVAL;
  1201. }
  1202. if (err || (!(flags & FB_IGNOREMON) &&
  1203. (timings->vfreq < vfmin || timings->vfreq > vfmax ||
  1204. timings->hfreq < hfmin || timings->hfreq > hfmax ||
  1205. timings->dclk < dclkmin || timings->dclk > dclkmax))) {
  1206. err = -EINVAL;
  1207. } else {
  1208. var->pixclock = KHZ2PICOS(timings->dclk/1000);
  1209. var->hsync_len = (timings->htotal * 8)/100;
  1210. var->right_margin = (timings->hblank/2) - var->hsync_len;
  1211. var->left_margin = timings->hblank - var->right_margin -
  1212. var->hsync_len;
  1213. var->vsync_len = (3 * interlace)/dscan;
  1214. var->lower_margin = (1 * interlace)/dscan;
  1215. var->upper_margin = (timings->vblank * interlace)/dscan -
  1216. (var->vsync_len + var->lower_margin);
  1217. }
  1218. kfree(timings);
  1219. return err;
  1220. }
  1221. #ifdef CONFIG_VIDEOMODE_HELPERS
  1222. int fb_videomode_from_videomode(const struct videomode *vm,
  1223. struct fb_videomode *fbmode)
  1224. {
  1225. unsigned int htotal, vtotal;
  1226. fbmode->xres = vm->hactive;
  1227. fbmode->left_margin = vm->hback_porch;
  1228. fbmode->right_margin = vm->hfront_porch;
  1229. fbmode->hsync_len = vm->hsync_len;
  1230. fbmode->yres = vm->vactive;
  1231. fbmode->upper_margin = vm->vback_porch;
  1232. fbmode->lower_margin = vm->vfront_porch;
  1233. fbmode->vsync_len = vm->vsync_len;
  1234. /* prevent division by zero in KHZ2PICOS macro */
  1235. fbmode->pixclock = vm->pixelclock ?
  1236. KHZ2PICOS(vm->pixelclock / 1000) : 0;
  1237. fbmode->sync = 0;
  1238. fbmode->vmode = 0;
  1239. if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH)
  1240. fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
  1241. if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
  1242. fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
  1243. if (vm->flags & DISPLAY_FLAGS_INTERLACED)
  1244. fbmode->vmode |= FB_VMODE_INTERLACED;
  1245. if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
  1246. fbmode->vmode |= FB_VMODE_DOUBLE;
  1247. fbmode->flag = 0;
  1248. htotal = vm->hactive + vm->hfront_porch + vm->hback_porch +
  1249. vm->hsync_len;
  1250. vtotal = vm->vactive + vm->vfront_porch + vm->vback_porch +
  1251. vm->vsync_len;
  1252. /* prevent division by zero */
  1253. if (htotal && vtotal) {
  1254. fbmode->refresh = vm->pixelclock / (htotal * vtotal);
  1255. /* a mode must have htotal and vtotal != 0 or it is invalid */
  1256. } else {
  1257. fbmode->refresh = 0;
  1258. return -EINVAL;
  1259. }
  1260. return 0;
  1261. }
  1262. EXPORT_SYMBOL_GPL(fb_videomode_from_videomode);
  1263. #ifdef CONFIG_OF
  1264. static inline void dump_fb_videomode(const struct fb_videomode *m)
  1265. {
  1266. pr_debug("fb_videomode = %ux%u@%uHz (%ukHz) %u %u %u %u %u %u %u %u %u\n",
  1267. m->xres, m->yres, m->refresh, m->pixclock, m->left_margin,
  1268. m->right_margin, m->upper_margin, m->lower_margin,
  1269. m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
  1270. }
  1271. /**
  1272. * of_get_fb_videomode - get a fb_videomode from devicetree
  1273. * @np: device_node with the timing specification
  1274. * @fb: will be set to the return value
  1275. * @index: index into the list of display timings in devicetree
  1276. *
  1277. * DESCRIPTION:
  1278. * This function is expensive and should only be used, if only one mode is to be
  1279. * read from DT. To get multiple modes start with of_get_display_timings ond
  1280. * work with that instead.
  1281. */
  1282. int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
  1283. int index)
  1284. {
  1285. struct videomode vm;
  1286. int ret;
  1287. ret = of_get_videomode(np, &vm, index);
  1288. if (ret)
  1289. return ret;
  1290. fb_videomode_from_videomode(&vm, fb);
  1291. pr_debug("%s: got %dx%d display mode from %s\n",
  1292. of_node_full_name(np), vm.hactive, vm.vactive, np->name);
  1293. dump_fb_videomode(fb);
  1294. return 0;
  1295. }
  1296. EXPORT_SYMBOL_GPL(of_get_fb_videomode);
  1297. #endif /* CONFIG_OF */
  1298. #endif /* CONFIG_VIDEOMODE_HELPERS */
  1299. #else
  1300. int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
  1301. {
  1302. return 1;
  1303. }
  1304. void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
  1305. {
  1306. specs = NULL;
  1307. }
  1308. void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
  1309. {
  1310. }
  1311. void fb_destroy_modedb(struct fb_videomode *modedb)
  1312. {
  1313. }
  1314. int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
  1315. struct fb_info *info)
  1316. {
  1317. return -EINVAL;
  1318. }
  1319. #endif /* CONFIG_FB_MODE_HELPERS */
  1320. /*
  1321. * fb_validate_mode - validates var against monitor capabilities
  1322. * @var: pointer to fb_var_screeninfo
  1323. * @info: pointer to fb_info
  1324. *
  1325. * DESCRIPTION:
  1326. * Validates video mode against monitor capabilities specified in
  1327. * info->monspecs.
  1328. *
  1329. * REQUIRES:
  1330. * A valid info->monspecs.
  1331. */
  1332. int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
  1333. {
  1334. u32 hfreq, vfreq, htotal, vtotal, pixclock;
  1335. u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
  1336. /*
  1337. * If monspecs are invalid, use values that are enough
  1338. * for 640x480@60
  1339. */
  1340. if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
  1341. !info->monspecs.dclkmax ||
  1342. info->monspecs.hfmax < info->monspecs.hfmin ||
  1343. info->monspecs.vfmax < info->monspecs.vfmin ||
  1344. info->monspecs.dclkmax < info->monspecs.dclkmin) {
  1345. hfmin = 29000; hfmax = 30000;
  1346. vfmin = 60; vfmax = 60;
  1347. dclkmin = 0; dclkmax = 25000000;
  1348. } else {
  1349. hfmin = info->monspecs.hfmin;
  1350. hfmax = info->monspecs.hfmax;
  1351. vfmin = info->monspecs.vfmin;
  1352. vfmax = info->monspecs.vfmax;
  1353. dclkmin = info->monspecs.dclkmin;
  1354. dclkmax = info->monspecs.dclkmax;
  1355. }
  1356. if (!var->pixclock)
  1357. return -EINVAL;
  1358. pixclock = PICOS2KHZ(var->pixclock) * 1000;
  1359. htotal = var->xres + var->right_margin + var->hsync_len +
  1360. var->left_margin;
  1361. vtotal = var->yres + var->lower_margin + var->vsync_len +
  1362. var->upper_margin;
  1363. if (var->vmode & FB_VMODE_INTERLACED)
  1364. vtotal /= 2;
  1365. if (var->vmode & FB_VMODE_DOUBLE)
  1366. vtotal *= 2;
  1367. hfreq = pixclock/htotal;
  1368. hfreq = (hfreq + 500) / 1000 * 1000;
  1369. vfreq = hfreq/vtotal;
  1370. return (vfreq < vfmin || vfreq > vfmax ||
  1371. hfreq < hfmin || hfreq > hfmax ||
  1372. pixclock < dclkmin || pixclock > dclkmax) ?
  1373. -EINVAL : 0;
  1374. }
  1375. #if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86)
  1376. /*
  1377. * We need to ensure that the EDID block is only returned for
  1378. * the primary graphics adapter.
  1379. */
  1380. const unsigned char *fb_firmware_edid(struct device *device)
  1381. {
  1382. struct pci_dev *dev = NULL;
  1383. struct resource *res = NULL;
  1384. unsigned char *edid = NULL;
  1385. if (device)
  1386. dev = to_pci_dev(device);
  1387. if (dev)
  1388. res = &dev->resource[PCI_ROM_RESOURCE];
  1389. if (res && res->flags & IORESOURCE_ROM_SHADOW)
  1390. edid = edid_info.dummy;
  1391. return edid;
  1392. }
  1393. #else
  1394. const unsigned char *fb_firmware_edid(struct device *device)
  1395. {
  1396. return NULL;
  1397. }
  1398. #endif
  1399. EXPORT_SYMBOL(fb_firmware_edid);
  1400. EXPORT_SYMBOL(fb_parse_edid);
  1401. EXPORT_SYMBOL(fb_edid_to_monspecs);
  1402. EXPORT_SYMBOL(fb_edid_add_monspecs);
  1403. EXPORT_SYMBOL(fb_get_mode);
  1404. EXPORT_SYMBOL(fb_validate_mode);
  1405. EXPORT_SYMBOL(fb_destroy_modedb);