mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 21:21:37 +00:00
Merge git://git.denx.de/u-boot-dm
This commit is contained in:
commit
6905f4d3c7
122 changed files with 7454 additions and 421 deletions
|
@ -6,7 +6,13 @@
|
|||
#
|
||||
|
||||
obj-y := reset.o
|
||||
ifeq ($(CONFIG_TIMER),)
|
||||
obj-y += timer.o
|
||||
else
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += timer.o
|
||||
endif
|
||||
endif
|
||||
obj-y += utils.o
|
||||
|
||||
ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
|
||||
|
|
|
@ -93,7 +93,7 @@ dtb-$(CONFIG_TARGET_BEAGLE_X15) += am57xx-beagle-x15.dtb
|
|||
dtb-$(CONFIG_TARGET_STV0991) += stv0991.dtb
|
||||
|
||||
dtb-$(CONFIG_LS102XA) += ls1021a-qds.dtb \
|
||||
ls1021a-twr.dtb
|
||||
ls1021a-twr-duart.dtb ls1021a-twr-lpuart.dtb
|
||||
dtb-$(CONFIG_FSL_LSCH3) += fsl-ls2080a-qds.dtb \
|
||||
fsl-ls2080a-rdb.dtb
|
||||
dtb-$(CONFIG_FSL_LSCH2) += fsl-ls1043a-qds.dtb \
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
tick-timer = &timer2;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
tick-timer = &timer2;
|
||||
};
|
||||
|
||||
cpus {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
tick-timer = &timer2;
|
||||
};
|
||||
|
||||
vmmcsd_fixed: fixedregulator-sd {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
tick-timer = &timer2;
|
||||
};
|
||||
|
||||
backlight {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
chosen {
|
||||
stdout-path = &uart1;
|
||||
tick-timer = &timer2;
|
||||
};
|
||||
|
||||
memory {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
chosen {
|
||||
stdout-path = &uart1;
|
||||
tick-timer = &timer2;
|
||||
};
|
||||
|
||||
memory {
|
||||
|
|
16
arch/arm/dts/ls1021a-twr-duart.dts
Normal file
16
arch/arm/dts/ls1021a-twr-duart.dts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Freescale ls1021a TWR board device tree source
|
||||
*
|
||||
* Copyright 2013-2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "ls1021a-twr.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
};
|
||||
};
|
16
arch/arm/dts/ls1021a-twr-lpuart.dts
Normal file
16
arch/arm/dts/ls1021a-twr-lpuart.dts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Freescale ls1021a TWR board device tree source
|
||||
*
|
||||
* Copyright 2013-2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "ls1021a-twr.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = &lpuart0;
|
||||
};
|
||||
};
|
|
@ -1,12 +1,11 @@
|
|||
/*
|
||||
* Freescale ls1021a TWR board device tree source
|
||||
* Freescale ls1021a TWR board common device tree source
|
||||
*
|
||||
* Copyright 2013-2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "ls1021a.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -19,6 +18,10 @@
|
|||
spi0 = &qspi;
|
||||
spi1 = &dspi1;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
};
|
||||
};
|
||||
|
||||
&qspi {
|
|
@ -218,7 +218,6 @@
|
|||
compatible = "fsl,16550-FIFO64", "ns16550a";
|
||||
reg = <0x21c0500 0x100>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency = <0>;
|
||||
fifo-size = <15>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -227,7 +226,6 @@
|
|||
compatible = "fsl,16550-FIFO64", "ns16550a";
|
||||
reg = <0x21c0600 0x100>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency = <0>;
|
||||
fifo-size = <15>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -236,7 +234,6 @@
|
|||
compatible = "fsl,16550-FIFO64", "ns16550a";
|
||||
reg = <0x21d0500 0x100>;
|
||||
interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency = <0>;
|
||||
fifo-size = <15>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -245,7 +242,6 @@
|
|||
compatible = "fsl,16550-FIFO64", "ns16550a";
|
||||
reg = <0x21d0600 0x100>;
|
||||
interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency = <0>;
|
||||
fifo-size = <15>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
};
|
||||
|
||||
lcd {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,lcd-sdl";
|
||||
xres = <1366>;
|
||||
yres = <768>;
|
||||
|
|
|
@ -195,6 +195,13 @@
|
|||
vss-microvolts = <0>;
|
||||
};
|
||||
|
||||
lcd {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,lcd-sdl";
|
||||
xres = <1366>;
|
||||
yres = <768>;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
|
|
|
@ -47,23 +47,6 @@ int dram_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOARD_EARLY_INIT_F
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
#ifdef CONFIG_VIDEO_SANDBOX_SDL
|
||||
int ret;
|
||||
|
||||
ret = sandbox_lcd_sdl_early_init();
|
||||
if (ret) {
|
||||
puts("Could not init sandbox LCD emulation\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOARD_LATE_INIT
|
||||
int board_late_init(void)
|
||||
{
|
||||
|
|
|
@ -205,7 +205,9 @@ obj-$(CONFIG_I2C_EDID) += edid.o
|
|||
obj-$(CONFIG_KALLSYMS) += kallsyms.o
|
||||
obj-y += splash.o
|
||||
obj-$(CONFIG_SPLASH_SOURCE) += splash_source.o
|
||||
ifndef CONFIG_DM_VIDEO
|
||||
obj-$(CONFIG_LCD) += lcd.o lcd_console.o
|
||||
endif
|
||||
obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o
|
||||
obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
|
||||
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <spi.h>
|
||||
#include <status_led.h>
|
||||
#include <trace.h>
|
||||
#include <video.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -437,19 +438,50 @@ static int reserve_mmu(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LCD
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
static int reserve_video(void)
|
||||
{
|
||||
ulong addr;
|
||||
int ret;
|
||||
|
||||
addr = gd->relocaddr;
|
||||
ret = video_reserve(&addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
gd->relocaddr = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
# ifdef CONFIG_LCD
|
||||
static int reserve_lcd(void)
|
||||
{
|
||||
#ifdef CONFIG_FB_ADDR
|
||||
# ifdef CONFIG_FB_ADDR
|
||||
gd->fb_base = CONFIG_FB_ADDR;
|
||||
#else
|
||||
# else
|
||||
/* reserve memory for LCD display (always full pages) */
|
||||
gd->relocaddr = lcd_setmem(gd->relocaddr);
|
||||
gd->fb_base = gd->relocaddr;
|
||||
#endif /* CONFIG_FB_ADDR */
|
||||
# endif /* CONFIG_FB_ADDR */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_LCD */
|
||||
# endif /* CONFIG_LCD */
|
||||
|
||||
# if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
|
||||
!defined(CONFIG_ARM) && !defined(CONFIG_X86) && \
|
||||
!defined(CONFIG_BLACKFIN) && !defined(CONFIG_M68K)
|
||||
static int reserve_legacy_video(void)
|
||||
{
|
||||
/* reserve memory for video display (always full pages) */
|
||||
gd->relocaddr = video_setmem(gd->relocaddr);
|
||||
gd->fb_base = gd->relocaddr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
#endif /* !CONFIG_DM_VIDEO */
|
||||
|
||||
static int reserve_trace(void)
|
||||
{
|
||||
|
@ -463,19 +495,6 @@ static int reserve_trace(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
|
||||
!defined(CONFIG_ARM) && !defined(CONFIG_X86) && \
|
||||
!defined(CONFIG_BLACKFIN) && !defined(CONFIG_M68K)
|
||||
static int reserve_video(void)
|
||||
{
|
||||
/* reserve memory for video display (always full pages) */
|
||||
gd->relocaddr = video_setmem(gd->relocaddr);
|
||||
gd->fb_base = gd->relocaddr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int reserve_uboot(void)
|
||||
{
|
||||
/*
|
||||
|
@ -957,16 +976,20 @@ static init_fnc_t init_sequence_f[] = {
|
|||
defined(CONFIG_ARM)
|
||||
reserve_mmu,
|
||||
#endif
|
||||
#ifdef CONFIG_LCD
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
reserve_video,
|
||||
#else
|
||||
# ifdef CONFIG_LCD
|
||||
reserve_lcd,
|
||||
#endif
|
||||
reserve_trace,
|
||||
# endif
|
||||
/* TODO: Why the dependency on CONFIG_8xx? */
|
||||
#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
|
||||
# if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
|
||||
!defined(CONFIG_ARM) && !defined(CONFIG_X86) && \
|
||||
!defined(CONFIG_BLACKFIN) && !defined(CONFIG_M68K)
|
||||
reserve_video,
|
||||
#endif
|
||||
reserve_legacy_video,
|
||||
# endif
|
||||
#endif /* CONFIG_DM_VIDEO */
|
||||
reserve_trace,
|
||||
#if !defined(CONFIG_BLACKFIN)
|
||||
reserve_uboot,
|
||||
#endif
|
||||
|
|
|
@ -10,11 +10,14 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <lcd.h>
|
||||
#include <mapmem.h>
|
||||
#include <bmp_layout.h>
|
||||
#include <command.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <malloc.h>
|
||||
#include <mapmem.h>
|
||||
#include <splash.h>
|
||||
#include <video.h>
|
||||
|
||||
|
@ -57,7 +60,8 @@ struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
|
|||
/* align to 32-bit-aligned-address + 2 */
|
||||
bmp = (struct bmp_image *)((((unsigned int)dst + 1) & ~3) + 2);
|
||||
|
||||
if (gunzip(bmp, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, (uchar *)addr, &len) != 0) {
|
||||
if (gunzip(bmp, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, map_sysmem(addr, 0),
|
||||
&len) != 0) {
|
||||
free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -187,7 +191,7 @@ U_BOOT_CMD(
|
|||
*/
|
||||
static int bmp_info(ulong addr)
|
||||
{
|
||||
struct bmp_image *bmp = (struct bmp_image *)addr;
|
||||
struct bmp_image *bmp = (struct bmp_image *)map_sysmem(addr, 0);
|
||||
void *bmp_alloc_addr = NULL;
|
||||
unsigned long len;
|
||||
|
||||
|
@ -223,8 +227,11 @@ static int bmp_info(ulong addr)
|
|||
*/
|
||||
int bmp_display(ulong addr, int x, int y)
|
||||
{
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
int ret;
|
||||
struct bmp_image *bmp = (struct bmp_image *)addr;
|
||||
struct bmp_image *bmp = map_sysmem(addr, 0);
|
||||
void *bmp_alloc_addr = NULL;
|
||||
unsigned long len;
|
||||
|
||||
|
@ -236,11 +243,27 @@ int bmp_display(ulong addr, int x, int y)
|
|||
printf("There is no valid bmp file at the given address\n");
|
||||
return 1;
|
||||
}
|
||||
addr = map_to_sysmem(bmp);
|
||||
|
||||
#if defined(CONFIG_LCD)
|
||||
ret = lcd_display_bitmap((ulong)bmp, x, y);
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
ret = uclass_first_device(UCLASS_VIDEO, &dev);
|
||||
if (!ret) {
|
||||
if (!dev)
|
||||
ret = -ENODEV;
|
||||
if (!ret) {
|
||||
bool align = false;
|
||||
|
||||
# ifdef CONFIG_SPLASH_SCREEN_ALIGN
|
||||
align = true;
|
||||
# endif /* CONFIG_SPLASH_SCREEN_ALIGN */
|
||||
ret = video_bmp_display(dev, addr, x, y, align);
|
||||
}
|
||||
}
|
||||
return ret ? CMD_RET_FAILURE : 0;
|
||||
#elif defined(CONFIG_LCD)
|
||||
ret = lcd_display_bitmap(addr, x, y);
|
||||
#elif defined(CONFIG_VIDEO)
|
||||
ret = video_display_bitmap((unsigned long)bmp, x, y);
|
||||
ret = video_display_bitmap(addr, x, y);
|
||||
#else
|
||||
# error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO
|
||||
#endif
|
||||
|
|
|
@ -1809,7 +1809,8 @@ static int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||
if (ret)
|
||||
printf("Failure changing bus number (%d)\n", ret);
|
||||
}
|
||||
return ret;
|
||||
|
||||
return ret ? CMD_RET_FAILURE : 0;
|
||||
}
|
||||
#endif /* defined(CONFIG_SYS_I2C) */
|
||||
|
||||
|
@ -1852,7 +1853,8 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const
|
|||
if (ret)
|
||||
printf("Failure changing bus speed (%d)\n", ret);
|
||||
}
|
||||
return ret;
|
||||
|
||||
return ret ? CMD_RET_FAILURE : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -131,18 +131,6 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff)
|
|||
OF_STDOUT_PATH, strlen(OF_STDOUT_PATH) + 1);
|
||||
}
|
||||
#elif defined(CONFIG_OF_STDOUT_VIA_ALIAS) && defined(CONFIG_CONS_INDEX)
|
||||
static void fdt_fill_multisername(char *sername, size_t maxlen)
|
||||
{
|
||||
const char *outname = stdio_devices[stdout]->name;
|
||||
|
||||
if (strcmp(outname, "serial") > 0)
|
||||
strncpy(sername, outname, maxlen);
|
||||
|
||||
/* eserial? */
|
||||
if (strcmp(outname + 1, "serial") > 0)
|
||||
strncpy(sername, outname + 1, maxlen);
|
||||
}
|
||||
|
||||
static int fdt_fixup_stdout(void *fdt, int chosenoff)
|
||||
{
|
||||
int err;
|
||||
|
@ -152,9 +140,7 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff)
|
|||
int len;
|
||||
char tmp[256]; /* long enough */
|
||||
|
||||
fdt_fill_multisername(sername, sizeof(sername) - 1);
|
||||
if (!sername[0])
|
||||
sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1);
|
||||
sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1);
|
||||
|
||||
aliasoff = fdt_path_offset(fdt, "/aliases");
|
||||
if (aliasoff < 0) {
|
||||
|
|
11
common/lcd.c
11
common/lcd.c
|
@ -31,10 +31,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SANDBOX
|
||||
#include <asm/sdl.h>
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LCD_ALIGNMENT
|
||||
#define CONFIG_LCD_ALIGNMENT PAGE_SIZE
|
||||
#endif
|
||||
|
@ -72,13 +68,6 @@ void lcd_sync(void)
|
|||
if (lcd_flush_dcache)
|
||||
flush_dcache_range((u32)lcd_base,
|
||||
(u32)(lcd_base + lcd_get_size(&line_length)));
|
||||
#elif defined(CONFIG_SANDBOX) && defined(CONFIG_VIDEO_SANDBOX_SDL)
|
||||
static ulong last_sync;
|
||||
|
||||
if (get_timer(last_sync) > 10) {
|
||||
sandbox_sdl_sync(lcd_base);
|
||||
last_sync = get_timer(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -281,12 +281,23 @@ int stdio_add_devices(void)
|
|||
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_LCD
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
struct udevice *vdev;
|
||||
|
||||
for (ret = uclass_first_device(UCLASS_VIDEO, &vdev);
|
||||
vdev;
|
||||
ret = uclass_next_device(&vdev))
|
||||
;
|
||||
if (ret)
|
||||
printf("%s: Video device failed (ret=%d)\n", __func__, ret);
|
||||
#else
|
||||
# if defined(CONFIG_LCD)
|
||||
drv_lcd_init ();
|
||||
#endif
|
||||
#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
|
||||
# endif
|
||||
# if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
|
||||
drv_video_init ();
|
||||
#endif
|
||||
# endif
|
||||
#endif /* CONFIG_DM_VIDEO */
|
||||
#if defined(CONFIG_KEYBOARD) && !defined(CONFIG_DM_KEYBOARD)
|
||||
drv_keyboard_init ();
|
||||
#endif
|
||||
|
|
|
@ -65,7 +65,6 @@ static const unsigned char us_direction[256/8] = {
|
|||
static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
|
||||
static __u32 CBWTag;
|
||||
|
||||
#define USB_MAX_STOR_DEV 7
|
||||
static int usb_max_devs; /* number of highest available usb device */
|
||||
|
||||
static block_dev_desc_t usb_dev_desc[USB_MAX_STOR_DEV];
|
||||
|
|
|
@ -22,3 +22,5 @@ CONFIG_SPI_FLASH=y
|
|||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_OMAP_TIMER=y
|
||||
|
|
|
@ -16,3 +16,5 @@ CONFIG_SPI_FLASH_WINBOND=y
|
|||
CONFIG_DM_ETH=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_RSA=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_OMAP_TIMER=y
|
||||
|
|
|
@ -18,3 +18,5 @@ CONFIG_SPI_FLASH=y
|
|||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_TI_QSPI=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_OMAP_TIMER=y
|
||||
|
|
|
@ -21,3 +21,5 @@ CONFIG_TI_QSPI=y
|
|||
CONFIG_DM_SPI=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_BAR=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_OMAP_TIMER=y
|
||||
|
|
|
@ -8,3 +8,4 @@ CONFIG_CMD_GPIO=y
|
|||
CONFIG_DM=y
|
||||
CONFIG_NAND_VF610_NFC=y
|
||||
CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
|
@ -11,3 +11,4 @@ CONFIG_OF_CONTROL=y
|
|||
CONFIG_DM=y
|
||||
CONFIG_NAND_VF610_NFC=y
|
||||
CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
|
@ -22,3 +22,5 @@ CONFIG_SYS_NS16550=y
|
|||
CONFIG_TI_QSPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_OMAP_TIMER=y
|
||||
|
|
|
@ -21,3 +21,5 @@ CONFIG_SYS_NS16550=y
|
|||
CONFIG_TI_QSPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_OMAP_TIMER=y
|
||||
|
|
|
@ -4,3 +4,4 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4,LPUART"
|
|||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_E1000=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
|
@ -4,3 +4,4 @@ CONFIG_SYS_EXTRA_OPTIONS="LPUART"
|
|||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_E1000=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_TARGET_LS1021ATWR=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ls1021a-twr-duart"
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_E1000=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_TARGET_LS1021ATWR=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ls1021a-twr-lpuart"
|
||||
CONFIG_SYS_EXTRA_OPTIONS="LPUART"
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_E1000=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_TARGET_LS1021ATWR=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ls1021a-twr"
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ls1021a-twr-duart"
|
||||
CONFIG_SYS_EXTRA_OPTIONS="QSPI_BOOT"
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_TARGET_LS1021ATWR=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ls1021a-twr"
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ls1021a-twr-duart"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SPL_FSL_PBL,SD_BOOT,SD_BOOT_QSPI"
|
||||
CONFIG_OF_CONTROL=y
|
||||
|
|
|
@ -3,3 +3,4 @@ CONFIG_TARGET_PCM052=y
|
|||
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/phytec/pcm052/imximage.cfg,ENV_IS_IN_NAND"
|
||||
CONFIG_NAND_VF610_NFC=y
|
||||
CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
CONFIG_SYS_MALLOC_F_LEN=0x2000
|
||||
CONFIG_PCI=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
|
||||
CONFIG_DM_PCI_COMPAT=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
|
@ -51,7 +52,6 @@ CONFIG_SPI_FLASH_SST=y
|
|||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_DM_PCI=y
|
||||
CONFIG_DM_PCI_COMPAT=y
|
||||
CONFIG_PCI_SANDBOX=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
|
@ -76,6 +76,9 @@ CONFIG_USB_EMUL=y
|
|||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_SYS_USB_EVENT_POLL=y
|
||||
CONFIG_DM_VIDEO=y
|
||||
CONFIG_VIDEO_ROTATION=y
|
||||
CONFIG_VIDEO_SANDBOX_SDL=y
|
||||
CONFIG_CMD_DHRYSTONE=y
|
||||
CONFIG_TPM=y
|
||||
CONFIG_LZ4=y
|
||||
|
|
|
@ -6,3 +6,4 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/vf610twr/imximage.cfg,ENV_I
|
|||
CONFIG_NAND_VF610_NFC=y
|
||||
CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
|
@ -6,3 +6,4 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/vf610twr/imximage.cfg,ENV_I
|
|||
CONFIG_NAND_VF610_NFC=y
|
||||
CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_FSL_LPUART=y
|
||||
|
|
43
doc/device-tree-bindings/chosen.txt
Normal file
43
doc/device-tree-bindings/chosen.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
The chosen node
|
||||
---------------
|
||||
The chosen node does not represent a real device, but serves as a place
|
||||
for passing data like which serial device to used to print the logs etc
|
||||
|
||||
|
||||
stdout-path property
|
||||
--------------------
|
||||
Device trees may specify the device to be used for boot console output
|
||||
with a stdout-path property under /chosen.
|
||||
|
||||
Example
|
||||
-------
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = "/serial@f00:115200";
|
||||
};
|
||||
|
||||
serial@f00 {
|
||||
compatible = "vendor,some-uart";
|
||||
reg = <0xf00 0x10>;
|
||||
};
|
||||
};
|
||||
|
||||
tick-timer property
|
||||
-------------------
|
||||
In a system there are multiple timers, specify which timer to be used
|
||||
as the tick-timer. Earlier it was hardcoded in the timer driver now
|
||||
since device tree has all the timer nodes. Specify which timer to be
|
||||
used as tick timer.
|
||||
|
||||
Example
|
||||
-------
|
||||
/ {
|
||||
chosen {
|
||||
tick-timer = "/timer2@f00";
|
||||
};
|
||||
|
||||
timer2@f00 {
|
||||
compatible = "vendor,some-timer";
|
||||
reg = <0xf00 0x10>;
|
||||
};
|
||||
};
|
|
@ -11,7 +11,6 @@ is time for maintainers to start converting over the remaining serial drivers:
|
|||
opencores_yanu.c
|
||||
serial_bfin.c
|
||||
serial_imx.c
|
||||
serial_lpuart.c
|
||||
serial_max3100.c
|
||||
serial_pxa.c
|
||||
serial_s3c24x0.c
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
menu "Clock"
|
||||
|
||||
config CLK
|
||||
bool "Enable clock driver support"
|
||||
depends on DM
|
||||
|
@ -17,3 +19,5 @@ config SPL_CLK
|
|||
SPL, enable this option. It might provide a cleaner interface to
|
||||
setting up clocks within SPL, and allows the same drivers to be
|
||||
used as U-Boot proper.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -32,6 +32,16 @@ ulong clk_set_rate(struct udevice *dev, ulong rate)
|
|||
return ops->set_rate(dev, rate);
|
||||
}
|
||||
|
||||
int clk_enable(struct udevice *dev, int periph)
|
||||
{
|
||||
struct clk_ops *ops = clk_get_ops(dev);
|
||||
|
||||
if (!ops->enable)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->enable(dev, periph);
|
||||
}
|
||||
|
||||
ulong clk_get_periph_rate(struct udevice *dev, int periph)
|
||||
{
|
||||
struct clk_ops *ops = clk_get_ops(dev);
|
||||
|
|
|
@ -314,7 +314,7 @@ static ulong rk3036_clk_set_rate(struct udevice *dev, ulong rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ulong rk3036_set_periph_rate(struct udevice *dev, int periph, ulong rate)
|
||||
static ulong rk3036_set_periph_rate(struct udevice *dev, int periph, ulong rate)
|
||||
{
|
||||
struct rk3036_clk_priv *priv = dev_get_priv(dev);
|
||||
ulong new_rate;
|
||||
|
|
|
@ -508,7 +508,7 @@ static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint clk_general_rate,
|
|||
return rockchip_spi_get_clk(cru, clk_general_rate, periph);
|
||||
}
|
||||
|
||||
ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
|
||||
static ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
|
||||
{
|
||||
struct rk3288_clk_priv *priv = dev_get_priv(dev);
|
||||
ulong new_rate;
|
||||
|
|
|
@ -32,7 +32,7 @@ static ulong sandbox_clk_set_rate(struct udevice *dev, ulong rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ulong sandbox_get_periph_rate(struct udevice *dev, int periph)
|
||||
static ulong sandbox_get_periph_rate(struct udevice *dev, int periph)
|
||||
{
|
||||
struct sandbox_clk_priv *priv = dev_get_priv(dev);
|
||||
|
||||
|
@ -41,7 +41,8 @@ ulong sandbox_get_periph_rate(struct udevice *dev, int periph)
|
|||
return priv->periph_rate[periph];
|
||||
}
|
||||
|
||||
ulong sandbox_set_periph_rate(struct udevice *dev, int periph, ulong rate)
|
||||
static ulong sandbox_set_periph_rate(struct udevice *dev, int periph,
|
||||
ulong rate)
|
||||
{
|
||||
struct sandbox_clk_priv *priv = dev_get_priv(dev);
|
||||
ulong old_rate;
|
||||
|
|
|
@ -135,6 +135,11 @@ int device_bind(struct udevice *parent, const struct driver *drv,
|
|||
if (ret)
|
||||
goto fail_child_post_bind;
|
||||
}
|
||||
if (uc->uc_drv->post_bind) {
|
||||
ret = uc->uc_drv->post_bind(dev);
|
||||
if (ret)
|
||||
goto fail_uclass_post_bind;
|
||||
}
|
||||
|
||||
if (parent)
|
||||
dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
|
||||
|
@ -145,6 +150,8 @@ int device_bind(struct udevice *parent, const struct driver *drv,
|
|||
|
||||
return 0;
|
||||
|
||||
fail_uclass_post_bind:
|
||||
/* There is no child unbind() method, so no clean-up required */
|
||||
fail_child_post_bind:
|
||||
if (CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)) {
|
||||
if (drv->unbind && drv->unbind(dev)) {
|
||||
|
|
|
@ -278,6 +278,7 @@ static int uclass_find_device_by_of_offset(enum uclass_id id, int node,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
static int uclass_find_device_by_phandle(enum uclass_id id,
|
||||
struct udevice *parent,
|
||||
const char *name,
|
||||
|
@ -308,6 +309,7 @@ static int uclass_find_device_by_phandle(enum uclass_id id,
|
|||
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
int uclass_get_device_tail(struct udevice *dev, int ret,
|
||||
struct udevice **devp)
|
||||
|
@ -374,6 +376,7 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node,
|
|||
return uclass_get_device_tail(dev, ret, devp);
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
|
||||
const char *name, struct udevice **devp)
|
||||
{
|
||||
|
@ -384,6 +387,7 @@ int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
|
|||
ret = uclass_find_device_by_phandle(id, parent, name, &dev);
|
||||
return uclass_get_device_tail(dev, ret, devp);
|
||||
}
|
||||
#endif
|
||||
|
||||
int uclass_first_device(enum uclass_id id, struct udevice **devp)
|
||||
{
|
||||
|
@ -426,11 +430,6 @@ int uclass_bind_device(struct udevice *dev)
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
if (uc->uc_drv->post_bind) {
|
||||
ret = uc->uc_drv->post_bind(dev);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
|
|
|
@ -154,6 +154,7 @@ int dm_gpio_request(struct gpio_desc *desc, const char *label)
|
|||
|
||||
static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
|
||||
{
|
||||
#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF)
|
||||
va_list args;
|
||||
char buf[40];
|
||||
|
||||
|
@ -161,6 +162,9 @@ static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
|
|||
vscnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
return dm_gpio_request(desc, buf);
|
||||
#else
|
||||
return dm_gpio_request(desc, fmt);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,6 +203,7 @@ int gpio_request(unsigned gpio, const char *label)
|
|||
*/
|
||||
int gpio_requestf(unsigned gpio, const char *fmt, ...)
|
||||
{
|
||||
#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF)
|
||||
va_list args;
|
||||
char buf[40];
|
||||
|
||||
|
@ -206,6 +211,9 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...)
|
|||
vscnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
return gpio_request(gpio, buf);
|
||||
#else
|
||||
return gpio_request(gpio, fmt);
|
||||
#endif
|
||||
}
|
||||
|
||||
int _dm_gpio_free(struct udevice *dev, uint offset)
|
||||
|
|
|
@ -1780,18 +1780,28 @@ static int mmc_probe(bd_t *bis)
|
|||
#elif defined(CONFIG_DM_MMC)
|
||||
static int mmc_probe(bd_t *bis)
|
||||
{
|
||||
int ret;
|
||||
int ret, i;
|
||||
struct uclass *uc;
|
||||
struct udevice *m;
|
||||
struct udevice *dev;
|
||||
|
||||
ret = uclass_get(UCLASS_MMC, &uc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
uclass_foreach_dev(m, uc) {
|
||||
ret = device_probe(m);
|
||||
/*
|
||||
* Try to add them in sequence order. Really with driver model we
|
||||
* should allow holes, but the current MMC list does not allow that.
|
||||
* So if we request 0, 1, 3 we will get 0, 1, 2.
|
||||
*/
|
||||
for (i = 0; ; i++) {
|
||||
ret = uclass_get_device_by_seq(UCLASS_MMC, i, &dev);
|
||||
if (ret == -ENODEV)
|
||||
break;
|
||||
}
|
||||
uclass_foreach_dev(dev, uc) {
|
||||
ret = device_probe(dev);
|
||||
if (ret)
|
||||
printf("%s - probe failed: %d\n", m->name, ret);
|
||||
printf("%s - probe failed: %d\n", dev->name, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -111,12 +111,16 @@ static int pinconfig_post_bind(struct udevice *dev)
|
|||
{
|
||||
const void *fdt = gd->fdt_blob;
|
||||
int offset = dev->of_offset;
|
||||
bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
|
||||
const char *name;
|
||||
int ret;
|
||||
|
||||
for (offset = fdt_first_subnode(fdt, offset);
|
||||
offset > 0;
|
||||
offset = fdt_next_subnode(fdt, offset)) {
|
||||
if (pre_reloc_only &&
|
||||
!fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
|
||||
continue;
|
||||
/*
|
||||
* If this node has "compatible" property, this is not
|
||||
* a pin configuration node, but a normal device. skip.
|
||||
|
|
|
@ -228,6 +228,12 @@ config ALTERA_UART
|
|||
Select this to enable an UART for Altera devices. Please find
|
||||
details on the "Embedded Peripherals IP User Guide" of Altera.
|
||||
|
||||
config FSL_LPUART
|
||||
bool "Freescale LPUART support"
|
||||
help
|
||||
Select this to enable a Low Power UART for Freescale VF610 and
|
||||
QorIQ Layerscape devices.
|
||||
|
||||
config SYS_NS16550
|
||||
bool "NS16550 UART or compatible"
|
||||
help
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <lcd.h>
|
||||
#include <os.h>
|
||||
#include <serial.h>
|
||||
#include <video.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/state.h>
|
||||
|
||||
|
@ -114,9 +115,7 @@ static int sandbox_serial_pending(struct udevice *dev, bool input)
|
|||
return 0;
|
||||
|
||||
os_usleep(100);
|
||||
#ifdef CONFIG_LCD
|
||||
lcd_sync();
|
||||
#endif
|
||||
video_sync_all();
|
||||
if (next_index == serial_buf_read)
|
||||
return 1; /* buffer full */
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/io.h>
|
||||
#include <serial.h>
|
||||
|
@ -12,15 +13,15 @@
|
|||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
#define US1_TDRE (1 << 7)
|
||||
#define US1_RDRF (1 << 5)
|
||||
#define US1_OR (1 << 3)
|
||||
#define UC2_TE (1 << 3)
|
||||
#define UC2_RE (1 << 2)
|
||||
#define CFIFO_TXFLUSH (1 << 7)
|
||||
#define CFIFO_RXFLUSH (1 << 6)
|
||||
#define SFIFO_RXOF (1 << 2)
|
||||
#define SFIFO_RXUF (1 << 0)
|
||||
#define US1_TDRE (1 << 7)
|
||||
#define US1_RDRF (1 << 5)
|
||||
#define US1_OR (1 << 3)
|
||||
#define UC2_TE (1 << 3)
|
||||
#define UC2_RE (1 << 2)
|
||||
#define CFIFO_TXFLUSH (1 << 7)
|
||||
#define CFIFO_RXFLUSH (1 << 6)
|
||||
#define SFIFO_RXOF (1 << 2)
|
||||
#define SFIFO_RXUF (1 << 0)
|
||||
|
||||
#define STAT_LBKDIF (1 << 31)
|
||||
#define STAT_RXEDGIF (1 << 30)
|
||||
|
@ -34,7 +35,7 @@
|
|||
#define STAT_MA1F (1 << 15)
|
||||
#define STAT_MA2F (1 << 14)
|
||||
#define STAT_FLAGS (STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \
|
||||
STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)
|
||||
STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)
|
||||
|
||||
#define CTRL_TE (1 << 19)
|
||||
#define CTRL_RE (1 << 18)
|
||||
|
@ -49,23 +50,24 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE;
|
||||
|
||||
struct lpuart_serial_platdata {
|
||||
struct lpuart_fsl *reg;
|
||||
};
|
||||
|
||||
#ifndef CONFIG_LPUART_32B_REG
|
||||
static void lpuart_serial_setbrg(void)
|
||||
static void _lpuart_serial_setbrg(struct lpuart_fsl *base, int baudrate)
|
||||
{
|
||||
u32 clk = mxc_get_clock(MXC_UART_CLK);
|
||||
u16 sbr;
|
||||
|
||||
if (!gd->baudrate)
|
||||
gd->baudrate = CONFIG_BAUDRATE;
|
||||
sbr = (u16)(clk / (16 * baudrate));
|
||||
|
||||
sbr = (u16)(clk / (16 * gd->baudrate));
|
||||
/* place adjustment later - n/32 BRFA */
|
||||
|
||||
__raw_writeb(sbr >> 8, &base->ubdh);
|
||||
__raw_writeb(sbr & 0xff, &base->ubdl);
|
||||
}
|
||||
|
||||
static int lpuart_serial_getc(void)
|
||||
static int _lpuart_serial_getc(struct lpuart_fsl *base)
|
||||
{
|
||||
while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR)))
|
||||
WATCHDOG_RESET();
|
||||
|
@ -75,10 +77,10 @@ static int lpuart_serial_getc(void)
|
|||
return __raw_readb(&base->ud);
|
||||
}
|
||||
|
||||
static void lpuart_serial_putc(const char c)
|
||||
static void _lpuart_serial_putc(struct lpuart_fsl *base, const char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
serial_putc('\r');
|
||||
_lpuart_serial_putc(base, '\r');
|
||||
|
||||
while (!(__raw_readb(&base->us1) & US1_TDRE))
|
||||
WATCHDOG_RESET();
|
||||
|
@ -86,10 +88,8 @@ static void lpuart_serial_putc(const char c)
|
|||
__raw_writeb(c, &base->ud);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether a character is in the RX buffer
|
||||
*/
|
||||
static int lpuart_serial_tstc(void)
|
||||
/* Test whether a character is in the RX buffer */
|
||||
static int _lpuart_serial_tstc(struct lpuart_fsl *base)
|
||||
{
|
||||
if (__raw_readb(&base->urcfifo) == 0)
|
||||
return 0;
|
||||
|
@ -101,7 +101,7 @@ static int lpuart_serial_tstc(void)
|
|||
* Initialise the serial port with the given baudrate. The settings
|
||||
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
||||
*/
|
||||
static int lpuart_serial_init(void)
|
||||
static int _lpuart_serial_init(struct lpuart_fsl *base)
|
||||
{
|
||||
u8 ctrl;
|
||||
|
||||
|
@ -120,14 +120,39 @@ static int lpuart_serial_init(void)
|
|||
__raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo);
|
||||
|
||||
/* provide data bits, parity, stop bit, etc */
|
||||
|
||||
serial_setbrg();
|
||||
_lpuart_serial_setbrg(base, gd->baudrate);
|
||||
|
||||
__raw_writeb(UC2_RE | UC2_TE, &base->uc2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_SERIAL
|
||||
static void lpuart_serial_setbrg(void)
|
||||
{
|
||||
_lpuart_serial_setbrg(base, gd->baudrate);
|
||||
}
|
||||
|
||||
static int lpuart_serial_getc(void)
|
||||
{
|
||||
return _lpuart_serial_getc(base);
|
||||
}
|
||||
|
||||
static void lpuart_serial_putc(const char c)
|
||||
{
|
||||
_lpuart_serial_putc(base, c);
|
||||
}
|
||||
|
||||
static int lpuart_serial_tstc(void)
|
||||
{
|
||||
return _lpuart_serial_tstc(base);
|
||||
}
|
||||
|
||||
static int lpuart_serial_init(void)
|
||||
{
|
||||
return _lpuart_serial_init(base);
|
||||
}
|
||||
|
||||
static struct serial_device lpuart_serial_drv = {
|
||||
.name = "lpuart_serial",
|
||||
.start = lpuart_serial_init,
|
||||
|
@ -138,22 +163,67 @@ static struct serial_device lpuart_serial_drv = {
|
|||
.getc = lpuart_serial_getc,
|
||||
.tstc = lpuart_serial_tstc,
|
||||
};
|
||||
#else /* CONFIG_DM_SERIAL */
|
||||
static int lpuart_serial_setbrg(struct udevice *dev, int baudrate)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
_lpuart_serial_setbrg(reg, baudrate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lpuart_serial_getc(struct udevice *dev)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
return _lpuart_serial_getc(reg);
|
||||
}
|
||||
|
||||
static int lpuart_serial_putc(struct udevice *dev, const char c)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
_lpuart_serial_putc(reg, c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lpuart_serial_pending(struct udevice *dev, bool input)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
if (input)
|
||||
return _lpuart_serial_tstc(reg);
|
||||
else
|
||||
return __raw_readb(®->us1) & US1_TDRE ? 0 : 1;
|
||||
}
|
||||
|
||||
static int lpuart_serial_probe(struct udevice *dev)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
return _lpuart_serial_init(reg);
|
||||
}
|
||||
#endif /* CONFIG_DM_SERIAL */
|
||||
#else
|
||||
static void lpuart32_serial_setbrg(void)
|
||||
static void _lpuart32_serial_setbrg(struct lpuart_fsl *base, int baudrate)
|
||||
{
|
||||
u32 clk = CONFIG_SYS_CLK_FREQ;
|
||||
u32 sbr;
|
||||
|
||||
if (!gd->baudrate)
|
||||
gd->baudrate = CONFIG_BAUDRATE;
|
||||
sbr = (clk / (16 * baudrate));
|
||||
|
||||
sbr = (clk / (16 * gd->baudrate));
|
||||
/* place adjustment later - n/32 BRFA */
|
||||
|
||||
out_be32(&base->baud, sbr);
|
||||
}
|
||||
|
||||
static int lpuart32_serial_getc(void)
|
||||
static int _lpuart32_serial_getc(struct lpuart_fsl *base)
|
||||
{
|
||||
u32 stat;
|
||||
|
||||
|
@ -165,10 +235,10 @@ static int lpuart32_serial_getc(void)
|
|||
return in_be32(&base->data) & 0x3ff;
|
||||
}
|
||||
|
||||
static void lpuart32_serial_putc(const char c)
|
||||
static void _lpuart32_serial_putc(struct lpuart_fsl *base, const char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
serial_putc('\r');
|
||||
_lpuart32_serial_putc(base, '\r');
|
||||
|
||||
while (!(in_be32(&base->stat) & STAT_TDRE))
|
||||
WATCHDOG_RESET();
|
||||
|
@ -176,10 +246,8 @@ static void lpuart32_serial_putc(const char c)
|
|||
out_be32(&base->data, c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether a character is in the RX buffer
|
||||
*/
|
||||
static int lpuart32_serial_tstc(void)
|
||||
/* Test whether a character is in the RX buffer */
|
||||
static int _lpuart32_serial_tstc(struct lpuart_fsl *base)
|
||||
{
|
||||
if ((in_be32(&base->water) >> 24) == 0)
|
||||
return 0;
|
||||
|
@ -191,7 +259,7 @@ static int lpuart32_serial_tstc(void)
|
|||
* Initialise the serial port with the given baudrate. The settings
|
||||
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
||||
*/
|
||||
static int lpuart32_serial_init(void)
|
||||
static int _lpuart32_serial_init(struct lpuart_fsl *base)
|
||||
{
|
||||
u8 ctrl;
|
||||
|
||||
|
@ -204,15 +272,41 @@ static int lpuart32_serial_init(void)
|
|||
out_be32(&base->fifo, ~(FIFO_TXFE | FIFO_RXFE));
|
||||
|
||||
out_be32(&base->match, 0);
|
||||
/* provide data bits, parity, stop bit, etc */
|
||||
|
||||
serial_setbrg();
|
||||
/* provide data bits, parity, stop bit, etc */
|
||||
_lpuart32_serial_setbrg(base, gd->baudrate);
|
||||
|
||||
out_be32(&base->ctrl, CTRL_RE | CTRL_TE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_SERIAL
|
||||
static void lpuart32_serial_setbrg(void)
|
||||
{
|
||||
_lpuart32_serial_setbrg(base, gd->baudrate);
|
||||
}
|
||||
|
||||
static int lpuart32_serial_getc(void)
|
||||
{
|
||||
return _lpuart32_serial_getc(base);
|
||||
}
|
||||
|
||||
static void lpuart32_serial_putc(const char c)
|
||||
{
|
||||
_lpuart32_serial_putc(base, c);
|
||||
}
|
||||
|
||||
static int lpuart32_serial_tstc(void)
|
||||
{
|
||||
return _lpuart32_serial_tstc(base);
|
||||
}
|
||||
|
||||
static int lpuart32_serial_init(void)
|
||||
{
|
||||
return _lpuart32_serial_init(base);
|
||||
}
|
||||
|
||||
static struct serial_device lpuart32_serial_drv = {
|
||||
.name = "lpuart32_serial",
|
||||
.start = lpuart32_serial_init,
|
||||
|
@ -223,8 +317,57 @@ static struct serial_device lpuart32_serial_drv = {
|
|||
.getc = lpuart32_serial_getc,
|
||||
.tstc = lpuart32_serial_tstc,
|
||||
};
|
||||
#else /* CONFIG_DM_SERIAL */
|
||||
static int lpuart32_serial_setbrg(struct udevice *dev, int baudrate)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
_lpuart32_serial_setbrg(reg, baudrate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lpuart32_serial_getc(struct udevice *dev)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
return _lpuart32_serial_getc(reg);
|
||||
}
|
||||
|
||||
static int lpuart32_serial_putc(struct udevice *dev, const char c)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
_lpuart32_serial_putc(reg, c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lpuart32_serial_pending(struct udevice *dev, bool input)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
if (input)
|
||||
return _lpuart32_serial_tstc(reg);
|
||||
else
|
||||
return in_be32(®->stat) & STAT_TDRE ? 0 : 1;
|
||||
}
|
||||
|
||||
static int lpuart32_serial_probe(struct udevice *dev)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
struct lpuart_fsl *reg = plat->reg;
|
||||
|
||||
return _lpuart32_serial_init(reg);
|
||||
}
|
||||
#endif /* CONFIG_DM_SERIAL */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DM_SERIAL
|
||||
void lpuart_serial_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_LPUART_32B_REG
|
||||
|
@ -242,3 +385,66 @@ __weak struct serial_device *default_serial_console(void)
|
|||
return &lpuart_serial_drv;
|
||||
#endif
|
||||
}
|
||||
#else /* CONFIG_DM_SERIAL */
|
||||
static int lpuart_serial_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct lpuart_serial_platdata *plat = dev->platdata;
|
||||
fdt_addr_t addr;
|
||||
|
||||
addr = dev_get_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
plat->reg = (struct lpuart_fsl *)addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LPUART_32B_REG
|
||||
static const struct dm_serial_ops lpuart_serial_ops = {
|
||||
.putc = lpuart_serial_putc,
|
||||
.pending = lpuart_serial_pending,
|
||||
.getc = lpuart_serial_getc,
|
||||
.setbrg = lpuart_serial_setbrg,
|
||||
};
|
||||
|
||||
static const struct udevice_id lpuart_serial_ids[] = {
|
||||
{ .compatible = "fsl,vf610-lpuart" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(serial_lpuart) = {
|
||||
.name = "serial_lpuart",
|
||||
.id = UCLASS_SERIAL,
|
||||
.of_match = lpuart_serial_ids,
|
||||
.ofdata_to_platdata = lpuart_serial_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct lpuart_serial_platdata),
|
||||
.probe = lpuart_serial_probe,
|
||||
.ops = &lpuart_serial_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
#else /* CONFIG_LPUART_32B_REG */
|
||||
static const struct dm_serial_ops lpuart32_serial_ops = {
|
||||
.putc = lpuart32_serial_putc,
|
||||
.pending = lpuart32_serial_pending,
|
||||
.getc = lpuart32_serial_getc,
|
||||
.setbrg = lpuart32_serial_setbrg,
|
||||
};
|
||||
|
||||
static const struct udevice_id lpuart32_serial_ids[] = {
|
||||
{ .compatible = "fsl,ls1021a-lpuart" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(serial_lpuart32) = {
|
||||
.name = "serial_lpuart32",
|
||||
.id = UCLASS_SERIAL,
|
||||
.of_match = lpuart32_serial_ids,
|
||||
.ofdata_to_platdata = lpuart_serial_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct lpuart_serial_platdata),
|
||||
.probe = lpuart32_serial_probe,
|
||||
.ops = &lpuart32_serial_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
#endif /* CONFIG_LPUART_32B_REG */
|
||||
#endif /* CONFIG_DM_SERIAL */
|
||||
|
|
|
@ -30,4 +30,10 @@ config X86_TSC_TIMER
|
|||
help
|
||||
Select this to enable Time-Stamp Counter (TSC) timer for x86.
|
||||
|
||||
config OMAP_TIMER
|
||||
bool "Omap timer support"
|
||||
depends on TIMER
|
||||
help
|
||||
Select this to enable an timer for Omap devices.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -8,3 +8,4 @@ obj-$(CONFIG_TIMER) += timer-uclass.o
|
|||
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
|
||||
obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o
|
||||
obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
|
||||
obj-$(CONFIG_OMAP_TIMER) += omap-timer.o
|
||||
|
|
108
drivers/timer/omap-timer.c
Normal file
108
drivers/timer/omap-timer.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* TI OMAP timer driver
|
||||
*
|
||||
* Copyright (C) 2015, Texas Instruments, Incorporated
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <timer.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* Timer register bits */
|
||||
#define TCLR_START BIT(0) /* Start=1 */
|
||||
#define TCLR_AUTO_RELOAD BIT(1) /* Auto reload */
|
||||
#define TCLR_PRE_EN BIT(5) /* Pre-scaler enable */
|
||||
#define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */
|
||||
|
||||
#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV))
|
||||
|
||||
struct omap_gptimer_regs {
|
||||
unsigned int tidr; /* offset 0x00 */
|
||||
unsigned char res1[12];
|
||||
unsigned int tiocp_cfg; /* offset 0x10 */
|
||||
unsigned char res2[12];
|
||||
unsigned int tier; /* offset 0x20 */
|
||||
unsigned int tistatr; /* offset 0x24 */
|
||||
unsigned int tistat; /* offset 0x28 */
|
||||
unsigned int tisr; /* offset 0x2c */
|
||||
unsigned int tcicr; /* offset 0x30 */
|
||||
unsigned int twer; /* offset 0x34 */
|
||||
unsigned int tclr; /* offset 0x38 */
|
||||
unsigned int tcrr; /* offset 0x3c */
|
||||
unsigned int tldr; /* offset 0x40 */
|
||||
unsigned int ttgr; /* offset 0x44 */
|
||||
unsigned int twpc; /* offset 0x48 */
|
||||
unsigned int tmar; /* offset 0x4c */
|
||||
unsigned int tcar1; /* offset 0x50 */
|
||||
unsigned int tscir; /* offset 0x54 */
|
||||
unsigned int tcar2; /* offset 0x58 */
|
||||
};
|
||||
|
||||
/* Omap Timer Priv */
|
||||
struct omap_timer_priv {
|
||||
struct omap_gptimer_regs *regs;
|
||||
};
|
||||
|
||||
static int omap_timer_get_count(struct udevice *dev, u64 *count)
|
||||
{
|
||||
struct omap_timer_priv *priv = dev_get_priv(dev);
|
||||
|
||||
*count = readl(&priv->regs->tcrr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_timer_probe(struct udevice *dev)
|
||||
{
|
||||
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct omap_timer_priv *priv = dev_get_priv(dev);
|
||||
|
||||
uc_priv->clock_rate = TIMER_CLOCK;
|
||||
|
||||
/* start the counter ticking up, reload value on overflow */
|
||||
writel(0, &priv->regs->tldr);
|
||||
/* enable timer */
|
||||
writel((CONFIG_SYS_PTV << 2) | TCLR_PRE_EN | TCLR_AUTO_RELOAD |
|
||||
TCLR_START, &priv->regs->tclr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_timer_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct omap_timer_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->regs = (struct omap_gptimer_regs *)dev_get_addr(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct timer_ops omap_timer_ops = {
|
||||
.get_count = omap_timer_get_count,
|
||||
};
|
||||
|
||||
static const struct udevice_id omap_timer_ids[] = {
|
||||
{ .compatible = "ti,am335x-timer" },
|
||||
{ .compatible = "ti,am4372-timer" },
|
||||
{ .compatible = "ti,omap5430-timer" },
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(omap_timer) = {
|
||||
.name = "omap_timer",
|
||||
.id = UCLASS_TIMER,
|
||||
.of_match = omap_timer_ids,
|
||||
.ofdata_to_platdata = omap_timer_ofdata_to_platdata,
|
||||
.priv_auto_alloc_size = sizeof(struct omap_timer_priv),
|
||||
.probe = omap_timer_probe,
|
||||
.ops = &omap_timer_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
|
@ -27,6 +27,11 @@ static int sandbox_timer_get_count(struct udevice *dev, u64 *count)
|
|||
|
||||
static int sandbox_timer_probe(struct udevice *dev)
|
||||
{
|
||||
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
|
||||
if (!uc_priv->clock_rate)
|
||||
uc_priv->clock_rate = 1000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -47,3 +52,8 @@ U_BOOT_DRIVER(sandbox_timer) = {
|
|||
.ops = &sandbox_timer_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
/* This is here in case we don't have a device tree */
|
||||
U_BOOT_DEVICE(sandbox_timer_non_fdt) = {
|
||||
.name = "sandbox_timer",
|
||||
};
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <errno.h>
|
||||
#include <timer.h>
|
||||
|
||||
|
@ -47,6 +49,16 @@ static int timer_pre_probe(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int timer_post_probe(struct udevice *dev)
|
||||
{
|
||||
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
|
||||
if (!uc_priv->clock_rate)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 timer_conv_64(u32 count)
|
||||
{
|
||||
/* increment tbh if tbl has rolled over */
|
||||
|
@ -56,9 +68,53 @@ u64 timer_conv_64(u32 count)
|
|||
return ((u64)gd->timebase_h << 32) | gd->timebase_l;
|
||||
}
|
||||
|
||||
int notrace dm_timer_init(void)
|
||||
{
|
||||
const void *blob = gd->fdt_blob;
|
||||
struct udevice *dev = NULL;
|
||||
int node;
|
||||
int ret;
|
||||
|
||||
if (gd->timer)
|
||||
return 0;
|
||||
|
||||
/* Check for a chosen timer to be used for tick */
|
||||
node = fdtdec_get_chosen_node(blob, "tick-timer");
|
||||
if (node < 0) {
|
||||
/* No chosen timer, trying first available timer */
|
||||
ret = uclass_first_device(UCLASS_TIMER, &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
} else {
|
||||
if (uclass_get_device_by_of_offset(UCLASS_TIMER, node, &dev)) {
|
||||
/*
|
||||
* If the timer is not marked to be bound before
|
||||
* relocation, bind it anyway.
|
||||
*/
|
||||
if (node > 0 &&
|
||||
!lists_bind_fdt(gd->dm_root, blob, node, &dev)) {
|
||||
ret = device_probe(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev) {
|
||||
gd->timer = dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(timer) = {
|
||||
.id = UCLASS_TIMER,
|
||||
.name = "timer",
|
||||
.pre_probe = timer_pre_probe,
|
||||
.flags = DM_UC_FLAG_SEQ_ALIAS,
|
||||
.post_probe = timer_post_probe,
|
||||
.per_device_auto_alloc_size = sizeof(struct timer_dev_priv),
|
||||
};
|
||||
|
|
|
@ -4,6 +4,59 @@
|
|||
|
||||
menu "Graphics support"
|
||||
|
||||
config DM_VIDEO
|
||||
bool "Enable driver model support for LCD/video"
|
||||
depends on DM
|
||||
help
|
||||
This enables driver model for LCD and video devices. These support
|
||||
a bitmap display of various sizes and depths which can be drawn on
|
||||
to display a command-line console or splash screen. Enabling this
|
||||
option compiles in the video uclass and routes all LCD/video access
|
||||
through this.
|
||||
|
||||
config VIDEO_BPP8
|
||||
bool "Support 8-bit-per-pixel displays"
|
||||
depends on DM_VIDEO
|
||||
default y if DM_VIDEO
|
||||
help
|
||||
Support drawing text and bitmaps onto a 8-bit-per-pixel display.
|
||||
Enabling this will include code to support this display. Without
|
||||
this option, such displays will not be supported and console output
|
||||
will be empty.
|
||||
|
||||
config VIDEO_BPP16
|
||||
bool "Support 16-bit-per-pixel displays"
|
||||
depends on DM_VIDEO
|
||||
default y if DM_VIDEO
|
||||
help
|
||||
Support drawing text and bitmaps onto a 16-bit-per-pixel display.
|
||||
Enabling this will include code to support this display. Without
|
||||
this option, such displays will not be supported and console output
|
||||
will be empty.
|
||||
|
||||
config VIDEO_BPP32
|
||||
bool "Support 32-bit-per-pixel displays"
|
||||
depends on DM_VIDEO
|
||||
default y if DM_VIDEO
|
||||
help
|
||||
Support drawing text and bitmaps onto a 32-bit-per-pixel display.
|
||||
Enabling this will include code to support this display. Without
|
||||
this option, such displays will not be supported and console output
|
||||
will be empty.
|
||||
|
||||
config VIDEO_ROTATION
|
||||
bool "Support rotated displays"
|
||||
depends on DM_VIDEO
|
||||
help
|
||||
Sometimes, for example if the display is mounted in portrait
|
||||
mode or even if it's mounted landscape but rotated by 180degree,
|
||||
we need to rotate our content of the display relative to the
|
||||
framebuffer, so that user can read the messages which are
|
||||
printed out. Enable this option to include a text driver which can
|
||||
support this. The rotation is set by the 'rot' parameter in
|
||||
struct video_priv: 0=unrotated, 1=90 degrees clockwise, 2=180
|
||||
degrees, 3=270 degrees.
|
||||
|
||||
config VIDEO_VESA
|
||||
bool "Enable VESA video driver support"
|
||||
default n
|
||||
|
@ -247,6 +300,15 @@ config DISPLAY_PORT
|
|||
to drive LCD panels. This framework provides support for enabling
|
||||
these displays where supported by the video hardware.
|
||||
|
||||
config VIDEO_SANDBOX_SDL
|
||||
bool "Enable sandbox video console using SDL"
|
||||
depends on SANDBOX
|
||||
help
|
||||
When using sandbox you can enable an emulated LCD display which
|
||||
appears as an SDL (Simple DirectMedia Layer) window. This is a
|
||||
console device and can display stdout output. Within U-Boot is is
|
||||
a normal bitmap display and can display images as well as text.
|
||||
|
||||
config VIDEO_TEGRA124
|
||||
bool "Enable video support on Tegra124"
|
||||
help
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
ifdef CONFIG_DM
|
||||
obj-$(CONFIG_DISPLAY_PORT) += dp-uclass.o
|
||||
obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o console_normal.o
|
||||
obj-$(CONFIG_DM_VIDEO) += video_bmp.o
|
||||
obj-$(CONFIG_VIDEO_ROTATION) += console_rotate.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
|
||||
|
|
141
drivers/video/console_normal.c
Normal file
141
drivers/video/console_normal.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* (C) Copyright 2001-2015
|
||||
* DENX Software Engineering -- wd@denx.de
|
||||
* Compulab Ltd - http://compulab.co.il/
|
||||
* Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <video.h>
|
||||
#include <video_console.h>
|
||||
#include <video_font.h> /* Get font data, width and height */
|
||||
|
||||
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;
|
||||
int pixels = VIDEO_FONT_HEIGHT * vid_priv->line_length;
|
||||
int i;
|
||||
|
||||
line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_normal_move_rows(struct udevice *dev, uint rowdst,
|
||||
uint rowsrc, uint count)
|
||||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
void *dst;
|
||||
void *src;
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_normal_putc_xy(struct udevice *dev, uint x, uint y, char ch)
|
||||
{
|
||||
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 +
|
||||
x * VNBYTES(vid_priv->bpix);
|
||||
|
||||
for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
|
||||
uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
|
||||
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
|
||||
*dst++ = (bits & 0x80) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
bits <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
|
||||
*dst++ = (bits & 0x80) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
bits <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
|
||||
*dst++ = (bits & 0x80) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
bits <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vidconsole_ops console_normal_ops = {
|
||||
.putc_xy = console_normal_putc_xy,
|
||||
.move_rows = console_normal_move_rows,
|
||||
.set_row = console_normal_set_row,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(vidconsole_normal) = {
|
||||
.name = "vidconsole0",
|
||||
.id = UCLASS_VIDEO_CONSOLE,
|
||||
.ops = &console_normal_ops,
|
||||
};
|
436
drivers/video/console_rotate.c
Normal file
436
drivers/video/console_rotate.c
Normal file
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* (C) Copyright 2015
|
||||
* Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <video.h>
|
||||
#include <video_console.h>
|
||||
#include <video_font.h> /* Get font data, width and height */
|
||||
|
||||
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;
|
||||
int i, j;
|
||||
|
||||
line = vid_priv->fb + vid_priv->line_length -
|
||||
(row + 1) * VIDEO_FONT_HEIGHT * pbytes;
|
||||
for (j = 0; j < vid_priv->ysize; j++) {
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
void *dst;
|
||||
void *src;
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int j;
|
||||
|
||||
dst = vid_priv->fb + vid_priv->line_length -
|
||||
(rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
|
||||
src = vid_priv->fb + vid_priv->line_length -
|
||||
(rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
|
||||
|
||||
for (j = 0; j < vid_priv->ysize; j++) {
|
||||
memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
|
||||
src += vid_priv->line_length;
|
||||
dst += vid_priv->line_length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_putc_xy_1(struct udevice *dev, uint x, uint y, char ch)
|
||||
{
|
||||
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 + (x + 1) * vid_priv->line_length -
|
||||
(y + 1) * pbytes;
|
||||
uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
|
||||
|
||||
for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
|
||||
*dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
|
||||
*dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
|
||||
*dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
line += vid_priv->line_length;
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
|
||||
int i;
|
||||
|
||||
line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
|
||||
(row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
|
||||
uint count)
|
||||
{
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
void *dst;
|
||||
void *src;
|
||||
void *end;
|
||||
|
||||
end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length;
|
||||
dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT *
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_putc_xy_2(struct udevice *dev, uint x, uint y, char ch)
|
||||
{
|
||||
struct udevice *vid = dev->parent;
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
|
||||
int i, row;
|
||||
void *line;
|
||||
|
||||
line = vid_priv->fb + (vid_priv->ysize - y - 1) *
|
||||
vid_priv->line_length +
|
||||
(vid_priv->xsize - x - VIDEO_FONT_WIDTH - 1) *
|
||||
VNBYTES(vid_priv->bpix);
|
||||
|
||||
for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
|
||||
uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
|
||||
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
|
||||
*dst-- = (bits & 0x80) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
bits <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
|
||||
*dst-- = (bits & 0x80) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
bits <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
|
||||
*dst-- = (bits & 0x80) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
bits <<= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
line -= vid_priv->line_length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
|
||||
for (j = 0; j < vid_priv->ysize; j++) {
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
|
||||
*dst++ = clr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
line += vid_priv->line_length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
void *dst;
|
||||
void *src;
|
||||
int pbytes = VNBYTES(vid_priv->bpix);
|
||||
int j;
|
||||
|
||||
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);
|
||||
src += vid_priv->line_length;
|
||||
dst += vid_priv->line_length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_putc_xy_3(struct udevice *dev, uint x, uint y, char ch)
|
||||
{
|
||||
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 - x - 1) *
|
||||
vid_priv->line_length + y * pbytes;
|
||||
uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
|
||||
|
||||
for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
|
||||
switch (vid_priv->bpix) {
|
||||
#ifdef CONFIG_VIDEO_BPP8
|
||||
case VIDEO_BPP8: {
|
||||
uint8_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
|
||||
*dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP16
|
||||
case VIDEO_BPP16: {
|
||||
uint16_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
|
||||
*dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_BPP32
|
||||
case VIDEO_BPP32: {
|
||||
uint32_t *dst = line;
|
||||
|
||||
for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
|
||||
*dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
|
||||
: vid_priv->colour_bg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
line -= vid_priv->line_length;
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int console_probe_1_3(struct udevice *dev)
|
||||
{
|
||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
|
||||
|
||||
priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH;
|
||||
priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vidconsole_ops console_ops_1 = {
|
||||
.putc_xy = console_putc_xy_1,
|
||||
.move_rows = console_move_rows_1,
|
||||
.set_row = console_set_row_1,
|
||||
};
|
||||
|
||||
struct vidconsole_ops console_ops_2 = {
|
||||
.putc_xy = console_putc_xy_2,
|
||||
.move_rows = console_move_rows_2,
|
||||
.set_row = console_set_row_2,
|
||||
};
|
||||
|
||||
struct vidconsole_ops console_ops_3 = {
|
||||
.putc_xy = console_putc_xy_3,
|
||||
.move_rows = console_move_rows_3,
|
||||
.set_row = console_set_row_3,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(vidconsole_1) = {
|
||||
.name = "vidconsole1",
|
||||
.id = UCLASS_VIDEO_CONSOLE,
|
||||
.ops = &console_ops_1,
|
||||
.probe = console_probe_1_3,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(vidconsole_2) = {
|
||||
.name = "vidconsole2",
|
||||
.id = UCLASS_VIDEO_CONSOLE,
|
||||
.ops = &console_ops_2,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(vidconsole_3) = {
|
||||
.name = "vidconsole3",
|
||||
.id = UCLASS_VIDEO_CONSOLE,
|
||||
.ops = &console_ops_3,
|
||||
.probe = console_probe_1_3,
|
||||
};
|
|
@ -5,75 +5,67 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <lcd.h>
|
||||
#include <malloc.h>
|
||||
#include <video.h>
|
||||
#include <asm/sdl.h>
|
||||
#include <asm/u-boot-sandbox.h>
|
||||
#include <dm/test.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum {
|
||||
/* Maximum LCD size we support */
|
||||
/* Default LCD size we support */
|
||||
LCD_MAX_WIDTH = 1366,
|
||||
LCD_MAX_HEIGHT = 768,
|
||||
LCD_MAX_LOG2_BPP = 4, /* 2^4 = 16 bpp */
|
||||
};
|
||||
|
||||
vidinfo_t panel_info;
|
||||
|
||||
void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
|
||||
static int sandbox_sdl_probe(struct udevice *dev)
|
||||
{
|
||||
}
|
||||
struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
|
||||
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
int ret;
|
||||
|
||||
void lcd_ctrl_init(void *lcdbase)
|
||||
{
|
||||
/*
|
||||
* Allocate memory to keep BMP color conversion map. This is required
|
||||
* for 8 bit BMPs only (hence 256 colors). If malloc fails - keep
|
||||
* going, it is not even clear if displyaing the bitmap will be
|
||||
* required on the way up.
|
||||
*/
|
||||
panel_info.cmap = malloc(256 * NBITS(panel_info.vl_bpix) / 8);
|
||||
}
|
||||
|
||||
void lcd_enable(void)
|
||||
{
|
||||
if (sandbox_sdl_init_display(panel_info.vl_col, panel_info.vl_row,
|
||||
panel_info.vl_bpix))
|
||||
ret = sandbox_sdl_init_display(plat->xres, plat->yres, plat->bpix);
|
||||
if (ret) {
|
||||
puts("LCD init failed\n");
|
||||
return ret;
|
||||
}
|
||||
uc_priv->xsize = plat->xres;
|
||||
uc_priv->ysize = plat->yres;
|
||||
uc_priv->bpix = plat->bpix;
|
||||
uc_priv->rot = plat->rot;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sandbox_lcd_sdl_early_init(void)
|
||||
static int sandbox_sdl_bind(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
|
||||
struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
|
||||
const void *blob = gd->fdt_blob;
|
||||
int xres = LCD_MAX_WIDTH, yres = LCD_MAX_HEIGHT;
|
||||
int node;
|
||||
int node = dev->of_offset;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* The code in common/lcd.c does not cope with not being able to
|
||||
* set up a frame buffer. It will just happily keep writing to
|
||||
* invalid memory. So here we make sure that at least some buffer
|
||||
* is available even if it actually won't be displayed.
|
||||
*/
|
||||
node = fdtdec_next_compatible(blob, 0, COMPAT_SANDBOX_LCD_SDL);
|
||||
if (node >= 0) {
|
||||
xres = fdtdec_get_int(blob, node, "xres", LCD_MAX_WIDTH);
|
||||
yres = fdtdec_get_int(blob, node, "yres", LCD_MAX_HEIGHT);
|
||||
if (xres < 0 || xres > LCD_MAX_WIDTH) {
|
||||
xres = LCD_MAX_WIDTH;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (yres < 0 || yres > LCD_MAX_HEIGHT) {
|
||||
yres = LCD_MAX_HEIGHT;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
panel_info.vl_col = xres;
|
||||
panel_info.vl_row = yres;
|
||||
panel_info.vl_bpix = LCD_COLOR16;
|
||||
plat->xres = fdtdec_get_int(blob, node, "xres", LCD_MAX_WIDTH);
|
||||
plat->yres = fdtdec_get_int(blob, node, "yres", LCD_MAX_HEIGHT);
|
||||
plat->bpix = VIDEO_BPP16;
|
||||
uc_plat->size = plat->xres * plat->yres * (1 << plat->bpix) / 8;
|
||||
debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct udevice_id sandbox_sdl_ids[] = {
|
||||
{ .compatible = "sandbox,lcd-sdl" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sdl_sandbox) = {
|
||||
.name = "sdl_sandbox",
|
||||
.id = UCLASS_VIDEO,
|
||||
.of_match = sandbox_sdl_ids,
|
||||
.bind = sandbox_sdl_bind,
|
||||
.probe = sandbox_sdl_probe,
|
||||
.platdata_auto_alloc_size = sizeof(struct sandbox_sdl_plat),
|
||||
};
|
||||
|
|
239
drivers/video/vidconsole-uclass.c
Normal file
239
drivers/video/vidconsole-uclass.c
Normal file
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* (C) Copyright 2001-2015
|
||||
* DENX Software Engineering -- wd@denx.de
|
||||
* Compulab Ltd - http://compulab.co.il/
|
||||
* Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <video.h>
|
||||
#include <video_console.h>
|
||||
#include <video_font.h> /* Get font data, width and height */
|
||||
|
||||
/* By default we scroll by a single line */
|
||||
#ifndef CONFIG_CONSOLE_SCROLL_LINES
|
||||
#define CONFIG_CONSOLE_SCROLL_LINES 1
|
||||
#endif
|
||||
|
||||
int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, char ch)
|
||||
{
|
||||
struct vidconsole_ops *ops = vidconsole_get_ops(dev);
|
||||
|
||||
if (!ops->putc_xy)
|
||||
return -ENOSYS;
|
||||
return ops->putc_xy(dev, x, y, ch);
|
||||
}
|
||||
|
||||
int vidconsole_move_rows(struct udevice *dev, uint rowdst, uint rowsrc,
|
||||
uint count)
|
||||
{
|
||||
struct vidconsole_ops *ops = vidconsole_get_ops(dev);
|
||||
|
||||
if (!ops->move_rows)
|
||||
return -ENOSYS;
|
||||
return ops->move_rows(dev, rowdst, rowsrc, count);
|
||||
}
|
||||
|
||||
int vidconsole_set_row(struct udevice *dev, uint row, int clr)
|
||||
{
|
||||
struct vidconsole_ops *ops = vidconsole_get_ops(dev);
|
||||
|
||||
if (!ops->set_row)
|
||||
return -ENOSYS;
|
||||
return ops->set_row(dev, row, clr);
|
||||
}
|
||||
|
||||
/* Move backwards one space */
|
||||
static void vidconsole_back(struct udevice *dev)
|
||||
{
|
||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
if (--priv->curr_col < 0) {
|
||||
priv->curr_col = priv->cols - 1;
|
||||
if (--priv->curr_row < 0)
|
||||
priv->curr_row = 0;
|
||||
}
|
||||
|
||||
vidconsole_putc_xy(dev, priv->curr_col * VIDEO_FONT_WIDTH,
|
||||
priv->curr_row * VIDEO_FONT_HEIGHT, ' ');
|
||||
}
|
||||
|
||||
/* Move to a newline, scrolling the display if necessary */
|
||||
static void vidconsole_newline(struct udevice *dev)
|
||||
{
|
||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||
struct udevice *vid_dev = dev->parent;
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
|
||||
const int rows = CONFIG_CONSOLE_SCROLL_LINES;
|
||||
int i;
|
||||
|
||||
priv->curr_col = 0;
|
||||
|
||||
/* Check if we need to scroll the terminal */
|
||||
if (++priv->curr_row >= priv->rows) {
|
||||
vidconsole_move_rows(dev, 0, rows, priv->rows - rows);
|
||||
for (i = 0; i < rows; i++)
|
||||
vidconsole_set_row(dev, priv->rows - i - 1,
|
||||
vid_priv->colour_bg);
|
||||
priv->curr_row -= rows;
|
||||
}
|
||||
video_sync(dev->parent);
|
||||
}
|
||||
|
||||
int vidconsole_put_char(struct udevice *dev, char ch)
|
||||
{
|
||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||
int ret;
|
||||
|
||||
switch (ch) {
|
||||
case '\r':
|
||||
priv->curr_col = 0;
|
||||
break;
|
||||
case '\n':
|
||||
vidconsole_newline(dev);
|
||||
break;
|
||||
case '\t': /* Tab (8 chars alignment) */
|
||||
priv->curr_col += 8;
|
||||
priv->curr_col &= ~7;
|
||||
|
||||
if (priv->curr_col >= priv->cols)
|
||||
vidconsole_newline(dev);
|
||||
break;
|
||||
case '\b':
|
||||
vidconsole_back(dev);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Failure of this function normally indicates an unsupported
|
||||
* colour depth. Check this and return an error to help with
|
||||
* diagnosis.
|
||||
*/
|
||||
ret = vidconsole_putc_xy(dev,
|
||||
priv->curr_col * VIDEO_FONT_WIDTH,
|
||||
priv->curr_row * VIDEO_FONT_HEIGHT,
|
||||
ch);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (++priv->curr_col >= priv->cols)
|
||||
vidconsole_newline(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
|
||||
{
|
||||
struct udevice *dev = sdev->priv;
|
||||
|
||||
vidconsole_put_char(dev, ch);
|
||||
}
|
||||
|
||||
static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
|
||||
{
|
||||
struct udevice *dev = sdev->priv;
|
||||
|
||||
while (*s)
|
||||
vidconsole_put_char(dev, *s++);
|
||||
}
|
||||
|
||||
/* Set up the number of rows and colours (rotated drivers override this) */
|
||||
static int vidconsole_pre_probe(struct udevice *dev)
|
||||
{
|
||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||
struct udevice *vid = dev->parent;
|
||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
|
||||
|
||||
priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
|
||||
priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Register the device with stdio */
|
||||
static int vidconsole_post_probe(struct udevice *dev)
|
||||
{
|
||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||
struct stdio_dev *sdev = &priv->sdev;
|
||||
int ret;
|
||||
|
||||
strlcpy(sdev->name, dev->name, sizeof(sdev->name));
|
||||
sdev->flags = DEV_FLAGS_OUTPUT;
|
||||
sdev->putc = vidconsole_putc;
|
||||
sdev->puts = vidconsole_puts;
|
||||
sdev->priv = dev;
|
||||
ret = stdio_register(sdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(vidconsole) = {
|
||||
.id = UCLASS_VIDEO_CONSOLE,
|
||||
.name = "vidconsole0",
|
||||
.pre_probe = vidconsole_pre_probe,
|
||||
.post_probe = vidconsole_post_probe,
|
||||
.per_device_auto_alloc_size = sizeof(struct vidconsole_priv),
|
||||
};
|
||||
|
||||
void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
|
||||
{
|
||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
priv->curr_col = min_t(short, col, priv->cols - 1);
|
||||
priv->curr_row = min_t(short, row, priv->rows - 1);
|
||||
}
|
||||
|
||||
static int do_video_setcursor(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
unsigned int col, row;
|
||||
struct udevice *dev;
|
||||
|
||||
if (argc != 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
uclass_first_device(UCLASS_VIDEO_CONSOLE, &dev);
|
||||
if (!dev)
|
||||
return CMD_RET_FAILURE;
|
||||
col = simple_strtoul(argv[1], NULL, 10);
|
||||
row = simple_strtoul(argv[2], NULL, 10);
|
||||
vidconsole_position_cursor(dev, col, row);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_video_puts(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
struct udevice *dev;
|
||||
const char *s;
|
||||
|
||||
if (argc != 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
uclass_first_device(UCLASS_VIDEO_CONSOLE, &dev);
|
||||
if (!dev)
|
||||
return CMD_RET_FAILURE;
|
||||
for (s = argv[1]; *s; s++)
|
||||
vidconsole_put_char(dev, *s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
setcurs, 3, 1, do_video_setcursor,
|
||||
"set cursor position within screen",
|
||||
" <col> <row> in character"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
lcdputs, 2, 1, do_video_puts,
|
||||
"print string on video framebuffer",
|
||||
" <string>"
|
||||
);
|
249
drivers/video/video-uclass.c
Normal file
249
drivers/video/video-uclass.c
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <mapmem.h>
|
||||
#include <stdio_dev.h>
|
||||
#include <video.h>
|
||||
#include <video_console.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#ifdef CONFIG_SANDBOX
|
||||
#include <asm/sdl.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Theory of operation:
|
||||
*
|
||||
* Before relocation each device is bound. The driver for each device must
|
||||
* set the @align and @size values in struct video_uc_platdata. This
|
||||
* information represents the requires size and alignment of the frame buffer
|
||||
* for the device. The values can be an over-estimate but cannot be too
|
||||
* small. The actual values will be suppled (in the same manner) by the bind()
|
||||
* method after relocation.
|
||||
*
|
||||
* This information is then picked up by video_reserve() which works out how
|
||||
* much memory is needed for all devices. This is allocated between
|
||||
* gd->video_bottom and gd->video_top.
|
||||
*
|
||||
* After relocation the same process occurs. The driver supplies the same
|
||||
* @size and @align information and this time video_post_bind() checks that
|
||||
* the drivers does not overflow the allocated memory.
|
||||
*
|
||||
* The frame buffer address is actually set (to plat->base) in
|
||||
* video_post_probe(). This function also clears the frame buffer and
|
||||
* allocates a suitable text console device. This can then be used to write
|
||||
* text to the video device.
|
||||
*/
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static ulong alloc_fb(struct udevice *dev, ulong *addrp)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
ulong base, align, size;
|
||||
|
||||
align = plat->align ? plat->align : 1 << 20;
|
||||
base = *addrp - plat->size;
|
||||
base &= ~(align - 1);
|
||||
plat->base = base;
|
||||
size = *addrp - base;
|
||||
*addrp = base;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int video_reserve(ulong *addrp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
ulong size;
|
||||
|
||||
gd->video_top = *addrp;
|
||||
for (uclass_find_first_device(UCLASS_VIDEO, &dev);
|
||||
dev;
|
||||
uclass_find_next_device(&dev)) {
|
||||
size = alloc_fb(dev, addrp);
|
||||
debug("%s: Reserving %lx bytes at %lx for video device '%s'\n",
|
||||
__func__, size, *addrp, dev->name);
|
||||
}
|
||||
gd->video_bottom = *addrp;
|
||||
debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
|
||||
gd->video_top);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int video_clear(struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
if (priv->bpix == VIDEO_BPP32) {
|
||||
u32 *ppix = priv->fb;
|
||||
u32 *end = priv->fb + priv->fb_size;
|
||||
|
||||
while (ppix < end)
|
||||
*ppix++ = priv->colour_bg;
|
||||
} else {
|
||||
memset(priv->fb, priv->colour_bg, priv->fb_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Flush video activity to the caches */
|
||||
void video_sync(struct udevice *vid)
|
||||
{
|
||||
/*
|
||||
* flush_dcache_range() is declared in common.h but it seems that some
|
||||
* architectures do not actually implement it. Is there a way to find
|
||||
* out whether it exists? For now, ARM is safe.
|
||||
*/
|
||||
#if defined(CONFIG_ARM) && !defined(CONFIG_SYS_DCACHE_OFF)
|
||||
struct video_priv *priv = dev_get_uclass_priv(vid);
|
||||
|
||||
if (priv->flush_dcache) {
|
||||
flush_dcache_range((ulong)priv->fb,
|
||||
(ulong)priv->fb + priv->fb_size);
|
||||
}
|
||||
#elif defined(CONFIG_VIDEO_SANDBOX_SDL)
|
||||
struct video_priv *priv = dev_get_uclass_priv(vid);
|
||||
static ulong last_sync;
|
||||
|
||||
if (get_timer(last_sync) > 10) {
|
||||
sandbox_sdl_sync(priv->fb);
|
||||
last_sync = get_timer(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_sync_all(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
||||
for (uclass_find_first_device(UCLASS_VIDEO, &dev);
|
||||
dev;
|
||||
uclass_find_next_device(&dev)) {
|
||||
if (device_active(dev))
|
||||
video_sync(dev);
|
||||
}
|
||||
}
|
||||
|
||||
int video_get_xsize(struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
return priv->xsize;
|
||||
}
|
||||
|
||||
int video_get_ysize(struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
return priv->ysize;
|
||||
}
|
||||
|
||||
/* Set up the colour map */
|
||||
static int video_pre_probe(struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
priv->cmap = calloc(256, sizeof(ushort));
|
||||
if (!priv->cmap)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int video_pre_remove(struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
|
||||
free(priv->cmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set up the display ready for use */
|
||||
static int video_post_probe(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
char name[30], drv[15], *str;
|
||||
struct udevice *cons;
|
||||
int ret;
|
||||
|
||||
/* Set up the line and display size */
|
||||
priv->fb = map_sysmem(plat->base, plat->size);
|
||||
priv->line_length = priv->xsize * VNBYTES(priv->bpix);
|
||||
priv->fb_size = priv->line_length * priv->ysize;
|
||||
|
||||
/* Set up colours - we could in future support other colours */
|
||||
#ifdef CONFIG_SYS_WHITE_ON_BLACK
|
||||
priv->colour_fg = 0xffffff;
|
||||
#else
|
||||
priv->colour_bg = 0xffffff;
|
||||
#endif
|
||||
video_clear(dev);
|
||||
|
||||
/*
|
||||
* Create a text console devices. For now we always do this, although
|
||||
* it might be useful to support only bitmap drawing on the device
|
||||
* for boards that don't need to display text.
|
||||
*/
|
||||
snprintf(name, sizeof(name), "%s.vidconsole", dev->name);
|
||||
str = strdup(name);
|
||||
if (!str)
|
||||
return -ENOMEM;
|
||||
snprintf(drv, sizeof(drv), "vidconsole%d", priv->rot);
|
||||
ret = device_bind_driver(dev, drv, str, &cons);
|
||||
if (ret) {
|
||||
debug("%s: Cannot bind console driver\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
ret = device_probe(cons);
|
||||
if (ret) {
|
||||
debug("%s: Cannot probe console driver\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/* Post-relocation, allocate memory for the frame buffer */
|
||||
static int video_post_bind(struct udevice *dev)
|
||||
{
|
||||
ulong addr = gd->video_top;
|
||||
ulong size;
|
||||
|
||||
/* Before relocation there is nothing to do here */
|
||||
if ((!gd->flags & GD_FLG_RELOC))
|
||||
return 0;
|
||||
size = alloc_fb(dev, &addr);
|
||||
if (addr < gd->video_bottom) {
|
||||
/* Device tree node may need the 'u-boot,dm-pre-reloc' tag */
|
||||
printf("Video device '%s' cannot allocate frame buffer memory -ensure the device is set up before relocation\n",
|
||||
dev->name);
|
||||
return -ENOSPC;
|
||||
}
|
||||
debug("%s: Claiming %lx bytes at %lx for video device '%s'\n",
|
||||
__func__, size, addr, dev->name);
|
||||
gd->video_bottom = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(video) = {
|
||||
.id = UCLASS_VIDEO,
|
||||
.name = "video",
|
||||
.flags = DM_UC_FLAG_SEQ_ALIAS,
|
||||
.post_bind = video_post_bind,
|
||||
.pre_probe = video_pre_probe,
|
||||
.post_probe = video_post_probe,
|
||||
.pre_remove = video_pre_remove,
|
||||
.per_device_auto_alloc_size = sizeof(struct video_priv),
|
||||
.per_device_platdata_auto_alloc_size = sizeof(struct video_uc_platdata),
|
||||
};
|
353
drivers/video/video_bmp.c
Normal file
353
drivers/video/video_bmp.c
Normal file
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <bmp_layout.h>
|
||||
#include <dm.h>
|
||||
#include <mapmem.h>
|
||||
#include <video.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#ifdef CONFIG_VIDEO_BMP_RLE8
|
||||
#define BMP_RLE8_ESCAPE 0
|
||||
#define BMP_RLE8_EOL 0
|
||||
#define BMP_RLE8_EOBMP 1
|
||||
#define BMP_RLE8_DELTA 2
|
||||
|
||||
static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap,
|
||||
int cnt)
|
||||
{
|
||||
while (cnt > 0) {
|
||||
*(*fbp)++ = cmap[*bmap++];
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_encoded_bitmap(ushort **fbp, ushort col, int cnt)
|
||||
{
|
||||
ushort *fb = *fbp;
|
||||
|
||||
while (cnt > 0) {
|
||||
*fb++ = col;
|
||||
cnt--;
|
||||
}
|
||||
*fbp = fb;
|
||||
}
|
||||
|
||||
static void video_display_rle8_bitmap(struct udevice *dev,
|
||||
struct bmp_image *bmp, ushort *cmap,
|
||||
uchar *fb, int x_off, int y_off)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
uchar *bmap;
|
||||
ulong width, height;
|
||||
ulong cnt, runlen;
|
||||
int x, y;
|
||||
int decode = 1;
|
||||
|
||||
debug("%s\n", __func__);
|
||||
width = get_unaligned_le32(&bmp->header.width);
|
||||
height = get_unaligned_le32(&bmp->header.height);
|
||||
bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
|
||||
|
||||
x = 0;
|
||||
y = height - 1;
|
||||
|
||||
while (decode) {
|
||||
if (bmap[0] == BMP_RLE8_ESCAPE) {
|
||||
switch (bmap[1]) {
|
||||
case BMP_RLE8_EOL:
|
||||
/* end of line */
|
||||
bmap += 2;
|
||||
x = 0;
|
||||
y--;
|
||||
/* 16bpix, 2-byte per pixel, width should *2 */
|
||||
fb -= (width * 2 + priv->line_length);
|
||||
break;
|
||||
case BMP_RLE8_EOBMP:
|
||||
/* end of bitmap */
|
||||
decode = 0;
|
||||
break;
|
||||
case BMP_RLE8_DELTA:
|
||||
/* delta run */
|
||||
x += bmap[2];
|
||||
y -= bmap[3];
|
||||
/* 16bpix, 2-byte per pixel, x should *2 */
|
||||
fb = (uchar *)(priv->fb + (y + y_off - 1)
|
||||
* priv->line_length + (x + x_off) * 2);
|
||||
bmap += 4;
|
||||
break;
|
||||
default:
|
||||
/* unencoded run */
|
||||
runlen = bmap[1];
|
||||
bmap += 2;
|
||||
if (y < height) {
|
||||
if (x < width) {
|
||||
if (x + runlen > width)
|
||||
cnt = width - x;
|
||||
else
|
||||
cnt = runlen;
|
||||
draw_unencoded_bitmap(
|
||||
(ushort **)&fb,
|
||||
bmap, cmap, cnt);
|
||||
}
|
||||
x += runlen;
|
||||
}
|
||||
bmap += runlen;
|
||||
if (runlen & 1)
|
||||
bmap++;
|
||||
}
|
||||
} else {
|
||||
/* encoded run */
|
||||
if (y < height) {
|
||||
runlen = bmap[0];
|
||||
if (x < width) {
|
||||
/* aggregate the same code */
|
||||
while (bmap[0] == 0xff &&
|
||||
bmap[2] != BMP_RLE8_ESCAPE &&
|
||||
bmap[1] == bmap[3]) {
|
||||
runlen += bmap[2];
|
||||
bmap += 2;
|
||||
}
|
||||
if (x + runlen > width)
|
||||
cnt = width - x;
|
||||
else
|
||||
cnt = runlen;
|
||||
draw_encoded_bitmap((ushort **)&fb,
|
||||
cmap[bmap[1]], cnt);
|
||||
}
|
||||
x += runlen;
|
||||
}
|
||||
bmap += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__weak void fb_put_byte(uchar **fb, uchar **from)
|
||||
{
|
||||
*(*fb)++ = *(*from)++;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BMP_16BPP)
|
||||
__weak void fb_put_word(uchar **fb, uchar **from)
|
||||
{
|
||||
*(*fb)++ = *(*from)++;
|
||||
*(*fb)++ = *(*from)++;
|
||||
}
|
||||
#endif /* CONFIG_BMP_16BPP */
|
||||
|
||||
#define BMP_ALIGN_CENTER 0x7fff
|
||||
|
||||
/**
|
||||
* video_splash_align_axis() - Align a single coordinate
|
||||
*
|
||||
*- if a coordinate is 0x7fff then the image will be centred in
|
||||
* that direction
|
||||
*- if a coordinate is -ve then it will be offset to the
|
||||
* left/top of the centre by that many pixels
|
||||
*- if a coordinate is positive it will be used unchnaged.
|
||||
*
|
||||
* @axis: Input and output coordinate
|
||||
* @panel_size: Size of panel in pixels for that axis
|
||||
* @picture_size: Size of bitmap in pixels for that axis
|
||||
*/
|
||||
static void video_splash_align_axis(int *axis, unsigned long panel_size,
|
||||
unsigned long picture_size)
|
||||
{
|
||||
unsigned long panel_picture_delta = panel_size - picture_size;
|
||||
unsigned long axis_alignment;
|
||||
|
||||
if (*axis == BMP_ALIGN_CENTER)
|
||||
axis_alignment = panel_picture_delta / 2;
|
||||
else if (*axis < 0)
|
||||
axis_alignment = panel_picture_delta + *axis + 1;
|
||||
else
|
||||
return;
|
||||
|
||||
*axis = max(0, (int)axis_alignment);
|
||||
}
|
||||
|
||||
static void video_set_cmap(struct udevice *dev,
|
||||
struct bmp_color_table_entry *cte, unsigned colours)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
int i;
|
||||
ushort *cmap = priv->cmap;
|
||||
|
||||
debug("%s: colours=%d\n", __func__, colours);
|
||||
for (i = 0; i < colours; ++i) {
|
||||
*cmap = ((cte->red << 8) & 0xf800) |
|
||||
((cte->green << 3) & 0x07e0) |
|
||||
((cte->blue >> 3) & 0x001f);
|
||||
cmap++;
|
||||
cte++;
|
||||
}
|
||||
}
|
||||
|
||||
int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
|
||||
bool align)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
ushort *cmap_base = NULL;
|
||||
ushort i, j;
|
||||
uchar *fb;
|
||||
struct bmp_image *bmp = map_sysmem(bmp_image, 0);
|
||||
uchar *bmap;
|
||||
ushort padded_width;
|
||||
unsigned long width, height, byte_width;
|
||||
unsigned long pwidth = priv->xsize;
|
||||
unsigned colours, bpix, bmp_bpix;
|
||||
struct bmp_color_table_entry *palette;
|
||||
int hdr_size;
|
||||
|
||||
if (!bmp || !(bmp->header.signature[0] == 'B' &&
|
||||
bmp->header.signature[1] == 'M')) {
|
||||
printf("Error: no valid bmp image at %lx\n", bmp_image);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
width = get_unaligned_le32(&bmp->header.width);
|
||||
height = get_unaligned_le32(&bmp->header.height);
|
||||
bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
|
||||
hdr_size = get_unaligned_le16(&bmp->header.size);
|
||||
debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix);
|
||||
palette = (void *)bmp + 14 + hdr_size;
|
||||
|
||||
colours = 1 << bmp_bpix;
|
||||
|
||||
bpix = VNBITS(priv->bpix);
|
||||
|
||||
if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) {
|
||||
printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
|
||||
bpix, bmp_bpix);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We support displaying 8bpp BMPs on 16bpp LCDs
|
||||
* and displaying 24bpp BMPs on 32bpp LCDs
|
||||
* */
|
||||
if (bpix != bmp_bpix &&
|
||||
!(bmp_bpix == 8 && bpix == 16) &&
|
||||
!(bmp_bpix == 24 && bpix == 32)) {
|
||||
printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
|
||||
bpix, get_unaligned_le16(&bmp->header.bit_count));
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
debug("Display-bmp: %d x %d with %d colours, display %d\n",
|
||||
(int)width, (int)height, (int)colours, 1 << bpix);
|
||||
|
||||
if (bmp_bpix == 8)
|
||||
video_set_cmap(dev, palette, colours);
|
||||
|
||||
padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
|
||||
|
||||
if (align) {
|
||||
video_splash_align_axis(&x, priv->xsize, width);
|
||||
video_splash_align_axis(&y, priv->ysize, height);
|
||||
}
|
||||
|
||||
if ((x + width) > pwidth)
|
||||
width = pwidth - x;
|
||||
if ((y + height) > priv->ysize)
|
||||
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);
|
||||
|
||||
switch (bmp_bpix) {
|
||||
case 1:
|
||||
case 8: {
|
||||
cmap_base = priv->cmap;
|
||||
#ifdef CONFIG_VIDEO_BMP_RLE8
|
||||
u32 compression = get_unaligned_le32(&bmp->header.compression);
|
||||
debug("compressed %d %d\n", compression, BMP_BI_RLE8);
|
||||
if (compression == BMP_BI_RLE8) {
|
||||
if (bpix != 16) {
|
||||
/* TODO implement render code for bpix != 16 */
|
||||
printf("Error: only support 16 bpix");
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
video_display_rle8_bitmap(dev, bmp, cmap_base, fb, x,
|
||||
y);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bpix != 16)
|
||||
byte_width = width;
|
||||
else
|
||||
byte_width = width * 2;
|
||||
|
||||
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];
|
||||
bmap++;
|
||||
fb += sizeof(uint16_t) / sizeof(*fb);
|
||||
}
|
||||
}
|
||||
bmap += (padded_width - width);
|
||||
fb -= byte_width + priv->line_length;
|
||||
}
|
||||
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;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BMP_16BPP */
|
||||
#if defined(CONFIG_BMP_24BMP)
|
||||
case 24:
|
||||
for (i = 0; i < height; ++i) {
|
||||
for (j = 0; j < width; j++) {
|
||||
*(fb++) = *(bmap++);
|
||||
*(fb++) = *(bmap++);
|
||||
*(fb++) = *(bmap++);
|
||||
*(fb++) = 0;
|
||||
}
|
||||
fb -= lcd_line_length + width * (bpix / 8);
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BMP_24BMP */
|
||||
#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 */
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
video_sync(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -122,6 +122,10 @@ typedef struct global_data {
|
|||
struct membuff console_out; /* console output */
|
||||
struct membuff console_in; /* console input */
|
||||
#endif
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
ulong video_top; /* Top of video frame buffer area */
|
||||
ulong video_bottom; /* Bottom of video frame buffer area */
|
||||
#endif
|
||||
} gd_t;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -68,7 +68,10 @@
|
|||
|
||||
/* Configure for U-Boot environment */
|
||||
#define BZ_NO_STDIO
|
||||
|
||||
#ifndef CONFIG_SANDBOX
|
||||
#define BZ_NO_COMPRESS
|
||||
#endif
|
||||
/* End of configuration for U-Boot environment */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#ifndef _CLK_H_
|
||||
#define _CLK_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct udevice;
|
||||
|
||||
int soc_clk_dump(void);
|
||||
|
||||
struct clk_ops {
|
||||
|
@ -29,19 +33,28 @@ struct clk_ops {
|
|||
ulong (*set_rate)(struct udevice *dev, ulong rate);
|
||||
|
||||
/**
|
||||
* clk_set_periph_rate() - Set clock rate for a peripheral
|
||||
*
|
||||
* @dev: Device to adjust (UCLASS_CLK)
|
||||
* @rate: New clock rate in Hz
|
||||
* @return new clock rate in Hz, or -ve error code
|
||||
*/
|
||||
* enable() - Enable the clock for a peripheral
|
||||
*
|
||||
* @dev: clock provider
|
||||
* @periph: Peripheral ID to enable
|
||||
* @return zero on success, or -ve error code
|
||||
*/
|
||||
int (*enable)(struct udevice *dev, int periph);
|
||||
|
||||
/**
|
||||
* get_periph_rate() - Get clock rate for a peripheral
|
||||
*
|
||||
* @dev: Device to check (UCLASS_CLK)
|
||||
* @periph: Peripheral ID to check
|
||||
* @return clock rate in Hz, or -ve error code
|
||||
*/
|
||||
ulong (*get_periph_rate)(struct udevice *dev, int periph);
|
||||
|
||||
/**
|
||||
* clk_set_periph_rate() - Set current clock rate for a peripheral
|
||||
* set_periph_rate() - Set current clock rate for a peripheral
|
||||
*
|
||||
* @dev: Device to update (UCLASS_CLK)
|
||||
* @periph: Peripheral ID to cupdate
|
||||
* @periph: Peripheral ID to update
|
||||
* @return new clock rate in Hz, or -ve error code
|
||||
*/
|
||||
ulong (*set_periph_rate)(struct udevice *dev, int periph, ulong rate);
|
||||
|
@ -58,7 +71,7 @@ struct clk_ops {
|
|||
ulong clk_get_rate(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* set_rate() - Set current clock rate
|
||||
* clk_set_rate() - Set current clock rate
|
||||
*
|
||||
* @dev: Device to adjust
|
||||
* @rate: New clock rate in Hz
|
||||
|
@ -66,6 +79,15 @@ ulong clk_get_rate(struct udevice *dev);
|
|||
*/
|
||||
ulong clk_set_rate(struct udevice *dev, ulong rate);
|
||||
|
||||
/**
|
||||
* clk_enable() - Enable the clock for a peripheral
|
||||
*
|
||||
* @dev: clock provider
|
||||
* @periph: Peripheral ID to enable
|
||||
* @return zero on success, or -ve error code
|
||||
*/
|
||||
int clk_enable(struct udevice *dev, int periph);
|
||||
|
||||
/**
|
||||
* clk_get_periph_rate() - Get current clock rate for a peripheral
|
||||
*
|
||||
|
@ -78,7 +100,7 @@ ulong clk_get_periph_rate(struct udevice *dev, int periph);
|
|||
* clk_set_periph_rate() - Set current clock rate for a peripheral
|
||||
*
|
||||
* @dev: Device to update (UCLASS_CLK)
|
||||
* @periph: Peripheral ID to cupdate
|
||||
* @periph: Peripheral ID to update
|
||||
* @return new clock rate in Hz, or -ve error code
|
||||
*/
|
||||
ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate);
|
||||
|
|
|
@ -357,6 +357,7 @@
|
|||
*/
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#undef CONFIG_DM_MMC
|
||||
#undef CONFIG_TIMER
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_USBETH_SUPPORT)
|
||||
|
|
|
@ -144,6 +144,7 @@
|
|||
#undef CONFIG_DM_MMC
|
||||
#undef CONFIG_DM_SPI
|
||||
#undef CONFIG_DM_SPI_FLASH
|
||||
#undef CONFIG_TIMER
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_FSL_LPUART
|
||||
#define LPUART_BASE UART0_BASE
|
||||
|
||||
/* Allow to overwrite serial and ethaddr */
|
||||
|
|
|
@ -371,7 +371,6 @@ unsigned long get_board_ddr_clk(void);
|
|||
* Serial Port
|
||||
*/
|
||||
#ifdef CONFIG_LPUART
|
||||
#define CONFIG_FSL_LPUART
|
||||
#define CONFIG_LPUART_32B_REG
|
||||
#else
|
||||
#define CONFIG_CONS_INDEX 1
|
||||
|
|
|
@ -266,12 +266,13 @@
|
|||
* Serial Port
|
||||
*/
|
||||
#ifdef CONFIG_LPUART
|
||||
#define CONFIG_FSL_LPUART
|
||||
#define CONFIG_LPUART_32B_REG
|
||||
#else
|
||||
#define CONFIG_CONS_INDEX 1
|
||||
#define CONFIG_SYS_NS16550_SERIAL
|
||||
#ifndef CONFIG_DM_SERIAL
|
||||
#define CONFIG_SYS_NS16550_REG_SIZE 1
|
||||
#endif
|
||||
#define CONFIG_SYS_NS16550_CLK get_serial_clock()
|
||||
#endif
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_FSL_LPUART
|
||||
#define LPUART_BASE UART1_BASE
|
||||
|
||||
/* Allow to overwrite serial and ethaddr */
|
||||
|
|
|
@ -158,24 +158,23 @@
|
|||
|
||||
/* LCD and keyboard require SDL support */
|
||||
#ifdef CONFIG_SANDBOX_SDL
|
||||
#define CONFIG_LCD
|
||||
#define CONFIG_VIDEO_SANDBOX_SDL
|
||||
#define CONFIG_CMD_BMP
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
#define CONFIG_CONSOLE_MUX
|
||||
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
|
||||
#define LCD_BPP LCD_COLOR16
|
||||
#define CONFIG_LCD_BMP_RLE8
|
||||
#define CONFIG_VIDEO_BMP_RLE8
|
||||
#define CONFIG_SPLASH_SCREEN_ALIGN
|
||||
|
||||
#define CONFIG_KEYBOARD
|
||||
|
||||
#define SANDBOX_SERIAL_SETTINGS "stdin=serial,cros-ec-keyb,usbkbd\0" \
|
||||
"stdout=serial,lcd\0" \
|
||||
"stderr=serial,lcd\0"
|
||||
"stdout=serial,lcd.vidconsole\0" \
|
||||
"stderr=serial,lcd.vidconsole\0"
|
||||
#else
|
||||
#define SANDBOX_SERIAL_SETTINGS "stdin=serial\0" \
|
||||
"stdout=serial,lcd\0" \
|
||||
"stderr=serial,lcd\0"
|
||||
"stdout=serial,lcd.vidconsole\0" \
|
||||
"stderr=serial,lcd.vidconsole\0"
|
||||
#endif
|
||||
|
||||
#define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \
|
||||
|
|
|
@ -164,6 +164,7 @@
|
|||
*/
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#undef CONFIG_DM_MMC
|
||||
#undef CONFIG_TIMER
|
||||
#endif
|
||||
|
||||
#endif /* __CONFIG_TI_OMAP5_COMMON_H */
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_FSL_LPUART
|
||||
#define LPUART_BASE UART1_BASE
|
||||
|
||||
/* Allow to overwrite serial and ethaddr */
|
||||
|
|
|
@ -155,6 +155,14 @@ 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 {
|
||||
int xres;
|
||||
int yres;
|
||||
int bpix;
|
||||
int rot;
|
||||
};
|
||||
|
||||
/* Declare ping methods for the drivers */
|
||||
int test_ping(struct udevice *dev, int pingval, int *pingret);
|
||||
int testfdt_ping(struct udevice *dev, int pingval, int *pingret);
|
||||
|
|
|
@ -66,7 +66,9 @@ enum uclass_id {
|
|||
UCLASS_USB, /* USB bus */
|
||||
UCLASS_USB_DEV_GENERIC, /* USB generic device */
|
||||
UCLASS_USB_HUB, /* USB hub */
|
||||
UCLASS_VIDEO, /* Video or LCD device */
|
||||
UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */
|
||||
UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */
|
||||
|
||||
UCLASS_COUNT,
|
||||
UCLASS_INVALID = -1,
|
||||
|
|
|
@ -151,7 +151,6 @@ enum fdt_compat_id {
|
|||
COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */
|
||||
COMPAT_MAXIM_98095_CODEC, /* MAX98095 Codec */
|
||||
COMPAT_SAMSUNG_EXYNOS5_I2C, /* Exynos5 High Speed I2C Controller */
|
||||
COMPAT_SANDBOX_LCD_SDL, /* Sandbox LCD emulation with SDL */
|
||||
COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */
|
||||
COMPAT_INTEL_MICROCODE, /* Intel microcode update */
|
||||
COMPAT_MEMORY_SPD, /* Memory SPD information */
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
#include <asm/byteorder.h>
|
||||
#endif
|
||||
|
||||
int bmp_display(ulong addr, int x, int y);
|
||||
struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
|
||||
void **alloc_addr);
|
||||
|
||||
#ifndef CONFIG_DM_VIDEO
|
||||
|
||||
extern char lcd_is_enabled;
|
||||
extern int lcd_line_length;
|
||||
extern struct vidinfo panel_info;
|
||||
|
@ -26,10 +32,6 @@ void lcd_ctrl_init(void *lcdbase);
|
|||
void lcd_enable(void);
|
||||
void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue);
|
||||
|
||||
struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
|
||||
void **alloc_addr);
|
||||
int bmp_display(ulong addr, int x, int y);
|
||||
|
||||
/**
|
||||
* Set whether we need to flush the dcache when changing the LCD image. This
|
||||
* defaults to off.
|
||||
|
@ -209,4 +211,6 @@ void lcd_sync(void);
|
|||
#define PAGE_SIZE 4096
|
||||
#endif
|
||||
|
||||
#endif /* !CONFIG_DM_VIDEO */
|
||||
|
||||
#endif /* _LCD_H_ */
|
||||
|
|
|
@ -7,6 +7,15 @@
|
|||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
/*
|
||||
* dm_timer_init - initialize a timer for time keeping. On success
|
||||
* initializes gd->timer so that lib/timer can use it for future
|
||||
* referrence.
|
||||
*
|
||||
* @return - 0 on success or error number
|
||||
*/
|
||||
int dm_timer_init(void);
|
||||
|
||||
/*
|
||||
* timer_conv_64 - convert 32-bit counter value to 64-bit
|
||||
*
|
||||
|
|
168
include/video.h
168
include/video.h
|
@ -1,14 +1,167 @@
|
|||
/*
|
||||
** MPC823 Video Controller
|
||||
** =======================
|
||||
** (C) 2000 by Paolo Scaffardi (arsenio@tin.it)
|
||||
** AIRVENT SAM s.p.a - RIMINI(ITALY)
|
||||
**
|
||||
*/
|
||||
* Video uclass and legacy implementation
|
||||
*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* MPC823 Video Controller
|
||||
* =======================
|
||||
* (C) 2000 by Paolo Scaffardi (arsenio@tin.it)
|
||||
* AIRVENT SAM s.p.a - RIMINI(ITALY)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _VIDEO_H_
|
||||
#define _VIDEO_H_
|
||||
|
||||
#ifdef CONFIG_DM_VIDEO
|
||||
|
||||
#include <stdio_dev.h>
|
||||
|
||||
struct video_uc_platdata {
|
||||
uint align;
|
||||
uint size;
|
||||
ulong base;
|
||||
};
|
||||
|
||||
/*
|
||||
* Bits per pixel selector. Each value n is such that the bits-per-pixel is
|
||||
* 2 ^ n
|
||||
*/
|
||||
enum video_log2_bpp {
|
||||
VIDEO_BPP1 = 0,
|
||||
VIDEO_BPP2,
|
||||
VIDEO_BPP4,
|
||||
VIDEO_BPP8,
|
||||
VIDEO_BPP16,
|
||||
VIDEO_BPP32,
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert enum video_log2_bpp to bytes and bits. Note we omit the outer
|
||||
* brackets to allow multiplication by fractional pixels.
|
||||
*/
|
||||
#define VNBYTES(bpix) (1 << (bpix)) / 8
|
||||
|
||||
#define VNBITS(bpix) (1 << (bpix))
|
||||
|
||||
/**
|
||||
* struct video_priv - Device information used by the video uclass
|
||||
*
|
||||
* @xsize: Number of pixel columns (e.g. 1366)
|
||||
* @ysize: Number of pixels rows (e.g.. 768)
|
||||
* @tor: Display rotation (0=none, 1=90 degrees clockwise, etc.)
|
||||
* @bpix: Encoded bits per pixel
|
||||
* @fb: Frame buffer
|
||||
* @fb_size: Frame buffer size
|
||||
* @line_length: Length of each frame buffer line, in bytes
|
||||
* @colour_fg: Foreground colour (pixel value)
|
||||
* @colour_bg: Background colour (pixel value)
|
||||
* @flush_dcache: true to enable flushing of the data cache after
|
||||
* the LCD is updated
|
||||
* @cmap: Colour map for 8-bit-per-pixel displays
|
||||
*/
|
||||
struct video_priv {
|
||||
/* Things set up by the driver: */
|
||||
ushort xsize;
|
||||
ushort ysize;
|
||||
ushort rot;
|
||||
enum video_log2_bpp bpix;
|
||||
|
||||
/*
|
||||
* Things that are private to the uclass: don't use these in the
|
||||
* driver
|
||||
*/
|
||||
void *fb;
|
||||
int fb_size;
|
||||
int line_length;
|
||||
int colour_fg;
|
||||
int colour_bg;
|
||||
bool flush_dcache;
|
||||
ushort *cmap;
|
||||
};
|
||||
|
||||
/* Placeholder - there are no video operations at present */
|
||||
struct video_ops {
|
||||
};
|
||||
|
||||
#define video_get_ops(dev) ((struct video_ops *)(dev)->driver->ops)
|
||||
|
||||
/**
|
||||
* video_reserve() - Reserve frame-buffer memory for video devices
|
||||
*
|
||||
* Note: This function is for internal use.
|
||||
*
|
||||
* This uses the uclass platdata's @size and @align members to figure out
|
||||
* a size and position for each frame buffer as part of the pre-relocation
|
||||
* process of determining the post-relocation memory layout.
|
||||
*
|
||||
* gd->video_top is set to the initial value of *@addrp and gd->video_bottom
|
||||
* is set to the final value.
|
||||
*
|
||||
* @addrp: On entry, the top of available memory. On exit, the new top,
|
||||
* after allocating the required memory.
|
||||
* @return 0
|
||||
*/
|
||||
int video_reserve(ulong *addrp);
|
||||
|
||||
/**
|
||||
* video_sync() - Sync a device's frame buffer with its hardware
|
||||
*
|
||||
* Some frame buffers are cached or have a secondary frame buffer. This
|
||||
* function syncs these up so that the current contents of the U-Boot frame
|
||||
* buffer are displayed to the user.
|
||||
*
|
||||
* @dev: Device to sync
|
||||
*/
|
||||
void video_sync(struct udevice *vid);
|
||||
|
||||
/**
|
||||
* video_sync_all() - Sync all devices' frame buffers with there hardware
|
||||
*
|
||||
* This calls video_sync() on all active video devices.
|
||||
*/
|
||||
void video_sync_all(void);
|
||||
|
||||
/**
|
||||
* video_bmp_display() - Display a BMP file
|
||||
*
|
||||
* @dev: Device to display the bitmap on
|
||||
* @bmp_image: Address of bitmap image to display
|
||||
* @x: X position in pixels from the left
|
||||
* @y: Y position in pixels from the top
|
||||
* @align: true to adjust the coordinates to centre the image. If false
|
||||
* the coordinates are used as is. If true:
|
||||
*
|
||||
* - if a coordinate is 0x7fff then the image will be centred in
|
||||
* that direction
|
||||
* - if a coordinate is -ve then it will be offset to the
|
||||
* left/top of the centre by that many pixels
|
||||
* - if a coordinate is positive it will be used unchnaged.
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
|
||||
bool align);
|
||||
|
||||
/**
|
||||
* video_get_xsize() - Get the width of the display in pixels
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @return device frame buffer width in pixels
|
||||
*/
|
||||
int video_get_xsize(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* video_get_ysize() - Get the height of the display in pixels
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @return device frame buffer height in pixels
|
||||
*/
|
||||
int video_get_ysize(struct udevice *dev);
|
||||
|
||||
#endif /* CONFIG_DM_VIDEO */
|
||||
|
||||
#ifndef CONFIG_DM_VIDEO
|
||||
|
||||
/* Video functions */
|
||||
|
||||
struct stdio_dev;
|
||||
|
@ -73,4 +226,7 @@ int kwh043st20_f01_spi_startup(unsigned int bus, unsigned int cs,
|
|||
int lg4573_spi_startup(unsigned int bus, unsigned int cs,
|
||||
unsigned int max_hz, unsigned int spi_mode);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DM_VIDEO */
|
||||
|
||||
#endif
|
||||
|
|
136
include/video_console.h
Normal file
136
include/video_console.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __video_console_h
|
||||
#define __video_console_h
|
||||
|
||||
/**
|
||||
* struct vidconsole_priv - uclass-private data about a console device
|
||||
*
|
||||
* @sdev: stdio device, acting as an output sink
|
||||
* @curr_col: Current text column (0=left)
|
||||
* @curr_row: Current row (0=top)
|
||||
* @rows: Number of text rows
|
||||
* @cols: Number of text columns
|
||||
*/
|
||||
struct vidconsole_priv {
|
||||
struct stdio_dev sdev;
|
||||
int curr_col;
|
||||
int curr_row;
|
||||
int rows;
|
||||
int cols;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct vidconsole_ops - Video console operations
|
||||
*
|
||||
* These operations work on either an absolute console position (measured
|
||||
* in pixels) or a text row number (measured in rows, where each row consists
|
||||
* of an entire line of text - typically 16 pixels).
|
||||
*/
|
||||
struct vidconsole_ops {
|
||||
/**
|
||||
* putc_xy() - write a single character to a position
|
||||
*
|
||||
* @dev: Device to write to
|
||||
* @x: Pixel X position (0=left-most pixel)
|
||||
* @y: Pixel Y position (0=top-most pixel)
|
||||
* @ch: Character to write
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*putc_xy)(struct udevice *dev, uint x, uint y, char ch);
|
||||
|
||||
/**
|
||||
* move_rows() - Move text rows from one place to another
|
||||
*
|
||||
* @dev: Device to adjust
|
||||
* @rowdst: Destination text row (0=top)
|
||||
* @rowsrc: Source start text row
|
||||
* @count: Number of text rows to move
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*move_rows)(struct udevice *dev, uint rowdst, uint rowsrc,
|
||||
uint count);
|
||||
|
||||
/**
|
||||
* set_row() - Set the colour of a text row
|
||||
*
|
||||
* Every pixel contained within the text row is adjusted
|
||||
*
|
||||
* @dev: Device to adjust
|
||||
* @row: Text row to adjust (0=top)
|
||||
* @clr: Raw colour (pixel value) to write to each pixel
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*set_row)(struct udevice *dev, uint row, int clr);
|
||||
};
|
||||
|
||||
/* Get a pointer to the driver operations for a video console device */
|
||||
#define vidconsole_get_ops(dev) ((struct vidconsole_ops *)(dev)->driver->ops)
|
||||
|
||||
/**
|
||||
* vidconsole_putc_xy() - write a single character to a position
|
||||
*
|
||||
* @dev: Device to write to
|
||||
* @x: Pixel X position (0=left-most pixel)
|
||||
* @y: Pixel Y position (0=top-most pixel)
|
||||
* @ch: Character to write
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, char ch);
|
||||
|
||||
/**
|
||||
* vidconsole_move_rows() - Move text rows from one place to another
|
||||
*
|
||||
* @dev: Device to adjust
|
||||
* @rowdst: Destination text row (0=top)
|
||||
* @rowsrc: Source start text row
|
||||
* @count: Number of text rows to move
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int vidconsole_move_rows(struct udevice *dev, uint rowdst, uint rowsrc,
|
||||
uint count);
|
||||
|
||||
/**
|
||||
* vidconsole_set_row() - Set the colour of a text row
|
||||
*
|
||||
* Every pixel contained within the text row is adjusted
|
||||
*
|
||||
* @dev: Device to adjust
|
||||
* @row: Text row to adjust (0=top)
|
||||
* @clr: Raw colour (pixel value) to write to each pixel
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int vidconsole_set_row(struct udevice *dev, uint row, int clr);
|
||||
|
||||
/**
|
||||
* vidconsole_put_char() - Output a character to the current console position
|
||||
*
|
||||
* Outputs a character to the console and advances the cursor. This function
|
||||
* handles wrapping to new lines and scrolling the console. Special
|
||||
* characters are handled also: \n, \r, \b and \t.
|
||||
*
|
||||
* The device always starts with the cursor at position 0,0 (top left). It
|
||||
* can be adjusted manually using vidconsole_position_cursor().
|
||||
*
|
||||
* @dev: Device to adjust
|
||||
* @ch: Character to write
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int vidconsole_put_char(struct udevice *dev, char ch);
|
||||
|
||||
/**
|
||||
* vidconsole_position_cursor() - Move the text cursor
|
||||
*
|
||||
* @dev: Device to adjust
|
||||
* @col: New cursor text column
|
||||
* @row: New cursor text row
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
void vidconsole_position_cursor(struct udevice *dev, unsigned col,
|
||||
unsigned row);
|
||||
|
||||
#endif
|
|
@ -4,3 +4,4 @@
|
|||
|
||||
obj-y += bzlib.o bzlib_crctable.o bzlib_decompress.o \
|
||||
bzlib_randtable.o bzlib_huffman.o
|
||||
obj-$(CONFIG_SANDBOX) += bzlib_compress.o bzlib_blocksort.o
|
||||
|
|
1134
lib/bzip2/bzlib_blocksort.c
Normal file
1134
lib/bzip2/bzlib_blocksort.c
Normal file
File diff suppressed because it is too large
Load diff
714
lib/bzip2/bzlib_compress.c
Normal file
714
lib/bzip2/bzlib_compress.c
Normal file
|
@ -0,0 +1,714 @@
|
|||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Compression machinery (not incl block sorting) ---*/
|
||||
/*--- compress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*--
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
David Wheeler
|
||||
Peter Fenwick
|
||||
Alistair Moffat
|
||||
Radford Neal
|
||||
Ian H. Witten
|
||||
Robert Sedgewick
|
||||
Jon L. Bentley
|
||||
|
||||
For more information on these sources, see the manual.
|
||||
--*/
|
||||
|
||||
/* CHANGES
|
||||
0.9.0 -- original version.
|
||||
0.9.0a/b -- no changes in this file.
|
||||
0.9.0c -- changed setting of nGroups in sendMTFValues()
|
||||
so as to do a bit better on small files
|
||||
*/
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
/*--- Bit stream I/O ---*/
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_bsInitWrite ( EState* s )
|
||||
{
|
||||
s->bsLive = 0;
|
||||
s->bsBuff = 0;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsFinishWrite ( EState* s )
|
||||
{
|
||||
while (s->bsLive > 0) {
|
||||
s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
|
||||
s->numZ++;
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define bsNEEDW(nz) \
|
||||
{ \
|
||||
while (s->bsLive >= 8) { \
|
||||
s->zbits[s->numZ] \
|
||||
= (UChar)(s->bsBuff >> 24); \
|
||||
s->numZ++; \
|
||||
s->bsBuff <<= 8; \
|
||||
s->bsLive -= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
__inline__
|
||||
void bsW ( EState* s, Int32 n, UInt32 v )
|
||||
{
|
||||
bsNEEDW ( n );
|
||||
s->bsBuff |= (v << (32 - s->bsLive - n));
|
||||
s->bsLive += n;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsPutUInt32 ( EState* s, UInt32 u )
|
||||
{
|
||||
bsW ( s, 8, (u >> 24) & 0xffL );
|
||||
bsW ( s, 8, (u >> 16) & 0xffL );
|
||||
bsW ( s, 8, (u >> 8) & 0xffL );
|
||||
bsW ( s, 8, u & 0xffL );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsPutUChar ( EState* s, UChar c )
|
||||
{
|
||||
bsW( s, 8, (UInt32)c );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
/*--- The back end proper ---*/
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void makeMaps_e ( EState* s )
|
||||
{
|
||||
Int32 i;
|
||||
s->nInUse = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (s->inUse[i]) {
|
||||
s->unseqToSeq[i] = s->nInUse;
|
||||
s->nInUse++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void generateMTFValues ( EState* s )
|
||||
{
|
||||
UChar yy[256];
|
||||
Int32 i, j;
|
||||
Int32 zPend;
|
||||
Int32 wr;
|
||||
Int32 EOB;
|
||||
|
||||
/*
|
||||
After sorting (eg, here),
|
||||
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
|
||||
and
|
||||
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
|
||||
holds the original block data.
|
||||
|
||||
The first thing to do is generate the MTF values,
|
||||
and put them in
|
||||
((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
|
||||
Because there are strictly fewer or equal MTF values
|
||||
than block values, ptr values in this area are overwritten
|
||||
with MTF values only when they are no longer needed.
|
||||
|
||||
The final compressed bitstream is generated into the
|
||||
area starting at
|
||||
(UChar*) (&((UChar*)s->arr2)[s->nblock])
|
||||
|
||||
These storage aliases are set up in bzCompressInit(),
|
||||
except for the last one, which is arranged in
|
||||
compressBlock().
|
||||
*/
|
||||
UInt32* ptr = s->ptr;
|
||||
UChar* block = s->block;
|
||||
UInt16* mtfv = s->mtfv;
|
||||
|
||||
makeMaps_e ( s );
|
||||
EOB = s->nInUse+1;
|
||||
|
||||
for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
|
||||
|
||||
wr = 0;
|
||||
zPend = 0;
|
||||
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
|
||||
|
||||
for (i = 0; i < s->nblock; i++) {
|
||||
UChar ll_i;
|
||||
AssertD ( wr <= i, "generateMTFValues(1)" );
|
||||
j = ptr[i]-1; if (j < 0) j += s->nblock;
|
||||
ll_i = s->unseqToSeq[block[j]];
|
||||
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
|
||||
|
||||
if (yy[0] == ll_i) {
|
||||
zPend++;
|
||||
} else {
|
||||
|
||||
if (zPend > 0) {
|
||||
zPend--;
|
||||
while (True) {
|
||||
if (zPend & 1) {
|
||||
mtfv[wr] = BZ_RUNB; wr++;
|
||||
s->mtfFreq[BZ_RUNB]++;
|
||||
} else {
|
||||
mtfv[wr] = BZ_RUNA; wr++;
|
||||
s->mtfFreq[BZ_RUNA]++;
|
||||
}
|
||||
if (zPend < 2) break;
|
||||
zPend = (zPend - 2) / 2;
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
{
|
||||
register UChar rtmp;
|
||||
register UChar* ryy_j;
|
||||
register UChar rll_i;
|
||||
rtmp = yy[1];
|
||||
yy[1] = yy[0];
|
||||
ryy_j = &(yy[1]);
|
||||
rll_i = ll_i;
|
||||
while ( rll_i != rtmp ) {
|
||||
register UChar rtmp2;
|
||||
ryy_j++;
|
||||
rtmp2 = rtmp;
|
||||
rtmp = *ryy_j;
|
||||
*ryy_j = rtmp2;
|
||||
};
|
||||
yy[0] = rtmp;
|
||||
j = ryy_j - &(yy[0]);
|
||||
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (zPend > 0) {
|
||||
zPend--;
|
||||
while (True) {
|
||||
if (zPend & 1) {
|
||||
mtfv[wr] = BZ_RUNB; wr++;
|
||||
s->mtfFreq[BZ_RUNB]++;
|
||||
} else {
|
||||
mtfv[wr] = BZ_RUNA; wr++;
|
||||
s->mtfFreq[BZ_RUNA]++;
|
||||
}
|
||||
if (zPend < 2) break;
|
||||
zPend = (zPend - 2) / 2;
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
|
||||
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
|
||||
|
||||
s->nMTF = wr;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define BZ_LESSER_ICOST 0
|
||||
#define BZ_GREATER_ICOST 15
|
||||
|
||||
static
|
||||
void sendMTFValues ( EState* s )
|
||||
{
|
||||
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
|
||||
Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
|
||||
Int32 nGroups, nBytes;
|
||||
|
||||
/*--
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
is a global since the decoder also needs it.
|
||||
|
||||
Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
are also globals only used in this proc.
|
||||
Made global to keep stack frame size small.
|
||||
--*/
|
||||
|
||||
|
||||
UInt16 cost[BZ_N_GROUPS];
|
||||
Int32 fave[BZ_N_GROUPS];
|
||||
|
||||
UInt16* mtfv = s->mtfv;
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
|
||||
"%d+2 syms in use\n",
|
||||
s->nblock, s->nMTF, s->nInUse );
|
||||
|
||||
alphaSize = s->nInUse+2;
|
||||
for (t = 0; t < BZ_N_GROUPS; t++)
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->len[t][v] = BZ_GREATER_ICOST;
|
||||
|
||||
/*--- Decide how many coding tables to use ---*/
|
||||
AssertH ( s->nMTF > 0, 3001 );
|
||||
if (s->nMTF < 200) nGroups = 2; else
|
||||
if (s->nMTF < 600) nGroups = 3; else
|
||||
if (s->nMTF < 1200) nGroups = 4; else
|
||||
if (s->nMTF < 2400) nGroups = 5; else
|
||||
nGroups = 6;
|
||||
|
||||
/*--- Generate an initial set of coding tables ---*/
|
||||
{
|
||||
Int32 nPart, remF, tFreq, aFreq;
|
||||
|
||||
nPart = nGroups;
|
||||
remF = s->nMTF;
|
||||
gs = 0;
|
||||
while (nPart > 0) {
|
||||
tFreq = remF / nPart;
|
||||
ge = gs-1;
|
||||
aFreq = 0;
|
||||
while (aFreq < tFreq && ge < alphaSize-1) {
|
||||
ge++;
|
||||
aFreq += s->mtfFreq[ge];
|
||||
}
|
||||
|
||||
if (ge > gs
|
||||
&& nPart != nGroups && nPart != 1
|
||||
&& ((nGroups-nPart) % 2 == 1)) {
|
||||
aFreq -= s->mtfFreq[ge];
|
||||
ge--;
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf5( " initial group %d, [%d .. %d], "
|
||||
"has %d syms (%4.1f%%)\n",
|
||||
nPart, gs, ge, aFreq,
|
||||
(100.0 * (float)aFreq) / (float)(s->nMTF) );
|
||||
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
if (v >= gs && v <= ge)
|
||||
s->len[nPart-1][v] = BZ_LESSER_ICOST; else
|
||||
s->len[nPart-1][v] = BZ_GREATER_ICOST;
|
||||
|
||||
nPart--;
|
||||
gs = ge+1;
|
||||
remF -= aFreq;
|
||||
}
|
||||
}
|
||||
|
||||
/*---
|
||||
Iterate up to BZ_N_ITERS times to improve the tables.
|
||||
---*/
|
||||
for (iter = 0; iter < BZ_N_ITERS; iter++) {
|
||||
|
||||
for (t = 0; t < nGroups; t++) fave[t] = 0;
|
||||
|
||||
for (t = 0; t < nGroups; t++)
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->rfreq[t][v] = 0;
|
||||
|
||||
/*---
|
||||
Set up an auxiliary length table which is used to fast-track
|
||||
the common case (nGroups == 6).
|
||||
---*/
|
||||
if (nGroups == 6) {
|
||||
for (v = 0; v < alphaSize; v++) {
|
||||
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
|
||||
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
|
||||
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
|
||||
}
|
||||
}
|
||||
|
||||
nSelectors = 0;
|
||||
totc = 0;
|
||||
gs = 0;
|
||||
while (True) {
|
||||
|
||||
/*--- Set group start & end marks. --*/
|
||||
if (gs >= s->nMTF) break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF) ge = s->nMTF-1;
|
||||
|
||||
/*--
|
||||
Calculate the cost of this group as coded
|
||||
by each of the coding tables.
|
||||
--*/
|
||||
for (t = 0; t < nGroups; t++) cost[t] = 0;
|
||||
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
register UInt32 cost01, cost23, cost45;
|
||||
register UInt16 icv;
|
||||
cost01 = cost23 = cost45 = 0;
|
||||
|
||||
# define BZ_ITER(nn) \
|
||||
icv = mtfv[gs+(nn)]; \
|
||||
cost01 += s->len_pack[icv][0]; \
|
||||
cost23 += s->len_pack[icv][1]; \
|
||||
cost45 += s->len_pack[icv][2]; \
|
||||
|
||||
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
|
||||
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
|
||||
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
|
||||
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
|
||||
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
|
||||
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
|
||||
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
|
||||
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
|
||||
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
|
||||
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
|
||||
|
||||
# undef BZ_ITER
|
||||
|
||||
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
|
||||
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
|
||||
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
UInt16 icv = mtfv[i];
|
||||
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
|
||||
}
|
||||
}
|
||||
|
||||
/*--
|
||||
Find the coding table which is best for this group,
|
||||
and record its identity in the selector table.
|
||||
--*/
|
||||
bc = 999999999; bt = -1;
|
||||
for (t = 0; t < nGroups; t++)
|
||||
if (cost[t] < bc) { bc = cost[t]; bt = t; };
|
||||
totc += bc;
|
||||
fave[bt]++;
|
||||
s->selector[nSelectors] = bt;
|
||||
nSelectors++;
|
||||
|
||||
/*--
|
||||
Increment the symbol frequencies for the selected table.
|
||||
--*/
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
|
||||
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
|
||||
|
||||
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
|
||||
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
|
||||
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
|
||||
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
|
||||
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
|
||||
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
|
||||
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
|
||||
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
|
||||
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
|
||||
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
|
||||
|
||||
# undef BZ_ITUR
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++)
|
||||
s->rfreq[bt][ mtfv[i] ]++;
|
||||
}
|
||||
|
||||
gs = ge+1;
|
||||
}
|
||||
if (s->verbosity >= 3) {
|
||||
VPrintf2 ( " pass %d: size is %d, grp uses are ",
|
||||
iter+1, totc/8 );
|
||||
for (t = 0; t < nGroups; t++)
|
||||
VPrintf1 ( "%d ", fave[t] );
|
||||
VPrintf0 ( "\n" );
|
||||
}
|
||||
|
||||
/*--
|
||||
Recompute the tables based on the accumulated frequencies.
|
||||
--*/
|
||||
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
|
||||
comment in huffman.c for details. */
|
||||
for (t = 0; t < nGroups; t++)
|
||||
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
|
||||
alphaSize, 17 /*20*/ );
|
||||
}
|
||||
|
||||
|
||||
AssertH( nGroups < 8, 3002 );
|
||||
AssertH( nSelectors < 32768 &&
|
||||
nSelectors <= (2 + (900000 / BZ_G_SIZE)),
|
||||
3003 );
|
||||
|
||||
|
||||
/*--- Compute MTF values for the selectors. ---*/
|
||||
{
|
||||
UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
|
||||
for (i = 0; i < nGroups; i++) pos[i] = i;
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
ll_i = s->selector[i];
|
||||
j = 0;
|
||||
tmp = pos[j];
|
||||
while ( ll_i != tmp ) {
|
||||
j++;
|
||||
tmp2 = tmp;
|
||||
tmp = pos[j];
|
||||
pos[j] = tmp2;
|
||||
};
|
||||
pos[0] = tmp;
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
};
|
||||
|
||||
/*--- Assign actual codes for the tables. --*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
minLen = 32;
|
||||
maxLen = 0;
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
|
||||
AssertH ( !(minLen < 1), 3005 );
|
||||
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize );
|
||||
}
|
||||
|
||||
/*--- Transmit the mapping table. ---*/
|
||||
{
|
||||
Bool inUse16[16];
|
||||
for (i = 0; i < 16; i++) {
|
||||
inUse16[i] = False;
|
||||
for (j = 0; j < 16; j++)
|
||||
if (s->inUse[i * 16 + j]) inUse16[i] = True;
|
||||
}
|
||||
|
||||
nBytes = s->numZ;
|
||||
for (i = 0; i < 16; i++)
|
||||
if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (inUse16[i])
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
|
||||
}
|
||||
|
||||
/*--- Now the selectors. ---*/
|
||||
nBytes = s->numZ;
|
||||
bsW ( s, 3, nGroups );
|
||||
bsW ( s, 15, nSelectors );
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
|
||||
bsW(s,1,0);
|
||||
}
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( "selectors %d, ", s->numZ-nBytes );
|
||||
|
||||
/*--- Now the coding tables. ---*/
|
||||
nBytes = s->numZ;
|
||||
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
Int32 curr = s->len[t][0];
|
||||
bsW ( s, 5, curr );
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
|
||||
while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
|
||||
bsW ( s, 1, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
|
||||
|
||||
/*--- And finally, the block data proper ---*/
|
||||
nBytes = s->numZ;
|
||||
selCtr = 0;
|
||||
gs = 0;
|
||||
while (True) {
|
||||
if (gs >= s->nMTF) break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF) ge = s->nMTF-1;
|
||||
AssertH ( s->selector[selCtr] < nGroups, 3006 );
|
||||
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
UInt16 mtfv_i;
|
||||
UChar* s_len_sel_selCtr
|
||||
= &(s->len[s->selector[selCtr]][0]);
|
||||
Int32* s_code_sel_selCtr
|
||||
= &(s->code[s->selector[selCtr]][0]);
|
||||
|
||||
# define BZ_ITAH(nn) \
|
||||
mtfv_i = mtfv[gs+(nn)]; \
|
||||
bsW ( s, \
|
||||
s_len_sel_selCtr[mtfv_i], \
|
||||
s_code_sel_selCtr[mtfv_i] )
|
||||
|
||||
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
|
||||
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
|
||||
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
|
||||
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
|
||||
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
|
||||
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
|
||||
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
|
||||
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
|
||||
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
|
||||
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
|
||||
|
||||
# undef BZ_ITAH
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
bsW ( s,
|
||||
s->len [s->selector[selCtr]] [mtfv[i]],
|
||||
s->code [s->selector[selCtr]] [mtfv[i]] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gs = ge+1;
|
||||
selCtr++;
|
||||
}
|
||||
AssertH( selCtr == nSelectors, 3007 );
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( "codes %d\n", s->numZ-nBytes );
|
||||
else /* squash compiler 'used but not set' warning */
|
||||
nBytes = nBytes;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_compressBlock ( EState* s, Bool is_last_block )
|
||||
{
|
||||
if (s->nblock > 0) {
|
||||
|
||||
BZ_FINALISE_CRC ( s->blockCRC );
|
||||
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
|
||||
s->combinedCRC ^= s->blockCRC;
|
||||
if (s->blockNo > 1) s->numZ = 0;
|
||||
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf4( " block %d: crc = 0x%08x, "
|
||||
"combined CRC = 0x%08x, size = %d\n",
|
||||
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
|
||||
|
||||
BZ2_blockSort ( s );
|
||||
}
|
||||
|
||||
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
|
||||
|
||||
/*-- If this is the first block, create the stream header. --*/
|
||||
if (s->blockNo == 1) {
|
||||
BZ2_bsInitWrite ( s );
|
||||
bsPutUChar ( s, BZ_HDR_B );
|
||||
bsPutUChar ( s, BZ_HDR_Z );
|
||||
bsPutUChar ( s, BZ_HDR_h );
|
||||
bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
|
||||
}
|
||||
|
||||
if (s->nblock > 0) {
|
||||
|
||||
bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
|
||||
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
|
||||
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
|
||||
|
||||
/*-- Now the block's CRC, so it is in a known place. --*/
|
||||
bsPutUInt32 ( s, s->blockCRC );
|
||||
|
||||
/*--
|
||||
Now a single bit indicating (non-)randomisation.
|
||||
As of version 0.9.5, we use a better sorting algorithm
|
||||
which makes randomisation unnecessary. So always set
|
||||
the randomised bit to 'no'. Of course, the decoder
|
||||
still needs to be able to handle randomised blocks
|
||||
so as to maintain backwards compatibility with
|
||||
older versions of bzip2.
|
||||
--*/
|
||||
bsW(s,1,0);
|
||||
|
||||
bsW ( s, 24, s->origPtr );
|
||||
generateMTFValues ( s );
|
||||
sendMTFValues ( s );
|
||||
}
|
||||
|
||||
|
||||
/*-- If this is the last block, add the stream trailer. --*/
|
||||
if (is_last_block) {
|
||||
|
||||
bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
|
||||
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
|
||||
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
|
||||
bsPutUInt32 ( s, s->combinedCRC );
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
|
||||
bsFinishWrite ( s );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end compress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
|
@ -56,7 +56,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
|
|||
COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
|
||||
COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
|
||||
COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
|
||||
COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
|
||||
COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
|
||||
COMPAT(INTEL_MICROCODE, "intel,microcode"),
|
||||
COMPAT(MEMORY_SPD, "memory-spd"),
|
||||
|
|
17
lib/time.c
17
lib/time.c
|
@ -41,23 +41,6 @@ extern unsigned long __weak timer_read_counter(void);
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_TIMER
|
||||
static int notrace dm_timer_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
if (!gd->timer) {
|
||||
ret = uclass_first_device(UCLASS_TIMER, &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
gd->timer = dev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong notrace get_tbclk(void)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -82,13 +82,21 @@ int vprintf(const char *fmt, va_list va)
|
|||
num = -(int)num;
|
||||
out('-');
|
||||
}
|
||||
for (div = 1000000000; div; div /= 10)
|
||||
div_out(&num, div);
|
||||
if (!num) {
|
||||
out_dgt(0);
|
||||
} else {
|
||||
for (div = 1000000000; div; div /= 10)
|
||||
div_out(&num, div);
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
num = va_arg(va, unsigned int);
|
||||
for (div = 0x10000000; div; div /= 0x10)
|
||||
div_out(&num, div);
|
||||
if (!num) {
|
||||
out_dgt(0);
|
||||
} else {
|
||||
for (div = 0x10000000; div; div /= 0x10)
|
||||
div_out(&num, div);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
out((char)(va_arg(va, int)));
|
||||
|
@ -108,8 +116,10 @@ int vprintf(const char *fmt, va_list va)
|
|||
w--;
|
||||
while (w-- > 0)
|
||||
putc(lz ? '0' : ' ');
|
||||
while ((ch = *p++))
|
||||
putc(ch);
|
||||
if (p) {
|
||||
while ((ch = *p++))
|
||||
putc(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Test for U-Boot cli including command repeat
|
||||
|
||||
BASE="$(dirname $0)"
|
||||
. $BASE/common.sh
|
||||
|
||||
run_test() {
|
||||
./${OUTPUT_DIR}/u-boot <<END
|
||||
setenv ctrlc_ignore y
|
||||
md 0
|
||||
|
||||
reset
|
||||
END
|
||||
}
|
||||
check_results() {
|
||||
echo "Check results"
|
||||
|
||||
grep -q 00000100 ${tmp} || fail "Command did not repeat"
|
||||
}
|
||||
|
||||
echo "Test CLI repeat"
|
||||
echo
|
||||
tmp="$(tempfile)"
|
||||
build_uboot
|
||||
run_test >${tmp}
|
||||
check_results ${tmp}
|
||||
rm ${tmp}
|
||||
echo "Test passed"
|
|
@ -7,9 +7,6 @@
|
|||
#define DEBUG
|
||||
|
||||
#include <common.h>
|
||||
#ifdef CONFIG_SANDBOX
|
||||
#include <os.h>
|
||||
#endif
|
||||
|
||||
static const char test_cmd[] = "setenv list 1\n setenv list ${list}2; "
|
||||
"setenv list ${list}3\0"
|
||||
|
@ -20,21 +17,6 @@ static int do_ut_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
printf("%s: Testing commands\n", __func__);
|
||||
run_command("env default -f -a", 0);
|
||||
|
||||
/* run a single command */
|
||||
run_command("setenv single 1", 0);
|
||||
assert(!strcmp("1", getenv("single")));
|
||||
|
||||
/* make sure that compound statements work */
|
||||
#ifdef CONFIG_SYS_HUSH_PARSER
|
||||
run_command("if test -n ${single} ; then setenv check 1; fi", 0);
|
||||
assert(!strcmp("1", getenv("check")));
|
||||
run_command("setenv check", 0);
|
||||
#endif
|
||||
|
||||
/* commands separated by ; */
|
||||
run_command_list("setenv list 1; setenv list ${list}1", -1, 0);
|
||||
assert(!strcmp("11", getenv("list")));
|
||||
|
||||
/* commands separated by \n */
|
||||
run_command_list("setenv list 1\n setenv list ${list}1", -1, 0);
|
||||
assert(!strcmp("11", getenv("list")));
|
||||
|
@ -43,11 +25,6 @@ static int do_ut_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
run_command_list("setenv list 1${list}\n", -1, 0);
|
||||
assert(!strcmp("111", getenv("list")));
|
||||
|
||||
/* three commands in a row */
|
||||
run_command_list("setenv list 1\n setenv list ${list}2; "
|
||||
"setenv list ${list}3", -1, 0);
|
||||
assert(!strcmp("123", getenv("list")));
|
||||
|
||||
/* a command string with \0 in it. Stuff after \0 should be ignored */
|
||||
run_command("setenv list", 0);
|
||||
run_command_list(test_cmd, sizeof(test_cmd), 0);
|
||||
|
@ -66,13 +43,6 @@ static int do_ut_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
assert(run_command_list("false", -1, 0) == 1);
|
||||
assert(run_command_list("echo", -1, 0) == 0);
|
||||
|
||||
run_command("setenv foo 'setenv monty 1; setenv python 2'", 0);
|
||||
run_command("run foo", 0);
|
||||
assert(getenv("monty") != NULL);
|
||||
assert(!strcmp("1", getenv("monty")));
|
||||
assert(getenv("python") != NULL);
|
||||
assert(!strcmp("2", getenv("python")));
|
||||
|
||||
#ifdef CONFIG_SYS_HUSH_PARSER
|
||||
run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0);
|
||||
run_command("run foo", 0);
|
||||
|
@ -80,112 +50,6 @@ static int do_ut_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
assert(!strcmp("1", getenv("black")));
|
||||
assert(getenv("adder") != NULL);
|
||||
assert(!strcmp("2", getenv("adder")));
|
||||
|
||||
/* Test the 'test' command */
|
||||
|
||||
#define HUSH_TEST(name, expr, expected_result) \
|
||||
run_command("if test " expr " ; then " \
|
||||
"setenv " #name "_" #expected_result " y; else " \
|
||||
"setenv " #name "_" #expected_result " n; fi", 0); \
|
||||
assert(!strcmp(#expected_result, getenv(#name "_" #expected_result))); \
|
||||
setenv(#name "_" #expected_result, NULL);
|
||||
|
||||
/* Basic operators */
|
||||
HUSH_TEST(streq, "aaa = aaa", y);
|
||||
HUSH_TEST(streq, "aaa = bbb", n);
|
||||
|
||||
HUSH_TEST(strneq, "aaa != bbb", y);
|
||||
HUSH_TEST(strneq, "aaa != aaa", n);
|
||||
|
||||
HUSH_TEST(strlt, "aaa < bbb", y);
|
||||
HUSH_TEST(strlt, "bbb < aaa", n);
|
||||
|
||||
HUSH_TEST(strgt, "bbb > aaa", y);
|
||||
HUSH_TEST(strgt, "aaa > bbb", n);
|
||||
|
||||
HUSH_TEST(eq, "123 -eq 123", y);
|
||||
HUSH_TEST(eq, "123 -eq 456", n);
|
||||
|
||||
HUSH_TEST(ne, "123 -ne 456", y);
|
||||
HUSH_TEST(ne, "123 -ne 123", n);
|
||||
|
||||
HUSH_TEST(lt, "123 -lt 456", y);
|
||||
HUSH_TEST(lt_eq, "123 -lt 123", n);
|
||||
HUSH_TEST(lt, "456 -lt 123", n);
|
||||
|
||||
HUSH_TEST(le, "123 -le 456", y);
|
||||
HUSH_TEST(le_eq, "123 -le 123", y);
|
||||
HUSH_TEST(le, "456 -le 123", n);
|
||||
|
||||
HUSH_TEST(gt, "456 -gt 123", y);
|
||||
HUSH_TEST(gt_eq, "123 -gt 123", n);
|
||||
HUSH_TEST(gt, "123 -gt 456", n);
|
||||
|
||||
HUSH_TEST(ge, "456 -ge 123", y);
|
||||
HUSH_TEST(ge_eq, "123 -ge 123", y);
|
||||
HUSH_TEST(ge, "123 -ge 456", n);
|
||||
|
||||
HUSH_TEST(z, "-z \"\"", y);
|
||||
HUSH_TEST(z, "-z \"aaa\"", n);
|
||||
|
||||
HUSH_TEST(n, "-n \"aaa\"", y);
|
||||
HUSH_TEST(n, "-n \"\"", n);
|
||||
|
||||
/* Inversion of simple tests */
|
||||
HUSH_TEST(streq_inv, "! aaa = aaa", n);
|
||||
HUSH_TEST(streq_inv, "! aaa = bbb", y);
|
||||
|
||||
HUSH_TEST(streq_inv_inv, "! ! aaa = aaa", y);
|
||||
HUSH_TEST(streq_inv_inv, "! ! aaa = bbb", n);
|
||||
|
||||
/* Binary operators */
|
||||
HUSH_TEST(or_0_0, "aaa != aaa -o bbb != bbb", n);
|
||||
HUSH_TEST(or_0_1, "aaa != aaa -o bbb = bbb", y);
|
||||
HUSH_TEST(or_1_0, "aaa = aaa -o bbb != bbb", y);
|
||||
HUSH_TEST(or_1_1, "aaa = aaa -o bbb = bbb", y);
|
||||
|
||||
HUSH_TEST(and_0_0, "aaa != aaa -a bbb != bbb", n);
|
||||
HUSH_TEST(and_0_1, "aaa != aaa -a bbb = bbb", n);
|
||||
HUSH_TEST(and_1_0, "aaa = aaa -a bbb != bbb", n);
|
||||
HUSH_TEST(and_1_1, "aaa = aaa -a bbb = bbb", y);
|
||||
|
||||
/* Inversion within binary operators */
|
||||
HUSH_TEST(or_0_0_inv, "! aaa != aaa -o ! bbb != bbb", y);
|
||||
HUSH_TEST(or_0_1_inv, "! aaa != aaa -o ! bbb = bbb", y);
|
||||
HUSH_TEST(or_1_0_inv, "! aaa = aaa -o ! bbb != bbb", y);
|
||||
HUSH_TEST(or_1_1_inv, "! aaa = aaa -o ! bbb = bbb", n);
|
||||
|
||||
HUSH_TEST(or_0_0_inv_inv, "! ! aaa != aaa -o ! ! bbb != bbb", n);
|
||||
HUSH_TEST(or_0_1_inv_inv, "! ! aaa != aaa -o ! ! bbb = bbb", y);
|
||||
HUSH_TEST(or_1_0_inv_inv, "! ! aaa = aaa -o ! ! bbb != bbb", y);
|
||||
HUSH_TEST(or_1_1_inv_inv, "! ! aaa = aaa -o ! ! bbb = bbb", y);
|
||||
|
||||
setenv("ut_var_nonexistent", NULL);
|
||||
setenv("ut_var_exists", "1");
|
||||
HUSH_TEST(z_varexp_quoted, "-z \"$ut_var_nonexistent\"", y);
|
||||
HUSH_TEST(z_varexp_quoted, "-z \"$ut_var_exists\"", n);
|
||||
setenv("ut_var_exists", NULL);
|
||||
|
||||
run_command("setenv ut_var_space \" \"", 0);
|
||||
assert(!strcmp(getenv("ut_var_space"), " "));
|
||||
run_command("setenv ut_var_test $ut_var_space", 0);
|
||||
assert(!getenv("ut_var_test"));
|
||||
run_command("setenv ut_var_test \"$ut_var_space\"", 0);
|
||||
assert(!strcmp(getenv("ut_var_test"), " "));
|
||||
run_command("setenv ut_var_test \" 1${ut_var_space}${ut_var_space} 2 \"", 0);
|
||||
assert(!strcmp(getenv("ut_var_test"), " 1 2 "));
|
||||
setenv("ut_var_space", NULL);
|
||||
setenv("ut_var_test", NULL);
|
||||
|
||||
#ifdef CONFIG_SANDBOX
|
||||
/* File existence */
|
||||
HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", n);
|
||||
run_command("sb save hostfs - creating_this_file_breaks_uboot_unit_test 0 1", 0);
|
||||
HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", y);
|
||||
/* Perhaps this could be replaced by an "rm" shell command one day */
|
||||
assert(!os_unlink("creating_this_file_breaks_uboot_unit_test"));
|
||||
HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", n);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
assert(run_command("", 0) == 0);
|
||||
|
|
|
@ -34,5 +34,6 @@ obj-$(CONFIG_DM_USB) += usb.o
|
|||
obj-$(CONFIG_DM_PMIC) += pmic.o
|
||||
obj-$(CONFIG_DM_REGULATOR) += regulator.o
|
||||
obj-$(CONFIG_TIMER) += timer.o
|
||||
obj-$(CONFIG_DM_VIDEO) += video.o
|
||||
obj-$(CONFIG_ADC) += adc.o
|
||||
endif
|
||||
|
|
271
test/dm/video.c
Normal file
271
test/dm/video.c
Normal file
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <bzlib.h>
|
||||
#include <dm.h>
|
||||
#include <mapmem.h>
|
||||
#include <os.h>
|
||||
#include <video.h>
|
||||
#include <video_console.h>
|
||||
#include <dm/test.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
/*
|
||||
* These tests use the standard sandbox frame buffer, the resolution of which
|
||||
* is defined in the device tree. This only supports 16bpp so the tests only
|
||||
* test that code path. It would be possible to adjust this fairly easily,
|
||||
* by adjusting the bpix value in struct sandbox_sdl_plat. However the code
|
||||
* in sandbox_sdl_sync() would also need to change to handle the different
|
||||
* surface depth.
|
||||
*/
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* Basic test of the video uclass */
|
||||
static int dm_test_video_base(struct unit_test_state *uts)
|
||||
{
|
||||
struct video_priv *priv;
|
||||
struct udevice *dev;
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_asserteq(1366, video_get_xsize(dev));
|
||||
ut_asserteq(768, video_get_ysize(dev));
|
||||
priv = dev_get_uclass_priv(dev);
|
||||
ut_asserteq(priv->fb_size, 1366 * 768 * 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/**
|
||||
* compress_frame_buffer() - Compress the frame buffer and return its size
|
||||
*
|
||||
* We want to write tests which perform operations on the video console and
|
||||
* check that the frame buffer ends up with the correct contents. But it is
|
||||
* painful to store 'known good' images for comparison with the frame
|
||||
* buffer. As an alternative, we can compress the frame buffer and check the
|
||||
* size of the compressed data. This provides a pretty good level of
|
||||
* certainty and the resulting tests need only check a single value.
|
||||
*
|
||||
* @dev: Video device
|
||||
* @return compressed size of the frame buffer, or -ve on error
|
||||
*/
|
||||
static int compress_frame_buffer(struct udevice *dev)
|
||||
{
|
||||
struct video_priv *priv = dev_get_uclass_priv(dev);
|
||||
uint destlen;
|
||||
void *dest;
|
||||
int ret;
|
||||
|
||||
destlen = priv->fb_size;
|
||||
dest = malloc(priv->fb_size);
|
||||
if (!dest)
|
||||
return -ENOMEM;
|
||||
ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
|
||||
priv->fb, priv->fb_size,
|
||||
3, 0, 0);
|
||||
free(dest);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return destlen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this function at any point to halt and show the current display. Be
|
||||
* sure to run the test with the -l flag.
|
||||
*/
|
||||
static void __maybe_unused see_output(void)
|
||||
{
|
||||
video_sync_all();
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Test text output works on the video console */
|
||||
static int dm_test_video_text(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev, *con;
|
||||
int i;
|
||||
|
||||
#define WHITE 0xffff
|
||||
#define SCROLL_LINES 100
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_asserteq(46, compress_frame_buffer(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));
|
||||
|
||||
vidconsole_putc_xy(con, 0, 0, ' ');
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
vidconsole_putc_xy(con, i * 8, 0, ' ' + i);
|
||||
ut_asserteq(273, compress_frame_buffer(dev));
|
||||
|
||||
vidconsole_set_row(con, 0, WHITE);
|
||||
ut_asserteq(46, compress_frame_buffer(dev));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
vidconsole_putc_xy(con, i * 8, 0, ' ' + i);
|
||||
ut_asserteq(273, compress_frame_buffer(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_text, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test handling of special characters in the console */
|
||||
static int dm_test_video_chars(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev, *con;
|
||||
const char *test_string = "Well\b\b\b\bxhe is\r \n\ta very modest \bman\n\t\tand Has much to\b\bto be modest about.";
|
||||
const char *s;
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
for (s = test_string; *s; s++)
|
||||
vidconsole_put_char(con, *s);
|
||||
ut_asserteq(466, compress_frame_buffer(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_chars, 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)
|
||||
* @wrap_size: Expected size of compressed frame buffer for the wrap test
|
||||
* @scroll_size: Same for the scroll test
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int check_vidconsole_output(struct unit_test_state *uts, int rot,
|
||||
int wrap_size, int scroll_size)
|
||||
{
|
||||
struct udevice *dev, *con;
|
||||
struct sandbox_sdl_plat *plat;
|
||||
int i;
|
||||
|
||||
ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
|
||||
ut_assert(!device_active(dev));
|
||||
plat = dev_get_platdata(dev);
|
||||
plat->rot = 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));
|
||||
|
||||
/* Check display wrap */
|
||||
for (i = 0; i < 120; i++)
|
||||
vidconsole_put_char(con, 'A' + i % 50);
|
||||
ut_asserteq(wrap_size, compress_frame_buffer(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));
|
||||
|
||||
/* 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));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test text output through the console uclass */
|
||||
static int dm_test_video_context(struct unit_test_state *uts)
|
||||
{
|
||||
return check_vidconsole_output(uts, 0, 788, 453);
|
||||
}
|
||||
DM_TEST(dm_test_video_context, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test rotated text output through the console uclass */
|
||||
static int dm_test_video_rotation1(struct unit_test_state *uts)
|
||||
{
|
||||
ut_assertok(check_vidconsole_output(uts, 1, 1112, 680));
|
||||
|
||||
return 0;
|
||||
}
|
||||
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));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_rotation2, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test rotated text output through the console uclass */
|
||||
static int dm_test_video_rotation3(struct unit_test_state *uts)
|
||||
{
|
||||
ut_assertok(check_vidconsole_output(uts, 3, 1134, 681));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_rotation3, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/* Read a file into memory and return a pointer to it */
|
||||
static int read_file(struct unit_test_state *uts, const char *fname,
|
||||
ulong *addrp)
|
||||
{
|
||||
int buf_size = 100000;
|
||||
ulong addr = 0;
|
||||
int size, fd;
|
||||
char *buf;
|
||||
|
||||
buf = map_sysmem(addr, 0);
|
||||
ut_assert(buf != NULL);
|
||||
fd = os_open(fname, OS_O_RDONLY);
|
||||
ut_assert(fd >= 0);
|
||||
size = os_read(fd, buf, buf_size);
|
||||
ut_assert(size >= 0);
|
||||
ut_assert(size < buf_size);
|
||||
os_close(fd);
|
||||
*addrp = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test drawing a bitmap file */
|
||||
static int dm_test_video_bmp(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
ulong addr;
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
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));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_bmp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test drawing a compressed bitmap file */
|
||||
static int dm_test_video_bmp_comp(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
ulong addr;
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
|
||||
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));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_bmp_comp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
1
test/py/.gitignore
vendored
Normal file
1
test/py/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.pyc
|
300
test/py/README.md
Normal file
300
test/py/README.md
Normal file
|
@ -0,0 +1,300 @@
|
|||
# U-Boot pytest suite
|
||||
|
||||
## Introduction
|
||||
|
||||
This tool aims to test U-Boot by executing U-Boot shell commands using the
|
||||
console interface. A single top-level script exists to execute or attach to the
|
||||
U-Boot console, run the entire script of tests against it, and summarize the
|
||||
results. Advantages of this approach are:
|
||||
|
||||
- Testing is performed in the same way a user or script would interact with
|
||||
U-Boot; there can be no disconnect.
|
||||
- There is no need to write or embed test-related code into U-Boot itself.
|
||||
It is asserted that writing test-related code in Python is simpler and more
|
||||
flexible that writing it all in C.
|
||||
- It is reasonably simple to interact with U-Boot in this way.
|
||||
|
||||
## Requirements
|
||||
|
||||
The test suite is implemented using pytest. Interaction with the U-Boot console
|
||||
involves executing some binary and interacting with its stdin/stdout. You will
|
||||
need to implement various "hook" scripts that are called by the test suite at
|
||||
the appropriate time.
|
||||
|
||||
On Debian or Debian-like distributions, the following packages are required.
|
||||
Similar package names should exist in other distributions.
|
||||
|
||||
| Package | Version tested (Ubuntu 14.04) |
|
||||
| -------------- | ----------------------------- |
|
||||
| python | 2.7.5-5ubuntu3 |
|
||||
| python-pytest | 2.5.1-1 |
|
||||
|
||||
The test script supports either:
|
||||
|
||||
- Executing a sandbox port of U-Boot on the local machine as a sub-process,
|
||||
and interacting with it over stdin/stdout.
|
||||
- Executing an external "hook" scripts to flash a U-Boot binary onto a
|
||||
physical board, attach to the board's console stream, and reset the board.
|
||||
Further details are described later.
|
||||
|
||||
### Using `virtualenv` to provide requirements
|
||||
|
||||
Older distributions (e.g. Ubuntu 10.04) may not provide all the required
|
||||
packages, or may provide versions that are too old to run the test suite. One
|
||||
can use the Python `virtualenv` script to locally install more up-to-date
|
||||
versions of the required packages without interfering with the OS installation.
|
||||
For example:
|
||||
|
||||
```bash
|
||||
$ cd /path/to/u-boot
|
||||
$ sudo apt-get install python python-virtualenv
|
||||
$ virtualenv venv
|
||||
$ . ./venv/bin/activate
|
||||
$ pip install pytest
|
||||
```
|
||||
|
||||
## Testing sandbox
|
||||
|
||||
To run the testsuite on the sandbox port (U-Boot built as a native user-space
|
||||
application), simply execute:
|
||||
|
||||
```
|
||||
./test/py/test.py --bd sandbox --build
|
||||
```
|
||||
|
||||
The `--bd` option tells the test suite which board type is being tested. This
|
||||
lets the test suite know which features the board has, and hence exactly what
|
||||
can be tested.
|
||||
|
||||
The `--build` option tells U-Boot to compile U-Boot. Alternatively, you may
|
||||
omit this option and build U-Boot yourself, in whatever way you choose, before
|
||||
running the test script.
|
||||
|
||||
The test script will attach to U-Boot, execute all valid tests for the board,
|
||||
then print a summary of the test process. A complete log of the test session
|
||||
will be written to `${build_dir}/test-log.html`. This is best viewed in a web
|
||||
browser, but may be read directly as plain text, perhaps with the aid of the
|
||||
`html2text` utility.
|
||||
|
||||
## Command-line options
|
||||
|
||||
- `--board-type`, `--bd`, `-B` set the type of the board to be tested. For
|
||||
example, `sandbox` or `seaboard`.
|
||||
- `--board-identity`, `--id` set the identity of the board to be tested.
|
||||
This allows differentiation between multiple instances of the same type of
|
||||
physical board that are attached to the same host machine. This parameter is
|
||||
not interpreted by the test script in any way, but rather is simply passed
|
||||
to the hook scripts described below, and may be used in any site-specific
|
||||
way deemed necessary.
|
||||
- `--build` indicates that the test script should compile U-Boot itself
|
||||
before running the tests. If using this option, make sure that any
|
||||
environment variables required by the build process are already set, such as
|
||||
`$CROSS_COMPILE`.
|
||||
- `--build-dir` sets the directory containing the compiled U-Boot binaries.
|
||||
If omitted, this is `${source_dir}/build-${board_type}`.
|
||||
- `--result-dir` sets the directory to write results, such as log files,
|
||||
into. If omitted, the build directory is used.
|
||||
- `--persistent-data-dir` sets the directory used to store persistent test
|
||||
data. This is test data that may be re-used across test runs, such as file-
|
||||
system images.
|
||||
|
||||
`pytest` also implements a number of its own command-line options. Please see
|
||||
`pytest` documentation for complete details. Execute `py.test --version` for
|
||||
a brief summary. Note that U-Boot's test.py script passes all command-line
|
||||
arguments directly to `pytest` for processing.
|
||||
|
||||
## Testing real hardware
|
||||
|
||||
The tools and techniques used to interact with real hardware will vary
|
||||
radically between different host and target systems, and the whims of the user.
|
||||
For this reason, the test suite does not attempt to directly interact with real
|
||||
hardware in any way. Rather, it executes a standardized set of "hook" scripts
|
||||
via `$PATH`. These scripts implement certain actions on behalf of the test
|
||||
suite. This keeps the test suite simple and isolated from system variances
|
||||
unrelated to U-Boot features.
|
||||
|
||||
### Hook scripts
|
||||
|
||||
#### Environment variables
|
||||
|
||||
The following environment variables are set when running hook scripts:
|
||||
|
||||
- `UBOOT_BOARD_TYPE` the board type being tested.
|
||||
- `UBOOT_BOARD_IDENTITY` the board identity being tested, or `na` if none was
|
||||
specified.
|
||||
- `UBOOT_SOURCE_DIR` the U-Boot source directory.
|
||||
- `UBOOT_TEST_PY_DIR` the full path to `test/py/` in the source directory.
|
||||
- `UBOOT_BUILD_DIR` the U-Boot build directory.
|
||||
- `UBOOT_RESULT_DIR` the test result directory.
|
||||
- `UBOOT_PERSISTENT_DATA_DIR` the test peristent data directory.
|
||||
|
||||
#### `u-boot-test-console`
|
||||
|
||||
This script provides access to the U-Boot console. The script's stdin/stdout
|
||||
should be connected to the board's console. This process should continue to run
|
||||
indefinitely, until killed. The test suite will run this script in parallel
|
||||
with all other hooks.
|
||||
|
||||
This script may be implemented e.g. by exec()ing `cu`, `kermit`, `conmux`, etc.
|
||||
|
||||
If you are able to run U-Boot under a hardware simulator such as qemu, then
|
||||
you would likely spawn that simulator from this script. However, note that
|
||||
`u-boot-test-reset` may be called multiple times per test script run, and must
|
||||
cause U-Boot to start execution from scratch each time. Hopefully your
|
||||
simulator includes a virtual reset button! If not, you can launch the
|
||||
simulator from `u-boot-test-reset` instead, while arranging for this console
|
||||
process to always communicate with the current simulator instance.
|
||||
|
||||
#### `u-boot-test-flash`
|
||||
|
||||
Prior to running the test suite against a board, some arrangement must be made
|
||||
so that the board executes the particular U-Boot binary to be tested. Often,
|
||||
this involves writing the U-Boot binary to the board's flash ROM. The test
|
||||
suite calls this hook script for that purpose.
|
||||
|
||||
This script should perform the entire flashing process synchronously; the
|
||||
script should only exit once flashing is complete, and a board reset will
|
||||
cause the newly flashed U-Boot binary to be executed.
|
||||
|
||||
It is conceivable that this script will do nothing. This might be useful in
|
||||
the following cases:
|
||||
|
||||
- Some other process has already written the desired U-Boot binary into the
|
||||
board's flash prior to running the test suite.
|
||||
- The board allows U-Boot to be downloaded directly into RAM, and executed
|
||||
from there. Use of this feature will reduce wear on the board's flash, so
|
||||
may be preferable if available, and if cold boot testing of U-Boot is not
|
||||
required. If this feature is used, the `u-boot-test-reset` script should
|
||||
peform this download, since the board could conceivably be reset multiple
|
||||
times in a single test run.
|
||||
|
||||
It is up to the user to determine if those situations exist, and to code this
|
||||
hook script appropriately.
|
||||
|
||||
This script will typically be implemented by calling out to some SoC- or
|
||||
board-specific vendor flashing utility.
|
||||
|
||||
#### `u-boot-test-reset`
|
||||
|
||||
Whenever the test suite needs to reset the target board, this script is
|
||||
executed. This is guaranteed to happen at least once, prior to executing the
|
||||
first test function. If any test fails, the test infra-structure will execute
|
||||
this script again to restore U-Boot to an operational state before running the
|
||||
next test function.
|
||||
|
||||
This script will likely be implemented by communicating with some form of
|
||||
relay or electronic switch attached to the board's reset signal.
|
||||
|
||||
The semantics of this script require that when it is executed, U-Boot will
|
||||
start running from scratch. If the U-Boot binary to be tested has been written
|
||||
to flash, pulsing the board's reset signal is likely all this script need do.
|
||||
However, in some scenarios, this script may perform other actions. For
|
||||
example, it may call out to some SoC- or board-specific vendor utility in order
|
||||
to download the U-Boot binary directly into RAM and execute it. This would
|
||||
avoid the need for `u-boot-test-flash` to actually write U-Boot to flash, thus
|
||||
saving wear on the flash chip(s).
|
||||
|
||||
### Board-type-specific configuration
|
||||
|
||||
Each board has a different configuration and behaviour. Many of these
|
||||
differences can be automatically detected by parsing the `.config` file in the
|
||||
build directory. However, some differences can't yet be handled automatically.
|
||||
|
||||
For each board, an optional Python module `u_boot_board_${board_type}` may exist
|
||||
to provide board-specific information to the test script. Any global value
|
||||
defined in these modules is available for use by any test function. The data
|
||||
contained in these scripts must be purely derived from U-Boot source code.
|
||||
Hence, these configuration files are part of the U-Boot source tree too.
|
||||
|
||||
### Execution environment configuration
|
||||
|
||||
Each user's hardware setup may enable testing different subsets of the features
|
||||
implemented by a particular board's configuration of U-Boot. For example, a
|
||||
U-Boot configuration may support USB device mode and USB Mass Storage, but this
|
||||
can only be tested if a USB cable is connected between the board and the host
|
||||
machine running the test script.
|
||||
|
||||
For each board, optional Python modules `u_boot_boardenv_${board_type}` and
|
||||
`u_boot_boardenv_${board_type}_${board_identity}` may exist to provide
|
||||
board-specific and board-identity-specific information to the test script. Any
|
||||
global value defined in these modules is available for use by any test
|
||||
function. The data contained in these is specific to a particular user's
|
||||
hardware configuration. Hence, these configuration files are not part of the
|
||||
U-Boot source tree, and should be installed outside of the source tree. Users
|
||||
should set `$PYTHONPATH` prior to running the test script to allow these
|
||||
modules to be loaded.
|
||||
|
||||
### Board module parameter usage
|
||||
|
||||
The test scripts rely on the following variables being defined by the board
|
||||
module:
|
||||
|
||||
- None at present.
|
||||
|
||||
### U-Boot `.config` feature usage
|
||||
|
||||
The test scripts rely on various U-Boot `.config` features, either directly in
|
||||
order to test those features, or indirectly in order to query information from
|
||||
the running U-Boot instance in order to test other features.
|
||||
|
||||
One example is that testing of the `md` command requires knowledge of a RAM
|
||||
address to use for the test. This data is parsed from the output of the
|
||||
`bdinfo` command, and hence relies on CONFIG_CMD_BDI being enabled.
|
||||
|
||||
For a complete list of dependencies, please search the test scripts for
|
||||
instances of:
|
||||
|
||||
- `buildconfig.get(...`
|
||||
- `@pytest.mark.buildconfigspec(...`
|
||||
|
||||
### Complete invocation example
|
||||
|
||||
Assuming that you have installed the hook scripts into $HOME/ubtest/bin, and
|
||||
any required environment configuration Python modules into $HOME/ubtest/py,
|
||||
then you would likely invoke the test script as follows:
|
||||
|
||||
If U-Boot has already been built:
|
||||
|
||||
```bash
|
||||
PATH=$HOME/ubtest/bin:$PATH \
|
||||
PYTHONPATH=${HOME}/ubtest/py:${PYTHONPATH} \
|
||||
./test/py/test.py --bd seaboard
|
||||
```
|
||||
|
||||
If you want the test script to compile U-Boot for you too, then you likely
|
||||
need to set `$CROSS_COMPILE` to allow this, and invoke the test script as
|
||||
follow:
|
||||
|
||||
```bash
|
||||
CROSS_COMPILE=arm-none-eabi- \
|
||||
PATH=$HOME/ubtest/bin:$PATH \
|
||||
PYTHONPATH=${HOME}/ubtest/py:${PYTHONPATH} \
|
||||
./test/py/test.py --bd seaboard --build
|
||||
```
|
||||
|
||||
## Writing tests
|
||||
|
||||
Please refer to the pytest documentation for details of writing pytest tests.
|
||||
Details specific to the U-Boot test suite are described below.
|
||||
|
||||
A test fixture named `u_boot_console` should be used by each test function. This
|
||||
provides the means to interact with the U-Boot console, and retrieve board and
|
||||
environment configuration information.
|
||||
|
||||
The function `u_boot_console.run_command()` executes a shell command on the
|
||||
U-Boot console, and returns all output from that command. This allows
|
||||
validation or interpretation of the command output. This function validates
|
||||
that certain strings are not seen on the U-Boot console. These include shell
|
||||
error messages and the U-Boot sign-on message (in order to detect unexpected
|
||||
board resets). See the source of `u_boot_console_base.py` for a complete list of
|
||||
"bad" strings. Some test scenarios are expected to trigger these strings. Use
|
||||
`u_boot_console.disable_check()` to temporarily disable checking for specific
|
||||
strings. See `test_unknown_cmd.py` for an example.
|
||||
|
||||
Board- and board-environment configuration values may be accessed as sub-fields
|
||||
of the `u_boot_console.config` object, for example
|
||||
`u_boot_console.config.ram_base`.
|
||||
|
||||
Build configuration values (from `.config`) may be accessed via the dictionary
|
||||
`u_boot_console.config.buildconfig`, with keys equal to the Kconfig variable
|
||||
names.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue