#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;
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;
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)
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;
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)
{
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);
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;
}