diff options
Diffstat (limited to 'testing/linux-amlogic/0002-drm-meson-Make-DMT-timings-parameters-and-pixel-cloc.patch')
-rw-r--r-- | testing/linux-amlogic/0002-drm-meson-Make-DMT-timings-parameters-and-pixel-cloc.patch | 1314 |
1 files changed, 0 insertions, 1314 deletions
diff --git a/testing/linux-amlogic/0002-drm-meson-Make-DMT-timings-parameters-and-pixel-cloc.patch b/testing/linux-amlogic/0002-drm-meson-Make-DMT-timings-parameters-and-pixel-cloc.patch deleted file mode 100644 index 7625f11f5b..0000000000 --- a/testing/linux-amlogic/0002-drm-meson-Make-DMT-timings-parameters-and-pixel-cloc.patch +++ /dev/null @@ -1,1314 +0,0 @@ -From 8ea8dd0432a9964e3e2642433d942c3aa9116fd3 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong <narmstrong@baylibre.com> -Date: Fri, 27 Apr 2018 17:19:46 +0200 -Subject: [PATCH] drm/meson: Make DMT timings parameters and pixel clock - generic - -Remove the modes timings tables for DMT modes and calculate the HW -paremeters from the modes timings. - -Switch the DMT modes pixel clock calculation out of the static frequency -list to a generic calculation from a range of possible PLL dividers. - -This setup permits setting non-CEA modes like : -- 1600x900-60Hz -- 1280x1024-75Hz -- 1280x1024-60Hz -- 1440x900-60Hz -- 1366x768-60Hz -- 1280x800-60Hz -- 1152x864-75Hz -- 1024x768-75Hz -- 1024x768-70Hz -- 1024x768-60Hz -- 832x624-75Hz -- 800x600-75Hz -- 800x600-72Hz -- 800x600-60Hz -- 640x480-75Hz -- 640x480-73Hz -- 640x480-67Hz - -Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> ---- - drivers/gpu/drm/meson/meson_dw_hdmi.c | 22 +- - drivers/gpu/drm/meson/meson_vclk.c | 658 +++++++++++++++------------------- - drivers/gpu/drm/meson/meson_vclk.h | 4 + - drivers/gpu/drm/meson/meson_venc.c | 379 +++----------------- - drivers/gpu/drm/meson/meson_venc.h | 3 +- - 5 files changed, 352 insertions(+), 714 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c -index c9ad456..df7247c 100644 ---- a/drivers/gpu/drm/meson/meson_dw_hdmi.c -+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c -@@ -329,6 +329,12 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, - - vclk_freq = mode->clock; - -+ if (!vic) { -+ meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq, -+ vclk_freq, vclk_freq, false); -+ return; -+ } -+ - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - vclk_freq *= 2; - -@@ -542,10 +548,12 @@ static enum drm_mode_status - dw_hdmi_mode_valid(struct drm_connector *connector, - const struct drm_display_mode *mode) - { -+ struct meson_drm *priv = connector->dev->dev_private; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int hdmi_freq; - int vic = drm_match_cea_mode(mode); -+ enum drm_mode_status status; - - DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", - mode->base.id, mode->name, mode->vrefresh, mode->clock, -@@ -556,8 +564,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector, - - /* Check against non-VIC supported modes */ - if (!vic) { -- if (!meson_venc_hdmi_supported_mode(mode)) -- return MODE_BAD; -+ status = meson_venc_hdmi_supported_mode(mode); -+ if (status != MODE_OK) -+ return status; -+ -+ return meson_vclk_dmt_supported_freq(priv, mode->clock); - /* Check against supported VIC modes */ - } else if (!meson_venc_hdmi_supported_vic(vic)) - return MODE_BAD; -@@ -583,16 +594,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector, - dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, - vclk_freq, venc_freq, hdmi_freq); - -- /* Finally filter by configurable vclk frequencies */ -+ /* Finally filter by configurable vclk frequencies for VIC modes */ - switch (vclk_freq) { -- case 25175: -- case 40000: - case 54000: -- case 65000: - case 74250: -- case 108000: - case 148500: -- case 162000: - case 297000: - case 594000: - return MODE_OK; -diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c -index f051122..0b17788 100644 ---- a/drivers/gpu/drm/meson/meson_vclk.c -+++ b/drivers/gpu/drm/meson/meson_vclk.c -@@ -320,32 +320,23 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) - CTS_VDAC_EN, CTS_VDAC_EN); - } - -- -+enum { - /* PLL O1 O2 O3 VP DV EN TX */ - /* 4320 /4 /4 /1 /5 /1 => /2 /2 */ --#define MESON_VCLK_HDMI_ENCI_54000 1 -+ MESON_VCLK_HDMI_ENCI_54000 = 1, - /* 4320 /4 /4 /1 /5 /1 => /1 /2 */ --#define MESON_VCLK_HDMI_DDR_54000 2 -+ MESON_VCLK_HDMI_DDR_54000, - /* 2970 /4 /1 /1 /5 /1 => /1 /2 */ --#define MESON_VCLK_HDMI_DDR_148500 3 --/* 4028 /4 /4 /1 /5 /2 => /1 /1 */ --#define MESON_VCLK_HDMI_25175 4 --/* 3200 /4 /2 /1 /5 /2 => /1 /1 */ --#define MESON_VCLK_HDMI_40000 5 --/* 5200 /4 /2 /1 /5 /2 => /1 /1 */ --#define MESON_VCLK_HDMI_65000 6 -+ MESON_VCLK_HDMI_DDR_148500, - /* 2970 /2 /2 /2 /5 /1 => /1 /1 */ --#define MESON_VCLK_HDMI_74250 7 --/* 4320 /4 /1 /1 /5 /2 => /1 /1 */ --#define MESON_VCLK_HDMI_108000 8 -+ MESON_VCLK_HDMI_74250, - /* 2970 /1 /2 /2 /5 /1 => /1 /1 */ --#define MESON_VCLK_HDMI_148500 9 --/* 3240 /2 /1 /1 /5 /2 => /1 /1 */ --#define MESON_VCLK_HDMI_162000 10 -+ MESON_VCLK_HDMI_148500, - /* 2970 /1 /1 /1 /5 /2 => /1 /1 */ --#define MESON_VCLK_HDMI_297000 11 -+ MESON_VCLK_HDMI_297000, - /* 5940 /1 /1 /2 /5 /1 => /1 /1 */ --#define MESON_VCLK_HDMI_594000 12 -+ MESON_VCLK_HDMI_594000 -+}; - - struct meson_vclk_params { - unsigned int pll_base_freq; -@@ -411,46 +402,6 @@ struct meson_vclk_params { - .vid_pll_div = VID_PLL_DIV_5, - .vclk_div = 1, - }, -- [MESON_VCLK_HDMI_25175] = { -- .pll_base_freq = 4028000, -- .pll_od1 = 4, -- .pll_od2 = 4, -- .pll_od3 = 1, -- .vid_pll_div = VID_PLL_DIV_5, -- .vclk_div = 2, -- }, -- [MESON_VCLK_HDMI_40000] = { -- .pll_base_freq = 3200000, -- .pll_od1 = 4, -- .pll_od2 = 2, -- .pll_od3 = 1, -- .vid_pll_div = VID_PLL_DIV_5, -- .vclk_div = 2, -- }, -- [MESON_VCLK_HDMI_65000] = { -- .pll_base_freq = 5200000, -- .pll_od1 = 4, -- .pll_od2 = 2, -- .pll_od3 = 1, -- .vid_pll_div = VID_PLL_DIV_5, -- .vclk_div = 2, -- }, -- [MESON_VCLK_HDMI_108000] = { -- .pll_base_freq = 4320000, -- .pll_od1 = 4, -- .pll_od2 = 1, -- .pll_od3 = 1, -- .vid_pll_div = VID_PLL_DIV_5, -- .vclk_div = 2, -- }, -- [MESON_VCLK_HDMI_162000] = { -- .pll_base_freq = 3240000, -- .pll_od1 = 2, -- .pll_od2 = 1, -- .pll_od3 = 1, -- .vid_pll_div = VID_PLL_DIV_5, -- .vclk_div = 2, -- }, - }; - - static inline unsigned int pll_od_to_reg(unsigned int od) -@@ -470,358 +421,217 @@ static inline unsigned int pll_od_to_reg(unsigned int od) - return 0; - } - --void meson_hdmi_pll_set(struct meson_drm *priv, -- unsigned int base, -- unsigned int od1, -- unsigned int od2, -- unsigned int od3) -+void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m, -+ unsigned int frac, unsigned int od1, -+ unsigned int od2, unsigned int od3) - { - unsigned int val; - - if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { -- switch (base) { -- case 2970000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* Enable and unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- 0x7 << 28, 0x4 << 28); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- -- /* div_frac */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 0xFFFF, 0x4e00); -- break; -- -- case 3200000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000242); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- BIT(28), 0); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- -- /* div_frac */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 0xFFFF, 0x4aab); -- break; -- -- case 3240000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000243); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- BIT(28), 0); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- -- /* div_frac */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 0xFFFF, 0x4800); -- break; -- -- case 3865000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000250); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- BIT(28), 0); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- -- /* div_frac */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 0xFFFF, 0x4855); -- break; -- -- case 4028000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000253); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- BIT(28), 0); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- -- /* div_frac */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 0xFFFF, 0x4eab); -- break; -- -- case 4320000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- BIT(28), 0); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- break; -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m); -+ if (frac) -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, -+ 0x00004000 | frac); -+ else -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, -+ 0x00000000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); - -- case 5940000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b); -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 0xFFFF, 0x4c00); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- BIT(28), 0); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- break; -+ /* Enable and unreset */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -+ 0x7 << 28, 0x4 << 28); - -- case 5200000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -- -- /* unreset */ -- regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- BIT(28), 0); -- -- /* Poll for lock bit */ -- regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -- val, (val & HDMI_PLL_LOCK), 10, 0); -- break; -- }; -+ /* Poll for lock bit */ -+ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -+ val, (val & HDMI_PLL_LOCK), 10, 0); - } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { -- switch (base) { -- case 2970000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- case 3200000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000285); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb155); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- case 3240000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000287); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- case 3865000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a1); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb02b); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- case 4028000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a7); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb355); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- case 4320000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- case 5940000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002f7); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- case 5200000: -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002d8); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -- regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -- break; -- -- }; -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); - - /* Reset PLL */ - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- HDMI_PLL_RESET, HDMI_PLL_RESET); -+ HDMI_PLL_RESET, HDMI_PLL_RESET); - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -- HDMI_PLL_RESET, 0); -+ HDMI_PLL_RESET, 0); - - /* Poll for lock bit */ - regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val, - (val & HDMI_PLL_LOCK), 10, 0); -- }; -+ } - - if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 3 << 16, pll_od_to_reg(od1) << 16); -+ 3 << 16, pll_od_to_reg(od1) << 16); - else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3, -- 3 << 21, pll_od_to_reg(od1) << 21); -+ 3 << 21, pll_od_to_reg(od1) << 21); - - if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 3 << 22, pll_od_to_reg(od2) << 22); -+ 3 << 22, pll_od_to_reg(od2) << 22); - else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3, -- 3 << 23, pll_od_to_reg(od2) << 23); -+ 3 << 23, pll_od_to_reg(od2) << 23); - - if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -- 3 << 18, pll_od_to_reg(od3) << 18); -+ 3 << 18, pll_od_to_reg(od3) << 18); - else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) - regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3, -- 3 << 19, pll_od_to_reg(od3) << 19); -+ 3 << 19, pll_od_to_reg(od3) << 19); -+ - } - --void meson_vclk_setup(struct meson_drm *priv, unsigned int target, -- unsigned int vclk_freq, unsigned int venc_freq, -- unsigned int dac_freq, bool hdmi_use_enci) -+#define XTAL_FREQ 24000 -+ -+static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv, -+ unsigned int pll_freq) - { -- unsigned int freq; -- unsigned int hdmi_tx_div; -- unsigned int venc_div; -+ /* The GXBB PLL has a /2 pre-multiplier */ -+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) -+ pll_freq /= 2; - -- if (target == MESON_VCLK_TARGET_CVBS) { -- meson_venci_cvbs_clock_config(priv); -- return; -+ return pll_freq / XTAL_FREQ; -+} -+ -+#define HDMI_FRAC_MAX_GXBB 4096 -+#define HDMI_FRAC_MAX_GXL 1024 -+ -+static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, -+ unsigned int m, -+ unsigned int pll_freq) -+{ -+ unsigned int parent_freq = XTAL_FREQ; -+ unsigned int frac_max = HDMI_FRAC_MAX_GXL; -+ unsigned int frac_m; -+ unsigned int frac; -+ -+ /* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */ -+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { -+ frac_max = HDMI_FRAC_MAX_GXBB; -+ parent_freq *= 2; - } - -- hdmi_tx_div = vclk_freq / dac_freq; -+ /* We can have a perfect match !*/ -+ if (pll_freq / m == parent_freq && -+ pll_freq % m == 0) -+ return 0; - -- if (hdmi_tx_div == 0) { -- pr_err("Fatal Error, invalid HDMI-TX freq %d\n", -- dac_freq); -- return; -+ frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq); -+ frac_m = m * frac_max; -+ if (frac_m > frac) -+ return frac_max; -+ frac -= frac_m; -+ -+ return min((u16)frac, (u16)(frac_max - 1)); -+} -+ -+static bool meson_hdmi_pll_validate_params(struct meson_drm *priv, -+ unsigned int m, -+ unsigned int frac) -+{ -+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { -+ /* Empiric supported min/max dividers */ -+ if (m < 53 || m > 123) -+ return false; -+ if (frac >= HDMI_FRAC_MAX_GXBB) -+ return false; -+ } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { -+ /* Empiric supported min/max dividers */ -+ if (m < 106 || m > 247) -+ return false; -+ if (frac >= HDMI_FRAC_MAX_GXL) -+ return false; - } - -- venc_div = vclk_freq / venc_freq; -+ return true; -+} - -- if (venc_div == 0) { -- pr_err("Fatal Error, invalid HDMI venc freq %d\n", -- venc_freq); -- return; -+static bool meson_hdmi_pll_find_params(struct meson_drm *priv, -+ unsigned int freq, -+ unsigned int *m, -+ unsigned int *frac, -+ unsigned int *od) -+{ -+ /* Cycle from /16 to /2 */ -+ for (*od = 16 ; *od > 1 ; *od >>= 1) { -+ *m = meson_hdmi_pll_get_m(priv, freq * *od); -+ if (!*m) -+ continue; -+ *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od); -+ -+ DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n", -+ freq, *m, *frac, *od); -+ -+ if (meson_hdmi_pll_validate_params(priv, *m, *frac)) -+ return true; - } - -- switch (vclk_freq) { -- case 54000: -- if (hdmi_use_enci) -- freq = MESON_VCLK_HDMI_ENCI_54000; -- else -- freq = MESON_VCLK_HDMI_DDR_54000; -- break; -- case 25175: -- freq = MESON_VCLK_HDMI_25175; -- break; -- case 40000: -- freq = MESON_VCLK_HDMI_40000; -- break; -- case 65000: -- freq = MESON_VCLK_HDMI_65000; -- break; -- case 74250: -- freq = MESON_VCLK_HDMI_74250; -- break; -- case 108000: -- freq = MESON_VCLK_HDMI_108000; -- break; -- case 148500: -- if (dac_freq != 148500) -- freq = MESON_VCLK_HDMI_DDR_148500; -- else -- freq = MESON_VCLK_HDMI_148500; -- break; -- case 162000: -- freq = MESON_VCLK_HDMI_162000; -- break; -- case 297000: -- freq = MESON_VCLK_HDMI_297000; -- break; -- case 594000: -- freq = MESON_VCLK_HDMI_594000; -- break; -- default: -- pr_err("Fatal Error, invalid HDMI vclk freq %d\n", -- vclk_freq); -+ return false; -+} -+ -+/* pll_freq is the frequency after the OD dividers */ -+enum drm_mode_status -+meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq) -+{ -+ unsigned int od, m, frac; -+ -+ /* In DMT mode, path after PLL is always /10 */ -+ freq *= 10; -+ -+ if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od)) -+ return MODE_OK; -+ -+ return MODE_CLOCK_RANGE; -+} -+EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq); -+ -+/* pll_freq is the frequency after the OD dividers */ -+static void meson_hdmi_pll_generic_set(struct meson_drm *priv, -+ unsigned int pll_freq) -+{ -+ unsigned int od, m, frac, od1, od2, od3; -+ -+ if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) { -+ od3 = 1; -+ if (od < 4) { -+ od1 = 2; -+ od2 = 1; -+ } else { -+ od2 = od / 4; -+ od1 = od / od2; -+ } -+ -+ DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n", -+ pll_freq, m, frac, od1, od2, od3); -+ -+ meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); -+ - return; - } - -+ DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n", -+ pll_freq); -+} -+ -+static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, -+ unsigned int od1, unsigned int od2, unsigned int od3, -+ unsigned int vid_pll_div, unsigned int vclk_div, -+ unsigned int hdmi_tx_div, unsigned int venc_div, -+ bool hdmi_use_enci) -+{ - /* Set HDMI-TX sys clock */ - regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, - CTS_HDMI_SYS_SEL_MASK, 0); -@@ -831,19 +641,49 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN); - - /* Set HDMI PLL rate */ -- meson_hdmi_pll_set(priv, params[freq].pll_base_freq, -- params[freq].pll_od1, -- params[freq].pll_od2, -- params[freq].pll_od3); -+ if (!od1 && !od2 && !od3) -+ meson_hdmi_pll_generic_set(priv, pll_base_freq); -+ else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { -+ switch (pll_base_freq) { -+ case 2970000: -+ meson_hdmi_pll_set_params(priv, 0x3d, 0xe00, -+ od1, od2, od3); -+ break; -+ case 4320000: -+ meson_hdmi_pll_set_params(priv, 0x5a, 0, -+ od1, od2, od3); -+ break; -+ case 5940000: -+ meson_hdmi_pll_set_params(priv, 0x7b, 0xc00, -+ od1, od2, od3); -+ break; -+ } -+ } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { -+ switch (pll_base_freq) { -+ case 2970000: -+ meson_hdmi_pll_set_params(priv, 0x7b, 0x300, -+ od1, od2, od3); -+ break; -+ case 4320000: -+ meson_hdmi_pll_set_params(priv, 0xb4, 0, -+ od1, od2, od3); -+ break; -+ case 5940000: -+ meson_hdmi_pll_set_params(priv, 0xf7, 0x200, -+ od1, od2, od3); -+ break; -+ } -+ } - - /* Setup vid_pll divider */ -- meson_vid_pll_set(priv, params[freq].vid_pll_div); -+ meson_vid_pll_set(priv, vid_pll_div); - - /* Set VCLK div */ - regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, - VCLK_SEL_MASK, 0); - regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -- VCLK_DIV_MASK, params[freq].vclk_div - 1); -+ VCLK_DIV_MASK, vclk_div - 1); - - /* Set HDMI-TX source */ - switch (hdmi_tx_div) { -@@ -981,4 +821,80 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - - regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN); - } -+ -+void meson_vclk_setup(struct meson_drm *priv, unsigned int target, -+ unsigned int vclk_freq, unsigned int venc_freq, -+ unsigned int dac_freq, bool hdmi_use_enci) -+{ -+ unsigned int freq; -+ unsigned int hdmi_tx_div; -+ unsigned int venc_div; -+ -+ if (target == MESON_VCLK_TARGET_CVBS) { -+ meson_venci_cvbs_clock_config(priv); -+ return; -+ } else if (target == MESON_VCLK_TARGET_DMT) { -+ /* The DMT clock path is fixed after the PLL: -+ * - automatic PLL freq + OD management -+ * - vid_pll_div = VID_PLL_DIV_5 -+ * - vclk_div = 2 -+ * - hdmi_tx_div = 1 -+ * - venc_div = 1 -+ * - encp encoder -+ */ -+ meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0, -+ VID_PLL_DIV_5, 2, 1, 1, false); -+ return; -+ } -+ -+ hdmi_tx_div = vclk_freq / dac_freq; -+ -+ if (hdmi_tx_div == 0) { -+ pr_err("Fatal Error, invalid HDMI-TX freq %d\n", -+ dac_freq); -+ return; -+ } -+ -+ venc_div = vclk_freq / venc_freq; -+ -+ if (venc_div == 0) { -+ pr_err("Fatal Error, invalid HDMI venc freq %d\n", -+ venc_freq); -+ return; -+ } -+ -+ switch (vclk_freq) { -+ case 54000: -+ if (hdmi_use_enci) -+ freq = MESON_VCLK_HDMI_ENCI_54000; -+ else -+ freq = MESON_VCLK_HDMI_DDR_54000; -+ break; -+ case 74250: -+ freq = MESON_VCLK_HDMI_74250; -+ break; -+ case 148500: -+ if (dac_freq != 148500) -+ freq = MESON_VCLK_HDMI_DDR_148500; -+ else -+ freq = MESON_VCLK_HDMI_148500; -+ break; -+ case 297000: -+ freq = MESON_VCLK_HDMI_297000; -+ break; -+ case 594000: -+ freq = MESON_VCLK_HDMI_594000; -+ break; -+ default: -+ pr_err("Fatal Error, invalid HDMI vclk freq %d\n", -+ vclk_freq); -+ return; -+ } -+ -+ meson_vclk_set(priv, params[freq].pll_base_freq, -+ params[freq].pll_od1, params[freq].pll_od2, -+ params[freq].pll_od3, params[freq].vid_pll_div, -+ params[freq].vclk_div, hdmi_tx_div, venc_div, -+ hdmi_use_enci); -+} - EXPORT_SYMBOL_GPL(meson_vclk_setup); -diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h -index 0401b52..869fa3a 100644 ---- a/drivers/gpu/drm/meson/meson_vclk.h -+++ b/drivers/gpu/drm/meson/meson_vclk.h -@@ -24,11 +24,15 @@ - enum { - MESON_VCLK_TARGET_CVBS = 0, - MESON_VCLK_TARGET_HDMI = 1, -+ MESON_VCLK_TARGET_DMT = 2, - }; - - /* 27MHz is the CVBS Pixel Clock */ - #define MESON_VCLK_CVBS 27000 - -+enum drm_mode_status -+meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq); -+ - void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int vclk_freq, unsigned int venc_freq, - unsigned int dac_freq, bool hdmi_use_enci); -diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c -index 6e27013..d9f33b0 100644 ---- a/drivers/gpu/drm/meson/meson_venc.c -+++ b/drivers/gpu/drm/meson/meson_venc.c -@@ -697,314 +697,6 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { - }, - }; - --union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = { -- .encp = { -- .dvi_settings = 0x21, -- .video_mode = 0x4040, -- .video_mode_adv = 0x18, -- /* video_prog_mode */ -- /* video_sync_mode */ -- /* video_yc_dly */ -- /* video_rgb_ctrl */ -- /* video_filt_ctrl */ -- /* video_ofld_voav_ofst */ -- /* yfp1_htime */ -- /* yfp2_htime */ -- .max_pxcnt = 0x31f, -- /* hspuls_begin */ -- /* hspuls_end */ -- /* hspuls_switch */ -- /* vspuls_begin */ -- /* vspuls_end */ -- /* vspuls_bline */ -- /* vspuls_eline */ -- .havon_begin = 0x90, -- .havon_end = 0x30f, -- .vavon_bline = 0x23, -- .vavon_eline = 0x202, -- /* eqpuls_begin */ -- /* eqpuls_end */ -- /* eqpuls_bline */ -- /* eqpuls_eline */ -- .hso_begin = 0, -- .hso_end = 0x60, -- .vso_begin = 0x1e, -- .vso_end = 0x32, -- .vso_bline = 0, -- .vso_eline = 2, -- .vso_eline_present = true, -- /* sy_val */ -- /* sy2_val */ -- .max_lncnt = 0x20c, -- }, --}; -- --union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = { -- .encp = { -- .dvi_settings = 0x21, -- .video_mode = 0x4040, -- .video_mode_adv = 0x18, -- /* video_prog_mode */ -- /* video_sync_mode */ -- /* video_yc_dly */ -- /* video_rgb_ctrl */ -- /* video_filt_ctrl */ -- /* video_ofld_voav_ofst */ -- /* yfp1_htime */ -- /* yfp2_htime */ -- .max_pxcnt = 0x41f, -- /* hspuls_begin */ -- /* hspuls_end */ -- /* hspuls_switch */ -- /* vspuls_begin */ -- /* vspuls_end */ -- /* vspuls_bline */ -- /* vspuls_eline */ -- .havon_begin = 0xD8, -- .havon_end = 0x3f7, -- .vavon_bline = 0x1b, -- .vavon_eline = 0x272, -- /* eqpuls_begin */ -- /* eqpuls_end */ -- /* eqpuls_bline */ -- /* eqpuls_eline */ -- .hso_begin = 0, -- .hso_end = 0x80, -- .vso_begin = 0x1e, -- .vso_end = 0x32, -- .vso_bline = 0, -- .vso_eline = 4, -- .vso_eline_present = true, -- /* sy_val */ -- /* sy2_val */ -- .max_lncnt = 0x273, -- }, --}; -- --union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = { -- .encp = { -- .dvi_settings = 0x21, -- .video_mode = 0x4040, -- .video_mode_adv = 0x18, -- /* video_prog_mode */ -- /* video_sync_mode */ -- /* video_yc_dly */ -- /* video_rgb_ctrl */ -- /* video_filt_ctrl */ -- /* video_ofld_voav_ofst */ -- /* yfp1_htime */ -- /* yfp2_htime */ -- .max_pxcnt = 1343, -- /* hspuls_begin */ -- /* hspuls_end */ -- /* hspuls_switch */ -- /* vspuls_begin */ -- /* vspuls_end */ -- /* vspuls_bline */ -- /* vspuls_eline */ -- .havon_begin = 296, -- .havon_end = 1319, -- .vavon_bline = 35, -- .vavon_eline = 802, -- /* eqpuls_begin */ -- /* eqpuls_end */ -- /* eqpuls_bline */ -- /* eqpuls_eline */ -- .hso_begin = 0, -- .hso_end = 136, -- .vso_begin = 30, -- .vso_end = 50, -- .vso_bline = 0, -- .vso_eline = 6, -- .vso_eline_present = true, -- /* sy_val */ -- /* sy2_val */ -- .max_lncnt = 805, -- }, --}; -- --union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = { -- .encp = { -- .dvi_settings = 0x21, -- .video_mode = 0x4040, -- .video_mode_adv = 0x18, -- /* video_prog_mode */ -- /* video_sync_mode */ -- /* video_yc_dly */ -- /* video_rgb_ctrl */ -- /* video_filt_ctrl */ -- /* video_ofld_voav_ofst */ -- /* yfp1_htime */ -- /* yfp2_htime */ -- .max_pxcnt = 0x63f, -- /* hspuls_begin */ -- /* hspuls_end */ -- /* hspuls_switch */ -- /* vspuls_begin */ -- /* vspuls_end */ -- /* vspuls_bline */ -- /* vspuls_eline */ -- .havon_begin = 0x180, -- .havon_end = 0x5ff, -- .vavon_bline = 0x23, -- .vavon_eline = 0x382, -- /* eqpuls_begin */ -- /* eqpuls_end */ -- /* eqpuls_bline */ -- /* eqpuls_eline */ -- .hso_begin = 0, -- .hso_end = 0x80, -- .vso_begin = 0x1e, -- .vso_end = 0x32, -- .vso_bline = 0, -- .vso_eline = 3, -- .vso_eline_present = true, -- /* sy_val */ -- /* sy2_val */ -- .max_lncnt = 0x383, -- }, --}; -- --union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = { -- .encp = { -- .dvi_settings = 0x21, -- .video_mode = 0x4040, -- .video_mode_adv = 0x18, -- /* video_prog_mode */ -- /* video_sync_mode */ -- /* video_yc_dly */ -- /* video_rgb_ctrl */ -- /* video_filt_ctrl */ -- /* video_ofld_voav_ofst */ -- /* yfp1_htime */ -- /* yfp2_htime */ -- .max_pxcnt = 0x697, -- /* hspuls_begin */ -- /* hspuls_end */ -- /* hspuls_switch */ -- /* vspuls_begin */ -- /* vspuls_end */ -- /* vspuls_bline */ -- /* vspuls_eline */ -- .havon_begin = 0x168, -- .havon_end = 0x667, -- .vavon_bline = 0x29, -- .vavon_eline = 0x428, -- /* eqpuls_begin */ -- /* eqpuls_end */ -- /* eqpuls_bline */ -- /* eqpuls_eline */ -- .hso_begin = 0, -- .hso_end = 0x70, -- .vso_begin = 0x1e, -- .vso_end = 0x32, -- .vso_bline = 0, -- .vso_eline = 3, -- .vso_eline_present = true, -- /* sy_val */ -- /* sy2_val */ -- .max_lncnt = 0x429, -- }, --}; -- --union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = { -- .encp = { -- .dvi_settings = 0x21, -- .video_mode = 0x4040, -- .video_mode_adv = 0x18, -- /* video_prog_mode */ -- /* video_sync_mode */ -- /* video_yc_dly */ -- /* video_rgb_ctrl */ -- /* video_filt_ctrl */ -- /* video_ofld_voav_ofst */ -- /* yfp1_htime */ -- /* yfp2_htime */ -- .max_pxcnt = 0x86f, -- /* hspuls_begin */ -- /* hspuls_end */ -- /* hspuls_switch */ -- /* vspuls_begin */ -- /* vspuls_end */ -- /* vspuls_bline */ -- /* vspuls_eline */ -- .havon_begin = 0x1f0, -- .havon_end = 0x82f, -- .vavon_bline = 0x31, -- .vavon_eline = 0x4e0, -- /* eqpuls_begin */ -- /* eqpuls_end */ -- /* eqpuls_bline */ -- /* eqpuls_eline */ -- .hso_begin = 0, -- .hso_end = 0xc0, -- .vso_begin = 0x1e, -- .vso_end = 0x32, -- .vso_bline = 0, -- .vso_eline = 3, -- .vso_eline_present = true, -- /* sy_val */ -- /* sy2_val */ -- .max_lncnt = 0x4e1, -- }, --}; -- --struct meson_hdmi_venc_dmt_mode { -- struct drm_display_mode drm_mode; -- union meson_hdmi_venc_mode *mode; --} meson_hdmi_venc_dmt_modes[] = { -- /* 640x480@60Hz */ -- { -- { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, -- 752, 800, 0, 480, 490, 492, 525, 0, -- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -- &meson_hdmi_encp_mode_640x480_60, -- }, -- /* 800x600@60Hz */ -- { -- { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, -- 968, 1056, 0, 600, 601, 605, 628, 0, -- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -- &meson_hdmi_encp_mode_800x600_60, -- }, -- /* 1024x768@60Hz */ -- { -- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, -- 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, -- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -- &meson_hdmi_encp_mode_1024x768_60, -- }, -- /* 1152x864@75Hz */ -- { -- { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, -- 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, -- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -- &meson_hdmi_encp_mode_1152x864_75, -- }, -- /* 1280x1024@60Hz */ -- { -- { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, -- 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, -- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -- &meson_hdmi_encp_mode_1280x1024_60, -- }, -- /* 1600x1200@60Hz */ -- { -- { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, -- 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, -- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -- &meson_hdmi_encp_mode_1600x1200_60, -- }, -- /* 1920x1080@60Hz */ -- { -- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, -- 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, -- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -- &meson_hdmi_encp_mode_1080p60 -- }, -- { }, /* sentinel */ --}; -- - struct meson_hdmi_venc_vic_mode { - unsigned int vic; - union meson_hdmi_venc_mode *mode; -@@ -1044,17 +736,20 @@ static unsigned long modulo(unsigned long a, unsigned long b) - return a; - } - --bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) -+enum drm_mode_status -+meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) - { -- struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; -+ if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC | -+ DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)) -+ return MODE_BAD; - -- while (vmode->mode) { -- if (drm_mode_equal(&vmode->drm_mode, mode)) -- return true; -- vmode++; -- } -+ if (mode->hdisplay < 640 || mode->hdisplay > 1920) -+ return MODE_BAD_HVALUE; - -- return false; -+ if (mode->vdisplay < 480 || mode->vdisplay > 1200) -+ return MODE_BAD_VVALUE; -+ -+ return MODE_OK; - } - EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode); - -@@ -1072,18 +767,29 @@ bool meson_venc_hdmi_supported_vic(int vic) - } - EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); - --static union meson_hdmi_venc_mode --*meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode) -+void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode, -+ union meson_hdmi_venc_mode *dmt_mode) - { -- struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes; -- -- while (vmode->mode) { -- if (drm_mode_equal(&vmode->drm_mode, mode)) -- return vmode->mode; -- vmode++; -- } -- -- return NULL; -+ memset(dmt_mode, 0, sizeof(*dmt_mode)); -+ -+ dmt_mode->encp.dvi_settings = 0x21; -+ dmt_mode->encp.video_mode = 0x4040; -+ dmt_mode->encp.video_mode_adv = 0x18; -+ dmt_mode->encp.max_pxcnt = mode->htotal - 1; -+ dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start; -+ dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin + -+ mode->hdisplay - 1; -+ dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start; -+ dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline + -+ mode->vdisplay - 1; -+ dmt_mode->encp.hso_begin = 0; -+ dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start; -+ dmt_mode->encp.vso_begin = 30; -+ dmt_mode->encp.vso_end = 50; -+ dmt_mode->encp.vso_bline = 0; -+ dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start; -+ dmt_mode->encp.vso_eline_present = true; -+ dmt_mode->encp.max_lncnt = mode->vtotal - 1; - } - - static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) -@@ -1120,6 +826,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, - struct drm_display_mode *mode) - { - union meson_hdmi_venc_mode *vmode = NULL; -+ union meson_hdmi_venc_mode vmode_dmt; - bool use_enci = false; - bool venc_repeat = false; - bool hdmi_repeat = false; -@@ -1147,14 +854,18 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, - unsigned int sof_lines; - unsigned int vsync_lines; - -- if (meson_venc_hdmi_supported_vic(vic)) -+ if (meson_venc_hdmi_supported_vic(vic)) { - vmode = meson_venc_hdmi_get_vic_vmode(vic); -- else -- vmode = meson_venc_hdmi_get_dmt_vmode(mode); -- if (!vmode) { -- dev_err(priv->dev, "%s: Fatal Error, unsupported mode " -- DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode)); -- return; -+ if (!vmode) { -+ dev_err(priv->dev, "%s: Fatal Error, unsupported mode " -+ DRM_MODE_FMT "\n", __func__, -+ DRM_MODE_ARG(mode)); -+ return; -+ } -+ } -+ else { -+ meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt); -+ vmode = &vmode_dmt; - } - - /* Use VENCI for 480i and 576i and double HDMI pixels */ -diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h -index 7c18a36..97eaebb 100644 ---- a/drivers/gpu/drm/meson/meson_venc.h -+++ b/drivers/gpu/drm/meson/meson_venc.h -@@ -58,7 +58,8 @@ struct meson_cvbs_enci_mode { - }; - - /* HDMI Clock parameters */ --bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); -+enum drm_mode_status -+meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); - bool meson_venc_hdmi_supported_vic(int vic); - bool meson_venc_hdmi_venc_repeat(int vic); - |