smc.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615
  1. // SPDX-License-Identifier: Intel
  2. /*
  3. * Copyright (C) 2013, Intel Corporation
  4. * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
  5. *
  6. * Ported from Intel released Quark UEFI BIOS
  7. * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei
  8. */
  9. #include <common.h>
  10. #include <pci.h>
  11. #include <asm/arch/device.h>
  12. #include <asm/arch/mrc.h>
  13. #include <asm/arch/msg_port.h>
  14. #include "mrc_util.h"
  15. #include "hte.h"
  16. #include "smc.h"
  17. /* t_ck clock period in picoseconds per speed index 800, 1066, 1333 */
  18. static const uint32_t t_ck[3] = {
  19. 2500,
  20. 1875,
  21. 1500
  22. };
  23. /* Global variables */
  24. static const uint16_t ddr_wclk[] = {193, 158};
  25. #ifdef BACKUP_WCTL
  26. static const uint16_t ddr_wctl[] = {1, 217};
  27. #endif
  28. #ifdef BACKUP_WCMD
  29. static const uint16_t ddr_wcmd[] = {1, 220};
  30. #endif
  31. #ifdef BACKUP_RCVN
  32. static const uint16_t ddr_rcvn[] = {129, 498};
  33. #endif
  34. #ifdef BACKUP_WDQS
  35. static const uint16_t ddr_wdqs[] = {65, 289};
  36. #endif
  37. #ifdef BACKUP_RDQS
  38. static const uint8_t ddr_rdqs[] = {32, 24};
  39. #endif
  40. #ifdef BACKUP_WDQ
  41. static const uint16_t ddr_wdq[] = {32, 257};
  42. #endif
  43. /* Stop self refresh driven by MCU */
  44. void clear_self_refresh(struct mrc_params *mrc_params)
  45. {
  46. ENTERFN();
  47. /* clear the PMSTS Channel Self Refresh bits */
  48. mrc_write_mask(MEM_CTLR, PMSTS, PMSTS_DISR, PMSTS_DISR);
  49. LEAVEFN();
  50. }
  51. /* It will initialize timing registers in the MCU (DTR0..DTR4) */
  52. void prog_ddr_timing_control(struct mrc_params *mrc_params)
  53. {
  54. uint8_t tcl, wl;
  55. uint8_t trp, trcd, tras, twr, twtr, trrd, trtp, tfaw;
  56. uint32_t tck;
  57. u32 dtr0, dtr1, dtr2, dtr3, dtr4;
  58. u32 tmp1, tmp2;
  59. ENTERFN();
  60. /* mcu_init starts */
  61. mrc_post_code(0x02, 0x00);
  62. dtr0 = msg_port_read(MEM_CTLR, DTR0);
  63. dtr1 = msg_port_read(MEM_CTLR, DTR1);
  64. dtr2 = msg_port_read(MEM_CTLR, DTR2);
  65. dtr3 = msg_port_read(MEM_CTLR, DTR3);
  66. dtr4 = msg_port_read(MEM_CTLR, DTR4);
  67. tck = t_ck[mrc_params->ddr_speed]; /* Clock in picoseconds */
  68. tcl = mrc_params->params.cl; /* CAS latency in clocks */
  69. trp = tcl; /* Per CAT MRC */
  70. trcd = tcl; /* Per CAT MRC */
  71. tras = MCEIL(mrc_params->params.ras, tck);
  72. /* Per JEDEC: tWR=15000ps DDR2/3 from 800-1600 */
  73. twr = MCEIL(15000, tck);
  74. twtr = MCEIL(mrc_params->params.wtr, tck);
  75. trrd = MCEIL(mrc_params->params.rrd, tck);
  76. trtp = 4; /* Valid for 800 and 1066, use 5 for 1333 */
  77. tfaw = MCEIL(mrc_params->params.faw, tck);
  78. wl = 5 + mrc_params->ddr_speed;
  79. dtr0 &= ~DTR0_DFREQ_MASK;
  80. dtr0 |= mrc_params->ddr_speed;
  81. dtr0 &= ~DTR0_TCL_MASK;
  82. tmp1 = tcl - 5;
  83. dtr0 |= ((tcl - 5) << 12);
  84. dtr0 &= ~DTR0_TRP_MASK;
  85. dtr0 |= ((trp - 5) << 4); /* 5 bit DRAM Clock */
  86. dtr0 &= ~DTR0_TRCD_MASK;
  87. dtr0 |= ((trcd - 5) << 8); /* 5 bit DRAM Clock */
  88. dtr1 &= ~DTR1_TWCL_MASK;
  89. tmp2 = wl - 3;
  90. dtr1 |= (wl - 3);
  91. dtr1 &= ~DTR1_TWTP_MASK;
  92. dtr1 |= ((wl + 4 + twr - 14) << 8); /* Change to tWTP */
  93. dtr1 &= ~DTR1_TRTP_MASK;
  94. dtr1 |= ((MMAX(trtp, 4) - 3) << 28); /* 4 bit DRAM Clock */
  95. dtr1 &= ~DTR1_TRRD_MASK;
  96. dtr1 |= ((trrd - 4) << 24); /* 4 bit DRAM Clock */
  97. dtr1 &= ~DTR1_TCMD_MASK;
  98. dtr1 |= (1 << 4);
  99. dtr1 &= ~DTR1_TRAS_MASK;
  100. dtr1 |= ((tras - 14) << 20); /* 6 bit DRAM Clock */
  101. dtr1 &= ~DTR1_TFAW_MASK;
  102. dtr1 |= ((((tfaw + 1) >> 1) - 5) << 16);/* 4 bit DRAM Clock */
  103. /* Set 4 Clock CAS to CAS delay (multi-burst) */
  104. dtr1 &= ~DTR1_TCCD_MASK;
  105. dtr2 &= ~DTR2_TRRDR_MASK;
  106. dtr2 |= 1;
  107. dtr2 &= ~DTR2_TWWDR_MASK;
  108. dtr2 |= (2 << 8);
  109. dtr2 &= ~DTR2_TRWDR_MASK;
  110. dtr2 |= (2 << 16);
  111. dtr3 &= ~DTR3_TWRDR_MASK;
  112. dtr3 |= 2;
  113. dtr3 &= ~DTR3_TXXXX_MASK;
  114. dtr3 |= (2 << 4);
  115. dtr3 &= ~DTR3_TRWSR_MASK;
  116. if (mrc_params->ddr_speed == DDRFREQ_800) {
  117. /* Extended RW delay (+1) */
  118. dtr3 |= ((tcl - 5 + 1) << 8);
  119. } else if (mrc_params->ddr_speed == DDRFREQ_1066) {
  120. /* Extended RW delay (+1) */
  121. dtr3 |= ((tcl - 5 + 1) << 8);
  122. }
  123. dtr3 &= ~DTR3_TWRSR_MASK;
  124. dtr3 |= ((4 + wl + twtr - 11) << 13);
  125. dtr3 &= ~DTR3_TXP_MASK;
  126. if (mrc_params->ddr_speed == DDRFREQ_800)
  127. dtr3 |= ((MMAX(0, 1 - 1)) << 22);
  128. else
  129. dtr3 |= ((MMAX(0, 2 - 1)) << 22);
  130. dtr4 &= ~DTR4_WRODTSTRT_MASK;
  131. dtr4 |= 1;
  132. dtr4 &= ~DTR4_WRODTSTOP_MASK;
  133. dtr4 |= (1 << 4);
  134. dtr4 &= ~DTR4_XXXX1_MASK;
  135. dtr4 |= ((1 + tmp1 - tmp2 + 2) << 8);
  136. dtr4 &= ~DTR4_XXXX2_MASK;
  137. dtr4 |= ((1 + tmp1 - tmp2 + 2) << 12);
  138. dtr4 &= ~(DTR4_ODTDIS | DTR4_TRGSTRDIS);
  139. msg_port_write(MEM_CTLR, DTR0, dtr0);
  140. msg_port_write(MEM_CTLR, DTR1, dtr1);
  141. msg_port_write(MEM_CTLR, DTR2, dtr2);
  142. msg_port_write(MEM_CTLR, DTR3, dtr3);
  143. msg_port_write(MEM_CTLR, DTR4, dtr4);
  144. LEAVEFN();
  145. }
  146. /* Configure MCU before jedec init sequence */
  147. void prog_decode_before_jedec(struct mrc_params *mrc_params)
  148. {
  149. u32 drp;
  150. u32 drfc;
  151. u32 dcal;
  152. u32 dsch;
  153. u32 dpmc0;
  154. ENTERFN();
  155. /* Disable power saving features */
  156. dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
  157. dpmc0 |= (DPMC0_CLKGTDIS | DPMC0_DISPWRDN);
  158. dpmc0 &= ~DPMC0_PCLSTO_MASK;
  159. dpmc0 &= ~DPMC0_DYNSREN;
  160. msg_port_write(MEM_CTLR, DPMC0, dpmc0);
  161. /* Disable out of order transactions */
  162. dsch = msg_port_read(MEM_CTLR, DSCH);
  163. dsch |= (DSCH_OOODIS | DSCH_NEWBYPDIS);
  164. msg_port_write(MEM_CTLR, DSCH, dsch);
  165. /* Disable issuing the REF command */
  166. drfc = msg_port_read(MEM_CTLR, DRFC);
  167. drfc &= ~DRFC_TREFI_MASK;
  168. msg_port_write(MEM_CTLR, DRFC, drfc);
  169. /* Disable ZQ calibration short */
  170. dcal = msg_port_read(MEM_CTLR, DCAL);
  171. dcal &= ~DCAL_ZQCINT_MASK;
  172. dcal &= ~DCAL_SRXZQCL_MASK;
  173. msg_port_write(MEM_CTLR, DCAL, dcal);
  174. /*
  175. * Training performed in address mode 0, rank population has limited
  176. * impact, however simulator complains if enabled non-existing rank.
  177. */
  178. drp = 0;
  179. if (mrc_params->rank_enables & 1)
  180. drp |= DRP_RKEN0;
  181. if (mrc_params->rank_enables & 2)
  182. drp |= DRP_RKEN1;
  183. msg_port_write(MEM_CTLR, DRP, drp);
  184. LEAVEFN();
  185. }
  186. /*
  187. * After Cold Reset, BIOS should set COLDWAKE bit to 1 before
  188. * sending the WAKE message to the Dunit.
  189. *
  190. * For Standby Exit, or any other mode in which the DRAM is in
  191. * SR, this bit must be set to 0.
  192. */
  193. void perform_ddr_reset(struct mrc_params *mrc_params)
  194. {
  195. ENTERFN();
  196. /* Set COLDWAKE bit before sending the WAKE message */
  197. mrc_write_mask(MEM_CTLR, DRMC, DRMC_COLDWAKE, DRMC_COLDWAKE);
  198. /* Send wake command to DUNIT (MUST be done before JEDEC) */
  199. dram_wake_command();
  200. /* Set default value */
  201. msg_port_write(MEM_CTLR, DRMC,
  202. mrc_params->rd_odt_value == 0 ? DRMC_ODTMODE : 0);
  203. LEAVEFN();
  204. }
  205. /*
  206. * This function performs some initialization on the DDRIO unit.
  207. * This function is dependent on BOARD_ID, DDR_SPEED, and CHANNEL_ENABLES.
  208. */
  209. void ddrphy_init(struct mrc_params *mrc_params)
  210. {
  211. uint32_t temp;
  212. uint8_t ch; /* channel counter */
  213. uint8_t rk; /* rank counter */
  214. uint8_t bl_grp; /* byte lane group counter (2 BLs per module) */
  215. uint8_t bl_divisor = 1; /* byte lane divisor */
  216. /* For DDR3 --> 0 == 800, 1 == 1066, 2 == 1333 */
  217. uint8_t speed = mrc_params->ddr_speed & 3;
  218. uint8_t cas;
  219. uint8_t cwl;
  220. ENTERFN();
  221. cas = mrc_params->params.cl;
  222. cwl = 5 + mrc_params->ddr_speed;
  223. /* ddrphy_init starts */
  224. mrc_post_code(0x03, 0x00);
  225. /*
  226. * HSD#231531
  227. * Make sure IOBUFACT is deasserted before initializing the DDR PHY
  228. *
  229. * HSD#234845
  230. * Make sure WRPTRENABLE is deasserted before initializing the DDR PHY
  231. */
  232. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  233. if (mrc_params->channel_enables & (1 << ch)) {
  234. /* Deassert DDRPHY Initialization Complete */
  235. mrc_alt_write_mask(DDRPHY,
  236. CMDPMCONFIG0 + ch * DDRIOCCC_CH_OFFSET,
  237. ~(1 << 20), 1 << 20); /* SPID_INIT_COMPLETE=0 */
  238. /* Deassert IOBUFACT */
  239. mrc_alt_write_mask(DDRPHY,
  240. CMDCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
  241. ~(1 << 2), 1 << 2); /* IOBUFACTRST_N=0 */
  242. /* Disable WRPTR */
  243. mrc_alt_write_mask(DDRPHY,
  244. CMDPTRREG + ch * DDRIOCCC_CH_OFFSET,
  245. ~(1 << 0), 1 << 0); /* WRPTRENABLE=0 */
  246. }
  247. }
  248. /* Put PHY in reset */
  249. mrc_alt_write_mask(DDRPHY, MASTERRSTN, 0, 1);
  250. /* Initialize DQ01, DQ23, CMD, CLK-CTL, COMP modules */
  251. /* STEP0 */
  252. mrc_post_code(0x03, 0x10);
  253. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  254. if (mrc_params->channel_enables & (1 << ch)) {
  255. /* DQ01-DQ23 */
  256. for (bl_grp = 0;
  257. bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
  258. bl_grp++) {
  259. /* Analog MUX select - IO2xCLKSEL */
  260. mrc_alt_write_mask(DDRPHY,
  261. DQOBSCKEBBCTL +
  262. bl_grp * DDRIODQ_BL_OFFSET +
  263. ch * DDRIODQ_CH_OFFSET,
  264. bl_grp ? 0 : (1 << 22), 1 << 22);
  265. /* ODT Strength */
  266. switch (mrc_params->rd_odt_value) {
  267. case 1:
  268. temp = 0x3;
  269. break; /* 60 ohm */
  270. case 2:
  271. temp = 0x3;
  272. break; /* 120 ohm */
  273. case 3:
  274. temp = 0x3;
  275. break; /* 180 ohm */
  276. default:
  277. temp = 0x3;
  278. break; /* 120 ohm */
  279. }
  280. /* ODT strength */
  281. mrc_alt_write_mask(DDRPHY,
  282. B0RXIOBUFCTL +
  283. bl_grp * DDRIODQ_BL_OFFSET +
  284. ch * DDRIODQ_CH_OFFSET,
  285. temp << 5, 0x60);
  286. /* ODT strength */
  287. mrc_alt_write_mask(DDRPHY,
  288. B1RXIOBUFCTL +
  289. bl_grp * DDRIODQ_BL_OFFSET +
  290. ch * DDRIODQ_CH_OFFSET,
  291. temp << 5, 0x60);
  292. /* Dynamic ODT/DIFFAMP */
  293. temp = (cas << 24) | (cas << 16) |
  294. (cas << 8) | (cas << 0);
  295. switch (speed) {
  296. case 0:
  297. temp -= 0x01010101;
  298. break; /* 800 */
  299. case 1:
  300. temp -= 0x02020202;
  301. break; /* 1066 */
  302. case 2:
  303. temp -= 0x03030303;
  304. break; /* 1333 */
  305. case 3:
  306. temp -= 0x04040404;
  307. break; /* 1600 */
  308. }
  309. /* Launch Time: ODT, DIFFAMP, ODT, DIFFAMP */
  310. mrc_alt_write_mask(DDRPHY,
  311. B01LATCTL1 +
  312. bl_grp * DDRIODQ_BL_OFFSET +
  313. ch * DDRIODQ_CH_OFFSET,
  314. temp, 0x1f1f1f1f);
  315. switch (speed) {
  316. /* HSD#234715 */
  317. case 0:
  318. temp = (0x06 << 16) | (0x07 << 8);
  319. break; /* 800 */
  320. case 1:
  321. temp = (0x07 << 16) | (0x08 << 8);
  322. break; /* 1066 */
  323. case 2:
  324. temp = (0x09 << 16) | (0x0a << 8);
  325. break; /* 1333 */
  326. case 3:
  327. temp = (0x0a << 16) | (0x0b << 8);
  328. break; /* 1600 */
  329. }
  330. /* On Duration: ODT, DIFFAMP */
  331. mrc_alt_write_mask(DDRPHY,
  332. B0ONDURCTL +
  333. bl_grp * DDRIODQ_BL_OFFSET +
  334. ch * DDRIODQ_CH_OFFSET,
  335. temp, 0x003f3f00);
  336. /* On Duration: ODT, DIFFAMP */
  337. mrc_alt_write_mask(DDRPHY,
  338. B1ONDURCTL +
  339. bl_grp * DDRIODQ_BL_OFFSET +
  340. ch * DDRIODQ_CH_OFFSET,
  341. temp, 0x003f3f00);
  342. switch (mrc_params->rd_odt_value) {
  343. case 0:
  344. /* override DIFFAMP=on, ODT=off */
  345. temp = (0x3f << 16) | (0x3f << 10);
  346. break;
  347. default:
  348. /* override DIFFAMP=on, ODT=on */
  349. temp = (0x3f << 16) | (0x2a << 10);
  350. break;
  351. }
  352. /* Override: DIFFAMP, ODT */
  353. mrc_alt_write_mask(DDRPHY,
  354. B0OVRCTL +
  355. bl_grp * DDRIODQ_BL_OFFSET +
  356. ch * DDRIODQ_CH_OFFSET,
  357. temp, 0x003ffc00);
  358. /* Override: DIFFAMP, ODT */
  359. mrc_alt_write_mask(DDRPHY,
  360. B1OVRCTL +
  361. bl_grp * DDRIODQ_BL_OFFSET +
  362. ch * DDRIODQ_CH_OFFSET,
  363. temp, 0x003ffc00);
  364. /* DLL Setup */
  365. /* 1xCLK Domain Timings: tEDP,RCVEN,WDQS (PO) */
  366. mrc_alt_write_mask(DDRPHY,
  367. B0LATCTL0 +
  368. bl_grp * DDRIODQ_BL_OFFSET +
  369. ch * DDRIODQ_CH_OFFSET,
  370. ((cas + 7) << 16) | ((cas - 4) << 8) |
  371. ((cwl - 2) << 0), 0x003f1f1f);
  372. mrc_alt_write_mask(DDRPHY,
  373. B1LATCTL0 +
  374. bl_grp * DDRIODQ_BL_OFFSET +
  375. ch * DDRIODQ_CH_OFFSET,
  376. ((cas + 7) << 16) | ((cas - 4) << 8) |
  377. ((cwl - 2) << 0), 0x003f1f1f);
  378. /* RCVEN Bypass (PO) */
  379. mrc_alt_write_mask(DDRPHY,
  380. B0RXIOBUFCTL +
  381. bl_grp * DDRIODQ_BL_OFFSET +
  382. ch * DDRIODQ_CH_OFFSET,
  383. 0, 0x81);
  384. mrc_alt_write_mask(DDRPHY,
  385. B1RXIOBUFCTL +
  386. bl_grp * DDRIODQ_BL_OFFSET +
  387. ch * DDRIODQ_CH_OFFSET,
  388. 0, 0x81);
  389. /* TX */
  390. mrc_alt_write_mask(DDRPHY,
  391. DQCTL +
  392. bl_grp * DDRIODQ_BL_OFFSET +
  393. ch * DDRIODQ_CH_OFFSET,
  394. 1 << 16, 1 << 16);
  395. mrc_alt_write_mask(DDRPHY,
  396. B01PTRCTL1 +
  397. bl_grp * DDRIODQ_BL_OFFSET +
  398. ch * DDRIODQ_CH_OFFSET,
  399. 1 << 8, 1 << 8);
  400. /* RX (PO) */
  401. /* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */
  402. mrc_alt_write_mask(DDRPHY,
  403. B0VREFCTL +
  404. bl_grp * DDRIODQ_BL_OFFSET +
  405. ch * DDRIODQ_CH_OFFSET,
  406. (0x03 << 2) | (0x0 << 1) | (0x0 << 0),
  407. 0xff);
  408. /* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */
  409. mrc_alt_write_mask(DDRPHY,
  410. B1VREFCTL +
  411. bl_grp * DDRIODQ_BL_OFFSET +
  412. ch * DDRIODQ_CH_OFFSET,
  413. (0x03 << 2) | (0x0 << 1) | (0x0 << 0),
  414. 0xff);
  415. /* Per-Bit De-Skew Enable */
  416. mrc_alt_write_mask(DDRPHY,
  417. B0RXIOBUFCTL +
  418. bl_grp * DDRIODQ_BL_OFFSET +
  419. ch * DDRIODQ_CH_OFFSET,
  420. 0, 0x10);
  421. /* Per-Bit De-Skew Enable */
  422. mrc_alt_write_mask(DDRPHY,
  423. B1RXIOBUFCTL +
  424. bl_grp * DDRIODQ_BL_OFFSET +
  425. ch * DDRIODQ_CH_OFFSET,
  426. 0, 0x10);
  427. }
  428. /* CLKEBB */
  429. mrc_alt_write_mask(DDRPHY,
  430. CMDOBSCKEBBCTL + ch * DDRIOCCC_CH_OFFSET,
  431. 0, 1 << 23);
  432. /* Enable tristate control of cmd/address bus */
  433. mrc_alt_write_mask(DDRPHY,
  434. CMDCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
  435. 0, 0x03);
  436. /* ODT RCOMP */
  437. mrc_alt_write_mask(DDRPHY,
  438. CMDRCOMPODT + ch * DDRIOCCC_CH_OFFSET,
  439. (0x03 << 5) | (0x03 << 0), 0x3ff);
  440. /* CMDPM* registers must be programmed in this order */
  441. /* Turn On Delays: SFR (regulator), MPLL */
  442. mrc_alt_write_mask(DDRPHY,
  443. CMDPMDLYREG4 + ch * DDRIOCCC_CH_OFFSET,
  444. 0xffffffff, 0xffffffff);
  445. /*
  446. * Delays: ASSERT_IOBUFACT_to_ALLON0_for_PM_MSG_3,
  447. * VREG (MDLL) Turn On, ALLON0_to_DEASSERT_IOBUFACT
  448. * for_PM_MSG_gt0, MDLL Turn On
  449. */
  450. mrc_alt_write_mask(DDRPHY,
  451. CMDPMDLYREG3 + ch * DDRIOCCC_CH_OFFSET,
  452. 0xfffff616, 0xffffffff);
  453. /* MPLL Divider Reset Delays */
  454. mrc_alt_write_mask(DDRPHY,
  455. CMDPMDLYREG2 + ch * DDRIOCCC_CH_OFFSET,
  456. 0xffffffff, 0xffffffff);
  457. /* Turn Off Delays: VREG, Staggered MDLL, MDLL, PI */
  458. mrc_alt_write_mask(DDRPHY,
  459. CMDPMDLYREG1 + ch * DDRIOCCC_CH_OFFSET,
  460. 0xffffffff, 0xffffffff);
  461. /* Turn On Delays: MPLL, Staggered MDLL, PI, IOBUFACT */
  462. mrc_alt_write_mask(DDRPHY,
  463. CMDPMDLYREG0 + ch * DDRIOCCC_CH_OFFSET,
  464. 0xffffffff, 0xffffffff);
  465. /* Allow PUnit signals */
  466. mrc_alt_write_mask(DDRPHY,
  467. CMDPMCONFIG0 + ch * DDRIOCCC_CH_OFFSET,
  468. (0x6 << 8) | (0x1 << 6) | (0x4 << 0),
  469. 0xffe00f4f);
  470. /* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */
  471. mrc_alt_write_mask(DDRPHY,
  472. CMDMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
  473. (0x3 << 4) | (0x7 << 0), 0x7f);
  474. /* CLK-CTL */
  475. mrc_alt_write_mask(DDRPHY,
  476. CCOBSCKEBBCTL + ch * DDRIOCCC_CH_OFFSET,
  477. 0, 1 << 24); /* CLKEBB */
  478. /* Buffer Enable: CS,CKE,ODT,CLK */
  479. mrc_alt_write_mask(DDRPHY,
  480. CCCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
  481. 0x1f, 0x000ffff1);
  482. /* ODT RCOMP */
  483. mrc_alt_write_mask(DDRPHY,
  484. CCRCOMPODT + ch * DDRIOCCC_CH_OFFSET,
  485. (0x03 << 8) | (0x03 << 0), 0x00001f1f);
  486. /* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */
  487. mrc_alt_write_mask(DDRPHY,
  488. CCMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
  489. (0x3 << 4) | (0x7 << 0), 0x7f);
  490. /*
  491. * COMP (RON channel specific)
  492. * - DQ/DQS/DM RON: 32 Ohm
  493. * - CTRL/CMD RON: 27 Ohm
  494. * - CLK RON: 26 Ohm
  495. */
  496. /* RCOMP Vref PU/PD */
  497. mrc_alt_write_mask(DDRPHY,
  498. DQVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  499. (0x08 << 24) | (0x03 << 16), 0x3f3f0000);
  500. /* RCOMP Vref PU/PD */
  501. mrc_alt_write_mask(DDRPHY,
  502. CMDVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  503. (0x0C << 24) | (0x03 << 16), 0x3f3f0000);
  504. /* RCOMP Vref PU/PD */
  505. mrc_alt_write_mask(DDRPHY,
  506. CLKVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  507. (0x0F << 24) | (0x03 << 16), 0x3f3f0000);
  508. /* RCOMP Vref PU/PD */
  509. mrc_alt_write_mask(DDRPHY,
  510. DQSVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  511. (0x08 << 24) | (0x03 << 16), 0x3f3f0000);
  512. /* RCOMP Vref PU/PD */
  513. mrc_alt_write_mask(DDRPHY,
  514. CTLVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  515. (0x0C << 24) | (0x03 << 16), 0x3f3f0000);
  516. /* DQS Swapped Input Enable */
  517. mrc_alt_write_mask(DDRPHY,
  518. COMPEN1CH0 + ch * DDRCOMP_CH_OFFSET,
  519. (1 << 19) | (1 << 17), 0xc00ac000);
  520. /* ODT VREF = 1.5 x 274/360+274 = 0.65V (code of ~50) */
  521. /* ODT Vref PU/PD */
  522. mrc_alt_write_mask(DDRPHY,
  523. DQVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  524. (0x32 << 8) | (0x03 << 0), 0x00003f3f);
  525. /* ODT Vref PU/PD */
  526. mrc_alt_write_mask(DDRPHY,
  527. DQSVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  528. (0x32 << 8) | (0x03 << 0), 0x00003f3f);
  529. /* ODT Vref PU/PD */
  530. mrc_alt_write_mask(DDRPHY,
  531. CLKVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  532. (0x0E << 8) | (0x05 << 0), 0x00003f3f);
  533. /*
  534. * Slew rate settings are frequency specific,
  535. * numbers below are for 800Mhz (speed == 0)
  536. * - DQ/DQS/DM/CLK SR: 4V/ns,
  537. * - CTRL/CMD SR: 1.5V/ns
  538. */
  539. temp = (0x0e << 16) | (0x0e << 12) | (0x08 << 8) |
  540. (0x0b << 4) | (0x0b << 0);
  541. /* DCOMP Delay Select: CTL,CMD,CLK,DQS,DQ */
  542. mrc_alt_write_mask(DDRPHY,
  543. DLYSELCH0 + ch * DDRCOMP_CH_OFFSET,
  544. temp, 0x000fffff);
  545. /* TCO Vref CLK,DQS,DQ */
  546. mrc_alt_write_mask(DDRPHY,
  547. TCOVREFCH0 + ch * DDRCOMP_CH_OFFSET,
  548. (0x05 << 16) | (0x05 << 8) | (0x05 << 0),
  549. 0x003f3f3f);
  550. /* ODTCOMP CMD/CTL PU/PD */
  551. mrc_alt_write_mask(DDRPHY,
  552. CCBUFODTCH0 + ch * DDRCOMP_CH_OFFSET,
  553. (0x03 << 8) | (0x03 << 0),
  554. 0x00001f1f);
  555. /* COMP */
  556. mrc_alt_write_mask(DDRPHY,
  557. COMPEN0CH0 + ch * DDRCOMP_CH_OFFSET,
  558. 0, 0xc0000100);
  559. #ifdef BACKUP_COMPS
  560. /* DQ COMP Overrides */
  561. /* RCOMP PU */
  562. mrc_alt_write_mask(DDRPHY,
  563. DQDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  564. (1 << 31) | (0x0a << 16),
  565. 0x801f0000);
  566. /* RCOMP PD */
  567. mrc_alt_write_mask(DDRPHY,
  568. DQDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  569. (1 << 31) | (0x0a << 16),
  570. 0x801f0000);
  571. /* DCOMP PU */
  572. mrc_alt_write_mask(DDRPHY,
  573. DQDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  574. (1 << 31) | (0x10 << 16),
  575. 0x801f0000);
  576. /* DCOMP PD */
  577. mrc_alt_write_mask(DDRPHY,
  578. DQDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  579. (1 << 31) | (0x10 << 16),
  580. 0x801f0000);
  581. /* ODTCOMP PU */
  582. mrc_alt_write_mask(DDRPHY,
  583. DQODTPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  584. (1 << 31) | (0x0b << 16),
  585. 0x801f0000);
  586. /* ODTCOMP PD */
  587. mrc_alt_write_mask(DDRPHY,
  588. DQODTPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  589. (1 << 31) | (0x0b << 16),
  590. 0x801f0000);
  591. /* TCOCOMP PU */
  592. mrc_alt_write_mask(DDRPHY,
  593. DQTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  594. 1 << 31, 1 << 31);
  595. /* TCOCOMP PD */
  596. mrc_alt_write_mask(DDRPHY,
  597. DQTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  598. 1 << 31, 1 << 31);
  599. /* DQS COMP Overrides */
  600. /* RCOMP PU */
  601. mrc_alt_write_mask(DDRPHY,
  602. DQSDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  603. (1 << 31) | (0x0a << 16),
  604. 0x801f0000);
  605. /* RCOMP PD */
  606. mrc_alt_write_mask(DDRPHY,
  607. DQSDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  608. (1 << 31) | (0x0a << 16),
  609. 0x801f0000);
  610. /* DCOMP PU */
  611. mrc_alt_write_mask(DDRPHY,
  612. DQSDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  613. (1 << 31) | (0x10 << 16),
  614. 0x801f0000);
  615. /* DCOMP PD */
  616. mrc_alt_write_mask(DDRPHY,
  617. DQSDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  618. (1 << 31) | (0x10 << 16),
  619. 0x801f0000);
  620. /* ODTCOMP PU */
  621. mrc_alt_write_mask(DDRPHY,
  622. DQSODTPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  623. (1 << 31) | (0x0b << 16),
  624. 0x801f0000);
  625. /* ODTCOMP PD */
  626. mrc_alt_write_mask(DDRPHY,
  627. DQSODTPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  628. (1 << 31) | (0x0b << 16),
  629. 0x801f0000);
  630. /* TCOCOMP PU */
  631. mrc_alt_write_mask(DDRPHY,
  632. DQSTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  633. 1 << 31, 1 << 31);
  634. /* TCOCOMP PD */
  635. mrc_alt_write_mask(DDRPHY,
  636. DQSTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  637. 1 << 31, 1 << 31);
  638. /* CLK COMP Overrides */
  639. /* RCOMP PU */
  640. mrc_alt_write_mask(DDRPHY,
  641. CLKDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  642. (1 << 31) | (0x0c << 16),
  643. 0x801f0000);
  644. /* RCOMP PD */
  645. mrc_alt_write_mask(DDRPHY,
  646. CLKDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  647. (1 << 31) | (0x0c << 16),
  648. 0x801f0000);
  649. /* DCOMP PU */
  650. mrc_alt_write_mask(DDRPHY,
  651. CLKDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  652. (1 << 31) | (0x07 << 16),
  653. 0x801f0000);
  654. /* DCOMP PD */
  655. mrc_alt_write_mask(DDRPHY,
  656. CLKDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  657. (1 << 31) | (0x07 << 16),
  658. 0x801f0000);
  659. /* ODTCOMP PU */
  660. mrc_alt_write_mask(DDRPHY,
  661. CLKODTPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  662. (1 << 31) | (0x0b << 16),
  663. 0x801f0000);
  664. /* ODTCOMP PD */
  665. mrc_alt_write_mask(DDRPHY,
  666. CLKODTPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  667. (1 << 31) | (0x0b << 16),
  668. 0x801f0000);
  669. /* TCOCOMP PU */
  670. mrc_alt_write_mask(DDRPHY,
  671. CLKTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  672. 1 << 31, 1 << 31);
  673. /* TCOCOMP PD */
  674. mrc_alt_write_mask(DDRPHY,
  675. CLKTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  676. 1 << 31, 1 << 31);
  677. /* CMD COMP Overrides */
  678. /* RCOMP PU */
  679. mrc_alt_write_mask(DDRPHY,
  680. CMDDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  681. (1 << 31) | (0x0d << 16),
  682. 0x803f0000);
  683. /* RCOMP PD */
  684. mrc_alt_write_mask(DDRPHY,
  685. CMDDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  686. (1 << 31) | (0x0d << 16),
  687. 0x803f0000);
  688. /* DCOMP PU */
  689. mrc_alt_write_mask(DDRPHY,
  690. CMDDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  691. (1 << 31) | (0x0a << 16),
  692. 0x801f0000);
  693. /* DCOMP PD */
  694. mrc_alt_write_mask(DDRPHY,
  695. CMDDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  696. (1 << 31) | (0x0a << 16),
  697. 0x801f0000);
  698. /* CTL COMP Overrides */
  699. /* RCOMP PU */
  700. mrc_alt_write_mask(DDRPHY,
  701. CTLDRVPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  702. (1 << 31) | (0x0d << 16),
  703. 0x803f0000);
  704. /* RCOMP PD */
  705. mrc_alt_write_mask(DDRPHY,
  706. CTLDRVPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  707. (1 << 31) | (0x0d << 16),
  708. 0x803f0000);
  709. /* DCOMP PU */
  710. mrc_alt_write_mask(DDRPHY,
  711. CTLDLYPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  712. (1 << 31) | (0x0a << 16),
  713. 0x801f0000);
  714. /* DCOMP PD */
  715. mrc_alt_write_mask(DDRPHY,
  716. CTLDLYPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  717. (1 << 31) | (0x0a << 16),
  718. 0x801f0000);
  719. #else
  720. /* DQ TCOCOMP Overrides */
  721. /* TCOCOMP PU */
  722. mrc_alt_write_mask(DDRPHY,
  723. DQTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  724. (1 << 31) | (0x1f << 16),
  725. 0x801f0000);
  726. /* TCOCOMP PD */
  727. mrc_alt_write_mask(DDRPHY,
  728. DQTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  729. (1 << 31) | (0x1f << 16),
  730. 0x801f0000);
  731. /* DQS TCOCOMP Overrides */
  732. /* TCOCOMP PU */
  733. mrc_alt_write_mask(DDRPHY,
  734. DQSTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  735. (1 << 31) | (0x1f << 16),
  736. 0x801f0000);
  737. /* TCOCOMP PD */
  738. mrc_alt_write_mask(DDRPHY,
  739. DQSTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  740. (1 << 31) | (0x1f << 16),
  741. 0x801f0000);
  742. /* CLK TCOCOMP Overrides */
  743. /* TCOCOMP PU */
  744. mrc_alt_write_mask(DDRPHY,
  745. CLKTCOPUCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  746. (1 << 31) | (0x1f << 16),
  747. 0x801f0000);
  748. /* TCOCOMP PD */
  749. mrc_alt_write_mask(DDRPHY,
  750. CLKTCOPDCTLCH0 + ch * DDRCOMP_CH_OFFSET,
  751. (1 << 31) | (0x1f << 16),
  752. 0x801f0000);
  753. #endif
  754. /* program STATIC delays */
  755. #ifdef BACKUP_WCMD
  756. set_wcmd(ch, ddr_wcmd[PLATFORM_ID]);
  757. #else
  758. set_wcmd(ch, ddr_wclk[PLATFORM_ID] + HALF_CLK);
  759. #endif
  760. for (rk = 0; rk < NUM_RANKS; rk++) {
  761. if (mrc_params->rank_enables & (1 << rk)) {
  762. set_wclk(ch, rk, ddr_wclk[PLATFORM_ID]);
  763. #ifdef BACKUP_WCTL
  764. set_wctl(ch, rk, ddr_wctl[PLATFORM_ID]);
  765. #else
  766. set_wctl(ch, rk, ddr_wclk[PLATFORM_ID] + HALF_CLK);
  767. #endif
  768. }
  769. }
  770. }
  771. }
  772. /* COMP (non channel specific) */
  773. /* RCOMP: Dither PU Enable */
  774. mrc_alt_write_mask(DDRPHY, DQANADRVPUCTL, 1 << 30, 1 << 30);
  775. /* RCOMP: Dither PD Enable */
  776. mrc_alt_write_mask(DDRPHY, DQANADRVPDCTL, 1 << 30, 1 << 30);
  777. /* RCOMP: Dither PU Enable */
  778. mrc_alt_write_mask(DDRPHY, CMDANADRVPUCTL, 1 << 30, 1 << 30);
  779. /* RCOMP: Dither PD Enable */
  780. mrc_alt_write_mask(DDRPHY, CMDANADRVPDCTL, 1 << 30, 1 << 30);
  781. /* RCOMP: Dither PU Enable */
  782. mrc_alt_write_mask(DDRPHY, CLKANADRVPUCTL, 1 << 30, 1 << 30);
  783. /* RCOMP: Dither PD Enable */
  784. mrc_alt_write_mask(DDRPHY, CLKANADRVPDCTL, 1 << 30, 1 << 30);
  785. /* RCOMP: Dither PU Enable */
  786. mrc_alt_write_mask(DDRPHY, DQSANADRVPUCTL, 1 << 30, 1 << 30);
  787. /* RCOMP: Dither PD Enable */
  788. mrc_alt_write_mask(DDRPHY, DQSANADRVPDCTL, 1 << 30, 1 << 30);
  789. /* RCOMP: Dither PU Enable */
  790. mrc_alt_write_mask(DDRPHY, CTLANADRVPUCTL, 1 << 30, 1 << 30);
  791. /* RCOMP: Dither PD Enable */
  792. mrc_alt_write_mask(DDRPHY, CTLANADRVPDCTL, 1 << 30, 1 << 30);
  793. /* ODT: Dither PU Enable */
  794. mrc_alt_write_mask(DDRPHY, DQANAODTPUCTL, 1 << 30, 1 << 30);
  795. /* ODT: Dither PD Enable */
  796. mrc_alt_write_mask(DDRPHY, DQANAODTPDCTL, 1 << 30, 1 << 30);
  797. /* ODT: Dither PU Enable */
  798. mrc_alt_write_mask(DDRPHY, CLKANAODTPUCTL, 1 << 30, 1 << 30);
  799. /* ODT: Dither PD Enable */
  800. mrc_alt_write_mask(DDRPHY, CLKANAODTPDCTL, 1 << 30, 1 << 30);
  801. /* ODT: Dither PU Enable */
  802. mrc_alt_write_mask(DDRPHY, DQSANAODTPUCTL, 1 << 30, 1 << 30);
  803. /* ODT: Dither PD Enable */
  804. mrc_alt_write_mask(DDRPHY, DQSANAODTPDCTL, 1 << 30, 1 << 30);
  805. /* DCOMP: Dither PU Enable */
  806. mrc_alt_write_mask(DDRPHY, DQANADLYPUCTL, 1 << 30, 1 << 30);
  807. /* DCOMP: Dither PD Enable */
  808. mrc_alt_write_mask(DDRPHY, DQANADLYPDCTL, 1 << 30, 1 << 30);
  809. /* DCOMP: Dither PU Enable */
  810. mrc_alt_write_mask(DDRPHY, CMDANADLYPUCTL, 1 << 30, 1 << 30);
  811. /* DCOMP: Dither PD Enable */
  812. mrc_alt_write_mask(DDRPHY, CMDANADLYPDCTL, 1 << 30, 1 << 30);
  813. /* DCOMP: Dither PU Enable */
  814. mrc_alt_write_mask(DDRPHY, CLKANADLYPUCTL, 1 << 30, 1 << 30);
  815. /* DCOMP: Dither PD Enable */
  816. mrc_alt_write_mask(DDRPHY, CLKANADLYPDCTL, 1 << 30, 1 << 30);
  817. /* DCOMP: Dither PU Enable */
  818. mrc_alt_write_mask(DDRPHY, DQSANADLYPUCTL, 1 << 30, 1 << 30);
  819. /* DCOMP: Dither PD Enable */
  820. mrc_alt_write_mask(DDRPHY, DQSANADLYPDCTL, 1 << 30, 1 << 30);
  821. /* DCOMP: Dither PU Enable */
  822. mrc_alt_write_mask(DDRPHY, CTLANADLYPUCTL, 1 << 30, 1 << 30);
  823. /* DCOMP: Dither PD Enable */
  824. mrc_alt_write_mask(DDRPHY, CTLANADLYPDCTL, 1 << 30, 1 << 30);
  825. /* TCO: Dither PU Enable */
  826. mrc_alt_write_mask(DDRPHY, DQANATCOPUCTL, 1 << 30, 1 << 30);
  827. /* TCO: Dither PD Enable */
  828. mrc_alt_write_mask(DDRPHY, DQANATCOPDCTL, 1 << 30, 1 << 30);
  829. /* TCO: Dither PU Enable */
  830. mrc_alt_write_mask(DDRPHY, CLKANATCOPUCTL, 1 << 30, 1 << 30);
  831. /* TCO: Dither PD Enable */
  832. mrc_alt_write_mask(DDRPHY, CLKANATCOPDCTL, 1 << 30, 1 << 30);
  833. /* TCO: Dither PU Enable */
  834. mrc_alt_write_mask(DDRPHY, DQSANATCOPUCTL, 1 << 30, 1 << 30);
  835. /* TCO: Dither PD Enable */
  836. mrc_alt_write_mask(DDRPHY, DQSANATCOPDCTL, 1 << 30, 1 << 30);
  837. /* TCOCOMP: Pulse Count */
  838. mrc_alt_write_mask(DDRPHY, TCOCNTCTRL, 1, 3);
  839. /* ODT: CMD/CTL PD/PU */
  840. mrc_alt_write_mask(DDRPHY, CHNLBUFSTATIC,
  841. (0x03 << 24) | (0x03 << 16), 0x1f1f0000);
  842. /* Set 1us counter */
  843. mrc_alt_write_mask(DDRPHY, MSCNTR, 0x64, 0xff);
  844. mrc_alt_write_mask(DDRPHY, LATCH1CTL, 0x1 << 28, 0x70000000);
  845. /* Release PHY from reset */
  846. mrc_alt_write_mask(DDRPHY, MASTERRSTN, 1, 1);
  847. /* STEP1 */
  848. mrc_post_code(0x03, 0x11);
  849. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  850. if (mrc_params->channel_enables & (1 << ch)) {
  851. /* DQ01-DQ23 */
  852. for (bl_grp = 0;
  853. bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
  854. bl_grp++) {
  855. mrc_alt_write_mask(DDRPHY,
  856. DQMDLLCTL +
  857. bl_grp * DDRIODQ_BL_OFFSET +
  858. ch * DDRIODQ_CH_OFFSET,
  859. 1 << 13,
  860. 1 << 13); /* Enable VREG */
  861. delay_n(3);
  862. }
  863. /* ECC */
  864. mrc_alt_write_mask(DDRPHY, ECCMDLLCTL,
  865. 1 << 13, 1 << 13); /* Enable VREG */
  866. delay_n(3);
  867. /* CMD */
  868. mrc_alt_write_mask(DDRPHY,
  869. CMDMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
  870. 1 << 13, 1 << 13); /* Enable VREG */
  871. delay_n(3);
  872. /* CLK-CTL */
  873. mrc_alt_write_mask(DDRPHY,
  874. CCMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
  875. 1 << 13, 1 << 13); /* Enable VREG */
  876. delay_n(3);
  877. }
  878. }
  879. /* STEP2 */
  880. mrc_post_code(0x03, 0x12);
  881. delay_n(200);
  882. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  883. if (mrc_params->channel_enables & (1 << ch)) {
  884. /* DQ01-DQ23 */
  885. for (bl_grp = 0;
  886. bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
  887. bl_grp++) {
  888. mrc_alt_write_mask(DDRPHY,
  889. DQMDLLCTL +
  890. bl_grp * DDRIODQ_BL_OFFSET +
  891. ch * DDRIODQ_CH_OFFSET,
  892. 1 << 17,
  893. 1 << 17); /* Enable MCDLL */
  894. delay_n(50);
  895. }
  896. /* ECC */
  897. mrc_alt_write_mask(DDRPHY, ECCMDLLCTL,
  898. 1 << 17, 1 << 17); /* Enable MCDLL */
  899. delay_n(50);
  900. /* CMD */
  901. mrc_alt_write_mask(DDRPHY,
  902. CMDMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
  903. 1 << 18, 1 << 18); /* Enable MCDLL */
  904. delay_n(50);
  905. /* CLK-CTL */
  906. mrc_alt_write_mask(DDRPHY,
  907. CCMDLLCTL + ch * DDRIOCCC_CH_OFFSET,
  908. 1 << 18, 1 << 18); /* Enable MCDLL */
  909. delay_n(50);
  910. }
  911. }
  912. /* STEP3: */
  913. mrc_post_code(0x03, 0x13);
  914. delay_n(100);
  915. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  916. if (mrc_params->channel_enables & (1 << ch)) {
  917. /* DQ01-DQ23 */
  918. for (bl_grp = 0;
  919. bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
  920. bl_grp++) {
  921. #ifdef FORCE_16BIT_DDRIO
  922. temp = (bl_grp &&
  923. (mrc_params->channel_width == X16)) ?
  924. 0x11ff : 0xffff;
  925. #else
  926. temp = 0xffff;
  927. #endif
  928. /* Enable TXDLL */
  929. mrc_alt_write_mask(DDRPHY,
  930. DQDLLTXCTL +
  931. bl_grp * DDRIODQ_BL_OFFSET +
  932. ch * DDRIODQ_CH_OFFSET,
  933. temp, 0xffff);
  934. delay_n(3);
  935. /* Enable RXDLL */
  936. mrc_alt_write_mask(DDRPHY,
  937. DQDLLRXCTL +
  938. bl_grp * DDRIODQ_BL_OFFSET +
  939. ch * DDRIODQ_CH_OFFSET,
  940. 0xf, 0xf);
  941. delay_n(3);
  942. /* Enable RXDLL Overrides BL0 */
  943. mrc_alt_write_mask(DDRPHY,
  944. B0OVRCTL +
  945. bl_grp * DDRIODQ_BL_OFFSET +
  946. ch * DDRIODQ_CH_OFFSET,
  947. 0xf, 0xf);
  948. }
  949. /* ECC */
  950. temp = 0xffff;
  951. mrc_alt_write_mask(DDRPHY, ECCDLLTXCTL,
  952. temp, 0xffff);
  953. delay_n(3);
  954. /* CMD (PO) */
  955. mrc_alt_write_mask(DDRPHY,
  956. CMDDLLTXCTL + ch * DDRIOCCC_CH_OFFSET,
  957. temp, 0xffff);
  958. delay_n(3);
  959. }
  960. }
  961. /* STEP4 */
  962. mrc_post_code(0x03, 0x14);
  963. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  964. if (mrc_params->channel_enables & (1 << ch)) {
  965. /* Host To Memory Clock Alignment (HMC) for 800/1066 */
  966. for (bl_grp = 0;
  967. bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2;
  968. bl_grp++) {
  969. /* CLK_ALIGN_MOD_ID */
  970. mrc_alt_write_mask(DDRPHY,
  971. DQCLKALIGNREG2 +
  972. bl_grp * DDRIODQ_BL_OFFSET +
  973. ch * DDRIODQ_CH_OFFSET,
  974. bl_grp ? 3 : 1,
  975. 0xf);
  976. }
  977. mrc_alt_write_mask(DDRPHY,
  978. ECCCLKALIGNREG2 + ch * DDRIODQ_CH_OFFSET,
  979. 0x2, 0xf);
  980. mrc_alt_write_mask(DDRPHY,
  981. CMDCLKALIGNREG2 + ch * DDRIODQ_CH_OFFSET,
  982. 0x0, 0xf);
  983. mrc_alt_write_mask(DDRPHY,
  984. CCCLKALIGNREG2 + ch * DDRIODQ_CH_OFFSET,
  985. 0x2, 0xf);
  986. mrc_alt_write_mask(DDRPHY,
  987. CMDCLKALIGNREG0 + ch * DDRIOCCC_CH_OFFSET,
  988. 0x20, 0x30);
  989. /*
  990. * NUM_SAMPLES, MAX_SAMPLES,
  991. * MACRO_PI_STEP, MICRO_PI_STEP
  992. */
  993. mrc_alt_write_mask(DDRPHY,
  994. CMDCLKALIGNREG1 + ch * DDRIOCCC_CH_OFFSET,
  995. (0x18 << 16) | (0x10 << 8) |
  996. (0x8 << 2) | (0x1 << 0),
  997. 0x007f7fff);
  998. /* TOTAL_NUM_MODULES, FIRST_U_PARTITION */
  999. mrc_alt_write_mask(DDRPHY,
  1000. CMDCLKALIGNREG2 + ch * DDRIOCCC_CH_OFFSET,
  1001. (0x10 << 16) | (0x4 << 8) | (0x2 << 4),
  1002. 0x001f0ff0);
  1003. #ifdef HMC_TEST
  1004. /* START_CLK_ALIGN=1 */
  1005. mrc_alt_write_mask(DDRPHY,
  1006. CMDCLKALIGNREG0 + ch * DDRIOCCC_CH_OFFSET,
  1007. 1 << 24, 1 << 24);
  1008. while (msg_port_alt_read(DDRPHY,
  1009. CMDCLKALIGNREG0 + ch * DDRIOCCC_CH_OFFSET) &
  1010. (1 << 24))
  1011. ; /* wait for START_CLK_ALIGN=0 */
  1012. #endif
  1013. /* Set RD/WR Pointer Seperation & COUNTEN & FIFOPTREN */
  1014. mrc_alt_write_mask(DDRPHY,
  1015. CMDPTRREG + ch * DDRIOCCC_CH_OFFSET,
  1016. 1, 1); /* WRPTRENABLE=1 */
  1017. /* COMP initial */
  1018. /* enable bypass for CLK buffer (PO) */
  1019. mrc_alt_write_mask(DDRPHY,
  1020. COMPEN0CH0 + ch * DDRCOMP_CH_OFFSET,
  1021. 1 << 5, 1 << 5);
  1022. /* Initial COMP Enable */
  1023. mrc_alt_write_mask(DDRPHY, CMPCTRL, 1, 1);
  1024. /* wait for Initial COMP Enable = 0 */
  1025. while (msg_port_alt_read(DDRPHY, CMPCTRL) & 1)
  1026. ;
  1027. /* disable bypass for CLK buffer (PO) */
  1028. mrc_alt_write_mask(DDRPHY,
  1029. COMPEN0CH0 + ch * DDRCOMP_CH_OFFSET,
  1030. ~(1 << 5), 1 << 5);
  1031. /* IOBUFACT */
  1032. /* STEP4a */
  1033. mrc_alt_write_mask(DDRPHY,
  1034. CMDCFGREG0 + ch * DDRIOCCC_CH_OFFSET,
  1035. 1 << 2, 1 << 2); /* IOBUFACTRST_N=1 */
  1036. /* DDRPHY initialization complete */
  1037. mrc_alt_write_mask(DDRPHY,
  1038. CMDPMCONFIG0 + ch * DDRIOCCC_CH_OFFSET,
  1039. 1 << 20, 1 << 20); /* SPID_INIT_COMPLETE=1 */
  1040. }
  1041. }
  1042. LEAVEFN();
  1043. }
  1044. /* This function performs JEDEC initialization on all enabled channels */
  1045. void perform_jedec_init(struct mrc_params *mrc_params)
  1046. {
  1047. uint8_t twr, wl, rank;
  1048. uint32_t tck;
  1049. u32 dtr0;
  1050. u32 drp;
  1051. u32 drmc;
  1052. u32 mrs0_cmd = 0;
  1053. u32 emrs1_cmd = 0;
  1054. u32 emrs2_cmd = 0;
  1055. u32 emrs3_cmd = 0;
  1056. ENTERFN();
  1057. /* jedec_init starts */
  1058. mrc_post_code(0x04, 0x00);
  1059. /* DDR3_RESET_SET=0, DDR3_RESET_RESET=1 */
  1060. mrc_alt_write_mask(DDRPHY, CCDDR3RESETCTL, 2, 0x102);
  1061. /* Assert RESET# for 200us */
  1062. delay_u(200);
  1063. /* DDR3_RESET_SET=1, DDR3_RESET_RESET=0 */
  1064. mrc_alt_write_mask(DDRPHY, CCDDR3RESETCTL, 0x100, 0x102);
  1065. dtr0 = msg_port_read(MEM_CTLR, DTR0);
  1066. /*
  1067. * Set CKEVAL for populated ranks
  1068. * then send NOP to each rank (#4550197)
  1069. */
  1070. drp = msg_port_read(MEM_CTLR, DRP);
  1071. drp &= 0x3;
  1072. drmc = msg_port_read(MEM_CTLR, DRMC);
  1073. drmc &= 0xfffffffc;
  1074. drmc |= (DRMC_CKEMODE | drp);
  1075. msg_port_write(MEM_CTLR, DRMC, drmc);
  1076. for (rank = 0; rank < NUM_RANKS; rank++) {
  1077. /* Skip to next populated rank */
  1078. if ((mrc_params->rank_enables & (1 << rank)) == 0)
  1079. continue;
  1080. dram_init_command(DCMD_NOP(rank));
  1081. }
  1082. msg_port_write(MEM_CTLR, DRMC,
  1083. (mrc_params->rd_odt_value == 0 ? DRMC_ODTMODE : 0));
  1084. /*
  1085. * setup for emrs 2
  1086. * BIT[15:11] --> Always "0"
  1087. * BIT[10:09] --> Rtt_WR: want "Dynamic ODT Off" (0)
  1088. * BIT[08] --> Always "0"
  1089. * BIT[07] --> SRT: use sr_temp_range
  1090. * BIT[06] --> ASR: want "Manual SR Reference" (0)
  1091. * BIT[05:03] --> CWL: use oem_tCWL
  1092. * BIT[02:00] --> PASR: want "Full Array" (0)
  1093. */
  1094. emrs2_cmd |= (2 << 3);
  1095. wl = 5 + mrc_params->ddr_speed;
  1096. emrs2_cmd |= ((wl - 5) << 9);
  1097. emrs2_cmd |= (mrc_params->sr_temp_range << 13);
  1098. /*
  1099. * setup for emrs 3
  1100. * BIT[15:03] --> Always "0"
  1101. * BIT[02] --> MPR: want "Normal Operation" (0)
  1102. * BIT[01:00] --> MPR_Loc: want "Predefined Pattern" (0)
  1103. */
  1104. emrs3_cmd |= (3 << 3);
  1105. /*
  1106. * setup for emrs 1
  1107. * BIT[15:13] --> Always "0"
  1108. * BIT[12:12] --> Qoff: want "Output Buffer Enabled" (0)
  1109. * BIT[11:11] --> TDQS: want "Disabled" (0)
  1110. * BIT[10:10] --> Always "0"
  1111. * BIT[09,06,02] --> Rtt_nom: use rtt_nom_value
  1112. * BIT[08] --> Always "0"
  1113. * BIT[07] --> WR_LVL: want "Disabled" (0)
  1114. * BIT[05,01] --> DIC: use ron_value
  1115. * BIT[04:03] --> AL: additive latency want "0" (0)
  1116. * BIT[00] --> DLL: want "Enable" (0)
  1117. *
  1118. * (BIT5|BIT1) set Ron value
  1119. * 00 --> RZQ/6 (40ohm)
  1120. * 01 --> RZQ/7 (34ohm)
  1121. * 1* --> RESERVED
  1122. *
  1123. * (BIT9|BIT6|BIT2) set Rtt_nom value
  1124. * 000 --> Disabled
  1125. * 001 --> RZQ/4 ( 60ohm)
  1126. * 010 --> RZQ/2 (120ohm)
  1127. * 011 --> RZQ/6 ( 40ohm)
  1128. * 1** --> RESERVED
  1129. */
  1130. emrs1_cmd |= (1 << 3);
  1131. emrs1_cmd &= ~(1 << 6);
  1132. if (mrc_params->ron_value == 0)
  1133. emrs1_cmd |= (1 << 7);
  1134. else
  1135. emrs1_cmd &= ~(1 << 7);
  1136. if (mrc_params->rtt_nom_value == 0)
  1137. emrs1_cmd |= (DDR3_EMRS1_RTTNOM_40 << 6);
  1138. else if (mrc_params->rtt_nom_value == 1)
  1139. emrs1_cmd |= (DDR3_EMRS1_RTTNOM_60 << 6);
  1140. else if (mrc_params->rtt_nom_value == 2)
  1141. emrs1_cmd |= (DDR3_EMRS1_RTTNOM_120 << 6);
  1142. /* save MRS1 value (excluding control fields) */
  1143. mrc_params->mrs1 = emrs1_cmd >> 6;
  1144. /*
  1145. * setup for mrs 0
  1146. * BIT[15:13] --> Always "0"
  1147. * BIT[12] --> PPD: for Quark (1)
  1148. * BIT[11:09] --> WR: use oem_tWR
  1149. * BIT[08] --> DLL: want "Reset" (1, self clearing)
  1150. * BIT[07] --> MODE: want "Normal" (0)
  1151. * BIT[06:04,02] --> CL: use oem_tCAS
  1152. * BIT[03] --> RD_BURST_TYPE: want "Interleave" (1)
  1153. * BIT[01:00] --> BL: want "8 Fixed" (0)
  1154. * WR:
  1155. * 0 --> 16
  1156. * 1 --> 5
  1157. * 2 --> 6
  1158. * 3 --> 7
  1159. * 4 --> 8
  1160. * 5 --> 10
  1161. * 6 --> 12
  1162. * 7 --> 14
  1163. * CL:
  1164. * BIT[02:02] "0" if oem_tCAS <= 11 (1866?)
  1165. * BIT[06:04] use oem_tCAS-4
  1166. */
  1167. mrs0_cmd |= (1 << 14);
  1168. mrs0_cmd |= (1 << 18);
  1169. mrs0_cmd |= ((((dtr0 >> 12) & 7) + 1) << 10);
  1170. tck = t_ck[mrc_params->ddr_speed];
  1171. /* Per JEDEC: tWR=15000ps DDR2/3 from 800-1600 */
  1172. twr = MCEIL(15000, tck);
  1173. mrs0_cmd |= ((twr - 4) << 15);
  1174. for (rank = 0; rank < NUM_RANKS; rank++) {
  1175. /* Skip to next populated rank */
  1176. if ((mrc_params->rank_enables & (1 << rank)) == 0)
  1177. continue;
  1178. emrs2_cmd |= (rank << 22);
  1179. dram_init_command(emrs2_cmd);
  1180. emrs3_cmd |= (rank << 22);
  1181. dram_init_command(emrs3_cmd);
  1182. emrs1_cmd |= (rank << 22);
  1183. dram_init_command(emrs1_cmd);
  1184. mrs0_cmd |= (rank << 22);
  1185. dram_init_command(mrs0_cmd);
  1186. dram_init_command(DCMD_ZQCL(rank));
  1187. }
  1188. LEAVEFN();
  1189. }
  1190. /*
  1191. * Dunit Initialization Complete
  1192. *
  1193. * Indicates that initialization of the Dunit has completed.
  1194. *
  1195. * Memory accesses are permitted and maintenance operation begins.
  1196. * Until this bit is set to a 1, the memory controller will not accept
  1197. * DRAM requests from the MEMORY_MANAGER or HTE.
  1198. */
  1199. void set_ddr_init_complete(struct mrc_params *mrc_params)
  1200. {
  1201. u32 dco;
  1202. ENTERFN();
  1203. dco = msg_port_read(MEM_CTLR, DCO);
  1204. dco &= ~DCO_PMICTL;
  1205. dco |= DCO_IC;
  1206. msg_port_write(MEM_CTLR, DCO, dco);
  1207. LEAVEFN();
  1208. }
  1209. /*
  1210. * This function will retrieve relevant timing data
  1211. *
  1212. * This data will be used on subsequent boots to speed up boot times
  1213. * and is required for Suspend To RAM capabilities.
  1214. */
  1215. void restore_timings(struct mrc_params *mrc_params)
  1216. {
  1217. uint8_t ch, rk, bl;
  1218. const struct mrc_timings *mt = &mrc_params->timings;
  1219. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1220. for (rk = 0; rk < NUM_RANKS; rk++) {
  1221. for (bl = 0; bl < NUM_BYTE_LANES; bl++) {
  1222. set_rcvn(ch, rk, bl, mt->rcvn[ch][rk][bl]);
  1223. set_rdqs(ch, rk, bl, mt->rdqs[ch][rk][bl]);
  1224. set_wdqs(ch, rk, bl, mt->wdqs[ch][rk][bl]);
  1225. set_wdq(ch, rk, bl, mt->wdq[ch][rk][bl]);
  1226. if (rk == 0) {
  1227. /* VREF (RANK0 only) */
  1228. set_vref(ch, bl, mt->vref[ch][bl]);
  1229. }
  1230. }
  1231. set_wctl(ch, rk, mt->wctl[ch][rk]);
  1232. }
  1233. set_wcmd(ch, mt->wcmd[ch]);
  1234. }
  1235. }
  1236. /*
  1237. * Configure default settings normally set as part of read training
  1238. *
  1239. * Some defaults have to be set earlier as they may affect earlier
  1240. * training steps.
  1241. */
  1242. void default_timings(struct mrc_params *mrc_params)
  1243. {
  1244. uint8_t ch, rk, bl;
  1245. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1246. for (rk = 0; rk < NUM_RANKS; rk++) {
  1247. for (bl = 0; bl < NUM_BYTE_LANES; bl++) {
  1248. set_rdqs(ch, rk, bl, 24);
  1249. if (rk == 0) {
  1250. /* VREF (RANK0 only) */
  1251. set_vref(ch, bl, 32);
  1252. }
  1253. }
  1254. }
  1255. }
  1256. }
  1257. /*
  1258. * This function will perform our RCVEN Calibration Algorithm.
  1259. * We will only use the 2xCLK domain timings to perform RCVEN Calibration.
  1260. * All byte lanes will be calibrated "simultaneously" per channel per rank.
  1261. */
  1262. void rcvn_cal(struct mrc_params *mrc_params)
  1263. {
  1264. uint8_t ch; /* channel counter */
  1265. uint8_t rk; /* rank counter */
  1266. uint8_t bl; /* byte lane counter */
  1267. uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
  1268. #ifdef R2R_SHARING
  1269. /* used to find placement for rank2rank sharing configs */
  1270. uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
  1271. #ifndef BACKUP_RCVN
  1272. /* used to find placement for rank2rank sharing configs */
  1273. uint32_t num_ranks_enabled = 0;
  1274. #endif
  1275. #endif
  1276. #ifdef BACKUP_RCVN
  1277. #else
  1278. uint32_t temp;
  1279. /* absolute PI value to be programmed on the byte lane */
  1280. uint32_t delay[NUM_BYTE_LANES];
  1281. u32 dtr1, dtr1_save;
  1282. #endif
  1283. ENTERFN();
  1284. /* rcvn_cal starts */
  1285. mrc_post_code(0x05, 0x00);
  1286. #ifndef BACKUP_RCVN
  1287. /* need separate burst to sample DQS preamble */
  1288. dtr1 = msg_port_read(MEM_CTLR, DTR1);
  1289. dtr1_save = dtr1;
  1290. dtr1 |= DTR1_TCCD_12CLK;
  1291. msg_port_write(MEM_CTLR, DTR1, dtr1);
  1292. #endif
  1293. #ifdef R2R_SHARING
  1294. /* need to set "final_delay[][]" elements to "0" */
  1295. memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
  1296. #endif
  1297. /* loop through each enabled channel */
  1298. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1299. if (mrc_params->channel_enables & (1 << ch)) {
  1300. /* perform RCVEN Calibration on a per rank basis */
  1301. for (rk = 0; rk < NUM_RANKS; rk++) {
  1302. if (mrc_params->rank_enables & (1 << rk)) {
  1303. /*
  1304. * POST_CODE here indicates the current
  1305. * channel and rank being calibrated
  1306. */
  1307. mrc_post_code(0x05, 0x10 + ((ch << 4) | rk));
  1308. #ifdef BACKUP_RCVN
  1309. /* et hard-coded timing values */
  1310. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++)
  1311. set_rcvn(ch, rk, bl, ddr_rcvn[PLATFORM_ID]);
  1312. #else
  1313. /* enable FIFORST */
  1314. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl += 2) {
  1315. mrc_alt_write_mask(DDRPHY,
  1316. B01PTRCTL1 +
  1317. (bl >> 1) * DDRIODQ_BL_OFFSET +
  1318. ch * DDRIODQ_CH_OFFSET,
  1319. 0, 1 << 8);
  1320. }
  1321. /* initialize the starting delay to 128 PI (cas +1 CLK) */
  1322. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1323. /* 1x CLK domain timing is cas-4 */
  1324. delay[bl] = (4 + 1) * FULL_CLK;
  1325. set_rcvn(ch, rk, bl, delay[bl]);
  1326. }
  1327. /* now find the rising edge */
  1328. find_rising_edge(mrc_params, delay, ch, rk, true);
  1329. /* Now increase delay by 32 PI (1/4 CLK) to place in center of high pulse */
  1330. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1331. delay[bl] += QRTR_CLK;
  1332. set_rcvn(ch, rk, bl, delay[bl]);
  1333. }
  1334. /* Now decrement delay by 128 PI (1 CLK) until we sample a "0" */
  1335. do {
  1336. temp = sample_dqs(mrc_params, ch, rk, true);
  1337. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1338. if (temp & (1 << bl)) {
  1339. if (delay[bl] >= FULL_CLK) {
  1340. delay[bl] -= FULL_CLK;
  1341. set_rcvn(ch, rk, bl, delay[bl]);
  1342. } else {
  1343. /* not enough delay */
  1344. training_message(ch, rk, bl);
  1345. mrc_post_code(0xee, 0x50);
  1346. }
  1347. }
  1348. }
  1349. } while (temp & 0xff);
  1350. #ifdef R2R_SHARING
  1351. /* increment "num_ranks_enabled" */
  1352. num_ranks_enabled++;
  1353. /* Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble */
  1354. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1355. delay[bl] += QRTR_CLK;
  1356. /* add "delay[]" values to "final_delay[][]" for rolling average */
  1357. final_delay[ch][bl] += delay[bl];
  1358. /* set timing based on rolling average values */
  1359. set_rcvn(ch, rk, bl, final_delay[ch][bl] / num_ranks_enabled);
  1360. }
  1361. #else
  1362. /* Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble */
  1363. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1364. delay[bl] += QRTR_CLK;
  1365. set_rcvn(ch, rk, bl, delay[bl]);
  1366. }
  1367. #endif
  1368. /* disable FIFORST */
  1369. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl += 2) {
  1370. mrc_alt_write_mask(DDRPHY,
  1371. B01PTRCTL1 +
  1372. (bl >> 1) * DDRIODQ_BL_OFFSET +
  1373. ch * DDRIODQ_CH_OFFSET,
  1374. 1 << 8, 1 << 8);
  1375. }
  1376. #endif
  1377. }
  1378. }
  1379. }
  1380. }
  1381. #ifndef BACKUP_RCVN
  1382. /* restore original */
  1383. msg_port_write(MEM_CTLR, DTR1, dtr1_save);
  1384. #endif
  1385. LEAVEFN();
  1386. }
  1387. /*
  1388. * This function will perform the Write Levelling algorithm
  1389. * (align WCLK and WDQS).
  1390. *
  1391. * This algorithm will act on each rank in each channel separately.
  1392. */
  1393. void wr_level(struct mrc_params *mrc_params)
  1394. {
  1395. uint8_t ch; /* channel counter */
  1396. uint8_t rk; /* rank counter */
  1397. uint8_t bl; /* byte lane counter */
  1398. uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
  1399. #ifdef R2R_SHARING
  1400. /* used to find placement for rank2rank sharing configs */
  1401. uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
  1402. #ifndef BACKUP_WDQS
  1403. /* used to find placement for rank2rank sharing configs */
  1404. uint32_t num_ranks_enabled = 0;
  1405. #endif
  1406. #endif
  1407. #ifdef BACKUP_WDQS
  1408. #else
  1409. /* determines stop condition for CRS_WR_LVL */
  1410. bool all_edges_found;
  1411. /* absolute PI value to be programmed on the byte lane */
  1412. uint32_t delay[NUM_BYTE_LANES];
  1413. /*
  1414. * static makes it so the data is loaded in the heap once by shadow(),
  1415. * where non-static copies the data onto the stack every time this
  1416. * function is called
  1417. */
  1418. uint32_t address; /* address to be checked during COARSE_WR_LVL */
  1419. u32 dtr4, dtr4_save;
  1420. #endif
  1421. ENTERFN();
  1422. /* wr_level starts */
  1423. mrc_post_code(0x06, 0x00);
  1424. #ifdef R2R_SHARING
  1425. /* need to set "final_delay[][]" elements to "0" */
  1426. memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
  1427. #endif
  1428. /* loop through each enabled channel */
  1429. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1430. if (mrc_params->channel_enables & (1 << ch)) {
  1431. /* perform WRITE LEVELING algorithm on a per rank basis */
  1432. for (rk = 0; rk < NUM_RANKS; rk++) {
  1433. if (mrc_params->rank_enables & (1 << rk)) {
  1434. /*
  1435. * POST_CODE here indicates the current
  1436. * rank and channel being calibrated
  1437. */
  1438. mrc_post_code(0x06, 0x10 + ((ch << 4) | rk));
  1439. #ifdef BACKUP_WDQS
  1440. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1441. set_wdqs(ch, rk, bl, ddr_wdqs[PLATFORM_ID]);
  1442. set_wdq(ch, rk, bl, ddr_wdqs[PLATFORM_ID] - QRTR_CLK);
  1443. }
  1444. #else
  1445. /*
  1446. * perform a single PRECHARGE_ALL command to
  1447. * make DRAM state machine go to IDLE state
  1448. */
  1449. dram_init_command(DCMD_PREA(rk));
  1450. /*
  1451. * enable Write Levelling Mode
  1452. * (EMRS1 w/ Write Levelling Mode Enable)
  1453. */
  1454. dram_init_command(DCMD_MRS1(rk, 0x82));
  1455. /*
  1456. * set ODT DRAM Full Time Termination
  1457. * disable in MCU
  1458. */
  1459. dtr4 = msg_port_read(MEM_CTLR, DTR4);
  1460. dtr4_save = dtr4;
  1461. dtr4 |= DTR4_ODTDIS;
  1462. msg_port_write(MEM_CTLR, DTR4, dtr4);
  1463. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor) / 2; bl++) {
  1464. /*
  1465. * Enable Sandy Bridge Mode (WDQ Tri-State) &
  1466. * Ensure 5 WDQS pulses during Write Leveling
  1467. */
  1468. mrc_alt_write_mask(DDRPHY,
  1469. DQCTL + DDRIODQ_BL_OFFSET * bl + DDRIODQ_CH_OFFSET * ch,
  1470. 0x10000154,
  1471. 0x100003fc);
  1472. }
  1473. /* Write Leveling Mode enabled in IO */
  1474. mrc_alt_write_mask(DDRPHY,
  1475. CCDDR3RESETCTL + DDRIOCCC_CH_OFFSET * ch,
  1476. 1 << 16, 1 << 16);
  1477. /* Initialize the starting delay to WCLK */
  1478. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1479. /*
  1480. * CLK0 --> RK0
  1481. * CLK1 --> RK1
  1482. */
  1483. delay[bl] = get_wclk(ch, rk);
  1484. set_wdqs(ch, rk, bl, delay[bl]);
  1485. }
  1486. /* now find the rising edge */
  1487. find_rising_edge(mrc_params, delay, ch, rk, false);
  1488. /* disable Write Levelling Mode */
  1489. mrc_alt_write_mask(DDRPHY,
  1490. CCDDR3RESETCTL + DDRIOCCC_CH_OFFSET * ch,
  1491. 0, 1 << 16);
  1492. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor) / 2; bl++) {
  1493. /* Disable Sandy Bridge Mode & Ensure 4 WDQS pulses during normal operation */
  1494. mrc_alt_write_mask(DDRPHY,
  1495. DQCTL + DDRIODQ_BL_OFFSET * bl + DDRIODQ_CH_OFFSET * ch,
  1496. 0x00000154,
  1497. 0x100003fc);
  1498. }
  1499. /* restore original DTR4 */
  1500. msg_port_write(MEM_CTLR, DTR4, dtr4_save);
  1501. /*
  1502. * restore original value
  1503. * (Write Levelling Mode Disable)
  1504. */
  1505. dram_init_command(DCMD_MRS1(rk, mrc_params->mrs1));
  1506. /*
  1507. * perform a single PRECHARGE_ALL command to
  1508. * make DRAM state machine go to IDLE state
  1509. */
  1510. dram_init_command(DCMD_PREA(rk));
  1511. mrc_post_code(0x06, 0x30 + ((ch << 4) | rk));
  1512. /*
  1513. * COARSE WRITE LEVEL:
  1514. * check that we're on the correct clock edge
  1515. */
  1516. /* hte reconfiguration request */
  1517. mrc_params->hte_setup = 1;
  1518. /* start CRS_WR_LVL with WDQS = WDQS + 128 PI */
  1519. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1520. delay[bl] = get_wdqs(ch, rk, bl) + FULL_CLK;
  1521. set_wdqs(ch, rk, bl, delay[bl]);
  1522. /*
  1523. * program WDQ timings based on WDQS
  1524. * (WDQ = WDQS - 32 PI)
  1525. */
  1526. set_wdq(ch, rk, bl, (delay[bl] - QRTR_CLK));
  1527. }
  1528. /* get an address in the targeted channel/rank */
  1529. address = get_addr(ch, rk);
  1530. do {
  1531. uint32_t coarse_result = 0x00;
  1532. uint32_t coarse_result_mask = byte_lane_mask(mrc_params);
  1533. /* assume pass */
  1534. all_edges_found = true;
  1535. mrc_params->hte_setup = 1;
  1536. coarse_result = check_rw_coarse(mrc_params, address);
  1537. /* check for failures and margin the byte lane back 128 PI (1 CLK) */
  1538. for (bl = 0; bl < NUM_BYTE_LANES / bl_divisor; bl++) {
  1539. if (coarse_result & (coarse_result_mask << bl)) {
  1540. all_edges_found = false;
  1541. delay[bl] -= FULL_CLK;
  1542. set_wdqs(ch, rk, bl, delay[bl]);
  1543. /* program WDQ timings based on WDQS (WDQ = WDQS - 32 PI) */
  1544. set_wdq(ch, rk, bl, delay[bl] - QRTR_CLK);
  1545. }
  1546. }
  1547. } while (!all_edges_found);
  1548. #ifdef R2R_SHARING
  1549. /* increment "num_ranks_enabled" */
  1550. num_ranks_enabled++;
  1551. /* accumulate "final_delay[][]" values from "delay[]" values for rolling average */
  1552. for (bl = 0; bl < NUM_BYTE_LANES / bl_divisor; bl++) {
  1553. final_delay[ch][bl] += delay[bl];
  1554. set_wdqs(ch, rk, bl, final_delay[ch][bl] / num_ranks_enabled);
  1555. /* program WDQ timings based on WDQS (WDQ = WDQS - 32 PI) */
  1556. set_wdq(ch, rk, bl, final_delay[ch][bl] / num_ranks_enabled - QRTR_CLK);
  1557. }
  1558. #endif
  1559. #endif
  1560. }
  1561. }
  1562. }
  1563. }
  1564. LEAVEFN();
  1565. }
  1566. void prog_page_ctrl(struct mrc_params *mrc_params)
  1567. {
  1568. u32 dpmc0;
  1569. ENTERFN();
  1570. dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
  1571. dpmc0 &= ~DPMC0_PCLSTO_MASK;
  1572. dpmc0 |= (4 << 16);
  1573. dpmc0 |= DPMC0_PREAPWDEN;
  1574. msg_port_write(MEM_CTLR, DPMC0, dpmc0);
  1575. }
  1576. /*
  1577. * This function will perform the READ TRAINING Algorithm on all
  1578. * channels/ranks/byte_lanes simultaneously to minimize execution time.
  1579. *
  1580. * The idea here is to train the VREF and RDQS (and eventually RDQ) values
  1581. * to achieve maximum READ margins. The algorithm will first determine the
  1582. * X coordinate (RDQS setting). This is done by collapsing the VREF eye
  1583. * until we find a minimum required RDQS eye for VREF_MIN and VREF_MAX.
  1584. * Then we take the averages of the RDQS eye at VREF_MIN and VREF_MAX,
  1585. * then average those; this will be the final X coordinate. The algorithm
  1586. * will then determine the Y coordinate (VREF setting). This is done by
  1587. * collapsing the RDQS eye until we find a minimum required VREF eye for
  1588. * RDQS_MIN and RDQS_MAX. Then we take the averages of the VREF eye at
  1589. * RDQS_MIN and RDQS_MAX, then average those; this will be the final Y
  1590. * coordinate.
  1591. *
  1592. * NOTE: this algorithm assumes the eye curves have a one-to-one relationship,
  1593. * meaning for each X the curve has only one Y and vice-a-versa.
  1594. */
  1595. void rd_train(struct mrc_params *mrc_params)
  1596. {
  1597. uint8_t ch; /* channel counter */
  1598. uint8_t rk; /* rank counter */
  1599. uint8_t bl; /* byte lane counter */
  1600. uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
  1601. #ifdef BACKUP_RDQS
  1602. #else
  1603. uint8_t side_x; /* tracks LEFT/RIGHT approach vectors */
  1604. uint8_t side_y; /* tracks BOTTOM/TOP approach vectors */
  1605. /* X coordinate data (passing RDQS values) for approach vectors */
  1606. uint8_t x_coordinate[2][2][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
  1607. /* Y coordinate data (passing VREF values) for approach vectors */
  1608. uint8_t y_coordinate[2][2][NUM_CHANNELS][NUM_BYTE_LANES];
  1609. /* centered X (RDQS) */
  1610. uint8_t x_center[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
  1611. /* centered Y (VREF) */
  1612. uint8_t y_center[NUM_CHANNELS][NUM_BYTE_LANES];
  1613. uint32_t address; /* target address for check_bls_ex() */
  1614. uint32_t result; /* result of check_bls_ex() */
  1615. uint32_t bl_mask; /* byte lane mask for result checking */
  1616. #ifdef R2R_SHARING
  1617. /* used to find placement for rank2rank sharing configs */
  1618. uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
  1619. /* used to find placement for rank2rank sharing configs */
  1620. uint32_t num_ranks_enabled = 0;
  1621. #endif
  1622. #endif
  1623. /* rd_train starts */
  1624. mrc_post_code(0x07, 0x00);
  1625. ENTERFN();
  1626. #ifdef BACKUP_RDQS
  1627. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1628. if (mrc_params->channel_enables & (1 << ch)) {
  1629. for (rk = 0; rk < NUM_RANKS; rk++) {
  1630. if (mrc_params->rank_enables & (1 << rk)) {
  1631. for (bl = 0;
  1632. bl < NUM_BYTE_LANES / bl_divisor;
  1633. bl++) {
  1634. set_rdqs(ch, rk, bl, ddr_rdqs[PLATFORM_ID]);
  1635. }
  1636. }
  1637. }
  1638. }
  1639. }
  1640. #else
  1641. /* initialize x/y_coordinate arrays */
  1642. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1643. if (mrc_params->channel_enables & (1 << ch)) {
  1644. for (rk = 0; rk < NUM_RANKS; rk++) {
  1645. if (mrc_params->rank_enables & (1 << rk)) {
  1646. for (bl = 0;
  1647. bl < NUM_BYTE_LANES / bl_divisor;
  1648. bl++) {
  1649. /* x_coordinate */
  1650. x_coordinate[L][B][ch][rk][bl] = RDQS_MIN;
  1651. x_coordinate[R][B][ch][rk][bl] = RDQS_MAX;
  1652. x_coordinate[L][T][ch][rk][bl] = RDQS_MIN;
  1653. x_coordinate[R][T][ch][rk][bl] = RDQS_MAX;
  1654. /* y_coordinate */
  1655. y_coordinate[L][B][ch][bl] = VREF_MIN;
  1656. y_coordinate[R][B][ch][bl] = VREF_MIN;
  1657. y_coordinate[L][T][ch][bl] = VREF_MAX;
  1658. y_coordinate[R][T][ch][bl] = VREF_MAX;
  1659. }
  1660. }
  1661. }
  1662. }
  1663. }
  1664. /* initialize other variables */
  1665. bl_mask = byte_lane_mask(mrc_params);
  1666. address = get_addr(0, 0);
  1667. #ifdef R2R_SHARING
  1668. /* need to set "final_delay[][]" elements to "0" */
  1669. memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
  1670. #endif
  1671. /* look for passing coordinates */
  1672. for (side_y = B; side_y <= T; side_y++) {
  1673. for (side_x = L; side_x <= R; side_x++) {
  1674. mrc_post_code(0x07, 0x10 + side_y * 2 + side_x);
  1675. /* find passing values */
  1676. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1677. if (mrc_params->channel_enables & (0x1 << ch)) {
  1678. for (rk = 0; rk < NUM_RANKS; rk++) {
  1679. if (mrc_params->rank_enables &
  1680. (0x1 << rk)) {
  1681. /* set x/y_coordinate search starting settings */
  1682. for (bl = 0;
  1683. bl < NUM_BYTE_LANES / bl_divisor;
  1684. bl++) {
  1685. set_rdqs(ch, rk, bl,
  1686. x_coordinate[side_x][side_y][ch][rk][bl]);
  1687. set_vref(ch, bl,
  1688. y_coordinate[side_x][side_y][ch][bl]);
  1689. }
  1690. /* get an address in the target channel/rank */
  1691. address = get_addr(ch, rk);
  1692. /* request HTE reconfiguration */
  1693. mrc_params->hte_setup = 1;
  1694. /* test the settings */
  1695. do {
  1696. /* result[07:00] == failing byte lane (MAX 8) */
  1697. result = check_bls_ex(mrc_params, address);
  1698. /* check for failures */
  1699. if (result & 0xff) {
  1700. /* at least 1 byte lane failed */
  1701. for (bl = 0; bl < NUM_BYTE_LANES / bl_divisor; bl++) {
  1702. if (result &
  1703. (bl_mask << bl)) {
  1704. /* adjust the RDQS values accordingly */
  1705. if (side_x == L)
  1706. x_coordinate[L][side_y][ch][rk][bl] += RDQS_STEP;
  1707. else
  1708. x_coordinate[R][side_y][ch][rk][bl] -= RDQS_STEP;
  1709. /* check that we haven't closed the RDQS_EYE too much */
  1710. if ((x_coordinate[L][side_y][ch][rk][bl] > (RDQS_MAX - MIN_RDQS_EYE)) ||
  1711. (x_coordinate[R][side_y][ch][rk][bl] < (RDQS_MIN + MIN_RDQS_EYE)) ||
  1712. (x_coordinate[L][side_y][ch][rk][bl] ==
  1713. x_coordinate[R][side_y][ch][rk][bl])) {
  1714. /*
  1715. * not enough RDQS margin available at this VREF
  1716. * update VREF values accordingly
  1717. */
  1718. if (side_y == B)
  1719. y_coordinate[side_x][B][ch][bl] += VREF_STEP;
  1720. else
  1721. y_coordinate[side_x][T][ch][bl] -= VREF_STEP;
  1722. /* check that we haven't closed the VREF_EYE too much */
  1723. if ((y_coordinate[side_x][B][ch][bl] > (VREF_MAX - MIN_VREF_EYE)) ||
  1724. (y_coordinate[side_x][T][ch][bl] < (VREF_MIN + MIN_VREF_EYE)) ||
  1725. (y_coordinate[side_x][B][ch][bl] == y_coordinate[side_x][T][ch][bl])) {
  1726. /* VREF_EYE collapsed below MIN_VREF_EYE */
  1727. training_message(ch, rk, bl);
  1728. mrc_post_code(0xEE, 0x70 + side_y * 2 + side_x);
  1729. } else {
  1730. /* update the VREF setting */
  1731. set_vref(ch, bl, y_coordinate[side_x][side_y][ch][bl]);
  1732. /* reset the X coordinate to begin the search at the new VREF */
  1733. x_coordinate[side_x][side_y][ch][rk][bl] =
  1734. (side_x == L) ? RDQS_MIN : RDQS_MAX;
  1735. }
  1736. }
  1737. /* update the RDQS setting */
  1738. set_rdqs(ch, rk, bl, x_coordinate[side_x][side_y][ch][rk][bl]);
  1739. }
  1740. }
  1741. }
  1742. } while (result & 0xff);
  1743. }
  1744. }
  1745. }
  1746. }
  1747. }
  1748. }
  1749. mrc_post_code(0x07, 0x20);
  1750. /* find final RDQS (X coordinate) & final VREF (Y coordinate) */
  1751. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1752. if (mrc_params->channel_enables & (1 << ch)) {
  1753. for (rk = 0; rk < NUM_RANKS; rk++) {
  1754. if (mrc_params->rank_enables & (1 << rk)) {
  1755. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1756. uint32_t temp1;
  1757. uint32_t temp2;
  1758. /* x_coordinate */
  1759. DPF(D_INFO,
  1760. "RDQS T/B eye rank%d lane%d : %d-%d %d-%d\n",
  1761. rk, bl,
  1762. x_coordinate[L][T][ch][rk][bl],
  1763. x_coordinate[R][T][ch][rk][bl],
  1764. x_coordinate[L][B][ch][rk][bl],
  1765. x_coordinate[R][B][ch][rk][bl]);
  1766. /* average the TOP side LEFT & RIGHT values */
  1767. temp1 = (x_coordinate[R][T][ch][rk][bl] + x_coordinate[L][T][ch][rk][bl]) / 2;
  1768. /* average the BOTTOM side LEFT & RIGHT values */
  1769. temp2 = (x_coordinate[R][B][ch][rk][bl] + x_coordinate[L][B][ch][rk][bl]) / 2;
  1770. /* average the above averages */
  1771. x_center[ch][rk][bl] = (uint8_t) ((temp1 + temp2) / 2);
  1772. /* y_coordinate */
  1773. DPF(D_INFO,
  1774. "VREF R/L eye lane%d : %d-%d %d-%d\n",
  1775. bl,
  1776. y_coordinate[R][B][ch][bl],
  1777. y_coordinate[R][T][ch][bl],
  1778. y_coordinate[L][B][ch][bl],
  1779. y_coordinate[L][T][ch][bl]);
  1780. /* average the RIGHT side TOP & BOTTOM values */
  1781. temp1 = (y_coordinate[R][T][ch][bl] + y_coordinate[R][B][ch][bl]) / 2;
  1782. /* average the LEFT side TOP & BOTTOM values */
  1783. temp2 = (y_coordinate[L][T][ch][bl] + y_coordinate[L][B][ch][bl]) / 2;
  1784. /* average the above averages */
  1785. y_center[ch][bl] = (uint8_t) ((temp1 + temp2) / 2);
  1786. }
  1787. }
  1788. }
  1789. }
  1790. }
  1791. #ifdef RX_EYE_CHECK
  1792. /* perform an eye check */
  1793. for (side_y = B; side_y <= T; side_y++) {
  1794. for (side_x = L; side_x <= R; side_x++) {
  1795. mrc_post_code(0x07, 0x30 + side_y * 2 + side_x);
  1796. /* update the settings for the eye check */
  1797. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1798. if (mrc_params->channel_enables & (1 << ch)) {
  1799. for (rk = 0; rk < NUM_RANKS; rk++) {
  1800. if (mrc_params->rank_enables & (1 << rk)) {
  1801. for (bl = 0; bl < NUM_BYTE_LANES / bl_divisor; bl++) {
  1802. if (side_x == L)
  1803. set_rdqs(ch, rk, bl, x_center[ch][rk][bl] - (MIN_RDQS_EYE / 2));
  1804. else
  1805. set_rdqs(ch, rk, bl, x_center[ch][rk][bl] + (MIN_RDQS_EYE / 2));
  1806. if (side_y == B)
  1807. set_vref(ch, bl, y_center[ch][bl] - (MIN_VREF_EYE / 2));
  1808. else
  1809. set_vref(ch, bl, y_center[ch][bl] + (MIN_VREF_EYE / 2));
  1810. }
  1811. }
  1812. }
  1813. }
  1814. }
  1815. /* request HTE reconfiguration */
  1816. mrc_params->hte_setup = 1;
  1817. /* check the eye */
  1818. if (check_bls_ex(mrc_params, address) & 0xff) {
  1819. /* one or more byte lanes failed */
  1820. mrc_post_code(0xee, 0x74 + side_x * 2 + side_y);
  1821. }
  1822. }
  1823. }
  1824. #endif
  1825. mrc_post_code(0x07, 0x40);
  1826. /* set final placements */
  1827. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1828. if (mrc_params->channel_enables & (1 << ch)) {
  1829. for (rk = 0; rk < NUM_RANKS; rk++) {
  1830. if (mrc_params->rank_enables & (1 << rk)) {
  1831. #ifdef R2R_SHARING
  1832. /* increment "num_ranks_enabled" */
  1833. num_ranks_enabled++;
  1834. #endif
  1835. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
  1836. /* x_coordinate */
  1837. #ifdef R2R_SHARING
  1838. final_delay[ch][bl] += x_center[ch][rk][bl];
  1839. set_rdqs(ch, rk, bl, final_delay[ch][bl] / num_ranks_enabled);
  1840. #else
  1841. set_rdqs(ch, rk, bl, x_center[ch][rk][bl]);
  1842. #endif
  1843. /* y_coordinate */
  1844. set_vref(ch, bl, y_center[ch][bl]);
  1845. }
  1846. }
  1847. }
  1848. }
  1849. }
  1850. #endif
  1851. LEAVEFN();
  1852. }
  1853. /*
  1854. * This function will perform the WRITE TRAINING Algorithm on all
  1855. * channels/ranks/byte_lanes simultaneously to minimize execution time.
  1856. *
  1857. * The idea here is to train the WDQ timings to achieve maximum WRITE margins.
  1858. * The algorithm will start with WDQ at the current WDQ setting (tracks WDQS
  1859. * in WR_LVL) +/- 32 PIs (+/- 1/4 CLK) and collapse the eye until all data
  1860. * patterns pass. This is because WDQS will be aligned to WCLK by the
  1861. * Write Leveling algorithm and WDQ will only ever have a 1/2 CLK window
  1862. * of validity.
  1863. */
  1864. void wr_train(struct mrc_params *mrc_params)
  1865. {
  1866. uint8_t ch; /* channel counter */
  1867. uint8_t rk; /* rank counter */
  1868. uint8_t bl; /* byte lane counter */
  1869. uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
  1870. #ifdef BACKUP_WDQ
  1871. #else
  1872. uint8_t side; /* LEFT/RIGHT side indicator (0=L, 1=R) */
  1873. uint32_t temp; /* temporary DWORD */
  1874. /* 2 arrays, for L & R side passing delays */
  1875. uint32_t delay[2][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
  1876. uint32_t address; /* target address for check_bls_ex() */
  1877. uint32_t result; /* result of check_bls_ex() */
  1878. uint32_t bl_mask; /* byte lane mask for result checking */
  1879. #ifdef R2R_SHARING
  1880. /* used to find placement for rank2rank sharing configs */
  1881. uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
  1882. /* used to find placement for rank2rank sharing configs */
  1883. uint32_t num_ranks_enabled = 0;
  1884. #endif
  1885. #endif
  1886. /* wr_train starts */
  1887. mrc_post_code(0x08, 0x00);
  1888. ENTERFN();
  1889. #ifdef BACKUP_WDQ
  1890. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1891. if (mrc_params->channel_enables & (1 << ch)) {
  1892. for (rk = 0; rk < NUM_RANKS; rk++) {
  1893. if (mrc_params->rank_enables & (1 << rk)) {
  1894. for (bl = 0;
  1895. bl < NUM_BYTE_LANES / bl_divisor;
  1896. bl++) {
  1897. set_wdq(ch, rk, bl, ddr_wdq[PLATFORM_ID]);
  1898. }
  1899. }
  1900. }
  1901. }
  1902. }
  1903. #else
  1904. /* initialize "delay" */
  1905. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1906. if (mrc_params->channel_enables & (1 << ch)) {
  1907. for (rk = 0; rk < NUM_RANKS; rk++) {
  1908. if (mrc_params->rank_enables & (1 << rk)) {
  1909. for (bl = 0;
  1910. bl < NUM_BYTE_LANES / bl_divisor;
  1911. bl++) {
  1912. /*
  1913. * want to start with
  1914. * WDQ = (WDQS - QRTR_CLK)
  1915. * +/- QRTR_CLK
  1916. */
  1917. temp = get_wdqs(ch, rk, bl) - QRTR_CLK;
  1918. delay[L][ch][rk][bl] = temp - QRTR_CLK;
  1919. delay[R][ch][rk][bl] = temp + QRTR_CLK;
  1920. }
  1921. }
  1922. }
  1923. }
  1924. }
  1925. /* initialize other variables */
  1926. bl_mask = byte_lane_mask(mrc_params);
  1927. address = get_addr(0, 0);
  1928. #ifdef R2R_SHARING
  1929. /* need to set "final_delay[][]" elements to "0" */
  1930. memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
  1931. #endif
  1932. /*
  1933. * start algorithm on the LEFT side and train each channel/bl
  1934. * until no failures are observed, then repeat for the RIGHT side.
  1935. */
  1936. for (side = L; side <= R; side++) {
  1937. mrc_post_code(0x08, 0x10 + side);
  1938. /* set starting values */
  1939. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1940. if (mrc_params->channel_enables & (1 << ch)) {
  1941. for (rk = 0; rk < NUM_RANKS; rk++) {
  1942. if (mrc_params->rank_enables &
  1943. (1 << rk)) {
  1944. for (bl = 0;
  1945. bl < NUM_BYTE_LANES / bl_divisor;
  1946. bl++) {
  1947. set_wdq(ch, rk, bl, delay[side][ch][rk][bl]);
  1948. }
  1949. }
  1950. }
  1951. }
  1952. }
  1953. /* find passing values */
  1954. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  1955. if (mrc_params->channel_enables & (1 << ch)) {
  1956. for (rk = 0; rk < NUM_RANKS; rk++) {
  1957. if (mrc_params->rank_enables &
  1958. (1 << rk)) {
  1959. /* get an address in the target channel/rank */
  1960. address = get_addr(ch, rk);
  1961. /* request HTE reconfiguration */
  1962. mrc_params->hte_setup = 1;
  1963. /* check the settings */
  1964. do {
  1965. /* result[07:00] == failing byte lane (MAX 8) */
  1966. result = check_bls_ex(mrc_params, address);
  1967. /* check for failures */
  1968. if (result & 0xff) {
  1969. /* at least 1 byte lane failed */
  1970. for (bl = 0; bl < NUM_BYTE_LANES / bl_divisor; bl++) {
  1971. if (result &
  1972. (bl_mask << bl)) {
  1973. if (side == L)
  1974. delay[L][ch][rk][bl] += WDQ_STEP;
  1975. else
  1976. delay[R][ch][rk][bl] -= WDQ_STEP;
  1977. /* check for algorithm failure */
  1978. if (delay[L][ch][rk][bl] != delay[R][ch][rk][bl]) {
  1979. /*
  1980. * margin available
  1981. * update delay setting
  1982. */
  1983. set_wdq(ch, rk, bl,
  1984. delay[side][ch][rk][bl]);
  1985. } else {
  1986. /*
  1987. * no margin available
  1988. * notify the user and halt
  1989. */
  1990. training_message(ch, rk, bl);
  1991. mrc_post_code(0xee, 0x80 + side);
  1992. }
  1993. }
  1994. }
  1995. }
  1996. /* stop when all byte lanes pass */
  1997. } while (result & 0xff);
  1998. }
  1999. }
  2000. }
  2001. }
  2002. }
  2003. /* program WDQ to the middle of passing window */
  2004. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  2005. if (mrc_params->channel_enables & (1 << ch)) {
  2006. for (rk = 0; rk < NUM_RANKS; rk++) {
  2007. if (mrc_params->rank_enables & (1 << rk)) {
  2008. #ifdef R2R_SHARING
  2009. /* increment "num_ranks_enabled" */
  2010. num_ranks_enabled++;
  2011. #endif
  2012. for (bl = 0; bl < NUM_BYTE_LANES / bl_divisor; bl++) {
  2013. DPF(D_INFO,
  2014. "WDQ eye rank%d lane%d : %d-%d\n",
  2015. rk, bl,
  2016. delay[L][ch][rk][bl],
  2017. delay[R][ch][rk][bl]);
  2018. temp = (delay[R][ch][rk][bl] + delay[L][ch][rk][bl]) / 2;
  2019. #ifdef R2R_SHARING
  2020. final_delay[ch][bl] += temp;
  2021. set_wdq(ch, rk, bl,
  2022. final_delay[ch][bl] / num_ranks_enabled);
  2023. #else
  2024. set_wdq(ch, rk, bl, temp);
  2025. #endif
  2026. }
  2027. }
  2028. }
  2029. }
  2030. }
  2031. #endif
  2032. LEAVEFN();
  2033. }
  2034. /*
  2035. * This function will store relevant timing data
  2036. *
  2037. * This data will be used on subsequent boots to speed up boot times
  2038. * and is required for Suspend To RAM capabilities.
  2039. */
  2040. void store_timings(struct mrc_params *mrc_params)
  2041. {
  2042. uint8_t ch, rk, bl;
  2043. struct mrc_timings *mt = &mrc_params->timings;
  2044. for (ch = 0; ch < NUM_CHANNELS; ch++) {
  2045. for (rk = 0; rk < NUM_RANKS; rk++) {
  2046. for (bl = 0; bl < NUM_BYTE_LANES; bl++) {
  2047. mt->rcvn[ch][rk][bl] = get_rcvn(ch, rk, bl);
  2048. mt->rdqs[ch][rk][bl] = get_rdqs(ch, rk, bl);
  2049. mt->wdqs[ch][rk][bl] = get_wdqs(ch, rk, bl);
  2050. mt->wdq[ch][rk][bl] = get_wdq(ch, rk, bl);
  2051. if (rk == 0)
  2052. mt->vref[ch][bl] = get_vref(ch, bl);
  2053. }
  2054. mt->wctl[ch][rk] = get_wctl(ch, rk);
  2055. }
  2056. mt->wcmd[ch] = get_wcmd(ch);
  2057. }
  2058. /* need to save for a case of changing frequency after warm reset */
  2059. mt->ddr_speed = mrc_params->ddr_speed;
  2060. }
  2061. /*
  2062. * The purpose of this function is to ensure the SEC comes out of reset
  2063. * and IA initiates the SEC enabling Memory Scrambling.
  2064. */
  2065. void enable_scrambling(struct mrc_params *mrc_params)
  2066. {
  2067. uint32_t lfsr = 0;
  2068. uint8_t i;
  2069. if (mrc_params->scrambling_enables == 0)
  2070. return;
  2071. ENTERFN();
  2072. /* 32 bit seed is always stored in BIOS NVM */
  2073. lfsr = mrc_params->timings.scrambler_seed;
  2074. if (mrc_params->boot_mode == BM_COLD) {
  2075. /*
  2076. * factory value is 0 and in first boot,
  2077. * a clock based seed is loaded.
  2078. */
  2079. if (lfsr == 0) {
  2080. /*
  2081. * get seed from system clock
  2082. * and make sure it is not all 1's
  2083. */
  2084. lfsr = rdtsc() & 0x0fffffff;
  2085. } else {
  2086. /*
  2087. * Need to replace scrambler
  2088. *
  2089. * get next 32bit LFSR 16 times which is the last
  2090. * part of the previous scrambler vector
  2091. */
  2092. for (i = 0; i < 16; i++)
  2093. lfsr32(&lfsr);
  2094. }
  2095. /* save new seed */
  2096. mrc_params->timings.scrambler_seed = lfsr;
  2097. }
  2098. /*
  2099. * In warm boot or S3 exit, we have the previous seed.
  2100. * In cold boot, we have the last 32bit LFSR which is the new seed.
  2101. */
  2102. lfsr32(&lfsr); /* shift to next value */
  2103. msg_port_write(MEM_CTLR, SCRMSEED, (lfsr & 0x0003ffff));
  2104. for (i = 0; i < 2; i++)
  2105. msg_port_write(MEM_CTLR, SCRMLO + i, (lfsr & 0xaaaaaaaa));
  2106. LEAVEFN();
  2107. }
  2108. /*
  2109. * Configure MCU Power Management Control Register
  2110. * and Scheduler Control Register
  2111. */
  2112. void prog_ddr_control(struct mrc_params *mrc_params)
  2113. {
  2114. u32 dsch;
  2115. u32 dpmc0;
  2116. ENTERFN();
  2117. dsch = msg_port_read(MEM_CTLR, DSCH);
  2118. dsch &= ~(DSCH_OOODIS | DSCH_OOOST3DIS | DSCH_NEWBYPDIS);
  2119. msg_port_write(MEM_CTLR, DSCH, dsch);
  2120. dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
  2121. dpmc0 &= ~DPMC0_DISPWRDN;
  2122. dpmc0 |= (mrc_params->power_down_disable << 25);
  2123. dpmc0 &= ~DPMC0_CLKGTDIS;
  2124. dpmc0 &= ~DPMC0_PCLSTO_MASK;
  2125. dpmc0 |= (4 << 16);
  2126. dpmc0 |= DPMC0_PREAPWDEN;
  2127. msg_port_write(MEM_CTLR, DPMC0, dpmc0);
  2128. /* CMDTRIST = 2h - CMD/ADDR are tristated when no valid command */
  2129. mrc_write_mask(MEM_CTLR, DPMC1, 0x20, 0x30);
  2130. LEAVEFN();
  2131. }
  2132. /*
  2133. * After training complete configure MCU Rank Population Register
  2134. * specifying: ranks enabled, device width, density, address mode
  2135. */
  2136. void prog_dra_drb(struct mrc_params *mrc_params)
  2137. {
  2138. u32 drp;
  2139. u32 dco;
  2140. u8 density = mrc_params->params.density;
  2141. ENTERFN();
  2142. dco = msg_port_read(MEM_CTLR, DCO);
  2143. dco &= ~DCO_IC;
  2144. msg_port_write(MEM_CTLR, DCO, dco);
  2145. drp = 0;
  2146. if (mrc_params->rank_enables & 1)
  2147. drp |= DRP_RKEN0;
  2148. if (mrc_params->rank_enables & 2)
  2149. drp |= DRP_RKEN1;
  2150. if (mrc_params->dram_width == X16) {
  2151. drp |= (1 << 4);
  2152. drp |= (1 << 9);
  2153. }
  2154. /*
  2155. * Density encoding in struct dram_params: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb
  2156. * has to be mapped RANKDENSx encoding (0=1Gb)
  2157. */
  2158. if (density == 0)
  2159. density = 4;
  2160. drp |= ((density - 1) << 6);
  2161. drp |= ((density - 1) << 11);
  2162. /* Address mode can be overwritten if ECC enabled */
  2163. drp |= (mrc_params->address_mode << 14);
  2164. msg_port_write(MEM_CTLR, DRP, drp);
  2165. dco &= ~DCO_PMICTL;
  2166. dco |= DCO_IC;
  2167. msg_port_write(MEM_CTLR, DCO, dco);
  2168. LEAVEFN();
  2169. }
  2170. /* Send DRAM wake command */
  2171. void perform_wake(struct mrc_params *mrc_params)
  2172. {
  2173. ENTERFN();
  2174. dram_wake_command();
  2175. LEAVEFN();
  2176. }
  2177. /*
  2178. * Configure refresh rate and short ZQ calibration interval
  2179. * Activate dynamic self refresh
  2180. */
  2181. void change_refresh_period(struct mrc_params *mrc_params)
  2182. {
  2183. u32 drfc;
  2184. u32 dcal;
  2185. u32 dpmc0;
  2186. ENTERFN();
  2187. drfc = msg_port_read(MEM_CTLR, DRFC);
  2188. drfc &= ~DRFC_TREFI_MASK;
  2189. drfc |= (mrc_params->refresh_rate << 12);
  2190. drfc |= DRFC_REFDBTCLR;
  2191. msg_port_write(MEM_CTLR, DRFC, drfc);
  2192. dcal = msg_port_read(MEM_CTLR, DCAL);
  2193. dcal &= ~DCAL_ZQCINT_MASK;
  2194. dcal |= (3 << 8); /* 63ms */
  2195. msg_port_write(MEM_CTLR, DCAL, dcal);
  2196. dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
  2197. dpmc0 |= (DPMC0_DYNSREN | DPMC0_ENPHYCLKGATE);
  2198. msg_port_write(MEM_CTLR, DPMC0, dpmc0);
  2199. LEAVEFN();
  2200. }
  2201. /*
  2202. * Configure DDRPHY for Auto-Refresh, Periodic Compensations,
  2203. * Dynamic Diff-Amp, ZQSPERIOD, Auto-Precharge, CKE Power-Down
  2204. */
  2205. void set_auto_refresh(struct mrc_params *mrc_params)
  2206. {
  2207. uint32_t channel;
  2208. uint32_t rank;
  2209. uint32_t bl;
  2210. uint32_t bl_divisor = 1;
  2211. uint32_t temp;
  2212. ENTERFN();
  2213. /*
  2214. * Enable Auto-Refresh, Periodic Compensations, Dynamic Diff-Amp,
  2215. * ZQSPERIOD, Auto-Precharge, CKE Power-Down
  2216. */
  2217. for (channel = 0; channel < NUM_CHANNELS; channel++) {
  2218. if (mrc_params->channel_enables & (1 << channel)) {
  2219. /* Enable Periodic RCOMPS */
  2220. mrc_alt_write_mask(DDRPHY, CMPCTRL, 2, 2);
  2221. /* Enable Dynamic DiffAmp & Set Read ODT Value */
  2222. switch (mrc_params->rd_odt_value) {
  2223. case 0:
  2224. temp = 0x3f; /* OFF */
  2225. break;
  2226. default:
  2227. temp = 0x00; /* Auto */
  2228. break;
  2229. }
  2230. for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor) / 2; bl++) {
  2231. /* Override: DIFFAMP, ODT */
  2232. mrc_alt_write_mask(DDRPHY,
  2233. B0OVRCTL + bl * DDRIODQ_BL_OFFSET +
  2234. channel * DDRIODQ_CH_OFFSET,
  2235. temp << 10,
  2236. 0x003ffc00);
  2237. /* Override: DIFFAMP, ODT */
  2238. mrc_alt_write_mask(DDRPHY,
  2239. B1OVRCTL + bl * DDRIODQ_BL_OFFSET +
  2240. channel * DDRIODQ_CH_OFFSET,
  2241. temp << 10,
  2242. 0x003ffc00);
  2243. }
  2244. /* Issue ZQCS command */
  2245. for (rank = 0; rank < NUM_RANKS; rank++) {
  2246. if (mrc_params->rank_enables & (1 << rank))
  2247. dram_init_command(DCMD_ZQCS(rank));
  2248. }
  2249. }
  2250. }
  2251. clear_pointers();
  2252. LEAVEFN();
  2253. }
  2254. /*
  2255. * Depending on configuration enables ECC support
  2256. *
  2257. * Available memory size is decreased, and updated with 0s
  2258. * in order to clear error status. Address mode 2 forced.
  2259. */
  2260. void ecc_enable(struct mrc_params *mrc_params)
  2261. {
  2262. u32 drp;
  2263. u32 dsch;
  2264. u32 ecc_ctrl;
  2265. if (mrc_params->ecc_enables == 0)
  2266. return;
  2267. ENTERFN();
  2268. /* Configuration required in ECC mode */
  2269. drp = msg_port_read(MEM_CTLR, DRP);
  2270. drp &= ~DRP_ADDRMAP_MASK;
  2271. drp |= DRP_ADDRMAP_MAP1;
  2272. drp |= DRP_PRI64BSPLITEN;
  2273. msg_port_write(MEM_CTLR, DRP, drp);
  2274. /* Disable new request bypass */
  2275. dsch = msg_port_read(MEM_CTLR, DSCH);
  2276. dsch |= DSCH_NEWBYPDIS;
  2277. msg_port_write(MEM_CTLR, DSCH, dsch);
  2278. /* Enable ECC */
  2279. ecc_ctrl = (DECCCTRL_SBEEN | DECCCTRL_DBEEN | DECCCTRL_ENCBGEN);
  2280. msg_port_write(MEM_CTLR, DECCCTRL, ecc_ctrl);
  2281. /* Assume 8 bank memory, one bank is gone for ECC */
  2282. mrc_params->mem_size -= mrc_params->mem_size / 8;
  2283. /* For S3 resume memory content has to be preserved */
  2284. if (mrc_params->boot_mode != BM_S3) {
  2285. select_hte();
  2286. hte_mem_init(mrc_params, MRC_MEM_INIT);
  2287. select_mem_mgr();
  2288. }
  2289. LEAVEFN();
  2290. }
  2291. /*
  2292. * Execute memory test
  2293. * if error detected it is indicated in mrc_params->status
  2294. */
  2295. void memory_test(struct mrc_params *mrc_params)
  2296. {
  2297. uint32_t result = 0;
  2298. ENTERFN();
  2299. select_hte();
  2300. result = hte_mem_init(mrc_params, MRC_MEM_TEST);
  2301. select_mem_mgr();
  2302. DPF(D_INFO, "Memory test result %x\n", result);
  2303. mrc_params->status = ((result == 0) ? MRC_SUCCESS : MRC_E_MEMTEST);
  2304. LEAVEFN();
  2305. }
  2306. /* Lock MCU registers at the end of initialization sequence */
  2307. void lock_registers(struct mrc_params *mrc_params)
  2308. {
  2309. u32 dco;
  2310. ENTERFN();
  2311. dco = msg_port_read(MEM_CTLR, DCO);
  2312. dco &= ~(DCO_PMICTL | DCO_PMIDIS);
  2313. dco |= (DCO_DRPLOCK | DCO_CPGCLOCK);
  2314. msg_port_write(MEM_CTLR, DCO, dco);
  2315. LEAVEFN();
  2316. }