diff options
-rw-r--r-- | board/raspberrypi/rpi_b/rpi_b.c | 14 | ||||
-rw-r--r-- | common/lcd.c | 87 | ||||
-rw-r--r-- | doc/device-tree-bindings/video/simple-framebuffer.txt | 25 | ||||
-rw-r--r-- | drivers/video/cfb_console.c | 15 | ||||
-rw-r--r-- | include/configs/rpi_b.h | 2 | ||||
-rw-r--r-- | include/lcd.h | 3 |
6 files changed, 139 insertions, 7 deletions
diff --git a/board/raspberrypi/rpi_b/rpi_b.c b/board/raspberrypi/rpi_b/rpi_b.c index 6b3e095ba8..16d442aa62 100644 --- a/board/raspberrypi/rpi_b/rpi_b.c +++ b/board/raspberrypi/rpi_b/rpi_b.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012 Stephen Warren + * (C) Copyright 2012-2013 Stephen Warren * * See file CREDITS for list of people who contributed to this * project. @@ -15,6 +15,8 @@ */ #include <common.h> +#include <config.h> +#include <lcd.h> #include <asm/arch/mbox.h> #include <asm/arch/sdhci.h> #include <asm/global_data.h> @@ -77,3 +79,13 @@ int board_mmc_init(void) return bcm2835_sdhci_init(BCM2835_SDHCI_BASE, msg_clk->get_clock_rate.body.resp.rate_hz); } + +void ft_board_setup(void *blob, bd_t *bd) +{ + /* + * For now, we simply always add the simplefb DT node. Later, we + * should be more intelligent, and e.g. only do this if no enabled DT + * node exists for the "real" graphics driver. + */ + lcd_dt_simplefb_add_node(blob); +} diff --git a/common/lcd.c b/common/lcd.c index edae835fb0..3a60484eea 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -57,6 +57,10 @@ #include <atmel_lcdc.h> #endif +#if defined(CONFIG_LCD_DT_SIMPLEFB) +#include <libfdt.h> +#endif + /************************************************************************/ /* ** FONT DATA */ /************************************************************************/ @@ -1182,3 +1186,86 @@ 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; + const char format[] = +#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) +{ + const char compat[] = "simple-framebuffer"; + 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 diff --git a/doc/device-tree-bindings/video/simple-framebuffer.txt b/doc/device-tree-bindings/video/simple-framebuffer.txt new file mode 100644 index 0000000000..3ea4605831 --- /dev/null +++ b/doc/device-tree-bindings/video/simple-framebuffer.txt @@ -0,0 +1,25 @@ +Simple Framebuffer + +A simple frame-buffer describes a raw memory region that may be rendered to, +with the assumption that the display hardware has already been set up to scan +out from that buffer. + +Required properties: +- compatible: "simple-framebuffer" +- reg: Should contain the location and size of the framebuffer memory. +- width: The width of the framebuffer in pixels. +- height: The height of the framebuffer in pixels. +- stride: The number of bytes in each line of the framebuffer. +- format: The format of the framebuffer surface. Valid values are: + - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b). + +Example: + + framebuffer { + compatible = "simple-framebuffer"; + reg = <0x1d385000 (1600 * 1200 * 2)>; + width = <1600>; + height = <1200>; + stride = <(1600 * 2)>; + format = "r5g6b5"; + }; diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 0793f07f24..b10f1590ba 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -572,8 +572,6 @@ static void video_drawchars(int xx, int yy, unsigned char *s, int count) SWAP32((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx); } - if (cfb_do_flush_cache) - flush_cache((ulong)dest0, 32); dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; s++; } @@ -642,8 +640,6 @@ static void video_invertchar(int xx, int yy) for (x = firstx; x < lastx; x++) { u8 *dest = (u8 *)(video_fb_address) + x + y; *dest = ~*dest; - if (cfb_do_flush_cache) - flush_cache((ulong)dest, 4); } } } @@ -687,6 +683,8 @@ void console_cursor(int state) } cursor_state = state; } + if (cfb_do_flush_cache) + flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE); } #endif @@ -739,8 +737,6 @@ static void console_clear_line(int line, int begin, int end) memsetl(offset + i * VIDEO_LINE_LEN, size, bgx); } #endif - if (cfb_do_flush_cache) - flush_cache((ulong)CONSOLE_ROW_FIRST, CONSOLE_SIZE); } static void console_scrollup(void) @@ -1146,6 +1142,8 @@ void video_putc(const char c) #else parse_putc(c); #endif + if (cfb_do_flush_cache) + flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE); } void video_puts(const char *s) @@ -1799,6 +1797,8 @@ int video_display_bitmap(ulong bmp_image, int x, int y) } #endif + if (cfb_do_flush_cache) + flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE); return (0); } #endif @@ -2209,6 +2209,9 @@ static int video_init(void) console_col = 0; console_row = 0; + if (cfb_do_flush_cache) + flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE); + return 0; } diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h index c18b35b057..216c6cb70b 100644 --- a/include/configs/rpi_b.h +++ b/include/configs/rpi_b.h @@ -61,6 +61,7 @@ #define CONFIG_BCM2835_GPIO /* LCD */ #define CONFIG_LCD +#define CONFIG_LCD_DT_SIMPLEFB #define LCD_BPP LCD_COLOR16 /* * Prevent allocation of RAM for FB; the real FB address is queried @@ -175,6 +176,7 @@ /* Device tree support for bootm/bootz */ #define CONFIG_OF_LIBFDT +#define CONFIG_OF_BOARD_SETUP /* ATAGs support for bootm/bootz */ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_CMDLINE_TAG diff --git a/include/lcd.h b/include/lcd.h index c6e7fc5216..30225edf56 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -324,6 +324,9 @@ void lcd_show_board_info(void); /* Return the size of the LCD frame buffer, and the line length */ int lcd_get_size(int *line_length); +int lcd_dt_simplefb_add_node(void *blob); +int lcd_dt_simplefb_enable_existing_node(void *blob); + /************************************************************************/ /* ** BITMAP DISPLAY SUPPORT */ /************************************************************************/ |