static unsigned mddi_init_regs(void) { 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(0x001A, MDDI_TA2_LEN); writel(0x0096, MDDI_DRIVE_HI); writel(0x0050, MDDI_DRIVE_LO); writel(0x003C, MDDI_DISP_WAKE); writel(0x0004, MDDI_REV_RATE_DIV); /* needs to settle for 5uS */ if (readl(MDDI_PAD_CTL) == 0) { writel(0x08000, MDDI_PAD_CTL); udelay(5); } writel(0xA850F, MDDI_PAD_CTL); writel(0x60006, MDDI_DRIVER_START_CNT); mddi_init_rev_encap(); /* disable hibernate */ mddi_do_cmd(CMD_HIBERNATE | 0); return readl(MDDI_CORE_VER) & 0xffff; }
void mddi_get_caps(void) { unsigned timeout = 100000; unsigned n; memset(rev_pkt_buf, 0xee, 256); // writel(CMD_HIBERNATE, MDDI_CMD); // writel(CMD_LINK_ACTIVE, MDDI_CMD); writel(256, MDDI_REV_SIZE); writel((unsigned) rev_pkt_buf, MDDI_REV_PTR); mddi_do_cmd(CMD_FORCE_NEW_REV_PTR); /* sometimes this will fail -- do it three times for luck... */ mddi_do_cmd(CMD_RTD_MEASURE); mdelay(1); mddi_do_cmd(CMD_RTD_MEASURE); mdelay(1); mddi_do_cmd(CMD_RTD_MEASURE); 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("timeout\n"); printcaps((mddi_client_caps*) rev_pkt_buf); }
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 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); writel(MDDI_REV_PKT_BUF_SIZE, MDDI_REV_SIZE); writel(MDDI_REV_PKT_BUF_SIZE, MDDI_REV_ENCAP_SZ); mddi_do_cmd(CMD_FORCE_NEW_REV_PTR); }
void mddi_init(void) { unsigned n; // dprintf("mddi_init()\n"); rev_pkt_buf = alloc(256); mddi_do_cmd(CMD_RESET); /* disable periodic rev encap */ mddi_do_cmd(CMD_PERIODIC_REV_ENC | 0); 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); /* needs to settle for 5uS */ if (readl(MDDI_PAD_CTL) == 0) { writel(0x08000, MDDI_PAD_CTL); udelay(5); } writel(0xA850F, MDDI_PAD_CTL); writel(0x60006, MDDI_DRIVER_START_CNT); writel((unsigned) rev_pkt_buf, MDDI_REV_PTR); writel(256, MDDI_REV_SIZE); writel(256, MDDI_REV_ENCAP_SZ); mddi_do_cmd(CMD_FORCE_NEW_REV_PTR); /* disable hibernate */ mddi_do_cmd(CMD_HIBERNATE | 0); panel_backlight(0); panel_poweron(); mddi_do_cmd(CMD_LINK_ACTIVE); do { n = readl(MDDI_STAT); } while(!(n & MDDI_STAT_LINK_ACTIVE)); /* v > 8? v > 8 && < 0x19 ? */ writel(2, MDDI_TEST); // writel(CMD_PERIODIC_REV_ENC | 0, MDDI_CMD); /* disable */ mddi_get_caps(); #if 0 writel(0x5666, MDDI_MDP_VID_FMT_DES); writel(0x00C3, MDDI_MDP_VID_PIX_ATTR); writel(0x0000, MDDI_MDP_CLIENTID); #endif dprintf("panel is %d x %d\n", fb_width, fb_height); FB = alloc(2 * fb_width * fb_height); mlist = alloc(sizeof(mddi_llentry) * (fb_height / 8)); // dprintf("FB @ %x mlist @ %x\n", (unsigned) FB, (unsigned) mlist); for(n = 0; n < (fb_height / 8); n++) { unsigned y = n * 8; unsigned pixels = fb_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_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; wr32(&mlist[n].data, ((unsigned) FB) + (y * fb_width * 2)); mlist[n].flags = 0; wr32(&mlist[n].next, (unsigned) (mlist + n + 1)); } mlist[n-1].flags = 1; wr32(&mlist[n-1].next, 0); writel(CMD_HIBERNATE, MDDI_CMD); writel(CMD_LINK_ACTIVE, MDDI_CMD); for(n = 0; n < (fb_width * fb_height); n++) FB[n] = 0; mddi_start_update(); panel_backlight(1); }
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); //if(!(client_caps.length == 0x4a && client_caps.type == 0x42)) { mddi_set_caps(&client_caps); } fb_cfg.width = client_caps.bitmap_width; fb_cfg.stride = fb_cfg.width; fb_cfg.height = client_caps.bitmap_height; 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; }
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); }
void mddi_init(void) { unsigned n; int i = 0; // dprintf("mddi_init()\n"); rev_pkt_buf = alloc(256); writel((unsigned) rev_pkt_buf, MDDI_REV_PTR); writel(256, MDDI_REV_SIZE); writel(256, MDDI_REV_ENCAP_SZ); mddi_do_cmd(CMD_FORCE_NEW_REV_PTR); mddi_do_cmd(CMD_LINK_ACTIVE); do { if(i++ > 0x100) break; n = readl(MDDI_STAT); } while(!(n & MDDI_STAT_LINK_ACTIVE)); /* v > 8? v > 8 && < 0x19 ? */ writel(2, MDDI_TEST); // writel(CMD_PERIODIC_REV_ENC | 0, MDDI_CMD); /* disable */ fb_width = 480; fb_height = 854; dprintf("panel is %d x %d\n", fb_width, fb_height); // FB = alloc(2 * fb_width * fb_height); FB = 0x2b00000; mlist = alloc(sizeof(mddi_llentry) * (fb_height / 8)); // dprintf("FB @ %x mlist @ %x\n", (unsigned) FB, (unsigned) mlist); for(n = 0; n < (fb_height / 8); n++) { unsigned y = n * 8; unsigned pixels = fb_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_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; wr32(&mlist[n].data, ((unsigned) FB) + (y * fb_width * 2)); mlist[n].flags = 0; wr32(&mlist[n].next, (unsigned) (mlist + n + 1)); } mlist[n-1].flags = 1; wr32(&mlist[n-1].next, 0); writel(CMD_HIBERNATE, MDDI_CMD); writel(CMD_LINK_ACTIVE, MDDI_CMD); for(n = 0; n < (fb_width * fb_height); n++) FB[n] = 0;//0x88; mddi_start_update(); }