display.c
来自「omap3 linux 2.6 用nocc去除了冗余代码」· C语言 代码 · 共 2,061 行 · 第 1/5 页
C
2,061 行
if(mirroring ==1) row_inc_value = row_inc_value - MAX_PIXELS_PER_LINE * ps; else row_inc_value = row_inc_value + MAX_PIXELS_PER_LINE * ps; } else{ if(mirroring ==1) row_inc_value = row_inc_value + pix->width * ps / vr_ps; else row_inc_value = row_inc_value + pix->width * ps; } dispc_reg_out(DISPC_VID_ROW_INC(v), row_inc_value); dispc_reg_out(DISPC_VID_PIXEL_INC(v), pixel_inc_value); } /* * Store BA0 BA1 for TV, BA1 points to the alternate row */ if(flicker_filter == 1){ layer[ltype].dma[1].row_inc = row_inc_value; } else if (rotation_deg >= 0){ if(mirroring ==1) layer[ltype].dma[1].row_inc = row_inc_value - MAX_PIXELS_PER_LINE * ps; else layer[ltype].dma[1].row_inc = row_inc_value + MAX_PIXELS_PER_LINE * ps; } else{ if(mirroring ==1) layer[ltype].dma[1].row_inc = row_inc_value + pix->width * ps/vr_ps; else row_inc_value = row_inc_value + pix->width * ps; } layer[ltype].dma[1].pix_inc = pixel_inc_value; layer[ltype].size_x = cropwidth; layer[ltype].size_y = cropheight; vid_position = ((vid_position_x << DISPC_VID_POSITION_VIDPOSX_SHIFT) & DISPC_VID_POSITION_VIDPOSX) | ((vid_position_y << DISPC_VID_POSITION_VIDPOSY_SHIFT) & DISPC_VID_POSITION_VIDPOSY); dispc_reg_out(DISPC_VID_POSITION(v), vid_position); dispc_reg_out(DISPC_VID_SIZE(v), vid_size); dispc_reg_out(DISPC_VID_PICTURE_SIZE(v), vid_picture_size); omap2_disp_save_initstate(ltype);}/* Many display controller registers are shadowed. Setting the GO bit causes * changes to these registers to take effect in hardware. */voidomap2_disp_reg_sync(int output_dev){ if (output_dev == OMAP2_OUTPUT_LCD) dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GOLCD, DISPC_CONTROL_GOLCD); else dispc_reg_merge(DISPC_CONTROL, DISPC_CONTROL_GODIGITAL, DISPC_CONTROL_GODIGITAL);}/* This function provides the status of the GO bit. After the GO bit is set * through software, register changes take affect at the next VFP (vertical * front porch) or EVSYNC. Per the specs, no further register changes * must be done until the GO bit is reset by hardware. This function allows * drivers to poll the status of the GO bit, and wait until it is reset if they * wish to. */intomap2_disp_reg_sync_done(int output_dev){ u32 control = dispc_reg_in(DISPC_CONTROL); if (output_dev == OMAP2_OUTPUT_LCD) return ~(control & DISPC_CONTROL_GOLCD); else return ~(control & DISPC_CONTROL_GODIGITAL);}/* This function turns on/off the clocks needed for TV-out. * - 2430SDP: Controls the dss_54m_fck * - 3430SDP: Controls the dss_tv_fck * - 3430LAB: Controls both dss_tv_fck and dss_96m_fck. * By default Labrador turns off the 96MHz DAC clock for * power saving reasons. */static voidomap24xx_ll_config_tv_clocks(int sleep_state){ static int start = 1; static struct clk *tv_clk; static int disabled = 0; static int enabled = 0; if(start) { tv_clk = clk_get(NULL,"dss_tv_fck"); if(IS_ERR(tv_clk)) { printk("\n UNABLE to get dss TV fclk \n"); return; } start = 0; } if (sleep_state == 1) { if (disabled == 0) { clk_disable(tv_clk); disabled = 1; } enabled = 0; } else { if (enabled == 0) { if(clk_enable(tv_clk) != 0) { printk("\n UNABLE to enable dss TV fclk \n"); return; } enabled = 1; } disabled = 0; }}/* * Disable the display controller. May be called in interrupt or process * context. However, this function should not be called with interrupts * disabled as jiffies will not increment. */voidomap2_disp_disable(unsigned long timeout_ticks){ unsigned long timeout; if (dispc_reg_in(DISPC_CONTROL) & (DISPC_CONTROL_DIGITALENABLE | DISPC_CONTROL_LCDENABLE)) { /* disable the display controller */ dispc_reg_merge(DISPC_CONTROL, 0, DISPC_CONTROL_DIGITALENABLE | DISPC_CONTROL_LCDENABLE); /* wait for any frame in progress to complete */ dispc_reg_out(DISPC_IRQSTATUS, DISPC_IRQSTATUS_FRAMEDONE); timeout = jiffies + timeout_ticks; while(!(dispc_reg_in(DISPC_IRQSTATUS) & DISPC_IRQSTATUS_FRAMEDONE) && time_before(jiffies, timeout)) { int a_ctx = (in_atomic() || irqs_disabled() || in_interrupt()); if (!a_ctx) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); } else udelay(100); } if (!(dispc_reg_in(DISPC_IRQSTATUS) & DISPC_IRQSTATUS_FRAMEDONE)) { printk(KERN_WARNING "timeout waiting for " "frame-done interrupt\n"); } omap24xx_ll_config_tv_clocks(1); } return;}voidomap2_disp_set_gfx_palette(u32 palette_ba){ dispc_reg_out(DISPC_GFX_TABLE_BA, palette_ba); dispc_reg_merge(DISPC_CONFIG, DISPC_CONFIG_LOADMODE_PGTABUSETB, DISPC_CONFIG_LOADMODE_PGTABUSETB);}/* Configure Graphics layer parameters */voidomap2_disp_config_gfxlayer(u32 size_x, u32 size_y, int color_depth){ u32 config = 0; u32 gfx_attributes = 0, gfx_fifo_threshold = 0, gfx_format = 0; u32 gfx_position = 0, gfx_window_skip = 0; config = dispc_reg_in(DISPC_CONFIG); config |= (DISPC_CONFIG_LOADMODE_PGTABUSETB | DISPC_CONFIG_LOADMODE_FRDATLEFR); /* This driver doesn't currently support the video windows, so * we force the palette/gamma table to be a palette table and * force both video windows to be disabled. */ config &= ~DISPC_CONFIG_PALETTEGAMMATABLE; gfx_attributes = DISPC_GFX_ATTRIBUTES_GFXBURSTSIZE_BURST16X32; /* enable the graphics window only if its size is not zero */ gfx_fifo_threshold = (RMODE_GFX_FIFO_HIGH_THRES << DISPC_GFX_FIFO_THRESHOLD_HIGH_SHIFT) | (RMODE_GFX_FIFO_LOW_THRES << DISPC_GFX_FIFO_THRESHOLD_LOW_SHIFT); gfx_position = 0; gfx_window_skip = 0; switch(color_depth) { case 1: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP1; break; case 2: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP2; break; case 4: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP4; break; case 8: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_BITMAP8; break; case 12: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB12; break; case 16: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB16; break; case 24: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGB24; break; case 32: gfx_format = DISPC_GFX_ATTRIBUTES_GFXFORMAT_RGBA32; break; default: gfx_format = dispc_reg_in(DISPC_GFX_ATTRIBUTES) & DISPC_GFX_ATTRIBUTES_GFXFORMAT; break; } gfx_attributes |= gfx_format; dispc_reg_out(DISPC_GFX_FIFO_THRESHOLD, gfx_fifo_threshold); dispc_reg_out(DISPC_GFX_POSITION, gfx_position); dispc_reg_out(DISPC_GFX_WINDOW_SKIP, gfx_window_skip); dispc_reg_out(DISPC_CONFIG, config); dispc_reg_out(DISPC_GFX_ATTRIBUTES, gfx_attributes); layer[OMAP2_GRAPHICS].size_x = size_x; layer[OMAP2_GRAPHICS].size_y = size_y;}/* Calculate the number of pixels sent to the display per pixel clock as * (nom/den) pixels per clock. */voidomap2_disp_pixels_per_clock(unsigned int *nom, unsigned int *den){ u32 dispc_control; dispc_control = dispc_reg_in(DISPC_CONTROL); if (dispc_control & DISPC_CONTROL_STNTFT) { /* active display (TFT) */ if (dispc_control & DISPC_CONTROL_TDMENABLE) { /* TFT with TDM */ switch (dispc_control & DISPC_CONTROL_TDMCYCLEFORMAT) { case DISPC_CONTROL_TDMCYCLEFORMAT_1CYCPERPIX: *nom = 1; *den = 1; break; case DISPC_CONTROL_TDMCYCLEFORMAT_2CYCPERPIX: *nom = 1; *den = 2; break; case DISPC_CONTROL_TDMCYCLEFORMAT_3CYCPERPIX: *nom = 1; *den = 3; break; case DISPC_CONTROL_TDMCYCLEFORMAT_3CYCPER2PIX: *nom = 2; *den = 3; break; } } else { /* TFT without TDM */ *nom = 1; *den = 1; } } else { /* passive display (STN) */ if (dispc_control & DISPC_CONTROL_MONOCOLOR) { /* STN mono */ if (dispc_control & DISPC_CONTROL_M8B) { /* 8 pixels per pixclock */ *nom = 8; *den = 1; } else { /* 4 pixels per pixclock */ *nom = 4; *den = 1; } } else { /* STN color--8 pixels per 3 pixclocks */ *nom = 8; *den = 3; } }}/* Configure the signal configuration for LCD panel */voidomap2_disp_lcdcfg_polfreq(u32 hsync_high, u32 vsync_high, u32 acb,u32 ipc, u32 onoff){ u32 pol_freq = 0; /* set the sync polarity */ if (!hsync_high) pol_freq &= ~DISPC_POL_FREQ_IHS; else pol_freq |= DISPC_POL_FREQ_IHS; if (!vsync_high) pol_freq &= ~DISPC_POL_FREQ_IVS; else pol_freq |= DISPC_POL_FREQ_IVS; pol_freq |= acb | (ipc << DISPC_POL_FREQ_IPC_SHIFT) << (onoff << DISPC_POL_FREQ_ONOFF_SHIFT) ; dispc_reg_out(DISPC_POL_FREQ, pol_freq);}/* Configure LCD parameters */void omap2_disp_config_lcd(u32 clkdiv, u32 hbp, u32 hfp, u32 hsw, u32 vbp, u32 vfp, u32 vsw){ u32 control, divisor, timing_h, timing_v; divisor = (1 << DISPC_DIVISOR_LCD_SHIFT) | (2 << DISPC_DIVISOR_PCD_SHIFT); //clkdiv replaced with 2 if (hbp > 255) hbp = 255; if (hfp > 255) hfp = 255; if (hsw > 63) hsw = 63; if (vbp > 255) vbp = 255; if (vfp > 255) vfp = 255; if (vsw > 63) vsw = 63; timing_h = (hbp << DISPC_TIMING_H_HBP_SHIFT) | (hfp << DISPC_TIMING_H_HFP_SHIFT) | (hsw << DISPC_TIMING_H_HSW_SHIFT); timing_v = (vbp << DISPC_TIMING_V_VBP_SHIFT) | (vfp << DISPC_TIMING_V_VFP_SHIFT) | (vsw << DISPC_TIMING_V_VSW_SHIFT);// dispc_reg_out(DISPC_TIMING_H, timing_h);// dispc_reg_out(DISPC_TIMING_V, timing_v); dispc_reg_out(DISPC_TIMING_H, 0x0FF03F31); dispc_reg_out(DISPC_TIMING_V, 0x01400504); dispc_reg_out(DISPC_DIVISOR, divisor); control = dispc_reg_in(DISPC_CONTROL); control |= DISPC_CONTROL_TFTDATALINES_OALSB18B; control |= DISPC_CONTROL_GPOUT1 | DISPC_CONTROL_GPOUT0 | DISPC_CONTROL_STNTFT; dispc_reg_out(DISPC_CONTROL, control);}/* Set the pixel clock divisor for the LCD */voidomap2_disp_set_pcd(u32 pcd){ dispc_reg_out(DISPC_DIVISOR, (1 << DISPC_DIVISOR_LCD_SHIFT) | (pcd << DISPC_DIVISOR_PCD_SHIFT));}/* * Set the DSS Functional clock * The DSS clock should be 4 times the Panel's Pixel clock * For TV the Pixel clock required is 13.5Mhz * For LCD the Pixel clock is 6Mhz */voidomap2_disp_set_dssfclk(void){ /* TODO set the LCD pixel clock rate based on the LCD configuration */ static int LCD_pixel_clk = 26000000; /* to get more bandwidth*/ static int TV_pixel_clk = 14000000; /* rounded 13.5 to 14*/ u32 ask_clkrate=0,sup_clkrate=0,tgt_clkrate=0,i;// ask_clkrate = LCD_pixel_clk * 4; if(ask_clkrate < (TV_pixel_clk * 4)) ask_clkrate = TV_pixel_clk * 4; ask_clkrate = 148500000; tgt_clkrate = ask_clkrate; sup_clkrate = clk_round_rate(dss1f_scale, ask_clkrate); if(is_sil_rev_less_than(OMAP3430_REV_ES2_0)){ if(clk_get_rate(dss1f_scale) == 96000000){ /*96M already, dont do anything for ES 1.0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?