/* Config lcdc timimg when hdmi chooses a resolution * params: mode[lcdc_timimg_parms_t] lcdc timimg to * set * return: null */ void sep0611_hdmi_lcdc_timing(struct lcdc_timing_params_t *mode) { unsigned int plcr = 0; unsigned int pfcr = 0; unsigned int lcdcscr = 0; unsigned int lcdcbcr = 0; plcr = H_WIDTH(mode->lpw) | H_WAIT1((mode->lswc + 1)) | H_WAIT2((mode->lewc + 1)); pfcr = V_WIDTH(mode->fpw) | V_WAIT1((mode->fswc + 1)) | V_WAIT2((mode->fewc + 1)); lcdcscr = XMAX((mode->lpc + 1))|YMAX((mode->flc + 1)); lcdcbcr = readl(LCDC_BCR_V); lcdcbcr &= ~0x3f; lcdcbcr |= PCD(mode->pcd); writel(0x0, LCDC_ECR_V); msleep(20); writel(lcdcbcr, LCDC_BCR_V); writel(plcr, LCDC_PLCR_V); writel(pfcr, LCDC_PFCR_V); writel(lcdcscr, LCDC_SCR_V); msleep(20); writel(0x1, LCDC_ECR_V); msleep(10); }
/******************************** the module driver ************************************************************/ static int sep0611_overlay_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { unsigned int intArg,data; overlay_config_t config; lcdc_timming timming_tmp; switch(cmd) { #if 0 case OVERLAY_FORBID: if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; overlay_forbid = intArg; return 0; #endif #if USE_PICTURE case 111://GET_IMG //if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) // return -EFAULT; return sep0611_overlay_get_img(); #endif case OVERLAY_PRINT_REGS: dprintk("print regs:\n"); for(intArg=0; intArg<=0xCC;intArg+=4) { printk("reg[0x%x] = (0x%x)\n", (unsigned int)io + intArg, readl(io + intArg)); } break; case OVERLAY_GET_STARTBUF: dprintk("overlay_kernel ioctl get startbuffer!\n"); if(copy_to_user((unsigned int *)arg, &over1_addr_phy, sizeof(unsigned int))) { dprintk("error while copy!\n"); return -EFAULT; }else{ // dprintk("success get startbuf: 0x%x",over1_addr_phy); } break; case OVERLAY_AUTORP_CTL: if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; if(intArg == 1){ writel(0, io + SEP0611_ACSR); data = readl(io + SEP0611_LCDCBCR); data &=~(0x3<<13); data |=(0x2<<13); writel(data, io + SEP0611_LCDCBCR); mdelay(10); writel(1, io + SEP0611_ACSR); dprintk("ctl enable auto repair\n"); }else{ data = readl(io + SEP0611_LCDCBCR); data &=~(0x3<<13); writel(data, io + SEP0611_LCDCBCR); dprintk("ctl disable auto repair\n"); } break; case OVERLAY_SHOW_CURSOR: return sep0611_overlay_drawcursor(); case OVERLAY_SETPOS_CURSOR: if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; return sep0611_overlay_setpos_cursor(intArg); case OVERLAY_LAYERS_CTL://enable or disable layers if(copy_from_user(&intArg, (int *)arg, sizeof(int))) return -EFAULT; sep0611_overlay_layers_ctl(intArg); break; case 114://set lcdc timming if(copy_from_user(&timming_tmp, (lcdc_timming *)arg, sizeof(lcdc_timming))) return -EFAULT; sep0611_overlay_settimming(timming_tmp); break; case 115://set lcdc base layer size and format if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) return -EFAULT; intArg = 0; dprintk("set base size:(%d,%d)\n", config.width, config.height); intArg = XMAX(config.width)|YMAX(config.height); writel(intArg, io + SEP0611_BBPCR); writel(config.width, io + SEP0611_BASE_RAW_IMAGE_WIDTH); switch(config.format) { case V4L2_PIX_FMT_RGB565: dprintk("use rgb565\n"); data = readl(io + SEP0611_LCDCBCR); data &=~(0x3<<27); writel(data, io + SEP0611_LCDCBCR); break; case V4L2_PIX_FMT_RGB24: dprintk("use rgb888\n"); data = readl(io + SEP0611_LCDCBCR); data &= ~(0x3<<27); data |= (0x2<<27); writel(data, io + SEP0611_LCDCBCR); break; default: dprintk("not support!\n"); break; } break; case OVERLAY_GET_POSITION: return sep0611_overlay_get_pos((overlay_config_t*)arg); case OVERLAY_GET_SCREEN_INFO: return sep0611_overlay_get_screenInfo((overlay_config_t*)arg); case OVERLAY_SET_POSITION: if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) return -EFAULT; return sep0611_overlay_set_pos(config); case OVERLAY_QUEUE_BUFFER: if(copy_from_user(&intArg, (overlay_config_t *)arg, sizeof(unsigned int))) return -EFAULT; return sep0611_overlay_q_buffer((unsigned int)intArg); case OVERLAY_SET_CONFIGURE: if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t))) return -EFAULT; sep0611_overlay_set_configure(config); //sep0611_overlay_q_buffer(over1_addr_phy); break; case OVERLAY_SET_DISABLE: return sep0611_overlay_disable(); case OVERLAY_SET_ENABLE: return sep0611_overlay_enable(); case OVERLAY_COMMON_ENABLE: sep0611_common_enable(); return 0; case OVERLAY_COMMON_DISABLE: sep0611_common_disable(); return 0; case OVERLAY_SWITCHTO_VIDEO: sep0611_switchto_mode(0); break; case OVERLAY_SWITCHTO_HDMI: sep0611_switchto_mode(1); break; case OVERLAY_SWITCHTO_LCD: sep0611_switchto_mode(2); break; default: dprintk(" Unsupported IOCTL(%d)!!!\n", cmd); break; } return 0; }
static void miSubtractSpans (SpanGroup *spanGroup, Spans *sub) { int i, subCount, spansCount; int ymin, ymax, xmin, xmax; Spans *spans; DDXPointPtr subPt, spansPt; int *subWid, *spansWid; int extra; ymin = YMIN(sub); ymax = YMAX(sub); spans = spanGroup->group; for (i = spanGroup->count; i; i--, spans++) { if (YMIN(spans) <= ymax && ymin <= YMAX(spans)) { subCount = sub->count; subPt = sub->points; subWid = sub->widths; spansCount = spans->count; spansPt = spans->points; spansWid = spans->widths; extra = 0; for (;;) { while (spansCount && spansPt->y < subPt->y) { spansPt++; spansWid++; spansCount--; } if (!spansCount) break; while (subCount && subPt->y < spansPt->y) { subPt++; subWid++; subCount--; } if (!subCount) break; if (subPt->y == spansPt->y) { xmin = subPt->x; xmax = xmin + *subWid; if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax) { ; } else if (xmin <= spansPt->x) { if (xmax >= spansPt->x + *spansWid) { memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1)); memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1)); spansPt--; spansWid--; spans->count--; extra++; } else { *spansWid = *spansWid - (xmax - spansPt->x); spansPt->x = xmax; } } else { if (xmax >= spansPt->x + *spansWid) { *spansWid = xmin - spansPt->x; } else { if (!extra) { DDXPointPtr newPt; int *newwid; #define EXTRA 8 newPt = (DDXPointPtr) realloc(spans->points, (spans->count + EXTRA) * sizeof (DDXPointRec)); if (!newPt) break; spansPt = newPt + (spansPt - spans->points); spans->points = newPt; newwid = (int *) realloc(spans->widths, (spans->count + EXTRA) * sizeof (int)); if (!newwid) break; spansWid = newwid + (spansWid - spans->widths); spans->widths = newwid; extra = EXTRA; } memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount)); memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount)); spans->count++; extra--; *spansWid = xmin - spansPt->x; spansWid++; spansPt++; *spansWid = *spansWid - (xmax - spansPt->x); spansPt->x = xmax; } } } spansPt++; spansWid++; spansCount--; } } } }
static int sep0611_overlay_settimming(lcdc_timming timming) { unsigned int data; dprintk("go to %s\n", __func__); //disable LCDC writel(WIN_DISABLE, io + SEP0611_LCDCECR); #if 1 if(timming.width == 9999)//switch PLL source { data = readl(io_pmu + 0x2c); dprintk("pmu_0x2c = 0x%x\n", data); data = readl(io_pmu + 0x34); dprintk("pmu_0x34 = 0x%x\n", data); data = readl(io_pmu + 0x2c); data &= ~(0x3<<4); if(timming.height == 9999) ;//use MPLL else {data |= 0x1<<4; /*data|=0x1;*/} //use APLL writel(data, io_pmu + 0x2c);//to use APLL 800MHz data = readl(io_pmu + 0x34); data &= ~(0x1<<3); data |= 0x1<<3; writel(data , io_pmu + 0x34); for(;;) { data = readl(io_pmu + 0x34); data &= 0x1<<3; dprintk("data = %d\n",data); if(data ==0) break; msleep(100); } dprintk("after write the regs\n"); data = readl(io_pmu + 0x2c); dprintk("pmu_0x2c = 0x%x\n", data); data = readl(io_pmu + 0x34); dprintk("pmu_0x34 = 0x%x\n", data); dprintk("pmu config OK\n"); writel(WIN_ENABLE, io + SEP0611_LCDCECR); return 0; } #endif dprintk("lcd.t=%d, %d, %d, %d, %d, %d, %d, %d, %d\n",timming.width,timming.height,timming.pcd,timming.h_width,timming.h_wait1,timming.h_wait2,timming.v_width,timming.v_wait1,timming.v_wait2); msleep(10); //size data = 0; data |= XMAX(timming.width)|YMAX(timming.height); writel(data, io + SEP0611_LCDCSCR); // PCD data = readl(io + SEP0611_LCDCBCR); data &=~(0x1F); data |=timming.pcd; writel(data, io + SEP0611_LCDCBCR); // H timming data = 0; data = H_WIDTH(timming.h_width) | H_WAIT1(timming.h_wait1) | H_WAIT2(timming.h_wait2); writel(data, io + SEP0611_PLCR); // V timming data = 0; data = V_WIDTH(timming.v_width) | V_WAIT1(timming.v_wait1) | V_WAIT2(timming.v_wait2); writel(data, io + SEP0611_PFCR); msleep(10); //enable LCDC writel(WIN_ENABLE, io + SEP0611_LCDCECR); return 0; }