hw.c 70 KB

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