diff options
author | Joy Cho <joy.cho@hardkernel.com> | 2019-01-11 09:39:04 +0900 |
---|---|---|
committer | Dongjin Kim <tobetter@gmail.com> | 2020-02-10 22:49:50 +0900 |
commit | 686d7003114979732e2afff15b85745a34cec4ea (patch) | |
tree | a6f1dba77fb98b3d39929a5442a7af4522dc620c /arch | |
parent | 9e53299712e2e7e621123c42b28bcdc5bb7d08ae (diff) | |
download | u-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.c | 64 |
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 |