⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mq200fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * linux/drivers/video/mq200fb.c -- MQ-200 for a frame buffer device * based on linux/driver/video/pm2fb.c * * Copyright (C) 2000 Lineo, Japan * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file COPYING in the main directory of this archive * for more details. */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/malloc.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/selection.h>#include <linux/console.h>#include <linux/init.h>#include <linux/timer.h>#include <video/fbcon.h>#include <video/fbcon-cfb8.h>#include <asm/io.h>#include "mq200fb.h"#if 0#define PRINTK(args...) printk(args)#else#define PRINTK(args...)#endif#define WITH_NONE 0#define WITH_HSYNC (1 << 0)#define WITH_VSYNC (1 << 1)/**************************************************************** * type definitions *//**** * PLL parameters */struct pll_par {    u16 m_par;                 /* M parameter */    u16 n_par;                 /* N parameter */    u16 p_par;                 /* P parameter */};/**** * display control values */struct disp_par {    u16 hdt;                   /* horizontal display total;                                * hdt >= hse + 4; val = hdt - 2 */    u16 hde;                   /* horizontal display end */    u16 vdt;                   /* vertical display total;                                * vdt >= vse + 2; val = vdt - 1 */    u16 vde;                   /* vertical display end; val = vde - 1 */    u16 hss;                   /* horizontal sync start; hss >= hde + 4 */    u16 hse;                   /* horizontal sync end; hse >= hss + 4 */    u16 vss;                   /* vertical sync start; vss >= vde + 1 */    u16 vse;                   /* vertical sync end; vse >= vss + 1 */};/**** * window control values */struct win_par {    u16 hws;                   /* horizontal window start */    u16 hww;                   /* horizontal window width;                                * hww >= 8; val = hww - 1 */    u16 wald;                  /* window additional line data */    u16 vws;                   /* vertical window start */    u16 vwh;                   /* vertical window height;                                * vwh >= 1; val = vwh - 1 */    s16 wst;                   /* window stride; do NOT use a negative                                  number */    unsigned long wsa;         /* window start address */};/**** *  The hardware specific data in this structure uniquely defines a video *  mode. * *  If your hardware supports only one video mode, you can leave it empty. */struct mq200fb_par {    struct pll_par pll[3];     /* PLL 1, 2 and 3 */    struct {       struct disp_par disp;   /* display control */       struct win_par win;     /* window control */       struct win_par awin;    /* alternate window control */       u16 gcd;                /* graphics color depth */       u16 agcd;               /* alternate graphics color depth */       u16 v_height;           /* virtual height for main window */       u16 v_aheight;          /* virtual height for alternate window */       u16 fd;                 /* pixclock = source_clock / fd / sd */       u16 sd;    } gc[2];                   /* graphics controller 1 and 2 */};struct mq200fb_cursor_info {    struct {       u16 x, y;    } size;    int enable;    struct timer_list timer;};struct mq200fb_info {    struct fb_info_gen gen;    struct mq200fb_par current_par;    int current_par_valid;    u16 vendor_id;             /* MQ-200 vendor ID */    u16 device_id;             /* MQ-200 device ID */    struct {       u32 fb_size;            /* framebuffer size */       unsigned long rg_base;  /* physical register memory base */       unsigned long p_fb;     /* physical address of frame buffer */       unsigned long v_fb;     /* virtual address of frame buffer */       unsigned long p_regs;   /* physical address of rg_base */       unsigned long v_regs;   /* virtual address of rg_base */    } regions;    unsigned long pmu_base;    /* power management unit */    unsigned long cpu_base;    /* CPU interface */    unsigned long miu_base;    /* memory interface unit */    unsigned long in_base;     /* interrupt controller */    unsigned long gc_base;     /* graphics controller 1&2 */    unsigned long ge_base;     /* graphics engine */    unsigned long fpi_base;    /* flat panel interface */    unsigned long cp1_base;    /* color palette 1 */    unsigned long dc_base;     /* device configuration */    unsigned long pci_base;    /* PCI configuration */    unsigned long psf_base;    /* ??? */    struct display disp;    struct mq200fb_cursor_info cursor_info;    spinlock_t lock;};/**************************************************************** * function prototype declarations */static int mq200fb_open(struct fb_info*, int);static int mq200fb_release(struct fb_info*, int);static void mq200fb_detect(void);static int mq200fb_encode_fix(struct fb_fix_screeninfo*, const void*,                             struct fb_info_gen*);static int mq200fb_decode_var(const struct fb_var_screeninfo*, void*,                             struct fb_info_gen*);static int mq200fb_encode_var(struct fb_var_screeninfo*, const void*,                             struct fb_info_gen*);static void mq200fb_get_par(void*, struct fb_info_gen*);static void mq200fb_set_par(const void*, struct fb_info_gen*);static int mq200fb_getcolreg(unsigned, unsigned*, unsigned*, unsigned*,                            unsigned*, struct fb_info*);static int mq200fb_setcolreg(unsigned, unsigned, unsigned, unsigned,                            unsigned, struct fb_info*);static int mq200fb_pan_display(const struct fb_var_screeninfo*,                              struct fb_info_gen*);static int mq200fb_blank(int, struct fb_info_gen*);static void mq200fb_set_disp(const void*, struct display*,                            struct fb_info_gen*);#ifdef FBCON_HAS_CFB8static void mq200fb_cursor(struct display*, int, int, int);static int mq200fb_set_font(struct display*, int, int);static void mq200fb_clear(struct vc_data*, struct display*, int, int, int,                         int);static void mq200fb_clear_margins(struct vc_data*, struct display*, int);static void mq200fb_putc(struct vc_data*, struct display*, int, int, int);static void mq200fb_putcs(struct vc_data*, struct display*,                         const unsigned short*, int, int, int);#endifstatic int is_color_palette_enabled(const struct mq200fb_par*);static u32 get_line_length(const struct mq200fb_par*);static u32 get_width(const struct mq200fb_par*);#if 0static void set_v_width(struct mq200fb_par*, int);#endifstatic u32 get_v_height(const struct mq200fb_par*);static u32 get_height(const struct mq200fb_par*);#if 0static void set_v_height(struct mq200fb_par*, int);#endifstatic int get_bits_per_pixel(const struct mq200fb_par*);#if 0static void set_bits_per_pixel(struct mq200fb_par*, int);#endifstatic u32 get_right_margin(const struct mq200fb_par*);static u32 get_left_margin(const struct mq200fb_par*);static u32 get_lower_margin(const struct mq200fb_par*);static u32 get_upper_margin(const struct mq200fb_par*);static u32 get_hsync_len(const struct mq200fb_par*);static u32 get_vsync_len(const struct mq200fb_par*);static u32 get_xoffset(const struct mq200fb_par*);static u32 get_yoffset(const struct mq200fb_par*);static u32 get_pixclock(const struct mq200fb_par*);static double get_pll_freq(const struct pll_par*);static double get_fd_val(const struct mq200fb_par*);static double get_sd_val(const struct mq200fb_par*);static void power_state_transition(const struct mq200fb_info*, int);#if 0static void vsync(void);static void mq200_interrupt(int, void*, struct pt_regs*);static void mq200_enable_irq(const struct mq200fb_info*);#endifstatic int mq200fb_conf(struct mq200fb_info*);static int mq200_probe(struct mq200fb_info*);static void mq200_reset(const struct mq200fb_info*);static void dc_reset(const struct mq200fb_info*);static void miu_reset(const struct mq200fb_info*);static void pmu_reset(const struct mq200fb_info*);static void gc1_reset(const struct mq200fb_info*);static void ge_reset(const struct mq200fb_info*);static void cp1_reset(const struct mq200fb_info*);static void set_screen(const struct mq200fb_info*,                      const struct mq200fb_par*);static void set_cursor_shape(const struct mq200fb_info*);static void enable_cursor(struct mq200fb_info*);static void disable_cursor(struct mq200fb_info*);static int set_cursor_pos(const struct mq200fb_info*, unsigned, unsigned);static void cursor_timer_handler(unsigned long);static void get_color_palette(const struct mq200fb_info*, unsigned,                             unsigned*, unsigned*, unsigned*);static void set_color_palette(const struct mq200fb_info*, unsigned,                             unsigned, unsigned, unsigned);static void enable_dac(const struct mq200fb_info*);static void disable_dac(const struct mq200fb_info*, unsigned);static int __inline__ is_enough_cmd_fifo(const struct mq200fb_info*, int);static int __inline__ is_enough_src_fifo(const struct mq200fb_info*, int);static void wait_cmd_fifo(const struct mq200fb_info*, int);static void wait_src_fifo(const struct mq200fb_info*, int);static void ge_rect_fill(const struct mq200fb_info*, int, int, int, int,                        u32);static void ge_bitblt_char(const struct mq200fb_info*, int, int, u8*, int,                          int, u32, u32);static void add_cursor_timer(struct mq200fb_cursor_info*);/**************************************************************** * static variables definitions *//**** *  In most cases the `generic' routines (fbgen_*) should be satisfactory. *  However, you're free to fill in your own replacements. */static struct fb_ops mq200fb_ops = {#if LINUX_VERSION_CODE >= 0x020400    owner:             THIS_MODULE,#else    fb_open:           mq200fb_open,    fb_release:                mq200fb_release,#endif    fb_get_fix:                fbgen_get_fix,    fb_get_var:                fbgen_get_var,    fb_set_var:                fbgen_set_var,    fb_get_cmap:       fbgen_get_cmap,    fb_set_cmap:       fbgen_set_cmap,    fb_pan_display:    fbgen_pan_display,};static struct mq200fb_info mq200fb_info;static struct {    char font[40];    struct mq200fb_par par;} mq200fb_options = {    font: "",    {       {           { 219, 16, 2 },     /* PLL1 = 12.288MHz * 220 / 17 / 4 = 39.76 */           { 242, 16, 2 },     /* PLL2 = 12.288MHz * 243 / 17 / 4 = 43.91 */           { 242, 22, 2 },     /* PLL3 = 12.288MHz * 243 / 23 / 4 = 32.46 */       },       {           {                   /* graphics controller 1 */               { 1047, 800, 624, 599, 832, 976, 601, 604 }, /* display */               { 0, 800, 0, 0, 600, 800, 0 }, /* window */               { },            /* alternate window */               3,              /* gcd = 8-bpp */               3,              /* agcd = 8-bpp */               600,            /* virtual height for main window */               0,              /* virtual height for alternate window */               0,              /* fd = 1 */               1               /* sd = 1 */           },           {                   /* graphics controller 2 */           }       },    }};/**** * Interfaces to hardware functions */static struct fbgen_hwswitch mq200_switch = {    detect: mq200fb_detect,    encode_fix: mq200fb_encode_fix,    decode_var: mq200fb_decode_var,    encode_var: mq200fb_encode_var,    get_par: mq200fb_get_par,    set_par: mq200fb_set_par,    getcolreg: mq200fb_getcolreg,    setcolreg: mq200fb_setcolreg,    pan_display: mq200fb_pan_display,    blank: mq200fb_blank,    set_disp: mq200fb_set_disp};#ifdef FBCON_HAS_CFB8static void mq200fb_ds_setup(struct display* disp){    fbcon_cfb8_setup(disp);}/**** * fbcon switch for the low level operations. */static struct display_switch mq200_cfb8 = {    setup: mq200fb_ds_setup,    bmove: fbcon_cfb8_bmove,    clear: mq200fb_clear,    putc: mq200fb_putc,    putcs: mq200fb_putcs,    cursor: mq200fb_cursor,    set_font: mq200fb_set_font,    clear_margins: mq200fb_clear_margins,    fontwidthmask: FONTWIDTH(8) | FONTWIDTH(16)};#endif/**************************************************************** * functions for struct fb_ops member */#if LINUX_VERSION_CODE < 0x020400static intmq200fb_open(struct fb_info* info,            int user){    MOD_INC_USE_COUNT;    return 0;}#endif#if LINUX_VERSION_CODE < 0x020400static intmq200fb_release(struct fb_info* info,               int user){    MOD_DEC_USE_COUNT;    return 0;}#endif/**************************************************************** * functions for struct fbgen_hwswitch member *//**** *  This function should detect the current video mode settings and store *  it as the default video mode */static voidmq200fb_detect(void){}/**** *  This function should fill in the 'fix' structure based on the values *  in the `par' structure. */static intmq200fb_encode_fix(struct fb_fix_screeninfo* fix,                  const void* par,                  struct fb_info_gen* info){    const struct mq200fb_par* mq200fb_par = par;    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;    strcpy(fix->id, CHIPNAME);#if LINUX_VERSION_CODE >= 0x020400    fix->smem_start = fb_info->regions.p_fb;    fix->mmio_start = fb_info->regions.p_regs;#else    fix->smem_start = (char*)fb_info->regions.p_fb;    fix->mmio_start = (char*)fb_info->regions.p_regs;#endif    fix->smem_len = fb_info->regions.fb_size;    fix->mmio_len = MQ200_REGS_SIZE;    fix->accel = FB_ACCEL_MEDIAQ_MQ200;    fix->type = FB_TYPE_PACKED_PIXELS;    fix->visual = is_color_palette_enabled(mq200fb_par)       ?  FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;    if (fb_info->current_par_valid)       fix->line_length = get_line_length(mq200fb_par);    else       fix->line_length = 0;    fix->xpanstep = 0;         /* $H$j$"$($: */    fix->ypanstep = 1;         /* $H$j$"$($: */    fix->ywrapstep = 0;    return 0;}/**** *  Get the video params out of 'var'. If a value doesn't fit, round it up, *  if it's too big, return -EINVAL. * *  Suggestion: Round up in the following order: bits_per_pixel, xres, *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, *  bitfields, horizontal timing, vertical timing. */static intmq200fb_decode_var(const struct fb_var_screeninfo *var,                  void* par,                  struct fb_info_gen *info){    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;    struct mq200fb_par* fb_par = (struct mq200fb_par*)par;    *fb_par = fb_info->current_par;    return 0;}/**** *  Fill the 'var' structure based on the values in 'par' and maybe other *  values read out of the hardware. */static intmq200fb_encode_var(struct fb_var_screeninfo* var,                  const void* par,                  struct fb_info_gen* info){    const struct mq200fb_par* mq200fb_par = par;    struct fb_var_screeninfo new_var;    memset(&new_var, 0, sizeof new_var);    new_var.xres_virtual = get_line_length(mq200fb_par) * 8;    new_var.yres_virtual = get_v_height(mq200fb_par);    new_var.xres = get_width(mq200fb_par);    new_var.yres = get_height(mq200fb_par);    new_var.right_margin = get_right_margin(mq200fb_par);    new_var.hsync_len = get_hsync_len(mq200fb_par);    new_var.left_margin = get_left_margin(mq200fb_par);    new_var.lower_margin = get_lower_margin(mq200fb_par);    new_var.vsync_len = get_vsync_len(mq200fb_par);    new_var.upper_margin = get_upper_margin(mq200fb_par);    new_var.bits_per_pixel = get_bits_per_pixel(mq200fb_par);    switch (get_bits_per_pixel(mq200fb_par)) {    case 1:    case 2:    case 4:    case 16:    case 24:    case 32:       PRINTK(CHIPNAME ": %d bpp is not supported depth.\n",              get_bits_per_pixel(mq200fb_par));       break;    case 8:       new_var.red.length = new_var.green.length = new_var.blue.length = 8;       break;    }    new_var.xoffset = get_xoffset(mq200fb_par);    new_var.yoffset = get_yoffset(mq200fb_par);    new_var.height = new_var.width = -1;    new_var.pixclock = get_pixclock(mq200fb_par);    new_var.sync = 0;    new_var.vmode = FB_VMODE_NONINTERLACED;    new_var.activate = FB_ACTIVATE_NOW;    *var = new_var;    return 0;}/**** *  Fill the hardware's 'par' structure. */static void mq200fb_get_par(void* par,                           struct fb_info_gen *info){    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;    if (! fb_info->current_par_valid) {//     mq200_reset(fb_info);       set_screen(fb_info, &fb_info->current_par);       fb_info->current_par_valid = 1;    }    *((struct mq200fb_par*)par) = fb_info->current_par;}/**** *  Set the hardware according to 'par'. */static void mq200fb_set_par(const void* par,                           struct fb_info_gen *info){    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;    struct mq200fb_par* fb_par = (struct mq200fb_par*)par;    set_screen(fb_info, fb_par);    fb_info->current_par = *fb_par;    fb_info->current_par_valid = 1;}/**** *  Read a single color register and split it into colors/transparent. *  The return values must have a 16 bit magnitude. *  Return != 0 for invalid regno. */static int mq200fb_getcolreg(unsigned regno,                            unsigned* red,                            unsigned* green,                            unsigned* blue,                            unsigned* transp,                            struct fb_info* info){    struct mq200fb_info* fb_info = (struct mq200fb_info*)info;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -