misc-mv64x60.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Relocate bridge's register base and call board specific routine.
  3. *
  4. * Author: Mark A. Greer <source@mvista.com>
  5. *
  6. * 2005 (c) MontaVista Software, Inc. This file is licensed under
  7. * the terms of the GNU General Public License version 2. This program
  8. * is licensed "as is" without any warranty of any kind, whether express
  9. * or implied.
  10. */
  11. #include <linux/types.h>
  12. #include <asm/io.h>
  13. #include <asm/mv64x60_defs.h>
  14. extern struct bi_record *decompress_kernel(unsigned long load_addr,
  15. int num_words, unsigned long cksum);
  16. u32 size_reg[MV64x60_CPU2MEM_WINDOWS] = {
  17. MV64x60_CPU2MEM_0_SIZE, MV64x60_CPU2MEM_1_SIZE,
  18. MV64x60_CPU2MEM_2_SIZE, MV64x60_CPU2MEM_3_SIZE
  19. };
  20. /* Read mem ctlr to get the amount of mem in system */
  21. unsigned long
  22. mv64360_get_mem_size(void)
  23. {
  24. u32 enables, i, v;
  25. u32 mem = 0;
  26. enables = in_le32((void __iomem *)CONFIG_MV64X60_NEW_BASE +
  27. MV64360_CPU_BAR_ENABLE) & 0xf;
  28. for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
  29. if (!(enables & (1<<i))) {
  30. v = in_le32((void __iomem *)CONFIG_MV64X60_NEW_BASE
  31. + size_reg[i]) & 0xffff;
  32. v = (v + 1) << 16;
  33. mem += v;
  34. }
  35. return mem;
  36. }
  37. void
  38. mv64x60_move_base(void __iomem *old_base, void __iomem *new_base)
  39. {
  40. u32 bits, mask, b;
  41. if (old_base != new_base) {
  42. #ifdef CONFIG_GT64260
  43. bits = 12;
  44. mask = 0x07000000;
  45. #else /* Must be mv64[34]60 */
  46. bits = 16;
  47. mask = 0x03000000;
  48. #endif
  49. b = in_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE);
  50. b &= mask;
  51. b |= ((u32)new_base >> (32 - bits));
  52. out_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE, b);
  53. __asm__ __volatile__("sync");
  54. /* Wait for change to happen (in accordance with the manual) */
  55. while (in_le32(new_base + MV64x60_INTERNAL_SPACE_DECODE) != b);
  56. }
  57. }
  58. void __attribute__ ((weak))
  59. mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
  60. {
  61. }
  62. void *
  63. load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
  64. void *ign1, void *ign2)
  65. {
  66. mv64x60_move_base((void __iomem *)CONFIG_MV64X60_BASE,
  67. (void __iomem *)CONFIG_MV64X60_NEW_BASE);
  68. mv64x60_board_init((void __iomem *)CONFIG_MV64X60_BASE,
  69. (void __iomem *)CONFIG_MV64X60_NEW_BASE);
  70. return decompress_kernel(load_addr, num_words, cksum);
  71. }