summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun6i.h8
-rw-r--r--arch/arm/include/asm/arch-sunxi/display.h107
-rw-r--r--arch/arm/include/asm/arch-sunxi/tve.h131
-rw-r--r--common/edid.c56
-rw-r--r--common/lcd.c4
-rw-r--r--drivers/video/Kconfig9
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/dw_hdmi.c31
-rw-r--r--drivers/video/rockchip/Kconfig1
-rw-r--r--drivers/video/rockchip/Makefile2
-rw-r--r--drivers/video/sunxi/Makefile2
-rw-r--r--drivers/video/sunxi/sunxi_display.c73
-rw-r--r--drivers/video/sunxi/tve.c86
-rw-r--r--drivers/video/video_bmp.c4
-rw-r--r--include/configs/brxre1.h2
-rw-r--r--include/edid.h14
-rw-r--r--include/fdtdec.h1
-rw-r--r--scripts/config_whitelist.txt1
18 files changed, 341 insertions, 192 deletions
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index faa14791f9..d328df9597 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
diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index 93803addfb..e10197784e 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 0000000000..41a14a68e4
--- /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 <hdegoede@redhat.com>
+ * (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ * 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/common/edid.c b/common/edid.c
index e08e420920..19410aa4fc 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",
@@ -122,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)
{
@@ -167,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/common/lcd.c b/common/lcd.c
index 783626e3d5..2405146cf0 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/Kconfig b/drivers/video/Kconfig
index 446cca90d4..61dfed8c06 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 a80af3104d..58f5de5200 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/dw_hdmi.c b/drivers/video/dw_hdmi.c
index 8a53109823..6039d676c5 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);
diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig
index 9267b28781..80e399f7d7 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 c742902ddb..cd54b12a4e 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
diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile
index b8afd892ad..dbaab61b59 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 92c9d06054..de768ba94a 100644
--- a/drivers/video/sunxi/sunxi_display.c
+++ b/drivers/video/sunxi/sunxi_display.c
@@ -14,6 +14,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/lcdc.h>
#include <asm/arch/pwm.h>
+#include <asm/arch/tve.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
@@ -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 0000000000..adea78a69a
--- /dev/null
+++ b/drivers/video/sunxi/tve.c
@@ -0,0 +1,86 @@
+/*
+ * TV encoder driver for Allwinner SoCs.
+ *
+ * (C) Copyright 2013-2014 Luc Verhaegen <libv@skynet.be>
+ * (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
+ * (C) Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+
+#include <asm/arch/tve.h>
+#include <asm/io.h>
+
+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);
+}
diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
index 32a4e7f8a9..f803067da3 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 49f223a32a..99846890e0 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/include/edid.h b/include/edid.h
index 8b022fa98a..a9f2f3d3ab 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 b0e5b2767d..3000ecbb58 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? */
};
/**
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 33501859d6..fa9c3fc8cb 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