diff --git a/arch/arm64/boot/dts/amlogic/meson-s7.dtsi b/arch/arm64/boot/dts/amlogic/meson-s7.dtsi index 1f0399602..d079ef66d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-s7.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-s7.dtsi @@ -1284,14 +1284,14 @@ vclk_serve: vclk_serve { compatible = "amlogic, vclk_serve"; - status = "disabled"; - reg = <0xfe008000 0x300 /* ana reg */ - 0xfe000000 0x4a0>; /* clk reg */ + status = "okay"; + reg = <0x0 0xfe008000 0x0 0x300 /* ana reg */ + 0x0 0xfe000000 0x0 0xc00>; /* clk reg */ }; vdac { - compatible = "amlogic, vdac-s4d"; - status = "disabled"; + compatible = "amlogic, vdac-s7"; + status = "okay"; }; vout: vout { diff --git a/arch/arm64/boot/dts/amlogic/s7_s905y5_bh201.dts b/arch/arm64/boot/dts/amlogic/s7_s905y5_bh201.dts index 0b352c57f..0be76bf4a 100644 --- a/arch/arm64/boot/dts/amlogic/s7_s905y5_bh201.dts +++ b/arch/arm64/boot/dts/amlogic/s7_s905y5_bh201.dts @@ -195,8 +195,8 @@ tv_mode = <0>;/*1:enable ;0:disable*/ }; cvbsout { - compatible = "amlogic, cvbsout-s4"; - status = "disabled"; + compatible = "amlogic, cvbsout-s7"; + status = "okay"; /* clk path */ /* 0:vid_pll vid2_clk */ diff --git a/arch/arm64/boot/dts/amlogic/s7_s905y5_bh202.dts b/arch/arm64/boot/dts/amlogic/s7_s905y5_bh202.dts index 1182df682..d4989f70a 100644 --- a/arch/arm64/boot/dts/amlogic/s7_s905y5_bh202.dts +++ b/arch/arm64/boot/dts/amlogic/s7_s905y5_bh202.dts @@ -195,8 +195,8 @@ tv_mode = <0>;/*1:enable ;0:disable*/ }; cvbsout { - compatible = "amlogic, cvbsout-s4"; - status = "disabled"; + compatible = "amlogic, cvbsout-s7"; + status = "okay"; /* clk path */ /* 0:vid_pll vid2_clk */ diff --git a/arch/arm64/boot/dts/amlogic/s7_s905y5_bh209.dts b/arch/arm64/boot/dts/amlogic/s7_s905y5_bh209.dts index e31b2db32..b9ccaadf0 100644 --- a/arch/arm64/boot/dts/amlogic/s7_s905y5_bh209.dts +++ b/arch/arm64/boot/dts/amlogic/s7_s905y5_bh209.dts @@ -195,8 +195,8 @@ tv_mode = <0>;/*1:enable ;0:disable*/ }; cvbsout { - compatible = "amlogic, cvbsout-s4"; - status = "disabled"; + compatible = "amlogic, cvbsout-s7"; + status = "okay"; /* clk path */ /* 0:vid_pll vid2_clk */ diff --git a/drivers/media/vout/cvbs/cvbs_out.c b/drivers/media/vout/cvbs/cvbs_out.c index cfef54a1f..210293ce8 100644 --- a/drivers/media/vout/cvbs/cvbs_out.c +++ b/drivers/media/vout/cvbs/cvbs_out.c @@ -1893,6 +1893,21 @@ struct meson_cvbsout_data meson_s1a_cvbsout_data = { .reg_vid_clk_ctrl2 = CLKCTRL_VID_CLK_CTRL2, }; +struct meson_cvbsout_data meson_s7_cvbsout_data = { + .cpu_id = CVBS_CPU_TYPE_S7, + .name = "meson-s7-cvbsout", + + .vdac_vref_adj = 0x10, + .vdac_gsw = 0x5c, + + .reg_vid_pll_clk_div = CLKCTRL_VID_PLL_CLK_DIV, + .reg_vid_clk_div = CLKCTRL_VID_CLK_DIV, + .reg_vid_clk_ctrl = CLKCTRL_VID_CLK_CTRL, + .reg_vid2_clk_div = CLKCTRL_VIID_CLK_DIV, + .reg_vid2_clk_ctrl = CLKCTRL_VIID_CLK_CTRL, + .reg_vid_clk_ctrl2 = CLKCTRL_VID_CLK_CTRL2, +}; + static const struct of_device_id meson_cvbsout_dt_match[] = { { .compatible = "amlogic, cvbsout-g12a", @@ -1937,6 +1952,9 @@ static const struct of_device_id meson_cvbsout_dt_match[] = { }, { .compatible = "amlogic, cvbsout-s1a", .data = &meson_s1a_cvbsout_data, + }, { + .compatible = "amlogic, cvbsout-s7", + .data = &meson_s7_cvbsout_data, }, {} }; @@ -2070,7 +2088,7 @@ static int cvbsout_probe(struct platform_device *pdev) cvbs_log_dbg("%s, cpu_id:%d,name:%s\n", __func__, cvbs_drv->cvbs_data->cpu_id, cvbs_drv->cvbs_data->name); - if (cvbs_drv->cvbs_data->cpu_id != CVBS_CPU_TYPE_SC2 && + if (cvbs_drv->cvbs_data->cpu_id <= CVBS_CPU_TYPE_S1A && cvbs_drv->cvbs_data->cpu_id >= CVBS_CPU_TYPE_S4) cvbsout_clktree_probe(&pdev->dev); diff --git a/drivers/media/vout/cvbs/cvbs_out.h b/drivers/media/vout/cvbs/cvbs_out.h index e5d7eb656..26e86decf 100644 --- a/drivers/media/vout/cvbs/cvbs_out.h +++ b/drivers/media/vout/cvbs/cvbs_out.h @@ -61,12 +61,16 @@ enum cvbs_cpu_type { CVBS_CPU_TYPE_S4D = 10, CVBS_CPU_TYPE_T5W = 11, CVBS_CPU_TYPE_S1A = 12, + CVBS_CPU_TYPE_S7 = 13, }; struct meson_cvbsout_data { enum cvbs_cpu_type cpu_id; const char *name; unsigned int vdac_vref_adj; + /* not used on new chips, only used for old + * chips which have no efuse for gsw store + */ unsigned int vdac_gsw; unsigned int reg_vid_pll_clk_div; unsigned int reg_vid_clk_div; diff --git a/drivers/media/vout/cvbs/enc_clk_config.c b/drivers/media/vout/cvbs/enc_clk_config.c index 3a694a305..9aefca3ea 100644 --- a/drivers/media/vout/cvbs/enc_clk_config.c +++ b/drivers/media/vout/cvbs/enc_clk_config.c @@ -187,6 +187,99 @@ static void cvbs_set_vid2_clk(unsigned int src_pll) usleep_range(5, 7); } +/* htx pll VCO output: (3G, 6G), for tmds */ +static void cvbs_s7_htxpll_clk_vco(const u32 clk) +{ + u32 quotient; + u32 remainder; + + if (clk < 3000000 || clk > 6000000) { + pr_err("%s[%d] clock should be 3~6G\n", __func__, __LINE__); + return; + } + + quotient = clk / 24000; + remainder = clk - quotient * 24000; + /* remainder range: 0 ~ 23999, 0x5dbf, 15bits */ + remainder *= 1 << 17; + remainder /= 24000; + + cvbs_out_ana_write(ANACTRL_HDMIPLL_CTRL0, 0x00801000 | (quotient << 0)); + cvbs_out_ana_write(ANACTRL_HDMIPLL_CTRL1, 0x2c6011c8); + cvbs_out_ana_write(ANACTRL_HDMIPLL_CTRL2, 0x86801000); + cvbs_out_ana_write(ANACTRL_HDMIPLL_CTRL3, 0x00000000 | remainder); + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL0, 1, 28, 1); + usleep_range(10, 20); + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL2, 1, 29, 1); + usleep_range(10, 20); + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL0, 1, 29, 1); + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL2, 0, 29, 1); + usleep_range(80, 90); + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL1, 1, 2, 1); + usleep_range(80, 90); + pll_wait_lock(ANACTRL_HDMIPLL_CTRL0, 31); +} + +void cvbs_s7_htxpll_clk_out(const u32 clk, u32 div) +{ + u32 pll_od1 = 0; + u32 pll_od10 = 0; + u32 pll_od11 = 0; + u32 pll_od21 = 0; + + pr_debug("%s[%d] htxpll vco %d div %d\n", __func__, __LINE__, clk, div); + + if (clk < 3000000 || clk > 6000000) { + pr_err("%s[%d] %d out of htxpll range(3~6G)\n", __func__, __LINE__, clk); + return; + } + cvbs_s7_htxpll_clk_vco(clk); + + //pll_od10 + if ((div % 8) == 0) { + pll_od10 = 3; //div8 + div = div / 8; + } else if ((div % 4) == 0) { + pll_od10 = 2; //div4 + div = div / 4; + } else if ((div % 2) == 0) { + pll_od10 = 1; //div2 + div = div / 2; + } + + //pll_od11 + if ((div % 8) == 0) { + pll_od11 = 3; + div = div / 8; + } else if ((div % 4) == 0) { + pll_od11 = 2; + div = div / 4; + } else if ((div % 2) == 0) { + pll_od11 = 1; + div = div / 2; + } + + //pll_od1 + pll_od1 = (pll_od10 << 2) | pll_od11; + + /* od2 for divider for hdmi_clk_out2 */ + if ((div % 8) == 0) { + pll_od21 = 3; + div = div / 8; + } else if ((div % 4) == 0) { + pll_od21 = 2; + div = div / 4; + } else if ((div % 2) == 0) { + pll_od21 = 1; + div = div / 2; + } + + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL0, 1, 19, 1); + pr_debug("pll_od1 = %d, pll_od21 = %d\n", pll_od1, pll_od21); + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL2, pll_od21, 15, 2); + cvbs_out_ana_setb(ANACTRL_HDMIPLL_CTRL2, pll_od1, 19, 4); +} + void set_vmode_clk(void) { struct meson_cvbsout_data *cvbs_data; @@ -351,6 +444,9 @@ void set_vmode_clk(void) ret = pll_wait_lock(ANACTRL_HDMIPLL_CTRL0, 31); if (ret) pr_info("[error]:hdmi_pll lock failed\n"); + } else if (cvbs_cpu_type() == CVBS_CPU_TYPE_S7) { + /* hdmi_clk_out2: 1485Mhz */ + cvbs_s7_htxpll_clk_out(5940000, 4); } else { pr_info("config eqafter gxl hdmi pll\n"); cvbs_out_ana_write(HHI_HDMI_PLL_CNTL, 0x4000027b); diff --git a/drivers/media/vout/vdac/vdac_config.c b/drivers/media/vout/vdac/vdac_config.c index 2a07f247f..04705ab5a 100644 --- a/drivers/media/vout/vdac/vdac_config.c +++ b/drivers/media/vout/vdac/vdac_config.c @@ -64,9 +64,20 @@ static struct meson_vdac_ctrl_s vdac_ctrl_enable_t5[] = { #endif static struct meson_vdac_ctrl_s vdac_ctrl_enable_s4[] = { + /* byp_bias<1:0> */ {ANACTRL_VDAC_CTRL0, 0, 9, 1}, + /* cdac_ctrl_rsv1[7:0] clk_delay_adj<2:0> */ {ANACTRL_VDAC_CTRL0, 2, 0, 3}, - {ANACTRL_VDAC_CTRL1, 1, 7, 1}, /* cdac_pwd */ + /* cdac_pwd, 1: on, 0: off */ + {ANACTRL_VDAC_CTRL1, 1, 7, 1}, + {VDAC_REG_MAX, 0, 0, 0}, +}; + +static struct meson_vdac_ctrl_s vdac_ctrl_enable_s7[] = { + /* cdac_ctrl_rsv1[7:0] clk_delay_adj<2:0> */ + {ANACTRL_VDAC_CTRL0, 2, 0, 3}, + /* cdac_pwd, 1: on, 0: off */ + {ANACTRL_VDAC_CTRL1, 1, 7, 1}, {VDAC_REG_MAX, 0, 0, 0}, }; @@ -271,6 +282,19 @@ static struct meson_vdac_data meson_s1a_vdac_data = { .cvbsout_cfg_cntl0 = 0x00418982, //vlsi suggestion value }; +static struct meson_vdac_data meson_s7_vdac_data = { + .cpu_id = VDAC_CPU_S7, + .name = "meson-s7-vdac", + + .reg_cntl0 = ANACTRL_VDAC_CTRL0, + .reg_cntl1 = ANACTRL_VDAC_CTRL1, + .reg_vid_clk_ctrl2 = CLKCTRL_VID_CLK_CTRL2, + .reg_vid2_clk_div = CLKCTRL_VIID_CLK_DIV, + .ctrl_table = vdac_ctrl_enable_s7, + .bypass_cfg_cntl0 = 0x00419A82, //vlsi suggestion value + .cvbsout_cfg_cntl0 = 0x00419A82, //vlsi suggestion value +}; + const struct of_device_id meson_vdac_dt_match[] = { #ifndef CONFIG_AMLOGIC_ZAPPER_CUT { @@ -336,6 +360,10 @@ const struct of_device_id meson_vdac_dt_match[] = { .compatible = "amlogic, vdac-s1a", .data = &meson_s1a_vdac_data, }, + { + .compatible = "amlogic, vdac-s7", + .data = &meson_s7_vdac_data, + }, {} }; diff --git a/drivers/media/vout/vdac/vdac_dev.c b/drivers/media/vout/vdac/vdac_dev.c index f6a4d5fe3..25a861b25 100644 --- a/drivers/media/vout/vdac/vdac_dev.c +++ b/drivers/media/vout/vdac/vdac_dev.c @@ -467,8 +467,7 @@ static void vdac_enable_cvbs_out(bool on) vdac_ana_reg_write(reg_cntl0, s_vdac_data->cvbsout_cfg_cntl0); vdac_ctrl_table_config(1); } - } else if (s_vdac_data->cpu_id >= VDAC_CPU_T5 && - s_vdac_data->cpu_id < VDAC_CPU_MAX) { + } else if (s_vdac_data->cpu_id >= VDAC_CPU_T5) { vdac_enable_dac_input(reg_cntl0); if (!s_vdac_data->cdac_disable) vdac_ctrl_config(1, reg_cntl1, 7); @@ -484,8 +483,7 @@ static void vdac_enable_cvbs_out(bool on) } else { if (s_vdac_data->cpu_id >= VDAC_CPU_T5M) { vdac_ctrl_table_config(0); - } else if (s_vdac_data->cpu_id >= VDAC_CPU_T5 && - s_vdac_data->cpu_id < VDAC_CPU_MAX) { + } else if (s_vdac_data->cpu_id >= VDAC_CPU_T5) { vdac_ana_reg_setb(reg_cntl0, 0x0, 4, 1); vdac_ctrl_config(0, reg_cntl1, 7); } else { diff --git a/drivers/media/vout/vdac/vdac_dev.h b/drivers/media/vout/vdac/vdac_dev.h index 1e2a6ed62..dd993bf50 100644 --- a/drivers/media/vout/vdac/vdac_dev.h +++ b/drivers/media/vout/vdac/vdac_dev.h @@ -45,7 +45,7 @@ /* 20220419:adjust cvbsout clk delay */ /* 20230426:add vdac control node */ /* 20230325:t3x bringup */ -#define VDAC_VER "20230325:t3x bringup" +#define VDAC_VER "20240116:s7 bringup" enum vdac_cpu_type { VDAC_CPU_G12AB = 0, @@ -63,6 +63,7 @@ enum vdac_cpu_type { VDAC_CPU_T3X, VDAC_CPU_TXHD2, VDAC_CPU_S1A, + VDAC_CPU_S7, VDAC_CPU_MAX, };