mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-video
This commit is contained in:
commit
d2e1ee686a
9 changed files with 161 additions and 16 deletions
|
@ -34,7 +34,9 @@
|
|||
#define SUNXI_MS_BASE 0x01c07000
|
||||
#define SUNXI_TVD_BASE 0x01c08000
|
||||
#define SUNXI_CSI0_BASE 0x01c09000
|
||||
#ifndef CONFIG_MACH_SUNXI_H3_H5
|
||||
#define SUNXI_TVE0_BASE 0x01c0a000
|
||||
#endif
|
||||
#define SUNXI_EMAC_BASE 0x01c0b000
|
||||
#define SUNXI_LCD0_BASE 0x01c0C000
|
||||
#define SUNXI_LCD1_BASE 0x01c0d000
|
||||
|
@ -161,10 +163,18 @@ defined(CONFIG_MACH_SUN50I)
|
|||
/* module sram */
|
||||
#define SUNXI_SRAM_C_BASE 0x01d00000
|
||||
|
||||
#ifndef CONFIG_MACH_SUN8I_H3
|
||||
#define SUNXI_DE_FE0_BASE 0x01e00000
|
||||
#else
|
||||
#define SUNXI_TVE0_BASE 0x01e00000
|
||||
#endif
|
||||
#define SUNXI_DE_FE1_BASE 0x01e20000
|
||||
#define SUNXI_DE_BE0_BASE 0x01e60000
|
||||
#ifndef CONFIG_MACH_SUN50I_H5
|
||||
#define SUNXI_DE_BE1_BASE 0x01e40000
|
||||
#else
|
||||
#define SUNXI_TVE0_BASE 0x01e40000
|
||||
#endif
|
||||
#define SUNXI_MP_BASE 0x01e80000
|
||||
#define SUNXI_AVG_BASE 0x01ea0000
|
||||
|
||||
|
|
|
@ -90,6 +90,23 @@ struct de_ui {
|
|||
u32 ovl_size;
|
||||
};
|
||||
|
||||
struct de_csc {
|
||||
u32 csc_ctl;
|
||||
u8 res[0xc];
|
||||
u32 coef11;
|
||||
u32 coef12;
|
||||
u32 coef13;
|
||||
u32 coef14;
|
||||
u32 coef21;
|
||||
u32 coef22;
|
||||
u32 coef23;
|
||||
u32 coef24;
|
||||
u32 coef31;
|
||||
u32 coef32;
|
||||
u32 coef33;
|
||||
u32 coef34;
|
||||
};
|
||||
|
||||
/*
|
||||
* DE register constants.
|
||||
*/
|
||||
|
|
|
@ -295,7 +295,7 @@ static void edid_print_dtd(struct edid_monitor_descriptor *monitor,
|
|||
|
||||
h_total = h_active + h_blanking;
|
||||
v_total = v_active + v_blanking;
|
||||
if (v_total * h_total)
|
||||
if (v_total > 0 && h_total > 0)
|
||||
vfreq = pixclock / (v_total * h_total);
|
||||
else
|
||||
vfreq = 1; /* Error case */
|
||||
|
|
|
@ -426,7 +426,9 @@ static void atmel_hlcdc_init(struct udevice *dev)
|
|||
writel(~0UL, ®s->lcdc_baseidr);
|
||||
|
||||
/* Setup the DMA descriptor, this descriptor will loop to itself */
|
||||
desc = (struct lcd_dma_desc *)(uc_plat->base - 16);
|
||||
desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc));
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
desc->address = (u32)uc_plat->base;
|
||||
|
||||
|
@ -436,7 +438,9 @@ static void atmel_hlcdc_init(struct udevice *dev)
|
|||
desc->next = (u32)desc;
|
||||
|
||||
/* Flush the DMA descriptor if we enabled dcache */
|
||||
flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc));
|
||||
flush_dcache_range((u32)desc,
|
||||
ALIGN(((u32)desc + sizeof(*desc)),
|
||||
CONFIG_SYS_CACHELINE_SIZE));
|
||||
|
||||
writel(desc->address, ®s->lcdc_baseaddr);
|
||||
writel(desc->control, ®s->lcdc_basectrl);
|
||||
|
|
|
@ -23,10 +23,54 @@ struct rk_hdmi_priv {
|
|||
void *grf;
|
||||
};
|
||||
|
||||
/**
|
||||
* rk_hdmi_read_edid() - read the attached HDMI/DVI monitor's EDID
|
||||
*
|
||||
* N.B.: The buffer should be large enough to hold 2 EDID blocks, as
|
||||
* this function calls dw_hdmi_read_edid, which ignores buf_size
|
||||
* argument and assumes that there's always enough space for 2
|
||||
* EDID blocks.
|
||||
*
|
||||
* @dev: device
|
||||
* @buf: output buffer for the EDID
|
||||
* @buf_size: number of bytes in the buffer
|
||||
* @return number of bytes read if OK, -ve if something went wrong
|
||||
*/
|
||||
int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size);
|
||||
|
||||
/**
|
||||
* rk_hdmi_probe_regulators() - probe (autoset + enable) regulators
|
||||
*
|
||||
* Probes a list of regulators by performing autoset and enable
|
||||
* operations on them. The list of regulators is an array of string
|
||||
* pointers and any individual regulator-probe may fail without
|
||||
* counting as an error.
|
||||
*
|
||||
* @dev: device
|
||||
* @names: array of string-pointers to regulator names to probe
|
||||
* @cnt: number of elements in the 'names' array
|
||||
*/
|
||||
void rk_hdmi_probe_regulators(struct udevice *dev,
|
||||
const char * const *names, int cnt);
|
||||
/**
|
||||
* rk_hdmi_ofdata_to_platdata() - common ofdata_to_platdata implementation
|
||||
*
|
||||
* @dev: device
|
||||
* @return 0 if OK, -ve if something went wrong
|
||||
*/
|
||||
int rk_hdmi_ofdata_to_platdata(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* rk_hdmi_probe() - common probe implementation
|
||||
*
|
||||
* Performs the following, common initialisation steps:
|
||||
* 1. checks for HPD (i.e. a HDMI monitor being attached)
|
||||
* 2. initialises the Designware HDMI core
|
||||
* 3. initialises the Designware HDMI PHY
|
||||
*
|
||||
* @dev: device
|
||||
* @return 0 if OK, -ve if something went wrong
|
||||
*/
|
||||
int rk_hdmi_probe(struct udevice *dev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,8 +25,42 @@ struct rkvop_driverdata {
|
|||
void (*set_pin_polarity)(struct udevice *, enum vop_modes, u32);
|
||||
};
|
||||
|
||||
/**
|
||||
* rk_vop_probe() - common probe implementation
|
||||
*
|
||||
* Performs the rk_display_init on each port-subnode until finding a
|
||||
* working port (or returning an error if none of the ports could be
|
||||
* successfully initialised).
|
||||
*
|
||||
* @dev: device
|
||||
* @return 0 if OK, -ve if something went wrong
|
||||
*/
|
||||
int rk_vop_probe(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* rk_vop_bind() - common bind implementation
|
||||
*
|
||||
* Sets the plat->size field to the amount of memory to be reserved for
|
||||
* the framebuffer: this is always
|
||||
* (32 BPP) x VIDEO_ROCKCHIP_MAX_XRES x VIDEO_ROCKCHIP_MAX_YRES
|
||||
*
|
||||
* @dev: device
|
||||
* @return 0 (always OK)
|
||||
*/
|
||||
int rk_vop_bind(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* rk_vop_probe_regulators() - probe (autoset + enable) regulators
|
||||
*
|
||||
* Probes a list of regulators by performing autoset and enable
|
||||
* operations on them. The list of regulators is an array of string
|
||||
* pointers and any individual regulator-probe may fail without
|
||||
* counting as an error.
|
||||
*
|
||||
* @dev: device
|
||||
* @names: array of string-pointers to regulator names to probe
|
||||
* @cnt: number of elements in the 'names' array
|
||||
*/
|
||||
void rk_vop_probe_regulators(struct udevice *dev,
|
||||
const char * const *names, int cnt);
|
||||
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve.o ../videomodes.o
|
||||
obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve_common.o ../videomodes.o
|
||||
obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o
|
||||
|
|
|
@ -56,7 +56,7 @@ static void sunxi_de2_composer_init(void)
|
|||
}
|
||||
|
||||
static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
|
||||
int bpp, ulong address)
|
||||
int bpp, ulong address, bool is_composite)
|
||||
{
|
||||
ulong de_mux_base = (mux == 0) ?
|
||||
SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE;
|
||||
|
@ -72,6 +72,9 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
|
|||
(struct de_ui *)(de_mux_base +
|
||||
SUNXI_DE2_MUX_CHAN_REGS +
|
||||
SUNXI_DE2_MUX_CHAN_SZ * 1);
|
||||
struct de_csc * const de_csc_regs =
|
||||
(struct de_csc *)(de_mux_base +
|
||||
SUNXI_DE2_MUX_DCSC_REGS);
|
||||
u32 size = SUNXI_DE2_WH(mode->hactive.typ, mode->vactive.typ);
|
||||
int channel;
|
||||
u32 format;
|
||||
|
@ -128,7 +131,27 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
|
|||
writel(0, de_mux_base + SUNXI_DE2_MUX_PEAK_REGS);
|
||||
writel(0, de_mux_base + SUNXI_DE2_MUX_ASE_REGS);
|
||||
writel(0, de_mux_base + SUNXI_DE2_MUX_FCC_REGS);
|
||||
writel(0, de_mux_base + SUNXI_DE2_MUX_DCSC_REGS);
|
||||
|
||||
if (is_composite) {
|
||||
/* set CSC coefficients */
|
||||
writel(0x107, &de_csc_regs->coef11);
|
||||
writel(0x204, &de_csc_regs->coef12);
|
||||
writel(0x64, &de_csc_regs->coef13);
|
||||
writel(0x4200, &de_csc_regs->coef14);
|
||||
writel(0x1f68, &de_csc_regs->coef21);
|
||||
writel(0x1ed6, &de_csc_regs->coef22);
|
||||
writel(0x1c2, &de_csc_regs->coef23);
|
||||
writel(0x20200, &de_csc_regs->coef24);
|
||||
writel(0x1c2, &de_csc_regs->coef31);
|
||||
writel(0x1e87, &de_csc_regs->coef32);
|
||||
writel(0x1fb7, &de_csc_regs->coef33);
|
||||
writel(0x20200, &de_csc_regs->coef34);
|
||||
|
||||
/* enable CSC unit */
|
||||
writel(1, &de_csc_regs->csc_ctl);
|
||||
} else {
|
||||
writel(0, &de_csc_regs->csc_ctl);
|
||||
}
|
||||
|
||||
switch (bpp) {
|
||||
case 16:
|
||||
|
@ -153,7 +176,7 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
|
|||
|
||||
static int sunxi_de2_init(struct udevice *dev, ulong fbbase,
|
||||
enum video_log2_bpp l2bpp,
|
||||
struct udevice *disp, int mux)
|
||||
struct udevice *disp, int mux, bool is_composite)
|
||||
{
|
||||
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct display_timing timing;
|
||||
|
@ -183,7 +206,7 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase,
|
|||
}
|
||||
|
||||
sunxi_de2_composer_init();
|
||||
sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase);
|
||||
sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase, is_composite);
|
||||
|
||||
ret = display_enable(disp, 1 << l2bpp, &timing);
|
||||
if (ret) {
|
||||
|
@ -204,7 +227,6 @@ static int sunxi_de2_probe(struct udevice *dev)
|
|||
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
|
||||
struct udevice *disp;
|
||||
int ret;
|
||||
int mux;
|
||||
|
||||
/* Before relocation we don't need to do anything */
|
||||
if (!(gd->flags & GD_FLG_RELOC))
|
||||
|
@ -212,17 +234,31 @@ static int sunxi_de2_probe(struct udevice *dev)
|
|||
|
||||
ret = uclass_find_device_by_name(UCLASS_DISPLAY,
|
||||
"sunxi_dw_hdmi", &disp);
|
||||
if (!ret) {
|
||||
int mux;
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
|
||||
mux = 0;
|
||||
else
|
||||
mux = 1;
|
||||
|
||||
ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux,
|
||||
false);
|
||||
if (!ret) {
|
||||
video_set_flush_dcache(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
debug("%s: hdmi display not found (ret=%d)\n", __func__, ret);
|
||||
|
||||
ret = uclass_find_device_by_name(UCLASS_DISPLAY,
|
||||
"sunxi_tve", &disp);
|
||||
if (ret) {
|
||||
debug("%s: hdmi display not found (ret=%d)\n", __func__, ret);
|
||||
debug("%s: tv not found (ret=%d)\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
|
||||
mux = 0;
|
||||
else
|
||||
mux = 1;
|
||||
|
||||
ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux);
|
||||
ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, 1, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
Loading…
Reference in a new issue