/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include "bochs.h"
#include <drm/drm_plane_helper.h>

static int defx = 1024;
static int defy = 768;

module_param(defx, int, 0444);
module_param(defy, int, 0444);
MODULE_PARM_DESC(defx, "default x resolution");
MODULE_PARM_DESC(defy, "default y resolution");

/* ---------------------------------------------------------------------- */

static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	switch (mode) {
	case DRM_MODE_DPMS_ON:
	case DRM_MODE_DPMS_STANDBY:
	case DRM_MODE_DPMS_SUSPEND:
	case DRM_MODE_DPMS_OFF:
	default:
		return;
	}
}

static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
				    struct drm_framebuffer *old_fb)
{
	struct bochs_device *bochs =
		container_of(crtc, struct bochs_device, crtc);
	struct bochs_bo *bo;
	u64 gpu_addr = 0;
	int ret;

	if (old_fb) {
		bo = gem_to_bochs_bo(old_fb->obj[0]);
		ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
		if (ret) {
			DRM_ERROR("failed to reserve old_fb bo\n");
		} else {
			bochs_bo_unpin(bo);
			ttm_bo_unreserve(&bo->bo);
		}
	}

	if (WARN_ON(crtc->primary->fb == NULL))
		return -EINVAL;

	bo = gem_to_bochs_bo(crtc->primary->fb->obj[0]);
	ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
	if (ret)
		return ret;

	ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
	if (ret) {
		ttm_bo_unreserve(&bo->bo);
		return ret;
	}

	ttm_bo_unreserve(&bo->bo);
	bochs_hw_setbase(bochs, x, y, gpu_addr);
	return 0;
}

static int bochs_crtc_mode_set(struct drm_crtc *crtc,
			       struct drm_display_mode *mode,
			       struct drm_display_mode *adjusted_mode,
			       int x, int y, struct drm_framebuffer *old_fb)
{
	struct bochs_device *bochs =
		container_of(crtc, struct bochs_device, crtc);

	if (WARN_ON(crtc->primary->fb == NULL))
		return -EINVAL;

	bochs_hw_setmode(bochs, mode, crtc->primary->fb->format);
	bochs_crtc_mode_set_base(crtc, x, y, old_fb);
	return 0;
}

static void bochs_crtc_prepare(struct drm_crtc *crtc)
{
}

static void bochs_crtc_commit(struct drm_crtc *crtc)
{
}

static int bochs_crtc_page_flip(struct drm_crtc *crtc,
				struct drm_framebuffer *fb,
				struct drm_pending_vblank_event *event,
				uint32_t page_flip_flags,
				struct drm_modeset_acquire_ctx *ctx)
{
	struct bochs_device *bochs =
		container_of(crtc, struct bochs_device, crtc);
	struct drm_framebuffer *old_fb = crtc->primary->fb;
	unsigned long irqflags;

	crtc->primary->fb = fb;
	bochs_crtc_mode_set_base(crtc, 0, 0, old_fb);
	if (event) {
		spin_lock_irqsave(&bochs->dev->event_lock, irqflags);
		drm_crtc_send_vblank_event(crtc, event);
		spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags);
	}
	return 0;
}

/* These provide the minimum set of functions required to handle a CRTC */
static const struct drm_crtc_funcs bochs_crtc_funcs = {
	.set_config = drm_crtc_helper_set_config,
	.destroy = drm_crtc_cleanup,
	.page_flip = bochs_crtc_page_flip,
};

static const struct drm_crtc_helper_funcs bochs_helper_funcs = {
	.dpms = bochs_crtc_dpms,
	.mode_set = bochs_crtc_mode_set,
	.mode_set_base = bochs_crtc_mode_set_base,
	.prepare = bochs_crtc_prepare,
	.commit = bochs_crtc_commit,
};

static const uint32_t bochs_formats[] = {
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_BGRX8888,
};

static struct drm_plane *bochs_primary_plane(struct drm_device *dev)
{
	struct drm_plane *primary;
	int ret;

	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
	if (primary == NULL) {
		DRM_DEBUG_KMS("Failed to allocate primary plane\n");
		return NULL;
	}

	ret = drm_universal_plane_init(dev, primary, 0,
				       &drm_primary_helper_funcs,
				       bochs_formats,
				       ARRAY_SIZE(bochs_formats),
				       NULL,
				       DRM_PLANE_TYPE_PRIMARY, NULL);
	if (ret) {
		kfree(primary);
		primary = NULL;
	}

	return primary;
}

static void bochs_crtc_init(struct drm_device *dev)
{
	struct bochs_device *bochs = dev->dev_private;
	struct drm_crtc *crtc = &bochs->crtc;
	struct drm_plane *primary = bochs_primary_plane(dev);

	drm_crtc_init_with_planes(dev, crtc, primary, NULL,
				  &bochs_crtc_funcs, NULL);
	drm_crtc_helper_add(crtc, &bochs_helper_funcs);
}

static void bochs_encoder_mode_set(struct drm_encoder *encoder,
				   struct drm_display_mode *mode,
				   struct drm_display_mode *adjusted_mode)
{
}

static void bochs_encoder_dpms(struct drm_encoder *encoder, int state)
{
}

static void bochs_encoder_prepare(struct drm_encoder *encoder)
{
}

static void bochs_encoder_commit(struct drm_encoder *encoder)
{
}

static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = {
	.dpms = bochs_encoder_dpms,
	.mode_set = bochs_encoder_mode_set,
	.prepare = bochs_encoder_prepare,
	.commit = bochs_encoder_commit,
};

static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = {
	.destroy = drm_encoder_cleanup,
};

static void bochs_encoder_init(struct drm_device *dev)
{
	struct bochs_device *bochs = dev->dev_private;
	struct drm_encoder *encoder = &bochs->encoder;

	encoder->possible_crtcs = 0x1;
	drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs,
			 DRM_MODE_ENCODER_DAC, NULL);
	drm_encoder_helper_add(encoder, &bochs_encoder_helper_funcs);
}


static int bochs_connector_get_modes(struct drm_connector *connector)
{
	int count;

	count = drm_add_modes_noedid(connector, 8192, 8192);
	drm_set_preferred_mode(connector, defx, defy);
	return count;
}

static enum drm_mode_status bochs_connector_mode_valid(struct drm_connector *connector,
				      struct drm_display_mode *mode)
{
	struct bochs_device *bochs =
		container_of(connector, struct bochs_device, connector);
	unsigned long size = mode->hdisplay * mode->vdisplay * 4;

	/*
	 * Make sure we can fit two framebuffers into video memory.
	 * This allows up to 1600x1200 with 16 MB (default size).
	 * If you want more try this:
	 *     'qemu -vga std -global VGA.vgamem_mb=32 $otherargs'
	 */
	if (size * 2 > bochs->fb_size)
		return MODE_BAD;

	return MODE_OK;
}

static struct drm_encoder *
bochs_connector_best_encoder(struct drm_connector *connector)
{
	int enc_id = connector->encoder_ids[0];
	/* pick the encoder ids */
	if (enc_id)
		return drm_encoder_find(connector->dev, NULL, enc_id);
	return NULL;
}

static const struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = {
	.get_modes = bochs_connector_get_modes,
	.mode_valid = bochs_connector_mode_valid,
	.best_encoder = bochs_connector_best_encoder,
};

static const struct drm_connector_funcs bochs_connector_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_connector_cleanup,
};

static void bochs_connector_init(struct drm_device *dev)
{
	struct bochs_device *bochs = dev->dev_private;
	struct drm_connector *connector = &bochs->connector;

	drm_connector_init(dev, connector, &bochs_connector_connector_funcs,
			   DRM_MODE_CONNECTOR_VIRTUAL);
	drm_connector_helper_add(connector,
				 &bochs_connector_connector_helper_funcs);
	drm_connector_register(connector);
}


int bochs_kms_init(struct bochs_device *bochs)
{
	drm_mode_config_init(bochs->dev);
	bochs->mode_config_initialized = true;

	bochs->dev->mode_config.max_width = 8192;
	bochs->dev->mode_config.max_height = 8192;

	bochs->dev->mode_config.fb_base = bochs->fb_base;
	bochs->dev->mode_config.preferred_depth = 24;
	bochs->dev->mode_config.prefer_shadow = 0;
	bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true;

	bochs->dev->mode_config.funcs = &bochs_mode_funcs;

	bochs_crtc_init(bochs->dev);
	bochs_encoder_init(bochs->dev);
	bochs_connector_init(bochs->dev);
	drm_connector_attach_encoder(&bochs->connector,
					  &bochs->encoder);

	return 0;
}

void bochs_kms_fini(struct bochs_device *bochs)
{
	if (bochs->mode_config_initialized) {
		drm_mode_config_cleanup(bochs->dev);
		bochs->mode_config_initialized = false;
	}
}
