Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #define R300_TEST
  3.  
  4. #include "r5xx_regs.h"
  5.  
  6. #define RADEON_BUS_CNTL                 0x0030
  7. #       define RADEON_BUS_MASTER_DIS            (1 << 6)
  8.  
  9.  
  10. #define RADEON_SCRATCH_UMSK             0x0770
  11. #define RADEON_SCRATCH_ADDR             0x0774
  12.  
  13. #define RADEON_CP_ME_RAM_ADDR           0x07d4
  14. #define RADEON_CP_ME_RAM_RADDR          0x07d8
  15. #define RADEON_CP_ME_RAM_DATAH          0x07dc
  16. #define RADEON_CP_ME_RAM_DATAL          0x07e0
  17.  
  18. #define RADEON_AIC_CNTL                 0x01d0
  19. #define RADEON_PCIGART_TRANSLATE_EN      (1 << 0)
  20.  
  21.  
  22. #define RADEON_CP_RB_BASE               0x0700
  23. #define RADEON_CP_RB_CNTL               0x0704
  24. #       define RADEON_BUF_SWAP_32BIT            (2 << 16)
  25. #       define RADEON_RB_NO_UPDATE              (1 << 27)
  26. #define RADEON_CP_RB_RPTR_ADDR          0x070c
  27. #define RADEON_CP_RB_RPTR               0x0710
  28. #define RADEON_CP_RB_WPTR               0x0714
  29.  
  30. #define RADEON_CP_RB_WPTR_DELAY         0x0718
  31. #       define RADEON_PRE_WRITE_TIMER_SHIFT     0
  32. #       define RADEON_PRE_WRITE_LIMIT_SHIFT     23
  33.  
  34. #define RADEON_CP_IB_BASE               0x0738
  35.  
  36. #define RADEON_CP_CSQ_CNTL              0x0740
  37. #       define RADEON_CSQ_CNT_PRIMARY_MASK      (0xff << 0)
  38. #       define RADEON_CSQ_PRIDIS_INDDIS         (0 << 28)
  39. #       define RADEON_CSQ_PRIPIO_INDDIS         (1 << 28)
  40. #       define RADEON_CSQ_PRIBM_INDDIS          (2 << 28)
  41. #       define RADEON_CSQ_PRIPIO_INDBM          (3 << 28)
  42. #       define RADEON_CSQ_PRIBM_INDBM           (4 << 28)
  43. #       define RADEON_CSQ_PRIPIO_INDPIO         (15 << 28)
  44.  
  45. #define RADEON_ISYNC_CNTL               0x1724
  46. #       define RADEON_ISYNC_ANY2D_IDLE3D        (1 << 0)
  47. #       define RADEON_ISYNC_ANY3D_IDLE2D        (1 << 1)
  48. #       define RADEON_ISYNC_TRIG2D_IDLE3D       (1 << 2)
  49. #       define RADEON_ISYNC_TRIG3D_IDLE2D       (1 << 3)
  50. #       define RADEON_ISYNC_WAIT_IDLEGUI        (1 << 4)
  51. #       define RADEON_ISYNC_CPSCRATCH_IDLEGUI   (1 << 5)
  52.  
  53. #define R5XX_LOOP_COUNT 2000000
  54.  
  55. #include "microcode.h"
  56.  
  57. #define RADEON_CLOCK_CNTL_DATA              0x000c
  58.  
  59. #define RADEON_CLOCK_CNTL_INDEX             0x0008
  60. #       define RADEON_PLL_WR_EN             (1 << 7)
  61. #       define RADEON_PLL_DIV_SEL           (3 << 8)
  62. #       define RADEON_PLL2_DIV_SEL_MASK     ~(3 << 8)
  63.  
  64. #define RADEON_MCLK_CNTL                    0x0012 /* PLL */
  65. #       define RADEON_FORCEON_MCLKA         (1 << 16)
  66. #       define RADEON_FORCEON_MCLKB         (1 << 17)
  67. #       define RADEON_FORCEON_YCLKA         (1 << 18)
  68. #       define RADEON_FORCEON_YCLKB         (1 << 19)
  69. #       define RADEON_FORCEON_MC            (1 << 20)
  70. #       define RADEON_FORCEON_AIC           (1 << 21)
  71. #       define R300_DISABLE_MC_MCLKA        (1 << 21)
  72. #       define R300_DISABLE_MC_MCLKB        (1 << 21)
  73.  
  74.  
  75. void RADEONPllErrataAfterData()
  76. {
  77.  
  78.     /* This function is required to workaround a hardware bug in some (all?)
  79.      * revisions of the R300.  This workaround should be called after every
  80.      * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
  81.      * may not be correct.
  82.      */
  83.     if (rhd.ChipSet <= RHD_RV380)
  84.     {
  85.         u32_t save, tmp;
  86.  
  87.         save = INREG(RADEON_CLOCK_CNTL_INDEX);
  88.         tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
  89.         OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp);
  90.         tmp = INREG(RADEON_CLOCK_CNTL_DATA);
  91.         OUTREG(RADEON_CLOCK_CNTL_INDEX, save);
  92.     }
  93. }
  94.  
  95.  
  96. /* Read PLL register */
  97. u32_t RADEONINPLL(int addr)
  98. {
  99.     u32_t       data;
  100.  
  101.     OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);
  102.     //RADEONPllErrataAfterIndex();
  103.     data = INREG(RADEON_CLOCK_CNTL_DATA);
  104.     RADEONPllErrataAfterData();
  105.  
  106.     return data;
  107. };
  108.  
  109. /* Write PLL information */
  110. void RADEONOUTPLL(int addr, u32_t data)
  111. {
  112.     OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) |
  113.                                       RADEON_PLL_WR_EN));
  114. //    RADEONPllErrataAfterIndex(info);
  115.     OUTREG(RADEON_CLOCK_CNTL_DATA, data);
  116.     RADEONPllErrataAfterData();
  117. }
  118.  
  119.  
  120.  
  121. static Bool
  122. R5xxFIFOWaitLocal(u32_t required)             //R100-R500
  123. {
  124.   int i;
  125.  
  126.   for (i = 0; i < R5XX_LOOP_COUNT; i++)
  127.     if (required <= (INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_FIFOCNT_MASK))
  128.             return TRUE;
  129.  
  130.   dbgprintf("%s: Timeout 0x%08X.\n", __func__,
  131.          (unsigned int) INREG(R5XX_RBBM_STATUS));
  132.   return FALSE;
  133. }
  134.  
  135. /*
  136.  * Flush all dirty data in the Pixel Cache to memory.
  137.  */
  138.  
  139. static Bool
  140. R5xx2DFlush()
  141. {
  142.     int i;
  143.  
  144.     MASKREG(R5XX_DSTCACHE_CTLSTAT,
  145.                 R5XX_DSTCACHE_FLUSH_ALL, R5XX_DSTCACHE_FLUSH_ALL);
  146.  
  147.     for (i = 0; i < R5XX_LOOP_COUNT; i++)
  148.       if (!(INREG(R5XX_DSTCACHE_CTLSTAT) & R5XX_DSTCACHE_BUSY))
  149.         return TRUE;
  150.  
  151.     dbgprintf("%s: Timeout 0x%08x.\n", __func__,
  152.          (unsigned int)INREG(R5XX_DSTCACHE_CTLSTAT));
  153.     return FALSE;
  154. }
  155.  
  156. static Bool
  157. R5xx2DIdleLocal()                                //R100-R500
  158. {
  159.     int i;
  160.  
  161.       /* wait for fifo to clear */
  162.     for (i = 0; i < R5XX_LOOP_COUNT; i++)
  163.       if (64 == (INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_FIFOCNT_MASK))
  164.         break;
  165.  
  166.     if (i == R5XX_LOOP_COUNT) {
  167.       dbgprintf("%s: FIFO Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS));
  168.       return FALSE;
  169.     }
  170.  
  171.       /* wait for engine to go idle */
  172.     for (i = 0; i < R5XX_LOOP_COUNT; i++) {
  173.       if (!(INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_ACTIVE)) {
  174.         R5xx2DFlush();
  175.         return TRUE;
  176.       }
  177.     }
  178.     dbgprintf("%s: Idle Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS));
  179.     return FALSE;
  180.  
  181. }
  182.  
  183. static void
  184. R5xx2DReset()
  185. {
  186.     u32_t save, tmp;
  187.     u32_t       clock_cntl_index;
  188.     u32_t       mclk_cntl;
  189.  
  190.       /* The following RBBM_SOFT_RESET sequence can help un-wedge
  191.        * an R300 after the command processor got stuck. */
  192.     save = INREG(R5XX_RBBM_SOFT_RESET);
  193.     tmp = save | R5XX_SOFT_RESET_CP |
  194.       R5XX_SOFT_RESET_HI | R5XX_SOFT_RESET_SE |
  195.       R5XX_SOFT_RESET_RE | R5XX_SOFT_RESET_PP |
  196.       R5XX_SOFT_RESET_E2 | R5XX_SOFT_RESET_RB;
  197.     OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
  198.  
  199.     INREG(R5XX_RBBM_SOFT_RESET);
  200.     tmp &= ~(R5XX_SOFT_RESET_CP | R5XX_SOFT_RESET_HI |
  201.          R5XX_SOFT_RESET_SE | R5XX_SOFT_RESET_RE |
  202.          R5XX_SOFT_RESET_PP | R5XX_SOFT_RESET_E2 |
  203.          R5XX_SOFT_RESET_RB);
  204.     OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
  205.  
  206.     INREG(R5XX_RBBM_SOFT_RESET);
  207.     OUTREG(R5XX_RBBM_SOFT_RESET, save);
  208.     INREG(R5XX_RBBM_SOFT_RESET);
  209.  
  210.     R5xx2DFlush();
  211.  
  212. #if 0
  213.     clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
  214.     RADEONPllErrataAfterIndex(info);
  215.  
  216.     mclk_cntl = RADEONINPLL(RADEON_MCLK_CNTL);
  217.  
  218.     RADEONOUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |
  219.                               RADEON_FORCEON_MCLKA |
  220.                               RADEON_FORCEON_MCLKB |
  221.                               RADEON_FORCEON_YCLKA |
  222.                               RADEON_FORCEON_YCLKB |
  223.                               RADEON_FORCEON_MC |
  224.                               RADEON_FORCEON_AIC));
  225. #endif
  226.  
  227.       /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
  228.        * unexpected behaviour on some machines.  Here we use
  229.        * R5XX_HOST_PATH_CNTL to reset it. */
  230.     save = INREG(R5XX_HOST_PATH_CNTL);
  231.  
  232.     tmp = INREG(R5XX_RBBM_SOFT_RESET);
  233.     tmp |= R5XX_SOFT_RESET_CP | R5XX_SOFT_RESET_HI | R5XX_SOFT_RESET_E2;
  234.     OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
  235.  
  236.     INREG(R5XX_RBBM_SOFT_RESET);
  237.     OUTREG(R5XX_RBBM_SOFT_RESET, 0);
  238.  
  239.     MASKREG(R5XX_RB2D_DSTCACHE_MODE,
  240.                R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE,
  241.                R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE);
  242.  
  243.     OUTREG(R5XX_HOST_PATH_CNTL, save | R5XX_HDP_SOFT_RESET);
  244.     INREG(R5XX_HOST_PATH_CNTL);
  245.     OUTREG(R5XX_HOST_PATH_CNTL, save);
  246.  
  247. #if 0
  248.     OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
  249.     RADEONPllErrataAfterIndex(info);
  250.     RADEONOUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
  251. #endif
  252. }
  253.  
  254. void
  255. R5xx2DSetup()
  256. {
  257.  
  258.     /* Setup engine location. This shouldn't be necessary since we
  259.     * set them appropriately before any accel ops, but let's avoid
  260.      * random bogus DMA in case we inadvertently trigger the engine
  261.      * in the wrong place (happened). */
  262.     R5xxFIFOWaitLocal(2);
  263.     OUTREG(R5XX_DST_PITCH_OFFSET,rhd.dst_pitch_offset);
  264.     OUTREG(R5XX_SRC_PITCH_OFFSET,rhd.dst_pitch_offset);
  265.  
  266.     R5xxFIFOWaitLocal(1);
  267.     MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN);
  268.  
  269.     OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl);
  270.  
  271.     R5xxFIFOWaitLocal(1);
  272.     OUTREG(R5XX_DEFAULT_SC_BOTTOM_RIGHT,
  273.            R5XX_DEFAULT_SC_RIGHT_MAX | R5XX_DEFAULT_SC_BOTTOM_MAX);
  274.     R5xxFIFOWaitLocal(1);
  275.     OUTREG(R5XX_DP_GUI_MASTER_CNTL, rhd.gui_control |
  276.            R5XX_GMC_BRUSH_SOLID_COLOR | R5XX_GMC_SRC_DATATYPE_COLOR);
  277.  
  278.     R5xxFIFOWaitLocal(5);
  279.     OUTREG(R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF);
  280.     OUTREG(R5XX_DP_BRUSH_BKGD_CLR, 0x00000000);
  281.     OUTREG(R5XX_DP_SRC_FRGD_CLR, 0xFFFFFFFF);
  282.     OUTREG(R5XX_DP_SRC_BKGD_CLR, 0x00000000);
  283.     OUTREG(R5XX_DP_WRITE_MASK, 0xFFFFFFFF);
  284.  
  285.     R5xx2DIdleLocal();
  286. }
  287.  
  288. void R5xxFIFOWait(u32_t required)
  289. {
  290.     if (!R5xxFIFOWaitLocal(required)) {
  291.       R5xx2DReset();
  292.       R5xx2DSetup();
  293.     }
  294. }
  295.  
  296. void R5xx2DIdle()
  297. {
  298.     if (!R5xx2DIdleLocal()) {
  299.       R5xx2DReset();
  300.       R5xx2DSetup();
  301.     }
  302. }
  303.  
  304. static void load_microcode()
  305. {
  306.   u32_t ifl;
  307.   int i;
  308.  
  309.   ifl = safe_cli();
  310.  
  311.   OUTREG(RADEON_CP_ME_RAM_ADDR,0);
  312.  
  313.   R5xx2DIdleLocal();
  314.  
  315.   switch(rhd.ChipSet)
  316.   {
  317.     case RHD_R300:
  318.     case RHD_R350:
  319.     case RHD_RV350:
  320.     case RHD_RV370:
  321.     case RHD_RV380:
  322.       dbgprintf("Loading R300 microcode\n");
  323.       for (i = 0; i < 256; i++)
  324.       {
  325.         OUTREG(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]);
  326.         OUTREG(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]);
  327.       }
  328.       break;
  329.  
  330.     case RHD_RV505:
  331.     case RHD_RV515:
  332.     case RHD_RV516:
  333.     case RHD_R520:
  334.     case RHD_RV530:
  335.     case RHD_RV535:
  336.     case RHD_RV550:
  337.     case RHD_RV560:
  338.     case RHD_RV570:
  339.     case RHD_R580:
  340.       dbgprintf("Loading R500 microcode\n");
  341.       for (i = 0; i < 256; i++)
  342.       {
  343.         OUTREG(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]);
  344.         OUTREG(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]);
  345.       }
  346.   }
  347.   safe_sti(ifl);
  348. };
  349.  
  350.  
  351. void  R5xx2DInit()
  352. {
  353.     u32_t base;
  354.     int screensize;
  355.     int screenpitch;
  356.  
  357.     screensize = GetScreenSize();
  358.     screenpitch = GetScreenPitch();
  359.  
  360.     rhd.displayWidth  = screensize >> 16;
  361.     rhd.displayHeight = screensize & 0xFFFF;
  362.  
  363.     rhd.__xmin = 0;
  364.     rhd.__ymin = 0;
  365.     rhd.__xmax = rhd.displayWidth  - 1;
  366.     rhd.__ymax = rhd.displayHeight - 1;
  367.  
  368.     clip.xmin = 0;
  369.     clip.ymin = 0;
  370.     clip.xmax = rhd.displayWidth  - 1;
  371.     clip.ymax = rhd.displayHeight - 1;
  372.  
  373.     dbgprintf("width  %d \n", rhd.displayWidth);
  374.     dbgprintf("height %d \n", rhd.displayHeight);
  375.  
  376.     rhd.gui_control = (R5XX_DATATYPE_ARGB8888 << R5XX_GMC_DST_DATATYPE_SHIFT) |
  377.                        R5XX_GMC_CLR_CMP_CNTL_DIS | R5XX_GMC_DST_PITCH_OFFSET_CNTL;
  378.  
  379.     dbgprintf("gui_control %x \n", rhd.gui_control);
  380.  
  381.     rhd.surface_cntl = 0;
  382.     rhd.dst_pitch_offset = ((screenpitch / 64) << 22) |
  383.                             ((rhd.FbIntAddress + rhd.FbScanoutStart) >> 10);
  384.  
  385.     dbgprintf("dst_pitch_offset %x \n", rhd.dst_pitch_offset);
  386.  
  387.  
  388.     scr_pixmap.width  = rhd.displayWidth;
  389.     scr_pixmap.height = rhd.displayHeight;
  390.     scr_pixmap.format = PICT_a8r8g8b8;
  391.     scr_pixmap.pitch  = screenpitch;
  392.     scr_pixmap.local  = (void*)rhd.FbIntAddress;
  393.     scr_pixmap.pitch_offset =  rhd.dst_pitch_offset;
  394.     scr_pixmap.mapped = (void*)0;
  395.  
  396.  
  397.     MASKREG(R5XX_GB_TILE_CONFIG, 0, R5XX_ENABLE_TILING);
  398.     OUTREG (R5XX_WAIT_UNTIL, R5XX_WAIT_2D_IDLECLEAN | R5XX_WAIT_3D_IDLECLEAN);
  399.     MASKREG(R5XX_DST_PIPE_CONFIG, R5XX_PIPE_AUTO_CONFIG, R5XX_PIPE_AUTO_CONFIG);
  400.     MASKREG(R5XX_RB2D_DSTCACHE_MODE,
  401.             R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE,
  402.             R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE);
  403.  
  404.  
  405.     R5xx2DReset();
  406.     R5xx2DSetup();
  407.  
  408.     MASKREG( RADEON_AIC_CNTL,0, RADEON_PCIGART_TRANSLATE_EN);
  409.  
  410.   //  load_microcode();
  411.  
  412.  //   rhd.ring_base = CreateRingBuffer(0x8000, PG_SW | PG_NOCACHE);
  413.  //   dbgprintf("create cp ring buffer %x\n", rhd.ring_base);
  414.  //   base = GetPgAddr(rhd.ring_base);
  415.  
  416.  //   OUTREG(RADEON_CP_RB_BASE, base);
  417.  //   dbgprintf("ring base %x\n", base);
  418.  
  419.  //   OUTREG(RADEON_CP_RB_WPTR_DELAY, 0);
  420.  
  421.  //   rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
  422.  //   OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp);
  423.  
  424.  //   OUTREG(RADEON_CP_RB_RPTR_ADDR, 0); // ring buffer read pointer no update
  425.  
  426.  //   OUTREG(RADEON_CP_RB_CNTL, RADEON_RB_NO_UPDATE | 12);
  427.  //   OUTREG(RADEON_SCRATCH_UMSK, 0);          // no scratch update
  428.  
  429.  //   MASKREG(RADEON_BUS_CNTL,0,RADEON_BUS_MASTER_DIS);
  430.  
  431.  //   R5xx2DIdleLocal();
  432.  
  433.  //   OUTREG(RADEON_ISYNC_CNTL, RADEON_ISYNC_ANY2D_IDLE3D |
  434.  //                             RADEON_ISYNC_ANY3D_IDLE2D |
  435.  //                             RADEON_ISYNC_WAIT_IDLEGUI |
  436.  //                             RADEON_ISYNC_CPSCRATCH_IDLEGUI);
  437.  
  438.  //   OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);    // run
  439.  
  440. }
  441.  
  442.  
  443.  
  444.