hw.c 72 KB

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