/*
 * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
 * Copyright (C) 2010-2011 LunarG Inc.
 *
 * Based on xf86-video-ati, which has
 *
 * Copyright © 2009 Red Hat, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/* XXX This driver assumes evergreen. */

#define LOG_TAG "GRALLOC-RADEON"

#include <cutils/log.h>
#include <stdlib.h>
#include <errno.h>
#include <drm.h>
#include <radeon_drm.h>
#include <radeon_bo_gem.h>
#include <radeon_bo.h>

#include "gralloc_drm.h"
#include "gralloc_drm_priv.h"

#include "radeon/radeon.h"
#include "radeon/radeon_chipinfo_gen.h"

#define RADEON_GPU_PAGE_SIZE 4096

#define MAX(a, b) (((a) > (b)) ? (a) : (b))

struct radeon_info {
	struct gralloc_drm_drv_t base;

	int fd;
	struct radeon_bo_manager *bufmgr;

	uint32_t chipset;
	RADEONChipFamily chip_family;
	int is_mobility;
	int is_igp;

	uint32_t tile_config;
	int num_channels;
	int num_banks;
	int group_bytes;
	/* r6xx+ tile config */
	int have_tiling_info;

	int allow_color_tiling;

	int vram_size;
	int gart_size;
};

struct radeon_buffer {
	struct gralloc_drm_bo_t base;

	struct radeon_bo *rbo;
};

/* returns pitch alignment in pixels */
static int radeon_get_pitch_align(struct radeon_info *info, int bpe, uint32_t tiling)
{
	int pitch_align = 1;

	if (info->chip_family >= CHIP_FAMILY_R600) {
		if (tiling & RADEON_TILING_MACRO) {
			/* general surface requirements */
			pitch_align = (((info->group_bytes / 8) / bpe) *
					info->num_banks) * 8;
			/* further restrictions for scanout */
			pitch_align = MAX(info->num_banks * 8, pitch_align);
		} else if (tiling & RADEON_TILING_MICRO) {
			/* general surface requirements */
			pitch_align = MAX(8, (info->group_bytes / (8 * bpe)));
			/* further restrictions for scanout */
			pitch_align = MAX(info->group_bytes / bpe, pitch_align);
		} else {
			if (info->have_tiling_info)
				/* linear aligned requirements */
				pitch_align = MAX(64, info->group_bytes / bpe);
			else
				/* default to 512 elements if we don't know the real
				 * group size otherwise the kernel may reject the CS
				 * if the group sizes don't match as the pitch won't
				 * be aligned properly.
				 */
				pitch_align = 512;
		}
	}
	else {
                /* general surface requirements */
                if (tiling)
                        pitch_align = 256 / bpe;
                else
                        pitch_align = 64;
	}

	return pitch_align;
}

/* returns height alignment in pixels */
static int radeon_get_height_align(struct radeon_info *info, uint32_t tiling)
{
	int height_align = 1;

	if (info->chip_family >= CHIP_FAMILY_R600) {
		if (tiling & RADEON_TILING_MACRO)
			height_align =  info->num_channels * 8;
		else if (tiling & RADEON_TILING_MICRO)
			height_align = 8;
		else
			height_align = 8;
	}
	else {
		if (tiling)
			height_align = 16;
		else
			height_align = 1;
	}

	return height_align;
}

/* returns base alignment in bytes */
static int radeon_get_base_align(struct radeon_info *info,
		int bpe, uint32_t tiling)
{
        int pixel_align = radeon_get_pitch_align(info, bpe, tiling);
        int height_align = radeon_get_height_align(info, tiling);
        int base_align = RADEON_GPU_PAGE_SIZE;

        if (info->chip_family >= CHIP_FAMILY_R600) {
                if (tiling & RADEON_TILING_MACRO)
                        base_align = MAX(info->num_banks * info->num_channels * 8 * 8 * bpe,
                                         pixel_align * bpe * height_align);
                else {
                        if (info->have_tiling_info)
                                base_align = info->group_bytes;
                        else
                                /* default to 512 if we don't know the real
                                 * group size otherwise the kernel may reject the CS
                                 * if the group sizes don't match as the base won't
                                 * be aligned properly.
                                 */
                                base_align = 512;
                }
        }
        return base_align;
}

static uint32_t radeon_get_tiling(struct radeon_info *info,
		const struct gralloc_drm_handle_t *handle)
{
	int sw = (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK);

	if ((handle->usage & sw) && !info->allow_color_tiling)
		return 0;

	if (info->chip_family >= CHIP_FAMILY_R600)
		return RADEON_TILING_MICRO;
	else
		return RADEON_TILING_MACRO;
}

static struct radeon_bo *radeon_alloc(struct radeon_info *info,
		struct gralloc_drm_handle_t *handle)
{
	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) {
		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) {
			ALOGE("failed to create rbo from name %u",
					handle->name);
			free(rbuf);
			return NULL;
		}
	}
	else {
		rbuf->rbo = radeon_alloc(info, handle);
		if (!rbuf->rbo) {
			free(rbuf);
			return NULL;
		}

		/* Android expects the buffer to be zeroed */
		radeon_zero(info, rbuf->rbo);
	}

	if (handle->usage & GRALLOC_USAGE_HW_FB)
		rbuf->base.fb_handle = rbuf->rbo->handle;

	rbuf->base.handle = handle;

	return &rbuf->base;
}

static void drm_gem_radeon_free(struct gralloc_drm_drv_t *drv,
		struct gralloc_drm_bo_t *bo)
{
	struct radeon_buffer *rbuf = (struct radeon_buffer *) bo;
	radeon_bo_unref(rbuf->rbo);
}

static int drm_gem_radeon_map(struct gralloc_drm_drv_t *drv,
		struct gralloc_drm_bo_t *bo, int x, int y, int w, int h,
		int enable_write, void **addr)
{
	struct radeon_buffer *rbuf = (struct radeon_buffer *) bo;
	int err;

	err = radeon_bo_map(rbuf->rbo, enable_write);
	if (!err)
		*addr = rbuf->rbo->ptr;

	return err;
}

static void drm_gem_radeon_unmap(struct gralloc_drm_drv_t *drv,
		struct gralloc_drm_bo_t *bo)
{
	struct radeon_buffer *rbuf = (struct radeon_buffer *) bo;
	radeon_bo_unmap(rbuf->rbo);
}

static void drm_gem_radeon_init_kms_features(struct gralloc_drm_drv_t *drv,
		struct gralloc_drm_t *drm)
{
	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;
	drm->vblank_secondary = 0;
}

static void drm_gem_radeon_destroy(struct gralloc_drm_drv_t *drv)
{
	struct radeon_info *info = (struct radeon_info *) drv;

	radeon_bo_manager_gem_dtor(info->bufmgr);
	free(info);
}

static int radeon_init_tile_config(struct radeon_info *info)
{
	struct drm_radeon_info ginfo;
	uint32_t val;
	int ret;

	memset(&ginfo, 0, sizeof(ginfo));
	ginfo.request = RADEON_INFO_TILING_CONFIG;
	ginfo.value = (long) &val;
	ret = drmCommandWriteRead(info->fd, DRM_RADEON_INFO,
			&ginfo, sizeof(ginfo));
	if (ret)
		return ret;

	info->tile_config = val;

	if (info->chip_family >= CHIP_FAMILY_CEDAR) {
		switch (info->tile_config & 0xf) {
		case 0:
			info->num_channels = 1;
			break;
		case 1:
			info->num_channels = 2;
			break;
		case 2:
			info->num_channels = 4;
			break;
		case 3:
			info->num_channels = 8;
			break;
		default:
			return -EINVAL;
			break;
		}

		switch ((info->tile_config & 0xf0) >> 4) {
		case 0:
			info->num_banks = 4;
			break;
		case 1:
			info->num_banks = 8;
			break;
		case 2:
			info->num_banks = 16;
			break;
		default:
			return -EINVAL;
			break;
		}

		switch ((info->tile_config & 0xf00) >> 8) {
		case 0:
			info->group_bytes = 256;
			break;
		case 1:
			info->group_bytes = 512;
			break;
		default:
			return -EINVAL;
			break;
		}
	}
	else {
		switch ((info->tile_config & 0xe) >> 1) {
		case 0:
			info->num_channels = 1;
			break;
		case 1:
			info->num_channels = 2;
			break;
		case 2:
			info->num_channels = 4;
			break;
		case 3:
			info->num_channels = 8;
			break;
		default:
			return -EINVAL;
			break;
		}

		switch ((info->tile_config & 0x30) >> 4) {
		case 0:
			info->num_banks = 4;
			break;
		case 1:
			info->num_banks = 8;
			break;
		default:
			return -EINVAL;
			break;
		}

		switch ((info->tile_config & 0xc0) >> 6) {
		case 0:
			info->group_bytes = 256;
			break;
		case 1:
			info->group_bytes = 512;
			break;
		default:
			return -EINVAL;
			break;
		}
	}

	info->have_tiling_info = 1;

	return 0;
}

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;
	err = drmCommandWriteRead(info->fd, DRM_RADEON_INFO, &kinfo, sizeof(kinfo));
	if (err) {
		ALOGE("failed to get device id");
		return err;
	}

	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) {
		ALOGE("failed to get tiling config");
		return err;
	}

	/* 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) {
		ALOGE("failed to get gem info");
		return err;
	}

	info->vram_size = mminfo.vram_visible;
	info->gart_size = mminfo.gart_size;

	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);

	return 0;
}

struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_radeon(int fd)
{
	struct radeon_info *info;

	info = calloc(1, sizeof(*info));
	if (!info)
		return NULL;

	info->fd = fd;
	if (radeon_probe(info)) {
		free(info);
		return NULL;
	}

	info->bufmgr = radeon_bo_manager_gem_ctor(info->fd);
	if (!info->bufmgr) {
		ALOGE("failed to create buffer manager");
		free(info);
		return NULL;
	}

	info->base.destroy = drm_gem_radeon_destroy;
	info->base.init_kms_features = drm_gem_radeon_init_kms_features;
	info->base.alloc = drm_gem_radeon_alloc;
	info->base.free = drm_gem_radeon_free;
	info->base.map = drm_gem_radeon_map;
	info->base.unmap = drm_gem_radeon_unmap;

	return &info->base;
}
