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";
|
compatible = "toradex,colibri-imx6ull", "fsl,imx6ull";
|
||||||
|
|
||||||
aliases {
|
aliases {
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
mmc0 = &usdhc1;
|
mmc0 = &usdhc1;
|
||||||
usb0 = &usbotg1; /* required for ums */
|
usb0 = &usbotg1; /* required for ums */
|
||||||
|
display0 = &lcdif;
|
||||||
};
|
};
|
||||||
|
|
||||||
chosen {
|
chosen {
|
||||||
@ -156,6 +158,36 @@
|
|||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&pinctrl_lcdif_dat
|
pinctrl-0 = <&pinctrl_lcdif_dat
|
||||||
&pinctrl_lcdif_ctrl>;
|
&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> */
|
/* PWM <A> */
|
||||||
|
@ -113,29 +113,34 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
&lcdif {
|
&lcdif {
|
||||||
u-boot,dm-pre-reloc;
|
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
display = <&display0>;
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
|
|
||||||
display-timings {
|
display0: display0 {
|
||||||
native-mode = <&timing_vga>;
|
bits-per-pixel = <18>;
|
||||||
|
bus-width = <24>;
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
/* Standard VGA timing */
|
display-timings {
|
||||||
timing_vga: 640x480 {
|
native-mode = <&timing_vga>;
|
||||||
u-boot,dm-pre-reloc;
|
timing_vga: 640x480 {
|
||||||
clock-frequency = <25175000>;
|
u-boot,dm-pre-reloc;
|
||||||
hactive = <640>;
|
clock-frequency = <25175000>;
|
||||||
vactive = <480>;
|
hactive = <640>;
|
||||||
hback-porch = <48>;
|
vactive = <480>;
|
||||||
hfront-porch = <16>;
|
hback-porch = <48>;
|
||||||
vback-porch = <33>;
|
hfront-porch = <16>;
|
||||||
vfront-porch = <10>;
|
vback-porch = <33>;
|
||||||
hsync-len = <96>;
|
vfront-porch = <10>;
|
||||||
vsync-len = <2>;
|
hsync-len = <96>;
|
||||||
|
vsync-len = <2>;
|
||||||
|
|
||||||
de-active = <1>;
|
de-active = <1>;
|
||||||
hsync-active = <0>;
|
hsync-active = <0>;
|
||||||
vsync-active = <0>;
|
vsync-active = <0>;
|
||||||
pixelclk-active = <0>;
|
pixelclk-active = <0>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -21,3 +21,7 @@
|
|||||||
&uart0 {
|
&uart0 {
|
||||||
u-boot,dm-pre-reloc;
|
u-boot,dm-pre-reloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&dcu0 {
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
|
};
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
aliases {
|
aliases {
|
||||||
usb0 = &ehci0; /* required for ums */
|
usb0 = &ehci0; /* required for ums */
|
||||||
|
display1 = &dcu0;
|
||||||
};
|
};
|
||||||
|
|
||||||
reg_usbh_vbus: regulator-usbh-vbus {
|
reg_usbh_vbus: regulator-usbh-vbus {
|
||||||
@ -241,3 +242,7 @@
|
|||||||
pinctrl-0 = <&pinctrl_uart0>;
|
pinctrl-0 = <&pinctrl_uart0>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&dcu0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
@ -145,6 +145,12 @@
|
|||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dcu0: dcu@40058000 {
|
||||||
|
compatible = "fsl,vf610-dcu";
|
||||||
|
reg = <0x40058000 0x1200>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
ehci0: ehci@40034000 {
|
ehci0: ehci@40034000 {
|
||||||
compatible = "fsl,vf610-usb";
|
compatible = "fsl,vf610-usb";
|
||||||
reg = <0x40034000 0x800>;
|
reg = <0x40034000 0x800>;
|
||||||
|
@ -554,7 +554,7 @@ const struct boot_mode soc_boot_modes[] = {
|
|||||||
void reset_misc(void)
|
void reset_misc(void)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_SPL_BUILD
|
#ifndef CONFIG_SPL_BUILD
|
||||||
#ifdef CONFIG_VIDEO_MXS
|
#if defined(CONFIG_VIDEO_MXS) && !defined(CONFIG_DM_VIDEO)
|
||||||
lcdif_power_down();
|
lcdif_power_down();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,9 +23,10 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
|||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
int platform_dcu_init(unsigned int xres, unsigned int yres,
|
int platform_dcu_init(struct fb_info *fbinfo,
|
||||||
const char *port,
|
unsigned int xres, unsigned int yres,
|
||||||
struct fb_videomode *dcu_fb_videomode)
|
const char *port,
|
||||||
|
struct fb_videomode *dcu_fb_videomode)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned int pixel_format;
|
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);
|
printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
|
||||||
|
|
||||||
pixel_format = 32;
|
pixel_format = 32;
|
||||||
fsl_dcu_init(xres, yres, pixel_format);
|
fsl_dcu_init(fbinfo, xres, yres, pixel_format);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,9 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
|||||||
return div;
|
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,
|
const char *port,
|
||||||
struct fb_videomode *dcu_fb_videomode)
|
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);
|
printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
|
||||||
|
|
||||||
pixel_format = 32;
|
pixel_format = 32;
|
||||||
fsl_dcu_init(xres, yres, pixel_format);
|
fsl_dcu_init(fbinfo, xres, yres, pixel_format);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
|||||||
return div;
|
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,
|
const char *port,
|
||||||
struct fb_videomode *dcu_fb_videomode)
|
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);
|
printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
|
||||||
|
|
||||||
pixel_format = 32;
|
pixel_format = 32;
|
||||||
fsl_dcu_init(xres, yres, pixel_format);
|
fsl_dcu_init(fbinfo, xres, yres, pixel_format);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,9 @@ int checkboard(void)
|
|||||||
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
|
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
|
||||||
int ft_board_setup(void *blob, bd_t *bd)
|
int ft_board_setup(void *blob, bd_t *bd)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_DM_VIDEO
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
|
||||||
static const struct node_info nodes[] = {
|
static const struct node_info nodes[] = {
|
||||||
{ "fsl,vf610-nfc", MTD_DEV_TYPE_NAND, }, /* NAND flash */
|
{ "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");
|
puts(" Updating MTD partitions...\n");
|
||||||
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
|
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_VIDEO_FSL_DCU_FB
|
#if defined(CONFIG_VIDEO_FSL_DCU_FB) && !defined(CONFIG_DM_VIDEO)
|
||||||
ret = fsl_dcu_fixedfb_setup(blob);
|
ret = fsl_dcu_fixedfb_setup(blob);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -26,11 +26,13 @@ unsigned int dcu_set_pixel_clock(unsigned int pixclock)
|
|||||||
return div;
|
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,
|
const char *port,
|
||||||
struct fb_videomode *dcu_fb_videomode)
|
struct fb_videomode *dcu_fb_videomode)
|
||||||
{
|
{
|
||||||
fsl_dcu_init(xres, yres, 32);
|
fsl_dcu_init(fbinfo, xres, yres, 32);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -168,8 +168,12 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
|
int edid_get_timing_validate(u8 *buf, int buf_size,
|
||||||
int *panel_bits_per_colourp)
|
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;
|
struct edid1_info *edid = (struct edid1_info *)buf;
|
||||||
bool timing_done;
|
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];
|
desc = &edid->monitor_details.descriptor[i];
|
||||||
if (desc->zero_flag_1 != 0) {
|
if (desc->zero_flag_1 != 0) {
|
||||||
decode_timing((u8 *)desc, timing);
|
decode_timing((u8 *)desc, timing);
|
||||||
timing_done = true;
|
if (mode_valid)
|
||||||
|
timing_done = mode_valid(mode_valid_priv,
|
||||||
|
timing);
|
||||||
|
else
|
||||||
|
timing_done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,6 +233,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
|
|||||||
return 0;
|
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.
|
* 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_USB_GADGET_PRODUCT_NUM=0x4000
|
||||||
CONFIG_CI_UDC=y
|
CONFIG_CI_UDC=y
|
||||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||||
CONFIG_VIDEO=y
|
CONFIG_DM_VIDEO=y
|
||||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||||
CONFIG_FDT_FIXUP_PARTITIONS=y
|
CONFIG_FDT_FIXUP_PARTITIONS=y
|
||||||
|
@ -74,6 +74,6 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
|
|||||||
CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
|
CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
|
||||||
CONFIG_CI_UDC=y
|
CONFIG_CI_UDC=y
|
||||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||||
CONFIG_VIDEO=y
|
CONFIG_DM_VIDEO=y
|
||||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||||
CONFIG_FDT_FIXUP_PARTITIONS=y
|
CONFIG_FDT_FIXUP_PARTITIONS=y
|
||||||
|
@ -89,7 +89,7 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
|
|||||||
CONFIG_CI_UDC=y
|
CONFIG_CI_UDC=y
|
||||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||||
CONFIG_VIDEO_FSL_DCU_FB=y
|
CONFIG_VIDEO_FSL_DCU_FB=y
|
||||||
CONFIG_VIDEO=y
|
CONFIG_DM_VIDEO=y
|
||||||
CONFIG_SYS_CONSOLE_FG_COL=0x00
|
CONFIG_SYS_CONSOLE_FG_COL=0x00
|
||||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||||
CONFIG_FDT_FIXUP_PARTITIONS=y
|
CONFIG_FDT_FIXUP_PARTITIONS=y
|
||||||
|
@ -484,7 +484,7 @@ config VIDEO_IVYBRIDGE_IGD
|
|||||||
|
|
||||||
config VIDEO_FSL_DCU_FB
|
config VIDEO_FSL_DCU_FB
|
||||||
bool "Enable Freescale Display Control Unit"
|
bool "Enable Freescale Display Control Unit"
|
||||||
depends on VIDEO
|
depends on VIDEO || DM_VIDEO
|
||||||
help
|
help
|
||||||
This enables support for Freescale Display Control Unit (DCU4)
|
This enables support for Freescale Display Control Unit (DCU4)
|
||||||
module found on Freescale Vybrid and QorIQ family of SoCs.
|
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");
|
debug("bcm2835: Query resolution...\n");
|
||||||
ret = bcm2835_get_video_size(&w, &h);
|
ret = bcm2835_get_video_size(&w, &h);
|
||||||
if (ret)
|
if (ret || w == 0 || h == 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
debug("bcm2835: Setting up display for %d x %d\n", w, h);
|
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,
|
ret = bcm2835_set_video_params(&w, &h, 32, BCM2835_MBOX_PIXEL_ORDER_RGB,
|
||||||
BCM2835_MBOX_ALPHA_MODE_IGNORED,
|
BCM2835_MBOX_ALPHA_MODE_IGNORED,
|
||||||
&fb_base, &fb_size, &pitch);
|
&fb_base, &fb_size, &pitch);
|
||||||
|
if (ret)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
debug("bcm2835: Final resolution is %d x %d\n", w, h);
|
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;
|
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)
|
int display_read_timing(struct udevice *dev, struct display_timing *timing)
|
||||||
{
|
{
|
||||||
struct dm_display_ops *ops = display_get_ops(dev);
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
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)
|
bool display_in_use(struct udevice *dev)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#include <i2c.h>
|
||||||
#include <media_bus_format.h>
|
#include <media_bus_format.h>
|
||||||
#include "dw_hdmi.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 trytime = 5;
|
||||||
u32 n;
|
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 */
|
/* 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_high, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
|
||||||
hdmi_write(hdmi, hdmi->i2c_clk_low, HDMI_I2CM_SS_SCL_LCNT_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+
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2019 Toradex AG
|
||||||
*
|
*
|
||||||
* FSL DCU Framebuffer driver
|
* FSL DCU Framebuffer driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <fdt_support.h>
|
#include <fdt_support.h>
|
||||||
#include <fsl_dcu_fb.h>
|
#include <fsl_dcu_fb.h>
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <video.h>
|
||||||
#include <video_fb.h>
|
#include <video_fb.h>
|
||||||
#include "videomodes.h"
|
#include "videomodes.h"
|
||||||
|
|
||||||
@ -218,8 +221,6 @@ struct dcu_reg {
|
|||||||
u32 ctrldescl[DCU_LAYER_MAX_NUM][16];
|
u32 ctrldescl[DCU_LAYER_MAX_NUM][16];
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct fb_info info;
|
|
||||||
|
|
||||||
static void reset_total_layers(void)
|
static void reset_total_layers(void)
|
||||||
{
|
{
|
||||||
struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
|
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;
|
struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
|
||||||
unsigned int bpp = BPP_24_RGB888;
|
unsigned int bpp = BPP_24_RGB888;
|
||||||
|
|
||||||
dcu_write32(®s->ctrldescl[index][0],
|
dcu_write32(®s->ctrldescl[index][0],
|
||||||
DCU_CTRLDESCLN_1_HEIGHT(info.var.yres) |
|
DCU_CTRLDESCLN_1_HEIGHT(fbinfo.var.yres) |
|
||||||
DCU_CTRLDESCLN_1_WIDTH(info.var.xres));
|
DCU_CTRLDESCLN_1_WIDTH(fbinfo.var.xres));
|
||||||
|
|
||||||
dcu_write32(®s->ctrldescl[index][1],
|
dcu_write32(®s->ctrldescl[index][1],
|
||||||
DCU_CTRLDESCLN_2_POSY(0) |
|
DCU_CTRLDESCLN_2_POSY(0) |
|
||||||
DCU_CTRLDESCLN_2_POSX(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) {
|
switch (pixel_format) {
|
||||||
case 16:
|
case 16:
|
||||||
@ -294,42 +297,46 @@ static int layer_ctrldesc_init(int index, u32 pixel_format)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fsl_dcu_init(unsigned int xres, unsigned int yres,
|
int fsl_dcu_init(struct fb_info *fbinfo, unsigned int xres,
|
||||||
unsigned int pixel_format)
|
unsigned int yres, unsigned int pixel_format)
|
||||||
{
|
{
|
||||||
struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
|
struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
|
||||||
unsigned int div, mode;
|
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 =
|
if (fbinfo->screen_size > CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB) {
|
||||||
info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
|
fbinfo->screen_size = 0;
|
||||||
|
|
||||||
if (info.screen_size > CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB) {
|
|
||||||
info.screen_size = 0;
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reserve framebuffer at the end of memory */
|
/* Reserve framebuffer at the end of memory */
|
||||||
gd->fb_base = gd->bd->bi_dram[0].start +
|
gd->fb_base = gd->bd->bi_dram[0].start +
|
||||||
gd->bd->bi_dram[0].size - info.screen_size;
|
gd->bd->bi_dram[0].size - fbinfo->screen_size;
|
||||||
info.screen_base = (char *)gd->fb_base;
|
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();
|
reset_total_layers();
|
||||||
|
|
||||||
dcu_write32(®s->disp_size,
|
dcu_write32(®s->disp_size,
|
||||||
DCU_DISP_SIZE_DELTA_Y(info.var.yres) |
|
DCU_DISP_SIZE_DELTA_Y(fbinfo->var.yres) |
|
||||||
DCU_DISP_SIZE_DELTA_X(info.var.xres / 16));
|
DCU_DISP_SIZE_DELTA_X(fbinfo->var.xres / 16));
|
||||||
|
|
||||||
dcu_write32(®s->hsyn_para,
|
dcu_write32(®s->hsyn_para,
|
||||||
DCU_HSYN_PARA_BP(info.var.left_margin) |
|
DCU_HSYN_PARA_BP(fbinfo->var.left_margin) |
|
||||||
DCU_HSYN_PARA_PW(info.var.hsync_len) |
|
DCU_HSYN_PARA_PW(fbinfo->var.hsync_len) |
|
||||||
DCU_HSYN_PARA_FP(info.var.right_margin));
|
DCU_HSYN_PARA_FP(fbinfo->var.right_margin));
|
||||||
|
|
||||||
dcu_write32(®s->vsyn_para,
|
dcu_write32(®s->vsyn_para,
|
||||||
DCU_VSYN_PARA_BP(info.var.upper_margin) |
|
DCU_VSYN_PARA_BP(fbinfo->var.upper_margin) |
|
||||||
DCU_VSYN_PARA_PW(info.var.vsync_len) |
|
DCU_VSYN_PARA_PW(fbinfo->var.vsync_len) |
|
||||||
DCU_VSYN_PARA_FP(info.var.lower_margin));
|
DCU_VSYN_PARA_FP(fbinfo->var.lower_margin));
|
||||||
|
|
||||||
dcu_write32(®s->synpol,
|
dcu_write32(®s->synpol,
|
||||||
DCU_SYN_POL_INV_PXCK_FALL |
|
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);
|
mode = dcu_read32(®s->mode);
|
||||||
dcu_write32(®s->mode, mode | DCU_MODE_NORMAL);
|
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->div_ratio, (div - 1));
|
||||||
|
|
||||||
dcu_write32(®s->update_mode, DCU_UPDATE_MODE_READREG);
|
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;
|
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;
|
const char *options;
|
||||||
unsigned int depth = 0, freq = 0;
|
unsigned int depth = 0, freq = 0;
|
||||||
|
|
||||||
struct fb_videomode *fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
|
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))
|
&options))
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Find the monitor port, which is a required option */
|
/* Find the monitor port, which is a required option */
|
||||||
if (!options)
|
if (!options)
|
||||||
return NULL;
|
return -EINVAL;
|
||||||
if (strncmp(options, "monitor=", 8) != 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
switch (RESOLUTION(ctfb.winSizeX, ctfb.winSizeY)) {
|
if (strncmp(options, "monitor=", 8) != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (RESOLUTION(*win_x, *win_y)) {
|
||||||
case RESOLUTION(480, 272):
|
case RESOLUTION(480, 272):
|
||||||
fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
|
fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
|
||||||
break;
|
break;
|
||||||
@ -402,39 +411,31 @@ void *video_hw_init(void)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unsupported resolution %ux%u\n",
|
printf("unsupported resolution %ux%u\n",
|
||||||
ctfb.winSizeX, ctfb.winSizeY);
|
*win_x, *win_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.var.xres = fsl_dcu_mode_db->xres;
|
fbinfo->var.xres = fsl_dcu_mode_db->xres;
|
||||||
info.var.yres = fsl_dcu_mode_db->yres;
|
fbinfo->var.yres = fsl_dcu_mode_db->yres;
|
||||||
info.var.bits_per_pixel = 32;
|
fbinfo->var.bits_per_pixel = 32;
|
||||||
info.var.pixclock = fsl_dcu_mode_db->pixclock;
|
fbinfo->var.pixclock = fsl_dcu_mode_db->pixclock;
|
||||||
info.var.left_margin = fsl_dcu_mode_db->left_margin;
|
fbinfo->var.left_margin = fsl_dcu_mode_db->left_margin;
|
||||||
info.var.right_margin = fsl_dcu_mode_db->right_margin;
|
fbinfo->var.right_margin = fsl_dcu_mode_db->right_margin;
|
||||||
info.var.upper_margin = fsl_dcu_mode_db->upper_margin;
|
fbinfo->var.upper_margin = fsl_dcu_mode_db->upper_margin;
|
||||||
info.var.lower_margin = fsl_dcu_mode_db->lower_margin;
|
fbinfo->var.lower_margin = fsl_dcu_mode_db->lower_margin;
|
||||||
info.var.hsync_len = fsl_dcu_mode_db->hsync_len;
|
fbinfo->var.hsync_len = fsl_dcu_mode_db->hsync_len;
|
||||||
info.var.vsync_len = fsl_dcu_mode_db->vsync_len;
|
fbinfo->var.vsync_len = fsl_dcu_mode_db->vsync_len;
|
||||||
info.var.sync = fsl_dcu_mode_db->sync;
|
fbinfo->var.sync = fsl_dcu_mode_db->sync;
|
||||||
info.var.vmode = fsl_dcu_mode_db->vmode;
|
fbinfo->var.vmode = fsl_dcu_mode_db->vmode;
|
||||||
info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8;
|
fbinfo->fix.line_length = fbinfo->var.xres *
|
||||||
|
fbinfo->var.bits_per_pixel / 8;
|
||||||
|
|
||||||
if (platform_dcu_init(ctfb.winSizeX, ctfb.winSizeY,
|
return platform_dcu_init(fbinfo, *win_x, *win_y,
|
||||||
options + 8, fsl_dcu_mode_db) < 0)
|
options + 8, fsl_dcu_mode_db);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_VIDEO
|
||||||
|
static struct fb_info info;
|
||||||
|
|
||||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||||
int fsl_dcu_fixedfb_setup(void *blob)
|
int fsl_dcu_fixedfb_setup(void *blob)
|
||||||
{
|
{
|
||||||
@ -457,3 +458,89 @@ int fsl_dcu_fixedfb_setup(void *blob)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
|
uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
|
||||||
|
&priv->hdmi.ddc_bus);
|
||||||
|
|
||||||
ret = reset_get_bulk(dev, &resets);
|
ret = reset_get_bulk(dev, &resets);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -426,9 +429,16 @@ static int meson_dw_hdmi_probe(struct udevice *dev)
|
|||||||
return ret;
|
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 = {
|
static const struct dm_display_ops meson_dw_hdmi_ops = {
|
||||||
.read_edid = meson_dw_hdmi_read_edid,
|
.read_edid = meson_dw_hdmi_read_edid,
|
||||||
.enable = meson_dw_hdmi_enable,
|
.enable = meson_dw_hdmi_enable,
|
||||||
|
.mode_valid = meson_dw_hdmi_mode_valid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct udevice_id meson_dw_hdmi_ids[] = {
|
static const struct udevice_id meson_dw_hdmi_ids[] = {
|
||||||
|
@ -271,6 +271,42 @@ dealloc_fb:
|
|||||||
}
|
}
|
||||||
#else /* ifndef CONFIG_DM_VIDEO */
|
#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)
|
static int mxs_video_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct video_uc_platdata *plat = dev_get_uclass_platdata(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 ctfb_res_modes mode;
|
||||||
struct display_timing timings;
|
struct display_timing timings;
|
||||||
int bpp = -1;
|
u32 bpp = 0;
|
||||||
u32 fb_start, fb_end;
|
u32 fb_start, fb_end;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
debug("%s() plat: base 0x%lx, size 0x%x\n",
|
debug("%s() plat: base 0x%lx, size 0x%x\n",
|
||||||
__func__, plat->base, plat->size);
|
__func__, plat->base, plat->size);
|
||||||
|
|
||||||
ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, &timings);
|
ret = mxs_of_get_timings(dev, &timings, &bpp);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to get any display timings\n");
|
return ret;
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mode.xres = timings.hactive.typ;
|
mode.xres = timings.hactive.typ;
|
||||||
mode.yres = timings.vactive.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.vsync_len = timings.vsync_len.typ;
|
||||||
mode.pixclock = HZ2PS(timings.pixelclock.typ);
|
mode.pixclock = HZ2PS(timings.pixelclock.typ);
|
||||||
|
|
||||||
bpp = BITS_PP;
|
|
||||||
|
|
||||||
ret = mxs_probe_common(&mode, bpp, plat->base);
|
ret = mxs_probe_common(&mode, bpp, plat->base);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
switch (bpp) {
|
switch (bpp) {
|
||||||
|
case 32:
|
||||||
case 24:
|
case 24:
|
||||||
case 18:
|
case 18:
|
||||||
uc_priv->bpix = VIDEO_BPP32;
|
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 video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||||
struct display_timing timings;
|
struct display_timing timings;
|
||||||
|
u32 bpp = 0;
|
||||||
|
u32 bytes_pp = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ofnode_decode_display_timing(dev_ofnode(dev), 0, &timings);
|
ret = mxs_of_get_timings(dev, &timings, &bpp);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(dev, "failed to get any display timings\n");
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
plat->size = timings.hactive.typ * timings.vactive.typ * BYTES_PP;
|
plat->size = timings.hactive.typ * timings.vactive.typ * bytes_pp;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,9 @@ int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
|
|||||||
|
|
||||||
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ static const struct udevice_id simple_panel_ids[] = {
|
|||||||
{ .compatible = "auo,b133xtn01" },
|
{ .compatible = "auo,b133xtn01" },
|
||||||
{ .compatible = "auo,b116xw03" },
|
{ .compatible = "auo,b116xw03" },
|
||||||
{ .compatible = "auo,b133htn01" },
|
{ .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->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg;
|
||||||
priv->mux = uc_plat->source_id;
|
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);
|
dw_hdmi_init(&priv->hdmi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -170,7 +170,7 @@
|
|||||||
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_16M
|
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_16M
|
||||||
#define DFU_DEFAULT_POLL_TIMEOUT 300
|
#define DFU_DEFAULT_POLL_TIMEOUT 300
|
||||||
|
|
||||||
#ifdef CONFIG_VIDEO
|
#if defined(CONFIG_VIDEO) || defined(CONFIG_DM_VIDEO)
|
||||||
#define CONFIG_VIDEO_MXS
|
#define CONFIG_VIDEO_MXS
|
||||||
#define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
|
#define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR
|
||||||
#define CONFIG_VIDEO_LOGO
|
#define CONFIG_VIDEO_LOGO
|
||||||
|
@ -80,6 +80,16 @@ struct dm_display_ops {
|
|||||||
*/
|
*/
|
||||||
int (*enable)(struct udevice *dev, int panel_bpp,
|
int (*enable)(struct udevice *dev, int panel_bpp,
|
||||||
const struct display_timing *timing);
|
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)
|
#define display_get_ops(dev) ((struct dm_display_ops *)(dev)->driver->ops)
|
||||||
|
@ -542,6 +542,7 @@ struct dw_hdmi {
|
|||||||
u8 i2c_clk_low;
|
u8 i2c_clk_low;
|
||||||
u8 reg_io_width;
|
u8 reg_io_width;
|
||||||
struct hdmi_data_info hdmi_data;
|
struct hdmi_data_info hdmi_data;
|
||||||
|
struct udevice *ddc_bus;
|
||||||
|
|
||||||
int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock);
|
int (*phy_set)(struct dw_hdmi *hdmi, uint mpixelclock);
|
||||||
void (*write_reg)(struct dw_hdmi *hdmi, u8 val, int offset);
|
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;
|
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
|
* edid_get_timing() - Get basic digital display parameters
|
||||||
*
|
*
|
||||||
|
@ -6,11 +6,17 @@
|
|||||||
*/
|
*/
|
||||||
#include <linux/fb.h>
|
#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);
|
unsigned int pixel_format);
|
||||||
|
|
||||||
int fsl_dcu_fixedfb_setup(void *blob);
|
int fsl_dcu_fixedfb_setup(void *blob);
|
||||||
|
|
||||||
/* Prototypes for external board-specific functions */
|
/* Prototypes for external board-specific functions */
|
||||||
int platform_dcu_init(unsigned int xres, unsigned int yres,
|
int platform_dcu_init(struct fb_info *fbinfo,
|
||||||
const char *port, struct fb_videomode *dcu_fb_videomode);
|
unsigned int xres,
|
||||||
|
unsigned int yres,
|
||||||
|
const char *port,
|
||||||
|
struct fb_videomode *dcu_fb_videomode);
|
||||||
unsigned int dcu_set_pixel_clock(unsigned int pixclock);
|
unsigned int dcu_set_pixel_clock(unsigned int pixclock);
|
||||||
|
@ -269,8 +269,14 @@ __build: $(LOGO-y)
|
|||||||
$(LOGO_H): $(obj)/bmp_logo $(LOGO_BMP)
|
$(LOGO_H): $(obj)/bmp_logo $(LOGO_BMP)
|
||||||
$(obj)/bmp_logo --gen-info $(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)
|
$(LOGO_DATA_H): $(obj)/bmp_logo $(LOGO_BMP)
|
||||||
$(obj)/bmp_logo --gen-data $(LOGO_BMP) > $@
|
$(obj)/bmp_logo --gen-data $(LOGO_BMP) > $@
|
||||||
|
#endif
|
||||||
|
endif
|
||||||
|
|
||||||
# Let clean descend into subdirs
|
# Let clean descend into subdirs
|
||||||
subdir- += env
|
subdir- += env
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
MODE_GEN_INFO,
|
MODE_GEN_INFO,
|
||||||
MODE_GEN_DATA
|
MODE_GEN_DATA,
|
||||||
|
MODE_GEN_BMP
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct bitmap_s { /* bitmap description */
|
typedef struct bitmap_s { /* bitmap description */
|
||||||
@ -16,7 +17,8 @@ typedef struct bitmap_s { /* bitmap description */
|
|||||||
|
|
||||||
void usage(const char *prog)
|
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 main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int mode, i, x;
|
int mode, i, x;
|
||||||
|
int size;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
bitmap_t bmp;
|
bitmap_t bmp;
|
||||||
bitmap_t *b = &bmp;
|
bitmap_t *b = &bmp;
|
||||||
@ -87,6 +90,8 @@ int main (int argc, char *argv[])
|
|||||||
mode = MODE_GEN_INFO;
|
mode = MODE_GEN_INFO;
|
||||||
else if (!strcmp(argv[1], "--gen-data"))
|
else if (!strcmp(argv[1], "--gen-data"))
|
||||||
mode = MODE_GEN_DATA;
|
mode = MODE_GEN_DATA;
|
||||||
|
else if (!strcmp(argv[1], "--gen-bmp"))
|
||||||
|
mode = MODE_GEN_BMP;
|
||||||
else {
|
else {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@ -131,6 +136,7 @@ int main (int argc, char *argv[])
|
|||||||
b->width = le_short(b->width);
|
b->width = le_short(b->width);
|
||||||
b->height = le_short(b->height);
|
b->height = le_short(b->height);
|
||||||
n_colors = le_short(n_colors);
|
n_colors = le_short(n_colors);
|
||||||
|
size = b->width * b->height;
|
||||||
|
|
||||||
/* assume we are working with an 8-bit file */
|
/* assume we are working with an 8-bit file */
|
||||||
if ((n_colors == 0) || (n_colors > 256 - DEFAULT_CMAP_SIZE)) {
|
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"
|
"#ifndef __BMP_LOGO_DATA_H__\n"
|
||||||
"#define __BMP_LOGO_DATA_H__\n\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 */
|
/* read and print the palette information */
|
||||||
printf("unsigned short bmp_logo_palette[] = {\n");
|
printf("unsigned short bmp_logo_palette[] = {\n");
|
||||||
|
|
||||||
@ -175,21 +177,39 @@ int main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* seek to offset indicated by file header */
|
/* 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 */
|
/* read the bitmap; leave room for default color map */
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("};\n");
|
printf ("};\n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf("unsigned char bmp_logo_bitmap[] = {\n");
|
printf("unsigned char bmp_logo_bitmap[] = {\n");
|
||||||
for (i=(b->height-1)*b->width; i>=0; i-=b->width) {
|
if (mode == MODE_GEN_BMP) {
|
||||||
for (x = 0; x < b->width; x++) {
|
/* write full bmp */
|
||||||
b->data[i + x] = (uint8_t) fgetc(fp)
|
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;
|
+ DEFAULT_CMAP_SIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<(b->height*b->width); ++i) {
|
for (i = 0; i < size; ++i) {
|
||||||
if ((i%8) == 0)
|
if ((i%8) == 0)
|
||||||
putchar ('\t');
|
putchar ('\t');
|
||||||
printf ("0x%02X,%c",
|
printf ("0x%02X,%c",
|
||||||
|
Loading…
Reference in New Issue
Block a user