| // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| /* |
| * Copyright (c) 2019 Amlogic, Inc. All rights reserved. |
| */ |
| |
| #include <common.h> |
| #include <asm/io.h> |
| #include <amlogic/media/vout/aml_vout.h> |
| #include <amlogic/media/vout/hdmitx/hdmitx.h> |
| #include <amlogic/auge_sound.h> |
| #include "hdmitx_drv.h" |
| |
| #ifdef CONFIG_VENDOR_NAME |
| const static char *vend_name = CONFIG_VENDOR_NAME; /* Max 8 bytes */ |
| #else |
| const static char *vend_name = "Amlogic"; /* Max 8 bytes */ |
| #endif |
| |
| #ifdef CONFIG_PRODUCT_NAME |
| const static char *prod_desc = CONFIG_PRODUCT_NAME; /* Max 16 bytes */ |
| #else |
| const static char *prod_desc = "MBox Meson Ref"; /* Max 16 bytes */ |
| #endif |
| |
| static struct hdmitx_dev hdmitx_device; |
| |
| DECLARE_GLOBAL_DATA_PTR; |
| |
| struct hdmitx_dev *hdmitx_get_hdev(void) |
| { |
| return &hdmitx_device; |
| } |
| |
| static void hdmi_tvenc_set(enum hdmi_vic vic); |
| extern void _udelay(unsigned int us); |
| static void set_tmds_clk_div40(unsigned int div40); |
| |
| #define HSYNC_POLARITY 1 /*HSYNC polarity: active high*/ |
| #define VSYNC_POLARITY 1 /*VSYNC polarity: active high*/ |
| |
| /*Pixel format: 0=RGB444; 1=YCbCr422; 2=YCbCr444; 3=YCbCr420.*/ |
| #define TX_INPUT_COLOR_FORMAT HDMI_COLOR_FORMAT_444 |
| /*Pixel range: 0=limited; 1=full.*/ |
| #define TX_INPUT_COLOR_RANGE HDMI_COLOR_RANGE_LIM |
| /*Pixel range: 0=limited; 1=full.*/ |
| #define TX_OUTPUT_COLOR_RANGE HDMI_COLOR_RANGE_LIM |
| |
| static void hdelay(int us) |
| { |
| _udelay(us * 1000); |
| } |
| |
| #define mdelay(i) hdelay(i) |
| #define msleep(i) hdelay(i) |
| |
| static void hdmitx_set_hw(struct hdmitx_dev *hdev); |
| static int hdmitx_set_audmode(struct hdmitx_dev *hdev); |
| |
| /*Internal functions:*/ |
| static void hdmitx_csc_config (unsigned char input_color_format, |
| unsigned char output_color_format, |
| unsigned char color_depth); |
| |
| static void dump_regs(void) |
| { |
| unsigned int reg_adr; |
| unsigned int reg_val; |
| unsigned int ladr; |
| |
| for (reg_adr = 0x0000; reg_adr < 0x0100; reg_adr++) { |
| ladr = PERIPHS_REG_ADDR(0x0) + (reg_adr << 2); |
| reg_val = hd_read_reg(ladr); |
| printk("[0x%08x] = 0x%X\n", hd_get_paddr(ladr), reg_val); |
| } |
| for (reg_adr = 0x0000; reg_adr < 0x0100; reg_adr++) { |
| ladr = HHI_REG_ADDR(0x0) + (reg_adr << 2); |
| reg_val = hd_read_reg(ladr); |
| printk("[0x%08x] = 0x%X\n", hd_get_paddr(ladr), reg_val); |
| } |
| for (reg_adr = 0x0000; reg_adr < 0x0100; reg_adr++) { |
| ladr = ANACTRL_REG_ADDR(0x0) + (reg_adr << 2); |
| reg_val = hd_read_reg(ladr); |
| printk("[0x%08x] = 0x%X\n", hd_get_paddr(ladr), reg_val); |
| } |
| #define VPU_REG_ADDR(reg) ((VCBUS_REG_IDX << BASE_REG_OFFSET) + (reg << 2)) |
| for (reg_adr = 0x1b00; reg_adr < 0x1c00; reg_adr++) { |
| ladr = VPU_REG_ADDR(reg_adr); |
| reg_val = hd_read_reg(ladr); |
| printk("[0x%08x] = 0x%X\n", hd_get_paddr(ladr), reg_val); |
| } |
| for (reg_adr = 0x1c01; reg_adr < 0x1d00; reg_adr++) { |
| ladr = VPU_REG_ADDR(reg_adr); |
| reg_val = hd_read_reg(ladr); |
| printk("[0x%08x] = 0x%X\n", hd_get_paddr(ladr), reg_val); |
| } |
| for (reg_adr = 0x2700; reg_adr < 0x2780; reg_adr++) { |
| ladr = VPU_REG_ADDR(reg_adr); |
| reg_val = hd_read_reg(ladr); |
| printk("[0x%08x] = 0x%X\n", hd_get_paddr(ladr), reg_val); |
| } |
| for (reg_adr = HDMITX_TOP_SW_RESET; reg_adr < HDMITX_TOP_DONT_TOUCH1 + 1; reg_adr++) { |
| reg_val = hdmitx_rd_reg(reg_adr); |
| printk("TOP[0x%x]: 0x%x\n", reg_adr, reg_val); |
| } |
| for (reg_adr = HDMITX_DWC_DESIGN_ID; reg_adr < HDMITX_DWC_I2CM_SCDC_UPDATE1 + 1; reg_adr++) { |
| if ((reg_adr > (DWC_OFFSET_MASK + 0x5016)) && (reg_adr < (DWC_OFFSET_MASK + 0x7800))) |
| reg_val = 0;//hdmitx_rd_reg(reg_adr); |
| else |
| reg_val = hdmitx_rd_reg(reg_adr); |
| if (reg_val) |
| printk("hdmitx: [0x%x]: 0x%x\n", reg_adr, reg_val); |
| } |
| } |
| |
| static void hdmitx_hw_init(void) |
| { |
| static int hw_init_flag; |
| |
| if (hw_init_flag) |
| return; |
| else |
| hw_init_flag = 1; |
| |
| /* Enable clocks and bring out of reset */ |
| |
| /* Enable hdmitx_sys_clk */ |
| /* .clk0 ( cts_oscin_clk ), */ |
| /* .clk1 ( fclk_div4 ), */ |
| /* .clk2 ( fclk_div3 ), */ |
| /* .clk3 ( fclk_div5 ), */ |
| hd_set_reg_bits(P_CLKCTRL_HDMI_CLK_CTRL, 0x0100, 0, 16); |
| |
| /* Enable clk81_hdmitx_pclk */ |
| hd_set_reg_bits(P_CLKCTRL_SYS_CLK_EN0_REG2, 1, 4, 1); |
| |
| /* wire wr_enable = control[3]; */ |
| /* wire fifo_enable = control[2]; */ |
| /* assign phy_clk_en = control[1]; */ |
| /* Enable tmds_clk */ |
| /* Bring HDMITX MEM output of power down */ |
| hd_set_reg_bits(P_PWRCTRL_MEM_PD11, 0, 8, 8); |
| /* reset HDMITX APB & TX & PHY */ |
| |
| /* Refer to SC2-system-Registers.docx */ |
| hd_write_reg(P_RESETCTRL_RESET0, 1 << 29); /* hdmi_tx */ |
| hd_write_reg(P_RESETCTRL_RESET0, 1 << 22); /* hdmitxphy */ |
| hd_write_reg(P_RESETCTRL_RESET0, 1 << 19); /* vid_pll_div */ |
| hd_write_reg(P_RESETCTRL_RESET0, 1 << 16); /* hdmitx_apb */ |
| |
| /* Bring out of reset */ |
| hdmitx_wr_reg(HDMITX_TOP_SW_RESET, 0); |
| _udelay(200); |
| /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */ |
| hdmitx_wr_reg(HDMITX_TOP_CLK_CNTL, 0x000000ff); |
| |
| hdmitx_wr_reg(HDMITX_DWC_MC_LOCKONCLOCK, 0xff); |
| |
| hdmitx_wr_reg(HDMITX_DWC_MC_CLKDIS, 0x00); |
| /*disable null package*/ |
| hdmitx_wr_reg(HDMITX_TOP_DISABLE_NULL, 0x7); |
| } |
| |
| /* |
| * Note: read 8 Bytes of EDID data every time |
| */ |
| 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, 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 < 5)) { |
| mdelay(1); |
| timeout ++; |
| } |
| if (timeout == 5) { |
| printk("ddc timeout\n"); |
| return 0; |
| } |
| /* add extra delay time for reading segment block */ |
| if (blk_no >= 2) |
| mdelay(1); |
| hdmitx_wr_reg(HDMITX_DWC_IH_I2CM_STAT0, 1 << 1); /*clear INT*/ |
| /*Read back 8 bytes*/ |
| for (i = 0; i < 8; i ++) { |
| rx_edid[i] = hdmitx_rd_reg(HDMITX_DWC_I2CM_READ_BUFF0 + i); |
| } |
| return 1; |
| } |
| |
| static void ddc_init_(void) |
| { |
| static int ddc_init_flag; |
| unsigned int data32 = 0; |
| |
| hdmitx_hw_init(); |
| if (ddc_init_flag) |
| return; |
| else |
| ddc_init_flag = 1; |
| |
| hdmitx_ddc_init(); |
| |
| data32 = 0; |
| data32 |= (0 << 6); /*[ 6] read_req_mask*/ |
| data32 |= (0 << 2); /*[ 2] done_mask*/ |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_INT, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 6); /*[ 6] nack_mask*/ |
| data32 |= (0 << 2); /*[ 2] arbitration_error_mask*/ |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_CTLINT, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 3); /*[ 3] i2c_fast_mode: 0=standard mode; 1=fast mode.*/ |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_DIV, data32); |
| |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_HCNT_1, 0); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_HCNT_0, 0xcf); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_LCNT_1, 0); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SS_SCL_LCNT_0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_HCNT_1, 0); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_HCNT_0, 0x0f); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_LCNT_1, 0); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_FS_SCL_LCNT_0, 0x20); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SDA_HOLD, 0x08); |
| |
| data32 = 0; |
| data32 |= (0 << 5); /*[ 5] updt_rd_vsyncpoll_en*/ |
| data32 |= (0 << 4); /*[ 4] read_request_en scdc*/ |
| data32 |= (0 << 0); /*[ 0] read_update*/ |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SCDC_UPDATE, data32); |
| } |
| |
| static int hdmitx_read_edid(unsigned char *buf, unsigned char addr, |
| unsigned char blk_no) |
| { |
| ddc_init_(); |
| return read_edid_8bytes(buf, (addr + blk_no * 128) & 0xff, blk_no); |
| } |
| |
| static void scdc_rd_sink(unsigned char adr, unsigned char *val) |
| { |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SLAVE, 0x54); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_ADDRESS, adr); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 1); |
| _udelay(2000); |
| *val = (unsigned char)hdmitx_rd_reg(HDMITX_DWC_I2CM_DATAI); |
| } |
| |
| static void scdc_wr_sink(unsigned char adr, unsigned char val) |
| { |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_SLAVE, 0x54); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_ADDRESS, adr); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_DATAO, val); |
| hdmitx_wr_reg(HDMITX_DWC_I2CM_OPERATION, 0x10); |
| _udelay(2000); |
| } |
| |
| static void scdc_prepare(unsigned int div) |
| { |
| unsigned char rx_ver = 0; |
| |
| scdc_rd_sink(SINK_VER, &rx_ver); |
| if (rx_ver != 1) |
| scdc_rd_sink(SINK_VER, &rx_ver); /* Recheck */ |
| if (0) |
| printf("rx version is %s div=%d\n", |
| (rx_ver == 1) ? "2.0" : "1.4 or below", |
| div ? 40 : 10); |
| |
| scdc_wr_sink(SOURCE_VER, 0x1); |
| scdc_wr_sink(SOURCE_VER, 0x1); |
| scdc_wr_sink(TMDS_CFG, div ? 0x3 : 0); /* TMDS 1/40 & Scramble */ |
| scdc_wr_sink(TMDS_CFG, div ? 0x3 : 0); /* TMDS 1/40 & Scramble */ |
| } |
| |
| static struct hdmi_support_mode gxbb_modes[] = { |
| {HDMI_3840x2160p60_16x9, "2160p60hz", 0}, |
| {HDMI_3840x2160p50_16x9, "2160p50hz", 0}, |
| {HDMI_3840x2160p30_16x9, "2160p30hz", 0}, |
| {HDMI_3840x2160p25_16x9, "2160p25hz", 0}, |
| {HDMI_3840x2160p24_16x9, "2160p24hz", 0}, |
| {HDMI_4096x2160p60_256x135, "smpte60hz", 0}, |
| {HDMI_4096x2160p50_256x135, "smpte50hz", 0}, |
| {HDMI_4096x2160p30_256x135, "smpte30hz", 0}, |
| {HDMI_4096x2160p25_256x135, "smpte25hz", 0}, |
| {HDMI_4096x2160p24_256x135, "smpte24hz", 0}, |
| {HDMI_3840x2160p60_16x9, "2160p60hz420", 1}, |
| {HDMI_3840x2160p50_16x9, "2160p50hz420", 1}, |
| {HDMI_4096x2160p50_256x135, "smpte50hz420", 1}, |
| {HDMI_4096x2160p60_256x135, "smpte60hz420", 1}, |
| {HDMI_1920x1080p120_16x9, "1080p120hz", 0}, |
| {HDMI_1920x1080p60_16x9, "1080p60hz", 0}, |
| {HDMI_1920x1080p50_16x9, "1080p50hz", 0}, |
| {HDMI_1920x1080p30_16x9, "1080p30hz", 0}, |
| {HDMI_1920x1080p25_16x9, "1080p25hz", 0}, |
| {HDMI_1920x1080p24_16x9, "1080p24hz", 0}, |
| {HDMI_1920x1080i60_16x9, "1080i60hz", 0}, |
| {HDMI_1920x1080i50_16x9, "1080i50hz", 0}, |
| {HDMI_1280x720p60_16x9, "720p60hz", 0}, |
| {HDMI_1280x720p50_16x9, "720p50hz", 0}, |
| {HDMI_720x576p50_16x9, "576p50hz", 0}, |
| {HDMI_720x480p60_16x9, "480p60hz", 0}, |
| {HDMI_720x576i50_16x9, "576i50hz", 0}, |
| {HDMI_720x480i60_16x9, "480i60hz", 0}, |
| {HDMI_720x576p50_4x3, "576p50hz_4x3", 0}, |
| {HDMI_720x480p60_4x3, "480p60hz_4x3", 0}, |
| {HDMI_720x576i50_4x3, "576i50hz_4x3", 0}, |
| {HDMI_720x480i60_4x3, "480i60hz_4x3", 0}, |
| {HDMIV_1440x2560p60hz, "1440x2560p60hz", 0}, |
| {HDMIV_3440x1440p60hz, "3440x1440p60hz", 0}, |
| {HDMIV_2400x1200p90hz, "2400x1200p90hz", 0}, |
| {HDMIV_1280x1024p60hz, "1280x1024p60hz", 0}, |
| {HDMIV_1680x1050p60hz, "1680x1050p60hz", 0}, |
| {HDMIV_1024x600p60hz, "1024x600p60hz", 0}, |
| }; |
| |
| static void hdmitx_list_support_modes(void) |
| { |
| int i; |
| |
| for (i = 0; i < ARRAY_SIZE(gxbb_modes); i++) |
| printf("%s\n", gxbb_modes[i].sname); |
| } |
| |
| void hdmitx_test_bist(unsigned int mode) |
| { |
| switch (mode) { |
| case 1: |
| case 2: |
| case 3: |
| hd_set_reg_bits(P_ENCP_VIDEO_MODE_ADV, 0, 3, 1); |
| hd_write_reg(P_VENC_VIDEO_TST_EN, 1); |
| hd_write_reg(P_VENC_VIDEO_TST_MDSEL, mode); |
| break; |
| case 0: |
| default: |
| hd_set_reg_bits(P_ENCP_VIDEO_MODE_ADV, 1, 3, 1); |
| hd_write_reg(P_VENC_VIDEO_TST_EN, 0); |
| break; |
| } |
| } |
| |
| static void hdmitx_output_blank(unsigned int blank) |
| { |
| if (blank == 1) |
| hd_write_reg(P_VPU_HDMI_DATA_OVR, |
| ((1 << 31) | (1 << 29) | (1 << 9))); |
| if (blank == 0) |
| hd_write_reg(P_VPU_HDMI_DATA_OVR, 0); |
| } |
| |
| void hdmitx_set_div40(bool div40) |
| { |
| set_tmds_clk_div40(div40); |
| } |
| |
| static void hdmitx_load_dts_config(struct hdmitx_dev *hdev) |
| { |
| const void *dt_blob; |
| int node; |
| char *propdata; |
| int ret; |
| |
| hdev->limit_res_1080p = 0; |
| dt_blob = gd->fdt_blob; |
| if (dt_blob == NULL) { |
| printf("ERR: hdmitx: dt_blob is null\n"); |
| return; |
| } |
| |
| ret = fdt_check_header(dt_blob); |
| if (ret < 0) { |
| printf("ERR: hdmitx: check dts: %s\n", fdt_strerror(ret)); |
| return; |
| } |
| |
| node = fdt_path_offset(dt_blob, "/amhdmitx"); |
| if (node < 0) { |
| printf("ERR: hdmitx: not find /amhdmitx node: %s\n", fdt_strerror(node)); |
| return; |
| } |
| |
| propdata = (char *)fdt_getprop(dt_blob, node, "res_1080p", NULL); |
| if (propdata) { |
| if (!strcmp(propdata, "0")) |
| hdev->limit_res_1080p = 0; |
| else |
| hdev->limit_res_1080p = 1; |
| } else { |
| hdev->limit_res_1080p = 0; |
| } |
| printf("limit_res_1080p: %d\n", hdev->limit_res_1080p); |
| } |
| |
| void hdmitx_init(void) |
| { |
| struct hdmitx_dev *hdev = hdmitx_get_hdev(); |
| char *dongle_mode = NULL; |
| |
| dongle_mode = env_get("dongle_mode"); |
| if (dongle_mode && (dongle_mode[0] == '1')) |
| hdev->dongle_mode = 1; |
| hdev->hwop.get_hpd_state = hdmitx_get_hpd_state; |
| hdev->hwop.read_edid = hdmitx_read_edid; |
| hdev->hwop.turn_off = hdmitx_turnoff; |
| hdev->hwop.list_support_modes = hdmitx_list_support_modes; |
| hdev->hwop.dump_regs = dump_regs; |
| hdev->hwop.test_bist = hdmitx_test_bist; |
| hdev->hwop.test_prbs = hdmitx_test_prbs; |
| hdev->hwop.set_div40 = hdmitx_set_div40; |
| hdev->hwop.output_blank = hdmitx_output_blank; |
| hdmitx_load_dts_config(hdev); |
| } |
| |
| void hdmi_tx_set(struct hdmitx_dev *hdev) |
| { |
| unsigned char checksum[11]; |
| aml_audio_init(); /* Init audio hw firstly */ |
| hdmitx_hw_init(); |
| ddc_init_(); |
| hdmitx_set_hw(hdev); |
| /* add audio */ |
| hdmitx_set_audmode(hdev); |
| |
| /* null char needed to terminate the string |
| otherwise garbage in checksum logopara */ |
| memcpy(checksum, hdev->RXCap.checksum, 10); |
| checksum[10] = '\0'; |
| env_set("hdmichecksum", (const char*)checksum); |
| printf("hdmi_tx_set: save mode: %s, attr: %s, hdmichecksum: %s\n", |
| env_get("outputmode"), env_get("colorattribute"), env_get("hdmichecksum")); |
| run_command("saveenv", 0); |
| return; |
| |
| #if 0 |
| hdmi_tx_gate(vic); |
| hdmi_tx_clk(vic); |
| hdmi_tx_misc(vic); |
| hdmi_tx_enc(vic); |
| hdmi_tx_set_vend_spec_infofram(vic); |
| hdmi_tx_phy(vic); |
| #endif |
| } |
| |
| /*********************************************** |
| * parameters: mode, such as 720p60hz, 1080p50hz... |
| * frac, 1=59.94/29.97hz. |
| * return: viu_mux |
| ************************************************/ |
| unsigned int hdmi_outputmode_check(char *mode, unsigned int frac) |
| { |
| int i, ret = 0xff; |
| |
| for (i = 0; i < ARRAY_SIZE(gxbb_modes); i++) { |
| if (!strcmp(mode, gxbb_modes[i].sname)) { |
| ret = 0; |
| break; |
| } |
| } |
| |
| if (ret) { |
| //printf("hdmitx: outputmode[%s] is invalid\n", mode); |
| return VIU_MUX_MAX; |
| } |
| |
| if (frac) { |
| if (hdmitx_likely_frac_rate_mode(mode) == 0) { |
| printf("hdmitx: outputmode[%s] don't support frac\n", mode); |
| return VIU_MUX_MAX; |
| } |
| } |
| |
| if ((!strcmp(mode, "480i60hz")) || (!strcmp(mode, "576i50hz"))) |
| ret = VIU_MUX_ENCI; |
| else |
| ret = VIU_MUX_ENCP; |
| return ret; |
| } |
| |
| static int hdmitx_set_audmode(struct hdmitx_dev *hdev) |
| { |
| int i; |
| unsigned int data32; |
| unsigned int aud_n_para; |
| |
| pr_info("hdmtix: set audio\n"); |
| hdmitx_set_reg_bits(HDMITX_TOP_CLK_CNTL, 3, 2, 2); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 0, 1); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 3, 1); |
| #if 0 /* TODO */ |
| /* Disable HDMI audio clock input and its I2S input */ |
| hd_write_reg(P_AIU_HDMI_CLK_DATA_CTRL, 0); |
| |
| /* Enable HDMI I2S input from the selected source */ |
| hd_write_reg(P_AIU_HDMI_CLK_DATA_CTRL, 0x22); |
| #endif |
| /* I2S Sampler config */ |
| data32 = 0; |
| /* [ 3] fifo_empty_mask: 0=enable int; 1=mask int. */ |
| data32 |= (1 << 3); |
| /* [ 2] fifo_full_mask: 0=enable int; 1=mask int. */ |
| data32 |= (1 << 2); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_INT, data32); |
| |
| data32 = 0; |
| /* [ 4] fifo_overrun_mask: 0=enable int; 1=mask int. |
| * Enable it later when audio starts. */ |
| data32 |= (1 << 4); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_INT1, data32); |
| /* [ 5] 0=select SPDIF; 1=select I2S. */ |
| data32 = 0; |
| data32 |= (0 << 7); /* [ 7] sw_audio_fifo_rst */ |
| data32 |= (0 << 5); |
| data32 |= (0 << 0); /* [3:0] i2s_in_en: enable it later in test.c */ |
| /* if enable it now, fifo_overrun will happen, because packet don't get sent |
| * out until initial DE detected. */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CONF0, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 5); /* [7:5] i2s_mode: 0=standard I2S mode */ |
| data32 |= (24 << 0); /* [4:0] i2s_width */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CONF1, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 1); /* [ 1] NLPCM */ |
| data32 |= (0 << 0); /* [ 0] HBR */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CONF2, data32); |
| |
| /* spdif sampler config */ |
| /* [ 2] SPDIF fifo_full_mask: 0=enable int; 1=mask int. */ |
| /* [ 3] SPDIF fifo_empty_mask: 0=enable int; 1=mask int. */ |
| data32 = 0; |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT, data32); |
| /* [ 4] SPDIF fifo_overrun_mask: 0=enable int; 1=mask int. */ |
| data32 = 0; |
| data32 |= (0 << 4); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT1, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 7); /* [ 7] sw_audio_fifo_rst */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIF0, data32); |
| |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0, 0, 0, 4); /* CT */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF0, 1, 4, 3); /* CC */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF1, 0, 0, 3); /* SF */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDICONF1, 0, 4, 2); /* SS */ |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF2, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDICONF3, 0); |
| |
| /* audio packetizer config */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_INPUTCLKFS, 0); |
| |
| /* 48kHz 2ch PCM as default */ |
| aud_n_para = 6144; |
| switch (hdev->vic) { |
| case HDMI_3840x2160p24_16x9: |
| case HDMI_3840x2160p25_16x9: |
| case HDMI_3840x2160p30_16x9: |
| case HDMI_4096x2160p24_256x135: |
| case HDMI_4096x2160p25_256x135: |
| case HDMI_4096x2160p30_256x135: |
| aud_n_para = 5120; |
| break; |
| case HDMI_3840x2160p50_16x9: |
| case HDMI_3840x2160p60_16x9: |
| case HDMI_3840x2160p50_64x27: |
| case HDMI_3840x2160p60_64x27: |
| if (hdev->para->cs == HDMI_COLOR_FORMAT_420) |
| aud_n_para = 5120; |
| break; |
| default: |
| break; |
| } |
| |
| /* ACR packet configuration */ |
| data32 = 0; |
| data32 |= (1 << 7); /* [ 7] ncts_atomic_write */ |
| data32 |= (0 << 0); /* [3:0] AudN[19:16] */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_N3, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 7); /* [7:5] N_shift */ |
| data32 |= (0 << 4); /* [ 4] CTS_manual */ |
| data32 |= (0 << 0); /* [3:0] manual AudCTS[19:16] */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CTS3, data32); |
| |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CTS2, 0); /* manual AudCTS[15:8] */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CTS1, 0); /* manual AudCTS[7:0] */ |
| |
| data32 = 0; |
| data32 |= (1 << 7); /* [ 7] ncts_atomic_write */ |
| data32 |= (((aud_n_para>>16)&0xf) << 0); /* [3:0] AudN[19:16] */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_N3, data32); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_N2, (aud_n_para>>8)&0xff); /* AudN[15:8] */ |
| hdmitx_wr_reg(HDMITX_DWC_AUD_N1, aud_n_para&0xff); /* AudN[7:0] */ |
| for (i = 0; i < 9; i++) |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS0+i, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDSV, 0x11); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS7, 0x02); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS8, 0xd2); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS3, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AUDSCHNLS5, 0x00); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS7, |
| 0x2, 0, 4); /*CSB 27:24*/ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS7, 0x0, 6, 2); /*CSB 31:30*/ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS7, 0x0, 4, 2); /*CSB 29:28*/ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS8, 0x2, 0, 4); /*CSB 35:32*/ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AUDSCHNLS8, /* CSB 39:36 */ |
| 0xd, 4, 4); |
| |
| hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0, 0, 5, 1); |
| /* reset audio fifo */ |
| hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0, 1, 7, 1); |
| hdmitx_set_reg_bits(HDMITX_DWC_AUD_CONF0, 0, 7, 1); |
| hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 1, 7, 1); |
| hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 0, 7, 1); |
| hdmitx_wr_reg(HDMITX_DWC_MC_SWRSTZREQ, 0xe7); |
| /* need reset again */ |
| hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 1, 7, 1); |
| hdmitx_set_reg_bits(HDMITX_DWC_AUD_SPDIF0, 0, 7, 1); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_N1, hdmitx_rd_reg(HDMITX_DWC_AUD_N1)); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 1, 0, 1); |
| return 0; |
| } |
| |
| /* |
| * set Source Product Description InfoFrame |
| */ |
| static void hdmitx_set_spdinfo(void) |
| { |
| int i; |
| |
| if (!(vend_name && prod_desc)) |
| return; |
| |
| for (i = 0; (i < 8) && vend_name[i]; i++) |
| hdmitx_wr_reg(HDMITX_DWC_FC_SPDVENDORNAME0 + i, vend_name[i]); |
| for (i = 0; (i < 16) && prod_desc[i]; i++) |
| hdmitx_wr_reg(HDMITX_DWC_FC_SDPPRODUCTNAME0 + i, prod_desc[i]); |
| hdmitx_wr_reg(HDMITX_DWC_FC_SPDDEVICEINF, 0x1); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO0, 1, 4, 1); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO2, 1, 4, 4); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 4, 1); |
| } |
| |
| #define NUM_INT_VSYNC INT_VEC_VIU1_VSYNC |
| |
| static unsigned long modulo(unsigned long a, unsigned long b); |
| static signed int to_signed(unsigned int a); |
| |
| /*Pixel bit width: 4=24-bit; 5=30-bit; 6=36-bit; 7=48-bit. |
| *Pixel format: 0=RGB444; 1=YCbCr422; 2=YCbCr444; 3=YCbCr420. |
| *Pixel range: 0=limited; 1=full. |
| *Pixel format: 0=RGB444; 1=YCbCr422; 2=YCbCr444; 3=YCbCr420. |
| *Pixel range: 0=limited; 1=full. |
| *0:TMDS_CLK_rate=TMDS_Character_rate; 1:TMDS_CLK_rate=TMDS_Character_rate/4, |
| *for TMDS_Character_rate>340Mcsc. |
| */ |
| static void config_hdmi20_tx (struct hdmitx_dev* hdev, enum hdmi_vic vic, |
| struct hdmi_format_para *para, |
| unsigned char color_depth, unsigned char input_color_format, |
| unsigned char input_color_range, unsigned char output_color_format, |
| unsigned char output_color_range) |
| { |
| struct hdmi_cea_timing *t = ¶->timing; |
| unsigned long data32; |
| unsigned char vid_map; |
| unsigned char csc_en; |
| unsigned char default_phase = 0; |
| unsigned char tmp = 0; |
| |
| #define GET_TIMING(name) (t->name) |
| |
| hdmitx_hw_init(); |
| data32 = 0; |
| data32 |= (1 << 12); |
| data32 |= (0 << 8); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_TOP_BIST_CNTL, data32); |
| |
| /* Configure video */ |
| |
| /*Configure video sampler*/ |
| vid_map = ( input_color_format == HDMI_COLOR_FORMAT_RGB )? ((color_depth == HDMI_COLOR_DEPTH_24B)? 0x01 : |
| (color_depth == HDMI_COLOR_DEPTH_30B)? 0x03 : |
| (color_depth == HDMI_COLOR_DEPTH_36B)? 0x05 : |
| 0x07) : |
| ((input_color_format == HDMI_COLOR_FORMAT_444) || |
| (input_color_format == HDMI_COLOR_FORMAT_420))? ((color_depth == HDMI_COLOR_DEPTH_24B)? 0x09 : |
| (color_depth == HDMI_COLOR_DEPTH_30B)? 0x0b : |
| (color_depth == HDMI_COLOR_DEPTH_36B)? 0x0d : |
| 0x0f) : |
| ((color_depth == HDMI_COLOR_DEPTH_24B)? 0x16 : |
| (color_depth == HDMI_COLOR_DEPTH_30B)? 0x14 : |
| 0x12); |
| |
| data32 = 0; |
| data32 |= (0 << 7); |
| data32 |= (vid_map << 0); |
| hdmitx_wr_reg(HDMITX_DWC_TX_INVID0, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 2); |
| data32 |= (0 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_TX_INSTUFFING, data32); |
| hdmitx_wr_reg(HDMITX_DWC_TX_GYDATA0, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_TX_GYDATA1, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_TX_RCRDATA0, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_TX_RCRDATA1, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_TX_BCBDATA0, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_TX_BCBDATA1, 0x00); |
| |
| /* Configure Color Space Converter */ |
| |
| csc_en = (input_color_format != output_color_format) ? 1 : 0; |
| |
| data32 = 0; |
| data32 |= (csc_en << 0); |
| hdmitx_wr_reg(HDMITX_DWC_MC_FLOWCTRL, data32); |
| |
| data32 = 0; |
| data32 |= ((((input_color_format ==HDMI_COLOR_FORMAT_422) && |
| (output_color_format!=HDMI_COLOR_FORMAT_422))? 2 : 0 ) << 4); /*[5:4] intmode*/ |
| data32 |= ((((input_color_format !=HDMI_COLOR_FORMAT_422) && |
| (output_color_format==HDMI_COLOR_FORMAT_422))? 2 : 0 ) << 0); /*[1:0] decmode*/ |
| hdmitx_wr_reg(HDMITX_DWC_CSC_CFG, data32); |
| |
| hdmitx_csc_config(input_color_format, output_color_format, color_depth); |
| |
| /* Configure video packetizer */ |
| |
| /* Video Packet color depth and pixel repetition */ |
| data32 = 0; |
| data32 |= (((output_color_format==HDMI_COLOR_FORMAT_422)? |
| HDMI_COLOR_DEPTH_24B : color_depth) << 4); /*[7:4] color_depth*/ |
| data32 |= (0 << 0); |
| if ((data32 & 0xf0) == 0x40 ) |
| data32 &= ~(0xf << 4); |
| hdmitx_wr_reg(HDMITX_DWC_VP_PR_CD, data32); |
| if (output_color_format == HDMI_COLOR_FORMAT_422) { |
| switch (color_depth) { |
| case HDMI_COLOR_DEPTH_24B: |
| tmp = 4; |
| break; |
| default: |
| tmp = 0; |
| break; |
| } |
| hdmitx_set_reg_bits(HDMITX_DWC_VP_PR_CD, tmp, 4, 4); |
| } |
| |
| /* Video Packet Stuffing */ |
| data32 = 0; |
| data32 |= (default_phase << 5); |
| data32 |= (0 << 2); |
| data32 |= (0 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_VP_STUFF, data32); |
| |
| /* Video Packet YCC color remapping */ |
| data32 = 0; |
| hdmitx_wr_reg(HDMITX_DWC_VP_REMAP, data32); |
| if (output_color_format == HDMI_COLOR_FORMAT_422) { |
| switch (color_depth) { |
| case HDMI_COLOR_DEPTH_36B: |
| tmp = 2; |
| break; |
| case HDMI_COLOR_DEPTH_30B: |
| tmp = 1; |
| break; |
| case HDMI_COLOR_DEPTH_24B: |
| tmp = 0; |
| break; |
| } |
| } |
| hdmitx_set_reg_bits(HDMITX_DWC_VP_REMAP, tmp, 0, 2); /*[1:0] ycc422_size*/ |
| |
| /* Video Packet configuration */ |
| data32 = 0; |
| data32 |= ((((output_color_format != HDMI_COLOR_FORMAT_422) && |
| (color_depth == HDMI_COLOR_DEPTH_24B))? 1 : 0) << 6); /*[ 6] bypass_en*/ |
| data32 |= ((((output_color_format == HDMI_COLOR_FORMAT_422) || |
| (color_depth == HDMI_COLOR_DEPTH_24B))? 0 : 1) << 5); /*[ 5] pp_en*/ |
| data32 |= (0 << 4); /*[ 4] pr_en*/ |
| data32 |= (((output_color_format == HDMI_COLOR_FORMAT_422)? 1 : 0) << 3); /*[ 3] ycc422_en*/ |
| data32 |= (1 << 2); /*[ 2] pr_bypass_select*/ |
| data32 |= (((output_color_format == HDMI_COLOR_FORMAT_422)? 1 : |
| (color_depth == HDMI_COLOR_DEPTH_24B)? 2 : 0) << 0); |
| /*[1:0] output_selector: 0=pixel packing; 1=YCC422 remap; 2/3=8-bit bypass*/ |
| hdmitx_wr_reg(HDMITX_DWC_VP_CONF, data32); |
| |
| data32 = 0; |
| data32 |= (1 << 7); |
| data32 |= (1 << 6); |
| data32 |= (1 << 5); |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_VP_MASK, data32); |
| |
| /* Configure audio */ |
| /* I2S Sampler config */ |
| |
| data32 = 0; |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_INT, data32); |
| |
| data32 = 0; |
| data32 |= (1 << 4); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_INT1, data32); |
| |
| hdmitx_wr_reg(HDMITX_DWC_FC_MULTISTREAM_CTRL, 0); |
| |
| /* if enable it now, fifo_overrun will happen, because packet don't get |
| * sent out until initial DE detected. |
| */ |
| data32 = 0; |
| data32 |= (0 << 7); |
| data32 |= (1 << 5); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CONF0, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 5); |
| data32 |= (24 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CONF1, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_CONF2, data32); |
| |
| /* spdif sampler config */ |
| |
| data32 = 0; |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 4); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIFINT1, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 7); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIF0, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 7); |
| data32 |= (0 << 6); |
| data32 |= (24 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_AUD_SPDIF1, data32); |
| |
| /* Frame Composer configuration */ |
| |
| /* Video definitions, as per output video(for packet gen/schedulling) */ |
| |
| data32 = 0; |
| data32 |= (1 << 7); |
| data32 |= (GET_TIMING(vsync_polarity) << 6); |
| data32 |= (GET_TIMING(hsync_polarity) << 5); |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (!(para->progress_mode) << 1); |
| data32 |= (!(para->progress_mode) << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_INVIDCONF, data32); |
| if (!hdev->RXCap.IEEEOUI) /* DVI devices */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_INVIDCONF, 0, 3, 1); |
| |
| data32 = GET_TIMING(h_active)&0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INHACTV0, data32); |
| data32 = (GET_TIMING(h_active)>>8) & 0x3f; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INHACTV1, data32); |
| |
| data32 = GET_TIMING(h_blank) & 0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INHBLANK0, data32); |
| data32 = (GET_TIMING(h_blank)>>8)&0x1f; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INHBLANK1, data32); |
| |
| data32 = GET_TIMING(v_active)&0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INVACTV0, data32); |
| data32 = (GET_TIMING(v_active)>>8)&0x1f; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INVACTV1, data32); |
| |
| data32 = GET_TIMING(v_blank)&0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INVBLANK, data32); |
| |
| data32 = GET_TIMING(h_front)&0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINDELAY0, data32); |
| data32 = (GET_TIMING(h_front)>>8)&0x1f; |
| hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINDELAY1, data32); |
| |
| data32 = GET_TIMING(h_sync)&0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINWIDTH0, data32); |
| data32 = (GET_TIMING(h_sync)>>8)&0x3; |
| hdmitx_wr_reg(HDMITX_DWC_FC_HSYNCINWIDTH1, data32); |
| |
| data32 = GET_TIMING(v_front)&0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSYNCINDELAY, data32); |
| |
| data32 = GET_TIMING(v_sync)&0x3f; |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSYNCINWIDTH, data32); |
| |
| /* control period duration (typ 12 tmds periods) */ |
| hdmitx_wr_reg(HDMITX_DWC_FC_CTRLDUR, 12); |
| /* extended control period duration (typ 32 tmds periods) */ |
| hdmitx_wr_reg(HDMITX_DWC_FC_EXCTRLDUR, 32); |
| /* max interval betwen extended control period duration (typ 50) */ |
| hdmitx_wr_reg(HDMITX_DWC_FC_EXCTRLSPAC, 1); |
| /* preamble filler */ |
| hdmitx_wr_reg(HDMITX_DWC_FC_CH0PREAM, 0x0b); |
| hdmitx_wr_reg(HDMITX_DWC_FC_CH1PREAM, 0x16); |
| hdmitx_wr_reg(HDMITX_DWC_FC_CH2PREAM, 0x21); |
| |
| /* write GCP packet configuration */ |
| data32 = 0; |
| data32 |= (default_phase << 2); |
| data32 |= (0 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_GCP, data32); |
| |
| /* write AVI Infoframe packet configuration */ |
| |
| data32 = 0; |
| data32 |= (((output_color_format>>2)&0x1) << 7); |
| data32 |= (1 << 6); |
| data32 |= (0x2 << 4); |
| data32 |= (0 << 2); |
| data32 |= (0x2 << 0); /* FIXED YCBCR 444 */ |
| hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF0, data32); |
| switch (output_color_format) { |
| case HDMI_COLOR_FORMAT_RGB: |
| tmp = 0; |
| break; |
| case HDMI_COLOR_FORMAT_422: |
| tmp = 1; |
| break; |
| case HDMI_COLOR_FORMAT_420: |
| tmp = 3; |
| break; |
| case HDMI_COLOR_FORMAT_444: |
| default: |
| tmp = 2; |
| break; |
| } |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF0, tmp, 0, 2); |
| |
| hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF1, 0x8); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AVICONF2, 0); |
| |
| /* set Aspect Ratio in AVIInfo */ |
| switch (para->vic) { |
| case HDMI_640x480p60_4x3: |
| case HDMI_720x480p60_4x3: |
| case HDMI_720x480i60_4x3: |
| case HDMI_720x240p60_4x3: |
| case HDMI_2880x480i60_4x3: |
| case HDMI_2880x240p60_4x3: |
| case HDMI_1440x480p60_4x3: |
| case HDMI_720x576p50_4x3: |
| case HDMI_720x576i50_4x3: |
| case HDMI_720x288p_4x3: |
| case HDMI_2880x576i50_4x3: |
| case HDMI_2880x288p50_4x3: |
| case HDMI_1440x576p_4x3: |
| case HDMI_2880x480p60_4x3: |
| case HDMI_2880x576p50_4x3: |
| case HDMI_720x576p100_4x3: |
| case HDMI_720x576i100_4x3: |
| case HDMI_720x480p120_4x3: |
| case HDMI_720x480i120_4x3: |
| case HDMI_720x576p200_4x3: |
| case HDMI_720x576i200_4x3: |
| case HDMI_720x480p240_4x3: |
| case HDMI_720x480i240_4x3: |
| /* Picture Aspect Ratio M1/M0 4:3 */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 0x1, 4, 2); |
| break; |
| default: |
| /* Picture Aspect Ratio M1/M0 16:9 */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 0x2, 4, 2); |
| break; |
| } |
| /* Active Format Aspect Ratio R3~R0 Same as picture aspect ratio */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 0x8, 0, 4); |
| |
| /* set Colorimetry in AVIInfo */ |
| switch (para->vic) { |
| case HDMI_640x480p60_4x3: |
| case HDMI_720x480p60_4x3: |
| case HDMI_720x480p60_16x9: |
| case HDMI_720x480i60_4x3: |
| case HDMI_720x480i60_16x9: |
| case HDMI_720x240p60_4x3: |
| case HDMI_720x240p60_16x9: |
| case HDMI_2880x480i60_4x3: |
| case HDMI_2880x480i60_16x9: |
| case HDMI_2880x240p60_4x3: |
| case HDMI_2880x240p60_16x9: |
| case HDMI_1440x480p60_4x3: |
| case HDMI_1440x480p60_16x9: |
| case HDMI_720x576p50_4x3: |
| case HDMI_720x576p50_16x9: |
| case HDMI_720x576i50_4x3: |
| case HDMI_720x576i50_16x9: |
| case HDMI_720x288p_4x3: |
| case HDMI_720x288p_16x9: |
| case HDMI_2880x576i50_4x3: |
| case HDMI_2880x576i50_16x9: |
| case HDMI_2880x288p50_4x3: |
| case HDMI_2880x288p50_16x9: |
| case HDMI_1440x576p_4x3: |
| case HDMI_1440x576p_16x9: |
| case HDMI_2880x480p60_4x3: |
| case HDMI_2880x480p60_16x9: |
| case HDMI_2880x576p50_4x3: |
| case HDMI_2880x576p50_16x9: |
| case HDMI_720x576p100_4x3: |
| case HDMI_720x576p100_16x9: |
| case HDMI_720x576i100_4x3: |
| case HDMI_720x576i100_16x9: |
| case HDMI_720x480p120_4x3: |
| case HDMI_720x480p120_16x9: |
| case HDMI_720x480i120_4x3: |
| case HDMI_720x480i120_16x9: |
| case HDMI_720x576p200_4x3: |
| case HDMI_720x576p200_16x9: |
| case HDMI_720x576i200_4x3: |
| case HDMI_720x576i200_16x9: |
| case HDMI_720x480p240_4x3: |
| case HDMI_720x480p240_16x9: |
| case HDMI_720x480i240_4x3: |
| case HDMI_720x480i240_16x9: |
| /* C1C0 601 , now is 709*/ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 1, 6, 2); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 0, 4, 3); |
| break; |
| default: |
| /* C1C0 709 */ |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 2, 6, 2); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF2, 0, 4, 3); |
| break; |
| } |
| |
| data32 = 0; |
| data32 |= (((output_color_range == HDMI_COLOR_RANGE_FUL)?1:0) << 2); /*[3:2] YQ*/ |
| 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 |
| * insertion |
| */ |
| |
| /* packet queue priority (auto mode) */ |
| hdmitx_wr_reg(HDMITX_DWC_FC_CTRLQHIGH, 15); |
| hdmitx_wr_reg(HDMITX_DWC_FC_CTRLQLOW, 3); |
| |
| /* packet scheduller configuration for SPD, VSD, ISRC1/2, ACP. */ |
| data32 = 0; |
| data32 |= (0 << 4); |
| data32 |= (0 << 3); |
| data32 |= (0 << 2); |
| data32 |= (0 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO0, data32); |
| hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO1, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO2, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_DATMAN, 0); |
| hdmitx_set_spdinfo(); |
| |
| /* packet scheduller configuration for AVI, GCP, AUDI, ACR. */ |
| data32 = 0; |
| data32 |= (0 << 5); |
| data32 |= (0 << 4); |
| data32 |= (0 << 3); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_DATAUTO3, data32); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB0, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB1, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB2, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB3, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB4, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB5, 0); |
| /* AVI info usb RDRB mode and place in line 10*/ |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB6, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB7, 0x1a); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB8, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB9, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB10, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_RDRB11, 0); |
| |
| /* Packet transmission enable */ |
| data32 = 0; |
| data32 |= (0 << 6); |
| data32 |= (0 << 5); |
| data32 |= (0 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, data32, 0, 4); |
| |
| /* For 3D video */ |
| data32 = 0; |
| data32 |= (0 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_ACTSPC_HDLR_CFG, data32); |
| |
| data32 = GET_TIMING(v_active)&0xff; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INVACT_2D_0, data32); |
| data32 = (GET_TIMING(v_active)>>8)&0xf; |
| hdmitx_wr_reg(HDMITX_DWC_FC_INVACT_2D_1, data32); |
| |
| /* Do not enable these interrupt below, we can check them at RX side. */ |
| data32 = 0; |
| data32 |= (1 << 7); |
| data32 |= (1 << 6); |
| data32 |= (1 << 5); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_MASK0, data32); |
| |
| data32 = 0; |
| data32 |= (1 << 7); |
| data32 |= (1 << 6); |
| data32 |= (1 << 5); |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_MASK1, data32); |
| |
| data32 = 0; |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_MASK2, data32); |
| |
| /* Pixel repetition ratio the input and output video */ |
| data32 = 0; |
| data32 |= ((para->pixel_repetition_factor+1) << 4); |
| data32 |= (para->pixel_repetition_factor << 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_PRCONF, data32); |
| |
| /* Configure HDCP */ |
| data32 = 0; |
| data32 |= (0 << 7); |
| data32 |= (0 << 6); |
| data32 |= (0 << 4); |
| data32 |= (0 << 3); |
| data32 |= (0 << 2); |
| data32 |= (0 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_A_APIINTMSK, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 5); |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 1); |
| hdmitx_wr_reg(HDMITX_DWC_A_VIDPOLCFG, data32); |
| |
| hdmitx_wr_reg(HDMITX_DWC_A_OESSWCFG, 0x40); |
| hdmitx_hdcp_init(); |
| |
| /* Interrupts */ |
| /* Clear interrupts */ |
| hdmitx_wr_reg(HDMITX_DWC_IH_FC_STAT0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_FC_STAT1, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_FC_STAT2, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_AS_STAT0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_PHY_STAT0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_I2CM_STAT0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_CEC_STAT0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_VP_STAT0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_IH_I2CMPHY_STAT0, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_A_APIINTCLR, 0xff); |
| hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_STAT, 0xff); |
| |
| hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, 0x0000001f); |
| |
| /* Selectively enable/mute interrupt sources */ |
| data32 = 0; |
| data32 |= (1 << 7); |
| data32 |= (1 << 6); |
| data32 |= (1 << 5); |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_FC_STAT0, data32); |
| |
| data32 = 0; |
| data32 |= (1 << 7); |
| data32 |= (1 << 6); |
| data32 |= (1 << 5); |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_FC_STAT1, data32); |
| |
| data32 = 0; |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_FC_STAT2, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 4); |
| data32 |= (0 << 3); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_AS_STAT0, data32); |
| |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_PHY_STAT0, 0x3f); |
| |
| data32 = 0; |
| data32 |= (0 << 2); |
| data32 |= (1 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_I2CM_STAT0, data32); |
| |
| data32 = 0; |
| data32 |= (0 << 6); |
| data32 |= (0 << 5); |
| data32 |= (0 << 4); |
| data32 |= (0 << 3); |
| data32 |= (0 << 2); |
| data32 |= (0 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_CEC_STAT0, data32); |
| |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_VP_STAT0, 0xff); |
| |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE_I2CMPHY_STAT0, 0x03); |
| |
| data32 = 0; |
| data32 |= (0 << 1); |
| data32 |= (0 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_IH_MUTE, data32); |
| |
| data32 = 0; |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| data32 |= (1 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_TOP_INTR_MASKN, data32); |
| |
| /* Reset pulse */ |
| hdmitx_rd_check_reg(HDMITX_DWC_MC_LOCKONCLOCK, 0xff, 0x9f); |
| |
| hdmitx_wr_reg(HDMITX_DWC_MC_SWRSTZREQ, 0); |
| mdelay(10); |
| |
| data32 = 0; |
| data32 |= (1 << 7); |
| data32 |= (1 << 6); |
| data32 |= (1 << 4); |
| data32 |= (1 << 3); |
| data32 |= (1 << 2); |
| data32 |= (0 << 1); |
| data32 |= (1 << 0); |
| hdmitx_wr_reg(HDMITX_DWC_MC_SWRSTZREQ, data32); |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSYNCINWIDTH, |
| hdmitx_rd_reg(HDMITX_DWC_FC_VSYNCINWIDTH)); |
| } /* config_hdmi20_tx */ |
| |
| /* Set TV encoder for HDMI */ |
| static void hdmitx_enc(enum hdmi_vic vic) |
| { |
| set_vmode_enc_hw(vic); |
| hdmi_tvenc_set(vic); |
| return; |
| } |
| |
| static void hdmitx_set_pll(struct hdmitx_dev *hdev) |
| { |
| hdmitx_set_clk(hdev); |
| } |
| |
| /* |
| * mode: 1 means Progressive; 0 means interlaced |
| */ |
| static void enc_vpu_bridge_reset(int mode) |
| { |
| unsigned int wr_clk = 0; |
| |
| wr_clk = (hd_read_reg(P_VPU_HDMI_SETTING) & 0xf00) >> 8; |
| if (mode) { |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 0, 2); /*[ 0] src_sel_enci: Disable ENCP output to HDMI*/ |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 8, 4); /*[ 0] src_sel_enci: Disable ENCP output to HDMI*/ |
| mdelay(1); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, wr_clk, 8, 4); |
| mdelay(1); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 2, 0, 2); /*[ 0] src_sel_enci: Enable ENCP output to HDMI*/ |
| } else { |
| hd_write_reg(P_ENCI_VIDEO_EN, 0); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 0, 2); /*[ 0] src_sel_enci: Disable ENCI output to HDMI*/ |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 8, 4); /*[ 0] src_sel_enci: Disable ENCP output to HDMI*/ |
| mdelay(1); |
| hd_write_reg(P_ENCI_VIDEO_EN, 1); |
| mdelay(1); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, wr_clk, 8, 4); |
| mdelay(1); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 0, 2); /*[ 0] src_sel_enci: Enable ENCI output to HDMI*/ |
| } |
| } |
| |
| static void hdmi_tvenc1080i_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 = 88, HSYNC_PIXELS = 0, ACTIVE_LINES = 0, |
| INTERLACE_MODE = 0, TOTAL_LINES = 0, SOF_LINES = 0, |
| VSYNC_LINES = 0; |
| unsigned LINES_F0 = 0, LINES_F1 = 563, 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; |
| |
| if ((vic == HDMI_1920x1080i60_16x9) || |
| (vic == HDMI_1920x1080i120_16x9)) { |
| INTERLACE_MODE = 1; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (1080/(1+INTERLACE_MODE)); |
| LINES_F0 = 562; |
| LINES_F1 = 563; |
| FRONT_PORCH = 88; |
| HSYNC_PIXELS = 44; |
| BACK_PORCH = 148; |
| VSYNC_LINES = 5; |
| SOF_LINES = 15; |
| } else if ((vic == HDMI_1920x1080i50_16x9) || |
| (vic == HDMI_1920x1080i100_16x9)) { |
| INTERLACE_MODE = 1; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (1080/(1+INTERLACE_MODE)); |
| LINES_F0 = 562; |
| LINES_F1 = 563; |
| FRONT_PORCH = 528; |
| HSYNC_PIXELS = 44; |
| BACK_PORCH = 148; |
| VSYNC_LINES = 5; |
| SOF_LINES = 15; |
| } |
| 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); |
| hd_write_reg(P_ENCP_DE_H_END, de_h_end); |
| /* 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); |
| /* 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);/* 583 */ |
| hd_write_reg(P_ENCP_DE_V_END_ODD, de_v_end_odd); /* 1123 */ |
| } |
| |
| /* 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); /* 0 */ |
| hd_write_reg(P_ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); /* 5 */ |
| vso_begin_evn = hs_begin; /* 2 */ |
| hd_write_reg(P_ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); /* 2 */ |
| hd_write_reg(P_ENCP_DVI_VSO_END_EVN, vso_begin_evn); /* 2 */ |
| /* 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); |
| } |
| |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | |
| (0 << 1) | |
| (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); |
| |
| } |
| |
| static bool is_hdmi4k_420(enum hdmi_vic vic) |
| { |
| if ((vic & HDMITX_VIC420_OFFSET) == HDMITX_VIC420_OFFSET) |
| return 1; |
| return 0; |
| } |
| |
| static void hdmi_tvenc4k2k_set(enum hdmi_vic vic) |
| { |
| unsigned long VFIFO2VD_TO_HDMI_LATENCY = 2; |
| unsigned long TOTAL_PIXELS = 4400, PIXEL_REPEAT_HDMI = 0, |
| PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 3840; |
| unsigned FRONT_PORCH = 1020, HSYNC_PIXELS = 0, ACTIVE_LINES = 2160, |
| INTERLACE_MODE = 0, TOTAL_LINES = 0, SOF_LINES = 0, |
| VSYNC_LINES = 0; |
| unsigned LINES_F0 = 2250, LINES_F1 = 2250, 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; |
| unsigned long hs_begin = 0, hs_end = 0; |
| unsigned long vs_adjust = 0; |
| unsigned long vs_adjust_420 = 0; |
| unsigned long vs_bline_evn = 0, vs_eline_evn = 0; |
| unsigned long vso_begin_evn = 0; |
| |
| /* Due to 444->420 line buffer latency, the active line output from |
| * 444->420 conversion will be delayed by 1 line. So for 420 mode, |
| * we need to delay Vsync by 1 line as well, to meet the timing |
| */ |
| if (is_hdmi4k_420(vic)) |
| vs_adjust_420 = 1; |
| |
| switch (vic) { |
| case HDMI_3840x2160p30_16x9: |
| case HDMI_3840x2160p60_16x9: |
| case HDMI_3840x2160p60_16x9_Y420: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (3840*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (2160/(1+INTERLACE_MODE)); |
| LINES_F0 = 2250; |
| LINES_F1 = 2250; |
| FRONT_PORCH = 176; |
| HSYNC_PIXELS = 88; |
| BACK_PORCH = 296; |
| VSYNC_LINES = 10; |
| SOF_LINES = 72 + 1; |
| break; |
| case HDMI_3840x2160p25_16x9: |
| case HDMI_3840x2160p50_16x9: |
| case HDMI_3840x2160p50_16x9_Y420: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (3840*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (2160/(1+INTERLACE_MODE)); |
| LINES_F0 = 2250; |
| LINES_F1 = 2250; |
| FRONT_PORCH = 1056; |
| HSYNC_PIXELS = 88; |
| BACK_PORCH = 296; |
| VSYNC_LINES = 10; |
| SOF_LINES = 72 + 1; |
| break; |
| case HDMI_3840x2160p24_16x9: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (3840*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (2160/(1+INTERLACE_MODE)); |
| LINES_F0 = 2250; |
| LINES_F1 = 2250; |
| FRONT_PORCH = 1276; |
| HSYNC_PIXELS = 88; |
| BACK_PORCH = 296; |
| VSYNC_LINES = 10; |
| SOF_LINES = 72 + 1; |
| break; |
| case HDMI_4096x2160p24_256x135: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (4096*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (2160/(1+INTERLACE_MODE)); |
| LINES_F0 = 2250; |
| LINES_F1 = 2250; |
| FRONT_PORCH = 1020; |
| HSYNC_PIXELS = 88; |
| BACK_PORCH = 296; |
| VSYNC_LINES = 10; |
| SOF_LINES = 72 + 1; |
| break; |
| case HDMI_4096x2160p25_256x135: |
| case HDMI_4096x2160p50_256x135: |
| case HDMI_4096x2160p50_256x135_Y420: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (4096*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (2160/(1+INTERLACE_MODE)); |
| LINES_F0 = 2250; |
| LINES_F1 = 2250; |
| FRONT_PORCH = 968; |
| HSYNC_PIXELS = 88; |
| BACK_PORCH = 128; |
| VSYNC_LINES = 10; |
| SOF_LINES = 72; |
| break; |
| case HDMI_4096x2160p30_256x135: |
| case HDMI_4096x2160p60_256x135: |
| case HDMI_4096x2160p60_256x135_Y420: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (4096*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (2160/(1+INTERLACE_MODE)); |
| LINES_F0 = 2250; |
| LINES_F1 = 2250; |
| FRONT_PORCH = 88; |
| HSYNC_PIXELS = 88; |
| BACK_PORCH = 128; |
| VSYNC_LINES = 10; |
| SOF_LINES = 72; |
| break; |
| default: |
| printk("hdmitx20: no setting for VIC = %d\n", vic); |
| break; |
| } |
| |
| 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); |
| |
| 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); |
| hd_write_reg(P_ENCP_DE_H_END, de_h_end); |
| /* Program DE timing for even field */ |
| de_v_begin_even = hd_read_reg(P_ENCP_VIDEO_VAVON_BLINE); |
| de_v_end_even = modulo(de_v_begin_even + ACTIVE_LINES, TOTAL_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); |
| |
| /* 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 = 1; |
| } |
| 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 + vs_adjust_420 >= |
| SOF_LINES + VSYNC_LINES + (1 - vs_adjust)) |
| vs_bline_evn = de_v_begin_even + vs_adjust_420 - SOF_LINES - |
| VSYNC_LINES - (1 - vs_adjust); |
| else |
| vs_bline_evn = TOTAL_LINES + de_v_begin_even + vs_adjust_420 - |
| 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); |
| hd_write_reg(P_ENCP_DVI_VSO_ELINE_EVN, vs_eline_evn); |
| vso_begin_evn = hs_begin; |
| hd_write_reg(P_ENCP_DVI_VSO_BEGIN_EVN, vso_begin_evn); |
| hd_write_reg(P_ENCP_DVI_VSO_END_EVN, vso_begin_evn); |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | |
| (0 << 1) | |
| (HSYNC_POLARITY << 2) | |
| (VSYNC_POLARITY << 3) | |
| (0 << 4) | |
| (4 << 5) | |
| (0 << 8) | |
| (0 << 12) |
| ); |
| if (is_hdmi4k_420(vic)) { |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 8, 1); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 20, 1); |
| } |
| |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); |
| } |
| |
| static void hdmi_tvenc480i_set(enum hdmi_vic vic) |
| { |
| unsigned long VFIFO2VD_TO_HDMI_LATENCY = 1; |
| unsigned long TOTAL_PIXELS = 0, PIXEL_REPEAT_HDMI = 0, |
| PIXEL_REPEAT_VENC = 0, ACTIVE_PIXELS = 0; |
| unsigned FRONT_PORCH = 38, HSYNC_PIXELS = 124, ACTIVE_LINES = 0, |
| INTERLACE_MODE = 0, VSYNC_LINES = 0; |
| unsigned LINES_F0 = 262, LINES_F1 = 263, BACK_PORCH = 114, |
| EOF_LINES = 2; |
| |
| 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; |
| |
| /* hd_set_reg_bits(P_HHI_GCLK_OTHER, 1, 8, 1); TODO */ |
| switch (vic) { |
| case HDMI_720x480i60_4x3: |
| case HDMI_720x480i60_16x9: |
| case HDMI_720x480i120_4x3: |
| case HDMI_720x480i120_16x9: |
| case HDMI_720x480i240_4x3: |
| case HDMI_720x480i240_16x9: |
| INTERLACE_MODE = 1; |
| PIXEL_REPEAT_VENC = 1; |
| PIXEL_REPEAT_HDMI = 1; |
| ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (480/(1+INTERLACE_MODE)); |
| LINES_F0 = 262; |
| LINES_F1 = 263; |
| FRONT_PORCH = 38; |
| HSYNC_PIXELS = 124; |
| BACK_PORCH = 114; |
| EOF_LINES = 4; |
| VSYNC_LINES = 3; |
| break; |
| case HDMI_720x576i50_4x3: |
| case HDMI_720x576i50_16x9: |
| case HDMI_720x576i100_4x3: |
| case HDMI_720x576i100_16x9: |
| case HDMI_720x576i200_4x3: |
| case HDMI_720x576i200_16x9: |
| INTERLACE_MODE = 1; |
| PIXEL_REPEAT_VENC = 1; |
| PIXEL_REPEAT_HDMI = 1; |
| ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (576/(1+INTERLACE_MODE)); |
| LINES_F0 = 312; |
| LINES_F1 = 313; |
| FRONT_PORCH = 24; |
| HSYNC_PIXELS = 126; |
| BACK_PORCH = 138; |
| EOF_LINES = 2; |
| VSYNC_LINES = 3; |
| break; |
| default: |
| break; |
| } |
| |
| TOTAL_PIXELS = (FRONT_PORCH+HSYNC_PIXELS+BACK_PORCH+ACTIVE_PIXELS); |
| |
| total_pixels_venc = (TOTAL_PIXELS / (1+PIXEL_REPEAT_HDMI)) * |
| (1+PIXEL_REPEAT_VENC); /* 1716 / 2 * 2 = 1716 */ |
| 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); /* 38 / 2 * 2 = 38 */ |
| hsync_pixels_venc = (HSYNC_PIXELS / (1+PIXEL_REPEAT_HDMI)) * |
| (1+PIXEL_REPEAT_VENC); /* 124 / 2 * 2 = 124 */ |
| |
| de_h_begin = modulo(hd_read_reg(P_ENCI_VFIFO2VD_PIXEL_START) + |
| VFIFO2VD_TO_HDMI_LATENCY, total_pixels_venc); |
| de_h_end = modulo(de_h_begin + active_pixels_venc, total_pixels_venc); |
| hd_write_reg(P_ENCI_DE_H_BEGIN, de_h_begin); /* 235 */ |
| hd_write_reg(P_ENCI_DE_H_END, de_h_end); /* 1675 */ |
| |
| de_v_begin_even = hd_read_reg(P_ENCI_VFIFO2VD_LINE_TOP_START); |
| de_v_end_even = de_v_begin_even + ACTIVE_LINES; |
| de_v_begin_odd = hd_read_reg(P_ENCI_VFIFO2VD_LINE_BOT_START); |
| de_v_end_odd = de_v_begin_odd + ACTIVE_LINES; |
| hd_write_reg(P_ENCI_DE_V_BEGIN_EVEN, de_v_begin_even); |
| hd_write_reg(P_ENCI_DE_V_END_EVEN, de_v_end_even); |
| hd_write_reg(P_ENCI_DE_V_BEGIN_ODD, de_v_begin_odd); |
| hd_write_reg(P_ENCI_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_ENCI_DVI_HSO_BEGIN, hs_begin); /* 1713 */ |
| hd_write_reg(P_ENCI_DVI_HSO_END, hs_end); /* 121 */ |
| |
| /* Program Vsync timing for even field */ |
| if (de_v_end_odd-1 + EOF_LINES + vs_adjust >= LINES_F1) { |
| vs_bline_evn = de_v_end_odd-1 + EOF_LINES + vs_adjust |
| - LINES_F1; |
| vs_eline_evn = vs_bline_evn + VSYNC_LINES; |
| hd_write_reg(P_ENCI_DVI_VSO_BLINE_EVN, vs_bline_evn); |
| /* vso_bline_evn_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn); |
| /* vso_eline_evn_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_BEGIN_EVN, hs_begin); |
| hd_write_reg(P_ENCI_DVI_VSO_END_EVN, hs_begin); |
| } else { |
| vs_bline_odd = de_v_end_odd-1 + EOF_LINES + vs_adjust; |
| hd_write_reg(P_ENCI_DVI_VSO_BLINE_ODD, vs_bline_odd); |
| /* vso_bline_odd_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_BEGIN_ODD, hs_begin); |
| if (vs_bline_odd + VSYNC_LINES >= LINES_F1) { |
| vs_eline_evn = vs_bline_odd + VSYNC_LINES - LINES_F1; |
| hd_write_reg(P_ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn); |
| /* vso_eline_evn_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_END_EVN, hs_begin); |
| } else { |
| vs_eline_odd = vs_bline_odd + VSYNC_LINES; |
| hd_write_reg(P_ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd); |
| /* vso_eline_odd_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_END_ODD, hs_begin); |
| } |
| } |
| /* Program Vsync timing for odd field */ |
| if (de_v_end_even-1 + EOF_LINES + 1 >= LINES_F0) { |
| vs_bline_odd = de_v_end_even-1 + EOF_LINES + 1 - LINES_F0; |
| vs_eline_odd = vs_bline_odd + VSYNC_LINES; |
| hd_write_reg(P_ENCI_DVI_VSO_BLINE_ODD, vs_bline_odd); |
| /* vso_bline_odd_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd); |
| /* vso_eline_odd_reg_wr_cnt ++; */ |
| vso_begin_odd = modulo(hs_begin + (total_pixels_venc>>1), |
| total_pixels_venc); |
| hd_write_reg(P_ENCI_DVI_VSO_BEGIN_ODD, vso_begin_odd); |
| hd_write_reg(P_ENCI_DVI_VSO_END_ODD, vso_begin_odd); |
| } else { |
| vs_bline_evn = de_v_end_even-1 + EOF_LINES + 1; |
| hd_write_reg(P_ENCI_DVI_VSO_BLINE_EVN, vs_bline_evn); /* 261 */ |
| /* vso_bline_evn_reg_wr_cnt ++; */ |
| vso_begin_evn = modulo(hs_begin + (total_pixels_venc>>1), |
| total_pixels_venc); |
| hd_write_reg(P_ENCI_DVI_VSO_BEGIN_EVN, vso_begin_evn); |
| if (vs_bline_evn + VSYNC_LINES >= LINES_F0) { |
| vs_eline_odd = vs_bline_evn + VSYNC_LINES - LINES_F0; |
| hd_write_reg(P_ENCI_DVI_VSO_ELINE_ODD, vs_eline_odd); |
| /* vso_eline_odd_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_END_ODD, vso_begin_evn); |
| } else { |
| vs_eline_evn = vs_bline_evn + VSYNC_LINES; |
| hd_write_reg(P_ENCI_DVI_VSO_ELINE_EVN, vs_eline_evn); |
| /* vso_eline_evn_reg_wr_cnt ++; */ |
| hd_write_reg(P_ENCI_DVI_VSO_END_EVN, vso_begin_evn); |
| } |
| } |
| |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | |
| (0 << 1) | |
| (0 << 2) | |
| (0 << 3) | |
| (0 << 4) | |
| (4 << 5) | |
| (1 << 8) | |
| (1 << 12) |
| ); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 0, 1); |
| } |
| |
| static void hdmi_tvenc_set_def(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; |
| unsigned long hs_begin = 0, hs_end = 0; |
| unsigned long vs_adjust = 0; |
| unsigned long vs_bline_evn = 0, vs_eline_evn = 0; |
| unsigned long vso_begin_evn = 0; |
| |
| |
| switch (vic) { |
| case HDMI_720x480p60_16x9: |
| case HDMI_720x480p120_16x9: |
| case HDMI_720x480p60_4x3: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (480/(1+INTERLACE_MODE)); |
| LINES_F0 = 525; |
| LINES_F1 = 525; |
| FRONT_PORCH = 16; |
| HSYNC_PIXELS = 62; |
| BACK_PORCH = 60; |
| VSYNC_LINES = 6; |
| SOF_LINES = 30; |
| break; |
| case HDMI_720x576p50_16x9: |
| case HDMI_720x576p100_16x9: |
| case HDMI_720x576p50_4x3: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (720*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (576/(1+INTERLACE_MODE)); |
| LINES_F0 = 625; |
| LINES_F1 = 625; |
| FRONT_PORCH = 12; |
| HSYNC_PIXELS = 64; |
| BACK_PORCH = 68; |
| VSYNC_LINES = 5; |
| SOF_LINES = 39; |
| break; |
| case HDMI_1280x720p60_16x9: |
| case HDMI_1280x720p120_16x9: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (1280*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (720/(1+INTERLACE_MODE)); |
| LINES_F0 = 750; |
| LINES_F1 = 750; |
| FRONT_PORCH = 110; |
| HSYNC_PIXELS = 40; |
| BACK_PORCH = 220; |
| VSYNC_LINES = 5; |
| SOF_LINES = 20; |
| break; |
| case HDMI_1280x720p50_16x9: |
| case HDMI_1280x720p100_16x9: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (1280*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (720/(1+INTERLACE_MODE)); |
| LINES_F0 = 750; |
| LINES_F1 = 750; |
| FRONT_PORCH = 440; |
| HSYNC_PIXELS = 40; |
| BACK_PORCH = 220; |
| VSYNC_LINES = 5; |
| SOF_LINES = 20; |
| break; |
| case HDMI_1920x1080p50_16x9: |
| case HDMI_1920x1080p25_16x9: |
| case HDMI_1920x1080p100_16x9: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (1080/(1+INTERLACE_MODE)); |
| LINES_F0 = 1125; |
| LINES_F1 = 1125; |
| FRONT_PORCH = 528; |
| HSYNC_PIXELS = 44; |
| BACK_PORCH = 148; |
| VSYNC_LINES = 5; |
| SOF_LINES = 36; |
| break; |
| case HDMI_1920x1080p24_16x9: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (1080/(1+INTERLACE_MODE)); |
| LINES_F0 = 1125; |
| LINES_F1 = 1125; |
| FRONT_PORCH = 638; |
| HSYNC_PIXELS = 44; |
| BACK_PORCH = 148; |
| VSYNC_LINES = 5; |
| SOF_LINES = 36; |
| break; |
| case HDMI_1920x1080p60_16x9: |
| case HDMI_1920x1080p30_16x9: |
| case HDMI_1920x1080p120_16x9: |
| INTERLACE_MODE = 0; |
| PIXEL_REPEAT_VENC = 0; |
| PIXEL_REPEAT_HDMI = 0; |
| ACTIVE_PIXELS = (1920*(1+PIXEL_REPEAT_HDMI)); |
| ACTIVE_LINES = (1080/(1+INTERLACE_MODE)); |
| LINES_F0 = 1125; |
| LINES_F1 = 1125; |
| FRONT_PORCH = 88; |
| HSYNC_PIXELS = 44; |
| BACK_PORCH = 148; |
| VSYNC_LINES = 5; |
| SOF_LINES = 36; |
| break; |
| default: |
| break; |
| } |
| |
| 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 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 */ |
| |
| switch (vic) { |
| case HDMI_720x480i60_16x9: |
| case HDMI_720x576i50_16x9: |
| case HDMI_720x480i60_4x3: |
| case HDMI_720x576i50_4x3: |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | |
| (0 << 1) | |
| (0 << 2) | |
| (0 << 3) | |
| (0 << 4) | |
| (4 << 5) | |
| (1 << 8) | |
| (1 << 12) |
| ); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 0, 1); |
| break; |
| case HDMI_1920x1080i60_16x9: |
| case HDMI_1920x1080i50_16x9: |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | |
| (0 << 1) | |
| (HSYNC_POLARITY << 2) | |
| (VSYNC_POLARITY << 3) | |
| (0 << 4) | |
| (((TX_INPUT_COLOR_FORMAT == 0) ? 1 : 0) << 5) | |
| (0 << 8) | |
| (0 << 12) |
| ); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); |
| break; |
| case HDMI_3840x2160p30_16x9: |
| case HDMI_3840x2160p25_16x9: |
| case HDMI_3840x2160p24_16x9: |
| case HDMI_4096x2160p24_256x135: |
| case HDMI_4096x2160p25_256x135: |
| case HDMI_4096x2160p30_256x135: |
| case HDMI_4096x2160p50_256x135: |
| case HDMI_4096x2160p60_256x135: |
| case HDMI_3840x2160p50_16x9: |
| case HDMI_3840x2160p60_16x9: |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | |
| (0 << 1) | |
| (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); |
| break; |
| case HDMI_720x480p60_16x9: |
| case HDMI_720x576p50_16x9: |
| case HDMI_720x480p60_4x3: |
| case HDMI_720x576p50_4x3: |
| case HDMI_720x480p120_16x9: |
| case HDMI_720x576p100_16x9: |
| 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; |
| case HDMI_1280x720p60_16x9: |
| case HDMI_1280x720p50_16x9: |
| case HDMI_1280x720p100_16x9: |
| case HDMI_1280x720p120_16x9: |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | |
| (0 << 1) | |
| (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); |
| 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_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; |
| unsigned long hs_begin = 0, hs_end = 0; |
| unsigned long vs_adjust = 0; |
| unsigned long vs_bline_evn = 0, vs_eline_evn = 0; |
| unsigned long vso_begin_evn = 0; |
| struct hdmi_format_para *vpara = NULL; |
| struct hdmi_cea_timing *vtiming = NULL; |
| |
| vpara = hdmi_get_fmt_paras(vic); |
| if (vpara == NULL) { |
| printf("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 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 */ |
| |
| 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: |
| case HDMI_720x480i60_4x3: |
| case HDMI_720x576i50_4x3: |
| hdmi_tvenc480i_set(vic); |
| break; |
| case HDMI_1920x1080i60_16x9: |
| case HDMI_1920x1080i50_16x9: |
| case HDMI_1920x1080i100_16x9: |
| case HDMI_1920x1080i120_16x9: |
| hdmi_tvenc1080i_set(vic); |
| break; |
| case HDMI_3840x2160p30_16x9: |
| case HDMI_3840x2160p25_16x9: |
| case HDMI_3840x2160p24_16x9: |
| case HDMI_4096x2160p24_256x135: |
| case HDMI_4096x2160p25_256x135: |
| case HDMI_4096x2160p30_256x135: |
| case HDMI_4096x2160p50_256x135: |
| case HDMI_4096x2160p60_256x135: |
| case HDMI_3840x2160p50_16x9: |
| case HDMI_3840x2160p60_16x9: |
| case HDMI_4096x2160p50_256x135_Y420: |
| case HDMI_4096x2160p60_256x135_Y420: |
| case HDMI_3840x2160p50_16x9_Y420: |
| case HDMI_3840x2160p60_16x9_Y420: |
| hdmi_tvenc4k2k_set(vic); |
| break; |
| default: |
| hdmi_tvenc_set_def(vic); |
| break; |
| } |
| |
| switch (vic) { |
| case HDMI_720x480i60_16x9: |
| case HDMI_720x576i50_16x9: |
| case HDMI_720x480i60_4x3: |
| case HDMI_720x576i50_4x3: |
| /* Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | /* [ 0] src_sel_enci*/ |
| (0 << 1) | /* [ 1] src_sel_encp*/ |
| (0 << 2) | /* [ 2] inv_hsync. 1=Invert Hsync polarity.*/ |
| (0 << 3) | /* [ 3] inv_vsync. 1=Invert Vsync polarity.*/ |
| (0 << 4) | /* [ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).*/ |
| (4 << 5) | /* [ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:*/ |
| /* 0=output CrYCb(BRG);*/ |
| /* 1=output YCbCr(RGB);*/ |
| /* 2=output YCrCb(RBG);*/ |
| /* 3=output CbCrY(GBR);*/ |
| /* 4=output CbYCr(GRB);*/ |
| /* 5=output CrCbY(BGR);*/ |
| /* 6,7=Rsrv.*/ |
| (1 << 8) | /* [11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.*/ |
| (1 <<12) /* [15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.*/ |
| ); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 0, 1); // [ 0] src_sel_enci: Enable ENCI output to HDMI*/ |
| break; |
| case HDMI_1920x1080i60_16x9: |
| case HDMI_1920x1080i50_16x9: |
| case HDMI_1920x1080i100_16x9: |
| case HDMI_1920x1080i120_16x9: |
| /*Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | /*[ 0] src_sel_enci*/ |
| (0 << 1) | /*[ 1] src_sel_encp*/ |
| (HSYNC_POLARITY << 2) | /*[ 2] inv_hsync. 1=Invert Hsync polarity.*/ |
| (VSYNC_POLARITY << 3) | /*[ 3] inv_vsync. 1=Invert Vsync polarity.*/ |
| (0 << 4) | /*[ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).*/ |
| (4 << 5) | /*[ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:*/ |
| /* 0=output CrYCb(BRG);*/ |
| /* 1=output YCbCr(RGB);*/ |
| /* 2=output YCrCb(RBG);*/ |
| /* 3=output CbCrY(GBR);*/ |
| /* 4=output CbYCr(GRB);*/ |
| /* 5=output CrCbY(BGR);*/ |
| /* 6,7=Rsrv.*/ |
| (0 << 8) | /*[11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.*/ |
| (0 <<12) /*[15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.*/ |
| ); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); /*[ 1] src_sel_encp: Enable ENCP output to HDMI*/ |
| break; |
| case HDMI_3840x2160p30_16x9: |
| case HDMI_3840x2160p25_16x9: |
| case HDMI_3840x2160p24_16x9: |
| case HDMI_4096x2160p24_256x135: |
| case HDMI_4096x2160p25_256x135: |
| case HDMI_4096x2160p30_256x135: |
| case HDMI_4096x2160p50_256x135: |
| case HDMI_4096x2160p60_256x135: |
| case HDMI_3840x2160p50_16x9: |
| case HDMI_3840x2160p60_16x9: |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | /*[ 0] src_sel_enci*/ |
| (0 << 1) | /*[ 1] src_sel_encp*/ |
| (HSYNC_POLARITY << 2) | /*[ 2] inv_hsync. 1=Invert Hsync polarity.*/ |
| (VSYNC_POLARITY << 3) | /*[ 3] inv_vsync. 1=Invert Vsync polarity.*/ |
| (0 << 4) | /*[ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).*/ |
| (4 << 5) | /*[ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:*/ |
| /* 0=output CrYCb(BRG);*/ |
| /* 1=output YCbCr(RGB);*/ |
| /* 2=output YCrCb(RBG);*/ |
| /* 3=output CbCrY(GBR);*/ |
| /* 4=output CbYCr(GRB);*/ |
| /* 5=output CrCbY(BGR);*/ |
| /* 6,7=Rsrv.*/ |
| (0 << 8) | /*[11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.*/ |
| (0 <<12) /*[15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.*/ |
| ); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); /*[ 1] src_sel_encp: Enable ENCP output to HDMI*/ |
| break; |
| case HDMI_720x480p60_16x9: |
| case HDMI_720x576p50_16x9: |
| case HDMI_720x480p60_4x3: |
| case HDMI_720x576p50_4x3: |
| case HDMI_720x480p120_16x9: |
| case HDMI_720x576p100_16x9: |
| /*Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | /*[ 0] src_sel_enci*/ |
| (0 << 1) | /*[ 1] src_sel_encp*/ |
| (0 << 2) | /*[ 2] inv_hsync. 1=Invert Hsync polarity.*/ |
| (0 << 3) | /*[ 3] inv_vsync. 1=Invert Vsync polarity.*/ |
| (0 << 4) | /*[ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).*/ |
| (4 << 5) | /*[ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:*/ |
| /* 0=output CrYCb(BRG);*/ |
| /* 1=output YCbCr(RGB);*/ |
| /* 2=output YCrCb(RBG);*/ |
| /* 3=output CbCrY(GBR);*/ |
| /* 4=output CbYCr(GRB);*/ |
| /* 5=output CrCbY(BGR);*/ |
| /* 6,7=Rsrv.*/ |
| (0 << 8) | /*[11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.*/ |
| (0 <<12) /*[15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.*/ |
| ); |
| /*Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); /*[ 1] src_sel_encp: Enable ENCP output to HDMI*/ |
| break; |
| case HDMI_1280x720p60_16x9: |
| case HDMI_1280x720p50_16x9: |
| case HDMI_1280x720p100_16x9: |
| case HDMI_1280x720p120_16x9: |
| /*Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | /*[ 0] src_sel_enci*/ |
| (0 << 1) | /*[ 1] src_sel_encp*/ |
| (HSYNC_POLARITY << 2) | /*[ 2] inv_hsync. 1=Invert Hsync polarity.*/ |
| (VSYNC_POLARITY << 3) | /*[ 3] inv_vsync. 1=Invert Vsync polarity.*/ |
| (0 << 4) | /*[ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).*/ |
| (4 << 5) | /*[ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:*/ |
| /* 0=output CrYCb(BRG);*/ |
| /* 1=output YCbCr(RGB);*/ |
| /* 2=output YCrCb(RBG);*/ |
| /* 3=output CbCrY(GBR);*/ |
| /* 4=output CbYCr(GRB);*/ |
| /* 5=output CrCbY(BGR);*/ |
| /* 6,7=Rsrv.*/ |
| (0 << 8) | /*[11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.*/ |
| (0 <<12) /*[15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.*/ |
| ); |
| /*Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); /*[ 1] src_sel_encp: Enable ENCP output to HDMI*/ |
| break; |
| default: |
| /*Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_write_reg(P_VPU_HDMI_SETTING, (0 << 0) | /*[ 0] src_sel_enci*/ |
| (0 << 1) | /*[ 1] src_sel_encp*/ |
| (HSYNC_POLARITY << 2) | /*[ 2] inv_hsync. 1=Invert Hsync polarity.*/ |
| (VSYNC_POLARITY << 3) | /*[ 3] inv_vsync. 1=Invert Vsync polarity.*/ |
| (0 << 4) | /*[ 4] inv_dvi_clk. 1=Invert clock to external DVI, (clock invertion exists at internal HDMI).*/ |
| (4 << 5) | /*[ 7: 5] data_comp_map. Input data is CrYCb(BRG), map the output data to desired format:*/ |
| /* 0=output CrYCb(BRG);*/ |
| /* 1=output YCbCr(RGB);*/ |
| /* 2=output YCrCb(RBG);*/ |
| /* 3=output CbCrY(GBR);*/ |
| /* 4=output CbYCr(GRB);*/ |
| /* 5=output CrCbY(BGR);*/ |
| /* 6,7=Rsrv.*/ |
| (0 << 8) | /*[11: 8] wr_rate. 0=A write every clk1; 1=A write every 2 clk1; ...; 15=A write every 16 clk1.*/ |
| (0 <<12) /*[15:12] rd_rate. 0=A read every clk2; 1=A read every 2 clk2; ...; 15=A read every 16 clk2.*/ |
| ); |
| if (is_hdmi4k_420(vic)) { |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 8, 1); |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 20, 1); |
| } |
| /*Annie 01Sep2011: Register VENC_DVI_SETTING and VENC_DVI_SETTING_MORE are no long valid, use VPU_HDMI_SETTING instead.*/ |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 1, 1, 1); /*[ 1] src_sel_encp: Enable ENCP output to HDMI*/ |
| } |
| } |
| |
| static void hdmitx_set_dith(struct hdmitx_dev* hdev) |
| { |
| unsigned int hs_flag = 0; |
| |
| switch (hdev->para->cd) { |
| case HDMI_COLOR_DEPTH_30B: |
| case HDMI_COLOR_DEPTH_36B: |
| case HDMI_COLOR_DEPTH_48B: |
| /* 12-10 dithering on */ |
| hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 4, 1); |
| hs_flag = (hd_read_reg(P_VPU_HDMI_SETTING) >> 2) & 0x3; |
| hd_set_reg_bits(P_VPU_HDMI_SETTING, 0, 2, 2); |
| /* 12-10 rounding off */ |
| hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 10, 1); |
| /* 10-8 dithering off (2x2 old dither) */ |
| hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, 0, 4, 1); |
| /* set hsync/vsync */ |
| hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, hs_flag, 2, 2); |
| break; |
| default: |
| /* 12-10 dithering off */ |
| hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 0, 4, 1); |
| /* 12-10 rounding on */ |
| hd_set_reg_bits(P_VPU_HDMI_FMT_CTRL, 1, 10, 1); |
| /* 10-8 dithering on (2x2 old dither) */ |
| hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, 1, 4, 1); |
| /* set hsync/vsync as default 0 */ |
| hd_set_reg_bits(P_VPU_HDMI_DITH_CNTL, 0, 2, 2); |
| break; |
| } |
| } |
| |
| static void set_tmds_clk_div40(unsigned int div40) |
| { |
| struct hdmitx_dev *hdev = hdmitx_get_hdev(); |
| |
| if (div40 == 1) { |
| hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_01, 0); /*[25:16] tmds_clk_pttn[19:10] [ 9: 0] tmds_clk_pttn[ 9: 0]*/ |
| hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_23, 0x03ff03ff); /*[25:16] tmds_clk_pttn[39:30] [ 9: 0] tmds_clk_pttn[29:20]*/ |
| } else { |
| hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_01, 0x001f001f); |
| hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_23, 0x001f001f); |
| } |
| hdmitx_set_reg_bits(HDMITX_DWC_FC_SCRAMBLER_CTRL, (div40 == 1) ? 1 : 0, 0, 1); |
| |
| hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1); /*0xc*/ |
| msleep(2); |
| hdmitx_wr_reg(HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); /*0xc*/ |
| if (hdev->RXCap.scdc_present) |
| scdc_prepare((div40 == 1) ? 1:0); |
| } |
| |
| static void hdmitx_set_vsi_pkt(enum hdmi_vic vic) |
| { |
| /* convert to HDMI_VIC */ |
| if (vic == HDMI_3840x2160p30_16x9) |
| vic = 1; |
| else if (vic == HDMI_3840x2160p25_16x9) |
| vic = 2; |
| else if (vic == HDMI_3840x2160p24_16x9) |
| vic = 3; |
| else |
| vic = 4; |
| |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID0, 0x03); |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID1, 0x0c); |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSDIEEEID2, 0x00); |
| hdmitx_wr_reg(HDMITX_DWC_FC_AVIVID, 0); |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD0, 0x20); |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSDPAYLOAD1, vic); |
| hdmitx_wr_reg(HDMITX_DWC_FC_VSDSIZE, 5); |
| 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); |
| } |
| |
| 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 (NULL == data) { |
| return; |
| } |
| 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; |
|