📄 s3c2410_sm501.c
字号:
/* Wait for start of vsync */ timeout = 0; do { status = FIELD_GET(regRead32(CMD_INTPR_STATUS), CMD_INTPR_STATUS, PANEL_SYNC); if (++timeout == VSYNCTIMEOUT) break; } while (status == CMD_INTPR_STATUS_PANEL_SYNC_INACTIVE); }}static void panelPowerSequence(panel_state_t on_off, int vsync_delay){ u_long panelControl = regRead32(PANEL_DISPLAY_CTRL); if (on_off == PANEL_ON) { // Turn on FPVDDEN. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, FPVDDEN, HIGH); regWrite32(PANEL_DISPLAY_CTRL, panelControl); panelWaitVSync(vsync_delay); // Turn on FPDATA. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, DATA, ENABLE); regWrite32(PANEL_DISPLAY_CTRL, panelControl); panelWaitVSync(vsync_delay); // Turn on FPVBIAS. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, VBIASEN, HIGH); regWrite32(PANEL_DISPLAY_CTRL, panelControl); panelWaitVSync(vsync_delay); // Turn on FPEN. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, FPEN, HIGH); regWrite32(PANEL_DISPLAY_CTRL, panelControl); } else { // Turn off FPEN. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, FPEN, LOW); regWrite32(PANEL_DISPLAY_CTRL, panelControl); panelWaitVSync(vsync_delay); // Turn off FPVBIASEN. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, VBIASEN, LOW); regWrite32(PANEL_DISPLAY_CTRL, panelControl); panelWaitVSync(vsync_delay); // Turn off FPDATA. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, DATA, DISABLE); regWrite32(PANEL_DISPLAY_CTRL, panelControl); panelWaitVSync(vsync_delay); // Turn off FPVDDEN. panelControl = FIELD_SET(panelControl, PANEL_DISPLAY_CTRL, FPVDDEN, LOW); regWrite32(PANEL_DISPLAY_CTRL, panelControl); }}// Program the mode with the registers specified.void programMode(reg_table_t *register_table){ unsigned long value, gate, clock; unsigned long palette_ram; unsigned long fb_size, offset; //printk(" programMode\n"); // Get current power configuration. gate = regRead32(CURRENT_POWER_GATE); clock = regRead32(CURRENT_POWER_CLOCK); // Program panel. if (register_table->display == PANEL) { //printk(" programMode PANEL\n"); // Program clock, enable display controller. gate = FIELD_SET(gate, CURRENT_POWER_GATE, DISPLAY, ENABLE); clock &= FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SELECT) & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIVIDER) & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SHIFT); setPower(gate, clock | register_table->clock); udelay(125); //hqj_06_08_23 //printk("ProgramMode PANEL::CURRENT_POWER_CLOCK=%x\n",regRead32(CURRENT_POWER_CLOCK)); // Calculate frame buffer address. value = 0; fb_size = register_table->fb_width * register_table->height; if (FIELD_GET(regRead32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, PLANE) == CRT_DISPLAY_CTRL_PLANE_ENABLE) { value = FIELD_GET(regRead32(CRT_FB_ADDRESS), CRT_FB_ADDRESS, ADDRESS); if (fb_size < value) { value = 0; } else { value += FIELD_GET(regRead32(CRT_FB_WIDTH), CRT_FB_WIDTH, OFFSET) * (FIELD_GET(regRead32(CRT_VERTICAL_TOTAL), CRT_VERTICAL_TOTAL, DISPLAY_END) + 1); } } // need add? modify by kavin very important regWrite32(MISC_CTRL, FIELD_SET(0, MISC_CTRL, DAC_POWER, ENABLE) | FIELD_SET(0, MISC_CTRL, CRYSTAL, 12) | FIELD_SET(0, MISC_CTRL, HOST_BUS, XSCALE)); while(regRead32(MISC_CTRL)!=0x1000002){ //hqj_06_08_23 start regWrite32(MISC_CTRL, FIELD_SET(0, MISC_CTRL, DAC_POWER, ENABLE) | FIELD_SET(0, MISC_CTRL, CRYSTAL, 12) | FIELD_SET(0, MISC_CTRL, HOST_BUS, XSCALE)); udelay(10); //hqj_06_08_31 printk("MISC_CTRL error\n"); //hqj_06_08_23 end } // Program panel registers. regWrite32(PANEL_FB_ADDRESS, FIELD_SET(0, PANEL_FB_ADDRESS, STATUS, PENDING) | FIELD_SET(0, PANEL_FB_ADDRESS, EXT, LOCAL) | FIELD_VALUE(0, PANEL_FB_ADDRESS, ADDRESS, value) ); regWrite32(PANEL_FB_WIDTH, FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH, register_table->fb_width) | FIELD_VALUE(0, PANEL_FB_WIDTH, OFFSET, register_table->fb_width) ); regWrite32(PANEL_WINDOW_WIDTH, FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, register_table->width) | FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, 0) ); regWrite32(PANEL_WINDOW_HEIGHT, FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, register_table->height) | FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, 0) ); regWrite32(PANEL_PLANE_TL, FIELD_VALUE(0, PANEL_PLANE_TL, TOP, 0) | FIELD_VALUE(0, PANEL_PLANE_TL, LEFT, 0) ); regWrite32(PANEL_PLANE_BR, FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM, register_table->height - 1) | FIELD_VALUE(0, PANEL_PLANE_BR, RIGHT, register_table->width - 1) ); regWrite32(PANEL_HORIZONTAL_TOTAL, register_table->horizontal_total); regWrite32(PANEL_HORIZONTAL_SYNC, register_table->horizontal_sync); regWrite32(PANEL_VERTICAL_TOTAL, register_table->vertical_total); regWrite32(PANEL_VERTICAL_SYNC, register_table->vertical_sync); // Program panel display control register. value = regRead32(PANEL_DISPLAY_CTRL) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE) & FIELD_CLEAR(PANEL_DISPLAY_CTRL, FORMAT); regWrite32(PANEL_DISPLAY_CTRL, value | register_table->control); //printk("programMode2 PANEL::CURRENT_POWER_CLOCK=%x\n",regRead32(CURRENT_POWER_CLOCK)); sm501_get_panel_info(); // Palette RAM. palette_ram = PANEL_PALETTE_RAM; // Turn on panel. panelPowerSequence(PANEL_ON, 4); } // Program CRT. else { // Program clock, enable display controller. gate = FIELD_SET(gate, CURRENT_POWER_GATE, DISPLAY, ENABLE); clock &= FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_SELECT) & FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_DIVIDER) & FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_SHIFT); setPower(gate, clock | register_table->clock); // Turn on DAC. modify by kavin very important regWrite32(MISC_CTRL, FIELD_SET(0, MISC_CTRL, DAC_POWER, ENABLE) | FIELD_SET(0, MISC_CTRL, CRYSTAL, 12) | FIELD_SET(0, MISC_CTRL, HOST_BUS, XSCALE)); // Calculate frame buffer address. value = 0; fb_size = register_table->fb_width * register_table->height; if (FIELD_GET(regRead32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, PLANE) == PANEL_DISPLAY_CTRL_PLANE_ENABLE) { value = FIELD_GET(regRead32(PANEL_FB_ADDRESS), PANEL_FB_ADDRESS, ADDRESS); if (fb_size < value) { value = 0; } else { value += FIELD_GET(regRead32(PANEL_FB_WIDTH), PANEL_FB_WIDTH, OFFSET) * FIELD_GET(regRead32(PANEL_WINDOW_HEIGHT), PANEL_WINDOW_HEIGHT, HEIGHT); } } // Program CRT registers. regWrite32(CRT_FB_ADDRESS, FIELD_SET(0, CRT_FB_ADDRESS, STATUS, CURRENT) | FIELD_SET(0, CRT_FB_ADDRESS, EXT, LOCAL) | FIELD_SET(0, CRT_FB_ADDRESS, CS, 1) | FIELD_VALUE(0, CRT_FB_ADDRESS, ADDRESS, value) ); regWrite32(CRT_FB_WIDTH, FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH, register_table->fb_width) | FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET, register_table->fb_width) ); regWrite32(CRT_HORIZONTAL_TOTAL, register_table->horizontal_total); regWrite32(CRT_HORIZONTAL_SYNC, register_table->horizontal_sync); regWrite32(CRT_VERTICAL_TOTAL, register_table->vertical_total); regWrite32(CRT_VERTICAL_SYNC, register_table->vertical_sync); // Program CRT display control register. value = regRead32(CRT_DISPLAY_CTRL) & FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE) & FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE) & FIELD_CLEAR(CRT_DISPLAY_CTRL, SELECT) & FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING) & FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE) & FIELD_CLEAR(CRT_DISPLAY_CTRL, FORMAT); regWrite32(CRT_DISPLAY_CTRL, value | register_table->control); // Palette RAM. palette_ram = CRT_PALETTE_RAM; // Turn on CRT. setDPMS(DPMS_ON); } // In case of 8-bpp, fill palette. if (FIELD_GET(register_table->control, PANEL_DISPLAY_CTRL, FORMAT) == PANEL_DISPLAY_CTRL_FORMAT_8) { // Start with RGB = 0,0,0. unsigned char red = 0, green = 0, blue = 0; unsigned long gray = 0; for (offset = 0; offset < 256 * 4; offset += 4) { // Store current RGB value. /* regWrite32(palette_ram + offset, gray ? RGB((gray + 50) / 100, (gray + 50) / 100, (gray + 50) / 100) : RGB(red, green, blue)); */ if (gray) { // Walk through grays (40 in total). gray += 654; } else { // Walk through colors (6 per base color). if (blue != 255) { blue += 51; } else if (green != 255) { blue = 0; green += 51; } else if (red != 255) { green = blue = 0; red += 51; } else { gray = 1; } } } } // For 16- and 32-bpp, fill palette with gamma values. else { // Start with RGB = 0,0,0. value = 0x000000; for (offset = 0; offset < 256 * 4; offset += 4) { regWrite32(palette_ram + offset, value); // Advance RGB by 1,1,1. value += 0x010101; } } //sm501_get_panel_info();}void SetMode(int nWidth, int nHeight, long nHertz, display_t display, int bpp) //hqj add function start{ mode_table_t mode; pmode_table_t vesaMode; reg_table_t register_table; // Locate the mode vesaMode = findMode(mode_table, nWidth, nHeight, nHertz); //printk("ready findMode\n") ; if (vesaMode != NULL) { //printk("findMide\n"); // 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); //hqj_06_12_20 } //sm501_get_panel_info();}int sm501modeinit(void){ //hqj_add_function int i; int detect=0; int XRES; int YRES; int BPP; int DEVICE; int result = 0; int HZv; //printk("sm501modeinit\n"); if((detect = sm501_detect()) == -1) return 0; XRES = mode_table[sm501mode - 1].horizontal_display_end; YRES = mode_table[sm501mode - 1].vertical_display_end; HZv = mode_table[sm501mode - 1].vertical_frequency; BPP = sm501bpp; if(!sm501out){ DEVICE = CRT; detect |= SM501_CRT; } else{ DEVICE = PANEL; detect |= SM501_PANEL; //hqj detect |= SM501_DUPLICATE; printk("crt and panel same things\n"); } error = 0; for(i = 0;i < 10; i++) { SetMode(XRES, YRES, HZv, DEVICE, BPP); if(!error) break; else error = 0; } return detect;}static void sm501_serial_init(void){ unsigned long val=0; unsigned long gate=0; printk("init sm501 serial and gpio\n"); val=INT_MASK_UART1_ENABLE<<13; //set int mask! val|=INT_MASK_UART0_ENABLE<<12; regWrite32(INT_MASK,val); val=0xFF<<5; regWrite32(GPIO_MUX_HIGH,val); //printk("set gpio high drect\n"); val=0x11<<5; regWrite32(0x01000C,val); printk("GPIO FOR NIBP\n"); //hqj_07_03_16 start GPGCON =0xff95ff9a; printk("GCON=%x\n",GPGCON); //hqj_07_03_16 end gate = regRead32(POWER_MODE1_GATE); //open uart power 0! gate|=POWER_MODE1_GATE_UART0_ENABLE<<7; gate|=POWER_MODE1_GATE_UART1_ENABLE<<8; regWrite32(POWER_MODE1_GATE,gate); gate = regRead32(POWER_MODE0_GATE); //open uart power 1! gate|=POWER_MODE0_GATE_UART0_ENABLE<<7; gate|=POWER_MODE0_GATE_UART1_ENABLE<<8; regWrite32(POWER_MODE0_GATE,gate); set_external_irq(IRQ_EINT17, EXT_HIGHLEVEL, GPIO_PULLUP_DIS);// set_external_irq(IRQ_EINT17, EXT_FALLING_EDGE, GPIO_MODE_IN | GPIO_PULLUP_DIS);//GPIO_PULLUP_DIS | GPIO_F0}int __init sm501_init(void){ struct sm501_info *panel_fbi = NULL, *crt_fbi = NULL; int detect; int ret; int test; printk("pSM501_BASE=%x\n",pSM501_BASE); sm501Mem = ioremap_nocache(pSM501_BASE, min(SM501_MEM_SIZE, SM501_REG_OFFSET)); sm501Reg = ioremap_nocache(pSM501_BASE+ SM501_REG_OFFSET, SM501_REG_SIZE); printk("sm501Mem=%x,sm501Reg=%x\n",sm501Mem,sm501Reg); //sm501_hwinit(); //hqj_06_12_20 /
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -