📄 s3c2410_sm501.c
字号:
} else { i = FIELD_GET(regRead32(SYSTEM_DRAM_CTRL), SYSTEM_DRAM_CTRL, DIVIDER); printk(" SYSTEM_DRAM_CTRL\n"); clock = clock_lookup[i]; } i = FIELD_GET(regRead32(CURRENT_POWER_CLOCK), CURRENT_POWER_CLOCK, V2XCLK_DIVIDER); divider = divider_lookup[i]; if (divider == -1) { printk("Invalid value for panel clock divider. CURRENT_POWER_CLOCK: %#lx, divider index: %#x\n", regRead32(CURRENT_POWER_CLOCK), i); return NULL; } shift = FIELD_GET(regRead32(CURRENT_POWER_CLOCK), CURRENT_POWER_CLOCK, V2XCLK_SHIFT); printk("clock: %d, divider: %d, shift: %d\n", clock, divider, shift); info.pixclock = (clock / divider) >> shift; info.xres = FIELD_GET(regRead32(CRT_HORIZONTAL_TOTAL), CRT_HORIZONTAL_TOTAL, DISPLAY_END) + 1; info.yres = FIELD_GET(regRead32(CRT_VERTICAL_TOTAL), CRT_VERTICAL_TOTAL, DISPLAY_END) + 1; info.hsync_len = FIELD_GET(regRead32(CRT_HORIZONTAL_SYNC), CRT_HORIZONTAL_SYNC, WIDTH); info.left_margin = 0; info.right_margin = 0; info.vsync_len = FIELD_GET(regRead32(CRT_VERTICAL_SYNC), CRT_VERTICAL_SYNC, HEIGHT); info.upper_margin = 0; info.lower_margin = 0; info.sync = 0; i = FIELD_GET(regRead32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, VSYNC_PHASE); if (i == CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH) info.sync |= FB_SYNC_HOR_HIGH_ACT; i = FIELD_GET(regRead32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, HSYNC_PHASE); if (i == CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH) info.sync |= FB_SYNC_VERT_HIGH_ACT; //#if DEBUG printk("CRT:\n"); printk("pixclock: %ld\n", info.pixclock); printk("bpp : %d\n", info.bpp); printk("xres : %d\n", info.xres); printk("yres : %d\n", info.yres); printk("hsync : %d\n", info.hsync_len); printk("vsync : %d\n", info.vsync_len); printk("left : %d\n", info.left_margin); printk("upper : %d\n", info.upper_margin); printk("right : %d\n", info.right_margin); printk("lower : %d\n", info.lower_margin); printk("sync : %d\n", info.sync); printk("\n"); printk("CRT_HORIZONTAL_TOTAL=%#lx\n",regRead32(MISC_CTRL)); printk("DRAM_CTRL=%#lx\n",regRead32(DRAM_CTRL)); printk("ARBITRATION_CTRL=%#lx\n",regRead32(ARBITRATION_CTRL)); printk("POWER_MODE1_GATE=%#lx\n",regRead32(POWER_MODE1_GATE)); printk("POWER_MODE1_CLOCK=%#lx\n",regRead32(POWER_MODE1_CLOCK)); printk("POWER_MODE_CTRL=%#lx\n",regRead32(POWER_MODE_CTRL)); printk("ENDIAN_CTRL=%#lx\n",regRead32(ENDIAN_CTRL)); printk("SYSTEM_DRAM_CTRL=%#lx\n",regRead32(SYSTEM_DRAM_CTRL)); printk("PANEL_DISPLAY_CTRL=%#lx\n",regRead32(PANEL_DISPLAY_CTRL)); printk("PANEL_PAN_CTRL=%#lx\n",regRead32(PANEL_PAN_CTRL)); printk("PANEL_COLOR_KEY=%#lx\n",regRead32(PANEL_COLOR_KEY)); printk("PANEL_FB_ADDRESS=%#lx\n",regRead32(PANEL_FB_ADDRESS)); printk("PANEL_FB_WIDTH=%#lx\n",regRead32(PANEL_FB_WIDTH)); printk("PANEL_WINDOW_WIDTH=%#lx\n",regRead32(PANEL_WINDOW_WIDTH)); printk("PANEL_WINDOW_HEIGHT=%#lx\n",regRead32(PANEL_WINDOW_HEIGHT)); printk("PANEL_PLANE_TL=%#lx\n",regRead32(PANEL_PLANE_TL)); printk("PANEL_PLANE_BR=%#lx\n",regRead32(PANEL_PLANE_BR)); printk("PANEL_HORIZONTAL_TOTAL=%#lx\n",regRead32(PANEL_HORIZONTAL_TOTAL)); printk("PANEL_HORIZONTAL_SYNC=%#lx\n",regRead32(PANEL_HORIZONTAL_SYNC)); printk("PANEL_VERTICAL_TOTAL=%#lx\n",regRead32(PANEL_VERTICAL_TOTAL)); printk("PANEL_VERTICAL_SYNC=%#lx\n",regRead32(PANEL_VERTICAL_SYNC)); printk("CRT_DISPLAY_CTRL=%#lx\n",regRead32(CRT_DISPLAY_CTRL)); printk("CRT_FB_ADDRESS=%#lx\n",regRead32(CRT_FB_ADDRESS)); printk("CRT_FB_WIDTH=%#lx\n",regRead32(CRT_FB_WIDTH)); printk("CRT_HORIZONTAL_TOTAL=%#lx\n",regRead32(CRT_HORIZONTAL_TOTAL)); printk("CRT_HORIZONTAL_SYNC=%#lx\n",regRead32(CRT_HORIZONTAL_SYNC)); printk("CRT_VERTICAL_TOTAL=%#lx\n",regRead32(CRT_VERTICAL_TOTAL)); printk("CRT_VERTICAL_SYNC=%#lx\n",regRead32(CRT_VERTICAL_SYNC)); printk("\n"); //#endif return &info;}static int sm501_valid_panel(void){ int result; result = (FIELD_GET(regRead32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) == PANEL_DISPLAY_CTRL_TIMING_ENABLE); if (result) result = (FIELD_GET(regRead32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, PLANE) == PANEL_DISPLAY_CTRL_PLANE_ENABLE); if (result) result = (FIELD_GET(regRead32(PANEL_HORIZONTAL_TOTAL), PANEL_HORIZONTAL_TOTAL, DISPLAY_END) > 120); if (result) result = (FIELD_GET(regRead32(PANEL_VERTICAL_TOTAL), PANEL_VERTICAL_TOTAL, DISPLAY_END) > 120); return result;}static int sm501_valid_crt(void){ int result; result = (FIELD_GET(regRead32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) == CRT_DISPLAY_CTRL_TIMING_ENABLE); if (result) result = (FIELD_GET(regRead32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, PLANE) == CRT_DISPLAY_CTRL_PLANE_ENABLE); if (result) result = (FIELD_GET(regRead32(CRT_HORIZONTAL_TOTAL), CRT_HORIZONTAL_TOTAL, DISPLAY_END) > 120); if (result) result = (FIELD_GET(regRead32(CRT_VERTICAL_TOTAL), CRT_VERTICAL_TOTAL, DISPLAY_END) > 120); return result;}static int __init sm501_default_setup(void){ int i; struct {u_long offset; u_long value;} sm501_reg_init[] = { /* 16bpp, VGA, works for Sharp LQ64343 LCD and VGA CRT */ /* #ifdef VGA_640X480 {MISC_CTRL, 0x01000400}, {DRAM_CTRL, 0xa6F22402}, {ARBITRATION_CTRL, 0x05146732}, {POWER_MODE1_GATE, 0x0002187F}, {POWER_MODE1_CLOCK, 0x09090801}, {POWER_MODE_CTRL, 0x00000001}, {ENDIAN_CTRL, 0x00000000}, {SYSTEM_DRAM_CTRL, 0x00080800}, {PANEL_DISPLAY_CTRL, 0x0F013105}, {PANEL_PAN_CTRL, 0x04000000}, {PANEL_COLOR_KEY, 0x00000000}, {PANEL_FB_ADDRESS, 0x04000000}, {PANEL_FB_WIDTH, 0x05000500}, {PANEL_WINDOW_WIDTH, 0x02800000}, {PANEL_WINDOW_HEIGHT, 0x01E00000}, {PANEL_PLANE_TL, 0x00000000}, {PANEL_PLANE_BR, 0x01DF027F}, {PANEL_HORIZONTAL_TOTAL, 0x02FA027F}, {PANEL_HORIZONTAL_SYNC, 0x004A028B}, {PANEL_VERTICAL_TOTAL, 0x020C01DF}, {PANEL_VERTICAL_SYNC, 0x000201E9}, {CRT_DISPLAY_CTRL, 0x00013500}, {CRT_FB_ADDRESS, 0x04000000}, {CRT_FB_WIDTH, 0x05000500}, {CRT_HORIZONTAL_TOTAL, 0x02FA027F}, {CRT_HORIZONTAL_SYNC, 0x004A028B}, {CRT_VERTICAL_TOTAL, 0x020C01DF}, {CRT_VERTICAL_SYNC, 0x000201E9} #endif #ifdef VGA_1024x768 */ /* {MISC_CTRL, 0x10000400}, {DRAM_CTRL, 0xa6F22402}, // {ARBITRATION_CTRL, 0x05146732}, {POWER_MODE1_GATE, 0x0002187F}, {POWER_MODE1_CLOCK, 0x08080801}, {POWER_MODE_CTRL, 0x00000001}, {ENDIAN_CTRL, 0x00000000}, {SYSTEM_DRAM_CTRL, 0x00080800}, {PANEL_DISPLAY_CTRL, 0x0F013105}, {PANEL_PAN_CTRL, 0x04000000}, {PANEL_COLOR_KEY, 0x00000000}, {PANEL_FB_ADDRESS, 0x04000000}, {PANEL_FB_WIDTH, 0x05000500}, {PANEL_WINDOW_WIDTH, 0x02800000}, // {PANEL_WINDOW_HEIGHT, 0x01E00000}, {PANEL_PLANE_TL, 0x00000000}, {PANEL_PLANE_BR, 0x01DF027F}, {PANEL_HORIZONTAL_TOTAL, 0x02FA027F}, {PANEL_HORIZONTAL_SYNC, 0x004A028B}, {PANEL_VERTICAL_TOTAL, 0x020C01DF}, {PANEL_VERTICAL_SYNC, 0x000201E9}, {CRT_DISPLAY_CTRL, 0x00013500}, {CRT_FB_ADDRESS, 0x04000000}, {CRT_FB_WIDTH, 0x05000500}, {CRT_HORIZONTAL_TOTAL, 0x02FA027F}, {CRT_HORIZONTAL_SYNC, 0x004A028B}, {CRT_VERTICAL_TOTAL, 0x020C01DF}, {CRT_VERTICAL_SYNC, 0x000201E9} //#endif */ {MISC_CTRL, 0x1000002}, {DRAM_CTRL, 0x7f147c0}, // {ARBITRATION_CTRL, 0x05146732}, {POWER_MODE1_GATE, 0x2000f}, {POWER_MODE1_CLOCK, 0x2a010a09}, {POWER_MODE_CTRL, 0x00000001}, {ENDIAN_CTRL, 0x00000000}, {SYSTEM_DRAM_CTRL, 0x90900}, {PANEL_DISPLAY_CTRL, 0x10000}, {PANEL_PAN_CTRL, 0x6208c505}, {PANEL_COLOR_KEY, 0x10000800}, {PANEL_FB_ADDRESS, 0x0}, {PANEL_FB_WIDTH, 0x10002000}, {PANEL_WINDOW_WIDTH, 0x8a90202}, // {PANEL_WINDOW_HEIGHT, 0x600900}, {PANEL_PLANE_TL, 0x30}, {PANEL_PLANE_BR, 0x200020}, {PANEL_HORIZONTAL_TOTAL, 0x1020000}, {PANEL_HORIZONTAL_SYNC, 0x10000}, {PANEL_VERTICAL_TOTAL, 0x10}, {PANEL_VERTICAL_SYNC, 0x0}, {CRT_DISPLAY_CTRL, 0x13305}, {CRT_FB_ADDRESS, 0x4000000}, {CRT_FB_WIDTH, 0x8000800}, {CRT_HORIZONTAL_TOTAL, 0x4fa03ff}, {CRT_HORIZONTAL_SYNC, 0x710413}, {CRT_VERTICAL_TOTAL, 0x32502ef}, {CRT_VERTICAL_SYNC, 0x60302} }; for (i=0; i<arraysize(sm501_reg_init); i++) { regWrite32(sm501_reg_init[i].offset, sm501_reg_init[i].value); } for(i=0;i<0x1000;i++) {memWrite32(i, 0x0); } return SM501_PANEL;}static struct sm501_info * __init sm501_init_fbinfo(int fb_type){ struct sm501_mach_info *inf; struct sm501_info *fbi; fbi = kmalloc(sizeof(struct sm501_info) + sizeof(struct display) + sizeof(u32) * 16, GFP_KERNEL); if (!fbi) return NULL; memset(fbi, 0, sizeof(struct sm501_info) + sizeof(struct display)); fbi->fb_type = fb_type; fbi->currcon = -1; fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; fbi->fb.fix.type_aux = 0; fbi->fb.fix.xpanstep = 0; fbi->fb.fix.ypanstep = 0; fbi->fb.fix.ywrapstep = 0; fbi->fb.fix.accel = FB_ACCEL_NONE; fbi->fb.var.nonstd = 0; fbi->fb.var.activate = FB_ACTIVATE_NOW; fbi->fb.var.height = -1; fbi->fb.var.width = -1; fbi->fb.var.accel_flags = 0; fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; if (fb_type & SM501_PANEL) { strcpy(fbi->fb.modename, SM501_PANEL_NAME); strcpy(fbi->fb.fix.id, SM501_PANEL_NAME); } else { strcpy(fbi->fb.modename, SM501_CRT_NAME); strcpy(fbi->fb.fix.id, SM501_CRT_NAME); } strcpy(fbi->fb.fontname, "VGA8x8"); fbi->fb.fbops = &sm501_ops; fbi->fb.changevar = NULL; fbi->fb.switch_con = sm501_switch; fbi->fb.updatevar = sm501_updatevar; fbi->fb.blank = sm501_blank; fbi->fb.flags = FBINFO_FLAG_DEFAULT; fbi->fb.node = -1; fbi->fb.monspecs = monspecs; fbi->fb.disp = (struct display *)(fbi + 1); fbi->fb.pseudo_palette = (void *)(fbi->fb.disp + 1); fbi->rgb[RGB_8] = &rgb_8; fbi->rgb[RGB_16] = &rgb_16; fbi->rgb[RGB_32] = &rgb_32; if (fb_type & SM501_PANEL) { inf = sm501_get_panel_info(); } else { inf = sm501_get_crt_info(); } fbi->xres = inf->xres; fbi->fb.var.xres = inf->xres; fbi->fb.var.xres_virtual = inf->xres; fbi->yres = inf->yres; fbi->fb.var.yres = inf->yres; fbi->fb.var.yres_virtual = inf->yres; fbi->bpp = inf->bpp; fbi->fb.var.bits_per_pixel = inf->bpp; fbi->fb.var.pixclock = inf->pixclock; fbi->fb.var.hsync_len = inf->hsync_len; fbi->fb.var.left_margin = inf->left_margin; fbi->fb.var.right_margin = inf->right_margin; fbi->fb.var.vsync_len = inf->vsync_len; fbi->fb.var.upper_margin = inf->upper_margin; fbi->fb.var.lower_margin = inf->lower_margin; fbi->fb.var.sync = inf->sync; fbi->fb.var.grayscale = 0; fbi->state = C_DISABLE; fbi->task_state = (u_char)-1; fbi->fb.fix.smem_len = fbi->xres * fbi->yres * fbi->bpp / 8; init_waitqueue_head(&fbi->ctrlr_wait); INIT_TQUEUE(&fbi->task, sm501_task, fbi); init_MUTEX(&fbi->ctrlr_sem); return fbi;}/*//Set M1XCLK;288/3temp = regRead32(CURRENT_POWER_CLOCK);temp &= 0xfffffff0;regWrite32(POWER_MODE0_CLOCK,temp | 8);//Set MCLK 288/3temp = regRead32(CURRENT_POWER_CLOCK);temp &= 0xfffff0ff;regWrite32(POWER_MODE0_CLOCK,temp | 8<<8); */unsigned long clockvaltran(unsigned long temp){ //hqj_06_07_31 start temp &= 0xfffffff0; temp |= 8 ; temp &= 0xfffff0ff; temp |= 8<<8; return temp;} //hqj_06_07_31 end// Program new power mode.void setPower(unsigned long nGates, unsigned long Clock){ unsigned long gate_reg, clock_reg; unsigned long control_value; unsigned long dram_value; // Get current power mode. control_value = FIELD_GET(regRead32(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE); switch (control_value) { case POWER_MODE_CTRL_MODE_MODE0: // Switch from mode 0 to mode 1. gate_reg = POWER_MODE1_GATE; clock_reg = POWER_MODE1_CLOCK; control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE1); //printk("use POWER_MODE1_CLOCK\n"); //hqj_06_07_31 break; case POWER_MODE_CTRL_MODE_MODE1: case POWER_MODE_CTRL_MODE_SLEEP: // Switch from mode 1 or sleep to mode 0. gate_reg = POWER_MODE0_GATE; clock_reg = POWER_MODE0_CLOCK; control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE0); //printk("use POWER_MODE0_CLOCK\n"); //hqj_06_07_31 break; default: // Invalid mode return; } dram_value = regRead32(SYSTEM_DRAM_CTRL); //hqj_06_07_31 start dram_value &= 0xfffff0Cf; regWrite32(SYSTEM_DRAM_CTRL,( dram_value | 8<<8 ) | 1<<4); //hqj_06_07_31 end // Program new power mode. regWrite32(gate_reg, nGates); //printk("Clock1=%d\n",Clock); //hqj_06_07_31 start Clock=clockvaltran(Clock); //printk("Clock2=%d\n",Clock); regWrite32(clock_reg, Clock); //hqj_06_07_31 end regWrite32(POWER_MODE_CTRL, control_value); // When returning from sleep, wait until finished. while (FIELD_GET(regRead32(POWER_MODE_CTRL), POWER_MODE_CTRL, SLEEP_STATUS) == POWER_MODE_CTRL_SLEEP_STATUS_ACTIVE) ;}// Set DPMS state.void setDPMS(DPMS_t state){ u_long value; value = regRead32(SYSTEM_CTRL); switch (state) { case DPMS_ON: value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VPHP); break; case DPMS_STANDBY: value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VPHN); break; case DPMS_SUSPEND: value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VNHP); break; case DPMS_OFF: value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VNHN); break; } regWrite32(SYSTEM_CTRL, value);}static void panelWaitVSync(int vsync_count){ u_long status; u_long timeout; while (vsync_count-- > 0) { /* Wait for end 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_ACTIVE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -