ok6410的LCD驱动
来源:互联网 发布:c语言数组 编辑:程序博客网 时间:2024/06/06 09:45
经过 几天的研究 终于在飞凌的6410板子上的LCD出现了一些字符,虽然还有些不完美 就是那些字符不清晰,先写下来,我继续调这个bug。
飞凌的开发板首先要屏蔽自身的LCD驱动,在上一篇的博客中已经说过,这里不说了。我的代码 也是参考了别人了的,都大同小异,我感觉最大的区别可能是飞凌的板子LCD的电源控制和背光控制不需要人为控制,他的硬件是直接连通,上电LCD就会亮。我的代码如下:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <asm/uaccess.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/clk.h>#include <linux/dma-mapping.h>static struct fb_info *s3c_lcd_info;static u32 s3c_pseudo_palette[16];static volatile unsigned long *gpbcon;static volatile unsigned long *gpbdat;static volatile unsigned long *gpfcon;static volatile unsigned long *gpfdat;static volatile unsigned long *gpicon;static volatile unsigned long *gpjcon;static volatile unsigned long *mifpcon;static volatile unsigned long *spcon;struct s3c6410_lcd_regs {unsigned long vidcon0;unsigned long vidcon1;unsigned long vidcon2;unsigned long reserver1;unsigned long vidtcon0;unsigned long vidtcon1;unsigned long vidtcon2;unsigned long reserver2;unsigned long wincon0;unsigned long wincon1;unsigned long wincon2;unsigned long wincon3;unsigned long wincon4;unsigned long reserver3[3];unsigned long vidosd0a;unsigned long vidosd0b;unsigned long vidosd0c;unsigned long reserver4;unsigned long vidosd1a;unsigned long vidosd1b;unsigned long vidosd1c;unsigned long vidosd1d;unsigned long vidosd2a;unsigned long vidosd2b;unsigned long vidosd2c;unsigned long vidosd2d;unsigned long vidosd3a;unsigned long vidosd3b;unsigned long vidosd3c;unsigned long reserver5;unsigned long vidosd4a;unsigned long vidosd4b;unsigned long vidosd4c;unsigned long reserver6[5];unsigned long vidw00add0b0;unsigned long vidw00add0b1;unsigned long vidw01add0b0;unsigned long vidw01add0b1;unsigned long vidw02add0;unsigned long reserver7;unsigned long vidw03add0;unsigned long reserver8;unsigned long vidw04add0;unsigned long reserver9[3];unsigned long vidw00add1b0;unsigned long vidw00add1b1;};static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf){chan &= 0xffff;chan >>= 16 - bf->length;return chan << bf->offset;}static int s3c_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, unsigned int transp, struct fb_info *info){unsigned int val;if (regno > 16)return 1;u32 *pal = info->pseudo_palette;/* 用red,green,blue三原色构造出val */val = chan_to_field(red,&info->var.red);val |= chan_to_field(green, &info->var.green);val |= chan_to_field(blue,&info->var.blue);pal[regno] = val;return 0;}static struct fb_ops s3c_fb_ops = {.owner = THIS_MODULE,.fb_setcolreg= s3c_fb_setcolreg,.fb_fillrect= cfb_fillrect,.fb_copyarea= cfb_copyarea,.fb_imageblit= cfb_imageblit,};static struct s3c6410_lcd_regs * lcd_regs;static int s3c_lcd_init(void){struct clk *clk;int hclk;int clkval;/* 1. 分配fb_info */s3c_lcd_info = framebuffer_alloc(0, NULL);/* 2. 设置 *//* 2.1 设置固定的信息 */strcpy(s3c_lcd_info->fix.id, "uplooking_lcd");s3c_lcd_info->fix.smem_len = 480*272*2;s3c_lcd_info->fix.type = FB_TYPE_PACKED_PIXELS;s3c_lcd_info->fix.visual = FB_VISUAL_TRUECOLOR;s3c_lcd_info->fix.line_length = 480*2;/* 2.2 设置可变的信息 */s3c_lcd_info->var.xres = 480;s3c_lcd_info->var.yres = 272;s3c_lcd_info->var.xres_virtual = 480;s3c_lcd_info->var.yres_virtual = 272;s3c_lcd_info->var.bits_per_pixel = 16;s3c_lcd_info->var.red.length = 5;s3c_lcd_info->var.red.offset = 11;s3c_lcd_info->var.green.length = 6;s3c_lcd_info->var.green.offset = 5;s3c_lcd_info->var.blue.length = 5;s3c_lcd_info->var.blue.offset = 0;s3c_lcd_info->var.activate = FB_ACTIVATE_NOW;/* 2.3 设置操作函数 */s3c_lcd_info->fbops = &s3c_fb_ops;/* 2.4 设置其他信息 *///s3c_lcd_info->screen_base = ;/* 显存的虚拟地址 */s3c_lcd_info->screen_size = 480*272*2;s3c_lcd_info->pseudo_palette = &s3c_pseudo_palette;/* 4. 硬件相关的操作 *//* 4.1 配置GPIO用于LCD */gpicon = ioremap(0x7F008100, 4);*gpicon = 0xAAAAAAAA;gpjcon = ioremap(0x7F008120, 4);*gpjcon = 0xAAAAAAAA;gpbcon = ioremap(0x7F008020, 4);gpbdat = gpbcon + 1;gpfcon = ioremap(0x7F0080A0, 4);gpfdat = gpfcon + 1;/* 4.2 根据LCD的性能设置LCD控制器 *//* MIFPCON */mifpcon = ioremap(0x7410800C, 4);*mifpcon &= ~(1<<3);spcon = ioremap(0x7F0081A0, 4);*spcon &= ~(3);*spcon |= 1;lcd_regs = ioremap(0x77100000, sizeof(struct s3c6410_lcd_regs));clk = clk_get(NULL, "lcd");clk_enable(clk); /* HCLK_GATE[3]设为1 *//* HCLK_GATE = ioremap(0x7E00F030, 4);* HCLK_GATE |= (1<<3);*//* bit[13:6], CLKVAL_F,VCLK = Video Clock Source / (CLKVAL+1) VCLK = 9000000 CLKVAL_F = hclk/9000000 - 1 * bit[3:2], CLKSEL_F, 00 = HCLK * bit[1], ENVID-使能LCD控制器的输出, 先设为0, 最后全部设置好了再设为1 */clk = clk_get(NULL, "hclk");hclk = clk_get_rate(clk);clkval = hclk/9000000 - 1;printk(KERN_INFO "hclk = %d, clkval = %d\n", hclk, clkval);lcd_regs->vidcon0 = (0<<29)|(0<<26) | (0<<17) | (clkval << 6) | (1<<4);/* bit[7], 0-在VLCK下降沿读数据 * bit[6], HSYNC低脉冲有效 * bit[5], VSYNC低脉冲有效 * bit[4], VDEN高电平有效 */lcd_regs->vidcon1 = (0<<7) | (1<<6) | (1<<5) | (0<<4);/* LCD手册P11 * tvp = 10, tvb = 2, tvf=2 */lcd_regs->vidtcon0 = (2<<16) | (2<<8) | (10<<0); /*修改了 都加1*//* LCD手册P11 * thp = 41, thb = 2, thf=2 */lcd_regs->vidtcon1 = (1<<16) | (1<<8) | (40<<0);lcd_regs->vidtcon2 = (271<<11) | (479<<0);/* 4.3 分配显存, 并告诉LCD控制器 */s3c_lcd_info->screen_base = dma_alloc_writecombine(NULL, s3c_lcd_info->screen_size, &s3c_lcd_info->fix.smem_start, GFP_KERNEL);/* bit[17],BSWP = 0, bit[16],HWSWP = 0 * bit[5:2],BPPMODE_F, 0b1011, 24bpp * bit[0], ENWIN_F, 0-先不使能 */lcd_regs->wincon0 &= ~(0xf << 2);//lcd_regs->wincon0 |= (0xb<<2); /* unpacked 24 BPP (non-palletized R:8-G:8-B:8 ) */lcd_regs->wincon0 |= (0x5<<2); #define LeftTopX 0#define LeftTopY 0#define RightBotX 479#define RightBotY 271lcd_regs->vidosd0a = (LeftTopX<<11) | (LeftTopY << 0);lcd_regs->vidosd0b = (RightBotX<<11) | (RightBotY << 0);//lcd_regs->vidosd0c = 480*272/2;lcd_regs->vidosd0c = 480*272;lcd_regs->vidw00add0b0 = s3c_lcd_info->fix.smem_start;lcd_regs->vidw00add1b0 = (s3c_lcd_info->fix.smem_start + s3c_lcd_info->fix.smem_len) & 0xffffff;/* 4.4 使能 */lcd_regs->vidcon0 |= (3); /* 使能LCD控制器输出信号 */lcd_regs->wincon0 |= (1<<0); /* 使能窗口0 *//* 3. 注册 */register_framebuffer(s3c_lcd_info);return 0;}static void s3c_lcd_exit(void){struct clk *clk;unregister_framebuffer(s3c_lcd_info);lcd_regs->vidcon0 &= ~(1<<1); /* 禁止LCD控制器输出信号 */lcd_regs->wincon0 &= ~(1<<0); /* 禁止窗口0 */dma_free_writecombine(NULL, s3c_lcd_info->screen_size, s3c_lcd_info->screen_base, s3c_lcd_info->fix.smem_start);clk = clk_get(NULL, "lcd");clk_disable(clk); /* HCLK_GATE[3]设为0 */iounmap(lcd_regs);iounmap(gpbcon);iounmap(gpfcon);iounmap(gpicon);iounmap(gpjcon);iounmap(mifpcon);iounmap(spcon);framebuffer_release(s3c_lcd_info);}module_init(s3c_lcd_init);module_exit(s3c_lcd_exit);MODULE_LICENSE("GPL");
其中 有注释 。欢迎留言,一起讨论!
0 0
- OK6410的LCD驱动
- ok6410的LCD驱动
- OK6410 LCD驱动移植
- 【OK6410裸机程序】LCD驱动
- Linux3.8.3在OK6410平台的移植LCD驱动
- 基于OK6410的LCD操作
- 基于ok6410的韦东山驱动视频简要分析--lcd驱动
- OK6410的按键驱动
- OK6410的LED驱动
- OK6410的ds18b20驱动
- 让OK6410 linux支持自己的LCD
- 飞凌OK6410之LCD的学习
- OK6410 LCD驱动移植,主要参考LCD驱动都涉及了哪些文件!
- ok6410 官方的驱动卸载
- 基于OK6410的触摸屏驱动
- LCD驱动的问题
- LCD驱动的移植
- 6410的lcd驱动
- 利用Object的wait、notify来实现线程同步原理
- Ant脚本模板,仅供参考
- php session 跨域的解决办法
- 利用microtime()函数计算程序运行时间
- activity清除的所有方法
- ok6410的LCD驱动
- Servlet系列(一)----Servlet简介
- C++模版是怎么一回事
- Jquery 的Ajax 注意事项
- OpenCV基础篇之像素访问
- 2048游戏动画渲染animframe_polyfill.js
- Python和Django安装步骤
- linux(debian)系统django配远程连接sqlserver数据库
- [LeetCode] Largest Rectangle in Histogram