/*
 * MSM MDDI Transport
 *
 * Copyright (C) 2007 Google Incorporated
 * Copyright (C) 2007 QUALCOMM Incorporated
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/sched.h>
#include <mach/msm_iomap.h>
#include <mach/irqs.h>
#include <mach/board.h>
#include <mach/msm_fb.h>
#include "mddi_hw.h"

#define FLAG_DISABLE_HIBERNATION 0x0001
#define FLAG_HAVE_CAPS		 0x0002
#define FLAG_HAS_VSYNC_IRQ	 0x0004
#define FLAG_HAVE_STATUS	 0x0008

#define CMD_GET_CLIENT_CAP     0x0601
#define CMD_GET_CLIENT_STATUS  0x0602

union mddi_rev {
	unsigned char raw[MDDI_REV_BUFFER_SIZE];
	struct mddi_rev_packet hdr;
	struct mddi_client_status status;
	struct mddi_client_caps caps;
	struct mddi_register_access reg;
};

struct reg_read_info {
	struct completion done;
	uint32_t reg;
	uint32_t status;
	uint32_t result;
};

struct mddi_info {
	uint16_t flags;
	uint16_t version;
	char __iomem *base;
	int irq;
	struct clk *clk;
	struct msm_mddi_client_data client_data;

	/* buffer for rev encap packets */
	void *rev_data;
	dma_addr_t rev_addr;
	struct mddi_llentry *reg_write_data;
	dma_addr_t reg_write_addr;
	struct mddi_llentry *reg_read_data;
	dma_addr_t reg_read_addr;
	size_t rev_data_curr;

	spinlock_t int_lock;
	uint32_t int_enable;
	uint32_t got_int;
	wait_queue_head_t int_wait;

	struct mutex reg_write_lock;
	struct mutex reg_read_lock;
	struct reg_read_info *reg_read;

	struct mddi_client_caps caps;
	struct mddi_client_status status;

	void (*power_client)(struct msm_mddi_client_data *, int);

	/* client device published to bind us to the
	 * appropriate mddi_client driver
	 */
	char client_name[20];

	struct platform_device client_pdev;
};

static void mddi_init_rev_encap(struct mddi_info *mddi);

#define mddi_readl(r) readl(mddi->base + (MDDI_##r))
#define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))

void mddi_activate_link(struct msm_mddi_client_data *cdata)
{
	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
					      client_data);

	mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
}

static void mddi_handle_link_list_done(struct mddi_info *mddi)
{
}

static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi)
{
	printk(KERN_INFO "mddi: resetting rev ptr\n");
	mddi->rev_data_curr = 0;
	mddi_writel(mddi->rev_addr, REV_PTR);
	mddi_writel(mddi->rev_addr, REV_PTR);
	mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
}

static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev)
{
	int i;
	struct reg_read_info *ri;

	if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) &&
	   (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) {

		switch (rev->hdr.type) {
		case TYPE_CLIENT_CAPS:
			memcpy(&mddi->caps, &rev->caps,
			       sizeof(struct mddi_client_caps));
			mddi->flags |= FLAG_HAVE_CAPS;
			wake_up(&mddi->int_wait);
			break;
		case TYPE_CLIENT_STATUS:
			memcpy(&mddi->status, &rev->status,
			       sizeof(struct mddi_client_status));
			mddi->flags |= FLAG_HAVE_STATUS;
			wake_up(&mddi->int_wait);
			break;
		case TYPE_REGISTER_ACCESS:
			ri = mddi->reg_read;
			if (ri == 0) {
				printk(KERN_INFO "rev: got reg %x = %x without "
						 " pending read\n",
				       rev->reg.register_address,
				       rev->reg.register_data_list);
				break;
			}
			if (ri->reg != rev->reg.register_address) {
				printk(KERN_INFO "rev: got reg %x = %x for "
						 "wrong register, expected "
						 "%x\n",
				       rev->reg.register_address,
				       rev->reg.register_data_list, ri->reg);
				break;
			}
			mddi->reg_read = NULL;
			ri->status = 0;
			ri->result = rev->reg.register_data_list;
			complete(&ri->done);
			break;
		default:
			printk(KERN_INFO "rev: unknown reverse packet: "
					 "len=%04x type=%04x CURR_REV_PTR=%x\n",
			       rev->hdr.length, rev->hdr.type,
			       mddi_readl(CURR_REV_PTR));
			for (i = 0; i < rev->hdr.length + 2; i++) {
				if ((i % 16) == 0)
					printk(KERN_INFO "\n");
				printk(KERN_INFO " %02x", rev->raw[i]);
			}
			printk(KERN_INFO "\n");
			mddi_reset_rev_encap_ptr(mddi);
		}
	} else {
		printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n",
		       rev->hdr.length, mddi_readl(CURR_REV_PTR));
		mddi_reset_rev_encap_ptr(mddi);
	}
}

static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);

static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
{
	union mddi_rev *rev = mddi->rev_data;
	uint32_t rev_data_count;
	uint32_t rev_crc_err_count;
	int i;
	struct reg_read_info *ri;
	size_t prev_offset;
	uint16_t length;

	union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr;

	/* clear the interrupt */
	mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT);
	rev_data_count = mddi_readl(REV_PKT_CNT);
	rev_crc_err_count = mddi_readl(REV_CRC_ERR);
	if (rev_data_count > 1)
		printk(KERN_INFO "rev_data_count %d\n", rev_data_count);

	if (rev_crc_err_count) {
		printk(KERN_INFO "rev_crc_err_count %d, INT %x\n",
		       rev_crc_err_count,  mddi_readl(INT));
		ri = mddi->reg_read;
		if (ri == 0) {
			printk(KERN_INFO "rev: got crc error without pending "
			       "read\n");
		} else {
			mddi->reg_read = NULL;
			ri->status = -EIO;
			ri->result = -1;
			complete(&ri->done);
		}
	}

	if (rev_data_count == 0)
		return;

	prev_offset = mddi->rev_data_curr;

	length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr);
	mddi->rev_data_curr++;
	if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE)
		mddi->rev_data_curr = 0;
	length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8;
	mddi->rev_data_curr += 1 + length;
	if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE)
		mddi->rev_data_curr =
			mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE;

	if (length > MDDI_REV_BUFFER_SIZE - 2) {
		printk(KERN_INFO "mddi: rev data length greater than buffer"
			"size\n");
		mddi_reset_rev_encap_ptr(mddi);
		return;
	}

	if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) {
		union mddi_rev tmprev;
		size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset;
		memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem);
		memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem);
		mddi_handle_rev_data(mddi, &tmprev);
	} else {
		mddi_handle_rev_data(mddi, crev);
	}

	if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
	    mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
		mddi_writel(mddi->rev_addr, REV_PTR);
	}
}

static irqreturn_t mddi_isr(int irq, void *data)
{
	struct msm_mddi_client_data *cdata = data;
	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
					      client_data);
	uint32_t active, status;

	spin_lock(&mddi->int_lock);

	active = mddi_readl(INT);
	status = mddi_readl(STAT);

	mddi_writel(active, INT);

	/* ignore any interrupts we have disabled */
	active &= mddi->int_enable;

	mddi->got_int |= active;
	wake_up(&mddi->int_wait);

	if (active & MDDI_INT_PRI_LINK_LIST_DONE) {
		mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE);
		mddi_handle_link_list_done(mddi);
	}
	if (active & MDDI_INT_REV_DATA_AVAIL)
		mddi_handle_rev_data_avail(mddi);

	if (active & ~MDDI_INT_NEED_CLEAR)
		mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR);

	if (active & MDDI_INT_LINK_ACTIVE) {
		mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE);
		mddi->int_enable |= MDDI_INT_IN_HIBERNATION;
	}

	if (active & MDDI_INT_IN_HIBERNATION) {
		mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
		mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
	}

	mddi_writel(mddi->int_enable, INTEN);
	spin_unlock(&mddi->int_lock);

	return IRQ_HANDLED;
}

static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
					uint32_t intmask, int timeout)
{
	unsigned long irq_flags;

	spin_lock_irqsave(&mddi->int_lock, irq_flags);
	mddi->got_int &= ~intmask;
	mddi->int_enable |= intmask;
	mddi_writel(mddi->int_enable, INTEN);
	spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
	return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask,
				  timeout);
}

static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
{
	if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
		printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout "
		       "waiting for %x, INT = %x, STAT = %x gotint = %x\n",
		       current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
		       mddi->got_int);
}

static void mddi_init_rev_encap(struct mddi_info *mddi)
{
	memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE);
	mddi_writel(mddi->rev_addr, REV_PTR);
	mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
}

void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on)
{
	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
					      client_data);
	mddi_writel(MDDI_CMD_POWERDOWN, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
	mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
}


static uint16_t mddi_init_registers(struct mddi_info *mddi)
{
	mddi_writel(0x0001, VERSION);
	mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
	mddi_writel(0x0003, SPM); /* subframes per media */
	mddi_writel(0x0005, TA1_LEN);
	mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
	mddi_writel(0x0096, DRIVE_HI);
	/* 0x32 normal, 0x50 for Toshiba display */
	mddi_writel(0x0050, DRIVE_LO);
	mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
	mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);

	mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE);
	mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ);

	/* disable periodic rev encap */
	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);

	if (mddi_readl(PAD_CTL) == 0) {
		/* If we are turning on band gap, need to wait 5us before
		 * turning on the rest of the PAD */
		mddi_writel(0x08000, PAD_CTL);
		udelay(5);
	}

	/* Recommendation from PAD hw team */
	mddi_writel(0xa850f, PAD_CTL);


	/* Need an even number for counts */
	mddi_writel(0x60006, DRIVER_START_CNT);

	mddi_set_auto_hibernate(&mddi->client_data, 0);

	mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);

	mddi_init_rev_encap(mddi);
	return mddi_readl(CORE_VER) & 0xffff;
}

static void mddi_suspend(struct msm_mddi_client_data *cdata)
{
	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
					      client_data);
	/* turn off the client */
	if (mddi->power_client)
		mddi->power_client(&mddi->client_data, 0);
	/* turn off the link */
	mddi_writel(MDDI_CMD_RESET, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
	/* turn off the clock */
	clk_disable(mddi->clk);
}

static void mddi_resume(struct msm_mddi_client_data *cdata)
{
	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
					      client_data);
	mddi_set_auto_hibernate(&mddi->client_data, 0);
	/* turn on the client */
	if (mddi->power_client)
		mddi->power_client(&mddi->client_data, 1);
	/* turn on the clock */
	clk_enable(mddi->clk);
	/* set up the local registers */
	mddi->rev_data_curr = 0;
	mddi_init_registers(mddi);
	mddi_writel(mddi->int_enable, INTEN);
	mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
	mddi_writel(MDDI_CMD_SEND_RTD, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
	mddi_set_auto_hibernate(&mddi->client_data, 1);
}

static int __init mddi_get_client_caps(struct mddi_info *mddi)
{
	int i, j;

	/* clear any stale interrupts */
	mddi_writel(0xffffffff, INT);

	mddi->int_enable = MDDI_INT_LINK_ACTIVE |
			   MDDI_INT_IN_HIBERNATION |
			   MDDI_INT_PRI_LINK_LIST_DONE |
			   MDDI_INT_REV_DATA_AVAIL |
			   MDDI_INT_REV_OVERFLOW |
			   MDDI_INT_REV_OVERWRITE |
			   MDDI_INT_RTD_FAILURE;
	mddi_writel(mddi->int_enable, INTEN);

	mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);

	for (j = 0; j < 3; j++) {
		/* the toshiba vga panel does not respond to get
		 * caps unless you SEND_RTD, but the first SEND_RTD
		 * will fail...
		 */
		for (i = 0; i < 4; i++) {
			uint32_t stat;

			mddi_writel(MDDI_CMD_SEND_RTD, CMD);
			mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
			stat = mddi_readl(STAT);
			printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, "
					"rtd val %x\n", mddi_readl(INT), stat,
					mddi_readl(RTD_VAL));
			if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0)
				break;
			msleep(1);
		}

		mddi_writel(CMD_GET_CLIENT_CAP, CMD);
		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
		wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS,
				   HZ / 100);

		if (mddi->flags & FLAG_HAVE_CAPS)
			break;
		printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for "
				"caps\n");
	}
	return mddi->flags & FLAG_HAVE_CAPS;
}

/* link must be active when this is called */
int mddi_check_status(struct mddi_info *mddi)
{
	int ret = -1, retry = 3;
	mutex_lock(&mddi->reg_read_lock);
	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);

	do {
		mddi->flags &= ~FLAG_HAVE_STATUS;
		mddi_writel(CMD_GET_CLIENT_STATUS, CMD);
		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
		wait_event_timeout(mddi->int_wait,
				   mddi->flags & FLAG_HAVE_STATUS,
				   HZ / 100);

		if (mddi->flags & FLAG_HAVE_STATUS) {
			if (mddi->status.crc_error_count)
				printk(KERN_INFO "mddi status: crc_error "
					"count: %d\n",
					mddi->status.crc_error_count);
			else
				ret = 0;
			break;
		} else
			printk(KERN_INFO "mddi status: failed to get client "
				"status\n");
		mddi_writel(MDDI_CMD_SEND_RTD, CMD);
		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
	} while (--retry);

	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
	mutex_unlock(&mddi->reg_read_lock);
	return ret;
}


void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
		       uint32_t reg)
{
	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
					      client_data);
	struct mddi_llentry *ll;
	struct mddi_register_access *ra;

	mutex_lock(&mddi->reg_write_lock);

	ll = mddi->reg_write_data;

	ra = &(ll->u.r);
	ra->length = 14 + 4;
	ra->type = TYPE_REGISTER_ACCESS;
	ra->client_id = 0;
	ra->read_write_info = MDDI_WRITE | 1;
	ra->crc16 = 0;

	ra->register_address = reg;
	ra->register_data_list = val;

	ll->flags = 1;
	ll->header_count = 14;
	ll->data_count = 4;
	ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry,
						   u.r.register_data_list);
	ll->next = 0;
	ll->reserved = 0;

	mddi_writel(mddi->reg_write_addr, PRI_PTR);

	mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
	mutex_unlock(&mddi->reg_write_lock);
}

uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
{
	struct mddi_info *mddi = container_of(cdata, struct mddi_info,
					      client_data);
	struct mddi_llentry *ll;
	struct mddi_register_access *ra;
	struct reg_read_info ri;
	unsigned s;
	int retry_count = 2;
	unsigned long irq_flags;

	mutex_lock(&mddi->reg_read_lock);

	ll = mddi->reg_read_data;

	ra = &(ll->u.r);
	ra->length = 14;
	ra->type = TYPE_REGISTER_ACCESS;
	ra->client_id = 0;
	ra->read_write_info = MDDI_READ | 1;
	ra->crc16 = 0;

	ra->register_address = reg;

	ll->flags = 0x11;
	ll->header_count = 14;
	ll->data_count = 0;
	ll->data = 0;
	ll->next = 0;
	ll->reserved = 0;

	s = mddi_readl(STAT);

	ri.reg = reg;
	ri.status = -1;

	do {
		init_completion(&ri.done);
		mddi->reg_read = &ri;
		mddi_writel(mddi->reg_read_addr, PRI_PTR);

		mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);

		/* Enable Periodic Reverse Encapsulation. */
		mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
		if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
		    !ri.done.done) {
			printk(KERN_INFO "mddi_remote_read(%x) timeout "
					 "(%d %d %d)\n",
			       reg, ri.status, ri.result, ri.done.done);
			spin_lock_irqsave(&mddi->int_lock, irq_flags);
			mddi->reg_read = NULL;
			spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
			ri.status = -1;
			ri.result = -1;
		}
		if (ri.status == 0)
			break;

		mddi_writel(MDDI_CMD_SEND_RTD, CMD);
		mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
		mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
		printk(KERN_INFO "mddi_remote_read: failed, sent "
		       "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
		       "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
		       mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
	} while (retry_count-- > 0);
	/* Disable Periodic Reverse Encapsulation. */
	mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
	mddi->reg_read = NULL;
	mutex_unlock(&mddi->reg_read_lock);
	return ri.result;
}

static struct mddi_info mddi_info[2];

static int __init mddi_clk_setup(struct platform_device *pdev,
				 struct mddi_info *mddi,
				 unsigned long clk_rate)
{
	int ret;

	/* set up the clocks */
	mddi->clk = clk_get(&pdev->dev, "mddi_clk");
	if (IS_ERR(mddi->clk)) {
		printk(KERN_INFO "mddi: failed to get clock\n");
		return PTR_ERR(mddi->clk);
	}
	ret =  clk_enable(mddi->clk);
	if (ret)
		goto fail;
	ret = clk_set_rate(mddi->clk, clk_rate);
	if (ret)
		goto fail;
	return 0;

fail:
	clk_put(mddi->clk);
	return ret;
}

static int __init mddi_rev_data_setup(struct mddi_info *mddi)
{
	void *dma;
	dma_addr_t dma_addr;

	/* set up dma buffer */
	dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL);
	if (dma == 0)
		return -ENOMEM;
	mddi->rev_data = dma;
	mddi->rev_data_curr = 0;
	mddi->rev_addr = dma_addr;
	mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE;
	mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE;
	mddi->reg_read_data = mddi->reg_write_data + 1;
	mddi->reg_read_addr = mddi->reg_write_addr +
			      sizeof(*mddi->reg_write_data);
	return 0;
}

static int __init mddi_probe(struct platform_device *pdev)
{
	struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
	struct mddi_info *mddi = &mddi_info[pdev->id];
	struct resource *resource;
	int ret, i;

	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!resource) {
		printk(KERN_ERR "mddi: no associated mem resource!\n");
		return -ENOMEM;
	}
	mddi->base = ioremap(resource->start, resource->end - resource->start);
	if (!mddi->base) {
		printk(KERN_ERR "mddi: failed to remap base!\n");
		ret = -EINVAL;
		goto error_ioremap;
	}
	resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!resource) {
		printk(KERN_ERR "mddi: no associated irq resource!\n");
		ret = -EINVAL;
		goto error_get_irq_resource;
	}
	mddi->irq = resource->start;
	printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
	       mddi->irq);
	mddi->power_client = pdata->power_client;

	mutex_init(&mddi->reg_write_lock);
	mutex_init(&mddi->reg_read_lock);
	spin_lock_init(&mddi->int_lock);
	init_waitqueue_head(&mddi->int_wait);

	ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
	if (ret) {
		printk(KERN_ERR "mddi: failed to setup clock!\n");
		goto error_clk_setup;
	}

	ret = mddi_rev_data_setup(mddi);
	if (ret) {
		printk(KERN_ERR "mddi: failed to setup rev data!\n");
		goto error_rev_data;
	}

	mddi->int_enable = 0;
	mddi_writel(mddi->int_enable, INTEN);
	ret = request_irq(mddi->irq, mddi_isr, IRQF_DISABLED, "mddi",
			  &mddi->client_data);
	if (ret) {
		printk(KERN_ERR "mddi: failed to request enable irq!\n");
		goto error_request_irq;
	}

	/* turn on the mddi client bridge chip */
	if (mddi->power_client)
		mddi->power_client(&mddi->client_data, 1);

	/* initialize the mddi registers */
	mddi_set_auto_hibernate(&mddi->client_data, 0);
	mddi_writel(MDDI_CMD_RESET, CMD);
	mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
	mddi->version = mddi_init_registers(mddi);
	if (mddi->version < 0x20) {
		printk(KERN_ERR "mddi: unsupported version 0x%x\n",
		       mddi->version);
		ret = -ENODEV;
		goto error_mddi_version;
	}

	/* read the capabilities off the client */
	if (!mddi_get_client_caps(mddi)) {
		printk(KERN_INFO "mddi: no client found\n");
		/* power down the panel */
		mddi_writel(MDDI_CMD_POWERDOWN, CMD);
		printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
		msleep(100);
		printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
		return 0;
	}
	mddi_set_auto_hibernate(&mddi->client_data, 1);

	if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0)
		pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code);

	mddi->client_pdev.id = 0;
	for (i = 0; i < pdata->num_clients; i++) {
		if (pdata->client_platform_data[i].product_id ==
		    (mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) {
			mddi->client_data.private_client_data =
				pdata->client_platform_data[i].client_data;
			mddi->client_pdev.name =
				pdata->client_platform_data[i].name;
			mddi->client_pdev.id =
				pdata->client_platform_data[i].id;
			/* XXX: possibly set clock */
			break;
		}
	}

	if (i >= pdata->num_clients)
		mddi->client_pdev.name = "mddi_c_dummy";
	printk(KERN_INFO "mddi: registering panel %s\n",
		mddi->client_pdev.name);

	mddi->client_data.suspend = mddi_suspend;
	mddi->client_data.resume = mddi_resume;
	mddi->client_data.activate_link = mddi_activate_link;
	mddi->client_data.remote_write = mddi_remote_write;
	mddi->client_data.remote_read = mddi_remote_read;
	mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
	mddi->client_data.fb_resource = pdata->fb_resource;
	if (pdev->id == 0)
		mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE;
	else if (pdev->id == 1)
		mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE;
	else {
		printk(KERN_ERR "mddi: can not determine interface %d!\n",
		       pdev->id);
		ret = -EINVAL;
		goto error_mddi_interface;
	}

	mddi->client_pdev.dev.platform_data = &mddi->client_data;
	printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name);
	platform_device_register(&mddi->client_pdev);
	return 0;

error_mddi_interface:
error_mddi_version:
	free_irq(mddi->irq, 0);
error_request_irq:
	dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr);
error_rev_data:
error_clk_setup:
error_get_irq_resource:
	iounmap(mddi->base);
error_ioremap:

	printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret);
	return ret;
}


static struct platform_driver mddi_driver = {
	.probe = mddi_probe,
	.driver = { .name = "msm_mddi" },
};

static int __init _mddi_init(void)
{
	return platform_driver_register(&mddi_driver);
}

module_init(_mddi_init);
