Skip to content
Snippets Groups Projects
lcd.c 29.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
    
    
    #ifdef CONFIG_SPLASH_SCREEN_ALIGN
    
    	splash_align_axis(&x, pwidth, width);
    	splash_align_axis(&y, panel_info.vl_row, height);
    
    #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
    
    
    	if ((x + width) > pwidth)
    
    		width = pwidth - x;
    
    	if ((y + height) > panel_info.vl_row)
    
    		height = panel_info.vl_row - y;
    
    
    	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
    	fb   = (uchar *)(lcd_base +
    
    		(y + height - 1) * lcd_line_length + x * bpix / 8);
    
    	switch (bmp_bpix) {
    
    Mark Jackson's avatar
    Mark Jackson committed
    	case 1: /* pass through */
    	case 8:
    
    #ifdef CONFIG_LCD_BMP_RLE8
    
    		u32 compression = get_unaligned_le32(&bmp->header.compression);
    		if (compression == BMP_BI_RLE8) {
    
    			if (bpix != 16) {
    				/* TODO implement render code for bpix != 16 */
    				printf("Error: only support 16 bpix");
    				return 1;
    			}
    			lcd_display_rle8_bitmap(bmp, cmap_base, fb, x, y);
    			break;
    		}
    #endif
    
    
    		if (bpix != 16)
    			byte_width = width;
    		else
    			byte_width = width * 2;
    
    
    Mark Jackson's avatar
    Mark Jackson committed
    		for (i = 0; i < height; ++i) {
    			WATCHDOG_RESET();
    
    			for (j = 0; j < width; j++) {
    				if (bpix != 16) {
    
    					FB_PUT_BYTE(fb, bmap);
    
    				} else {
    					*(uint16_t *)fb = cmap_base[*(bmap++)];
    					fb += sizeof(uint16_t) / sizeof(*fb);
    				}
    			}
    
    			bmap += (padded_width - width);
    
    			fb -= byte_width + lcd_line_length;
    
    Mark Jackson's avatar
    Mark Jackson committed
    		}
    		break;
    
    #if defined(CONFIG_BMP_16BPP)
    	case 16:
    		for (i = 0; i < height; ++i) {
    			WATCHDOG_RESET();
    
    			for (j = 0; j < width; j++)
    				fb_put_word(&fb, &bmap);
    
    
    			bmap += (padded_width - width) * 2;
    
    			fb -= width * 2 + lcd_line_length;
    
    Mark Jackson's avatar
    Mark Jackson committed
    		}
    		break;
    #endif /* CONFIG_BMP_16BPP */
    
    
    #if defined(CONFIG_BMP_32BPP)
    	case 32:
    		for (i = 0; i < height; ++i) {
    			for (j = 0; j < width; j++) {
    				*(fb++) = *(bmap++);
    				*(fb++) = *(bmap++);
    				*(fb++) = *(bmap++);
    				*(fb++) = *(bmap++);
    			}
    
    			fb -= lcd_line_length + width * (bpix / 8);
    
    		}
    		break;
    #endif /* CONFIG_BMP_32BPP */
    
    Mark Jackson's avatar
    Mark Jackson committed
    	default:
    		break;
    	};
    
    static void *lcd_logo(void)
    
    {
    #ifdef CONFIG_SPLASH_SCREEN
    	char *s;
    	ulong addr;
    	static int do_splash = 1;
    
    	if (do_splash && (s = getenv("splashimage")) != NULL) {
    
    		addr = simple_strtoul (s, NULL, 16);
    
    		if (bmp_display(addr, x, y) == 0)
    
    			return (void *)lcd_base;
    
    #ifdef CONFIG_LCD_INFO
    	console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;
    	console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;
    	lcd_show_board_info();
    #endif /* CONFIG_LCD_INFO */
    
    Stelian Pop's avatar
    Stelian Pop committed
    
    
    #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
    
    	return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length);
    
    	return (void *)lcd_base;
    
    #endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */
    
    #ifdef CONFIG_SPLASHIMAGE_GUARD
    static int on_splashimage(const char *name, const char *value, enum env_op op,
    	int flags)
    {
    	ulong addr;
    	int aligned;
    
    	if (op == env_op_delete)
    		return 0;
    
    	addr = simple_strtoul(value, NULL, 16);
    	/* See README.displaying-bmps */
    	aligned = (addr % 4 == 2);
    	if (!aligned) {
    		printf("Invalid splashimage value. Value must be 16 bit aligned, but not 32 bit aligned\n");
    		return -1;
    	}
    
    	return 0;
    }
    
    U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
    #endif
    
    
    void lcd_position_cursor(unsigned col, unsigned row)
    {
    	console_col = min(col, CONSOLE_COLS - 1);
    	console_row = min(row, CONSOLE_ROWS - 1);
    }
    
    int lcd_get_pixel_width(void)
    {
    	return panel_info.vl_col;
    }
    
    int lcd_get_pixel_height(void)
    {
    	return panel_info.vl_row;
    }
    
    int lcd_get_screen_rows(void)
    {
    	return CONSOLE_ROWS;
    }
    
    int lcd_get_screen_columns(void)
    {
    	return CONSOLE_COLS;
    }
    
    
    #if defined(CONFIG_LCD_DT_SIMPLEFB)
    static int lcd_dt_simplefb_configure_node(void *blob, int off)
    {
    	u32 stride;
    	fdt32_t cells[2];
    	int ret;
    
    #if LCD_BPP == LCD_COLOR16
    		"r5g6b5";
    #else
    		"";
    #endif
    
    	if (!format[0])
    		return -1;
    
    	stride = panel_info.vl_col * 2;
    
    	cells[0] = cpu_to_fdt32(gd->fb_base);
    	cells[1] = cpu_to_fdt32(stride * panel_info.vl_row);
    	ret = fdt_setprop(blob, off, "reg", cells, sizeof(cells[0]) * 2);
    	if (ret < 0)
    		return -1;
    
    	cells[0] = cpu_to_fdt32(panel_info.vl_col);
    	ret = fdt_setprop(blob, off, "width", cells, sizeof(cells[0]));
    	if (ret < 0)
    		return -1;
    
    	cells[0] = cpu_to_fdt32(panel_info.vl_row);
    	ret = fdt_setprop(blob, off, "height", cells, sizeof(cells[0]));
    	if (ret < 0)
    		return -1;
    
    	cells[0] = cpu_to_fdt32(stride);
    	ret = fdt_setprop(blob, off, "stride", cells, sizeof(cells[0]));
    	if (ret < 0)
    		return -1;
    
    	ret = fdt_setprop(blob, off, "format", format, strlen(format) + 1);
    	if (ret < 0)
    		return -1;
    
    	ret = fdt_delprop(blob, off, "status");
    	if (ret < 0)
    		return -1;
    
    	return 0;
    }
    
    int lcd_dt_simplefb_add_node(void *blob)
    {
    
    	static const char compat[] = "simple-framebuffer";
    	static const char disabled[] = "disabled";
    
    	int off, ret;
    
    	off = fdt_add_subnode(blob, 0, "framebuffer");
    	if (off < 0)
    		return -1;
    
    	ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled));
    	if (ret < 0)
    		return -1;
    
    	ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat));
    	if (ret < 0)
    		return -1;
    
    	return lcd_dt_simplefb_configure_node(blob, off);
    }
    
    int lcd_dt_simplefb_enable_existing_node(void *blob)
    {
    	int off;
    
    	off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
    	if (off < 0)
    		return -1;
    
    	return lcd_dt_simplefb_configure_node(blob, off);
    }
    #endif