asm_init.S 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. /*
  2. * (C) Copyright 2004-05; Tundra Semiconductor Corp.
  3. *
  4. * Added automatic detect of SDC settings
  5. * Copyright (c) 2005 Freescale Semiconductor, Inc.
  6. * Maintainer tie-fei.zang@freescale.com
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /*
  24. * FILENAME: asm_init.s
  25. *
  26. * Originator: Alex Bounine
  27. *
  28. * DESCRIPTION:
  29. * Initialization code for the Tundra Tsi108 bridge chip
  30. *
  31. */
  32. #include <config.h>
  33. #include <version.h>
  34. #include <ppc_asm.tmpl>
  35. #include <ppc_defs.h>
  36. #include <asm/processor.h>
  37. #include <tsi108.h>
  38. /*
  39. * Build Configuration Options
  40. */
  41. /* #define DISABLE_PBM disables usage of PB Master */
  42. /* #define SDC_HARDCODED_INIT config SDRAM controller with hardcoded values */
  43. /* #define SDC_AUTOPRECH_EN enable SDRAM auto precharge */
  44. /*
  45. * Hardcoded SDC settings
  46. */
  47. #ifdef SDC_HARDCODED_INIT
  48. /* Micron MT9HTF6472AY-40EA1 : Unbuffered, 512MB, 400, CL3, Single Rank */
  49. #define VAL_SD_REFRESH (0x61A)
  50. #define VAL_SD_TIMING (0x0308336b)
  51. #define VAL_SD_D0_CTRL (0x07100021) /* auto-precharge disabled */
  52. #define VAL_SD_D0_BAR (0x0FE00000) /* 512MB @ 0x00000000 */
  53. #define VAL_SD_D1_CTRL (0x07100021) /* auto-precharge disabled */
  54. #define VAL_SD_D1_BAR (0x0FE00200) /* 512MB @ 0x20000000 */
  55. #endif /* SDC_HARDCODED_INIT */
  56. /*
  57. CPU Configuration:
  58. CPU Address and Data Parity enables.
  59. #define CPU_AP
  60. #define CPU_DP
  61. */
  62. /*
  63. * Macros
  64. * !!! Attention !!! Macros LOAD_PTR, LOAD_U32 and LOAD_MEM defined below are
  65. * expected to work correctly for the CSR space within 32KB range.
  66. *
  67. * LOAD_PTR and LOAD_U32 - load specified register with a 32 bit constant.
  68. * These macros are absolutely identical except their names. This difference
  69. * is provided intentionally for better readable code.
  70. */
  71. #define LOAD_PTR(reg,const32) \
  72. addis reg,r0,const32@h; ori reg,reg,const32@l
  73. #define LOAD_U32(reg,const32) \
  74. addis reg,r0,const32@h; ori reg,reg,const32@l
  75. /* LOADMEM initializes a register with the contents of a specified 32-bit
  76. * memory location, usually a CSR value.
  77. */
  78. #define LOAD_MEM(reg,addr32) \
  79. addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)
  80. #ifndef SDC_HARDCODED_INIT
  81. sdc_clk_sync:
  82. /* MHz: 0,0,183,100,133,167,200,233 */
  83. .long 0, 0, 6, 10, 8, 6, 5, 4 /* nSec */
  84. #endif
  85. /*
  86. * board_asm_init() - early initialization function. Coded to be portable to
  87. * dual-CPU configuration.
  88. * Checks CPU number and performs board HW initialization if called for CPU0.
  89. * Registers used: r3,r4,r5,r6,r19,r29
  90. *
  91. * NOTE: For dual-CPU configuration only CPU0 is allowed to configure Tsi108
  92. * and the rest of the board. Current implementation demonstrates two
  93. * possible ways to identify CPU number:
  94. * - for MPC74xx platform: uses MSSCR0[ID] bit as defined in UM.
  95. * - for PPC750FX/GX boards: uses WHO_AM_I bit reported by Tsi108.
  96. */
  97. .globl board_asm_init
  98. board_asm_init:
  99. mflr r19 /* Save LR to be able return later. */
  100. bl icache_enable /* Enable icache to reduce reads from flash. */
  101. /* Initialize pointer to Tsi108 register space */
  102. LOAD_PTR(r29,CFG_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */
  103. ori r4,r29,TSI108_PB_REG_OFFSET
  104. /* Check Processor Version Number */
  105. mfspr r3, PVR
  106. rlwinm r3,r3,16,16,23 /* get ((Processor Version Number) & 0xFF00) */
  107. cmpli 0,0,r3,0x8000 /* MPC74xx */
  108. bne cont_brd_init
  109. /*
  110. * For MPC744x/5x enable extended BATs[4-7]
  111. * Sri: Set HIGH_BAT_EN and XBSEN, and SPD =1
  112. * to disable prefetch
  113. */
  114. mfspr r5, HID0
  115. oris r5, r5, 0x0080 /* Set HID0[HIGH_BAT_EN] bit #8 */
  116. ori r5, r5, 0x0380 /* Set SPD,XBSEN,SGE bits #22,23,24 */
  117. mtspr HID0, r5
  118. isync
  119. sync
  120. /* Adding code to disable external interventions in MPX bus mode */
  121. mfspr r3, 1014
  122. oris r3, r3, 0x0100 /* Set the EIDIS bit in MSSCR0: bit 7 */
  123. mtspr 1014, r3
  124. isync
  125. sync
  126. /* Sri: code to enable FP unit */
  127. mfmsr r3
  128. ori r3, r3, 0x2000
  129. mtmsr r3
  130. isync
  131. sync
  132. /* def CONFIG_DUAL_CPU
  133. * For MPC74xx processor, use MSSCR0[ID] bit to identify CPU number.
  134. */
  135. #if(1)
  136. mfspr r3,1014 /* read MSSCR0 */
  137. rlwinm. r3,r3,27,31,31 /* get processor ID number */
  138. mtspr SPRN_PIR,r3 /* Save CPU ID */
  139. sync
  140. bne init_done
  141. b do_tsi108_init
  142. cont_brd_init:
  143. /* An alternative method of checking the processor number (in addition
  144. * to configuration using MSSCR0[ID] bit on MPC74xx).
  145. * Good for IBM PPC750FX/GX.
  146. */
  147. lwz r3,PB_BUS_MS_SELECT(r4) /* read PB_ID register */
  148. rlwinm. r3,r3,24,31,31 /* get processor ID number */
  149. bne init_done
  150. #else
  151. cont_brd_init:
  152. #endif /* CONFIG_DUAL_CPU */
  153. /* Initialize Tsi108 chip */
  154. do_tsi108_init:
  155. /*
  156. * Adjust HLP/Flash parameters. By default after reset the HLP port is
  157. * set to support slow devices. Better performance can be achived when
  158. * an optimal parameters are used for specific EPROM device.
  159. * NOTE: This should be performed ASAP for the emulation platform
  160. * because it has 5MHz HLP clocking.
  161. */
  162. #ifdef CONFIG_TSI108EMU
  163. ori r4,r29,TSI108_HLP_REG_OFFSET
  164. LOAD_U32(r5,0x434422c0)
  165. stw r5,0x08(r4) /* set HLP B0_CTRL0 */
  166. sync
  167. LOAD_U32(r5,0xd0012000)
  168. stw r5,0x0c(r4) /* set HLP B0_CTRL1 */
  169. sync
  170. #endif
  171. /* Initialize PB interface. */
  172. ori r4,r29,TSI108_PB_REG_OFFSET
  173. #if (CFG_TSI108_CSR_BASE != CFG_TSI108_CSR_RST_BASE)
  174. /* Relocate (if required) Tsi108 registers. Set new value for
  175. * PB_REG_BAR:
  176. * Note we are in the 32-bit address mode.
  177. */
  178. LOAD_U32(r5,(CFG_TSI108_CSR_BASE | 0x01)) /* PB_REG_BAR: BA + EN */
  179. stw r5,PB_REG_BAR(r4)
  180. andis. r29,r5,0xFFFF
  181. sync
  182. ori r4,r29,TSI108_PB_REG_OFFSET
  183. #endif
  184. /* Set PB Slave configuration register */
  185. LOAD_U32(r5,0x00002481) /* PB_SCR: TEA enabled,AACK delay = 1 */
  186. lwz r3, PB_RSR(r4) /* get PB bus mode */
  187. xori r3,r3,0x0001 /* mask PB_BMODE: r3 -> (0 = 60X, 1 = MPX) */
  188. rlwimi r5,r3,14,17,17 /* for MPX: set DTI_MODE bit */
  189. stw r5,PB_SCR(r4)
  190. sync
  191. /* Configure PB Arbiter */
  192. lwz r5,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */
  193. li r3, 0x00F0 /* ARB_PIPELINE_DEP mask */
  194. #ifdef DISABLE_PBM
  195. ori r3,r3,0x1000 /* add PBM_EN to clear (enabled by default) */
  196. #endif
  197. andc r5,r5,r3 /* Clear the masked bit fields */
  198. ori r5,r5,0x0001 /* Set pipeline depth */
  199. stw r5,PB_ARB_CTRL(r4)
  200. #if (0) /* currently using the default settings for PBM after reset */
  201. LOAD_U32(r5,0x) /* value for PB_MCR */
  202. stw r5,PB_MCR(r4)
  203. sync
  204. LOAD_U32(r5,0x) /* value for PB_MCMD */
  205. stw r5,PB_MCMD(r4)
  206. sync
  207. #endif
  208. /* Disable or enable PVT based on processor bus frequency
  209. * 1. Read CG_PWRUP_STATUS register field bits 18,17,16
  210. * 2. See if the value is < or > 133mhz (18:16 = 100)
  211. * 3. If > enable PVT
  212. */
  213. LOAD_U32(r3,0xC0002234)
  214. lwz r3,0(r3)
  215. rlwinm r3,r3,16,29,31
  216. cmpi 0,0,r3,0x0004
  217. bgt sdc_init
  218. #ifndef CONFIG_TSI108EMU
  219. /* FIXME: Disable PB calibration control for any real Tsi108 board */
  220. li r5,0x0101 /* disable calibration control */
  221. stw r5,PB_PVT_CTRL2(r4)
  222. sync
  223. #endif
  224. /* Initialize SDRAM controller. */
  225. sdc_init:
  226. #ifndef SDC_HARDCODED_INIT
  227. /* get SDC clock prior doing sdram controller autoconfig */
  228. ori r4,r29,TSI108_CLK_REG_OFFSET /* r4 - ptr to CG registers */
  229. lwz r3, CG_PWRUP_STATUS(r4) /* get CG configuration */
  230. rlwinm r3,r3,12,29,31 /* r3 - SD clk */
  231. lis r5,sdc_clk_sync@h
  232. ori r5,r5,sdc_clk_sync@l
  233. /* Sri: At this point check if r3 = 001. If yes,
  234. * the memory frequency should be same as the
  235. * MPX bus frequency
  236. */
  237. cmpi 0,0,r3,0x0001
  238. bne get_nsec
  239. lwz r6, CG_PWRUP_STATUS(r4)
  240. rlwinm r6,r6,16,29,31
  241. mr r3,r6
  242. get_nsec:
  243. rlwinm r3,r3,2,0,31
  244. lwzx r9,r5,r3 /* get SD clk rate in nSec */
  245. /* ATTN: r9 will be used by SPD routine */
  246. #endif /* !SDC_HARDCODED_INIT */
  247. ori r4,r29,TSI108_SD_REG_OFFSET /* r4 - ptr to SDRAM registers */
  248. /* Initialize SDRAM controller. SDRAM Size = 512MB, One DIMM. */
  249. LOAD_U32(r5,0x00)
  250. stw r5,SD_INT_ENABLE(r4) /* Ensure that interrupts are disabled */
  251. #ifdef ENABLE_SDRAM_ECC
  252. li r5, 0x01
  253. #endif /* ENABLE_SDRAM_ECC */
  254. stw r5,SD_ECC_CTRL(r4) /* Enable/Disable ECC */
  255. sync
  256. #ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */
  257. /* First read the CG_PWRUP_STATUS register to get the
  258. * memory speed from bits 22,21,20
  259. */
  260. LOAD_U32(r3,0xC0002234)
  261. lwz r3,0(r3)
  262. rlwinm r3,r3,12,29,31
  263. /* Now first check for 166, then 200, or default */
  264. cmpi 0,0,r3,0x0005
  265. bne check_for_200mhz
  266. /* set values for 166 Mhz memory speed
  267. * Set refresh rate and timing parameters
  268. */
  269. LOAD_U32(r5,0x00000515)
  270. stw r5,SD_REFRESH(r4)
  271. LOAD_U32(r5,0x03073368)
  272. stw r5,SD_TIMING(r4)
  273. sync
  274. /* Initialize DIMM0 control and BAR registers */
  275. LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
  276. #ifdef SDC_AUTOPRECH_EN
  277. oris r5,r5,0x0001 /* set auto precharge EN bit */
  278. #endif
  279. stw r5,SD_D0_CTRL(r4)
  280. LOAD_U32(r5,VAL_SD_D0_BAR)
  281. stw r5,SD_D0_BAR(r4)
  282. sync
  283. /* Initialize DIMM1 control and BAR registers
  284. * (same as dimm 0, next 512MB, disabled)
  285. */
  286. LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */
  287. #ifdef SDC_AUTOPRECH_EN
  288. oris r5,r5,0x0001 /* set auto precharge EN bit */
  289. #endif
  290. stw r5,SD_D1_CTRL(r4)
  291. LOAD_U32(r5,VAL_SD_D1_BAR)
  292. stw r5,SD_D1_BAR(r4)
  293. sync
  294. b sdc_init_done
  295. check_for_200mhz:
  296. cmpi 0,0,r3,0x0006
  297. bne set_default_values
  298. /* set values for 200Mhz memory speed
  299. * Set refresh rate and timing parameters
  300. */
  301. LOAD_U32(r5,0x0000061a)
  302. stw r5,SD_REFRESH(r4)
  303. LOAD_U32(r5,0x03083348)
  304. stw r5,SD_TIMING(r4)
  305. sync
  306. /* Initialize DIMM0 control and BAR registers */
  307. LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
  308. #ifdef SDC_AUTOPRECH_EN
  309. oris r5,r5,0x0001 /* set auto precharge EN bit */
  310. #endif
  311. stw r5,SD_D0_CTRL(r4)
  312. LOAD_U32(r5,VAL_SD_D0_BAR)
  313. stw r5,SD_D0_BAR(r4)
  314. sync
  315. /* Initialize DIMM1 control and BAR registers
  316. * (same as dimm 0, next 512MB, disabled)
  317. */
  318. LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */
  319. #ifdef SDC_AUTOPRECH_EN
  320. oris r5,r5,0x0001 /* set auto precharge EN bit */
  321. #endif
  322. stw r5,SD_D1_CTRL(r4)
  323. LOAD_U32(r5,VAL_SD_D1_BAR)
  324. stw r5,SD_D1_BAR(r4)
  325. sync
  326. b sdc_init_done
  327. set_default_values:
  328. /* Set refresh rate and timing parameters */
  329. LOAD_U32(r5,VAL_SD_REFRESH)
  330. stw r5,SD_REFRESH(r4)
  331. LOAD_U32(r5,VAL_SD_TIMING)
  332. stw r5,SD_TIMING(r4)
  333. sync
  334. /* Initialize DIMM0 control and BAR registers */
  335. LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */
  336. #ifdef SDC_AUTOPRECH_EN
  337. oris r5,r5,0x0001 /* set auto precharge EN bit */
  338. #endif
  339. stw r5,SD_D0_CTRL(r4)
  340. LOAD_U32(r5,VAL_SD_D0_BAR)
  341. stw r5,SD_D0_BAR(r4)
  342. sync
  343. /* Initialize DIMM1 control and BAR registers
  344. * (same as dimm 0, next 512MB, disabled)
  345. */
  346. LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */
  347. #ifdef SDC_AUTOPRECH_EN
  348. oris r5,r5,0x0001 /* set auto precharge EN bit */
  349. #endif
  350. stw r5,SD_D1_CTRL(r4)
  351. LOAD_U32(r5,VAL_SD_D1_BAR)
  352. stw r5,SD_D1_BAR(r4)
  353. sync
  354. #else /* !SDC_HARDCODED_INIT */
  355. bl tsi108_sdram_spd /* automatically detect SDC settings */
  356. #endif /* SDC_HARDCODED_INIT */
  357. sdc_init_done:
  358. #ifdef DISABLE_PBM
  359. LOAD_U32(r5,0x00000030) /* PB_EN + OCN_EN */
  360. #else
  361. LOAD_U32(r5,0x00000230) /* PB_EN + OCN_EN + PB/OCN=80/20 */
  362. #endif /* DISABLE_PBM */
  363. #ifdef CONFIG_TSI108EMU
  364. oris r5,r5,0x0010 /* set EMULATION_MODE bit */
  365. #endif
  366. stw r5,SD_CTRL(r4)
  367. eieio
  368. sync
  369. /* Enable SDRAM access */
  370. oris r5,r5,0x8000 /* start SDC: set SD_CTRL[ENABLE] bit */
  371. stw r5,SD_CTRL(r4)
  372. sync
  373. wait_init_complete:
  374. lwz r5,SD_STATUS(r4)
  375. andi. r5,r5,0x0001
  376. /* wait until SDRAM initialization is complete */
  377. beq wait_init_complete
  378. /* Map SDRAM into the processor bus address space */
  379. ori r4,r29,TSI108_PB_REG_OFFSET
  380. /* Setup BARs associated with direct path PB<->SDRAM */
  381. /* PB_SDRAM_BAR1:
  382. * provides a direct path to the main system memory (cacheable SDRAM)
  383. */
  384. /* BA=0,Size=512MB, ENable, No Addr.Translation */
  385. LOAD_U32(r5, 0x00000011)
  386. stw r5,PB_SDRAM_BAR1(r4)
  387. sync
  388. /* Make sure that PB_SDRAM_BAR1 decoder is set
  389. * (to allow following immediate read from SDRAM)
  390. */
  391. lwz r5,PB_SDRAM_BAR1(r4)
  392. sync
  393. /* PB_SDRAM_BAR2:
  394. * provides non-cacheable alias (via the direct path) to main
  395. * system memory.
  396. * Size = 512MB, ENable, Addr.Translation - ON,
  397. * BA = 0x0_40000000, TA = 0x0_00000000
  398. */
  399. LOAD_U32(r5, 0x40010011)
  400. stw r5,PB_SDRAM_BAR2(r4)
  401. sync
  402. /* Make sure that PB_SDRAM_BAR2 decoder is set
  403. * (to allow following immediate read from SDRAM)
  404. */
  405. lwz r5,PB_SDRAM_BAR2(r4)
  406. sync
  407. init_done:
  408. /* All done. Restore LR and return. */
  409. mtlr r19
  410. blr
  411. #if (0)
  412. /*
  413. * init_cpu1
  414. * This routine enables CPU1 on the dual-processor system.
  415. * Now there is only one processor in the system
  416. */
  417. .global enable_cpu1
  418. enable_cpu1:
  419. lis r3,Tsi108_Base@ha /* Get Grendel CSR Base Addr */
  420. addi r3,r3,Tsi108_Base@l
  421. lwz r3,0(r3) /* R3 = CSR Base Addr */
  422. ori r4,r3,TSI108_PB_REG_OFFSET
  423. lwz r3,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */
  424. ori r3,r3,0x0200 /* Set M1_EN bit */
  425. stw r3,PB_ARB_CTRL(r4)
  426. blr
  427. #endif
  428. /*
  429. * enable_EI
  430. * Enable CPU core external interrupt
  431. */
  432. .global enable_EI
  433. enable_EI:
  434. mfmsr r3
  435. ori r3,r3,0x8000 /* set EE bit */
  436. mtmsr r3
  437. blr
  438. /*
  439. * disable_EI
  440. * Disable CPU core external interrupt
  441. */
  442. .global disable_EI
  443. disable_EI:
  444. mfmsr r3
  445. li r4,-32768 /* aka "li r4,0x8000" */
  446. andc r3,r3,r4 /* clear EE bit */
  447. mtmsr r3
  448. blr
  449. #ifdef ENABLE_SDRAM_ECC
  450. /* enables SDRAM ECC */
  451. .global enable_ECC
  452. enable_ECC:
  453. ori r4,r29,TSI108_SD_REG_OFFSET
  454. lwz r3,SD_ECC_CTRL(r4) /* Read SDRAM ECC Control Register */
  455. ori r3,r3,0x0001 /* Set ECC_EN bit */
  456. stw r3,SD_ECC_CTRL(r4)
  457. blr
  458. /*
  459. * clear_ECC_err
  460. * Clears all pending SDRAM ECC errors
  461. * (normally after SDRAM scrubbing/initialization)
  462. */
  463. .global clear_ECC_err
  464. clear_ECC_err:
  465. ori r4,r29,TSI108_SD_REG_OFFSET
  466. ori r3,r0,0x0030 /* ECC_UE_INT + ECC_CE_INT bits */
  467. stw r3,SD_INT_STATUS(r4)
  468. blr
  469. #endif /* ENABLE_SDRAM_ECC */
  470. #ifndef SDC_HARDCODED_INIT
  471. /* SDRAM SPD Support */
  472. #define SD_I2C_CTRL1 (0x400)
  473. #define SD_I2C_CTRL2 (0x404)
  474. #define SD_I2C_RD_DATA (0x408)
  475. #define SD_I2C_WR_DATA (0x40C)
  476. /*
  477. * SDRAM SPD Support Macros
  478. */
  479. #define SPD_DIMM0 (0x00000100)
  480. #define SPD_DIMM1 (0x00000200) /* SPD_DIMM1 was 0x00000000 */
  481. #define SPD_RDIMM (0x01)
  482. #define SPD_UDIMM (0x02)
  483. #define SPD_CAS_3 0x8
  484. #define SPD_CAS_4 0x10
  485. #define SPD_CAS_5 0x20
  486. #define ERR_NO_DIMM_FOUND (0xdb0)
  487. #define ERR_TRAS_FAIL (0xdb1)
  488. #define ERR_TRCD_FAIL (0xdb2)
  489. #define ERR_TRP_FAIL (0xdb3)
  490. #define ERR_TWR_FAIL (0xdb4)
  491. #define ERR_UNKNOWN_PART (0xdb5)
  492. #define ERR_NRANK_INVALID (0xdb6)
  493. #define ERR_DIMM_SIZE (0xdb7)
  494. #define ERR_ADDR_MODE (0xdb8)
  495. #define ERR_RFRSH_RATE (0xdb9)
  496. #define ERR_DIMM_TYPE (0xdba)
  497. #define ERR_CL_VALUE (0xdbb)
  498. #define ERR_TRFC_FAIL (0xdbc)
  499. /* READ_SPD requirements:
  500. * byte - byte address in SPD device (0 - 255)
  501. * r3 = will return data read from I2C Byte location
  502. * r4 - unchanged (SDC base addr)
  503. * r5 - clobbered in routine (I2C status)
  504. * r10 - number of DDR slot where first SPD device is detected
  505. */
  506. #define READ_SPD(byte_num) \
  507. addis r3, 0, byte_num@l; \
  508. or r3, r3, r10; \
  509. ori r3, r3, 0x0A; \
  510. stw r3, SD_I2C_CTRL1(r4); \
  511. li r3, I2C_CNTRL2_START; \
  512. stw r3, SD_I2C_CTRL2(r4); \
  513. eieio; \
  514. sync; \
  515. li r3, 0x100; \
  516. 1:; \
  517. addic. r3, r3, -1; \
  518. bne 1b; \
  519. 2:; \
  520. lwz r5, SD_I2C_CTRL2(r4); \
  521. rlwinm. r3,r5,0,23,23; \
  522. bne 2b; \
  523. rlwinm. r3,r5,0,3,3; \
  524. lwz r3,SD_I2C_RD_DATA(r4)
  525. #define SPD_MIN_RFRSH (0x80)
  526. #define SPD_MAX_RFRSH (0x85)
  527. refresh_rates: /* in nSec */
  528. .long 15625 /* Normal (0x80) */
  529. .long 3900 /* Reduced 0.25x (0x81) */
  530. .long 7800 /* Reduced 0.5x (0x82) */
  531. .long 31300 /* Extended 2x (0x83) */
  532. .long 62500 /* Extended 4x (0x84) */
  533. .long 125000 /* Extended 8x (0x85) */
  534. /*
  535. * tsi108_sdram_spd
  536. *
  537. * Inittializes SDRAM Controller using DDR2 DIMM Serial Presence Detect data
  538. * Uses registers: r4 - SDC base address (not changed)
  539. * r9 - SDC clocking period in nSec
  540. * Changes registers: r3,r5,r6,r7,r8,r10,r11
  541. */
  542. tsi108_sdram_spd:
  543. li r10,SPD_DIMM0
  544. xor r11,r11,r11 /* DIMM Base Address: starts from 0 */
  545. do_first_dimm:
  546. /* Program Refresh Rate Register */
  547. READ_SPD(12) /* get Refresh Rate */
  548. beq check_next_slot
  549. li r5, ERR_RFRSH_RATE
  550. cmpi 0,0,r3,SPD_MIN_RFRSH
  551. ble spd_fail
  552. cmpi 0,0,r3,SPD_MAX_RFRSH
  553. bgt spd_fail
  554. addi r3,r3,-SPD_MIN_RFRSH
  555. rlwinm r3,r3,2,0,31
  556. lis r5,refresh_rates@h
  557. ori r5,r5,refresh_rates@l
  558. lwzx r5,r5,r3 /* get refresh rate in nSec */
  559. divwu r5,r5,r9 /* calculate # of SDC clocks */
  560. stw r5,SD_REFRESH(r4) /* Set refresh rate */
  561. sync
  562. /* Program SD Timing Register */
  563. li r7, 0 /* clear r7 prior parameter collection */
  564. READ_SPD(20) /* get DIMM type: Registered or Unbuffered */
  565. beq spd_read_fail
  566. li r5, ERR_DIMM_TYPE
  567. cmpi 0,0,r3,SPD_UDIMM
  568. beq do_cl
  569. cmpi 0,0,r3,SPD_RDIMM
  570. bne spd_fail
  571. oris r7,r7,0x1000 /* set SD_TIMING[DIMM_TYPE] bit */
  572. do_cl:
  573. READ_SPD(18) /* Get CAS Latency */
  574. beq spd_read_fail
  575. li r5,ERR_CL_VALUE
  576. andi. r6,r3,SPD_CAS_3
  577. beq cl_4
  578. li r6,3
  579. b set_cl
  580. cl_4:
  581. andi. r6,r3,SPD_CAS_4
  582. beq cl_5
  583. li r6,4
  584. b set_cl
  585. cl_5:
  586. andi. r6,r3,SPD_CAS_5
  587. beq spd_fail
  588. li r6,5
  589. set_cl:
  590. rlwimi r7,r6,24,5,7
  591. READ_SPD(30) /* Get tRAS */
  592. beq spd_read_fail
  593. divwu r6,r3,r9
  594. mullw r8,r6,r9
  595. subf. r8,r8,r3
  596. beq set_tras
  597. addi r6,r6,1
  598. set_tras:
  599. li r5,ERR_TRAS_FAIL
  600. cmpi 0,0,r6,0x0F /* max supported value */
  601. bgt spd_fail
  602. rlwimi r7,r6,16,12,15
  603. READ_SPD(29) /* Get tRCD */
  604. beq spd_read_fail
  605. /* right shift tRCD by 2 bits as per DDR2 spec */
  606. rlwinm r3,r3,30,2,31
  607. divwu r6,r3,r9
  608. mullw r8,r6,r9
  609. subf. r8,r8,r3
  610. beq set_trcd
  611. addi r6,r6,1
  612. set_trcd:
  613. li r5,ERR_TRCD_FAIL
  614. cmpi 0,0,r6,0x07 /* max supported value */
  615. bgt spd_fail
  616. rlwimi r7,r6,12,17,19
  617. READ_SPD(27) /* Get tRP value */
  618. beq spd_read_fail
  619. rlwinm r3,r3,30,2,31 /* right shift tRP by 2 bits as per DDR2 spec */
  620. divwu r6,r3,r9
  621. mullw r8,r6,r9
  622. subf. r8,r8,r3
  623. beq set_trp
  624. addi r6,r6,1
  625. set_trp:
  626. li r5,ERR_TRP_FAIL
  627. cmpi 0,0,r6,0x07 /* max supported value */
  628. bgt spd_fail
  629. rlwimi r7,r6,8,21,23
  630. READ_SPD(36) /* Get tWR value */
  631. beq spd_read_fail
  632. rlwinm r3,r3,30,2,31 /* right shift tWR by 2 bits as per DDR2 spec */
  633. divwu r6,r3,r9
  634. mullw r8,r6,r9
  635. subf. r8,r8,r3
  636. beq set_twr
  637. addi r6,r6,1
  638. set_twr:
  639. addi r6,r6,-1 /* Tsi108 SDC always gives one extra clock */
  640. li r5,ERR_TWR_FAIL
  641. cmpi 0,0,r6,0x07 /* max supported value */
  642. bgt spd_fail
  643. rlwimi r7,r6,5,24,26
  644. READ_SPD(42) /* Get tRFC */
  645. beq spd_read_fail
  646. li r5, ERR_TRFC_FAIL
  647. /* Tsi108 spec: tRFC=(tRFC + 1)/2 */
  648. addi r3,r3,1
  649. rlwinm. r3,r3,31,1,31 /* divide by 2 */
  650. beq spd_fail
  651. divwu r6,r3,r9
  652. mullw r8,r6,r9
  653. subf. r8,r8,r3
  654. beq set_trfc
  655. addi r6,r6,1
  656. set_trfc:
  657. cmpi 0,0,r6,0x1F /* max supported value */
  658. bgt spd_fail
  659. rlwimi r7,r6,0,27,31
  660. stw r7,SD_TIMING(r4)
  661. sync
  662. /*
  663. * The following two registers are set on per-DIMM basis.
  664. * The SD_REFRESH and SD_TIMING settings are common for both DIMMS
  665. */
  666. do_each_dimm:
  667. /* Program SDRAM DIMM Control Register */
  668. li r7, 0 /* clear r7 prior parameter collection */
  669. READ_SPD(13) /* Get Primary SDRAM Width */
  670. beq spd_read_fail
  671. cmpi 0,0,r3,4 /* Check for 4-bit SDRAM */
  672. beq do_nbank
  673. oris r7,r7,0x0010 /* Set MEM_WIDTH bit */
  674. do_nbank:
  675. READ_SPD(17) /* Get Number of banks on SDRAM device */
  676. beq spd_read_fail
  677. /* Grendel only distinguish betw. 4 or 8-bank memory parts */
  678. li r5,ERR_UNKNOWN_PART /* non-supported memory part */
  679. cmpi 0,0,r3,4
  680. beq do_nrank
  681. cmpi 0,0,r3,8
  682. bne spd_fail
  683. ori r7,r7,0x1000
  684. do_nrank:
  685. READ_SPD(5) /* Get # of Ranks */
  686. beq spd_read_fail
  687. li r5,ERR_NRANK_INVALID
  688. andi. r6,r3,0x7 /* Use bits [2..0] only */
  689. beq do_addr_mode
  690. cmpi 0,0,r6,1
  691. bgt spd_fail
  692. rlwimi r7,r6,8,23,23
  693. do_addr_mode:
  694. READ_SPD(4) /* Get # of Column Addresses */
  695. beq spd_read_fail
  696. li r5, ERR_ADDR_MODE
  697. andi. r3,r3,0x0f /* cut off reserved bits */
  698. cmpi 0,0,r3,8
  699. ble spd_fail
  700. cmpi 0,0,r3,15
  701. bgt spd_fail
  702. addi r6,r3,-8 /* calculate ADDR_MODE parameter */
  703. rlwimi r7,r6,4,24,27 /* set ADDR_MODE field */
  704. set_dimm_ctrl:
  705. #ifdef SDC_AUTOPRECH_EN
  706. oris r7,r7,0x0001 /* set auto precharge EN bit */
  707. #endif
  708. ori r7,r7,1 /* set ENABLE bit */
  709. cmpi 0,0,r10,SPD_DIMM0
  710. bne 1f
  711. stw r7,SD_D0_CTRL(r4)
  712. sync
  713. b set_dimm_bar
  714. 1:
  715. stw r7,SD_D1_CTRL(r4)
  716. sync
  717. /* Program SDRAM DIMMx Base Address Register */
  718. set_dimm_bar:
  719. READ_SPD(5) /* get # of Ranks */
  720. beq spd_read_fail
  721. andi. r7,r3,0x7
  722. addi r7,r7,1
  723. READ_SPD(31) /* Read DIMM rank density */
  724. beq spd_read_fail
  725. rlwinm r5,r3,27,29,31
  726. rlwinm r6,r3,3,24,28
  727. or r5,r6,r5 /* r5 = Normalized Rank Density byte */
  728. lis r8, 0x0080 /* 128MB >> 4 */
  729. mullw r8,r8,r5 /* r8 = (rank_size >> 4) */
  730. mullw r8,r8,r7 /* r8 = (DIMM_size >> 4) */
  731. neg r7,r8
  732. rlwinm r7,r7,28,4,31
  733. or r7,r7,r11 /* set ADDR field */
  734. rlwinm r8,r8,12,20,31
  735. add r11,r11,r8 /* set Base Addr for next DIMM */
  736. cmpi 0,0,r10,SPD_DIMM0
  737. bne set_dimm1_size
  738. stw r7,SD_D0_BAR(r4)
  739. sync
  740. li r10,SPD_DIMM1
  741. READ_SPD(0)
  742. bne do_each_dimm
  743. b spd_done
  744. set_dimm1_size:
  745. stw r7,SD_D1_BAR(r4)
  746. sync
  747. spd_done:
  748. blr
  749. check_next_slot:
  750. cmpi 0,0,r10,SPD_DIMM1
  751. beq spd_read_fail
  752. li r10,SPD_DIMM1
  753. b do_first_dimm
  754. spd_read_fail:
  755. ori r3,r0,0xdead
  756. b err_hung
  757. spd_fail:
  758. li r3,0x0bad
  759. sync
  760. err_hung: /* hang here for debugging */
  761. nop
  762. nop
  763. b err_hung
  764. #endif /* !SDC_HARDCODED_INIT */