Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
  3.  *                VA Linux Systems Inc., Fremont, California.
  4.  *
  5.  * All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining
  8.  * a copy of this software and associated documentation files (the
  9.  * "Software"), to deal in the Software without restriction, including
  10.  * without limitation on the rights to use, copy, modify, merge,
  11.  * publish, distribute, sublicense, and/or sell copies of the Software,
  12.  * and to permit persons to whom the Software is furnished to do so,
  13.  * subject to the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice (including the
  16.  * next paragraph) shall be included in all copies or substantial
  17.  * portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22.  * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
  23.  * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  24.  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  26.  * DEALINGS IN THE SOFTWARE.
  27.  */
  28.  
  29.  
  30. int Init3DEngine(RHDPtr info)
  31. {
  32.     u32_t gb_tile_config, su_reg_dest, vap_cntl;
  33.  
  34.     u32_t *ring;
  35.     u32_t ifl;
  36.  
  37.    // info->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1;
  38.  
  39.     ifl = safe_cli();
  40.  
  41.     FIFOWait(64);
  42.     delay(2);
  43.  
  44.     if (IS_R300_3D || IS_R500_3D) {
  45.  
  46.         BEGIN_ACCEL(3);
  47.         OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
  48.         OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
  49.         OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
  50.         FINISH_ACCEL();
  51.  
  52.         gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
  53.  
  54.         switch(info->num_gb_pipes)
  55.         {
  56.             case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
  57.             case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
  58.             case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
  59.             default:
  60.             case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
  61.         }
  62.  
  63.         BEGIN_ACCEL(5);
  64.         OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config);
  65.         OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
  66.         OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG);
  67.         OUT_ACCEL_REG(R300_GB_SELECT, 0);
  68.         OUT_ACCEL_REG(R300_GB_ENABLE, 0);
  69.         FINISH_ACCEL();
  70.  
  71.         if (IS_R500_3D) {
  72.         su_reg_dest = ((1 << info->num_gb_pipes) - 1);
  73.             BEGIN_ACCEL(2);
  74.             OUT_ACCEL_REG(R500_SU_REG_DEST, su_reg_dest);
  75.             OUT_ACCEL_REG(R500_VAP_INDEX_OFFSET, 0);
  76.             FINISH_ACCEL();
  77.         }
  78.  
  79.         BEGIN_ACCEL(3);
  80.         OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
  81.         OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
  82.         OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
  83.         FINISH_ACCEL();
  84.  
  85.         BEGIN_ACCEL(5);
  86.         OUT_ACCEL_REG(R300_GB_AA_CONFIG, 0);
  87.         OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
  88.         OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
  89.         OUT_ACCEL_REG(R300_GB_MSPOS0, ((8 << R300_MS_X0_SHIFT) |
  90.                                        (8 << R300_MS_Y0_SHIFT) |
  91.                                        (8 << R300_MS_X1_SHIFT) |
  92.                                        (8 << R300_MS_Y1_SHIFT) |
  93.                                        (8 << R300_MS_X2_SHIFT) |
  94.                                        (8 << R300_MS_Y2_SHIFT) |
  95.                                        (8 << R300_MSBD0_Y_SHIFT) |
  96.                                        (7 << R300_MSBD0_X_SHIFT)));
  97.         OUT_ACCEL_REG(R300_GB_MSPOS1, ((8 << R300_MS_X3_SHIFT) |
  98.                                        (8 << R300_MS_Y3_SHIFT) |
  99.                                        (8 << R300_MS_X4_SHIFT) |
  100.                                        (8 << R300_MS_Y4_SHIFT) |
  101.                                        (8 << R300_MS_X5_SHIFT) |
  102.                                        (8 << R300_MS_Y5_SHIFT) |
  103.                                        (8 << R300_MSBD1_SHIFT)));
  104.         FINISH_ACCEL();
  105.  
  106.         BEGIN_ACCEL(5);
  107.         OUT_ACCEL_REG(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL);
  108.         OUT_ACCEL_REG(R300_GA_POLY_MODE, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE);
  109.         OUT_ACCEL_REG(R300_GA_ROUND_MODE, (R300_GEOMETRY_ROUND_NEAREST |
  110.                                           R300_COLOR_ROUND_NEAREST));
  111.         OUT_ACCEL_REG(R300_GA_COLOR_CONTROL, (R300_RGB0_SHADING_GOURAUD |
  112.                                               R300_ALPHA0_SHADING_GOURAUD |
  113.                                               R300_RGB1_SHADING_GOURAUD |
  114.                                               R300_ALPHA1_SHADING_GOURAUD |
  115.                                               R300_RGB2_SHADING_GOURAUD |
  116.                                               R300_ALPHA2_SHADING_GOURAUD |
  117.                                               R300_RGB3_SHADING_GOURAUD |
  118.                                               R300_ALPHA3_SHADING_GOURAUD));
  119.         OUT_ACCEL_REG(R300_GA_OFFSET, 0);
  120.         FINISH_ACCEL();
  121.  
  122.         BEGIN_ACCEL(5);
  123.         OUT_ACCEL_REG(R300_SU_TEX_WRAP, 0);
  124.         OUT_ACCEL_REG(R300_SU_POLY_OFFSET_ENABLE, 0);
  125.         OUT_ACCEL_REG(R300_SU_CULL_MODE, R300_FACE_NEG);
  126.         OUT_ACCEL_REG(R300_SU_DEPTH_SCALE, 0x4b7fffff);
  127.         OUT_ACCEL_REG(R300_SU_DEPTH_OFFSET, 0);
  128.         FINISH_ACCEL();
  129.  
  130.         /* setup the VAP */
  131.         if (info->has_tcl)
  132.             vap_cntl = ((5 << R300_PVS_NUM_SLOTS_SHIFT) |
  133.                         (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
  134.                         (9 << R300_VF_MAX_VTX_NUM_SHIFT));
  135.         else
  136.             vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
  137.                         (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
  138.                         (5 << R300_VF_MAX_VTX_NUM_SHIFT));
  139.  
  140.         if (info->ChipFamily == CHIP_FAMILY_RV515)
  141.             vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
  142.         else if ((info->ChipFamily == CHIP_FAMILY_RV530) ||
  143.                  (info->ChipFamily == CHIP_FAMILY_RV560) ||
  144.                  (info->ChipFamily == CHIP_FAMILY_RV570))
  145.             vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
  146.         else if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
  147.                  (info->ChipFamily == CHIP_FAMILY_R420))
  148.             vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
  149.         else if ((info->ChipFamily == CHIP_FAMILY_R520) ||
  150.                  (info->ChipFamily == CHIP_FAMILY_R580))
  151.             vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
  152.         else
  153.             vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
  154.  
  155.     if (info->has_tcl)
  156.         BEGIN_ACCEL(15);
  157.         else
  158.             BEGIN_ACCEL(9);
  159.         OUT_ACCEL_REG(R300_VAP_VTX_STATE_CNTL, 0);
  160.         OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
  161.  
  162.         if (info->has_tcl)
  163.             OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, 0);
  164.         else
  165.             OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
  166.         OUT_ACCEL_REG(R300_VAP_CNTL, vap_cntl);
  167.         OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
  168.         OUT_ACCEL_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
  169.         OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
  170.  
  171.         OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
  172.                     ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
  173.                      (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
  174.                      (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
  175.                      (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_0_SHIFT) |
  176.                        ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
  177.                         << R300_WRITE_ENA_0_SHIFT) |
  178.                      (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
  179.                      (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
  180.                      (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
  181.                      (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_1_SHIFT) |
  182.                        ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
  183.                         << R300_WRITE_ENA_1_SHIFT)));
  184.         OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_1,
  185.                      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_2_SHIFT) |
  186.                       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_2_SHIFT) |
  187.                       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_2_SHIFT) |
  188.                       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_2_SHIFT) |
  189.                        ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
  190.                         << R300_WRITE_ENA_2_SHIFT)));
  191.  
  192.     if (info->has_tcl) {
  193.             OUT_ACCEL_REG(R300_VAP_PVS_FLOW_CNTL_OPC, 0);
  194.             OUT_ACCEL_REG(R300_VAP_GB_VERT_CLIP_ADJ, 0x3f800000);
  195.             OUT_ACCEL_REG(R300_VAP_GB_VERT_DISC_ADJ, 0x3f800000);
  196.             OUT_ACCEL_REG(R300_VAP_GB_HORZ_CLIP_ADJ, 0x3f800000);
  197.             OUT_ACCEL_REG(R300_VAP_GB_HORZ_DISC_ADJ, 0x3f800000);
  198.             OUT_ACCEL_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
  199.         }
  200.         FINISH_ACCEL();
  201.  
  202.         /* pre-load the vertex shaders */
  203.     if (info->has_tcl) {
  204.         /* exa mask/Xv bicubic shader program
  205.  
  206.            dcl_position   v0
  207.            dcl_texcoord   v1
  208.            dcl_texcoord1  v2
  209.  
  210.            mov oPos,  v0
  211.            mov oT0,   v1
  212.            mov oT1,   v2      */
  213.  
  214.  
  215.             BEGIN_ACCEL(13);
  216.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
  217.             /* PVS inst 0 */
  218.             OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
  219.                           (R300_PVS_DST_OPCODE(R300_VE_ADD) |
  220.                            R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
  221.                            R300_PVS_DST_OFFSET(0) |
  222.                            R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
  223.                            R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
  224.             OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
  225.                       (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  226.                        R300_PVS_SRC_OFFSET(0) |
  227.                        R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
  228.                        R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
  229.                        R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
  230.                        R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
  231.             OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
  232.                       (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  233.                        R300_PVS_SRC_OFFSET(0) |
  234.                        R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  235.                        R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  236.                        R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  237.                        R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  238.             OUT_ACCEL_REG (R300_VAP_PVS_VECTOR_DATA_REG,
  239.                       (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  240.                        R300_PVS_SRC_OFFSET(0) |
  241.                        R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  242.                        R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  243.                        R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  244.                        R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  245.  
  246.             /* PVS inst 1 */
  247.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  248.                      (R300_PVS_DST_OPCODE(R300_VE_ADD) |
  249.                       R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
  250.                       R300_PVS_DST_OFFSET(1) |
  251.                       R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
  252.                       R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
  253.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  254.                      (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  255.                       R300_PVS_SRC_OFFSET(6) |
  256.                       R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
  257.                       R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
  258.                       R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
  259.                       R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
  260.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  261.                      (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  262.                       R300_PVS_SRC_OFFSET(6) |
  263.                       R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  264.                       R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  265.                       R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  266.                       R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  267.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  268.                      (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  269.                       R300_PVS_SRC_OFFSET(6) |
  270.                       R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  271.                       R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  272.                       R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  273.                       R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  274.  
  275.             /* PVS inst 2 */
  276.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  277.                           (R300_PVS_DST_OPCODE(R300_VE_ADD) |
  278.                            R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
  279.                            R300_PVS_DST_OFFSET(2) |
  280.                            R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
  281.                            R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
  282.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  283.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  284.                            R300_PVS_SRC_OFFSET(7) |
  285.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
  286.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
  287.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
  288.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
  289.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  290.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  291.                            R300_PVS_SRC_OFFSET(7) |
  292.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  293.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  294.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  295.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  296.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  297.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  298.                            R300_PVS_SRC_OFFSET(7) |
  299.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  300.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  301.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  302.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  303.             FINISH_ACCEL();
  304.  
  305.             BEGIN_ACCEL(9);
  306.  
  307.         /* exa no mask instruction
  308.  
  309.              dcl_position   v0
  310.              dcl_texcoord   v1
  311.  
  312.              mov oPos,  v0
  313.              mov oT0,   v1      */
  314.  
  315.  
  316.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 3);
  317.             /* PVS inst 0 */
  318.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  319.                           (R300_PVS_DST_OPCODE(R300_VE_ADD) |
  320.                            R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
  321.                            R300_PVS_DST_OFFSET(0) |
  322.                            R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
  323.                            R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
  324.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  325.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  326.                            R300_PVS_SRC_OFFSET(0) |
  327.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
  328.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
  329.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
  330.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
  331.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  332.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  333.                            R300_PVS_SRC_OFFSET(0) |
  334.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  335.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  336.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  337.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  338.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  339.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  340.                            R300_PVS_SRC_OFFSET(0) |
  341.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  342.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  343.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  344.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  345.  
  346.             /* PVS inst 1 */
  347.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  348.                           (R300_PVS_DST_OPCODE(R300_VE_ADD) |
  349.                            R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
  350.                            R300_PVS_DST_OFFSET(1) |
  351.                            R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
  352.                            R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
  353.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  354.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  355.                            R300_PVS_SRC_OFFSET(6) |
  356.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
  357.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
  358.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
  359.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
  360.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  361.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  362.                            R300_PVS_SRC_OFFSET(6) |
  363.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  364.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  365.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  366.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  367.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  368.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  369.                            R300_PVS_SRC_OFFSET(6) |
  370.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  371.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  372.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  373.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  374.             FINISH_ACCEL();
  375.  
  376.             /* Xv shader program */
  377.             BEGIN_ACCEL(9);
  378.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 5);
  379.  
  380.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  381.                           (R300_PVS_DST_OPCODE(R300_VE_ADD) |
  382.                            R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
  383.                            R300_PVS_DST_OFFSET(0) |
  384.                            R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
  385.                            R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
  386.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  387.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  388.                            R300_PVS_SRC_OFFSET(0) |
  389.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
  390.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
  391.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
  392.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
  393.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  394.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  395.                            R300_PVS_SRC_OFFSET(0) |
  396.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  397.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  398.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  399.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  400.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  401.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  402.                            R300_PVS_SRC_OFFSET(0) |
  403.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  404.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  405.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  406.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  407.  
  408.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  409.                           (R300_PVS_DST_OPCODE(R300_VE_ADD) |
  410.                            R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
  411.                            R300_PVS_DST_OFFSET(1) |
  412.                            R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
  413.                            R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
  414.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  415.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  416.                            R300_PVS_SRC_OFFSET(6) |
  417.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
  418.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
  419.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
  420.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
  421.            OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  422.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  423.                            R300_PVS_SRC_OFFSET(6) |
  424.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  425.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  426.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  427.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  428.             OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
  429.                           (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
  430.                            R300_PVS_SRC_OFFSET(6) |
  431.                            R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
  432.                            R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
  433.                            R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
  434.                            R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
  435.             FINISH_ACCEL();
  436.         }
  437.  
  438.         /* pre-load the RS instructions */
  439.         BEGIN_ACCEL(4);
  440.         if (IS_R300_3D) {
  441.             /* rasterizer source table
  442.              * R300_RS_TEX_PTR is the offset into the input RS stream
  443.              * 0,1 are tex0
  444.              * 2,3 are tex1
  445.              */
  446.             OUT_ACCEL_REG(R300_RS_IP_0,
  447.                           (R300_RS_TEX_PTR(0) |
  448.                            R300_RS_SEL_S(R300_RS_SEL_C0) |
  449.                            R300_RS_SEL_T(R300_RS_SEL_C1) |
  450.                            R300_RS_SEL_R(R300_RS_SEL_K0) |
  451.                            R300_RS_SEL_Q(R300_RS_SEL_K1)));
  452.             OUT_ACCEL_REG(R300_RS_IP_1,
  453.                           (R300_RS_TEX_PTR(2) |
  454.                            R300_RS_SEL_S(R300_RS_SEL_C0) |
  455.                            R300_RS_SEL_T(R300_RS_SEL_C1) |
  456.                            R300_RS_SEL_R(R300_RS_SEL_K0) |
  457.                            R300_RS_SEL_Q(R300_RS_SEL_K1)));
  458.             /* src tex */
  459.             /* R300_INST_TEX_ID - select the RS source table entry
  460.              * R300_INST_TEX_ADDR - the FS temp register for the texture data
  461.              */
  462.             OUT_ACCEL_REG(R300_RS_INST_0, (R300_INST_TEX_ID(0) |
  463.                                            R300_RS_INST_TEX_CN_WRITE |
  464.                                            R300_INST_TEX_ADDR(0)));
  465.             /* mask tex */
  466.             OUT_ACCEL_REG(R300_RS_INST_1, (R300_INST_TEX_ID(1) |
  467.                                            R300_RS_INST_TEX_CN_WRITE |
  468.                                            R300_INST_TEX_ADDR(1)));
  469.  
  470.         } else {
  471.             /* rasterizer source table
  472.              * R300_RS_TEX_PTR is the offset into the input RS stream
  473.              * 0,1 are tex0
  474.              * 2,3 are tex1
  475.              */
  476.             OUT_ACCEL_REG(R500_RS_IP_0, ((0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
  477.                                          (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
  478.                                          (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
  479.                                          (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
  480.  
  481.            OUT_ACCEL_REG(R500_RS_IP_1, ((2 << R500_RS_IP_TEX_PTR_S_SHIFT) |
  482.                                          (3 << R500_RS_IP_TEX_PTR_T_SHIFT) |
  483.                                          (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
  484.                                          (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
  485.             /* src tex */
  486.             /* R500_RS_INST_TEX_ID_SHIFT - select the RS source table entry
  487.              * R500_RS_INST_TEX_ADDR_SHIFT - the FS temp register for the texture data
  488.              */
  489.           OUT_ACCEL_REG(R500_RS_INST_0, ((0 << R500_RS_INST_TEX_ID_SHIFT) |
  490.                           R500_RS_INST_TEX_CN_WRITE |
  491.                                            (0 << R500_RS_INST_TEX_ADDR_SHIFT)));
  492.             /* mask tex */
  493.           OUT_ACCEL_REG(R500_RS_INST_1, ((1 << R500_RS_INST_TEX_ID_SHIFT) |
  494.                                            R500_RS_INST_TEX_CN_WRITE |
  495.                                            (1 << R500_RS_INST_TEX_ADDR_SHIFT)));
  496.         }
  497.         FINISH_ACCEL();
  498.  
  499.         if (IS_R300_3D)
  500.             BEGIN_ACCEL(4);
  501.         else {
  502.             BEGIN_ACCEL(6);
  503.             OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
  504.             OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
  505.         }
  506.         OUT_ACCEL_REG(R300_US_W_FMT, 0);
  507.         OUT_ACCEL_REG(R300_US_OUT_FMT_1, (R300_OUT_FMT_UNUSED |
  508.                                           R300_OUT_FMT_C0_SEL_BLUE |
  509.                                           R300_OUT_FMT_C1_SEL_GREEN |
  510.                                           R300_OUT_FMT_C2_SEL_RED |
  511.                                           R300_OUT_FMT_C3_SEL_ALPHA));
  512.         OUT_ACCEL_REG(R300_US_OUT_FMT_2, (R300_OUT_FMT_UNUSED |
  513.                                           R300_OUT_FMT_C0_SEL_BLUE |
  514.                                           R300_OUT_FMT_C1_SEL_GREEN |
  515.                                           R300_OUT_FMT_C2_SEL_RED |
  516.                                           R300_OUT_FMT_C3_SEL_ALPHA));
  517.         OUT_ACCEL_REG(R300_US_OUT_FMT_3, (R300_OUT_FMT_UNUSED |
  518.                                           R300_OUT_FMT_C0_SEL_BLUE |
  519.                                           R300_OUT_FMT_C1_SEL_GREEN |
  520.                                           R300_OUT_FMT_C2_SEL_RED |
  521.                                           R300_OUT_FMT_C3_SEL_ALPHA));
  522.         FINISH_ACCEL();
  523.  
  524.  
  525.         BEGIN_ACCEL(3);
  526.         OUT_ACCEL_REG(R300_FG_DEPTH_SRC, 0);
  527.         OUT_ACCEL_REG(R300_FG_FOG_BLEND, 0);
  528.         OUT_ACCEL_REG(R300_FG_ALPHA_FUNC, 0);
  529.         FINISH_ACCEL();
  530.  
  531.         BEGIN_ACCEL(13);
  532.         OUT_ACCEL_REG(R300_RB3D_ABLENDCNTL, 0);
  533.         OUT_ACCEL_REG(R300_RB3D_ZSTENCILCNTL, 0);
  534.         OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
  535.         OUT_ACCEL_REG(R300_RB3D_BW_CNTL, 0);
  536.         OUT_ACCEL_REG(R300_RB3D_ZCNTL, 0);
  537.         OUT_ACCEL_REG(R300_RB3D_ZTOP, 0);
  538.         OUT_ACCEL_REG(R300_RB3D_ROPCNTL, 0);
  539.  
  540.         OUT_ACCEL_REG(R300_RB3D_AARESOLVE_CTL, 0);
  541.         OUT_ACCEL_REG(R300_RB3D_COLOR_CHANNEL_MASK, (R300_BLUE_MASK_EN |
  542.                                                      R300_GREEN_MASK_EN |
  543.                                                      R300_RED_MASK_EN |
  544.                                                      R300_ALPHA_MASK_EN));
  545.         OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
  546.         OUT_ACCEL_REG(R300_RB3D_CCTL, 0);
  547.         OUT_ACCEL_REG(R300_RB3D_DITHER_CTL, 0);
  548.         OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
  549.         FINISH_ACCEL();
  550.  
  551.         BEGIN_ACCEL(5);
  552.         OUT_ACCEL_REG(R300_SC_EDGERULE, 0xA5294A5);
  553.         if (IS_R300_3D) {
  554.             /* clip has offset 1440 */
  555.             OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((1088 << R300_CLIP_X_SHIFT) |
  556.                                          (1088 << R300_CLIP_Y_SHIFT)));
  557.             OUT_ACCEL_REG(R300_SC_CLIP_0_B, (((1080 + 2920) << R300_CLIP_X_SHIFT) |
  558.                                          ((1080 + 2920) << R300_CLIP_Y_SHIFT)));
  559.         } else {
  560.             OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((0 << R300_CLIP_X_SHIFT) |
  561.                                          (0 << R300_CLIP_Y_SHIFT)));
  562.             OUT_ACCEL_REG(R300_SC_CLIP_0_B, ((4080 << R300_CLIP_X_SHIFT) |
  563.                                          (4080 << R300_CLIP_Y_SHIFT)));
  564.         }
  565.         OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
  566.         OUT_ACCEL_REG(R300_SC_SCREENDOOR, 0xffffff);
  567.         FINISH_ACCEL();
  568.     } else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
  569.              (info->ChipFamily == CHIP_FAMILY_RV280) ||
  570.              (info->ChipFamily == CHIP_FAMILY_RS300) ||
  571.                (info->ChipFamily == CHIP_FAMILY_R200)) {
  572.  
  573.         BEGIN_ACCEL(6);
  574.         if (info->ChipFamily == CHIP_FAMILY_RS300) {
  575.             OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS);
  576.         } else {
  577.             OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, 0);
  578.         }
  579.         OUT_ACCEL_REG(R200_PP_CNTL_X, 0);
  580.         OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0);
  581.         OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0);
  582.         OUT_ACCEL_REG(R200_SE_VTE_CNTL, 0);
  583.         OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE |
  584.                         R200_VAP_VF_MAX_VTX_NUM);
  585.         FINISH_ACCEL();
  586.  
  587.         BEGIN_ACCEL(5);
  588.         OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
  589.         OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
  590.         OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
  591.         OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
  592.         OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
  593.                                        RADEON_BFACE_SOLID |
  594.                                        RADEON_FFACE_SOLID |
  595.                                        RADEON_VTX_PIX_CENTER_OGL |
  596.                                        RADEON_ROUND_MODE_ROUND |
  597.                                        RADEON_ROUND_PREC_4TH_PIX));
  598.         FINISH_ACCEL();
  599.     } else {
  600.         BEGIN_ACCEL(2);
  601.         if ((info->ChipFamily == CHIP_FAMILY_RADEON) ||
  602.             (info->ChipFamily == CHIP_FAMILY_RV200))
  603.             OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0);
  604.         else
  605.             OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS);
  606.         OUT_ACCEL_REG(RADEON_SE_COORD_FMT,
  607.             RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
  608.                                        RADEON_VTX_ST0_NONPARAMETRIC     |
  609.                                        RADEON_VTX_ST1_NONPARAMETRIC     |
  610.                                        RADEON_TEX1_W_ROUTING_USE_W0);
  611.         FINISH_ACCEL();
  612.  
  613.         BEGIN_ACCEL(5);
  614.         OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
  615.         OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
  616.         OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
  617.         OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
  618.         OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
  619.                                        RADEON_BFACE_SOLID |
  620.                                        RADEON_FFACE_SOLID |
  621.                                        RADEON_VTX_PIX_CENTER_OGL |
  622.                                        RADEON_ROUND_MODE_ROUND |
  623.                                        RADEON_ROUND_PREC_4TH_PIX));
  624.         FINISH_ACCEL();
  625.     }
  626.     safe_sti(ifl);
  627.     FIFOWait(64);
  628.     delay(2);
  629.  
  630. }
  631.  
  632.