mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-31 11:11:49 +00:00
remove useless patch for 5.0.y
This commit is contained in:
parent
146f682d31
commit
042da80afe
3 changed files with 0 additions and 806 deletions
|
@ -1,197 +0,0 @@
|
||||||
From e79ea0fbd040b03b2c58fe92fefe5e90a4ae586a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
|
||||||
Date: Mon, 29 Oct 2018 17:04:05 +0100
|
|
||||||
Subject: [PATCH] drm/meson: move OSD scaler management into plane atomic
|
|
||||||
update
|
|
||||||
|
|
||||||
In preparation to support the Primary Plane scaling, move the basic
|
|
||||||
OSD Interlace-Only scaler setup code into the primary plane atomic
|
|
||||||
update callback and handle the vsync scaler update like the overlay
|
|
||||||
plane scaling registers update.
|
|
||||||
---
|
|
||||||
drivers/gpu/drm/meson/meson_crtc.c | 35 ++++++++++++----------
|
|
||||||
drivers/gpu/drm/meson/meson_drv.h | 10 +++++++
|
|
||||||
drivers/gpu/drm/meson/meson_plane.c | 39 +++++++++++++++++++++++-
|
|
||||||
drivers/gpu/drm/meson/meson_vpp.c | 46 -----------------------------
|
|
||||||
4 files changed, 68 insertions(+), 62 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
|
|
||||||
index 631a51391440..75d97f1b2e8f 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_crtc.c
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_crtc.c
|
|
||||||
@@ -212,21 +212,26 @@ void meson_crtc_irq(struct meson_drm *priv)
|
|
||||||
priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3));
|
|
||||||
writel_relaxed(priv->viu.osd1_blk0_cfg[4],
|
|
||||||
priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4));
|
|
||||||
-
|
|
||||||
- /* If output is interlace, make use of the Scaler */
|
|
||||||
- if (priv->viu.osd1_interlace) {
|
|
||||||
- struct drm_plane *plane = priv->primary_plane;
|
|
||||||
- struct drm_plane_state *state = plane->state;
|
|
||||||
- struct drm_rect dest = {
|
|
||||||
- .x1 = state->crtc_x,
|
|
||||||
- .y1 = state->crtc_y,
|
|
||||||
- .x2 = state->crtc_x + state->crtc_w,
|
|
||||||
- .y2 = state->crtc_y + state->crtc_h,
|
|
||||||
- };
|
|
||||||
-
|
|
||||||
- meson_vpp_setup_interlace_vscaler_osd1(priv, &dest);
|
|
||||||
- } else
|
|
||||||
- meson_vpp_disable_interlace_vscaler_osd1(priv);
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_ctrl0,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_SC_CTRL0));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_i_wh_m1,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_o_h_start_end,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_o_v_start_end,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_v_ini_phase,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_v_phase_step,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_h_ini_phase,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_HSC_INI_PHASE));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_h_phase_step,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_HSC_PHASE_STEP));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_h_ctrl0,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
|
|
||||||
+ writel_relaxed(priv->viu.osd_sc_v_ctrl0,
|
|
||||||
+ priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
|
|
||||||
|
|
||||||
if (priv->canvas)
|
|
||||||
meson_canvas_config(priv->canvas, priv->canvas_id_osd1,
|
|
||||||
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
|
|
||||||
index 83e73491039a..4dccf4cd042a 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_drv.h
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_drv.h
|
|
||||||
@@ -53,6 +53,16 @@ struct meson_drm {
|
|
||||||
uint32_t osd1_addr;
|
|
||||||
uint32_t osd1_stride;
|
|
||||||
uint32_t osd1_height;
|
|
||||||
+ uint32_t osd_sc_ctrl0;
|
|
||||||
+ uint32_t osd_sc_i_wh_m1;
|
|
||||||
+ uint32_t osd_sc_o_h_start_end;
|
|
||||||
+ uint32_t osd_sc_o_v_start_end;
|
|
||||||
+ uint32_t osd_sc_v_ini_phase;
|
|
||||||
+ uint32_t osd_sc_v_phase_step;
|
|
||||||
+ uint32_t osd_sc_h_ini_phase;
|
|
||||||
+ uint32_t osd_sc_h_phase_step;
|
|
||||||
+ uint32_t osd_sc_h_ctrl0;
|
|
||||||
+ uint32_t osd_sc_v_ctrl0;
|
|
||||||
|
|
||||||
bool vd1_enabled;
|
|
||||||
bool vd1_commit;
|
|
||||||
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
|
|
||||||
index 51bec8e98a39..f915a79ae81c 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_plane.c
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_plane.c
|
|
||||||
@@ -143,13 +143,50 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * When the output is interlaced, the OSD must switch between
|
|
||||||
+ * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
|
|
||||||
+ * at each vsync.
|
|
||||||
+ * But the vertical scaler can provide such funtionnality if
|
|
||||||
+ * is configured for 2:1 scaling with interlace options enabled.
|
|
||||||
+ */
|
|
||||||
if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
|
|
||||||
priv->viu.osd1_interlace = true;
|
|
||||||
|
|
||||||
dest.y1 /= 2;
|
|
||||||
dest.y2 /= 2;
|
|
||||||
- } else
|
|
||||||
+
|
|
||||||
+ priv->viu.osd_sc_ctrl0 = BIT(3)| /* Enable scaler */
|
|
||||||
+ BIT(2); /* Select OSD1 */
|
|
||||||
+
|
|
||||||
+ /* 2:1 scaling */
|
|
||||||
+ priv->viu.osd_sc_i_wh_m1 = ((drm_rect_width(&dest) - 1) << 16) |
|
|
||||||
+ (drm_rect_height(&dest) - 1);
|
|
||||||
+ priv->viu.osd_sc_o_h_start_end = (dest.x1 << 16) | dest.x2;
|
|
||||||
+ priv->viu.osd_sc_o_v_start_end = (dest.y1 << 16) | dest.y2;
|
|
||||||
+
|
|
||||||
+ /* 2:1 vertical scaling values */
|
|
||||||
+ priv->viu.osd_sc_v_ini_phase = BIT(16);
|
|
||||||
+ priv->viu.osd_sc_v_phase_step = BIT(25);
|
|
||||||
+ priv->viu.osd_sc_v_ctrl0 =
|
|
||||||
+ (4 << 0) | /* osd_vsc_bank_length */
|
|
||||||
+ (4 << 3) | /* osd_vsc_top_ini_rcv_num0 */
|
|
||||||
+ (1 << 8) | /* osd_vsc_top_rpt_p0_num0 */
|
|
||||||
+ (6 << 11) | /* osd_vsc_bot_ini_rcv_num0 */
|
|
||||||
+ (2 << 16) | /* osd_vsc_bot_rpt_p0_num0 */
|
|
||||||
+ BIT(23) | /* osd_prog_interlace */
|
|
||||||
+ BIT(24); /* Enable vertical scaler */
|
|
||||||
+
|
|
||||||
+ /* No horizontal scaling */
|
|
||||||
+ priv->viu.osd_sc_h_ini_phase = 0;
|
|
||||||
+ priv->viu.osd_sc_h_phase_step = 0;
|
|
||||||
+ priv->viu.osd_sc_h_ctrl0 = 0;
|
|
||||||
+ } else {
|
|
||||||
priv->viu.osd1_interlace = false;
|
|
||||||
+ priv->viu.osd_sc_ctrl0 = 0;
|
|
||||||
+ priv->viu.osd_sc_h_ctrl0 = 0;
|
|
||||||
+ priv->viu.osd_sc_v_ctrl0 = 0;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The format of these registers is (x2 << 16 | x1),
|
|
||||||
diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c
|
|
||||||
index 5dc24a99e978..f9efb431e953 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_vpp.c
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_vpp.c
|
|
||||||
@@ -51,52 +51,6 @@ void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux)
|
|
||||||
writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
|
|
||||||
}
|
|
||||||
|
|
||||||
-/*
|
|
||||||
- * When the output is interlaced, the OSD must switch between
|
|
||||||
- * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
|
|
||||||
- * at each vsync.
|
|
||||||
- * But the vertical scaler can provide such funtionnality if
|
|
||||||
- * is configured for 2:1 scaling with interlace options enabled.
|
|
||||||
- */
|
|
||||||
-void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv,
|
|
||||||
- struct drm_rect *input)
|
|
||||||
-{
|
|
||||||
- writel_relaxed(BIT(3) /* Enable scaler */ |
|
|
||||||
- BIT(2), /* Select OSD1 */
|
|
||||||
- priv->io_base + _REG(VPP_OSD_SC_CTRL0));
|
|
||||||
-
|
|
||||||
- writel_relaxed(((drm_rect_width(input) - 1) << 16) |
|
|
||||||
- (drm_rect_height(input) - 1),
|
|
||||||
- priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
|
|
||||||
- /* 2:1 scaling */
|
|
||||||
- writel_relaxed(((input->x1) << 16) | (input->x2),
|
|
||||||
- priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
|
|
||||||
- writel_relaxed(((input->y1 >> 1) << 16) | (input->y2 >> 1),
|
|
||||||
- priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
|
|
||||||
-
|
|
||||||
- /* 2:1 scaling values */
|
|
||||||
- writel_relaxed(BIT(16), priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
|
|
||||||
- writel_relaxed(BIT(25), priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
|
|
||||||
-
|
|
||||||
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
|
|
||||||
-
|
|
||||||
- writel_relaxed((4 << 0) /* osd_vsc_bank_length */ |
|
|
||||||
- (4 << 3) /* osd_vsc_top_ini_rcv_num0 */ |
|
|
||||||
- (1 << 8) /* osd_vsc_top_rpt_p0_num0 */ |
|
|
||||||
- (6 << 11) /* osd_vsc_bot_ini_rcv_num0 */ |
|
|
||||||
- (2 << 16) /* osd_vsc_bot_rpt_p0_num0 */ |
|
|
||||||
- BIT(23) /* osd_prog_interlace */ |
|
|
||||||
- BIT(24), /* Enable vertical scaler */
|
|
||||||
- priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv)
|
|
||||||
-{
|
|
||||||
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
|
|
||||||
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
|
|
||||||
- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static unsigned int vpp_filter_coefs_4point_bspline[] = {
|
|
||||||
0x15561500, 0x14561600, 0x13561700, 0x12561800,
|
|
||||||
0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
|
|
|
@ -1,284 +0,0 @@
|
||||||
From 73b48fb586af15ca3f1dd3a8e90a4f93bee28ea4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
|
||||||
Date: Tue, 30 Oct 2018 14:29:10 +0100
|
|
||||||
Subject: [PATCH] drm/meson: Add primary plane scaling
|
|
||||||
|
|
||||||
This patch adds support for the Primary Plane scaling.
|
|
||||||
|
|
||||||
On the Amlogic GX SoCs, the primary plane is used as On-Screen-Display
|
|
||||||
layer on top of video, and it's needed to keep the OSD layer to a lower
|
|
||||||
size as the physical display size to :
|
|
||||||
- lower the memory bandwidth
|
|
||||||
- lower the OSD rendering
|
|
||||||
- lower the memory usage
|
|
||||||
|
|
||||||
This use-case is used when setting the display mode to 3840x2160 and the
|
|
||||||
OSD layer is rendered using the GPU. In this case, the GXBB & GXL cannot
|
|
||||||
work on more than 2000x2000 buffer, thus needing the OSD layer to be kept
|
|
||||||
at 1920x1080 and upscaled to 3840x2160 in hardware.
|
|
||||||
|
|
||||||
The primary plane atomic check still allow 1:1 scaling, allowing native
|
|
||||||
3840x2160 if needed by user-space applications.
|
|
||||||
---
|
|
||||||
drivers/gpu/drm/meson/meson_plane.c | 186 +++++++++++++++++++++-------
|
|
||||||
1 file changed, 141 insertions(+), 45 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
|
|
||||||
index f915a79ae81c..12a47b4f65a5 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_plane.c
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_plane.c
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
+#include <linux/bitfield.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <drm/drmP.h>
|
|
||||||
#include <drm/drm_atomic.h>
|
|
||||||
@@ -39,12 +40,50 @@
|
|
||||||
#include "meson_canvas.h"
|
|
||||||
#include "meson_registers.h"
|
|
||||||
|
|
||||||
+/* OSD_SCI_WH_M1 */
|
|
||||||
+#define SCI_WH_M1_W(w) FIELD_PREP(GENMASK(28, 16), w)
|
|
||||||
+#define SCI_WH_M1_H(h) FIELD_PREP(GENMASK(12, 0), h)
|
|
||||||
+
|
|
||||||
+/* OSD_SCO_H_START_END */
|
|
||||||
+/* OSD_SCO_V_START_END */
|
|
||||||
+#define SCO_HV_START(start) FIELD_PREP(GENMASK(27, 16), start)
|
|
||||||
+#define SCO_HV_END(end) FIELD_PREP(GENMASK(11, 0), end)
|
|
||||||
+
|
|
||||||
+/* OSD_SC_CTRL0 */
|
|
||||||
+#define SC_CTRL0_PATH_EN BIT(3)
|
|
||||||
+#define SC_CTRL0_SEL_OSD1 BIT(2)
|
|
||||||
+
|
|
||||||
+/* OSD_VSC_CTRL0 */
|
|
||||||
+#define VSC_BANK_LEN(value) FIELD_PREP(GENMASK(2, 0), value)
|
|
||||||
+#define VSC_TOP_INI_RCV_NUM(value) FIELD_PREP(GENMASK(6, 3), value)
|
|
||||||
+#define VSC_TOP_RPT_L0_NUM(value) FIELD_PREP(GENMASK(9, 8), value)
|
|
||||||
+#define VSC_BOT_INI_RCV_NUM(value) FIELD_PREP(GENMASK(14, 11), value)
|
|
||||||
+#define VSC_BOT_RPT_L0_NUM(value) FIELD_PREP(GENMASK(17, 16), value)
|
|
||||||
+#define VSC_PROG_INTERLACE BIT(23)
|
|
||||||
+#define VSC_VERTICAL_SCALER_EN BIT(24)
|
|
||||||
+
|
|
||||||
+/* OSD_VSC_INI_PHASE */
|
|
||||||
+#define VSC_INI_PHASE_BOT(bottom) FIELD_PREP(GENMASK(31, 16), bottom)
|
|
||||||
+#define VSC_INI_PHASE_TOP(top) FIELD_PREP(GENMASK(15, 0), top)
|
|
||||||
+
|
|
||||||
+/* OSD_HSC_CTRL0 */
|
|
||||||
+#define HSC_BANK_LENGTH(value) FIELD_PREP(GENMASK(2, 0), value)
|
|
||||||
+#define HSC_INI_RCV_NUM0(value) FIELD_PREP(GENMASK(6, 3), value)
|
|
||||||
+#define HSC_RPT_P0_NUM0(value) FIELD_PREP(GENMASK(9, 8), value)
|
|
||||||
+#define HSC_HORIZ_SCALER_EN BIT(22)
|
|
||||||
+
|
|
||||||
+/* VPP_OSD_VSC_PHASE_STEP */
|
|
||||||
+/* VPP_OSD_HSC_PHASE_STEP */
|
|
||||||
+#define SC_PHASE_STEP(value) FIELD_PREP(GENMASK(27, 0), value)
|
|
||||||
+
|
|
||||||
struct meson_plane {
|
|
||||||
struct drm_plane base;
|
|
||||||
struct meson_drm *priv;
|
|
||||||
};
|
|
||||||
#define to_meson_plane(x) container_of(x, struct meson_plane, base)
|
|
||||||
|
|
||||||
+#define FRAC_16_16(mult, div) (((mult) << 16) / (div))
|
|
||||||
+
|
|
||||||
static int meson_plane_atomic_check(struct drm_plane *plane,
|
|
||||||
struct drm_plane_state *state)
|
|
||||||
{
|
|
||||||
@@ -57,10 +96,15 @@ static int meson_plane_atomic_check(struct drm_plane *plane,
|
|
||||||
if (IS_ERR(crtc_state))
|
|
||||||
return PTR_ERR(crtc_state);
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Only allow :
|
|
||||||
+ * - Upscaling up to 5x, vertical and horizontal
|
|
||||||
+ * - Final coordinates must match crtc size
|
|
||||||
+ */
|
|
||||||
return drm_atomic_helper_check_plane_state(state, crtc_state,
|
|
||||||
+ FRAC_16_16(1, 5),
|
|
||||||
DRM_PLANE_HELPER_NO_SCALING,
|
|
||||||
- DRM_PLANE_HELPER_NO_SCALING,
|
|
||||||
- true, true);
|
|
||||||
+ false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Takes a fixed 16.16 number and converts it to integer. */
|
|
||||||
@@ -74,22 +118,19 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
|
||||||
{
|
|
||||||
struct meson_plane *meson_plane = to_meson_plane(plane);
|
|
||||||
struct drm_plane_state *state = plane->state;
|
|
||||||
- struct drm_framebuffer *fb = state->fb;
|
|
||||||
+ struct drm_rect dest = drm_plane_state_dest(state);
|
|
||||||
struct meson_drm *priv = meson_plane->priv;
|
|
||||||
+ struct drm_framebuffer *fb = state->fb;
|
|
||||||
struct drm_gem_cma_object *gem;
|
|
||||||
- struct drm_rect src = {
|
|
||||||
- .x1 = (state->src_x),
|
|
||||||
- .y1 = (state->src_y),
|
|
||||||
- .x2 = (state->src_x + state->src_w),
|
|
||||||
- .y2 = (state->src_y + state->src_h),
|
|
||||||
- };
|
|
||||||
- struct drm_rect dest = {
|
|
||||||
- .x1 = state->crtc_x,
|
|
||||||
- .y1 = state->crtc_y,
|
|
||||||
- .x2 = state->crtc_x + state->crtc_w,
|
|
||||||
- .y2 = state->crtc_y + state->crtc_h,
|
|
||||||
- };
|
|
||||||
unsigned long flags;
|
|
||||||
+ int vsc_ini_rcv_num, vsc_ini_rpt_p0_num;
|
|
||||||
+ int vsc_bot_rcv_num, vsc_bot_rpt_p0_num;
|
|
||||||
+ int hsc_ini_rcv_num, hsc_ini_rpt_p0_num;
|
|
||||||
+ int hf_phase_step, vf_phase_step;
|
|
||||||
+ int src_w, src_h, dst_w, dst_h;
|
|
||||||
+ int bot_ini_phase;
|
|
||||||
+ int hf_bank_len;
|
|
||||||
+ int vf_bank_len;
|
|
||||||
u8 canvas_id_osd1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -143,6 +184,27 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
+ /* Default scaler parameters */
|
|
||||||
+ vsc_bot_rcv_num = 0;
|
|
||||||
+ vsc_bot_rpt_p0_num = 0;
|
|
||||||
+ hf_bank_len = 4;
|
|
||||||
+ vf_bank_len = 4;
|
|
||||||
+
|
|
||||||
+ if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
|
|
||||||
+ vsc_bot_rcv_num = 6;
|
|
||||||
+ vsc_bot_rpt_p0_num = 2;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ hsc_ini_rcv_num = hf_bank_len;
|
|
||||||
+ vsc_ini_rcv_num = vf_bank_len;
|
|
||||||
+ hsc_ini_rpt_p0_num = (hf_bank_len / 2) - 1;
|
|
||||||
+ vsc_ini_rpt_p0_num = (vf_bank_len / 2) - 1;
|
|
||||||
+
|
|
||||||
+ src_w = fixed16_to_int(state->src_w);
|
|
||||||
+ src_h = fixed16_to_int(state->src_h);
|
|
||||||
+ dst_w = state->crtc_w;
|
|
||||||
+ dst_h = state->crtc_h;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* When the output is interlaced, the OSD must switch between
|
|
||||||
* each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
|
|
||||||
@@ -151,41 +213,73 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
|
||||||
* is configured for 2:1 scaling with interlace options enabled.
|
|
||||||
*/
|
|
||||||
if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
|
|
||||||
- priv->viu.osd1_interlace = true;
|
|
||||||
-
|
|
||||||
dest.y1 /= 2;
|
|
||||||
dest.y2 /= 2;
|
|
||||||
+ dst_h /= 2;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- priv->viu.osd_sc_ctrl0 = BIT(3)| /* Enable scaler */
|
|
||||||
- BIT(2); /* Select OSD1 */
|
|
||||||
+ hf_phase_step = ((src_w << 18) / dst_w) << 6;
|
|
||||||
+ vf_phase_step = (src_h << 20) / dst_h;
|
|
||||||
|
|
||||||
- /* 2:1 scaling */
|
|
||||||
- priv->viu.osd_sc_i_wh_m1 = ((drm_rect_width(&dest) - 1) << 16) |
|
|
||||||
- (drm_rect_height(&dest) - 1);
|
|
||||||
- priv->viu.osd_sc_o_h_start_end = (dest.x1 << 16) | dest.x2;
|
|
||||||
- priv->viu.osd_sc_o_v_start_end = (dest.y1 << 16) | dest.y2;
|
|
||||||
+ if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
|
|
||||||
+ bot_ini_phase = ((vf_phase_step / 2) >> 4);
|
|
||||||
+ else
|
|
||||||
+ bot_ini_phase = 0;
|
|
||||||
+
|
|
||||||
+ vf_phase_step = (vf_phase_step << 4);
|
|
||||||
+
|
|
||||||
+ /* In interlaced mode, scaler is always active */
|
|
||||||
+ if (src_h != dst_h || src_w != dst_w) {
|
|
||||||
+ priv->viu.osd_sc_i_wh_m1 = SCI_WH_M1_W(src_w - 1) |
|
|
||||||
+ SCI_WH_M1_H(src_h - 1);
|
|
||||||
+ priv->viu.osd_sc_o_h_start_end = SCO_HV_START(dest.x1) |
|
|
||||||
+ SCO_HV_END(dest.x2 - 1);
|
|
||||||
+ priv->viu.osd_sc_o_v_start_end = SCO_HV_START(dest.y1) |
|
|
||||||
+ SCO_HV_END(dest.y2 - 1);
|
|
||||||
+ /* Enable OSD Scaler */
|
|
||||||
+ priv->viu.osd_sc_ctrl0 = SC_CTRL0_PATH_EN | SC_CTRL0_SEL_OSD1;
|
|
||||||
+ } else {
|
|
||||||
+ priv->viu.osd_sc_i_wh_m1 = 0;
|
|
||||||
+ priv->viu.osd_sc_o_h_start_end = 0;
|
|
||||||
+ priv->viu.osd_sc_o_v_start_end = 0;
|
|
||||||
+ priv->viu.osd_sc_ctrl0 = 0;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- /* 2:1 vertical scaling values */
|
|
||||||
- priv->viu.osd_sc_v_ini_phase = BIT(16);
|
|
||||||
- priv->viu.osd_sc_v_phase_step = BIT(25);
|
|
||||||
+ /* In interlaced mode, vertical scaler is always active */
|
|
||||||
+ if (src_h != dst_h) {
|
|
||||||
priv->viu.osd_sc_v_ctrl0 =
|
|
||||||
- (4 << 0) | /* osd_vsc_bank_length */
|
|
||||||
- (4 << 3) | /* osd_vsc_top_ini_rcv_num0 */
|
|
||||||
- (1 << 8) | /* osd_vsc_top_rpt_p0_num0 */
|
|
||||||
- (6 << 11) | /* osd_vsc_bot_ini_rcv_num0 */
|
|
||||||
- (2 << 16) | /* osd_vsc_bot_rpt_p0_num0 */
|
|
||||||
- BIT(23) | /* osd_prog_interlace */
|
|
||||||
- BIT(24); /* Enable vertical scaler */
|
|
||||||
-
|
|
||||||
- /* No horizontal scaling */
|
|
||||||
+ VSC_BANK_LEN(vf_bank_len) |
|
|
||||||
+ VSC_TOP_INI_RCV_NUM(vsc_ini_rcv_num) |
|
|
||||||
+ VSC_TOP_RPT_L0_NUM(vsc_ini_rpt_p0_num) |
|
|
||||||
+ VSC_VERTICAL_SCALER_EN;
|
|
||||||
+
|
|
||||||
+ if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
|
|
||||||
+ priv->viu.osd_sc_v_ctrl0 |=
|
|
||||||
+ VSC_BOT_INI_RCV_NUM(vsc_bot_rcv_num) |
|
|
||||||
+ VSC_BOT_RPT_L0_NUM(vsc_bot_rpt_p0_num) |
|
|
||||||
+ VSC_PROG_INTERLACE;
|
|
||||||
+
|
|
||||||
+ priv->viu.osd_sc_v_phase_step = SC_PHASE_STEP(vf_phase_step);
|
|
||||||
+ priv->viu.osd_sc_v_ini_phase = VSC_INI_PHASE_BOT(bot_ini_phase);
|
|
||||||
+ } else {
|
|
||||||
+ priv->viu.osd_sc_v_ctrl0 = 0;
|
|
||||||
+ priv->viu.osd_sc_v_phase_step = 0;
|
|
||||||
+ priv->viu.osd_sc_v_ini_phase = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Horizontal scaler is only used if width does not match */
|
|
||||||
+ if (src_w != dst_w) {
|
|
||||||
+ priv->viu.osd_sc_h_ctrl0 =
|
|
||||||
+ HSC_BANK_LENGTH(hf_bank_len) |
|
|
||||||
+ HSC_INI_RCV_NUM0(hsc_ini_rcv_num) |
|
|
||||||
+ HSC_RPT_P0_NUM0(hsc_ini_rpt_p0_num) |
|
|
||||||
+ HSC_HORIZ_SCALER_EN;
|
|
||||||
+ priv->viu.osd_sc_h_phase_step = SC_PHASE_STEP(hf_phase_step);
|
|
||||||
priv->viu.osd_sc_h_ini_phase = 0;
|
|
||||||
- priv->viu.osd_sc_h_phase_step = 0;
|
|
||||||
- priv->viu.osd_sc_h_ctrl0 = 0;
|
|
||||||
} else {
|
|
||||||
- priv->viu.osd1_interlace = false;
|
|
||||||
- priv->viu.osd_sc_ctrl0 = 0;
|
|
||||||
priv->viu.osd_sc_h_ctrl0 = 0;
|
|
||||||
- priv->viu.osd_sc_v_ctrl0 = 0;
|
|
||||||
+ priv->viu.osd_sc_h_phase_step = 0;
|
|
||||||
+ priv->viu.osd_sc_h_ini_phase = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -193,10 +287,12 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
|
||||||
* where x2 is exclusive.
|
|
||||||
* e.g. +30x1920 would be (1919 << 16) | 30
|
|
||||||
*/
|
|
||||||
- priv->viu.osd1_blk0_cfg[1] = ((fixed16_to_int(src.x2) - 1) << 16) |
|
|
||||||
- fixed16_to_int(src.x1);
|
|
||||||
- priv->viu.osd1_blk0_cfg[2] = ((fixed16_to_int(src.y2) - 1) << 16) |
|
|
||||||
- fixed16_to_int(src.y1);
|
|
||||||
+ priv->viu.osd1_blk0_cfg[1] =
|
|
||||||
+ ((fixed16_to_int(state->src.x2) - 1) << 16) |
|
|
||||||
+ fixed16_to_int(state->src.x1);
|
|
||||||
+ priv->viu.osd1_blk0_cfg[2] =
|
|
||||||
+ ((fixed16_to_int(state->src.y2) - 1) << 16) |
|
|
||||||
+ fixed16_to_int(state->src.y1);
|
|
||||||
priv->viu.osd1_blk0_cfg[3] = ((dest.x2 - 1) << 16) | dest.x1;
|
|
||||||
priv->viu.osd1_blk0_cfg[4] = ((dest.y2 - 1) << 16) | dest.y1;
|
|
||||||
|
|
|
@ -1,325 +0,0 @@
|
||||||
From 1085ede288f54b468e255b1b223382680ba3a745 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
|
||||||
Date: Mon, 23 Jul 2018 16:34:03 +0200
|
|
||||||
Subject: [PATCH] drm/meson: Add support for VIC alternate timings
|
|
||||||
|
|
||||||
This change is an attempt to handle the alternate clock for the CEA mode.
|
|
||||||
60Hz vs. 59.94Hz, 30Hz vs 29.97Hz or 24Hz vs 23.97Hz on the Amlogic Meson SoC
|
|
||||||
DRM Driver pixel clock generation.
|
|
||||||
|
|
||||||
The actual clock generation will be moved to the Common Clock framework once
|
|
||||||
all the video clock are handled by the Amlogic Meson SoC clock driver,
|
|
||||||
then these alternate timings will be handled in the same time in a cleaner
|
|
||||||
fashion.
|
|
||||||
---
|
|
||||||
drivers/gpu/drm/meson/meson_dw_hdmi.c | 12 +--
|
|
||||||
drivers/gpu/drm/meson/meson_vclk.c | 127 +++++++++++++++++---------
|
|
||||||
drivers/gpu/drm/meson/meson_vclk.h | 2 +
|
|
||||||
3 files changed, 89 insertions(+), 52 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
|
|
||||||
index 2cb2ad26d716..807111ebfdd9 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
|
|
||||||
@@ -594,17 +594,7 @@ 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 for VIC modes */
|
|
||||||
- switch (vclk_freq) {
|
|
||||||
- case 54000:
|
|
||||||
- case 74250:
|
|
||||||
- case 148500:
|
|
||||||
- case 297000:
|
|
||||||
- case 594000:
|
|
||||||
- return MODE_OK;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return MODE_CLOCK_RANGE;
|
|
||||||
+ return meson_vclk_vic_supported_freq(vclk_freq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Encoder */
|
|
||||||
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
|
|
||||||
index ae5473257f72..5acccebd026d 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_vclk.c
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_vclk.c
|
|
||||||
@@ -117,6 +117,8 @@
|
|
||||||
#define HDMI_PLL_RESET BIT(28)
|
|
||||||
#define HDMI_PLL_LOCK BIT(31)
|
|
||||||
|
|
||||||
+#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001)
|
|
||||||
+
|
|
||||||
/* VID PLL Dividers */
|
|
||||||
enum {
|
|
||||||
VID_PLL_DIV_1 = 0,
|
|
||||||
@@ -323,7 +325,7 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
|
|
||||||
enum {
|
|
||||||
/* PLL O1 O2 O3 VP DV EN TX */
|
|
||||||
/* 4320 /4 /4 /1 /5 /1 => /2 /2 */
|
|
||||||
- MESON_VCLK_HDMI_ENCI_54000 = 1,
|
|
||||||
+ MESON_VCLK_HDMI_ENCI_54000 = 0,
|
|
||||||
/* 4320 /4 /4 /1 /5 /1 => /1 /2 */
|
|
||||||
MESON_VCLK_HDMI_DDR_54000,
|
|
||||||
/* 2970 /4 /1 /1 /5 /1 => /1 /2 */
|
|
||||||
@@ -339,6 +341,7 @@ enum {
|
|
||||||
};
|
|
||||||
|
|
||||||
struct meson_vclk_params {
|
|
||||||
+ unsigned int pixel_freq;
|
|
||||||
unsigned int pll_base_freq;
|
|
||||||
unsigned int pll_od1;
|
|
||||||
unsigned int pll_od2;
|
|
||||||
@@ -347,6 +350,7 @@ struct meson_vclk_params {
|
|
||||||
unsigned int vclk_div;
|
|
||||||
} params[] = {
|
|
||||||
[MESON_VCLK_HDMI_ENCI_54000] = {
|
|
||||||
+ .pixel_freq = 54000,
|
|
||||||
.pll_base_freq = 4320000,
|
|
||||||
.pll_od1 = 4,
|
|
||||||
.pll_od2 = 4,
|
|
||||||
@@ -355,6 +359,7 @@ struct meson_vclk_params {
|
|
||||||
.vclk_div = 1,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_DDR_54000] = {
|
|
||||||
+ .pixel_freq = 54000,
|
|
||||||
.pll_base_freq = 4320000,
|
|
||||||
.pll_od1 = 4,
|
|
||||||
.pll_od2 = 4,
|
|
||||||
@@ -363,6 +368,7 @@ struct meson_vclk_params {
|
|
||||||
.vclk_div = 1,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_DDR_148500] = {
|
|
||||||
+ .pixel_freq = 148500,
|
|
||||||
.pll_base_freq = 2970000,
|
|
||||||
.pll_od1 = 4,
|
|
||||||
.pll_od2 = 1,
|
|
||||||
@@ -371,6 +377,7 @@ struct meson_vclk_params {
|
|
||||||
.vclk_div = 1,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_74250] = {
|
|
||||||
+ .pixel_freq = 74250,
|
|
||||||
.pll_base_freq = 2970000,
|
|
||||||
.pll_od1 = 2,
|
|
||||||
.pll_od2 = 2,
|
|
||||||
@@ -379,6 +386,7 @@ struct meson_vclk_params {
|
|
||||||
.vclk_div = 1,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_148500] = {
|
|
||||||
+ .pixel_freq = 148500,
|
|
||||||
.pll_base_freq = 2970000,
|
|
||||||
.pll_od1 = 1,
|
|
||||||
.pll_od2 = 2,
|
|
||||||
@@ -387,6 +395,7 @@ struct meson_vclk_params {
|
|
||||||
.vclk_div = 1,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_297000] = {
|
|
||||||
+ .pixel_freq = 297000,
|
|
||||||
.pll_base_freq = 2970000,
|
|
||||||
.pll_od1 = 1,
|
|
||||||
.pll_od2 = 1,
|
|
||||||
@@ -395,6 +404,7 @@ struct meson_vclk_params {
|
|
||||||
.vclk_div = 2,
|
|
||||||
},
|
|
||||||
[MESON_VCLK_HDMI_594000] = {
|
|
||||||
+ .pixel_freq = 594000,
|
|
||||||
.pll_base_freq = 5940000,
|
|
||||||
.pll_od1 = 1,
|
|
||||||
.pll_od2 = 1,
|
|
||||||
@@ -402,6 +412,7 @@ struct meson_vclk_params {
|
|
||||||
.vid_pll_div = VID_PLL_DIV_5,
|
|
||||||
.vclk_div = 1,
|
|
||||||
},
|
|
||||||
+ { /* sentinel */ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline unsigned int pll_od_to_reg(unsigned int od)
|
|
||||||
@@ -626,12 +637,37 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
|
||||||
pll_freq);
|
|
||||||
}
|
|
||||||
|
|
||||||
+enum drm_mode_status
|
|
||||||
+meson_vclk_vic_supported_freq(unsigned int freq)
|
|
||||||
+{
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ DRM_DEBUG_DRIVER("freq = %d\n", freq);
|
|
||||||
+
|
|
||||||
+ for (i = 0 ; params[i].pixel_freq ; ++i) {
|
|
||||||
+ DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
|
|
||||||
+ i, params[i].pixel_freq,
|
|
||||||
+ FREQ_1000_1001(params[i].pixel_freq));
|
|
||||||
+ /* Match strict frequency */
|
|
||||||
+ if (freq == params[i].pixel_freq)
|
|
||||||
+ return MODE_OK;
|
|
||||||
+ /* Match 1000/1001 variant */
|
|
||||||
+ if (freq == FREQ_1000_1001(params[i].pixel_freq))
|
|
||||||
+ return MODE_OK;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return MODE_CLOCK_RANGE;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_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)
|
|
||||||
+ bool hdmi_use_enci, bool vic_alternate_clock)
|
|
||||||
{
|
|
||||||
+ unsigned int m, frac;
|
|
||||||
+
|
|
||||||
/* Set HDMI-TX sys clock */
|
|
||||||
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
|
|
||||||
CTS_HDMI_SYS_SEL_MASK, 0);
|
|
||||||
@@ -646,34 +682,38 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int 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);
|
|
||||||
+ m = 0x3d;
|
|
||||||
+ frac = vic_alternate_clock ? 0xd02 : 0xe00;
|
|
||||||
break;
|
|
||||||
case 4320000:
|
|
||||||
- meson_hdmi_pll_set_params(priv, 0x5a, 0,
|
|
||||||
- od1, od2, od3);
|
|
||||||
+ m = vic_alternate_clock ? 0x59 : 0x5a;
|
|
||||||
+ frac = vic_alternate_clock ? 0xe8f : 0;
|
|
||||||
break;
|
|
||||||
case 5940000:
|
|
||||||
- meson_hdmi_pll_set_params(priv, 0x7b, 0xc00,
|
|
||||||
- od1, od2, od3);
|
|
||||||
+ m = 0x7b;
|
|
||||||
+ frac = vic_alternate_clock ? 0xa05 : 0xc00;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
|
|
||||||
} 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);
|
|
||||||
+ m = 0x7b;
|
|
||||||
+ frac = vic_alternate_clock ? 0x281 : 0x300;
|
|
||||||
break;
|
|
||||||
case 4320000:
|
|
||||||
- meson_hdmi_pll_set_params(priv, 0xb4, 0,
|
|
||||||
- od1, od2, od3);
|
|
||||||
+ m = vic_alternate_clock ? 0xb3 : 0xb4;
|
|
||||||
+ frac = vic_alternate_clock ? 0x347 : 0;
|
|
||||||
break;
|
|
||||||
case 5940000:
|
|
||||||
- meson_hdmi_pll_set_params(priv, 0xf7, 0x200,
|
|
||||||
- od1, od2, od3);
|
|
||||||
+ m = 0xf7;
|
|
||||||
+ frac = vic_alternate_clock ? 0x102 : 0x200;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup vid_pll divider */
|
|
||||||
@@ -826,6 +866,7 @@ 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)
|
|
||||||
{
|
|
||||||
+ bool vic_alternate_clock = false;
|
|
||||||
unsigned int freq;
|
|
||||||
unsigned int hdmi_tx_div;
|
|
||||||
unsigned int venc_div;
|
|
||||||
@@ -843,7 +884,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
||||||
* - encp encoder
|
|
||||||
*/
|
|
||||||
meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
|
|
||||||
- VID_PLL_DIV_5, 2, 1, 1, false);
|
|
||||||
+ VID_PLL_DIV_5, 2, 1, 1, false, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -863,31 +904,35 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
||||||
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);
|
|
||||||
+ for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
|
|
||||||
+ if (vclk_freq == params[freq].pixel_freq ||
|
|
||||||
+ vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) {
|
|
||||||
+ if (vclk_freq != params[freq].pixel_freq)
|
|
||||||
+ vic_alternate_clock = true;
|
|
||||||
+ else
|
|
||||||
+ vic_alternate_clock = false;
|
|
||||||
+
|
|
||||||
+ if (freq == MESON_VCLK_HDMI_ENCI_54000 &&
|
|
||||||
+ !hdmi_use_enci)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (freq == MESON_VCLK_HDMI_DDR_54000 &&
|
|
||||||
+ hdmi_use_enci)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (freq == MESON_VCLK_HDMI_DDR_148500 &&
|
|
||||||
+ dac_freq == vclk_freq)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (freq == MESON_VCLK_HDMI_148500 &&
|
|
||||||
+ dac_freq != vclk_freq)
|
|
||||||
+ continue;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!params[freq].pixel_freq) {
|
|
||||||
+ pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -895,6 +940,6 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
||||||
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);
|
|
||||||
+ hdmi_use_enci, vic_alternate_clock);
|
|
||||||
}
|
|
||||||
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 869fa3a3073e..4bd8752da02a 100644
|
|
||||||
--- a/drivers/gpu/drm/meson/meson_vclk.h
|
|
||||||
+++ b/drivers/gpu/drm/meson/meson_vclk.h
|
|
||||||
@@ -32,6 +32,8 @@ enum {
|
|
||||||
|
|
||||||
enum drm_mode_status
|
|
||||||
meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
|
|
||||||
+enum drm_mode_status
|
|
||||||
+meson_vclk_vic_supported_freq(unsigned int freq);
|
|
||||||
|
|
||||||
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
||||||
unsigned int vclk_freq, unsigned int venc_freq,
|
|
Loading…
Add table
Reference in a new issue