/*
 * Copyright © 2010 Intel Corporation
 *
 * 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
 * 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.
 *
 * Authors:
 * Jim Liu <jim.liu@intel.com>
 * Jackie Li<yaodong.li@intel.com>
 * Gideon Eaton <eaton.
 * Scott Rowe <scott.m.rowe@intel.com>
 */

#include <linux/delay.h>

#include "mdfld_dsi_dpi.h"
#include "mdfld_dsi_pkg_sender.h"

static struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev)
{
	struct drm_display_mode *mode;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD;
	bool use_gct = false; /*Disable GCT for now*/

	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
	if (!mode)
		return NULL;

	if (use_gct) {
		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
		mode->hsync_start = mode->hdisplay + \
				((ti->hsync_offset_hi << 8) | \
				ti->hsync_offset_lo);
		mode->hsync_end = mode->hsync_start + \
				((ti->hsync_pulse_width_hi << 8) | \
				ti->hsync_pulse_width_lo);
		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
								ti->hblank_lo);
		mode->vsync_start = \
			mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
						ti->vsync_offset_lo);
		mode->vsync_end = \
			mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
						ti->vsync_pulse_width_lo);
		mode->vtotal = mode->vdisplay + \
				((ti->vblank_hi << 8) | ti->vblank_lo);
		mode->clock = ti->pixel_clock * 10;

		dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
		dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
		dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
		dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
		dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
		dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
		dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
		dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
		dev_dbg(dev->dev, "clock is %d\n", mode->clock);
	} else {
		mode->hdisplay = 480;
		mode->vdisplay = 854;
		mode->hsync_start = 487;
		mode->hsync_end = 490;
		mode->htotal = 499;
		mode->vsync_start = 861;
		mode->vsync_end = 865;
		mode->vtotal = 873;
		mode->clock = 33264;
	}

	drm_mode_set_name(mode);
	drm_mode_set_crtcinfo(mode, 0);

	mode->type |= DRM_MODE_TYPE_PREFERRED;

	return mode;
}

static int tmd_vid_get_panel_info(struct drm_device *dev,
				int pipe,
				struct panel_info *pi)
{
	if (!dev || !pi)
		return -EINVAL;

	pi->width_mm = TMD_PANEL_WIDTH;
	pi->height_mm = TMD_PANEL_HEIGHT;

	return 0;
}

/* ************************************************************************* *\
 * FUNCTION: mdfld_init_TMD_MIPI
 *
 * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
 *               restore_display_registers.  since this function does not
 *               acquire the mutex, it is important that the calling function
 *               does!
\* ************************************************************************* */

/* FIXME: make the below data u8 instead of u32; note byte order! */
static u32 tmd_cmd_mcap_off[] = {0x000000b2};
static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef};
static u32 tmd_cmd_set_lane_num[] = {0x006360ef};
static u32 tmd_cmd_pushing_clock0[] = {0x00cc2fef};
static u32 tmd_cmd_pushing_clock1[] = {0x00dd6eef};
static u32 tmd_cmd_set_mode[] = {0x000000b3};
static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef};
static u32 tmd_cmd_set_column[] = {0x0100002a, 0x000000df};
static u32 tmd_cmd_set_page[] = {0x0300002b, 0x00000055};
static u32 tmd_cmd_set_video_mode[] = {0x00000153};
/*no auto_bl,need add in furture*/
static u32 tmd_cmd_enable_backlight[] = {0x00005ab4};
static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd};

static void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config,
				      int pipe)
{
	struct mdfld_dsi_pkg_sender *sender
			= mdfld_dsi_get_pkg_sender(dsi_config);

	DRM_INFO("Enter mdfld init TMD MIPI display.\n");

	if (!sender) {
		DRM_ERROR("Cannot get sender\n");
		return;
	}

	if (dsi_config->dvr_ic_inited)
		return;

	msleep(3);

	/* FIXME: make the below data u8 instead of u32; note byte order! */

	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_mcap_off,
				sizeof(tmd_cmd_mcap_off), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_enable_lane_switch,
				sizeof(tmd_cmd_enable_lane_switch), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_lane_num,
				sizeof(tmd_cmd_set_lane_num), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_pushing_clock0,
				sizeof(tmd_cmd_pushing_clock0), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_pushing_clock1,
				sizeof(tmd_cmd_pushing_clock1), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_mode,
				sizeof(tmd_cmd_set_mode), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_sync_pulse_mode,
				sizeof(tmd_cmd_set_sync_pulse_mode), false);
	mdfld_dsi_send_mcs_long(sender, (u8 *) tmd_cmd_set_column,
				sizeof(tmd_cmd_set_column), false);
	mdfld_dsi_send_mcs_long(sender, (u8 *) tmd_cmd_set_page,
				sizeof(tmd_cmd_set_page), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_video_mode,
				sizeof(tmd_cmd_set_video_mode), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_enable_backlight,
				sizeof(tmd_cmd_enable_backlight), false);
	mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_backlight_dimming,
				sizeof(tmd_cmd_set_backlight_dimming), false);

	dsi_config->dvr_ic_inited = 1;
}

/*TPO DPI encoder helper funcs*/
static const struct drm_encoder_helper_funcs
				mdfld_tpo_dpi_encoder_helper_funcs = {
	.dpms = mdfld_dsi_dpi_dpms,
	.mode_fixup = mdfld_dsi_dpi_mode_fixup,
	.prepare = mdfld_dsi_dpi_prepare,
	.mode_set = mdfld_dsi_dpi_mode_set,
	.commit = mdfld_dsi_dpi_commit,
};

/*TPO DPI encoder funcs*/
static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
	.destroy = drm_encoder_cleanup,
};

const struct panel_funcs mdfld_tmd_vid_funcs = {
	.encoder_funcs = &mdfld_tpo_dpi_encoder_funcs,
	.encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs,
	.get_config_mode = &tmd_vid_get_config_mode,
	.get_panel_info = tmd_vid_get_panel_info,
	.reset = mdfld_dsi_panel_reset,
	.drv_ic_init = mdfld_dsi_tmd_drv_ic_init,
};
