drm/radeon/kms: add 3DC compression support
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / radeon / r300.c
index 2f43ee8e40480cc2895c663fec62751570a1332f..3f2cc9e2e8d9a9f4a629361a2ea545c5f1b61f2c 100644 (file)
@@ -137,14 +137,19 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
 
 void rv370_pcie_gart_disable(struct radeon_device *rdev)
 {
-       uint32_t tmp;
+       u32 tmp;
+       int r;
 
        tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
        tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
        WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
        if (rdev->gart.table.vram.robj) {
-               radeon_object_kunmap(rdev->gart.table.vram.robj);
-               radeon_object_unpin(rdev->gart.table.vram.robj);
+               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+               if (likely(r == 0)) {
+                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
+                       radeon_bo_unpin(rdev->gart.table.vram.robj);
+                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
+               }
        }
 }
 
@@ -681,7 +686,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        r100_cs_dump_packet(p, pkt);
                        return r;
                }
-               ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
+
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                       tile_flags |= R300_TXO_MACRO_TILE;
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                       tile_flags |= R300_TXO_MICRO_TILE;
+
+               tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
+               tmp |= tile_flags;
+               ib[idx] = tmp;
                track->textures[i].robj = reloc->robj;
                break;
        /* Tracked registers */
@@ -847,7 +860,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                case R300_TX_FORMAT_Z6Y5X5:
                case R300_TX_FORMAT_W4Z4Y4X4:
                case R300_TX_FORMAT_W1Z5Y5X5:
-               case R300_TX_FORMAT_DXT1:
                case R300_TX_FORMAT_D3DMFT_CxV8U8:
                case R300_TX_FORMAT_B8G8_B8G8:
                case R300_TX_FORMAT_G8R8_G8B8:
@@ -861,8 +873,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                case 0x17:
                case R300_TX_FORMAT_FL_I32:
                case 0x1e:
-               case R300_TX_FORMAT_DXT3:
-               case R300_TX_FORMAT_DXT5:
                        track->textures[i].cpp = 4;
                        break;
                case R300_TX_FORMAT_W16Z16Y16X16:
@@ -873,6 +883,23 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                case R300_TX_FORMAT_FL_R32G32B32A32:
                        track->textures[i].cpp = 16;
                        break;
+               case R300_TX_FORMAT_DXT1:
+                       track->textures[i].cpp = 1;
+                       track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
+                       break;
+               case R300_TX_FORMAT_ATI2N:
+                       if (p->rdev->family < CHIP_R420) {
+                               DRM_ERROR("Invalid texture format %u\n",
+                                         (idx_value & 0x1F));
+                               return -EINVAL;
+                       }
+                       /* The same rules apply as for DXT3/5. */
+                       /* Pass through. */
+               case R300_TX_FORMAT_DXT3:
+               case R300_TX_FORMAT_DXT5:
+                       track->textures[i].cpp = 1;
+                       track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
+                       break;
                default:
                        DRM_ERROR("Invalid texture format %u\n",
                                  (idx_value & 0x1F));
@@ -932,6 +959,16 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        track->textures[i].width_11 = tmp;
                        tmp = ((idx_value >> 16) & 1) << 11;
                        track->textures[i].height_11 = tmp;
+
+                       /* ATI1N */
+                       if (idx_value & (1 << 14)) {
+                               /* The same rules apply as for DXT1. */
+                               track->textures[i].compress_format =
+                                       R100_TRACK_COMP_DXT1;
+                       }
+               } else if (idx_value & (1 << 14)) {
+                       DRM_ERROR("Forbidden bit TXFORMAT_MSB\n");
+                       return -EINVAL;
                }
                break;
        case 0x4480:
@@ -973,6 +1010,18 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                }
                ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
                break;
+       case 0x4e0c:
+               /* RB3D_COLOR_CHANNEL_MASK */
+               track->color_channel_mask = idx_value;
+               break;
+       case 0x4d1c:
+               /* ZB_BW_CNTL */
+               track->fastfill = !!(idx_value & (1 << 2));
+               break;
+       case 0x4e04:
+               /* RB3D_BLENDCNTL */
+               track->blend_read_enable = !!(idx_value & (1 << 2));
+               break;
        case 0x4be8:
                /* valid register only on RV530 */
                if (p->rdev->family == CHIP_RV530)
@@ -1181,6 +1230,9 @@ static int r300_startup(struct radeon_device *rdev)
 {
        int r;
 
+       /* set common regs */
+       r100_set_common_regs(rdev);
+       /* program mc */
        r300_mc_program(rdev);
        /* Resume clock */
        r300_clock_startup(rdev);
@@ -1193,13 +1245,18 @@ static int r300_startup(struct radeon_device *rdev)
                if (r)
                        return r;
        }
+
+       if (rdev->family == CHIP_R300 ||
+           rdev->family == CHIP_R350 ||
+           rdev->family == CHIP_RV350)
+               r100_enable_bm(rdev);
+
        if (rdev->flags & RADEON_IS_PCI) {
                r = r100_pci_gart_enable(rdev);
                if (r)
                        return r;
        }
        /* Enable IRQ */
-       rdev->irq.sw_int = true;
        r100_irq_set(rdev);
        /* 1M ring buffer */
        r = r100_cp_init(rdev, 1024 * 1024);
@@ -1237,6 +1294,8 @@ int r300_resume(struct radeon_device *rdev)
        radeon_combios_asic_init(rdev->ddev);
        /* Resume clock after posting */
        r300_clock_startup(rdev);
+       /* Initialize surface registers */
+       radeon_surface_init(rdev);
        return r300_startup(rdev);
 }
 
@@ -1265,7 +1324,7 @@ void r300_fini(struct radeon_device *rdev)
                r100_pci_gart_fini(rdev);
        radeon_irq_kms_fini(rdev);
        radeon_fence_driver_fini(rdev);
-       radeon_object_fini(rdev);
+       radeon_bo_fini(rdev);
        radeon_atombios_fini(rdev);
        kfree(rdev->bios);
        rdev->bios = NULL;
@@ -1303,14 +1362,14 @@ int r300_init(struct radeon_device *rdev)
                        RREG32(R_0007C0_CP_STAT));
        }
        /* check if cards are posted or not */
-       if (!radeon_card_posted(rdev) && rdev->bios) {
-               DRM_INFO("GPU not posted. posting now...\n");
-               radeon_combios_asic_init(rdev->ddev);
-       }
+       if (radeon_boot_test_post_card(rdev) == false)
+               return -EINVAL;
        /* Set asic errata */
        r300_errata(rdev);
        /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Get vram informations */
        r300_vram_info(rdev);
        /* Initialize memory controller (also test AGP) */
@@ -1325,7 +1384,7 @@ int r300_init(struct radeon_device *rdev)
        if (r)
                return r;
        /* Memory manager */
-       r = radeon_object_init(rdev);
+       r = radeon_bo_init(rdev);
        if (r)
                return r;
        if (rdev->flags & RADEON_IS_PCIE) {