summaryrefslogtreecommitdiff
authorZongdong 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)
commit4b9b578ec047d72e9f57f711541619a31ff0d3e1 (patch)
tree67cd940a1ba6bb0aa6110074c05e18aea6ca25c7
parent43e1b61dba94f9699757ed7103f72f095793640a (diff)
downloaduboot-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>
Diffstat
-rw-r--r--arch/arm/cpu/armv8/g12a/hdmitx20/enc_clk_config.c34
-rw-r--r--arch/arm/cpu/armv8/g12a/hdmitx20/hdmitx_set.c26
-rw-r--r--arch/arm/cpu/armv8/g12b/hdmitx20/enc_clk_config.c34
-rw-r--r--arch/arm/cpu/armv8/g12b/hdmitx20/hdmitx_set.c26
-rw-r--r--include/amlogic/hdmi.h2
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);