From 4260c508f6c86d823a27f5782a9100a5324cf4dc Mon Sep 17 00:00:00 2001 From: Yong Qin Date: Tue, 25 Sep 2018 15:59:28 +0800 Subject: [PATCH] hdmirx: hdmirx driver for tl1 [1/1] PD#172587 Problem: hdmirx bringup for tl1 Solution: 1.modify write top api, add addr offset -qy 2.modify write edid api -qy 3.replace top hw reset api 4.add aocec access register idle -qy 5.for tl1 bypass sw eq -qy 6.replace pddq api -qy 7.modify arc control for tl1 -qy 8.add n/cts auto mode 9.add hdcp balance path 10.add sscp mode 11.optimize reg map(rm unused reg addr) 12.add recent commits from 4.9 trunk 13.modify top clk cntl bit definition 14.modify top offset addr handle(x4) 15.add audio pll setting -qy 16.update phy setting - qy 17.modify audio pll ctrl api for tl1 -qy -add clk monitor function -add clk stable api for tl1 18.add emp data to pfifo -qy 19.modify edid write and other function -qy 20.add emp data to ddr -qy 21.add tmds data to ddr -qy 22.add cec for tl1 -qy -fix ctc 7-1 -add status register for cec a/b 23.add cec and hdmirx dts -qy 24.clean tl1 rx related clk measure 25.hdmirx and cec dts Verify: 1.run PTM 2.need verify on chip Change-Id: Ia7cc5a2d84925587bdfae825936ba763713926af Signed-off-by: Yong Qin --- arch/arm/boot/dts/amlogic/mesontl1.dtsi | 40 + arch/arm/boot/dts/amlogic/tl1_pxp.dts | 94 ++ drivers/amlogic/cec/ee_cec_reg.h | 2 +- drivers/amlogic/cec/hdmi_ao_cec.c | 91 +- drivers/amlogic/cec/hdmi_ao_cec.h | 102 +- drivers/amlogic/media/vin/tvin/hdmirx/Makefile | 5 +- .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c | 121 +- .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h | 45 +- .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c | 4 +- drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c | 12 + drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c | 1280 +++++++++++++++++--- drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h | 194 ++- .../media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c | 75 +- .../media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h | 47 +- .../media/vin/tvin/hdmirx/hdmi_rx_wrapper.c | 166 ++- .../media/vin/tvin/hdmirx/hdmi_rx_wrapper.h | 4 +- 16 files changed, 1994 insertions(+), 288 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/mesontl1.dtsi b/arch/arm/boot/dts/amlogic/mesontl1.dtsi index 3e98475..7f35d8a 100644 --- a/arch/arm/boot/dts/amlogic/mesontl1.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontl1.dtsi @@ -242,6 +242,20 @@ gpio-controller; #gpio-cells = <2>; }; + + aoceca_mux:aoceca_mux { + mux { + groups = "cec_ao_a"; + function = "cec_ao"; + }; + }; + + aocecb_mux:aocecb_mux { + mux { + groups = "cec_ao_b"; + function = "cec_ao"; + }; + }; }; pinctrl_periphs: pinctrl@ff6346c0 { @@ -264,6 +278,32 @@ gpio-controller; #gpio-cells = <2>; }; + + + hdmirx_a_mux:hdmirx_a_mux { + mux { + groups = "hdmirx_a_hpd", "hdmirx_a_det", + "hdmirx_a_sda", "hdmirx_a_sck"; + function = "hdmirx_a"; + }; + }; + + hdmirx_b_mux:hdmirx_b_mux { + mux { + groups = "hdmirx_b_hpd", "hdmirx_b_det", + "hdmirx_b_sda", "hdmirx_b_sck"; + function = "hdmirx_b"; + }; + }; + + hdmirx_c_mux:hdmirx_c_mux { + mux { + groups = "hdmirx_c_hpd", "hdmirx_c_det", + "hdmirx_c_sda", "hdmirx_c_sck"; + function = "hdmirx_c"; + }; + }; + }; wdt: watchdog@0xffd0f0d0 { diff --git a/arch/arm/boot/dts/amlogic/tl1_pxp.dts b/arch/arm/boot/dts/amlogic/tl1_pxp.dts index 50b7fe1..4a89853 100644 --- a/arch/arm/boot/dts/amlogic/tl1_pxp.dts +++ b/arch/arm/boot/dts/amlogic/tl1_pxp.dts @@ -100,6 +100,17 @@ size = <0x1400000>; alignment = <0x400000>; }; + + /* for hdmi rx emp use */ + hdmirx_emp_cma_reserved:linux,emp_cma { + compatible = "shared-dma-pool"; + /*linux,phandle = <5>;*/ + reusable; + /* 2M-30M for emp or tmds to ddr */ + size = <0x01e00000>; + alignment = <0x10000>; + alloc-ranges = <0x00200000 0x01e00000>; + }; }; /* end of reserved-memory */ codec_mm { @@ -343,6 +354,89 @@ */ tv_bit_mode = <0x15>; }; + + hdmirx { + compatible = "amlogic, hdmirx_tl1"; + #address-cells=<1>; + #size-cells=<1>; + memory-region = <&hdmirx_emp_cma_reserved>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmirx_a_mux &hdmirx_b_mux + &hdmirx_c_mux>; + repeat = <0>; + interrupts = <0 56 1>; + clocks = <&clkc CLKID_HDMIRX_MODET_COMP>, + <&clkc CLKID_HDMIRX_CFG_COMP>, + <&clkc CLKID_HDMIRX_ACR_COMP>, + <&clkc CLKID_HDMIRX_AUDMEAS_COMP>, + <&xtal>, + <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_FCLK_DIV7>, + <&clkc CLKID_HDCP22_SKP_COMP>, + <&clkc CLKID_HDCP22_ESM_COMP>; + // <&clkc CLK_AUD_PLL2FS>, + // <&clkc CLK_AUD_PLL4FS>, + // <&clkc CLK_AUD_OUT>; + clock-names = "hdmirx_modet_clk", + "hdmirx_cfg_clk", + "hdmirx_acr_ref_clk", + "hdmirx_audmeas_clk", + "xtal", + "fclk_div5", + "fclk_div7", + "hdcp_rx22_skp", + "hdcp_rx22_esm"; + // "hdmirx_aud_pll2fs", + // "hdmirx_aud_pll4f", + // "clk_aud_out"; + hdmirx_id = <0>; + en_4k_2_2k = <0>; + hpd_low_cec_off = <1>; + /* bit4: enable feature, bit3~0: port number */ + disable_port = <0x0>; + /* MAP_ADDR_MODULE_CBUS */ + /* MAP_ADDR_MODULE_HIU */ + /* MAP_ADDR_MODULE_HDMIRX_CAPB3 */ + /* MAP_ADDR_MODULE_SEC_AHB */ + /* MAP_ADDR_MODULE_SEC_AHB2 */ + /* MAP_ADDR_MODULE_APB4 */ + /* MAP_ADDR_MODULE_TOP */ + reg = < 0x0 0x0 + 0xff63C000 0x2000 + 0xffe0d000 0x2000 + 0x0 0x0 + 0x0 0x0 + 0x0 0x0 + 0xff610000 0xa000>; + }; + + aocec: aocec { + compatible = "amlogic, aocec-tl1"; + /*device_name = "aocec";*/ + status = "okay"; + vendor_name = "Amlogic"; /* Max Chars: 8 */ + /* Refer to the following URL at: + * http://standards.ieee.org/develop/regauth/oui/oui.txt + */ + vendor_id = <0x000000>; + product_desc = "TL1"; /* Max Chars: 16 */ + cec_osd_string = "AML_TV"; /* Max Chars: 14 */ + port_num = <3>; + ee_cec; + arc_port_mask = <0x2>; + interrupts = <0 205 1 + 0 199 1>; + interrupt-names = "hdmi_aocecb","hdmi_aocec"; + pinctrl-names = "default","hdmitx_aocecb","cec_pin_sleep"; + pinctrl-0=<&aoceca_mux>; + pinctrl-1=<&aocecb_mux>; + pinctrl-2=<&aoceca_mux>; + reg = <0xFF80023c 0x4 + 0xFF800000 0x400>; + reg-names = "ao_exit","ao"; + }; + }; /* end of / */ &audiobus { diff --git a/drivers/amlogic/cec/ee_cec_reg.h b/drivers/amlogic/cec/ee_cec_reg.h index 2561374..2978a24 100644 --- a/drivers/amlogic/cec/ee_cec_reg.h +++ b/drivers/amlogic/cec/ee_cec_reg.h @@ -41,7 +41,7 @@ /*---- registers for EE CEC ----*/ #define DWC_CEC_CTRL 0x1F00 -#define DWC_CEC_STAT 0x1F04 +#define DWC_CEC_CTRL2 0x1F04/*tl1 later*/ #define DWC_CEC_MASK 0x1F08 #define DWC_CEC_POLARITY 0x1F0C #define DWC_CEC_INT 0x1F10 diff --git a/drivers/amlogic/cec/hdmi_ao_cec.c b/drivers/amlogic/cec/hdmi_ao_cec.c index 9722df7..b0624e2 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.c +++ b/drivers/amlogic/cec/hdmi_ao_cec.c @@ -76,6 +76,7 @@ static struct early_suspend aocec_suspend_handler; #define MAX_INT 0x7ffffff struct cec_platform_data_s { + unsigned int chip_id; unsigned char line_reg;/*cec gpio_i reg:0 ao;1 periph*/ unsigned int line_bit;/*cec gpio position in reg*/ bool ee_to_ao;/*ee cec hw module mv to ao;ao cec delete*/ @@ -237,6 +238,7 @@ static unsigned int aocecb_rd_reg(unsigned long addr) { unsigned int data32; unsigned long flags; + unsigned int timeout = 0; spin_lock_irqsave(&cec_dev->cec_reg_lock, flags); data32 = 0; @@ -244,8 +246,17 @@ static unsigned int aocecb_rd_reg(unsigned long addr) data32 |= 0 << 8; /* [15:8] cec_reg_wrdata */ data32 |= addr << 0; /* [7:0] cec_reg_addr */ writel(data32, cec_dev->cec_reg + AO_CECB_RW_REG); - - data32 = ((readl(cec_dev->cec_reg + AO_CECB_RW_REG)) >> 24) & 0xff; + /* add for check access busy */ + data32 = readl(cec_dev->cec_reg + AO_CECB_RW_REG); + while (data32 & (1 << 23)) { + if (timeout++ > 200) { + CEC_ERR("cecb access reg 0x%x fail\n", + (unsigned int)addr); + break; + } + data32 = readl(cec_dev->cec_reg + AO_CECB_RW_REG); + } + data32 = (data32 >> 24) & 0xff; spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags); return data32; } /* aocecb_rd_reg */ @@ -545,6 +556,14 @@ static void ao_cecb_init(void) /* Release SW reset */ cec_set_reg_bits(AO_CECB_GEN_CNTL, 0, 0, 1); + if (cec_dev->plat_data->chip_id >= CEC_CHIP_ID_TL1) { + reg = 0; + reg |= (0 << 6);/*curb_err_init*/ + reg |= (0 << 5);/*en_chk_sbitlow*/ + reg |= (2 << 0);/*rise_del_max*/ + hdmirx_cec_write(DWC_CEC_CTRL2, reg); + } + /* Enable all AO_CECB interrupt sources */ cec_irq_enable(true); hdmirx_cec_write(DWC_CEC_WKUPCTRL, WAKEUP_EN_MASK); @@ -668,11 +687,17 @@ static int dump_cecrx_reg(char *b) s += sprintf(b + s, "CEC MODULE REGS:\n"); s += sprintf(b + s, "CEC_CTRL = 0x%02x\n", hdmirx_cec_read(0x1f00)); + if (cec_dev->plat_data->chip_id >= CEC_CHIP_ID_TL1) + s += sprintf(b + s, "CEC_CTRL2 = 0x%02x\n", + hdmirx_cec_read(0x1f04)); s += sprintf(b + s, "CEC_MASK = 0x%02x\n", hdmirx_cec_read(0x1f08)); s += sprintf(b + s, "CEC_ADDR_L = 0x%02x\n", hdmirx_cec_read(0x1f14)); s += sprintf(b + s, "CEC_ADDR_H = 0x%02x\n", hdmirx_cec_read(0x1f18)); s += sprintf(b + s, "CEC_TX_CNT = 0x%02x\n", hdmirx_cec_read(0x1f1c)); s += sprintf(b + s, "CEC_RX_CNT = 0x%02x\n", hdmirx_cec_read(0x1f20)); + if (cec_dev->plat_data->chip_id >= CEC_CHIP_ID_TL1) + s += sprintf(b + s, "CEC_STAT0 = 0x%02x\n", + hdmirx_cec_read(0x1f24)); s += sprintf(b + s, "CEC_LOCK = 0x%02x\n", hdmirx_cec_read(0x1fc0)); s += sprintf(b + s, "CEC_WKUPCTRL = 0x%02x\n", hdmirx_cec_read(0x1fc4)); @@ -829,13 +854,26 @@ static void cec_clear_logical_addr(void) void cec_enable_arc_pin(bool enable) { - /* select arc according arg */ - if (enable) - hdmirx_wr_top(TOP_ARCTX_CNTL, 0x01); - else - hdmirx_wr_top(TOP_ARCTX_CNTL, 0x00); - CEC_INFO("set arc en:%d, reg:%lx\n", - enable, hdmirx_rd_top(TOP_ARCTX_CNTL)); + unsigned int data; + + if (cec_dev->plat_data->chip_id >= CEC_CHIP_ID_TL1) { + data = rd_reg_hhi(HHI_HDMIRX_ARC_CNTL); + /* enable bit 1:1 bit 0: 0*/ + if (enable) + data |= 0x02; + else + data &= 0xffffffffd; + wr_reg_hhi(HHI_HDMIRX_ARC_CNTL, data); + CEC_INFO("set arc en:%d, reg:%x\n", enable, data); + } else { + /* select arc according arg */ + if (enable) + hdmirx_wr_top(TOP_ARCTX_CNTL, 0x01); + else + hdmirx_wr_top(TOP_ARCTX_CNTL, 0x00); + CEC_INFO("set arc en:%d, reg:%lx\n", + enable, hdmirx_rd_top(TOP_ARCTX_CNTL)); + } } EXPORT_SYMBOL(cec_enable_arc_pin); @@ -1835,6 +1873,17 @@ static const char * const cec_reg_name2[] = { "CEC_TX_NUM_MSG" }; +static const char * const ceca_reg_name3[] = { + "STAT_0_0", + "STAT_0_1", + "STAT_0_2", + "STAT_0_3", + "STAT_1_0", + "STAT_1_1", + "STAT_1_2" +}; + + static ssize_t dump_reg_show(struct class *cla, struct class_attribute *attr, char *b) { @@ -1860,6 +1909,14 @@ static ssize_t dump_reg_show(struct class *cla, s += sprintf(b + s, "%s:%2x\n", cec_reg_name2[i], aocec_rd_reg(i + 0x90)); } + + if (cec_dev->plat_data->chip_id >= CEC_CHIP_ID_TL1) { + for (i = 0; i < ARRAY_SIZE(ceca_reg_name3); i++) { + s += sprintf(b + s, "%s:%2x\n", + ceca_reg_name3[i], aocec_rd_reg(i + 0xA0)); + } + } + return s; } @@ -2639,29 +2696,41 @@ static void aocec_late_resume(struct early_suspend *h) #ifdef CONFIG_OF static const struct cec_platform_data_s cec_gxl_data = { + .chip_id = CEC_CHIP_ID_GXTVBB, .line_reg = 0, .line_bit = 8, .ee_to_ao = 0, }; static const struct cec_platform_data_s cec_txlx_data = { + .chip_id = CEC_CHIP_ID_TXLX, .line_reg = 0, .line_bit = 7, .ee_to_ao = 1, }; static const struct cec_platform_data_s cec_g12a_data = { + .chip_id = CEC_CHIP_ID_G12A, .line_reg = 1, .line_bit = 3, .ee_to_ao = 1, }; static const struct cec_platform_data_s cec_txl_data = { + .chip_id = CEC_CHIP_ID_TXL, .line_reg = 0, .line_bit = 7, .ee_to_ao = 0, }; +static const struct cec_platform_data_s cec_tl1_data = { + .chip_id = CEC_CHIP_ID_TL1, + .line_reg = 0, + .line_bit = 7, + .ee_to_ao = 1, +}; + + static const struct of_device_id aml_cec_dt_match[] = { { .compatible = "amlogic, amlogic-aocec", @@ -2679,6 +2748,10 @@ static const struct of_device_id aml_cec_dt_match[] = { .compatible = "amlogic, aocec-txl", .data = &cec_txl_data, }, + { + .compatible = "amlogic, aocec-tl1", + .data = &cec_tl1_data, + }, {} }; #endif diff --git a/drivers/amlogic/cec/hdmi_ao_cec.h b/drivers/amlogic/cec/hdmi_ao_cec.h index dbfab7d..e2dcf9f 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.h +++ b/drivers/amlogic/cec/hdmi_ao_cec.h @@ -18,7 +18,7 @@ #ifndef __AO_CEC_H__ #define __AO_CEC_H__ -#define CEC_DRIVER_VERSION "Ver 2018/09/2\n" +#define CEC_DRIVER_VERSION "Ver 2018/10/23\n" #define CEC_FRAME_DELAY msecs_to_jiffies(400) #define CEC_DEV_NAME "cec" @@ -28,6 +28,15 @@ #define HR_DELAY(n) (ktime_set(0, n * 1000 * 1000)) +enum cec_chip_ver { + CEC_CHIP_ID_GXTVBB = 0, + CEC_CHIP_ID_TXL, + CEC_CHIP_ID_TXLX, + CEC_CHIP_ID_G12A, + CEC_CHIP_ID_TXHD, + CEC_CHIP_ID_TL1, +}; + #define L_1 1 #define L_2 2 #define L_3 3 @@ -81,7 +90,7 @@ #define AO_CEC_STICKY_DATA7 ((0xd1 << 2)) /* - * AOCEC_B + * AOCEC_B register */ #define AO_CECB_CLK_CNTL_REG0 ((0xa0 << 2)) #define AO_CECB_CLK_CNTL_REG1 ((0xa1 << 2)) @@ -91,7 +100,10 @@ #define AO_CECB_INTR_CLR ((0xa5 << 2)) #define AO_CECB_INTR_STAT ((0xa6 << 2)) -/* read/write */ +/* + * AOCEC_A internal register + * read/write tx register list + */ #define CEC_TX_MSG_0_HEADER 0x00 #define CEC_TX_MSG_1_OPCODE 0x01 #define CEC_TX_MSG_2_OP1 0x02 @@ -108,8 +120,6 @@ #define CEC_TX_MSG_D_OP12 0x0D #define CEC_TX_MSG_E_OP13 0x0E #define CEC_TX_MSG_F_OP14 0x0F - -/* read/write */ #define CEC_TX_MSG_LENGTH 0x10 #define CEC_TX_MSG_CMD 0x11 #define CEC_TX_WRITE_BUF 0x12 @@ -124,7 +134,9 @@ #define CEC_CLOCK_DIV_H 0x1B #define CEC_CLOCK_DIV_L 0x1C -/* The following registers are for fine tuning CEC bit timing parameters. +/* + * AOCEC_A internal register + * The following registers are for fine tuning CEC bit timing parameters. * They are only valid in AO CEC, NOT valid in HDMITX CEC. * The AO CEC's timing parameters are already set default to work with * 32768Hz clock, so hopefully SW never need to program these registers. @@ -186,11 +198,13 @@ #define AO_CEC_NOMSMPACKPOINT_0MS45 0x58 #define AO_CEC_ACK0NOML2H_1MS5_BIT7_0 0x5A #define AO_CEC_ACK0NOML2H_1MS5_BIT8 0x5B - #define AO_CEC_BUGFIX_DISABLE_0 0x60 #define AO_CEC_BUGFIX_DISABLE_1 0x61 -/* read only */ +/* + * AOCEC_A internal register + * read only register list + */ #define CEC_RX_MSG_0_HEADER 0x80 #define CEC_RX_MSG_1_OPCODE 0x81 #define CEC_RX_MSG_2_OP1 0x82 @@ -207,13 +221,22 @@ #define CEC_RX_MSG_D_OP12 0x8D #define CEC_RX_MSG_E_OP13 0x8E #define CEC_RX_MSG_F_OP14 0x8F - -/* read only */ #define CEC_RX_MSG_LENGTH 0x90 #define CEC_RX_MSG_STATUS 0x91 #define CEC_RX_NUM_MSG 0x92 #define CEC_TX_MSG_STATUS 0x93 #define CEC_TX_NUM_MSG 0x94 +/* + * AOCEC_A internal register + * read only (tl1 later) + */ +#define CEC_STAT_0_0 0xA0 +#define CEC_STAT_0_1 0xA1 +#define CEC_STAT_0_2 0xA2 +#define CEC_STAT_0_3 0xA3 +#define CEC_STAT_1_0 0xA4 +#define CEC_STAT_1_1 0xA5 +#define CEC_STAT_1_2 0xA6 /* tx_msg_cmd definition */ #define TX_NO_OP 0 /* No transaction */ @@ -263,9 +286,12 @@ /** Register address: DMI disable interface */ #define DWC_DMI_DISABLE_IF (0xFF4UL) -/*---- registers for EE CEC ----*/ +/* + * AOCEC_B internal register + * for EE CEC + */ #define DWC_CEC_CTRL 0x1F00 -#define DWC_CEC_STAT 0x1F04 +#define DWC_CEC_CTRL2 0x1F04/*tl1 later*/ #define DWC_CEC_MASK 0x1F08 #define DWC_CEC_POLARITY 0x1F0C #define DWC_CEC_INT 0x1F10 @@ -273,6 +299,7 @@ #define DWC_CEC_ADDR_H 0x1F18 #define DWC_CEC_TX_CNT 0x1F1C #define DWC_CEC_RX_CNT 0x1F20 +#define DWC_CEC_STAT0 0x1F24/*tl1 later*/ #define DWC_CEC_TX_DATA0 0x1F40 #define DWC_CEC_TX_DATA1 0x1F44 #define DWC_CEC_TX_DATA2 0x1F48 @@ -308,13 +335,19 @@ #define DWC_CEC_LOCK 0x1FC0 #define DWC_CEC_WKUPCTRL 0x1FC4 -/* FOR AO_CECB */ +/* + * AOCEC_B internal register + * for EE CEC + */ +/* #define AO_CECB_CTRL_ADDR 0x00 +#define AO_CECB_CTRL2_ADDR 0x01 #define AO_CECB_INTR_MASK_ADDR 0x02 #define AO_CECB_LADD_LOW_ADDR 0x05 #define AO_CECB_LADD_HIGH_ADDR 0x06 #define AO_CECB_TX_CNT_ADDR 0x07 #define AO_CECB_RX_CNT_ADDR 0x08 +#define AO_CECB_STAT0_ADDR 0x09 #define AO_CECB_TX_DATA00_ADDR 0x10 #define AO_CECB_TX_DATA01_ADDR 0x11 #define AO_CECB_TX_DATA02_ADDR 0x12 @@ -349,6 +382,34 @@ #define AO_CECB_RX_DATA15_ADDR 0x2F #define AO_CECB_LOCK_BUF_ADDR 0x30 #define AO_CECB_WAKEUPCTRL_ADDR 0x31 +*/ + + +/* + * AOCEC B CEC_STAT0 + */ +enum { + CECB_STAT0_S2P_IDLE = 0, + CECB_STAT0_S2P_SBITLOWER = 1, + CECB_STAT0_S2P_SBH = 2, + CECB_STAT0_S2P_L1LOWER = 5, + CECB_STAT0_S2P_SMP1 = 6, + CECB_STAT0_S2P_SMP0 = 7, + CECB_STAT0_S2P_L0H = 8, + CECB_STAT0_S2P_ERRLMIN = 9, + CECB_STAT0_S2P_ERRLMAX = 0xe, +}; + +enum { + CECB_STAT0_P2S_TIDLE = 0, + CECB_STAT0_P2S_SEND_SBIT = 1, + CECB_STAT0_P2S_SEND_DBIT = 2, + CECB_STAT0_P2S_SEND_EOM = 3, + CECB_STAT0_P2S_SEND_ACK = 4, + CECB_STAT0_P2S_FBACK_ACK = 5, + CECB_STAT0_P2S_FBACK_RX_ERR = 6, +}; + /* cec ip irq flags bit discription */ #define EECEC_IRQ_TX_DONE (1 << 16) @@ -397,6 +458,8 @@ #define EDID_AUTO_CEC_EN 0 #define HHI_32K_CLK_CNTL (0x89 << 2) +#define HHI_HDMIRX_ARC_CNTL (0xe8 << 2) + struct dbgflg { unsigned int hal_cmd_bypass:1; @@ -408,6 +471,9 @@ extern unsigned long hdmirx_rd_top(unsigned long addr); extern void hdmirx_wr_top(unsigned long addr, unsigned long data); extern uint32_t hdmirx_rd_dwc(uint16_t addr); extern void hdmirx_wr_dwc(uint16_t addr, uint32_t data); +extern unsigned int rd_reg_hhi(unsigned int offset); +extern void wr_reg_hhi(unsigned int offset, unsigned int val); + #else static inline unsigned long hdmirx_rd_top(unsigned long addr) { @@ -425,6 +491,16 @@ static inline uint32_t hdmirx_rd_dwc(uint16_t addr) static inline void hdmirx_wr_dwc(uint16_t addr, uint32_t data) { } + +unsigned int rd_reg_hhi(unsigned int offset) +{ + return 0; +} + +void wr_reg_hhi(unsigned int offset, unsigned int val) +{ +} + #endif extern int hdmirx_get_connect_info(void); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/Makefile b/drivers/amlogic/media/vin/tvin/hdmirx/Makefile index 6b55e98..b19edee1 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/Makefile +++ b/drivers/amlogic/media/vin/tvin/hdmirx/Makefile @@ -3,5 +3,6 @@ # obj-$(CONFIG_AMLOGIC_MEDIA_TVIN_HDMI) += tvin_hdmirx.o -tvin_hdmirx-objs := hdmi_rx_wrapper.o hdmi_rx_hw.o hdmi_rx_drv.o hdcp_rx_main.o hdmi_rx_eq.o \ - hdmi_rx_repeater.o hdmi_rx_pktinfo.o hdmi_rx_edid.o +tvin_hdmirx-objs := hdmi_rx_wrapper.o hdmi_rx_hw.o hdmi_rx_drv.o \ + hdcp_rx_main.o hdmi_rx_eq.o \ + hdmi_rx_repeater.o hdmi_rx_pktinfo.o hdmi_rx_edid.o \ No newline at end of file diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c index 25ed702..4ddf66b 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c @@ -39,6 +39,8 @@ /* #include */ #include #include +#include + /* Amlogic headers */ /*#include */ @@ -58,6 +60,7 @@ #include "hdmi_rx_edid.h" #include "hdmi_rx_eq.h" #include "hdmi_rx_repeater.h" + /*------------------------extern function------------------------------*/ static int aml_hdcp22_pm_notify(struct notifier_block *nb, unsigned long event, void *dummy); @@ -110,10 +113,6 @@ int hdmi_yuv444_enable; module_param(hdmi_yuv444_enable, int, 0664); MODULE_PARM_DESC(hdmi_yuv444_enable, "hdmi_yuv444_enable"); -static int force_color_range; -MODULE_PARM_DESC(force_color_range, "\n force_color_range\n"); -module_param(force_color_range, int, 0664); - int pc_mode_en; MODULE_PARM_DESC(pc_mode_en, "\n pc_mode_en\n"); module_param(pc_mode_en, int, 0664); @@ -146,28 +145,42 @@ static bool early_suspend_flag; struct reg_map reg_maps[MAP_ADDR_MODULE_NUM]; + static struct notifier_block aml_hdcp22_pm_notifier = { .notifier_call = aml_hdcp22_pm_notify, }; +static struct meson_hdmirx_data rx_tl1_data = { + .chip_id = CHIP_ID_TL1, + .phy_ver = PHY_VER_TL1, +}; + static struct meson_hdmirx_data rx_txhd_data = { .chip_id = CHIP_ID_TXHD, + .phy_ver = PHY_VER_ORG, }; static struct meson_hdmirx_data rx_txlx_data = { .chip_id = CHIP_ID_TXLX, + .phy_ver = PHY_VER_ORG, }; static struct meson_hdmirx_data rx_txl_data = { .chip_id = CHIP_ID_TXL, + .phy_ver = PHY_VER_ORG, }; static struct meson_hdmirx_data rx_gxtvbb_data = { .chip_id = CHIP_ID_GXTVBB, + .phy_ver = PHY_VER_ORG, }; static const struct of_device_id hdmirx_dt_match[] = { { + .compatible = "amlogic, hdmirx_tl1", + .data = &rx_tl1_data + }, + { .compatible = "amlogic, hdmirx_txhd", .data = &rx_txhd_data }, @@ -210,8 +223,9 @@ int rx_init_reg_map(struct platform_device *pdev) reg_maps[i].phy_addr = res->start; reg_maps[i].p = devm_ioremap_nocache(&pdev->dev, res->start, size); - /* rx_pr("phy_addr = 0x%x, size = 0x%x, maped:%p\n", */ - /* reg_maps[i].phy_addr, size, reg_maps[i].p); */ + reg_maps[i].size = size; + rx_pr("phy_addr = 0x%x, size = 0x%x, maped:%p\n", + reg_maps[i].phy_addr, size, reg_maps[i].p); } return ret; } @@ -333,7 +347,8 @@ void hdmirx_dec_close(struct tvin_frontend_s *fe) * txlx:dont disable the adc ref signal for audio pll(not * reset the vdac) to avoid noise issue */ - if (rx.chip_id == CHIP_ID_TXL) + /*if (rx.chip_id == CHIP_ID_TXL)*/ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TXL) vdac_enable(0, 0x10); /* open_flage = 0; */ @@ -1550,14 +1565,11 @@ static void rx_phy_suspend(void) if (hdmi_cec_en != 0) { if (suspend_pddq_sel == 2) { /* set rxsense pulse */ - hdmirx_phy_pddq(1); - mdelay(10); - hdmirx_phy_pddq(0); - mdelay(10); + rx_phy_rxsense_pulse(10, 10); } } /* phy powerdown */ - hdmirx_phy_pddq(1); + rx_phy_power_on(0); } } @@ -1569,10 +1581,7 @@ static void rx_phy_resume(void) * rxsense pulse and phy_int shottern than * 50ms, SDA may be pulled low 800ms on MTK box */ - hdmirx_phy_pddq(0); - msleep(20); - hdmirx_phy_pddq(1); - msleep(50); + rx_phy_rxsense_pulse(20, 50); } } hdmirx_phy_init(); @@ -1580,6 +1589,68 @@ static void rx_phy_resume(void) rx.boot_flag = true; } +void rx_emp_resource_allocate(struct device *dev) +{ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* allocate buffer */ + rx.empbuff.storeA = kmalloc(EMP_BUFFER_SIZE, GFP_KERNEL); + if (rx.empbuff.storeA) + rx.empbuff.storeB = + rx.empbuff.storeA + (EMP_BUFFER_SIZE >> 1); + else + rx_pr("emp buff err-0\n"); + rx_pr("pktbuffa=0x%p\n", rx.empbuff.storeA); + rx_pr("pktbuffb=0x%p\n", rx.empbuff.storeB); + rx.empbuff.dump_mode = DUMP_MODE_EMP; + /* allocate buffer for hw access*/ + rx.empbuff.pg_addr = + dma_alloc_from_contiguous(dev, + EMP_BUFFER_SIZE >> PAGE_SHIFT, 0); + if (rx.empbuff.pg_addr) { + /* hw access */ + /* page to real address*/ + rx.empbuff.p_addr_a = + page_to_phys(rx.empbuff.pg_addr); + rx.empbuff.p_addr_b = + rx.empbuff.p_addr_a + (EMP_BUFFER_SIZE >> 1); + rx_pr("buffa paddr=0x%x\n", rx.empbuff.p_addr_a); + rx_pr("buffb paddr=0x%x\n", rx.empbuff.p_addr_b); + } else { + rx_pr("emp buff err-1\n"); + } + rx.empbuff.emppktcnt = 0; + } +} + +void rx_tmds_resource_allocate(struct device *dev) +{ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + if (rx.empbuff.dump_mode == DUMP_MODE_EMP) { + if (rx.empbuff.pg_addr) { + dma_release_from_contiguous(dev, + rx.empbuff.pg_addr, + EMP_BUFFER_SIZE >> PAGE_SHIFT); + rx.empbuff.pg_addr = 0; + } + } else { + dma_release_from_contiguous(dev, rx.empbuff.pg_addr, + TMDS_BUFFER_SIZE >> PAGE_SHIFT); + rx.empbuff.pg_addr = 0; + } + + /* allocate buffer for tmds to ddr */ + rx.empbuff.pg_addr = + dma_alloc_from_contiguous(dev, + TMDS_BUFFER_SIZE >> PAGE_SHIFT, 0); + if (rx.empbuff.pg_addr) + rx.empbuff.p_addr_a = + page_to_phys(rx.empbuff.pg_addr); + + rx.empbuff.dump_mode = DUMP_MODE_TMDS; + rx_pr("buffa paddr=0x%x\n", rx.empbuff.p_addr_a); + } +} + #ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND static void hdmirx_early_suspend(struct early_suspend *h) { @@ -1640,11 +1711,17 @@ static int hdmirx_probe(struct platform_device *pdev) } memset(hdevp, 0, sizeof(struct hdmirx_dev_s)); hdevp->data = of_id->data; - if (hdevp->data) + rx.hdmirxdev = hdevp; + + if (hdevp->data) { rx.chip_id = hdevp->data->chip_id; - else + rx_pr("chip id:%d\n", rx.hdmirxdev->data->chip_id); + rx_pr("phy ver:%d\n", rx.hdmirxdev->data->phy_ver); + } else { /*txlx chip for default*/ rx.chip_id = CHIP_ID_TXLX; + rx_pr("err: hdevp->data null\n"); + } ret = rx_init_reg_map(pdev); if (ret < 0) { @@ -1816,8 +1893,8 @@ static int hdmirx_probe(struct platform_device *pdev) clk_rate = clk_get_rate(hdevp->skp_clk); } } - if ((rx.chip_id == CHIP_ID_TXLX) || - (rx.chip_id == CHIP_ID_TXHD)) { + if ((rx.hdmirxdev->data->chip_id == CHIP_ID_TXLX) || + (rx.hdmirxdev->data->chip_id == CHIP_ID_TXHD)) { tmds_clk_fs = clk_get(&pdev->dev, "hdmirx_aud_pll2fs"); if (IS_ERR(tmds_clk_fs)) rx_pr("get tmds_clk_fs err\n"); @@ -1898,6 +1975,8 @@ static int hdmirx_probe(struct platform_device *pdev) disable_port_en = (disable_port >> 4) & 0x1; disable_port_num = disable_port & 0xF; } + + rx_emp_resource_allocate(&(pdev->dev)); hdmirx_hw_probe(); hdmirx_switch_pinmux(&(pdev->dev)); #ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND @@ -2055,7 +2134,7 @@ static void hdmirx_shutdown(struct platform_device *pdev) if (!hdmi_cec_en) rx_set_port_hpd(ALL_PORTS, 0); /* phy powerdown */ - hdmirx_phy_pddq(1); + rx_phy_power_on(0); if (hdcp22_on) hdcp22_clk_en(0); rx_pr("[hdmirx]: shutdown success\n"); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h index be8cd89..ee05f9e 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -41,7 +41,7 @@ * * */ -#define RX_VER1 "ver.2018/08/22" +#define RX_VER1 "ver.2018/10/22" /* * * @@ -85,10 +85,18 @@ enum chip_id_e { CHIP_ID_TXL, CHIP_ID_TXLX, CHIP_ID_TXHD, + CHIP_ID_TL1, +}; + +enum phy_ver_e { + PHY_VER_ORG, + PHY_VER_TL1, }; struct meson_hdmirx_data { enum chip_id_e chip_id; + enum phy_ver_e phy_ver; + struct ctrl *phyctrl; }; struct hdmirx_dev_s { @@ -250,6 +258,15 @@ struct rx_video_info { /** Encrypted keys size - 40 bits x 40 keys */ #define HDCP_KEYS_SIZE (2 * 40) +/*emp buffer config*/ +#define DUMP_MODE_EMP 0 +#define DUMP_MODE_TMDS 1 +#define TMDS_BUFFER_SIZE 0x1e00000 /*30M*/ +#define EMP_BUFFER_SIZE 0x200000 /*2M*/ +#define EMP_BUFF_MAC_PKT_CNT ((EMP_BUFFER_SIZE/2)/32 - 200) +#define TMDS_DATA_BUFFER_SIZE 0x200000 + + /** * @short HDMI RX controller HDCP configuration */ @@ -335,8 +352,32 @@ struct aud_info_s { int real_sr; }; +struct phy_sts { + uint32_t cable_clk; + uint32_t tmds_clk; + uint32_t aud_div; + uint32_t pll_rate; + uint32_t clk_rate; + uint32_t phy_bw; +}; + +struct emp_buff { + unsigned int dump_mode; + struct page *pg_addr; + phys_addr_t p_addr_a; + phys_addr_t p_addr_b; + /*void __iomem *v_addr_a;*/ + /*void __iomem *v_addr_b;*/ + void __iomem *storeA; + void __iomem *storeB; + void __iomem *ready; + unsigned int emppktcnt; + unsigned long irqcnt; +}; + struct rx_s { enum chip_id_e chip_id; + struct hdmirx_dev_s *hdmirxdev; /** HDMI RX received signal changed */ uint8_t skip; /*avmute*/ @@ -384,6 +425,8 @@ struct rx_s { unsigned int pwr_sts; /* for debug */ /*struct pd_infoframe_s dbg_info;*/ + struct phy_sts physts; + struct emp_buff empbuff; }; struct _hdcp_ksv { diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c index f689ee3..7a81a4d 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c @@ -948,7 +948,7 @@ void rx_edid_fill_to_register( /* fill first edid buffer */ hdmirx_wr_top(TOP_EDID_OFFSET + i, pedid[i]); /* fill second edid buffer */ - hdmirx_wr_top(0x100+TOP_EDID_OFFSET + i, pedid[i]); + hdmirx_wr_top(TOP_EDID_OFFSET + 0x100 + i, pedid[i]); } /* caculate 4 port check sum */ if (brepeat) { @@ -1056,7 +1056,7 @@ unsigned char rx_parse_arc_aud_type(const unsigned char *buff) break; } if ((i < aud_length) && - ((aud_data & 0xff) == 1)) { + ((aud_data & 0x1) == 0x1)) { if (!need_support_atmos_bit) { need_support_atmos_bit = true; hdmi_rx_top_edid_update(); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c index 7b130b3..a5c5d7a 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c @@ -178,6 +178,12 @@ void eq_dwork_handler(struct work_struct *work) unsigned int i; cancel_delayed_work(&eq_dwork); + + /* for tl1 no SW eq */ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + return; + } + for (i = 0; i < NTRYS; i++) { if (SettingFinder() == 1) { rx_pr("EQ-%d-%d-%d-", @@ -481,6 +487,12 @@ int rx_eq_algorithm(void) static uint8_t pre_eq_freq = 0xff; uint8_t pll_rate = hdmirx_rd_phy(PHY_MAINFSM_STATUS1) >> 9 & 3; + /* for tl1 no SW eq */ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + eq_sts = E_EQ_FINISH; + return 1; + } + if (is_6g_mode()) pll_rate = E_EQ_6G; diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c index aeacfca..526ed63 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -96,7 +96,8 @@ module_param(hdcp22_on, int, 0664); int hdcp14_key_mode = NORMAL_MODE; int aud_ch_map; - +int ignore_sscp_charerr = 1; +int ignore_sscp_tmds = 1; /*------------------------variable define end------------------------------*/ static int check_regmap_flag(unsigned int addr) @@ -117,10 +118,17 @@ unsigned int hdmirx_rd_dwc(unsigned int addr) int data; unsigned long dev_offset = 0x10; - spin_lock_irqsave(®_rw_lock, flags); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_addr_port | dev_offset, addr); - data = rd_reg(MAP_ADDR_MODULE_TOP, hdmirx_data_port | dev_offset); - spin_unlock_irqrestore(®_rw_lock, flags); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + data = rd_reg(MAP_ADDR_MODULE_TOP, + addr + reg_maps[MAP_ADDR_MODULE_TOP].phy_addr); + } else { + spin_lock_irqsave(®_rw_lock, flags); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_addr_port | dev_offset, addr); + data = rd_reg(MAP_ADDR_MODULE_TOP, + hdmirx_data_port | dev_offset); + spin_unlock_irqrestore(®_rw_lock, flags); + } return data; } @@ -146,10 +154,17 @@ void hdmirx_wr_dwc(unsigned int addr, unsigned int data) ulong flags; unsigned int dev_offset = 0x10; - spin_lock_irqsave(®_rw_lock, flags); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_addr_port | dev_offset, addr); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_data_port | dev_offset, data); - spin_unlock_irqrestore(®_rw_lock, flags); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + wr_reg(MAP_ADDR_MODULE_TOP, + addr + reg_maps[MAP_ADDR_MODULE_TOP].phy_addr, data); + } else { + spin_lock_irqsave(®_rw_lock, flags); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_addr_port | dev_offset, addr); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_data_port | dev_offset, data); + spin_unlock_irqrestore(®_rw_lock, flags); + } } /* @@ -269,12 +284,29 @@ unsigned int hdmirx_rd_top(unsigned int addr) ulong flags; int data; unsigned int dev_offset = 0; - - spin_lock_irqsave(®_rw_lock, flags); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_addr_port | dev_offset, addr); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_addr_port | dev_offset, addr); - data = rd_reg(MAP_ADDR_MODULE_TOP, hdmirx_data_port | dev_offset); - spin_unlock_irqrestore(®_rw_lock, flags); + unsigned int tempaddr = 0; + + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + dev_offset = TOP_DWC_BASE_OFFSET + + reg_maps[MAP_ADDR_MODULE_TOP].phy_addr; + if ((addr >= TOP_EDID_OFFSET) && + (addr <= (TOP_EDID_OFFSET + 0x1ff))) { + /*edid address range*/ + tempaddr = TOP_EDID_ADDR_S + (addr - 0x200); + data = rd_reg_b(MAP_ADDR_MODULE_TOP, + dev_offset + tempaddr); + } else { + data = rd_reg(MAP_ADDR_MODULE_TOP, + dev_offset + (addr<<2)); + } + } else { + spin_lock_irqsave(®_rw_lock, flags); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_addr_port | dev_offset, addr); + data = rd_reg(MAP_ADDR_MODULE_TOP, + hdmirx_data_port | dev_offset); + spin_unlock_irqrestore(®_rw_lock, flags); + } return data; } @@ -299,11 +331,29 @@ void hdmirx_wr_top(unsigned int addr, unsigned int data) { ulong flags; unsigned long dev_offset = 0; - - spin_lock_irqsave(®_rw_lock, flags); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_addr_port | dev_offset, addr); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_data_port | dev_offset, data); - spin_unlock_irqrestore(®_rw_lock, flags); + unsigned int tempaddr = 0; + + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + dev_offset = TOP_DWC_BASE_OFFSET + + reg_maps[MAP_ADDR_MODULE_TOP].phy_addr; + if ((addr >= TOP_EDID_OFFSET) && + (addr <= (TOP_EDID_OFFSET + 0x1ff))) { + /*edid address range*/ + tempaddr = TOP_EDID_ADDR_S + (addr - 0x200); + wr_reg_b(MAP_ADDR_MODULE_TOP, + dev_offset + tempaddr, (unsigned char)data); + } else { + wr_reg(MAP_ADDR_MODULE_TOP, + dev_offset + (addr<<2), data); + } + } else { + spin_lock_irqsave(®_rw_lock, flags); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_addr_port | dev_offset, addr); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_data_port | dev_offset, data); + spin_unlock_irqrestore(®_rw_lock, flags); + } } /* @@ -318,69 +368,108 @@ void hdmirx_wr_bits_top(unsigned int addr, hdmirx_wr_top(addr, rx_set_bits(hdmirx_rd_top(addr), mask, value)); } - /* - * rd_reg_hhi - * @offset: offset address of hhi physical addr - * - * returns unsigned int bytes read from the addr - */ - unsigned int rd_reg_hhi(unsigned int offset) - { - unsigned int addr = offset + - reg_maps[MAP_ADDR_MODULE_HIU].phy_addr; +/* + * rd_reg_hhi + * @offset: offset address of hhi physical addr + * + * returns unsigned int bytes read from the addr + */ +unsigned int rd_reg_hhi(unsigned int offset) +{ + unsigned int addr = offset + + reg_maps[MAP_ADDR_MODULE_HIU].phy_addr; - return rd_reg(MAP_ADDR_MODULE_HIU, addr); - } + return rd_reg(MAP_ADDR_MODULE_HIU, addr); +} - /* - * wr_reg_hhi - * @offset: offset address of hhi physical addr - * @val: value being written - */ - void wr_reg_hhi(unsigned int offset, unsigned int val) - { - unsigned int addr = offset + - reg_maps[MAP_ADDR_MODULE_HIU].phy_addr; - wr_reg(MAP_ADDR_MODULE_HIU, addr, val); - } +/* + * wr_reg_hhi + * @offset: offset address of hhi physical addr + * @val: value being written + */ +void wr_reg_hhi(unsigned int offset, unsigned int val) +{ + unsigned int addr = offset + + reg_maps[MAP_ADDR_MODULE_HIU].phy_addr; + wr_reg(MAP_ADDR_MODULE_HIU, addr, val); +} - /* - * rd_reg - regisger read - * @module: module index of the reg_map table - * @reg_addr: offset address of specified phy addr - * - * returns unsigned int bytes read from the addr - */ - unsigned int rd_reg(enum map_addr_module_e module, - unsigned int reg_addr) - { - unsigned int val = 0; - - if ((module < MAP_ADDR_MODULE_NUM) - && check_regmap_flag(reg_addr)) - val = readl(reg_maps[module].p + - (reg_addr - reg_maps[module].phy_addr)); - else - rx_pr("rd reg %x error\n", reg_addr); - return val; - } +/* + * rd_reg - regisger read + * @module: module index of the reg_map table + * @reg_addr: offset address of specified phy addr + * + * returns unsigned int bytes read from the addr + */ +unsigned int rd_reg(enum map_addr_module_e module, + unsigned int reg_addr) +{ + unsigned int val = 0; + + if ((module < MAP_ADDR_MODULE_NUM) + && check_regmap_flag(reg_addr)) + val = readl(reg_maps[module].p + + (reg_addr - reg_maps[module].phy_addr)); + else + rx_pr("rd reg %x error,md %d\n", reg_addr, module); + return val; +} + +/* + * wr_reg - regisger write + * @module: module index of the reg_map table + * @reg_addr: offset address of specified phy addr + * @val: value being written + */ +void wr_reg(enum map_addr_module_e module, + unsigned int reg_addr, unsigned int val) +{ + if ((module < MAP_ADDR_MODULE_NUM) + && check_regmap_flag(reg_addr)) + writel(val, reg_maps[module].p + + (reg_addr - reg_maps[module].phy_addr)); + else + rx_pr("wr reg %x err\n", reg_addr); +} + +/* + * rd_reg_b - regisger read byte mode + * @module: module index of the reg_map table + * @reg_addr: offset address of specified phy addr + * + * returns unsigned char bytes read from the addr + */ +unsigned char rd_reg_b(enum map_addr_module_e module, + unsigned char reg_addr) +{ + unsigned char val = 0; + + if ((module < MAP_ADDR_MODULE_NUM) + && check_regmap_flag(reg_addr)) + val = readb(reg_maps[module].p + + (reg_addr - reg_maps[module].phy_addr)); + else + rx_pr("rd reg %x error,md %d\n", reg_addr, module); + return val; +} + +/* + * wr_reg_b - regisger write byte mode + * @module: module index of the reg_map table + * @reg_addr: offset address of specified phy addr + * @val: value being written + */ +void wr_reg_b(enum map_addr_module_e module, + unsigned int reg_addr, unsigned char val) +{ + if ((module < MAP_ADDR_MODULE_NUM) + && check_regmap_flag(reg_addr)) + writeb(val, reg_maps[module].p + + (reg_addr - reg_maps[module].phy_addr)); + else + rx_pr("wr reg %x err\n", reg_addr); +} - /* - * wr_reg - regisger write - * @module: module index of the reg_map table - * @reg_addr: offset address of specified phy addr - * @val: value being written - */ - void wr_reg(enum map_addr_module_e module, - unsigned int reg_addr, unsigned int val) - { - if ((module < MAP_ADDR_MODULE_NUM) - && check_regmap_flag(reg_addr)) - writel(val, reg_maps[module].p + - (reg_addr - reg_maps[module].phy_addr)); - else - rx_pr("wr reg %x err\n", reg_addr); - } /* * rx_hdcp22_wr_only @@ -579,10 +668,13 @@ void hdmirx_phy_pddq(unsigned int enable) void hdmirx_wr_ctl_port(unsigned int offset, unsigned int data) { unsigned long flags; - - spin_lock_irqsave(®_rw_lock, flags); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_ctrl_port+offset, data); - spin_unlock_irqrestore(®_rw_lock, flags); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* ??? */ + } else { + spin_lock_irqsave(®_rw_lock, flags); + wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_ctrl_port+offset, data); + spin_unlock_irqrestore(®_rw_lock, flags); + } } /* @@ -594,14 +686,21 @@ void hdmirx_top_sw_reset(void) unsigned long dev_offset = 0; spin_lock_irqsave(®_rw_lock, flags); - wr_reg(MAP_ADDR_MODULE_TOP, - hdmirx_addr_port | dev_offset, TOP_SW_RESET); - wr_reg(MAP_ADDR_MODULE_TOP, - hdmirx_data_port | dev_offset, 1); - udelay(1); - wr_reg(MAP_ADDR_MODULE_TOP, - hdmirx_addr_port | dev_offset, TOP_SW_RESET); - wr_reg(MAP_ADDR_MODULE_TOP, hdmirx_data_port | dev_offset, 0); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + hdmirx_wr_top(TOP_SW_RESET, 1); + udelay(1); + hdmirx_wr_top(TOP_SW_RESET, 0); + } else { + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_addr_port | dev_offset, TOP_SW_RESET); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_data_port | dev_offset, 1); + udelay(1); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_addr_port | dev_offset, TOP_SW_RESET); + wr_reg(MAP_ADDR_MODULE_TOP, + hdmirx_data_port | dev_offset, 0); + } spin_unlock_irqrestore(®_rw_lock, flags); } @@ -614,7 +713,35 @@ void rx_irq_en(bool enable) unsigned int data32 = 0; if (enable) { - if (rx.chip_id == CHIP_ID_TXLX) { + if (rx.chip_id == CHIP_ID_TL1) { + data32 |= 1 << 31; /* DRC_CKS_CHG */ + data32 |= 1 << 30; /* DRC_RCV */ + data32 |= 0 << 29; /* AUD_TYPE_CHG */ + data32 |= 0 << 28; /* DVI_DET */ + data32 |= 1 << 27; /* VSI_CKS_CHG */ + data32 |= 0 << 26; /* GMD_CKS_CHG */ + data32 |= 0 << 25; /* AIF_CKS_CHG */ + data32 |= 1 << 24; /* AVI_CKS_CHG */ + data32 |= 0 << 23; /* ACR_N_CHG */ + data32 |= 0 << 22; /* ACR_CTS_CHG */ + data32 |= 1 << 21; /* GCP_AV_MUTE_CHG */ + data32 |= 0 << 20; /* GMD_RCV */ + data32 |= 0 << 19; /* AIF_RCV */ + data32 |= 0 << 18; /* AVI_RCV */ + data32 |= 0 << 17; /* ACR_RCV */ + data32 |= 0 << 16; /* GCP_RCV */ + data32 |= 1 << 15; /* VSI_RCV */ + data32 |= 0 << 14; /* AMP_RCV */ + data32 |= 0 << 13; /* AMP_CHG */ + data32 |= 1 << 9; /* EMP_RCV*/ + data32 |= 0 << 8; /* PD_FIFO_NEW_ENTRY */ + data32 |= 0 << 4; /* PD_FIFO_OVERFL */ + data32 |= 0 << 3; /* PD_FIFO_UNDERFL */ + data32 |= 0 << 2; /* PD_FIFO_TH_START_PASS */ + data32 |= 0 << 1; /* PD_FIFO_TH_MAX_PASS */ + data32 |= 0 << 0; /* PD_FIFO_TH_MIN_PASS */ + data32 |= pdec_ists_en; + } else if (rx.chip_id == CHIP_ID_TXLX) { data32 |= 1 << 31; /* DRC_CKS_CHG */ data32 |= 1 << 30; /* DRC_RCV */ data32 |= 0 << 29; /* AUD_TYPE_CHG */ @@ -770,7 +897,8 @@ void rx_get_audinfo(struct aud_info_s *audio_info) audio_info->n = hdmirx_rd_dwc(DWC_PDEC_ACR_N); if (audio_info->cts != 0) { - audio_info->arc = (hdmirx_get_tmds_clock()/audio_info->cts)* + audio_info->arc = + (rx_measure_clock(MEASURE_CLK_TMDS)/audio_info->cts)* audio_info->n/128; } else audio_info->arc = 0; @@ -855,11 +983,17 @@ bool rx_get_aud_pll_lock_sts(void) */ bool is_clk_stable(void) { - int clk; + int clk = false; + + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* sqofclk */ + clk = rd_reg_hhi(HHI_HDMIRX_PHY_MISC_STAT) & 0x80000000; + } else { + /* phy clk */ + clk = hdmirx_rd_phy(PHY_MAINFSM_STATUS1) & 0x100; + } - clk = hdmirx_rd_phy(PHY_MAINFSM_STATUS1); - clk = (clk >> 8) & 1; - if (clk == 1) + if (clk) return true; else return false; @@ -933,6 +1067,7 @@ int packet_init(void) data32 = hdmirx_rd_dwc(DWC_PDEC_CTRL); data32 |= 1 << 31; /* PFIFO_STORE_FILTER_EN */ + data32 |= 0 << 30; /* Enable packet FIFO to store EMP */ data32 |= 1 << 4; /* PD_FIFO_WE */ data32 |= 1 << 0; /* PDEC_BCH_EN */ data32 &= (~GCP_GLOBAVMUTE); @@ -1022,9 +1157,18 @@ static int TOP_init(void) hdmirx_wr_top(TOP_VID_CNTL2, data32); } data32 = 0; + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* n_cts_auto_mode: */ + /* 0-every ACR packet */ + /* 1-on N or CTS value change */ + data32 |= 0 << 4; + } /* delay cycles before n/cts update pulse */ data32 |= 7 << 0; - hdmirx_wr_top(TOP_ACR_CNTL2, data32); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + hdmirx_wr_top(TOP_TL1_ACR_CNTL2, data32); + else + hdmirx_wr_top(TOP_ACR_CNTL2, data32); data32 = 0; /* bit4: hpd override, bit5: hpd reverse */ @@ -1035,6 +1179,16 @@ static int TOP_init(void) data32 |= 1 << 5; /* pull down all the hpd */ hdmirx_wr_top(TOP_HPD_PWR5V, data32); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + data32 = hdmirx_rd_dwc(DWC_HDCP_CTRL); + /* 0: Original behaviour */ + /* 1: Balance path delay between non-HDCP and HDCP */ + data32 |= 1 << 27; /* none & hdcp */ + /* 0: Original behaviour */ + /* 1: Balance path delay between HDCP14 and HDCP22. */ + data32 |= 1 << 26; /* 1.4 & 2.2 */ + hdmirx_wr_dwc(DWC_HDCP_CTRL, data32); + } return err; } @@ -1209,23 +1363,27 @@ void rx_set_term_enable(bool enable) void rx_set_term_value(unsigned char port, bool value) { - if (port < E_PORT_NUM) { - if (value) - hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, - _BIT(port + 4), 1); - else - hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, - _BIT(port + 4), 0); - } else if (port == ALL_PORTS) { - if (value) - hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, - PHY_TERM_OV_VALUE, 0xF); - else - hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, - PHY_TERM_OV_VALUE, 0); - } else - rx_pr("%s port num overflow\n", __func__); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* need to do : for tl1 */ + } else { + if (port < E_PORT_NUM) { + if (value) + hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, + _BIT(port + 4), 1); + else + hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, + _BIT(port + 4), 0); + } else if (port == ALL_PORTS) { + if (value) + hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, + PHY_TERM_OV_VALUE, 0xF); + else + hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, + PHY_TERM_OV_VALUE, 0); + } else + rx_pr("%s port num overflow\n", __func__); + } } int rx_set_port_hpd(uint8_t port_id, bool val) @@ -1288,17 +1446,23 @@ void rx_force_rxsense_cfg(uint8_t level) { unsigned int term_ovr_value; - if (level) { - if (disable_port_en) - term_ovr_value = (~(1 << disable_port_num)) & 0xF; - else - term_ovr_value = 0xF; + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* need to do: for tl1 ...*/ - hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, - PHY_TERM_OV_VALUE, term_ovr_value); - } else - hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, - PHY_TERM_OV_VALUE, 0x0); + } else { + if (level) { + if (disable_port_en) + term_ovr_value = + (~(1 << disable_port_num)) & 0xF; + else + term_ovr_value = 0xF; + + hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, + PHY_TERM_OV_VALUE, term_ovr_value); + } else + hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, + PHY_TERM_OV_VALUE, 0x0); + } } /* @@ -1367,7 +1531,12 @@ void hdcp22_clk_en(bool en) ((0 << 25) | (1 << 24) | /* [ 24] Enable gated clock */ (0 << 16))); - hdmirx_wr_bits_top(TOP_CLK_CNTL, MSK(3, 3), 0x7); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + /* TL1:esm related clk bit9-11 */ + hdmirx_wr_bits_top(TOP_CLK_CNTL, MSK(3, 9), 0x7); + else + /* TL1:esm related clk bit3-5 */ + hdmirx_wr_bits_top(TOP_CLK_CNTL, MSK(3, 3), 0x7); } else { hdmirx_wr_bits_top(TOP_CLK_CNTL, MSK(3, 3), 0x0); wr_reg_hhi(HHI_HDCP22_CLK_CNTL, 0); @@ -1475,6 +1644,7 @@ void clk_init(void) /* Enable APB3 fail on error */ /* APB3 to HDMIRX-TOP err_en */ /* default 0x3ff, | bit15 = 1 | bit12 = 1 */ + hdmirx_wr_ctl_port(0, 0x93ff); hdmirx_wr_ctl_port(0x10, 0x93ff); @@ -1510,7 +1680,8 @@ void clk_init(void) wr_reg_hhi(HHI_HDMIRX_AUD_CLK_CNTL, data32); #endif if ((rx.chip_id == CHIP_ID_TXLX) || - (rx.chip_id == CHIP_ID_TXHD)) { + (rx.chip_id == CHIP_ID_TXHD) || + (rx.chip_id == CHIP_ID_TL1)) { /* [15] hdmirx_aud_pll4x_en override enable */ /* [14] hdmirx_aud_pll4x_en override value */ /* [6:5] clk_sel for cts_hdmirx_aud_pll_clk: */ @@ -1532,9 +1703,22 @@ void clk_init(void) data32 |= 0 << 31; /* [31] disable clkgating */ data32 |= 1 << 17; /* [17] audfifo_rd_en */ data32 |= 1 << 16; /* [16] pktfifo_rd_en */ - data32 |= 1 << 2; /* [2] hdmirx_cecclk_en */ - data32 |= 0 << 1; /* [1] bus_clk_inv */ - data32 |= 0 << 0; /* [0] hdmi_clk_inv */ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + data32 |= 0 << 8; /* [8] tmds_ch2_clk_inv */ + data32 |= 0 << 7; /* [7] tmds_ch1_clk_inv */ + data32 |= 0 << 6; /* [6] tmds_ch0_clk_inv */ + data32 |= 0 << 5; /* [5] pll4x_cfg */ + /* force_pll4x: + * 1=Force pll4x_en value to be pll4x_cfg. + * 0=Use auto detect. + */ + data32 |= 0 << 4; /* [4] force_pll4x */ + data32 |= 0 << 3; /* [3] phy_clk_inv: 1-invert */ + } else { + data32 |= 1 << 2; /* [2] hdmirx_cecclk_en */ + data32 |= 0 << 1; /* [1] bus_clk_inv */ + data32 |= 0 << 0; /* [0] hdmi_clk_inv */ + } hdmirx_wr_top(TOP_CLK_CNTL, data32); /* DEFAULT: {32'h0} */ } @@ -1552,6 +1736,22 @@ void hdmirx_20_init(void) data32 |= 1 << 9; /* [9] preamb_checken */ data32 |= 1 << 8; /* [8] ctrl_checken */ data32 |= 1 << 4; /* [4] scdc_enable */ + /* To support some TX that sends out SSCP even when not scrambling: + * 0: Original behaviour + * 1: During TMDS character error detection, treat SSCP character + * as normal TMDS character. + * Note: If scramble is turned on, this bit will not take effect, + * revert to original IP behaviour. + */ + data32 |= ignore_sscp_charerr << 3; /* [3]ignore sscp character err */ + /* To support some TX that sends out SSCP even when not scrambling: + * 0: Original behaviour + * 1: During TMDS decoding, treat SSCP character + * as normal TMDS character + * Note: If scramble is turned on, this bit will not take effect, + * revert to original IP behaviour. + */ + data32 |= ignore_sscp_tmds << 2; /* [2] ignore sscp tmds */ data32 |= SCRAMBLE_SEL << 0; /* [1:0] scramble_sel */ hdmirx_wr_dwc(DWC_HDMI20_CONTROL, data32); @@ -1712,9 +1912,9 @@ int hdmirx_audio_init(void) } /* - * hdmirx_phy_init - hdmirx phy initialization + * snps phy g3 initial */ -void hdmirx_phy_init(void) +void snps_phyg3_init(void) { unsigned int data32; unsigned int term_value = @@ -1794,13 +1994,11 @@ void hdmirx_phy_init(void) hdmirx_wr_bits_phy(PHY_CDR_CTRL_CNT, CLK_RATE_BIT, 0); last_clk_rate = 0; - #if 1 /* enable all ports's termination */ data32 = 0; data32 |= 1 << 8; data32 |= ((term_value & 0xF) << 4); hdmirx_wr_phy(PHY_MAIN_FSM_OVERRIDE1, data32); - #endif data32 = 0; data32 |= 1 << 6; @@ -1809,6 +2007,24 @@ void hdmirx_phy_init(void) data32 |= 0 << 1; data32 |= 0 << 0; hdmirx_wr_dwc(DWC_SNPS_PHYG3_CTRL, data32); + +} + +/* + * hdmirx_phy_init - hdmirx phy initialization + */ +void hdmirx_phy_init(void) +{ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + #ifdef K_BRINGUP_PTM + return; + #endif + /* give default value */ + aml_phy_bw_switch(100000, 0); + } else { + snps_phyg3_init(); + } + rx_pr("%s Done!\n", __func__); } @@ -1834,12 +2050,14 @@ bool rx_clkrate_monitor(void) if (clk_rate != last_clk_rate) { changed = true; - for (i = 0; i < 3; i++) { - error = hdmirx_wr_bits_phy(PHY_CDR_CTRL_CNT, - CLK_RATE_BIT, clk_rate); + if (rx.chip_id != CHIP_ID_TL1) { + for (i = 0; i < 3; i++) { + error = hdmirx_wr_bits_phy(PHY_CDR_CTRL_CNT, + CLK_RATE_BIT, clk_rate); - if (error == 0) - break; + if (error == 0) + break; + } } if (log_level & VIDEO_LOG) rx_pr("clk_rate:%d, last_clk_rate: %d\n", @@ -1931,6 +2149,7 @@ void hdmirx_hw_probe(void) TOP_init(); control_reset(); DWC_init(); + rx_emp_to_ddr_init(); hdmi_rx_top_edid_update(); /*hdmirx_irq_enable(FALSE);*/ /*hdmirx_irq_hdcp22_enable(FALSE);*/ @@ -2000,7 +2219,7 @@ bool is_afifo_error(void) bool is_aud_pll_error(void) { bool ret = true; - int32_t clk = hdmirx_get_audio_clock(); + int32_t clk = rx_measure_clock(MEASURE_CLK_AUD_PLL); int32_t aud_128fs = rx.aud_info.real_sr * 128; int32_t aud_512fs = rx.aud_info.real_sr * 512; @@ -2021,25 +2240,47 @@ bool is_aud_pll_error(void) void rx_aud_pll_ctl(bool en) { int tmp = 0; - - if (en) { - tmp = hdmirx_rd_phy(PHY_MAINFSM_STATUS1); - wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x20000000); - /* audio pll div depends on input freq */ - wr_reg_hhi(HHI_AUD_PLL_CNTL6, (tmp >> 9 & 3) << 28); - /* audio pll div fixed to N/CTS as below*/ - /* wr_reg_hhi(HHI_AUD_PLL_CNTL6, 0x40000000); */ - wr_reg_hhi(HHI_AUD_PLL_CNTL5, 0x0000002e); - wr_reg_hhi(HHI_AUD_PLL_CNTL4, 0x30000000); - wr_reg_hhi(HHI_AUD_PLL_CNTL3, 0x00000000); - wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x40000000); - wr_reg_hhi(HHI_ADC_PLL_CNTL4, 0x805); - rx_audio_pll_sw_update(); - /*External_Mute(0);*/ - } else{ - /* disable pll, into reset mode */ - External_Mute(1); - wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x20000000); + /*unsigned int od, od2;*/ + + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + if (en) { + /* AUD_CLK=N/CTS*TMDS_CLK */ + /* bandgap enable */ + tmp = rd_reg_hhi(HHI_VDAC_CNTL1); + wr_reg_hhi(HHI_VDAC_CNTL1, tmp|0x80); + wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x40000540); + wr_reg_hhi(HHI_AUD_PLL_CNTL2, 0x00000000); + /* cntl3 2:0 000=1*cts 001=2*cts 010=4*cts 011=8*cts */ + wr_reg_hhi(HHI_AUD_PLL_CNTL3, rx.physts.aud_div); + rx_pr("aud div=%d\n", rd_reg_hhi(HHI_AUD_PLL_CNTL3)); + wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x60000540); + rx_pr("audio pll lock:0x%x\n", + rd_reg_hhi(HHI_AUD_PLL_CNTL_I)); + } else { + /* disable pll, into reset mode */ + External_Mute(1); + wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x0); + } + } else { + if (en) { + tmp = hdmirx_rd_phy(PHY_MAINFSM_STATUS1); + wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x20000000); + /* audio pll div depends on input freq */ + wr_reg_hhi(HHI_AUD_PLL_CNTL6, (tmp >> 9 & 3) << 28); + /* audio pll div fixed to N/CTS as below*/ + /* wr_reg_hhi(HHI_AUD_PLL_CNTL6, 0x40000000); */ + wr_reg_hhi(HHI_AUD_PLL_CNTL5, 0x0000002e); + wr_reg_hhi(HHI_AUD_PLL_CNTL4, 0x30000000); + wr_reg_hhi(HHI_AUD_PLL_CNTL3, 0x00000000); + wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x40000000); + wr_reg_hhi(HHI_ADC_PLL_CNTL4, 0x805); + rx_audio_pll_sw_update(); + /*External_Mute(0);*/ + } else{ + /* disable pll, into reset mode */ + External_Mute(1); + wr_reg_hhi(HHI_AUD_PLL_CNTL, 0x20000000); + } } } @@ -2163,7 +2404,7 @@ void rx_get_video_info(void) break; } /* pixel clock */ - rx.cur.pixel_clk = hdmirx_get_pixel_clock() / divider; + rx.cur.pixel_clk = rx_measure_clock(MEASURE_CLK_PIXEL) / divider; /* image parameters */ rx.cur.interlaced = hdmirx_rd_bits_dwc(DWC_MD_STS, ILACE) != 0; rx.cur.voffset = hdmirx_rd_bits_dwc(DWC_MD_VOL, VOFS_LIN); @@ -2228,9 +2469,42 @@ void hdmirx_config_audio(void) } /* + * rx_get_clock: git clock from hdmi top + * tl1: have hdmi, cable clock + * other: have hdmi clock + */ +unsigned int rx_get_clock(unsigned int clk_src) +{ + uint32_t clock = 0; + uint32_t tmp_data = 0; + uint32_t meas_cycles = 0; + + if (clk_src == K_MEASURE_SRC_HDMI_TMDSCLK) + tmp_data = hdmirx_rd_top(TOP_METER_HDMI_STAT); + else if (clk_src == K_MEASURE_SRC_HDMI_CABLECLK) { + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + tmp_data = hdmirx_rd_top(TOP_METER_CABLE_STAT); + } else + tmp_data = 0; + + /* measure stable */ + if (tmp_data & 0x80000000) { + meas_cycles = tmp_data & 0xffffff; + clock = (2930 * meas_cycles); + /*clock = (24000000 * meas_cycles) / 8192;*/ + /*rx_pr("hdmi_clk cycle cnt=%d,frq=%d\n",cycle_cnt,clock);*/ + } + + hdmirx_wr_top(TOP_SW_RESET, 0x6); + hdmirx_wr_top(TOP_SW_RESET, 0x0); + return clock; +} + +#if 0 +/* * clk_util_clk_msr */ -static unsigned int clk_util_clk_msr(unsigned int clk_mux) +unsigned int clk_util_clk_msr(unsigned int clk_mux) { return meson_clk_measure(clk_mux); } @@ -2244,6 +2518,7 @@ unsigned int hdmirx_get_clock(int index) return clk_util_clk_msr(index); } + /* * hdmirx_get_tmds_clock - get tmds clock */ @@ -2291,6 +2566,74 @@ unsigned int hdmirx_get_esm_clock(void) { return clk_util_clk_msr(68); } +#endif +/* + * function - get clk related with hdmirx + */ +unsigned int rx_measure_clock(enum measure_clk_src clksrc) +{ + unsigned int clock = 0; + + /* from clock measure: txlx_clk_measure + * cable [x] need read from hdmitop + * tmds clock [25] Hdmirx_tmds_clk + * pixel clock [29] Hdmirx_pix_clk + * audio clock [24] Hdmirx_aud_pll_clk + * cts audio [98] cts_hdmirx_aud_pll_clk + * mpll clock [27] Hdmirx_mpll_div_clk + * esm clock [68] Cts_hdcp22_esm + */ + + /* from clock measure: tl1_table + * cable clock [30] hdmirx_cable_clk + * tmds clock [63] hdmirx_tmds_clk + * pixel clock [29] hdmirx_apll_clk_out_div + * audio clock [74] hdmirx_aud_pll_clk + * cts audio [60] cts_hdmirx_aud_pll_clk + * mpll clock [67] hdmirx_apll_clk_audio + * esm clock [68] Cts_hdcp22_esm + */ + + if (clksrc == MEASURE_CLK_CABLE) { + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + clock = meson_clk_measure(30); + /*clock = rx_get_clock(K_MEASURE_SRC_HDMI_CABLECLK);*/ + } + } else if (clksrc == MEASURE_CLK_TMDS) { + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + clock = meson_clk_measure(63); + else { + clock = meson_clk_measure(25); + if (clock == 0) { + clock = + hdmirx_rd_dwc(DWC_HDMI_CKM_RESULT) & 0xffff; + clock = clock * 158000 / 4095 * 1000; + } + } + } else if (clksrc == MEASURE_CLK_PIXEL) { + clock = meson_clk_measure(29); + } else if (clksrc == MEASURE_CLK_AUD_PLL) { + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + clock = meson_clk_measure(74); + else + clock = meson_clk_measure(24); + } else if (clksrc == MEASURE_CLK_AUD_DIV) { + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + clock = meson_clk_measure(60); + else + clock = meson_clk_measure(98); + + } else if (clksrc == MEASURE_CLK_MPLL) { + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + clock = meson_clk_measure(67);/*apll_clk_audio*/ + else + clock = meson_clk_measure(27); + } else if (clksrc == MEASURE_CLK_ESM) { + clock = meson_clk_measure(68); + } + + return clock; +} static const unsigned int wr_only_register[] = { 0x0c, 0x3c, 0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x8c, 0xa0, @@ -2459,6 +2802,7 @@ void dump_edid_reg(void) rx_pr("0x4 1.4 edid with 420 video data\n"); rx_pr("0x5 2.0 edid with HDR,DV,420\n"); rx_pr("********************************\n"); + for (i = 0; i < 16; i++) { rx_pr("[%2d] ", i); for (j = 0; j < 16; j++) { @@ -2545,27 +2889,609 @@ int rx_debug_rd_reg(const char *buf, char *tmpbuf) int rx_get_aud_pll_err_sts(void) { int ret = E_AUDPLL_OK; - int32_t req_clk = hdmirx_get_mpll_div_clk(); - int32_t aud_clk = hdmirx_get_audio_clock(); + int32_t req_clk = rx_measure_clock(MEASURE_CLK_MPLL); + int32_t aud_clk = rx_measure_clock(MEASURE_CLK_AUD_PLL); uint32_t phy_pll_rate = (hdmirx_rd_phy(PHY_MAINFSM_STATUS1)>>9)&0x3; uint32_t aud_pll_cntl = (rd_reg_hhi(HHI_AUD_PLL_CNTL6)>>28)&0x3; - if (req_clk > PHY_REQUEST_CLK_MAX || - req_clk < PHY_REQUEST_CLK_MIN) { - ret = E_REQUESTCLK_ERR; - if (log_level & AUDIO_LOG) - rx_pr("request clk err:%d\n", req_clk); - } else if (phy_pll_rate != aud_pll_cntl) { - ret = E_PLLRATE_CHG; - if (log_level & AUDIO_LOG) - rx_pr("pll rate chg,phy=%d,pll=%d\n", - phy_pll_rate, aud_pll_cntl); - } else if (aud_clk == 0) { - ret = E_AUDCLK_ERR; - if (log_level & AUDIO_LOG) - rx_pr("aud_clk=0\n"); + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* need to do something ...*/ + } else { + if (req_clk > PHY_REQUEST_CLK_MAX || + req_clk < PHY_REQUEST_CLK_MIN) { + ret = E_REQUESTCLK_ERR; + if (log_level & AUDIO_LOG) + rx_pr("request clk err:%d\n", req_clk); + } else if (phy_pll_rate != aud_pll_cntl) { + ret = E_PLLRATE_CHG; + if (log_level & AUDIO_LOG) + rx_pr("pll rate chg,phy=%d,pll=%d\n", + phy_pll_rate, aud_pll_cntl); + } else if (aud_clk == 0) { + ret = E_AUDCLK_ERR; + if (log_level & AUDIO_LOG) + rx_pr("aud_clk=0\n"); + } } - return ret; } +/* + * for tl1 phy function + */ +struct apll_param apll_tab[] = { + /* bw M, N, od, div, od2, od2_div */ + {apll_bw_24_40, 160, 1, 0x5, 32, 0x4, 16}, + {apll_bw_40_80, 80, 1, 0x4, 16, 0x3, 8}, + {apll_bw_80_150, 40, 1, 0x3, 8, 0x2, 4}, + {apll_bw_150_300, 0, 2, 0x2, 4, 0x1, 2}, + {apll_bw_300_600, 40, 1, 0x1, 2, 0x0, 1}, + {apll_bw_null, 40, 1, 0x3, 8, 0x2, 4}, +}; + +unsigned int aml_check_clk_bandwidth(unsigned int cableclk, + unsigned int clkrate) +{ + unsigned int bw; + unsigned int cab_clk = cableclk; + + /* 1:40 */ + if (clkrate) + cab_clk = cableclk << 2; + + /* 1:10 */ + if (cab_clk < 40000000) + bw = apll_bw_24_40; + else if (cab_clk < 80000000) + bw = apll_bw_40_80; + else if (cab_clk < 150000000) + bw = apll_bw_80_150; + else if (cab_clk < 300000000) + bw = apll_bw_150_300; + else if (cab_clk < 600000000) + bw = apll_bw_300_600; + else { + bw = apll_bw_80_150; + rx_pr("phy err: bw clk=%d\n", cableclk); + } + return bw; +} + +void aml_phy_init(unsigned int bw) +{ + unsigned int data32; + static unsigned int cnt; + + rx_pr("init phy port %d, bw:%d\n", rx.port, bw); + if (bw == apll_bw_null) { + return; + } else if (bw <= apll_bw_24_40) { + /* set port number and enable terminal connect */ + data32 = 0x30034078; + data32 |= (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + /* channel reset */ + data32 = 0x300347f8; + data32 |= (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + rx_pr("MISC_CNTL0=0x%x\n", data32); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02200000); + /* reset and select data port */ + data32 = 0x00000010; + data32 |= ((1 << rx.port) << 6); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + /* release reset */ + data32 |= (1 << 11); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + rx_pr("MISC_CNTL3=0x%x\n", data32); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000182); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x2800c202); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x010088a2); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e013130); + } else if (bw <= apll_bw_40_80) { + /* set port number and enable terminal connect */ + data32 = 0x30034078; + data32 |= (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + /* channel reset */ + data32 = 0x300347f8; + data32 |= (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + rx_pr("MISC_CNTL0=0x%x\n", data32); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02200000); + /* reset and select data port */ + data32 = 0x00000010; + data32 |= ((1 << rx.port) << 6); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + /* release reset */ + data32 |= (1 << 11); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + rx_pr("MISC_CNTL3=0x%x\n", data32); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000182); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x4800c202); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x01009126); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a); + if (cnt & 0x1) { + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e020200); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e420200); + } else { + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e060600); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e460600); + } + } else if (bw <= apll_bw_80_150) { + //phy default setting + /* set port number and enable terminal connect */ + data32 = 0x30034078 | (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + /* channel reset */ + data32 = 0x300347f8 | (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + rx_pr("MISC_CNTL0=0x%x\n", data32); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02200000); + /* reset and select data port */ + data32 = 0x00000010; + data32 |= ((1 << rx.port) << 6); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + /* release reset */ + data32 |= (1 << 11); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000222); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x4800c202); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x01009126); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000); + if (cnt & 0x1) { + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e020200); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e420200); + } else { + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e060600); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e460600); + } + } else if (bw <= apll_bw_150_300) { + /* 3G */ + /* set port number and enable terminal connect */ + data32 = 0x30034078 | (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + /* channel reset */ + data32 = 0x300347f8 | (1 << rx.port); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32); + rx_pr("MISC_CNTL0=0x%x\n", data32); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02200000); + /* reset and select data port */ + data32 = 0x00000010; + data32 |= ((1 << rx.port) << 6); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + /* release reset */ + data32 |= (1 << 11); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000242); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x0800c202); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x0100fc31); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a); + + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x000a0000); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e040410); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e440410); + udelay(1); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00120000); + udelay(1); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00020000); + } else { + /*6G*/ + } + cnt++; +} + +void aml_eq_setting(unsigned int bw) +{ + unsigned int data32; + + if (bw == apll_bw_null) { + return; + } else if (bw <= apll_bw_24_40) { + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000182); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x2800c202); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x010088a2); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e013130); + } else if (bw <= apll_bw_80_150) { + data32 = rd_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, data32); + /*reset*/ + data32 = rd_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1); + data32 &= (~(1 << 24)); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, data32); + /*eq reset*/ + data32 |= (1 << 24); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, data32); + } else { + /* 3G , 6G */ + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x000a0000); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e040410); + udelay(5); + /*eq reset*/ + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e440410); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00120000); + udelay(5); + wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00020000); + } +} + +void aml_phy_pll_setting(unsigned int bandwidth, unsigned int cableclk) +{ + unsigned int M, N; + unsigned int od, od_div; + unsigned int od2, od2_div; + unsigned int bw = bandwidth; + unsigned int vco_clk; + unsigned int apll_out; + unsigned int aud_pll_out; + unsigned int data, data2; + unsigned int aud_div; + + rx_pr("bw:%d, clkrate:%d\n", bandwidth, cableclk); + od_div = apll_tab[bw].od_div; + od = apll_tab[bw].od; + M = apll_tab[bw].M; + N = apll_tab[bw].N; + od2_div = apll_tab[bw].od2_div; + od2 = apll_tab[bw].od2; + + vco_clk = (cableclk * M) / N; + if ((vco_clk < 2970000) || (vco_clk > 6000000)) + rx_pr("err: M=%d,N=%d,vco_clk=%d\n", M, N, vco_clk); + + apll_out = (((cableclk * M)/N)/od_div)/5; + rx_pr("M=%d,N=%d,od=%d,od_div=%d\n", M, N, od, od_div); + rx_pr("apll_out=%d, vco_clk=%d\n", apll_out, vco_clk); + rx_pr("od2=%d, od2_div=%d\n", od2, od2_div); + + aud_pll_out = ((vco_clk/od2_div)/5); + rx_pr("aud pll out=%d\n", aud_pll_out); + + /*cntl0 M <7:0> N<14:10>*/ + data = 0x00090400 & 0xffff8300; + data |= M; + data |= (N << 10); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x20000000); + udelay(2); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x30000000); + rx_pr("APLL_CNTL0 4c:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0)); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL1, 0x00000000); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL2, 0x00001108); + data2 = 0x10058f30|od2; + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL3, data2); + + data2 = 0x000100c0 /*& 0xf8ffffff*/; + data2 |= (od << 24); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL4, data2); + udelay(2); + /*apll_vctrl_mon_en*/ + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL4, data2|0x00800000); + rx_pr("APLL_CNTL4 50:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL4)); + + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x34000000); + udelay(2); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x14000000); + rx_pr("APLL_CNTL0 4c:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0)); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL2, 0x00003008); + + + /*wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);*/ + /*wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e040400);*/ + /*udelay(2);*/ + /*wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e440400);*/ + + /* common block release reset */ + data = rd_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0); + data &= ~(0x7 << 7); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data); + udelay(2); + /* data channel release reset */ + data |= (0x7 << 7); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data); + + /*set audio pll divider*/ + aud_div = aud_pll_out/apll_out; + rx_pr("aud div=%d\n", aud_div); + if (aud_div == 1) + data = 0; + else if (aud_div == 2) + data = 1; + else if (aud_div == 4) + data = 2; + else if (aud_div == 8) + data = 3; + else if (aud_div == 16) + data = 4; + rx.physts.aud_div = data; +} + +void aml_phy_pw_onoff(unsigned int onoff) +{ + unsigned int data = rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0); + + if (onoff) { + /* apll power down */ + data &= ~(1 << 26); + data &= ~(1 << 28); + data |= (1 << 29); + wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data); + + /*phy */ + data = rd_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0); + data &= ~(1 << 7); + data &= ~(1 << 8); + data &= ~(1 << 9); + wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data); + } else { + aml_phy_init(apll_bw_80_150); + /*tl1_apll_setting(apll_bw_80_150);*/ + } +} + +/* + * aml phy initial + */ +void aml_phy_bw_switch(unsigned int cableclk, unsigned int clkrate) +{ + unsigned int bw = aml_check_clk_bandwidth(cableclk, clkrate); + + aml_phy_init(bw); + udelay(1); + aml_phy_pll_setting(bw, cableclk); + udelay(1); + aml_eq_setting(bw); +} + +unsigned int aml_phy_pll_lock(void) +{ + if (rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0) & 0x80000000) + return true; + else + return false; +} + +unsigned int aml_phy_tmds_valid(void) +{ + unsigned int tmvds_valid; + unsigned int sqofclk; + unsigned int pll_lock; + unsigned int tmds_align; + + tmvds_valid = hdmirx_rd_dwc(DWC_HDMI_PLL_LCK_STS) & 0x01; + sqofclk = rd_reg_hhi(HHI_HDMIRX_PHY_MISC_STAT) & 0x80000000; + pll_lock = rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0) & 0x80000000; + tmds_align = hdmirx_rd_top(TOP_TMDS_ALIGN_STAT) & 0x3f000000; + if (tmvds_valid && sqofclk && pll_lock && + (tmds_align == 0x3f000000)) + return true; + else + return false; +} + +void rx_phy_rxsense_pulse(unsigned int t1, unsigned int t2) +{ + /* for tl1 no SW eq */ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* ... */ + } else { + /* set rxsense pulse */ + hdmirx_phy_pddq(1); + mdelay(t1); + hdmirx_phy_pddq(0); + mdelay(t2); + } +} + +void rx_phy_power_on(unsigned int onoff) +{ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + /* ... */ + + } else { + if (onoff) + hdmirx_phy_pddq(0); + else + hdmirx_phy_pddq(1); + } +} + +void rx_emp_to_ddr_init(void) +{ + unsigned int data; + + if (rx.hdmirxdev->data->chip_id != CHIP_ID_TL1) + return; + + if (rx.empbuff.pg_addr) { + rx_pr("rx_emp_to_ddr_init\n"); + /* emp int enable */ + /* config ddr buffer */ + hdmirx_wr_top(TOP_EMP_DDR_START_A, + rx.empbuff.p_addr_a); + hdmirx_wr_top(TOP_EMP_DDR_START_B, + rx.empbuff.p_addr_b); + + /* enable store EMP pkt type */ + hdmirx_wr_top(TOP_EMP_DDR_FILTER, _BIT(15)); + /* max pkt count */ + hdmirx_wr_top(TOP_EMP_CNTMAX, EMP_BUFF_MAC_PKT_CNT); + + data = 0; + data |= 0xf << 16;/*[23:16] hs_beat_rate=0xf */ + /*[14] buffer_info_mode=0 */ + data |= 0x1 << 13;/*[13] reset_on_de=1 */ + data |= 0x1 << 12;/*[12] burst_end_on_last_emp=1 */ + /*[11:2] de_rise_delay=0 */ + /*[1:0] Endian = 0 */ + hdmirx_wr_top(TOP_EMP_CNTL_0, data); + + data = 0; + data |= 0 << 1;/*ddr_mode[1] 0: emp 1: tmds*/ + hdmirx_wr_top(TOP_EMP_CNTL_1, data); + + data |= 1; /*ddr_en[0] 1:enable*/ + hdmirx_wr_top(TOP_EMP_CNTL_1, data); + + /* emp int enable TOP_INTR_MASKN*/ + /* emp field end done at DE rist bit[25]*/ + /* emp last EMP pkt recv done bit[26]*/ + top_intr_maskn_value |= _BIT(25); + /*hdmirx_wr_top(TOP_INTR_MASKN, top_intr_maskn_value);*/ + } + + rx.empbuff.ready = 0; + rx.empbuff.irqcnt = 0; +} + +void rx_emp_field_done_irq(void) +{ + phys_addr_t p_addr; + unsigned int recv_pkt_cnt, emp_pkt_cnt; + unsigned char *src_addr; + unsigned char *dts_addr; + unsigned int i, j; + unsigned int datacnt = 0; + + /*emp data start p address*/ + p_addr = hdmirx_rd_top(TOP_EMP_DDR_PTR_S_BUF); + /*buffer number*/ + recv_pkt_cnt = hdmirx_rd_top(TOP_EMP_RCV_CNT_BUF); + /* p addr to v addr for cpu access */ + src_addr = phys_to_virt(p_addr); + + if (rx.empbuff.irqcnt & 0x1) + dts_addr = rx.empbuff.storeB; + else + dts_addr = rx.empbuff.storeA; + emp_pkt_cnt = 0; + if (recv_pkt_cnt < EMP_BUFF_MAC_PKT_CNT) { + for (i = 0; i < recv_pkt_cnt; i++) { + /*check PKT_TYPE_EMP = 0x7f*/ + if (src_addr[i] == 0x7f) { + emp_pkt_cnt++; + /*32 bytes per emp pkt*/ + for (j = 0; j < 32; j++) { + dts_addr[datacnt] = src_addr[i]; + datacnt++; + } + } + + } + } else { + rx_pr("pkt cnt err:%d\n", recv_pkt_cnt); + } + /*ready address*/ + rx.empbuff.ready = dts_addr; + /*ready pkt cnt*/ + rx.empbuff.emppktcnt = emp_pkt_cnt; + /*emp field dont irq counter*/ + rx.empbuff.irqcnt++; +} + +void rx_emp_status(void) +{ + unsigned int i, j; + unsigned char *pdata; + + rx_pr("p_addr_a=0x%x\n", rx.empbuff.p_addr_a); + rx_pr("p_addr_b=0x%x\n", rx.empbuff.p_addr_b); + rx_pr("irq cnt =0x%x\n", rx.empbuff.irqcnt); + rx_pr("p_addr_b=0x%p\n", rx.empbuff.ready); + rx_pr("recv pkt cnt=0x%x\n", rx.empbuff.emppktcnt); + + pdata = rx.empbuff.ready; + for (i = 0; i < rx.empbuff.emppktcnt; i++) { + for (j = 0; j < 32; j++) + rx_pr("0x%02lx, ", pdata[i*32 + j]); + rx_pr("\n"); + } +} + + +void rx_tmds_to_ddr_init(void) +{ + unsigned int data, data2; + unsigned int i = 0; + + if (rx.hdmirxdev->data->chip_id != CHIP_ID_TL1) + return; + + if (rx.empbuff.pg_addr) { + rx_pr("rx_emp_to_ddr_init\n"); + /* disable emp rev */ + data = hdmirx_rd_top(TOP_EMP_CNTL_1); + data &= ~0x1; + hdmirx_wr_top(TOP_EMP_CNTL_1, data); + /* wait until emp finish */ + data2 = hdmirx_rd_top(TOP_EMP_STAT_0) & 0x7fffffff; + data = hdmirx_rd_top(TOP_EMP_STAT_1); + while (data2 || data) { + mdelay(1); + data2 = hdmirx_rd_top(TOP_EMP_STAT_0) & 0x7fffffff; + data = hdmirx_rd_top(TOP_EMP_STAT_1); + if (i++ > 100) { + rx_pr("warning: wait emp finish\n"); + break; + } + } + + /* config ddr buffer */ + hdmirx_wr_top(TOP_EMP_DDR_START_A, + rx.empbuff.p_addr_a); + + /* max pkt count */ + /* one frame size: HxVx3x1.25 bytes */ + data = ((rx.empbuff.emppktcnt/8) * 8) - 1; + hdmirx_wr_top(TOP_EMP_CNTMAX, data); + rx_pr("cnt max=0x%x\n", data); + + data = 0; + data |= 0xf << 16;/*[23:16] hs_beat_rate=0xf */ + /*[14] buffer_info_mode=0 */ + data |= 0x1 << 13;/*[13] reset_on_de=1 */ + data |= 0x0 << 12;/*[12] burst_end_on_last_emp=1 */ + data |= 0x0 << 2;/*[11:2] de_rise_delay=0 */ + data |= 0x0 << 0;/*[1:0] Endian = 0 */ + hdmirx_wr_top(TOP_EMP_CNTL_0, data); + + data = 0; + data |= 1 << 1;/*ddr_mode[1] 0: emp 1: tmds*/ + hdmirx_wr_top(TOP_EMP_CNTL_1, data); + + data |= 1; /*ddr_en[0] 1:enable*/ + hdmirx_wr_top(TOP_EMP_CNTL_1, data); + + /* emp int enable TOP_INTR_MASKN*/ + /* emp field end done at DE rist bit[25]*/ + /* emp last EMP pkt recv done bit[26]*/ + top_intr_maskn_value |= _BIT(26); + hdmirx_wr_top(TOP_INTR_MASKN, top_intr_maskn_value); + } +} + +void rx_emp_lastpkt_done_irq(void) +{ + /* need to do ...*/ +} + diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h index b906ad2..c56d304 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -19,6 +19,8 @@ #define __HDMI_RX_HW_H__ +/*#define K_BRINGUP_PTM*/ + /** * Bit field mask * @param m width @@ -31,10 +33,12 @@ */ #define _BIT(n) MSK(1, (n)) +#define diff(a, b) ((a > b) ? (a - b) : (b - a)) #define HHI_GCLK_MPEG0 (0x50 << 2) /* (0xC883C000 + 0x140) */ #define HHI_HDMIRX_CLK_CNTL 0x200 /* (0xC883C000 + 0x200) */ #define HHI_HDMIRX_AUD_CLK_CNTL 0x204 /* 0x1081 */ +#define HHI_VDAC_CNTL1 (0xbc * 4) #define HHI_AUD_PLL_CNTL (0xf8 * 4) #define HHI_AUD_PLL_CNTL2 (0xf9 * 4) #define HHI_AUD_PLL_CNTL3 (0xfa * 4) @@ -196,6 +200,13 @@ #define TOP_EDID_GEN_STAT_B 0x025 #define TOP_EDID_GEN_STAT_C 0x026 #define TOP_EDID_GEN_STAT_D 0x027 +/* tl1 */ +#define TOP_CHAN_SWITCH_0 0x028 +#define TOP_TMDS_ALIGN_CNTL0 0x029 +#define TOP_TMDS_ALIGN_CNTL1 0x02a +#define TOP_TMDS_ALIGN_STAT 0x02b + +/* GXTVBB/TXL/TXLX */ #define TOP_ACR_CNTL2 0x02a /* Gxtvbb */ #define TOP_INFILTER_GXTVBB 0x02b @@ -206,28 +217,79 @@ #define TOP_INFILTER_I2C1 0x02E #define TOP_INFILTER_I2C2 0x02F #define TOP_INFILTER_I2C3 0x030 +/* tl1 */ +#define TOP_PRBS_GEN 0x033 +#define TOP_PRBS_ANA_0 0x034 +#define TOP_PRBS_ANA_1 0x035 +#define TOP_PRBS_ANA_STAT 0x036 +#define TOP_PRBS_ANA_BER_CH0 0x037 +#define TOP_PRBS_ANA_BER_CH1 0x038 +#define TOP_PRBS_ANA_BER_CH2 0x039 +#define TOP_METER_CABLE_CNTL 0x03a +#define TOP_METER_CABLE_STAT 0x03b +#define TOP_CHAN_SWITCH_1 0x03c +/* tl1 */ +#define TOP_AUDPLL_LOCK_FILTER 0x040 + +/* tl1 */ +#define TOP_CHAN01_ERRCNT 0x041 +#define TOP_CHAN2_ERRCNT 0x042 +#define TOP_TL1_ACR_CNTL2 0x043 +#define TOP_ACR_N_STAT 0x044 +#define TOP_ACR_CTS_STAT 0x045 +#define TOP_AUDMEAS_CTRL 0x046 +#define TOP_AUDMEAS_CYCLES_M1 0x047 +#define TOP_AUDMEAS_INTR_MASKN 0x048 +#define TOP_AUDMEAS_INTR_STAT 0x049 +#define TOP_AUDMEAS_REF_CYCLES_STAT0 0x04a +#define TOP_AUDMEAS_REF_CYCLES_STAT1 0x04b +#define TOP_HDCP22_BSOD 0x060 + + +#define TOP_SKP_CNTL_STAT 0x061 +#define TOP_NONCE_0 0x062 +#define TOP_NONCE_1 0x063 +#define TOP_NONCE_2 0x064 +#define TOP_NONCE_3 0x065 +#define TOP_PKF_0 0x066 +#define TOP_PKF_1 0x067 +#define TOP_PKF_2 0x068 +#define TOP_PKF_3 0x069 +#define TOP_DUK_0 0x06a +#define TOP_DUK_1 0x06b +#define TOP_DUK_2 0x06c +#define TOP_DUK_3 0x06d +#define TOP_NSEC_SCRATCH 0x06e +#define TOP_SEC_SCRATCH 0x06f +/* TL1 */ +#define TOP_EMP_DDR_START_A 0x070 +#define TOP_EMP_DDR_START_B 0x071 +#define TOP_EMP_DDR_FILTER 0x072 +#define TOP_EMP_CNTL_0 0x073 +#define TOP_EMP_CNTL_1 0x074 +#define TOP_EMP_CNTMAX 0x075 +#define TOP_EMP_ERR_STAT 0x076 +#define TOP_EMP_RCV_CNT_CUR 0x077 +#define TOP_EMP_RCV_CNT_BUF 0x078 +#define TOP_EMP_DDR_ADDR_CUR 0x079 +#define TOP_EMP_DDR_PTR_S_BUF 0x07a +#define TOP_EMP_STAT_0 0x07b +#define TOP_EMP_STAT_1 0x07c +#define TOP_AXI_CNTL_0 0x080 +#define TOP_AXI_ASYNC_HOLD_ESM 0x081 +#define TOP_AXI_ASYNC_HOLD_EMP 0x082 +#define TOP_AXI_STAT_0 0x083 +#define TOP_MISC_STAT0 0x084 +#define TOP_EDID_ADDR_S 0x1000 +#define TOP_EDID_ADDR_E 0x11ff +#define TOP_DWC_BASE_OFFSET 0x8000 + -#define TOP_SKP_CNTL_STAT 0x061 -#define TOP_NONCE_0 0x062 -#define TOP_NONCE_1 0x063 -#define TOP_NONCE_2 0x064 -#define TOP_NONCE_3 0x065 -#define TOP_PKF_0 0x066 -#define TOP_PKF_1 0x067 -#define TOP_PKF_2 0x068 -#define TOP_PKF_3 0x069 -#define TOP_DUK_0 0x06a -#define TOP_DUK_1 0x06b -#define TOP_DUK_2 0x06c -#define TOP_DUK_3 0x06d -#define TOP_NSEC_SCRATCH 0x06e -#define TOP_SEC_SCRATCH 0x06f #define TOP_DONT_TOUCH0 0x0fe #define TOP_DONT_TOUCH1 0x0ff - /* hdmi2.0 new end */ -#define TOP_EDID_OFFSET 0x200 +#define TOP_EDID_OFFSET 0x200 /* * HDMI registers @@ -564,6 +626,8 @@ #define PFIFO_ACP_EN _BIT(18)/*type:0x04*/ #define PFIFO_GCP_EN _BIT(17)/*type:0x03*/ #define PFIFO_ACR_EN _BIT(16)/*type:0x01*/ +/*tl1*/ +#define PFIFO_EMP_EN _BIT(9)/*type:0x7f*/ #define GCP_GLOBAVMUTE _BIT(15) /** Packet FIFO clear min/max information */ @@ -977,6 +1041,29 @@ #define EXCEPTION_CODE MSK(8, 1) #define AUD_PLL_THRESHOLD 1000000 +/* tl1 HIU apll register */ +#define HHI_HDMIRX_APLL_CNTL0 (0xd2<<2)/* 0x4C */ +#define HHI_HDMIRX_APLL_CNTL1 (0xd3<<2)/* 0x4D */ +#define HHI_HDMIRX_APLL_CNTL2 (0xd4<<2)/* 0x4E */ +#define HHI_HDMIRX_APLL_CNTL3 (0xd5<<2)/* 0x4F */ +#define HHI_HDMIRX_APLL_CNTL4 (0xd6<<2)/* 0x50 */ + +/* tl1 HIU PHY register */ +#define HHI_HDMIRX_PHY_MISC_CNTL0 (0xd7<<2)/*0x040*/ +#define HHI_HDMIRX_PHY_MISC_CNTL1 (0xd8<<2)/*0x041*/ +#define HHI_HDMIRX_PHY_MISC_CNTL2 (0xe0<<2)/*0x042*/ +#define HHI_HDMIRX_PHY_MISC_CNTL3 (0xe1<<2)/*0x043*/ +#define HHI_HDMIRX_PHY_MISC_STAT (0xee<<2)/*0x044*/ +#define HHI_HDMIRX_PHY_DCHA_CNTL0 (0xe2<<2)/*0x045*/ +#define HHI_HDMIRX_PHY_DCHA_CNTL1 (0xe3<<2)/*0x046*/ +#define HHI_HDMIRX_PHY_DCHA_CNTL2 (0xe4<<2)/*0x047*/ +#define HHI_HDMIRX_PHY_DCHD_CNTL0 (0xe5<<2)/*0x048*/ +#define HHI_HDMIRX_PHY_DCHD_CNTL1 (0xe6<<2)/*0x049*/ +#define HHI_HDMIRX_PHY_DCHD_CNTL2 (0xe7<<2)/*0x04A*/ +#define HHI_HDMIRX_PHY_DCHD_STAT (0xef<<2)/*0x04B*/ + + + #define TMDS_CLK_MIN (24000UL) #define TMDS_CLK_MAX (340000UL) @@ -1010,6 +1097,8 @@ extern int md_ists_en; extern int eq_ref_voltage; extern int aud_ch_map; extern int hdcp14_key_mode; +extern int ignore_sscp_charerr; +extern int ignore_sscp_tmds; extern void wr_reg_hhi(unsigned int offset, unsigned int val); extern unsigned int rd_reg_hhi(unsigned int offset); @@ -1018,6 +1107,10 @@ extern unsigned int rd_reg(enum map_addr_module_e module, extern void wr_reg(enum map_addr_module_e module, unsigned int reg_addr, unsigned int val); +extern unsigned char rd_reg_b(enum map_addr_module_e module, + unsigned char reg_addr); +extern void wr_reg_b(enum map_addr_module_e module, + unsigned int reg_addr, unsigned char val); extern void hdmirx_wr_top(unsigned int addr, unsigned int data); extern unsigned int hdmirx_rd_top(unsigned int addr); extern void hdmirx_wr_dwc(unsigned int addr, unsigned int data); @@ -1035,12 +1128,13 @@ extern unsigned int rx_get_bits(unsigned int data, unsigned int mask); extern unsigned int rx_set_bits(unsigned int data, unsigned int mask, unsigned int value); -extern unsigned int hdmirx_get_tmds_clock(void); -extern unsigned int hdmirx_get_pixel_clock(void); -extern unsigned int hdmirx_get_audio_clock(void); -extern unsigned int hdmirx_get_esm_clock(void); -extern unsigned int hdmirx_get_mpll_div_clk(void); -extern unsigned int hdmirx_get_clock(int index); +/*extern unsigned int hdmirx_get_tmds_clock(void);*/ +/*extern unsigned int hdmirx_get_pixel_clock(void);*/ +/*extern unsigned int hdmirx_get_audio_clock(void);*/ +/*extern unsigned int hdmirx_get_esm_clock(void);*/ +/*extern unsigned int hdmirx_get_cable_clock(void);*/ +/*extern unsigned int hdmirx_get_mpll_div_clk(void);*/ +/*extern unsigned int hdmirx_get_clock(int index);*/ extern unsigned int meson_clk_measure(unsigned int clk_mux); /* hdcp22 */ @@ -1102,6 +1196,60 @@ extern void rx_force_hpd_cfg(uint8_t hpd_level); extern void rx_force_rxsense_cfg(uint8_t level); extern void rx_force_hpd_rxsense_cfg(uint8_t level); extern void rx_audio_bandgap_rst(void); +extern void rx_audio_bandgap_rst(void); +extern void rx_phy_rxsense_pulse(unsigned int t1, unsigned int t2); +extern void rx_phy_power_on(unsigned int onoff); + + +#define K_MEASURE_SRC_HDMI_TMDSCLK 0 +#define K_MEASURE_SRC_HDMI_CABLECLK 1 + +enum measure_clk_src { + MEASURE_CLK_CABLE, + MEASURE_CLK_TMDS, + MEASURE_CLK_PIXEL, + MEASURE_CLK_MPLL, + MEASURE_CLK_AUD_PLL, + MEASURE_CLK_AUD_DIV, + MEASURE_CLK_ESM, +}; + +enum apllbw { + apll_bw_24_40 = 0, + apll_bw_40_80, + apll_bw_80_150, + apll_bw_150_300, + apll_bw_300_600, + apll_bw_null = 0xf, +}; + + +struct apll_param { + unsigned int bw; + unsigned int M; + unsigned int N; + unsigned int od; + unsigned int od_div; + unsigned int od2; + unsigned int od2_div; +}; + +extern unsigned int rx_get_clock(unsigned int clk_src); +extern unsigned int clk_util_clk_msr(unsigned int clk_mux); +extern unsigned int rx_measure_clock(enum measure_clk_src clksrc); +extern void aml_phy_init(unsigned int bw); +extern void aml_phy_pw_onoff(unsigned int onoff); +extern unsigned int aml_check_clk_bandwidth(unsigned int cableclk, + unsigned int clkrate); +extern void aml_sw_apll(unsigned int bandwidth, unsigned int cableclk); +extern void aml_phy_bw_switch(unsigned int cableclk, unsigned int clkrate); +extern unsigned int aml_phy_pll_lock(void); +extern unsigned int aml_phy_tmds_valid(void); +extern void rx_emp_to_ddr_init(void); +extern void rx_emp_field_done_irq(void); +extern void rx_emp_status(void); +extern void rx_emp_lastpkt_done_irq(void); + #endif diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c index a78d454..dcaafe1 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c @@ -63,6 +63,8 @@ static struct pkt_typeregmap_st pktmaping[] = { {PKT_TYPE_ISRC2, PFIFO_ISRC2_EN}, {PKT_TYPE_GAMUT_META, PFIFO_GMT_EN}, {PKT_TYPE_AUD_META, PFIFO_AMP_EN}, + {PKT_TYPE_EMP, PFIFO_EMP_EN}, + /*end of the table*/ {K_FLAG_TAB_END, K_FLAG_TAB_END}, }; @@ -99,6 +101,7 @@ void rx_pkt_status(void) rx_pr("pkt_cnt_isrc2=%d\n", rxpktsts.pkt_cnt_isrc2); rx_pr("pkt_cnt_gameta=%d\n", rxpktsts.pkt_cnt_gameta); rx_pr("pkt_cnt_amp=%d\n", rxpktsts.pkt_cnt_amp); + rx_pr("pkt_cnt_emp=%d\n", rxpktsts.pkt_cnt_emp); rx_pr("pkt_cnt_vsi_ex=%d\n", rxpktsts.pkt_cnt_vsi_ex); rx_pr("pkt_cnt_drm_ex=%d\n", rxpktsts.pkt_cnt_drm_ex); @@ -109,6 +112,7 @@ void rx_pkt_status(void) rx_pr("pkt_cnt_gcp_ex=%d\n", rxpktsts.pkt_cnt_gcp_ex); rx_pr("pkt_cnt_amp_ex=%d\n", rxpktsts.pkt_cnt_amp_ex); rx_pr("pkt_cnt_nvbi_ex=%d\n", rxpktsts.pkt_cnt_nvbi_ex); + rx_pr("pkt_cnt_nvbi_ex=%d\n", rxpktsts.pkt_cnt_emp_ex); rx_pr("pkt_chk_flg=%d\n", rxpktsts.pkt_chk_flg); @@ -133,8 +137,8 @@ void rx_pkt_debug(void) rx_pr("vbi_infoframe_st size=%d\n", sizeof(struct vbi_infoframe_st)); rx_pr("drm_infoframe_st size=%d\n", sizeof(struct drm_infoframe_st)); - rx_pr("acr_ptk_st size=%d\n", - sizeof(struct acr_ptk_st)); + rx_pr("acr_pkt_st size=%d\n", + sizeof(struct acr_pkt_st)); rx_pr("aud_sample_pkt_st size=%d\n", sizeof(struct aud_sample_pkt_st)); rx_pr("gcp_pkt_st size=%d\n", sizeof(struct gcp_pkt_st)); @@ -158,7 +162,8 @@ void rx_pkt_debug(void) sizeof(struct msaudsmp_pkt_st)); rx_pr("onebmtstr_smaud_pkt_st size=%d\n", sizeof(struct obmaudsmp_pkt_st)); - + rx_pr("emp size=%d\n", + sizeof(struct emp_pkt_st)); memset(&rxpktsts, 0, sizeof(struct rxpkt_st)); data32 = hdmirx_rd_dwc(DWC_PDEC_CTRL); @@ -179,6 +184,9 @@ void rx_pkt_debug(void) data32 |= (rx_pkt_type_mapping(PKT_TYPE_ISRC1)); data32 |= (rx_pkt_type_mapping(PKT_TYPE_ISRC2)); data32 |= (rx_pkt_type_mapping(PKT_TYPE_GAMUT_META)); + if (rx.chip_id == CHIP_ID_TL1) + data32 |= (rx_pkt_type_mapping(PKT_TYPE_EMP)); + hdmirx_wr_dwc(DWC_PDEC_CTRL, data32); rx_pr("enable fifo\n"); @@ -342,6 +350,8 @@ void rx_debug_pktinfo(char input[][20]) enable |= _BIT(30);/* DRC_RCV*/ else enable |= _BIT(9);/* DRC_RCV*/ + if (rx.chip_id == CHIP_ID_TL1) + enable |= _BIT(9);/* EMP_RCV*/ enable |= _BIT(20);/* GMD_RCV */ enable |= _BIT(19);/* AIF_RCV */ enable |= _BIT(18);/* AVI_RCV */ @@ -382,7 +392,12 @@ void rx_debug_pktinfo(char input[][20]) sts = VSI_RCV; else if (strncmp(input[2], "amp", 3) == 0) sts = _BIT(14); - + else if (strncmp(input[2], "emp", 3) == 0) { + if (rx.chip_id == CHIP_ID_TL1) + sts = _BIT(9); + else + rx_pr("no emp function\n"); + } pdec_ists_en &= ~sts; rx_pr("pdec_ists_en=0x%x\n", pdec_ists_en); /*disable irq*/ @@ -411,6 +426,12 @@ void rx_debug_pktinfo(char input[][20]) enable |= VSI_RCV; else if (strncmp(input[2], "amp", 3) == 0) enable |= _BIT(14); + else if (strncmp(input[2], "emp", 3) == 0) { + if (rx.chip_id == CHIP_ID_TL1) + enable |= _BIT(9); + else + rx_pr("no emp function\n"); + } pdec_ists_en = enable|sts; rx_pr("pdec_ists_en=0x%x\n", pdec_ists_en); /*open irq*/ @@ -675,7 +696,7 @@ static void rx_pktdump_drm(void *pdata) static void rx_pktdump_acr(void *pdata) { - struct acr_ptk_st *pktdata = pdata; + struct acr_pkt_st *pktdata = pdata; uint32_t CTS; uint32_t N; @@ -729,6 +750,25 @@ static void rx_pktdump_acr(void *pdata) rx_pr(">------------------>end\n"); } +static void rx_pktdump_emp(void *pdata) +{ + struct emp_pkt_st *pktdata = pdata; + + rx_pr("pkttype=0x%x\n", pktdata->pkttype); + rx_pr("first=0x%x\n", pktdata->first); + rx_pr("last=0x%x\n", pktdata->last); + rx_pr("sequence_idx=0x%x\n", pktdata->sequence_idx); + rx_pr("cnt.new=0x%x\n", pktdata->cnt.new); + rx_pr("cnt.end=0x%x\n", pktdata->cnt.end); + rx_pr("cnt.ds_type=0x%x\n", pktdata->cnt.ds_type); + rx_pr("cnt.afr=0x%x\n", pktdata->cnt.afr); + rx_pr("cnt.vfr=0x%x\n", pktdata->cnt.vfr); + rx_pr("cnt.sync=0x%x\n", pktdata->cnt.sync); + rx_pr("cnt.or_id=0x%x\n", pktdata->cnt.organization_id); + rx_pr("cnt.tag=0x%x\n", pktdata->cnt.data_set_tag); + rx_pr("cnt.length=0x%x\n", pktdata->cnt.data_set_length); +} + void rx_pkt_dump(enum pkt_type_e typeID) { struct packet_info_s *prx = &rx_pkt; @@ -818,7 +858,10 @@ void rx_pkt_dump(enum pkt_type_e typeID) rx_pkt_get_amp_ex(&pktdata); rx_pktdump_raw(&pktdata); break; - + case PKT_TYPE_EMP: + rx_pktdump_emp(&prx->emp_info); + rx_pktdump_raw(&prx->emp_info); + break; default: rx_pr("warning: not support\n"); rx_pr("vsi->0x81:Vendor-Specific infoframe\n"); @@ -835,7 +878,7 @@ void rx_pkt_dump(enum pkt_type_e typeID) rx_pr("isrc2->0x06\n"); rx_pr("gmd->0x0a\n"); rx_pr("amp->0x0d\n"); - /*rx_pktdump_raw(&prx->dbg_info);*/ + rx_pr("emp->0x7f:EMP\n"); break; } @@ -895,6 +938,7 @@ void rx_pkt_initial(void) memset(&rx_pkt.mpegs_info, 0, sizeof(struct pd_infoframe_s)); memset(&rx_pkt.ntscvbi_info, 0, sizeof(struct pd_infoframe_s)); memset(&rx_pkt.drm_info, 0, sizeof(struct pd_infoframe_s)); + memset(&rx_pkt.emp_info, 0, sizeof(struct pd_infoframe_s)); memset(&rx_pkt.acr_info, 0, sizeof(struct pd_infoframe_s)); memset(&rx_pkt.gcp_info, 0, sizeof(struct pd_infoframe_s)); @@ -950,7 +994,7 @@ void rx_pkt_get_audif_ex(void *pktinfo) void rx_pkt_get_acr_ex(void *pktinfo) { - struct acr_ptk_st *pkt = pktinfo; + struct acr_pkt_st *pkt = pktinfo; uint32_t N, CTS; if (pktinfo == NULL) { @@ -958,7 +1002,7 @@ void rx_pkt_get_acr_ex(void *pktinfo) return; } - /*memset(pkt, 0, sizeof(struct acr_ptk_st));*/ + /*memset(pkt, 0, sizeof(struct acr_pkt_st));*/ pkt->pkttype = PKT_TYPE_ACR; pkt->zero0 = 0x0; @@ -1426,6 +1470,8 @@ void rx_pkt_buffclear(enum pkt_type_e pkt_type) pktinfo = &prx->ntscvbi_info; else if (pkt_type == PKT_TYPE_INFOFRAME_DRM) pktinfo = &prx->drm_info; + else if (pkt_type == PKT_TYPE_EMP) + pktinfo = &prx->emp_info; else if (pkt_type == PKT_TYPE_ACR) pktinfo = &prx->acr_info; else if (pkt_type == PKT_TYPE_GCP) @@ -1909,6 +1955,14 @@ int rx_pkt_fifodecode(struct packet_info_s *prx, pktdata, sizeof(struct pd_infoframe_s)); pktsts->pkt_op_flag &= ~PKT_OP_AMP; break; + case PKT_TYPE_EMP: + pktsts->pkt_cnt_emp++; + pktsts->pkt_op_flag |= PKT_OP_EMP; + memcpy(&prx->emp_info, + pktdata, sizeof(struct pd_infoframe_s)); + pktsts->pkt_op_flag &= ~PKT_OP_EMP; + break; + default: break; } @@ -2018,6 +2072,9 @@ readpkt: rx_pkt_get_ntscvbi_ex(&prx->ntscvbi_info); rxpktsts.pkt_op_flag &= ~PKT_OP_NVBI; rxpktsts.pkt_cnt_nvbi_ex++; + } else if (pkt_int_src == PKT_BUFF_SET_EMP) { + rxpktsts.pkt_op_flag &= ~PKT_OP_EMP; + rxpktsts.pkt_cnt_emp_ex++; } /*t2 = sched_clock();*/ diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h index 68f79d9..c9fcc1a 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h @@ -46,6 +46,7 @@ enum pkt_decode_type { PKT_BUFF_SET_AMP = 0x80, PKT_BUFF_SET_DRM = 0x100, PKT_BUFF_SET_NVBI = 0x200, + PKT_BUFF_SET_EMP = 0x400, PKT_BUFF_SET_UNKNOWN = 0xffff, }; @@ -76,6 +77,7 @@ enum pkt_type_e { PKT_TYPE_INFOFRAME_MPEGSRC = 0x85, PKT_TYPE_INFOFRAME_NVBI = 0x86, PKT_TYPE_INFOFRAME_DRM = 0x87, + PKT_TYPE_EMP = 0x7f, PKT_TYPE_UNKNOWN, }; @@ -90,6 +92,7 @@ enum pkt_op_flag { PKT_OP_MPEGS = 0x10, PKT_OP_NVBI = 0x20, PKT_OP_DRM = 0x40, + PKT_OP_EMP = 0x80, PKT_OP_ACR = 0x100, PKT_OP_GCP = 0x200, @@ -107,7 +110,7 @@ struct pkt_typeregmap_st { }; /* audio clock regeneration pkt - 0x1 */ -struct acr_ptk_st { +struct acr_pkt_st { /*packet header*/ uint8_t pkttype; uint8_t zero0; @@ -512,6 +515,37 @@ struct obmaudsmp_pkt_st { } __packed sbpkt; } __packed; + +/* EMP pkt - 0x7f */ +struct emp_pkt_st { + /*packet header*/ + uint8_t pkttype; + /*hb1*/ + uint8_t first:1; + uint8_t last:1; + uint8_t hb1_rsvd:6; + /*hb2*/ + uint8_t sequence_idx; + + uint8_t rsvd; + /*content*/ + struct content_st { + uint8_t new:1; + uint8_t end:1; + uint8_t ds_type:2; + uint8_t afr:1; + uint8_t vfr:1; + uint8_t sync:1; + uint8_t rev_0:1; + uint8_t rev_1; + uint8_t organization_id; + uint16_t data_set_tag; + uint16_t data_set_length; + uint8_t md[21]; + } __packed cnt; +} __packed; + + /* fifo raw data type - 0x8x */ struct fifo_rawdata_st { /*packet header*/ @@ -773,7 +807,7 @@ struct drm_infoframe_st { union pktinfo { /*normal packet 0x0-0xf*/ - struct acr_ptk_st audclkgen_ptk; + struct acr_pkt_st audclkgen_ptk; struct aud_sample_pkt_st audsmp_pkt; struct gcp_pkt_st gcp_pkt; struct acp_pkt_st acp_pkt; @@ -787,6 +821,7 @@ union pktinfo { struct audmtdata_pkt_st audmeta_pkt; struct msaudsmp_pkt_st mulstraudsamp_pkt; struct obmaudsmp_pkt_st obmasmpaud_pkt; + struct emp_pkt_st emp_pkt; }; union infoframe_u { @@ -825,6 +860,7 @@ struct rxpkt_st { uint32_t pkt_cnt_isrc2; uint32_t pkt_cnt_gameta; uint32_t pkt_cnt_amp; + uint32_t pkt_cnt_emp; uint32_t pkt_cnt_vsi_ex; uint32_t pkt_cnt_drm_ex; @@ -835,6 +871,7 @@ struct rxpkt_st { uint32_t pkt_cnt_gcp_ex; uint32_t pkt_cnt_amp_ex; uint32_t pkt_cnt_nvbi_ex; + uint32_t pkt_cnt_emp_ex; uint32_t pkt_op_flag; @@ -888,6 +925,9 @@ struct packet_info_s { struct pd_infoframe_s gameta_info; /* packet type 0x0d audio metadata data */ struct pd_infoframe_s amp_info; + + /* packet type 0x7f emp */ + struct pd_infoframe_s emp_info; }; struct st_pkt_test_buff { @@ -921,6 +961,9 @@ struct st_pkt_test_buff { /* packet type 0x0d audio metadata data */ struct pd_infoframe_s amp_info; + /* packet type 0x7f EMP */ + struct pd_infoframe_s emp_info; + /*externl set*/ struct pd_infoframe_s ex_vsi; struct pd_infoframe_s ex_avi; diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index 97aacda..ecf4640 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -266,6 +266,7 @@ static int hdmi_rx_ctrl_irq_handler(void) uint32_t intr_hdcp22 = 0; bool vsi_handle_flag = false; bool drm_handle_flag = false; + bool emp_handle_flag = false; uint32_t rx_top_intr_stat = 0; bool irq_need_clr = 0; @@ -396,9 +397,18 @@ static int hdmi_rx_ctrl_irq_handler(void) if (log_level & 0x200) rx_pr("[irq] FIFO MIN\n"); } - if (rx.chip_id != CHIP_ID_TXLX) { + + if (rx.chip_id == CHIP_ID_TL1) { if (rx_get_bits(intr_pedc, - DRM_RCV_EN) != 0) { + _BIT(9)) != 0) { + if (log_level & 0x400) + rx_pr("[irq] EMP_RCV %#x\n", + intr_pedc); + emp_handle_flag = true; + } + } else if (rx.chip_id == CHIP_ID_TXLX) { + if (rx_get_bits(intr_pedc, + DRM_RCV_EN_TXLX) != 0) { if (log_level & 0x400) rx_pr("[irq] DRM_RCV_EN %#x\n", intr_pedc); @@ -406,7 +416,7 @@ static int hdmi_rx_ctrl_irq_handler(void) } } else { if (rx_get_bits(intr_pedc, - DRM_RCV_EN_TXLX) != 0) { + DRM_RCV_EN) != 0) { if (log_level & 0x400) rx_pr("[irq] DRM_RCV_EN %#x\n", intr_pedc); @@ -449,6 +459,9 @@ static int hdmi_rx_ctrl_irq_handler(void) if (drm_handle_flag) rx_pkt_handler(PKT_BUFF_SET_DRM); + if (emp_handle_flag) + rx_pkt_handler(PKT_BUFF_SET_EMP); + if (rx.irq_flag) tasklet_schedule(&rx_tasklet); @@ -474,6 +487,33 @@ reisr:hdmirx_top_intr_stat = hdmirx_rd_top(TOP_INTR_STAT); hdmirx_wr_top(TOP_INTR_STAT_CLR, hdmirx_top_intr_stat); /* modify interrupt flow for isr loading */ /* top interrupt handler */ + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) { + if (hdmirx_top_intr_stat & (1 << 29)) + if (log_level & 0x100) + rx_pr("[isr] sqofclk_fall\n"); + if (hdmirx_top_intr_stat & (1 << 28)) + if (log_level & 0x100) + rx_pr("[isr] sqofclk_rise\n"); + if (hdmirx_top_intr_stat & (1 << 27)) + if (log_level & 0x400) + rx_pr("[isr] DE rise edge.\n"); + if (hdmirx_top_intr_stat & (1 << 26)) { + rx_emp_lastpkt_done_irq(); + if (log_level & 0x400) + rx_pr("[isr] last_emp_done\n"); + } + if (hdmirx_top_intr_stat & (1 << 25)) { + rx_emp_field_done_irq(); + if (log_level & 0x400) + rx_pr("[isr] emp_field_done\n"); + } + if (hdmirx_top_intr_stat & (1 << 24)) + if (log_level & 0x100) + rx_pr("[isr] tmds_align_stable_chg\n"); + if (hdmirx_top_intr_stat & (1 << 23)) + if (log_level & 0x100) + rx_pr("[isr] meter_stable_chg_cable\n"); + } if (hdmirx_top_intr_stat & (1 << 13)) rx_pr("[isr] auth rise\n"); if (hdmirx_top_intr_stat & (1 << 14)) @@ -1188,7 +1228,10 @@ bool is_tmds_valid(void) if (force_vic) return true; - return (rx_get_pll_lock_sts() == 1) ? true : false; + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + return (aml_phy_tmds_valid() == 1) ? true : false; + else + return (rx_get_pll_lock_sts() == 1) ? true : false; } void esm_set_reset(bool reset) @@ -1671,6 +1714,10 @@ int rx_set_global_variable(const char *buf, int size) return pr_var(pll_unlock_max, index); if (set_pr_var(tmpbuf, esd_phy_rst_max, value, &index, ret)) return pr_var(esd_phy_rst_max, index); + if (set_pr_var(tmpbuf, ignore_sscp_charerr, value, &index, ret)) + return pr_var(ignore_sscp_charerr, index); + if (set_pr_var(tmpbuf, ignore_sscp_tmds, value, &index, ret)) + return pr_var(ignore_sscp_tmds, index); return 0; } @@ -1773,6 +1820,8 @@ void rx_get_global_variable(const char *buf) pr_var(hdcp_none_wait_max, i++); pr_var(pll_unlock_max, i++); pr_var(esd_phy_rst_max, i++); + pr_var(ignore_sscp_charerr, i++); + pr_var(ignore_sscp_tmds, i++); } void skip_frame(unsigned int cnt) @@ -1916,6 +1965,52 @@ void rx_5v_monitor(void) rx.cur_5v_sts = (pwr_sts >> rx.port) & 1; } +/* + * func : check hdmi cable clk and clk rate + * + * note : tl1 phy, need change phy setting manually + * + */ +void rx_clk_rate_monitor(void) +{ + unsigned int cur_cable_clk; + unsigned int clk_diff; + unsigned int cur_phy_bw, i = 0; + static unsigned int phy_bw_cnt; + unsigned int cur_clk_rate; + +#ifdef K_BRINGUP_PTM + return; +#endif + + cur_cable_clk = rx_measure_clock(MEASURE_CLK_CABLE); + clk_diff = diff(rx.physts.cable_clk, cur_cable_clk); + + cur_clk_rate = rx_get_scdc_clkrate_sts(); + cur_phy_bw = aml_check_clk_bandwidth(cur_cable_clk, cur_clk_rate); + + if ((rx.cur_5v_sts) && (cur_cable_clk > 20000) && + ((rx.physts.phy_bw != cur_phy_bw) || + (rx.physts.clk_rate != cur_clk_rate) || + (clk_diff > 700))) { + + if (phy_bw_cnt++ > 1) { + phy_bw_cnt = 0; + while (i++ < 3) { + rx_pr("chg phy i=%d, cable clk:%d\n", + i, cur_cable_clk); + aml_phy_bw_switch(cur_cable_clk, cur_clk_rate); + if ((cur_cable_clk < 20000) || + aml_phy_pll_lock()) + break; + } + rx.physts.cable_clk = cur_cable_clk; + rx.physts.clk_rate = cur_clk_rate; + rx.physts.phy_bw = cur_phy_bw; + } + } +} + #ifdef USE_NEW_FSM_METHODE void rx_err_monitor(void) { @@ -1985,6 +2080,9 @@ void rx_main_state_machine(void) { int pre_auds_ch_alloc; + if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) + rx_clk_rate_monitor(); + switch (rx.state) { case FSM_5V_LOST: if (rx.cur_5v_sts) @@ -2664,9 +2762,9 @@ unsigned int hdmirx_show_info(unsigned char *buf, int size) pos += snprintf(buf+pos, size-pos, "avmute skip: %d\n", rx.avmute_skip); pos += snprintf(buf+pos, size-pos, - "TMDS clock: %d\n", hdmirx_get_tmds_clock()); + "TMDS clock: %d\n", rx_measure_clock(MEASURE_CLK_TMDS)); pos += snprintf(buf+pos, size-pos, - "Pixel clock: %d\n", hdmirx_get_pixel_clock()); + "Pixel clock: %d\n", rx_measure_clock(MEASURE_CLK_PIXEL)); if (drmpkt->des_u.tp1.eotf == EOTF_SDR) pos += snprintf(buf+pos, size-pos, "HDR EOTF: %s\n", "SDR"); @@ -2694,9 +2792,9 @@ unsigned int hdmirx_show_info(unsigned char *buf, int size) pos += snprintf(buf+pos, size-pos, "audio receive data: %d\n", auds_rcv_sts); pos += snprintf(buf+pos, size-pos, - "Audio PLL clock: %d\n", hdmirx_get_audio_clock()); + "Audio PLL clock: %d\n", rx_measure_clock(MEASURE_CLK_AUD_PLL)); pos += snprintf(buf+pos, size-pos, - "mpll_div_clk: %d\n", hdmirx_get_mpll_div_clk()); + "mpll_div_clk: %d\n", rx_measure_clock(MEASURE_CLK_MPLL)); pos += snprintf(buf+pos, size-pos, "\n\nHDCP info\n\n"); @@ -2765,30 +2863,34 @@ void dump_state(unsigned char enable) rx_pr("repetition %d\n", rx.cur.repeat); rx_pr("colordepth %d", rx.cur.colordepth); rx_pr("frame_rate %d\n", rx.cur.frame_rate); + rx_pr("fmt=0x%x,", hdmirx_hw_get_fmt()); + rx_pr("rx.no_signal=%d,rx.state=%d,", + rx.no_signal, rx.state); rx_pr("TMDS clock = %d\n,", - hdmirx_get_tmds_clock()); + rx_measure_clock(MEASURE_CLK_TMDS)); rx_pr("Pixel clock = %d\n", - hdmirx_get_pixel_clock()); - rx_pr("rx.no_signal=%d,rx.state=%d,", - rx.no_signal, - rx.state); - rx_pr("fmt=0x%x,", hdmirx_hw_get_fmt()); + rx_measure_clock(MEASURE_CLK_PIXEL)); + rx_pr("cable clock = %d\n", + rx_measure_clock(MEASURE_CLK_CABLE)); + rx_pr("audio clock = %d\n", + rx_measure_clock(MEASURE_CLK_AUD_PLL)); + rx_pr("aud div clock = %d\n", + rx_measure_clock(MEASURE_CLK_AUD_DIV)); + rx_pr("mpll clock = %d\n", + rx_measure_clock(MEASURE_CLK_MPLL)); + rx_pr("esm clock = %d\n", + rx_measure_clock(MEASURE_CLK_ESM)); } if (enable & 2) { rx_get_audinfo(&a); rx_pr("AudioInfo:"); - rx_pr(" CT=%u CC=%u", - a.coding_type, + rx_pr(" CT=%u CC=%u", a.coding_type, a.channel_count); - rx_pr(" SF=%u SS=%u", - a.sample_frequency, + rx_pr(" SF=%u SS=%u", a.sample_frequency, a.sample_size); - rx_pr(" CA=%u", - a.auds_ch_alloc); - rx_pr(" CTS=%d, N=%d,", - a.cts, a.n); - rx_pr("recovery clock is %d\n", - a.arc); + rx_pr(" CA=%u", a.auds_ch_alloc); + rx_pr(" CTS=%d, N=%d,", a.cts, a.n); + rx_pr("recovery clock is %d\n", a.arc); } if (enable & 4) { /***************hdcp*****************/ @@ -2814,7 +2916,7 @@ void dump_state(unsigned char enable) if (enable & 8) { rx_pr("hw_vic %d,", rx.cur.hw_vic); rx_pr("ESM clock = %d\n", - hdmirx_get_esm_clock()); + rx_measure_clock(MEASURE_CLK_ESM)); rx_pr("HDCP debug value=0x%x\n", hdmirx_rd_dwc(DWC_HDCP_DBG)); rx_pr("HDCP14 state:%d\n", @@ -2826,7 +2928,7 @@ void dump_state(unsigned char enable) rx_pr("skip frame=%d\n", rx.skip); rx_pr("avmute_skip:0x%x\n", rx.avmute_skip); rx_pr("Audio PLL clock = %d\n", - hdmirx_get_audio_clock()); + rx_measure_clock(MEASURE_CLK_AUD_PLL)); } dump_hdcp_data(); @@ -2967,7 +3069,19 @@ int hdmirx_debug(const char *buf, int size) } else if (strncmp(input[0], "port3", 5) == 0) { hdmirx_open_port(TVIN_PORT_HDMI3); rx.open_fg = 1; + } else if (strncmp(input[0], "empsts", 6) == 0) { + rx_emp_status(); + } else if (strncmp(input[0], "dumpemp", 7) == 0) { + rx_emp_resource_allocate(hdmirx_dev); + } else if (strncmp(input[0], "dumptmds", 8) == 0) { + rx_tmds_resource_allocate(hdmirx_dev); + } else if (strncmp(input[0], "empbuff", 7) == 0) { + if (kstrtol(input[1], 16, &value) < 0) + rx_pr("error input Value\n"); + rx_pr("set pkt cnt:0x%x\n", value); + rx.empbuff.emppktcnt = value; } + return 0; } diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h index df77607..85dc099 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.h @@ -123,8 +123,8 @@ extern void rx_acr_info_sw_update(void); extern void rx_sw_reset(int level); extern void rx_aud_pll_ctl(bool en); extern void hdmirx_timer_handler(unsigned long arg); - - +extern void rx_tmds_resource_allocate(struct device *dev); +extern void rx_emp_resource_allocate(struct device *dev); #endif -- 2.7.4