hw.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133
  1. /*
  2. * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
  3. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License as published by the Free Software Foundation;
  7. * either version 2, or (at your option) any later version.
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
  10. * the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. * A PARTICULAR PURPOSE.See the GNU General Public License
  12. * for more details.
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc.,
  16. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include <linux/via-core.h>
  19. #include "global.h"
  20. #include "via_clock.h"
  21. static struct pll_limit cle266_pll_limits[] = {
  22. {19, 19, 4, 0},
  23. {26, 102, 5, 0},
  24. {53, 112, 6, 0},
  25. {41, 100, 7, 0},
  26. {83, 108, 8, 0},
  27. {87, 118, 9, 0},
  28. {95, 115, 12, 0},
  29. {108, 108, 13, 0},
  30. {83, 83, 17, 0},
  31. {67, 98, 20, 0},
  32. {121, 121, 24, 0},
  33. {99, 99, 29, 0},
  34. {33, 33, 3, 1},
  35. {15, 23, 4, 1},
  36. {37, 121, 5, 1},
  37. {82, 82, 6, 1},
  38. {31, 84, 7, 1},
  39. {83, 83, 8, 1},
  40. {76, 127, 9, 1},
  41. {33, 121, 4, 2},
  42. {91, 118, 5, 2},
  43. {83, 109, 6, 2},
  44. {90, 90, 7, 2},
  45. {93, 93, 2, 3},
  46. {53, 53, 3, 3},
  47. {73, 117, 4, 3},
  48. {101, 127, 5, 3},
  49. {99, 99, 7, 3}
  50. };
  51. static struct pll_limit k800_pll_limits[] = {
  52. {22, 22, 2, 0},
  53. {28, 28, 3, 0},
  54. {81, 112, 3, 1},
  55. {86, 166, 4, 1},
  56. {109, 153, 5, 1},
  57. {66, 116, 3, 2},
  58. {93, 137, 4, 2},
  59. {117, 208, 5, 2},
  60. {30, 30, 2, 3},
  61. {69, 125, 3, 3},
  62. {89, 161, 4, 3},
  63. {121, 208, 5, 3},
  64. {66, 66, 2, 4},
  65. {85, 85, 3, 4},
  66. {141, 161, 4, 4},
  67. {177, 177, 5, 4}
  68. };
  69. static struct pll_limit cx700_pll_limits[] = {
  70. {98, 98, 3, 1},
  71. {86, 86, 4, 1},
  72. {109, 208, 5, 1},
  73. {68, 68, 2, 2},
  74. {95, 116, 3, 2},
  75. {93, 166, 4, 2},
  76. {110, 206, 5, 2},
  77. {174, 174, 7, 2},
  78. {82, 109, 3, 3},
  79. {117, 161, 4, 3},
  80. {112, 208, 5, 3},
  81. {141, 202, 5, 4}
  82. };
  83. static struct pll_limit vx855_pll_limits[] = {
  84. {86, 86, 4, 1},
  85. {108, 208, 5, 1},
  86. {110, 208, 5, 2},
  87. {83, 112, 3, 3},
  88. {103, 161, 4, 3},
  89. {112, 209, 5, 3},
  90. {142, 161, 4, 4},
  91. {141, 176, 5, 4}
  92. };
  93. /* according to VIA Technologies these values are based on experiment */
  94. static struct io_reg scaling_parameters[] = {
  95. {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
  96. {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
  97. {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
  98. {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
  99. {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
  100. {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
  101. {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
  102. {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
  103. {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
  104. {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
  105. {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
  106. {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
  107. {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
  108. {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
  109. };
  110. static struct io_reg common_vga[] = {
  111. {VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8)
  112. [1] vertical display end (bit 8)
  113. [2] vertical retrace start (bit 8)
  114. [3] start vertical blanking (bit 8)
  115. [4] line compare (bit 8)
  116. [5] vertical total (bit 9)
  117. [6] vertical display end (bit 9)
  118. [7] vertical retrace start (bit 9) */
  119. {VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan
  120. [5-6] byte panning */
  121. {VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line
  122. [5] start vertical blanking (bit 9)
  123. [6] line compare (bit 9)
  124. [7] scan doubling */
  125. {VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start
  126. [5] cursor disable */
  127. {VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end
  128. [5-6] cursor skew */
  129. {VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */
  130. {VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */
  131. {VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end
  132. [6] memory refresh bandwidth
  133. [7] CRTC register protect enable */
  134. {VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location
  135. [5] divide memory address clock by 4
  136. [6] double word addressing */
  137. {VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14
  138. [2] divide scan line clock by 2
  139. [3] divide memory address clock by 2
  140. [5] address wrap
  141. [6] byte mode select
  142. [7] sync enable */
  143. {VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */
  144. };
  145. static struct fifo_depth_select display_fifo_depth_reg = {
  146. /* IGA1 FIFO Depth_Select */
  147. {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
  148. /* IGA2 FIFO Depth_Select */
  149. {IGA2_FIFO_DEPTH_SELECT_REG_NUM,
  150. {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
  151. };
  152. static struct fifo_threshold_select fifo_threshold_select_reg = {
  153. /* IGA1 FIFO Threshold Select */
  154. {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
  155. /* IGA2 FIFO Threshold Select */
  156. {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
  157. };
  158. static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
  159. /* IGA1 FIFO High Threshold Select */
  160. {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
  161. /* IGA2 FIFO High Threshold Select */
  162. {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
  163. };
  164. static struct display_queue_expire_num display_queue_expire_num_reg = {
  165. /* IGA1 Display Queue Expire Num */
  166. {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
  167. /* IGA2 Display Queue Expire Num */
  168. {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
  169. };
  170. /* Definition Fetch Count Registers*/
  171. static struct fetch_count fetch_count_reg = {
  172. /* IGA1 Fetch Count Register */
  173. {IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
  174. /* IGA2 Fetch Count Register */
  175. {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
  176. };
  177. static struct rgbLUT palLUT_table[] = {
  178. /* {R,G,B} */
  179. /* Index 0x00~0x03 */
  180. {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
  181. 0x2A,
  182. 0x2A},
  183. /* Index 0x04~0x07 */
  184. {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
  185. 0x2A,
  186. 0x2A},
  187. /* Index 0x08~0x0B */
  188. {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
  189. 0x3F,
  190. 0x3F},
  191. /* Index 0x0C~0x0F */
  192. {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
  193. 0x3F,
  194. 0x3F},
  195. /* Index 0x10~0x13 */
  196. {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
  197. 0x0B,
  198. 0x0B},
  199. /* Index 0x14~0x17 */
  200. {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
  201. 0x18,
  202. 0x18},
  203. /* Index 0x18~0x1B */
  204. {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
  205. 0x28,
  206. 0x28},
  207. /* Index 0x1C~0x1F */
  208. {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
  209. 0x3F,
  210. 0x3F},
  211. /* Index 0x20~0x23 */
  212. {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
  213. 0x00,
  214. 0x3F},
  215. /* Index 0x24~0x27 */
  216. {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
  217. 0x00,
  218. 0x10},
  219. /* Index 0x28~0x2B */
  220. {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
  221. 0x2F,
  222. 0x00},
  223. /* Index 0x2C~0x2F */
  224. {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
  225. 0x3F,
  226. 0x00},
  227. /* Index 0x30~0x33 */
  228. {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
  229. 0x3F,
  230. 0x2F},
  231. /* Index 0x34~0x37 */
  232. {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
  233. 0x10,
  234. 0x3F},
  235. /* Index 0x38~0x3B */
  236. {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
  237. 0x1F,
  238. 0x3F},
  239. /* Index 0x3C~0x3F */
  240. {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
  241. 0x1F,
  242. 0x27},
  243. /* Index 0x40~0x43 */
  244. {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
  245. 0x3F,
  246. 0x1F},
  247. /* Index 0x44~0x47 */
  248. {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
  249. 0x3F,
  250. 0x1F},
  251. /* Index 0x48~0x4B */
  252. {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
  253. 0x3F,
  254. 0x37},
  255. /* Index 0x4C~0x4F */
  256. {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
  257. 0x27,
  258. 0x3F},
  259. /* Index 0x50~0x53 */
  260. {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
  261. 0x2D,
  262. 0x3F},
  263. /* Index 0x54~0x57 */
  264. {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
  265. 0x2D,
  266. 0x31},
  267. /* Index 0x58~0x5B */
  268. {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
  269. 0x3A,
  270. 0x2D},
  271. /* Index 0x5C~0x5F */
  272. {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
  273. 0x3F,
  274. 0x2D},
  275. /* Index 0x60~0x63 */
  276. {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
  277. 0x3F,
  278. 0x3A},
  279. /* Index 0x64~0x67 */
  280. {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
  281. 0x31,
  282. 0x3F},
  283. /* Index 0x68~0x6B */
  284. {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
  285. 0x00,
  286. 0x1C},
  287. /* Index 0x6C~0x6F */
  288. {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
  289. 0x00,
  290. 0x07},
  291. /* Index 0x70~0x73 */
  292. {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
  293. 0x15,
  294. 0x00},
  295. /* Index 0x74~0x77 */
  296. {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
  297. 0x1C,
  298. 0x00},
  299. /* Index 0x78~0x7B */
  300. {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
  301. 0x1C,
  302. 0x15},
  303. /* Index 0x7C~0x7F */
  304. {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
  305. 0x07,
  306. 0x1C},
  307. /* Index 0x80~0x83 */
  308. {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
  309. 0x0E,
  310. 0x1C},
  311. /* Index 0x84~0x87 */
  312. {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
  313. 0x0E,
  314. 0x11},
  315. /* Index 0x88~0x8B */
  316. {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
  317. 0x18,
  318. 0x0E},
  319. /* Index 0x8C~0x8F */
  320. {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
  321. 0x1C,
  322. 0x0E},
  323. /* Index 0x90~0x93 */
  324. {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
  325. 0x1C,
  326. 0x18},
  327. /* Index 0x94~0x97 */
  328. {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
  329. 0x11,
  330. 0x1C},
  331. /* Index 0x98~0x9B */
  332. {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
  333. 0x14,
  334. 0x1C},
  335. /* Index 0x9C~0x9F */
  336. {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
  337. 0x14,
  338. 0x16},
  339. /* Index 0xA0~0xA3 */
  340. {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
  341. 0x1A,
  342. 0x14},
  343. /* Index 0xA4~0xA7 */
  344. {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
  345. 0x1C,
  346. 0x14},
  347. /* Index 0xA8~0xAB */
  348. {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
  349. 0x1C,
  350. 0x1A},
  351. /* Index 0xAC~0xAF */
  352. {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
  353. 0x16,
  354. 0x1C},
  355. /* Index 0xB0~0xB3 */
  356. {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
  357. 0x00,
  358. 0x10},
  359. /* Index 0xB4~0xB7 */
  360. {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
  361. 0x00,
  362. 0x04},
  363. /* Index 0xB8~0xBB */
  364. {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
  365. 0x0C,
  366. 0x00},
  367. /* Index 0xBC~0xBF */
  368. {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
  369. 0x10,
  370. 0x00},
  371. /* Index 0xC0~0xC3 */
  372. {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
  373. 0x10,
  374. 0x0C},
  375. /* Index 0xC4~0xC7 */
  376. {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
  377. 0x04,
  378. 0x10},
  379. /* Index 0xC8~0xCB */
  380. {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
  381. 0x08,
  382. 0x10},
  383. /* Index 0xCC~0xCF */
  384. {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
  385. 0x08,
  386. 0x0A},
  387. /* Index 0xD0~0xD3 */
  388. {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
  389. 0x0E,
  390. 0x08},
  391. /* Index 0xD4~0xD7 */
  392. {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
  393. 0x10,
  394. 0x08},
  395. /* Index 0xD8~0xDB */
  396. {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
  397. 0x10,
  398. 0x0E},
  399. /* Index 0xDC~0xDF */
  400. {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
  401. 0x0A,
  402. 0x10},
  403. /* Index 0xE0~0xE3 */
  404. {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
  405. 0x0B,
  406. 0x10},
  407. /* Index 0xE4~0xE7 */
  408. {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
  409. 0x0B,
  410. 0x0C},
  411. /* Index 0xE8~0xEB */
  412. {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
  413. 0x0F,
  414. 0x0B},
  415. /* Index 0xEC~0xEF */
  416. {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
  417. 0x10,
  418. 0x0B},
  419. /* Index 0xF0~0xF3 */
  420. {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
  421. 0x10,
  422. 0x0F},
  423. /* Index 0xF4~0xF7 */
  424. {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
  425. 0x0C,
  426. 0x10},
  427. /* Index 0xF8~0xFB */
  428. {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
  429. 0x00,
  430. 0x00},
  431. /* Index 0xFC~0xFF */
  432. {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
  433. 0x00,
  434. 0x00}
  435. };
  436. static struct via_device_mapping device_mapping[] = {
  437. {VIA_LDVP0, "LDVP0"},
  438. {VIA_LDVP1, "LDVP1"},
  439. {VIA_DVP0, "DVP0"},
  440. {VIA_CRT, "CRT"},
  441. {VIA_DVP1, "DVP1"},
  442. {VIA_LVDS1, "LVDS1"},
  443. {VIA_LVDS2, "LVDS2"}
  444. };
  445. /* structure with function pointers to support clock control */
  446. static struct via_clock clock;
  447. static void load_fix_bit_crtc_reg(void);
  448. static void init_gfx_chip_info(int chip_type);
  449. static void init_tmds_chip_info(void);
  450. static void init_lvds_chip_info(void);
  451. static void device_screen_off(void);
  452. static void device_screen_on(void);
  453. static void set_display_channel(void);
  454. static void device_off(void);
  455. static void device_on(void);
  456. static void enable_second_display_channel(void);
  457. static void disable_second_display_channel(void);
  458. void viafb_lock_crt(void)
  459. {
  460. viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
  461. }
  462. void viafb_unlock_crt(void)
  463. {
  464. viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
  465. viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
  466. }
  467. static void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
  468. {
  469. outb(index, LUT_INDEX_WRITE);
  470. outb(r, LUT_DATA);
  471. outb(g, LUT_DATA);
  472. outb(b, LUT_DATA);
  473. }
  474. static u32 get_dvi_devices(int output_interface)
  475. {
  476. switch (output_interface) {
  477. case INTERFACE_DVP0:
  478. return VIA_DVP0 | VIA_LDVP0;
  479. case INTERFACE_DVP1:
  480. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
  481. return VIA_LDVP1;
  482. else
  483. return VIA_DVP1;
  484. case INTERFACE_DFP_HIGH:
  485. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
  486. return 0;
  487. else
  488. return VIA_LVDS2 | VIA_DVP0;
  489. case INTERFACE_DFP_LOW:
  490. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
  491. return 0;
  492. else
  493. return VIA_DVP1 | VIA_LVDS1;
  494. case INTERFACE_TMDS:
  495. return VIA_LVDS1;
  496. }
  497. return 0;
  498. }
  499. static u32 get_lcd_devices(int output_interface)
  500. {
  501. switch (output_interface) {
  502. case INTERFACE_DVP0:
  503. return VIA_DVP0;
  504. case INTERFACE_DVP1:
  505. return VIA_DVP1;
  506. case INTERFACE_DFP_HIGH:
  507. return VIA_LVDS2 | VIA_DVP0;
  508. case INTERFACE_DFP_LOW:
  509. return VIA_LVDS1 | VIA_DVP1;
  510. case INTERFACE_DFP:
  511. return VIA_LVDS1 | VIA_LVDS2;
  512. case INTERFACE_LVDS0:
  513. case INTERFACE_LVDS0LVDS1:
  514. return VIA_LVDS1;
  515. case INTERFACE_LVDS1:
  516. return VIA_LVDS2;
  517. }
  518. return 0;
  519. }
  520. /*Set IGA path for each device*/
  521. void viafb_set_iga_path(void)
  522. {
  523. int crt_iga_path = 0;
  524. if (viafb_SAMM_ON == 1) {
  525. if (viafb_CRT_ON) {
  526. if (viafb_primary_dev == CRT_Device)
  527. crt_iga_path = IGA1;
  528. else
  529. crt_iga_path = IGA2;
  530. }
  531. if (viafb_DVI_ON) {
  532. if (viafb_primary_dev == DVI_Device)
  533. viaparinfo->tmds_setting_info->iga_path = IGA1;
  534. else
  535. viaparinfo->tmds_setting_info->iga_path = IGA2;
  536. }
  537. if (viafb_LCD_ON) {
  538. if (viafb_primary_dev == LCD_Device) {
  539. if (viafb_dual_fb &&
  540. (viaparinfo->chip_info->gfx_chip_name ==
  541. UNICHROME_CLE266)) {
  542. viaparinfo->
  543. lvds_setting_info->iga_path = IGA2;
  544. crt_iga_path = IGA1;
  545. viaparinfo->
  546. tmds_setting_info->iga_path = IGA1;
  547. } else
  548. viaparinfo->
  549. lvds_setting_info->iga_path = IGA1;
  550. } else {
  551. viaparinfo->lvds_setting_info->iga_path = IGA2;
  552. }
  553. }
  554. if (viafb_LCD2_ON) {
  555. if (LCD2_Device == viafb_primary_dev)
  556. viaparinfo->lvds_setting_info2->iga_path = IGA1;
  557. else
  558. viaparinfo->lvds_setting_info2->iga_path = IGA2;
  559. }
  560. } else {
  561. viafb_SAMM_ON = 0;
  562. if (viafb_CRT_ON && viafb_LCD_ON) {
  563. crt_iga_path = IGA1;
  564. viaparinfo->lvds_setting_info->iga_path = IGA2;
  565. } else if (viafb_CRT_ON && viafb_DVI_ON) {
  566. crt_iga_path = IGA1;
  567. viaparinfo->tmds_setting_info->iga_path = IGA2;
  568. } else if (viafb_LCD_ON && viafb_DVI_ON) {
  569. viaparinfo->tmds_setting_info->iga_path = IGA1;
  570. viaparinfo->lvds_setting_info->iga_path = IGA2;
  571. } else if (viafb_LCD_ON && viafb_LCD2_ON) {
  572. viaparinfo->lvds_setting_info->iga_path = IGA2;
  573. viaparinfo->lvds_setting_info2->iga_path = IGA2;
  574. } else if (viafb_CRT_ON) {
  575. crt_iga_path = IGA1;
  576. } else if (viafb_LCD_ON) {
  577. viaparinfo->lvds_setting_info->iga_path = IGA2;
  578. } else if (viafb_DVI_ON) {
  579. viaparinfo->tmds_setting_info->iga_path = IGA1;
  580. }
  581. }
  582. viaparinfo->shared->iga1_devices = 0;
  583. viaparinfo->shared->iga2_devices = 0;
  584. if (viafb_CRT_ON) {
  585. if (crt_iga_path == IGA1)
  586. viaparinfo->shared->iga1_devices |= VIA_CRT;
  587. else
  588. viaparinfo->shared->iga2_devices |= VIA_CRT;
  589. }
  590. if (viafb_DVI_ON) {
  591. if (viaparinfo->tmds_setting_info->iga_path == IGA1)
  592. viaparinfo->shared->iga1_devices |= get_dvi_devices(
  593. viaparinfo->chip_info->
  594. tmds_chip_info.output_interface);
  595. else
  596. viaparinfo->shared->iga2_devices |= get_dvi_devices(
  597. viaparinfo->chip_info->
  598. tmds_chip_info.output_interface);
  599. }
  600. if (viafb_LCD_ON) {
  601. if (viaparinfo->lvds_setting_info->iga_path == IGA1)
  602. viaparinfo->shared->iga1_devices |= get_lcd_devices(
  603. viaparinfo->chip_info->
  604. lvds_chip_info.output_interface);
  605. else
  606. viaparinfo->shared->iga2_devices |= get_lcd_devices(
  607. viaparinfo->chip_info->
  608. lvds_chip_info.output_interface);
  609. }
  610. if (viafb_LCD2_ON) {
  611. if (viaparinfo->lvds_setting_info2->iga_path == IGA1)
  612. viaparinfo->shared->iga1_devices |= get_lcd_devices(
  613. viaparinfo->chip_info->
  614. lvds_chip_info2.output_interface);
  615. else
  616. viaparinfo->shared->iga2_devices |= get_lcd_devices(
  617. viaparinfo->chip_info->
  618. lvds_chip_info2.output_interface);
  619. }
  620. /* looks like the OLPC has its display wired to DVP1 and LVDS2 */
  621. if (machine_is_olpc())
  622. viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;
  623. }
  624. static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
  625. {
  626. outb(0xFF, 0x3C6); /* bit mask of palette */
  627. outb(index, 0x3C8);
  628. outb(red, 0x3C9);
  629. outb(green, 0x3C9);
  630. outb(blue, 0x3C9);
  631. }
  632. void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)
  633. {
  634. viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);
  635. set_color_register(index, red, green, blue);
  636. }
  637. void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
  638. {
  639. viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);
  640. set_color_register(index, red, green, blue);
  641. }
  642. static void set_source_common(u8 index, u8 offset, u8 iga)
  643. {
  644. u8 value, mask = 1 << offset;
  645. switch (iga) {
  646. case IGA1:
  647. value = 0x00;
  648. break;
  649. case IGA2:
  650. value = mask;
  651. break;
  652. default:
  653. printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
  654. return;
  655. }
  656. via_write_reg_mask(VIACR, index, value, mask);
  657. }
  658. static void set_crt_source(u8 iga)
  659. {
  660. u8 value;
  661. switch (iga) {
  662. case IGA1:
  663. value = 0x00;
  664. break;
  665. case IGA2:
  666. value = 0x40;
  667. break;
  668. default:
  669. printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
  670. return;
  671. }
  672. via_write_reg_mask(VIASR, 0x16, value, 0x40);
  673. }
  674. static inline void set_ldvp0_source(u8 iga)
  675. {
  676. set_source_common(0x6C, 7, iga);
  677. }
  678. static inline void set_ldvp1_source(u8 iga)
  679. {
  680. set_source_common(0x93, 7, iga);
  681. }
  682. static inline void set_dvp0_source(u8 iga)
  683. {
  684. set_source_common(0x96, 4, iga);
  685. }
  686. static inline void set_dvp1_source(u8 iga)
  687. {
  688. set_source_common(0x9B, 4, iga);
  689. }
  690. static inline void set_lvds1_source(u8 iga)
  691. {
  692. set_source_common(0x99, 4, iga);
  693. }
  694. static inline void set_lvds2_source(u8 iga)
  695. {
  696. set_source_common(0x97, 4, iga);
  697. }
  698. void via_set_source(u32 devices, u8 iga)
  699. {
  700. if (devices & VIA_LDVP0)
  701. set_ldvp0_source(iga);
  702. if (devices & VIA_LDVP1)
  703. set_ldvp1_source(iga);
  704. if (devices & VIA_DVP0)
  705. set_dvp0_source(iga);
  706. if (devices & VIA_CRT)
  707. set_crt_source(iga);
  708. if (devices & VIA_DVP1)
  709. set_dvp1_source(iga);
  710. if (devices & VIA_LVDS1)
  711. set_lvds1_source(iga);
  712. if (devices & VIA_LVDS2)
  713. set_lvds2_source(iga);
  714. }
  715. static void set_crt_state(u8 state)
  716. {
  717. u8 value;
  718. switch (state) {
  719. case VIA_STATE_ON:
  720. value = 0x00;
  721. break;
  722. case VIA_STATE_STANDBY:
  723. value = 0x10;
  724. break;
  725. case VIA_STATE_SUSPEND:
  726. value = 0x20;
  727. break;
  728. case VIA_STATE_OFF:
  729. value = 0x30;
  730. break;
  731. default:
  732. return;
  733. }
  734. via_write_reg_mask(VIACR, 0x36, value, 0x30);
  735. }
  736. static void set_dvp0_state(u8 state)
  737. {
  738. u8 value;
  739. switch (state) {
  740. case VIA_STATE_ON:
  741. value = 0xC0;
  742. break;
  743. case VIA_STATE_OFF:
  744. value = 0x00;
  745. break;
  746. default:
  747. return;
  748. }
  749. via_write_reg_mask(VIASR, 0x1E, value, 0xC0);
  750. }
  751. static void set_dvp1_state(u8 state)
  752. {
  753. u8 value;
  754. switch (state) {
  755. case VIA_STATE_ON:
  756. value = 0x30;
  757. break;
  758. case VIA_STATE_OFF:
  759. value = 0x00;
  760. break;
  761. default:
  762. return;
  763. }
  764. via_write_reg_mask(VIASR, 0x1E, value, 0x30);
  765. }
  766. static void set_lvds1_state(u8 state)
  767. {
  768. u8 value;
  769. switch (state) {
  770. case VIA_STATE_ON:
  771. value = 0x03;
  772. break;
  773. case VIA_STATE_OFF:
  774. value = 0x00;
  775. break;
  776. default:
  777. return;
  778. }
  779. via_write_reg_mask(VIASR, 0x2A, value, 0x03);
  780. }
  781. static void set_lvds2_state(u8 state)
  782. {
  783. u8 value;
  784. switch (state) {
  785. case VIA_STATE_ON:
  786. value = 0x0C;
  787. break;
  788. case VIA_STATE_OFF:
  789. value = 0x00;
  790. break;
  791. default:
  792. return;
  793. }
  794. via_write_reg_mask(VIASR, 0x2A, value, 0x0C);
  795. }
  796. void via_set_state(u32 devices, u8 state)
  797. {
  798. /*
  799. TODO: Can we enable/disable these devices? How?
  800. if (devices & VIA_LDVP0)
  801. if (devices & VIA_LDVP1)
  802. */
  803. if (devices & VIA_DVP0)
  804. set_dvp0_state(state);
  805. if (devices & VIA_CRT)
  806. set_crt_state(state);
  807. if (devices & VIA_DVP1)
  808. set_dvp1_state(state);
  809. if (devices & VIA_LVDS1)
  810. set_lvds1_state(state);
  811. if (devices & VIA_LVDS2)
  812. set_lvds2_state(state);
  813. }
  814. void via_set_sync_polarity(u32 devices, u8 polarity)
  815. {
  816. if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) {
  817. printk(KERN_WARNING "viafb: Unsupported polarity: %d\n",
  818. polarity);
  819. return;
  820. }
  821. if (devices & VIA_CRT)
  822. via_write_misc_reg_mask(polarity << 6, 0xC0);
  823. if (devices & VIA_DVP1)
  824. via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60);
  825. if (devices & VIA_LVDS1)
  826. via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60);
  827. if (devices & VIA_LVDS2)
  828. via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60);
  829. }
  830. u32 via_parse_odev(char *input, char **end)
  831. {
  832. char *ptr = input;
  833. u32 odev = 0;
  834. bool next = true;
  835. int i, len;
  836. while (next) {
  837. next = false;
  838. for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
  839. len = strlen(device_mapping[i].name);
  840. if (!strncmp(ptr, device_mapping[i].name, len)) {
  841. odev |= device_mapping[i].device;
  842. ptr += len;
  843. if (*ptr == ',') {
  844. ptr++;
  845. next = true;
  846. }
  847. }
  848. }
  849. }
  850. *end = ptr;
  851. return odev;
  852. }
  853. void via_odev_to_seq(struct seq_file *m, u32 odev)
  854. {
  855. int i, count = 0;
  856. for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
  857. if (odev & device_mapping[i].device) {
  858. if (count > 0)
  859. seq_putc(m, ',');
  860. seq_puts(m, device_mapping[i].name);
  861. count++;
  862. }
  863. }
  864. seq_putc(m, '\n');
  865. }
  866. static void load_fix_bit_crtc_reg(void)
  867. {
  868. viafb_unlock_crt();
  869. /* always set to 1 */
  870. viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
  871. /* line compare should set all bits = 1 (extend modes) */
  872. viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
  873. /* line compare should set all bits = 1 (extend modes) */
  874. viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
  875. /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
  876. viafb_lock_crt();
  877. /* If K8M800, enable Prefetch Mode. */
  878. if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
  879. || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
  880. viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
  881. if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
  882. && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
  883. viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
  884. }
  885. void viafb_load_reg(int timing_value, int viafb_load_reg_num,
  886. struct io_register *reg,
  887. int io_type)
  888. {
  889. int reg_mask;
  890. int bit_num = 0;
  891. int data;
  892. int i, j;
  893. int shift_next_reg;
  894. int start_index, end_index, cr_index;
  895. u16 get_bit;
  896. for (i = 0; i < viafb_load_reg_num; i++) {
  897. reg_mask = 0;
  898. data = 0;
  899. start_index = reg[i].start_bit;
  900. end_index = reg[i].end_bit;
  901. cr_index = reg[i].io_addr;
  902. shift_next_reg = bit_num;
  903. for (j = start_index; j <= end_index; j++) {
  904. /*if (bit_num==8) timing_value = timing_value >>8; */
  905. reg_mask = reg_mask | (BIT0 << j);
  906. get_bit = (timing_value & (BIT0 << bit_num));
  907. data =
  908. data | ((get_bit >> shift_next_reg) << start_index);
  909. bit_num++;
  910. }
  911. if (io_type == VIACR)
  912. viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
  913. else
  914. viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
  915. }
  916. }
  917. /* Write Registers */
  918. void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
  919. {
  920. int i;
  921. /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
  922. for (i = 0; i < ItemNum; i++)
  923. via_write_reg_mask(RegTable[i].port, RegTable[i].index,
  924. RegTable[i].value, RegTable[i].mask);
  925. }
  926. void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
  927. {
  928. int reg_value;
  929. int viafb_load_reg_num;
  930. struct io_register *reg = NULL;
  931. switch (set_iga) {
  932. case IGA1:
  933. reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
  934. viafb_load_reg_num = fetch_count_reg.
  935. iga1_fetch_count_reg.reg_num;
  936. reg = fetch_count_reg.iga1_fetch_count_reg.reg;
  937. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
  938. break;
  939. case IGA2:
  940. reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
  941. viafb_load_reg_num = fetch_count_reg.
  942. iga2_fetch_count_reg.reg_num;
  943. reg = fetch_count_reg.iga2_fetch_count_reg.reg;
  944. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
  945. break;
  946. }
  947. }
  948. void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
  949. {
  950. int reg_value;
  951. int viafb_load_reg_num;
  952. struct io_register *reg = NULL;
  953. int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
  954. 0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
  955. int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
  956. 0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
  957. if (set_iga == IGA1) {
  958. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
  959. iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
  960. iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
  961. iga1_fifo_high_threshold =
  962. K800_IGA1_FIFO_HIGH_THRESHOLD;
  963. /* If resolution > 1280x1024, expire length = 64, else
  964. expire length = 128 */
  965. if ((hor_active > 1280) && (ver_active > 1024))
  966. iga1_display_queue_expire_num = 16;
  967. else
  968. iga1_display_queue_expire_num =
  969. K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  970. }
  971. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
  972. iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
  973. iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
  974. iga1_fifo_high_threshold =
  975. P880_IGA1_FIFO_HIGH_THRESHOLD;
  976. iga1_display_queue_expire_num =
  977. P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  978. /* If resolution > 1280x1024, expire length = 64, else
  979. expire length = 128 */
  980. if ((hor_active > 1280) && (ver_active > 1024))
  981. iga1_display_queue_expire_num = 16;
  982. else
  983. iga1_display_queue_expire_num =
  984. P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  985. }
  986. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
  987. iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
  988. iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
  989. iga1_fifo_high_threshold =
  990. CN700_IGA1_FIFO_HIGH_THRESHOLD;
  991. /* If resolution > 1280x1024, expire length = 64,
  992. else expire length = 128 */
  993. if ((hor_active > 1280) && (ver_active > 1024))
  994. iga1_display_queue_expire_num = 16;
  995. else
  996. iga1_display_queue_expire_num =
  997. CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  998. }
  999. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
  1000. iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
  1001. iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
  1002. iga1_fifo_high_threshold =
  1003. CX700_IGA1_FIFO_HIGH_THRESHOLD;
  1004. iga1_display_queue_expire_num =
  1005. CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  1006. }
  1007. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
  1008. iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
  1009. iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
  1010. iga1_fifo_high_threshold =
  1011. K8M890_IGA1_FIFO_HIGH_THRESHOLD;
  1012. iga1_display_queue_expire_num =
  1013. K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  1014. }
  1015. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
  1016. iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
  1017. iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
  1018. iga1_fifo_high_threshold =
  1019. P4M890_IGA1_FIFO_HIGH_THRESHOLD;
  1020. iga1_display_queue_expire_num =
  1021. P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  1022. }
  1023. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
  1024. iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
  1025. iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
  1026. iga1_fifo_high_threshold =
  1027. P4M900_IGA1_FIFO_HIGH_THRESHOLD;
  1028. iga1_display_queue_expire_num =
  1029. P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  1030. }
  1031. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
  1032. iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
  1033. iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
  1034. iga1_fifo_high_threshold =
  1035. VX800_IGA1_FIFO_HIGH_THRESHOLD;
  1036. iga1_display_queue_expire_num =
  1037. VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  1038. }
  1039. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
  1040. iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;
  1041. iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;
  1042. iga1_fifo_high_threshold =
  1043. VX855_IGA1_FIFO_HIGH_THRESHOLD;
  1044. iga1_display_queue_expire_num =
  1045. VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  1046. }
  1047. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
  1048. iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH;
  1049. iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD;
  1050. iga1_fifo_high_threshold =
  1051. VX900_IGA1_FIFO_HIGH_THRESHOLD;
  1052. iga1_display_queue_expire_num =
  1053. VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
  1054. }
  1055. /* Set Display FIFO Depath Select */
  1056. reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
  1057. viafb_load_reg_num =
  1058. display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
  1059. reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
  1060. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
  1061. /* Set Display FIFO Threshold Select */
  1062. reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
  1063. viafb_load_reg_num =
  1064. fifo_threshold_select_reg.
  1065. iga1_fifo_threshold_select_reg.reg_num;
  1066. reg =
  1067. fifo_threshold_select_reg.
  1068. iga1_fifo_threshold_select_reg.reg;
  1069. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
  1070. /* Set FIFO High Threshold Select */
  1071. reg_value =
  1072. IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
  1073. viafb_load_reg_num =
  1074. fifo_high_threshold_select_reg.
  1075. iga1_fifo_high_threshold_select_reg.reg_num;
  1076. reg =
  1077. fifo_high_threshold_select_reg.
  1078. iga1_fifo_high_threshold_select_reg.reg;
  1079. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
  1080. /* Set Display Queue Expire Num */
  1081. reg_value =
  1082. IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
  1083. (iga1_display_queue_expire_num);
  1084. viafb_load_reg_num =
  1085. display_queue_expire_num_reg.
  1086. iga1_display_queue_expire_num_reg.reg_num;
  1087. reg =
  1088. display_queue_expire_num_reg.
  1089. iga1_display_queue_expire_num_reg.reg;
  1090. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
  1091. } else {
  1092. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
  1093. iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
  1094. iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
  1095. iga2_fifo_high_threshold =
  1096. K800_IGA2_FIFO_HIGH_THRESHOLD;
  1097. /* If resolution > 1280x1024, expire length = 64,
  1098. else expire length = 128 */
  1099. if ((hor_active > 1280) && (ver_active > 1024))
  1100. iga2_display_queue_expire_num = 16;
  1101. else
  1102. iga2_display_queue_expire_num =
  1103. K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1104. }
  1105. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
  1106. iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
  1107. iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
  1108. iga2_fifo_high_threshold =
  1109. P880_IGA2_FIFO_HIGH_THRESHOLD;
  1110. /* If resolution > 1280x1024, expire length = 64,
  1111. else expire length = 128 */
  1112. if ((hor_active > 1280) && (ver_active > 1024))
  1113. iga2_display_queue_expire_num = 16;
  1114. else
  1115. iga2_display_queue_expire_num =
  1116. P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1117. }
  1118. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
  1119. iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
  1120. iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
  1121. iga2_fifo_high_threshold =
  1122. CN700_IGA2_FIFO_HIGH_THRESHOLD;
  1123. /* If resolution > 1280x1024, expire length = 64,
  1124. else expire length = 128 */
  1125. if ((hor_active > 1280) && (ver_active > 1024))
  1126. iga2_display_queue_expire_num = 16;
  1127. else
  1128. iga2_display_queue_expire_num =
  1129. CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1130. }
  1131. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
  1132. iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
  1133. iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
  1134. iga2_fifo_high_threshold =
  1135. CX700_IGA2_FIFO_HIGH_THRESHOLD;
  1136. iga2_display_queue_expire_num =
  1137. CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1138. }
  1139. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
  1140. iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
  1141. iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
  1142. iga2_fifo_high_threshold =
  1143. K8M890_IGA2_FIFO_HIGH_THRESHOLD;
  1144. iga2_display_queue_expire_num =
  1145. K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1146. }
  1147. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
  1148. iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
  1149. iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
  1150. iga2_fifo_high_threshold =
  1151. P4M890_IGA2_FIFO_HIGH_THRESHOLD;
  1152. iga2_display_queue_expire_num =
  1153. P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1154. }
  1155. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
  1156. iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
  1157. iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
  1158. iga2_fifo_high_threshold =
  1159. P4M900_IGA2_FIFO_HIGH_THRESHOLD;
  1160. iga2_display_queue_expire_num =
  1161. P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1162. }
  1163. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
  1164. iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
  1165. iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
  1166. iga2_fifo_high_threshold =
  1167. VX800_IGA2_FIFO_HIGH_THRESHOLD;
  1168. iga2_display_queue_expire_num =
  1169. VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1170. }
  1171. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
  1172. iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;
  1173. iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;
  1174. iga2_fifo_high_threshold =
  1175. VX855_IGA2_FIFO_HIGH_THRESHOLD;
  1176. iga2_display_queue_expire_num =
  1177. VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1178. }
  1179. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
  1180. iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH;
  1181. iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD;
  1182. iga2_fifo_high_threshold =
  1183. VX900_IGA2_FIFO_HIGH_THRESHOLD;
  1184. iga2_display_queue_expire_num =
  1185. VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
  1186. }
  1187. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
  1188. /* Set Display FIFO Depath Select */
  1189. reg_value =
  1190. IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
  1191. - 1;
  1192. /* Patch LCD in IGA2 case */
  1193. viafb_load_reg_num =
  1194. display_fifo_depth_reg.
  1195. iga2_fifo_depth_select_reg.reg_num;
  1196. reg =
  1197. display_fifo_depth_reg.
  1198. iga2_fifo_depth_select_reg.reg;
  1199. viafb_load_reg(reg_value,
  1200. viafb_load_reg_num, reg, VIACR);
  1201. } else {
  1202. /* Set Display FIFO Depath Select */
  1203. reg_value =
  1204. IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
  1205. viafb_load_reg_num =
  1206. display_fifo_depth_reg.
  1207. iga2_fifo_depth_select_reg.reg_num;
  1208. reg =
  1209. display_fifo_depth_reg.
  1210. iga2_fifo_depth_select_reg.reg;
  1211. viafb_load_reg(reg_value,
  1212. viafb_load_reg_num, reg, VIACR);
  1213. }
  1214. /* Set Display FIFO Threshold Select */
  1215. reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
  1216. viafb_load_reg_num =
  1217. fifo_threshold_select_reg.
  1218. iga2_fifo_threshold_select_reg.reg_num;
  1219. reg =
  1220. fifo_threshold_select_reg.
  1221. iga2_fifo_threshold_select_reg.reg;
  1222. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
  1223. /* Set FIFO High Threshold Select */
  1224. reg_value =
  1225. IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
  1226. viafb_load_reg_num =
  1227. fifo_high_threshold_select_reg.
  1228. iga2_fifo_high_threshold_select_reg.reg_num;
  1229. reg =
  1230. fifo_high_threshold_select_reg.
  1231. iga2_fifo_high_threshold_select_reg.reg;
  1232. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
  1233. /* Set Display Queue Expire Num */
  1234. reg_value =
  1235. IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
  1236. (iga2_display_queue_expire_num);
  1237. viafb_load_reg_num =
  1238. display_queue_expire_num_reg.
  1239. iga2_display_queue_expire_num_reg.reg_num;
  1240. reg =
  1241. display_queue_expire_num_reg.
  1242. iga2_display_queue_expire_num_reg.reg;
  1243. viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
  1244. }
  1245. }
  1246. static struct via_pll_config get_pll_config(struct pll_limit *limits, int size,
  1247. int clk)
  1248. {
  1249. struct via_pll_config cur, up, down, best = {0, 1, 0};
  1250. const u32 f0 = 14318180; /* X1 frequency */
  1251. int i, f;
  1252. for (i = 0; i < size; i++) {
  1253. cur.rshift = limits[i].rshift;
  1254. cur.divisor = limits[i].divisor;
  1255. cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);
  1256. f = abs(get_pll_output_frequency(f0, cur) - clk);
  1257. up = down = cur;
  1258. up.multiplier++;
  1259. down.multiplier--;
  1260. if (abs(get_pll_output_frequency(f0, up) - clk) < f)
  1261. cur = up;
  1262. else if (abs(get_pll_output_frequency(f0, down) - clk) < f)
  1263. cur = down;
  1264. if (cur.multiplier < limits[i].multiplier_min)
  1265. cur.multiplier = limits[i].multiplier_min;
  1266. else if (cur.multiplier > limits[i].multiplier_max)
  1267. cur.multiplier = limits[i].multiplier_max;
  1268. f = abs(get_pll_output_frequency(f0, cur) - clk);
  1269. if (f < abs(get_pll_output_frequency(f0, best) - clk))
  1270. best = cur;
  1271. }
  1272. return best;
  1273. }
  1274. static struct via_pll_config get_best_pll_config(int clk)
  1275. {
  1276. struct via_pll_config config;
  1277. switch (viaparinfo->chip_info->gfx_chip_name) {
  1278. case UNICHROME_CLE266:
  1279. case UNICHROME_K400:
  1280. config = get_pll_config(cle266_pll_limits,
  1281. ARRAY_SIZE(cle266_pll_limits), clk);
  1282. break;
  1283. case UNICHROME_K800:
  1284. case UNICHROME_PM800:
  1285. case UNICHROME_CN700:
  1286. config = get_pll_config(k800_pll_limits,
  1287. ARRAY_SIZE(k800_pll_limits), clk);
  1288. break;
  1289. case UNICHROME_CX700:
  1290. case UNICHROME_CN750:
  1291. case UNICHROME_K8M890:
  1292. case UNICHROME_P4M890:
  1293. case UNICHROME_P4M900:
  1294. case UNICHROME_VX800:
  1295. config = get_pll_config(cx700_pll_limits,
  1296. ARRAY_SIZE(cx700_pll_limits), clk);
  1297. break;
  1298. case UNICHROME_VX855:
  1299. case UNICHROME_VX900:
  1300. config = get_pll_config(vx855_pll_limits,
  1301. ARRAY_SIZE(vx855_pll_limits), clk);
  1302. break;
  1303. }
  1304. return config;
  1305. }
  1306. /* Set VCLK*/
  1307. void viafb_set_vclock(u32 clk, int set_iga)
  1308. {
  1309. struct via_pll_config config = get_best_pll_config(clk);
  1310. if (set_iga == IGA1)
  1311. clock.set_primary_pll(config);
  1312. if (set_iga == IGA2)
  1313. clock.set_secondary_pll(config);
  1314. /* Fire! */
  1315. via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
  1316. }
  1317. struct via_display_timing var_to_timing(const struct fb_var_screeninfo *var,
  1318. u16 cxres, u16 cyres)
  1319. {
  1320. struct via_display_timing timing;
  1321. u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
  1322. timing.hor_addr = cxres;
  1323. timing.hor_sync_start = timing.hor_addr + var->right_margin + dx;
  1324. timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
  1325. timing.hor_total = timing.hor_sync_end + var->left_margin + dx;
  1326. timing.hor_blank_start = timing.hor_addr + dx;
  1327. timing.hor_blank_end = timing.hor_total - dx;
  1328. timing.ver_addr = cyres;
  1329. timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy;
  1330. timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
  1331. timing.ver_total = timing.ver_sync_end + var->upper_margin + dy;
  1332. timing.ver_blank_start = timing.ver_addr + dy;
  1333. timing.ver_blank_end = timing.ver_total - dy;
  1334. return timing;
  1335. }
  1336. void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
  1337. u16 cxres, u16 cyres, int iga)
  1338. {
  1339. struct via_display_timing crt_reg = var_to_timing(var,
  1340. cxres ? cxres : var->xres, cyres ? cyres : var->yres);
  1341. if (iga == IGA1)
  1342. via_set_primary_timing(&crt_reg);
  1343. else if (iga == IGA2)
  1344. via_set_secondary_timing(&crt_reg);
  1345. viafb_load_fetch_count_reg(var->xres, var->bits_per_pixel / 8, iga);
  1346. if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266
  1347. && viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)
  1348. viafb_load_FIFO_reg(iga, var->xres, var->yres);
  1349. viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);
  1350. }
  1351. void viafb_init_chip_info(int chip_type)
  1352. {
  1353. via_clock_init(&clock, chip_type);
  1354. init_gfx_chip_info(chip_type);
  1355. init_tmds_chip_info();
  1356. init_lvds_chip_info();
  1357. /*Set IGA path for each device */
  1358. viafb_set_iga_path();
  1359. viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
  1360. viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
  1361. viaparinfo->lvds_setting_info2->display_method =
  1362. viaparinfo->lvds_setting_info->display_method;
  1363. viaparinfo->lvds_setting_info2->lcd_mode =
  1364. viaparinfo->lvds_setting_info->lcd_mode;
  1365. }
  1366. void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
  1367. {
  1368. if (flag == 0) {
  1369. viaparinfo->tmds_setting_info->h_active = hres;
  1370. viaparinfo->tmds_setting_info->v_active = vres;
  1371. } else {
  1372. if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
  1373. viaparinfo->tmds_setting_info->h_active = hres;
  1374. viaparinfo->tmds_setting_info->v_active = vres;
  1375. }
  1376. }
  1377. }
  1378. static void init_gfx_chip_info(int chip_type)
  1379. {
  1380. u8 tmp;
  1381. viaparinfo->chip_info->gfx_chip_name = chip_type;
  1382. /* Check revision of CLE266 Chip */
  1383. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
  1384. /* CR4F only define in CLE266.CX chip */
  1385. tmp = viafb_read_reg(VIACR, CR4F);
  1386. viafb_write_reg(CR4F, VIACR, 0x55);
  1387. if (viafb_read_reg(VIACR, CR4F) != 0x55)
  1388. viaparinfo->chip_info->gfx_chip_revision =
  1389. CLE266_REVISION_AX;
  1390. else
  1391. viaparinfo->chip_info->gfx_chip_revision =
  1392. CLE266_REVISION_CX;
  1393. /* restore orignal CR4F value */
  1394. viafb_write_reg(CR4F, VIACR, tmp);
  1395. }
  1396. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
  1397. tmp = viafb_read_reg(VIASR, SR43);
  1398. DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
  1399. if (tmp & 0x02) {
  1400. viaparinfo->chip_info->gfx_chip_revision =
  1401. CX700_REVISION_700M2;
  1402. } else if (tmp & 0x40) {
  1403. viaparinfo->chip_info->gfx_chip_revision =
  1404. CX700_REVISION_700M;
  1405. } else {
  1406. viaparinfo->chip_info->gfx_chip_revision =
  1407. CX700_REVISION_700;
  1408. }
  1409. }
  1410. /* Determine which 2D engine we have */
  1411. switch (viaparinfo->chip_info->gfx_chip_name) {
  1412. case UNICHROME_VX800:
  1413. case UNICHROME_VX855:
  1414. case UNICHROME_VX900:
  1415. viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
  1416. break;
  1417. case UNICHROME_K8M890:
  1418. case UNICHROME_P4M900:
  1419. viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;
  1420. break;
  1421. default:
  1422. viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;
  1423. break;
  1424. }
  1425. }
  1426. static void init_tmds_chip_info(void)
  1427. {
  1428. viafb_tmds_trasmitter_identify();
  1429. if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
  1430. output_interface) {
  1431. switch (viaparinfo->chip_info->gfx_chip_name) {
  1432. case UNICHROME_CX700:
  1433. {
  1434. /* we should check support by hardware layout.*/
  1435. if ((viafb_display_hardware_layout ==
  1436. HW_LAYOUT_DVI_ONLY)
  1437. || (viafb_display_hardware_layout ==
  1438. HW_LAYOUT_LCD_DVI)) {
  1439. viaparinfo->chip_info->tmds_chip_info.
  1440. output_interface = INTERFACE_TMDS;
  1441. } else {
  1442. viaparinfo->chip_info->tmds_chip_info.
  1443. output_interface =
  1444. INTERFACE_NONE;
  1445. }
  1446. break;
  1447. }
  1448. case UNICHROME_K8M890:
  1449. case UNICHROME_P4M900:
  1450. case UNICHROME_P4M890:
  1451. /* TMDS on PCIE, we set DFPLOW as default. */
  1452. viaparinfo->chip_info->tmds_chip_info.output_interface =
  1453. INTERFACE_DFP_LOW;
  1454. break;
  1455. default:
  1456. {
  1457. /* set DVP1 default for DVI */
  1458. viaparinfo->chip_info->tmds_chip_info
  1459. .output_interface = INTERFACE_DVP1;
  1460. }
  1461. }
  1462. }
  1463. DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
  1464. viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
  1465. viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,
  1466. &viaparinfo->shared->tmds_setting_info);
  1467. }
  1468. static void init_lvds_chip_info(void)
  1469. {
  1470. viafb_lvds_trasmitter_identify();
  1471. viafb_init_lcd_size();
  1472. viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
  1473. viaparinfo->lvds_setting_info);
  1474. if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
  1475. viafb_init_lvds_output_interface(&viaparinfo->chip_info->
  1476. lvds_chip_info2, viaparinfo->lvds_setting_info2);
  1477. }
  1478. /*If CX700,two singel LCD, we need to reassign
  1479. LCD interface to different LVDS port */
  1480. if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
  1481. && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
  1482. if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
  1483. lvds_chip_name) && (INTEGRATED_LVDS ==
  1484. viaparinfo->chip_info->
  1485. lvds_chip_info2.lvds_chip_name)) {
  1486. viaparinfo->chip_info->lvds_chip_info.output_interface =
  1487. INTERFACE_LVDS0;
  1488. viaparinfo->chip_info->lvds_chip_info2.
  1489. output_interface =
  1490. INTERFACE_LVDS1;
  1491. }
  1492. }
  1493. DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
  1494. viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
  1495. DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
  1496. viaparinfo->chip_info->lvds_chip_info.output_interface);
  1497. DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
  1498. viaparinfo->chip_info->lvds_chip_info.output_interface);
  1499. }
  1500. void viafb_init_dac(int set_iga)
  1501. {
  1502. int i;
  1503. u8 tmp;
  1504. if (set_iga == IGA1) {
  1505. /* access Primary Display's LUT */
  1506. viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
  1507. /* turn off LCK */
  1508. viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
  1509. for (i = 0; i < 256; i++) {
  1510. write_dac_reg(i, palLUT_table[i].red,
  1511. palLUT_table[i].green,
  1512. palLUT_table[i].blue);
  1513. }
  1514. /* turn on LCK */
  1515. viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
  1516. } else {
  1517. tmp = viafb_read_reg(VIACR, CR6A);
  1518. /* access Secondary Display's LUT */
  1519. viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
  1520. viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
  1521. for (i = 0; i < 256; i++) {
  1522. write_dac_reg(i, palLUT_table[i].red,
  1523. palLUT_table[i].green,
  1524. palLUT_table[i].blue);
  1525. }
  1526. /* set IGA1 DAC for default */
  1527. viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
  1528. viafb_write_reg(CR6A, VIACR, tmp);
  1529. }
  1530. }
  1531. static void device_screen_off(void)
  1532. {
  1533. /* turn off CRT screen (IGA1) */
  1534. viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
  1535. }
  1536. static void device_screen_on(void)
  1537. {
  1538. /* turn on CRT screen (IGA1) */
  1539. viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
  1540. }
  1541. static void set_display_channel(void)
  1542. {
  1543. /*If viafb_LCD2_ON, on cx700, internal lvds's information
  1544. is keeped on lvds_setting_info2 */
  1545. if (viafb_LCD2_ON &&
  1546. viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
  1547. /* For dual channel LCD: */
  1548. /* Set to Dual LVDS channel. */
  1549. viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
  1550. } else if (viafb_LCD_ON && viafb_DVI_ON) {
  1551. /* For LCD+DFP: */
  1552. /* Set to LVDS1 + TMDS channel. */
  1553. viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
  1554. } else if (viafb_DVI_ON) {
  1555. /* Set to single TMDS channel. */
  1556. viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
  1557. } else if (viafb_LCD_ON) {
  1558. if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
  1559. /* For dual channel LCD: */
  1560. /* Set to Dual LVDS channel. */
  1561. viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
  1562. } else {
  1563. /* Set to LVDS0 + LVDS1 channel. */
  1564. viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
  1565. }
  1566. }
  1567. }
  1568. static u8 get_sync(struct fb_var_screeninfo *var)
  1569. {
  1570. u8 polarity = 0;
  1571. if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
  1572. polarity |= VIA_HSYNC_NEGATIVE;
  1573. if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
  1574. polarity |= VIA_VSYNC_NEGATIVE;
  1575. return polarity;
  1576. }
  1577. static void hw_init(void)
  1578. {
  1579. int i;
  1580. inb(VIAStatus);
  1581. outb(0x00, VIAAR);
  1582. /* Write Common Setting for Video Mode */
  1583. viafb_write_regx(common_vga, ARRAY_SIZE(common_vga));
  1584. switch (viaparinfo->chip_info->gfx_chip_name) {
  1585. case UNICHROME_CLE266:
  1586. viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
  1587. break;
  1588. case UNICHROME_K400:
  1589. viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
  1590. break;
  1591. case UNICHROME_K800:
  1592. case UNICHROME_PM800:
  1593. viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
  1594. break;
  1595. case UNICHROME_CN700:
  1596. case UNICHROME_K8M890:
  1597. case UNICHROME_P4M890:
  1598. case UNICHROME_P4M900:
  1599. viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
  1600. break;
  1601. case UNICHROME_CX700:
  1602. case UNICHROME_VX800:
  1603. viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
  1604. break;
  1605. case UNICHROME_VX855:
  1606. case UNICHROME_VX900:
  1607. viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
  1608. break;
  1609. }
  1610. /* magic required on VX900 for correct modesetting on IGA1 */
  1611. via_write_reg_mask(VIACR, 0x45, 0x00, 0x01);
  1612. /* probably this should go to the scaling code one day */
  1613. via_write_reg_mask(VIACR, 0xFD, 0, 0x80); /* VX900 hw scale on IGA2 */
  1614. viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
  1615. /* Fill VPIT Parameters */
  1616. /* Write Misc Register */
  1617. outb(VPIT.Misc, VIA_MISC_REG_WRITE);
  1618. /* Write Sequencer */
  1619. for (i = 1; i <= StdSR; i++)
  1620. via_write_reg(VIASR, i, VPIT.SR[i - 1]);
  1621. viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
  1622. /* Write Graphic Controller */
  1623. for (i = 0; i < StdGR; i++)
  1624. via_write_reg(VIAGR, i, VPIT.GR[i]);
  1625. /* Write Attribute Controller */
  1626. for (i = 0; i < StdAR; i++) {
  1627. inb(VIAStatus);
  1628. outb(i, VIAAR);
  1629. outb(VPIT.AR[i], VIAAR);
  1630. }
  1631. inb(VIAStatus);
  1632. outb(0x20, VIAAR);
  1633. load_fix_bit_crtc_reg();
  1634. }
  1635. int viafb_setmode(void)
  1636. {
  1637. int j, cxres = 0, cyres = 0;
  1638. int port;
  1639. u32 devices = viaparinfo->shared->iga1_devices
  1640. | viaparinfo->shared->iga2_devices;
  1641. u8 value, index, mask;
  1642. struct fb_var_screeninfo var2;
  1643. device_screen_off();
  1644. device_off();
  1645. via_set_state(devices, VIA_STATE_OFF);
  1646. hw_init();
  1647. /* Update Patch Register */
  1648. if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
  1649. || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
  1650. && viafbinfo->var.xres == 1024 && viafbinfo->var.yres == 768) {
  1651. for (j = 0; j < res_patch_table[0].table_length; j++) {
  1652. index = res_patch_table[0].io_reg_table[j].index;
  1653. port = res_patch_table[0].io_reg_table[j].port;
  1654. value = res_patch_table[0].io_reg_table[j].value;
  1655. mask = res_patch_table[0].io_reg_table[j].mask;
  1656. viafb_write_reg_mask(index, port, value, mask);
  1657. }
  1658. }
  1659. via_set_primary_pitch(viafbinfo->fix.line_length);
  1660. via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
  1661. : viafbinfo->fix.line_length);
  1662. via_set_primary_color_depth(viaparinfo->depth);
  1663. via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
  1664. : viaparinfo->depth);
  1665. via_set_source(viaparinfo->shared->iga1_devices, IGA1);
  1666. via_set_source(viaparinfo->shared->iga2_devices, IGA2);
  1667. if (viaparinfo->shared->iga2_devices)
  1668. enable_second_display_channel();
  1669. else
  1670. disable_second_display_channel();
  1671. /* Update Refresh Rate Setting */
  1672. /* Clear On Screen */
  1673. if (viafb_dual_fb) {
  1674. var2 = viafbinfo1->var;
  1675. } else if (viafb_SAMM_ON) {
  1676. viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
  1677. viafb_second_xres, viafb_second_yres, viafb_refresh1));
  1678. cxres = viafbinfo->var.xres;
  1679. cyres = viafbinfo->var.yres;
  1680. var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
  1681. }
  1682. /* CRT set mode */
  1683. if (viafb_CRT_ON) {
  1684. if (viaparinfo->shared->iga2_devices & VIA_CRT
  1685. && viafb_SAMM_ON)
  1686. viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2);
  1687. else
  1688. viafb_fill_crtc_timing(&viafbinfo->var, 0, 0,
  1689. (viaparinfo->shared->iga1_devices & VIA_CRT)
  1690. ? IGA1 : IGA2);
  1691. /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
  1692. to 8 alignment (1368),there is several pixels (2 pixels)
  1693. on right side of screen. */
  1694. if (viafbinfo->var.xres % 8) {
  1695. viafb_unlock_crt();
  1696. viafb_write_reg(CR02, VIACR,
  1697. viafb_read_reg(VIACR, CR02) - 1);
  1698. viafb_lock_crt();
  1699. }
  1700. }
  1701. if (viafb_DVI_ON) {
  1702. if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
  1703. && viafb_SAMM_ON)
  1704. viafb_dvi_set_mode(&var2, cxres, cyres, IGA2);
  1705. else
  1706. viafb_dvi_set_mode(&viafbinfo->var, 0, 0,
  1707. viaparinfo->tmds_setting_info->iga_path);
  1708. }
  1709. if (viafb_LCD_ON) {
  1710. if (viafb_SAMM_ON &&
  1711. (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
  1712. viafb_lcd_set_mode(&var2, cxres, cyres,
  1713. viaparinfo->lvds_setting_info,
  1714. &viaparinfo->chip_info->lvds_chip_info);
  1715. } else {
  1716. /* IGA1 doesn't have LCD scaling, so set it center. */
  1717. if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
  1718. viaparinfo->lvds_setting_info->display_method =
  1719. LCD_CENTERING;
  1720. }
  1721. viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
  1722. viaparinfo->lvds_setting_info,
  1723. &viaparinfo->chip_info->lvds_chip_info);
  1724. }
  1725. }
  1726. if (viafb_LCD2_ON) {
  1727. if (viafb_SAMM_ON &&
  1728. (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
  1729. viafb_lcd_set_mode(&var2, cxres, cyres,
  1730. viaparinfo->lvds_setting_info2,
  1731. &viaparinfo->chip_info->lvds_chip_info2);
  1732. } else {
  1733. /* IGA1 doesn't have LCD scaling, so set it center. */
  1734. if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
  1735. viaparinfo->lvds_setting_info2->display_method =
  1736. LCD_CENTERING;
  1737. }
  1738. viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
  1739. viaparinfo->lvds_setting_info2,
  1740. &viaparinfo->chip_info->lvds_chip_info2);
  1741. }
  1742. }
  1743. if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
  1744. && (viafb_LCD_ON || viafb_DVI_ON))
  1745. set_display_channel();
  1746. /* If set mode normally, save resolution information for hot-plug . */
  1747. if (!viafb_hotplug) {
  1748. viafb_hotplug_Xres = viafbinfo->var.xres;
  1749. viafb_hotplug_Yres = viafbinfo->var.yres;
  1750. viafb_hotplug_bpp = viafbinfo->var.bits_per_pixel;
  1751. viafb_hotplug_refresh = viafb_refresh;
  1752. if (viafb_DVI_ON)
  1753. viafb_DeviceStatus = DVI_Device;
  1754. else
  1755. viafb_DeviceStatus = CRT_Device;
  1756. }
  1757. device_on();
  1758. if (!viafb_SAMM_ON)
  1759. via_set_sync_polarity(devices, get_sync(&viafbinfo->var));
  1760. else {
  1761. via_set_sync_polarity(viaparinfo->shared->iga1_devices,
  1762. get_sync(&viafbinfo->var));
  1763. via_set_sync_polarity(viaparinfo->shared->iga2_devices,
  1764. get_sync(&var2));
  1765. }
  1766. clock.set_engine_pll_state(VIA_STATE_ON);
  1767. clock.set_primary_clock_source(VIA_CLKSRC_X1, true);
  1768. clock.set_secondary_clock_source(VIA_CLKSRC_X1, true);
  1769. #ifdef CONFIG_FB_VIA_X_COMPATIBILITY
  1770. clock.set_primary_pll_state(VIA_STATE_ON);
  1771. clock.set_primary_clock_state(VIA_STATE_ON);
  1772. clock.set_secondary_pll_state(VIA_STATE_ON);
  1773. clock.set_secondary_clock_state(VIA_STATE_ON);
  1774. #else
  1775. if (viaparinfo->shared->iga1_devices) {
  1776. clock.set_primary_pll_state(VIA_STATE_ON);
  1777. clock.set_primary_clock_state(VIA_STATE_ON);
  1778. } else {
  1779. clock.set_primary_pll_state(VIA_STATE_OFF);
  1780. clock.set_primary_clock_state(VIA_STATE_OFF);
  1781. }
  1782. if (viaparinfo->shared->iga2_devices) {
  1783. clock.set_secondary_pll_state(VIA_STATE_ON);
  1784. clock.set_secondary_clock_state(VIA_STATE_ON);
  1785. } else {
  1786. clock.set_secondary_pll_state(VIA_STATE_OFF);
  1787. clock.set_secondary_clock_state(VIA_STATE_OFF);
  1788. }
  1789. #endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/
  1790. via_set_state(devices, VIA_STATE_ON);
  1791. device_screen_on();
  1792. return 1;
  1793. }
  1794. int viafb_get_refresh(int hres, int vres, u32 long_refresh)
  1795. {
  1796. const struct fb_videomode *best;
  1797. best = viafb_get_best_mode(hres, vres, long_refresh);
  1798. if (!best)
  1799. return 60;
  1800. if (abs(best->refresh - long_refresh) > 3) {
  1801. if (hres == 1200 && vres == 900)
  1802. return 49; /* OLPC DCON only supports 50 Hz */
  1803. else
  1804. return 60;
  1805. }
  1806. return best->refresh;
  1807. }
  1808. static void device_off(void)
  1809. {
  1810. viafb_dvi_disable();
  1811. viafb_lcd_disable();
  1812. }
  1813. static void device_on(void)
  1814. {
  1815. if (viafb_DVI_ON == 1)
  1816. viafb_dvi_enable();
  1817. if (viafb_LCD_ON == 1)
  1818. viafb_lcd_enable();
  1819. }
  1820. static void enable_second_display_channel(void)
  1821. {
  1822. /* to enable second display channel. */
  1823. viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
  1824. viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
  1825. viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
  1826. }
  1827. static void disable_second_display_channel(void)
  1828. {
  1829. /* to disable second display channel. */
  1830. viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
  1831. viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
  1832. viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
  1833. }
  1834. void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
  1835. *p_gfx_dpa_setting)
  1836. {
  1837. switch (output_interface) {
  1838. case INTERFACE_DVP0:
  1839. {
  1840. /* DVP0 Clock Polarity and Adjust: */
  1841. viafb_write_reg_mask(CR96, VIACR,
  1842. p_gfx_dpa_setting->DVP0, 0x0F);
  1843. /* DVP0 Clock and Data Pads Driving: */
  1844. viafb_write_reg_mask(SR1E, VIASR,
  1845. p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
  1846. viafb_write_reg_mask(SR2A, VIASR,
  1847. p_gfx_dpa_setting->DVP0ClockDri_S1,
  1848. BIT4);
  1849. viafb_write_reg_mask(SR1B, VIASR,
  1850. p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
  1851. viafb_write_reg_mask(SR2A, VIASR,
  1852. p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
  1853. break;
  1854. }
  1855. case INTERFACE_DVP1:
  1856. {
  1857. /* DVP1 Clock Polarity and Adjust: */
  1858. viafb_write_reg_mask(CR9B, VIACR,
  1859. p_gfx_dpa_setting->DVP1, 0x0F);
  1860. /* DVP1 Clock and Data Pads Driving: */
  1861. viafb_write_reg_mask(SR65, VIASR,
  1862. p_gfx_dpa_setting->DVP1Driving, 0x0F);
  1863. break;
  1864. }
  1865. case INTERFACE_DFP_HIGH:
  1866. {
  1867. viafb_write_reg_mask(CR97, VIACR,
  1868. p_gfx_dpa_setting->DFPHigh, 0x0F);
  1869. break;
  1870. }
  1871. case INTERFACE_DFP_LOW:
  1872. {
  1873. viafb_write_reg_mask(CR99, VIACR,
  1874. p_gfx_dpa_setting->DFPLow, 0x0F);
  1875. break;
  1876. }
  1877. case INTERFACE_DFP:
  1878. {
  1879. viafb_write_reg_mask(CR97, VIACR,
  1880. p_gfx_dpa_setting->DFPHigh, 0x0F);
  1881. viafb_write_reg_mask(CR99, VIACR,
  1882. p_gfx_dpa_setting->DFPLow, 0x0F);
  1883. break;
  1884. }
  1885. }
  1886. }
  1887. void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
  1888. const struct fb_videomode *mode)
  1889. {
  1890. var->pixclock = mode->pixclock;
  1891. var->xres = mode->xres;
  1892. var->yres = mode->yres;
  1893. var->left_margin = mode->left_margin;
  1894. var->right_margin = mode->right_margin;
  1895. var->hsync_len = mode->hsync_len;
  1896. var->upper_margin = mode->upper_margin;
  1897. var->lower_margin = mode->lower_margin;
  1898. var->vsync_len = mode->vsync_len;
  1899. var->sync = mode->sync;
  1900. }