hdmitx: add dongle_mode case for low power [2/2]
authorZongdong Jiao <zongdong.jiao@amlogic.com>
Fri, 8 Mar 2019 10:57:49 +0000 (18:57 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 18 Mar 2019 01:56:34 +0000 (17:56 -0800)
PD#SWPL-5302

Problem:
For dongle products, it is connected to TV directly, and some
parameters are different from mbox.

Solution:
Add dongle mode for driver's usage

Verify:
U211/S905Y2

Change-Id: Ibe45b167800d3b830d78ca8e9d7b67efd64d8564
Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
arch/arm/boot/dts/amlogic/mesong12a.dtsi
arch/arm64/boot/dts/amlogic/mesong12a.dtsi
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c
include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h

index 99493d9..2a8a386 100644 (file)
                 * 10:G12A
                 */
                ic_type = <10>;
+               dongle_mode = <0>;
                vend_data: vend_data{ /* Should modified by Customer */
                        vendor_name = "Amlogic"; /* Max Chars: 8 */
                        /* standards.ieee.org/develop/regauth/oui/oui.txt */
index 420dd20..2257e6d 100644 (file)
                 * 10:G12A
                 */
                ic_type = <10>;
+               dongle_mode = <0>;
                vend_data: vend_data{ /* Should modified by Customer */
                        vendor_name = "Amlogic"; /* Max Chars: 8 */
                        /* standards.ieee.org/develop/regauth/oui/oui.txt */
index 61b606f..b4ef4fd 100644 (file)
@@ -4408,6 +4408,7 @@ static int amhdmitx_get_dt_info(struct platform_device *pdev)
 
 #ifdef CONFIG_OF
        if (pdev->dev.of_node) {
+               int dongle_mode = 0;
                memset(&hdmitx_device.config_data, 0,
                        sizeof(struct hdmi_config_platform_data));
                /* Get ic type information */
@@ -4419,6 +4420,14 @@ static int amhdmitx_get_dt_info(struct platform_device *pdev)
                        pr_info(SYS "hdmitx_device.chip_type : %d\n",
                                hdmitx_device.chip_type);
 
+               /* Get dongle_mode information */
+               ret = of_property_read_u32(pdev->dev.of_node, "dongle_mode",
+                       &dongle_mode);
+               hdmitx_device.dongle_mode = !!dongle_mode;
+               if (!ret)
+                       pr_info(SYS "hdmitx_device.dongle_mode: %d\n",
+                               hdmitx_device.dongle_mode);
+
                ret = of_property_read_u32(pdev->dev.of_node,
                        "repeater_tx", &val);
                if (!ret)
index 2a5a85d..f9c7271 100644 (file)
@@ -1844,11 +1844,15 @@ static void set_phy_by_mode(unsigned int mode)
                switch (mode) {
                case 1: /* 5.94/4.5/3.7Gbps */
                        hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb65c4);
+                       if (hdev->dongle_mode)
+                               hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb5584);
                        hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
                        hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x0000080b);
                        break;
                case 2: /* 2.97Gbps */
                        hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb6262);
+                       if (hdev->dongle_mode)
+                               hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb4262);
                        hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
                        hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x00000003);
                        break;
index 50e5948..dcf7a2f 100644 (file)
@@ -164,11 +164,44 @@ static bool set_hpll_hclk_v3(unsigned int m, unsigned int frac_val)
        return ret; /* return hpll locked status */
 }
 
+#define IS_DONGLE_MODE(hdev) \
+       ((hdev->dongle_mode) \
+       && (hdev->para->cs == COLORSPACE_YUV422 \
+               || hdev->para->cd == COLORDEPTH_24B) \
+       && (hdev->cur_VIC == HDMI_1280x720p50_16x9 \
+               || hdev->cur_VIC == HDMI_1280x720p60_16x9 \
+               || hdev->cur_VIC == HDMI_1920x1080i60_16x9 \
+               || hdev->cur_VIC == HDMI_1920x1080i50_16x9 \
+               || hdev->cur_VIC == HDMI_1920x1080p60_16x9 \
+               || hdev->cur_VIC == HDMI_1920x1080p50_16x9))
+
+static void set_hpll_hclk_dongle_5940m(void)
+{
+       hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x0b3a04f7);
+       hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x3, 28, 2);
+       hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x10000);
+       hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00100140);
+       hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x2a295c00);
+       hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x65771290);
+       hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000);
+       hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000);
+       pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0));
+       hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1);
+       pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0));
+       WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0);
+       pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0));
+}
+
 void set_g12a_hpll_clk_out(unsigned int frac_rate, unsigned int clk)
 {
+       struct hdmitx_dev *hdev = get_hdmitx_device();
 
        switch (clk) {
        case 5940000:
+               if (IS_DONGLE_MODE(hdev)) {
+                       set_hpll_hclk_dongle_5940m();
+                       break;
+               }
                if (set_hpll_hclk_v1(0xf7, frac_rate ? 0x8148 : 0x10000))
                        break;
                if (set_hpll_hclk_v2(0x7b, 0x18000))
@@ -381,6 +414,8 @@ int hdmitx_hpd_hw_op_g12a(enum hpd_op cmd)
 
 void set_hpll_sspll_g12a(enum hdmi_vic vic)
 {
+       struct hdmitx_dev *hdev = get_hdmitx_device();
+
        switch (vic) {
        case HDMI_1920x1080p60_16x9:
        case HDMI_1920x1080p50_16x9:
@@ -397,6 +432,8 @@ void set_hpll_sspll_g12a(enum hdmi_vic vic)
                hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 1, 8, 1);
                /* 2: 1000ppm  1: 500ppm */
                hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 2, 4, 4);
+               if (hdev->dongle_mode)
+                       hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 4, 4, 4);
                /* bit[15] hdmi_dpll_sdmnc_en */
                hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL3, 0, 15, 1);
                hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0, 29, 1);
index 503f6f1..1ad6fe5 100644 (file)
@@ -447,6 +447,7 @@ struct hdmitx_dev {
        unsigned int flag_3dfp:1;
        unsigned int flag_3dtb:1;
        unsigned int flag_3dss:1;
+       unsigned int dongle_mode:1;
        unsigned int drm_feature;/*Direct Rander Management*/
 };