SmartAudio/lichee/brandy/u-boot-2011.09/common/cmd_sunxi_display.c

334 lines
10 KiB
C
Executable File

/*
* Driver for NAND support, Rick Bronson
* borrowed heavily from:
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
* Ported 'dynenv' to 'nand env.oob' command
* (C) 2010 Nanometrics, Inc.
* 'dynenv' -- Dynamic environment offset in NAND OOB
* (C) Copyright 2006-2007 OpenMoko, Inc.
* Added 16-bit nand support
* (C) 2004 Texas Instruments
*
* Copyright 2010 Freescale Semiconductor
* The portions of this file whose copyright is held by Freescale and which
* are not considered a derived work of GPL v2-only code may be distributed
* and/or modified under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*/
#include <common.h>
#include <command.h>
#include <asm/io.h>
#include <asm/arch/boot_type.h>
#include <asm/arch/drv_display.h>
#define BMP_MAGIC (0x4D42)
#define SUNXI_BMP_LIMIT (2 * 1024 *1024)
#define DISPALY_RESERVED_MEM (0x40000000 + (512 - 64 - 32) * 1024 * 1024 )
typedef struct tag_Picture
{
void *Buffer; /* 存放图片数据 */
__u32 BufferSize; /* buffer长度 */
__u32 BitCount; /* 一个像素的bit数 */
__u32 Width; /* 图片宽度 */
__u32 Height; /* 图片高度 */
__u32 RowSize; /* 图片一行的大小 */
}Picture_t;
/*bmp header struct*/
typedef struct
{
__u16 bfType; //bit map type
__u32 bfSize; //total file size
__u16 bfReserved1; //reserved , must be 0
__u16 bfReserved2; //reserved, must be 0
__u32 bfOffBits; //full img offet
}
__attribute__ ((packed)) __bmp_file_head_t;
/*bmp info struct,windows*/
typedef struct
{
__u32 biSize; //bit map info size
__u32 biWidth; //img width with pixel unit
__s32 biHeight; //img height with pixel unit
__u16 biPlanes; //bit map planes,always 1
__u16 biBitCount; //bit planes per pixel
__u32 biCompression; //compress method
__u32 biSizeImage; //img size with byte unit
__u32 biXPelsPerMeter; //the horizontal resolution with pixel/metre unit
__u32 biYPelsPerMeter; //the vertical resolution with pixel/metre unit
__u32 biClrUsed; //the color numbers used by bmp
__u32 biClrlmportant; //important color numbers
}
__attribute__ ((packed)) __bmp_info_header_t;
static int do_read_bmp_from_flash(char * argv[6])
{
int ret = 0;
char *const argvs[6] = {"fatload",argv[1],argv[2],argv[3],argv[4],NULL };
ret = do_fat_fsload(0,0,5,argv);
if(ret){
printf("do_fat_fsload fail in read_bmp_from_flash\n");
return ret;
}
return 0;
}
/*
* read_bmp_from_flash read bmp file from storage media
* dev_flag: storage media 0:nand 1:mmc
* dev_number: devices number (if mmcblk0 the number is 0)
* partition_number: parttion number of device(the min valid number is 1)
* addr: the destination address in memory of bmpfile start
* filename: bmp file name in flash(must with path)
*/
static int read_bmp_from_flash(char dev_flag,char dev_number,char partition_number,unsigned int addr,char* filename)
{
char * argv[6];
int ret =0;
char *const argv1[6] = { "fatload", "nand", "0", "40000000", "os_show/melis2.bmp", NULL };
//uboot_spare_head.boot_data.storage_type
argv[0] = "fatload";
argv[5] = NULL;
if(dev_flag)
argv[1] = "mmc";
else
argv[1] = "nand";
if(partition_number != 0)
sprintf(argv[2],"%u:%u",dev_number,partition_number);
else
sprintf(argv[2],"%u",dev_number);
sprintf(argv[3],"%x",addr);
argv[4] = filename;
ret = do_read_bmp_from_flash(argv);
if(ret){
printf("do_read_bmp_from_flash in read_bmp_from_flash\n");
return ret;
}
return ret;
}
static char *parse_buffer;
static int sunxi_bmp_parse(u32 start,Picture_t *PictureInfo)
{
__s32 ret = -1;
int length;
char *tmp_buffer;
__bmp_file_head_t *bmp_file_header;
__bmp_info_header_t *bmp_info_header;
bmp_file_header = (__bmp_file_head_t *)start;
if(bmp_file_header->bfType != BMP_MAGIC){
sunxi_printf("bad BMP_MAGIC!\n");
goto _get_bmp_by_name_error;
}
bmp_info_header = (__bmp_info_header_t *)(start + sizeof(__bmp_file_head_t));
PictureInfo->BitCount = bmp_info_header->biBitCount;
PictureInfo->Height = (bmp_info_header->biHeight > 0) ?
bmp_info_header->biHeight : (-bmp_info_header->biHeight);
PictureInfo->Width = bmp_info_header->biWidth;
PictureInfo->RowSize = PictureInfo->BitCount * PictureInfo->Width / 8;
PictureInfo->BufferSize = PictureInfo->Height * PictureInfo->RowSize;
length = PictureInfo->BufferSize+sizeof(__bmp_file_head_t)+ sizeof(__bmp_info_header_t);
/*
parse_buffer = (char *)malloc(length);
if(!parse_buffer){
goto _get_bmp_by_name_error;
}
*/
//memcpy(parse_buffer,(void *)start,length);
PictureInfo->Buffer = (char *)malloc(PictureInfo->BufferSize);
if(!PictureInfo->Buffer)
goto _get_bmp_by_name_error;
//tmp_buffer = parse_buffer + bmp_file_header->bfOffBits;
tmp_buffer = (char *)start + bmp_file_header->bfOffBits;
if(bmp_info_header->biHeight > 0){
__u32 i, j;
__s32 *src, *dest;
dest = (int *)PictureInfo->Buffer;
for(i=0; i<(bmp_info_header->biHeight); i++){
src = (int *)(tmp_buffer + (bmp_info_header->biHeight - i - 1) * (bmp_info_header->biWidth << 2));
for(j=0;j<bmp_info_header->biWidth; j++){
*dest ++ = *src ++;
}
}
}else{
memcpy(PictureInfo->Buffer, tmp_buffer, PictureInfo->BufferSize);
}
ret = 0;
_get_bmp_by_name_error:
/*
if(parse_bufferbuffer){
free(parse_buffer);
}
*/
return ret;
}
static int disp_bmp_show(Picture_t *PictureInfo)
{
__disp_layer_info_t layer_para;
__u32 layer_hdl;
__u32 screen_width, screen_height;
__u32 arg[4];
if(PictureInfo == NULL)
{
printf("null para \n");
return -1;
}
arg[0] = 0;
screen_width = disp_ioctl(NULL, DISP_CMD_SCN_GET_WIDTH, (void*)arg);
screen_height = disp_ioctl(NULL, DISP_CMD_SCN_GET_HEIGHT, (void*)arg);
memset(&layer_para, 0, sizeof(__disp_layer_info_t));
layer_para.fb.addr[0] = (__u32)PictureInfo->Buffer;
layer_para.fb.size.width = PictureInfo->Width;
layer_para.fb.size.height = PictureInfo->Height;
layer_para.fb.mode = DISP_MOD_INTERLEAVED;
layer_para.fb.format = (PictureInfo->BitCount == 24)? DISP_FORMAT_RGB888:DISP_FORMAT_ARGB8888;
layer_para.fb.br_swap = 0;
layer_para.fb.seq = DISP_SEQ_ARGB;
layer_para.fb.b_trd_src = 0;
layer_para.fb.trd_mode = 0;
layer_para.ck_enable = 0;
layer_para.alpha_en = 1;
layer_para.alpha_val = 0xff;
layer_para.pipe = 0;
layer_para.src_win.x = 0;
layer_para.src_win.y = 0;
layer_para.src_win.width = PictureInfo->Width;
layer_para.src_win.height = PictureInfo->Height;
layer_para.scn_win.x = (screen_width - PictureInfo->Width) / 2;
layer_para.scn_win.y = (screen_height - PictureInfo->Height) / 2;
layer_para.scn_win.width = PictureInfo->Width;
layer_para.scn_win.height = PictureInfo->Height;
layer_para.b_trd_out = 0;
layer_para.out_trd_mode = 0;
arg[0] = 0;
arg[1] = DISP_LAYER_WORK_MODE_NORMAL;
layer_hdl = disp_ioctl(NULL, DISP_CMD_LAYER_REQUEST, (void*)arg);
if(layer_hdl <= 0)
{
printf("DISP_CMD_LAYER_REQUEST, fail\n");
return -1;
}
else
{
layer_para.mode = DISP_LAYER_WORK_MODE_NORMAL;
arg[0] = 0;
arg[1] = layer_hdl;
arg[2] = (__u32)&layer_para;
arg[3] = 0;
disp_ioctl(NULL,DISP_CMD_LAYER_SET_PARA,(void*)arg);
arg[0] = 0;
arg[1] = layer_hdl;
arg[2] = 0;
arg[3] = 0;
disp_ioctl(NULL,DISP_CMD_LAYER_OPEN,(void*)arg);
printf("show bmp ok\n");
}
arg[0] = DISP_REG_IMAGE0;
disp_ioctl(NULL,DISP_CMD_PRINT_REG,(void*)arg);
return 0;
}
static int display_bmp(char dev_flag,char dev_number,char partition_number,char *file,unsigned int buff)
{
int ret = 0;
Picture_t PictureInfo;
unsigned int addr;
if(buff){
printf("use buff\n");
addr = (unsigned int)buff;
}else{
printf("use reserved mem\n");
addr = (unsigned int)DISPALY_RESERVED_MEM;
}
ret = read_bmp_from_flash(dev_flag,dev_number,partition_number,addr,file);
if(ret){
sunxi_printf("read_bmp_from_flash fail\n");
goto done;
}
ret = sunxi_bmp_parse(addr,&PictureInfo);
if(ret){
sunxi_printf("sunxi_bmp_parse fail\n");
goto done;
}
ret = disp_bmp_show(&PictureInfo);
if(ret){
sunxi_printf("disp_bmp_show fail\n");
goto done;
}
done:
return ret;
}
//-------------------------------------------------------------------------------
int do_sunxi_display(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
int ret = 0;
unsigned int addr,length;
char *ep;
char *file;
char *buf=NULL;
char storage_type,dev_number,partition_number,control;
if(argc < 6){
printf("sunxi_display <interface> <dev> <part> <addr> <filename>\n");
return 1;
}
length = SUNXI_BMP_LIMIT;
if(!strcmp(argv[1],"mmc"))
storage_type = 1;
else if(!strcmp(argv[1],"nand"))
storage_type = 0;
else{
printf("the media doesn`t support now!\n" );
return 1;
}
dev_number = (char)simple_strtoul(argv[2],&ep,16);
partition_number = (char)simple_strtoul(argv[3],&ep,16);
addr = (unsigned int)simple_strtoul(argv[4],&ep,16);
control = (char)simple_strtoul(argv[6],&ep,16);
if(control){
printf("reserved mode !\n");
display_bmp(storage_type,dev_number,partition_number,argv[5],0);
}else{
if(addr<40000000){
buf =(char *) malloc(length);
display_bmp(storage_type,dev_number,partition_number,argv[5],(unsigned int)buf);
}else{
display_bmp(storage_type,dev_number,partition_number,argv[5],addr);
}
}
if(buf)
free(buf);
return 0;
}
U_BOOT_CMD(
sunxi_display, CONFIG_SYS_MAXARGS, 0, do_sunxi_display,
"sunxi_flash sub-system",
"sunxi_display <interface> <dev> <part> <addr> <filename>\n"
);