Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #include "r5xx_regs.h"
  3.  
  4. #define RADEON_BUS_CNTL                 0x0030
  5. #       define RADEON_BUS_MASTER_DIS            (1 << 6)
  6.  
  7.  
  8. #define RADEON_SCRATCH_UMSK             0x0770
  9. #define RADEON_SCRATCH_ADDR             0x0774
  10.  
  11. #define RADEON_CP_ME_RAM_ADDR           0x07d4
  12. #define RADEON_CP_ME_RAM_RADDR          0x07d8
  13. #define RADEON_CP_ME_RAM_DATAH          0x07dc
  14. #define RADEON_CP_ME_RAM_DATAL          0x07e0
  15.  
  16. #define RADEON_AIC_CNTL                 0x01d0
  17. #define RADEON_PCIGART_TRANSLATE_EN      (1 << 0)
  18.  
  19.  
  20. #define RADEON_CP_RB_BASE               0x0700
  21. #define RADEON_CP_RB_CNTL               0x0704
  22. #       define RADEON_BUF_SWAP_32BIT            (2 << 16)
  23. #       define RADEON_RB_NO_UPDATE              (1 << 27)
  24. #define RADEON_CP_RB_RPTR_ADDR          0x070c
  25. #define RADEON_CP_RB_RPTR               0x0710
  26. #define RADEON_CP_RB_WPTR               0x0714
  27.  
  28. #define RADEON_CP_RB_WPTR_DELAY         0x0718
  29. #       define RADEON_PRE_WRITE_TIMER_SHIFT     0
  30. #       define RADEON_PRE_WRITE_LIMIT_SHIFT     23
  31.  
  32. #define RADEON_CP_IB_BASE               0x0738
  33.  
  34. #define RADEON_CP_CSQ_CNTL              0x0740
  35. #       define RADEON_CSQ_CNT_PRIMARY_MASK      (0xff << 0)
  36. #       define RADEON_CSQ_PRIDIS_INDDIS         (0 << 28)
  37. #       define RADEON_CSQ_PRIPIO_INDDIS         (1 << 28)
  38. #       define RADEON_CSQ_PRIBM_INDDIS          (2 << 28)
  39. #       define RADEON_CSQ_PRIPIO_INDBM          (3 << 28)
  40. #       define RADEON_CSQ_PRIBM_INDBM           (4 << 28)
  41. #       define RADEON_CSQ_PRIPIO_INDPIO         (15 << 28)
  42.  
  43. #define RADEON_ISYNC_CNTL               0x1724
  44. #       define RADEON_ISYNC_ANY2D_IDLE3D        (1 << 0)
  45. #       define RADEON_ISYNC_ANY3D_IDLE2D        (1 << 1)
  46. #       define RADEON_ISYNC_TRIG2D_IDLE3D       (1 << 2)
  47. #       define RADEON_ISYNC_TRIG3D_IDLE2D       (1 << 3)
  48. #       define RADEON_ISYNC_WAIT_IDLEGUI        (1 << 4)
  49. #       define RADEON_ISYNC_CPSCRATCH_IDLEGUI   (1 << 5)
  50.  
  51. #define R5XX_LOOP_COUNT 2000000
  52.  
  53. #include "microcode.h"
  54.  
  55. static Bool
  56. R5xxFIFOWaitLocal(CARD32 required)             //R100-R500
  57. {
  58.   int i;
  59.  
  60.   for (i = 0; i < R5XX_LOOP_COUNT; i++)
  61.     if (required <= (INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_FIFOCNT_MASK))
  62.             return TRUE;
  63.  
  64.   dbgprintf("%s: Timeout 0x%08X.\n", __func__,
  65.          (unsigned int) INREG(R5XX_RBBM_STATUS));
  66.   return FALSE;
  67. }
  68.  
  69. /*
  70.  * Flush all dirty data in the Pixel Cache to memory.
  71.  */
  72.  
  73. static Bool
  74. R5xx2DFlush()
  75. {
  76.     int i;
  77.  
  78.     MASKREG(R5XX_DSTCACHE_CTLSTAT,
  79.                 R5XX_DSTCACHE_FLUSH_ALL, R5XX_DSTCACHE_FLUSH_ALL);
  80.  
  81.     for (i = 0; i < R5XX_LOOP_COUNT; i++)
  82.       if (!(INREG(R5XX_DSTCACHE_CTLSTAT) & R5XX_DSTCACHE_BUSY))
  83.         return TRUE;
  84.  
  85.     dbgprintf("%s: Timeout 0x%08x.\n", __func__,
  86.          (unsigned int)INREG(R5XX_DSTCACHE_CTLSTAT));
  87.     return FALSE;
  88. }
  89.  
  90. static Bool
  91. R5xx2DIdleLocal()                                //R100-R500
  92. {
  93.     int i;
  94.  
  95.       /* wait for fifo to clear */
  96.     for (i = 0; i < R5XX_LOOP_COUNT; i++)
  97.       if (64 == (INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_FIFOCNT_MASK))
  98.         break;
  99.  
  100.     if (i == R5XX_LOOP_COUNT) {
  101.       dbgprintf("%s: FIFO Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS));
  102.       return FALSE;
  103.     }
  104.  
  105.       /* wait for engine to go idle */
  106.     for (i = 0; i < R5XX_LOOP_COUNT; i++) {
  107.       if (!(INREG(R5XX_RBBM_STATUS) & R5XX_RBBM_ACTIVE)) {
  108.         R5xx2DFlush();
  109.         return TRUE;
  110.       }
  111.     }
  112.     dbgprintf("%s: Idle Timeout 0x%08X.\n", __func__,INREG(R5XX_RBBM_STATUS));
  113.     return FALSE;
  114.  
  115. }
  116.  
  117. static void
  118. R5xx2DReset()
  119. {
  120.     CARD32 save, tmp;
  121.  
  122.       /* The following RBBM_SOFT_RESET sequence can help un-wedge
  123.        * an R300 after the command processor got stuck. */
  124.     save = INREG(R5XX_RBBM_SOFT_RESET);
  125.     tmp = save | R5XX_SOFT_RESET_CP |
  126.       R5XX_SOFT_RESET_HI | R5XX_SOFT_RESET_SE |
  127.       R5XX_SOFT_RESET_RE | R5XX_SOFT_RESET_PP |
  128.       R5XX_SOFT_RESET_E2 | R5XX_SOFT_RESET_RB;
  129.     OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
  130.  
  131.     INREG(R5XX_RBBM_SOFT_RESET);
  132.     tmp &= ~(R5XX_SOFT_RESET_CP | R5XX_SOFT_RESET_HI |
  133.          R5XX_SOFT_RESET_SE | R5XX_SOFT_RESET_RE |
  134.          R5XX_SOFT_RESET_PP | R5XX_SOFT_RESET_E2 |
  135.          R5XX_SOFT_RESET_RB);
  136.     OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
  137.  
  138.     INREG(R5XX_RBBM_SOFT_RESET);
  139.     OUTREG(R5XX_RBBM_SOFT_RESET, save);
  140.     INREG(R5XX_RBBM_SOFT_RESET);
  141.  
  142.     R5xx2DFlush();
  143.  
  144.       /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
  145.        * unexpected behaviour on some machines.  Here we use
  146.        * R5XX_HOST_PATH_CNTL to reset it. */
  147.     save = INREG(R5XX_HOST_PATH_CNTL);
  148.  
  149.     tmp = INREG(R5XX_RBBM_SOFT_RESET);
  150.     tmp |= R5XX_SOFT_RESET_CP | R5XX_SOFT_RESET_HI | R5XX_SOFT_RESET_E2;
  151.     OUTREG(R5XX_RBBM_SOFT_RESET, tmp);
  152.  
  153.     INREG(R5XX_RBBM_SOFT_RESET);
  154.     OUTREG(R5XX_RBBM_SOFT_RESET, 0);
  155.  
  156.     MASKREG(R5XX_RB2D_DSTCACHE_MODE,
  157.                R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE,
  158.                R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE);
  159.  
  160.     OUTREG(R5XX_HOST_PATH_CNTL, save | R5XX_HDP_SOFT_RESET);
  161.     INREG(R5XX_HOST_PATH_CNTL);
  162.     OUTREG(R5XX_HOST_PATH_CNTL, save);
  163. }
  164.  
  165. void
  166. R5xx2DSetup()
  167. {
  168.  
  169.     /* Setup engine location. This shouldn't be necessary since we
  170.     * set them appropriately before any accel ops, but let's avoid
  171.      * random bogus DMA in case we inadvertently trigger the engine
  172.      * in the wrong place (happened). */
  173.     R5xxFIFOWaitLocal(2);
  174.     OUTREG(R5XX_DST_PITCH_OFFSET,rhd.dst_pitch_offset);
  175.     OUTREG(R5XX_SRC_PITCH_OFFSET,rhd.dst_pitch_offset);
  176.  
  177.     R5xxFIFOWaitLocal(1);
  178.     MASKREG(R5XX_DP_DATATYPE, 0, R5XX_HOST_BIG_ENDIAN_EN);
  179.  
  180.     OUTREG(R5XX_SURFACE_CNTL, rhd.surface_cntl);
  181.  
  182.     R5xxFIFOWaitLocal(1);
  183.     OUTREG(R5XX_DEFAULT_SC_BOTTOM_RIGHT,
  184.            R5XX_DEFAULT_SC_RIGHT_MAX | R5XX_DEFAULT_SC_BOTTOM_MAX);
  185.     R5xxFIFOWaitLocal(1);
  186.     OUTREG(R5XX_DP_GUI_MASTER_CNTL, rhd.gui_control |
  187.            R5XX_GMC_BRUSH_SOLID_COLOR | R5XX_GMC_SRC_DATATYPE_COLOR);
  188.  
  189.     R5xxFIFOWaitLocal(5);
  190.     OUTREG(R5XX_DP_BRUSH_FRGD_CLR, 0xFFFFFFFF);
  191.     OUTREG(R5XX_DP_BRUSH_BKGD_CLR, 0x00000000);
  192.     OUTREG(R5XX_DP_SRC_FRGD_CLR, 0xFFFFFFFF);
  193.     OUTREG(R5XX_DP_SRC_BKGD_CLR, 0x00000000);
  194.     OUTREG(R5XX_DP_WRITE_MASK, 0xFFFFFFFF);
  195.  
  196.     R5xx2DIdleLocal();
  197. }
  198.  
  199. void R5xxFIFOWait(CARD32 required)
  200. {
  201.     if (!R5xxFIFOWaitLocal(required)) {
  202.       R5xx2DReset();
  203.       R5xx2DSetup();
  204.     }
  205. }
  206.  
  207. void R5xx2DIdle()
  208. {
  209.     if (!R5xx2DIdleLocal()) {
  210.       R5xx2DReset();
  211.       R5xx2DSetup();
  212.     }
  213. }
  214.  
  215. static void load_microcode()
  216. {
  217.   u32 ifl;
  218.   int i;
  219.  
  220.   ifl = safe_cli();
  221.  
  222.   R5xx2DIdleLocal();
  223.   OUTREG(RADEON_CP_ME_RAM_ADDR,0);
  224.   for (i = 0; i < 256; i++)
  225.   {
  226.     OUTREG(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]);
  227.     OUTREG(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]);
  228.   }
  229.   safe_sti(ifl);
  230. };
  231.  
  232.  
  233. void  R5xx2DInit()
  234. {
  235.     u32 base;
  236.  
  237.     rhd.displayWidth  = INREG(D1GRPH_X_END);
  238.     rhd.displayHeight = INREG(D1GRPH_Y_END);
  239.  
  240.     rhd.__xmin = 0;
  241.     rhd.__ymin = 0;
  242.     rhd.__xmax = rhd.displayWidth  - 1;
  243.     rhd.__ymax = rhd.displayHeight - 1;
  244.  
  245.     clip.xmin = 0;
  246.     clip.ymin = 0;
  247.     clip.xmax = rhd.displayWidth  - 1;
  248.     clip.ymax = rhd.displayHeight - 1;
  249.  
  250.     dbgprintf("width  %d \n", rhd.displayWidth);
  251.     dbgprintf("height %d \n", rhd.displayHeight);
  252.  
  253.     rhd.gui_control = (R5XX_DATATYPE_ARGB8888 << R5XX_GMC_DST_DATATYPE_SHIFT) |
  254.                        R5XX_GMC_CLR_CMP_CNTL_DIS | R5XX_GMC_DST_PITCH_OFFSET_CNTL;
  255.  
  256.     dbgprintf("gui_control %x \n", rhd.gui_control);
  257.  
  258.     rhd.surface_cntl = 0;
  259.     rhd.dst_pitch_offset = (((rhd.displayWidth * 4) / 64) << 22) |
  260.                             ((rhd.FbIntAddress + rhd.FbScanoutStart) >> 10);
  261.  
  262.     dbgprintf("dst_pitch_offset %x \n", rhd.dst_pitch_offset);
  263.  
  264.     MASKREG(R5XX_GB_TILE_CONFIG, 0, R5XX_ENABLE_TILING);
  265.     OUTREG (R5XX_WAIT_UNTIL, R5XX_WAIT_2D_IDLECLEAN | R5XX_WAIT_3D_IDLECLEAN);
  266.     MASKREG(R5XX_DST_PIPE_CONFIG, R5XX_PIPE_AUTO_CONFIG, R5XX_PIPE_AUTO_CONFIG);
  267.     MASKREG(R5XX_RB2D_DSTCACHE_MODE,
  268.             R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE,
  269.             R5XX_RB2D_DC_AUTOFLUSH_ENABLE | R5XX_RB2D_DC_DISABLE_IGNORE_PE);
  270.  
  271.  
  272.     R5xx2DReset();
  273.     R5xx2DSetup();
  274.  
  275.     MASKREG( RADEON_AIC_CNTL,0, RADEON_PCIGART_TRANSLATE_EN);
  276.  
  277.     load_microcode();
  278.  
  279.     rhd.ring_base = CreateRingBuffer(0x8000, PG_SW | PG_NOCACHE);
  280.     dbgprintf("create cp ring buffer %x\n", rhd.ring_base);
  281.     base = GetPgAddr(rhd.ring_base);
  282.  
  283.     OUTREG(RADEON_CP_RB_BASE, base);
  284.     dbgprintf("ring base %x\n", base);
  285.  
  286.     OUTREG(RADEON_CP_RB_WPTR_DELAY, 0);
  287.  
  288.     rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
  289.     OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp);
  290.  
  291.     OUTREG(RADEON_CP_RB_RPTR_ADDR, 0); // ring buffer read pointer no update
  292.  
  293.     OUTREG(RADEON_CP_RB_CNTL, RADEON_RB_NO_UPDATE | 12);
  294.     OUTREG(RADEON_SCRATCH_UMSK, 0);          // no scratch update
  295.  
  296.     MASKREG(RADEON_BUS_CNTL,0,RADEON_BUS_MASTER_DIS);
  297.  
  298.     R5xx2DIdleLocal();
  299.  
  300.     OUTREG(RADEON_ISYNC_CNTL, RADEON_ISYNC_ANY2D_IDLE3D |
  301.                               RADEON_ISYNC_ANY3D_IDLE2D |
  302.                               RADEON_ISYNC_WAIT_IDLEGUI |
  303.                               RADEON_ISYNC_CPSCRATCH_IDLEGUI);
  304.  
  305.     OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);    // run
  306.  
  307.  
  308.  //   OUTREG(D1CUR_SIZE, (31<<16)|31);
  309.  //   OUTREG(D1CUR_CONTROL, 0x300);
  310. }
  311.  
  312.  
  313.  
  314.