void * video_hw_init(void) { //register GraphicDevice *pGD = (GraphicDevice *)&smi; struct panel_config pcfg; /* int hsw=0, hfp=0, hbp=0; int vsw=0, vfp=0, vbp=0; int lclk = 1, pclk=2, pol_flags = 0; int acbi = 0, acb = 0;*/ int bpp = 0; struct ctfb_res_modes *res_mode; struct ctfb_res_modes var_mode; char * penv; pre_setup_video_env(); if (NULL == (penv = getenv("ub_vid"))) return NULL; res_mode = (struct ctfb_res_modes *) &var_mode; bpp = video_get_params (res_mode, penv); smi.winSizeX = res_mode->xres; smi.winSizeY = res_mode->yres; smi.plnSizeX = res_mode->xres; smi.plnSizeY = res_mode->yres; smi.gdfBytesPP = bpp; if (2 == bpp) smi.gdfIndex = GDF_16BIT_565RGB; else if (1 == bpp) smi.gdfIndex = GDF__8BIT_332RGB; pcfg.panel_type = res_mode->vmode&1; pcfg.timing_h = TIMING(res_mode->hsync_len, res_mode->left_margin, res_mode->right_margin); //hsw, hfp, hbp); pcfg.timing_v = TIMING(res_mode->vsync_len, res_mode->upper_margin, res_mode->lower_margin); //vsw, vfp, vbp); pcfg.data_lines = 3; pcfg.lcd_size = SIZE(smi.winSizeX, smi.winSizeY); pcfg.load_mode = 0; //0x00000204 >> FRAME_MODE_SHIFT; smi.frameAdrs = LCD_VIDEO_ADDR; smi.memSize = smi.winSizeX * smi.winSizeY * smi.gdfBytesPP; pcfg.panel_color= 0; pcfg.divisor = DIV(res_mode->pixclock >> 8, res_mode->pixclock & 0xff); //lclk, pclk); pcfg.pol_freq = omapdss_set_pol_freq(res_mode->vmode >>1, res_mode->sync >> 8, res_mode->sync & 0xff); //pol_flags, acbi, acb); // 0, 0); //0x30000; //printf("Done w/ lcd init\n"); /*if (!panel_cfg->panel_type) pcfg.gfx_attrib = GFX_BURST(2) | GFX_FMT(RGB_16) //GFX_FMT(BMP_8) | GFX_EN; else*/ pcfg.gfx_attrib = GFX_BURST(2) | GFX_FMT(RGB_16) | GFX_EN; vidmem_clear(smi.frameAdrs, smi.winSizeX, smi.winSizeY, smi.gdfBytesPP); omap3_dss_panel_config(&pcfg); omap3_dss_enable(); return ((void*)&smi); }
static void dsp_init(struct mb86r0x_gdc_dsp *dsp, char *modestr, u32 *videomem) { struct ctfb_res_modes var_mode; u32 dcm1, dcm2, dcm3; u16 htp, hdp, hdb, hsp, vtr, vsp, vdp; u8 hsw, vsw; u32 l2m, l2em, l2oa0, l2da0, l2oa1, l2da1; u16 l2dx, l2dy, l2wx, l2wy, l2ww, l2wh; unsigned long div; int bpp; u32 i; bpp = video_get_params(&var_mode, modestr); if (bpp == 0) { var_mode.xres = 640; var_mode.yres = 480; var_mode.pixclock = 39721; /* 25MHz */ var_mode.left_margin = 48; var_mode.right_margin = 16; var_mode.upper_margin = 33; var_mode.lower_margin = 10; var_mode.hsync_len = 96; var_mode.vsync_len = 2; var_mode.sync = 0; var_mode.vmode = 0; bpp = 15; } /* Fill memory with white */ memset(videomem, 0xFF, var_mode.xres * var_mode.yres * 2); mb86r0x.winSizeX = var_mode.xres; mb86r0x.winSizeY = var_mode.yres; /* LCD base clock is ~ 660MHZ. We do calculations in kHz */ div = 660000 / (1000000000L / var_mode.pixclock); if (div > 64) div = 64; if (0 == div) div = 1; dcm1 = (div - 1) << 8; dcm2 = 0x00000000; if (var_mode.sync & FB_SYNC_CLK_INV) dcm3 = 0x00000100; else dcm3 = 0x00000000; htp = var_mode.left_margin + var_mode.xres + var_mode.hsync_len + var_mode.right_margin; hdp = var_mode.xres; hdb = var_mode.xres; hsp = var_mode.xres + var_mode.right_margin; hsw = var_mode.hsync_len; vsw = var_mode.vsync_len; vtr = var_mode.upper_margin + var_mode.yres + var_mode.vsync_len + var_mode.lower_margin; vsp = var_mode.yres + var_mode.lower_margin; vdp = var_mode.yres; l2m = ((var_mode.yres - 1) << (0)) | (((var_mode.xres * 2) / 64) << (16)) | ((1) << (31)); l2em = (1 << 0) | (1 << 1); l2oa0 = mb86r0x.frameAdrs; l2da0 = mb86r0x.frameAdrs; l2oa1 = mb86r0x.frameAdrs; l2da1 = mb86r0x.frameAdrs; l2dx = 0; l2dy = 0; l2wx = 0; l2wy = 0; l2ww = var_mode.xres; l2wh = var_mode.yres - 1; writel(dcm1, &dsp->dcm1); writel(dcm2, &dsp->dcm2); writel(dcm3, &dsp->dcm3); writew(htp, &dsp->htp); writew(hdp, &dsp->hdp); writew(hdb, &dsp->hdb); writew(hsp, &dsp->hsp); writeb(hsw, &dsp->hsw); writeb(vsw, &dsp->vsw); writew(vtr, &dsp->vtr); writew(vsp, &dsp->vsp); writew(vdp, &dsp->vdp); writel(l2m, &dsp->l2m); writel(l2em, &dsp->l2em); writel(l2oa0, &dsp->l2oa0); writel(l2da0, &dsp->l2da0); writel(l2oa1, &dsp->l2oa1); writel(l2da1, &dsp->l2da1); writew(l2dx, &dsp->l2dx); writew(l2dy, &dsp->l2dy); writew(l2wx, &dsp->l2wx); writew(l2wy, &dsp->l2wy); writew(l2ww, &dsp->l2ww); writew(l2wh, &dsp->l2wh); writel(dcm1 | (1 << 18) | (1 << 31), &dsp->dcm1); }
unsigned int card_init (void) { GraphicDevice *pGD = (GraphicDevice *)&mb862xx; unsigned int cf, videomode, div = 0; unsigned long t1, hsync, vsync; char *penv; int tmp, i, bpp; struct ctfb_res_modes *res_mode; struct ctfb_res_modes var_mode; memset (pGD, 0, sizeof (GraphicDevice)); if (!pci_video_init ()) { return 0; } printf ("CoralP\n"); tmp = 0; videomode = 0x310; /* get video mode via environment */ if ((penv = getenv ("videomode")) != NULL) { /* deceide if it is a string */ if (penv[0] <= '9') { videomode = (int) simple_strtoul (penv, NULL, 16); tmp = 1; } } else { tmp = 1; } if (tmp) { /* parameter are vesa modes */ /* search params */ for (i = 0; i < VESA_MODES_COUNT; i++) { if (vesa_modes[i].vesanr == videomode) break; } if (i == VESA_MODES_COUNT) { printf ("\tno VESA Mode found, switching to mode 0x%x \n", videomode); i = 0; } res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex]; if (vesa_modes[i].resindex > 2) { printf ("\tUnsupported resolution, switching to default\n"); bpp = vesa_modes[1].bits_per_pixel; div = fr_div[1]; } bpp = vesa_modes[i].bits_per_pixel; div = fr_div[vesa_modes[i].resindex]; } else { res_mode = (struct ctfb_res_modes *) &var_mode; bpp = video_get_params (res_mode, penv); } /* calculate hsync and vsync freq (info only) */ t1 = (res_mode->left_margin + res_mode->xres + res_mode->right_margin + res_mode->hsync_len) / 8; t1 *= 8; t1 *= res_mode->pixclock; t1 /= 1000; hsync = 1000000000L / t1; t1 *= (res_mode->upper_margin + res_mode->yres + res_mode->lower_margin + res_mode->vsync_len); t1 /= 1000; vsync = 1000000000L / t1; /* fill in Graphic device struct */ sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres, res_mode->yres, bpp, (hsync / 1000), (vsync / 1000)); printf ("\t%s\n", pGD->modeIdent); pGD->winSizeX = res_mode->xres; pGD->winSizeY = res_mode->yres; pGD->memSize = VIDEO_MEM_SIZE; switch (bpp) { case 8: pGD->gdfIndex = GDF__8BIT_INDEX; pGD->gdfBytesPP = 1; break; case 15: case 16: pGD->gdfIndex = GDF_15BIT_555RGB; pGD->gdfBytesPP = 2; break; default: printf ("\t%d bpp configured, but only 8,15 and 16 supported.\n", bpp); printf ("\tSwitching back to 15bpp\n"); pGD->gdfIndex = GDF_15BIT_555RGB; pGD->gdfBytesPP = 2; } /* Setup dot clock (internal pll, division rate) */ DISP_WR_REG (0x0100, div); /* L0 init */ cf = (pGD->gdfBytesPP == 1) ? 0x00000000 : 0x80000000; DISP_WR_REG (0x0020, ((pGD->winSizeX * pGD->gdfBytesPP)/64)<<16 | (pGD->winSizeY-1) | cf); DISP_WR_REG (0x0024, 0x00000000); DISP_WR_REG (0x0028, 0x00000000); DISP_WR_REG (0x002c, 0x00000000); DISP_WR_REG (0x0110, 0x00000000); DISP_WR_REG (0x0114, 0x00000000); DISP_WR_REG (0x0118, (pGD->winSizeY-1)<<16 | pGD->winSizeX); /* Display timing init */ DISP_WR_REG (0x0004, (pGD->winSizeX+res_mode->left_margin+res_mode->right_margin+res_mode->hsync_len-1)<<16); DISP_WR_REG (0x0008, (pGD->winSizeX-1) << 16 | (pGD->winSizeX-1)); DISP_WR_REG (0x000c, (res_mode->vsync_len-1)<<24|(res_mode->hsync_len-1)<<16|(pGD->winSizeX+res_mode->right_margin-1)); DISP_WR_REG (0x0010, (pGD->winSizeY+res_mode->lower_margin+res_mode->upper_margin+res_mode->vsync_len-1)<<16); DISP_WR_REG (0x0014, (pGD->winSizeY-1) << 16 | (pGD->winSizeY+res_mode->lower_margin-1)); DISP_WR_REG (0x0018, 0x00000000); DISP_WR_REG (0x001c, pGD->winSizeY << 16 | pGD->winSizeX); /* Display enable, L0 layer */ DISP_WR_REG (0x0100, 0x80010000 | div); return pGD->frameAdrs; }
/******************************************************************************* * * Init video chip with common Linux graphic modes (lilo) */ void *video_hw_init (void) { S5PC11X_FB * const fb = S5PC11X_GetBase_FB(); GraphicDevice *pGD = (GraphicDevice *)&smi; int videomode; unsigned long t1, hsynch, vsynch; char *penv; int tmp, i, bits_per_pixel; struct ctfb_res_modes *res_mode; struct ctfb_res_modes var_mode; int clkval; /* Search for video chip */ printf("Video: "); tmp = 0; videomode = CFG_SYS_DEFAULT_VIDEO_MODE; /* get video mode via environment */ if ((penv = getenv ("videomode")) != NULL) { /* deceide if it is a string */ if (penv[0] <= '9') { videomode = (int) simple_strtoul (penv, NULL, 16); tmp = 1; } } else { tmp = 1; } if (tmp) { /* parameter are vesa modes */ /* search params */ for (i = 0; i < VESA_MODES_COUNT; i++) { if (vesa_modes[i].vesanr == videomode) break; } if (i == VESA_MODES_COUNT) { printf ("no VESA Mode found, switching to mode 0x%x ", CFG_SYS_DEFAULT_VIDEO_MODE); i = 0; } res_mode = (struct ctfb_res_modes *)&res_mode_init[vesa_modes[i].resindex]; bits_per_pixel = vesa_modes[i].bits_per_pixel; } else { res_mode = (struct ctfb_res_modes *) &var_mode; bits_per_pixel = video_get_params (res_mode, penv); } /* calculate hsynch and vsynch freq (info only) */ t1 = (res_mode->left_margin + res_mode->xres + res_mode->right_margin + res_mode->hsync_len) / 8; t1 *= 8; t1 *= res_mode->pixclock; t1 /= 1000; hsynch = 1000000000L / t1; t1 *= (res_mode->upper_margin + res_mode->yres + res_mode->lower_margin + res_mode->vsync_len); t1 /= 1000; vsynch = 1000000000L / t1; /* fill in Graphic device struct */ sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres, res_mode->yres, bits_per_pixel, (hsynch / 1000), (vsynch / 1000)); printf ("%s\n", pGD->modeIdent); pGD->winSizeX = res_mode->xres; pGD->winSizeY = res_mode->yres; pGD->plnSizeX = res_mode->xres; pGD->plnSizeY = res_mode->yres; switch (bits_per_pixel) { case 8: pGD->gdfBytesPP = 1; pGD->gdfIndex = GDF__8BIT_INDEX; break; case 15: pGD->gdfBytesPP = 2; pGD->gdfIndex = GDF_15BIT_555RGB; break; case 16: pGD->gdfBytesPP = 2; pGD->gdfIndex = GDF_16BIT_565RGB; break; case 24: pGD->gdfBytesPP = 3; pGD->gdfIndex = GDF_24BIT_888RGB; break; case 32: pGD->gdfBytesPP = 4; pGD->gdfIndex = GDF_32BIT_X888RGB; break; } #if 0 /* statically configure settings */ pGD->winSizeX = pGD->plnSizeX = 240; pGD->winSizeY = pGD->plnSizeY = 320; pGD->gdfBytesPP = 2; pGD->gdfIndex = GDF_16BIT_565RGB; #endif pGD->frameAdrs = LCD_VIDEO_ADDR; pGD->memSize = VIDEO_MEM_SIZE; /* Clear video memory */ memset((void *)pGD->frameAdrs, 0x00, pGD->memSize); board_video_init(pGD); t1 = res_mode->pixclock; t1 /= 1000; t1 = 1000000000L / t1; clkval = (CONFIG_SYS_VIDEO_VCLOCK_HZ / t1) - 1; /* 配置视频输出格式和显示使能/禁止。*/ fb->VIDCON0 = ( S3C_VIDCON0_VIDOUT_RGB | S3C_VIDCON0_PNRMODE_RGB_P | S3C_VIDCON0_CLKVALUP_ALWAYS | S3C_VIDCON0_CLKVAL_F(clkval)| S3C_VIDCON0_VCLKEN_NORMAL | S3C_VIDCON0_CLKDIR_DIVIDED| S3C_VIDCON0_CLKSEL_HCLK ); /* RGB I/F控制信号。*/ fb->VIDCON1 = ( S3C_VIDCON1_IVSYNC_INVERT | S3C_VIDCON1_IHSYNC_INVERT); /* 配置视频输出时序和显示尺寸。*/ fb->VIDTCON0 = ( S3C_VIDTCON0_VBPD(res_mode->upper_margin) | S3C_VIDTCON0_VFPD(res_mode->lower_margin) | S3C_VIDTCON0_VSPW(res_mode->vsync_len)); fb->VIDTCON1 = ( S3C_VIDTCON1_HBPD(res_mode->left_margin) | S3C_VIDTCON1_HFPD(res_mode->right_margin) | S3C_VIDTCON1_HSPW(res_mode->hsync_len)); fb->VIDTCON2 = ( S3C_VIDTCON2_LINEVAL(pGD->winSizeY - 1) | S3C_VIDTCON2_HOZVAL(pGD->winSizeX - 1)); #if defined(LCD_VIDEO_BACKGROUND) fb->WINCON0 = (S3C_WINCON_BPPMODE_16BPP_565 | S3C_WINCON_ENWIN_ENABLE | S3C_WINCON_HAWSWP_ENABLE); fb->VIDOSD0A = ( S3C_VIDOSD_LEFT_X(0) | S3C_VIDOSD_TOP_Y(0)); fb->VIDOSD0B = ( S3C_VIDOSD_RIGHT_X(pGD->winSizeX - 1) | S3C_VIDOSD_BOTTOM_Y(pGD->winSizeY - 1)); /* 指定视频窗口0的大小控制寄存器。*/ fb->VIDOSD0C = S3C_VIDOSD_SIZE(pGD->winSizeY * pGD->winSizeX); #endif /* 窗口格式设置 */ fb->WINCON1 = (S3C_WINCON_BPPMODE_16BPP_565 | S3C_WINCON_ENWIN_ENABLE | S3C_WINCON_HAWSWP_ENABLE); /* 指定OSD图像的左上角像素的横向屏幕坐标。*/ fb->VIDOSD1A = ( S3C_VIDOSD_LEFT_X(0) | S3C_VIDOSD_TOP_Y(0)); /* 指定横屏右下角的OSD图像的像素坐标。*/ fb->VIDOSD1B = ( S3C_VIDOSD_RIGHT_X(pGD->winSizeX - 1) | S3C_VIDOSD_BOTTOM_Y(pGD->winSizeY - 1)); #if defined(LCD_VIDEO_BACKGROUND) fb->VIDOSD1C = ( S3C_VIDOSD_ALPHA0_R(LCD_VIDEO_BACKGROUND_ALPHA) | S3C_VIDOSD_ALPHA0_G(LCD_VIDEO_BACKGROUND_ALPHA) | S3C_VIDOSD_ALPHA0_B(LCD_VIDEO_BACKGROUND_ALPHA) ); #endif /* 指定视频窗口1的大小控制寄存器。*/ fb->VIDOSD1D = S3C_VIDOSD_SIZE(pGD->winSizeY * pGD->winSizeX); fb->SHADOWCON = S3C_WINSHMAP_CH_ENABLE(1); //Enables Channel 1 #if defined(LCD_VIDEO_BACKGROUND) /* config Display framebuffer addr for background*/ /* 指定窗口0的缓冲区起始地址寄存器,缓冲器0。*/ fb->VIDW00ADD0B0 = LCD_VIDEO_BACKGROUND_ADDR; /* This marks the end of the frame buffer. */ /* 指定窗口0的缓冲区,缓冲区结束地址寄存器0。*/ fb->VIDW00ADD1B0 = (S3C_VIDW00ADD0B0 &0xffffffff) + (pGD->winSizeX+0) * pGD->winSizeY * (pGD->gdfBytesPP); /* 指定窗口0的缓冲区大小寄存器。*/ fb->VIDW00ADD2= ((pGD->winSizeX * pGD->gdfBytesPP) & 0x1fff); #endif /* config Display framebuffer addr for console*/ fb->VIDW01ADD0B0 = pGD->frameAdrs; /* This marks the end of the frame buffer. */ fb->VIDW01ADD1B0 = (S3C_VIDW01ADD0B0 &0xffffffff) + (pGD->winSizeX+0) * pGD->winSizeY * (pGD->gdfBytesPP); fb->VIDW01ADD2= ((pGD->winSizeX * pGD->gdfBytesPP) & 0x1fff); /* Enable Display */ fb->VIDCON0 |= (S3C_VIDCON0_ENVID_ENABLE | S3C_VIDCON0_ENVID_F_ENABLE); /* ENVID = 1 ENVID_F = 1*/ fb->TRIGCON = 3;//(TRGMODE_I80 | SWTRGCMD_I80);TRIGCON = 3 /* Enable Display */ //VIDCON0 |= (VIDCON0_ENVID_ENABLE | VIDCON0_ENVID_F_ENABLE); /* ENVID = 1 ENVID_F = 1*/ //TRIGCON = (TRGMODE_I80 | SWTRGCMD_I80); //TRIGCON = 3 printf("Video: video_hw_init complete \n"); return ((void*)&smi); }
void *video_hw_init(void) { static GraphicDevice *graphic_device = &sunxi_display.graphic_device; const struct ctfb_res_modes *mode; struct ctfb_res_modes custom; const char *options; #ifdef CONFIG_VIDEO_HDMI int ret, hpd, hpd_delay, edid; #endif int i, overscan_offset, overscan_x, overscan_y; unsigned int fb_dma_addr; char mon[16]; char *lcd_mode = CONFIG_VIDEO_LCD_MODE; memset(&sunxi_display, 0, sizeof(struct sunxi_display)); video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, &sunxi_display.depth, &options); #ifdef CONFIG_VIDEO_HDMI hpd = video_get_option_int(options, "hpd", 1); hpd_delay = video_get_option_int(options, "hpd_delay", 500); edid = video_get_option_int(options, "edid", 1); #endif overscan_x = video_get_option_int(options, "overscan_x", -1); overscan_y = video_get_option_int(options, "overscan_y", -1); sunxi_display.monitor = sunxi_get_default_mon(true); video_get_option_string(options, "monitor", mon, sizeof(mon), sunxi_get_mon_desc(sunxi_display.monitor)); for (i = 0; i <= SUNXI_MONITOR_LAST; i++) { if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) { sunxi_display.monitor = i; break; } } if (i > SUNXI_MONITOR_LAST) printf("Unknown monitor: '%s', falling back to '%s'\n", mon, sunxi_get_mon_desc(sunxi_display.monitor)); #ifdef CONFIG_VIDEO_HDMI /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */ if (sunxi_display.monitor == sunxi_monitor_dvi || sunxi_display.monitor == sunxi_monitor_hdmi) { /* Always call hdp_detect, as it also enables clocks, etc. */ ret = sunxi_hdmi_hpd_detect(hpd_delay); if (ret) { printf("HDMI connected: "); if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0) mode = &custom; } else if (hpd) { sunxi_hdmi_shutdown(); sunxi_display.monitor = sunxi_get_default_mon(false); } /* else continue with hdmi/dvi without a cable connected */ } #endif switch (sunxi_display.monitor) { case sunxi_monitor_none: return NULL; case sunxi_monitor_dvi: case sunxi_monitor_hdmi: if (!sunxi_has_hdmi()) { printf("HDMI/DVI not supported on this board\n"); sunxi_display.monitor = sunxi_monitor_none; return NULL; } break; case sunxi_monitor_lcd: if (!sunxi_has_lcd()) { printf("LCD not supported on this board\n"); sunxi_display.monitor = sunxi_monitor_none; return NULL; } sunxi_display.depth = video_get_params(&custom, lcd_mode); mode = &custom; break; case sunxi_monitor_vga: if (!sunxi_has_vga()) { printf("VGA not supported on this board\n"); sunxi_display.monitor = sunxi_monitor_none; return NULL; } sunxi_display.depth = 18; break; case sunxi_monitor_composite_pal: case sunxi_monitor_composite_ntsc: case sunxi_monitor_composite_pal_m: case sunxi_monitor_composite_pal_nc: if (!sunxi_has_composite()) { printf("Composite video not supported on this board\n"); sunxi_display.monitor = sunxi_monitor_none; return NULL; } if (sunxi_display.monitor == sunxi_monitor_composite_pal || sunxi_display.monitor == sunxi_monitor_composite_pal_nc) mode = &composite_video_modes[0]; else mode = &composite_video_modes[1]; sunxi_display.depth = 24; break; } /* Yes these defaults are quite high, overscan on composite sucks... */ if (overscan_x == -1) overscan_x = sunxi_is_composite() ? 32 : 0; if (overscan_y == -1) overscan_y = sunxi_is_composite() ? 20 : 0; sunxi_display.fb_size = (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff; overscan_offset = (overscan_y * mode->xres + overscan_x) * 4; /* We want to keep the fb_base for simplefb page aligned, where as * the sunxi dma engines will happily accept an unaligned address. */ if (overscan_offset) sunxi_display.fb_size += 0x1000; if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) { printf("Error need %dkB for fb, but only %dkB is reserved\n", sunxi_display.fb_size >> 10, CONFIG_SUNXI_MAX_FB_SIZE >> 10); return NULL; }
/******************************************************************************* * * Init video chip with common Linux graphic modes (lilo) */ void *video_hw_init (void) { struct s3c24x0_lcd * const lcd = s3c24x0_get_base_lcd(); GraphicDevice *pGD = (GraphicDevice *)&smi; int videomode; unsigned long t1, hsynch, vsynch; char *penv; int tmp, i, bits_per_pixel; struct ctfb_res_modes *res_mode; struct ctfb_res_modes var_mode; // unsigned char videoout; /* Search for video chip */ // printf("Video: "); //by mickeyos tmp = 0; videomode = CFG_SYS_DEFAULT_VIDEO_MODE; /* get video mode via environment */ if ((penv = getenv ("videomode")) != NULL) { /* deceide if it is a string */ if (penv[0] <= '9') { videomode = (int) simple_strtoul (penv, NULL, 16); tmp = 1; } } else { tmp = 1; } if (tmp) { /* parameter are vesa modes */ /* search params */ for (i = 0; i < VESA_MODES_COUNT; i++) { if (vesa_modes[i].vesanr == videomode) break; } if (i == VESA_MODES_COUNT) { printf ("no VESA Mode found, switching to mode 0x%x ", CFG_SYS_DEFAULT_VIDEO_MODE); i = 0; } res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i]. resindex]; bits_per_pixel = vesa_modes[i].bits_per_pixel; } else { res_mode = (struct ctfb_res_modes *) &var_mode; bits_per_pixel = video_get_params (res_mode, penv); } /* calculate hsynch and vsynch freq (info only) */ t1 = (res_mode->left_margin + res_mode->xres + res_mode->right_margin + res_mode->hsync_len) / 8; t1 *= 8; t1 *= res_mode->pixclock; t1 /= 1000; hsynch = 1000000000L / t1; t1 *= (res_mode->upper_margin + res_mode->yres + res_mode->lower_margin + res_mode->vsync_len); t1 /= 1000; vsynch = 1000000000L / t1; /* fill in Graphic device struct */ sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres, res_mode->yres, bits_per_pixel, (hsynch / 1000), (vsynch / 1000)); // printf ("%s\n", pGD->modeIdent); //by mickeyos pGD->winSizeX = res_mode->xres; pGD->winSizeY = res_mode->yres; pGD->plnSizeX = res_mode->xres; pGD->plnSizeY = res_mode->yres; switch (bits_per_pixel) { case 8: pGD->gdfBytesPP = 1; pGD->gdfIndex = GDF__8BIT_INDEX; break; case 15: pGD->gdfBytesPP = 2; pGD->gdfIndex = GDF_15BIT_555RGB; break; case 16: pGD->gdfBytesPP = 2; pGD->gdfIndex = GDF_16BIT_565RGB; break; case 24: pGD->gdfBytesPP = 3; pGD->gdfIndex = GDF_24BIT_888RGB; break; } /* statically configure settings */ pGD->winSizeX = pGD->plnSizeX = 320; pGD->winSizeY = pGD->plnSizeY = 240; pGD->gdfBytesPP = 2; pGD->gdfIndex = GDF_16BIT_565RGB; pGD->frameAdrs = LCD_VIDEO_ADDR; pGD->memSize = VIDEO_MEM_SIZE; board_video_init(pGD); writel((pGD->frameAdrs >> 1), &lcd->LCDSADDR1); /* This marks the end of the frame buffer. */ writel((((readl(&lcd->LCDSADDR1))&0x1fffff) + (pGD->winSizeX+0) * pGD->winSizeY), &lcd->LCDSADDR2); writel((pGD->winSizeX & 0x7ff), &lcd->LCDSADDR3); /* Clear video memory */ memset((void *)pGD->frameAdrs, 0, pGD->memSize); /* Enable Display */ writel((readl(&lcd->LCDCON1) | 0x01), & lcd->LCDCON1); /* ENVID = 1 */ return ((void*)&smi); }
void *video_hw_init(void) { int bpp = -1; char *penv; void *fb; struct ctfb_res_modes mode; puts("Video: "); /* Suck display configuration from "videomode" variable */ penv = getenv("videomode"); if (!penv) { puts("S3CFB: 'videomode' variable not set!\n"); return NULL; } bpp = video_get_params(&mode, penv); /* fill in Graphic device struct */ sprintf(panel.modeIdent, "%dx%dx%d", mode.xres, mode.yres, bpp); panel.winSizeX = mode.xres; panel.winSizeY = mode.yres; panel.plnSizeX = mode.xres; panel.plnSizeY = mode.yres; switch (bpp) { case 24: panel.gdfBytesPP = 4; panel.gdfIndex = GDF_32BIT_X888RGB; break; case 16: panel.gdfBytesPP = 2; panel.gdfIndex = GDF_16BIT_565RGB; break; default: printf("S3CFB: Invalid BPP specified! (bpp = %i)\n", bpp); return NULL; } panel.memSize = mode.xres * mode.yres * panel.gdfBytesPP; /* Allocate framebuffer */ fb = memalign(S3CFB_ALIGN, roundup(panel.memSize, S3CFB_ALIGN)); if (!fb) { printf("S3CFB: Error allocating framebuffer!\n"); return NULL; } /* Wipe framebuffer */ memset(fb, 0, panel.memSize); panel.frameAdrs = (u32)fb; printf("%s\n", panel.modeIdent); /* Start framebuffer */ s3c_lcd_init(&panel, &mode, bpp); return (void *)&panel; }