mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 13:11:31 +00:00
- Add two- and three-argument versions of CONFIG_IS_ENABLED in linux/kconfig.h - Adds a new feature which supports copying modified parts of the frame buffer to the uncached hardware buffer - Enable the copy framebuffer on various x86 targets
This commit is contained in:
commit
506d52308a
32 changed files with 657 additions and 167 deletions
|
@ -147,7 +147,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
/* Try bootm for legacy and FIT format image */
|
||||
if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
|
||||
do_bootm(cmdtp, 0, 4, bootm_argv);
|
||||
else if CONFIG_IS_ENABLED(CMD_BOOTZ)
|
||||
else if (CONFIG_IS_ENABLED(CMD_BOOTZ))
|
||||
do_bootz(cmdtp, 0, 4, bootm_argv);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# Copyright 2019 Google LLC
|
||||
|
||||
obj-$(CONFIG_SPL_BUILD) += cpu_spl.o
|
||||
obj-$(CONFIG_SPL_BUILD) += spl.o
|
||||
obj-$(CONFIG_SPL_BUILD) += systemagent.o
|
||||
obj-y += cpu_common.o
|
||||
|
||||
|
@ -11,7 +12,6 @@ obj-y += cpu.o
|
|||
obj-y += punit.o
|
||||
obj-y += fsp_bindings.o
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl.o
|
||||
obj-y += fsp_m.o
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -363,6 +363,11 @@ static void setup_cpu_features(void)
|
|||
: : "i" (em_rst), "i" (mp_ne_set) : "eax");
|
||||
}
|
||||
|
||||
void cpu_reinit_fpu(void)
|
||||
{
|
||||
asm ("fninit\n");
|
||||
}
|
||||
|
||||
static void setup_identity(void)
|
||||
{
|
||||
/* identify CPU via cpuid and store the decoded info into gd->arch */
|
||||
|
|
|
@ -43,6 +43,14 @@ int x86_cpu_reinit_f(void);
|
|||
*/
|
||||
int x86_cpu_init_tpl(void);
|
||||
|
||||
/**
|
||||
* cpu_reinit_fpu() - Reinit the FPU if something is wrong with it
|
||||
*
|
||||
* The FSP-M code can leave registers in use in the FPU. This functions reinits
|
||||
* it so that the FPU can be used safely
|
||||
*/
|
||||
void cpu_reinit_fpu(void);
|
||||
|
||||
int cpu_init_f(void);
|
||||
void setup_gdt(struct global_data *id, u64 *gdt_addr);
|
||||
/*
|
||||
|
|
|
@ -117,6 +117,16 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int fsp_video_bind(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
|
||||
/* Set the maximum supported resolution */
|
||||
plat->size = 2560 * 1600 * 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id fsp_video_ids[] = {
|
||||
{ .compatible = "fsp-fb" },
|
||||
{ }
|
||||
|
@ -126,7 +136,9 @@ U_BOOT_DRIVER(fsp_video) = {
|
|||
.name = "fsp_video",
|
||||
.id = UCLASS_VIDEO,
|
||||
.of_match = fsp_video_ids,
|
||||
.bind = fsp_video_bind,
|
||||
.probe = fsp_video_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
static struct pci_device_id fsp_video_supported[] = {
|
||||
|
|
|
@ -85,6 +85,7 @@ int fsp_memory_init(bool s3wake, bool use_spi_flash)
|
|||
func = (fsp_memory_init_func)(hdr->img_base + hdr->fsp_mem_init);
|
||||
ret = func(&upd, &hob);
|
||||
bootstage_accum(BOOTSTAGE_ID_ACCUM_FSP_M);
|
||||
cpu_reinit_fpu();
|
||||
if (ret)
|
||||
return log_msg_ret("SDRAM init fail\n", ret);
|
||||
|
||||
|
|
|
@ -229,18 +229,34 @@ static void console_putc(int file, const char c)
|
|||
}
|
||||
}
|
||||
|
||||
static void console_puts_noserial(int file, const char *s)
|
||||
/**
|
||||
* console_puts_select() - Output a string to all console devices
|
||||
*
|
||||
* @file: File number to output to (e,g, stdout, see stdio.h)
|
||||
* @serial_only: true to output only to serial, false to output to everything
|
||||
* else
|
||||
* @s: String to output
|
||||
*/
|
||||
static void console_puts_select(int file, bool serial_only, const char *s)
|
||||
{
|
||||
int i;
|
||||
struct stdio_dev *dev;
|
||||
|
||||
for (i = 0; i < cd_count[file]; i++) {
|
||||
bool is_serial;
|
||||
|
||||
dev = console_devices[file][i];
|
||||
if (dev->puts != NULL && !console_dev_is_serial(dev))
|
||||
is_serial = console_dev_is_serial(dev);
|
||||
if (dev->puts && serial_only == is_serial)
|
||||
dev->puts(dev, s);
|
||||
}
|
||||
}
|
||||
|
||||
void console_puts_select_stderr(bool serial_only, const char *s)
|
||||
{
|
||||
console_puts_select(stderr, serial_only, s);
|
||||
}
|
||||
|
||||
static void console_puts(int file, const char *s)
|
||||
{
|
||||
int i;
|
||||
|
@ -275,9 +291,9 @@ static inline void console_putc(int file, const char c)
|
|||
stdio_devices[file]->putc(stdio_devices[file], c);
|
||||
}
|
||||
|
||||
static inline void console_puts_noserial(int file, const char *s)
|
||||
void console_puts_select(int file, bool serial_only, const char *s)
|
||||
{
|
||||
if (!console_dev_is_serial(stdio_devices[file]))
|
||||
if (serial_only == console_dev_is_serial(stdio_devices[file]))
|
||||
stdio_devices[file]->puts(stdio_devices[file], s);
|
||||
}
|
||||
|
||||
|
@ -489,7 +505,7 @@ static void print_pre_console_buffer(int flushpoint)
|
|||
puts(buf_out);
|
||||
break;
|
||||
case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
|
||||
console_puts_noserial(stdout, buf_out);
|
||||
console_puts_select(stdout, false, buf_out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -776,7 +792,7 @@ int console_announce_r(void)
|
|||
|
||||
display_options_get_banner(false, buf, sizeof(buf));
|
||||
|
||||
console_puts_noserial(stdout, buf);
|
||||
console_puts_select(stdout, false, buf);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -62,10 +62,10 @@ CONFIG_SPI=y
|
|||
CONFIG_TPM_TIS_LPC=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_VIDEO_COPY=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
|
||||
CONFIG_VIDEO_IVYBRIDGE_IGD=y
|
||||
CONFIG_CONSOLE_SCROLL_LINES=5
|
||||
CONFIG_CMD_DHRYSTONE=y
|
||||
CONFIG_TPM=y
|
||||
# CONFIG_GZIP is not set
|
||||
|
|
|
@ -67,8 +67,8 @@ CONFIG_SPI=y
|
|||
CONFIG_TPM_TIS_LPC=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_VIDEO_COPY=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
|
||||
CONFIG_CONSOLE_SCROLL_LINES=5
|
||||
CONFIG_TPM=y
|
||||
# CONFIG_GZIP is not set
|
||||
|
|
|
@ -59,7 +59,7 @@ CONFIG_RTL8169=y
|
|||
CONFIG_SPI=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_VIDEO_COPY=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_11B=y
|
||||
CONFIG_CONSOLE_SCROLL_LINES=5
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_118=y
|
||||
# CONFIG_GZIP is not set
|
||||
|
|
|
@ -220,6 +220,7 @@ CONFIG_DM_USB=y
|
|||
CONFIG_USB_EMUL=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_DM_VIDEO=y
|
||||
CONFIG_VIDEO_COPY=y
|
||||
CONFIG_CONSOLE_ROTATION=y
|
||||
CONFIG_CONSOLE_TRUETYPE=y
|
||||
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
* Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_PCI
|
||||
|
||||
#include <common.h>
|
||||
#include <bios_emul.h>
|
||||
#include <bootstage.h>
|
||||
|
@ -344,7 +346,16 @@ int vbe_setup_video_priv(struct vesa_mode_info *vesa,
|
|||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
plat->base = vesa->phys_base_ptr;
|
||||
|
||||
/* Use double buffering if enabled */
|
||||
if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
|
||||
if (!plat->base)
|
||||
return log_msg_ret("copy", -ENFILE);
|
||||
plat->copy_base = vesa->phys_base_ptr;
|
||||
} else {
|
||||
plat->base = vesa->phys_base_ptr;
|
||||
}
|
||||
log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
|
||||
plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
|
||||
|
||||
return 0;
|
||||
|
@ -372,6 +383,15 @@ int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void))
|
|||
|
||||
ret = vbe_setup_video_priv(&mode_info.vesa, uc_priv, plat);
|
||||
if (ret) {
|
||||
if (ret == -ENFILE) {
|
||||
/*
|
||||
* See video-uclass.c for how to set up reserved memory
|
||||
* in your video driver
|
||||
*/
|
||||
log_err("CONFIG_VIDEO_COPY enabled but driver '%s' set up no reserved memory\n",
|
||||
dev->driver->name);
|
||||
}
|
||||
|
||||
debug("No video mode configured\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,37 @@ config BACKLIGHT
|
|||
This provides backlight uclass driver that enables basic panel
|
||||
backlight support.
|
||||
|
||||
config VIDEO_PCI_DEFAULT_FB_SIZE
|
||||
hex "Default framebuffer size to use if no drivers request it"
|
||||
depends on DM_VIDEO
|
||||
default 0x1000000 if X86 && PCI
|
||||
default 0 if !(X86 && PCI)
|
||||
help
|
||||
Generally, video drivers request the amount of memory they need for
|
||||
the frame buffer when they are bound, by setting the size field in
|
||||
struct video_uc_platdata. That memory is then reserved for use after
|
||||
relocation. But PCI drivers cannot be bound before relocation unless
|
||||
they are mentioned in the devicetree.
|
||||
|
||||
With this value set appropriately, it is possible for PCI video
|
||||
devices to have a framebuffer allocated by U-Boot.
|
||||
|
||||
Note: the framebuffer needs to be large enough to store all pixels at
|
||||
maximum resolution. For example, at 1920 x 1200 with 32 bits per
|
||||
pixel, 2560 * 1600 * 32 / 8 = 0xfa0000 bytes are needed.
|
||||
|
||||
config VIDEO_COPY
|
||||
bool "Enable copying the frame buffer to a hardware copy"
|
||||
depends on DM_VIDEO
|
||||
help
|
||||
On some machines (e.g. x86), reading from the frame buffer is very
|
||||
slow because it is uncached. To improve performance, this feature
|
||||
allows the frame buffer to be kept in cached memory (allocated by
|
||||
U-Boot) and then copied to the hardware frame-buffer as needed.
|
||||
|
||||
To use this, your video driver must set @copy_base in
|
||||
struct video_uc_platdata.
|
||||
|
||||
config BACKLIGHT_PWM
|
||||
bool "Generic PWM based Backlight Driver"
|
||||
depends on BACKLIGHT && DM_PWM
|
||||
|
|
|
@ -664,6 +664,7 @@ static int broadwell_igd_probe(struct udevice *dev)
|
|||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
bool is_broadwell;
|
||||
ulong fbbase;
|
||||
int ret;
|
||||
|
||||
if (!ll_boot_init()) {
|
||||
|
@ -690,7 +691,8 @@ static int broadwell_igd_probe(struct udevice *dev)
|
|||
return ret;
|
||||
|
||||
/* Use write-combining for the graphics memory, 256MB */
|
||||
ret = mtrr_add_request(MTRR_TYPE_WRCOMB, plat->base, 256 << 20);
|
||||
fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
|
||||
ret = mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
|
||||
if (!ret)
|
||||
ret = mtrr_commit(true);
|
||||
if (ret && ret != -ENOSYS) {
|
||||
|
@ -752,6 +754,17 @@ static int broadwell_igd_ofdata_to_platdata(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int broadwell_igd_bind(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
|
||||
|
||||
/* Set the maximum supported resolution */
|
||||
uc_plat->size = 2560 * 1600 * 4;
|
||||
log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct video_ops broadwell_igd_ops = {
|
||||
};
|
||||
|
||||
|
@ -766,6 +779,7 @@ U_BOOT_DRIVER(broadwell_igd) = {
|
|||
.of_match = broadwell_igd_ids,
|
||||
.ops = &broadwell_igd_ops,
|
||||
.ofdata_to_platdata = broadwell_igd_ofdata_to_platdata,
|
||||
.bind = broadwell_igd_bind,
|
||||
.probe = broadwell_igd_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct broadwell_igd_priv),
|
||||
.platdata_auto_alloc_size = sizeof(struct broadwell_igd_plat),
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
static int console_normal_set_row(struct udevice *dev, uint row, int clr)
|
||||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
void *line;
|
||||
void *line, *end;
|
||||
int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
|
||||
|
@ -28,6 +29,7 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
case VIDEO_BPP16:
|
||||
|
@ -36,6 +38,7 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
case VIDEO_BPP32:
|
||||
|
@ -44,11 +47,15 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, line, end);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -59,10 +66,15 @@ static int console_normal_move_rows(struct udevice *dev, uint rowdst,
|
|||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
void *dst;
|
||||
void *src;
|
||||
int size;
|
||||
int ret;
|
||||
|
||||
dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
|
||||
src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
|
||||
memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
|
||||
size = VIDEO_FONT_HEIGHT * vid_priv->line_length * count;
|
||||
ret = vidconsole_memmove(dev, dst, src, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -74,8 +86,13 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
|
|||
struct udevice *vid = dev->parent;
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
|
||||
int i, row;
|
||||
void *line = vid_priv->fb + y * vid_priv->line_length +
|
||||
void *start;
|
||||
void *line;
|
||||
int ret;
|
||||
|
||||
start = vid_priv->fb + y * vid_priv->line_length +
|
||||
VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
|
||||
line = start;
|
||||
|
||||
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
|
||||
return -EAGAIN;
|
||||
|
@ -126,6 +143,9 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
|
|||
}
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, start, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return VID_TO_POS(VIDEO_FONT_WIDTH);
|
||||
}
|
||||
|
|
|
@ -15,11 +15,13 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
|
|||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
void *line;
|
||||
void *start, *line;
|
||||
int i, j;
|
||||
int ret;
|
||||
|
||||
line = vid_priv->fb + vid_priv->line_length -
|
||||
start = vid_priv->fb + vid_priv->line_length -
|
||||
(row + 1) * VIDEO_FONT_HEIGHT * pbytes;
|
||||
line = start;
|
||||
for (j = 0; j < vid_priv->ysize; j++) {
|
||||
switch (vid_priv->bpix) {
|
||||
case VIDEO_BPP8:
|
||||
|
@ -51,6 +53,9 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
|
|||
}
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, start, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -59,10 +64,10 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
|
|||
uint count)
|
||||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
void *dst;
|
||||
void *src;
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int j;
|
||||
int j, ret;
|
||||
|
||||
dst = vid_priv->fb + vid_priv->line_length -
|
||||
(rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
|
||||
|
@ -70,7 +75,10 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
|
|||
(rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
|
||||
|
||||
for (j = 0; j < vid_priv->ysize; j++) {
|
||||
memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
|
||||
ret = vidconsole_memmove(dev, dst, src,
|
||||
VIDEO_FONT_HEIGHT * pbytes * count);
|
||||
if (ret)
|
||||
return ret;
|
||||
src += vid_priv->line_length;
|
||||
dst += vid_priv->line_length;
|
||||
}
|
||||
|
@ -83,14 +91,16 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
|
|||
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
|
||||
struct udevice *vid = dev->parent;
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int i, col;
|
||||
int mask = 0x80;
|
||||
void *line;
|
||||
uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int i, col, x, linenum, ret;
|
||||
int mask = 0x80;
|
||||
void *start, *line;
|
||||
|
||||
line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
|
||||
vid_priv->line_length - (y + 1) * pbytes;
|
||||
linenum = VID_TO_PIXEL(x_frac) + 1;
|
||||
x = y + 1;
|
||||
start = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes;
|
||||
line = start;
|
||||
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
|
||||
return -EAGAIN;
|
||||
|
||||
|
@ -135,6 +145,10 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
|
|||
line += vid_priv->line_length;
|
||||
mask >>= 1;
|
||||
}
|
||||
/* We draw backwards from 'start, so account for the first line */
|
||||
ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return VID_TO_POS(VIDEO_FONT_WIDTH);
|
||||
}
|
||||
|
@ -143,12 +157,13 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
|
|||
static int console_set_row_2(struct udevice *dev, uint row, int clr)
|
||||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
void *line;
|
||||
void *start, *line, *end;
|
||||
int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
|
||||
start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
|
||||
(row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
|
||||
line = start;
|
||||
switch (vid_priv->bpix) {
|
||||
case VIDEO_BPP8:
|
||||
if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
|
||||
|
@ -156,6 +171,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
case VIDEO_BPP16:
|
||||
|
@ -164,6 +180,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
case VIDEO_BPP32:
|
||||
|
@ -172,11 +189,15 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, start, end);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -194,7 +215,8 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
|
|||
vid_priv->line_length;
|
||||
src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
|
||||
vid_priv->line_length;
|
||||
memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
|
||||
vidconsole_memmove(dev, dst, src,
|
||||
VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -204,16 +226,16 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
|
|||
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
|
||||
struct udevice *vid = dev->parent;
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
|
||||
int i, row;
|
||||
void *line;
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int i, row, x, linenum, ret;
|
||||
void *start, *line;
|
||||
|
||||
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
|
||||
return -EAGAIN;
|
||||
|
||||
line = vid_priv->fb + (vid_priv->ysize - y - 1) *
|
||||
vid_priv->line_length +
|
||||
(vid_priv->xsize - VID_TO_PIXEL(x_frac) -
|
||||
VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
|
||||
linenum = vid_priv->ysize - y - 1;
|
||||
x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - 1;
|
||||
start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
|
||||
line = start;
|
||||
|
||||
for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
|
||||
unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
|
||||
|
@ -261,6 +283,10 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
|
|||
}
|
||||
line -= vid_priv->line_length;
|
||||
}
|
||||
/* Add 4 bytes to allow for the first pixel writen */
|
||||
ret = vidconsole_sync_copy(dev, start + 4, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return VID_TO_POS(VIDEO_FONT_WIDTH);
|
||||
}
|
||||
|
@ -269,10 +295,11 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
|
|||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
void *line;
|
||||
int i, j;
|
||||
void *start, *line;
|
||||
int i, j, ret;
|
||||
|
||||
line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
|
||||
start = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
|
||||
line = start;
|
||||
for (j = 0; j < vid_priv->ysize; j++) {
|
||||
switch (vid_priv->bpix) {
|
||||
case VIDEO_BPP8:
|
||||
|
@ -304,6 +331,9 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
|
|||
}
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, start, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -312,16 +342,19 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
|
|||
uint count)
|
||||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
void *dst;
|
||||
void *src;
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int j;
|
||||
int j, ret;
|
||||
|
||||
dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
|
||||
src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
|
||||
|
||||
for (j = 0; j < vid_priv->ysize; j++) {
|
||||
memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
|
||||
ret = vidconsole_memmove(dev, dst, src,
|
||||
VIDEO_FONT_HEIGHT * pbytes * count);
|
||||
if (ret)
|
||||
return ret;
|
||||
src += vid_priv->line_length;
|
||||
dst += vid_priv->line_length;
|
||||
}
|
||||
|
@ -334,17 +367,17 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
|
|||
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
|
||||
struct udevice *vid = dev->parent;
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int i, col;
|
||||
int mask = 0x80;
|
||||
void *line = vid_priv->fb +
|
||||
(vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
|
||||
vid_priv->line_length + y * pbytes;
|
||||
uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int i, col, x, ret;
|
||||
int mask = 0x80;
|
||||
void *start, *line;
|
||||
|
||||
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
|
||||
return -EAGAIN;
|
||||
|
||||
x = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1;
|
||||
start = vid_priv->fb + x * vid_priv->line_length + y * pbytes;
|
||||
line = start;
|
||||
for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
|
||||
switch (vid_priv->bpix) {
|
||||
case VIDEO_BPP8:
|
||||
|
@ -386,6 +419,10 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
|
|||
line -= vid_priv->line_length;
|
||||
mask >>= 1;
|
||||
}
|
||||
/* Add a line to allow for the first pixels writen */
|
||||
ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return VID_TO_POS(VIDEO_FONT_WIDTH);
|
||||
}
|
||||
|
|
|
@ -127,9 +127,9 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
|
|||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
struct console_tt_priv *priv = dev_get_priv(dev);
|
||||
void *line;
|
||||
void *end, *line;
|
||||
int pixels = priv->font_size * vid_priv->line_length;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
line = vid_priv->fb + row * priv->font_size * vid_priv->line_length;
|
||||
switch (vid_priv->bpix) {
|
||||
|
@ -139,6 +139,7 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -148,6 +149,7 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -157,12 +159,16 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
|
|||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, line, end);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -174,11 +180,14 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
|
|||
struct console_tt_priv *priv = dev_get_priv(dev);
|
||||
void *dst;
|
||||
void *src;
|
||||
int i, diff;
|
||||
int i, diff, ret;
|
||||
|
||||
dst = vid_priv->fb + rowdst * priv->font_size * vid_priv->line_length;
|
||||
src = vid_priv->fb + rowsrc * priv->font_size * vid_priv->line_length;
|
||||
memmove(dst, src, priv->font_size * vid_priv->line_length * count);
|
||||
ret = vidconsole_memmove(dev, dst, src, priv->font_size *
|
||||
vid_priv->line_length * count);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Scroll up our position history */
|
||||
diff = (rowsrc - rowdst) * priv->font_size;
|
||||
|
@ -203,8 +212,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
|
|||
struct pos_info *pos;
|
||||
u8 *bits, *data;
|
||||
int advance;
|
||||
void *line;
|
||||
int row;
|
||||
void *start, *end, *line;
|
||||
int row, ret;
|
||||
|
||||
/* First get some basic metrics about this character */
|
||||
stbtt_GetCodepointHMetrics(font, ch, &advance, &lsb);
|
||||
|
@ -253,11 +262,12 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
|
|||
|
||||
/* Figure out where to write the character in the frame buffer */
|
||||
bits = data;
|
||||
line = vid_priv->fb + y * vid_priv->line_length +
|
||||
start = vid_priv->fb + y * vid_priv->line_length +
|
||||
VID_TO_PIXEL(x) * VNBYTES(vid_priv->bpix);
|
||||
linenum = priv->baseline + yoff;
|
||||
if (linenum > 0)
|
||||
line += linenum * vid_priv->line_length;
|
||||
start += linenum * vid_priv->line_length;
|
||||
line = start;
|
||||
|
||||
/*
|
||||
* Write a row at a time, converting the 8bpp image into the colour
|
||||
|
@ -286,6 +296,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
|
|||
*dst++ &= out;
|
||||
bits++;
|
||||
}
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -307,6 +318,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
|
|||
*dst++ &= out;
|
||||
bits++;
|
||||
}
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -317,6 +329,9 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
|
|||
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, start, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
free(data);
|
||||
|
||||
return width_frac;
|
||||
|
@ -340,12 +355,13 @@ static int console_truetype_erase(struct udevice *dev, int xstart, int ystart,
|
|||
int xend, int yend, int clr)
|
||||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
void *line;
|
||||
void *start, *line;
|
||||
int pixels = xend - xstart;
|
||||
int row, i;
|
||||
int row, i, ret;
|
||||
|
||||
line = vid_priv->fb + ystart * vid_priv->line_length;
|
||||
line += xstart * VNBYTES(vid_priv->bpix);
|
||||
start = vid_priv->fb + ystart * vid_priv->line_length;
|
||||
start += xstart * VNBYTES(vid_priv->bpix);
|
||||
line = start;
|
||||
for (row = ystart; row < yend; row++) {
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
|
@ -380,6 +396,9 @@ static int console_truetype_erase(struct udevice *dev, int xstart, int ystart,
|
|||
}
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
ret = vidconsole_sync_copy(dev, start, line);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <log.h>
|
||||
#include <pci_rom.h>
|
||||
#include <vbe.h>
|
||||
#include <video.h>
|
||||
#include <asm/intel_regs.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mtrr.h>
|
||||
|
@ -722,7 +723,6 @@ static int gma_func0_init(struct udevice *dev)
|
|||
{
|
||||
struct udevice *nbridge;
|
||||
void *gtt_bar;
|
||||
ulong base;
|
||||
u32 reg32;
|
||||
int ret;
|
||||
int rev;
|
||||
|
@ -742,11 +742,6 @@ static int gma_func0_init(struct udevice *dev)
|
|||
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
||||
dm_pci_write_config32(dev, PCI_COMMAND, reg32);
|
||||
|
||||
/* Use write-combining for the graphics memory, 256MB */
|
||||
base = dm_pci_read_bar32(dev, 2);
|
||||
mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20);
|
||||
mtrr_commit(true);
|
||||
|
||||
gtt_bar = (void *)(ulong)dm_pci_read_bar32(dev, 0);
|
||||
debug("GT bar %p\n", gtt_bar);
|
||||
ret = gma_pm_init_pre_vbios(gtt_bar, rev);
|
||||
|
@ -758,6 +753,8 @@ static int gma_func0_init(struct udevice *dev)
|
|||
|
||||
static int bd82x6x_video_probe(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
ulong fbbase;
|
||||
void *gtt_bar;
|
||||
int ret, rev;
|
||||
|
||||
|
@ -774,6 +771,22 @@ static int bd82x6x_video_probe(struct udevice *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Use write-combining for the graphics memory, 256MB */
|
||||
fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
|
||||
mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
|
||||
mtrr_commit(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bd82x6x_video_bind(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
|
||||
|
||||
/* Set the maximum supported resolution */
|
||||
uc_plat->size = 2560 * 1600 * 4;
|
||||
log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -786,5 +799,6 @@ U_BOOT_DRIVER(bd82x6x_video) = {
|
|||
.name = "bd82x6x_video",
|
||||
.id = UCLASS_VIDEO,
|
||||
.of_match = bd82x6x_video_ids,
|
||||
.bind = bd82x6x_video_bind,
|
||||
.probe = bd82x6x_video_probe,
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ enum {
|
|||
|
||||
static int sandbox_sdl_probe(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
|
||||
struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
|
||||
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct sandbox_state *state = state_get_current();
|
||||
|
@ -40,6 +41,8 @@ static int sandbox_sdl_probe(struct udevice *dev)
|
|||
uc_priv->rot = plat->rot;
|
||||
uc_priv->vidconsole_drv_name = plat->vidconsole_drv_name;
|
||||
uc_priv->font_size = plat->font_size;
|
||||
if (IS_ENABLED(CONFIG_VIDEO_COPY))
|
||||
uc_plat->copy_base = uc_plat->base - uc_plat->size / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -53,8 +56,13 @@ static int sandbox_sdl_bind(struct udevice *dev)
|
|||
plat->xres = dev_read_u32_default(dev, "xres", LCD_MAX_WIDTH);
|
||||
plat->yres = dev_read_u32_default(dev, "yres", LCD_MAX_HEIGHT);
|
||||
plat->bpix = dev_read_u32_default(dev, "log2-depth", VIDEO_BPP16);
|
||||
plat->rot = dev_read_u32_default(dev, "rotate", 0);
|
||||
uc_plat->size = plat->xres * plat->yres * (1 << plat->bpix) / 8;
|
||||
debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
|
||||
|
||||
/* Allow space for two buffers, the lower one being the copy buffer */
|
||||
log_debug("Frame buffer size %x\n", uc_plat->size);
|
||||
if (IS_ENABLED(CONFIG_VIDEO_COPY))
|
||||
uc_plat->size *= 2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,39 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <pci.h>
|
||||
#include <vbe.h>
|
||||
#include <video.h>
|
||||
#include <asm/mtrr.h>
|
||||
|
||||
static int vesa_video_probe(struct udevice *dev)
|
||||
{
|
||||
return vbe_setup_video(dev, NULL);
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
ulong fbbase;
|
||||
int ret;
|
||||
|
||||
ret = vbe_setup_video(dev, NULL);
|
||||
if (ret)
|
||||
return log_ret(ret);
|
||||
|
||||
/* Use write-combining for the graphics memory, 256MB */
|
||||
fbbase = IS_ENABLED(CONFIG_VIDEO_COPY) ? plat->copy_base : plat->base;
|
||||
mtrr_add_request(MTRR_TYPE_WRCOMB, fbbase, 256 << 20);
|
||||
mtrr_commit(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vesa_video_bind(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
|
||||
|
||||
/* Set the maximum supported resolution */
|
||||
uc_plat->size = 2560 * 1600 * 4;
|
||||
log_debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id vesa_video_ids[] = {
|
||||
|
@ -22,6 +49,7 @@ U_BOOT_DRIVER(vesa_video) = {
|
|||
.name = "vesa_video",
|
||||
.id = UCLASS_VIDEO,
|
||||
.of_match = vesa_video_ids,
|
||||
.bind = vesa_video_bind,
|
||||
.probe = vesa_video_probe,
|
||||
};
|
||||
|
||||
|
|
|
@ -9,12 +9,13 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <console.h>
|
||||
#include <log.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <dm.h>
|
||||
#include <video.h>
|
||||
#include <video_console.h>
|
||||
#include <video_font.h> /* Bitmap font for code page 437 */
|
||||
#include <linux/ctype.h>
|
||||
|
||||
/*
|
||||
* Structure to describe a console color
|
||||
|
@ -556,16 +557,31 @@ int vidconsole_put_string(struct udevice *dev, const char *str)
|
|||
static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
|
||||
{
|
||||
struct udevice *dev = sdev->priv;
|
||||
int ret;
|
||||
|
||||
vidconsole_put_char(dev, ch);
|
||||
ret = vidconsole_put_char(dev, ch);
|
||||
if (ret) {
|
||||
#ifdef DEBUG
|
||||
console_puts_select_stderr(true, "[vc err: putc]");
|
||||
#endif
|
||||
}
|
||||
video_sync(dev->parent, false);
|
||||
}
|
||||
|
||||
static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
|
||||
{
|
||||
struct udevice *dev = sdev->priv;
|
||||
int ret;
|
||||
|
||||
vidconsole_put_string(dev, s);
|
||||
ret = vidconsole_put_string(dev, s);
|
||||
if (ret) {
|
||||
#ifdef DEBUG
|
||||
char str[30];
|
||||
|
||||
snprintf(str, sizeof(str), "[vc err: puts %d]", ret);
|
||||
console_puts_select_stderr(true, str);
|
||||
#endif
|
||||
}
|
||||
video_sync(dev->parent, false);
|
||||
}
|
||||
|
||||
|
@ -613,6 +629,22 @@ UCLASS_DRIVER(vidconsole) = {
|
|||
.per_device_auto_alloc_size = sizeof(struct vidconsole_priv),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_VIDEO_COPY
|
||||
int vidconsole_sync_copy(struct udevice *dev, void *from, void *to)
|
||||
{
|
||||
struct udevice *vid = dev_get_parent(dev);
|
||||
|
||||
return video_sync_copy(vid, from, to);
|
||||
}
|
||||
|
||||
int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
|
||||
int size)
|
||||
{
|
||||
memmove(dst, src, size);
|
||||
return vidconsole_sync_copy(dev, dst, dst + size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(CMD_VIDCONSOLE)
|
||||
void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <cpu_func.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
|
@ -45,6 +46,19 @@
|
|||
*/
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* struct video_uc_priv - Information for the video uclass
|
||||
*
|
||||
* @video_ptr: Current allocation position of the video framebuffer pointer.
|
||||
* While binding devices after relocation, this points to the next
|
||||
* available address to use for a device's framebuffer. It starts at
|
||||
* gd->video_top and works downwards, running out of space when it hits
|
||||
* gd->video_bottom.
|
||||
*/
|
||||
struct video_uc_priv {
|
||||
ulong video_ptr;
|
||||
};
|
||||
|
||||
void video_set_flush_dcache(struct udevice *dev, bool flush)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
@ -83,6 +97,11 @@ int video_reserve(ulong *addrp)
|
|||
debug("%s: Reserving %lx bytes at %lx for video device '%s'\n",
|
||||
__func__, size, *addrp, dev->name);
|
||||
}
|
||||
|
||||
/* Allocate space for PCI video devices in case there were not bound */
|
||||
if (*addrp == gd->video_top)
|
||||
*addrp -= CONFIG_VIDEO_PCI_DEFAULT_FB_SIZE;
|
||||
|
||||
gd->video_bottom = *addrp;
|
||||
gd->fb_base = *addrp;
|
||||
debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
|
||||
|
@ -94,6 +113,7 @@ int video_reserve(ulong *addrp)
|
|||
int video_clear(struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
int ret;
|
||||
|
||||
switch (priv->bpix) {
|
||||
case VIDEO_BPP16:
|
||||
|
@ -118,6 +138,9 @@ int video_clear(struct udevice *dev)
|
|||
memset(priv->fb, priv->colour_bg, priv->fb_size);
|
||||
break;
|
||||
}
|
||||
ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -201,6 +224,59 @@ int video_get_ysize(struct udevice *dev)
|
|||
return priv->ysize;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_COPY
|
||||
int video_sync_copy(struct udevice *dev, void *from, void *to)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
if (priv->copy_fb) {
|
||||
long offset, size;
|
||||
|
||||
/* Find the offset of the first byte to copy */
|
||||
if ((ulong)to > (ulong)from) {
|
||||
size = to - from;
|
||||
offset = from - priv->fb;
|
||||
} else {
|
||||
size = from - to;
|
||||
offset = to - priv->fb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow a bit of leeway for valid requests somewhere near the
|
||||
* frame buffer
|
||||
*/
|
||||
if (offset < -priv->fb_size || offset > 2 * priv->fb_size) {
|
||||
#ifdef DEBUG
|
||||
char str[80];
|
||||
|
||||
snprintf(str, sizeof(str),
|
||||
"[sync_copy fb=%p, from=%p, to=%p, offset=%lx]",
|
||||
priv->fb, from, to, offset);
|
||||
console_puts_select_stderr(true, str);
|
||||
#endif
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Silently crop the memcpy. This allows callers to avoid doing
|
||||
* this themselves. It is common for the end pointer to go a
|
||||
* few lines after the end of the frame buffer, since most of
|
||||
* the update algorithms terminate a line after their last write
|
||||
*/
|
||||
if (offset + size > priv->fb_size) {
|
||||
size = priv->fb_size - offset;
|
||||
} else if (offset < 0) {
|
||||
size += offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
memcpy(priv->copy_fb + offset, priv->fb + offset, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set up the colour map */
|
||||
static int video_pre_probe(struct udevice *dev)
|
||||
{
|
||||
|
@ -239,6 +315,9 @@ static int video_post_probe(struct udevice *dev)
|
|||
|
||||
priv->fb_size = priv->line_length * priv->ysize;
|
||||
|
||||
if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base)
|
||||
priv->copy_fb = map_sysmem(plat->copy_base, plat->size);
|
||||
|
||||
/* Set up colors */
|
||||
video_set_default_colors(dev, false);
|
||||
|
||||
|
@ -290,12 +369,21 @@ static int video_post_probe(struct udevice *dev)
|
|||
/* Post-relocation, allocate memory for the frame buffer */
|
||||
static int video_post_bind(struct udevice *dev)
|
||||
{
|
||||
ulong addr = gd->video_top;
|
||||
struct video_uc_priv *uc_priv;
|
||||
ulong addr;
|
||||
ulong size;
|
||||
|
||||
/* Before relocation there is nothing to do here */
|
||||
if (!(gd->flags & GD_FLG_RELOC))
|
||||
return 0;
|
||||
|
||||
/* Set up the video pointer, if this is the first device */
|
||||
uc_priv = dev->uclass->priv;
|
||||
if (!uc_priv->video_ptr)
|
||||
uc_priv->video_ptr = gd->video_top;
|
||||
|
||||
/* Allocate framebuffer space for this device */
|
||||
addr = uc_priv->video_ptr;
|
||||
size = alloc_fb(dev, &addr);
|
||||
if (addr < gd->video_bottom) {
|
||||
/* Device tree node may need the 'u-boot,dm-pre-reloc' or
|
||||
|
@ -307,7 +395,7 @@ static int video_post_bind(struct udevice *dev)
|
|||
}
|
||||
debug("%s: Claiming %lx bytes at %lx for video device '%s'\n",
|
||||
__func__, size, addr, dev->name);
|
||||
gd->video_bottom = addr;
|
||||
uc_priv->video_ptr = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -320,6 +408,7 @@ UCLASS_DRIVER(video) = {
|
|||
.pre_probe = video_pre_probe,
|
||||
.post_probe = video_post_probe,
|
||||
.pre_remove = video_pre_remove,
|
||||
.priv_auto_alloc_size = sizeof(struct video_uc_priv),
|
||||
.per_device_auto_alloc_size = sizeof(struct video_priv),
|
||||
.per_device_platdata_auto_alloc_size = sizeof(struct video_uc_platdata),
|
||||
};
|
||||
|
|
|
@ -192,7 +192,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
|
|||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
ushort *cmap_base = NULL;
|
||||
int i, j;
|
||||
uchar *fb;
|
||||
uchar *start, *fb;
|
||||
struct bmp_image *bmp = map_sysmem(bmp_image, 0);
|
||||
uchar *bmap;
|
||||
ushort padded_width;
|
||||
|
@ -201,6 +201,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
|
|||
unsigned colours, bpix, bmp_bpix;
|
||||
struct bmp_color_table_entry *palette;
|
||||
int hdr_size;
|
||||
int ret;
|
||||
|
||||
if (!bmp || !(bmp->header.signature[0] == 'B' &&
|
||||
bmp->header.signature[1] == 'M')) {
|
||||
|
@ -261,8 +262,11 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
|
|||
height = priv->ysize - y;
|
||||
|
||||
bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
|
||||
fb = (uchar *)(priv->fb +
|
||||
(y + height - 1) * priv->line_length + x * bpix / 8);
|
||||
start = (uchar *)(priv->fb +
|
||||
(y + height) * priv->line_length + x * bpix / 8);
|
||||
|
||||
/* Move back to the final line to be drawn */
|
||||
fb = start - priv->line_length;
|
||||
|
||||
switch (bmp_bpix) {
|
||||
case 1:
|
||||
|
@ -369,6 +373,12 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
|
|||
break;
|
||||
};
|
||||
|
||||
/* Find the position of the top left of the image in the framebuffer */
|
||||
fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
|
||||
ret = video_sync_copy(dev, start, fb);
|
||||
if (ret)
|
||||
return log_ret(ret);
|
||||
|
||||
video_sync(dev, false);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -338,7 +338,7 @@ int bootstage_stash(void *base, int size);
|
|||
* @param base Base address of memory buffer
|
||||
* @param size Size of memory buffer (-1 if unknown)
|
||||
* @return 0 if unstashed ok, -ENOENT if bootstage info not found, -ENOSPC if
|
||||
* there is not space for read the stacked data, or other error if
|
||||
* there is not space for read the stashed data, or other error if
|
||||
* something else went wrong
|
||||
*/
|
||||
int bootstage_unstash(const void *base, int size);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef __CONSOLE_H
|
||||
#define __CONSOLE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern char console_buffer[];
|
||||
|
||||
/* common/console.c */
|
||||
|
@ -72,6 +74,17 @@ int console_record_avail(void);
|
|||
*/
|
||||
int console_announce_r(void);
|
||||
|
||||
/**
|
||||
* console_puts_select_stderr() - Output a string to selected console devices
|
||||
*
|
||||
* This writes to stderr only. It is useful for outputting errors
|
||||
*
|
||||
* @serial_only: true to output only to serial, false to output to everything
|
||||
* else
|
||||
* @s: String to output
|
||||
*/
|
||||
void console_puts_select_stderr(bool serial_only, const char *s);
|
||||
|
||||
/*
|
||||
* CONSOLE multiplexing.
|
||||
*/
|
||||
|
|
|
@ -159,7 +159,19 @@ enum {
|
|||
/* Declare a new driver model test */
|
||||
#define DM_TEST(_name, _flags) UNIT_TEST(_name, _flags, dm_test)
|
||||
|
||||
/* This platform data is needed in tests, so declare it here */
|
||||
/*
|
||||
* struct sandbox_sdl_plat - Platform data for the SDL video driver
|
||||
*
|
||||
* This platform data is needed in tests, so declare it here
|
||||
*
|
||||
* @xres: Width of display in pixels
|
||||
* @yres: Height of display in pixels
|
||||
* @bpix: Log2 of bits per pixel (enum video_log2_bpp)
|
||||
* @rot: Console rotation (0=normal orientation, 1=90 degrees clockwise,
|
||||
* 2=upside down, 3=90 degree counterclockwise)
|
||||
* @vidconsole_drv_name: Name of video console driver (set by tests)
|
||||
* @font_size: Console font size to select (set by tests)
|
||||
*/
|
||||
struct sandbox_sdl_plat {
|
||||
int xres;
|
||||
int yres;
|
||||
|
|
|
@ -23,54 +23,30 @@
|
|||
#define ___config_enabled(__ignored, val, ...) val
|
||||
|
||||
/*
|
||||
* IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm',
|
||||
* IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y',
|
||||
* 0 otherwise.
|
||||
*
|
||||
*/
|
||||
#define IS_ENABLED(option) \
|
||||
(config_enabled(option) || config_enabled(option##_MODULE))
|
||||
|
||||
/*
|
||||
* IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0
|
||||
* otherwise. For boolean options, this is equivalent to
|
||||
* IS_ENABLED(CONFIG_FOO).
|
||||
*/
|
||||
#define IS_BUILTIN(option) config_enabled(option)
|
||||
|
||||
/*
|
||||
* IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0
|
||||
* otherwise.
|
||||
*/
|
||||
#define IS_MODULE(option) config_enabled(option##_MODULE)
|
||||
(config_enabled(option))
|
||||
|
||||
/*
|
||||
* U-Boot add-on: Helper macros to reference to different macros
|
||||
* (CONFIG_ or CONFIG_SPL_ prefixed), depending on the build context.
|
||||
*/
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#define _IS_SPL 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
#define _IS_TPL 1
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TPL_BUILD)
|
||||
#define config_val(cfg) _config_val(_IS_TPL, cfg)
|
||||
#define _config_val(x, cfg) __config_val(x, cfg)
|
||||
#define __config_val(x, cfg) ___config_val(__ARG_PLACEHOLDER_##x, cfg)
|
||||
#define ___config_val(arg1_or_junk, cfg) \
|
||||
____config_val(arg1_or_junk CONFIG_TPL_##cfg, CONFIG_##cfg)
|
||||
#define ____config_val(__ignored, val, ...) val
|
||||
#define _CONFIG_PREFIX TPL_
|
||||
#elif defined(CONFIG_SPL_BUILD)
|
||||
#define _CONFIG_PREFIX SPL_
|
||||
#else
|
||||
#define config_val(cfg) _config_val(_IS_SPL, cfg)
|
||||
#define _config_val(x, cfg) __config_val(x, cfg)
|
||||
#define __config_val(x, cfg) ___config_val(__ARG_PLACEHOLDER_##x, cfg)
|
||||
#define ___config_val(arg1_or_junk, cfg) \
|
||||
____config_val(arg1_or_junk CONFIG_SPL_##cfg, CONFIG_##cfg)
|
||||
#define ____config_val(__ignored, val, ...) val
|
||||
#define _CONFIG_PREFIX
|
||||
#endif
|
||||
|
||||
#define config_val(cfg) _config_val(_CONFIG_PREFIX, cfg)
|
||||
#define _config_val(pfx, cfg) __config_val(pfx, cfg)
|
||||
#define __config_val(pfx, cfg) CONFIG_ ## pfx ## cfg
|
||||
|
||||
/*
|
||||
* CONFIG_VAL(FOO) evaluates to the value of
|
||||
* CONFIG_FOO if CONFIG_SPL_BUILD is undefined,
|
||||
|
@ -80,30 +56,55 @@
|
|||
#define CONFIG_VAL(option) config_val(option)
|
||||
|
||||
/*
|
||||
* CONFIG_IS_ENABLED(FOO) evaluates to
|
||||
* 1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y' or 'm',
|
||||
* 1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y' or 'm',
|
||||
* 1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y' or 'm',
|
||||
* 0 otherwise.
|
||||
* Count number of arguments to a variadic macro. Currently only need
|
||||
* it for 1, 2 or 3 arguments.
|
||||
*/
|
||||
#define CONFIG_IS_ENABLED(option) \
|
||||
(config_enabled(CONFIG_VAL(option)) || \
|
||||
config_enabled(CONFIG_VAL(option##_MODULE)))
|
||||
#define __arg6(a1, a2, a3, a4, a5, a6, ...) a6
|
||||
#define __count_args(...) __arg6(dummy, ##__VA_ARGS__, 4, 3, 2, 1, 0)
|
||||
|
||||
#define __concat(a, b) ___concat(a, b)
|
||||
#define ___concat(a, b) a ## b
|
||||
|
||||
#define __unwrap(...) __VA_ARGS__
|
||||
#define __unwrap1(case1, case0) __unwrap case1
|
||||
#define __unwrap0(case1, case0) __unwrap case0
|
||||
|
||||
#define __CONFIG_IS_ENABLED_1(option) __CONFIG_IS_ENABLED_3(option, (1), (0))
|
||||
#define __CONFIG_IS_ENABLED_2(option, case1) __CONFIG_IS_ENABLED_3(option, case1, ())
|
||||
#define __CONFIG_IS_ENABLED_3(option, case1, case0) \
|
||||
__concat(__unwrap, config_enabled(CONFIG_VAL(option))) (case1, case0)
|
||||
|
||||
/*
|
||||
* CONFIG_IS_BUILTIN(FOO) evaluates to
|
||||
* CONFIG_IS_ENABLED(FOO) expands to
|
||||
* 1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
||||
* 1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
||||
* 1 if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
||||
* 0 otherwise.
|
||||
*
|
||||
* CONFIG_IS_ENABLED(FOO, (abc)) expands to
|
||||
* abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
||||
* abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
||||
* abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
||||
* nothing otherwise.
|
||||
*
|
||||
* CONFIG_IS_ENABLED(FOO, (abc), (def)) expands to
|
||||
* abc if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'y',
|
||||
* abc if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'y',
|
||||
* abc if CONFIG_TPL_BUILD is defined and CONFIG_TPL_FOO is set to 'y',
|
||||
* def otherwise.
|
||||
*
|
||||
* The optional second and third arguments must be parenthesized; that
|
||||
* allows one to include a trailing comma, e.g. for use in
|
||||
*
|
||||
* CONFIG_IS_ENABLED(ACME, ({.compatible = "acme,frobnozzle"},))
|
||||
*
|
||||
* which adds an entry to the array being defined if CONFIG_ACME (or
|
||||
* CONFIG_SPL_ACME/CONFIG_TPL_ACME, depending on build context) is
|
||||
* set, and nothing otherwise.
|
||||
*/
|
||||
#define CONFIG_IS_BUILTIN(option) config_enabled(CONFIG_VAL(option))
|
||||
|
||||
/*
|
||||
* CONFIG_IS_MODULE(FOO) evaluates to
|
||||
* 1 if CONFIG_SPL_BUILD is undefined and CONFIG_FOO is set to 'm',
|
||||
* 1 if CONFIG_SPL_BUILD is defined and CONFIG_SPL_FOO is set to 'm',
|
||||
* 0 otherwise.
|
||||
*/
|
||||
#define CONFIG_IS_MODULE(option) config_enabled(CONFIG_VAL(option##_MODULE))
|
||||
#define CONFIG_IS_ENABLED(option, ...) \
|
||||
__concat(__CONFIG_IS_ENABLED_, __count_args(option, ##__VA_ARGS__)) (option, ##__VA_ARGS__)
|
||||
|
||||
|
||||
#endif /* __LINUX_KCONFIG_H */
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
#define SPI_DEFAULT_WORDLEN 8
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_SPI)
|
||||
/* TODO(sjg@chromium.org): Remove this and use max_hz from struct spi_slave */
|
||||
struct dm_spi_bus {
|
||||
uint max_hz;
|
||||
|
@ -65,8 +64,6 @@ struct dm_spi_slave_platdata {
|
|||
uint mode;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_DM_SPI */
|
||||
|
||||
/**
|
||||
* enum spi_clock_phase - indicates the clock phase to use for SPI (CPHA)
|
||||
*
|
||||
|
@ -317,6 +314,11 @@ void spi_flash_copy_mmap(void *data, void *offset, size_t len);
|
|||
*/
|
||||
int spi_cs_is_valid(unsigned int bus, unsigned int cs);
|
||||
|
||||
/*
|
||||
* These names are used in several drivers and these declarations will be
|
||||
* removed soon as part of the SPI DM migration. Drop them if driver model is
|
||||
* enabled for SPI.
|
||||
*/
|
||||
#if !CONFIG_IS_ENABLED(DM_SPI)
|
||||
/**
|
||||
* Activate a SPI chipselect.
|
||||
|
@ -335,6 +337,7 @@ void spi_cs_activate(struct spi_slave *slave);
|
|||
* select to the device identified by "slave".
|
||||
*/
|
||||
void spi_cs_deactivate(struct spi_slave *slave);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set transfer speed.
|
||||
|
@ -343,7 +346,6 @@ void spi_cs_deactivate(struct spi_slave *slave);
|
|||
* @hz: The transfer speed
|
||||
*/
|
||||
void spi_set_speed(struct spi_slave *slave, uint hz);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Write 8 bits, then read 8 bits.
|
||||
|
@ -367,8 +369,6 @@ static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte)
|
|||
return ret < 0 ? ret : din[1];
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(DM_SPI)
|
||||
|
||||
/**
|
||||
* struct spi_cs_info - Information about a bus chip select
|
||||
*
|
||||
|
@ -717,6 +717,5 @@ int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
|
|||
/* Access the operations for a SPI device */
|
||||
#define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops)
|
||||
#define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops)
|
||||
#endif /* CONFIG_DM_SPI */
|
||||
|
||||
#endif /* _SPI_H_ */
|
||||
|
|
|
@ -19,10 +19,25 @@
|
|||
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
* struct video_uc_platdata - uclass platform data for a video device
|
||||
*
|
||||
* This holds information that the uclass needs to know about each device. It
|
||||
* is accessed using dev_get_uclass_platdata(dev). See 'Theory of operation' at
|
||||
* the top of video-uclass.c for details on how this information is set.
|
||||
*
|
||||
* @align: Frame-buffer alignment, indicating the memory boundary the frame
|
||||
* buffer should start on. If 0, 1MB is assumed
|
||||
* @size: Frame-buffer size, in bytes
|
||||
* @base: Base address of frame buffer, 0 if not yet known
|
||||
* @copy_base: Base address of a hardware copy of the frame buffer. See
|
||||
* CONFIG_VIDEO_COPY.
|
||||
*/
|
||||
struct video_uc_platdata {
|
||||
uint align;
|
||||
uint size;
|
||||
ulong base;
|
||||
ulong copy_base;
|
||||
};
|
||||
|
||||
enum video_polarity {
|
||||
|
@ -63,6 +78,8 @@ enum video_log2_bpp {
|
|||
* @font_size: Font size in pixels (0 to use a default value)
|
||||
* @fb: Frame buffer
|
||||
* @fb_size: Frame buffer size
|
||||
* @copy_fb: Copy of the frame buffer to keep up to date; see struct
|
||||
* video_uc_platdata
|
||||
* @line_length: Length of each frame buffer line, in bytes. This can be
|
||||
* set by the driver, but if not, the uclass will set it after
|
||||
* probing
|
||||
|
@ -89,6 +106,7 @@ struct video_priv {
|
|||
*/
|
||||
void *fb;
|
||||
int fb_size;
|
||||
void *copy_fb;
|
||||
int line_length;
|
||||
u32 colour_fg;
|
||||
u32 colour_bg;
|
||||
|
@ -202,6 +220,29 @@ void video_set_flush_dcache(struct udevice *dev, bool flush);
|
|||
*/
|
||||
void video_set_default_colors(struct udevice *dev, bool invert);
|
||||
|
||||
#ifdef CONFIG_VIDEO_COPY
|
||||
/**
|
||||
* vidconsole_sync_copy() - Sync back to the copy framebuffer
|
||||
*
|
||||
* This ensures that the copy framebuffer has the same data as the framebuffer
|
||||
* for a particular region. It should be called after the framebuffer is updated
|
||||
*
|
||||
* @from and @to can be in either order. The region between them is synced.
|
||||
*
|
||||
* @dev: Vidconsole device being updated
|
||||
* @from: Start/end address within the framebuffer (->fb)
|
||||
* @to: Other address within the frame buffer
|
||||
* @return 0 if OK, -EFAULT if the start address is before the start of the
|
||||
* frame buffer start
|
||||
*/
|
||||
int video_sync_copy(struct udevice *dev, void *from, void *to);
|
||||
#else
|
||||
static inline int video_sync_copy(struct udevice *dev, void *from, void *to)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DM_VIDEO */
|
||||
|
||||
#ifndef CONFIG_DM_VIDEO
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <video.h>
|
||||
|
||||
struct video_priv;
|
||||
|
||||
#define VID_FRAC_DIV 256
|
||||
|
||||
#define VID_TO_PIXEL(x) ((x) / VID_FRAC_DIV)
|
||||
|
@ -241,8 +243,6 @@ int vidconsole_put_string(struct udevice *dev, const char *str);
|
|||
void vidconsole_position_cursor(struct udevice *dev, unsigned col,
|
||||
unsigned row);
|
||||
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
|
||||
/**
|
||||
* vid_console_color() - convert a color code to a pixel's internal
|
||||
* representation
|
||||
|
@ -256,6 +256,53 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col,
|
|||
*/
|
||||
u32 vid_console_color(struct video_priv *priv, unsigned int idx);
|
||||
|
||||
#ifdef CONFIG_VIDEO_COPY
|
||||
/**
|
||||
* vidconsole_sync_copy() - Sync back to the copy framebuffer
|
||||
*
|
||||
* This ensures that the copy framebuffer has the same data as the framebuffer
|
||||
* for a particular region. It should be called after the framebuffer is updated
|
||||
*
|
||||
* @from and @to can be in either order. The region between them is synced.
|
||||
*
|
||||
* @dev: Vidconsole device being updated
|
||||
* @from: Start/end address within the framebuffer (->fb)
|
||||
* @to: Other address within the frame buffer
|
||||
* @return 0 if OK, -EFAULT if the start address is before the start of the
|
||||
* frame buffer start
|
||||
*/
|
||||
int vidconsole_sync_copy(struct udevice *dev, void *from, void *to);
|
||||
|
||||
/**
|
||||
* vidconsole_memmove() - Perform a memmove() within the frame buffer
|
||||
*
|
||||
* This handles a memmove(), e.g. for scrolling. It also updates the copy
|
||||
* framebuffer.
|
||||
*
|
||||
* @dev: Vidconsole device being updated
|
||||
* @dst: Destination address within the framebuffer (->fb)
|
||||
* @src: Source address within the framebuffer (->fb)
|
||||
* @size: Number of bytes to transfer
|
||||
* @return 0 if OK, -EFAULT if the start address is before the start of the
|
||||
* frame buffer start
|
||||
*/
|
||||
int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
|
||||
int size);
|
||||
#else
|
||||
static inline int vidconsole_sync_copy(struct udevice *dev, void *from,
|
||||
void *to)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int vidconsole_memmove(struct udevice *dev, void *dst,
|
||||
const void *src, int size)
|
||||
{
|
||||
memmove(dst, src, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -873,9 +873,7 @@ CONFIG_IRAM_SIZE
|
|||
CONFIG_IRAM_STACK
|
||||
CONFIG_IRAM_TOP
|
||||
CONFIG_IRDA_BASE
|
||||
CONFIG_IS_BUILTIN
|
||||
CONFIG_IS_ENABLED
|
||||
CONFIG_IS_MODULE
|
||||
CONFIG_JFFS2_CMDLINE
|
||||
CONFIG_JFFS2_DEV
|
||||
CONFIG_JFFS2_LZO
|
||||
|
|
|
@ -51,12 +51,18 @@ DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
|||
* size of the compressed data. This provides a pretty good level of
|
||||
* certainty and the resulting tests need only check a single value.
|
||||
*
|
||||
* If the copy framebuffer is enabled, this compares it to the main framebuffer
|
||||
* too.
|
||||
*
|
||||
* @uts: Test state
|
||||
* @dev: Video device
|
||||
* @return compressed size of the frame buffer, or -ve on error
|
||||
*/
|
||||
static int compress_frame_buffer(struct udevice *dev)
|
||||
static int compress_frame_buffer(struct unit_test_state *uts,
|
||||
struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
uint destlen;
|
||||
void *dest;
|
||||
int ret;
|
||||
|
@ -72,6 +78,13 @@ static int compress_frame_buffer(struct udevice *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check here that the copy frame buffer is working correctly */
|
||||
if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
|
||||
ut_assertf(!memcmp(uc_priv->fb, uc_priv->copy_fb,
|
||||
uc_priv->fb_size),
|
||||
"Copy framebuffer does not match fb");
|
||||
}
|
||||
|
||||
return destlen;
|
||||
}
|
||||
|
||||
|
@ -110,25 +123,25 @@ static int dm_test_video_text(struct unit_test_state *uts)
|
|||
|
||||
ut_assertok(select_vidconsole(uts, "vidconsole0"));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
vidconsole_putc_xy(con, 0, 0, 'a');
|
||||
ut_asserteq(79, compress_frame_buffer(dev));
|
||||
ut_asserteq(79, compress_frame_buffer(uts, dev));
|
||||
|
||||
vidconsole_putc_xy(con, 0, 0, ' ');
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||
ut_asserteq(273, compress_frame_buffer(dev));
|
||||
ut_asserteq(273, compress_frame_buffer(uts, dev));
|
||||
|
||||
vidconsole_set_row(con, 0, WHITE);
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||
ut_asserteq(273, compress_frame_buffer(dev));
|
||||
ut_asserteq(273, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -144,7 +157,7 @@ static int dm_test_video_chars(struct unit_test_state *uts)
|
|||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
vidconsole_put_string(con, test_string);
|
||||
ut_asserteq(466, compress_frame_buffer(dev));
|
||||
ut_asserteq(466, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -164,20 +177,20 @@ static int dm_test_video_ansi(struct unit_test_state *uts)
|
|||
/* reference clear: */
|
||||
video_clear(con->parent);
|
||||
video_sync(con->parent, false);
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
/* test clear escape sequence: [2J */
|
||||
vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
/* test set-cursor: [%d;%df */
|
||||
vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
|
||||
ut_asserteq(143, compress_frame_buffer(dev));
|
||||
ut_asserteq(143, compress_frame_buffer(uts, dev));
|
||||
|
||||
/* test colors (30-37 fg color, 40-47 bg color) */
|
||||
vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
|
||||
vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
|
||||
ut_asserteq(272, compress_frame_buffer(dev));
|
||||
ut_asserteq(272, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -188,7 +201,8 @@ DM_TEST(dm_test_video_ansi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
|||
* check_vidconsole_output() - Run a text console test
|
||||
*
|
||||
* @uts: Test state
|
||||
* @rot: Console rotation (0, 90, 180, 270)
|
||||
* @rot: Console rotation (0=normal orientation, 1=90 degrees clockwise,
|
||||
* 2=upside down, 3=90 degree counterclockwise)
|
||||
* @wrap_size: Expected size of compressed frame buffer for the wrap test
|
||||
* @scroll_size: Same for the scroll test
|
||||
* @return 0 on success
|
||||
|
@ -207,24 +221,24 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
|
|||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
/* Check display wrap */
|
||||
for (i = 0; i < 120; i++)
|
||||
vidconsole_put_char(con, 'A' + i % 50);
|
||||
ut_asserteq(wrap_size, compress_frame_buffer(dev));
|
||||
ut_asserteq(wrap_size, compress_frame_buffer(uts, dev));
|
||||
|
||||
/* Check display scrolling */
|
||||
for (i = 0; i < SCROLL_LINES; i++) {
|
||||
vidconsole_put_char(con, 'A' + i % 50);
|
||||
vidconsole_put_char(con, '\n');
|
||||
}
|
||||
ut_asserteq(scroll_size, compress_frame_buffer(dev));
|
||||
ut_asserteq(scroll_size, compress_frame_buffer(uts, dev));
|
||||
|
||||
/* If we scroll enough, the screen becomes blank again */
|
||||
for (i = 0; i < SCROLL_LINES; i++)
|
||||
vidconsole_put_char(con, '\n');
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -251,7 +265,7 @@ DM_TEST(dm_test_video_rotation1, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
|||
/* Test rotated text output through the console uclass */
|
||||
static int dm_test_video_rotation2(struct unit_test_state *uts)
|
||||
{
|
||||
ut_assertok(check_vidconsole_output(uts, 2, 785, 446));
|
||||
ut_assertok(check_vidconsole_output(uts, 2, 783, 445));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -298,7 +312,7 @@ static int dm_test_video_bmp(struct unit_test_state *uts)
|
|||
ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
|
||||
|
||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||
ut_asserteq(1368, compress_frame_buffer(dev));
|
||||
ut_asserteq(1368, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -314,7 +328,7 @@ static int dm_test_video_bmp_comp(struct unit_test_state *uts)
|
|||
ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
|
||||
|
||||
ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
|
||||
ut_asserteq(1368, compress_frame_buffer(dev));
|
||||
ut_asserteq(1368, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -329,7 +343,7 @@ static int dm_test_video_truetype(struct unit_test_state *uts)
|
|||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
vidconsole_put_string(con, test_string);
|
||||
ut_asserteq(12237, compress_frame_buffer(dev));
|
||||
ut_asserteq(12237, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -350,7 +364,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
|
|||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
vidconsole_put_string(con, test_string);
|
||||
ut_asserteq(35030, compress_frame_buffer(dev));
|
||||
ut_asserteq(35030, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -371,7 +385,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts)
|
|||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
vidconsole_put_string(con, test_string);
|
||||
ut_asserteq(29018, compress_frame_buffer(dev));
|
||||
ut_asserteq(29018, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue