Driver: s3c2410 LCD 和 Framebuffer驱动

s3c2410 LCD 和 Framebuffer驱动

s3c2410 lcd 控制器,属于 平台设备。系统启动后,会安装这个平台设备。
->
int __devinit s3c2410fb_init(void)
{
 return driver_register(&s3c2410fb_driver);
}
->系统回调
int __init s3c2410fb_probe(struct device *dev)
函数
->系统回调的参数比较重要,上面函数的回调参数为
s3c_device_lcd.dev

->系统s3c2410fb_probe最终目的,是注册 register_framebuffer(fbinfo);

->通过 s3c2410fb_probe 一些列动作,将 lcd驱动和framebuffer结合在一起。

->上层应用程序,主要是跟 framebuffer 打交道。如果需要设定lcd控制器这边时,便
会通过framebuffer的 struct fb_ops *fbops; 于 Lcd控制器 产生关联。

需要仔细研究的几个地方:
1)struct platform_device *pdev = to_platform_device(dev);
2)s3c2410fb_init_registers(info);
3)同1)原理大同小异,clk_get(NULL, "lcd");
4)ret = s3c2410fb_map_video_memory(info);此处得到关联dma,得到比较关键的smem_start地址。
5)ret = register_framebuffer(fbinfo); 此处,在数据及寄存器初始化完成后,于framebuffer关联。

===========================================================================
如下是涉及到相关的结构体和函数
/* LCD Controller */

static struct resource s3c_lcd_resource[] = {
 [0] = {
  .start = S3C2410_PA_LCD,
  .end   = S3C2410_PA_LCD + S3C24XX_SZ_LCD,
  .flags = IORESOURCE_MEM,
 },
 [1] = {
  .start = IRQ_LCD,
  .end   = IRQ_LCD,
  .flags = IORESOURCE_IRQ,
 }

};

static u64 s3c_device_lcd_dmamask = 0xffffffffUL;

struct platform_device s3c_device_lcd = {
 .name    = "s3c2410-lcd",
 .id    = -1,
 .num_resources   = ARRAY_SIZE(s3c_lcd_resource),
 .resource   = s3c_lcd_resource,
 .dev              = {
  .dma_mask  = &s3c_device_lcd_dmamask,
  .coherent_dma_mask = 0xffffffffUL
 }
};


EXPORT_SYMBOL(s3c_device_lcd);

static struct s3c2410fb_mach_info s3c2410fb_info;

void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info)
{
 memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info));
 s3c_device_lcd.dev.platform_data = &s3c2410fb_info;
}
EXPORT_SYMBOL(set_s3c2410fb_info);


static struct s3c2410fb_mach_info smdk2410_lcdcfg

__initdata = {

               .fixed_syncs= 0,

               .regs={

.lcdcon1=(7<<8)|(0<<7)|(3<<5)|(12<<1),
.lcdcon2=(14<<24)|(239<<14)|(11<<6)|2,
.lcdcon3=(37<<19)|(319<<8)|19,
.lcdcon4=(13<<8)|29,
.lcdcon5=(1<<11)|(1<<10)|(1<<9)|(1<<8)|(0<<7)|(0<<6)|(1<<5)|(1<<3)|(0<<1)|(1),
                        },

                .lpcsel=    0x0,

                .gpccon=    0xaaaaaaaa,

                .gpccon_mask=   0xffffffff,

                .gpcup=     0xffffffff,

                .gpcup_mask=    0xffffffff,

                .gpdcon=    0xaaaaaaaa,

                .gpdcon_mask=   0x0,

                .gpdup=     0xffffffff,

                .gpdup_mask=    0xffffffff,

                .width=     320,

                .height=    240,
    .xres=      {320,320,320},

                .yres=      {240,240,240},

                .bpp=       {16,16,16},

                            };

 static void __init sdmk2410_init(void)
{

 u32 upll_value;
 set_s3c2410fb_info(&smdk2410_lcdcfg);
 ......
}

MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
        * to SMDK2410 */
 /* Maintainer: Jonas Dietsche */
 .phys_ram = S3C2410_SDRAM_PA,
 .phys_io = S3C2410_PA_UART,
 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 .boot_params = S3C2410_SDRAM_PA + 0x100,
 .map_io  = smdk2410_map_io,
 .init_irq = smdk2410_init_irq,
  .init_machine   = sdmk2410_init,
 .timer  = &s3c24xx_timer,
MACHINE_END


device.h include/linux

struct device {
 struct klist  klist_children;
 struct klist_node knode_parent;  /* node in sibling list */
 struct klist_node knode_driver;
 struct klist_node knode_bus;
 struct device  * parent;

 struct kobject kobj;
 char bus_id[BUS_ID_SIZE]; /* position on parent bus */

 struct semaphore sem; /* semaphore to synchronize calls to
      * its driver.
      */

 struct bus_type * bus;  /* type of bus device is on */
 struct device_driver *driver; /* which driver has allocated this
        device */
 void  *driver_data; /* data private to the driver */
 void  *platform_data; /* Platform specific data, device
        core doesn't touch it */
 void  *firmware_data; /* Firmware specific data (e.g. ACPI,
        BIOS data),reserved for device core*/
 struct dev_pm_info power;

 u64  *dma_mask; /* dma mask (if dma'able device) */
 u64  coherent_dma_mask;/* Like dma_mask, but for
          alloc_coherent mappings as
          not all hardware supports
          64 bit addresses for consistent
          allocations such descriptors. */

 struct list_head dma_pools; /* dma pools (if dma'ble) */

 struct dma_coherent_mem *dma_mem; /* internal for coherent mem
          override */

 void (*release)(struct device * dev);
};


struct platform_device {
 const char * name;
 u32  id;
 struct device dev;
 u32  num_resources;
 struct resource * resource;
};

int __init s3c2410fb_probe(struct device *dev)回调时传递的参数即为:s3c_device_lcd.dev

而后通过:struct platform_device *pdev = to_platform_device(dev);

得到 s3c_device_lcd地址


struct s3c2410fb_val {
 unsigned int defval;
 unsigned int min;
 unsigned int max;
};

struct s3c2410fb_hw {
 unsigned long lcdcon1;
 unsigned long lcdcon2;
 unsigned long lcdcon3;
 unsigned long lcdcon4;
 unsigned long lcdcon5;
};
struct s3c2410fb_mach_info {
 unsigned char fixed_syncs; /* do not update sync/border */

 /* Screen size */
 int  width;
 int  height;

 /* Screen info */
 struct s3c2410fb_val xres;
 struct s3c2410fb_val yres;
 struct s3c2410fb_val bpp;

 /* lcd configuration registers */
 struct s3c2410fb_hw  regs;

 /* GPIOs */

 unsigned long gpcup;
 unsigned long gpcup_mask;
 unsigned long gpccon;
 unsigned long gpccon_mask;
 unsigned long gpdup;
 unsigned long gpdup_mask;
 unsigned long gpdcon;
 unsigned long gpdcon_mask;

 /* lpc3600 control register */
 unsigned long lpcsel;
};

 

struct fb_info {
 int node;
 int flags;
 struct fb_var_screeninfo var; /* Current var */
 struct fb_fix_screeninfo fix; /* Current fix */
 struct fb_monspecs monspecs; /* Current Monitor specs */
 struct work_struct queue; /* Framebuffer event queue */
 struct fb_pixmap pixmap; /* Image hardware mapper */
 struct fb_pixmap sprite; /* Cursor hardware mapper */
 struct fb_cmap cmap;  /* Current cmap */
 struct list_head modelist;      /* mode list */
 struct fb_videomode *mode; /* current mode */
 struct fb_ops *fbops;
 struct device *device;
 struct class_device *class_device; /* sysfs per device attrs */
#ifdef CONFIG_FB_TILEBLITTING
 struct fb_tile_ops *tileops;    /* Tile Blitting */
#endif
 char __iomem *screen_base; /* Virtual address */
 unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */
 void *pseudo_palette;  /* Fake palette of 16 colors */
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
 u32 state;   /* Hardware state i.e suspend */
 void *fbcon_par;                /* fbcon use-only private area */
 /* From here on everything is device dependent */
 void *par; 
};


struct s3c2410fb_info {
 struct fb_info  *fb;
 struct device  *dev;
 struct clk  *clk;

 struct s3c2410fb_mach_info *mach_info;

 /* raw memory addresses */
 dma_addr_t  map_dma; /* physical */
 u_char *  map_cpu; /* virtual */
 u_int   map_size;

 struct s3c2410fb_hw regs;

 /* addresses of pieces placed in raw buffer */
 u_char *  screen_cpu; /* virtual address of buffer */
 dma_addr_t  screen_dma; /* physical address of buffer */
 unsigned int  palette_ready;

 /* keep these registers in case we need to re-write palette */
 u32   palette_buffer[256];
 u32   pseudo_pal[16];
};

#define PALETTE_BUFF_CLEAR (0x80000000) /* entry is clear/invalid */


fbi->fb->fix.smem_start  = fbi->screen_dma; //申请DMA映射时,得到地址


struct fb_var_screeninfo {
 __u32 xres;   /* visible resolution  */
 __u32 yres;
 __u32 xres_virtual;  /* virtual resolution  */
 __u32 yres_virtual;
 __u32 xoffset;   /* offset from virtual to visible */
 __u32 yoffset;   /* resolution   */

 __u32 bits_per_pixel;  /* guess what   */
 __u32 grayscale;  /* != 0 Graylevels instead of colors */

 struct fb_bitfield red;  /* bitfield in fb mem if true color, */
 struct fb_bitfield green; /* else only length is significant */
 struct fb_bitfield blue;
 struct fb_bitfield transp; /* transparency   */ 

 __u32 nonstd;   /* != 0 Non standard pixel format */

 __u32 activate;   /* see FB_ACTIVATE_*  */

 __u32 height;   /* height of picture in mm    */
 __u32 width;   /* width of picture in mm     */

 __u32 accel_flags;  /* (OBSOLETE) see fb_info.flags */

 /* Timing: All values in pixclocks, except pixclock (of course) */
 __u32 pixclock;   /* pixel clock in ps (pico seconds) */
 __u32 left_margin;  /* time from sync to picture */
 __u32 right_margin;  /* time from picture to sync */
 __u32 upper_margin;  /* time from sync to picture */
 __u32 lower_margin;
 __u32 hsync_len;  /* length of horizontal sync */
 __u32 vsync_len;  /* length of vertical sync */
 __u32 sync;   /* see FB_SYNC_*  */
 __u32 vmode;   /* see FB_VMODE_*  */
 __u32 rotate;   /* angle we rotate counter clockwise */
 __u32 reserved[5];  /* Reserved for future compatibility */
};


struct fb_fix_screeninfo {
 char id[16];   /* identification string eg "TT Builtin" */
 unsigned long smem_start; /* Start of frame buffer mem */
     /* (physical address) */
 __u32 smem_len;   /* Length of frame buffer mem */
 __u32 type;   /* see FB_TYPE_*  */
 __u32 type_aux;   /* Interleave for interleaved Planes */
 __u32 visual;   /* see FB_VISUAL_*  */
 __u16 xpanstep;   /* zero if no hardware panning  */
 __u16 ypanstep;   /* zero if no hardware panning  */
 __u16 ywrapstep;  /* zero if no hardware ywrap    */
 __u32 line_length;  /* length of a line in bytes    */
 unsigned long mmio_start; /* Start of Memory Mapped I/O   */
     /* (physical address) */
 __u32 mmio_len;   /* Length of Memory Mapped I/O  */
 __u32 accel;   /* Indicate to driver which */
     /*  specific chip/card we have */
 __u16 reserved[3];  /* Reserved for future compatibility */
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值