ip22-mc.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  7.  * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
  8.  */
  9. #include <linux/init.h>
  10. #include <linux/kernel.h>
  11. #include <asm/addrspace.h>
  12. #include <asm/ptrace.h>
  13. #include <asm/sgi/sgimc.h>
  14. #include <asm/sgi/sgihpc.h>
  15. /* #define DEBUG_SGIMC */
  16. struct sgimc_misc_ctrl *mcmisc_regs;
  17. u32 *rpsscounter;
  18. struct sgimc_dma_ctrl *dmactrlregs;
  19. static inline char *mconfig_string(unsigned long val)
  20. {
  21. switch(val & SGIMC_MCONFIG_RMASK) {
  22. case SGIMC_MCONFIG_FOURMB:
  23. return "4MB";
  24. case SGIMC_MCONFIG_EIGHTMB:
  25. return "8MB";
  26. case SGIMC_MCONFIG_SXTEENMB:
  27. return "16MB";
  28. case SGIMC_MCONFIG_TTWOMB:
  29. return "32MB";
  30. case SGIMC_MCONFIG_SFOURMB:
  31. return "64MB";
  32. case SGIMC_MCONFIG_OTEIGHTMB:
  33. return "128MB";
  34. default:
  35. return "wheee, unknown";
  36. };
  37. }
  38. void __init sgimc_init(void)
  39. {
  40. unsigned long tmpreg;
  41. mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
  42. rpsscounter = (u32 *) (KSEG1 + 0x1fa01004);
  43. dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000);
  44. printk("MC: SGI memory controller Revision %dn",
  45.        (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV);
  46. #if 0 /* XXX Until I figure out what this bit really indicates XXX */
  47. /* XXX Is this systemid bit reliable? */
  48. if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) {
  49. EISA_bus = 1;
  50. printk("with EISAn");
  51. } else {
  52. EISA_bus = 0;
  53. printk("no EISAn");
  54. }
  55. #endif
  56. #ifdef DEBUG_SGIMC
  57. prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>n",
  58.     mconfig_string(mcmisc_regs->mconfig0),
  59.     mconfig_string(mcmisc_regs->mconfig1));
  60. prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>n",
  61.     mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1);
  62. prom_printf("mcdump: divider<%08lx>, gioparm<%04x>n",
  63.     mcmisc_regs->divider, mcmisc_regs->gioparm);
  64. #endif
  65. /* Place the MC into a known state.  This must be done before
  66.  * interrupts are first enabled etc.
  67.  */
  68. /* Step 1: The CPU/GIO error status registers will not latch
  69.  *         up a new error status until the register has been
  70.  *         cleared by the cpu.  These status registers are
  71.  *         cleared by writing any value to them.
  72.  */
  73. mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
  74. /* Step 2: Enable all parity checking in cpu control register
  75.  *         zero.
  76.  */
  77. tmpreg = mcmisc_regs->cpuctrl0;
  78. tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
  79.    SGIMC_CCTRL0_R4KNOCHKPARR);
  80. mcmisc_regs->cpuctrl0 = tmpreg;
  81. /* Step 3: Setup the MC write buffer depth, this is controlled
  82.  *         in cpu control register 1 in the lower 4 bits.
  83.  */
  84. tmpreg = mcmisc_regs->cpuctrl1;
  85. tmpreg &= ~0xf;
  86. tmpreg |= 0xd;
  87. mcmisc_regs->cpuctrl1 = tmpreg;
  88. /* Step 4: Initialize the RPSS divider register to run as fast
  89.  *         as it can correctly operate.  The register is laid
  90.  *         out as follows:
  91.  *
  92.  *         ----------------------------------------
  93.  *         |  RESERVED  |   INCREMENT   | DIVIDER |
  94.  *         ----------------------------------------
  95.  *          31        16 15            8 7       0
  96.  *
  97.  *         DIVIDER determines how often a 'tick' happens,
  98.  *         INCREMENT determines by how the RPSS increment
  99.  *         registers value increases at each 'tick'. Thus,
  100.  *         for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
  101.  */
  102. mcmisc_regs->divider = 0x101;
  103. /* Step 5: Initialize GIO64 arbitrator configuration register.
  104.  *
  105.  * NOTE: If you dork with startup code the HPC init code in
  106.  *       sgihpc_init() must run before us because of how we
  107.  *       need to know Guiness vs. FullHouse and the board
  108.  *       revision on this machine.  You have been warned.
  109.  */
  110. /* First the basic invariants across all gio64 implementations. */
  111. tmpreg = SGIMC_GIOPARM_HPC64;    /* All 1st HPC's interface at 64bits. */
  112. tmpreg |= SGIMC_GIOPARM_ONEBUS;  /* Only one physical GIO bus exists. */
  113. if(sgi_guiness) {
  114. /* Guiness specific settings. */
  115. tmpreg |= SGIMC_GIOPARM_EISA64;     /* MC talks to EISA at 64bits */
  116. tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */
  117. } else {
  118. /* Fullhouse specific settings. */
  119. if(sgi_boardid < 2) {
  120. tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */
  121. tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */
  122. tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */
  123. tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */
  124. } else {
  125. tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */
  126. tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */
  127. tmpreg |= SGIMC_GIOPARM_PLINEEXP1;
  128. tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */
  129. /* someone forgot this poor little guy... */
  130. tmpreg |= SGIMC_GIOPARM_GFX64;  /* GFX at 64 bits */
  131. }
  132. }
  133. mcmisc_regs->gioparm = tmpreg; /* poof */
  134. }