Subversion Repositories Kolibri OS

Rev

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