ast_post.c 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097
  1. /*
  2. * Copyright 2012 Red Hat Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sub license, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  15. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  16. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  17. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  18. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. *
  20. * The above copyright notice and this permission notice (including the
  21. * next paragraph) shall be included in all copies or substantial portions
  22. * of the Software.
  23. *
  24. */
  25. /*
  26. * Authors: Dave Airlie <airlied@redhat.com>
  27. */
  28. #include <linux/delay.h>
  29. #include <linux/pci.h>
  30. #include <drm/drm_print.h>
  31. #include "ast_dram_tables.h"
  32. #include "ast_drv.h"
  33. static void ast_post_chip_2300(struct drm_device *dev);
  34. static void ast_post_chip_2500(struct drm_device *dev);
  35. static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
  36. static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
  37. static void
  38. ast_set_def_ext_reg(struct drm_device *dev)
  39. {
  40. struct ast_device *ast = to_ast_device(dev);
  41. u8 i, index, reg;
  42. const u8 *ext_reg_info;
  43. /* reset scratch */
  44. for (i = 0x81; i <= 0x9f; i++)
  45. ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00);
  46. if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast))
  47. ext_reg_info = extreginfo_ast2300;
  48. else
  49. ext_reg_info = extreginfo;
  50. index = 0xa0;
  51. while (*ext_reg_info != 0xff) {
  52. ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info);
  53. index++;
  54. ext_reg_info++;
  55. }
  56. /* disable standard IO/MEM decode if secondary */
  57. /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */
  58. /* Set Ext. Default */
  59. ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01);
  60. ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00);
  61. /* Enable RAMDAC for A1 */
  62. reg = 0x04;
  63. if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast))
  64. reg |= 0x20;
  65. ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg);
  66. }
  67. static u32 __ast_mindwm(void __iomem *regs, u32 r)
  68. {
  69. u32 data;
  70. __ast_write32(regs, 0xf004, r & 0xffff0000);
  71. __ast_write32(regs, 0xf000, 0x1);
  72. do {
  73. data = __ast_read32(regs, 0xf004) & 0xffff0000;
  74. } while (data != (r & 0xffff0000));
  75. return __ast_read32(regs, 0x10000 + (r & 0x0000ffff));
  76. }
  77. static void __ast_moutdwm(void __iomem *regs, u32 r, u32 v)
  78. {
  79. u32 data;
  80. __ast_write32(regs, 0xf004, r & 0xffff0000);
  81. __ast_write32(regs, 0xf000, 0x1);
  82. do {
  83. data = __ast_read32(regs, 0xf004) & 0xffff0000;
  84. } while (data != (r & 0xffff0000));
  85. __ast_write32(regs, 0x10000 + (r & 0x0000ffff), v);
  86. }
  87. u32 ast_mindwm(struct ast_device *ast, u32 r)
  88. {
  89. return __ast_mindwm(ast->regs, r);
  90. }
  91. void ast_moutdwm(struct ast_device *ast, u32 r, u32 v)
  92. {
  93. __ast_moutdwm(ast->regs, r, v);
  94. }
  95. /*
  96. * AST2100/2150 DLL CBR Setting
  97. */
  98. #define CBR_SIZE_AST2150 ((16 << 10) - 1)
  99. #define CBR_PASSNUM_AST2150 5
  100. #define CBR_THRESHOLD_AST2150 10
  101. #define CBR_THRESHOLD2_AST2150 10
  102. #define TIMEOUT_AST2150 5000000
  103. #define CBR_PATNUM_AST2150 8
  104. static const u32 pattern_AST2150[14] = {
  105. 0xFF00FF00,
  106. 0xCC33CC33,
  107. 0xAA55AA55,
  108. 0xFFFE0001,
  109. 0x683501FE,
  110. 0x0F1929B0,
  111. 0x2D0B4346,
  112. 0x60767F02,
  113. 0x6FBE36A6,
  114. 0x3A253035,
  115. 0x3019686D,
  116. 0x41C6167E,
  117. 0x620152BF,
  118. 0x20F050E0
  119. };
  120. static u32 mmctestburst2_ast2150(struct ast_device *ast, u32 datagen)
  121. {
  122. u32 data, timeout;
  123. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  124. ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
  125. timeout = 0;
  126. do {
  127. data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
  128. if (++timeout > TIMEOUT_AST2150) {
  129. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  130. return 0xffffffff;
  131. }
  132. } while (!data);
  133. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  134. ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
  135. timeout = 0;
  136. do {
  137. data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
  138. if (++timeout > TIMEOUT_AST2150) {
  139. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  140. return 0xffffffff;
  141. }
  142. } while (!data);
  143. data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
  144. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  145. return data;
  146. }
  147. #if 0 /* unused in DDX driver - here for completeness */
  148. static u32 mmctestsingle2_ast2150(struct ast_device *ast, u32 datagen)
  149. {
  150. u32 data, timeout;
  151. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  152. ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
  153. timeout = 0;
  154. do {
  155. data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
  156. if (++timeout > TIMEOUT_AST2150) {
  157. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  158. return 0xffffffff;
  159. }
  160. } while (!data);
  161. data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
  162. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  163. return data;
  164. }
  165. #endif
  166. static int cbrtest_ast2150(struct ast_device *ast)
  167. {
  168. int i;
  169. for (i = 0; i < 8; i++)
  170. if (mmctestburst2_ast2150(ast, i))
  171. return 0;
  172. return 1;
  173. }
  174. static int cbrscan_ast2150(struct ast_device *ast, int busw)
  175. {
  176. u32 patcnt, loop;
  177. for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
  178. ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
  179. for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
  180. if (cbrtest_ast2150(ast))
  181. break;
  182. }
  183. if (loop == CBR_PASSNUM_AST2150)
  184. return 0;
  185. }
  186. return 1;
  187. }
  188. static void cbrdlli_ast2150(struct ast_device *ast, int busw)
  189. {
  190. u32 dll_min[4], dll_max[4], dlli, data, passcnt;
  191. cbr_start:
  192. dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
  193. dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
  194. passcnt = 0;
  195. for (dlli = 0; dlli < 100; dlli++) {
  196. ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
  197. data = cbrscan_ast2150(ast, busw);
  198. if (data != 0) {
  199. if (data & 0x1) {
  200. if (dll_min[0] > dlli)
  201. dll_min[0] = dlli;
  202. if (dll_max[0] < dlli)
  203. dll_max[0] = dlli;
  204. }
  205. passcnt++;
  206. } else if (passcnt >= CBR_THRESHOLD_AST2150)
  207. goto cbr_start;
  208. }
  209. if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
  210. goto cbr_start;
  211. dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
  212. ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
  213. }
  214. static void ast_init_dram_reg(struct drm_device *dev)
  215. {
  216. struct ast_device *ast = to_ast_device(dev);
  217. u8 j;
  218. u32 data, temp, i;
  219. const struct ast_dramstruct *dram_reg_info;
  220. j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
  221. if ((j & 0x80) == 0) { /* VGA only */
  222. if (IS_AST_GEN1(ast)) {
  223. dram_reg_info = ast2000_dram_table_data;
  224. ast_write32(ast, 0xf004, 0x1e6e0000);
  225. ast_write32(ast, 0xf000, 0x1);
  226. ast_write32(ast, 0x10100, 0xa8);
  227. do {
  228. ;
  229. } while (ast_read32(ast, 0x10100) != 0xa8);
  230. } else { /* GEN2/GEN3 */
  231. if (ast->chip == AST2100 || ast->chip == AST2200)
  232. dram_reg_info = ast2100_dram_table_data;
  233. else
  234. dram_reg_info = ast1100_dram_table_data;
  235. ast_write32(ast, 0xf004, 0x1e6e0000);
  236. ast_write32(ast, 0xf000, 0x1);
  237. ast_write32(ast, 0x12000, 0x1688A8A8);
  238. do {
  239. ;
  240. } while (ast_read32(ast, 0x12000) != 0x01);
  241. ast_write32(ast, 0x10000, 0xfc600309);
  242. do {
  243. ;
  244. } while (ast_read32(ast, 0x10000) != 0x01);
  245. }
  246. while (dram_reg_info->index != 0xffff) {
  247. if (dram_reg_info->index == 0xff00) {/* delay fn */
  248. for (i = 0; i < 15; i++)
  249. udelay(dram_reg_info->data);
  250. } else if (dram_reg_info->index == 0x4 && !IS_AST_GEN1(ast)) {
  251. data = dram_reg_info->data;
  252. if (ast->dram_type == AST_DRAM_1Gx16)
  253. data = 0x00000d89;
  254. else if (ast->dram_type == AST_DRAM_1Gx32)
  255. data = 0x00000c8d;
  256. temp = ast_read32(ast, 0x12070);
  257. temp &= 0xc;
  258. temp <<= 2;
  259. ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
  260. } else
  261. ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
  262. dram_reg_info++;
  263. }
  264. /* AST 2100/2150 DRAM calibration */
  265. data = ast_read32(ast, 0x10120);
  266. if (data == 0x5061) { /* 266Mhz */
  267. data = ast_read32(ast, 0x10004);
  268. if (data & 0x40)
  269. cbrdlli_ast2150(ast, 16); /* 16 bits */
  270. else
  271. cbrdlli_ast2150(ast, 32); /* 32 bits */
  272. }
  273. switch (AST_GEN(ast)) {
  274. case 1:
  275. temp = ast_read32(ast, 0x10140);
  276. ast_write32(ast, 0x10140, temp | 0x40);
  277. break;
  278. case 2:
  279. case 3:
  280. temp = ast_read32(ast, 0x1200c);
  281. ast_write32(ast, 0x1200c, temp & 0xfffffffd);
  282. temp = ast_read32(ast, 0x12040);
  283. ast_write32(ast, 0x12040, temp | 0x40);
  284. break;
  285. default:
  286. break;
  287. }
  288. }
  289. /* wait ready */
  290. do {
  291. j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
  292. } while ((j & 0x40) == 0);
  293. }
  294. void ast_post_gpu(struct drm_device *dev)
  295. {
  296. struct ast_device *ast = to_ast_device(dev);
  297. ast_set_def_ext_reg(dev);
  298. if (IS_AST_GEN7(ast)) {
  299. if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
  300. ast_dp_launch(ast);
  301. } else if (ast->config_mode == ast_use_p2a) {
  302. if (IS_AST_GEN6(ast))
  303. ast_post_chip_2500(dev);
  304. else if (IS_AST_GEN5(ast) || IS_AST_GEN4(ast))
  305. ast_post_chip_2300(dev);
  306. else
  307. ast_init_dram_reg(dev);
  308. ast_init_3rdtx(dev);
  309. } else {
  310. if (ast->tx_chip_types & AST_TX_SIL164_BIT)
  311. ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */
  312. }
  313. }
  314. /* AST 2300 DRAM settings */
  315. #define AST_DDR3 0
  316. #define AST_DDR2 1
  317. struct ast2300_dram_param {
  318. u32 dram_type;
  319. u32 dram_chipid;
  320. u32 dram_freq;
  321. u32 vram_size;
  322. u32 odt;
  323. u32 wodt;
  324. u32 rodt;
  325. u32 dram_config;
  326. u32 reg_PERIOD;
  327. u32 reg_MADJ;
  328. u32 reg_SADJ;
  329. u32 reg_MRS;
  330. u32 reg_EMRS;
  331. u32 reg_AC1;
  332. u32 reg_AC2;
  333. u32 reg_DQSIC;
  334. u32 reg_DRV;
  335. u32 reg_IOZ;
  336. u32 reg_DQIDLY;
  337. u32 reg_FREQ;
  338. u32 madj_max;
  339. u32 dll2_finetune_step;
  340. };
  341. /*
  342. * DQSI DLL CBR Setting
  343. */
  344. #define CBR_SIZE0 ((1 << 10) - 1)
  345. #define CBR_SIZE1 ((4 << 10) - 1)
  346. #define CBR_SIZE2 ((64 << 10) - 1)
  347. #define CBR_PASSNUM 5
  348. #define CBR_PASSNUM2 5
  349. #define CBR_THRESHOLD 10
  350. #define CBR_THRESHOLD2 10
  351. #define TIMEOUT 5000000
  352. #define CBR_PATNUM 8
  353. static const u32 pattern[8] = {
  354. 0xFF00FF00,
  355. 0xCC33CC33,
  356. 0xAA55AA55,
  357. 0x88778877,
  358. 0x92CC4D6E,
  359. 0x543D3CDE,
  360. 0xF1E843C7,
  361. 0x7C61D253
  362. };
  363. static bool mmc_test(struct ast_device *ast, u32 datagen, u8 test_ctl)
  364. {
  365. u32 data, timeout;
  366. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  367. ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
  368. timeout = 0;
  369. do {
  370. data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
  371. if (data & 0x2000)
  372. return false;
  373. if (++timeout > TIMEOUT) {
  374. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  375. return false;
  376. }
  377. } while (!data);
  378. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  379. return true;
  380. }
  381. static u32 mmc_test2(struct ast_device *ast, u32 datagen, u8 test_ctl)
  382. {
  383. u32 data, timeout;
  384. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  385. ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
  386. timeout = 0;
  387. do {
  388. data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
  389. if (++timeout > TIMEOUT) {
  390. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  391. return 0xffffffff;
  392. }
  393. } while (!data);
  394. data = ast_mindwm(ast, 0x1e6e0078);
  395. data = (data | (data >> 16)) & 0xffff;
  396. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  397. return data;
  398. }
  399. static bool mmc_test_burst(struct ast_device *ast, u32 datagen)
  400. {
  401. return mmc_test(ast, datagen, 0xc1);
  402. }
  403. static u32 mmc_test_burst2(struct ast_device *ast, u32 datagen)
  404. {
  405. return mmc_test2(ast, datagen, 0x41);
  406. }
  407. static bool mmc_test_single(struct ast_device *ast, u32 datagen)
  408. {
  409. return mmc_test(ast, datagen, 0xc5);
  410. }
  411. static u32 mmc_test_single2(struct ast_device *ast, u32 datagen)
  412. {
  413. return mmc_test2(ast, datagen, 0x05);
  414. }
  415. static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen)
  416. {
  417. return mmc_test(ast, datagen, 0x85);
  418. }
  419. static int cbr_test(struct ast_device *ast)
  420. {
  421. u32 data;
  422. int i;
  423. data = mmc_test_single2(ast, 0);
  424. if ((data & 0xff) && (data & 0xff00))
  425. return 0;
  426. for (i = 0; i < 8; i++) {
  427. data = mmc_test_burst2(ast, i);
  428. if ((data & 0xff) && (data & 0xff00))
  429. return 0;
  430. }
  431. if (!data)
  432. return 3;
  433. else if (data & 0xff)
  434. return 2;
  435. return 1;
  436. }
  437. static int cbr_scan(struct ast_device *ast)
  438. {
  439. u32 data, data2, patcnt, loop;
  440. data2 = 3;
  441. for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
  442. ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
  443. for (loop = 0; loop < CBR_PASSNUM2; loop++) {
  444. if ((data = cbr_test(ast)) != 0) {
  445. data2 &= data;
  446. if (!data2)
  447. return 0;
  448. break;
  449. }
  450. }
  451. if (loop == CBR_PASSNUM2)
  452. return 0;
  453. }
  454. return data2;
  455. }
  456. static u32 cbr_test2(struct ast_device *ast)
  457. {
  458. u32 data;
  459. data = mmc_test_burst2(ast, 0);
  460. if (data == 0xffff)
  461. return 0;
  462. data |= mmc_test_single2(ast, 0);
  463. if (data == 0xffff)
  464. return 0;
  465. return ~data & 0xffff;
  466. }
  467. static u32 cbr_scan2(struct ast_device *ast)
  468. {
  469. u32 data, data2, patcnt, loop;
  470. data2 = 0xffff;
  471. for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
  472. ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
  473. for (loop = 0; loop < CBR_PASSNUM2; loop++) {
  474. if ((data = cbr_test2(ast)) != 0) {
  475. data2 &= data;
  476. if (!data2)
  477. return 0;
  478. break;
  479. }
  480. }
  481. if (loop == CBR_PASSNUM2)
  482. return 0;
  483. }
  484. return data2;
  485. }
  486. static bool cbr_test3(struct ast_device *ast)
  487. {
  488. if (!mmc_test_burst(ast, 0))
  489. return false;
  490. if (!mmc_test_single(ast, 0))
  491. return false;
  492. return true;
  493. }
  494. static bool cbr_scan3(struct ast_device *ast)
  495. {
  496. u32 patcnt, loop;
  497. for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
  498. ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
  499. for (loop = 0; loop < 2; loop++) {
  500. if (cbr_test3(ast))
  501. break;
  502. }
  503. if (loop == 2)
  504. return false;
  505. }
  506. return true;
  507. }
  508. static bool finetuneDQI_L(struct ast_device *ast, struct ast2300_dram_param *param)
  509. {
  510. u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
  511. bool status = false;
  512. FINETUNE_START:
  513. for (cnt = 0; cnt < 16; cnt++) {
  514. dllmin[cnt] = 0xff;
  515. dllmax[cnt] = 0x0;
  516. }
  517. passcnt = 0;
  518. for (dlli = 0; dlli < 76; dlli++) {
  519. ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
  520. ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
  521. data = cbr_scan2(ast);
  522. if (data != 0) {
  523. mask = 0x00010001;
  524. for (cnt = 0; cnt < 16; cnt++) {
  525. if (data & mask) {
  526. if (dllmin[cnt] > dlli) {
  527. dllmin[cnt] = dlli;
  528. }
  529. if (dllmax[cnt] < dlli) {
  530. dllmax[cnt] = dlli;
  531. }
  532. }
  533. mask <<= 1;
  534. }
  535. passcnt++;
  536. } else if (passcnt >= CBR_THRESHOLD2) {
  537. break;
  538. }
  539. }
  540. gold_sadj[0] = 0x0;
  541. passcnt = 0;
  542. for (cnt = 0; cnt < 16; cnt++) {
  543. if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
  544. gold_sadj[0] += dllmin[cnt];
  545. passcnt++;
  546. }
  547. }
  548. if (retry++ > 10)
  549. goto FINETUNE_DONE;
  550. if (passcnt != 16) {
  551. goto FINETUNE_START;
  552. }
  553. status = true;
  554. FINETUNE_DONE:
  555. gold_sadj[0] = gold_sadj[0] >> 4;
  556. gold_sadj[1] = gold_sadj[0];
  557. data = 0;
  558. for (cnt = 0; cnt < 8; cnt++) {
  559. data >>= 3;
  560. if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
  561. dlli = dllmin[cnt];
  562. if (gold_sadj[0] >= dlli) {
  563. dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
  564. if (dlli > 3) {
  565. dlli = 3;
  566. }
  567. } else {
  568. dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
  569. if (dlli > 4) {
  570. dlli = 4;
  571. }
  572. dlli = (8 - dlli) & 0x7;
  573. }
  574. data |= dlli << 21;
  575. }
  576. }
  577. ast_moutdwm(ast, 0x1E6E0080, data);
  578. data = 0;
  579. for (cnt = 8; cnt < 16; cnt++) {
  580. data >>= 3;
  581. if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
  582. dlli = dllmin[cnt];
  583. if (gold_sadj[1] >= dlli) {
  584. dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
  585. if (dlli > 3) {
  586. dlli = 3;
  587. } else {
  588. dlli = (dlli - 1) & 0x7;
  589. }
  590. } else {
  591. dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
  592. dlli += 1;
  593. if (dlli > 4) {
  594. dlli = 4;
  595. }
  596. dlli = (8 - dlli) & 0x7;
  597. }
  598. data |= dlli << 21;
  599. }
  600. }
  601. ast_moutdwm(ast, 0x1E6E0084, data);
  602. return status;
  603. } /* finetuneDQI_L */
  604. static void finetuneDQSI(struct ast_device *ast)
  605. {
  606. u32 dlli, dqsip, dqidly;
  607. u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
  608. u32 g_dqidly, g_dqsip, g_margin, g_side;
  609. u16 pass[32][2][2];
  610. char tag[2][76];
  611. /* Disable DQI CBR */
  612. reg_mcr0c = ast_mindwm(ast, 0x1E6E000C);
  613. reg_mcr18 = ast_mindwm(ast, 0x1E6E0018);
  614. reg_mcr18 &= 0x0000ffff;
  615. ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
  616. for (dlli = 0; dlli < 76; dlli++) {
  617. tag[0][dlli] = 0x0;
  618. tag[1][dlli] = 0x0;
  619. }
  620. for (dqidly = 0; dqidly < 32; dqidly++) {
  621. pass[dqidly][0][0] = 0xff;
  622. pass[dqidly][0][1] = 0x0;
  623. pass[dqidly][1][0] = 0xff;
  624. pass[dqidly][1][1] = 0x0;
  625. }
  626. for (dqidly = 0; dqidly < 32; dqidly++) {
  627. passcnt[0] = passcnt[1] = 0;
  628. for (dqsip = 0; dqsip < 2; dqsip++) {
  629. ast_moutdwm(ast, 0x1E6E000C, 0);
  630. ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
  631. ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
  632. for (dlli = 0; dlli < 76; dlli++) {
  633. ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
  634. ast_moutdwm(ast, 0x1E6E0070, 0);
  635. ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
  636. if (cbr_scan3(ast)) {
  637. if (dlli == 0)
  638. break;
  639. passcnt[dqsip]++;
  640. tag[dqsip][dlli] = 'P';
  641. if (dlli < pass[dqidly][dqsip][0])
  642. pass[dqidly][dqsip][0] = (u16) dlli;
  643. if (dlli > pass[dqidly][dqsip][1])
  644. pass[dqidly][dqsip][1] = (u16) dlli;
  645. } else if (passcnt[dqsip] >= 5)
  646. break;
  647. else {
  648. pass[dqidly][dqsip][0] = 0xff;
  649. pass[dqidly][dqsip][1] = 0x0;
  650. }
  651. }
  652. }
  653. if (passcnt[0] == 0 && passcnt[1] == 0)
  654. dqidly++;
  655. }
  656. /* Search margin */
  657. g_dqidly = g_dqsip = g_margin = g_side = 0;
  658. for (dqidly = 0; dqidly < 32; dqidly++) {
  659. for (dqsip = 0; dqsip < 2; dqsip++) {
  660. if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
  661. continue;
  662. diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
  663. if ((diff+2) < g_margin)
  664. continue;
  665. passcnt[0] = passcnt[1] = 0;
  666. for (dlli = pass[dqidly][dqsip][0]; dlli > 0 && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++);
  667. for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++);
  668. if (passcnt[0] > passcnt[1])
  669. passcnt[0] = passcnt[1];
  670. passcnt[1] = 0;
  671. if (passcnt[0] > g_side)
  672. passcnt[1] = passcnt[0] - g_side;
  673. if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
  674. g_margin = diff;
  675. g_dqidly = dqidly;
  676. g_dqsip = dqsip;
  677. g_side = passcnt[0];
  678. } else if (passcnt[1] > 1 && g_side < 8) {
  679. if (diff > g_margin)
  680. g_margin = diff;
  681. g_dqidly = dqidly;
  682. g_dqsip = dqsip;
  683. g_side = passcnt[0];
  684. }
  685. }
  686. }
  687. reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
  688. ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
  689. }
  690. static bool cbr_dll2(struct ast_device *ast, struct ast2300_dram_param *param)
  691. {
  692. u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
  693. bool status = false;
  694. finetuneDQSI(ast);
  695. if (finetuneDQI_L(ast, param) == false)
  696. return status;
  697. CBR_START2:
  698. dllmin[0] = dllmin[1] = 0xff;
  699. dllmax[0] = dllmax[1] = 0x0;
  700. passcnt = 0;
  701. for (dlli = 0; dlli < 76; dlli++) {
  702. ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
  703. ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
  704. data = cbr_scan(ast);
  705. if (data != 0) {
  706. if (data & 0x1) {
  707. if (dllmin[0] > dlli) {
  708. dllmin[0] = dlli;
  709. }
  710. if (dllmax[0] < dlli) {
  711. dllmax[0] = dlli;
  712. }
  713. }
  714. if (data & 0x2) {
  715. if (dllmin[1] > dlli) {
  716. dllmin[1] = dlli;
  717. }
  718. if (dllmax[1] < dlli) {
  719. dllmax[1] = dlli;
  720. }
  721. }
  722. passcnt++;
  723. } else if (passcnt >= CBR_THRESHOLD) {
  724. break;
  725. }
  726. }
  727. if (retry++ > 10)
  728. goto CBR_DONE2;
  729. if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
  730. goto CBR_START2;
  731. }
  732. if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
  733. goto CBR_START2;
  734. }
  735. status = true;
  736. CBR_DONE2:
  737. dlli = (dllmin[1] + dllmax[1]) >> 1;
  738. dlli <<= 8;
  739. dlli += (dllmin[0] + dllmax[0]) >> 1;
  740. ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
  741. return status;
  742. } /* CBRDLL2 */
  743. static void get_ddr3_info(struct ast_device *ast, struct ast2300_dram_param *param)
  744. {
  745. u32 trap, trap_AC2, trap_MRS;
  746. ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
  747. /* Ger trap info */
  748. trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
  749. trap_AC2 = 0x00020000 + (trap << 16);
  750. trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
  751. trap_MRS = 0x00000010 + (trap << 4);
  752. trap_MRS |= ((trap & 0x2) << 18);
  753. param->reg_MADJ = 0x00034C4C;
  754. param->reg_SADJ = 0x00001800;
  755. param->reg_DRV = 0x000000F0;
  756. param->reg_PERIOD = param->dram_freq;
  757. param->rodt = 0;
  758. switch (param->dram_freq) {
  759. case 336:
  760. ast_moutdwm(ast, 0x1E6E2020, 0x0190);
  761. param->wodt = 0;
  762. param->reg_AC1 = 0x22202725;
  763. param->reg_AC2 = 0xAA007613 | trap_AC2;
  764. param->reg_DQSIC = 0x000000BA;
  765. param->reg_MRS = 0x04001400 | trap_MRS;
  766. param->reg_EMRS = 0x00000000;
  767. param->reg_IOZ = 0x00000023;
  768. param->reg_DQIDLY = 0x00000074;
  769. param->reg_FREQ = 0x00004DC0;
  770. param->madj_max = 96;
  771. param->dll2_finetune_step = 3;
  772. switch (param->dram_chipid) {
  773. default:
  774. case AST_DRAM_512Mx16:
  775. case AST_DRAM_1Gx16:
  776. param->reg_AC2 = 0xAA007613 | trap_AC2;
  777. break;
  778. case AST_DRAM_2Gx16:
  779. param->reg_AC2 = 0xAA00761C | trap_AC2;
  780. break;
  781. case AST_DRAM_4Gx16:
  782. param->reg_AC2 = 0xAA007636 | trap_AC2;
  783. break;
  784. }
  785. break;
  786. default:
  787. case 396:
  788. ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
  789. param->wodt = 1;
  790. param->reg_AC1 = 0x33302825;
  791. param->reg_AC2 = 0xCC009617 | trap_AC2;
  792. param->reg_DQSIC = 0x000000E2;
  793. param->reg_MRS = 0x04001600 | trap_MRS;
  794. param->reg_EMRS = 0x00000000;
  795. param->reg_IOZ = 0x00000034;
  796. param->reg_DRV = 0x000000FA;
  797. param->reg_DQIDLY = 0x00000089;
  798. param->reg_FREQ = 0x00005040;
  799. param->madj_max = 96;
  800. param->dll2_finetune_step = 4;
  801. switch (param->dram_chipid) {
  802. default:
  803. case AST_DRAM_512Mx16:
  804. case AST_DRAM_1Gx16:
  805. param->reg_AC2 = 0xCC009617 | trap_AC2;
  806. break;
  807. case AST_DRAM_2Gx16:
  808. param->reg_AC2 = 0xCC009622 | trap_AC2;
  809. break;
  810. case AST_DRAM_4Gx16:
  811. param->reg_AC2 = 0xCC00963F | trap_AC2;
  812. break;
  813. }
  814. break;
  815. case 408:
  816. ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
  817. param->wodt = 1;
  818. param->reg_AC1 = 0x33302825;
  819. param->reg_AC2 = 0xCC009617 | trap_AC2;
  820. param->reg_DQSIC = 0x000000E2;
  821. param->reg_MRS = 0x04001600 | trap_MRS;
  822. param->reg_EMRS = 0x00000000;
  823. param->reg_IOZ = 0x00000023;
  824. param->reg_DRV = 0x000000FA;
  825. param->reg_DQIDLY = 0x00000089;
  826. param->reg_FREQ = 0x000050C0;
  827. param->madj_max = 96;
  828. param->dll2_finetune_step = 4;
  829. switch (param->dram_chipid) {
  830. default:
  831. case AST_DRAM_512Mx16:
  832. case AST_DRAM_1Gx16:
  833. param->reg_AC2 = 0xCC009617 | trap_AC2;
  834. break;
  835. case AST_DRAM_2Gx16:
  836. param->reg_AC2 = 0xCC009622 | trap_AC2;
  837. break;
  838. case AST_DRAM_4Gx16:
  839. param->reg_AC2 = 0xCC00963F | trap_AC2;
  840. break;
  841. }
  842. break;
  843. case 456:
  844. ast_moutdwm(ast, 0x1E6E2020, 0x0230);
  845. param->wodt = 0;
  846. param->reg_AC1 = 0x33302926;
  847. param->reg_AC2 = 0xCD44961A;
  848. param->reg_DQSIC = 0x000000FC;
  849. param->reg_MRS = 0x00081830;
  850. param->reg_EMRS = 0x00000000;
  851. param->reg_IOZ = 0x00000045;
  852. param->reg_DQIDLY = 0x00000097;
  853. param->reg_FREQ = 0x000052C0;
  854. param->madj_max = 88;
  855. param->dll2_finetune_step = 4;
  856. break;
  857. case 504:
  858. ast_moutdwm(ast, 0x1E6E2020, 0x0270);
  859. param->wodt = 1;
  860. param->reg_AC1 = 0x33302926;
  861. param->reg_AC2 = 0xDE44A61D;
  862. param->reg_DQSIC = 0x00000117;
  863. param->reg_MRS = 0x00081A30;
  864. param->reg_EMRS = 0x00000000;
  865. param->reg_IOZ = 0x070000BB;
  866. param->reg_DQIDLY = 0x000000A0;
  867. param->reg_FREQ = 0x000054C0;
  868. param->madj_max = 79;
  869. param->dll2_finetune_step = 4;
  870. break;
  871. case 528:
  872. ast_moutdwm(ast, 0x1E6E2020, 0x0290);
  873. param->wodt = 1;
  874. param->rodt = 1;
  875. param->reg_AC1 = 0x33302926;
  876. param->reg_AC2 = 0xEF44B61E;
  877. param->reg_DQSIC = 0x00000125;
  878. param->reg_MRS = 0x00081A30;
  879. param->reg_EMRS = 0x00000040;
  880. param->reg_DRV = 0x000000F5;
  881. param->reg_IOZ = 0x00000023;
  882. param->reg_DQIDLY = 0x00000088;
  883. param->reg_FREQ = 0x000055C0;
  884. param->madj_max = 76;
  885. param->dll2_finetune_step = 3;
  886. break;
  887. case 576:
  888. ast_moutdwm(ast, 0x1E6E2020, 0x0140);
  889. param->reg_MADJ = 0x00136868;
  890. param->reg_SADJ = 0x00004534;
  891. param->wodt = 1;
  892. param->rodt = 1;
  893. param->reg_AC1 = 0x33302A37;
  894. param->reg_AC2 = 0xEF56B61E;
  895. param->reg_DQSIC = 0x0000013F;
  896. param->reg_MRS = 0x00101A50;
  897. param->reg_EMRS = 0x00000040;
  898. param->reg_DRV = 0x000000FA;
  899. param->reg_IOZ = 0x00000023;
  900. param->reg_DQIDLY = 0x00000078;
  901. param->reg_FREQ = 0x000057C0;
  902. param->madj_max = 136;
  903. param->dll2_finetune_step = 3;
  904. break;
  905. case 600:
  906. ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
  907. param->reg_MADJ = 0x00136868;
  908. param->reg_SADJ = 0x00004534;
  909. param->wodt = 1;
  910. param->rodt = 1;
  911. param->reg_AC1 = 0x32302A37;
  912. param->reg_AC2 = 0xDF56B61F;
  913. param->reg_DQSIC = 0x0000014D;
  914. param->reg_MRS = 0x00101A50;
  915. param->reg_EMRS = 0x00000004;
  916. param->reg_DRV = 0x000000F5;
  917. param->reg_IOZ = 0x00000023;
  918. param->reg_DQIDLY = 0x00000078;
  919. param->reg_FREQ = 0x000058C0;
  920. param->madj_max = 132;
  921. param->dll2_finetune_step = 3;
  922. break;
  923. case 624:
  924. ast_moutdwm(ast, 0x1E6E2020, 0x0160);
  925. param->reg_MADJ = 0x00136868;
  926. param->reg_SADJ = 0x00004534;
  927. param->wodt = 1;
  928. param->rodt = 1;
  929. param->reg_AC1 = 0x32302A37;
  930. param->reg_AC2 = 0xEF56B621;
  931. param->reg_DQSIC = 0x0000015A;
  932. param->reg_MRS = 0x02101A50;
  933. param->reg_EMRS = 0x00000004;
  934. param->reg_DRV = 0x000000F5;
  935. param->reg_IOZ = 0x00000034;
  936. param->reg_DQIDLY = 0x00000078;
  937. param->reg_FREQ = 0x000059C0;
  938. param->madj_max = 128;
  939. param->dll2_finetune_step = 3;
  940. break;
  941. } /* switch freq */
  942. switch (param->dram_chipid) {
  943. case AST_DRAM_512Mx16:
  944. param->dram_config = 0x130;
  945. break;
  946. default:
  947. case AST_DRAM_1Gx16:
  948. param->dram_config = 0x131;
  949. break;
  950. case AST_DRAM_2Gx16:
  951. param->dram_config = 0x132;
  952. break;
  953. case AST_DRAM_4Gx16:
  954. param->dram_config = 0x133;
  955. break;
  956. } /* switch size */
  957. switch (param->vram_size) {
  958. default:
  959. case AST_VIDMEM_SIZE_8M:
  960. param->dram_config |= 0x00;
  961. break;
  962. case AST_VIDMEM_SIZE_16M:
  963. param->dram_config |= 0x04;
  964. break;
  965. case AST_VIDMEM_SIZE_32M:
  966. param->dram_config |= 0x08;
  967. break;
  968. case AST_VIDMEM_SIZE_64M:
  969. param->dram_config |= 0x0c;
  970. break;
  971. }
  972. }
  973. static void ddr3_init(struct ast_device *ast, struct ast2300_dram_param *param)
  974. {
  975. u32 data, data2, retry = 0;
  976. ddr3_init_start:
  977. ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
  978. ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
  979. ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
  980. ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
  981. udelay(10);
  982. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
  983. ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
  984. udelay(10);
  985. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
  986. udelay(10);
  987. ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
  988. ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
  989. ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
  990. ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
  991. ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
  992. ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
  993. ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
  994. ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
  995. ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
  996. ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
  997. ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
  998. ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
  999. ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
  1000. ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
  1001. ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
  1002. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1003. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1004. ast_moutdwm(ast, 0x1E6E0054, 0);
  1005. ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
  1006. ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
  1007. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1008. ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
  1009. ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
  1010. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1011. /* Wait MCLK2X lock to MCLK */
  1012. do {
  1013. data = ast_mindwm(ast, 0x1E6E001C);
  1014. } while (!(data & 0x08000000));
  1015. data = ast_mindwm(ast, 0x1E6E001C);
  1016. data = (data >> 8) & 0xff;
  1017. while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
  1018. data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
  1019. if ((data2 & 0xff) > param->madj_max) {
  1020. break;
  1021. }
  1022. ast_moutdwm(ast, 0x1E6E0064, data2);
  1023. if (data2 & 0x00100000) {
  1024. data2 = ((data2 & 0xff) >> 3) + 3;
  1025. } else {
  1026. data2 = ((data2 & 0xff) >> 2) + 5;
  1027. }
  1028. data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
  1029. data2 += data & 0xff;
  1030. data = data | (data2 << 8);
  1031. ast_moutdwm(ast, 0x1E6E0068, data);
  1032. udelay(10);
  1033. ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
  1034. udelay(10);
  1035. data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
  1036. ast_moutdwm(ast, 0x1E6E0018, data);
  1037. data = data | 0x200;
  1038. ast_moutdwm(ast, 0x1E6E0018, data);
  1039. do {
  1040. data = ast_mindwm(ast, 0x1E6E001C);
  1041. } while (!(data & 0x08000000));
  1042. data = ast_mindwm(ast, 0x1E6E001C);
  1043. data = (data >> 8) & 0xff;
  1044. }
  1045. ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
  1046. data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
  1047. ast_moutdwm(ast, 0x1E6E0018, data);
  1048. ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
  1049. ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
  1050. udelay(50);
  1051. /* Mode Register Setting */
  1052. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
  1053. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
  1054. ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
  1055. ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
  1056. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1057. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1058. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
  1059. ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
  1060. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1061. ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
  1062. data = 0;
  1063. if (param->wodt) {
  1064. data = 0x300;
  1065. }
  1066. if (param->rodt) {
  1067. data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
  1068. }
  1069. ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
  1070. /* Calibrate the DQSI delay */
  1071. if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
  1072. goto ddr3_init_start;
  1073. ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
  1074. /* ECC Memory Initialization */
  1075. #ifdef ECC
  1076. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1077. ast_moutdwm(ast, 0x1E6E0070, 0x221);
  1078. do {
  1079. data = ast_mindwm(ast, 0x1E6E0070);
  1080. } while (!(data & 0x00001000));
  1081. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1082. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1083. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1084. #endif
  1085. }
  1086. static void get_ddr2_info(struct ast_device *ast, struct ast2300_dram_param *param)
  1087. {
  1088. u32 trap, trap_AC2, trap_MRS;
  1089. ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
  1090. /* Ger trap info */
  1091. trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
  1092. trap_AC2 = (trap << 20) | (trap << 16);
  1093. trap_AC2 += 0x00110000;
  1094. trap_MRS = 0x00000040 | (trap << 4);
  1095. param->reg_MADJ = 0x00034C4C;
  1096. param->reg_SADJ = 0x00001800;
  1097. param->reg_DRV = 0x000000F0;
  1098. param->reg_PERIOD = param->dram_freq;
  1099. param->rodt = 0;
  1100. switch (param->dram_freq) {
  1101. case 264:
  1102. ast_moutdwm(ast, 0x1E6E2020, 0x0130);
  1103. param->wodt = 0;
  1104. param->reg_AC1 = 0x11101513;
  1105. param->reg_AC2 = 0x78117011;
  1106. param->reg_DQSIC = 0x00000092;
  1107. param->reg_MRS = 0x00000842;
  1108. param->reg_EMRS = 0x00000000;
  1109. param->reg_DRV = 0x000000F0;
  1110. param->reg_IOZ = 0x00000034;
  1111. param->reg_DQIDLY = 0x0000005A;
  1112. param->reg_FREQ = 0x00004AC0;
  1113. param->madj_max = 138;
  1114. param->dll2_finetune_step = 3;
  1115. break;
  1116. case 336:
  1117. ast_moutdwm(ast, 0x1E6E2020, 0x0190);
  1118. param->wodt = 1;
  1119. param->reg_AC1 = 0x22202613;
  1120. param->reg_AC2 = 0xAA009016 | trap_AC2;
  1121. param->reg_DQSIC = 0x000000BA;
  1122. param->reg_MRS = 0x00000A02 | trap_MRS;
  1123. param->reg_EMRS = 0x00000040;
  1124. param->reg_DRV = 0x000000FA;
  1125. param->reg_IOZ = 0x00000034;
  1126. param->reg_DQIDLY = 0x00000074;
  1127. param->reg_FREQ = 0x00004DC0;
  1128. param->madj_max = 96;
  1129. param->dll2_finetune_step = 3;
  1130. switch (param->dram_chipid) {
  1131. default:
  1132. case AST_DRAM_512Mx16:
  1133. param->reg_AC2 = 0xAA009012 | trap_AC2;
  1134. break;
  1135. case AST_DRAM_1Gx16:
  1136. param->reg_AC2 = 0xAA009016 | trap_AC2;
  1137. break;
  1138. case AST_DRAM_2Gx16:
  1139. param->reg_AC2 = 0xAA009023 | trap_AC2;
  1140. break;
  1141. case AST_DRAM_4Gx16:
  1142. param->reg_AC2 = 0xAA00903B | trap_AC2;
  1143. break;
  1144. }
  1145. break;
  1146. default:
  1147. case 396:
  1148. ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
  1149. param->wodt = 1;
  1150. param->rodt = 0;
  1151. param->reg_AC1 = 0x33302714;
  1152. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1153. param->reg_DQSIC = 0x000000E2;
  1154. param->reg_MRS = 0x00000C02 | trap_MRS;
  1155. param->reg_EMRS = 0x00000040;
  1156. param->reg_DRV = 0x000000FA;
  1157. param->reg_IOZ = 0x00000034;
  1158. param->reg_DQIDLY = 0x00000089;
  1159. param->reg_FREQ = 0x00005040;
  1160. param->madj_max = 96;
  1161. param->dll2_finetune_step = 4;
  1162. switch (param->dram_chipid) {
  1163. case AST_DRAM_512Mx16:
  1164. param->reg_AC2 = 0xCC00B016 | trap_AC2;
  1165. break;
  1166. default:
  1167. case AST_DRAM_1Gx16:
  1168. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1169. break;
  1170. case AST_DRAM_2Gx16:
  1171. param->reg_AC2 = 0xCC00B02B | trap_AC2;
  1172. break;
  1173. case AST_DRAM_4Gx16:
  1174. param->reg_AC2 = 0xCC00B03F | trap_AC2;
  1175. break;
  1176. }
  1177. break;
  1178. case 408:
  1179. ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
  1180. param->wodt = 1;
  1181. param->rodt = 0;
  1182. param->reg_AC1 = 0x33302714;
  1183. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1184. param->reg_DQSIC = 0x000000E2;
  1185. param->reg_MRS = 0x00000C02 | trap_MRS;
  1186. param->reg_EMRS = 0x00000040;
  1187. param->reg_DRV = 0x000000FA;
  1188. param->reg_IOZ = 0x00000034;
  1189. param->reg_DQIDLY = 0x00000089;
  1190. param->reg_FREQ = 0x000050C0;
  1191. param->madj_max = 96;
  1192. param->dll2_finetune_step = 4;
  1193. switch (param->dram_chipid) {
  1194. case AST_DRAM_512Mx16:
  1195. param->reg_AC2 = 0xCC00B016 | trap_AC2;
  1196. break;
  1197. default:
  1198. case AST_DRAM_1Gx16:
  1199. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1200. break;
  1201. case AST_DRAM_2Gx16:
  1202. param->reg_AC2 = 0xCC00B02B | trap_AC2;
  1203. break;
  1204. case AST_DRAM_4Gx16:
  1205. param->reg_AC2 = 0xCC00B03F | trap_AC2;
  1206. break;
  1207. }
  1208. break;
  1209. case 456:
  1210. ast_moutdwm(ast, 0x1E6E2020, 0x0230);
  1211. param->wodt = 0;
  1212. param->reg_AC1 = 0x33302815;
  1213. param->reg_AC2 = 0xCD44B01E;
  1214. param->reg_DQSIC = 0x000000FC;
  1215. param->reg_MRS = 0x00000E72;
  1216. param->reg_EMRS = 0x00000000;
  1217. param->reg_DRV = 0x00000000;
  1218. param->reg_IOZ = 0x00000034;
  1219. param->reg_DQIDLY = 0x00000097;
  1220. param->reg_FREQ = 0x000052C0;
  1221. param->madj_max = 88;
  1222. param->dll2_finetune_step = 3;
  1223. break;
  1224. case 504:
  1225. ast_moutdwm(ast, 0x1E6E2020, 0x0261);
  1226. param->wodt = 1;
  1227. param->rodt = 1;
  1228. param->reg_AC1 = 0x33302815;
  1229. param->reg_AC2 = 0xDE44C022;
  1230. param->reg_DQSIC = 0x00000117;
  1231. param->reg_MRS = 0x00000E72;
  1232. param->reg_EMRS = 0x00000040;
  1233. param->reg_DRV = 0x0000000A;
  1234. param->reg_IOZ = 0x00000045;
  1235. param->reg_DQIDLY = 0x000000A0;
  1236. param->reg_FREQ = 0x000054C0;
  1237. param->madj_max = 79;
  1238. param->dll2_finetune_step = 3;
  1239. break;
  1240. case 528:
  1241. ast_moutdwm(ast, 0x1E6E2020, 0x0120);
  1242. param->wodt = 1;
  1243. param->rodt = 1;
  1244. param->reg_AC1 = 0x33302815;
  1245. param->reg_AC2 = 0xEF44D024;
  1246. param->reg_DQSIC = 0x00000125;
  1247. param->reg_MRS = 0x00000E72;
  1248. param->reg_EMRS = 0x00000004;
  1249. param->reg_DRV = 0x000000F9;
  1250. param->reg_IOZ = 0x00000045;
  1251. param->reg_DQIDLY = 0x000000A7;
  1252. param->reg_FREQ = 0x000055C0;
  1253. param->madj_max = 76;
  1254. param->dll2_finetune_step = 3;
  1255. break;
  1256. case 552:
  1257. ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
  1258. param->wodt = 1;
  1259. param->rodt = 1;
  1260. param->reg_AC1 = 0x43402915;
  1261. param->reg_AC2 = 0xFF44E025;
  1262. param->reg_DQSIC = 0x00000132;
  1263. param->reg_MRS = 0x00000E72;
  1264. param->reg_EMRS = 0x00000040;
  1265. param->reg_DRV = 0x0000000A;
  1266. param->reg_IOZ = 0x00000045;
  1267. param->reg_DQIDLY = 0x000000AD;
  1268. param->reg_FREQ = 0x000056C0;
  1269. param->madj_max = 76;
  1270. param->dll2_finetune_step = 3;
  1271. break;
  1272. case 576:
  1273. ast_moutdwm(ast, 0x1E6E2020, 0x0140);
  1274. param->wodt = 1;
  1275. param->rodt = 1;
  1276. param->reg_AC1 = 0x43402915;
  1277. param->reg_AC2 = 0xFF44E027;
  1278. param->reg_DQSIC = 0x0000013F;
  1279. param->reg_MRS = 0x00000E72;
  1280. param->reg_EMRS = 0x00000004;
  1281. param->reg_DRV = 0x000000F5;
  1282. param->reg_IOZ = 0x00000045;
  1283. param->reg_DQIDLY = 0x000000B3;
  1284. param->reg_FREQ = 0x000057C0;
  1285. param->madj_max = 76;
  1286. param->dll2_finetune_step = 3;
  1287. break;
  1288. }
  1289. switch (param->dram_chipid) {
  1290. case AST_DRAM_512Mx16:
  1291. param->dram_config = 0x100;
  1292. break;
  1293. default:
  1294. case AST_DRAM_1Gx16:
  1295. param->dram_config = 0x121;
  1296. break;
  1297. case AST_DRAM_2Gx16:
  1298. param->dram_config = 0x122;
  1299. break;
  1300. case AST_DRAM_4Gx16:
  1301. param->dram_config = 0x123;
  1302. break;
  1303. } /* switch size */
  1304. switch (param->vram_size) {
  1305. default:
  1306. case AST_VIDMEM_SIZE_8M:
  1307. param->dram_config |= 0x00;
  1308. break;
  1309. case AST_VIDMEM_SIZE_16M:
  1310. param->dram_config |= 0x04;
  1311. break;
  1312. case AST_VIDMEM_SIZE_32M:
  1313. param->dram_config |= 0x08;
  1314. break;
  1315. case AST_VIDMEM_SIZE_64M:
  1316. param->dram_config |= 0x0c;
  1317. break;
  1318. }
  1319. }
  1320. static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param)
  1321. {
  1322. u32 data, data2, retry = 0;
  1323. ddr2_init_start:
  1324. ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
  1325. ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
  1326. ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
  1327. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
  1328. ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
  1329. udelay(10);
  1330. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
  1331. udelay(10);
  1332. ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
  1333. ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
  1334. ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
  1335. ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
  1336. ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
  1337. ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
  1338. ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
  1339. ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
  1340. ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
  1341. ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
  1342. ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
  1343. ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
  1344. ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
  1345. ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
  1346. ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
  1347. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1348. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1349. ast_moutdwm(ast, 0x1E6E0054, 0);
  1350. ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
  1351. ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
  1352. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1353. ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
  1354. ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
  1355. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1356. /* Wait MCLK2X lock to MCLK */
  1357. do {
  1358. data = ast_mindwm(ast, 0x1E6E001C);
  1359. } while (!(data & 0x08000000));
  1360. data = ast_mindwm(ast, 0x1E6E001C);
  1361. data = (data >> 8) & 0xff;
  1362. while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
  1363. data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
  1364. if ((data2 & 0xff) > param->madj_max) {
  1365. break;
  1366. }
  1367. ast_moutdwm(ast, 0x1E6E0064, data2);
  1368. if (data2 & 0x00100000) {
  1369. data2 = ((data2 & 0xff) >> 3) + 3;
  1370. } else {
  1371. data2 = ((data2 & 0xff) >> 2) + 5;
  1372. }
  1373. data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
  1374. data2 += data & 0xff;
  1375. data = data | (data2 << 8);
  1376. ast_moutdwm(ast, 0x1E6E0068, data);
  1377. udelay(10);
  1378. ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
  1379. udelay(10);
  1380. data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
  1381. ast_moutdwm(ast, 0x1E6E0018, data);
  1382. data = data | 0x200;
  1383. ast_moutdwm(ast, 0x1E6E0018, data);
  1384. do {
  1385. data = ast_mindwm(ast, 0x1E6E001C);
  1386. } while (!(data & 0x08000000));
  1387. data = ast_mindwm(ast, 0x1E6E001C);
  1388. data = (data >> 8) & 0xff;
  1389. }
  1390. ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
  1391. data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
  1392. ast_moutdwm(ast, 0x1E6E0018, data);
  1393. ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
  1394. ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
  1395. udelay(50);
  1396. /* Mode Register Setting */
  1397. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
  1398. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
  1399. ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
  1400. ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
  1401. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1402. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1403. ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
  1404. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
  1405. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1406. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
  1407. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1408. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
  1409. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1410. ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
  1411. data = 0;
  1412. if (param->wodt) {
  1413. data = 0x500;
  1414. }
  1415. if (param->rodt) {
  1416. data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
  1417. }
  1418. ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
  1419. ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
  1420. /* Calibrate the DQSI delay */
  1421. if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
  1422. goto ddr2_init_start;
  1423. /* ECC Memory Initialization */
  1424. #ifdef ECC
  1425. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1426. ast_moutdwm(ast, 0x1E6E0070, 0x221);
  1427. do {
  1428. data = ast_mindwm(ast, 0x1E6E0070);
  1429. } while (!(data & 0x00001000));
  1430. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1431. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1432. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1433. #endif
  1434. }
  1435. static void ast_post_chip_2300(struct drm_device *dev)
  1436. {
  1437. struct ast_device *ast = to_ast_device(dev);
  1438. struct ast2300_dram_param param;
  1439. u32 temp;
  1440. u8 reg;
  1441. reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
  1442. if ((reg & 0x80) == 0) {/* vga only */
  1443. ast_write32(ast, 0xf004, 0x1e6e0000);
  1444. ast_write32(ast, 0xf000, 0x1);
  1445. ast_write32(ast, 0x12000, 0x1688a8a8);
  1446. do {
  1447. ;
  1448. } while (ast_read32(ast, 0x12000) != 0x1);
  1449. ast_write32(ast, 0x10000, 0xfc600309);
  1450. do {
  1451. ;
  1452. } while (ast_read32(ast, 0x10000) != 0x1);
  1453. /* Slow down CPU/AHB CLK in VGA only mode */
  1454. temp = ast_read32(ast, 0x12008);
  1455. temp |= 0x73;
  1456. ast_write32(ast, 0x12008, temp);
  1457. param.dram_freq = 396;
  1458. param.dram_type = AST_DDR3;
  1459. temp = ast_mindwm(ast, 0x1e6e2070);
  1460. if (temp & 0x01000000)
  1461. param.dram_type = AST_DDR2;
  1462. switch (temp & 0x18000000) {
  1463. case 0:
  1464. param.dram_chipid = AST_DRAM_512Mx16;
  1465. break;
  1466. default:
  1467. case 0x08000000:
  1468. param.dram_chipid = AST_DRAM_1Gx16;
  1469. break;
  1470. case 0x10000000:
  1471. param.dram_chipid = AST_DRAM_2Gx16;
  1472. break;
  1473. case 0x18000000:
  1474. param.dram_chipid = AST_DRAM_4Gx16;
  1475. break;
  1476. }
  1477. switch (temp & 0x0c) {
  1478. default:
  1479. case 0x00:
  1480. param.vram_size = AST_VIDMEM_SIZE_8M;
  1481. break;
  1482. case 0x04:
  1483. param.vram_size = AST_VIDMEM_SIZE_16M;
  1484. break;
  1485. case 0x08:
  1486. param.vram_size = AST_VIDMEM_SIZE_32M;
  1487. break;
  1488. case 0x0c:
  1489. param.vram_size = AST_VIDMEM_SIZE_64M;
  1490. break;
  1491. }
  1492. if (param.dram_type == AST_DDR3) {
  1493. get_ddr3_info(ast, &param);
  1494. ddr3_init(ast, &param);
  1495. } else {
  1496. get_ddr2_info(ast, &param);
  1497. ddr2_init(ast, &param);
  1498. }
  1499. temp = ast_mindwm(ast, 0x1e6e2040);
  1500. ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
  1501. }
  1502. /* wait ready */
  1503. do {
  1504. reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
  1505. } while ((reg & 0x40) == 0);
  1506. }
  1507. static bool cbr_test_2500(struct ast_device *ast)
  1508. {
  1509. ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
  1510. ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
  1511. if (!mmc_test_burst(ast, 0))
  1512. return false;
  1513. if (!mmc_test_single_2500(ast, 0))
  1514. return false;
  1515. return true;
  1516. }
  1517. static bool ddr_test_2500(struct ast_device *ast)
  1518. {
  1519. ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
  1520. ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
  1521. if (!mmc_test_burst(ast, 0))
  1522. return false;
  1523. if (!mmc_test_burst(ast, 1))
  1524. return false;
  1525. if (!mmc_test_burst(ast, 2))
  1526. return false;
  1527. if (!mmc_test_burst(ast, 3))
  1528. return false;
  1529. if (!mmc_test_single_2500(ast, 0))
  1530. return false;
  1531. return true;
  1532. }
  1533. static void ddr_init_common_2500(struct ast_device *ast)
  1534. {
  1535. ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
  1536. ast_moutdwm(ast, 0x1E6E0008, 0x2003000F);
  1537. ast_moutdwm(ast, 0x1E6E0038, 0x00000FFF);
  1538. ast_moutdwm(ast, 0x1E6E0040, 0x88448844);
  1539. ast_moutdwm(ast, 0x1E6E0044, 0x24422288);
  1540. ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
  1541. ast_moutdwm(ast, 0x1E6E004C, 0x22222222);
  1542. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1543. ast_moutdwm(ast, 0x1E6E0208, 0x00000000);
  1544. ast_moutdwm(ast, 0x1E6E0218, 0x00000000);
  1545. ast_moutdwm(ast, 0x1E6E0220, 0x00000000);
  1546. ast_moutdwm(ast, 0x1E6E0228, 0x00000000);
  1547. ast_moutdwm(ast, 0x1E6E0230, 0x00000000);
  1548. ast_moutdwm(ast, 0x1E6E02A8, 0x00000000);
  1549. ast_moutdwm(ast, 0x1E6E02B0, 0x00000000);
  1550. ast_moutdwm(ast, 0x1E6E0240, 0x86000000);
  1551. ast_moutdwm(ast, 0x1E6E0244, 0x00008600);
  1552. ast_moutdwm(ast, 0x1E6E0248, 0x80000000);
  1553. ast_moutdwm(ast, 0x1E6E024C, 0x80808080);
  1554. }
  1555. static void ddr_phy_init_2500(struct ast_device *ast)
  1556. {
  1557. u32 data, pass, timecnt;
  1558. pass = 0;
  1559. ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
  1560. while (!pass) {
  1561. for (timecnt = 0; timecnt < TIMEOUT; timecnt++) {
  1562. data = ast_mindwm(ast, 0x1E6E0060) & 0x1;
  1563. if (!data)
  1564. break;
  1565. }
  1566. if (timecnt != TIMEOUT) {
  1567. data = ast_mindwm(ast, 0x1E6E0300) & 0x000A0000;
  1568. if (!data)
  1569. pass = 1;
  1570. }
  1571. if (!pass) {
  1572. ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
  1573. udelay(10); /* delay 10 us */
  1574. ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
  1575. }
  1576. }
  1577. ast_moutdwm(ast, 0x1E6E0060, 0x00000006);
  1578. }
  1579. /*
  1580. * Check DRAM Size
  1581. * 1Gb : 0x80000000 ~ 0x87FFFFFF
  1582. * 2Gb : 0x80000000 ~ 0x8FFFFFFF
  1583. * 4Gb : 0x80000000 ~ 0x9FFFFFFF
  1584. * 8Gb : 0x80000000 ~ 0xBFFFFFFF
  1585. */
  1586. static void check_dram_size_2500(struct ast_device *ast, u32 tRFC)
  1587. {
  1588. u32 reg_04, reg_14;
  1589. reg_04 = ast_mindwm(ast, 0x1E6E0004) & 0xfffffffc;
  1590. reg_14 = ast_mindwm(ast, 0x1E6E0014) & 0xffffff00;
  1591. ast_moutdwm(ast, 0xA0100000, 0x41424344);
  1592. ast_moutdwm(ast, 0x90100000, 0x35363738);
  1593. ast_moutdwm(ast, 0x88100000, 0x292A2B2C);
  1594. ast_moutdwm(ast, 0x80100000, 0x1D1E1F10);
  1595. /* Check 8Gbit */
  1596. if (ast_mindwm(ast, 0xA0100000) == 0x41424344) {
  1597. reg_04 |= 0x03;
  1598. reg_14 |= (tRFC >> 24) & 0xFF;
  1599. /* Check 4Gbit */
  1600. } else if (ast_mindwm(ast, 0x90100000) == 0x35363738) {
  1601. reg_04 |= 0x02;
  1602. reg_14 |= (tRFC >> 16) & 0xFF;
  1603. /* Check 2Gbit */
  1604. } else if (ast_mindwm(ast, 0x88100000) == 0x292A2B2C) {
  1605. reg_04 |= 0x01;
  1606. reg_14 |= (tRFC >> 8) & 0xFF;
  1607. } else {
  1608. reg_14 |= tRFC & 0xFF;
  1609. }
  1610. ast_moutdwm(ast, 0x1E6E0004, reg_04);
  1611. ast_moutdwm(ast, 0x1E6E0014, reg_14);
  1612. }
  1613. static void enable_cache_2500(struct ast_device *ast)
  1614. {
  1615. u32 reg_04, data;
  1616. reg_04 = ast_mindwm(ast, 0x1E6E0004);
  1617. ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x1000);
  1618. do
  1619. data = ast_mindwm(ast, 0x1E6E0004);
  1620. while (!(data & 0x80000));
  1621. ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400);
  1622. }
  1623. static void set_mpll_2500(struct ast_device *ast)
  1624. {
  1625. u32 addr, data, param;
  1626. /* Reset MMC */
  1627. ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
  1628. ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
  1629. for (addr = 0x1e6e0004; addr < 0x1e6e0090;) {
  1630. ast_moutdwm(ast, addr, 0x0);
  1631. addr += 4;
  1632. }
  1633. ast_moutdwm(ast, 0x1E6E0034, 0x00020000);
  1634. ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
  1635. data = ast_mindwm(ast, 0x1E6E2070) & 0x00800000;
  1636. if (data) {
  1637. /* CLKIN = 25MHz */
  1638. param = 0x930023E0;
  1639. ast_moutdwm(ast, 0x1E6E2160, 0x00011320);
  1640. } else {
  1641. /* CLKIN = 24MHz */
  1642. param = 0x93002400;
  1643. }
  1644. ast_moutdwm(ast, 0x1E6E2020, param);
  1645. udelay(100);
  1646. }
  1647. static void reset_mmc_2500(struct ast_device *ast)
  1648. {
  1649. ast_moutdwm(ast, 0x1E78505C, 0x00000004);
  1650. ast_moutdwm(ast, 0x1E785044, 0x00000001);
  1651. ast_moutdwm(ast, 0x1E785048, 0x00004755);
  1652. ast_moutdwm(ast, 0x1E78504C, 0x00000013);
  1653. mdelay(100);
  1654. ast_moutdwm(ast, 0x1E785054, 0x00000077);
  1655. ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
  1656. }
  1657. static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table)
  1658. {
  1659. ast_moutdwm(ast, 0x1E6E0004, 0x00000303);
  1660. ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
  1661. ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
  1662. ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
  1663. ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
  1664. ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
  1665. ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
  1666. ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
  1667. /* DDR PHY Setting */
  1668. ast_moutdwm(ast, 0x1E6E0200, 0x02492AAE);
  1669. ast_moutdwm(ast, 0x1E6E0204, 0x00001001);
  1670. ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
  1671. ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
  1672. ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
  1673. ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
  1674. ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
  1675. ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
  1676. ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
  1677. ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
  1678. ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
  1679. ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
  1680. ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
  1681. ast_moutdwm(ast, 0x1E6E02C0, 0x00000006);
  1682. /* Controller Setting */
  1683. ast_moutdwm(ast, 0x1E6E0034, 0x00020091);
  1684. /* Wait DDR PHY init done */
  1685. ddr_phy_init_2500(ast);
  1686. ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
  1687. ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
  1688. ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
  1689. check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
  1690. enable_cache_2500(ast);
  1691. ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
  1692. ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
  1693. }
  1694. static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table)
  1695. {
  1696. u32 data, data2, pass, retrycnt;
  1697. u32 ddr_vref, phy_vref;
  1698. u32 min_ddr_vref = 0, min_phy_vref = 0;
  1699. u32 max_ddr_vref = 0, max_phy_vref = 0;
  1700. ast_moutdwm(ast, 0x1E6E0004, 0x00000313);
  1701. ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
  1702. ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
  1703. ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
  1704. ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
  1705. ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
  1706. ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
  1707. ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
  1708. /* DDR PHY Setting */
  1709. ast_moutdwm(ast, 0x1E6E0200, 0x42492AAE);
  1710. ast_moutdwm(ast, 0x1E6E0204, 0x09002000);
  1711. ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
  1712. ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
  1713. ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
  1714. ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
  1715. ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
  1716. ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
  1717. ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
  1718. ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
  1719. ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
  1720. ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
  1721. ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
  1722. ast_moutdwm(ast, 0x1E6E02C4, 0x3C183C3C);
  1723. ast_moutdwm(ast, 0x1E6E02C8, 0x00631E0E);
  1724. /* Controller Setting */
  1725. ast_moutdwm(ast, 0x1E6E0034, 0x0001A991);
  1726. /* Train PHY Vref first */
  1727. pass = 0;
  1728. for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
  1729. max_phy_vref = 0x0;
  1730. pass = 0;
  1731. ast_moutdwm(ast, 0x1E6E02C0, 0x00001C06);
  1732. for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) {
  1733. ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
  1734. ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
  1735. ast_moutdwm(ast, 0x1E6E02CC, phy_vref | (phy_vref << 8));
  1736. /* Fire DFI Init */
  1737. ddr_phy_init_2500(ast);
  1738. ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
  1739. if (cbr_test_2500(ast)) {
  1740. pass++;
  1741. data = ast_mindwm(ast, 0x1E6E03D0);
  1742. data2 = data >> 8;
  1743. data = data & 0xff;
  1744. if (data > data2)
  1745. data = data2;
  1746. if (max_phy_vref < data) {
  1747. max_phy_vref = data;
  1748. min_phy_vref = phy_vref;
  1749. }
  1750. } else if (pass > 0)
  1751. break;
  1752. }
  1753. }
  1754. ast_moutdwm(ast, 0x1E6E02CC, min_phy_vref | (min_phy_vref << 8));
  1755. /* Train DDR Vref next */
  1756. pass = 0;
  1757. for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
  1758. min_ddr_vref = 0xFF;
  1759. max_ddr_vref = 0x0;
  1760. pass = 0;
  1761. for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) {
  1762. ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
  1763. ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
  1764. ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
  1765. /* Fire DFI Init */
  1766. ddr_phy_init_2500(ast);
  1767. ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
  1768. if (cbr_test_2500(ast)) {
  1769. pass++;
  1770. if (min_ddr_vref > ddr_vref)
  1771. min_ddr_vref = ddr_vref;
  1772. if (max_ddr_vref < ddr_vref)
  1773. max_ddr_vref = ddr_vref;
  1774. } else if (pass != 0)
  1775. break;
  1776. }
  1777. }
  1778. ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
  1779. ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
  1780. ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
  1781. ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
  1782. /* Wait DDR PHY init done */
  1783. ddr_phy_init_2500(ast);
  1784. ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
  1785. ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
  1786. ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
  1787. check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
  1788. enable_cache_2500(ast);
  1789. ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
  1790. ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
  1791. }
  1792. static bool ast_dram_init_2500(struct ast_device *ast)
  1793. {
  1794. u32 data;
  1795. u32 max_tries = 5;
  1796. do {
  1797. if (max_tries-- == 0)
  1798. return false;
  1799. set_mpll_2500(ast);
  1800. reset_mmc_2500(ast);
  1801. ddr_init_common_2500(ast);
  1802. data = ast_mindwm(ast, 0x1E6E2070);
  1803. if (data & 0x01000000)
  1804. ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table);
  1805. else
  1806. ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table);
  1807. } while (!ddr_test_2500(ast));
  1808. ast_moutdwm(ast, 0x1E6E2040, ast_mindwm(ast, 0x1E6E2040) | 0x41);
  1809. /* Patch code */
  1810. data = ast_mindwm(ast, 0x1E6E200C) & 0xF9FFFFFF;
  1811. ast_moutdwm(ast, 0x1E6E200C, data | 0x10000000);
  1812. return true;
  1813. }
  1814. void ast_patch_ahb_2500(void __iomem *regs)
  1815. {
  1816. u32 data;
  1817. /* Clear bus lock condition */
  1818. __ast_moutdwm(regs, 0x1e600000, 0xAEED1A03);
  1819. __ast_moutdwm(regs, 0x1e600084, 0x00010000);
  1820. __ast_moutdwm(regs, 0x1e600088, 0x00000000);
  1821. __ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
  1822. data = __ast_mindwm(regs, 0x1e6e2070);
  1823. if (data & 0x08000000) { /* check fast reset */
  1824. /*
  1825. * If "Fast restet" is enabled for ARM-ICE debugger,
  1826. * then WDT needs to enable, that
  1827. * WDT04 is WDT#1 Reload reg.
  1828. * WDT08 is WDT#1 counter restart reg to avoid system deadlock
  1829. * WDT0C is WDT#1 control reg
  1830. * [6:5]:= 01:Full chip
  1831. * [4]:= 1:1MHz clock source
  1832. * [1]:= 1:WDT will be cleeared and disabled after timeout occurs
  1833. * [0]:= 1:WDT enable
  1834. */
  1835. __ast_moutdwm(regs, 0x1E785004, 0x00000010);
  1836. __ast_moutdwm(regs, 0x1E785008, 0x00004755);
  1837. __ast_moutdwm(regs, 0x1E78500c, 0x00000033);
  1838. udelay(1000);
  1839. }
  1840. do {
  1841. __ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
  1842. data = __ast_mindwm(regs, 0x1e6e2000);
  1843. } while (data != 1);
  1844. __ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */
  1845. }
  1846. void ast_post_chip_2500(struct drm_device *dev)
  1847. {
  1848. struct ast_device *ast = to_ast_device(dev);
  1849. u32 temp;
  1850. u8 reg;
  1851. reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
  1852. if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
  1853. /* Clear bus lock condition */
  1854. ast_patch_ahb_2500(ast->regs);
  1855. /* Disable watchdog */
  1856. ast_moutdwm(ast, 0x1E78502C, 0x00000000);
  1857. ast_moutdwm(ast, 0x1E78504C, 0x00000000);
  1858. /*
  1859. * Reset USB port to patch USB unknown device issue
  1860. * SCU90 is Multi-function Pin Control #5
  1861. * [29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub
  1862. * port).
  1863. * SCU94 is Multi-function Pin Control #6
  1864. * [14:13]:= 1x:USB2.0 Host2 controller
  1865. * SCU70 is Hardware Strap reg
  1866. * [23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by
  1867. * [18]: 0(24)/1(48) MHz)
  1868. * SCU7C is Write clear reg to SCU70
  1869. * [23]:= write 1 and then SCU70[23] will be clear as 0b.
  1870. */
  1871. ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
  1872. ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
  1873. if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
  1874. ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
  1875. mdelay(100);
  1876. ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
  1877. }
  1878. /* Modify eSPI reset pin */
  1879. temp = ast_mindwm(ast, 0x1E6E2070);
  1880. if (temp & 0x02000000)
  1881. ast_moutdwm(ast, 0x1E6E207C, 0x00004000);
  1882. /* Slow down CPU/AHB CLK in VGA only mode */
  1883. temp = ast_read32(ast, 0x12008);
  1884. temp |= 0x73;
  1885. ast_write32(ast, 0x12008, temp);
  1886. if (!ast_dram_init_2500(ast))
  1887. drm_err(dev, "DRAM init failed !\n");
  1888. temp = ast_mindwm(ast, 0x1e6e2040);
  1889. ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
  1890. }
  1891. /* wait ready */
  1892. do {
  1893. reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
  1894. } while ((reg & 0x40) == 0);
  1895. }