📄 sa1100fb.c
字号:
DPRINTK("Configuring xres = %d, yres = %d\n",var->xres, var->yres); if (machine_is_assabet()) { DPRINTK("Configuring Assabet LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_Act + LCCR0_LtlEnd + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(6) + LCCR1_BegLnDel(61) + LCCR1_EndLnDel(9); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + LCCR2_BegFrmDel(3) + LCCR2_EndFrmDel(0); lcd_shadow.lccr3 = LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH + LCCR3_HorSnchH + LCCR3_ACBsCntOff + LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(pcd); /* Set board control register to handle new color depth */ sa1100fb_assabet_set_truecolor(var->bits_per_pixel >= 16); } else if (machine_is_bitsy()) { DPRINTK("Configuring Bitsy LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth( var->xres ) + LCCR1_HorSnchWdth( 4 ) + LCCR1_BegLnDel( 0xC ) + LCCR1_EndLnDel( 0x11 ); lcd_shadow.lccr2 = LCCR2_DisHght( var->yres + 1 ) + LCCR2_VrtSnchWdth( 3 )+ LCCR2_BegFrmDel( 10 ) + LCCR2_EndFrmDel( 1 ); lcd_shadow.lccr3 = (/* PCD */ 0x10 | /* ACB */ 0 | /* API */ 0 | LCCR3_VrtSnchL | LCCR3_HorSnchL); } else if (machine_is_brutus()) { DPRINTK("Configuring Brutus LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Pas + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(4) + LCCR1_BegLnDel(41) + LCCR1_EndLnDel(101); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0); lcd_shadow.lccr3 = LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH + LCCR3_HorSnchH + LCCR3_ACBsCntOff + LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(44); } else if (machine_is_cerf()) { DPRINTK("Configuring Cerf LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_Pas + LCCR0_LtlEnd + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(6) + LCCR1_BegLnDel(61) + LCCR1_EndLnDel(9); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + LCCR2_BegFrmDel(3) + LCCR2_EndFrmDel(0); lcd_shadow.lccr3 = LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH + LCCR3_HorSnchH + LCCR3_ACBsCntOff + LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(38); } else if (machine_is_lart()) { DPRINTK("Configuring LART LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(2) + LCCR1_BegLnDel(4) + LCCR1_EndLnDel(2); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0); lcd_shadow.lccr3 = LCCR3_PixClkDiv(34) + LCCR3_ACBsDiv(512) + LCCR3_ACBsCntOff + LCCR3_HorSnchH + LCCR3_VrtSnchH; } else if (machine_is_penny()) { DPRINTK("Configuring Penny LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(65) + LCCR1_EndLnDel(43) + LCCR1_BegLnDel(43); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(35) + LCCR2_EndFrmDel(0) + LCCR2_BegFrmDel(0); lcd_shadow.lccr3 = LCCR3_PixClkDiv(16) + LCCR3_ACBsDiv (2) + LCCR3_ACBsCntOff + ((var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HorSnchH : LCCR3_HorSnchL) + ((var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); } else if (machine_is_thinclient() || machine_is_graphicsclient()) { DPRINTK("Configuring ThinClient LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act; lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(10) + LCCR1_EndLnDel(81) + LCCR1_BegLnDel(81); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(9) + LCCR2_EndFrmDel (20) + LCCR2_BegFrmDel(20); lcd_shadow.lccr3 = LCCR3_PixClkDiv(6) + LCCR3_ACBsDiv(2) + LCCR3_ACBsCntOff + LCCR3_HorSnchL + LCCR3_VrtSnchL; } else if (machine_is_tifon()) { DPRINTK("Configuring TIFON LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas + LCCR0_BigEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_8PixMono + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(var->hsync_len) + LCCR1_BegLnDel(var->left_margin) + LCCR1_EndLnDel(var->right_margin); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(var->vsync_len) + LCCR2_BegFrmDel(var->upper_margin) + LCCR2_EndFrmDel(var->lower_margin); lcd_shadow.lccr3 = LCCR3_PixClkDiv(pcd) + LCCR3_ACBsDiv(512) + LCCR3_ACBsCnt(0) + LCCR3_HorSnchH + LCCR3_VrtSnchH; /* ((current_var.sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HorSnchH : LCCR3_HorSnchL) + ((current_var.sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); */ } else if (machine_is_xp860()) { DPRINTK("Configuring XP860 LCD\n"); lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_ERM + LCCR0_DMADel(0); lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(var->hsync_len) + LCCR1_BegLnDel(var->left_margin) + LCCR1_EndLnDel(var->right_margin); lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(var->vsync_len) + LCCR2_BegFrmDel(var->upper_margin) + LCCR2_EndFrmDel(var->lower_margin); lcd_shadow.lccr3 = LCCR3_PixClkDiv(6) + LCCR3_HorSnchL + LCCR3_VrtSnchL; } /* Restore interrupt status */ local_irq_restore(flags); if (( LCCR0 != lcd_shadow.lccr0 ) || ( LCCR1 != lcd_shadow.lccr1 ) || ( LCCR2 != lcd_shadow.lccr2 ) || ( LCCR3 != lcd_shadow.lccr3 ) || ( DBAR1 != lcd_shadow.dbar1 ) || ( DBAR2 != lcd_shadow.dbar2 )) { sa1100fb_enable_lcd_controller(); } return 0;}/* * sa1100fb_inter_handler(): * Interrupt handler for LCD controller. Processes disable done interrupt (LDD) * to reenable controller if controller was disabled to change register values. */static void sa1100fb_inter_handler(int irq, void *dev_id, struct pt_regs *regs){ if (LCSR & LCSR_LDD) { int controller_state = current_par.controller_state; /* Disable Done Flag is set */ LCCR0 |= LCCR0_LDM; /* Mask LCD Disable Done Interrupt */ current_par.controller_state = LCD_MODE_DISABLED; if (controller_state == LCD_MODE_DISABLE_BEFORE_ENABLE) { DPRINTK("sa1100fb_inter_handler: re-enabling LCD controller\n"); sa1100fb_enable_lcd_controller(); } else { /* * Second half of sa1100fb_disable_lcd_controller() */ if (machine_is_assabet()) {#ifdef CONFIG_SA1100_ASSABET BCR_clear(BCR_LCD_ON);#endif } else if (machine_is_bitsy()) {#ifdef CONFIG_SA1100_BITSY if (current_par.controller_state != LCD_MODE_DISABLE_BEFORE_ENABLE) clr_bitsy_egpio(EGPIO_BITSY_LCD_ON | EGPIO_BITSY_LCD_PCI | EGPIO_BITSY_LCD_5V_ON | EGPIO_BITSY_LVDD_ON);#endif } else if (machine_is_penny()) {#ifdef CONFIG_SA1100_PENNY FpgaLcdCS1 = 0x000; /* LCD Backlight to 0% */ FpgaPortI &= ~LCD_ON; /* Turn off LCD Backlight */#endif } else if (machine_is_tifon()) { GPCR = GPIO_GPIO(24); /* turn off display */ } } } LCSR = 0; /* Clear LCD Status Register */}/* * sa1100fb_disable_lcd_controller(): * Disables LCD controller by and enables LDD interrupt. The controller_state * is not changed until the LDD interrupt is received to indicate the current * frame has completed. Platform specific hardware disabling is also included. */static void sa1100fb_disable_lcd_controller(void){ DPRINTK("Disabling LCD controller\n"); /* Exit if already LCD disabled, or LDD IRQ unmasked */ if ((current_par.controller_state == LCD_MODE_DISABLED) || (!(LCCR0 & LCCR0_LDM))) { DPRINTK("LCD already disabled\n"); return; } LCSR = 0; /* Clear LCD Status Register */ LCCR0 &= ~(LCCR0_LDM); /* Enable LCD Disable Done Interrupt */ enable_irq(IRQ_LCD); /* Enable LCD IRQ */ LCCR0 &= ~(LCCR0_LEN); /* Disable LCD Controller */}/* * sa1100fb_enable_lcd_controller(): * Enables LCD controller. If the controller is already enabled, it is first disabled. * This forces all changes to the LCD controller registers to be done when the * controller is disabled. Platform specific hardware enabling is also included. */static void sa1100fb_enable_lcd_controller(void){ u_long flags; local_irq_save(flags); /* Disable controller before changing parameters */ if (current_par.controller_state == LCD_MODE_ENABLED) { current_par.controller_state = LCD_MODE_DISABLE_BEFORE_ENABLE; sa1100fb_disable_lcd_controller(); } else { DPRINTK("Enabling LCD controller\n"); /* Make sure the mode bits are present in the first palette entry */ current_par.v_palette_base[0] &= 0x0FFF; current_par.v_palette_base[0] |= SA1100_PALETTE_MODE_VAL(current_par.bits_per_pixel); /* Enable GPIO<9:2> for LCD usage if dual-scan */ if (lcd_shadow.lccr0 & LCCR0_SDS) { GPDR |= 0x3fc; GAFR |= 0x3fc; } /* Sequence from 11.7.10 */ LCCR3 = lcd_shadow.lccr3; LCCR2 = lcd_shadow.lccr2; LCCR1 = lcd_shadow.lccr1; LCCR0 = lcd_shadow.lccr0 & ~LCCR0_LEN; DBAR1 = lcd_shadow.dbar1; DBAR2 = lcd_shadow.dbar2; LCCR0 |= LCCR0_LEN; if (machine_is_assabet()) {#ifdef CONFIG_SA1100_ASSABET BCR_set(BCR_LCD_ON);#endif } else if (machine_is_bitsy()) {#ifdef CONFIG_SA1100_BITSY set_bitsy_egpio(EGPIO_BITSY_LCD_ON | EGPIO_BITSY_LCD_PCI | EGPIO_BITSY_LCD_5V_ON | EGPIO_BITSY_LVDD_ON); DPRINTK("DBAR1=%p\n", DBAR1); DPRINTK("LCCR0=%x\n", LCCR0); DPRINTK("LCCR1=%x\n", LCCR1); DPRINTK("LCCR2=%x\n", LCCR2); DPRINTK("LCCR3=%x\n", LCCR3);#endif } else if (machine_is_penny()) {#ifdef CONFIG_SA1100_PENNY FpgaLcdCS1 = 0x0FF; /* LCD Backlight to 100% */ FpgaPortI |= LCD_ON; /* Turn on LCD Backlight */#endif } else if (machine_is_tifon()) { GPCR = GPIO_GPIO(24); /* cycle on/off-switch */ udelay(150); GPSR = GPIO_GPIO(24); /* turn on display */ } current_par.controller_state = LCD_MODE_ENABLED; } /* Restore interrupt status */ local_irq_restore(flags);}/* * sa1100fb_blank(): * Blank the display by setting all palette values to zero. Note, the * 12 and 16 bpp modes don't really use the palette, so this will not * blank the display in all modes. */static voidsa1100fb_blank(int blank, struct fb_info *info){ int i; DPRINTK("blank=%d info->modename=%s\n", blank, info->modename); if (blank) { if (current_par.visual != FB_VISUAL_TRUECOLOR) for (i = 0; i < current_par.palette_size; i++) sa1100fb_palette_write(i, sa1100fb_palette_encode(i, 0, 0, 0, 0)); sa1100fb_disable_lcd_controller(); } else { if (current_par.visual != FB_VISUAL_TRUECOLOR) sa1100fb_set_cmap(&fb_display[current_par.currcon].cmap, 1, current_par.currcon, info); sa1100fb_enable_lcd_controller(); } /* TODO: Bitsy support for blanking display */}/* * sa1100fb_switch(): * Change to the specified console. Palette and video mode * are changed to the console's stored parameters. */static intsa1100fb_switch(int con, struct fb_info *info){ DPRINTK("con=%d info->modename=%s\n", con, info->modename); if (current_par.visual != FB_VISUAL_TRUECOLOR) { struct fb_cmap *cmap; if (current_par.currcon >= 0) { // Get the colormap for the selected console cmap = &fb_display[current_par.currcon].cmap; if (cmap->len) fb_get_cmap(cmap, 1, sa1100fb_getcolreg, info); } } current_par.currcon = con; fb_display[con].var.activate = FB_ACTIVATE_NOW; DPRINTK("fb_display[%d].var.activate=%x\n", con, fb_display[con].var.activate); sa1100fb_set_var(&fb_display[con].var, con, info); current_par.v_palette_base[0] = (current_par.v_palette_base[0] & 0xcfff) | SA1100_PALETTE_MODE_VAL(current_par.bits_per_pixel); return 0;}int __init sa1100fb_init(void){ int ret; sa1100fb_init_fbinfo(); /* Initialize video memory */ if ((ret = sa1100fb_map_video_memory()) != 0) return ret; if (current_par.montype < 0 || current_par.montype > NR_MONTYPES) current_par.montype = 1; if (request_irq(IRQ_LCD, sa1100fb_inter_handler, SA_INTERRUPT, "SA1100 LCD", NULL) != 0) { printk(KERN_ERR "sa1100fb: failed in request_irq\n"); return -EBUSY; } DPRINTK("sa1100fb: request_irq succeeded\n"); disable_irq(IRQ_LCD); if (machine_is_assabet()) { GPDR |= 0x3fc; GAFR |= 0x3fc; sa1100fb_assabet_set_truecolor(current_par.visual == FB_VISUAL_TRUECOLOR); } else if (machine_is_bitsy()) { GPDR = (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8); GAFR |= (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8); } else if (machine_is_cerf()) { GPDR |= 0x3fc; GAFR |= 0x3fc; } else if (machine_is_penny()) {#ifdef CONFIG_SA1100_PENNY GPDR |= GPIO_GPDR_GFX; /* GPIO Data Direction register for LCD data bits 8-11 */ GAFR |= GPIO_GAFR_GFX; /* GPIO Alternate Function register for LCD data bits 8-11 */#endif } else if (machine_is_tifon()) { GPDR |= GPIO_GPIO(24); /* set GPIO24 to output */ } else if (machine_is_xp860()) { GPDR |= 0x3fc; GAFR |= 0x3fc; } if (sa1100fb_set_var(&init_var, -1, &fb_info)) current_par.allow_modeset = 0; sa1100fb_decode_var(&init_var, ¤t_par); register_framebuffer(&fb_info); /* This driver cannot be unloaded at the moment */ MOD_INC_USE_COUNT; return 0;}int __init sa1100fb_setup(char *options){ char *this_opt; if (!options || !*options) return 0; for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) { if (!strncmp(this_opt, "bpp:", 4)) current_par.max_bpp = simple_strtoul(this_opt+4, NULL, 0); if (!strncmp(this_opt, "lccr0:", 6)) lcd_shadow.lccr0 = simple_strtoul(this_opt+6, NULL, 0); if (!strncmp(this_opt, "lccr1:", 6)) { lcd_shadow.lccr1 = simple_strtoul(this_opt+6, NULL, 0); current_par.max_xres = (lcd_shadow.lccr1 & 0x3ff) + 16; } if (!strncmp(this_opt, "lccr2:", 6)) { lcd_shadow.lccr2 = simple_strtoul(this_opt+6, NULL, 0); current_par.max_yres = (lcd_shadow.lccr0 & LCCR0_SDS) ? ((lcd_shadow.lccr2 & 0x3ff) + 1) * 2 : ((lcd_shadow.lccr2 & 0x3ff) + 1); } if (!strncmp(this_opt, "lccr3:", 6)) lcd_shadow.lccr3 = simple_strtoul(this_opt+6, NULL, 0); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -