- update for using splashfile instead of location->name

when loading the splash image from a FIT
 - updates for loading internal and external splash data from FIT
 - DM_GPIO/DM_VIDEO migration for mx53 cx9020 board
 - fix boot issue on mx6sabresd board after DM_VIDEO migration
 - increase the max preallocated framebuffer BPP to 32 in ipuv3
   driver to prepare for configurations with higher color depth
 - allow to use vidconsole_put_string() in board code for text
   output on LCD displays
 -----BEGIN PGP SIGNATURE-----
 
 iGwEABECACwWIQSC4hxrSoIUVfFO0kRM6ATMmsalXAUCXOK5Sw4cYWd1c3RAZGVu
 eC5kZQAKCRBM6ATMmsalXBvoAJ96YrInVKKWtuVigA9lNpk5xbmbeQCdG9wML4LI
 dBbQyzD3mNqvnDMyNPQ=
 =Plt7
 -----END PGP SIGNATURE-----

Merge tag 'video-for-2019.07-rc3' of git://git.denx.de/u-boot-video

- update for using splashfile instead of location->name
  when loading the splash image from a FIT
- updates for loading internal and external splash data from FIT
- DM_GPIO/DM_VIDEO migration for mx53 cx9020 board
- fix boot issue on mx6sabresd board after DM_VIDEO migration
- increase the max preallocated framebuffer BPP to 32 in ipuv3
  driver to prepare for configurations with higher color depth
- allow to use vidconsole_put_string() in board code for text
  output on LCD displays
This commit is contained in:
Tom Rini 2019-05-21 07:12:46 -04:00
commit b9625abe03
15 changed files with 271 additions and 149 deletions

View file

@ -31,6 +31,7 @@
i2c0 = &i2c1;
i2c1 = &i2c2;
i2c2 = &i2c3;
ipu0 = &ipu;
mmc0 = &esdhc1;
mmc1 = &esdhc2;
mmc2 = &esdhc3;
@ -51,6 +52,7 @@
compatible = "simple-bus";
interrupt-parent = <&tzic>;
ranges;
u-boot,dm-pre-reloc;
aips@50000000 { /* AIPS1 */
compatible = "fsl,aips-bus", "simple-bus";
@ -283,5 +285,140 @@
status = "disabled";
};
};
ipu: ipu@18000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx53-ipu";
reg = <0x18000000 0x08000000>;
interrupts = <11 10>;
clocks = <&clks IMX5_CLK_IPU_GATE>,
<&clks IMX5_CLK_IPU_DI0_GATE>,
<&clks IMX5_CLK_IPU_DI1_GATE>;
clock-names = "bus", "di0", "di1";
resets = <&src 2>;
u-boot,dm-pre-reloc;
ipu_csi0: port@0 {
reg = <0>;
};
ipu_csi1: port@1 {
reg = <1>;
};
ipu_di0: port@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
ipu_di0_disp0: endpoint@0 {
reg = <0>;
};
ipu_di0_lvds0: endpoint@1 {
reg = <1>;
remote-endpoint = <&lvds0_in>;
};
};
ipu_di1: port@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
ipu_di1_disp1: endpoint@0 {
reg = <0>;
};
ipu_di1_lvds1: endpoint@1 {
reg = <1>;
remote-endpoint = <&lvds1_in>;
};
ipu_di1_tve: endpoint@2 {
reg = <2>;
remote-endpoint = <&tve_in>;
};
};
};
tve: tve@63ff0000 {
compatible = "fsl,imx53-tve";
reg = <0x63ff0000 0x1000>;
interrupts = <92>;
clocks = <&clks IMX5_CLK_TVE_GATE>,
<&clks IMX5_CLK_IPU_DI1_SEL>;
clock-names = "tve", "di_sel";
status = "disabled";
port {
tve_in: endpoint {
remote-endpoint = <&ipu_di1_tve>;
};
};
};
src: src@53fd0000 {
compatible = "fsl,imx53-src", "fsl,imx51-src";
reg = <0x53fd0000 0x4000>;
#reset-cells = <1>;
};
ldb: ldb@53fa8008 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx53-ldb";
reg = <0x53fa8008 0x4>;
gpr = <&gpr>;
clocks = <&clks IMX5_CLK_LDB_DI0_SEL>,
<&clks IMX5_CLK_LDB_DI1_SEL>,
<&clks IMX5_CLK_IPU_DI0_SEL>,
<&clks IMX5_CLK_IPU_DI1_SEL>,
<&clks IMX5_CLK_LDB_DI0_GATE>,
<&clks IMX5_CLK_LDB_DI1_GATE>;
clock-names = "di0_pll", "di1_pll",
"di0_sel", "di1_sel",
"di0", "di1";
status = "disabled";
lvds-channel@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
status = "disabled";
port@0 {
reg = <0>;
lvds0_in: endpoint {
remote-endpoint = <&ipu_di0_lvds0>;
};
};
port@2 {
reg = <2>;
};
};
lvds-channel@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
status = "disabled";
port@1 {
reg = <1>;
lvds1_in: endpoint {
remote-endpoint = <&ipu_di1_lvds1>;
};
};
port@2 {
reg = <2>;
};
};
};
};
};

View file

@ -9,6 +9,7 @@
/ {
aliases {
ipu1 = &ipu2;
video1 = &ipu2;
spi4 = &ecspi5;
};

View file

@ -33,6 +33,7 @@
i2c1 = &i2c2;
i2c2 = &i2c3;
ipu0 = &ipu1;
video0 = &ipu1;
mmc0 = &usdhc1;
mmc1 = &usdhc2;
mmc2 = &usdhc3;

View file

@ -4,4 +4,4 @@
# Patrick Bruenn <p.bruenn@beckhoff.com>
obj-y += mx53cx9020.o
obj-$(CONFIG_VIDEO) += mx53cx9020_video.o
obj-$(CONFIG_DM_VIDEO) += mx53cx9020_video.o

View file

@ -8,26 +8,12 @@
*/
#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/clock.h>
#include <asm/arch/iomux-mx53.h>
#include <asm/arch/clock.h>
#include <asm/mach-imx/mx5_video.h>
#include <ACEX1K.h>
#include <netdev.h>
#include <i2c.h>
#include <mmc.h>
#include <fsl_esdhc.h>
#include <asm/gpio.h>
#include <linux/fb.h>
#include <ipu_pixfmt.h>
#include <input.h>
#include <fs.h>
#include <dm/platform_data/serial_mxc.h>
enum LED_GPIOS {
GPIO_SD1_CD = IMX_GPIO_NR(1, 1),
@ -91,6 +77,9 @@ void weim_cs0_settings(u32 mode)
static void setup_gpio_eim(void)
{
gpio_request(GPIO_C3_STATUS, "GPIO_C3_STATUS");
gpio_request(GPIO_C3_DONE, "GPIO_C3_DONE");
gpio_request(GPIO_C3_CONFIG, "GPIO_C3_CONFIG");
gpio_direction_input(GPIO_C3_STATUS);
gpio_direction_input(GPIO_C3_DONE);
gpio_direction_output(GPIO_C3_CONFIG, 1);
@ -100,6 +89,7 @@ static void setup_gpio_eim(void)
static void setup_gpio_sups(void)
{
gpio_request(GPIO_SUPS_INT, "GPIO_SUPS_INT");
gpio_direction_input(GPIO_SUPS_INT);
static const int BLINK_INTERVALL = 50000;
@ -116,6 +106,16 @@ static void setup_gpio_sups(void)
static void setup_gpio_leds(void)
{
gpio_request(GPIO_LED_SD2_R, "GPIO_LED_SD2_R");
gpio_request(GPIO_LED_SD2_B, "GPIO_LED_SD2_B");
gpio_request(GPIO_LED_SD2_G, "GPIO_LED_SD2_G");
gpio_request(GPIO_LED_SD1_R, "GPIO_LED_SD1_R");
gpio_request(GPIO_LED_SD1_B, "GPIO_LED_SD1_B");
gpio_request(GPIO_LED_SD1_G, "GPIO_LED_SD1_G");
gpio_request(GPIO_LED_PWR_R, "GPIO_LED_PWR_R");
gpio_request(GPIO_LED_PWR_B, "GPIO_LED_PWR_B");
gpio_request(GPIO_LED_PWR_G, "GPIO_LED_PWR_G");
gpio_direction_output(GPIO_LED_SD2_R, 0);
gpio_direction_output(GPIO_LED_SD2_B, 0);
gpio_direction_output(GPIO_LED_SD2_G, 0);
@ -136,55 +136,6 @@ int board_ehci_hcd_init(int port)
}
#endif
#ifdef CONFIG_FSL_ESDHC
struct fsl_esdhc_cfg esdhc_cfg[2] = {
{MMC_SDHC1_BASE_ADDR},
{MMC_SDHC2_BASE_ADDR},
};
int board_mmc_getcd(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
int ret;
gpio_direction_input(GPIO_SD1_CD);
gpio_direction_input(GPIO_SD2_CD);
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
ret = !gpio_get_value(GPIO_SD1_CD);
else
ret = !gpio_get_value(GPIO_SD2_CD);
return ret;
}
int board_mmc_init(bd_t *bis)
{
u32 index;
int ret;
esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
esdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
for (index = 0; index < CONFIG_SYS_FSL_ESDHC_NUM; index++) {
switch (index) {
case 0:
break;
case 1:
break;
default:
printf("Warning: you configured more ESDHC controller(%d) as supported by the board(2)\n",
CONFIG_SYS_FSL_ESDHC_NUM);
return -EINVAL;
}
ret = fsl_esdhc_initialize(bis, &esdhc_cfg[index]);
if (ret)
return ret;
}
return 0;
}
#endif
static int power_init(void)
{
@ -212,29 +163,21 @@ static void clock_1GHz(void)
int board_early_init_f(void)
{
setup_gpio_leds();
setup_gpio_sups();
setup_gpio_eim();
setup_iomux_lcd();
return 0;
}
/*
* Do not overwrite the console
* Use always serial for U-Boot console
*/
int overwrite_console(void)
{
return 1;
}
int board_init(void)
{
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
mxc_set_sata_internal_clock();
setup_gpio_leds();
setup_gpio_sups();
setup_gpio_eim();
setup_iomux_lcd();
return 0;
}

View file

@ -8,41 +8,39 @@
*/
#include <common.h>
#include <linux/list.h>
#include <asm/gpio.h>
#include <asm/arch/iomux-mx53.h>
#include <linux/fb.h>
#include <ipu_pixfmt.h>
#include <asm/gpio.h>
#include <asm/mach-imx/video.h>
#define CX9020_DVI_PWD IMX_GPIO_NR(6, 1)
static struct fb_videomode const vga_640x480 = {
.name = "VESA_VGA_640x480",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721, /* picosecond (25.175 MHz) */
.left_margin = 40,
.right_margin = 60,
.upper_margin = 10,
.lower_margin = 10,
.hsync_len = 20,
.vsync_len = 10,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
};
struct display_info_t const displays[] = {{
.bus = -1,
.addr = 0,
.pixfmt = IPU_PIX_FMT_RGB24,
.detect = NULL,
.enable = NULL,
.mode = {
.name = "DVI",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721, /* picosecond (25.175 MHz) */
.left_margin = 40,
.right_margin = 60,
.upper_margin = 10,
.lower_margin = 10,
.hsync_len = 20,
.vsync_len = 10,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
} } };
size_t display_count = ARRAY_SIZE(displays);
void setup_iomux_lcd(void)
{
/* Turn on DVI_PWD */
imx_iomux_v3_setup_pad(MX53_PAD_CSI0_DAT15__GPIO6_1);
gpio_request(CX9020_DVI_PWD, "CX9020_DVI_PWD");
gpio_direction_output(CX9020_DVI_PWD, 1);
}
int board_video_skip(void)
{
const int ret = ipuv3_fb_init(&vga_640x480, 0, IPU_PIX_FMT_RGB24);
if (ret)
printf("VESA VG 640x480 cannot be configured: %d\n", ret);
return ret;
}

View file

@ -303,8 +303,12 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr)
{
int res;
int node_offset;
int splash_offset;
int splash_size;
const char *splash_file;
const void *internal_splash_data;
size_t internal_splash_size;
int external_splash_addr;
int external_splash_size;
bool is_splash_external = false;
struct image_header *img_header;
const u32 *fit_header;
u32 fit_size;
@ -335,36 +339,51 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr)
return -EINVAL;
}
node_offset = fit_image_get_node(fit_header, location->name);
/* Get the splash image node */
splash_file = env_get("splashfile");
if (!splash_file)
splash_file = SPLASH_SOURCE_DEFAULT_FILE_NAME;
node_offset = fit_image_get_node(fit_header, splash_file);
if (node_offset < 0) {
debug("Could not find splash image '%s' in FIT\n",
location->name);
splash_file);
return -ENOENT;
}
res = fit_image_get_data_offset(fit_header, node_offset,
&splash_offset);
if (res < 0) {
printf("Failed to load splash image (err=%d)\n", res);
return res;
/* Extract the splash data from FIT */
/* 1. Test if splash is in FIT internal data. */
if (!fit_image_get_data(fit_header, node_offset, &internal_splash_data, &internal_splash_size))
memmove((void *)bmp_load_addr, internal_splash_data, internal_splash_size);
/* 2. Test if splash is in FIT external data with fixed position. */
else if (!fit_image_get_data_position(fit_header, node_offset, &external_splash_addr))
is_splash_external = true;
/* 3. Test if splash is in FIT external data with offset. */
else if (!fit_image_get_data_offset(fit_header, node_offset, &external_splash_addr)) {
/* Align data offset to 4-byte boundary */
fit_size = ALIGN(fdt_totalsize(fit_header), 4);
/* External splash offset means the offset by end of FIT header */
external_splash_addr += location->offset + fit_size;
is_splash_external = true;
} else {
printf("Failed to get splash image from FIT\n");
return -ENODATA;
}
res = fit_image_get_data_size(fit_header, node_offset, &splash_size);
if (res < 0) {
printf("Failed to load splash image (err=%d)\n", res);
return res;
if (is_splash_external) {
res = fit_image_get_data_size(fit_header, node_offset, &external_splash_size);
if (res < 0) {
printf("Failed to get size of splash image (err=%d)\n", res);
return res;
}
/* Read in the splash data */
location->offset = external_splash_addr;
res = splash_storage_read_raw(location, bmp_load_addr, external_splash_size);
if (res < 0)
return res;
}
/* Align data offset to 4-byte boundrary */
fit_size = fdt_totalsize(fit_header);
fit_size = (fit_size + 3) & ~3;
/* Read in the splash data */
location->offset = (location->offset + fit_size + splash_offset);
res = splash_storage_read_raw(location, bmp_load_addr , splash_size);
if (res < 0)
return res;
return 0;
}
#endif /* CONFIG_FIT */

View file

@ -24,13 +24,14 @@ CONFIG_DEFAULT_DEVICE_TREE="imx53-cx9020"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_FPGA_ALTERA=y
CONFIG_FPGA_CYCLON2=y
CONFIG_DM=y
CONFIG_DM_MMC=y
CONFIG_DM_GPIO=y
CONFIG_FSL_ESDHC=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_IMX5=y
CONFIG_MXC_UART=y
CONFIG_DM_VIDEO=y
CONFIG_VIDEO_IPUV3=y
CONFIG_VIDEO=y
# CONFIG_VIDEO_SW_CURSOR is not set

View file

@ -4,13 +4,13 @@ CONFIG_SYS_TEXT_BASE=0x17800000
CONFIG_SPL_GPIO_SUPPORT=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_TARGET_MX6SABRESD=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_SPL_LIBDISK_SUPPORT=y
# CONFIG_SYS_MALLOC_F is not set
CONFIG_FIT=y
CONFIG_SPL_FIT_PRINT=y
CONFIG_SPL_LOAD_FIT=y
@ -63,6 +63,7 @@ CONFIG_OF_LIST="imx6q-sabresd imx6qp-sabresd imx6dl-sabresd"
CONFIG_MULTI_DTB_FIT=y
CONFIG_SPL_MULTI_DTB_FIT=y
CONFIG_SPL_OF_LIST="imx6dl-sabresd imx6q-sabresd imx6qp-sabresd"
CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_SPL_DM=y

View file

@ -26,6 +26,9 @@ screen data is loaded as a file. The name of the splash screen file can be
controlled with the environment variable "splashfile".
To enable loading the splash image from a FIT image, CONFIG_FIT must be
enabled. Struct splash_location field 'name' should match the splash image
name within the FIT and the FIT should start at the 'offset' field address in
the specified storage.
enabled. The FIT image has to start at the 'offset' field address in the
selected splash location. The name of splash image within the FIT shall be
specified by the environment variable "splashfile".
In case the environment variable "splashfile" is not defined the default name
'splash.bmp' will be used.

View file

@ -678,13 +678,14 @@ static int ipuv3_video_bind(struct udevice *dev)
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
(1 << LCD_MAX_LOG2_BPP) / 8;
(1 << VIDEO_BPP32) / 8;
return 0;
}
static const struct udevice_id ipuv3_video_ids[] = {
{ .compatible = "fsl,imx6q-ipu" },
{ .compatible = "fsl,imx53-ipu" },
{ }
};

View file

@ -529,6 +529,20 @@ int vidconsole_put_char(struct udevice *dev, char ch)
return 0;
}
int vidconsole_put_string(struct udevice *dev, const char *str)
{
const char *s;
int ret;
for (s = str; *s; s++) {
ret = vidconsole_put_char(dev, *s);
if (ret)
return ret;
}
return 0;
}
static void vidconsole_putc(struct stdio_dev *sdev, const char ch)
{
struct udevice *dev = sdev->priv;
@ -541,8 +555,7 @@ static void vidconsole_puts(struct stdio_dev *sdev, const char *s)
{
struct udevice *dev = sdev->priv;
while (*s)
vidconsole_put_char(dev, *s++);
vidconsole_put_string(dev, s);
video_sync(dev->parent, false);
}

View file

@ -159,11 +159,7 @@
#define CONFIG_SYS_MMC_ENV_DEV 0
/* Framebuffer and LCD */
#define CONFIG_IMX_VIDEO_SKIP
#define CONFIG_PREBOOT
#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_SPLASH_SCREEN
#define CONFIG_BMP_16BPP
#define CONFIG_VIDEO_LOGO
#endif /* __CONFIG_H */

View file

@ -214,6 +214,22 @@ int vidconsole_set_row(struct udevice *dev, uint row, int clr);
*/
int vidconsole_put_char(struct udevice *dev, char ch);
/**
* vidconsole_put_string() - Output a string to the current console position
*
* Outputs a string 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
* @str: String to write
* @return 0 if OK, -ve on error
*/
int vidconsole_put_string(struct udevice *dev, const char *str);
/**
* vidconsole_position_cursor() - Move the text cursor
*

View file

@ -97,14 +97,6 @@ static int select_vidconsole(struct unit_test_state *uts, const char *drv_name)
return 0;
}
static void vidconsole_put_string(struct udevice *dev, const char *str)
{
const char *s;
for (s = str; *s; s++)
vidconsole_put_char(dev, *s);
}
/* Test text output works on the video console */
static int dm_test_video_text(struct unit_test_state *uts)
{