[msm7k] mddi support for msm7k and surf-msm7k wvga panel.
diff --git a/platform/msm7k/include/platform/mddi.h b/platform/msm7k/include/platform/mddi.h
new file mode 100644
index 0000000..d1d3a77
--- /dev/null
+++ b/platform/msm7k/include/platform/mddi.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the 
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_MDDI_H
+#define __PLATFORM_MDDI_H
+
+struct fbcon_config;
+
+struct __attribute__((packed)) mddi_client_caps 
+{
+    unsigned short length;
+    unsigned short type;
+    unsigned short client_id;
+
+    unsigned short protocol_ver;
+    unsigned short min_protocol_ver;
+    unsigned short data_rate_cap;
+    unsigned char interface_type_cap;
+    unsigned char num_alt_displays;
+    unsigned short postcal_data_rate;
+    unsigned short bitmap_width;
+    unsigned short bitmap_height;
+    unsigned short display_window_width;
+    unsigned short display_window_height;
+    unsigned cmap_size;
+    unsigned short cmap_rgb_width;
+    unsigned short rgb_cap;
+    unsigned char mono_cap;
+    unsigned char reserved1;
+    unsigned short ycbcr_cap;
+    unsigned short bayer_cap;
+    unsigned short alpha_cursor_planes;
+    unsigned client_feature_cap;
+    unsigned char max_video_frame_rate_cap;
+    unsigned char min_video_frame_rate_cap;
+    unsigned short min_sub_frame_rate;
+    unsigned short audio_buf_depth;
+    unsigned short audio_channel_cap;
+    unsigned short audio_sampe_rate_rap;
+    unsigned char audio_sample_res;
+    unsigned char mic_audio_sample_res;
+    unsigned short mic_sample_rate_cap;
+    unsigned char keyboard_data_fmt;
+    unsigned char pointing_device_data_fmt;
+    unsigned short content_protection_type;
+    unsigned short manufacturer_name;
+    unsigned short product_code;
+    unsigned short reserved3;
+    unsigned serial_no;
+    unsigned char week_of_manufacture;
+    unsigned char year_of_manufacture;
+
+    unsigned short crc;    
+};
+
+void mddi_remote_write(unsigned val, unsigned reg);
+struct fbcon_config *mddi_init(void);
+
+#endif /* __PLATFORM_MDDI_H */
diff --git a/platform/msm7k/mddi.c b/platform/msm7k/mddi.c
new file mode 100644
index 0000000..7472953
--- /dev/null
+++ b/platform/msm7k/mddi.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <reg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dev/fbcon.h>
+#include <kernel/thread.h>
+#include <platform/iomap.h>
+#include <platform/mddi.h>
+
+#include "mddi_hw.h"
+
+static mddi_llentry *mlist = NULL;
+static mddi_llentry *mlist_remote_write = NULL;
+
+#define MDDI_MAX_REV_PKT_SIZE 0x60
+#define MDDI_REV_PKT_BUF_SIZE (MDDI_MAX_REV_PKT_SIZE * 4)
+static void *rev_pkt_buf;
+
+/* functions provided by the target specific panel code */
+void panel_init(struct mddi_client_caps *client_caps);
+void panel_poweron(void);
+void panel_backlight(int on);
+
+/* forward decls */
+static void mddi_start_update(void);
+static int mddi_update_done(void);
+
+static struct fbcon_config fb_cfg = {
+	.format		= FB_FORMAT_RGB565,
+	.bpp		= 16,
+	.update_start	= mddi_start_update,
+	.update_done	= mddi_update_done,
+};
+
+static void printcaps(struct mddi_client_caps *c)
+{
+	if ((c->length != 0x4a) || (c->type != 0x42)) {
+		dprintf(INFO, "bad caps header\n");
+		memset(c, 0, sizeof(*c));
+		return;
+	}
+
+	dprintf(INFO, "mddi: bm: %d,%d win %d,%d rgb %x\n",
+		c->bitmap_width, c->bitmap_height,
+		c->display_window_width, c->display_window_height,
+		c->rgb_cap);
+	dprintf(INFO, "mddi: vend %x prod %x\n",
+		c->manufacturer_name, c->product_code);
+}
+
+/* TODO: add timeout */
+static int mddi_wait_status(unsigned statmask)
+{
+	while ((readl(MDDI_STAT) & statmask) == 0);
+	return 0;
+}
+
+/* TODO: add timeout */
+static int mddi_wait_interrupt(unsigned intmask)
+{
+	while ((readl(MDDI_INT) & intmask) == 0);
+	return 0;
+}
+
+void mddi_remote_write(unsigned val, unsigned reg)
+{
+	mddi_llentry *ll;
+	mddi_register_access *ra;
+
+	ll = mlist_remote_write;
+	
+	ra = &(ll->u.r);
+	ra->length = 14 + 4;
+	ra->type = TYPE_REGISTER_ACCESS;
+	ra->client_id = 0;
+	ra->rw_info = MDDI_WRITE | 1;
+	ra->crc = 0;
+
+	ra->reg_addr = reg;
+	ra->reg_data = val;
+
+	ll->flags = 1;
+	ll->header_count = 14;
+	ll->data_count = 4;
+	ll->data = &ra->reg_data;
+	ll->next = (void *) 0;
+	ll->reserved = 0;
+
+	writel((unsigned) ll, MDDI_PRI_PTR);
+
+	mddi_wait_status(MDDI_STAT_PRI_LINK_LIST_DONE);
+}
+
+static void mddi_start_update(void)
+{
+	writel((unsigned) mlist, MDDI_PRI_PTR);
+}
+
+static int mddi_update_done(void)
+{
+	return !!(readl(MDDI_STAT) & MDDI_STAT_PRI_LINK_LIST_DONE);
+}
+
+static void mddi_do_cmd(unsigned cmd)
+{
+	writel(cmd, MDDI_CMD);
+	mddi_wait_interrupt(MDDI_INT_NO_REQ_PKTS_PENDING);
+}
+
+static void mddi_init_rev_encap(void)
+{
+	memset(rev_pkt_buf, 0xee, MDDI_REV_PKT_BUF_SIZE);
+	writel((unsigned) rev_pkt_buf, MDDI_REV_PTR);
+	writel((unsigned) rev_pkt_buf, MDDI_REV_PTR);
+	mddi_do_cmd(CMD_FORCE_NEW_REV_PTR);
+}
+
+static void mddi_set_auto_hibernate(unsigned on)
+{
+	writel(CMD_POWER_DOWN, MDDI_CMD);
+	mddi_wait_interrupt(MDDI_INT_IN_HIBERNATION);
+	mddi_do_cmd(CMD_HIBERNATE | !!on);
+}
+
+static void mddi_get_caps(struct mddi_client_caps *caps)
+{
+	unsigned timeout = 100000;
+	unsigned n;
+
+	writel(0xffffffff, MDDI_INT);
+	mddi_do_cmd(CMD_LINK_ACTIVE);
+
+	/* sometimes this will fail -- do it three times for luck... */
+	mddi_do_cmd(CMD_RTD_MEASURE);
+	thread_sleep(1);//mdelay(1);
+
+	mddi_do_cmd(CMD_RTD_MEASURE);
+	thread_sleep(1);//mdelay(1);
+
+	mddi_do_cmd(CMD_RTD_MEASURE);
+	thread_sleep(1);//mdelay(1);
+
+	mddi_do_cmd(CMD_GET_CLIENT_CAP);
+
+	do {
+		n = readl(MDDI_INT);
+	} while (!(n & MDDI_INT_REV_DATA_AVAIL) && (--timeout));
+	
+	if (timeout == 0)
+		dprintf(INFO, "timeout\n");
+
+	memcpy(caps, rev_pkt_buf, sizeof(struct mddi_client_caps));
+}
+
+static unsigned mddi_init_regs(void)
+{
+	mddi_set_auto_hibernate(0);
+	mddi_do_cmd(CMD_RESET);
+
+	mddi_do_cmd(CMD_PERIODIC_REV_ENC);
+
+	writel(0x0001, MDDI_VERSION);
+	writel(0x3C00, MDDI_BPS);
+	writel(0x0003, MDDI_SPM);
+
+	writel(0x0005, MDDI_TA1_LEN);
+	writel(0x000C, MDDI_TA2_LEN);
+	writel(0x0096, MDDI_DRIVE_HI);
+	writel(0x0050, MDDI_DRIVE_LO);
+	writel(0x003C, MDDI_DISP_WAKE);
+	writel(0x0002, MDDI_REV_RATE_DIV);
+
+	writel(MDDI_REV_PKT_BUF_SIZE, MDDI_REV_SIZE);
+//	writel(MDDI_REV_PKT_BUF_SIZE, MDDI_REV_ENCAP_SZ);
+	writel(MDDI_MAX_REV_PKT_SIZE, MDDI_REV_ENCAP_SZ);
+
+	mddi_do_cmd(CMD_PERIODIC_REV_ENC);
+
+	/* needs to settle for 5uS */
+	if (readl(MDDI_PAD_CTL) == 0) {
+		writel(0x08000, MDDI_PAD_CTL);
+		thread_sleep(1);//udelay(5);
+	}
+
+	writel(0xA850F, MDDI_PAD_CTL);
+	writel(0x60006, MDDI_DRIVER_START_CNT);
+
+	/* disable hibernate */
+	mddi_set_auto_hibernate(0);
+	mddi_do_cmd(CMD_IGNORE);
+
+	mddi_init_rev_encap();
+	return readl(MDDI_CORE_VER) & 0xffff;
+}
+
+struct fbcon_config *mddi_init(void)
+{
+	unsigned n;
+	struct mddi_client_caps client_caps;
+
+	dprintf(INFO, "mddi_init()\n");
+
+	rev_pkt_buf = memalign(32, MDDI_REV_PKT_BUF_SIZE);
+	mlist_remote_write = memalign(32, sizeof(struct mddi_llentry));
+
+	n = mddi_init_regs();
+	dprintf(INFO, "mddi version: 0x%08x\n", n);
+
+	mddi_get_caps(&client_caps);
+	ASSERT(client_caps.length == 0x4a && client_caps.type == 0x42);
+
+	fb_cfg.width = client_caps.bitmap_width;
+	fb_cfg.stride = fb_cfg.width;
+	fb_cfg.height = client_caps.bitmap_height;
+
+	printcaps(&client_caps);
+
+	panel_init(&client_caps);
+
+	panel_backlight(0);
+	panel_poweron();
+
+	/* v > 8?  v > 8 && < 0x19 ? */
+	writel(2, MDDI_TEST);
+
+	dprintf(INFO, "panel is %d x %d\n", fb_cfg.width, fb_cfg.height);
+
+	fb_cfg.base =
+		memalign(4096, fb_cfg.width * fb_cfg.height * (fb_cfg.bpp / 8));
+
+	mlist = memalign(32, sizeof(mddi_llentry) * (fb_cfg.height / 8));
+	dprintf(INFO, "FB @ %p  mlist @ %x\n", fb_cfg.base, (unsigned) mlist);
+	
+	for(n = 0; n < (fb_cfg.height / 8); n++) {
+		unsigned y = n * 8;
+		unsigned pixels = fb_cfg.width * 8;
+		mddi_video_stream *vs = &(mlist[n].u.v);
+
+		vs->length = sizeof(mddi_video_stream) - 2 + (pixels * 2);
+		vs->type = TYPE_VIDEO_STREAM;
+		vs->client_id = 0;
+		vs->format = 0x5565; // FORMAT_16BPP;
+		vs->pixattr = PIXATTR_BOTH_EYES | PIXATTR_TO_ALL;
+		
+		vs->left = 0;
+		vs->right = fb_cfg.width - 1;
+		vs->top = y;
+		vs->bottom = y + 7;
+		
+		vs->start_x = 0;
+		vs->start_y = y;
+		
+		vs->pixels = pixels;
+		vs->crc = 0;
+		vs->reserved = 0;
+		
+		mlist[n].header_count = sizeof(mddi_video_stream) - 2;
+		mlist[n].data_count = pixels * 2;
+		mlist[n].reserved = 0;
+		mlist[n].data = fb_cfg.base + (y * fb_cfg.width * 2);
+		mlist[n].next = &mlist[n + 1];
+		mlist[n].flags = 0;
+	}
+
+	mlist[n-1].flags = 1;
+	mlist[n-1].next = 0;
+
+	mddi_set_auto_hibernate(1);
+	mddi_do_cmd(CMD_LINK_ACTIVE);
+
+	panel_backlight(1);
+
+	return &fb_cfg;
+}
diff --git a/platform/msm7k/mddi_hw.h b/platform/msm7k/mddi_hw.h
new file mode 100644
index 0000000..814ea0e
--- /dev/null
+++ b/platform/msm7k/mddi_hw.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the 
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_MSM7K_MDDI_HW_H
+#define __PLATFORM_MSM7K_MDDI_HW_H
+
+#define MSM_MDDI_BASE 0xAA600000
+
+/* see 80-VA736-2 C pp 776-787 */
+
+#define MDDI_REG(off) (MSM_MDDI_BASE + (off))
+
+#define MDDI_CMD               MDDI_REG(0x0000)
+#define MDDI_VERSION           MDDI_REG(0x0004)
+#define MDDI_PRI_PTR           MDDI_REG(0x0008)
+#define MDDI_SEC_PTR           MDDI_REG(0x000C)
+#define MDDI_BPS               MDDI_REG(0x0010)
+#define MDDI_SPM               MDDI_REG(0x0014)
+#define MDDI_INT               MDDI_REG(0x0018)
+
+#define MDDI_INT_PRI_PTR_READ          (1 << 0)
+#define MDDI_INT_SEC_PTR_READ          (1 << 1)
+#define MDDI_INT_REV_DATA_AVAIL        (1 << 2)
+#define MDDI_INT_DISP_REQ              (1 << 3)
+#define MDDI_INT_PRI_UNDERFLOW         (1 << 4)
+#define MDDI_INT_SEC_UNDERFLOW         (1 << 5)
+#define MDDI_INT_REV_OVERFLOW          (1 << 6)
+#define MDDI_INT_CRC_ERROR             (1 << 7)
+#define MDDI_INT_MDDI_IN               (1 << 8)
+#define MDDI_INT_PRI_OVERWRITE         (1 << 9)
+#define MDDI_INT_SEC_OVERWRITE         (1 << 10)
+#define MDDI_INT_REV_OVERWRITE         (1 << 11)
+#define MDDI_INT_DMA_FAILURE           (1 << 12)
+#define MDDI_INT_LINK_ACTIVE           (1 << 13)
+#define MDDI_INT_IN_HIBERNATION        (1 << 14)
+#define MDDI_INT_PRI_LINK_LIST_DONE    (1 << 15)
+#define MDDI_INT_SEC_LINK_LIST_DONE    (1 << 16)
+#define MDDI_INT_NO_REQ_PKTS_PENDING   (1 << 17)
+#define MDDI_INT_RTD_FAILURE           (1 << 18)
+#define MDDI_INT_REV_PKT_RECEIVED      (1 << 19)
+#define MDDI_INT_REV_PKTS_AVAIL        (1 << 20)
+
+#define MDDI_INTEN             MDDI_REG(0x001C)
+#define MDDI_REV_PTR           MDDI_REG(0x0020)
+#define MDDI_REV_SIZE          MDDI_REG(0x0024)
+#define MDDI_STAT              MDDI_REG(0x0028)
+
+#define MDDI_STAT_LINK_ACTIVE                (1 << 0)
+#define MDDI_STAT_NEW_REV_PTR                (1 << 1)
+#define MDDI_STAT_NEW_PRI_PTR                (1 << 2)
+#define MDDI_STAT_NEW_SEC_PTR                (1 << 3)
+#define MDDI_STAT_IN_HIBERNATION             (1 << 4)
+#define MDDI_STAT_PRI_LINK_LIST_DONE         (1 << 5)
+#define MDDI_STAT_SEC_LINK_LIST_DONE         (1 << 6)
+#define MDDI_STAT_SEND_TIMING_PKT            (1 << 7)
+#define MDDI_STAT_SEND_REV_ENCAP_WITH_FLAGS  (1 << 8)
+#define MDDI_STAT_SEND_POWER_DOWN            (1 << 9)
+#define MDDI_STAT_DO_HANDSHAKE               (1 << 10)
+#define MDDI_STAT_RTD_MEAS_FAIL              (1 << 11)
+#define MDDI_STAT_CLIENT_WAKEUP_REQ          (1 << 12)
+#define MDDI_STAT_DMA_ABORT                  (1 << 13)
+#define MDDI_STAT_REV_OVERFLOW_RESET         (1 << 14)
+#define MDDI_STAT_FORCE_NEW_REV_PTR          (1 << 15)
+#define MDDI_STAT_CRC_ERRORS                 (1 << 16)
+
+#define MDDI_REV_RATE_DIV      MDDI_REG(0x002C)
+#define MDDI_REV_CRC_ERR       MDDI_REG(0x0030)
+#define MDDI_TA1_LEN           MDDI_REG(0x0034)
+#define MDDI_TA2_LEN           MDDI_REG(0x0038)
+#define MDDI_TEST_BUS          MDDI_REG(0x003C)
+#define MDDI_TEST              MDDI_REG(0x0040)
+#define MDDI_REV_PKT_CNT       MDDI_REG(0x0044)
+#define MDDI_DRIVE_HI          MDDI_REG(0x0048)
+#define MDDI_DRIVE_LO          MDDI_REG(0x004C)
+#define MDDI_DISP_WAKE         MDDI_REG(0x0050)
+#define MDDI_REV_ENCAP_SZ      MDDI_REG(0x0054)
+#define MDDI_RTD_VAL           MDDI_REG(0x0058)
+#define MDDI_MDP_VID_FMT_DES   MDDI_REG(0x005C)
+#define MDDI_MDP_VID_PIX_ATTR  MDDI_REG(0x0060)
+#define MDDI_MDP_VID_CLIENTID  MDDI_REG(0x0064)
+#define MDDI_PAD_CTL           MDDI_REG(0x0068)
+#define MDDI_DRIVER_START_CNT  MDDI_REG(0x006C)
+#define MDDI_NEXT_PRI_PTR      MDDI_REG(0x0070)
+#define MDDI_NEXT_SEC_PTR      MDDI_REG(0x0074)
+#define MDDI_MISR_CTL          MDDI_REG(0x0078)
+#define MDDI_MISR_DATA         MDDI_REG(0x007C)
+#define MDDI_SF_CNT            MDDI_REG(0x0080)
+#define MDDI_MF_CNT            MDDI_REG(0x0084)
+#define MDDI_CURR_REV_PTR      MDDI_REG(0x0088)
+#define MDDI_CORE_VER          MDDI_REG(0x008C)
+
+#define CMD_POWER_DOWN         0x0100
+#define CMD_POWER_UP           0x0200
+#define CMD_HIBERNATE          0x0300
+#define CMD_RESET              0x0400
+#define CMD_IGNORE             0x0501
+#define CMD_LISTEN             0x0500
+#define CMD_REV_ENC_REQ        0x0600
+#define CMD_RTD_MEASURE        0x0700
+#define CMD_LINK_ACTIVE        0x0900
+#define CMD_PERIODIC_REV_ENC   0x0A00
+#define CMD_FORCE_NEW_REV_PTR  0x0C00
+
+#define CMD_GET_CLIENT_CAP     0x0601
+#define CMD_GET_CLIENT_STATUS  0x0602
+
+#if 1
+#define FORMAT_18BPP           0x5666
+#define FORMAT_24BPP           0x5888
+#define FORMAT_16BPP           0x5565
+#else
+#define FORMAT_MONOCHROME      (0 << 13)
+#define FORMAT_PALETTE         (1 << 13)
+#define FORMAT_RGB             (2 << 13)
+#define FORMAT_YCBCR422        (3 << 13)
+#define FORMAT_BAYER           (4 << 13)
+#endif
+
+#define PIXATTR_BOTH_EYES      3
+#define PIXATTR_LEFT_EYE       2
+#define PIXATTR_RIGHT_EYE      1
+#define PIXATTR_ALT_DISPLAY    0
+
+#define PIXATTR_PROGRESSIVE    0
+#define PIXATTR_INTERLACED     (1 << 2)
+#define PIXATTR_ALTERNATE      (1 << 3)
+
+#define PIXATTR_IGNORE_LRTB    (1 << 5)
+
+#define PIXATTR_TO_REFRESH     (0 << 6)
+#define PIXATTR_TO_OFFLINE     (1 << 6)
+#define PIXATTR_TO_ALL         (3 << 6)
+
+#define PIXATTR_LAST_ROW       (1 << 15)
+
+#define TYPE_VIDEO_STREAM      16
+#define TYPE_CLIENT_CAPS       66
+#define TYPE_REGISTER_ACCESS   146
+#define TYPE_CLIENT_STATUS     70
+
+typedef struct mddi_video_stream mddi_video_stream;
+typedef struct mddi_register_access mddi_register_access;
+typedef struct mddi_client_caps mddi_client_caps;
+
+typedef struct mddi_llentry mddi_llentry;
+
+struct __attribute__((packed)) mddi_video_stream 
+{
+    unsigned short length;      /* length in bytes excluding this field */
+    unsigned short type;        /* MDDI_TYPE_VIDEO_STREAM */
+    unsigned short client_id;   /* set to zero */
+    
+    unsigned short format;
+    unsigned short pixattr;
+
+    unsigned short left;
+    unsigned short top;
+    unsigned short right;
+    unsigned short bottom;
+
+    unsigned short start_x;
+    unsigned short start_y;
+
+    unsigned short pixels;
+
+    unsigned short crc;
+    unsigned short reserved;
+};
+
+struct __attribute__((packed)) mddi_register_access
+{
+    unsigned short length;
+    unsigned short type;
+    unsigned short client_id;
+
+    unsigned short rw_info;    /* flag below | count of reg_data */
+#define MDDI_WRITE     (0 << 14)
+#define MDDI_READ      (2 << 14)
+#define MDDI_READ_RESP (3 << 14)
+    
+    unsigned reg_addr;
+    unsigned short crc;        /* 16 bit crc of the above */
+
+    unsigned reg_data;         /* "list" of 3byte data values */
+};
+
+struct __attribute__((packed)) mddi_llentry {
+    unsigned short flags;
+    unsigned short header_count;
+    unsigned short data_count;
+    void *data;
+    mddi_llentry *next;
+    unsigned short reserved;
+    union {
+        mddi_video_stream v;
+        mddi_register_access r;
+        unsigned _[12];
+    } u;
+};
+
+#endif /* __PLATFORM_MSM7K_MDDI_HW_H */
diff --git a/platform/msm7k/platform.c b/platform/msm7k/platform.c
index 15ee2eb..c545262 100644
--- a/platform/msm7k/platform.c
+++ b/platform/msm7k/platform.c
@@ -30,9 +30,12 @@
  */
 
 #include <debug.h>
-
 #include <kernel/thread.h>
 #include <platform/debug.h>
+#include <platform/mddi.h>
+#include <dev/fbcon.h>
+
+static struct fbcon_config *fb_config;
 
 void platform_init_interrupts(void);
 void platform_init_timer();
@@ -40,6 +43,8 @@
 void uart3_clock_init(void);
 void uart_init(void);
 
+void mddi_clock_init(unsigned num, unsigned rate);
+
 void platform_early_init(void)
 {
 	uart3_clock_init();
@@ -52,4 +57,9 @@
 void platform_init(void)
 {
 	dprintf(INFO, "platform_init()\n");
+
+	mddi_clock_init(0, 122880000);
+	fb_config = mddi_init();
+	ASSERT(fb_config);
+	fbcon_setup(fb_config);
 }
diff --git a/platform/msm7k/rules.mk b/platform/msm7k/rules.mk
index 4a756fc..5c96a32 100644
--- a/platform/msm7k/rules.mk
+++ b/platform/msm7k/rules.mk
@@ -6,9 +6,12 @@
 
 INCLUDES += -I$(LOCAL_DIR)/include
 
+MODULES += dev/fbcon
+
 OBJS += \
 	$(LOCAL_DIR)/platform.o \
 	$(LOCAL_DIR)/interrupts.o \
+	$(LOCAL_DIR)/mddi.o \
 	$(LOCAL_DIR)/gpio.o \
 	$(LOCAL_DIR)/debug.o
 
diff --git a/platform/msm_shared/proc_comm.c b/platform/msm_shared/proc_comm.c
index 53c32a7..4315c28 100644
--- a/platform/msm_shared/proc_comm.c
+++ b/platform/msm_shared/proc_comm.c
@@ -220,3 +220,16 @@
 	clock_enable(USB_HS_CLK);
 	clock_enable(USB_HS_PCLK);
 }
+
+void mddi_clock_init(unsigned num, unsigned rate)
+{
+	unsigned clock_id;
+
+	if (num == 0)
+		clock_id = PMDH_CLK;
+	else
+		clock_id = EMDH_CLK;
+
+	clock_enable(clock_id);
+	clock_set_rate(clock_id, rate);
+}