/* exynos_drm_fbdev.c
 *
 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
 * Authors:
 *	Inki Dae <inki.dae@samsung.com>
 *	Joonyoung Shim <jy0922.shim@samsung.com>
 *	Seung-Woo Kim <sw0312.kim@samsung.com>
 *
 * 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 (including the next
 * paragraph) 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
 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
 */

#include "drmP.h"
#include "drm_crtc.h"
#include "drm_fb_helper.h"
#include "drm_crtc_helper.h"

#include "exynos_drm_drv.h"
#include "exynos_drm_fb.h"
#include "exynos_drm_buf.h"

#define MAX_CONNECTOR		4
#define PREFERRED_BPP		32

#define to_exynos_fbdev(x)	container_of(x, struct exynos_drm_fbdev,\
				drm_fb_helper)

struct exynos_drm_fbdev {
	struct drm_fb_helper	drm_fb_helper;
	struct drm_framebuffer	*fb;
};

static int exynos_drm_fbdev_set_par(struct fb_info *info)
{
	struct fb_var_screeninfo *var = &info->var;

	switch (var->bits_per_pixel) {
	case 32:
	case 24:
	case 18:
	case 16:
	case 12:
		info->fix.visual = FB_VISUAL_TRUECOLOR;
		break;
	case 1:
		info->fix.visual = FB_VISUAL_MONO01;
		break;
	default:
		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
		break;
	}

	info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;

	return drm_fb_helper_set_par(info);
}


static struct fb_ops exynos_drm_fb_ops = {
	.owner		= THIS_MODULE,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
	.fb_check_var	= drm_fb_helper_check_var,
	.fb_set_par	= exynos_drm_fbdev_set_par,
	.fb_blank	= drm_fb_helper_blank,
	.fb_pan_display	= drm_fb_helper_pan_display,
	.fb_setcmap	= drm_fb_helper_setcmap,
};

static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
				     struct drm_framebuffer *fb,
				     unsigned int fb_width,
				     unsigned int fb_height)
{
	struct fb_info *fbi = helper->fbdev;
	struct drm_device *dev = helper->dev;
	struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper);
	struct exynos_drm_buf_entry *entry;
	unsigned int size = fb_width * fb_height * (fb->bits_per_pixel >> 3);
	unsigned long offset;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	exynos_fb->fb = fb;

	drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
	drm_fb_helper_fill_var(fbi, helper, fb_width, fb_height);

	entry = exynos_drm_fb_get_buf(fb);
	if (!entry) {
		DRM_LOG_KMS("entry is null.\n");
		return -EFAULT;
	}

	offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
	offset += fbi->var.yoffset * fb->pitch;

	dev->mode_config.fb_base = entry->paddr;
	fbi->screen_base = entry->vaddr + offset;
	fbi->fix.smem_start = entry->paddr + offset;
	fbi->screen_size = size;
	fbi->fix.smem_len = size;

	return 0;
}

static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
				    struct drm_fb_helper_surface_size *sizes)
{
	struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
	struct drm_device *dev = helper->dev;
	struct fb_info *fbi;
	struct drm_mode_fb_cmd mode_cmd = { 0 };
	struct platform_device *pdev = dev->platformdev;
	int ret;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n",
			sizes->surface_width, sizes->surface_height,
			sizes->surface_bpp);

	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;
	mode_cmd.bpp = sizes->surface_bpp;
	mode_cmd.depth = sizes->surface_depth;

	mutex_lock(&dev->struct_mutex);

	fbi = framebuffer_alloc(0, &pdev->dev);
	if (!fbi) {
		DRM_ERROR("failed to allocate fb info.\n");
		ret = -ENOMEM;
		goto out;
	}

	exynos_fbdev->fb = exynos_drm_fb_create(dev, NULL, &mode_cmd);
	if (IS_ERR_OR_NULL(exynos_fbdev->fb)) {
		DRM_ERROR("failed to create drm framebuffer.\n");
		ret = PTR_ERR(exynos_fbdev->fb);
		goto out;
	}

	helper->fb = exynos_fbdev->fb;
	helper->fbdev = fbi;

	fbi->par = helper;
	fbi->flags = FBINFO_FLAG_DEFAULT;
	fbi->fbops = &exynos_drm_fb_ops;

	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
	if (ret) {
		DRM_ERROR("failed to allocate cmap.\n");
		goto out;
	}

	ret = exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
			sizes->fb_height);
	if (ret < 0)
		fb_dealloc_cmap(&fbi->cmap);

/*
 * if failed, all resources allocated above would be released by
 * drm_mode_config_cleanup() when drm_load() had been called prior
 * to any specific driver such as fimd or hdmi driver.
 */
out:
	mutex_unlock(&dev->struct_mutex);
	return ret;
}

static bool
exynos_drm_fbdev_is_samefb(struct drm_framebuffer *fb,
			    struct drm_fb_helper_surface_size *sizes)
{
	if (fb->width != sizes->surface_width)
		return false;
	if (fb->height != sizes->surface_height)
		return false;
	if (fb->bits_per_pixel != sizes->surface_bpp)
		return false;
	if (fb->depth != sizes->surface_depth)
		return false;

	return true;
}

static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
				      struct drm_fb_helper_surface_size *sizes)
{
	struct drm_device *dev = helper->dev;
	struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
	struct drm_framebuffer *fb = exynos_fbdev->fb;
	struct drm_mode_fb_cmd mode_cmd = { 0 };

	DRM_DEBUG_KMS("%s\n", __FILE__);

	if (helper->fb != fb) {
		DRM_ERROR("drm framebuffer is different\n");
		return -EINVAL;
	}

	if (exynos_drm_fbdev_is_samefb(fb, sizes))
		return 0;

	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;
	mode_cmd.bpp = sizes->surface_bpp;
	mode_cmd.depth = sizes->surface_depth;

	if (fb->funcs->destroy)
		fb->funcs->destroy(fb);

	exynos_fbdev->fb = exynos_drm_fb_create(dev, NULL, &mode_cmd);
	if (IS_ERR(exynos_fbdev->fb)) {
		DRM_ERROR("failed to allocate fb.\n");
		return PTR_ERR(exynos_fbdev->fb);
	}

	helper->fb = exynos_fbdev->fb;
	return exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
			sizes->fb_height);
}

static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
				   struct drm_fb_helper_surface_size *sizes)
{
	int ret = 0;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	if (!helper->fb) {
		ret = exynos_drm_fbdev_create(helper, sizes);
		if (ret < 0) {
			DRM_ERROR("failed to create fbdev.\n");
			return ret;
		}

		/*
		 * fb_helper expects a value more than 1 if succeed
		 * because register_framebuffer() should be called.
		 */
		ret = 1;
	} else {
		ret = exynos_drm_fbdev_recreate(helper, sizes);
		if (ret < 0) {
			DRM_ERROR("failed to reconfigure fbdev\n");
			return ret;
		}
	}

	return ret;
}

static struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = {
	.fb_probe =	exynos_drm_fbdev_probe,
};

int exynos_drm_fbdev_init(struct drm_device *dev)
{
	struct exynos_drm_fbdev *fbdev;
	struct exynos_drm_private *private = dev->dev_private;
	struct drm_fb_helper *helper;
	unsigned int num_crtc;
	int ret;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
		return 0;

	fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
	if (!fbdev) {
		DRM_ERROR("failed to allocate drm fbdev.\n");
		return -ENOMEM;
	}

	private->fb_helper = helper = &fbdev->drm_fb_helper;
	helper->funcs = &exynos_drm_fb_helper_funcs;

	num_crtc = dev->mode_config.num_crtc;

	ret = drm_fb_helper_init(dev, helper, num_crtc, MAX_CONNECTOR);
	if (ret < 0) {
		DRM_ERROR("failed to initialize drm fb helper.\n");
		goto err_init;
	}

	ret = drm_fb_helper_single_add_all_connectors(helper);
	if (ret < 0) {
		DRM_ERROR("failed to register drm_fb_helper_connector.\n");
		goto err_setup;

	}

	ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP);
	if (ret < 0) {
		DRM_ERROR("failed to set up hw configuration.\n");
		goto err_setup;
	}

	return 0;

err_setup:
	drm_fb_helper_fini(helper);

err_init:
	private->fb_helper = NULL;
	kfree(fbdev);

	return ret;
}

static void exynos_drm_fbdev_destroy(struct drm_device *dev,
				      struct drm_fb_helper *fb_helper)
{
	struct drm_framebuffer *fb;

	/* release drm framebuffer and real buffer */
	if (fb_helper->fb && fb_helper->fb->funcs) {
		fb = fb_helper->fb;
		if (fb && fb->funcs->destroy)
			fb->funcs->destroy(fb);
	}

	/* release linux framebuffer */
	if (fb_helper->fbdev) {
		struct fb_info *info;
		int ret;

		info = fb_helper->fbdev;
		ret = unregister_framebuffer(info);
		if (ret < 0)
			DRM_DEBUG_KMS("failed unregister_framebuffer()\n");

		if (info->cmap.len)
			fb_dealloc_cmap(&info->cmap);

		framebuffer_release(info);
	}

	drm_fb_helper_fini(fb_helper);
}

void exynos_drm_fbdev_fini(struct drm_device *dev)
{
	struct exynos_drm_private *private = dev->dev_private;
	struct exynos_drm_fbdev *fbdev;

	if (!private || !private->fb_helper)
		return;

	fbdev = to_exynos_fbdev(private->fb_helper);

	exynos_drm_fbdev_destroy(dev, private->fb_helper);
	kfree(fbdev);
	private->fb_helper = NULL;
}

void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
{
	struct exynos_drm_private *private = dev->dev_private;

	if (!private || !private->fb_helper)
		return;

	drm_fb_helper_restore_fbdev_mode(private->fb_helper);
}

int exynos_drm_fbdev_reinit(struct drm_device *dev)
{
	struct exynos_drm_private *private = dev->dev_private;
	struct drm_fb_helper *fb_helper;
	int ret;

	if (!private)
		return -EINVAL;

	/*
	 * if all sub drivers were unloaded then num_connector is 0
	 * so at this time, the framebuffers also should be destroyed.
	 */
	if (!dev->mode_config.num_connector) {
		exynos_drm_fbdev_fini(dev);
		return 0;
	}

	fb_helper = private->fb_helper;

	if (fb_helper) {
		drm_fb_helper_fini(fb_helper);

		ret = drm_fb_helper_init(dev, fb_helper,
				dev->mode_config.num_crtc, MAX_CONNECTOR);
		if (ret < 0) {
			DRM_ERROR("failed to initialize drm fb helper\n");
			return ret;
		}

		ret = drm_fb_helper_single_add_all_connectors(fb_helper);
		if (ret < 0) {
			DRM_ERROR("failed to add fb helper to connectors\n");
			goto err;
		}

		ret = drm_fb_helper_initial_config(fb_helper, PREFERRED_BPP);
		if (ret < 0) {
			DRM_ERROR("failed to set up hw configuration.\n");
			goto err;
		}
	} else {
		/*
		 * if drm_load() failed whem drm load() was called prior
		 * to specific drivers, fb_helper must be NULL and so
		 * this fuction should be called again to re-initialize and
		 * re-configure the fb helper. it means that this function
		 * has been called by the specific drivers.
		 */
		ret = exynos_drm_fbdev_init(dev);
	}

	return ret;

err:
	/*
	 * if drm_load() failed when drm load() was called prior
	 * to specific drivers, the fb_helper must be NULL and so check it.
	 */
	if (fb_helper)
		drm_fb_helper_fini(fb_helper);

	return ret;
}

MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
MODULE_DESCRIPTION("Samsung SoC DRM FBDEV Driver");
MODULE_LICENSE("GPL");
