drm/radeon: init pipe setup in kernel code.
authorAlex Deucher <alexdeucher@gmail.com>
Wed, 28 May 2008 01:57:40 +0000 (11:57 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 19 Jun 2008 01:27:40 +0000 (11:27 +1000)
This inits the card pipes in the kernel and lets userspace getparam
the correct setup.

Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/char/drm/radeon_cp.c
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_state.c

index 77bd90f..5991875 100644 (file)
@@ -247,6 +247,50 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
        return -EBUSY;
 }
 
+static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
+{
+       uint32_t gb_tile_config, gb_pipe_sel = 0;
+
+       /* RS4xx/RS6xx/R4xx/R5xx */
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
+               gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
+               dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+       } else {
+               /* R3xx */
+               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
+                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+                       dev_priv->num_gb_pipes = 2;
+               } else {
+                       /* R3Vxx */
+                       dev_priv->num_gb_pipes = 1;
+               }
+       }
+       DRM_INFO("Num pipes: %d\n", dev_priv->num_gb_pipes);
+
+       gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/);
+
+       switch (dev_priv->num_gb_pipes) {
+       case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+       case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+       case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+       default:
+       case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
+       }
+
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
+               RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+               RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
+       }
+       RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
+       radeon_do_wait_for_idle(dev_priv);
+       RADEON_WRITE(R300_DST_PIPE_CONFIG, RADEON_READ(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
+       RADEON_WRITE(R300_RB2D_DSTCACHE_MODE, (RADEON_READ(R300_RB2D_DSTCACHE_MODE) |
+                                              R300_DC_AUTOFLUSH_ENABLE |
+                                              R300_DC_DC_DISABLE_IGNORE_PE));
+
+
+}
+
 /* ================================================================
  * CP control, initialization
  */
@@ -464,6 +508,10 @@ static int radeon_do_engine_reset(struct drm_device * dev)
                RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
        }
 
+       /* setup the raster pipes */
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
+           radeon_init_pipes(dev_priv);
+
        /* Reset the CP ring */
        radeon_do_cp_reset(dev_priv);
 
index aab82e1..68b0608 100644 (file)
@@ -669,6 +669,7 @@ typedef struct drm_radeon_indirect {
 #define RADEON_PARAM_CARD_TYPE             12
 #define RADEON_PARAM_VBLANK_CRTC           13   /* VBLANK CRTC */
 #define RADEON_PARAM_FB_LOCATION           14   /* FB location */
+#define RADEON_PARAM_NUM_GB_PIPES          15   /* num GB pipes */
 
 typedef struct drm_radeon_getparam {
        int param;
index 5e6f461..c3615cf 100644 (file)
@@ -307,6 +307,8 @@ typedef struct drm_radeon_private {
        /* starting from here on, data is preserved accross an open */
        uint32_t flags;         /* see radeon_chip_flags */
        unsigned long fb_aper_offset;
+
+       int num_gb_pipes;
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
@@ -529,6 +531,27 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 #define RS480_AGP_BASE_2               0x0164
 #define RADEON_AGP_BASE                        0x0170
 
+/* pipe config regs */
+#define R400_GB_PIPE_SELECT             0x402c
+#define R500_DYN_SCLK_PWMEM_PIPE        0x000d /* PLL */
+#define R500_SU_REG_DEST                0x42c8
+#define R300_GB_TILE_CONFIG             0x4018
+#       define R300_ENABLE_TILING       (1 << 0)
+#       define R300_PIPE_COUNT_RV350    (0 << 1)
+#       define R300_PIPE_COUNT_R300     (3 << 1)
+#       define R300_PIPE_COUNT_R420_3P  (6 << 1)
+#       define R300_PIPE_COUNT_R420     (7 << 1)
+#       define R300_TILE_SIZE_8         (0 << 4)
+#       define R300_TILE_SIZE_16        (1 << 4)
+#       define R300_TILE_SIZE_32        (2 << 4)
+#       define R300_SUBPIXEL_1_12       (0 << 16)
+#       define R300_SUBPIXEL_1_16       (1 << 16)
+#define R300_DST_PIPE_CONFIG            0x170c
+#       define R300_PIPE_AUTO_CONFIG    (1 << 31)
+#define R300_RB2D_DSTCACHE_MODE         0x3428
+#       define R300_DC_AUTOFLUSH_ENABLE (1 << 8)
+#       define R300_DC_DC_DISABLE_IGNORE_PE (1 << 17)
+
 #define RADEON_RB3D_COLOROFFSET                0x1c40
 #define RADEON_RB3D_COLORPITCH         0x1c48
 
index 6f75512..eee1357 100644 (file)
@@ -3037,6 +3037,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
        case RADEON_PARAM_FB_LOCATION:
                value = radeon_read_fb_location(dev_priv);
                break;
+       case RADEON_PARAM_NUM_GB_PIPES:
+               value = dev_priv->num_gb_pipes;
+               break;
        default:
                DRM_DEBUG("Invalid parameter %d\n", param->param);
                return -EINVAL;