OSDN Git Service

gralloc_drm_pipe: add support for winsys handle types
[android-x86/external-drm_gralloc.git] / gralloc_drm_nouveau.c
index 3d27bc9..f3ecfd6 100644 (file)
 #define NV_FERMI    0xc0
 #define NV_KEPLER   0xe0
 #define NV_MAXWELL  0x110
+#define NV_PASCAL   0x130
 
 #define NV50_TILE_HEIGHT(m) (4 << ((m) >> 4))
 #define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4))
 
+
+// Comment out the following to switch between the "sw_indicator disables all
+// tiling" and "sw_indicator zeroes the tile|surf_flags (object tiling?)".
+// Does the latter even make sense ... ? Going through the kernel on the
+// topic is slightly annoying :/
+
+#undef SW_INDICATOR_FULLY_DISABLES_TILING
+
 struct nouveau_info {
        struct gralloc_drm_drv_t base;
 
@@ -74,7 +83,7 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
        struct nouveau_bo *bo = NULL;
        union nouveau_bo_config cfg = {};
        int flags;
-       int tiled, scanout;
+       int tiled, scanout, sw_indicator;
        unsigned int align;
 
        flags = NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM;
@@ -84,6 +93,9 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
        tiled = !(usage & (GRALLOC_USAGE_SW_READ_OFTEN |
                           GRALLOC_USAGE_SW_WRITE_OFTEN));
 
+       sw_indicator = (usage & (GRALLOC_USAGE_SW_READ_OFTEN |
+                                GRALLOC_USAGE_SW_WRITE_OFTEN));
+
        if (info->arch >= NV_TESLA) {
                tiled = 1;
                align = 64;
@@ -109,7 +121,12 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
                        else
                                cfg.nvc0.tile_mode = 0x0000;
 
-                       cfg.nvc0.memtype = 0x00fe;
+#ifndef SW_INDICATOR_FULLY_DISABLES_TILING
+                       if (sw_indicator)
+                               cfg.nvc0.memtype = 0x0000;
+                       else
+#endif
+                               cfg.nvc0.memtype = 0x00fe;
 
                        align = NVC0_TILE_HEIGHT(cfg.nvc0.tile_mode);
                        height = ALIGN(height, align);
@@ -126,8 +143,13 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
                        else
                                cfg.nv50.tile_mode = 0x0000;
 
-                       cfg.nv50.memtype = (scanout && cpp != 2) ?
-                                       0x007a : 0x0070;
+#ifndef SW_INDICATOR_FULLY_DISABLES_TILING
+                       if (sw_indicator)
+                               cfg.nv50.memtype = 0x0000;
+                       else
+#endif
+                               cfg.nv50.memtype = (scanout && cpp != 2) ?
+                                               0x007a : 0x0070;
 
                        align = NV50_TILE_HEIGHT(cfg.nv50.tile_mode);
                        height = ALIGN(height, align);
@@ -154,6 +176,11 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
        }
 
        if (info->arch < NV_TESLA) {
+#ifndef SW_INDICATOR_FULLY_DISABLES_TILING
+               if (sw_indicator)
+                       cfg.nv04.surf_flags = 0x0000;
+               else
+#endif
                if (cpp == 4)
                        cfg.nv04.surf_flags |= NV04_BO_32BPP;
                else if (cpp == 2)
@@ -163,7 +190,11 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
        if (scanout)
                flags |= NOUVEAU_BO_CONTIG;
 
+#ifdef SW_INDICATOR_FULLY_DISABLES_TILING
+       if (nouveau_bo_new(info->dev, flags, 0, *pitch * height, NULL, &bo)) {
+#else
        if (nouveau_bo_new(info->dev, flags, 0, *pitch * height, &cfg, &bo)) {
+#endif
                ALOGE("failed to allocate bo (flags 0x%x, size %d)",
                                flags, *pitch * height);
                bo = NULL;
@@ -272,12 +303,12 @@ static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv,
 {
        struct nouveau_info *info = (struct nouveau_info *) drv;
 
-       switch (drm->primary.fb_format) {
+       switch (drm->primary->fb_format) {
        case HAL_PIXEL_FORMAT_BGRA_8888:
        case HAL_PIXEL_FORMAT_RGB_565:
                break;
        default:
-               drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+               drm->primary->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
                break;
        }
 
@@ -332,11 +363,16 @@ static int nouveau_init(struct nouveau_info *info)
                break;
        case 0xe0:
        case 0xf0:
+       case 0x100:
                info->arch = NV_KEPLER;
                break;
        case 0x110:
+       case 0x120:
                info->arch = NV_MAXWELL;
                break;
+       case 0x130:
+               info->arch = NV_PASCAL;
+               break;
        default:
                ALOGE("unknown nouveau chipset 0x%x", info->dev->chipset);
                err = -EINVAL;