From dc8cae4df3c016cbcb6eb8a841a7a94ff36b9e0b Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 29 Apr 2017 14:43:35 +0200 Subject: edid: Set timings flags according to edid Timing flags are never set, so they may contain garbage. Since some drivers check them, video output may be broken on those drivers. Initialize them to 0 and check for few common flags. Signed-off-by: Jernej Skrabec Reviewed-by: Simon Glass diff --git a/common/edid.c b/common/edid.c index e08e420..ab7069f 100644 --- a/common/edid.c +++ b/common/edid.c @@ -85,6 +85,7 @@ static void decode_timing(u8 *buf, struct display_timing *timing) uint x_mm, y_mm; unsigned int ha, hbl, hso, hspw, hborder; unsigned int va, vbl, vso, vspw, vborder; + struct edid_detailed_timing *t = (struct edid_detailed_timing *)buf; /* Edid contains pixel clock in terms of 10KHz */ set_entry(&timing->pixelclock, (buf[0] + (buf[1] << 8)) * 10000); @@ -111,6 +112,19 @@ static void decode_timing(u8 *buf, struct display_timing *timing) set_entry(&timing->vback_porch, vbl - vso - vspw); set_entry(&timing->vsync_len, vspw); + timing->flags = 0; + if (EDID_DETAILED_TIMING_FLAG_HSYNC_POLARITY(*t)) + timing->flags |= DISPLAY_FLAGS_HSYNC_HIGH; + else + timing->flags |= DISPLAY_FLAGS_HSYNC_LOW; + if (EDID_DETAILED_TIMING_FLAG_VSYNC_POLARITY(*t)) + timing->flags |= DISPLAY_FLAGS_VSYNC_HIGH; + else + timing->flags |= DISPLAY_FLAGS_VSYNC_LOW; + + if (EDID_DETAILED_TIMING_FLAG_INTERLACED(*t)) + timing->flags = DISPLAY_FLAGS_INTERLACED; + debug("Detailed mode clock %u Hz, %d mm x %d mm\n" " %04x %04x %04x %04x hborder %x\n" " %04x %04x %04x %04x vborder %x\n", -- cgit v0.10.2 From 43c6bdd0209ca31be84d572278485ed604582730 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 29 Apr 2017 14:43:36 +0200 Subject: edid: Add HDMI flag to timing info Some DVI monitors don't show anything in HDMI mode since audio stream confuses them. To solve this situation, this commit adds HDMI flag in timing data and sets it accordingly during edid parsing. First existence of extension block is checked. If it exists and it is CEA861 extension, then data blocks are checked for presence of HDMI vendor specific data block. If it is present, HDMI flag is set. Signed-off-by: Jernej Skrabec Reviewed-by: Simon Glass diff --git a/common/edid.c b/common/edid.c index ab7069f..19410aa 100644 --- a/common/edid.c +++ b/common/edid.c @@ -136,6 +136,39 @@ static void decode_timing(u8 *buf, struct display_timing *timing) va + vbl, vborder); } +/** + * Check if HDMI vendor specific data block is present in CEA block + * @param info CEA extension block + * @return true if block is found + */ +static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info) +{ + u8 end, i = 0; + + /* check for end of data block */ + end = info->dtd_offset; + if (end == 0) + end = 127; + if (end < 4 || end > 127) + return false; + end -= 4; + + while (i < end) { + /* Look for vendor specific data block of appropriate size */ + if ((EDID_CEA861_DB_TYPE(*info, i) == EDID_CEA861_DB_VENDOR) && + (EDID_CEA861_DB_LEN(*info, i) >= 5)) { + u8 *db = &info->data[i + 1]; + u32 oui = db[0] | (db[1] << 8) | (db[2] << 16); + + if (oui == HDMI_IEEE_OUI) + return true; + } + i += EDID_CEA861_DB_LEN(*info, i) + 1; + } + + return false; +} + int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, int *panel_bits_per_colourp) { @@ -181,6 +214,15 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, ((edid->video_input_definition & 0x70) >> 3) + 4; } + timing->hdmi_monitor = false; + if (edid->extension_flag && (buf_size >= EDID_EXT_SIZE)) { + struct edid_cea861_info *info = + (struct edid_cea861_info *)(buf + sizeof(*edid)); + + if (info->extension_tag == EDID_CEA861_EXTENSION_TAG) + timing->hdmi_monitor = cea_is_hdmi_vsdb_present(info); + } + return 0; } diff --git a/include/edid.h b/include/edid.h index 8b022fa..a9f2f3d 100644 --- a/include/edid.h +++ b/include/edid.h @@ -19,6 +19,9 @@ #define EDID_SIZE 128 #define EDID_EXT_SIZE 256 +/* OUI of HDMI vendor specific data block */ +#define HDMI_IEEE_OUI 0x000c03 + #define GET_BIT(_x, _pos) \ (((_x) >> (_pos)) & 1) #define GET_BITS(_x, _pos_msb, _pos_lsb) \ @@ -234,6 +237,13 @@ struct edid1_info { unsigned char checksum; } __attribute__ ((__packed__)); +enum edid_cea861_db_types { + EDID_CEA861_DB_AUDIO = 0x01, + EDID_CEA861_DB_VIDEO = 0x02, + EDID_CEA861_DB_VENDOR = 0x03, + EDID_CEA861_DB_SPEAKER = 0x04, +}; + struct edid_cea861_info { unsigned char extension_tag; #define EDID_CEA861_EXTENSION_TAG 0x02 @@ -251,6 +261,10 @@ struct edid_cea861_info { #define EDID_CEA861_DTD_COUNT(_x) \ GET_BITS(((_x).dtd_count), 3, 0) unsigned char data[124]; +#define EDID_CEA861_DB_TYPE(_x, offset) \ + GET_BITS((_x).data[offset], 7, 5) +#define EDID_CEA861_DB_LEN(_x, offset) \ + GET_BITS((_x).data[offset], 4, 0) } __attribute__ ((__packed__)); /** diff --git a/include/fdtdec.h b/include/fdtdec.h index b0e5b27..3000ecb 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -967,6 +967,7 @@ struct display_timing { struct timing_entry vsync_len; /* ver. sync len */ enum display_flags flags; /* display flags */ + bool hdmi_monitor; /* is hdmi monitor? */ }; /** -- cgit v0.10.2 From 4f4e1b6365fef4f19ea440a2c2340e3cf1f57bf3 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 29 Apr 2017 14:43:37 +0200 Subject: video: dw_hdmi: Select HDMI mode only if monitor supports it Some DVI monitors don't work in HDMI mode. Set it only if edid data explicitly states that it is supported. Signed-off-by: Jernej Skrabec Reviewed-by: Simon Glass diff --git a/drivers/video/dw_hdmi.c b/drivers/video/dw_hdmi.c index 8a53109..6039d67 100644 --- a/drivers/video/dw_hdmi.c +++ b/drivers/video/dw_hdmi.c @@ -414,13 +414,9 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); - /* - * TODO(sjg@chromium.org>: Need to check for HDMI / DVI - * inv_val |= (edid->hdmi_monitor_detected ? - * HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE : - * HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE); - */ - inv_val |= HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE; + inv_val |= (edid->hdmi_monitor ? + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE : + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE); inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW; @@ -459,7 +455,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, } /* hdmi initialization step b.4 */ -static void hdmi_enable_video_path(struct dw_hdmi *hdmi) +static void hdmi_enable_video_path(struct dw_hdmi *hdmi, bool audio) { uint clkdis; @@ -484,8 +480,10 @@ static void hdmi_enable_video_path(struct dw_hdmi *hdmi) clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS); - clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; - hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS); + if (audio) { + clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; + hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS); + } } /* workaround to clear the overflow condition */ @@ -716,7 +714,8 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) { int ret; - debug("hdmi, mode info : clock %d hdis %d vdis %d\n", + debug("%s, mode info : clock %d hdis %d vdis %d\n", + edid->hdmi_monitor ? "hdmi" : "dvi", edid->pixelclock.typ, edid->hactive.typ, edid->vactive.typ); hdmi_av_composer(hdmi, edid); @@ -725,11 +724,13 @@ int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid) if (ret) return ret; - hdmi_enable_video_path(hdmi); + hdmi_enable_video_path(hdmi, edid->hdmi_monitor); - hdmi_audio_fifo_reset(hdmi); - hdmi_audio_set_format(hdmi); - hdmi_audio_set_samplerate(hdmi, edid->pixelclock.typ); + if (edid->hdmi_monitor) { + hdmi_audio_fifo_reset(hdmi); + hdmi_audio_set_format(hdmi); + hdmi_audio_set_samplerate(hdmi, edid->pixelclock.typ); + } hdmi_video_packetize(hdmi); hdmi_video_sample(hdmi); -- cgit v0.10.2 From 8517f64fe67f851eb128cc594666fb2615cde08d Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 5 May 2017 21:48:26 +0200 Subject: rockchip: video: introduce VIDEO_DW_HDMI and select for Rockchip HDMI Instead of having drivers/video/rockchip/Kconfig point outside of its hierarchy for dw_hdmi.o, we should use a configuration-option to include the Designware HDMI support. This change introduces a new config option (not to be selected via menuconfig, but to be selected from a dependent video driver's configuration option) that enables dw_hdmi.o and selects it whenever the HDMI support for Rockchip SoCs is selected. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 446cca9..61dfed8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -619,4 +619,13 @@ config LCD CONFIG option. See the README for details. Drives which have been converted to driver model will instead used CONFIG_DM_VIDEO. +config VIDEO_DW_HDMI + bool + help + Enables the common driver code for the Designware HDMI TX + block found in SoCs from various vendors. + As this does not provide any functionality by itself (but + rather requires a SoC-specific glue driver to call it), it + can not be enabled from the configuration menu. + endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index a80af31..58f5de5 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_VIDEO_VESA) += vesa.o obj-$(CONFIG_FORMIKE) += formike.o obj-$(CONFIG_LG4573) += lg4573.o obj-$(CONFIG_AM335X_LCD) += am335x-fb.o +obj-$(CONFIG_VIDEO_DW_HDMI) += dw_hdmi.o obj-${CONFIG_VIDEO_TEGRA124} += tegra124/ obj-${CONFIG_EXYNOS_FB} += exynos/ diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index 9267b28..80e399f 100644 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -35,6 +35,7 @@ config DISPLAY_ROCKCHIP_LVDS config DISPLAY_ROCKCHIP_HDMI bool "HDMI port" + select VIDEO_DW_HDMI depends on VIDEO_ROCKCHIP help This enables High-Definition Multimedia Interface display support. diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile index c742902..cd54b12 100644 --- a/drivers/video/rockchip/Makefile +++ b/drivers/video/rockchip/Makefile @@ -9,6 +9,6 @@ ifdef CONFIG_VIDEO_ROCKCHIP obj-y += rk_vop.o obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o -obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o ../dw_hdmi.o +obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o obj-$(CONFIG_DISPLAY_ROCKCHIP_MIPI) += rk_mipi.o endif -- cgit v0.10.2 From 10ba6b333955b7be491f9dd8c1241309dfcb5c8b Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Fri, 5 May 2017 21:48:30 +0200 Subject: video: bmp: rename CONFIG_BMP_24BMP to CONFIG_BMP_24BPP Due to a typo, the 24 bit-per-pixel configuration ends in 24BMP instead of 24BPP. This change renames it throughout the source tree for consistency and to make moving these options into Kconfig easier and less error-prone. Signed-off-by: Philipp Tomsich Reviewed-by: Simon Glass Reviewed-by: Hannes Schmelzer diff --git a/common/lcd.c b/common/lcd.c index 783626e..2405146 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -704,7 +704,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } break; #endif /* CONFIG_BMP_16BPP */ -#if defined(CONFIG_BMP_24BMP) +#if defined(CONFIG_BMP_24BPP) case 24: for (i = 0; i < height; ++i) { for (j = 0; j < width; j++) { @@ -716,7 +716,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) fb -= lcd_line_length + width * (bpix / 8); } break; -#endif /* CONFIG_BMP_24BMP */ +#endif /* CONFIG_BMP_24BPP */ #if defined(CONFIG_BMP_32BPP) case 32: for (i = 0; i < height; ++i) { diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index 32a4e7f..f803067 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -316,7 +316,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, } break; #endif /* CONFIG_BMP_16BPP */ -#if defined(CONFIG_BMP_24BMP) +#if defined(CONFIG_BMP_24BPP) case 24: for (i = 0; i < height; ++i) { for (j = 0; j < width; j++) { @@ -328,7 +328,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, fb -= priv->line_length + width * (bpix / 8); } break; -#endif /* CONFIG_BMP_24BMP */ +#endif /* CONFIG_BMP_24BPP */ #if defined(CONFIG_BMP_32BPP) case 32: for (i = 0; i < height; ++i) { diff --git a/include/configs/brxre1.h b/include/configs/brxre1.h index 49f223a..9984689 100644 --- a/include/configs/brxre1.h +++ b/include/configs/brxre1.h @@ -21,7 +21,7 @@ #define CONFIG_VIDEO_BMP_GZIP #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (1366*767*4) -#define CONFIG_BMP_24BMP +#define CONFIG_BMP_24BPP #define CONFIG_BMP_32BPP /* memory */ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 7646bb6..f3d9f12 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -236,7 +236,6 @@ CONFIG_BL1_SIZE CONFIG_BL2_OFFSET CONFIG_BL2_SIZE CONFIG_BMP_16BPP -CONFIG_BMP_24BMP CONFIG_BMP_24BPP CONFIG_BMP_32BPP CONFIG_BOARDDIR -- cgit v0.10.2 From c10806267d8409a49e638984e6f674e44f19d4a8 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Wed, 10 May 2017 18:46:28 +0200 Subject: sunxi: video: Split out TVE code Newer SoCs use same TV encoder unit. Split it out so it can be reused with new DM video driver. Signed-off-by: Jernej Skrabec Reviewed-by: Simon Glass diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h index 93803ad..e101977 100644 --- a/arch/arm/include/asm/arch-sunxi/display.h +++ b/arch/arm/include/asm/arch-sunxi/display.h @@ -225,52 +225,6 @@ struct sunxi_hdmi_reg { }; /* - * This is based on the A10s User Manual, and the A10s only supports - * composite video and not vga like the A10 / A20 does, still other - * than the removed vga out capability the tvencoder seems to be the same. - * "unknown#" registers are registers which are used in the A10 kernel code, - * but not documented in the A10s User Manual. - */ -struct sunxi_tve_reg { - u32 gctrl; /* 0x000 */ - u32 cfg0; /* 0x004 */ - u32 dac_cfg0; /* 0x008 */ - u32 filter; /* 0x00c */ - u32 chroma_freq; /* 0x010 */ - u32 porch_num; /* 0x014 */ - u32 unknown0; /* 0x018 */ - u32 line_num; /* 0x01c */ - u32 blank_black_level; /* 0x020 */ - u32 unknown1; /* 0x024, seems to be 1 byte per dac */ - u8 res0[0x08]; /* 0x028 */ - u32 auto_detect_en; /* 0x030 */ - u32 auto_detect_int_status; /* 0x034 */ - u32 auto_detect_status; /* 0x038 */ - u32 auto_detect_debounce; /* 0x03c */ - u32 csc_reg0; /* 0x040 */ - u32 csc_reg1; /* 0x044 */ - u32 csc_reg2; /* 0x048 */ - u32 csc_reg3; /* 0x04c */ - u8 res1[0xb0]; /* 0x050 */ - u32 color_burst; /* 0x100 */ - u32 vsync_num; /* 0x104 */ - u32 notch_freq; /* 0x108 */ - u32 cbr_level; /* 0x10c */ - u32 burst_phase; /* 0x110 */ - u32 burst_width; /* 0x114 */ - u32 unknown2; /* 0x118 */ - u32 sync_vbi_level; /* 0x11c */ - u32 white_level; /* 0x120 */ - u32 active_num; /* 0x124 */ - u32 chroma_bw_gain; /* 0x128 */ - u32 notch_width; /* 0x12c */ - u32 resync_num; /* 0x130 */ - u32 slave_para; /* 0x134 */ - u32 cfg1; /* 0x138 */ - u32 cfg2; /* 0x13c */ -}; - -/* * DE-FE register constants. */ #define SUNXI_DE_FE_WIDTH(x) (((x) - 1) << 0) @@ -394,67 +348,6 @@ struct sunxi_tve_reg { #define SUNXI_HMDI_DDC_LINE_CTRL_SCL_ENABLE (1 << 8) #define SUNXI_HMDI_DDC_LINE_CTRL_SDA_ENABLE (1 << 9) -/* - * TVE register constants. - */ -#define SUNXI_TVE_GCTRL_ENABLE (1 << 0) -/* - * Select input 0 to disable dac, 1 - 4 to feed dac from tve0, 5 - 8 to feed - * dac from tve1. When using tve1 the mux value must be written to both tve0's - * and tve1's gctrl reg. - */ -#define SUNXI_TVE_GCTRL_DAC_INPUT_MASK(dac) (0xf << (((dac) + 1) * 4)) -#define SUNXI_TVE_GCTRL_DAC_INPUT(dac, sel) ((sel) << (((dac) + 1) * 4)) -#define SUNXI_TVE_CFG0_VGA 0x20000000 -#define SUNXI_TVE_CFG0_PAL 0x07030001 -#define SUNXI_TVE_CFG0_NTSC 0x07030000 -#define SUNXI_TVE_DAC_CFG0_VGA 0x403e1ac7 -#ifdef CONFIG_MACH_SUN5I -#define SUNXI_TVE_DAC_CFG0_COMPOSITE 0x433f0009 -#else -#define SUNXI_TVE_DAC_CFG0_COMPOSITE 0x403f0008 -#endif -#define SUNXI_TVE_FILTER_COMPOSITE 0x00000120 -#define SUNXI_TVE_CHROMA_FREQ_PAL_M 0x21e6efe3 -#define SUNXI_TVE_CHROMA_FREQ_PAL_NC 0x21f69446 -#define SUNXI_TVE_PORCH_NUM_PAL 0x008a0018 -#define SUNXI_TVE_PORCH_NUM_NTSC 0x00760020 -#define SUNXI_TVE_LINE_NUM_PAL 0x00160271 -#define SUNXI_TVE_LINE_NUM_NTSC 0x0016020d -#define SUNXI_TVE_BLANK_BLACK_LEVEL_PAL 0x00fc00fc -#define SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC 0x00f0011a -#define SUNXI_TVE_UNKNOWN1_VGA 0x00000000 -#define SUNXI_TVE_UNKNOWN1_COMPOSITE 0x18181818 -#define SUNXI_TVE_AUTO_DETECT_EN_DET_EN(dac) (1 << ((dac) + 0)) -#define SUNXI_TVE_AUTO_DETECT_EN_INT_EN(dac) (1 << ((dac) + 16)) -#define SUNXI_TVE_AUTO_DETECT_INT_STATUS(dac) (1 << ((dac) + 0)) -#define SUNXI_TVE_AUTO_DETECT_STATUS_SHIFT(dac) ((dac) * 8) -#define SUNXI_TVE_AUTO_DETECT_STATUS_MASK(dac) (3 << ((dac) * 8)) -#define SUNXI_TVE_AUTO_DETECT_STATUS_NONE 0 -#define SUNXI_TVE_AUTO_DETECT_STATUS_CONNECTED 1 -#define SUNXI_TVE_AUTO_DETECT_STATUS_SHORT_GND 3 -#define SUNXI_TVE_AUTO_DETECT_DEBOUNCE_SHIFT(d) ((d) * 8) -#define SUNXI_TVE_AUTO_DETECT_DEBOUNCE_MASK(d) (0xf << ((d) * 8)) -#define SUNXI_TVE_CSC_REG0_ENABLE (1 << 31) -#define SUNXI_TVE_CSC_REG0 0x08440832 -#define SUNXI_TVE_CSC_REG1 0x3b6dace1 -#define SUNXI_TVE_CSC_REG2 0x0e1d13dc -#define SUNXI_TVE_CSC_REG3 0x00108080 -#define SUNXI_TVE_COLOR_BURST_PAL_M 0x00000000 -#define SUNXI_TVE_CBR_LEVEL_PAL 0x00002828 -#define SUNXI_TVE_CBR_LEVEL_NTSC 0x0000004f -#define SUNXI_TVE_BURST_PHASE_NTSC 0x00000000 -#define SUNXI_TVE_BURST_WIDTH_COMPOSITE 0x0016447e -#define SUNXI_TVE_UNKNOWN2_PAL 0x0000e0e0 -#define SUNXI_TVE_UNKNOWN2_NTSC 0x0000a0a0 -#define SUNXI_TVE_SYNC_VBI_LEVEL_NTSC 0x001000f0 -#define SUNXI_TVE_ACTIVE_NUM_COMPOSITE 0x000005a0 -#define SUNXI_TVE_CHROMA_BW_GAIN_COMP 0x00000002 -#define SUNXI_TVE_NOTCH_WIDTH_COMPOSITE 0x00000101 -#define SUNXI_TVE_RESYNC_NUM_PAL 0x800d000c -#define SUNXI_TVE_RESYNC_NUM_NTSC 0x000e000c -#define SUNXI_TVE_SLAVE_PARA_COMPOSITE 0x00000000 - int sunxi_simplefb_setup(void *blob); #endif /* _SUNXI_DISPLAY_H */ diff --git a/arch/arm/include/asm/arch-sunxi/tve.h b/arch/arm/include/asm/arch-sunxi/tve.h new file mode 100644 index 0000000..41a14a6 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/tve.h @@ -0,0 +1,131 @@ +/* + * Sunxi TV encoder register and constant defines + * + * (C) Copyright 2014 Hans de Goede + * (C) Copyright 2017 Jernej Skrabec + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _TVE_H +#define _TVE_H + +enum tve_mode { + tve_mode_vga, + tve_mode_composite_pal, + tve_mode_composite_ntsc, + tve_mode_composite_pal_m, + tve_mode_composite_pal_nc, +}; + +/* + * This is based on the A10s User Manual, and the A10s only supports + * composite video and not vga like the A10 / A20 does, still other + * than the removed vga out capability the tvencoder seems to be the same. + * "unknown#" registers are registers which are used in the A10 kernel code, + * but not documented in the A10s User Manual. + */ +struct sunxi_tve_reg { + u32 gctrl; /* 0x000 */ + u32 cfg0; /* 0x004 */ + u32 dac_cfg0; /* 0x008 */ + u32 filter; /* 0x00c */ + u32 chroma_freq; /* 0x010 */ + u32 porch_num; /* 0x014 */ + u32 unknown0; /* 0x018 */ + u32 line_num; /* 0x01c */ + u32 blank_black_level; /* 0x020 */ + u32 unknown1; /* 0x024, seems to be 1 byte per dac */ + u8 res0[0x08]; /* 0x028 */ + u32 auto_detect_en; /* 0x030 */ + u32 auto_detect_int_status; /* 0x034 */ + u32 auto_detect_status; /* 0x038 */ + u32 auto_detect_debounce; /* 0x03c */ + u32 csc_reg0; /* 0x040 */ + u32 csc_reg1; /* 0x044 */ + u32 csc_reg2; /* 0x048 */ + u32 csc_reg3; /* 0x04c */ + u8 res1[0xb0]; /* 0x050 */ + u32 color_burst; /* 0x100 */ + u32 vsync_num; /* 0x104 */ + u32 notch_freq; /* 0x108 */ + u32 cbr_level; /* 0x10c */ + u32 burst_phase; /* 0x110 */ + u32 burst_width; /* 0x114 */ + u32 unknown2; /* 0x118 */ + u32 sync_vbi_level; /* 0x11c */ + u32 white_level; /* 0x120 */ + u32 active_num; /* 0x124 */ + u32 chroma_bw_gain; /* 0x128 */ + u32 notch_width; /* 0x12c */ + u32 resync_num; /* 0x130 */ + u32 slave_para; /* 0x134 */ + u32 cfg1; /* 0x138 */ + u32 cfg2; /* 0x13c */ +}; + +/* + * TVE register constants. + */ +#define SUNXI_TVE_GCTRL_ENABLE (1 << 0) +/* + * Select input 0 to disable dac, 1 - 4 to feed dac from tve0, 5 - 8 to feed + * dac from tve1. When using tve1 the mux value must be written to both tve0's + * and tve1's gctrl reg. + */ +#define SUNXI_TVE_GCTRL_DAC_INPUT_MASK(dac) (0xf << (((dac) + 1) * 4)) +#define SUNXI_TVE_GCTRL_DAC_INPUT(dac, sel) ((sel) << (((dac) + 1) * 4)) +#define SUNXI_TVE_CFG0_VGA 0x20000000 +#define SUNXI_TVE_CFG0_PAL 0x07030001 +#define SUNXI_TVE_CFG0_NTSC 0x07030000 +#define SUNXI_TVE_DAC_CFG0_VGA 0x403e1ac7 +#ifdef CONFIG_MACH_SUN5I +#define SUNXI_TVE_DAC_CFG0_COMPOSITE 0x433f0009 +#else +#define SUNXI_TVE_DAC_CFG0_COMPOSITE 0x403f0008 +#endif +#define SUNXI_TVE_FILTER_COMPOSITE 0x00000120 +#define SUNXI_TVE_CHROMA_FREQ_PAL_M 0x21e6efe3 +#define SUNXI_TVE_CHROMA_FREQ_PAL_NC 0x21f69446 +#define SUNXI_TVE_PORCH_NUM_PAL 0x008a0018 +#define SUNXI_TVE_PORCH_NUM_NTSC 0x00760020 +#define SUNXI_TVE_LINE_NUM_PAL 0x00160271 +#define SUNXI_TVE_LINE_NUM_NTSC 0x0016020d +#define SUNXI_TVE_BLANK_BLACK_LEVEL_PAL 0x00fc00fc +#define SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC 0x00f0011a +#define SUNXI_TVE_UNKNOWN1_VGA 0x00000000 +#define SUNXI_TVE_UNKNOWN1_COMPOSITE 0x18181818 +#define SUNXI_TVE_AUTO_DETECT_EN_DET_EN(dac) (1 << ((dac) + 0)) +#define SUNXI_TVE_AUTO_DETECT_EN_INT_EN(dac) (1 << ((dac) + 16)) +#define SUNXI_TVE_AUTO_DETECT_INT_STATUS(dac) (1 << ((dac) + 0)) +#define SUNXI_TVE_AUTO_DETECT_STATUS_SHIFT(dac) ((dac) * 8) +#define SUNXI_TVE_AUTO_DETECT_STATUS_MASK(dac) (3 << ((dac) * 8)) +#define SUNXI_TVE_AUTO_DETECT_STATUS_NONE 0 +#define SUNXI_TVE_AUTO_DETECT_STATUS_CONNECTED 1 +#define SUNXI_TVE_AUTO_DETECT_STATUS_SHORT_GND 3 +#define SUNXI_TVE_AUTO_DETECT_DEBOUNCE_SHIFT(d) ((d) * 8) +#define SUNXI_TVE_AUTO_DETECT_DEBOUNCE_MASK(d) (0xf << ((d) * 8)) +#define SUNXI_TVE_CSC_REG0_ENABLE (1 << 31) +#define SUNXI_TVE_CSC_REG0 0x08440832 +#define SUNXI_TVE_CSC_REG1 0x3b6dace1 +#define SUNXI_TVE_CSC_REG2 0x0e1d13dc +#define SUNXI_TVE_CSC_REG3 0x00108080 +#define SUNXI_TVE_COLOR_BURST_PAL_M 0x00000000 +#define SUNXI_TVE_CBR_LEVEL_PAL 0x00002828 +#define SUNXI_TVE_CBR_LEVEL_NTSC 0x0000004f +#define SUNXI_TVE_BURST_PHASE_NTSC 0x00000000 +#define SUNXI_TVE_BURST_WIDTH_COMPOSITE 0x0016447e +#define SUNXI_TVE_UNKNOWN2_PAL 0x0000e0e0 +#define SUNXI_TVE_UNKNOWN2_NTSC 0x0000a0a0 +#define SUNXI_TVE_SYNC_VBI_LEVEL_NTSC 0x001000f0 +#define SUNXI_TVE_ACTIVE_NUM_COMPOSITE 0x000005a0 +#define SUNXI_TVE_CHROMA_BW_GAIN_COMP 0x00000002 +#define SUNXI_TVE_NOTCH_WIDTH_COMPOSITE 0x00000101 +#define SUNXI_TVE_RESYNC_NUM_PAL 0x800d000c +#define SUNXI_TVE_RESYNC_NUM_NTSC 0x000e000c +#define SUNXI_TVE_SLAVE_PARA_COMPOSITE 0x00000000 + +void tvencoder_mode_set(struct sunxi_tve_reg * const tve, enum tve_mode mode); +void tvencoder_enable(struct sunxi_tve_reg * const tve); + +#endif /* _TVE_H */ diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile index b8afd89..dbaab61 100644 --- a/drivers/video/sunxi/Makefile +++ b/drivers/video/sunxi/Makefile @@ -5,5 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o ../videomodes.o +obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve.o ../videomodes.o obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c index 92c9d06..de768ba 100644 --- a/drivers/video/sunxi/sunxi_display.c +++ b/drivers/video/sunxi/sunxi_display.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -929,63 +930,19 @@ static void sunxi_tvencoder_mode_set(void) switch (sunxi_display.monitor) { case sunxi_monitor_vga: - writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | - SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | - SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl); - writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0); - writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0); - writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1); + tvencoder_mode_set(tve, tve_mode_vga); break; case sunxi_monitor_composite_pal_nc: - writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq); - /* Fall through */ + tvencoder_mode_set(tve, tve_mode_composite_pal_nc); + break; case sunxi_monitor_composite_pal: - writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | - SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | - SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | - SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); - writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0); - writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); - writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); - writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num); - writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num); - writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level); - writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); - writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level); - writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); - writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2); - writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); - writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); - writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); - writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num); - writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); + tvencoder_mode_set(tve, tve_mode_composite_pal); break; case sunxi_monitor_composite_pal_m: - writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq); - writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst); - /* Fall through */ + tvencoder_mode_set(tve, tve_mode_composite_pal_m); + break; case sunxi_monitor_composite_ntsc: - writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | - SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | - SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | - SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); - writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0); - writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); - writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); - writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num); - writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num); - writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level); - writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); - writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level); - writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase); - writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); - writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2); - writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level); - writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); - writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); - writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); - writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num); - writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); + tvencoder_mode_set(tve, tve_mode_composite_ntsc); break; case sunxi_monitor_none: case sunxi_monitor_dvi: @@ -995,14 +952,6 @@ static void sunxi_tvencoder_mode_set(void) } } -static void sunxi_tvencoder_enable(void) -{ - struct sunxi_tve_reg * const tve = - (struct sunxi_tve_reg *)SUNXI_TVE0_BASE; - - setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE); -} - #endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */ static void sunxi_drc_init(void) @@ -1080,6 +1029,8 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, int __maybe_unused clk_div, clk_double; struct sunxi_lcdc_reg * const lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; + struct sunxi_tve_reg * __maybe_unused const tve = + (struct sunxi_tve_reg *)SUNXI_TVE0_BASE; switch (sunxi_display.monitor) { case sunxi_monitor_none: @@ -1134,7 +1085,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, sunxi_tvencoder_mode_set(); sunxi_composer_enable(); lcdc_enable(lcdc, sunxi_display.depth); - sunxi_tvencoder_enable(); + tvencoder_enable(tve); #elif defined CONFIG_VIDEO_VGA_VIA_LCD sunxi_composer_mode_set(mode, address); sunxi_lcdc_tcon0_mode_set(mode, true); @@ -1153,7 +1104,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, sunxi_tvencoder_mode_set(); sunxi_composer_enable(); lcdc_enable(lcdc, sunxi_display.depth); - sunxi_tvencoder_enable(); + tvencoder_enable(tve); #endif break; } diff --git a/drivers/video/sunxi/tve.c b/drivers/video/sunxi/tve.c new file mode 100644 index 0000000..adea78a --- /dev/null +++ b/drivers/video/sunxi/tve.c @@ -0,0 +1,86 @@ +/* + * TV encoder driver for Allwinner SoCs. + * + * (C) Copyright 2013-2014 Luc Verhaegen + * (C) Copyright 2014-2015 Hans de Goede + * (C) Copyright 2017 Jernej Skrabec + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#include +#include + +void tvencoder_mode_set(struct sunxi_tve_reg * const tve, enum tve_mode mode) +{ + switch (mode) { + case tve_mode_vga: + writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | + SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | + SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl); + writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0); + writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0); + writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1); + break; + case tve_mode_composite_pal_nc: + writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq); + /* Fall through */ + case tve_mode_composite_pal: + writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | + SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | + SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | + SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); + writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0); + writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); + writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); + writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num); + writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num); + writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, + &tve->blank_black_level); + writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); + writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level); + writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); + writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2); + writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); + writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); + writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); + writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num); + writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); + break; + case tve_mode_composite_pal_m: + writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq); + writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst); + /* Fall through */ + case tve_mode_composite_ntsc: + writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | + SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | + SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | + SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); + writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0); + writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); + writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); + writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num); + writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num); + writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, + &tve->blank_black_level); + writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); + writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level); + writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase); + writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); + writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2); + writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level); + writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); + writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); + writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); + writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num); + writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); + break; + } +} + +void tvencoder_enable(struct sunxi_tve_reg * const tve) +{ + setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE); +} -- cgit v0.10.2 From 940aed8f6bacfc8c0dbaf9da0008e0a6a76463a8 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Wed, 10 May 2017 18:46:29 +0200 Subject: sunxi: Add clock support for TV encoder This patch adds support for TV encoder clocks which will be used later. Signed-off-by: Jernej Skrabec diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index faa1479..d328df9 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -84,7 +84,8 @@ struct sunxi_ccm_reg { u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */ u32 lcd1_ch0_clk_cfg; /* 0x11c LCD1 CH0 module clock */ #endif - u32 reserved14[3]; + u32 tve_clk_cfg; /* 0x120 H3/H5 TVE module clock */ + u32 reserved14[2]; u32 lcd0_ch1_clk_cfg; /* 0x12c LCD0 CH1 module clock */ u32 lcd1_ch1_clk_cfg; /* 0x130 LCD1 CH1 module clock */ u32 csi0_clk_cfg; /* 0x134 CSI0 module clock */ @@ -307,6 +308,7 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DE_BE0 12 #define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 +#define AHB_GATE_OFFSET_TVE 9 #ifndef CONFIG_SUNXI_DE2 #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 @@ -415,6 +417,9 @@ struct sunxi_ccm_reg { #define CCM_HDMI_SLOW_CTRL_DDC_GATE (1 << 31) +#define CCM_TVE_CTRL_GATE (0x1 << 31) +#define CCM_TVE_CTRL_M(n) ((((n) - 1) & 0xf) << 0) + #if defined(CONFIG_MACH_SUN50I) #define MBUS_CLK_DEFAULT 0x81000002 /* PLL6x2 / 3 */ #elif defined(CONFIG_MACH_SUN8I) @@ -448,6 +453,7 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_DE 12 #define AHB_RESET_OFFSET_HDMI 11 #define AHB_RESET_OFFSET_HDMI2 10 +#define AHB_RESET_OFFSET_TVE 9 #ifndef CONFIG_SUNXI_DE2 #define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 -- cgit v0.10.2