author | Zongdong Jiao <zongdong.jiao@amlogic.com> | 2019-03-08 08:20:48 (GMT) |
---|---|---|
committer | Luan Yuan <luan.yuan@amlogic.com> | 2019-05-16 05:17:31 (GMT) |
commit | 4b9b578ec047d72e9f57f711541619a31ff0d3e1 (patch) | |
tree | 67cd940a1ba6bb0aa6110074c05e18aea6ca25c7 | |
parent | 43e1b61dba94f9699757ed7103f72f095793640a (diff) | |
download | uboot-4b9b578ec047d72e9f57f711541619a31ff0d3e1.zip uboot-4b9b578ec047d72e9f57f711541619a31ff0d3e1.tar.gz uboot-4b9b578ec047d72e9f57f711541619a31ff0d3e1.tar.bz2 |
hdmitx: add dongle_mode case for low power [1/2]
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: I0ad63c32c736fa6b5eb4cbb010a3863a8263418d
Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
-rw-r--r-- | arch/arm/cpu/armv8/g12a/hdmitx20/enc_clk_config.c | 34 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c | 26 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/g12b/hdmitx20/enc_clk_config.c | 34 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/g12b/hdmitx20/hdmitx_set.c | 26 | ||||
-rw-r--r-- | include/amlogic/hdmi.h | 2 |
5 files changed, 106 insertions, 16 deletions
diff --git a/arch/arm/cpu/armv8/g12a/hdmitx20/enc_clk_config.c b/arch/arm/cpu/armv8/g12a/hdmitx20/enc_clk_config.c index c110794..fe0af17 100644 --- a/arch/arm/cpu/armv8/g12a/hdmitx20/enc_clk_config.c +++ b/arch/arm/cpu/armv8/g12a/hdmitx20/enc_clk_config.c @@ -176,6 +176,34 @@ static bool set_hpll_hclk_v3(unsigned int m, unsigned int frac_val) return ret; /* return hpll locked status */ } +#define IS_DONGLE_MODE(hdev) \ + ((hdev->dongle_mode) \ + && (hdev->para->cs == HDMI_COLOR_FORMAT_422 \ + || hdev->para->cd == HDMI_COLOR_DEPTH_24B) \ + && (hdev->vic == HDMI_1280x720p50_16x9 \ + || hdev->vic == HDMI_1280x720p60_16x9 \ + || hdev->vic == HDMI_1920x1080i60_16x9 \ + || hdev->vic == HDMI_1920x1080i50_16x9 \ + || hdev->vic == HDMI_1920x1080p60_16x9 \ + || hdev->vic == HDMI_1920x1080p50_16x9)) + +static void set_hpll_hclk_dongle_5940m(void) +{ + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x0b3a04f7); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x3, 28, 2); + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x10000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00100140); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x2a295c00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x65771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); +} + static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) { unsigned int frac_rate = 1; @@ -186,6 +214,10 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) switch (clk) { case 5940000: + if (IS_DONGLE_MODE(hdev)) { + set_hpll_hclk_dongle_5940m(); + break; + } if (set_hpll_hclk_v1(0xf7, frac_rate ? 0x8148 : 0x10000, hdev)) break; else if (set_hpll_hclk_v2(0x7b,0x18000)) @@ -332,6 +364,8 @@ static void set_hpll_sspll(struct hdmitx_dev *hdev) hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 1, 8, 1); /* 2: 1000ppm 1: 500ppm */ hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 2, 4, 4); + if (hdev->dongle_mode) + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 4, 4, 4); /* bit[15] hdmi_dpll_sdmnc_en */ hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL3, 0, 15, 1); hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0, 29, 1); diff --git a/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c b/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c index 9967f99..0a0d9fc 100644 --- a/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c +++ b/arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c @@ -403,6 +403,12 @@ static void hdmitx_output_blank(unsigned int blank) void hdmi_tx_init(void) { + char *dongle_mode = NULL; + + dongle_mode = getenv("dongle_mode"); + if (dongle_mode && (dongle_mode[0] == '1')) + hdmitx_device.dongle_mode = 1; + hdmitx_device.HWOp.get_hpd_state = hdmitx_get_hpd_state; hdmitx_device.HWOp.read_edid = hdmitx_read_edid; hdmitx_device.HWOp.turn_off = hdmitx_turnoff; @@ -1124,16 +1130,20 @@ static void hdmitx_set_pll(struct hdmitx_dev *hdev) hdmitx_set_clk(hdev); } -static void set_phy_by_mode(unsigned int mode) +static void set_phy_by_mode(struct hdmitx_dev *hdev, unsigned int mode) { switch (mode) { case 1: /* 5.94/4.5/3.7Gbps */ hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb65c4); + if (hdev->dongle_mode) + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb5584); hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x0000080b); break; case 2: /* 2.97Gbps */ hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb6262); + if (hdev->dongle_mode) + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb4262); hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x00000003); break; @@ -1158,18 +1168,18 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_4096x2160p60_256x135: if ((hdev->para->cs == HDMI_COLOR_FORMAT_420) && (hdev->para->cd == HDMI_COLOR_DEPTH_24B)) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_3840x2160p50_16x9_Y420: case HDMI_3840x2160p60_16x9_Y420: case HDMI_4096x2160p50_256x135_Y420: case HDMI_4096x2160p60_256x135_Y420: if (hdev->para->cd == HDMI_COLOR_DEPTH_24B) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_3840x2160p24_16x9: case HDMI_3840x2160p24_64x27: @@ -1182,9 +1192,9 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_4096x2160p30_256x135: if ((hdev->para->cs == HDMI_COLOR_FORMAT_422) || (hdev->para->cd == HDMI_COLOR_DEPTH_24B)) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_1920x1080p60_16x9: case HDMI_1920x1080p50_16x9: @@ -1193,7 +1203,7 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_1280x720p100_16x9: case HDMI_1280x720p120_16x9: default: - set_phy_by_mode(3); + set_phy_by_mode(hdev, 3); break; } /* P_HHI_HDMI_PHY_CNTL1 bit[1]: enable clock bit[0]: soft reset */ diff --git a/arch/arm/cpu/armv8/g12b/hdmitx20/enc_clk_config.c b/arch/arm/cpu/armv8/g12b/hdmitx20/enc_clk_config.c index c110794..fe0af17 100644 --- a/arch/arm/cpu/armv8/g12b/hdmitx20/enc_clk_config.c +++ b/arch/arm/cpu/armv8/g12b/hdmitx20/enc_clk_config.c @@ -176,6 +176,34 @@ static bool set_hpll_hclk_v3(unsigned int m, unsigned int frac_val) return ret; /* return hpll locked status */ } +#define IS_DONGLE_MODE(hdev) \ + ((hdev->dongle_mode) \ + && (hdev->para->cs == HDMI_COLOR_FORMAT_422 \ + || hdev->para->cd == HDMI_COLOR_DEPTH_24B) \ + && (hdev->vic == HDMI_1280x720p50_16x9 \ + || hdev->vic == HDMI_1280x720p60_16x9 \ + || hdev->vic == HDMI_1920x1080i60_16x9 \ + || hdev->vic == HDMI_1920x1080i50_16x9 \ + || hdev->vic == HDMI_1920x1080p60_16x9 \ + || hdev->vic == HDMI_1920x1080p50_16x9)) + +static void set_hpll_hclk_dongle_5940m(void) +{ + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x0b3a04f7); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x3, 28, 2); + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x10000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00100140); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x2a295c00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x65771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + printk("HPLL: 0x%lx\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); +} + static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) { unsigned int frac_rate = 1; @@ -186,6 +214,10 @@ static void set_hpll_clk_out(unsigned clk, struct hdmitx_dev *hdev) switch (clk) { case 5940000: + if (IS_DONGLE_MODE(hdev)) { + set_hpll_hclk_dongle_5940m(); + break; + } if (set_hpll_hclk_v1(0xf7, frac_rate ? 0x8148 : 0x10000, hdev)) break; else if (set_hpll_hclk_v2(0x7b,0x18000)) @@ -332,6 +364,8 @@ static void set_hpll_sspll(struct hdmitx_dev *hdev) hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 1, 8, 1); /* 2: 1000ppm 1: 500ppm */ hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 2, 4, 4); + if (hdev->dongle_mode) + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 4, 4, 4); /* bit[15] hdmi_dpll_sdmnc_en */ hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL3, 0, 15, 1); hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0, 29, 1); diff --git a/arch/arm/cpu/armv8/g12b/hdmitx20/hdmitx_set.c b/arch/arm/cpu/armv8/g12b/hdmitx20/hdmitx_set.c index 9967f99..0a0d9fc 100644 --- a/arch/arm/cpu/armv8/g12b/hdmitx20/hdmitx_set.c +++ b/arch/arm/cpu/armv8/g12b/hdmitx20/hdmitx_set.c @@ -403,6 +403,12 @@ static void hdmitx_output_blank(unsigned int blank) void hdmi_tx_init(void) { + char *dongle_mode = NULL; + + dongle_mode = getenv("dongle_mode"); + if (dongle_mode && (dongle_mode[0] == '1')) + hdmitx_device.dongle_mode = 1; + hdmitx_device.HWOp.get_hpd_state = hdmitx_get_hpd_state; hdmitx_device.HWOp.read_edid = hdmitx_read_edid; hdmitx_device.HWOp.turn_off = hdmitx_turnoff; @@ -1124,16 +1130,20 @@ static void hdmitx_set_pll(struct hdmitx_dev *hdev) hdmitx_set_clk(hdev); } -static void set_phy_by_mode(unsigned int mode) +static void set_phy_by_mode(struct hdmitx_dev *hdev, unsigned int mode) { switch (mode) { case 1: /* 5.94/4.5/3.7Gbps */ hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb65c4); + if (hdev->dongle_mode) + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb5584); hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x0000080b); break; case 2: /* 2.97Gbps */ hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb6262); + if (hdev->dongle_mode) + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb4262); hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x00000003); break; @@ -1158,18 +1168,18 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_4096x2160p60_256x135: if ((hdev->para->cs == HDMI_COLOR_FORMAT_420) && (hdev->para->cd == HDMI_COLOR_DEPTH_24B)) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_3840x2160p50_16x9_Y420: case HDMI_3840x2160p60_16x9_Y420: case HDMI_4096x2160p50_256x135_Y420: case HDMI_4096x2160p60_256x135_Y420: if (hdev->para->cd == HDMI_COLOR_DEPTH_24B) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_3840x2160p24_16x9: case HDMI_3840x2160p24_64x27: @@ -1182,9 +1192,9 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_4096x2160p30_256x135: if ((hdev->para->cs == HDMI_COLOR_FORMAT_422) || (hdev->para->cd == HDMI_COLOR_DEPTH_24B)) - set_phy_by_mode(2); + set_phy_by_mode(hdev, 2); else - set_phy_by_mode(1); + set_phy_by_mode(hdev, 1); break; case HDMI_1920x1080p60_16x9: case HDMI_1920x1080p50_16x9: @@ -1193,7 +1203,7 @@ static void hdmitx_set_phy(struct hdmitx_dev *hdev) case HDMI_1280x720p100_16x9: case HDMI_1280x720p120_16x9: default: - set_phy_by_mode(3); + set_phy_by_mode(hdev, 3); break; } /* P_HHI_HDMI_PHY_CNTL1 bit[1]: enable clock bit[0]: soft reset */ diff --git a/include/amlogic/hdmi.h b/include/amlogic/hdmi.h index 1cc1647..78bf7fe 100644 --- a/include/amlogic/hdmi.h +++ b/include/amlogic/hdmi.h @@ -551,6 +551,8 @@ struct hdmitx_dev { unsigned int dc30; enum eotf_type hdmi_current_eotf_type; enum mode_type hdmi_current_tunnel_mode; + /* Add dongle_mode, clock, phy may be different from mbox */ + unsigned int dongle_mode; }; struct hdmi_format_para *hdmi_get_fmt_paras(enum hdmi_vic vic); |