[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);
+}