我是靠谱客的博主 体贴黑猫,最近开发中收集的这篇文章主要介绍frame buffer驱动,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

因为移植的需要,对linux内核的fb驱动进行了封装,但是由于以前没有调试过fb驱动所以还是遇到了很多未知的问题,所以先把封装好的驱动移植到uboot中进行调试,下面是为这次fb驱动移植所做的总结:

     首先在这篇文章中把代码贴出来,后续文章对fb驱动移植进行总结!!!


1.uboot中frame buffer hal驱动的头文件:

#ifndef __JZ_FB_HAL_H__
#define __JZ_FB_HAL_H__
/* smart lcd init code type */
enum smart_config_type {
SMART_CONFIG_CMD = 0,
SMART_CONFIG_DATA = 1,
SMART_CONFIG_UDELAY = 2,
};
struct smart_lcd_data_table {
enum smart_config_type type;
uint32_t value;
};
struct fb_videomode {
const char *name;	/* optional */
u32 refresh;
/* optional */
u32 xres;
u32 yres;
u32 pixclock;
u32 left_margin;
u32 right_margin;
u32 upper_margin;
u32 lower_margin;
u32 hsync_len;
u32 vsync_len;
u32 sync;
u32 vmode;
u32 flag;
};
struct jz_fb_dma_descriptor {
u_long fdadr;
/* Frame descriptor address register */
u_long fsadr;
/* Frame source address register */
u_long fidr;
/* Frame ID register */
u_long ldcmd;
/* Command register */
u_long offsize;
/* Stride Offsize(in word) */
u_long page_width;	/* Stride Pagewidth(in word) */
u_long cmd_num;
/* Command Number(for SLCD) */
u_long desc_size;	/* Foreground Size */
};
/**
* @next: physical address of next frame descriptor
* @databuf: physical address of buffer
* @id: frame ID
* @cmd: DMA command and buffer length(in word)
* @offsize: DMA off size, in word
* @page_width: DMA page width, in word
* @cpos: smart LCD mode is commands' number, other is bpp,
* premulti and position of foreground 0, 1
* @desc_size: alpha and size of foreground 0, 1
*/
struct jzfb_framedesc {
uint32_t next;
uint32_t databuf;
uint32_t id;
uint32_t cmd;
uint32_t offsize;
uint32_t page_width;
uint32_t cpos;
uint32_t desc_size;
};
/**
* @framedesc: framedesc pointer
* @framedesc_phys: framedesc phys address
* @databuf: phys address to databuf, 0 if not enable this fg
* @bpp: foreground bpp
* @x: foreground start position x
* @y: foreground start position y
* @w: foreground width
* @h: foreground height
*/
struct jzfb_fg_t {
struct jzfb_framedesc *framedesc;
long framedesc_phys;
u32 databuf;
u32 bpp;
u32 x;
u32 y;
u32 w;
u32 h;
u32 line_length;
};
enum format_order {
FORMAT_X8R8G8B8 = 1,
FORMAT_X8B8G8R8,
};
/* LCD controller supported display device output mode */
enum lcd_type {
LCD_TYPE_GENERIC_16_BIT = 0,
LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 7),
LCD_TYPE_GENERIC_24_BIT = 0 | (1 << 6),
LCD_TYPE_SPECIAL_TFT_1 = 1,
LCD_TYPE_SPECIAL_TFT_2 = 2,
LCD_TYPE_SPECIAL_TFT_3 = 3,
LCD_TYPE_NON_INTERLACED_TV = 4 | (1 << 26),
LCD_TYPE_INTERLACED_TV = 6 | (1 << 6) | (1 << 30),
LCD_TYPE_8BIT_SERIAL = 0xc,
LCD_TYPE_SLCD = 0xd | (1 << 31),
};
/* smart lcd interface_type */
enum smart_lcd_type {
SMART_LCD_TYPE_PARALLEL,
SMART_LCD_TYPE_SERIAL,
};
/* smart lcd command width */
enum smart_lcd_cwidth {
SMART_LCD_CWIDTH_16_BIT_ONCE = (0 << 8),
SMART_LCD_CWIDTH_9_BIT_ONCE = SMART_LCD_CWIDTH_16_BIT_ONCE,
SMART_LCD_CWIDTH_8_BIT_ONCE = (0x1 << 8),
SMART_LCD_CWIDTH_18_BIT_ONCE = (0x2 << 8),
SMART_LCD_CWIDTH_24_BIT_ONCE = (0x3 << 8),
};
/* smart lcd data width */
enum smart_lcd_dwidth {
SMART_LCD_DWIDTH_18_BIT_ONCE_PARALLEL_SERIAL = (0 << 10),
SMART_LCD_DWIDTH_16_BIT_ONCE_PARALLEL_SERIAL = (0x1 << 10),
SMART_LCD_DWIDTH_8_BIT_THIRD_TIME_PARALLEL = (0x2 << 10),
SMART_LCD_DWIDTH_8_BIT_TWICE_TIME_PARALLEL = (0x3 << 10),
SMART_LCD_DWIDTH_8_BIT_ONCE_PARALLEL_SERIAL = (0x4 << 10),
SMART_LCD_DWIDTH_24_BIT_ONCE_PARALLEL = (0x5 << 10),
SMART_LCD_DWIDTH_9_BIT_TWICE_TIME_PARALLEL = (0x7 << 10),
SMART_LCD_DWIDTH_MASK = (0x7 << 10)
};
/* smart lcd new data width */
enum smart_lcd_new_dwidth {
SMART_LCD_NEW_DWIDTH_24_BIT = (4 << 13),
SMART_LCD_NEW_DWIDTH_18_BIT = (3 << 13),
SMART_LCD_NEW_DWIDTH_16_BIT = (2 << 13),
SMART_LCD_NEW_DWIDTH_9_BIT = (1 << 13),
SMART_LCD_NEW_DWIDTH_8_BIT = (0 << 13),
};
/* smart lcd data times */
enum smart_lcd_new_dtimes {
SMART_LCD_NEW_DTIMES_ONCE = (0 << 8),
SMART_LCD_NEW_DTIMES_TWICE = (1 << 8),
SMART_LCD_NEW_DTIMES_THICE = (2 << 8),
SMART_LCD_NEW_DTIMES_MASK = (3 << 8),
};
struct jzfb_hal {
int base;
unsigned int is_enable:1;
struct fb_videomode *mode;
enum lcd_type lcd_type;
enum format_order fmt_order;	/* frame buffer pixel format order */
unsigned int bpp;
unsigned pinmd:1;
unsigned booting:1;
unsigned pixclk_falling_edge:1;
unsigned data_enable_active_low:1;
struct {
enum smart_lcd_type smart_type;
unsigned clkply_active_rising:1;
unsigned rsply_cmd_high:1;
unsigned csply_active_high:1;
unsigned newcfg_6800_md:1;
unsigned newcfg_fmt_conv:1;
unsigned newcfg_datatx_type:1;
unsigned newcfg_cmdtx_type:1;
unsigned newcfg_cmd_9bit:1;
size_t length_cmd;
unsigned long *write_gram_cmd;
unsigned bus_width;
unsigned int length_data_table; /* array size of data table */
struct smart_lcd_data_table *data_table; /* init data table */
} smart_config;
unsigned dither_enable:1;
struct {
unsigned dither_red;
unsigned dither_green;
unsigned dither_blue;
} dither;
struct {
uint32_t spl;
uint32_t cls;
uint32_t ps;
uint32_t rev;
} special_tft_config;
struct jzfb_framedesc *cmd_framedesc;
long cmd_framedesc_phys;
struct jzfb_fg_t fg0;
struct jzfb_fg_t fg1;
};
#define PICOS2KHZ(a) (1000000000/(a))
#define KHZ2PICOS(a) (1000000000/(a))
#define FB_MODE_IS_VGA (1 << 30)
#define FB_SYNC_HOR_HIGH_ACT
1	/* horizontal sync high active
*/
#define FB_SYNC_VERT_HIGH_ACT
2	/* vertical sync high active
*/
#define FB_SYNC_EXT
4	/* external sync
*/
#define FB_SYNC_COMP_HIGH_ACT
8	/* composite sync high active
*/
#define FB_SYNC_BROADCAST	16	/* broadcast video timings
*/
/* vtotal = 144d/288n/576i => PAL
*/
/* vtotal = 121d/242n/484i => NTSC */
#define FB_SYNC_ON_GREEN	32	/* sync on green */
#define FB_VMODE_NONINTERLACED
0	/* non interlaced */
#define FB_VMODE_INTERLACED	1	/* interlaced
*/
#define FB_VMODE_DOUBLE
2	/* double scan */
#define FB_VMODE_ODD_FLD_FIRST	4	/* interlaced: top line first */
#define FB_VMODE_MASK
255
extern struct fb_videomode jzfb1_videomode;
extern void jzfb_hal_enable(struct jzfb_hal *hal);
extern void jzfb_hal_disable(struct jzfb_hal *hal);
extern void jzfb_hal_refresh_pixclock_auto_adapt(struct jzfb_hal *hal);
extern int jzfb_hal_set_par(struct jzfb_hal *hal);
#endif /* __JZ_FB_HAL_H__ */

2.uboot中frame buffer hal的驱动代码:

#include <common.h>
#include <asm/io.h>
#include <asm/arch/lcdc.h>
#include <jz_lcd/jz_lcd_v1_2.h>
#ifdef debug
#undef debug
#define debug printf
#endif
#ifdef error
#undef error
#define error printf
#endif
#define hal_reg_write(hal, addr, config)

writel(config, hal->base + addr)
#define hal_reg_read(hal, addr)

readl(hal->base + addr)
extern struct dsi_device *dsi;
extern void flush_cache_all(void);
extern void jzfb_mipi_config(void);
extern void jzfb_dsi_video_cfg(void);
extern void dump_dsi_reg(struct dsi_device *dsi);
extern void dump_lcd_reg(void);
void jzfb_hal_mipi_config(void)
{
jzfb_mipi_config();
}
void jzfb_hal_dsi_video_cfg(void)
{
jzfb_dsi_video_cfg();
}
int jzfb_hal_get_controller_bpp(unsigned int bpp)
{
switch (bpp) {
case 18:
case 24:
return 32;
case 15:
return 16;
default:
return bpp;
}
}
static void inline jzfb_hal_enable_frame_end_irq(struct jzfb_hal *hal)
{
unsigned long reg;
reg = hal_reg_read(hal, LCDC_CTRL);
if ( reg & LCDC_CTRL_EOFM ) {
return;
}
/* clear previous EOF flag */
reg = hal_reg_read(hal, LCDC_STATE);
hal_reg_write(hal, LCDC_STATE, reg & ~LCDC_STATE_EOF);
/* enable end of frame interrupt */
reg = hal_reg_read(hal, LCDC_CTRL);
hal_reg_write(hal, LCDC_CTRL, reg | LCDC_CTRL_EOFM);
return ;
}
static void inline jzfb_hal_disable_frame_end_irq(struct jzfb_hal *hal)
{
unsigned long reg;
reg = hal_reg_read(hal, LCDC_CTRL);
if ( reg & LCDC_CTRL_EOFM ) {
hal_reg_write(hal, LCDC_CTRL, reg & ~LCDC_CTRL_EOFM);
}
return ;
}
void jzfb_hal_refresh_pixclock_auto_adapt(struct jzfb_hal *hal)
{
struct fb_videomode *mode;
uint16_t hds, vds;
uint16_t hde, vde;
uint16_t ht, vt;
unsigned long rate;
if (hal == NULL) {
error("invalid argument: struct jzfb_config_info *hal == NULL.n");
return ;
}
mode = hal->mode;
if (mode == NULL) {
error("%s error: get video mode failed.n", __func__);
return ;
}
hds = mode->hsync_len + mode->left_margin;
hde = hds + mode->xres;
ht = hde + mode->right_margin;
vds = mode->vsync_len + mode->upper_margin;
vde = vds + mode->yres;
vt = vde + mode->lower_margin;
if (mode->refresh) {
if (hal->lcd_type == LCD_TYPE_8BIT_SERIAL) {
rate = mode->refresh * (vt + 2 * mode->xres) * ht;
} else {
rate = mode->refresh * ht * vt;
}
mode->pixclock = KHZ2PICOS(rate / 1000);
} else if (mode->pixclock) {
rate = PICOS2KHZ(mode->pixclock) * 1000;
mode->refresh = rate / vt / ht;
} else {
error("%s error: lcd important config hal is absenced.n", __func__);
}
}
extern struct jzfb_hal *save_hal;
void lcd_restart_dma(void)
{
#ifndef CONFIG_SLCDC_CONTINUA
if (save_hal->is_enable != 0) {
int smart_ctrl = 0;
smart_ctrl = hal_reg_read(save_hal, SLCDC_CTRL);
smart_ctrl |= SLCDC_CTRL_DMA_START; //trigger a new frame
hal_reg_write(save_hal, SLCDC_CTRL, smart_ctrl);
}
#endif
}
void jzfb_hal_slcd_restart(struct jzfb_hal *hal)
{
unsigned int tmp;
tmp = hal_reg_read(hal, SLCDC_CTRL);
tmp |= SLCDC_CTRL_DMA_START | SLCDC_CTRL_DMA_MODE;
hal_reg_write(hal, SLCDC_CTRL, tmp);
}
static void jzfb_hal_config_tft_lcd_dma(struct jzfb_hal *hal)
{
struct jzfb_fg_t *fg = &hal->fg0;
struct jzfb_framedesc *framedesc = fg->framedesc;
#define BYTES_PER_PANEL
(((hal->mode->xres * jzfb_hal_get_controller_bpp(hal->bpp) / 8 + 3) >> 2 << 2) * hal->mode->yres)
framedesc->id = 0xda0;
framedesc->next = fg->framedesc_phys;
framedesc->databuf = fg->databuf;
framedesc->cmd = LCDC_CMD_EOFINT | LCDC_CMD_FRM_EN;
framedesc->cmd |= BYTES_PER_PANEL / 4;
framedesc->offsize = 0;
framedesc->page_width = 0;
switch(fg->bpp) {
case 16:
framedesc->cpos = LCDC_CPOS_RGB_RGB565 | LCDC_CPOS_BPP_16;
break;
case 30:
framedesc->cpos = LCDC_CPOS_BPP_30;
break;
default:
framedesc->cpos = LCDC_CPOS_BPP_18_24;
break;
}
/* global alpha mode */
framedesc->cpos |= 0;
/* data has not been premultied */
framedesc->cpos |= LCDC_CPOS_PREMULTI;
/* coef_sle 0 use 1 */
framedesc->cpos |= LCDC_CPOS_COEF_SLE_1;
/* fg0 alpha value */
framedesc->desc_size = 0xff << LCDC_DESSIZE_ALPHA_BIT;
framedesc->desc_size |=
(((hal->mode->yres -
1) << LCDC_DESSIZE_HEIGHT_BIT & LCDC_DESSIZE_HEIGHT_MASK) |
((hal->mode->xres -
1) << LCDC_DESSIZE_WIDTH_BIT & LCDC_DESSIZE_WIDTH_MASK));
}
static void jzfb_hal_config_smart_lcd_dma(struct jzfb_hal *hal)
{
unsigned long bypes_per_panel;
struct jzfb_fg_t *fg0 = &hal->fg0;
struct jzfb_fg_t *fg1 = &hal->fg1;
struct jzfb_framedesc *framedesc0 = fg0->framedesc;
struct jzfb_framedesc *framedesc1 = fg1->framedesc;
struct jzfb_framedesc *cmd_framedesc = hal->cmd_framedesc;
struct jzfb_config_info *info = (struct jzfb_config_info *)hal;
fg0->bpp = jzfb_hal_get_controller_bpp(hal->bpp);
fg0->x = 0;
fg0->y = 0;
fg0->w = hal->mode->xres;
fg0->h = hal->mode->yres;
fg1->bpp = jzfb_hal_get_controller_bpp(hal->bpp);
fg1->x = 0;
fg1->y = 0;
fg1->w = hal->mode->xres;
fg1->h = hal->mode->yres;
bypes_per_panel = (((hal->mode->xres * jzfb_hal_get_controller_bpp(hal->bpp) / 8 + 3) >> 2 << 2) * hal->mode->yres);
/* framedesc0 */
framedesc0->id = 0xda0;
framedesc0->next = hal->cmd_framedesc_phys;
framedesc0->databuf = fg0->databuf;
framedesc0->cmd = LCDC_CMD_EOFINT | LCDC_CMD_FRM_EN;
framedesc0->cmd |= bypes_per_panel / 4;
framedesc0->offsize = 0;
framedesc0->page_width = 0;
switch (fg0->bpp) {
case 16:
framedesc0->cpos = LCDC_CPOS_RGB_RGB565 | LCDC_CPOS_BPP_16;
break;
case 30:
framedesc0->cpos = LCDC_CPOS_BPP_30;
break;
default:
framedesc0->cpos = LCDC_CPOS_BPP_18_24;
break;
}
/* global alpha mode */
framedesc0->cpos |= 0;
/* data has not been premultied */
framedesc0->cpos |= LCDC_CPOS_PREMULTI;
/* coef_sle 0 use 1 */
framedesc0->cpos |= LCDC_CPOS_COEF_SLE_1;
/* fg0 alpha value */
framedesc0->desc_size = 0xff << LCDC_DESSIZE_ALPHA_BIT;
framedesc0->desc_size |=
(((hal->mode->yres - 1) << LCDC_DESSIZE_HEIGHT_BIT & LCDC_DESSIZE_HEIGHT_MASK) |
((hal->mode->xres - 1) << LCDC_DESSIZE_WIDTH_BIT & LCDC_DESSIZE_WIDTH_MASK));
/* framedesc1 */
framedesc1->id = 0xda1;
framedesc1->next = fg1->framedesc_phys;
framedesc1->databuf = fg1->databuf;
framedesc1->cmd = (LCDC_CMD_EOFINT & ~LCDC_CMD_FRM_EN) | (bypes_per_panel / 4);
framedesc1->offsize = 0;
framedesc1->page_width = 0;
framedesc1->cpos = LCDC_CPOS_BPP_18_24 | LCDC_CPOS_COEF_SLE_3 | LCDC_CPOS_PREMULTI;
framedesc1->desc_size = (((hal->mode->yres - 1) << LCDC_DESSIZE_HEIGHT_BIT & LCDC_DESSIZE_HEIGHT_MASK) |
((hal->mode->xres - 1) << LCDC_DESSIZE_WIDTH_BIT & LCDC_DESSIZE_WIDTH_MASK));
framedesc1->desc_size |= 0xff << LCDC_DESSIZE_ALPHA_BIT;
/* cmd_framedesc */
cmd_framedesc->id = 0xda2;
cmd_framedesc->next = fg0->framedesc_phys;
cmd_framedesc->databuf = info->desc_cmd_phys;
cmd_framedesc->offsize = 0;
cmd_framedesc->page_width = 0;
cmd_framedesc->desc_size = 0;
/* if connect mipi smart lcd, do not sent command by slcdc, send command by mipi dsi controller. */
#ifdef CONFIG_JZ_MIPI_DSI
cmd_framedesc->cmd = LCDC_CMD_CMD | LCDC_CMD_FRM_EN | 0;
cmd_framedesc->cpos = 0;
#else
/* CONFIG_JZ_MIPI_DSI */
switch (hal->smart_config.bus_width) {
case 8:
cmd_framedesc->cmd = LCDC_CMD_CMD | LCDC_CMD_FRM_EN | 1;
cmd_framedesc->cpos = 4;
break;
case 9:
case 16:
cmd_framdesc->cmd = LCDC_CMD_CMD | LCDC_CMD_FRM_EN | 1;
cmd_framedesc->cpos = 2;
break;
default:
cmd_framdesc->cmd = LCDC_CMD_CMD | LCDC_CMD_FRM_EN | 1;
cmd_framedesc->cpos = 1;
break;
}
#endif /* CONFIG_JZ_MIPI_DSI */
hal_reg_write(hal, LCDC_DA0, hal->cmd_framedesc_phys);
}
static void jzfb_hal_config_fg1_dma(struct jzfb_hal *hal)
{
struct jzfb_fg_t *fg = &hal->fg1;
hal_reg_write(hal, LCDC_DA1, fg->framedesc_phys);
}
static int jzfb_hal_prepare_dma_desc(struct jzfb_hal *hal)
{
unsigned int rgb_ctrl, cfg;
/* OSD mode enable and alpha blending is enabled */
cfg = LCDC_OSDC_OSDEN | LCDC_OSDC_ALPHAEN;
cfg |= 1 << 16;
/* once transfer two pixels */
if (hal->fmt_order == FORMAT_X8B8G8R8) {
rgb_ctrl =
LCDC_RGBC_RGBFMT | LCDC_RGBC_ODD_BGR | LCDC_RGBC_EVEN_BGR;
} else {
/* default: FORMAT_X8R8G8B8 */
rgb_ctrl =
LCDC_RGBC_RGBFMT | LCDC_RGBC_ODD_RGB | LCDC_RGBC_EVEN_RGB;
}
hal_reg_write(hal, LCDC_OSDC, cfg);
hal_reg_write(hal, LCDC_RGBC, rgb_ctrl);
if (hal->lcd_type != LCD_TYPE_SLCD) {
jzfb_hal_config_tft_lcd_dma(hal);
} else {
jzfb_hal_config_smart_lcd_dma(hal);
}
jzfb_hal_config_fg1_dma(hal);
return 0;
}
void jzfb_hal_enable(struct jzfb_hal *hal)
{
uint32_t ctrl;
if (hal->is_enable == 0) {
hal_reg_write(hal, LCDC_STATE, 0);
hal_reg_write(hal, LCDC_OSDS, 0);
ctrl = hal_reg_read(hal, LCDC_CTRL);
ctrl |= LCDC_CTRL_ENA;
ctrl &= ~LCDC_CTRL_DIS;
hal_reg_write(hal, LCDC_CTRL, ctrl);
}
hal->is_enable = 1;
//dump_dsi_reg(dsi);
//dump_lcd_reg();
}
void jzfb_hal_disable(struct jzfb_hal *hal)
{
uint32_t ctrl;
//	int count = 20000;
if (hal->is_enable == 1) {
if (hal->lcd_type != LCD_TYPE_SLCD) {
ctrl = hal_reg_read(hal, LCDC_CTRL);
ctrl |= LCDC_CTRL_DIS;
hal_reg_write(hal, LCDC_CTRL, ctrl);
while (!(hal_reg_read(hal, LCDC_STATE) & LCDC_STATE_LDD));
} else {
/* SLCD and TVE only support quick disable */
ctrl = hal_reg_read(hal, LCDC_CTRL);
ctrl &= ~LCDC_CTRL_ENA;
hal_reg_write(hal, LCDC_CTRL, ctrl);
}
}
hal->is_enable = 0;
}
/* Sent a command without data (18-bit bus, 16-bit index) */
void jzfb_hal_slcd_send_mcu_command(struct jzfb_hal *hal, unsigned long cmd)
{
int count = 10000;
cmd &= 0x3fffffff;
while ((hal_reg_read(hal, SLCDC_STATE) & SLCDC_STATE_BUSY) && count--) {
udelay(10);
}
if (count < 0) {
error("SLCDC wait busy state wrong");
}
hal_reg_write(hal, SLCDC_DATA, SLCDC_DATA_RS_COMMAND | cmd);
}
void jzfb_hal_slcd_send_mcu_data(struct jzfb_hal *hal, unsigned long data)
{
int count = 10000;
data &= 0x3fffffff;
while ((hal_reg_read(hal, SLCDC_STATE) & SLCDC_STATE_BUSY) && count--) {
udelay(10);
}
if (count < 0) {
error("SLCDC wait busy state wrong");
}
hal_reg_write(hal, SLCDC_DATA, SLCDC_DATA_RS_DATA | data);
}
static void jzfb_slcd_mcu_init(struct jzfb_hal *hal)
{
unsigned int is_enable, i;
unsigned long tmp;
if (hal->lcd_type != LCD_TYPE_SLCD)
return;
is_enable = hal->is_enable;
if (!is_enable) {
jzfb_hal_enable(hal);
}
if (hal->smart_config.length_data_table &&
hal->smart_config.data_table) {
for (i = 0; i < hal->smart_config.length_data_table; i++) {
switch (hal->smart_config.data_table[i].type) {
case SMART_CONFIG_DATA:
jzfb_hal_slcd_send_mcu_data(hal, hal->smart_config.data_table[i].value);
break;
case SMART_CONFIG_CMD:
jzfb_hal_slcd_send_mcu_command(hal, hal->smart_config.data_table[i].value);
break;
case SMART_CONFIG_UDELAY:
udelay(hal->smart_config.data_table[i].value);
break;
default:
error("Unknow SLCD data type!n");
break;
}
}
{
int count = 10000;
while ((hal_reg_read(hal, SLCDC_STATE) & SLCDC_STATE_BUSY) && count--) {
udelay(10);
}
if (count < 0) {
error("SLCD wait busy state wrong!n");
}
}
}
if (hal->bpp / hal->smart_config.bus_width != 1) {
unsigned int tmp = hal_reg_read(hal, SLCDC_CFG_NEW);
tmp &= ~(SMART_LCD_DWIDTH_MASK); //mask the 8~9bit
tmp |= (hal->bpp / hal->smart_config.bus_width) == 2 ? SMART_LCD_NEW_DTIMES_TWICE : SMART_LCD_NEW_DTIMES_THICE;
hal_reg_write(hal, SLCDC_CFG_NEW, tmp);
printf("the slcd slcd_cfg_new is %08xn", tmp);
}
/* SLCD DMA mode select 0 */
if (!is_enable) {
jzfb_hal_disable(hal);
}
}
int jzfb_hal_set_par(struct jzfb_hal *hal)
{
struct fb_videomode *mode = hal->mode;
uint16_t hds, vds;
uint16_t hde, vde;
uint16_t ht, vt;
uint32_t cfg, ctrl;
uint32_t size0, size1;
uint32_t smart_cfg = 0, smart_ctrl = 0;
uint32_t smart_new_cfg = 0;
uint32_t smart_wtime = 0, smart_tas = 0;
uint32_t pcfg;
//unsigned long rate;
hds = mode->hsync_len + mode->left_margin;
hde = hds + mode->xres;
ht = hde + mode->right_margin;
vds = mode->vsync_len + mode->upper_margin;
vde = vds + mode->yres;
vt = vde + mode->lower_margin;
/*
* configure LCDC config register
* use 8words descriptor, not use palette
* ! M200 NOT SUPPORT PALETTE FUNCTION, DO NOT SET LCDC_CFG_PALBP(BIT27), IT CAUGHT BPP16 COLOR ERROR.
*/
/*SET PALBP TO AVOID FORMAT TRANSFER */
cfg = LCDC_CFG_NEWDES | LCDC_CFG_RECOVER;
cfg |= hal->lcd_type;
if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
cfg |= LCDC_CFG_HSP;
if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
cfg |= LCDC_CFG_VSP;
if (hal->pixclk_falling_edge)
cfg |= LCDC_CFG_PCP;
if (hal->data_enable_active_low)
cfg |= LCDC_CFG_DEP;
/* configure LCDC control register */
ctrl = LCDC_CTRL_BST_64 | LCDC_CTRL_OFUM;
if (hal->pinmd)
ctrl |= LCDC_CTRL_PINMD;
/* new add the ctrl */
ctrl |= LCDC_CTRL_BPP_18_24;
/* configure smart LCDC registers */
if (hal->lcd_type == LCD_TYPE_SLCD) {
smart_cfg = hal->smart_config.smart_type | SMART_LCD_DWIDTH_24_BIT_ONCE_PARALLEL;
switch(hal->smart_config.bus_width){
case 8:
smart_cfg |= SMART_LCD_CWIDTH_8_BIT_ONCE;
smart_new_cfg |= SMART_LCD_NEW_DWIDTH_8_BIT;
break;
case 9:
smart_cfg |= SMART_LCD_CWIDTH_9_BIT_ONCE;
smart_new_cfg |= SMART_LCD_NEW_DWIDTH_9_BIT;
break;
case 16:
smart_cfg |= SMART_LCD_CWIDTH_16_BIT_ONCE;
smart_new_cfg |= SMART_LCD_NEW_DWIDTH_16_BIT;
break;
case 18:
smart_cfg |= SMART_LCD_CWIDTH_18_BIT_ONCE;
smart_new_cfg |= SMART_LCD_NEW_DWIDTH_18_BIT;
break;
case 24:
smart_cfg |= SMART_LCD_CWIDTH_24_BIT_ONCE;
smart_new_cfg |= SMART_LCD_NEW_DWIDTH_24_BIT;
break;
default:
debug("ERR: please check out your bus width confign");
break;
}
if (hal->smart_config.clkply_active_rising)
smart_cfg |= SLCDC_CFG_CLK_ACTIVE_RISING;
if (hal->smart_config.rsply_cmd_high)
smart_cfg |= SLCDC_CFG_RS_CMD_HIGH;
if (hal->smart_config.csply_active_high)
smart_cfg |= SLCDC_CFG_CS_ACTIVE_HIGH;
smart_ctrl = SLCDC_CTRL_DMA_MODE;
//smart_ctrl |= SLCDC_CTRL_GATE_MASK; //for saving power
smart_ctrl &= ~SLCDC_CTRL_GATE_MASK;
smart_ctrl |= (SLCDC_CTRL_NEW_MODE | SLCDC_CTRL_NOT_USE_TE); //new slcd mode
smart_ctrl &= ~SLCDC_CTRL_MIPI_MODE;
smart_new_cfg |= SMART_LCD_NEW_DTIMES_ONCE;
if (hal->smart_config.newcfg_6800_md)
smart_new_cfg |= SLCDC_NEW_CFG_6800_MD;
if (hal->smart_config.newcfg_datatx_type &&
hal->smart_config.newcfg_cmdtx_type)
smart_new_cfg |=
SLCDC_NEW_CFG_DTYPE_SERIAL |
SLCDC_NEW_CFG_CTYPE_SERIAL;
/* if (hal->smart_config.datatx_type_serial
&& hal->smart_config.cmdtx_type_serial)
smart_new_cfg |=
SLCDC_NEW_CFG_DTYPE_SERIAL |
SLCDC_NEW_CFG_CTYPE_SERIAL; */
if (hal->smart_config.newcfg_cmd_9bit)
smart_new_cfg |= SLCDC_NEW_CFG_CMD_9BIT;
smart_wtime = 0;
smart_tas = 0;
}
switch (hal->lcd_type) {
case LCD_TYPE_SPECIAL_TFT_1:
case LCD_TYPE_SPECIAL_TFT_2:
case LCD_TYPE_SPECIAL_TFT_3:
hal_reg_write(hal, LCDC_SPL, hal->special_tft_config.spl);
hal_reg_write(hal, LCDC_CLS, hal->special_tft_config.cls);
hal_reg_write(hal, LCDC_PS, hal->special_tft_config.ps);
hal_reg_write(hal, LCDC_REV, hal->special_tft_config.ps);
break;
default:
cfg |= LCDC_CFG_PSM;
cfg |= LCDC_CFG_CLSM;
cfg |= LCDC_CFG_SPLM;
cfg |= LCDC_CFG_REVM;
break;
}
if (hal->lcd_type != LCD_TYPE_SLCD) {
hal_reg_write(hal, LCDC_VAT, (ht << 16) | vt);
hal_reg_write(hal, LCDC_DAH, (hds << 16) | hde);
hal_reg_write(hal, LCDC_DAV, (vds << 16) | vde);
hal_reg_write(hal, LCDC_HSYNC, mode->hsync_len);
hal_reg_write(hal, LCDC_VSYNC, mode->vsync_len);
} else {
#ifdef CONFIG_JZ_MIPI_DSI
smart_cfg |= 1 << 16;
smart_new_cfg |= 4 << 13;
smart_ctrl |= 1 << 7 | 1 << 6;
jzfb_hal_mipi_config();
#endif
hal_reg_write(hal, LCDC_VAT, (mode->xres << 16) | mode->yres);
hal_reg_write(hal, LCDC_DAH, mode->xres);
hal_reg_write(hal, LCDC_DAV, mode->yres);
hal_reg_write(hal, LCDC_HSYNC, 0);
hal_reg_write(hal, LCDC_VSYNC, 0);
hal_reg_write(hal, SLCDC_CFG, smart_cfg);
hal_reg_write(hal, SLCDC_CTRL, smart_ctrl);
hal_reg_write(hal, SLCDC_CFG_NEW, smart_new_cfg);
hal_reg_write(hal, SLCDC_WTIME, smart_wtime);
hal_reg_write(hal, SLCDC_TAS, smart_tas);
}
hal_reg_write(hal, LCDC_CFG, cfg);
hal_reg_write(hal, LCDC_CTRL, ctrl);
pcfg = 0xC0000000 | (511 << 18) | (400 << 9) | (256 << 0);
hal_reg_write(hal, LCDC_PCFG, pcfg);
size0 =
(hal->mode->xres << LCDC_SIZE_WIDTH_BIT) & LCDC_SIZE_WIDTH_MASK;
size0 |=
((hal->mode->
yres << LCDC_SIZE_HEIGHT_BIT) & LCDC_SIZE_HEIGHT_MASK);
size1 = size0;
hal_reg_write(hal, LCDC_SIZE0, size0);
hal_reg_write(hal, LCDC_SIZE1, size1);
/* prepare dma descriptor */
jzfb_hal_prepare_dma_desc(hal);
if (hal->lcd_type == LCD_TYPE_SLCD) {
/* jzfb_slcd_mcu_init */
jzfb_slcd_mcu_init(hal);
#ifdef CONFIG_SLCDC_CONTINUA
smart_ctrl &= ~SLCDC_CTRL_DMA_MODE;
#else
smart_ctrl |= SLCDC_CTRL_DMA_START;
#endif
smart_ctrl |= SLCDC_CTRL_DMA_EN;
#ifdef CONFIG_SLCDC_USE_TE
smart_ctrl &= ~SLCDC_CTRL_NOT_USE_TE;
#endif
if (hal->smart_config.newcfg_fmt_conv) {
smart_new_cfg = hal_reg_read(hal, SLCDC_CFG_NEW);
smart_new_cfg |= SLCDC_NEW_CFG_FMT_CONV_EN;
hal_reg_write(hal, SLCDC_CFG_NEW, smart_new_cfg);
}
hal_reg_write(hal, SLCDC_CTRL, smart_ctrl);
}
#ifdef CONFIG_JZ_MIPI_DSI
else {
cfg = hal_reg_read(hal, LCDC_CFG); //maby can delete
cfg |= 1 << 24;
hal_reg_write(hal, LCDC_CFG, cfg);
/* jzfb->dsi->master_ops->video_cfg(jzfb->dsi); */
jzfb_hal_dsi_video_cfg();
}
#endif
return 0;
}

3.uboot中frame buffer驱动的头文件:

#ifndef __JZ_LCD_V1_2_H__
#define __JZ_LCD_V1_2_H__
#include <common.h>
#include <linux/types.h>
#include "jz_fb_hal.h"
void panel_pin_init(void);
void panel_power_on(void);
void panel_power_off(void);
void panel_suspend(void);
void board_set_lcd_power_on(void);
void board_set_lcd_power_off(void);
#if PWM_BACKLIGHT_CHIP
void lcd_set_backlight_level(int num);
void lcd_close_backlight(void);
#else
void lcd_init_backlight(int num);
void send_low_pulse(int num);
void lcd_set_backlight_level(int num);
void lcd_close_backlight(void);
#endif
#ifdef CONFIG_TWO_FRAME_BUFFERS
#define NUM_FRAME_BUFFERS 2
#endif
#ifdef CONFIG_THREE_FRAME_BUFFERS
#define NUM_FRAME_BUFFERS 3
#endif
#define PIXEL_ALIGN 16
#define MODE_NAME_LEN 32
struct jzfb_config_info lcd_config_info;
struct jzfb_config_info {
struct jzfb_hal hal;
struct jzfb_framedesc *framedesc;
unsigned long framedesc_phys;
unsigned long *desc_cmd_vidmem;
unsigned long desc_cmd_phys;
void *vidmem;
unsigned long vidmem_phys;
};
int jzfb_get_controller_bpp(unsigned int);
extern struct jzfb_config_info lcd_config_info;
extern struct jzfb_config_info jzfb1_init_data;
extern struct fb_videomode jzfb1_videomode;
extern struct dsi_device jz_dsi;
#endif /*__JZ_LCD_H__*/

4.uboot中frame buffer的驱动代码:

#include <asm/io.h>
#include <config.h>
#include <serial.h>
#include <common.h>
#include <lcd.h>
#include <asm/arch/lcdc.h>
#include <asm/arch/gpio.h>
#include <asm/arch/clk.h>
#include <jz_lcd/jz_lcd_v1_2.h>
/*#define DEBUG*/
#ifdef CONFIG_JZ_MIPI_DSI
#include <jz_lcd/jz_dsim.h>
#include "./jz_mipi_dsi/jz_mipi_dsi_regs.h"
#include "./jz_mipi_dsi/jz_mipi_dsih_hal.h"
struct dsi_device *dsi;
void jz_dsi_init(struct dsi_device *dsi);
int jz_dsi_video_cfg(struct dsi_device *dsi);
#endif
void panel_init_set_sequence(struct dsi_device *dsi);
void board_set_lcd_power_on(void);
void flush_cache_all(void);
void lcd_close_backlight(void);
void lcd_set_backlight_level(int num);
#define reg_write(addr,config) 
writel(config,lcd_config_info.hal.base+addr)
#define reg_read(addr)	
readl(lcd_config_info.hal.base+addr)
struct jzfb_config_info lcd_config_info;
struct jzfb_hal *save_hal;
void dump_dsi_reg(struct dsi_device *dsi)
{
printf( "===========>dump dsi regn");
printf( "VERSION------------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VERSION));
printf( "PWR_UP:------------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PWR_UP));
printf( "CLKMGR_CFG---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_CLKMGR_CFG));
printf( "DPI_VCID-----------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DPI_VCID));
printf( "DPI_COLOR_CODING---:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DPI_COLOR_CODING));
printf( "DPI_CFG_POL--------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DPI_CFG_POL));
printf( "DPI_LP_CMD_TIM-----:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DPI_LP_CMD_TIM));
printf( "DBI_VCID-----------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DBI_VCID));
printf( "DBI_CFG------------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DBI_CFG));
printf( "DBI_PARTITIONING_EN:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DBI_PARTITIONING_EN));
printf( "DBI_CMDSIZE--------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DBI_CMDSIZE));
printf( "PCKHDL_CFG---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PCKHDL_CFG));
printf( "GEN_VCID-----------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_GEN_VCID));
printf( "MODE_CFG-----------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_MODE_CFG));
printf( "VID_MODE_CFG-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_MODE_CFG));
printf( "VID_PKT_SIZE-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_PKT_SIZE));
printf( "VID_NUM_CHUNKS-----:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_NUM_CHUNKS));
printf( "VID_NULL_SIZE------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_NULL_SIZE));
printf( "VID_HSA_TIME-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_HSA_TIME));
printf( "VID_HBP_TIME-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_HBP_TIME));
printf( "VID_HLINE_TIME-----:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_HLINE_TIME));
printf( "VID_VSA_LINES------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VSA_LINES));
printf( "VID_VBP_LINES------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VBP_LINES));
printf( "VID_VFP_LINES------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VFP_LINES));
printf( "VID_VACTIVE_LINES--:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VACTIVE_LINES));
printf( "EDPI_CMD_SIZE------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_EDPI_CMD_SIZE));
printf( "CMD_MODE_CFG-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_CMD_MODE_CFG));
printf( "GEN_HDR------------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_GEN_HDR));
printf( "GEN_PLD_DATA-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_GEN_PLD_DATA));
printf( "CMD_PKT_STATUS-----:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_CMD_PKT_STATUS));
printf( "TO_CNT_CFG---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_TO_CNT_CFG));
printf( "HS_RD_TO_CNT-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_HS_RD_TO_CNT));
printf( "LP_RD_TO_CNT-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_LP_RD_TO_CNT));
printf( "HS_WR_TO_CNT-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_HS_WR_TO_CNT));
printf( "LP_WR_TO_CNT_CFG---:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_LP_WR_TO_CNT));
printf( "BTA_TO_CNT---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_BTA_TO_CNT));
printf( "SDF_3D-------------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_SDF_3D));
printf( "LPCLK_CTRL---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_LPCLK_CTRL));
printf( "PHY_TMR_LPCLK_CFG--:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_TMR_LPCLK_CFG));
printf( "PHY_TMR_CFG--------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_TMR_CFG));
printf( "PHY_RSTZ-----------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_RSTZ));
printf( "PHY_IF_CFG---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_IF_CFG));
printf( "PHY_ULPS_CTRL------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_ULPS_CTRL));
printf( "PHY_TX_TRIGGERS----:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_TX_TRIGGERS));
printf( "PHY_STATUS---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_STATUS));
printf( "PHY_TST_CTRL0------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_TST_CTRL0));
printf( "PHY_TST_CTRL1------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_PHY_TST_CTRL1));
printf( "INT_ST0------------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_INT_ST0));
printf( "INT_ST1------------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_INT_ST1));
printf( "INT_MSK0-----------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_INT_MSK0));
printf( "INT_MSK1-----------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_INT_MSK1));
printf( "INT_FORCE0---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_INT_FORCE0));
printf( "INT_FORCE1---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_INT_FORCE1));
printf( "VID_SHADOW_CTRL----:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_SHADOW_CTRL));
printf( "DPI_VCID_ACT-------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DPI_VCID_ACT));
printf( "DPI_COLOR_CODING_AC:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DPI_COLOR_CODING_ACT));
printf( "DPI_LP_CMD_TIM_ACT-:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_DPI_LP_CMD_TIM_ACT));
printf( "VID_MODE_CFG_ACT---:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_MODE_CFG_ACT));
printf( "VID_PKT_SIZE_ACT---:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_PKT_SIZE_ACT));
printf( "VID_NUM_CHUNKS_ACT-:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_NUM_CHUNKS_ACT));
printf( "VID_HSA_TIME_ACT---:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_HSA_TIME_ACT));
printf( "VID_HBP_TIME_ACT---:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_HBP_TIME_ACT));
printf( "VID_HLINE_TIME_ACT-:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_HLINE_TIME_ACT));
printf( "VID_VSA_LINES_ACT--:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VSA_LINES_ACT));
printf( "VID_VBP_LINES_ACT--:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VBP_LINES_ACT));
printf( "VID_VFP_LINES_ACT--:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VFP_LINES_ACT));
printf( "VID_VACTIVE_LINES_ACT:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_VID_VACTIVE_LINES_ACT));
printf( "SDF_3D_ACT---------:%08xn",
mipi_dsih_read_word(dsi, R_DSI_HOST_SDF_3D_ACT));
}
void dump_lcd_reg(void)
{
printf("$$$dump_lcd_regn");
int tmp;
printf("LCDC_CFG:(0x%08x) t0x%08xn", LCDC_CFG,reg_read(LCDC_CFG));
printf("LCDC_CTRL:(0x%08x)t0x%08xn",LCDC_CTRL,reg_read(LCDC_CTRL));
printf("LCDC_STATE:(0x%08x)t0x%08xn",LCDC_STATE,reg_read(LCDC_STATE));
printf("LCDC_OSDC:(0x%08x)t0x%08xn", LCDC_OSDC,reg_read(LCDC_OSDC));
printf("LCDC_OSDCTRL:(0x%08x)t0x%08xn",LCDC_OSDCTRL,reg_read(LCDC_OSDCTRL));
printf("LCDC_OSDS:(0x%08x)t0x%08xn",LCDC_OSDS,reg_read(LCDC_OSDS));
printf("LCDC_BGC0:(0x%08x)t0x%08xn",LCDC_BGC0,reg_read(LCDC_BGC0));
printf("LCDC_BGC1:(0x%08x)t0x%08xn",LCDC_BGC1,reg_read(LCDC_BGC1));
printf("LCDC_KEY0:(0x%08x)t0x%08xn",LCDC_KEY0, reg_read(LCDC_KEY0));
printf("LCDC_KEY1:(0x%08x)t0x%08xn",LCDC_KEY1, reg_read(LCDC_KEY1));
printf("LCDC_ALPHA:(0x%08x)t0x%08xn",LCDC_ALPHA, reg_read(LCDC_ALPHA));
printf("==================================n");
tmp = reg_read(LCDC_VAT);
printf("LCDC_VAT:(0x%08x) t0x%08x, HT = %d, VT = %dn",LCDC_VAT, tmp,
(tmp & LCDC_VAT_HT_MASK) >> LCDC_VAT_HT_BIT,
(tmp & LCDC_VAT_VT_MASK) >> LCDC_VAT_VT_BIT);
tmp = reg_read(LCDC_DAH);
printf("LCDC_DAH:(0x%08x) t0x%08x, HDS = %d, HDE = %dn",LCDC_DAH, tmp,
(tmp & LCDC_DAH_HDS_MASK) >> LCDC_DAH_HDS_BIT,
(tmp & LCDC_DAH_HDE_MASK) >> LCDC_DAH_HDE_BIT);
tmp = reg_read(LCDC_DAV);
printf("LCDC_DAV:(0x%08x) t0x%08x, VDS = %d, VDE = %dn",LCDC_DAV, tmp,
(tmp & LCDC_DAV_VDS_MASK) >> LCDC_DAV_VDS_BIT,
(tmp & LCDC_DAV_VDE_MASK) >> LCDC_DAV_VDE_BIT);
tmp = reg_read(LCDC_HSYNC);
printf("LCDC_HSYNC:(0x%08x)t0x%08x, HPS = %d, HPE = %dn",LCDC_HSYNC, tmp,
(tmp & LCDC_HSYNC_HPS_MASK) >> LCDC_HSYNC_HPS_BIT,
(tmp & LCDC_HSYNC_HPE_MASK) >> LCDC_HSYNC_HPE_BIT);
tmp = reg_read(LCDC_VSYNC);
printf("LCDC_VSYNC:(0x%08x)t0x%08x, VPS = %d, VPE = %dn", LCDC_VSYNC,tmp,
(tmp & LCDC_VSYNC_VPS_MASK) >> LCDC_VSYNC_VPS_BIT,
(tmp & LCDC_VSYNC_VPE_MASK) >> LCDC_VSYNC_VPE_BIT);
printf("==================================n");
printf("LCDC_XYP0:(0x%08x)t0x%08xn",LCDC_XYP0, reg_read(LCDC_XYP0));
printf("LCDC_XYP1:(0x%08x)t0x%08xn",LCDC_XYP1, reg_read(LCDC_XYP1));
printf("LCDC_SIZE0:(0x%08x)t0x%08xn",LCDC_SIZE0, reg_read(LCDC_SIZE0));
printf("LCDC_SIZE1:(0x%08x)t0x%08xn",LCDC_SIZE1, reg_read(LCDC_SIZE1));
printf("LCDC_RGBC:(0x%08x) t0x%08xn",LCDC_RGBC, reg_read(LCDC_RGBC));
printf("LCDC_PS:(0x%08x)
t0x%08xn",LCDC_PS, reg_read(LCDC_PS));
printf("LCDC_CLS:(0x%08x) t0x%08xn", LCDC_CLS,reg_read(LCDC_CLS));
printf("LCDC_SPL:(0x%08x) t0x%08xn",LCDC_SPL, reg_read(LCDC_SPL));
printf("LCDC_REV:(0x%08x) t0x%08xn",LCDC_REV, reg_read(LCDC_REV));
printf("LCDC_IID:(0x%08x) t0x%08xn",LCDC_IID, reg_read(LCDC_IID));
printf("==================================n");
printf("LCDC_DA0:(0x%08x) t0x%08xn",LCDC_DA0, reg_read(LCDC_DA0));
printf("LCDC_SA0:(0x%08x) t0x%08xn",LCDC_SA0, reg_read(LCDC_SA0));
printf("LCDC_FID0:(0x%08x)t0x%08xn",LCDC_FID0, reg_read(LCDC_FID0));
printf("LCDC_CMD0:(0x%08x)t0x%08xn",LCDC_CMD0, reg_read(LCDC_CMD0));
printf("LCDC_OFFS0:(0x%08x)t0x%08xn",LCDC_OFFS0, reg_read(LCDC_OFFS0));
printf("LCDC_PW0:(0x%08x) t0x%08xn", LCDC_PW0,reg_read(LCDC_PW0));
printf("LCDC_CNUM0:(0x%08x)t0x%08xn",LCDC_CNUM0, reg_read(LCDC_CNUM0));
printf("LCDC_DESSIZE0:(0x%08x)t0x%08xn",LCDC_DESSIZE0, reg_read(LCDC_DESSIZE0));
printf("==================================n");
printf("LCDC_DA1:(0x%08x) t0x%08xn", LCDC_DA1, reg_read(LCDC_DA1));
printf("LCDC_SA1:(0x%08x) t0x%08xn",LCDC_SA1, reg_read(LCDC_SA1));
printf("LCDC_FID1:(0x%08x)t0x%08xn",LCDC_FID1, reg_read(LCDC_FID1));
printf("LCDC_CMD1:(0x%08x)t0x%08xn",LCDC_CMD1, reg_read(LCDC_CMD1));
printf("LCDC_OFFS1:(0x%08x)t0x%08xn",LCDC_OFFS1, reg_read(LCDC_OFFS1));
printf("LCDC_PW1:(0x%08x) t0x%08xn",LCDC_PW1, reg_read(LCDC_PW1));
printf("LCDC_CNUM1:(0x%08x)t0x%08xn",LCDC_CNUM1, reg_read(LCDC_CNUM1));
printf("LCDC_DESSIZE1:(0x%08x)t0x%08xn",LCDC_DESSIZE1, reg_read(LCDC_DESSIZE1));
printf("==================================n");
printf("LCDC_PCFG:(0x%08x)t0x%08xn", LCDC_PCFG,reg_read(LCDC_PCFG));
printf("==================================n");
printf("SLCDC_CFG:(0x%08x) t0x%08xn", SLCDC_CFG,reg_read(SLCDC_CFG));
printf("SLCDC_CTRL:(0x%08x) t0x%08xn", SLCDC_CTRL,reg_read(SLCDC_CTRL));
printf("SLCDC_STATE:(0x%08x) t0x%08xn", SLCDC_STATE,reg_read(SLCDC_STATE));
printf("SLCDC_DATA:(0x%08x)t0x%08xn", SLCDC_DATA,reg_read(SLCDC_DATA));
printf("SLCDC_CFG_NEW:(0x%08x) t0x%08xn", SLCDC_CFG_NEW,reg_read(SLCDC_CFG_NEW));
printf("SLCDC_WTIME:(0x%08x) t0x%08xn", SLCDC_WTIME,reg_read(SLCDC_WTIME));
printf("SLCDC_TAS:(0x%08x) t0x%08xn", SLCDC_TAS,reg_read(SLCDC_TAS));
printf("==================================n");
printf("reg:0x10000020 value=0x%08x
(24bit) Clock Gate Register0n",
*(unsigned int *)0xb0000020);
printf("reg:0x100000e4 value=0x%08x
(5bit_lcdc 21bit_lcdcs) Power Gate Register: n",
*(unsigned int *)0xb00000e4);
printf("reg:0x100000b8 value=0x%08x
(10bit) SRAM Power Control Register0 n",
*(unsigned int *)0xb00000b8);
printf("reg:0x10000064 value=0x%08x
Lcd pixclock n",
*(unsigned int *)0xb0000064);
printf("==================================n");
printf("PCINT:t0x%08xn", *(unsigned int *)0xb0010210);
printf("PCMASK:t0x%08xn",*(unsigned int *)0xb0010220);
printf("PCPAT1:t0x%08xn",*(unsigned int *)0xb0010230);
printf("PCPAT0:t0x%08xn",*(unsigned int *)0xb0010240);
printf("==================================n");
}/*end dump_lcd_reg*/
void lcd_enable(void)
{
jzfb_hal_enable(&lcd_config_info.hal);
}
void lcd_disable(void)
{
jzfb_hal_disable(&lcd_config_info.hal);
}
void jzfb_mipi_config(void)
{
mipi_dsih_write_word(dsi, R_DSI_HOST_CMD_MODE_CFG,
0x1); //te
mipi_dsih_dphy_enable_hs_clk(dsi, 1);
mipi_dsih_hal_gen_set_mode(dsi, 1);
mipi_dsih_hal_dpi_color_coding(dsi,
dsi->video_config->color_coding);
}
void jzfb_dsi_video_cfg(void)
{
jz_dsi_video_cfg(dsi);
}
int jzfb_get_controller_bpp(unsigned int bpp)
{
switch (bpp) {
case 18:
case 24:
return 32;
case 15:
return 16;
default:
return bpp;
}
}
static void jzfb_alloc_devmem(void *lcdbase, struct jzfb_config_info *info)
{
unsigned long palette_mem_size;
int fb_size = (info->hal.mode->xres * (jzfb_get_controller_bpp(info->hal.bpp) / 8)) *
info->hal.mode->yres;
info->vidmem = lcdbase;
info->vidmem_phys = virt_to_phys((void *)info->vidmem);
palette_mem_size = 256 * sizeof(u16);
info->framedesc = (struct jzfb_framedesc *)(lcdbase + fb_size + PAGE_SIZE - palette_mem_size) - 4;
info->framedesc_phys = virt_to_phys((void *)info->framedesc);
info->desc_cmd_vidmem = ((unsigned long)lcdbase + fb_size + PAGE_SIZE -1) & ~(PAGE_SIZE - 1);
info->desc_cmd_phys = virt_to_phys((void *)info->desc_cmd_vidmem);
if (info->hal.lcd_type == LCD_TYPE_SLCD) {
int i;
unsigned long *ptr;
ptr = (unsigned long *)info->desc_cmd_vidmem;
for (i = 0; i < info->hal.smart_config.length_cmd; i++) {
ptr[i] = info->hal.smart_config.write_gram_cmd[i];
}
flush_cache_all();
}
}
static void jzfb_init_fg(struct jzfb_config_info *info)
{
struct jzfb_fg_t *fg0 = &info->hal.fg0;
struct jzfb_fg_t *fg1 = &info->hal.fg1;
struct fb_videomode *mode = info->hal.mode;
#define BYTES_PER_PANEL
(((info->hal.mode->xres * jzfb_get_controller_bpp(info->hal.bpp) / 8 + 3) >> 2 << 2) * info->hal.mode->yres)
fg0->framedesc = info->framedesc + 0;
fg0->framedesc_phys = info->framedesc_phys;
fg0->databuf = info->vidmem_phys;
fg0->bpp = info->hal.bpp;
fg0->h = mode->yres;
fg0->w = mode->xres;
fg0->x = 0;
fg0->y = 0;
fg1->framedesc = info->framedesc + 1;
fg1->framedesc_phys = info->framedesc_phys + 1 * sizeof(*info->framedesc);
fg1->databuf = virt_to_phys((void *)(info->vidmem + BYTES_PER_PANEL));
fg1->bpp = info->hal.bpp;
fg1->h = mode->yres;
fg1->w = mode->xres;
fg1->x = 0;
fg1->y = 0;
if (info->hal.lcd_type == LCD_TYPE_SLCD) {
info->hal.cmd_framedesc = info->framedesc + 2;
info->hal.cmd_framedesc_phys = info->framedesc_phys + 2 * sizeof(*info->framedesc);
}
}
static void refresh_pixclock_auto_adapt(struct jzfb_config_info *info)
{
jzfb_hal_refresh_pixclock_auto_adapt(&info->hal);
}
static void jzfb_set_par(struct jzfb_config_info *info)
{
jzfb_hal_set_par(&info->hal);
}
void lcd_ctrl_init(void *lcd_base)
{
unsigned long pixel_clock_rate;
/* init registers base address */
lcd_config_info = jzfb1_init_data;
save_hal = &lcd_config_info.hal;
lcd_config_info.hal.base = 0;
#ifdef CONFIG_JZ_MIPI_DSI
dsi = &jz_dsi;
#endif
lcd_set_flush_dcache(1);
refresh_pixclock_auto_adapt(&lcd_config_info);
pixel_clock_rate = PICOS2KHZ(lcd_config_info.hal.mode->pixclock);
/* smart lcd WR freq = (lcd pixel clock)/2 */
if (lcd_config_info.hal.lcd_type == LCD_TYPE_SLCD) {
pixel_clock_rate *= 2;
}
clk_set_rate(LCD, pixel_clock_rate);
lcd_close_backlight();
panel_pin_init();
#ifdef CONFIG_LCD_FORMAT_X8B8G8R8
lcd_config_info.hal.fmt_order = FORMAT_X8B8G8R8;
#else
lcd_config_info.hal.fmt_order = FORMAT_X8R8G8B8;
#endif
//jz_lcd_init_mem(lcd_base, &lcd_config_info);
jzfb_alloc_devmem(lcd_base, &lcd_config_info);
jzfb_init_fg(&lcd_config_info);
board_set_lcd_power_on();
panel_power_on();
#ifdef CONFIG_JZ_MIPI_DSI
jz_dsi_init(dsi);
panel_init_set_sequence(dsi);
#endif
jzfb_set_par(&lcd_config_info);
flush_cache_all();
dump_dsi_reg(dsi);
dump_lcd_reg();
return;
}
void lcd_show_board_info(void)
{
return;
}
void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
{
return;
}
void __attribute__((weak)) panel_suspend(void)
{
printf("no %s implementn", __func__);
}
void __attribute__((weak)) board_set_lcd_power_off(void)
{
printf("no %s implementn", __func__);
}
static int do_lcd_suspend(cmd_tbl_t * cmdtp, int flag, int argc,
char *const argv[]) {
//	lcd_clear_black();
panel_suspend();
board_set_lcd_power_off();
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(lcd_suspend, 4, 1, do_lcd_suspend,
"suspend the lcd panel", "lcd_suspend");


最后

以上就是体贴黑猫为你收集整理的frame buffer驱动的全部内容,希望文章能够帮你解决frame buffer驱动所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部