/* * Driver for NAND support, Rick Bronson * borrowed heavily from: * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse * * 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 #include #include #include #include #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;jbiWidth; 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 \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 \n" );