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

📄 mq200fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 */static voidvsync(){}/**** * interrupt handler. */static voidmq200_interrupt(int irq,               void* dev_id,               struct pt_regs* regs){    u32 status;    status = readl(IN02R(&mq200fb_info));    writel(status, IN02R(&mq200fb_info));    if (status & 0x02)       vsync();}/**** * enable interrupt controller. */static voidmq200_enable_irq(const struct mq200fb_info* fb_info){    writel(0x1F02, IN01R(fb_info)); /* unmask */    writel(1, IN00R(fb_info)); /* interrupt enable */}#endif/**** * Configure register and framebuffer addresses. * If you need to get virtual addresses using ioremap(), rewrite this * function. * * [RETURN] *     1: success *     0: fail */static int __initmq200fb_conf(struct mq200fb_info* fb_info){    /* set framebuffer related values */    fb_info->regions.p_fb = virt_to_phys((void*)MQ200_FB_BASE);    fb_info->regions.v_fb = MQ200_FB_BASE;    fb_info->regions.p_regs = virt_to_phys((void*)MQ200_REGS_BASE);    fb_info->regions.v_regs = MQ200_REGS_BASE;    fb_info->regions.fb_size = MQ200_FB_SIZE - CURSOR_IMAGE_SIZE;    /* set addresses of module register */    fb_info->pmu_base = fb_info->regions.v_regs + PMU_OFFSET;    fb_info->cpu_base = fb_info->regions.v_regs + CPU_OFFSET;    fb_info->miu_base = fb_info->regions.v_regs + MIU_OFFSET;    fb_info->in_base = fb_info->regions.v_regs + IN_OFFSET;    fb_info->gc_base = fb_info->regions.v_regs + GC_OFFSET;    fb_info->ge_base = fb_info->regions.v_regs + GE_OFFSET;    fb_info->fpi_base = fb_info->regions.v_regs + FPI_OFFSET;    fb_info->pci_base = fb_info->regions.v_regs + PCI_OFFSET;    fb_info->dc_base = fb_info->regions.v_regs + DC_OFFSET;    fb_info->cp1_base = fb_info->regions.v_regs + CP1_OFFSET;    fb_info->psf_base = fb_info->regions.v_regs + PSF_OFFSET;    if (! mq200_probe(fb_info)) {       printk(CHIPNAME ": MQ-200 not found.\n");       return 0;    }    PRINTK(CHIPNAME ": MQ-200 found.\n");    /* set cursor info */    init_timer(&fb_info->cursor_info.timer);    fb_info->cursor_info.timer.data = (unsigned long)fb_info;    fb_info->cursor_info.timer.function = cursor_timer_handler;    add_cursor_timer(&fb_info->cursor_info);    return 1;}/**** * [RETURN] *     1: detect *     0: not found */static int __initmq200_probe(struct mq200fb_info* fb_info){    union pc00r pc00r;    if (readl(PMR(fb_info)) != PMR_VALUE)       return 0;    pc00r.whole = readl(PC00R(fb_info));    fb_info->vendor_id = pc00r.part.vendor;    fb_info->device_id = pc00r.part.device;    return 1;}/**** * mq-200 hardware reset. */static voidmq200_reset(const struct mq200fb_info* fb_info){    power_state_transition(fb_info, 0);        /* transition to D0 state */    dc_reset(fb_info);         /* device configuration */    miu_reset(fb_info);                /* memory interface unit */    pmu_reset(fb_info);                /* power management unit */    gc1_reset(fb_info);                /* graphics controller 1 */    ge_reset(fb_info);         /* graphics engine */    cp1_reset(fb_info);                /* color palette 1 */}/**** * device configuration initialization. */static voiddc_reset(const struct mq200fb_info* fb_info){    union dc00r dc00r;    dc00r.whole = 0;    dc00r.part.osc_enbl = 1;    dc00r.part.pll1_enbl = 1;    dc00r.part.pll1_p_par = fb_info->current_par.pll[0].p_par;    dc00r.part.pll1_n_par = fb_info->current_par.pll[0].n_par;    dc00r.part.pll1_m_par = fb_info->current_par.pll[0].m_par;    dc00r.part.fast_pwr = 1;    dc00r.part.osc_frq = 3;    /* oscillator frequency is in the range of                                  12 MHz to 25 MHz */    writel(dc00r.whole, DC00R(fb_info));    PRINTK(CHIPNAME ": DC00R = %lx\n", readl(DC00R(fb_info)));}/**** * initialize memory interface unit. */static voidmiu_reset(const struct mq200fb_info* fb_info){    union mm00r mm00r;    union mm01r mm01r;    union mm02r mm02r;    union mm03r mm03r;    union mm04r mm04r;    /* MIU interface control 1 */    mm00r.whole = 0;    mm00r.part.miu_enbl = 1;    mm00r.part.mr_dsbl = 1;    writel(mm00r.whole, MM00R(fb_info));    mdelay(100);    writel(0, MM00R(fb_info));    mdelay(50);    /* MIU interface control 2     * o PLL 1 output is used as memory clock source.     */    mm01r.whole = 0;    mm01r.part.msr_enbl = 1;    mm01r.part.pb_cpu = 1;    mm01r.part.pb_ge = 1;    mm01r.part.mr_interval = 3744; /* normal memory refresh time interval */    writel(mm01r.whole, MM01R(fb_info));    /* memory interface control 3 */    mm02r.whole = 0;    mm02r.part.bs_stnr = 1;    /* burst count for STN read is four */    mm02r.part.bs_ge = 3;      /* burst count for graphics engine is eight */    mm02r.part.fifo_gc1 = 2;    mm02r.part.fifo_gc2 = 1;    mm02r.part.fifo_stnr = 2;    mm02r.part.fifo_stnw = 1;    mm02r.part.fifo_ge_src = 3;    mm02r.part.fifo_ge_dst = 3;    writel(mm02r.whole, MM02R(fb_info));    /* memory interface control 5 */    mm04r.whole = 0;    mm04r.part.latency = 1;    /* EDRAM latency 1 */    mm04r.part.dmm_cyc = 1;    mm04r.part.bnk_act_cls = 1;    writel(mm04r.whole, MM04R(fb_info));    /* memory interface control 4 */    mm03r.whole = 0;    mm03r.part.rd_late_req = 1;    mm03r.part.reserved_1 = 134; /* ? */    writel(mm03r.whole, MM03R(fb_info));    mdelay(10);    /* MIU interface control 1 */    writel(mm00r.whole, MM00R(fb_info));    mdelay(50);    PRINTK(CHIPNAME ": MIU reset.\n");}/**** * initialize power management unit. */static voidpmu_reset(const struct mq200fb_info* fb_info){    union pm00r pm00r;    union pm01r pm01r;    union pm02r pm02r;    union pm06r pm06r;    union pm07r pm07r;    /* power management miscellaneous control     * o GE is driven by PLL 1 clock.     */    pm00r.whole = 0;    pm00r.part.pll2_enbl = 1;    pm00r.part.pll3_enbl = 1;    pm00r.part.ge_enbl = 1;    pm00r.part.ge_bsy_gl = 1;    pm00r.part.ge_bsy_lcl = 1;    pm00r.part.ge_clock = 1;   /* GE is driven by PLL 1 clock */    pm00r.part.d3_mem_rfsh = 1;    writel(pm00r.whole, PM00R(fb_info));    mdelay(1);    writel(pm00r.whole & 0x6000, PM00R(fb_info));    mdelay(1);    /* D1 state control */    pm01r.whole = 0;    pm01r.part.osc_enbl = 1;    pm01r.part.pll1_enbl = 1;    pm01r.part.pll2_enbl = 1;    pm01r.part.miu_enbl = 1;    pm01r.part.mem_rfsh = 1;    pm01r.part.ge_enbl = 1;    pm01r.part.fpd_enbl = 1;    pm01r.part.ctl1_enbl = 1;    pm01r.part.awin1_enbl = 1;    writel(pm01r.whole, PM01R(fb_info));    /* D2 state control */    pm02r.whole = 0;    pm02r.part.osc_enbl = 1;    pm02r.part.pll1_enbl = 1;    pm02r.part.pll2_enbl = 1;    pm02r.part.miu_enbl = 1;    pm02r.part.mem_rfsh = 1;    pm02r.part.ge_enbl = 1;    writel(pm02r.whole, PM02R(fb_info));    /* PLL 2 programming */    pm06r.whole = 0;    pm06r.part.p_par = fb_info->current_par.pll[1].p_par;    pm06r.part.n_par = fb_info->current_par.pll[1].n_par;    pm06r.part.m_par = fb_info->current_par.pll[1].m_par;    writel(pm06r.whole, PM06R(fb_info));    /* PLL 3 programming */    pm07r.whole = 0;    pm07r.part.p_par = fb_info->current_par.pll[2].p_par;    pm07r.part.n_par = fb_info->current_par.pll[2].n_par;    pm07r.part.m_par = fb_info->current_par.pll[2].m_par;    writel(pm07r.whole, PM07R(fb_info));    writel(pm00r.whole, PM00R(fb_info));    PRINTK(CHIPNAME ": PMU reset.\n");}/**** * initialize graphics controller 1. */static voidgc1_reset(const struct mq200fb_info* fb_info){    unsigned long flags;    union gc00r gc00r;    union gc01r gc01r;    union gc02r gc02r;    union gc03r gc03r;    union gc04r gc04r;    union gc05r gc05r;    union gc08r gc08r;    union gc09r gc09r;    union gc0er gc0er;    union gc11r gc11r;    spin_lock_irqsave(&fb_info->lock, flags);    /* graphics controller CRT control */    gc01r.whole = 0;    gc01r.part.dac_enbl = 1;    gc01r.part.hsync_out = 1;    gc01r.part.vsync_out = 1;    writel(gc01r.whole, GC01R(fb_info));    /* horizontal display 1 control */    gc02r.whole = 0;    gc02r.part.hd1t = fb_info->current_par.gc[0].disp.hdt;    gc02r.part.hd1e = fb_info->current_par.gc[0].disp.hde;    writel(gc02r.whole, GC02R(fb_info));    /* vertical display 1 control */    gc03r.whole = 0;    gc03r.part.vd1t = fb_info->current_par.gc[0].disp.vdt;    gc03r.part.vd1e = fb_info->current_par.gc[0].disp.vde;    writel(gc03r.whole, GC03R(fb_info));    /* horizontal sync 1 control */    gc04r.whole = 0;    gc04r.part.hs1s = fb_info->current_par.gc[0].disp.hss;    gc04r.part.hs1e = fb_info->current_par.gc[0].disp.hse;    writel(gc04r.whole, GC04R(fb_info));    /* vertical sync 1 control */    gc05r.whole = 0;    gc05r.part.vs1s = fb_info->current_par.gc[0].disp.vss;    gc05r.part.vs1e = fb_info->current_par.gc[0].disp.vse;    writel(gc05r.whole, GC05R(fb_info));    /* horizontal window 1 control */    gc08r.whole = 0;    gc08r.part.hw1s = fb_info->current_par.gc[0].win.hws;    gc08r.part.hw1w = fb_info->current_par.gc[0].win.hww;    gc08r.part.w1ald = fb_info->current_par.gc[0].win.wald;    writel(gc08r.whole, GC08R(fb_info));    /* vertical window 1 control */    gc09r.whole = 0;    gc09r.part.vw1s = fb_info->current_par.gc[0].win.vws;    gc09r.part.vw1h = fb_info->current_par.gc[0].win.vwh;    writel(gc09r.whole, GC09R(fb_info));    /* alternate horizontal window 1 control */    writel(0, GC0AR(fb_info));    /* alternate vertical window 1 control */    writel(0, GC0BR(fb_info));    /* window 1 start address */    writel(fb_info->current_par.gc[0].win.wsa, GC0CR(fb_info));    /* alternate window 1 start address */    writel(0, GC0DR(fb_info));    /* window 1 stride */    gc0er.whole = 0;    gc0er.part.w1st = fb_info->current_par.gc[0].win.wst;    gc0er.part.aw1st = fb_info->current_par.gc[0].awin.wst;    writel(gc0er.whole, GC0ER(fb_info));    /* reserved register - ??? - */    writel(0x31f, GC0FR(fb_info));    /* hardware cursor 1 position */    writel(0, GC10R(fb_info));    /* hardware cursor 1 start address and offset */    gc11r.whole = 0;    gc11r.part.hc1sa = CURSOR_OFFSET >> 10;    writel(gc11r.whole, GC11R(fb_info));    /* hardware cursor 1 foreground color */    writel(0x00ffffff, GC12R(fb_info));    /* hardware cursor 1 background color */    writel(0x00000000, GC13R(fb_info));    /* graphics controller 1 register     * o GC1 clock source is PLL 2.     * o hardware cursor is enabled.     */    gc00r.whole = 0;    gc00r.part.ctl_enbl = 1;    gc00r.part.iwin_enbl = 1;    gc00r.part.gcd = fb_info->current_par.gc[0].gcd;    gc00r.part.hc_enbl = 1;   gc00r.part.agcd = fb_info->current_par.gc[0].agcd;    gc00r.part.g1rclk_src = 2; /* PLL 2 */    gc00r.part.fd = 0;         /* FD = 1 */    gc00r.part.sd = 1;         /* SD = 1 */    writel(gc00r.whole, GC00R(fb_info));    spin_unlock_irqrestore(&fb_info->lock, flags);    PRINTK(CHIPNAME ": GC1 reset.\n");}/**** * initialize graphics engine. */static voidge_reset(const struct mq200fb_info* fb_info){    /* drawing command register */    writel(0, GE00R(fb_info));    /* promary width and height register */    writel(0, GE01R(fb_info));    /* primary destination address register */    writel(0, GE02R(fb_info));    /* primary source XY register */    writel(0, GE03R(fb_info));    /* primary color compare register */    writel(0, GE04R(fb_info));    /* primary clip left/top register */    writel(0, GE05R(fb_info));    /* primary clip right/bottom register */    writel(0, GE06R(fb_info));    /* primary source and pattern offset register */    writel(0, GE07R(fb_info));    /* primary foreground color register/rectangle fill color depth */    writel(0, GE08R(fb_info));    /* source stride/offset register */    writel(0, GE09R(fb_info));    /* destination stride register and color depth */    writel(0, GE0AR(fb_info));    /* image base address register */    writel(0, GE0BR(fb_info));    PRINTK(CHIPNAME ": GE reset.\n");}/**** * initialize Color Palette 1. */static voidcp1_reset(const struct mq200fb_info* fb_info){    int i;    for (i = 0; i < 256; i++)       writel(0, C1xxR(fb_info, i));}/**** * change screen size and depth, and so on. * Right now, screen attributes modification is not implemeted. */static voidset_screen(const struct mq200fb_info* fb_info,          const struct mq200fb_par* par){    unsigned long flags;    union ge0ar ge0ar;    /* set destination stride and color depth for GE */    ge0ar.whole = 0;    ge0ar.part.dst_strid = get_line_length(par);    switch (get_bits_per_pixel(par)) {    case 8:       ge0ar.part.col_dpth = 0;       break;    case 16:       ge0ar.part.col_dpth = 1;       break;    case 32:       ge0ar.part.col_dpth = 3;       break;    default:       printk(CHIPNAME ": unexpected %d bits/pixel\n",              get_bits_per_pixel(par));       break;    }    spin_lock_irqsave(&fb_info->lock, flags);    writel(ge0ar.whole, GE0AR(fb_info));    spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * set hardware cursor shape. * * [NOTE] *     This function assume that cursor width is less than or equal to 64 *     pixels. */static voidset_cursor_shape(const struct mq200fb_info* fb_info){    static int already_created;    static u32 cursor_images[2][256];    unsigned long flags;    u32 image;    if (! already_created) {       u16 and_bits[4], xor_bits[4];       u32 transparent = 0x0000FFFF;       int line, i;       /*        * set "CM_DRAW" cursor shape        */       image = fb_info->regions.v_fb + CURSOR_OFFSET;       /* inverse transparency */       for (i = 0; i < fb_info->cursor_info.size.x / 16; i++)           and_bits[i] = xor_bits[i] = ~0;       /* partially inverse transparency */       and_bits[i] = ~0;       xor_bits[i] = (u16)~0 >> (16 - fb_info->cursor_info.size.x % 16);       /* rest is transparent */       while (++i < 4) {           and_bits[i] = ~0;           xor_bits[i] = 0;       }       spin_lock_irqsave(&fb_info->lock, flags);       for (line = 0; line < fb_info->cursor_info.size.y; line++)           for (i = 0; i < 4; i++) {               writel(((u32)xor_bits[i] << 16) | (u32)and_bits[i], image);               image += 4;           }       while (line++ < 64)           for (i = 0; i < 4; i++) {               writel(transparent, image);               image += 4;           }       /*        * set "CM_ERASE" cursor shape        */       image = fb_info->regions.v_fb + CURSOR_OFFSET + 1024;       for (line = 0; line < 64; line++)           for (i = 0; i < 4; i++) {               writel(transparent, image);               image += 4;           }

⌨️ 快捷键说明

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