OSDN Git Service

WIP: synchronize gralloc entry points
[android-x86/external-drm_gralloc.git] / gralloc_drm_radeon.c
index 1aca76f..8320989 100644 (file)
 #include "gralloc_drm.h"
 #include "gralloc_drm_priv.h"
 
-#define RADEON_GPU_PAGE_SIZE 4096
-
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
+#include "radeon/radeon.h"
+#include "radeon/radeon_chipinfo_gen.h"
 
-enum {
-       CHIP_FAMILY_R600,
-       CHIP_FAMILY_CEDAR,
-       CHIP_FAMILY_PALM,
-       CHIP_FAMILY_LAST
-};
+#define RADEON_GPU_PAGE_SIZE 4096
 
 struct radeon_info {
        struct gralloc_drm_drv_t base;
@@ -58,8 +51,10 @@ struct radeon_info {
        int fd;
        struct radeon_bo_manager *bufmgr;
 
-       int chipset;
-       int chip_family;
+       uint32_t chipset;
+       RADEONChipFamily chip_family;
+       int is_mobility;
+       int is_igp;
 
        uint32_t tile_config;
        int num_channels;
@@ -185,84 +180,106 @@ static uint32_t radeon_get_tiling(struct radeon_info *info,
                return RADEON_TILING_MACRO;
 }
 
-static struct gralloc_drm_bo_t *
-drm_gem_radeon_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle)
+static struct radeon_bo *radeon_alloc(struct radeon_info *info,
+               struct gralloc_drm_handle_t *handle)
 {
-       struct radeon_info *info = (struct radeon_info *) drv;
-       struct radeon_buffer *rbuf;
+       struct radeon_bo *rbo;
+       int aligned_width, aligned_height;
+       int pitch, size, base_align;
+       uint32_t tiling, domain;
        int cpp;
 
        cpp = gralloc_drm_get_bpp(handle->format);
        if (!cpp) {
-               LOGE("unrecognized format 0x%x", handle->format);
+               ALOGE("unrecognized format 0x%x", handle->format);
                return NULL;
        }
 
+       tiling = radeon_get_tiling(info, handle);
+       domain = RADEON_GEM_DOMAIN_VRAM;
+
+       aligned_width = handle->width;
+       aligned_height = handle->height;
+       gralloc_drm_align_geometry(handle->format,
+                       &aligned_width, &aligned_height);
+
+       if (handle->usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_TEXTURE)) {
+               aligned_width = ALIGN(aligned_width,
+                               radeon_get_pitch_align(info, cpp, tiling));
+               aligned_height = ALIGN(aligned_height,
+                               radeon_get_height_align(info, tiling));
+       }
+
+       if (!(handle->usage & (GRALLOC_USAGE_HW_FB |
+                              GRALLOC_USAGE_HW_RENDER)) &&
+           (handle->usage & GRALLOC_USAGE_SW_READ_OFTEN))
+               domain = RADEON_GEM_DOMAIN_GTT;
+
+       pitch = aligned_width * cpp;
+       size = ALIGN(aligned_height * pitch, RADEON_GPU_PAGE_SIZE);
+       base_align = radeon_get_base_align(info, cpp, tiling);
+
+       rbo = radeon_bo_open(info->bufmgr, 0, size, base_align, domain, 0);
+       if (!rbo) {
+               ALOGE("failed to allocate rbo %dx%dx%d",
+                               handle->width, handle->height, cpp);
+               return NULL;
+       }
+
+       if (tiling)
+               radeon_bo_set_tiling(rbo, tiling, pitch);
+
+       if (radeon_gem_get_kernel_name(rbo,
+                               (uint32_t *) &handle->name)) {
+               ALOGE("failed to flink rbo");
+               radeon_bo_unref(rbo);
+               return NULL;
+       }
+
+       handle->stride = pitch;
+
+       return rbo;
+}
+
+static void radeon_zero(struct radeon_info *info,
+               struct radeon_bo *rbo)
+{
+       /* should use HW clear... */
+       if (!radeon_bo_map(rbo, 1)) {
+               memset(rbo->ptr, 0, rbo->size);
+               radeon_bo_unmap(rbo);
+       }
+}
+
+static struct gralloc_drm_bo_t *
+drm_gem_radeon_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle)
+{
+       struct radeon_info *info = (struct radeon_info *) drv;
+       struct radeon_buffer *rbuf;
+
        rbuf = calloc(1, sizeof(*rbuf));
        if (!rbuf)
                return NULL;
 
-
        if (handle->name) {
                rbuf->rbo = radeon_bo_open(info->bufmgr,
                                handle->name, 0, 0, 0, 0);
                if (!rbuf->rbo) {
-                       LOGE("failed to create rbo from name %u",
+                       ALOGE("failed to create rbo from name %u",
                                        handle->name);
                        free(rbuf);
                        return NULL;
                }
        }
        else {
-               int aligned_width, aligned_height;
-               int pitch, size, base_align;
-               uint32_t tiling, domain;
-
-               tiling = radeon_get_tiling(info, handle);
-               domain = RADEON_GEM_DOMAIN_VRAM;
-
-               if (handle->usage & (GRALLOC_USAGE_HW_FB |
-                                       GRALLOC_USAGE_HW_TEXTURE)) {
-                       aligned_width = ALIGN(handle->width,
-                                       radeon_get_pitch_align(info, cpp, tiling));
-                       aligned_height = ALIGN(handle->height,
-                                       radeon_get_height_align(info, tiling));
-               }
-               else {
-                       aligned_width = handle->width;
-                       aligned_height = handle->height;
-               }
-
-               if (!(handle->usage & (GRALLOC_USAGE_HW_FB |
-                                               GRALLOC_USAGE_HW_RENDER)) &&
-                   (handle->usage & GRALLOC_USAGE_SW_READ_OFTEN))
-                       domain = RADEON_GEM_DOMAIN_GTT;
-
-               pitch = aligned_width * cpp;
-               size = ALIGN(aligned_height * pitch, RADEON_GPU_PAGE_SIZE);
-               base_align = radeon_get_base_align(info, cpp, tiling);
-
-               rbuf->rbo = radeon_bo_open(info->bufmgr, 0,
-                               size, base_align, domain, 0);
+               rbuf->rbo = radeon_alloc(info, handle);
                if (!rbuf->rbo) {
-                       LOGE("failed to allocate rbo %dx%dx%d",
-                                       handle->width, handle->height, cpp);
-                       free(rbuf);
-                       return NULL;
-               }
-
-               if (tiling)
-                       radeon_bo_set_tiling(rbuf->rbo, tiling, pitch);
-
-               if (radeon_gem_get_kernel_name(rbuf->rbo,
-                                       (uint32_t *) &handle->name)) {
-                       LOGE("failed to flink rbo");
-                       radeon_bo_unref(rbuf->rbo);
                        free(rbuf);
                        return NULL;
                }
 
-               handle->stride = pitch;
+               /* Android expects the buffer to be zeroed */
+               radeon_zero(info, rbuf->rbo);
        }
 
        if (handle->usage & GRALLOC_USAGE_HW_FB)
@@ -304,8 +321,16 @@ static void drm_gem_radeon_unmap(struct gralloc_drm_drv_t *drv,
 static void drm_gem_radeon_init_kms_features(struct gralloc_drm_drv_t *drv,
                struct gralloc_drm_t *drm)
 {
-       drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
-       drm->mode_dirty_fb = 0;
+       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;
+               break;
+       }
+
+       drm->mode_quirk_vmwgfx = 0;
        drm->swap_mode = DRM_SWAP_FLIP;
        drm->mode_sync_flip = 1;
        drm->swap_interval = 1;
@@ -328,7 +353,7 @@ static int radeon_init_tile_config(struct radeon_info *info)
 
        memset(&ginfo, 0, sizeof(ginfo));
        ginfo.request = RADEON_INFO_TILING_CONFIG;
-       ginfo.value = (long) &val;
+       ginfo.value = (uintptr_t) &val;
        ret = drmCommandWriteRead(info->fd, DRM_RADEON_INFO,
                        &ginfo, sizeof(ginfo));
        if (ret)
@@ -435,41 +460,60 @@ static int radeon_probe(struct radeon_info *info)
 {
        struct drm_radeon_info kinfo;
        struct drm_radeon_gem_info mminfo;
+       unsigned int i;
        int err;
 
        memset(&kinfo, 0, sizeof(kinfo));
        kinfo.request = RADEON_INFO_DEVICE_ID;
-       kinfo.value = (long) &info->chipset;
+       kinfo.value = (uintptr_t) &info->chipset;
        err = drmCommandWriteRead(info->fd, DRM_RADEON_INFO, &kinfo, sizeof(kinfo));
-       if (err)
+       if (err) {
+               ALOGE("failed to get device id");
                return err;
+       }
 
-       /* XXX this is wrong and a table should be used */
-       if (info->chipset >= 0x68e4 && info->chipset <= 0x68fe)
-               info->chip_family = CHIP_FAMILY_CEDAR;
-       else if (info->chipset >= 0x9802 && info->chipset <= 0x9807)
-               info->chip_family = CHIP_FAMILY_PALM;
-       else
+       for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCards[0]); i++) {
+               const RADEONCardInfo *card = &RADEONCards[i];
+
+               if (info->chipset == card->pci_device_id) {
+                       info->chip_family = card->chip_family;
+                       info->is_mobility = card->mobility;
+                       info->is_igp = card->igp;
+                       break;
+               }
+       }
+
+       if (info->chip_family == CHIP_FAMILY_UNKNOW) {
+               ALOGE("unknown device id 0x%04x", info->chipset);
                return -EINVAL;
+       }
 
-       err = radeon_init_tile_config(info);
-       if (err)
-               return err;
+       if (info->chip_family >= CHIP_FAMILY_R600) {
+               err = radeon_init_tile_config(info);
+               if (err) {
+                       ALOGE("failed to get tiling config");
+                       return err;
+               }
+       } else {
+               /* No tiling config for family older than 06xx */
+               info->have_tiling_info = 0;
+       }
 
        /* CPU cannot handle tiled buffers (need scratch buffers) */
        info->allow_color_tiling = 0;
 
        memset(&mminfo, 0, sizeof(mminfo));
        err = drmCommandWriteRead(info->fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo));
-       if (err)
+       if (err) {
+               ALOGE("failed to get gem info");
                return err;
+       }
 
        info->vram_size = mminfo.vram_visible;
        info->gart_size = mminfo.gart_size;
 
-       LOGI("detected chip family %s (vram size %dMiB, gart size %dMiB)",
-                       (info->chip_family == CHIP_FAMILY_CEDAR) ?
-                       "CEDAR" : "PALM",
+       ALOGI("detected chipset 0x%04x family 0x%02x (vram size %dMiB, gart size %dMiB)",
+                       info->chipset, info->chip_family,
                        info->vram_size / 1024 / 1024,
                        info->gart_size / 1024 / 1024);
 
@@ -492,7 +536,7 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_radeon(int fd)
 
        info->bufmgr = radeon_bo_manager_gem_ctor(info->fd);
        if (!info->bufmgr) {
-               LOGE("failed to create buffer manager");
+               ALOGE("failed to create buffer manager");
                free(info);
                return NULL;
        }