ast_post.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652
  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 <drm/drmP.h>
  29. #include "ast_drv.h"
  30. #include "ast_dram_tables.h"
  31. static void ast_init_dram_2300(struct drm_device *dev);
  32. static void
  33. ast_enable_vga(struct drm_device *dev)
  34. {
  35. struct ast_private *ast = dev->dev_private;
  36. ast_io_write8(ast, 0x43, 0x01);
  37. ast_io_write8(ast, 0x42, 0x01);
  38. }
  39. #if 0 /* will use later */
  40. static bool
  41. ast_is_vga_enabled(struct drm_device *dev)
  42. {
  43. struct ast_private *ast = dev->dev_private;
  44. u8 ch;
  45. if (ast->chip == AST1180) {
  46. /* TODO 1180 */
  47. } else {
  48. ch = ast_io_read8(ast, 0x43);
  49. if (ch) {
  50. ast_open_key(ast);
  51. ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff);
  52. return ch & 0x04;
  53. }
  54. }
  55. return 0;
  56. }
  57. #endif
  58. static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
  59. static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff };
  60. static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
  61. static void
  62. ast_set_def_ext_reg(struct drm_device *dev)
  63. {
  64. struct ast_private *ast = dev->dev_private;
  65. u8 i, index, reg;
  66. const u8 *ext_reg_info;
  67. /* reset scratch */
  68. for (i = 0x81; i <= 0x8f; i++)
  69. ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
  70. if (ast->chip == AST2300 || ast->chip == AST2400) {
  71. if (dev->pdev->revision >= 0x20)
  72. ext_reg_info = extreginfo_ast2300;
  73. else
  74. ext_reg_info = extreginfo_ast2300a0;
  75. } else
  76. ext_reg_info = extreginfo;
  77. index = 0xa0;
  78. while (*ext_reg_info != 0xff) {
  79. ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info);
  80. index++;
  81. ext_reg_info++;
  82. }
  83. /* disable standard IO/MEM decode if secondary */
  84. /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
  85. /* Set Ext. Default */
  86. ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01);
  87. ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00);
  88. /* Enable RAMDAC for A1 */
  89. reg = 0x04;
  90. if (ast->chip == AST2300 || ast->chip == AST2400)
  91. reg |= 0x20;
  92. ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
  93. }
  94. u32 ast_mindwm(struct ast_private *ast, u32 r)
  95. {
  96. uint32_t data;
  97. ast_write32(ast, 0xf004, r & 0xffff0000);
  98. ast_write32(ast, 0xf000, 0x1);
  99. do {
  100. data = ast_read32(ast, 0xf004) & 0xffff0000;
  101. } while (data != (r & 0xffff0000));
  102. return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
  103. }
  104. void ast_moutdwm(struct ast_private *ast, u32 r, u32 v)
  105. {
  106. uint32_t data;
  107. ast_write32(ast, 0xf004, r & 0xffff0000);
  108. ast_write32(ast, 0xf000, 0x1);
  109. do {
  110. data = ast_read32(ast, 0xf004) & 0xffff0000;
  111. } while (data != (r & 0xffff0000));
  112. ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
  113. }
  114. /*
  115. * AST2100/2150 DLL CBR Setting
  116. */
  117. #define CBR_SIZE_AST2150 ((16 << 10) - 1)
  118. #define CBR_PASSNUM_AST2150 5
  119. #define CBR_THRESHOLD_AST2150 10
  120. #define CBR_THRESHOLD2_AST2150 10
  121. #define TIMEOUT_AST2150 5000000
  122. #define CBR_PATNUM_AST2150 8
  123. static const u32 pattern_AST2150[14] = {
  124. 0xFF00FF00,
  125. 0xCC33CC33,
  126. 0xAA55AA55,
  127. 0xFFFE0001,
  128. 0x683501FE,
  129. 0x0F1929B0,
  130. 0x2D0B4346,
  131. 0x60767F02,
  132. 0x6FBE36A6,
  133. 0x3A253035,
  134. 0x3019686D,
  135. 0x41C6167E,
  136. 0x620152BF,
  137. 0x20F050E0
  138. };
  139. static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
  140. {
  141. u32 data, timeout;
  142. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  143. ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
  144. timeout = 0;
  145. do {
  146. data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
  147. if (++timeout > TIMEOUT_AST2150) {
  148. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  149. return 0xffffffff;
  150. }
  151. } while (!data);
  152. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  153. ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
  154. timeout = 0;
  155. do {
  156. data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
  157. if (++timeout > TIMEOUT_AST2150) {
  158. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  159. return 0xffffffff;
  160. }
  161. } while (!data);
  162. data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
  163. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  164. return data;
  165. }
  166. #if 0 /* unused in DDX driver - here for completeness */
  167. static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
  168. {
  169. u32 data, timeout;
  170. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  171. ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
  172. timeout = 0;
  173. do {
  174. data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
  175. if (++timeout > TIMEOUT_AST2150) {
  176. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  177. return 0xffffffff;
  178. }
  179. } while (!data);
  180. data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
  181. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  182. return data;
  183. }
  184. #endif
  185. static int cbrtest_ast2150(struct ast_private *ast)
  186. {
  187. int i;
  188. for (i = 0; i < 8; i++)
  189. if (mmctestburst2_ast2150(ast, i))
  190. return 0;
  191. return 1;
  192. }
  193. static int cbrscan_ast2150(struct ast_private *ast, int busw)
  194. {
  195. u32 patcnt, loop;
  196. for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
  197. ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
  198. for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
  199. if (cbrtest_ast2150(ast))
  200. break;
  201. }
  202. if (loop == CBR_PASSNUM_AST2150)
  203. return 0;
  204. }
  205. return 1;
  206. }
  207. static void cbrdlli_ast2150(struct ast_private *ast, int busw)
  208. {
  209. u32 dll_min[4], dll_max[4], dlli, data, passcnt;
  210. cbr_start:
  211. dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
  212. dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
  213. passcnt = 0;
  214. for (dlli = 0; dlli < 100; dlli++) {
  215. ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
  216. data = cbrscan_ast2150(ast, busw);
  217. if (data != 0) {
  218. if (data & 0x1) {
  219. if (dll_min[0] > dlli)
  220. dll_min[0] = dlli;
  221. if (dll_max[0] < dlli)
  222. dll_max[0] = dlli;
  223. }
  224. passcnt++;
  225. } else if (passcnt >= CBR_THRESHOLD_AST2150)
  226. goto cbr_start;
  227. }
  228. if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
  229. goto cbr_start;
  230. dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
  231. ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
  232. }
  233. static void ast_init_dram_reg(struct drm_device *dev)
  234. {
  235. struct ast_private *ast = dev->dev_private;
  236. u8 j;
  237. u32 data, temp, i;
  238. const struct ast_dramstruct *dram_reg_info;
  239. j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
  240. if ((j & 0x80) == 0) { /* VGA only */
  241. if (ast->chip == AST2000) {
  242. dram_reg_info = ast2000_dram_table_data;
  243. ast_write32(ast, 0xf004, 0x1e6e0000);
  244. ast_write32(ast, 0xf000, 0x1);
  245. ast_write32(ast, 0x10100, 0xa8);
  246. do {
  247. ;
  248. } while (ast_read32(ast, 0x10100) != 0xa8);
  249. } else {/* AST2100/1100 */
  250. if (ast->chip == AST2100 || ast->chip == 2200)
  251. dram_reg_info = ast2100_dram_table_data;
  252. else
  253. dram_reg_info = ast1100_dram_table_data;
  254. ast_write32(ast, 0xf004, 0x1e6e0000);
  255. ast_write32(ast, 0xf000, 0x1);
  256. ast_write32(ast, 0x12000, 0x1688A8A8);
  257. do {
  258. ;
  259. } while (ast_read32(ast, 0x12000) != 0x01);
  260. ast_write32(ast, 0x10000, 0xfc600309);
  261. do {
  262. ;
  263. } while (ast_read32(ast, 0x10000) != 0x01);
  264. }
  265. while (dram_reg_info->index != 0xffff) {
  266. if (dram_reg_info->index == 0xff00) {/* delay fn */
  267. for (i = 0; i < 15; i++)
  268. udelay(dram_reg_info->data);
  269. } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) {
  270. data = dram_reg_info->data;
  271. if (ast->dram_type == AST_DRAM_1Gx16)
  272. data = 0x00000d89;
  273. else if (ast->dram_type == AST_DRAM_1Gx32)
  274. data = 0x00000c8d;
  275. temp = ast_read32(ast, 0x12070);
  276. temp &= 0xc;
  277. temp <<= 2;
  278. ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
  279. } else
  280. ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
  281. dram_reg_info++;
  282. }
  283. /* AST 2100/2150 DRAM calibration */
  284. data = ast_read32(ast, 0x10120);
  285. if (data == 0x5061) { /* 266Mhz */
  286. data = ast_read32(ast, 0x10004);
  287. if (data & 0x40)
  288. cbrdlli_ast2150(ast, 16); /* 16 bits */
  289. else
  290. cbrdlli_ast2150(ast, 32); /* 32 bits */
  291. }
  292. switch (ast->chip) {
  293. case AST2000:
  294. temp = ast_read32(ast, 0x10140);
  295. ast_write32(ast, 0x10140, temp | 0x40);
  296. break;
  297. case AST1100:
  298. case AST2100:
  299. case AST2200:
  300. case AST2150:
  301. temp = ast_read32(ast, 0x1200c);
  302. ast_write32(ast, 0x1200c, temp & 0xfffffffd);
  303. temp = ast_read32(ast, 0x12040);
  304. ast_write32(ast, 0x12040, temp | 0x40);
  305. break;
  306. default:
  307. break;
  308. }
  309. }
  310. /* wait ready */
  311. do {
  312. j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
  313. } while ((j & 0x40) == 0);
  314. }
  315. void ast_post_gpu(struct drm_device *dev)
  316. {
  317. u32 reg;
  318. struct ast_private *ast = dev->dev_private;
  319. pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
  320. reg |= 0x3;
  321. pci_write_config_dword(ast->dev->pdev, 0x04, reg);
  322. ast_enable_vga(dev);
  323. ast_open_key(ast);
  324. ast_set_def_ext_reg(dev);
  325. if (ast->chip == AST2300 || ast->chip == AST2400)
  326. ast_init_dram_2300(dev);
  327. else
  328. ast_init_dram_reg(dev);
  329. ast_init_3rdtx(dev);
  330. }
  331. /* AST 2300 DRAM settings */
  332. #define AST_DDR3 0
  333. #define AST_DDR2 1
  334. struct ast2300_dram_param {
  335. u32 dram_type;
  336. u32 dram_chipid;
  337. u32 dram_freq;
  338. u32 vram_size;
  339. u32 odt;
  340. u32 wodt;
  341. u32 rodt;
  342. u32 dram_config;
  343. u32 reg_PERIOD;
  344. u32 reg_MADJ;
  345. u32 reg_SADJ;
  346. u32 reg_MRS;
  347. u32 reg_EMRS;
  348. u32 reg_AC1;
  349. u32 reg_AC2;
  350. u32 reg_DQSIC;
  351. u32 reg_DRV;
  352. u32 reg_IOZ;
  353. u32 reg_DQIDLY;
  354. u32 reg_FREQ;
  355. u32 madj_max;
  356. u32 dll2_finetune_step;
  357. };
  358. /*
  359. * DQSI DLL CBR Setting
  360. */
  361. #define CBR_SIZE0 ((1 << 10) - 1)
  362. #define CBR_SIZE1 ((4 << 10) - 1)
  363. #define CBR_SIZE2 ((64 << 10) - 1)
  364. #define CBR_PASSNUM 5
  365. #define CBR_PASSNUM2 5
  366. #define CBR_THRESHOLD 10
  367. #define CBR_THRESHOLD2 10
  368. #define TIMEOUT 5000000
  369. #define CBR_PATNUM 8
  370. static const u32 pattern[8] = {
  371. 0xFF00FF00,
  372. 0xCC33CC33,
  373. 0xAA55AA55,
  374. 0x88778877,
  375. 0x92CC4D6E,
  376. 0x543D3CDE,
  377. 0xF1E843C7,
  378. 0x7C61D253
  379. };
  380. static int mmc_test_burst(struct ast_private *ast, u32 datagen)
  381. {
  382. u32 data, timeout;
  383. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  384. ast_moutdwm(ast, 0x1e6e0070, 0x000000c1 | (datagen << 3));
  385. timeout = 0;
  386. do {
  387. data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
  388. if (data & 0x2000) {
  389. return 0;
  390. }
  391. if (++timeout > TIMEOUT) {
  392. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  393. return 0;
  394. }
  395. } while (!data);
  396. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  397. return 1;
  398. }
  399. static int mmc_test_burst2(struct ast_private *ast, u32 datagen)
  400. {
  401. u32 data, timeout;
  402. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  403. ast_moutdwm(ast, 0x1e6e0070, 0x00000041 | (datagen << 3));
  404. timeout = 0;
  405. do {
  406. data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
  407. if (++timeout > TIMEOUT) {
  408. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  409. return -1;
  410. }
  411. } while (!data);
  412. data = ast_mindwm(ast, 0x1e6e0078);
  413. data = (data | (data >> 16)) & 0xffff;
  414. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  415. return data;
  416. }
  417. static int mmc_test_single(struct ast_private *ast, u32 datagen)
  418. {
  419. u32 data, timeout;
  420. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  421. ast_moutdwm(ast, 0x1e6e0070, 0x000000c5 | (datagen << 3));
  422. timeout = 0;
  423. do {
  424. data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
  425. if (data & 0x2000)
  426. return 0;
  427. if (++timeout > TIMEOUT) {
  428. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  429. return 0;
  430. }
  431. } while (!data);
  432. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  433. return 1;
  434. }
  435. static int mmc_test_single2(struct ast_private *ast, u32 datagen)
  436. {
  437. u32 data, timeout;
  438. ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
  439. ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
  440. timeout = 0;
  441. do {
  442. data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
  443. if (++timeout > TIMEOUT) {
  444. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  445. return -1;
  446. }
  447. } while (!data);
  448. data = ast_mindwm(ast, 0x1e6e0078);
  449. data = (data | (data >> 16)) & 0xffff;
  450. ast_moutdwm(ast, 0x1e6e0070, 0x0);
  451. return data;
  452. }
  453. static int cbr_test(struct ast_private *ast)
  454. {
  455. u32 data;
  456. int i;
  457. data = mmc_test_single2(ast, 0);
  458. if ((data & 0xff) && (data & 0xff00))
  459. return 0;
  460. for (i = 0; i < 8; i++) {
  461. data = mmc_test_burst2(ast, i);
  462. if ((data & 0xff) && (data & 0xff00))
  463. return 0;
  464. }
  465. if (!data)
  466. return 3;
  467. else if (data & 0xff)
  468. return 2;
  469. return 1;
  470. }
  471. static int cbr_scan(struct ast_private *ast)
  472. {
  473. u32 data, data2, patcnt, loop;
  474. data2 = 3;
  475. for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
  476. ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
  477. for (loop = 0; loop < CBR_PASSNUM2; loop++) {
  478. if ((data = cbr_test(ast)) != 0) {
  479. data2 &= data;
  480. if (!data2)
  481. return 0;
  482. break;
  483. }
  484. }
  485. if (loop == CBR_PASSNUM2)
  486. return 0;
  487. }
  488. return data2;
  489. }
  490. static u32 cbr_test2(struct ast_private *ast)
  491. {
  492. u32 data;
  493. data = mmc_test_burst2(ast, 0);
  494. if (data == 0xffff)
  495. return 0;
  496. data |= mmc_test_single2(ast, 0);
  497. if (data == 0xffff)
  498. return 0;
  499. return ~data & 0xffff;
  500. }
  501. static u32 cbr_scan2(struct ast_private *ast)
  502. {
  503. u32 data, data2, patcnt, loop;
  504. data2 = 0xffff;
  505. for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
  506. ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
  507. for (loop = 0; loop < CBR_PASSNUM2; loop++) {
  508. if ((data = cbr_test2(ast)) != 0) {
  509. data2 &= data;
  510. if (!data2)
  511. return 0;
  512. break;
  513. }
  514. }
  515. if (loop == CBR_PASSNUM2)
  516. return 0;
  517. }
  518. return data2;
  519. }
  520. static u32 cbr_test3(struct ast_private *ast)
  521. {
  522. if (!mmc_test_burst(ast, 0))
  523. return 0;
  524. if (!mmc_test_single(ast, 0))
  525. return 0;
  526. return 1;
  527. }
  528. static u32 cbr_scan3(struct ast_private *ast)
  529. {
  530. u32 patcnt, loop;
  531. for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
  532. ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
  533. for (loop = 0; loop < 2; loop++) {
  534. if (cbr_test3(ast))
  535. break;
  536. }
  537. if (loop == 2)
  538. return 0;
  539. }
  540. return 1;
  541. }
  542. static bool finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
  543. {
  544. u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
  545. bool status = false;
  546. FINETUNE_START:
  547. for (cnt = 0; cnt < 16; cnt++) {
  548. dllmin[cnt] = 0xff;
  549. dllmax[cnt] = 0x0;
  550. }
  551. passcnt = 0;
  552. for (dlli = 0; dlli < 76; dlli++) {
  553. ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
  554. ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
  555. data = cbr_scan2(ast);
  556. if (data != 0) {
  557. mask = 0x00010001;
  558. for (cnt = 0; cnt < 16; cnt++) {
  559. if (data & mask) {
  560. if (dllmin[cnt] > dlli) {
  561. dllmin[cnt] = dlli;
  562. }
  563. if (dllmax[cnt] < dlli) {
  564. dllmax[cnt] = dlli;
  565. }
  566. }
  567. mask <<= 1;
  568. }
  569. passcnt++;
  570. } else if (passcnt >= CBR_THRESHOLD2) {
  571. break;
  572. }
  573. }
  574. gold_sadj[0] = 0x0;
  575. passcnt = 0;
  576. for (cnt = 0; cnt < 16; cnt++) {
  577. if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
  578. gold_sadj[0] += dllmin[cnt];
  579. passcnt++;
  580. }
  581. }
  582. if (retry++ > 10)
  583. goto FINETUNE_DONE;
  584. if (passcnt != 16) {
  585. goto FINETUNE_START;
  586. }
  587. status = true;
  588. FINETUNE_DONE:
  589. gold_sadj[0] = gold_sadj[0] >> 4;
  590. gold_sadj[1] = gold_sadj[0];
  591. data = 0;
  592. for (cnt = 0; cnt < 8; cnt++) {
  593. data >>= 3;
  594. if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
  595. dlli = dllmin[cnt];
  596. if (gold_sadj[0] >= dlli) {
  597. dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
  598. if (dlli > 3) {
  599. dlli = 3;
  600. }
  601. } else {
  602. dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
  603. if (dlli > 4) {
  604. dlli = 4;
  605. }
  606. dlli = (8 - dlli) & 0x7;
  607. }
  608. data |= dlli << 21;
  609. }
  610. }
  611. ast_moutdwm(ast, 0x1E6E0080, data);
  612. data = 0;
  613. for (cnt = 8; cnt < 16; cnt++) {
  614. data >>= 3;
  615. if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
  616. dlli = dllmin[cnt];
  617. if (gold_sadj[1] >= dlli) {
  618. dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
  619. if (dlli > 3) {
  620. dlli = 3;
  621. } else {
  622. dlli = (dlli - 1) & 0x7;
  623. }
  624. } else {
  625. dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
  626. dlli += 1;
  627. if (dlli > 4) {
  628. dlli = 4;
  629. }
  630. dlli = (8 - dlli) & 0x7;
  631. }
  632. data |= dlli << 21;
  633. }
  634. }
  635. ast_moutdwm(ast, 0x1E6E0084, data);
  636. return status;
  637. } /* finetuneDQI_L */
  638. static void finetuneDQSI(struct ast_private *ast)
  639. {
  640. u32 dlli, dqsip, dqidly;
  641. u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
  642. u32 g_dqidly, g_dqsip, g_margin, g_side;
  643. u16 pass[32][2][2];
  644. char tag[2][76];
  645. /* Disable DQI CBR */
  646. reg_mcr0c = ast_mindwm(ast, 0x1E6E000C);
  647. reg_mcr18 = ast_mindwm(ast, 0x1E6E0018);
  648. reg_mcr18 &= 0x0000ffff;
  649. ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
  650. for (dlli = 0; dlli < 76; dlli++) {
  651. tag[0][dlli] = 0x0;
  652. tag[1][dlli] = 0x0;
  653. }
  654. for (dqidly = 0; dqidly < 32; dqidly++) {
  655. pass[dqidly][0][0] = 0xff;
  656. pass[dqidly][0][1] = 0x0;
  657. pass[dqidly][1][0] = 0xff;
  658. pass[dqidly][1][1] = 0x0;
  659. }
  660. for (dqidly = 0; dqidly < 32; dqidly++) {
  661. passcnt[0] = passcnt[1] = 0;
  662. for (dqsip = 0; dqsip < 2; dqsip++) {
  663. ast_moutdwm(ast, 0x1E6E000C, 0);
  664. ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
  665. ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
  666. for (dlli = 0; dlli < 76; dlli++) {
  667. ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
  668. ast_moutdwm(ast, 0x1E6E0070, 0);
  669. ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
  670. if (cbr_scan3(ast)) {
  671. if (dlli == 0)
  672. break;
  673. passcnt[dqsip]++;
  674. tag[dqsip][dlli] = 'P';
  675. if (dlli < pass[dqidly][dqsip][0])
  676. pass[dqidly][dqsip][0] = (u16) dlli;
  677. if (dlli > pass[dqidly][dqsip][1])
  678. pass[dqidly][dqsip][1] = (u16) dlli;
  679. } else if (passcnt[dqsip] >= 5)
  680. break;
  681. else {
  682. pass[dqidly][dqsip][0] = 0xff;
  683. pass[dqidly][dqsip][1] = 0x0;
  684. }
  685. }
  686. }
  687. if (passcnt[0] == 0 && passcnt[1] == 0)
  688. dqidly++;
  689. }
  690. /* Search margin */
  691. g_dqidly = g_dqsip = g_margin = g_side = 0;
  692. for (dqidly = 0; dqidly < 32; dqidly++) {
  693. for (dqsip = 0; dqsip < 2; dqsip++) {
  694. if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
  695. continue;
  696. diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
  697. if ((diff+2) < g_margin)
  698. continue;
  699. passcnt[0] = passcnt[1] = 0;
  700. for (dlli = pass[dqidly][dqsip][0]; dlli > 0 && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++);
  701. for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++);
  702. if (passcnt[0] > passcnt[1])
  703. passcnt[0] = passcnt[1];
  704. passcnt[1] = 0;
  705. if (passcnt[0] > g_side)
  706. passcnt[1] = passcnt[0] - g_side;
  707. if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
  708. g_margin = diff;
  709. g_dqidly = dqidly;
  710. g_dqsip = dqsip;
  711. g_side = passcnt[0];
  712. } else if (passcnt[1] > 1 && g_side < 8) {
  713. if (diff > g_margin)
  714. g_margin = diff;
  715. g_dqidly = dqidly;
  716. g_dqsip = dqsip;
  717. g_side = passcnt[0];
  718. }
  719. }
  720. }
  721. reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
  722. ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
  723. }
  724. static bool cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
  725. {
  726. u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
  727. bool status = false;
  728. finetuneDQSI(ast);
  729. if (finetuneDQI_L(ast, param) == false)
  730. return status;
  731. CBR_START2:
  732. dllmin[0] = dllmin[1] = 0xff;
  733. dllmax[0] = dllmax[1] = 0x0;
  734. passcnt = 0;
  735. for (dlli = 0; dlli < 76; dlli++) {
  736. ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
  737. ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
  738. data = cbr_scan(ast);
  739. if (data != 0) {
  740. if (data & 0x1) {
  741. if (dllmin[0] > dlli) {
  742. dllmin[0] = dlli;
  743. }
  744. if (dllmax[0] < dlli) {
  745. dllmax[0] = dlli;
  746. }
  747. }
  748. if (data & 0x2) {
  749. if (dllmin[1] > dlli) {
  750. dllmin[1] = dlli;
  751. }
  752. if (dllmax[1] < dlli) {
  753. dllmax[1] = dlli;
  754. }
  755. }
  756. passcnt++;
  757. } else if (passcnt >= CBR_THRESHOLD) {
  758. break;
  759. }
  760. }
  761. if (retry++ > 10)
  762. goto CBR_DONE2;
  763. if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
  764. goto CBR_START2;
  765. }
  766. if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
  767. goto CBR_START2;
  768. }
  769. status = true;
  770. CBR_DONE2:
  771. dlli = (dllmin[1] + dllmax[1]) >> 1;
  772. dlli <<= 8;
  773. dlli += (dllmin[0] + dllmax[0]) >> 1;
  774. ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
  775. return status;
  776. } /* CBRDLL2 */
  777. static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
  778. {
  779. u32 trap, trap_AC2, trap_MRS;
  780. ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
  781. /* Ger trap info */
  782. trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
  783. trap_AC2 = 0x00020000 + (trap << 16);
  784. trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
  785. trap_MRS = 0x00000010 + (trap << 4);
  786. trap_MRS |= ((trap & 0x2) << 18);
  787. param->reg_MADJ = 0x00034C4C;
  788. param->reg_SADJ = 0x00001800;
  789. param->reg_DRV = 0x000000F0;
  790. param->reg_PERIOD = param->dram_freq;
  791. param->rodt = 0;
  792. switch (param->dram_freq) {
  793. case 336:
  794. ast_moutdwm(ast, 0x1E6E2020, 0x0190);
  795. param->wodt = 0;
  796. param->reg_AC1 = 0x22202725;
  797. param->reg_AC2 = 0xAA007613 | trap_AC2;
  798. param->reg_DQSIC = 0x000000BA;
  799. param->reg_MRS = 0x04001400 | trap_MRS;
  800. param->reg_EMRS = 0x00000000;
  801. param->reg_IOZ = 0x00000023;
  802. param->reg_DQIDLY = 0x00000074;
  803. param->reg_FREQ = 0x00004DC0;
  804. param->madj_max = 96;
  805. param->dll2_finetune_step = 3;
  806. switch (param->dram_chipid) {
  807. default:
  808. case AST_DRAM_512Mx16:
  809. case AST_DRAM_1Gx16:
  810. param->reg_AC2 = 0xAA007613 | trap_AC2;
  811. break;
  812. case AST_DRAM_2Gx16:
  813. param->reg_AC2 = 0xAA00761C | trap_AC2;
  814. break;
  815. case AST_DRAM_4Gx16:
  816. param->reg_AC2 = 0xAA007636 | trap_AC2;
  817. break;
  818. }
  819. break;
  820. default:
  821. case 396:
  822. ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
  823. param->wodt = 1;
  824. param->reg_AC1 = 0x33302825;
  825. param->reg_AC2 = 0xCC009617 | trap_AC2;
  826. param->reg_DQSIC = 0x000000E2;
  827. param->reg_MRS = 0x04001600 | trap_MRS;
  828. param->reg_EMRS = 0x00000000;
  829. param->reg_IOZ = 0x00000034;
  830. param->reg_DRV = 0x000000FA;
  831. param->reg_DQIDLY = 0x00000089;
  832. param->reg_FREQ = 0x00005040;
  833. param->madj_max = 96;
  834. param->dll2_finetune_step = 4;
  835. switch (param->dram_chipid) {
  836. default:
  837. case AST_DRAM_512Mx16:
  838. case AST_DRAM_1Gx16:
  839. param->reg_AC2 = 0xCC009617 | trap_AC2;
  840. break;
  841. case AST_DRAM_2Gx16:
  842. param->reg_AC2 = 0xCC009622 | trap_AC2;
  843. break;
  844. case AST_DRAM_4Gx16:
  845. param->reg_AC2 = 0xCC00963F | trap_AC2;
  846. break;
  847. }
  848. break;
  849. case 408:
  850. ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
  851. param->wodt = 1;
  852. param->reg_AC1 = 0x33302825;
  853. param->reg_AC2 = 0xCC009617 | trap_AC2;
  854. param->reg_DQSIC = 0x000000E2;
  855. param->reg_MRS = 0x04001600 | trap_MRS;
  856. param->reg_EMRS = 0x00000000;
  857. param->reg_IOZ = 0x00000023;
  858. param->reg_DRV = 0x000000FA;
  859. param->reg_DQIDLY = 0x00000089;
  860. param->reg_FREQ = 0x000050C0;
  861. param->madj_max = 96;
  862. param->dll2_finetune_step = 4;
  863. switch (param->dram_chipid) {
  864. default:
  865. case AST_DRAM_512Mx16:
  866. case AST_DRAM_1Gx16:
  867. param->reg_AC2 = 0xCC009617 | trap_AC2;
  868. break;
  869. case AST_DRAM_2Gx16:
  870. param->reg_AC2 = 0xCC009622 | trap_AC2;
  871. break;
  872. case AST_DRAM_4Gx16:
  873. param->reg_AC2 = 0xCC00963F | trap_AC2;
  874. break;
  875. }
  876. break;
  877. case 456:
  878. ast_moutdwm(ast, 0x1E6E2020, 0x0230);
  879. param->wodt = 0;
  880. param->reg_AC1 = 0x33302926;
  881. param->reg_AC2 = 0xCD44961A;
  882. param->reg_DQSIC = 0x000000FC;
  883. param->reg_MRS = 0x00081830;
  884. param->reg_EMRS = 0x00000000;
  885. param->reg_IOZ = 0x00000045;
  886. param->reg_DQIDLY = 0x00000097;
  887. param->reg_FREQ = 0x000052C0;
  888. param->madj_max = 88;
  889. param->dll2_finetune_step = 4;
  890. break;
  891. case 504:
  892. ast_moutdwm(ast, 0x1E6E2020, 0x0270);
  893. param->wodt = 1;
  894. param->reg_AC1 = 0x33302926;
  895. param->reg_AC2 = 0xDE44A61D;
  896. param->reg_DQSIC = 0x00000117;
  897. param->reg_MRS = 0x00081A30;
  898. param->reg_EMRS = 0x00000000;
  899. param->reg_IOZ = 0x070000BB;
  900. param->reg_DQIDLY = 0x000000A0;
  901. param->reg_FREQ = 0x000054C0;
  902. param->madj_max = 79;
  903. param->dll2_finetune_step = 4;
  904. break;
  905. case 528:
  906. ast_moutdwm(ast, 0x1E6E2020, 0x0290);
  907. param->wodt = 1;
  908. param->rodt = 1;
  909. param->reg_AC1 = 0x33302926;
  910. param->reg_AC2 = 0xEF44B61E;
  911. param->reg_DQSIC = 0x00000125;
  912. param->reg_MRS = 0x00081A30;
  913. param->reg_EMRS = 0x00000040;
  914. param->reg_DRV = 0x000000F5;
  915. param->reg_IOZ = 0x00000023;
  916. param->reg_DQIDLY = 0x00000088;
  917. param->reg_FREQ = 0x000055C0;
  918. param->madj_max = 76;
  919. param->dll2_finetune_step = 3;
  920. break;
  921. case 576:
  922. ast_moutdwm(ast, 0x1E6E2020, 0x0140);
  923. param->reg_MADJ = 0x00136868;
  924. param->reg_SADJ = 0x00004534;
  925. param->wodt = 1;
  926. param->rodt = 1;
  927. param->reg_AC1 = 0x33302A37;
  928. param->reg_AC2 = 0xEF56B61E;
  929. param->reg_DQSIC = 0x0000013F;
  930. param->reg_MRS = 0x00101A50;
  931. param->reg_EMRS = 0x00000040;
  932. param->reg_DRV = 0x000000FA;
  933. param->reg_IOZ = 0x00000023;
  934. param->reg_DQIDLY = 0x00000078;
  935. param->reg_FREQ = 0x000057C0;
  936. param->madj_max = 136;
  937. param->dll2_finetune_step = 3;
  938. break;
  939. case 600:
  940. ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
  941. param->reg_MADJ = 0x00136868;
  942. param->reg_SADJ = 0x00004534;
  943. param->wodt = 1;
  944. param->rodt = 1;
  945. param->reg_AC1 = 0x32302A37;
  946. param->reg_AC2 = 0xDF56B61F;
  947. param->reg_DQSIC = 0x0000014D;
  948. param->reg_MRS = 0x00101A50;
  949. param->reg_EMRS = 0x00000004;
  950. param->reg_DRV = 0x000000F5;
  951. param->reg_IOZ = 0x00000023;
  952. param->reg_DQIDLY = 0x00000078;
  953. param->reg_FREQ = 0x000058C0;
  954. param->madj_max = 132;
  955. param->dll2_finetune_step = 3;
  956. break;
  957. case 624:
  958. ast_moutdwm(ast, 0x1E6E2020, 0x0160);
  959. param->reg_MADJ = 0x00136868;
  960. param->reg_SADJ = 0x00004534;
  961. param->wodt = 1;
  962. param->rodt = 1;
  963. param->reg_AC1 = 0x32302A37;
  964. param->reg_AC2 = 0xEF56B621;
  965. param->reg_DQSIC = 0x0000015A;
  966. param->reg_MRS = 0x02101A50;
  967. param->reg_EMRS = 0x00000004;
  968. param->reg_DRV = 0x000000F5;
  969. param->reg_IOZ = 0x00000034;
  970. param->reg_DQIDLY = 0x00000078;
  971. param->reg_FREQ = 0x000059C0;
  972. param->madj_max = 128;
  973. param->dll2_finetune_step = 3;
  974. break;
  975. } /* switch freq */
  976. switch (param->dram_chipid) {
  977. case AST_DRAM_512Mx16:
  978. param->dram_config = 0x130;
  979. break;
  980. default:
  981. case AST_DRAM_1Gx16:
  982. param->dram_config = 0x131;
  983. break;
  984. case AST_DRAM_2Gx16:
  985. param->dram_config = 0x132;
  986. break;
  987. case AST_DRAM_4Gx16:
  988. param->dram_config = 0x133;
  989. break;
  990. } /* switch size */
  991. switch (param->vram_size) {
  992. default:
  993. case AST_VIDMEM_SIZE_8M:
  994. param->dram_config |= 0x00;
  995. break;
  996. case AST_VIDMEM_SIZE_16M:
  997. param->dram_config |= 0x04;
  998. break;
  999. case AST_VIDMEM_SIZE_32M:
  1000. param->dram_config |= 0x08;
  1001. break;
  1002. case AST_VIDMEM_SIZE_64M:
  1003. param->dram_config |= 0x0c;
  1004. break;
  1005. }
  1006. }
  1007. static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
  1008. {
  1009. u32 data, data2, retry = 0;
  1010. ddr3_init_start:
  1011. ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
  1012. ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
  1013. ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
  1014. ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
  1015. udelay(10);
  1016. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
  1017. ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
  1018. udelay(10);
  1019. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
  1020. udelay(10);
  1021. ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
  1022. ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
  1023. ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
  1024. ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
  1025. ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
  1026. ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
  1027. ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
  1028. ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
  1029. ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
  1030. ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
  1031. ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
  1032. ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
  1033. ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
  1034. ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
  1035. ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
  1036. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1037. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1038. ast_moutdwm(ast, 0x1E6E0054, 0);
  1039. ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
  1040. ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
  1041. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1042. ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
  1043. ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
  1044. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1045. /* Wait MCLK2X lock to MCLK */
  1046. do {
  1047. data = ast_mindwm(ast, 0x1E6E001C);
  1048. } while (!(data & 0x08000000));
  1049. data = ast_mindwm(ast, 0x1E6E001C);
  1050. data = (data >> 8) & 0xff;
  1051. while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
  1052. data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
  1053. if ((data2 & 0xff) > param->madj_max) {
  1054. break;
  1055. }
  1056. ast_moutdwm(ast, 0x1E6E0064, data2);
  1057. if (data2 & 0x00100000) {
  1058. data2 = ((data2 & 0xff) >> 3) + 3;
  1059. } else {
  1060. data2 = ((data2 & 0xff) >> 2) + 5;
  1061. }
  1062. data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
  1063. data2 += data & 0xff;
  1064. data = data | (data2 << 8);
  1065. ast_moutdwm(ast, 0x1E6E0068, data);
  1066. udelay(10);
  1067. ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
  1068. udelay(10);
  1069. data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
  1070. ast_moutdwm(ast, 0x1E6E0018, data);
  1071. data = data | 0x200;
  1072. ast_moutdwm(ast, 0x1E6E0018, data);
  1073. do {
  1074. data = ast_mindwm(ast, 0x1E6E001C);
  1075. } while (!(data & 0x08000000));
  1076. data = ast_mindwm(ast, 0x1E6E001C);
  1077. data = (data >> 8) & 0xff;
  1078. }
  1079. ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
  1080. data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
  1081. ast_moutdwm(ast, 0x1E6E0018, data);
  1082. ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
  1083. ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
  1084. udelay(50);
  1085. /* Mode Register Setting */
  1086. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
  1087. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
  1088. ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
  1089. ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
  1090. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1091. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1092. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
  1093. ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
  1094. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1095. ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
  1096. data = 0;
  1097. if (param->wodt) {
  1098. data = 0x300;
  1099. }
  1100. if (param->rodt) {
  1101. data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
  1102. }
  1103. ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
  1104. /* Calibrate the DQSI delay */
  1105. if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
  1106. goto ddr3_init_start;
  1107. ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
  1108. /* ECC Memory Initialization */
  1109. #ifdef ECC
  1110. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1111. ast_moutdwm(ast, 0x1E6E0070, 0x221);
  1112. do {
  1113. data = ast_mindwm(ast, 0x1E6E0070);
  1114. } while (!(data & 0x00001000));
  1115. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1116. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1117. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1118. #endif
  1119. }
  1120. static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
  1121. {
  1122. u32 trap, trap_AC2, trap_MRS;
  1123. ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
  1124. /* Ger trap info */
  1125. trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
  1126. trap_AC2 = (trap << 20) | (trap << 16);
  1127. trap_AC2 += 0x00110000;
  1128. trap_MRS = 0x00000040 | (trap << 4);
  1129. param->reg_MADJ = 0x00034C4C;
  1130. param->reg_SADJ = 0x00001800;
  1131. param->reg_DRV = 0x000000F0;
  1132. param->reg_PERIOD = param->dram_freq;
  1133. param->rodt = 0;
  1134. switch (param->dram_freq) {
  1135. case 264:
  1136. ast_moutdwm(ast, 0x1E6E2020, 0x0130);
  1137. param->wodt = 0;
  1138. param->reg_AC1 = 0x11101513;
  1139. param->reg_AC2 = 0x78117011;
  1140. param->reg_DQSIC = 0x00000092;
  1141. param->reg_MRS = 0x00000842;
  1142. param->reg_EMRS = 0x00000000;
  1143. param->reg_DRV = 0x000000F0;
  1144. param->reg_IOZ = 0x00000034;
  1145. param->reg_DQIDLY = 0x0000005A;
  1146. param->reg_FREQ = 0x00004AC0;
  1147. param->madj_max = 138;
  1148. param->dll2_finetune_step = 3;
  1149. break;
  1150. case 336:
  1151. ast_moutdwm(ast, 0x1E6E2020, 0x0190);
  1152. param->wodt = 1;
  1153. param->reg_AC1 = 0x22202613;
  1154. param->reg_AC2 = 0xAA009016 | trap_AC2;
  1155. param->reg_DQSIC = 0x000000BA;
  1156. param->reg_MRS = 0x00000A02 | trap_MRS;
  1157. param->reg_EMRS = 0x00000040;
  1158. param->reg_DRV = 0x000000FA;
  1159. param->reg_IOZ = 0x00000034;
  1160. param->reg_DQIDLY = 0x00000074;
  1161. param->reg_FREQ = 0x00004DC0;
  1162. param->madj_max = 96;
  1163. param->dll2_finetune_step = 3;
  1164. switch (param->dram_chipid) {
  1165. default:
  1166. case AST_DRAM_512Mx16:
  1167. param->reg_AC2 = 0xAA009012 | trap_AC2;
  1168. break;
  1169. case AST_DRAM_1Gx16:
  1170. param->reg_AC2 = 0xAA009016 | trap_AC2;
  1171. break;
  1172. case AST_DRAM_2Gx16:
  1173. param->reg_AC2 = 0xAA009023 | trap_AC2;
  1174. break;
  1175. case AST_DRAM_4Gx16:
  1176. param->reg_AC2 = 0xAA00903B | trap_AC2;
  1177. break;
  1178. }
  1179. break;
  1180. default:
  1181. case 396:
  1182. ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
  1183. param->wodt = 1;
  1184. param->rodt = 0;
  1185. param->reg_AC1 = 0x33302714;
  1186. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1187. param->reg_DQSIC = 0x000000E2;
  1188. param->reg_MRS = 0x00000C02 | trap_MRS;
  1189. param->reg_EMRS = 0x00000040;
  1190. param->reg_DRV = 0x000000FA;
  1191. param->reg_IOZ = 0x00000034;
  1192. param->reg_DQIDLY = 0x00000089;
  1193. param->reg_FREQ = 0x00005040;
  1194. param->madj_max = 96;
  1195. param->dll2_finetune_step = 4;
  1196. switch (param->dram_chipid) {
  1197. case AST_DRAM_512Mx16:
  1198. param->reg_AC2 = 0xCC00B016 | trap_AC2;
  1199. break;
  1200. default:
  1201. case AST_DRAM_1Gx16:
  1202. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1203. break;
  1204. case AST_DRAM_2Gx16:
  1205. param->reg_AC2 = 0xCC00B02B | trap_AC2;
  1206. break;
  1207. case AST_DRAM_4Gx16:
  1208. param->reg_AC2 = 0xCC00B03F | trap_AC2;
  1209. break;
  1210. }
  1211. break;
  1212. case 408:
  1213. ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
  1214. param->wodt = 1;
  1215. param->rodt = 0;
  1216. param->reg_AC1 = 0x33302714;
  1217. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1218. param->reg_DQSIC = 0x000000E2;
  1219. param->reg_MRS = 0x00000C02 | trap_MRS;
  1220. param->reg_EMRS = 0x00000040;
  1221. param->reg_DRV = 0x000000FA;
  1222. param->reg_IOZ = 0x00000034;
  1223. param->reg_DQIDLY = 0x00000089;
  1224. param->reg_FREQ = 0x000050C0;
  1225. param->madj_max = 96;
  1226. param->dll2_finetune_step = 4;
  1227. switch (param->dram_chipid) {
  1228. case AST_DRAM_512Mx16:
  1229. param->reg_AC2 = 0xCC00B016 | trap_AC2;
  1230. break;
  1231. default:
  1232. case AST_DRAM_1Gx16:
  1233. param->reg_AC2 = 0xCC00B01B | trap_AC2;
  1234. break;
  1235. case AST_DRAM_2Gx16:
  1236. param->reg_AC2 = 0xCC00B02B | trap_AC2;
  1237. break;
  1238. case AST_DRAM_4Gx16:
  1239. param->reg_AC2 = 0xCC00B03F | trap_AC2;
  1240. break;
  1241. }
  1242. break;
  1243. case 456:
  1244. ast_moutdwm(ast, 0x1E6E2020, 0x0230);
  1245. param->wodt = 0;
  1246. param->reg_AC1 = 0x33302815;
  1247. param->reg_AC2 = 0xCD44B01E;
  1248. param->reg_DQSIC = 0x000000FC;
  1249. param->reg_MRS = 0x00000E72;
  1250. param->reg_EMRS = 0x00000000;
  1251. param->reg_DRV = 0x00000000;
  1252. param->reg_IOZ = 0x00000034;
  1253. param->reg_DQIDLY = 0x00000097;
  1254. param->reg_FREQ = 0x000052C0;
  1255. param->madj_max = 88;
  1256. param->dll2_finetune_step = 3;
  1257. break;
  1258. case 504:
  1259. ast_moutdwm(ast, 0x1E6E2020, 0x0261);
  1260. param->wodt = 1;
  1261. param->rodt = 1;
  1262. param->reg_AC1 = 0x33302815;
  1263. param->reg_AC2 = 0xDE44C022;
  1264. param->reg_DQSIC = 0x00000117;
  1265. param->reg_MRS = 0x00000E72;
  1266. param->reg_EMRS = 0x00000040;
  1267. param->reg_DRV = 0x0000000A;
  1268. param->reg_IOZ = 0x00000045;
  1269. param->reg_DQIDLY = 0x000000A0;
  1270. param->reg_FREQ = 0x000054C0;
  1271. param->madj_max = 79;
  1272. param->dll2_finetune_step = 3;
  1273. break;
  1274. case 528:
  1275. ast_moutdwm(ast, 0x1E6E2020, 0x0120);
  1276. param->wodt = 1;
  1277. param->rodt = 1;
  1278. param->reg_AC1 = 0x33302815;
  1279. param->reg_AC2 = 0xEF44D024;
  1280. param->reg_DQSIC = 0x00000125;
  1281. param->reg_MRS = 0x00000E72;
  1282. param->reg_EMRS = 0x00000004;
  1283. param->reg_DRV = 0x000000F9;
  1284. param->reg_IOZ = 0x00000045;
  1285. param->reg_DQIDLY = 0x000000A7;
  1286. param->reg_FREQ = 0x000055C0;
  1287. param->madj_max = 76;
  1288. param->dll2_finetune_step = 3;
  1289. break;
  1290. case 552:
  1291. ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
  1292. param->wodt = 1;
  1293. param->rodt = 1;
  1294. param->reg_AC1 = 0x43402915;
  1295. param->reg_AC2 = 0xFF44E025;
  1296. param->reg_DQSIC = 0x00000132;
  1297. param->reg_MRS = 0x00000E72;
  1298. param->reg_EMRS = 0x00000040;
  1299. param->reg_DRV = 0x0000000A;
  1300. param->reg_IOZ = 0x00000045;
  1301. param->reg_DQIDLY = 0x000000AD;
  1302. param->reg_FREQ = 0x000056C0;
  1303. param->madj_max = 76;
  1304. param->dll2_finetune_step = 3;
  1305. break;
  1306. case 576:
  1307. ast_moutdwm(ast, 0x1E6E2020, 0x0140);
  1308. param->wodt = 1;
  1309. param->rodt = 1;
  1310. param->reg_AC1 = 0x43402915;
  1311. param->reg_AC2 = 0xFF44E027;
  1312. param->reg_DQSIC = 0x0000013F;
  1313. param->reg_MRS = 0x00000E72;
  1314. param->reg_EMRS = 0x00000004;
  1315. param->reg_DRV = 0x000000F5;
  1316. param->reg_IOZ = 0x00000045;
  1317. param->reg_DQIDLY = 0x000000B3;
  1318. param->reg_FREQ = 0x000057C0;
  1319. param->madj_max = 76;
  1320. param->dll2_finetune_step = 3;
  1321. break;
  1322. }
  1323. switch (param->dram_chipid) {
  1324. case AST_DRAM_512Mx16:
  1325. param->dram_config = 0x100;
  1326. break;
  1327. default:
  1328. case AST_DRAM_1Gx16:
  1329. param->dram_config = 0x121;
  1330. break;
  1331. case AST_DRAM_2Gx16:
  1332. param->dram_config = 0x122;
  1333. break;
  1334. case AST_DRAM_4Gx16:
  1335. param->dram_config = 0x123;
  1336. break;
  1337. } /* switch size */
  1338. switch (param->vram_size) {
  1339. default:
  1340. case AST_VIDMEM_SIZE_8M:
  1341. param->dram_config |= 0x00;
  1342. break;
  1343. case AST_VIDMEM_SIZE_16M:
  1344. param->dram_config |= 0x04;
  1345. break;
  1346. case AST_VIDMEM_SIZE_32M:
  1347. param->dram_config |= 0x08;
  1348. break;
  1349. case AST_VIDMEM_SIZE_64M:
  1350. param->dram_config |= 0x0c;
  1351. break;
  1352. }
  1353. }
  1354. static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
  1355. {
  1356. u32 data, data2, retry = 0;
  1357. ddr2_init_start:
  1358. ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
  1359. ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
  1360. ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
  1361. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
  1362. ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
  1363. udelay(10);
  1364. ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
  1365. udelay(10);
  1366. ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
  1367. ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
  1368. ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
  1369. ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
  1370. ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
  1371. ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
  1372. ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
  1373. ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
  1374. ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
  1375. ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
  1376. ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
  1377. ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
  1378. ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
  1379. ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
  1380. ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
  1381. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1382. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1383. ast_moutdwm(ast, 0x1E6E0054, 0);
  1384. ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
  1385. ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
  1386. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1387. ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
  1388. ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
  1389. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1390. /* Wait MCLK2X lock to MCLK */
  1391. do {
  1392. data = ast_mindwm(ast, 0x1E6E001C);
  1393. } while (!(data & 0x08000000));
  1394. data = ast_mindwm(ast, 0x1E6E001C);
  1395. data = (data >> 8) & 0xff;
  1396. while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
  1397. data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
  1398. if ((data2 & 0xff) > param->madj_max) {
  1399. break;
  1400. }
  1401. ast_moutdwm(ast, 0x1E6E0064, data2);
  1402. if (data2 & 0x00100000) {
  1403. data2 = ((data2 & 0xff) >> 3) + 3;
  1404. } else {
  1405. data2 = ((data2 & 0xff) >> 2) + 5;
  1406. }
  1407. data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
  1408. data2 += data & 0xff;
  1409. data = data | (data2 << 8);
  1410. ast_moutdwm(ast, 0x1E6E0068, data);
  1411. udelay(10);
  1412. ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
  1413. udelay(10);
  1414. data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
  1415. ast_moutdwm(ast, 0x1E6E0018, data);
  1416. data = data | 0x200;
  1417. ast_moutdwm(ast, 0x1E6E0018, data);
  1418. do {
  1419. data = ast_mindwm(ast, 0x1E6E001C);
  1420. } while (!(data & 0x08000000));
  1421. data = ast_mindwm(ast, 0x1E6E001C);
  1422. data = (data >> 8) & 0xff;
  1423. }
  1424. ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
  1425. data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
  1426. ast_moutdwm(ast, 0x1E6E0018, data);
  1427. ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
  1428. ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
  1429. udelay(50);
  1430. /* Mode Register Setting */
  1431. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
  1432. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
  1433. ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
  1434. ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
  1435. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1436. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1437. ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
  1438. ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
  1439. ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
  1440. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
  1441. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1442. ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
  1443. ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
  1444. ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
  1445. data = 0;
  1446. if (param->wodt) {
  1447. data = 0x500;
  1448. }
  1449. if (param->rodt) {
  1450. data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
  1451. }
  1452. ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
  1453. ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
  1454. /* Calibrate the DQSI delay */
  1455. if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
  1456. goto ddr2_init_start;
  1457. /* ECC Memory Initialization */
  1458. #ifdef ECC
  1459. ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
  1460. ast_moutdwm(ast, 0x1E6E0070, 0x221);
  1461. do {
  1462. data = ast_mindwm(ast, 0x1E6E0070);
  1463. } while (!(data & 0x00001000));
  1464. ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
  1465. ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
  1466. ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
  1467. #endif
  1468. }
  1469. static void ast_init_dram_2300(struct drm_device *dev)
  1470. {
  1471. struct ast_private *ast = dev->dev_private;
  1472. struct ast2300_dram_param param;
  1473. u32 temp;
  1474. u8 reg;
  1475. reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
  1476. if ((reg & 0x80) == 0) {/* vga only */
  1477. ast_write32(ast, 0xf004, 0x1e6e0000);
  1478. ast_write32(ast, 0xf000, 0x1);
  1479. ast_write32(ast, 0x12000, 0x1688a8a8);
  1480. do {
  1481. ;
  1482. } while (ast_read32(ast, 0x12000) != 0x1);
  1483. ast_write32(ast, 0x10000, 0xfc600309);
  1484. do {
  1485. ;
  1486. } while (ast_read32(ast, 0x10000) != 0x1);
  1487. /* Slow down CPU/AHB CLK in VGA only mode */
  1488. temp = ast_read32(ast, 0x12008);
  1489. temp |= 0x73;
  1490. ast_write32(ast, 0x12008, temp);
  1491. param.dram_type = AST_DDR3;
  1492. if (temp & 0x01000000)
  1493. param.dram_type = AST_DDR2;
  1494. param.dram_chipid = ast->dram_type;
  1495. param.dram_freq = ast->mclk;
  1496. param.vram_size = ast->vram_size;
  1497. if (param.dram_type == AST_DDR3) {
  1498. get_ddr3_info(ast, &param);
  1499. ddr3_init(ast, &param);
  1500. } else {
  1501. get_ddr2_info(ast, &param);
  1502. ddr2_init(ast, &param);
  1503. }
  1504. temp = ast_mindwm(ast, 0x1e6e2040);
  1505. ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
  1506. }
  1507. /* wait ready */
  1508. do {
  1509. reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
  1510. } while ((reg & 0x40) == 0);
  1511. }