tsi108_init.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. /*****************************************************************************
  2. * (C) Copyright 2003; Tundra Semiconductor Corp.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17. * MA 02111-1307 USA
  18. *****************************************************************************/
  19. /*----------------------------------------------------------------------------
  20. * FILENAME: tsi108_init.c
  21. *
  22. * Originator: Alex Bounine
  23. *
  24. * DESCRIPTION:
  25. * Initialization code for the Tundra Tsi108 bridge chip
  26. *---------------------------------------------------------------------------*/
  27. #include <common.h>
  28. #include <74xx_7xx.h>
  29. #include <config.h>
  30. #include <version.h>
  31. #include <asm/processor.h>
  32. #include <tsi108.h>
  33. DECLARE_GLOBAL_DATA_PTR;
  34. extern void mpicInit (int verbose);
  35. /*
  36. * Configuration Options
  37. */
  38. typedef struct {
  39. ulong upper;
  40. ulong lower;
  41. } PB2OCN_LUT_ENTRY;
  42. PB2OCN_LUT_ENTRY pb2ocn_lut1[32] = {
  43. /* 0 - 7 */
  44. {0x00000000, 0x00000201}, /* PBA=0xE000_0000 -> PCI/X (Byte-Swap) */
  45. {0x00000000, 0x00000201}, /* PBA=0xE100_0000 -> PCI/X (Byte-Swap) */
  46. {0x00000000, 0x00000201}, /* PBA=0xE200_0000 -> PCI/X (Byte-Swap) */
  47. {0x00000000, 0x00000201}, /* PBA=0xE300_0000 -> PCI/X (Byte-Swap) */
  48. {0x00000000, 0x00000201}, /* PBA=0xE400_0000 -> PCI/X (Byte-Swap) */
  49. {0x00000000, 0x00000201}, /* PBA=0xE500_0000 -> PCI/X (Byte-Swap) */
  50. {0x00000000, 0x00000201}, /* PBA=0xE600_0000 -> PCI/X (Byte-Swap) */
  51. {0x00000000, 0x00000201}, /* PBA=0xE700_0000 -> PCI/X (Byte-Swap) */
  52. /* 8 - 15 */
  53. {0x00000000, 0x00000201}, /* PBA=0xE800_0000 -> PCI/X (Byte-Swap) */
  54. {0x00000000, 0x00000201}, /* PBA=0xE900_0000 -> PCI/X (Byte-Swap) */
  55. {0x00000000, 0x00000201}, /* PBA=0xEA00_0000 -> PCI/X (Byte-Swap) */
  56. {0x00000000, 0x00000201}, /* PBA=0xEB00_0000 -> PCI/X (Byte-Swap) */
  57. {0x00000000, 0x00000201}, /* PBA=0xEC00_0000 -> PCI/X (Byte-Swap) */
  58. {0x00000000, 0x00000201}, /* PBA=0xED00_0000 -> PCI/X (Byte-Swap) */
  59. {0x00000000, 0x00000201}, /* PBA=0xEE00_0000 -> PCI/X (Byte-Swap) */
  60. {0x00000000, 0x00000201}, /* PBA=0xEF00_0000 -> PCI/X (Byte-Swap) */
  61. /* 16 - 23 */
  62. {0x00000000, 0x00000201}, /* PBA=0xF000_0000 -> PCI/X (Byte-Swap) */
  63. {0x00000000, 0x00000201}, /* PBA=0xF100_0000 -> PCI/X (Byte-Swap) */
  64. {0x00000000, 0x00000201}, /* PBA=0xF200_0000 -> PCI/X (Byte-Swap) */
  65. {0x00000000, 0x00000201}, /* PBA=0xF300_0000 -> PCI/X (Byte-Swap) */
  66. {0x00000000, 0x00000201}, /* PBA=0xF400_0000 -> PCI/X (Byte-Swap) */
  67. {0x00000000, 0x00000201}, /* PBA=0xF500_0000 -> PCI/X (Byte-Swap) */
  68. {0x00000000, 0x00000201}, /* PBA=0xF600_0000 -> PCI/X (Byte-Swap) */
  69. {0x00000000, 0x00000201}, /* PBA=0xF700_0000 -> PCI/X (Byte-Swap) */
  70. /* 24 - 31 */
  71. {0x00000000, 0x00000201}, /* PBA=0xF800_0000 -> PCI/X (Byte-Swap) */
  72. {0x00000000, 0x00000201}, /* PBA=0xF900_0000 -> PCI/X (Byte-Swap) */
  73. {0x00000000, 0x00000201}, /* PBA=0xFA00_0000 -> PCI/X PCI I/O (Byte-Swap) */
  74. {0x00000000, 0x00000201}, /* PBA=0xFB00_0000 -> PCI/X PCI Config (Byte-Swap) */
  75. {0x00000000, 0x02000240}, /* PBA=0xFC00_0000 -> HLP */
  76. {0x00000000, 0x01000240}, /* PBA=0xFD00_0000 -> HLP */
  77. {0x00000000, 0x03000240}, /* PBA=0xFE00_0000 -> HLP */
  78. {0x00000000, 0x00000240} /* PBA=0xFF00_0000 -> HLP : (Translation Enabled + Byte-Swap)*/
  79. };
  80. #ifdef CFG_CLK_SPREAD
  81. typedef struct {
  82. ulong ctrl0;
  83. ulong ctrl1;
  84. } PLL_CTRL_SET;
  85. /*
  86. * Clock Generator SPLL0 initialization values
  87. * PLL0 configuration table for various PB_CLKO freq.
  88. * Uses pre-calculated values for Fs = 30 kHz, D = 0.5%
  89. * Fout depends on required PB_CLKO. Based on Fref = 33 MHz
  90. */
  91. static PLL_CTRL_SET pll0_config[8] = {
  92. {0x00000000, 0x00000000}, /* 0: bypass */
  93. {0x00000000, 0x00000000}, /* 1: reserved */
  94. {0x00430044, 0x00000043}, /* 2: CG_PB_CLKO = 183 MHz */
  95. {0x005c0044, 0x00000039}, /* 3: CG_PB_CLKO = 100 MHz */
  96. {0x005c0044, 0x00000039}, /* 4: CG_PB_CLKO = 133 MHz */
  97. {0x004a0044, 0x00000040}, /* 5: CG_PB_CLKO = 167 MHz */
  98. {0x005c0044, 0x00000039}, /* 6: CG_PB_CLKO = 200 MHz */
  99. {0x004f0044, 0x0000003e} /* 7: CG_PB_CLKO = 233 MHz */
  100. };
  101. #endif /* CFG_CLK_SPREAD */
  102. /*
  103. * Prosessor Bus Clock (in MHz) defined by CG_PB_SELECT
  104. * (based on recommended Tsi108 reference clock 33MHz)
  105. */
  106. static int pb_clk_sel[8] = { 0, 0, 183, 100, 133, 167, 200, 233 };
  107. /*
  108. * get_board_bus_clk ()
  109. *
  110. * returns the bus clock in Hz.
  111. */
  112. unsigned long get_board_bus_clk (void)
  113. {
  114. ulong i;
  115. /* Detect PB clock freq. */
  116. i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
  117. i = (i >> 16) & 0x07; /* Get PB PLL multiplier */
  118. return pb_clk_sel[i] * 1000000;
  119. }
  120. /*
  121. * board_early_init_f ()
  122. *
  123. * board-specific initialization executed from flash
  124. */
  125. int board_early_init_f (void)
  126. {
  127. ulong i;
  128. gd->mem_clk = 0;
  129. i = in32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
  130. CG_PWRUP_STATUS);
  131. i = (i >> 20) & 0x07; /* Get GD PLL multiplier */
  132. switch (i) {
  133. case 0: /* external clock */
  134. printf ("Using external clock\n");
  135. break;
  136. case 1: /* system clock */
  137. gd->mem_clk = gd->bus_clk;
  138. break;
  139. case 4: /* 133 MHz */
  140. case 5: /* 166 MHz */
  141. case 6: /* 200 MHz */
  142. gd->mem_clk = pb_clk_sel[i] * 1000000;
  143. break;
  144. default:
  145. printf ("Invalid DDR2 clock setting\n");
  146. return -1;
  147. }
  148. printf ("BUS: %d MHz\n", get_board_bus_clk() / 1000000);
  149. printf ("MEM: %d MHz\n", gd->mem_clk / 1000000);
  150. return 0;
  151. }
  152. /*
  153. * board_early_init_r() - Tsi108 initialization function executed right after
  154. * relocation. Contains code that cannot be executed from flash.
  155. */
  156. int board_early_init_r (void)
  157. {
  158. ulong temp, i;
  159. ulong reg_val;
  160. volatile ulong *reg_ptr;
  161. reg_ptr =
  162. (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x900);
  163. for (i = 0; i < 32; i++) {
  164. *reg_ptr++ = 0x00000201; /* SWAP ENABLED */
  165. *reg_ptr++ = 0x00;
  166. }
  167. __asm__ __volatile__ ("eieio");
  168. __asm__ __volatile__ ("sync");
  169. /* Setup PB_OCN_BAR2: size 256B + ENable @ 0x0_80000000 */
  170. out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2,
  171. 0x80000001);
  172. __asm__ __volatile__ ("sync");
  173. /* Make sure that OCN_BAR2 decoder is set (to allow following immediate
  174. * read from SDRAM)
  175. */
  176. temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2);
  177. __asm__ __volatile__ ("sync");
  178. /*
  179. * Remap PB_OCN_BAR1 to accomodate PCI-bus aperture and EPROM into the
  180. * processor bus address space. Immediately after reset LUT and address
  181. * translation are disabled for this BAR. Now we have to initialize LUT
  182. * and switch from the BOOT mode to the normal operation mode.
  183. *
  184. * The aperture defined by PB_OCN_BAR1 startes at address 0xE0000000
  185. * and covers 512MB of address space. To allow larger aperture we also
  186. * have to relocate register window of Tsi108
  187. *
  188. * Initialize LUT (32-entries) prior switching PB_OCN_BAR1 from BOOT
  189. * mode.
  190. *
  191. * initialize pointer to LUT associated with PB_OCN_BAR1
  192. */
  193. reg_ptr =
  194. (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x800);
  195. for (i = 0; i < 32; i++) {
  196. *reg_ptr++ = pb2ocn_lut1[i].lower;
  197. *reg_ptr++ = pb2ocn_lut1[i].upper;
  198. }
  199. __asm__ __volatile__ ("sync");
  200. /* Base addresses for CS0, CS1, CS2, CS3 */
  201. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_ADDR,
  202. 0x00000000);
  203. __asm__ __volatile__ ("sync");
  204. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_ADDR,
  205. 0x00100000);
  206. __asm__ __volatile__ ("sync");
  207. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_ADDR,
  208. 0x00200000);
  209. __asm__ __volatile__ ("sync");
  210. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_ADDR,
  211. 0x00300000);
  212. __asm__ __volatile__ ("sync");
  213. /* Masks for HLP banks */
  214. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_MASK,
  215. 0xFFF00000);
  216. __asm__ __volatile__ ("sync");
  217. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_MASK,
  218. 0xFFF00000);
  219. __asm__ __volatile__ ("sync");
  220. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_MASK,
  221. 0xFFF00000);
  222. __asm__ __volatile__ ("sync");
  223. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_MASK,
  224. 0xFFF00000);
  225. __asm__ __volatile__ ("sync");
  226. /* Set CTRL0 values for banks */
  227. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL0,
  228. 0x7FFC44C2);
  229. __asm__ __volatile__ ("sync");
  230. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL0,
  231. 0x7FFC44C0);
  232. __asm__ __volatile__ ("sync");
  233. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL0,
  234. 0x7FFC44C0);
  235. __asm__ __volatile__ ("sync");
  236. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL0,
  237. 0x7FFC44C2);
  238. __asm__ __volatile__ ("sync");
  239. /* Set banks to latched mode, enabled, and other default settings */
  240. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL1,
  241. 0x7C0F2000);
  242. __asm__ __volatile__ ("sync");
  243. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL1,
  244. 0x7C0F2000);
  245. __asm__ __volatile__ ("sync");
  246. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL1,
  247. 0x7C0F2000);
  248. __asm__ __volatile__ ("sync");
  249. out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL1,
  250. 0x7C0F2000);
  251. __asm__ __volatile__ ("sync");
  252. /*
  253. * Set new value for PB_OCN_BAR1: switch from BOOT to LUT mode.
  254. * value for PB_OCN_BAR1: (BA-0xE000_0000 + size 512MB + ENable)
  255. */
  256. out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1,
  257. 0xE0000011);
  258. __asm__ __volatile__ ("sync");
  259. /* Make sure that OCN_BAR2 decoder is set (to allow following
  260. * immediate read from SDRAM)
  261. */
  262. temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1);
  263. __asm__ __volatile__ ("sync");
  264. /*
  265. * SRI: At this point we have enabled the HLP banks. That means we can
  266. * now read from the NVRAM and initialize the environment variables.
  267. * We will over-ride the env_init called in board_init_f
  268. * This is really a work-around because, the HLP bank 1
  269. * where NVRAM resides is not visible during board_init_f
  270. * (lib_ppc/board.c)
  271. * Alternatively, we could use the I2C EEPROM at start-up to configure
  272. * and enable all HLP banks and not just HLP 0 as is being done for
  273. * Taiga Rev. 2.
  274. */
  275. env_init ();
  276. #ifndef DISABLE_PBM
  277. /*
  278. * For IBM processors we have to set Address-Only commands generated
  279. * by PBM that are different from ones set after reset.
  280. */
  281. temp = get_cpu_type ();
  282. if ((CPU_750FX == temp) || (CPU_750GX == temp))
  283. out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_MCMD,
  284. 0x00009955);
  285. #endif /* DISABLE_PBM */
  286. #ifdef CONFIG_PCI
  287. /*
  288. * Initialize PCI/X block
  289. */
  290. /* Map PCI/X Configuration Space (16MB @ 0x0_FE000000) */
  291. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
  292. PCI_PFAB_BAR0_UPPER, 0);
  293. __asm__ __volatile__ ("sync");
  294. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_BAR0,
  295. 0xFB000001);
  296. __asm__ __volatile__ ("sync");
  297. /* Set Bus Number for the attached PCI/X bus (we will use 0 for NB) */
  298. temp = in32(CFG_TSI108_CSR_BASE +
  299. TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT);
  300. temp &= ~0xFF00; /* Clear the BUS_NUM field */
  301. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT,
  302. temp);
  303. /* Map PCI/X IO Space (64KB @ 0x0_FD000000) takes one 16MB LUT entry */
  304. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO_UPPER,
  305. 0);
  306. __asm__ __volatile__ ("sync");
  307. /* This register is on the PCI side to interpret the address it receives
  308. * and maps it as a IO address.
  309. */
  310. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO,
  311. 0xFA000001);
  312. __asm__ __volatile__ ("sync");
  313. /*
  314. * Map PCI/X Memory Space
  315. *
  316. * Transactions directed from OCM to PCI Memory Space are directed
  317. * from PB to PCI
  318. * unchanged (as defined by PB_OCN_BAR1,2 and LUT settings).
  319. * If address remapping is required the corresponding PCI_PFAB_MEM32
  320. * and PCI_PFAB_PFMx register groups have to be configured.
  321. *
  322. * Map the path from the PCI/X bus into the system memory
  323. *
  324. * The memory mapped window assotiated with PCI P2O_BAR2 provides
  325. * access to the system memory without address remapping.
  326. * All system memory is opened for accesses initiated by PCI/X bus
  327. * masters.
  328. *
  329. * Initialize LUT associated with PCI P2O_BAR2
  330. *
  331. * set pointer to LUT associated with PCI P2O_BAR2
  332. */
  333. reg_ptr =
  334. (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x500);
  335. #ifdef DISABLE_PBM
  336. /* In case when PBM is disabled (no HW supported cache snoopng on PB)
  337. * P2O_BAR2 is directly mapped into the system memory without address
  338. * translation.
  339. */
  340. reg_val = 0x00000004; /* SDRAM port + NO Addr_Translation */
  341. for (i = 0; i < 32; i++) {
  342. *reg_ptr++ = reg_val; /* P2O_BAR2_LUTx */
  343. *reg_ptr++ = 0; /* P2O_BAR2_LUT_UPPERx */
  344. }
  345. /* value for PCI BAR2 (size = 512MB, Enabled, No Addr. Translation) */
  346. reg_val = 0x00007500;
  347. #else
  348. reg_val = 0x00000002; /* Destination port = PBM */
  349. for (i = 0; i < 32; i++) {
  350. *reg_ptr++ = reg_val; /* P2O_BAR2_LUTx */
  351. /* P2O_BAR2_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
  352. *reg_ptr++ = 0x40000000;
  353. /* offset = 16MB, address translation is enabled to allow byte swapping */
  354. reg_val += 0x01000000;
  355. }
  356. /* value for PCI BAR2 (size = 512MB, Enabled, Address Translation Enabled) */
  357. reg_val = 0x00007100;
  358. #endif
  359. __asm__ __volatile__ ("eieio");
  360. __asm__ __volatile__ ("sync");
  361. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
  362. reg_val);
  363. __asm__ __volatile__ ("sync");
  364. /* Set 64-bit PCI bus address for system memory
  365. * ( 0 is the best choice for easy mapping)
  366. */
  367. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2,
  368. 0x00000000);
  369. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2_UPPER,
  370. 0x00000000);
  371. __asm__ __volatile__ ("sync");
  372. #ifndef DISABLE_PBM
  373. /*
  374. * The memory mapped window assotiated with PCI P2O_BAR3 provides
  375. * access to the system memory using SDRAM OCN port and address
  376. * translation. This is alternative way to access SDRAM from PCI
  377. * required for Tsi108 emulation testing.
  378. * All system memory is opened for accesses initiated by
  379. * PCI/X bus masters.
  380. *
  381. * Initialize LUT associated with PCI P2O_BAR3
  382. *
  383. * set pointer to LUT associated with PCI P2O_BAR3
  384. */
  385. reg_ptr =
  386. (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x600);
  387. reg_val = 0x00000004; /* Destination port = SDC */
  388. for (i = 0; i < 32; i++) {
  389. *reg_ptr++ = reg_val; /* P2O_BAR3_LUTx */
  390. /* P2O_BAR3_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
  391. *reg_ptr++ = 0;
  392. /* offset = 16MB, address translation is enabled to allow byte swapping */
  393. reg_val += 0x01000000;
  394. }
  395. __asm__ __volatile__ ("eieio");
  396. __asm__ __volatile__ ("sync");
  397. /* Configure PCI P2O_BAR3 (size = 512MB, Enabled) */
  398. reg_val =
  399. in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
  400. PCI_P2O_PAGE_SIZES);
  401. reg_val &= ~0x00FF;
  402. reg_val |= 0x0071;
  403. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
  404. reg_val);
  405. __asm__ __volatile__ ("sync");
  406. /* Set 64-bit base PCI bus address for window (0x20000000) */
  407. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3_UPPER,
  408. 0x00000000);
  409. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3,
  410. 0x20000000);
  411. __asm__ __volatile__ ("sync");
  412. #endif /* !DISABLE_PBM */
  413. #ifdef ENABLE_PCI_CSR_BAR
  414. /* open if required access to Tsi108 CSRs from the PCI/X bus */
  415. /* enable BAR0 on the PCI/X bus */
  416. reg_val = in32(CFG_TSI108_CSR_BASE +
  417. TSI108_PCI_REG_OFFSET + PCI_MISC_CSR);
  418. reg_val |= 0x02;
  419. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR,
  420. reg_val);
  421. __asm__ __volatile__ ("sync");
  422. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0_UPPER,
  423. 0x00000000);
  424. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0,
  425. CFG_TSI108_CSR_BASE);
  426. __asm__ __volatile__ ("sync");
  427. #endif
  428. /*
  429. * Finally enable PCI/X Bus Master and Memory Space access
  430. */
  431. reg_val = in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR);
  432. reg_val |= 0x06;
  433. out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR, reg_val);
  434. __asm__ __volatile__ ("sync");
  435. #endif /* CONFIG_PCI */
  436. /*
  437. * Initialize MPIC outputs (interrupt pins):
  438. * Interrupt routing on the Grendel Emul. Board:
  439. * PB_INT[0] -> INT (CPU0)
  440. * PB_INT[1] -> INT (CPU1)
  441. * PB_INT[2] -> MCP (CPU0)
  442. * PB_INT[3] -> MCP (CPU1)
  443. * Set interrupt controller outputs as Level_Sensitive/Active_Low
  444. */
  445. out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(0), 0x02);
  446. out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(1), 0x02);
  447. out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(2), 0x02);
  448. out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(3), 0x02);
  449. __asm__ __volatile__ ("sync");
  450. /*
  451. * Ensure that Machine Check exception is enabled
  452. * We need it to support PCI Bus probing (configuration reads)
  453. */
  454. reg_val = mfmsr ();
  455. mtmsr(reg_val | MSR_ME);
  456. return 0;
  457. }
  458. /*
  459. * Needed to print out L2 cache info
  460. * used in the misc_init_r function
  461. */
  462. unsigned long get_l2cr (void)
  463. {
  464. unsigned long l2controlreg;
  465. asm volatile ("mfspr %0, 1017":"=r" (l2controlreg):);
  466. return l2controlreg;
  467. }
  468. /*
  469. * misc_init_r()
  470. *
  471. * various things to do after relocation
  472. *
  473. */
  474. int misc_init_r (void)
  475. {
  476. #ifdef CFG_CLK_SPREAD /* Initialize Spread-Spectrum Clock generation */
  477. ulong i;
  478. /* Ensure that Spread-Spectrum is disabled */
  479. out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, 0);
  480. out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0);
  481. /* Initialize PLL1: CG_PCI_CLK , internal OCN_CLK
  482. * Uses pre-calculated value for Fout = 800 MHz, Fs = 30 kHz, D = 0.5%
  483. */
  484. out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
  485. 0x002e0044); /* D = 0.25% */
  486. out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL1,
  487. 0x00000039); /* BWADJ */
  488. /* Initialize PLL0: CG_PB_CLKO */
  489. /* Detect PB clock freq. */
  490. i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
  491. i = (i >> 16) & 0x07; /* Get PB PLL multiplier */
  492. out32 (CFG_TSI108_CSR_BASE +
  493. TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, pll0_config[i].ctrl0);
  494. out32 (CFG_TSI108_CSR_BASE +
  495. TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL1, pll0_config[i].ctrl1);
  496. /* Wait and set SSEN for both PLL0 and 1 */
  497. udelay (1000);
  498. out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
  499. 0x802e0044); /* D=0.25% */
  500. out32 (CFG_TSI108_CSR_BASE +
  501. TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0,
  502. 0x80000000 | pll0_config[i].ctrl0);
  503. #endif /* CFG_CLK_SPREAD */
  504. #ifdef CFG_L2
  505. l2cache_enable ();
  506. #endif
  507. printf ("BUS: %d MHz\n", gd->bus_clk / 1000000);
  508. printf ("MEM: %d MHz\n", gd->mem_clk / 1000000);
  509. /*
  510. * All the information needed to print the cache details is avaiblable
  511. * at this point i.e. above call to l2cache_enable is the very last
  512. * thing done with regards to enabling diabling the cache.
  513. * So this seems like a good place to print all this information
  514. */
  515. printf ("CACHE: ");
  516. switch (get_cpu_type()) {
  517. case CPU_7447A:
  518. printf ("L1 Instruction cache - 32KB 8-way");
  519. (get_hid0 () & (1 << 15)) ? printf (" ENABLED\n") :
  520. printf (" DISABLED\n");
  521. printf ("L1 Data cache - 32KB 8-way");
  522. (get_hid0 () & (1 << 14)) ? printf (" ENABLED\n") :
  523. printf (" DISABLED\n");
  524. printf ("Unified L2 cache - 512KB 8-way");
  525. (get_l2cr () & (1 << 31)) ? printf (" ENABLED\n") :
  526. printf (" DISABLED\n");
  527. printf ("\n");
  528. break;
  529. case CPU_7448:
  530. printf ("L1 Instruction cache - 32KB 8-way");
  531. (get_hid0 () & (1 << 15)) ? printf (" ENABLED\n") :
  532. printf (" DISABLED\n");
  533. printf ("L1 Data cache - 32KB 8-way");
  534. (get_hid0 () & (1 << 14)) ? printf (" ENABLED\n") :
  535. printf (" DISABLED\n");
  536. printf ("Unified L2 cache - 1MB 8-way");
  537. (get_l2cr () & (1 << 31)) ? printf (" ENABLED\n") :
  538. printf (" DISABLED\n");
  539. break;
  540. default:
  541. break;
  542. }
  543. return 0;
  544. }