mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-10-02 09:30:43 +09:00
- dcu and imx7 DM_VIDEO conversion
- lb070wv8 compatible in simple_panel driver - bmp_logo improvements for DM_VIDEO - EDID updates to filter supported modes - meson_dw_hdmi: support EDID mode filtering - dw_hdmi: support ddc-i2c-bus phandle for external I2C masters - fix rpi crash when firmware doesn't report connected display -----BEGIN PGP SIGNATURE----- iGwEABECACwWIQSC4hxrSoIUVfFO0kRM6ATMmsalXAUCXT6z3g4cYWd1c3RAZGVu eC5kZQAKCRBM6ATMmsalXNhfAJ9r0ewu4sKAiLZl7fcOoYYjgz30TACeIrchuxwH x9SiZYFntOLL0trK/O0= =ZsD5 -----END PGP SIGNATURE----- Merge tag 'video-for-2019.10' of https://gitlab.denx.de/u-boot/custodians/u-boot-video - dcu and imx7 DM_VIDEO conversion - lb070wv8 compatible in simple_panel driver - bmp_logo improvements for DM_VIDEO - EDID updates to filter supported modes - meson_dw_hdmi: support EDID mode filtering - dw_hdmi: support ddc-i2c-bus phandle for external I2C masters - fix rpi crash when firmware doesn't report connected display
This commit is contained in:
commit
ad4a699cfe
@ -12,8 +12,10 @@
|
||||
compatible = "toradex,colibri-imx6ull", "fsl,imx6ull";
|
||||
|
||||
aliases {
|
||||
u-boot,dm-pre-reloc;
|
||||
mmc0 = &usdhc1;
|
||||
usb0 = &usbotg1; /* required for ums */
|
||||
display0 = &lcdif;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@ -156,6 +158,36 @@
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_lcdif_dat
|
||||
&pinctrl_lcdif_ctrl>;
|
||||
status = "okay";
|
||||
display = <&display0>;
|
||||
u-boot,dm-pre-reloc;
|
||||
|
||||
display0: display0 {
|
||||
bits-per-pixel = <18>;
|
||||
bus-width = <24>;
|
||||
status = "okay";
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing_vga>;
|
||||
timing_vga: 640x480 {
|
||||
u-boot,dm-pre-reloc;
|
||||
clock-frequency = <25175000>;
|
||||
hactive = <640>;
|
||||
vactive = <480>;
|
||||
hback-porch = <48>;
|
||||
hfront-porch = <16>;
|
||||
vback-porch = <33>;
|
||||
vfront-porch = <10>;
|
||||
hsync-len = <96>;
|
||||
vsync-len = <2>;
|
||||
|
||||
de-active = <1>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* PWM <A> */
|
||||
|
@ -113,29 +113,34 @@
|
||||
};
|
||||
|
||||
&lcdif {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
display = <&display0>;
|
||||
u-boot,dm-pre-reloc;
|
||||
|
||||
display-timings {
|
||||
native-mode = <&timing_vga>;
|
||||
display0: display0 {
|
||||
bits-per-pixel = <18>;
|
||||
bus-width = <24>;
|
||||
status = "okay";
|
||||
|
||||
/* Standard VGA timing */
|
||||
timing_vga: 640x480 {
|
||||
u-boot,dm-pre-reloc;
|
||||
clock-frequency = <25175000>;
|
||||
hactive = <640>;
|
||||
vactive = <480>;
|
||||
hback-porch = <48>;
|
||||
hfront-porch = <16>;
|
||||
vback-porch = <33>;
|
||||
vfront-porch = <10>;
|
||||
hsync-len = <96>;
|
||||
vsync-len = <2>;
|
||||
display-timings {
|
||||
native-mode = <&timing_vga>;
|
||||
timing_vga: 640x480 {
|
||||
u-boot,dm-pre-reloc;
|
||||
clock-frequency = <25175000>;
|
||||
hactive = <640>;
|
||||
vactive = <480>;
|
||||
hback-porch = <48>;
|
||||
hfront-porch = <16>;
|
||||
vback-porch = <33>;
|
||||
vfront-porch = <10>;
|
||||
hsync-len = <96>;
|
||||
vsync-len = <2>;
|
||||
|
||||
de-active = <1>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
de-active = <1>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
pixelclk-active = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -21,3 +21,7 @@
|
||||
&uart0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&dcu0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
aliases {
|
||||
usb0 = &ehci0; /* required for ums */
|
||||
display1 = &dcu0;
|
||||
};
|
||||
|
||||
reg_usbh_vbus: regulator-usbh-vbus {
|
||||
@ -241,3 +242,7 @@
|
||||
pinctrl-0 = <&pinctrl_uart0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&dcu0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -145,6 +145,12 @@
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
dcu0: dcu@40058000 {
|
||||
compatible = "fsl,vf610-dcu";
|
||||
reg = <0x40058000 0x1200>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ehci0: ehci@40034000 {
|
||||
compatible = "fsl,vf610-usb";
|
||||
reg = <0x40034000 0x800>;
|
||||
|
@ -554,7 +554,7 @@ const struct boot_mode soc_boot_modes[] = {
|
||||
void reset_misc(void)
|
||||
{
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#ifdef CONFIG_VIDEO_MXS
|
||||
#if defined(CONFIG_VIDEO_MXS) && !defined(CONFIG_DM_VIDEO)
|
||||
lcdif_power_down();
|
||||
#endif
|
||||
#endif
|
||||
|
@ -23,9 +23,10 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
||||
return div;
|
||||
}
|
||||
|
||||
int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
const char *port,
|
||||
struct fb_videomode *dcu_fb_videomode)
|
||||
int platform_dcu_init(struct fb_info *fbinfo,
|
||||
unsigned int xres, unsigned int yres,
|
||||
const char *port,
|
||||
struct fb_videomode *dcu_fb_videomode)
|
||||
{
|
||||
const char *name;
|
||||
unsigned int pixel_format;
|
||||
@ -40,7 +41,7 @@ int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
|
||||
|
||||
pixel_format = 32;
|
||||
fsl_dcu_init(xres, yres, pixel_format);
|
||||
fsl_dcu_init(fbinfo, xres, yres, pixel_format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -39,7 +39,9 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
||||
return div;
|
||||
}
|
||||
|
||||
int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
int platform_dcu_init(struct fb_info *fbinfo,
|
||||
unsigned int xres,
|
||||
unsigned int yres,
|
||||
const char *port,
|
||||
struct fb_videomode *dcu_fb_videomode)
|
||||
{
|
||||
@ -85,7 +87,7 @@ int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
|
||||
|
||||
pixel_format = 32;
|
||||
fsl_dcu_init(xres, yres, pixel_format);
|
||||
fsl_dcu_init(fbinfo, xres, yres, pixel_format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
||||
return div;
|
||||
}
|
||||
|
||||
int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
int platform_dcu_init(struct fb_info *fbinfo,
|
||||
unsigned int xres, unsigned int yres,
|
||||
const char *port,
|
||||
struct fb_videomode *dcu_fb_videomode)
|
||||
{
|
||||
@ -40,7 +41,7 @@ int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
|
||||
|
||||
pixel_format = 32;
|
||||
fsl_dcu_init(xres, yres, pixel_format);
|
||||
fsl_dcu_init(fbinfo, xres, yres, pixel_format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -430,7 +430,9 @@ int checkboard(void)
|
||||
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
#ifndef CONFIG_DM_VIDEO
|
||||
int ret = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
||||
static const struct node_info nodes[] = {
|
||||
{ "fsl,vf610-nfc", MTD_DEV_TYPE_NAND, }, /* NAND flash */
|
||||
@ -440,7 +442,7 @@ int ft_board_setup(void *blob, bd_t *bd)
|
||||
puts(" Updating MTD partitions...\n");
|
||||
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
|
||||
#endif
|
||||
#ifdef CONFIG_VIDEO_FSL_DCU_FB
|
||||
#if defined(CONFIG_VIDEO_FSL_DCU_FB) && !defined(CONFIG_DM_VIDEO)
|
||||
ret = fsl_dcu_fixedfb_setup(blob);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -26,11 +26,13 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
||||
return div;
|
||||
}
|
||||
|
||||
int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
int platform_dcu_init(struct fb_info *fbinfo,
|
||||
unsigned int xres,
|
||||
unsigned int yres,
|
||||
const char *port,
|
||||
struct fb_videomode *dcu_fb_videomode)
|
||||
{
|
||||
fsl_dcu_init(xres, yres, 32);
|
||||
fsl_dcu_init(fbinfo, xres, yres, 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -168,8 +168,12 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info)
|
||||
return false;
|
||||
}
|
||||
|
||||
int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
|
||||
int *panel_bits_per_colourp)
|
||||
int edid_get_timing_validate(u8 *buf, int buf_size,
|
||||
struct display_timing *timing,
|
||||
int *panel_bits_per_colourp,
|
||||
bool (*mode_valid)(void *priv,
|
||||
const struct display_timing *timing),
|
||||
void *mode_valid_priv)
|
||||
{
|
||||
struct edid1_info *edid = (struct edid1_info *)buf;
|
||||
bool timing_done;
|
||||
@ -193,7 +197,11 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
|
||||
desc = &edid->monitor_details.descriptor[i];
|
||||
if (desc->zero_flag_1 != 0) {
|
||||
decode_timing((u8 *)desc, timing);
|
||||
timing_done = true;
|
||||
if (mode_valid)
|
||||
timing_done = mode_valid(mode_valid_priv,
|
||||
timing);
|
||||
else
|
||||
timing_done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -225,6 +233,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
|
||||
int *panel_bits_per_colourp)
|
||||
{
|
||||
return edid_get_timing_validate(buf, buf_size, timing,
|
||||
panel_bits_per_colourp, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Snip the tailing whitespace/return of a string.
|
||||
*
|
||||
|
@ -78,6 +78,6 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
|
||||
CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
|
||||
CONFIG_CI_UDC=y
|
||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_DM_VIDEO=y
|
||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
CONFIG_FDT_FIXUP_PARTITIONS=y
|
||||
|
@ -74,6 +74,6 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
|
||||
CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
|
||||
CONFIG_CI_UDC=y
|
||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_DM_VIDEO=y
|
||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
CONFIG_FDT_FIXUP_PARTITIONS=y
|
||||
|
@ -89,7 +89,7 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
|
||||
CONFIG_CI_UDC=y
|
||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||
CONFIG_VIDEO_FSL_DCU_FB=y
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_DM_VIDEO=y
|
||||
CONFIG_SYS_CONSOLE_FG_COL=0x00
|
||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
CONFIG_FDT_FIXUP_PARTITIONS=y
|
||||
|
@ -484,7 +484,7 @@ config VIDEO_IVYBRIDGE_IGD
|
||||
|
||||
config VIDEO_FSL_DCU_FB
|
||||
bool "Enable Freescale Display Control Unit"
|
||||
depends on VIDEO
|
||||
depends on VIDEO || DM_VIDEO
|
||||
help
|
||||
This enables support for Freescale Display Control Unit (DCU4)
|
||||
module found on Freescale Vybrid and QorIQ family of SoCs.
|
||||
|
@ -19,13 +19,15 @@ static int bcm2835_video_probe(struct udevice *dev)
|
||||
|
||||
debug("bcm2835: Query resolution...\n");
|
||||
ret = bcm2835_get_video_size(&w, &h);
|
||||
if (ret)
|
||||
if (ret || w == 0 || h == 0)
|
||||
return -EIO;
|
||||
|
||||
debug("bcm2835: Setting up display for %d x %d\n", w, h);
|
||||
ret = bcm2835_set_video_params(&w, &h, 32, BCM2835_MBOX_PIXEL_ORDER_RGB,
|
||||
BCM2835_MBOX_ALPHA_MODE_IGNORED,
|
||||
&fb_base, &fb_size, &pitch);
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
debug("bcm2835: Final resolution is %d x %d\n", w, h);
|
||||
|
||||
|
@ -37,6 +37,17 @@ int display_enable(struct udevice *dev, int panel_bpp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool display_mode_valid(void *priv, const struct display_timing *timing)
|
||||
{
|
||||
struct udevice *dev = priv;
|
||||
struct dm_display_ops *ops = display_get_ops(dev);
|
||||
|
||||
if (ops && ops->mode_valid)
|
||||
return ops->mode_valid(dev, timing);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int display_read_timing(struct udevice *dev, struct display_timing *timing)
|
||||
{
|
||||
struct dm_display_ops *ops = display_get_ops(dev);
|
||||
@ -53,7 +64,9 @@ int display_read_timing(struct udevice *dev, struct display_timing *timing)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return edid_get_timing(buf, ret, timing, &panel_bits_per_colour);
|
||||
return edid_get_timing_validate(buf, ret, timing,
|
||||
&panel_bits_per_colour,
|
||||
display_mode_valid, dev);
|
||||
}
|
||||
|
||||
bool display_in_use(struct udevice *dev)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <asm/io.h>
|
||||
#include <i2c.h>
|
||||
#include <media_bus_format.h>
|
||||
#include "dw_hdmi.h"
|
||||
|
||||
@ -812,6 +813,18 @@ static int hdmi_read_edid(struct dw_hdmi *hdmi, int block, u8 *buff)
|
||||
u32 trytime = 5;
|
||||
u32 n;
|
||||
|
||||
if (CONFIG_IS_ENABLED(DM_I2C) && hdmi->ddc_bus) {
|
||||
struct udevice *chip;
|
||||
|
||||
edid_read_err = i2c_get_chip(hdmi->ddc_bus,
|
||||
HDMI_I2CM_SLAVE_DDC_ADDR,
|
||||
1, &chip);
|
||||
if (edid_read_err)
|
||||
return edid_read_err;
|
||||
|
||||
return dm_i2c_read(chip, shift, buff, HDMI_EDID_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* set ddc i2c clk which devided from ddc_clk to 100khz */
|
||||
hdmi_write(hdmi, hdmi->i2c_clk_high, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
|
||||
hdmi_write(hdmi, hdmi->i2c_clk_low, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
|
||||
|
@ -1,16 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
* Copyright 2019 Toradex AG
|
||||
*
|
||||
* FSL DCU Framebuffer driver
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdt_support.h>
|
||||
#include <fsl_dcu_fb.h>
|
||||
#include <linux/fb.h>
|
||||
#include <malloc.h>
|
||||
#include <video.h>
|
||||
#include <video_fb.h>
|
||||
#include "videomodes.h"
|
||||
|
||||
@ -218,8 +221,6 @@ struct dcu_reg {
|
||||
u32 ctrldescl[DCU_LAYER_MAX_NUM][16];
|
||||
};
|
||||
|
||||
static struct fb_info info;
|
||||
|
||||
static void reset_total_layers(void)
|
||||
{
|
||||
struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
|
||||
@ -240,20 +241,22 @@ static void reset_total_layers(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int layer_ctrldesc_init(int index, u32 pixel_format)
|
||||
static int layer_ctrldesc_init(struct fb_info fbinfo,
|
||||
int index, u32 pixel_format)
|
||||
{
|
||||
struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
|
||||
unsigned int bpp = BPP_24_RGB888;
|
||||
|
||||
dcu_write32(®s->ctrldescl[index][0],
|
||||
DCU_CTRLDESCLN_1_HEIGHT(info.var.yres) |
|
||||
DCU_CTRLDESCLN_1_WIDTH(info.var.xres));
|
||||
DCU_CTRLDESCLN_1_HEIGHT(fbinfo.var.yres) |
|
||||
DCU_CTRLDESCLN_1_WIDTH(fbinfo.var.xres));
|
||||
|
||||
dcu_write32(®s->ctrldescl[index][1],
|
||||
DCU_CTRLDESCLN_2_POSY(0) |
|
||||
DCU_CTRLDESCLN_2_POSX(0));
|
||||
|
||||
dcu_write32(®s->ctrldescl[index][2], (unsigned int)info.screen_base);
|
||||
dcu_write32(®s->ctrldescl[index][2],
|
||||
(unsigned int)fbinfo.screen_base);
|
||||
|
||||
switch (pixel_format) {
|
||||
case 16:
|
||||
@ -294,42 +297,46 @@ static int layer_ctrldesc_init(int index, u32 pixel_format)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsl_dcu_init(unsigned int xres, unsigned int yres,
|
||||
unsigned int pixel_format)
|
||||
int fsl_dcu_init(struct fb_info *fbinfo, unsigned int xres,
|
||||
unsigned int yres, unsigned int pixel_format)
|
||||
{
|
||||
struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
|
||||
unsigned int div, mode;
|
||||
/*
|
||||
* When DM_VIDEO is enabled reservation of framebuffer is done
|
||||
* in advance during bind() call.
|
||||
*/
|
||||
#if !CONFIG_IS_ENABLED(DM_VIDEO)
|
||||
fbinfo->screen_size = fbinfo->var.xres * fbinfo->var.yres *
|
||||
(fbinfo->var.bits_per_pixel / 8);
|
||||
|
||||
info.screen_size =
|
||||
info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
|
||||
|
||||
if (info.screen_size > CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB) {
|
||||
info.screen_size = 0;
|
||||
if (fbinfo->screen_size > CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB) {
|
||||
fbinfo->screen_size = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Reserve framebuffer at the end of memory */
|
||||
gd->fb_base = gd->bd->bi_dram[0].start +
|
||||
gd->bd->bi_dram[0].size - info.screen_size;
|
||||
info.screen_base = (char *)gd->fb_base;
|
||||
gd->bd->bi_dram[0].size - fbinfo->screen_size;
|
||||
fbinfo->screen_base = (char *)gd->fb_base;
|
||||
|
||||
memset(info.screen_base, 0, info.screen_size);
|
||||
memset(fbinfo->screen_base, 0, fbinfo->screen_size);
|
||||
#endif
|
||||
|
||||
reset_total_layers();
|
||||
|
||||
dcu_write32(®s->disp_size,
|
||||
DCU_DISP_SIZE_DELTA_Y(info.var.yres) |
|
||||
DCU_DISP_SIZE_DELTA_X(info.var.xres / 16));
|
||||
DCU_DISP_SIZE_DELTA_Y(fbinfo->var.yres) |
|
||||
DCU_DISP_SIZE_DELTA_X(fbinfo->var.xres / 16));
|
||||
|
||||
dcu_write32(®s->hsyn_para,
|
||||
DCU_HSYN_PARA_BP(info.var.left_margin) |
|
||||
DCU_HSYN_PARA_PW(info.var.hsync_len) |
|
||||
DCU_HSYN_PARA_FP(info.var.right_margin));
|
||||
DCU_HSYN_PARA_BP(fbinfo->var.left_margin) |
|
||||
DCU_HSYN_PARA_PW(fbinfo->var.hsync_len) |
|
||||
DCU_HSYN_PARA_FP(fbinfo->var.right_margin));
|
||||
|
||||
dcu_write32(®s->vsyn_para,
|
||||
DCU_VSYN_PARA_BP(info.var.upper_margin) |
|
||||
DCU_VSYN_PARA_PW(info.var.vsync_len) |
|
||||
DCU_VSYN_PARA_FP(info.var.lower_margin));
|
||||
DCU_VSYN_PARA_BP(fbinfo->var.upper_margin) |
|
||||
DCU_VSYN_PARA_PW(fbinfo->var.vsync_len) |
|
||||
DCU_VSYN_PARA_FP(fbinfo->var.lower_margin));
|
||||
|
||||
dcu_write32(®s->synpol,
|
||||
DCU_SYN_POL_INV_PXCK_FALL |
|
||||
@ -352,9 +359,9 @@ int fsl_dcu_init(unsigned int xres, unsigned int yres,
|
||||
mode = dcu_read32(®s->mode);
|
||||
dcu_write32(®s->mode, mode | DCU_MODE_NORMAL);
|
||||
|
||||
layer_ctrldesc_init(0, pixel_format);
|
||||
layer_ctrldesc_init(*fbinfo, 0, pixel_format);
|
||||
|
||||
div = dcu_set_pixel_clock(info.var.pixclock);
|
||||
div = dcu_set_pixel_clock(fbinfo->var.pixclock);
|
||||
dcu_write32(®s->div_ratio, (div - 1));
|
||||
|
||||
dcu_write32(®s->update_mode, DCU_UPDATE_MODE_READREG);
|
||||
@ -367,24 +374,26 @@ ulong board_get_usable_ram_top(ulong total_size)
|
||||
return gd->ram_top - CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB;
|
||||
}
|
||||
|
||||
void *video_hw_init(void)
|
||||
int fsl_probe_common(struct fb_info *fbinfo, unsigned int *win_x,
|
||||
unsigned int *win_y)
|
||||
{
|
||||
static GraphicDevice ctfb;
|
||||
const char *options;
|
||||
unsigned int depth = 0, freq = 0;
|
||||
|
||||
struct fb_videomode *fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
|
||||
|
||||
if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq,
|
||||
if (!video_get_video_mode(win_x, win_y, &depth, &freq,
|
||||
&options))
|
||||
return NULL;
|
||||
return -EINVAL;
|
||||
|
||||
/* Find the monitor port, which is a required option */
|
||||
if (!options)
|
||||
return NULL;
|
||||
if (strncmp(options, "monitor=", 8) != 0)
|
||||
return NULL;
|
||||
return -EINVAL;
|
||||
|
||||
switch (RESOLUTION(ctfb.winSizeX, ctfb.winSizeY)) {
|
||||
if (strncmp(options, "monitor=", 8) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (RESOLUTION(*win_x, *win_y)) {
|
||||
case RESOLUTION(480, 272):
|
||||
fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
|
||||
break;
|
||||
@ -402,39 +411,31 @@ void *video_hw_init(void)
|
||||
break;
|
||||
default:
|
||||
printf("unsupported resolution %ux%u\n",
|
||||
ctfb.winSizeX, ctfb.winSizeY);
|
||||
*win_x, *win_y);
|
||||
}
|
||||
|
||||
info.var.xres = fsl_dcu_mode_db->xres;
|
||||
info.var.yres = fsl_dcu_mode_db->yres;
|
||||
info.var.bits_per_pixel = 32;
|
||||
info.var.pixclock = fsl_dcu_mode_db->pixclock;
|
||||
info.var.left_margin = fsl_dcu_mode_db->left_margin;
|
||||
info.var.right_margin = fsl_dcu_mode_db->right_margin;
|
||||
info.var.upper_margin = fsl_dcu_mode_db->upper_margin;
|
||||
info.var.lower_margin = fsl_dcu_mode_db->lower_margin;
|
||||
info.var.hsync_len = fsl_dcu_mode_db->hsync_len;
|
||||
info.var.vsync_len = fsl_dcu_mode_db->vsync_len;
|
||||
info.var.sync = fsl_dcu_mode_db->sync;
|
||||
info.var.vmode = fsl_dcu_mode_db->vmode;
|
||||
info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8;
|
||||
fbinfo->var.xres = fsl_dcu_mode_db->xres;
|
||||
fbinfo->var.yres = fsl_dcu_mode_db->yres;
|
||||
fbinfo->var.bits_per_pixel = 32;
|
||||
fbinfo->var.pixclock = fsl_dcu_mode_db->pixclock;
|
||||
fbinfo->var.left_margin = fsl_dcu_mode_db->left_margin;
|
||||
fbinfo->var.right_margin = fsl_dcu_mode_db->right_margin;
|
||||
fbinfo->var.upper_margin = fsl_dcu_mode_db->upper_margin;
|
||||
fbinfo->var.lower_margin = fsl_dcu_mode_db->lower_margin;
|
||||
fbinfo->var.hsync_len = fsl_dcu_mode_db->hsync_len;
|
||||
fbinfo->var.vsync_len = fsl_dcu_mode_db->vsync_len;
|
||||
fbinfo->var.sync = fsl_dcu_mode_db->sync;
|
||||
fbinfo->var.vmode = fsl_dcu_mode_db->vmode;
|
||||
fbinfo->fix.line_length = fbinfo->var.xres *
|
||||
fbinfo->var.bits_per_pixel / 8;
|
||||
|
||||
if (platform_dcu_init(ctfb.winSizeX, ctfb.winSizeY,
|
||||
options + 8, fsl_dcu_mode_db) < 0)
|
||||
return NULL;
|
||||
|
||||
ctfb.frameAdrs = (unsigned int)info.screen_base;
|
||||
ctfb.plnSizeX = ctfb.winSizeX;
|
||||
ctfb.plnSizeY = ctfb.winSizeY;
|
||||
|
||||
ctfb.gdfBytesPP = 4;
|
||||
ctfb.gdfIndex = GDF_32BIT_X888RGB;
|
||||
|
||||
ctfb.memSize = info.screen_size;
|
||||
|
||||
return &ctfb;
|
||||
return platform_dcu_init(fbinfo, *win_x, *win_y,
|
||||
options + 8, fsl_dcu_mode_db);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_VIDEO
|
||||
static struct fb_info info;
|
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||
int fsl_dcu_fixedfb_setup(void *blob)
|
||||
{
|
||||
@ -457,3 +458,89 @@ int fsl_dcu_fixedfb_setup(void *blob)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *video_hw_init(void)
|
||||
{
|
||||
static GraphicDevice ctfb;
|
||||
|
||||
if (fsl_probe_common(&info, &ctfb.winSizeX, &ctfb.winSizeY) < 0)
|
||||
return NULL;
|
||||
|
||||
ctfb.frameAdrs = (unsigned int)info.screen_base;
|
||||
ctfb.plnSizeX = ctfb.winSizeX;
|
||||
ctfb.plnSizeY = ctfb.winSizeY;
|
||||
|
||||
ctfb.gdfBytesPP = 4;
|
||||
ctfb.gdfIndex = GDF_32BIT_X888RGB;
|
||||
|
||||
ctfb.memSize = info.screen_size;
|
||||
|
||||
return &ctfb;
|
||||
}
|
||||
|
||||
#else /* ifndef CONFIG_DM_VIDEO */
|
||||
|
||||
static int fsl_dcu_video_probe(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct fb_info fbinfo = { 0 };
|
||||
unsigned int win_x;
|
||||
unsigned int win_y;
|
||||
u32 fb_start, fb_end;
|
||||
int ret = 0;
|
||||
|
||||
fb_start = plat->base & ~(MMU_SECTION_SIZE - 1);
|
||||
fb_end = plat->base + plat->size;
|
||||
fb_end = ALIGN(fb_end, 1 << MMU_SECTION_SHIFT);
|
||||
|
||||
fbinfo.screen_base = (char *)fb_start;
|
||||
fbinfo.screen_size = plat->size;
|
||||
|
||||
ret = fsl_probe_common(&fbinfo, &win_x, &win_y);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
uc_priv->bpix = VIDEO_BPP32;
|
||||
uc_priv->xsize = win_x;
|
||||
uc_priv->ysize = win_y;
|
||||
|
||||
/* Enable dcache for the frame buffer */
|
||||
mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start,
|
||||
DCACHE_WRITEBACK);
|
||||
video_set_flush_dcache(dev, true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsl_dcu_video_bind(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
unsigned int win_x;
|
||||
unsigned int win_y;
|
||||
unsigned int depth = 0, freq = 0;
|
||||
const char *options;
|
||||
int ret = 0;
|
||||
|
||||
ret = video_get_video_mode(&win_x, &win_y, &depth, &freq, &options);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
plat->size = win_x * win_y * 32;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id fsl_dcu_video_ids[] = {
|
||||
{ .compatible = "fsl,vf610-dcu" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(fsl_dcu_video) = {
|
||||
.name = "fsl_dcu_video",
|
||||
.id = UCLASS_VIDEO,
|
||||
.of_match = fsl_dcu_video_ids,
|
||||
.bind = fsl_dcu_video_bind,
|
||||
.probe = fsl_dcu_video_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
#endif /* ifndef CONFIG_DM_VIDEO */
|
||||
|
@ -375,6 +375,9 @@ static int meson_dw_hdmi_probe(struct udevice *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
|
||||
&priv->hdmi.ddc_bus);
|
||||
|
||||
ret = reset_get_bulk(dev, &resets);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -426,9 +429,16 @@ static int meson_dw_hdmi_probe(struct udevice *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool meson_dw_hdmi_mode_valid(struct udevice *dev,
|
||||
const struct display_timing *timing)
|
||||
{
|
||||
return meson_venc_hdmi_supported_mode(timing);
|
||||
}
|
||||
|
||||
static const struct dm_display_ops meson_dw_hdmi_ops = {
|
||||
.read_edid = meson_dw_hdmi_read_edid,
|
||||
.enable = meson_dw_hdmi_enable,
|
||||
.mode_valid = meson_dw_hdmi_mode_valid,
|
||||
};
|
||||
|
||||
static const struct udevice_id meson_dw_hdmi_ids[] = {
|
||||
|
@ -271,6 +271,42 @@ dealloc_fb:
|
||||
}
|
||||
#else /* ifndef CONFIG_DM_VIDEO */
|
||||
|
||||
static int mxs_of_get_timings(struct udevice *dev,
|
||||
struct display_timing *timings,
|
||||
u32 *bpp)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 display_phandle;
|
||||
ofnode display_node;
|
||||
|
||||
ret = ofnode_read_u32(dev_ofnode(dev), "display", &display_phandle);
|
||||
if (ret) {
|
||||
dev_err(dev, "required display property isn't provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
display_node = ofnode_get_by_phandle(display_phandle);
|
||||
if (!ofnode_valid(display_node)) {
|
||||
dev_err(dev, "failed to find display subnode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ofnode_read_u32(display_node, "bits-per-pixel", bpp);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"required bits-per-pixel property isn't provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ofnode_decode_display_timing(display_node, 0, timings);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get any display timings\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxs_video_probe(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
@ -278,18 +314,16 @@ static int mxs_video_probe(struct udevice *dev)
|
||||
|
||||
struct ctfb_res_modes mode;
|
||||
struct display_timing timings;
|
||||
int bpp = -1;
|
||||
u32 bpp = 0;
|
||||
u32 fb_start, fb_end;
|
||||
int ret;
|
||||
|
||||
debug("%s() plat: base 0x%lx, size 0x%x\n",
|
||||
__func__, plat->base, plat->size);
|
||||
|
||||
ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, &timings);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get any display timings\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = mxs_of_get_timings(dev, &timings, &bpp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mode.xres = timings.hactive.typ;
|
||||
mode.yres = timings.vactive.typ;
|
||||
@ -301,13 +335,12 @@ static int mxs_video_probe(struct udevice *dev)
|
||||
mode.vsync_len = timings.vsync_len.typ;
|
||||
mode.pixclock = HZ2PS(timings.pixelclock.typ);
|
||||
|
||||
bpp = BITS_PP;
|
||||
|
||||
ret = mxs_probe_common(&mode, bpp, plat->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (bpp) {
|
||||
case 32:
|
||||
case 24:
|
||||
case 18:
|
||||
uc_priv->bpix = VIDEO_BPP32;
|
||||
@ -341,15 +374,32 @@ static int mxs_video_bind(struct udevice *dev)
|
||||
{
|
||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
struct display_timing timings;
|
||||
u32 bpp = 0;
|
||||
u32 bytes_pp = 0;
|
||||
int ret;
|
||||
|
||||
ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, &timings);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get any display timings\n");
|
||||
ret = mxs_of_get_timings(dev, &timings, &bpp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (bpp) {
|
||||
case 32:
|
||||
case 24:
|
||||
case 18:
|
||||
bytes_pp = 4;
|
||||
break;
|
||||
case 16:
|
||||
bytes_pp = 2;
|
||||
break;
|
||||
case 8:
|
||||
bytes_pp = 1;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "invalid bpp specified (bpp = %i)\n", bpp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
plat->size = timings.hactive.typ * timings.vactive.typ * BYTES_PP;
|
||||
plat->size = timings.hactive.typ * timings.vactive.typ * bytes_pp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -93,6 +93,9 @@ int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
|
||||
|
||||
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
|
||||
uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
|
||||
&hdmi->ddc_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,7 @@ static const struct udevice_id simple_panel_ids[] = {
|
||||
{ .compatible = "auo,b133xtn01" },
|
||||
{ .compatible = "auo,b116xw03" },
|
||||
{ .compatible = "auo,b133htn01" },
|
||||
{ .compatible = "lg,lb070wv8" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -373,6 +373,9 @@ static int sunxi_dw_hdmi_probe(struct udevice *dev)
|
||||
priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg;
|
||||
priv->mux = uc_plat->source_id;
|
||||
|
||||
uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
|
||||
&priv->hdmi.ddc_bus);
|
||||
|
||||
dw_hdmi_init(&priv->hdmi);
|
||||
|
||||
return 0;
|
||||
|
@ -170,7 +170,7 @@
|
||||
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_16M
|
||||
#define DFU_DEFAULT_POLL_TIMEOUT 300
|
||||
|
||||
#ifdef CONFIG_VIDEO
|
||||
#if defined(CONFIG_VIDEO) || defined(CONFIG_DM_VIDEO)
|
||||
#define CONFIG_VIDEO_MXS
|
||||
#define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
|
||||
#define CONFIG_VIDEO_LOGO
|
||||
|
@ -80,6 +80,16 @@ struct dm_display_ops {
|
||||
*/
|
||||
int (*enable)(struct udevice *dev, int panel_bpp,
|
||||
const struct display_timing *timing);
|
||||
|
||||
/**
|
||||
* mode_valid() - Check if mode is supported
|
||||
*
|
||||
* @dev: Device to enable
|
||||
* @timing: Display timings
|
||||
* @return true if supported, false if not
|
||||
*/
|
||||
bool (*mode_valid)(struct udevice *dev,
|
||||
const struct display_timing *timing);
|
||||
};
|
||||
|
||||
#define display_get_ops(dev) ((struct dm_display_ops *)(dev)->driver->ops)
|
||||
|
@ -542,6 +542,7 @@ struct dw_hdmi {
|
||||
u8 i2c_clk_low;
|
||||
u8 reg_io_width;
|
||||
struct hdmi_data_info hdmi_data;
|
||||
struct udevice *ddc_bus;
|
||||
|
||||
int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock);
|
||||
void (*write_reg)(struct dw_hdmi *hdmi, u8 val, int offset);
|
||||
|
@ -306,6 +306,28 @@ int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin,
|
||||
|
||||
struct display_timing;
|
||||
|
||||
/**
|
||||
* edid_get_timing_validate() - Get basic digital display parameters with
|
||||
* mode selection callback
|
||||
*
|
||||
* @param buf Buffer containing EDID data
|
||||
* @param buf_size Size of buffer in bytes
|
||||
* @param timing Place to put preferring timing information
|
||||
* @param panel_bits_per_colourp Place to put the number of bits per
|
||||
* colour supported by the panel. This will be set to
|
||||
* -1 if not available
|
||||
* @param mode_valid Callback validating mode, returning true is mode is
|
||||
* supported, false otherwise.
|
||||
* @parem valid_priv Pointer to private data for mode_valid callback
|
||||
* @return 0 if timings are OK, -ve on error
|
||||
*/
|
||||
int edid_get_timing_validate(u8 *buf, int buf_size,
|
||||
struct display_timing *timing,
|
||||
int *panel_bits_per_colourp,
|
||||
bool (*mode_valid)(void *priv,
|
||||
const struct display_timing *timing),
|
||||
void *mode_valid_priv);
|
||||
|
||||
/**
|
||||
* edid_get_timing() - Get basic digital display parameters
|
||||
*
|
||||
|
@ -6,11 +6,17 @@
|
||||
*/
|
||||
#include <linux/fb.h>
|
||||
|
||||
int fsl_dcu_init(unsigned int xres, unsigned int yres,
|
||||
int fsl_dcu_init(struct fb_info *fbinfo,
|
||||
unsigned int xres,
|
||||
unsigned int yres,
|
||||
unsigned int pixel_format);
|
||||
|
||||
int fsl_dcu_fixedfb_setup(void *blob);
|
||||
|
||||
/* Prototypes for external board-specific functions */
|
||||
int platform_dcu_init(unsigned int xres, unsigned int yres,
|
||||
const char *port, struct fb_videomode *dcu_fb_videomode);
|
||||
int platform_dcu_init(struct fb_info *fbinfo,
|
||||
unsigned int xres,
|
||||
unsigned int yres,
|
||||
const char *port,
|
||||
struct fb_videomode *dcu_fb_videomode);
|
||||
unsigned int dcu_set_pixel_clock(unsigned int pixclock);
|
||||
|
@ -269,8 +269,14 @@ __build: $(LOGO-y)
|
||||
$(LOGO_H): $(obj)/bmp_logo $(LOGO_BMP)
|
||||
$(obj)/bmp_logo --gen-info $(LOGO_BMP) > $@
|
||||
|
||||
ifeq ($(CONFIG_DM_VIDEO),y)
|
||||
$(LOGO_DATA_H): $(obj)/bmp_logo $(LOGO_BMP)
|
||||
$(obj)/bmp_logo --gen-bmp $(LOGO_BMP) > $@
|
||||
else
|
||||
$(LOGO_DATA_H): $(obj)/bmp_logo $(LOGO_BMP)
|
||||
$(obj)/bmp_logo --gen-data $(LOGO_BMP) > $@
|
||||
#endif
|
||||
endif
|
||||
|
||||
# Let clean descend into subdirs
|
||||
subdir- += env
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
enum {
|
||||
MODE_GEN_INFO,
|
||||
MODE_GEN_DATA
|
||||
MODE_GEN_DATA,
|
||||
MODE_GEN_BMP
|
||||
};
|
||||
|
||||
typedef struct bitmap_s { /* bitmap description */
|
||||
@ -16,7 +17,8 @@ typedef struct bitmap_s { /* bitmap description */
|
||||
|
||||
void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [--gen-info|--gen-data] file\n", prog);
|
||||
fprintf(stderr, "Usage: %s [--gen-info|--gen-data|--gen-bmp] file\n",
|
||||
prog);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -73,6 +75,7 @@ void gen_info(bitmap_t *b, uint16_t n_colors)
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int mode, i, x;
|
||||
int size;
|
||||
FILE *fp;
|
||||
bitmap_t bmp;
|
||||
bitmap_t *b = &bmp;
|
||||
@ -87,6 +90,8 @@ int main (int argc, char *argv[])
|
||||
mode = MODE_GEN_INFO;
|
||||
else if (!strcmp(argv[1], "--gen-data"))
|
||||
mode = MODE_GEN_DATA;
|
||||
else if (!strcmp(argv[1], "--gen-bmp"))
|
||||
mode = MODE_GEN_BMP;
|
||||
else {
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -131,6 +136,7 @@ int main (int argc, char *argv[])
|
||||
b->width = le_short(b->width);
|
||||
b->height = le_short(b->height);
|
||||
n_colors = le_short(n_colors);
|
||||
size = b->width * b->height;
|
||||
|
||||
/* assume we are working with an 8-bit file */
|
||||
if ((n_colors == 0) || (n_colors > 256 - DEFAULT_CMAP_SIZE)) {
|
||||
@ -152,10 +158,6 @@ int main (int argc, char *argv[])
|
||||
"#ifndef __BMP_LOGO_DATA_H__\n"
|
||||
"#define __BMP_LOGO_DATA_H__\n\n");
|
||||
|
||||
/* allocate memory */
|
||||
if ((b->data = (uint8_t *)malloc(b->width * b->height)) == NULL)
|
||||
error ("Error allocating memory for file", fp);
|
||||
|
||||
/* read and print the palette information */
|
||||
printf("unsigned short bmp_logo_palette[] = {\n");
|
||||
|
||||
@ -175,21 +177,39 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* seek to offset indicated by file header */
|
||||
fseek(fp, (long)data_offset, SEEK_SET);
|
||||
if (mode == MODE_GEN_BMP) {
|
||||
/* copy full bmp file */
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
} else {
|
||||
fseek(fp, (long)data_offset, SEEK_SET);
|
||||
}
|
||||
|
||||
/* allocate memory */
|
||||
b->data = (uint8_t *)malloc(size);
|
||||
if (!b->data)
|
||||
error("Error allocating memory for file", fp);
|
||||
|
||||
/* read the bitmap; leave room for default color map */
|
||||
printf ("\n");
|
||||
printf ("};\n");
|
||||
printf ("\n");
|
||||
printf("unsigned char bmp_logo_bitmap[] = {\n");
|
||||
for (i=(b->height-1)*b->width; i>=0; i-=b->width) {
|
||||
for (x = 0; x < b->width; x++) {
|
||||
b->data[i + x] = (uint8_t) fgetc(fp)
|
||||
if (mode == MODE_GEN_BMP) {
|
||||
/* write full bmp */
|
||||
for (i = 0; i < size; i++)
|
||||
b->data[i] = (uint8_t)fgetc(fp);
|
||||
} else {
|
||||
for (i = (b->height - 1) * b->width; i >= 0; i -= b->width) {
|
||||
for (x = 0; x < b->width; x++) {
|
||||
b->data[i + x] = (uint8_t)fgetc(fp)
|
||||
+ DEFAULT_CMAP_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<(b->height*b->width); ++i) {
|
||||
for (i = 0; i < size; ++i) {
|
||||
if ((i%8) == 0)
|
||||
putchar ('\t');
|
||||
printf ("0x%02X,%c",
|
||||
|
Loading…
Reference in New Issue
Block a user