📄 sm501.c
字号:
{ regWrite32(palette_ram + offset, value); // Advance RGB by 1,1,1. value += 0x010101; } }}// Converts the VESA timing into Voyager timing.void adjustMode(mode_table_t *vesaMode, mode_table_t *mode, display_t display){ long blank_width, sync_start, sync_width; clock_select_t clock; // Calculate the VESA line and screen frequencies. vesaMode->horizontal_frequency = roundDiv(vesaMode->pixel_clock, vesaMode->horizontal_total); vesaMode->vertical_frequency = roundDiv(vesaMode->horizontal_frequency, vesaMode->vertical_total); // Calculate the sync percentages of the VESA mode. blank_width = vesaMode->horizontal_total - vesaMode->horizontal_display_end; sync_start = roundDiv((vesaMode->horizontal_sync_start - vesaMode->horizontal_display_end) * 100, blank_width); sync_width = roundDiv(vesaMode->horizontal_sync_width * 100, blank_width); // Copy VESA mode into Voyager mode. *mode = *vesaMode; // Find the best pixel clock. mode->pixel_clock = findClock(vesaMode->pixel_clock * 2, &clock, display) / 2; // Calculate the horizontal total based on the pixel clock and VESA line // frequency. mode->horizontal_total = roundDiv(mode->pixel_clock, vesaMode->horizontal_frequency); // Calculate the sync start and width based on the VESA percentages. blank_width = mode->horizontal_total - mode->horizontal_display_end; mode->horizontal_sync_start = mode->horizontal_display_end + roundDiv(blank_width * sync_start, 100); mode->horizontal_sync_width = roundDiv(blank_width * sync_width, 100); // Calculate the line and screen frequencies. mode->horizontal_frequency = roundDiv(mode->pixel_clock, mode->horizontal_total); mode->vertical_frequency = roundDiv(mode->horizontal_frequency, mode->vertical_total);}static int sm501_detect(void){ int sm501_device_id = FIELD_GET(regRead32(DEVICE_ID), DEVICE_ID, DEVICE_ID); int result = 0; if (sm501_device_id != 0x0501) { printf("Silicon Motion 501 not detected\n"); result = -1; return result; } else printf("Silicom Motion SM501 detected\n"); return result;}void set_frame_fbinfo(int x, int y, int fb_type, display_t display){ static unsigned int gdfTab[] = { 1, 2, 2, 4, 3, 1 }; u_long fb_address; int a; sm501.winSizeX = x; sm501.winSizeY = y; sm501.gdfBytesPP = gdfTab[fb_type]; sm501.gdfIndex = fb_type; if (display == PANEL) fb_address = FIELD_GET(regRead32(PANEL_FB_ADDRESS), PANEL_FB_ADDRESS, ADDRESS); else fb_address = FIELD_GET(regRead32(CRT_FB_ADDRESS), CRT_FB_ADDRESS, ADDRESS); a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; a = 1; sm501.frameAdrs = fb_address + CONFIG_SM501_MEM_BASE; sm501.frameAdrs &= 0xfffffff0; printf("sm501 frame address start = 0x%x\n", sm501.frameAdrs);}static void sm501_disable_controller(display_t display){ ulong panel_ctrl; if (display == PANEL) { panel_ctrl = regRead32(PANEL_DISPLAY_CTRL); panel_ctrl = FIELD_SET(panel_ctrl, PANEL_DISPLAY_CTRL, PLANE, DISABLE); regWrite32(PANEL_DISPLAY_CTRL, panel_ctrl); } if (display == CRT) { panel_ctrl = regRead32(CRT_DISPLAY_CTRL); panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, PLANE, DISABLE); panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, BLANK, ON); regWrite32(CRT_DISPLAY_CTRL, panel_ctrl); }}static void sm501_enable_controller(display_t display){ if (display == PANEL) { u_long panel_ctrl = regRead32(PANEL_DISPLAY_CTRL); printf("Enabling LCD controller\n"); panel_ctrl = FIELD_SET(panel_ctrl, PANEL_DISPLAY_CTRL, PLANE, ENABLE); regWrite32(PANEL_DISPLAY_CTRL, panel_ctrl); } if (display == CRT) { u_long panel_ctrl = regRead32(CRT_DISPLAY_CTRL); printf("Enabling CRT controller\n"); panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, PLANE, ENABLE); panel_ctrl = FIELD_SET(panel_ctrl, CRT_DISPLAY_CTRL, BLANK, OFF); regWrite32(CRT_DISPLAY_CTRL, panel_ctrl); }}mode_table_t *findMode(mode_table_t *mode_table, int width, int height, long refresh_rate){ // Walk the entire mode table. while (mode_table->pixel_clock != 0) { // If this mode matches the requested mode, return it! if ((mode_table->horizontal_display_end == width) && (mode_table->vertical_display_end == height) && (mode_table->vertical_frequency == refresh_rate)) { return(mode_table); } // Next entry in the mode table. mode_table++; } // No mode found. return(NULL);}void SetMode(int nWidth, int nHeight, long nHertz, display_t display, int bpp){ mode_table_t mode; pmode_table_t vesaMode; reg_table_t register_table; // Locate the mode vesaMode = findMode(mode_table, nWidth, nHeight, nHertz); if (vesaMode != NULL) { // Convert VESA timing into Voyager timing adjustMode(vesaMode, &mode, display); // Fill the register structure setModeRegisters(®ister_table, &mode, display, bpp); // Program the registers programMode(®ister_table); }}int sm501mode = 9;int sm501bpp = 16;int sm501out = 1;void *video_hw_init (void){ int i; int detect; int XRES; int YRES; int BPP; int HZ; int DEVICE; //BWSCON=0x220005e0; //BANKCON1=((0<<13)+(3<<11)+(7<<8)+(1<<6)+(3<<4)+(3<<2)+0); sm501Reg = (char *)CONFIG_SM501_REG_BASE; sm501Mem = (char *)CONFIG_SM501_MEM_BASE; if((detect = sm501_detect()) == -1) return NULL; XRES = mode_table[sm501mode - 1].horizontal_display_end; YRES = mode_table[sm501mode - 1].vertical_display_end; HZ = mode_table[sm501mode - 1].vertical_frequency; BPP = sm501bpp; if(!sm501out) DEVICE = CRT; else DEVICE = PANEL; error = 0; for(i = 0;i < 10; i++) { SetMode(XRES, YRES, HZ, DEVICE, BPP); if(!error) break; else error = 0; } set_frame_fbinfo(XRES, YRES, FBTYPE_16BIT_565RGB, PANEL); sm501_enable_controller(PANEL); sm501info.Bpp = 2; sm501info.bitsPerPixel = 16; sm501info.width = XRES; sm501info.height = YRES; sm501info.rotate = 0; SMI_GEReset(); return &sm501;}void video_set_lut ( unsigned int index,unsigned char r, unsigned char g, unsigned char b){ regWrite32(index * 4 + CRT_PALETTE_RAM, RGB(r, g , b ));}void regWrite32DPR(unsigned long nOffset, unsigned long nData){ regWrite32(nOffset + 0x100000, nData);}void regWrite32SRC(unsigned long nOffset, unsigned long nData){ regWrite32(nOffset, nData);}unsigned long regRead32SRC(unsigned long nOffset){ return regRead32(nOffset);}static void SMI_DisableClipping(void){ sm501info.ScissorsLeft = 0; if (sm501info.bitsPerPixel == 24) sm501info.ScissorsRight = (sm501info.height << 16) | (sm501info.width * 3); else sm501info.ScissorsRight = (sm501info.height << 16) | sm501info.width; sm501info.ClipTurnedOn = FALSE; WaitQueue(); regWrite32DPR(0x2C, sm501info.ScissorsLeft); regWrite32DPR(0x30, sm501info.ScissorsRight);}static void SMI_EngineReset(void){ unsigned long DEDataFormat = 0; int i; int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 }; sm501info.Stride = (sm501info.width * sm501info.Bpp + 15) & ~15; switch (sm501info.bitsPerPixel) { case 8: DEDataFormat = 0x00000000; break; case 16: sm501info.Stride >>= 1; DEDataFormat = 0x00100000; break; case 24: DEDataFormat = 0x00300000; break; case 32: sm501info.Stride >>= 2; DEDataFormat = 0x00200000; break; } for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++) { if (sm501info.rotate) { if (xyAddress[i] == sm501info.height) { DEDataFormat |= i << 16; break; } } else { if (xyAddress[i] == sm501info.width) { DEDataFormat |= i << 16; break; } } } WaitIdleEmpty(); regWrite32DPR(0x10, (sm501info.Stride << 16) | sm501info.Stride); regWrite32DPR(0x1C, DEDataFormat); regWrite32DPR(0x24, 0xFFFFFFFF); regWrite32DPR(0x28, 0xFFFFFFFF); regWrite32DPR(0x3C, (sm501info.Stride << 16) | sm501info.Stride); regWrite32DPR(0x40, 0); regWrite32DPR(0x44, 0); SMI_DisableClipping();}void SMI_GEReset(void){ unsigned int iTempVal; WaitIdleEmpty(); iTempVal = regRead32SRC(0) & ~0x00003000; iTempVal = iTempVal & ~0x10000000; regWrite32SRC(0, (iTempVal | 0x00003000)); regWrite32SRC(0, iTempVal); WaitIdleEmpty(); SMI_EngineReset();}/******************************************************************************//* Screen to Screen Copies *//******************************************************************************/static void SMI_SetupForScreenToScreenCopy(int xdir, int ydir, int rop, int trans){ sm501info.AccelCmd = XAACopyROP[rop] | SMI_BITBLT | SMI_START_ENGINE; if ((xdir == -1) || (ydir == -1)) { sm501info.AccelCmd |= SMI_RIGHT_TO_LEFT; } if (trans != -1) { sm501info.AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL; WaitQueue(); regWrite32DPR(0x20, trans); } if (sm501info.ClipTurnedOn) { WaitQueue(); regWrite32DPR(0x2C, sm501info.ScissorsLeft); sm501info.ClipTurnedOn = FALSE; }}static void SMI_SubsequentScreenToScreenCopy(int x1, int y1, int x2, int y2, int w, int h){ if (sm501info.AccelCmd & SMI_RIGHT_TO_LEFT) { x1 += w - 1; y1 += h - 1; x2 += w - 1; y2 += h - 1; } if (sm501info.bitsPerPixel == 24) { x1 *= 3; x2 *= 3; w *= 3; if (sm501info.AccelCmd & SMI_RIGHT_TO_LEFT) { x1 += 2; x2 += 2; } } WaitQueue(); regWrite32DPR(0x00, (x1 << 16) + (y1 & 0xFFFF)); regWrite32DPR(0x04, (x2 << 16) + (y2 & 0xFFFF)); regWrite32DPR(0x08, (w << 16) + (h & 0xFFFF)); regWrite32DPR(0x0C, sm501info.AccelCmd);}void SMI_BlitRect(int srcx, int srcy, int dstx, int dsty, int w, int h){ //if (sm501info.AccelInfoRec) { int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; int ydir = (srcy < dsty) ? -1 : 1; SMI_SetupForScreenToScreenCopy(xdir, ydir, 3, -1); SMI_SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, w, h); }}/******************************************************************************//* Solid Fills *//******************************************************************************/static void SMI_SetupForSolidFill(int color, int rop){ sm501info.AccelCmd = XAAPatternROP[rop] | SMI_BITBLT | SMI_START_ENGINE; WaitQueue(); if (sm501info.ClipTurnedOn) { regWrite32DPR(0x2C, sm501info.ScissorsLeft); sm501info.ClipTurnedOn = FALSE; } regWrite32DPR(0x14, color); regWrite32DPR(0x34, 0xFFFFFFFF); regWrite32DPR(0x38, 0xFFFFFFFF);}static void SMI_SubsequentSolidFillRect(int x, int y, int w, int h){ if (sm501info.bitsPerPixel == 24) { x *= 3; w *= 3; } /* Clip to prevent negative screen coordinates */ if (x < 0) x = 0; if (y < 0) y = 0; WaitQueue(); regWrite32DPR(0x04, (x << 16) | (y & 0xFFFF)); regWrite32DPR(0x08, (w << 16) | (h & 0xFFFF)); regWrite32DPR(0x0C, sm501info.AccelCmd);}void SMI_FillRect(int x, int y, int w, int h, unsigned long color){ //if (sm501info.AccelInfoRec) { SMI_SetupForSolidFill(color, 3); //3=GXcopy SMI_SubsequentSolidFillRect(x, y, w, h); }}void video_hw_bitblt(int pixelsize, int x, int y, int x1, int y1, int w, int h){ SMI_BlitRect(x, y, x1, y1, w, h);}void video_hw_rectfill(int pixelsize, int x, int y, int w, int h, unsigned long color){ SMI_FillRect(x, y, w, h, color);}#endif /* endif CONFIG_VIDEO_SM501 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -