Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[sfrench/cifs-2.6.git] / drivers / gpu / drm / vc4 / vc4_plane.c
index d34cd5393a9b021f851fab8b16b042e84e99f6c4..fa6809d8b0fe69ed6f7372e48e704449d04b1878 100644 (file)
  * into the region of the HVS that it has allocated for us.
  */
 
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_plane_helper.h>
+
 #include "vc4_drv.h"
 #include "vc4_regs.h"
-#include "drm_atomic.h"
-#include "drm_atomic_helper.h"
-#include "drm_fb_cma_helper.h"
-#include "drm_plane_helper.h"
 
 enum vc4_scaling_mode {
        VC4_SCALING_NONE,
@@ -499,8 +500,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
        u32 ctl0_offset = vc4_state->dlist_count;
        const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
        int num_planes = drm_format_num_planes(format->drm);
-       u32 scl0, scl1;
-       u32 lbm_size;
+       u32 scl0, scl1, pitch0;
+       u32 lbm_size, tiling;
        unsigned long irqflags;
        int ret, i;
 
@@ -541,11 +542,31 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
                scl1 = vc4_get_scl_field(state, 0);
        }
 
+       switch (fb->modifier) {
+       case DRM_FORMAT_MOD_LINEAR:
+               tiling = SCALER_CTL0_TILING_LINEAR;
+               pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH);
+               break;
+       case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
+               tiling = SCALER_CTL0_TILING_256B_OR_T;
+
+               pitch0 = (VC4_SET_FIELD(0, SCALER_PITCH0_TILE_Y_OFFSET),
+                         VC4_SET_FIELD(0, SCALER_PITCH0_TILE_WIDTH_L),
+                         VC4_SET_FIELD((vc4_state->src_w[0] + 31) >> 5,
+                                       SCALER_PITCH0_TILE_WIDTH_R));
+               break;
+       default:
+               DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx",
+                             (long long)fb->modifier);
+               return -EINVAL;
+       }
+
        /* Control word */
        vc4_dlist_write(vc4_state,
                        SCALER_CTL0_VALID |
                        (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
                        (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
+                       VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) |
                        (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) |
                        VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) |
                        VC4_SET_FIELD(scl1, SCALER_CTL0_SCL1));
@@ -599,8 +620,11 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
        for (i = 0; i < num_planes; i++)
                vc4_dlist_write(vc4_state, 0xc0c0c0c0);
 
-       /* Pitch word 0/1/2 */
-       for (i = 0; i < num_planes; i++) {
+       /* Pitch word 0 */
+       vc4_dlist_write(vc4_state, pitch0);
+
+       /* Pitch word 1/2 */
+       for (i = 1; i < num_planes; i++) {
                vc4_dlist_write(vc4_state,
                                VC4_SET_FIELD(fb->pitches[i], SCALER_SRC_PITCH));
        }