Add enable sequence for writeback, use encoder->enable hook to
enable the transcoder.

Signed-off-by: Suraj Kandpal <suraj.kand...@intel.com>
---
 .../gpu/drm/i915/display/intel_writeback.c    | 104 ++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_writeback.c 
b/drivers/gpu/drm/i915/display/intel_writeback.c
index 7fb30cc61991..2db9ae7d810f 100644
--- a/drivers/gpu/drm/i915/display/intel_writeback.c
+++ b/drivers/gpu/drm/i915/display/intel_writeback.c
@@ -15,10 +15,13 @@
 #include <drm/drm_gem_framebuffer_helper.h>
 
 #include "i915_drv.h"
+#include "i915_reg.h"
 #include "i915_vma.h"
 #include "intel_atomic.h"
+#include "intel_crtc.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
+#include "intel_display_regs.h"
 #include "intel_display_driver.h"
 #include "intel_connector.h"
 #include "intel_fb_pin.h"
@@ -31,6 +34,7 @@ struct intel_writeback_connector {
        struct intel_connector connector;
        struct intel_writeback_job *job;
        enum transcoder trans;
+       enum pipe pipe;
        int frame_num;
 };
 
@@ -49,6 +53,12 @@ static const u32 writeback_formats[] = {
        DRM_FORMAT_XBGR2101010,
 };
 
+static struct intel_writeback_connector
+*enc_to_intel_writeback_connector(struct intel_encoder *encoder)
+{
+       return container_of(encoder, struct intel_writeback_connector, encoder);
+}
+
 static struct intel_writeback_connector
 *conn_to_intel_writeback_connector(struct intel_connector *connector)
 {
@@ -234,6 +244,99 @@ static int intel_writeback_atomic_check(struct 
drm_connector *connector,
        return 0;
 }
 
+static void intel_writeback_enable_encoder(struct intel_atomic_state *state,
+                                          struct intel_encoder *encoder,
+                                          const struct intel_crtc_state 
*crtc_state,
+                                          const struct drm_connector_state 
*conn_state)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct intel_writeback_connector *wb_conn =
+               enc_to_intel_writeback_connector(encoder);
+       struct intel_writeback_job *job = wb_conn->job;
+       const struct drm_display_mode *adjusted_mode = 
&crtc_state->hw.adjusted_mode;
+       enum transcoder trans = crtc_state->cpu_transcoder;
+       struct intel_crtc *pipe_crtc;
+       struct drm_framebuffer *fb;
+       u32 val = 0, hactive, vactive;
+       int i = 0;
+
+       if (!conn_state->writeback_job)
+               return;
+
+       wb_conn->trans = trans;
+       wb_conn->pipe = crtc->pipe;
+       fb = job->fb;
+       hactive = adjusted_mode->hdisplay;
+       vactive = adjusted_mode->vdisplay;
+
+       /* Configure WD_STRIDE, WD_SURF and WD_TAIL_CFG */
+       /* Enable Planes, Pipes and Transcoder */
+       /* TRANSCODER TIMINGS and other transcoder setting*/
+       /* minimum hactive as per bspec: 64 pixels */
+       if (hactive < 64)
+               drm_err(display->drm, "hactive is less then 64 pixels\n");
+
+       intel_de_write(display, TRANS_HTOTAL(display, trans), HACTIVE(hactive - 
1));
+       intel_de_write(display, TRANS_VTOTAL(display, trans), VACTIVE(vactive - 
1));
+
+       val = 0;
+       /* 2f) Configure and enable TRANS_WD_FUNC_CTL */
+       switch (crtc->pipe) {
+       default:
+               fallthrough;
+       case PIPE_A:
+               val |= WD_INPUT_PIPE_A;
+               break;
+       case PIPE_B:
+               val |= WD_INPUT_PIPE_B;
+               break;
+       case PIPE_C:
+               val |= WD_INPUT_PIPE_C;
+               break;
+       case PIPE_D:
+               val |= WD_INPUT_PIPE_D;
+               break;
+       }
+
+       switch (fb->format->format) {
+       default:
+               fallthrough;
+       case DRM_FORMAT_YUYV:
+               val |= WD_PIX_FMT_YUYV;
+               break;
+       case DRM_FORMAT_XYUV8888:
+               val |= WD_PIX_FMT_XYUV8888;
+               break;
+       case DRM_FORMAT_XBGR8888:
+               val |= WD_PIX_FMT_XBGR8888;
+               break;
+       case DRM_FORMAT_XBGR2101010:
+               val |= WD_PIX_FMT_XBGR2101010;
+               break;
+       }
+
+       val |= TRANS_WD_FUNC_ENABLE | WD_TRIGGERED_CAP_MODE_ENABLE |
+               WD_DISABLE_POINTERS;
+       intel_de_write(display, WD_TRANS_FUNC_CTL(trans), val);
+
+       if (DISPLAY_VER(display) >= 13)
+               intel_de_rmw(display, PIPE_CHICKEN(crtc->pipe),
+                            UNDERRUN_RECOVERY_DISABLE_ADLP,
+                            UNDERRUN_RECOVERY_DISABLE_ADLP);
+
+       /*  Configure and enable TRANS_CONF */
+       intel_de_write(display, TRANSCONF_WD(trans), WD_TRANS_ENABLE);
+       intel_de_posting_read(display, TRANSCONF_WD(trans));
+
+       for_each_pipe_crtc_modeset_enable(display, pipe_crtc, crtc_state, i) {
+               const struct intel_crtc_state *pipe_crtc_state =
+                       intel_atomic_get_new_crtc_state(state, pipe_crtc);
+
+               intel_crtc_vblank_on(pipe_crtc_state);
+       }
+}
+
 static struct drm_writeback_connector *
 intel_get_writeback_connector(struct drm_connector *connector)
 {
@@ -378,6 +481,7 @@ int intel_writeback_init(struct intel_display *display)
        encoder->get_config = intel_writeback_get_config;
        encoder->get_hw_state = intel_writeback_get_hw_state;
        encoder->compute_config = intel_writeback_compute_config;
+       encoder->enable = intel_writeback_enable_encoder;
 
        connector = &writeback_conn->connector;
        intel_writeback_connector_alloc(connector);
-- 
2.34.1

Reply via email to