Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #define RADEON_SCRATCH_REG0     0x15e0
  2. #define RADEON_SCRATCH_REG1             0x15e4
  3. #define RADEON_SCRATCH_REG2             0x15e8
  4. #define RADEON_SCRATCH_REG3             0x15ec
  5. #define RADEON_SCRATCH_REG4             0x15f0
  6. #define RADEON_SCRATCH_REG5             0x15f4
  7. #define RADEON_SCRATCH_UMSK             0x0770
  8. #define RADEON_SCRATCH_ADDR             0x0774
  9.  
  10. #   define RS400_BUS_MASTER_DIS      (1 << 14)
  11. //#   define RADEON_BUS_MASTER_DIS     (1 <<  6)
  12.  
  13. #define RADEON_ISYNC_CNTL       0x1724
  14. #       define RADEON_ISYNC_ANY2D_IDLE3D        (1 << 0)
  15. #       define RADEON_ISYNC_ANY3D_IDLE2D        (1 << 1)
  16. #       define RADEON_ISYNC_TRIG2D_IDLE3D       (1 << 2)
  17. #       define RADEON_ISYNC_TRIG3D_IDLE2D       (1 << 3)
  18. #       define RADEON_ISYNC_WAIT_IDLEGUI        (1 << 4)
  19. #       define RADEON_ISYNC_CPSCRATCH_IDLEGUI   (1 << 5)
  20.  
  21.  
  22. void RADEONEngineFlush(RHDPtr info)
  23. {
  24.      int i;
  25.  
  26.      if (info->ChipFamily <= CHIP_FAMILY_RV280)
  27.      {
  28.         MASKREG(RADEON_RB3D_DSTCACHE_CTLSTAT,RADEON_RB3D_DC_FLUSH_ALL,
  29.                                              ~RADEON_RB3D_DC_FLUSH_ALL);
  30.         for (i = 0; i < RADEON_TIMEOUT; i++) {
  31.            if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
  32.             break;
  33.         }
  34.         if (i == RADEON_TIMEOUT) {
  35.            dbgprintf("DC flush timeout: %x\n",
  36.                      (u32_t)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
  37.         }
  38.      }
  39.      else
  40.      {
  41. //        MASKREG(R300_DSTCACHE_CTLSTAT,R300_RB2D_DC_FLUSH_ALL,
  42. //                                      ~R300_RB2D_DC_FLUSH_ALL);
  43. //        for (i = 0; i < RADEON_TIMEOUT; i++) {
  44. //            if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY))
  45. //            break;
  46. //        }
  47. //        if (i == RADEON_TIMEOUT) {
  48. //           dbgprintf("DC flush timeout: %x\n",
  49. //                     (u32_t)INREG(R300_DSTCACHE_CTLSTAT));
  50. //        }
  51.      }
  52. }
  53.  
  54.  
  55. static int radeon_do_wait_for_idle()
  56. {
  57.         int i, ret;
  58.  
  59.     ret = R5xxFIFOWaitLocal(64);
  60.         if (ret)
  61.                 return ret;
  62.  
  63.     for (i = 0; i < RADEON_TIMEOUT; i++)
  64.     {
  65.         if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) {
  66.             RADEONEngineFlush(&rhd);
  67.                         return 0;
  68.                 }
  69.         usleep(1);
  70.         }
  71.     dbgprintf("wait idle failed status : 0x%08X 0x%08X\n",
  72.                INREG(RADEON_RBBM_STATUS),
  73.                INREG(R300_VAP_CNTL_STATUS));
  74.  
  75.     return 1;
  76. }
  77.  
  78.  
  79.  
  80. /* ================================================================
  81.  * CP control, initialization
  82.  */
  83.  
  84. /* Load the microcode for the CP */
  85.  
  86. #include "radeon_microcode.h"
  87.  
  88. static void load_microcode(RHDPtr info)
  89. {
  90.         int i;
  91.     const u32_t (*microcode)[2];
  92.  
  93.      OUTREG(RADEON_CP_ME_RAM_ADDR, 0);
  94.  
  95.      if ( (info->ChipFamily  == CHIP_FAMILY_LEGACY ) ||
  96.           (info->ChipFamily  == CHIP_FAMILY_RADEON ) ||
  97.           (info->ChipFamily  == CHIP_FAMILY_RV100  ) ||
  98.           (info->ChipFamily  == CHIP_FAMILY_RV200  ) ||
  99.           (info->ChipFamily  == CHIP_FAMILY_RS100  ) ||
  100.           (info->ChipFamily  == CHIP_FAMILY_RS200  ))
  101.      {
  102.         microcode = R100_cp_microcode;
  103.         dbgprintf("Loading R100 Microcode\n");
  104.      }
  105.      else if ((info->ChipFamily == CHIP_FAMILY_R200 ) ||
  106.               (info->ChipFamily == CHIP_FAMILY_RV250) ||
  107.               (info->ChipFamily == CHIP_FAMILY_RV280) ||
  108.               (info->ChipFamily == CHIP_FAMILY_RS300))
  109.      {
  110.         microcode = R200_cp_microcode;
  111.         dbgprintf("Loading R200 Microcode\n");
  112.      }
  113.      else if ((info->ChipFamily == CHIP_FAMILY_R300)  ||
  114.               (info->ChipFamily == CHIP_FAMILY_R350)  ||
  115.               (info->ChipFamily == CHIP_FAMILY_RV350) ||
  116.               (info->ChipFamily == CHIP_FAMILY_RV380) ||
  117.               (info->ChipFamily == CHIP_FAMILY_RS400) ||
  118.               (info->ChipFamily == CHIP_FAMILY_RS480))
  119.      {
  120.         dbgprintf("Loading R300 Microcode\n");
  121.         microcode = R300_cp_microcode;
  122.      }
  123.      else if ((info->ChipFamily == CHIP_FAMILY_R420)  ||
  124.               (info->ChipFamily == CHIP_FAMILY_RV410))
  125.      {
  126.         dbgprintf("Loading R400 Microcode\n");
  127.         microcode = R420_cp_microcode;
  128.  
  129.      }
  130.      else if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
  131.               (info->ChipFamily == CHIP_FAMILY_RS690) ||
  132.               (info->ChipFamily == CHIP_FAMILY_RS740))
  133.      {
  134.         dbgprintf("Loading RS690/RS740 Microcode\n");
  135.         microcode = RS690_cp_microcode;
  136.      }
  137.      else if ((info->ChipFamily == CHIP_FAMILY_RV515) ||
  138.               (info->ChipFamily == CHIP_FAMILY_R520)  ||
  139.               (info->ChipFamily == CHIP_FAMILY_RV530) ||
  140.               (info->ChipFamily == CHIP_FAMILY_R580)  ||
  141.               (info->ChipFamily == CHIP_FAMILY_RV560) ||
  142.               (info->ChipFamily == CHIP_FAMILY_RV570))
  143.      {
  144.         dbgprintf("Loading R500 Microcode\n");
  145.         microcode = R520_cp_microcode;
  146.      }
  147.  
  148.      for (i = 0; i < 256; i++) {
  149.        OUTREG(RADEON_CP_ME_RAM_DATAH, microcode[i][1]);
  150.        OUTREG(RADEON_CP_ME_RAM_DATAL, microcode[i][0]);
  151.      }
  152. }
  153.  
  154.  
  155. void init_ring_buffer(RHDPtr info)
  156. {
  157.      u32_t ring_base;
  158.      u32_t tmp;
  159.  
  160.      info->ringBase = CreateRingBuffer( 64*1024, PG_SW);
  161.  
  162.      dbgprintf("create cp ring buffer %x\n", rhd.ringBase);
  163.      ring_base = GetPgAddr(rhd.ringBase);
  164.      dbgprintf("ring base %x\n", ring_base);
  165.  
  166.      OUTREG(RADEON_CP_RB_BASE, ring_base);
  167.  
  168.      info->ring_avail = 64*1024/4 ;
  169.  
  170.         /* Set the write pointer delay */
  171.      OUTREG(RADEON_CP_RB_WPTR_DELAY, 0);
  172.  
  173.         /* Initialize the ring buffer's read and write pointers */
  174.      rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
  175.      rhd.host_rp =  rhd.ring_rp;
  176.  
  177.      OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp);
  178.  
  179.      tmp = (((u32_t)&rhd.host_rp) & 4095) + GetPgAddr((void*)&rhd.host_rp);
  180.  
  181.      OUTREG(RADEON_CP_RB_RPTR_ADDR, tmp); // ring buffer read pointer
  182.  
  183.         /* Set ring buffer size */
  184.      OUTREG(RADEON_CP_RB_CNTL, (1<<27)|(0<<18)|(10<<8)|13);
  185.  
  186.         /* Initialize the scratch register pointer.  This will cause
  187.          * the scratch register values to be written out to memory
  188.          * whenever they are updated.
  189.          *
  190.          * We simply put this behind the ring read pointer, this works
  191.          * with PCI GART as well as (whatever kind of) AGP GART
  192.          */
  193.  
  194.      tmp = (((u32_t)&rhd.scratch0) & 4095) + GetPgAddr((void*)&rhd.scratch0);
  195.      OUTREG(RADEON_SCRATCH_ADDR, tmp);
  196.  
  197.      OUTREG(RADEON_SCRATCH_UMSK, 0x0);
  198.      //OUTREG(0x778, 1);
  199.  
  200.         /* Turn on bus mastering */
  201.      if ( (info->ChipFamily == CHIP_FAMILY_RS400) ||
  202.           (info->ChipFamily == CHIP_FAMILY_RS690) ||
  203.           (info->ChipFamily == CHIP_FAMILY_RS740) )
  204.      {
  205.                 /* rs400, rs690/rs740 */
  206.         tmp = INREG(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS;
  207.         OUTREG(RADEON_BUS_CNTL, tmp);
  208.      }
  209.      else if (!((info->ChipFamily == CHIP_FAMILY_RV380) ||
  210.                 (info->ChipFamily >= CHIP_FAMILY_R420)))
  211.      {
  212.                 /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */
  213.         tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
  214.         OUTREG(RADEON_BUS_CNTL, tmp);
  215.         } /* PCIE cards appears to not need this */
  216.  
  217.     tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
  218.     OUTREG(RADEON_BUS_CNTL, tmp);
  219.  
  220.     radeon_do_wait_for_idle();
  221.  
  222.         /* Sync everything up */
  223.     OUTREG(RADEON_ISYNC_CNTL,
  224.           (RADEON_ISYNC_ANY2D_IDLE3D |
  225.            RADEON_ISYNC_ANY3D_IDLE2D |
  226.            RADEON_ISYNC_WAIT_IDLEGUI |
  227.            RADEON_ISYNC_CPSCRATCH_IDLEGUI));
  228. }
  229.  
  230.  
  231.  
  232. #define RADEON_WAIT_UNTIL_IDLE() do {                   \
  233.     OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 1 ) );         \
  234.         OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |                           \
  235.                    RADEON_WAIT_3D_IDLECLEAN |                           \
  236.                    RADEON_WAIT_HOST_IDLECLEAN) );                       \
  237. } while (0)
  238.  
  239. #define R300_ZB_ZCACHE_CTLSTAT                  0x4f18
  240. #   define RADEON_RB3D_ZC_FLUSH     (1 << 0)
  241. #       define RADEON_RB3D_ZC_FREE              (1 << 2)
  242. #       define RADEON_RB3D_ZC_FLUSH_ALL         0x5
  243. #   define RADEON_RB3D_ZC_BUSY      (1 << 31)
  244. #   define R300_ZC_FLUSH                (1 << 0)
  245. #       define R300_ZC_FREE                     (1 << 1)
  246. #   define R300_ZC_BUSY             (1 << 31)
  247. #   define RADEON_RB3D_DC_FLUSH     (3 << 0)
  248. #       define RADEON_RB3D_DC_FREE              (3 << 2)
  249. #       define RADEON_RB3D_DC_FLUSH_ALL         0xf
  250. #   define RADEON_RB3D_DC_BUSY      (1 << 31)
  251. #   define R300_RB3D_DC_FLUSH       (2 << 0)
  252. #       define R300_RB3D_DC_FREE                (2 << 2)
  253. #
  254. #define RADEON_PURGE_CACHE() do {                                    \
  255.     if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) {                      \
  256.             OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 1));  \
  257.             OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE);    \
  258.     } else {                                                         \
  259.             OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 1));     \
  260.             OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE );       \
  261.         }                                                            \
  262. } while (0)
  263.  
  264. #define RADEON_FLUSH_ZCACHE() do {                                   \
  265.     if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) {     \
  266.             OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 1 ) ); \
  267.             OUT_RING( RADEON_RB3D_ZC_FLUSH );                        \
  268.     } else {                                                         \
  269.             OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 1 ) );     \
  270.             OUT_RING( R300_ZC_FLUSH );                               \
  271.         }                                                            \
  272. } while (0)
  273. #define RADEON_PURGE_ZCACHE() do {                  \
  274.     if (rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
  275.             OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 1));    \
  276.                 OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE);   \
  277.         } else {                                                        \
  278.             OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 1));    \
  279.                 OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE);                 \
  280.         }                                                               \
  281. } while (0)
  282.  
  283. static int radeon_cp_start(RHDPtr info)
  284. {
  285.      u32_t *ring, write;
  286.      u32_t ifl;
  287.      radeon_do_wait_for_idle(64);
  288.  
  289.      OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);
  290.  
  291.      ifl = safe_cli();
  292.  
  293.      BEGIN_RING(8);
  294.         /* isync can only be written through cp on r5xx write it here */
  295.        OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 1));
  296.        OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
  297.                 RADEON_ISYNC_ANY3D_IDLE2D |
  298.                 RADEON_ISYNC_WAIT_IDLEGUI |
  299.                 RADEON_ISYNC_CPSCRATCH_IDLEGUI);
  300.        RADEON_PURGE_CACHE();
  301.        RADEON_PURGE_ZCACHE();
  302.        RADEON_WAIT_UNTIL_IDLE();
  303.        ADVANCE_RING();
  304.     COMMIT_RING();
  305.  
  306.     safe_sti(ifl);
  307.  
  308.     radeon_do_wait_for_idle();
  309. };
  310.  
  311.  
  312. Bool init_cp(RHDPtr info)
  313. {
  314.      load_microcode(&rhd);
  315.  
  316.      init_ring_buffer(&rhd);
  317.  
  318.      radeon_engine_reset(&rhd);
  319.  
  320.      rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
  321.      OUTREG(RADEON_CP_RB_WPTR, rhd.ring_rp);
  322.  
  323.      radeon_cp_start(&rhd);
  324.  
  325.     return TRUE;
  326. };
  327.  
  328.  
  329.