summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJoy Cho <joy.cho@hardkernel.com>2019-01-11 09:39:04 +0900
committerDongjin Kim <tobetter@gmail.com>2020-02-10 22:49:50 +0900
commit686d7003114979732e2afff15b85745a34cec4ea (patch)
treea6f1dba77fb98b3d39929a5442a7af4522dc620c /arch
parent9e53299712e2e7e621123c42b28bcdc5bb7d08ae (diff)
downloadu-boot-odroid-c1-686d7003114979732e2afff15b85745a34cec4ea.tar.gz
ODROID-C4: introduce display auto detection logic
Change-Id: I969bb06881382fc963d8c4a4e8bb875ed2941481
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c b/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c
index 931a2bb750..9e7215e880 100644
--- a/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c
+++ b/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c
@@ -92,6 +92,18 @@ static void hdmitx_csc_config (unsigned char input_color_format,
unsigned char output_color_format,
unsigned char color_depth);
+static void hdmitx_dvi_config(unsigned int dvi_mode)
+{
+ if (dvi_mode) {
+ /* DVI */
+ hdmitx_csc_config(TX_INPUT_COLOR_FORMAT, HDMI_COLOR_FORMAT_RGB, HDMI_COLOR_DEPTH_24B);
+ hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 0, 3, 1);
+ } else {
+ /* HDMI */
+ hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 1, 3, 1);
+ }
+}
+
static void dump_regs(void)
{
unsigned int reg_adr;
@@ -265,6 +277,54 @@ static int hdmitx_read_edid(unsigned char *buf, unsigned char addr, unsigned cha
return read_edid_8bytes(buf, addr);
}
+static int hdmitx_read_edid_raw(unsigned char *rx_edid)
+{
+ unsigned int timeout = 0;
+ unsigned int i;
+ unsigned int byte_num = 0;
+ unsigned int blk_no = 1;
+
+ /* Program SLAVE/SEGMENT/ADDR */
+ hdmitx_wr_reg(HDMITX_DWC_I2CM_SLAVE, 0x50);
+ hdmitx_wr_reg(HDMITX_DWC_I2CM_SEGADDR, 0x30);
+ /* Read complete EDID data sequentially */
+ while (byte_num < 128 * blk_no) {
+ if ((byte_num % 256) == 0)
+ hdmitx_wr_reg(HDMITX_DWC_I2CM_SEGPTR, byte_num>>8);
+ hdmitx_wr_reg(HDMITX_DWC_I2CM_ADDRESS, byte_num&0xff);
+ /* Do extended sequential read */
+ hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 1<<3);
+ /* Wait until I2C done */
+ timeout = 0;
+ while ((!(hdmitx_rd_reg(HDMITX_DWC_IH_I2CM_STAT0) & (1 << 1)))
+ && (timeout < 3)) {
+ mdelay(2);
+ timeout++;
+ }
+ if (timeout == 3)
+ printk("..............................\n");
+ hdmitx_wr_reg(HDMITX_DWC_IH_I2CM_STAT0, 1 << 1);
+ /* Read back 8 bytes */
+ for (i = 0; i < 8; i++) {
+ rx_edid[byte_num] =
+ hdmitx_rd_reg(HDMITX_DWC_I2CM_READ_BUFF0 + i);
+ if (byte_num == 126) {
+ blk_no = rx_edid[byte_num] + 1;
+ if (blk_no > 4) {
+ printk("edid extension block number:");
+ printk(" %d, reset to MAX 3\n",
+ blk_no - 1);
+ blk_no = 4; /* Max extended block */
+ }
+ }
+ byte_num++;
+ }
+ }
+
+ printk("edid extension block number : %d\n", blk_no);
+ return blk_no;
+}
+
static void scdc_rd_sink(unsigned char adr, unsigned char *val)
{
hdmitx_wr_reg(HDMITX_DWC_I2CM_SLAVE, 0x54);
@@ -396,6 +456,7 @@ void hdmi_tx_init(void)
{
hdmitx_device.HWOp.get_hpd_state = hdmitx_get_hpd_state;
hdmitx_device.HWOp.read_edid = hdmitx_read_edid;
+ hdmitx_device.HWOp.read_edid_raw = hdmitx_read_edid_raw;
hdmitx_device.HWOp.turn_off = hdmitx_turnoff;
hdmitx_device.HWOp.list_support_modes = hdmitx_list_support_modes;
hdmitx_device.HWOp.dump_regs = dump_regs;
@@ -2441,6 +2502,9 @@ static void hdmitx_set_hw(struct hdmitx_dev* hdev)
hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 0, 3, 1);
msleep(1);
hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 1, 3, 1);
+
+ /* hdmi/dvi switching */
+ hdmitx_dvi_config(hdev->dvimode);
}
// Use this self-made function rather than %, because % appears to produce wrong