diff options
author | Yi Zhou <yi.zhou@amlogic.com> | 2019-03-30 23:19:05 +0800 |
---|---|---|
committer | Dongjin Kim <tobetter@gmail.com> | 2019-05-16 13:20:53 +0900 |
commit | 55dddc516956acc858e5b08e4b88c9b4564eb491 (patch) | |
tree | 7a50a9f72da5d82f489571c67778fcd710c76e57 | |
parent | f226acc75019a0ca421d033a31b63706f35170d3 (diff) | |
download | u-boot-odroid-c1-55dddc516956acc858e5b08e4b88c9b4564eb491.tar.gz |
hdmitx: hdmitx bringup for tm2 [2/3]
PD#SWPL-5617
Problem:
hdmitx bringup for tm2
Solution:
hdmitx bringup for tm2, add chip id
Verify:
tm2 ptm / T962E2
Change-Id: I4188787168a3c7ebb8b65b840df16d9c22d3302d
Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
-rw-r--r-- | arch/arm/cpu/armv8/tm2/hdmitx20/enc_clk_config.c | 74 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_reg.h | 37 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_set.c | 666 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_tvenc.c | 26 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/tm2/hdmitx20/mach_reg.h | 21 | ||||
-rw-r--r-- | board/amlogic/configs/tm2_skt_v1.h | 2 |
6 files changed, 780 insertions, 46 deletions
diff --git a/arch/arm/cpu/armv8/tm2/hdmitx20/enc_clk_config.c b/arch/arm/cpu/armv8/tm2/hdmitx20/enc_clk_config.c index 63e990d67a..ed299943fc 100644 --- a/arch/arm/cpu/armv8/tm2/hdmitx20/enc_clk_config.c +++ b/arch/arm/cpu/armv8/tm2/hdmitx20/enc_clk_config.c @@ -176,6 +176,34 @@ static bool set_hpll_hclk_v3(unsigned int m, unsigned int frac_val) return ret; /* return hpll locked status */ } +#define IS_DONGLE_MODE(hdev) \ + ((hdev->dongle_mode) \ + && (hdev->para->cs == HDMI_COLOR_FORMAT_422 \ + || hdev->para->cd == HDMI_COLOR_DEPTH_24B) \ + && (hdev->vic == HDMI_1280x720p50_16x9 \ + || hdev->vic == HDMI_1280x720p60_16x9 \ + || hdev->vic == HDMI_1920x1080i60_16x9 \ + || hdev->vic == HDMI_1920x1080i50_16x9 \ + || hdev->vic == HDMI_1920x1080p60_16x9 \ + || hdev->vic == HDMI_1920x1080p50_16x9)) + +static void set_hpll_hclk_dongle_5940m(void) +{ + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x0b3a04f7); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x3, 28, 2); + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x10000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00100140); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x2a295c00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x65771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); +} + static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) { unsigned int frac_rate = 1; @@ -186,6 +214,10 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) switch (clk) { case 5940000: + if (IS_DONGLE_MODE(hdev)) { + set_hpll_hclk_dongle_5940m(); + break; + } if (set_hpll_hclk_v1(0xf7, frac_rate ? 0x8148 : 0x10000, hdev)) break; else if (set_hpll_hclk_v2(0x7b,0x18000)) @@ -209,9 +241,24 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); break; + case 4897000: + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b0004cc); + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x0000d560); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x6a685c00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x43231290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x29272000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x56540028); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + pr_info("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + break; case 4455000: hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b0004b9); - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00014000); + if (frac_rate) + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x0000e10e); + else + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00014000); hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x6a685c00); hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x43231290); @@ -225,7 +272,10 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) break; case 3712500: hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b00049a); - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00016000); + if (frac_rate) + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x000110e1); + else + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00016000); hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x6a685c00); hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x43231290); @@ -251,7 +301,10 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) break; case 3243240: hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b000487); - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x0000451f); + if (frac_rate) + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00000000); + else + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x0000451f); hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x0a691c00); hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x33771290); @@ -263,7 +316,10 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) break; case 2970000: hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b00047b); - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00018000); + if (frac_rate) + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x000140b4); + else + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00018000); hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x0a691c00); hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x33771290); @@ -277,7 +333,10 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) break; case 4324320: hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b0004b4); - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00000000); + if (frac_rate) + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00000000); + else + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00005c29); hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x0a691c00); hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x33771290); @@ -317,6 +376,8 @@ static void set_hpll_sspll(struct hdmitx_dev *hdev) hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 1, 8, 1); /* 2: 1000ppm 1: 500ppm */ hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 2, 4, 4); + if (hdev->dongle_mode) + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 4, 4, 4); /* bit[15] hdmi_dpll_sdmnc_en */ hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL3, 0, 15, 1); hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0, 29, 1); @@ -393,6 +454,9 @@ static void set_hpll_od3_clk_div(int div_sel) int shift_val = 0; int shift_sel = 0; + /* new added in TM2 */ + hd_set_reg_bits(P_HHI_LVDS_TX_PHY_CNTL1, 1, 29, 1); + /* When div 6.25, need to reset vid_pll_div */ if (div_sel == CLK_UTIL_VID_PLL_DIV_6p25) { msleep(1); diff --git a/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_reg.h b/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_reg.h index 30f617d939..af8486801d 100644 --- a/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_reg.h +++ b/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_reg.h @@ -46,8 +46,8 @@ void aocec_wr_reg(unsigned long addr, unsigned long data); #define TOP_SEC_OFFSET_MASK ((TOP_OFFSET_MASK) | (SEC_OFFSET)) #define DWC_OFFSET_MASK (0x10UL << 24) #define DWC_SEC_OFFSET_MASK ((DWC_OFFSET_MASK) | (SEC_OFFSET)) -#define HDMITX_DWC_BASE_OFFSET 0xFF600000 -#define HDMITX_TOP_BASE_OFFSET 0xFF608000 +#define HDMITX_DWC_BASE_OFFSET 0xFF670000 +#define HDMITX_TOP_BASE_OFFSET 0xFF678000 /* Bit 7 RW Reserved. Default 1. */ /* Bit 6 RW Reserved. Default 1. */ @@ -181,12 +181,14 @@ void aocec_wr_reg(unsigned long addr, unsigned long data); #define HDMITX_TOP_EMP_STAT0 (TOP_OFFSET_MASK + 0x023) #define HDMITX_TOP_EMP_STAT1 (TOP_OFFSET_MASK + 0x024) #define HDMITX_TOP_AXI_ASYNC_CNTL0 (TOP_OFFSET_MASK + 0x025) -#define HDMITX_TOP_AXI_ASYNC_CNTL1 (TOP_OFFSET_MASK + 0x026) +#define HDMITX_TOP_AXI_ASYNC_HOLD_EMP (TOP_OFFSET_MASK + 0x026) #define HDMITX_TOP_AXI_ASYNC_STAT0 (TOP_OFFSET_MASK + 0x027) #define HDMITX_TOP_I2C_BUSY_CNT_MAX (TOP_OFFSET_MASK + 0x028) #define HDMITX_TOP_I2C_BUSY_CNT_STAT (TOP_OFFSET_MASK + 0x029) #define HDMITX_TOP_HDCP22_BSOD (TOP_OFFSET_MASK + 0x02A) #define HDMITX_TOP_DDC_CNTL (TOP_OFFSET_MASK + 0x02B) +#define HDMITX_TOP_AXI_ASYNC_HOLD_ESM (TOP_OFFSET_MASK + 0x02C) +#define HDMITX_TOP_DISABLE_NULL (TOP_OFFSET_MASK + 0x030) #define HDMITX_TOP_REVOCMEM_ADDR_S (TOP_OFFSET_MASK + 0x2000 >> 2) #define HDMITX_TOP_REVOCMEM_ADDR_E (TOP_OFFSET_MASK + 0x365E >> 2) @@ -682,6 +684,35 @@ void aocec_wr_reg(unsigned long addr, unsigned long data); #define HDMITX_DWC_FC_NVBI_PB25 (DWC_OFFSET_MASK + 0x1162) #define HDMITX_DWC_FC_NVBI_PB26 (DWC_OFFSET_MASK + 0x1163) #define HDMITX_DWC_FC_NVBI_PB27 (DWC_OFFSET_MASK + 0x1164) +#define HDMITX_DWC_FC_DRM_HB01 (DWC_OFFSET_MASK + 0x1168) +#define HDMITX_DWC_FC_DRM_HB02 (DWC_OFFSET_MASK + 0x1169) +#define HDMITX_DWC_FC_DRM_PB00 (DWC_OFFSET_MASK + 0x116A) +#define HDMITX_DWC_FC_DRM_PB01 (DWC_OFFSET_MASK + 0x116B) +#define HDMITX_DWC_FC_DRM_PB02 (DWC_OFFSET_MASK + 0x116C) +#define HDMITX_DWC_FC_DRM_PB03 (DWC_OFFSET_MASK + 0x116D) +#define HDMITX_DWC_FC_DRM_PB04 (DWC_OFFSET_MASK + 0x116E) +#define HDMITX_DWC_FC_DRM_PB05 (DWC_OFFSET_MASK + 0x116F) +#define HDMITX_DWC_FC_DRM_PB06 (DWC_OFFSET_MASK + 0x1170) +#define HDMITX_DWC_FC_DRM_PB07 (DWC_OFFSET_MASK + 0x1171) +#define HDMITX_DWC_FC_DRM_PB08 (DWC_OFFSET_MASK + 0x1172) +#define HDMITX_DWC_FC_DRM_PB09 (DWC_OFFSET_MASK + 0x1173) +#define HDMITX_DWC_FC_DRM_PB10 (DWC_OFFSET_MASK + 0x1174) +#define HDMITX_DWC_FC_DRM_PB11 (DWC_OFFSET_MASK + 0x1175) +#define HDMITX_DWC_FC_DRM_PB12 (DWC_OFFSET_MASK + 0x1176) +#define HDMITX_DWC_FC_DRM_PB13 (DWC_OFFSET_MASK + 0x1177) +#define HDMITX_DWC_FC_DRM_PB14 (DWC_OFFSET_MASK + 0x1178) +#define HDMITX_DWC_FC_DRM_PB15 (DWC_OFFSET_MASK + 0x1179) +#define HDMITX_DWC_FC_DRM_PB16 (DWC_OFFSET_MASK + 0x117A) +#define HDMITX_DWC_FC_DRM_PB17 (DWC_OFFSET_MASK + 0x117B) +#define HDMITX_DWC_FC_DRM_PB18 (DWC_OFFSET_MASK + 0x117C) +#define HDMITX_DWC_FC_DRM_PB19 (DWC_OFFSET_MASK + 0x117D) +#define HDMITX_DWC_FC_DRM_PB20 (DWC_OFFSET_MASK + 0x117E) +#define HDMITX_DWC_FC_DRM_PB21 (DWC_OFFSET_MASK + 0x117F) +#define HDMITX_DWC_FC_DRM_PB22 (DWC_OFFSET_MASK + 0x1180) +#define HDMITX_DWC_FC_DRM_PB23 (DWC_OFFSET_MASK + 0x1181) +#define HDMITX_DWC_FC_DRM_PB24 (DWC_OFFSET_MASK + 0x1182) +#define HDMITX_DWC_FC_DRM_PB25 (DWC_OFFSET_MASK + 0x1183) +#define HDMITX_DWC_FC_DRM_PB26 (DWC_OFFSET_MASK + 0x1184) #define HDMITX_DWC_FC_DBGFORCE (DWC_OFFSET_MASK + 0x1200) #define HDMITX_DWC_FC_DBGAUD0CH0 (DWC_OFFSET_MASK + 0x1201) diff --git a/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_set.c b/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_set.c index 01ed7d321c..e372a1e470 100644 --- a/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_set.c +++ b/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_set.c @@ -65,16 +65,17 @@ static int hdmitx_get_hpd_state(void) { int st = 0; - st = !!(hd_read_reg(P_PREG_PAD_GPIO3_I) & (1 << 2)); + st = !!(hd_read_reg(P_PREG_PAD_GPIO2_I) & (1 << 16)); return st; } static void ddc_pinmux_init(void) { - hd_set_reg_bits(P_PAD_PULL_UP_EN_REG3, 0, 0, 2); // Disable GPIOH_1/2 pull-up/down - hd_set_reg_bits(P_PAD_PULL_UP_REG3, 0, 0, 2); - hd_set_reg_bits(P_PREG_PAD_GPIO3_EN_N, 3, 0, 2); // GPIOH_1/2 input - hd_set_reg_bits(P_PERIPHS_PIN_MUX_B, 0x11, 0, 8); // Mux DDC SDA/SCL + hd_set_reg_bits(P_PAD_PULL_UP_EN_REG2, 0, 23, 2); // Disable GPIOH_23/24 pull-up/down + hd_set_reg_bits(P_PAD_PULL_UP_REG2, 0, 23, 2); + hd_set_reg_bits(P_PREG_PAD_GPIO2_EN_N, 3, 23, 2); // GPIOH_23/24 input + hd_set_reg_bits(P_PERIPHS_PIN_MUX_9, 1, 28, 4); // Mux DDC SDA/SCL + hd_set_reg_bits(P_PERIPHS_PIN_MUX_6, 1, 16, 4); } static void hdelay(int us) @@ -186,30 +187,37 @@ static void hdmitx_hw_init(void) /* * Note: read 8 Bytes of EDID data every time */ -static int read_edid_8bytes(unsigned char *rx_edid, unsigned char addr) +static int read_edid_8bytes(unsigned char *rx_edid, unsigned char addr, + unsigned char blk_no) { unsigned int timeout = 0; unsigned int i = 0; // Program SLAVE/SEGMENT/ADDR hdmitx_wr_reg(HDMITX_DWC_I2CM_SLAVE, 0x50); hdmitx_wr_reg(HDMITX_DWC_I2CM_SEGADDR, 0x30); - hdmitx_wr_reg(HDMITX_DWC_I2CM_SEGPTR, 0); - hdmitx_wr_reg(HDMITX_DWC_I2CM_ADDRESS, addr & 0xff); - hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 1 << 3); + hdmitx_wr_reg(HDMITX_DWC_I2CM_SEGPTR, 1); + hdmitx_wr_reg(HDMITX_DWC_I2CM_ADDRESS, addr); + if (blk_no < 2) + hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 1 << 2); + else + hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 1 << 3); timeout = 0; - while ((!(hdmitx_rd_reg(HDMITX_DWC_IH_I2CM_STAT0) & (1 << 1))) && (timeout < 3)) { - mdelay(2); + while ((!(hdmitx_rd_reg(HDMITX_DWC_IH_I2CM_STAT0) & (1 << 1))) && (timeout < 5)) { + _udelay(1000); timeout ++; } - if (timeout == 3) { + if (timeout == 5) { printk("ddc timeout\n"); return 0; } + _udelay(1000); + /* add extra delay time for reading segment block */ + if (blk_no >= 2) + _udelay(1000); hdmitx_wr_reg(HDMITX_DWC_IH_I2CM_STAT0, 1 << 1); // clear INT // Read back 8 bytes - for (i = 0; i < 8; i ++) { + for (i = 0; i < 8; i ++) rx_edid[i] = hdmitx_rd_reg(HDMITX_DWC_I2CM_READ_BUFF0 + i); - } return 1; } @@ -257,12 +265,14 @@ static void ddc_init(void) hdmitx_wr_reg(HDMITX_DWC_I2CM_SCDC_UPDATE, data32); } -static int hdmitx_read_edid(unsigned char *buf, unsigned char addr, unsigned char size) +static int hdmitx_read_edid(unsigned char *buf, unsigned char addr, + unsigned char blk_no) { + unsigned char test_data[8]; + hdmitx_hw_init(); ddc_init(); - if ((addr + size) > 256) - return 0; - return read_edid_8bytes(buf, addr); + read_edid_8bytes(test_data, (addr + 0 * 128) & 0xff, 0); + return read_edid_8bytes(buf, (addr + blk_no * 128) & 0xff, blk_no); } static void scdc_rd_sink(unsigned char adr, unsigned char *val) @@ -338,6 +348,7 @@ static struct hdmi_support_mode gxbb_modes[] = { {HDMI_720x480p60_16x9, "480p60hz", 0}, {HDMI_720x576i50_16x9, "576i50hz", 0}, {HDMI_720x480i60_16x9, "480i60hz", 0}, + {HDMIV_1440x2560p60hz, "1440x2560p60hz", 0}, }; static void hdmitx_list_support_modes(void) @@ -394,6 +405,12 @@ static void hdmitx_output_blank(unsigned int blank) void hdmi_tx_init(void) { + char *dongle_mode = NULL; + + dongle_mode = getenv("dongle_mode"); + if (dongle_mode && (dongle_mode[0] == '1')) + hdmitx_device.dongle_mode = 1; + hdmitx_device.HWOp.get_hpd_state = hdmitx_get_hpd_state; hdmitx_device.HWOp.read_edid = hdmitx_read_edid; hdmitx_device.HWOp.turn_off = hdmitx_turnoff; @@ -499,6 +516,10 @@ static void config_hdmi20_tx ( enum hdmi_vic vic, struct hdmi_format_para *para, data32 |= (0 << 0); hdmitx_wr_reg(HDMITX_TOP_BIST_CNTL, data32); + /*disable null package*/ + data32 = 0x7; + hdmitx_wr_reg(HDMITX_TOP_DISABLE_NULL, data32); + /* Configure video */ // Configure video sampler @@ -868,6 +889,9 @@ static void config_hdmi20_tx ( enum hdmi_vic vic, struct hdmi_format_para *para, data32 |= (0 << 0); hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF3, data32); + if (para->vic >= HDMITX_VESA_OFFSET) + hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, 0); + else hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, para->vic); /* the audio setting bellow are only used for I2S audio IEC60958-3 frame @@ -1115,16 +1139,20 @@ static void hdmitx_set_pll(struct hdmitx_dev *hdev) hdmitx_set_clk(hdev); } -static void set_phy_by_mode(unsigned int mode) +static void set_phy_by_mode(struct hdmitx_dev *hdev, unsigned int mode) { switch (mode) { case 1: /* 5.94/4.5/3.7Gbps */ hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb65c4); + if (hdev->dongle_mode) + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb5584); hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x0000080b); break; case 2: /* 2.97Gbps */ hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb6262); + if (hdev->dongle_mode) + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb4262); hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x00000003); break; @@ -1149,18 +1177,18 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_4096x2160p60_256x135: if ((hdev->para->cs == HDMI_COLOR_FORMAT_420) && (hdev->para->cd == HDMI_COLOR_DEPTH_24B)) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_3840x2160p50_16x9_Y420: case HDMI_3840x2160p60_16x9_Y420: case HDMI_4096x2160p50_256x135_Y420: case HDMI_4096x2160p60_256x135_Y420: if (hdev->para->cd == HDMI_COLOR_DEPTH_24B) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_3840x2160p24_16x9: case HDMI_3840x2160p24_64x27: @@ -1173,9 +1201,9 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_4096x2160p30_256x135: if ((hdev->para->cs == HDMI_COLOR_FORMAT_422) || (hdev->para->cd == HDMI_COLOR_DEPTH_24B)) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_1920x1080p60_16x9: case HDMI_1920x1080p50_16x9: @@ -1184,7 +1212,7 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_1280x720p100_16x9: case HDMI_1280x720p120_16x9: default: - set_phy_by_mode(3); + set_phy_by_mode(hdev, 3); break; } /* P_HHI_HDMI_PHY_CNTL1 bit[1]: enable clock bit[0]: soft reset */ @@ -2048,8 +2076,158 @@ static void hdmi_tvenc_set_def(enum hdmi_vic vic) hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); } +static void hdmi_tvenc_vesa_set(enum hdmi_vic vic) +{ + unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2; + unsigned long TOTAL_PIXELS = 0, PIXEL_REPEAT_HDMI = 0, + PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 0; + unsigned FRONT_PORCH = 0, HSYNC_PIXELS = 0, ACTIVE_LINES = 0, + INTERLACE_MODE = 0, TOTAL_LINES = 0, SOF_LINES = 0, + VSYNC_LINES = 0; + unsigned LINES_F0 = 0, LINES_F1 = 0, BACK_PORCH = 0; + + unsigned long total_pixels_venc = 0; + unsigned long active_pixels_venc = 0; + unsigned long front_porch_venc = 0; + unsigned long hsync_pixels_venc = 0; + + unsigned long de_h_begin = 0, de_h_end = 0; + unsigned long de_v_begin_even = 0, de_v_end_even = 0, + de_v_begin_odd = 0, de_v_end_odd = 0; + unsigned long hs_begin = 0, hs_end = 0; + unsigned long vs_adjust = 0; + unsigned long vs_bline_evn = 0, vs_eline_evn = 0, + vs_bline_odd = 0, vs_eline_odd = 0; + unsigned long vso_begin_evn = 0, vso_begin_odd = 0; + struct hdmi_format_para *vpara = NULL; + struct hdmi_cea_timing *vtiming = NULL; + + vpara = hdmi_get_fmt_paras(vic); + if (vpara == NULL) { + pr_info("hdmitx: don't find Paras for VESA %d\n", vic); + return; + } else + vtiming = &vpara->timing; + + INTERLACE_MODE = 0; + PIXEL_REPEAT_VENC = 0; + PIXEL_REPEAT_HDMI = 0; + ACTIVE_PIXELS = vtiming->h_active; + ACTIVE_LINES = vtiming->v_active; + LINES_F0 = vtiming->v_total; + LINES_F1 = vtiming->v_total; + FRONT_PORCH = vtiming->h_front; + HSYNC_PIXELS = vtiming->h_sync; + BACK_PORCH = vtiming->h_back; + VSYNC_LINES = vtiming->v_sync; + SOF_LINES = vtiming->v_back; + + TOTAL_PIXELS = (FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS); + TOTAL_LINES = (LINES_F0+(LINES_F1*INTERLACE_MODE)); + + total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) * + (1+PIXEL_REPEAT_VENC); + active_pixels_venc = (ACTIVE_PIXELS / (1+PIXEL_REPEAT_HDMI)) * + (1+PIXEL_REPEAT_VENC); + front_porch_venc = (FRONT_PORCH / (1+PIXEL_REPEAT_HDMI)) * + (1+PIXEL_REPEAT_VENC); + hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) * + (1+PIXEL_REPEAT_VENC); + + hd_write_reg(P_ENCP_VIDEO_MODE, hd_read_reg(P_ENCP_VIDEO_MODE)|(1<<14)); + /* Program DE timing */ + de_h_begin = modulo(hd_read_reg(P_ENCP_VIDEO_HAVON_BEGIN) + + VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc); + de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc); + hd_write_reg(P_ENCP_DE_H_BEGIN, de_h_begin); /* 220 */ + hd_write_reg(P_ENCP_DE_H_END, de_h_end); /* 1660 */ + /* Program DE timing for even field */ + de_v_begin_even = hd_read_reg(P_ENCP_VIDEO_VAVON_BLINE); + de_v_end_even = de_v_begin_even + ACTIVE_LINES; + hd_write_reg(P_ENCP_DE_V_BEGIN_EVEN, de_v_begin_even); + hd_write_reg(P_ENCP_DE_V_END_EVEN, de_v_end_even); /* 522 */ + /* Program DE timing for odd field if needed */ + if (INTERLACE_MODE) { + de_v_begin_odd = to_signed( + (hd_read_reg(P_ENCP_VIDEO_OFLD_VOAV_OFST) + & 0xf0)>>4) + de_v_begin_even + (TOTAL_LINES-1)/2; + de_v_end_odd = de_v_begin_odd + ACTIVE_LINES; + hd_write_reg(P_ENCP_DE_V_BEGIN_ODD, de_v_begin_odd); + hd_write_reg(P_ENCP_DE_V_END_ODD, de_v_end_odd); + } + + /* Program Hsync timing */ + if (de_h_end + front_porch_venc >= total_pixels_venc) { + hs_begin = de_h_end + front_porch_venc - total_pixels_venc; + vs_adjust = 1; + } else { + hs_begin = de_h_end + front_porch_venc; + vs_adjust = 0; + } + hs_end = modulo(hs_begin + hsync_pixels_venc, total_pixels_venc); + hd_write_reg(P_ENCP_DVI_HSO_BEGIN, hs_begin); + hd_write_reg(P_ENCP_DVI_HSO_END, hs_end); + + /* Program Vsync timing for even field */ + if (de_v_begin_even >= SOF_LINES + VSYNC_LINES + (1-vs_adjust)) + vs_bline_evn = de_v_begin_even - SOF_LINES - VSYNC_LINES - + (1-vs_adjust); + else + vs_bline_evn = TOTAL_LINES + de_v_begin_even - SOF_LINES - + VSYNC_LINES - (1-vs_adjust); + vs_eline_evn = modulo(vs_bline_evn + VSYNC_LINES, TOTAL_LINES); + hd_write_reg(P_ENCP_DVI_VSO_BLINE_EVN, vs_bline_evn); /* 5 */ + hd_write_reg(P_ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); /* 11 */ + vso_begin_evn = hs_begin; /* 1692 */ + hd_write_reg(P_ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); /* 1692 */ + hd_write_reg(P_ENCP_DVI_VSO_END_EVN, vso_begin_evn); /* 1692 */ + /* Program Vsync timing for odd field if needed */ + if (INTERLACE_MODE) { + vs_bline_odd = de_v_begin_odd-1 - SOF_LINES - VSYNC_LINES; + vs_eline_odd = de_v_begin_odd-1 - SOF_LINES; + vso_begin_odd = modulo(hs_begin + (total_pixels_venc>>1), + total_pixels_venc); + hd_write_reg(P_ENCP_DVI_VSO_BLINE_ODD, vs_bline_odd); + hd_write_reg(P_ENCP_DVI_VSO_ELINE_ODD, vs_eline_odd); + hd_write_reg(P_ENCP_DVI_VSO_BEGIN_ODD, vso_begin_odd); + hd_write_reg(P_ENCP_DVI_VSO_END_ODD, vso_begin_odd); + } + + switch (vic) { + case HDMIV_640x480p60hz: + hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | + (0 << 1) | + (0 << 2) | + (0 << 3) | + (0 << 4) | + (4 << 5) | + (0 << 8) | + (0 << 12) + ); + hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); + break; + default: + hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | + (0 << 1) | /* [ 1] src_sel_encp */ + (HSYNC_POLARITY << 2) | + (VSYNC_POLARITY << 3) | + (0 << 4) | + (4 << 5) | + (0 << 8) | + (0 << 12) + ); + hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); + } + hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); +} static void hdmi_tvenc_set(enum hdmi_vic vic) { + if ((vic & HDMITX_VESA_OFFSET) == HDMITX_VESA_OFFSET) { + /* VESA modes setting */ + hdmi_tvenc_vesa_set(vic); + return; + } + switch (vic) { case HDMI_720x480i60_16x9: case HDMI_720x576i50_16x9: @@ -2301,6 +2479,442 @@ static void hdmitx_set_vsi_pkt(enum hdmi_vic vic) hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 4, 1); } +static void hdmitx_set_packet(int type, unsigned char *DB, unsigned char *HB) +{ + unsigned int i; + + switch (type) { + case HDMI_PACKET_VEND: + if ((!DB) || (!HB)) { + hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 0, 3, 1); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, 0x0); + return; + } + hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID0, DB[0]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID1, DB[1]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID2, DB[2]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD0, DB[3]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, HB[2]); + if (DB[3] == 0x20) { /* set HDMI VIC */ + hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, 0); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1, DB[4]); + } + if (HB[2] == 0x1b) {/*set dolby vsif data information*/ + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1, DB[4]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD2, DB[5]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD3, DB[6]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD4, DB[7]); + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD5, DB[8]); + } + + /*set hdr 10+ vsif data information*/ + if ((DB[0] == 0x8b) && (DB[1] == 0x84) && (DB[2] == 0x90)) { + for (i = 0; i < 23; i++) + hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1 + i, + DB[4 + i]); + } + + /* Enable VSI packet */ + hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 1, 3, 1); + hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO1, 0); + hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO2, 0x10); + hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 4, 1); + break; + case HDMI_PACKET_DRM: + if ((!DB) || (!HB)) { + hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 0, 6, 1); + hdmitx_set_reg_bits( + HDMITX_DWC_FC_PACKET_TX_EN, 0, 7, 1); + return; + } + /* Ignore HB[0] */ + hdmitx_wr_reg(HDMITX_DWC_FC_DRM_HB01, HB[1]); + hdmitx_wr_reg(HDMITX_DWC_FC_DRM_HB02, HB[2]); + for (i = 0; i < 26; i++) + hdmitx_wr_reg(HDMITX_DWC_FC_DRM_PB00 + i, DB[i]); + hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 1, 6, 1); + hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 7, 1); + break; + default: + break; + } +} + +static int hdmitx_cntl_config(struct hdmitx_dev *hdev, unsigned int cmd, + unsigned int argv) +{ + int ret = 0; + + switch (cmd) { + case CONF_AVI_BT2020: + if (argv == SET_AVI_BT2020) { + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 3, 6, 2); + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 6, 4, 3); + } + if (argv == CLR_AVI_BT2020) {/*bt709*/ + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 2, 6, 2); + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 0, 4, 3); + } + break; + case CONF_AVI_RGBYCC_INDIC: + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0, argv, 0, 2); + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0, 0, 7, 1); + break; + case CONF_AVI_Q01: + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, argv, 2, 2); + break; + case CONF_AVI_YQ01: + hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF3, argv, 2, 2); + break; + default: + break; + } + + return ret; +} + +#define GET_LOW8BIT(a) ((a) & 0xff) +#define GET_HIGH8BIT(a) (((a) >> 8) & 0xff) +void hdmitx_set_drm_pkt(struct master_display_info_s *data) +{ + struct hdmitx_dev *hdev = &hdmitx_device; + unsigned char DRM_HB[3] = {0x87, 0x1, 26}; + unsigned char DRM_DB[26] = {0x0}; + unsigned int hdr_transfer_feature = 0; + unsigned int hdr_color_feature = 0; + unsigned int hdr_mode = 0; + /* + *hdr_color_feature: bit 23-16: color_primaries + * 1:bt709 0x9:bt2020 + *hdr_transfer_feature: bit 15-8: transfer_characteristic + * 1:bt709 0xe:bt2020-10 0x10:smpte-st-2084 0x12:hlg(todo) + */ + if (data) { + hdr_transfer_feature = (data->features >> 8) & 0xff; + hdr_color_feature = (data->features >> 16) & 0xff; + } + + DRM_DB[1] = 0x0; + DRM_DB[2] = GET_LOW8BIT(data->primaries[0][0]); + DRM_DB[3] = GET_HIGH8BIT(data->primaries[0][0]); + DRM_DB[4] = GET_LOW8BIT(data->primaries[0][1]); + DRM_DB[5] = GET_HIGH8BIT(data->primaries[0][1]); + DRM_DB[6] = GET_LOW8BIT(data->primaries[1][0]); + DRM_DB[7] = GET_HIGH8BIT(data->primaries[1][0]); + DRM_DB[8] = GET_LOW8BIT(data->primaries[1][1]); + DRM_DB[9] = GET_HIGH8BIT(data->primaries[1][1]); + DRM_DB[10] = GET_LOW8BIT(data->primaries[2][0]); + DRM_DB[11] = GET_HIGH8BIT(data->primaries[2][0]); + DRM_DB[12] = GET_LOW8BIT(data->primaries[2][1]); + DRM_DB[13] = GET_HIGH8BIT(data->primaries[2][1]); + DRM_DB[14] = GET_LOW8BIT(data->white_point[0]); + DRM_DB[15] = GET_HIGH8BIT(data->white_point[0]); + DRM_DB[16] = GET_LOW8BIT(data->white_point[1]); + DRM_DB[17] = GET_HIGH8BIT(data->white_point[1]); + DRM_DB[18] = GET_LOW8BIT(data->luminance[0]); + DRM_DB[19] = GET_HIGH8BIT(data->luminance[0]); + DRM_DB[20] = GET_LOW8BIT(data->luminance[1]); + DRM_DB[21] = GET_HIGH8BIT(data->luminance[1]); + DRM_DB[22] = GET_LOW8BIT(data->max_content); + DRM_DB[23] = GET_HIGH8BIT(data->max_content); + DRM_DB[24] = GET_LOW8BIT(data->max_frame_average); + DRM_DB[25] = GET_HIGH8BIT(data->max_frame_average); + + + /* SMPTE ST 2084 and (BT2020 or NON_STANDARD) */ + if (hdr_transfer_feature == T_SMPTE_ST_2084 && + hdr_color_feature == C_BT2020) + hdr_mode = 1; + else if (hdr_transfer_feature == T_SMPTE_ST_2084 && + hdr_color_feature != C_BT2020) + hdr_mode = 2; + + /*HLG and BT2020*/ + if (hdr_color_feature == C_BT2020 && + (hdr_transfer_feature == T_BT2020_10 || + hdr_transfer_feature == T_HLG)) + hdr_mode = 3; + + switch (hdr_mode) { + case 1: + /*standard HDR*/ + DRM_DB[0] = 0x02; /* SMPTE ST 2084 */ + hdmitx_set_packet(HDMI_PACKET_DRM, DRM_DB, DRM_HB); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, SET_AVI_BT2020); + break; + case 2: + /*non standard*/ + DRM_DB[0] = 0x02; /* no standard SMPTE ST 2084 */ + hdmitx_set_packet(HDMI_PACKET_DRM, DRM_DB, DRM_HB); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, CLR_AVI_BT2020); + break; + case 3: + /*HLG*/ + DRM_DB[0] = 0x03;/* HLG is 0x03 */ + hdmitx_set_packet(HDMI_PACKET_DRM, DRM_DB, DRM_HB); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, SET_AVI_BT2020); + break; + case 0: + default: + /*other case*/ + hdmitx_set_packet(HDMI_PACKET_DRM, NULL, NULL); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, CLR_AVI_BT2020); + break; + } +} + +void hdmitx_set_vsif_pkt(enum eotf_type type, + enum mode_type tunnel_mode, struct dv_vsif_para *data) +{ + struct hdmitx_dev *hdev = &hdmitx_device; + struct dv_vsif_para para = {0}; + unsigned char VEN_HB[3] = {0x81, 0x01}; + unsigned char VEN_DB1[24] = {0x00}; + unsigned char VEN_DB2[27] = {0x00}; + unsigned char len = 0; + unsigned int vic = hdev->vic; + unsigned int hdmi_vic_4k_flag = 0; + + if ((hdev->RXCap.dv_info.ieeeoui != DV_IEEE_OUI)) + return; + + hdev->hdmi_current_eotf_type = type; + hdev->hdmi_current_tunnel_mode = tunnel_mode; + /*ver0 and ver1_15 and ver1_12bit with ll= 0 use hdmi 1.4b VSIF*/ + if ((hdev->RXCap.dv_info.ver == 0) || ((hdev->RXCap.dv_info.ver == 1) + && (hdev->RXCap.dv_info.length == 0xE)) + || ((hdev->RXCap.dv_info.ver == 1) + && (hdev->RXCap.dv_info.length == 0xB) + && (hdev->RXCap.dv_info.low_latency == 0))) { + if ((vic == HDMI_3840x2160p30_16x9) || + (vic == HDMI_3840x2160p25_16x9) || + (vic == HDMI_3840x2160p24_16x9) || + (vic == HDMI_4096x2160p24_256x135)) + hdmi_vic_4k_flag = 1; + + switch (type) { + case EOTF_T_DOLBYVISION: + len = 0x18; + break; + case EOTF_T_HDR10: + case EOTF_T_SDR: + case EOTF_T_NULL: + default: + len = 0x05; + break; + } + + VEN_HB[2] = len; + VEN_DB1[0] = 0x03; + VEN_DB1[1] = 0x0c; + VEN_DB1[2] = 0x00; + VEN_DB1[3] = 0x00; + + if (hdmi_vic_4k_flag) { + VEN_DB1[3] = 0x20; + if (vic == HDMI_3840x2160p30_16x9) + VEN_DB1[4] = 0x1; + else if (vic == HDMI_3840x2160p25_16x9) + VEN_DB1[4] = 0x2; + else if (vic == HDMI_3840x2160p24_16x9) + VEN_DB1[4] = 0x3; + else/*vic == HDMI_4096x2160p24_256x135*/ + VEN_DB1[4] = 0x4; + } + if (type == EOTF_T_DOLBYVISION) { + hdmitx_set_packet(HDMI_PACKET_VEND, VEN_DB1, VEN_HB); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + CLR_AVI_BT2020);/*BT709*/ + if (tunnel_mode == RGB_8BIT) { + hdmitx_cntl_config(hdev,CONF_AVI_RGBYCC_INDIC, + HDMI_COLOR_FORMAT_RGB); + hdmitx_cntl_config(hdev, CONF_AVI_Q01, + RGB_RANGE_FUL); + } else { + hdmitx_cntl_config(hdev, CONF_AVI_RGBYCC_INDIC, + HDMI_COLOR_FORMAT_422); + hdmitx_cntl_config(hdev, CONF_AVI_YQ01, + YCC_RANGE_FUL); + } + } else { + if (hdmi_vic_4k_flag) + hdmitx_set_packet(HDMI_PACKET_VEND, VEN_DB1, VEN_HB); + else + hdmitx_set_packet(HDMI_PACKET_VEND, NULL, NULL); + hdmitx_cntl_config(hdev, CONF_AVI_RGBYCC_INDIC, + hdev->para->cs); + hdmitx_cntl_config(hdev, CONF_AVI_Q01, RGB_RANGE_LIM); + hdmitx_cntl_config(hdev, CONF_AVI_YQ01, + YCC_RANGE_LIM); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + CLR_AVI_BT2020);/*BT709*/ + } + + } + /*ver1_12 with low_latency = 1 and ver2 use Dolby VSIF*/ + if ((hdev->RXCap.dv_info.ver == 2) || ((hdev->RXCap.dv_info.ver == 1) + && (hdev->RXCap.dv_info.length == 0xB) + && (hdev->RXCap.dv_info.low_latency == 1)) + || (type == EOTF_T_LL_MODE)) { + + if (data == NULL) + data = ¶ + /*4k vsif package */ + if ((vic == HDMI_3840x2160p30_16x9) || + (vic == HDMI_3840x2160p25_16x9) || + (vic == HDMI_3840x2160p24_16x9) || + (vic == HDMI_4096x2160p24_256x135)) + hdmi_vic_4k_flag = 1; + + switch (type) { + case EOTF_T_DOLBYVISION: + case EOTF_T_LL_MODE: + len = 0x1b; + break; + case EOTF_T_HDR10: + case EOTF_T_SDR: + case EOTF_T_NULL: + default: + len = 0x5; + break; + } + VEN_HB[2] = len; + VEN_DB2[0] = 0x46; + VEN_DB2[1] = 0xd0; + VEN_DB2[2] = 0x00; + VEN_DB2[3] = (data->vers.ver2.low_latency) | + (data->vers.ver2.dobly_vision_signal << 1); + VEN_DB2[4] = (data->vers.ver2.eff_tmax_PQ_hi) + | (data->vers.ver2.auxiliary_MD_present << 6) + | (data->vers.ver2.backlt_ctrl_MD_present << 7); + VEN_DB2[5] = data->vers.ver2.eff_tmax_PQ_low; + VEN_DB2[6] = data->vers.ver2.auxiliary_runmode; + VEN_DB2[7] = data->vers.ver2.auxiliary_runversion; + VEN_DB2[8] = data->vers.ver2.auxiliary_debug0; + + /*Dolby Vision standard case*/ + if (type == EOTF_T_DOLBYVISION) { + hdmitx_set_packet(HDMI_PACKET_VEND, VEN_DB2, VEN_HB); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + CLR_AVI_BT2020);/*BT709*/ + if (tunnel_mode == RGB_8BIT) {/*RGB444*/ + hdmitx_cntl_config(hdev, CONF_AVI_RGBYCC_INDIC, + HDMI_COLOR_FORMAT_RGB); + hdmitx_cntl_config(hdev, CONF_AVI_Q01, + RGB_RANGE_FUL); + } else {/*YUV422*/ + hdmitx_cntl_config(hdev, CONF_AVI_RGBYCC_INDIC, + HDMI_COLOR_FORMAT_422); + hdmitx_cntl_config(hdev, CONF_AVI_YQ01, + YCC_RANGE_FUL); + } + } + /*Dolby Vision low-latency case*/ + else if (type == EOTF_T_LL_MODE) { + hdmitx_set_packet(HDMI_PACKET_VEND, VEN_DB2, VEN_HB); + if (hdev->RXCap.colorimetry_data & 0xe0) + /*if RX support BT2020, then output BT2020*/ + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + SET_AVI_BT2020);/*BT2020*/ + else + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + CLR_AVI_BT2020);/*BT709*/ + if (tunnel_mode == RGB_10_12BIT) {/*10/12bit RGB444*/ + hdmitx_cntl_config(hdev, CONF_AVI_RGBYCC_INDIC, + HDMI_COLOR_FORMAT_RGB); + hdmitx_cntl_config(hdev, CONF_AVI_Q01, + RGB_RANGE_LIM); + } else if (tunnel_mode == YUV444_10_12BIT) { + /*10/12bit YUV444*/ + hdmitx_cntl_config(hdev, + CONF_AVI_RGBYCC_INDIC, + HDMI_COLOR_FORMAT_444); + hdmitx_cntl_config(hdev, CONF_AVI_YQ01, + YCC_RANGE_LIM); + } else {/*YUV422*/ + hdmitx_cntl_config(hdev, + CONF_AVI_RGBYCC_INDIC, + HDMI_COLOR_FORMAT_422); + hdmitx_cntl_config(hdev, CONF_AVI_YQ01, + YCC_RANGE_LIM); + } + } + /*SDR case*/ + else { + if (hdmi_vic_4k_flag) { + VEN_DB1[0] = 0x03; + VEN_DB1[1] = 0x0c; + VEN_DB1[2] = 0x00; + hdmitx_set_packet(HDMI_PACKET_VEND, + VEN_DB2, VEN_HB); + } else + hdmitx_set_packet(HDMI_PACKET_VEND, + NULL, NULL); + hdmitx_cntl_config(hdev, + CONF_AVI_RGBYCC_INDIC, hdev->para->cs); + hdmitx_cntl_config(hdev, + CONF_AVI_Q01, RGB_RANGE_LIM); + hdmitx_cntl_config(hdev, + CONF_AVI_YQ01, YCC_RANGE_LIM); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + CLR_AVI_BT2020);/*BT709*/ + } + } +} + +void hdmitx_set_hdr10plus_pkt(unsigned int flag, + struct hdr10plus_para *data) +{ + struct hdmitx_dev *hdev = &hdmitx_device; + unsigned char VEN_HB[3] = {0x81, 0x01, 0x1b}; + unsigned char VEN_DB[27] = {0x00}; + + if ((!data) || (!flag)) { + hdmitx_set_packet(HDMI_PACKET_VEND, NULL, NULL); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + CLR_AVI_BT2020); + return; + } + + VEN_DB[0] = 0x8b; + VEN_DB[1] = 0x84; + VEN_DB[2] = 0x90; + + VEN_DB[3] = ((data->application_version & 0x3) << 6) | + ((data->targeted_max_lum & 0x1f) << 1); + VEN_DB[4] = data->average_maxrgb; + VEN_DB[5] = data->distribution_values[0]; + VEN_DB[6] = data->distribution_values[1]; + VEN_DB[7] = data->distribution_values[2]; + VEN_DB[8] = data->distribution_values[3]; + VEN_DB[9] = data->distribution_values[4]; + VEN_DB[10] = data->distribution_values[5]; + VEN_DB[11] = data->distribution_values[6]; + VEN_DB[12] = data->distribution_values[7]; + VEN_DB[13] = data->distribution_values[8]; + VEN_DB[14] = ((data->num_bezier_curve_anchors & 0xf) << 4) | + ((data->knee_point_x >> 6) & 0xf); + VEN_DB[15] = ((data->knee_point_x & 0x3f) << 2) | + ((data->knee_point_y >> 8) & 0x3); + VEN_DB[16] = data->knee_point_y & 0xff; + VEN_DB[17] = data->bezier_curve_anchors[0]; + VEN_DB[18] = data->bezier_curve_anchors[1]; + VEN_DB[19] = data->bezier_curve_anchors[2]; + VEN_DB[20] = data->bezier_curve_anchors[3]; + VEN_DB[21] = data->bezier_curve_anchors[4]; + VEN_DB[22] = data->bezier_curve_anchors[5]; + VEN_DB[23] = data->bezier_curve_anchors[6]; + VEN_DB[24] = data->bezier_curve_anchors[7]; + VEN_DB[25] = data->bezier_curve_anchors[8]; + VEN_DB[26] = ((data->graphics_overlay_flag & 0x1) << 7)| + ((data->no_delay_flag & 0x1) << 6); + + hdmitx_set_packet(HDMI_PACKET_VEND, VEN_DB, VEN_HB); + hdmitx_cntl_config(hdev, CONF_AVI_BT2020, + SET_AVI_BT2020); + +} + /* record HDMITX current format */ /* ISA_DEBUG_REG0 0x2600 * bit[11]: Y420 diff --git a/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_tvenc.c b/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_tvenc.c index 25aebf5dca..e4b16828ef 100644 --- a/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_tvenc.c +++ b/arch/arm/cpu/armv8/tm2/hdmitx20/hdmitx_tvenc.c @@ -605,6 +605,31 @@ static const struct reg_t tvregs_4k2k_smpte_30hz[] = { {MREG_END_MARKER, 0}, }; +static const struct reg_t tvregs_vesa_1440x2560p60hz[] = { + {P_ENCP_VIDEO_EN, 0,}, + {P_ENCI_VIDEO_EN, 0,}, + + {P_ENCP_VIDEO_MODE, 0x4040,}, + {P_ENCP_VIDEO_MODE_ADV, 0x18,}, + {P_ENCP_VIDEO_MAX_PXCNT, 0x623,}, + {P_ENCP_VIDEO_MAX_LNCNT, 0xA23,}, + {P_ENCP_VIDEO_HAVON_BEGIN, 0x44,}, + {P_ENCP_VIDEO_HAVON_END, 0x5E3,}, + {P_ENCP_VIDEO_VAVON_BLINE, 0x14,}, + {P_ENCP_VIDEO_VAVON_ELINE, 0xA13,}, + {P_ENCP_VIDEO_HSO_BEGIN, 0x0,}, + {P_ENCP_VIDEO_HSO_END, 0x4,}, + {P_ENCP_VIDEO_VSO_BEGIN, 0x1E,}, + {P_ENCP_VIDEO_VSO_END, 0x32,}, + {P_ENCP_VIDEO_VSO_BLINE, 0x0,}, + {P_ENCP_VIDEO_VSO_ELINE, 0x4,}, + + {P_VPU_VIU_VENC_MUX_CTRL, 0xA}, + {P_ENCP_VIDEO_EN, 1,}, + {P_ENCI_VIDEO_EN, 0,}, + {MREG_END_MARKER, 0} +}; + struct vic_tvregs_set { enum hdmi_vic vic; const struct reg_t *reg_setting; @@ -643,6 +668,7 @@ static struct vic_tvregs_set tvregsTab[] = { {HDMI_3840x2160p50_16x9, tvregs_4k2k_25hz}, {HDMI_3840x2160p60_16x9_Y420, tvregs_4k2k_30hz}, {HDMI_3840x2160p50_16x9_Y420, tvregs_4k2k_25hz}, + {HDMIV_1440x2560p60hz, tvregs_vesa_1440x2560p60hz}, }; static inline void setreg(const struct reg_t *r) diff --git a/arch/arm/cpu/armv8/tm2/hdmitx20/mach_reg.h b/arch/arm/cpu/armv8/tm2/hdmitx20/mach_reg.h index 06b7d18f4f..ca9f00fc02 100644 --- a/arch/arm/cpu/armv8/tm2/hdmitx20/mach_reg.h +++ b/arch/arm/cpu/armv8/tm2/hdmitx20/mach_reg.h @@ -151,6 +151,14 @@ unsigned sec_reg_read(unsigned *addr); #define P_RESET5_MASK CBUS_REG_ADDR(0x415) #define P_RESET6_MASK CBUS_REG_ADDR(0x416) + +#define P_HHI_HDMI_PHY_CNTL0 HHI_MEM_REG_ADDR(0x05) +#define P_HHI_HDMI_PHY_CNTL1 HHI_MEM_REG_ADDR(0x06) +#define P_HHI_HDMI_PHY_CNTL2 HHI_MEM_REG_ADDR(0x07) +#define P_HHI_HDMI_PHY_CNTL3 HHI_MEM_REG_ADDR(0x08) +#define P_HHI_HDMI_PHY_CNTL4 HHI_MEM_REG_ADDR(0x09) +#define P_HHI_HDMI_PHY_CNTL5 HHI_MEM_REG_ADDR(0x0a) +#define P_HHI_HDMI_PHY_STATUS HHI_MEM_REG_ADDR(0x0d) /* Gated clock enables. * There are 64 enables for the MPEG clocks and 32 enables for other * clock domains. @@ -223,8 +231,8 @@ unsigned sec_reg_read(unsigned *addr); #define P_HHI_NAND_CLK_CNTL HHI_MEM_REG_ADDR(0x97) #define P_HHI_ISP_LED_CLK_CNTL HHI_MEM_REG_ADDR(0x98) #define P_HHI_SD_EMMC_CLK_CNTL HHI_MEM_REG_ADDR(0x99) -#define P_HHI_WAVE420L_CLK_CNTL HHI_MEM_REG_ADDR(0x9a) -#define P_HHI_WAVE420L_CLK_CNTL2 HHI_MEM_REG_ADDR(0x9b) +#define P_HHI_LVDS_TX_PHY_CNTL0 HHI_MEM_REG_ADDR(0x9a) +#define P_HHI_LVDS_TX_PHY_CNTL1 HHI_MEM_REG_ADDR(0x9b) #define P_HHI_EDP_TX_PHY_CNTL0 HHI_MEM_REG_ADDR(0x9c) #define P_HHI_EDP_TX_PHY_CNTL1 HHI_MEM_REG_ADDR(0x9d) #define P_HHI_MPLL_CNTL0 HHI_MEM_REG_ADDR(0x9e) @@ -287,21 +295,12 @@ unsigned sec_reg_read(unsigned *addr); #define P_HHI_DIF_CSI_PHY_CNTL3 HHI_MEM_REG_ADDR(0xdb) #define P_HHI_DIF_CSI_PHY_CNTL4 HHI_MEM_REG_ADDR(0xdc) #define P_HHI_DIF_CSI_PHY_CNTL5 HHI_MEM_REG_ADDR(0xdd) -#define P_HHI_LVDS_TX_PHY_CNTL0 HHI_MEM_REG_ADDR(0xde) -#define P_HHI_LVDS_TX_PHY_CNTL1 HHI_MEM_REG_ADDR(0xdf) #define P_HHI_VID2_PLL_CNTL HHI_MEM_REG_ADDR(0xe0) #define P_HHI_VID2_PLL_CNTL2 HHI_MEM_REG_ADDR(0xe1) #define P_HHI_VID2_PLL_CNTL3 HHI_MEM_REG_ADDR(0xe2) #define P_HHI_VID2_PLL_CNTL4 HHI_MEM_REG_ADDR(0xe3) #define P_HHI_VID2_PLL_CNTL5 HHI_MEM_REG_ADDR(0xe4) #define P_HHI_VID2_PLL_CNTL_I HHI_MEM_REG_ADDR(0xe5) -#define P_HHI_HDMI_PHY_CNTL0 HHI_MEM_REG_ADDR(0xe8) -#define P_HHI_HDMI_PHY_CNTL1 HHI_MEM_REG_ADDR(0xe9) -#define P_HHI_HDMI_PHY_CNTL2 HHI_MEM_REG_ADDR(0xea) -#define P_HHI_HDMI_PHY_CNTL3 HHI_MEM_REG_ADDR(0xeb) -#define P_HHI_HDMI_PHY_CNTL4 HHI_MEM_REG_ADDR(0xec) -#define P_HHI_HDMI_PHY_CNTL5 HHI_MEM_REG_ADDR(0xed) -#define P_HHI_HDMI_PHY_STATUS HHI_MEM_REG_ADDR(0xee) #define P_HHI_VID_LOCK_CLK_CNTL HHI_MEM_REG_ADDR(0xf2) #define P_HHI_ATV_DMD_SYS_CLK_CNTL HHI_MEM_REG_ADDR(0xf3) #define P_HHI_AXI_PIPEL_CNTL HHI_MEM_REG_ADDR(0xf4) diff --git a/board/amlogic/configs/tm2_skt_v1.h b/board/amlogic/configs/tm2_skt_v1.h index 4e29a1c471..29b6b40fdf 100644 --- a/board/amlogic/configs/tm2_skt_v1.h +++ b/board/amlogic/configs/tm2_skt_v1.h @@ -437,7 +437,7 @@ #define CONFIG_VPU_CLK_LEVEL_DFT 7 /* DISPLAY & HDMITX */ -//#define CONFIG_AML_HDMITX20 1 +#define CONFIG_AML_HDMITX20 1 #define CONFIG_AML_CANVAS 1 #define CONFIG_AML_VOUT 1 #define CONFIG_AML_OSD 1 |