sdm: Set fb id for inline rotator session

- Add support to set backup buffer fb id for inline rotator
  session.
- Define tiled and uncompressed layer buffer formats to handle
  setting of inline rotator buffer fb id.

Change-Id: I6be48c5abd418ec18816780e1af9e9783fa22233
CRs-Fixed: 2195047
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 4822089..fc40b2e 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -156,6 +156,12 @@
    */
   PLANE_SET_MULTIRECT_MODE,
   /*
+   * Op: Sets rotator output frame buffer ID for plane.
+   * Arg: uint32_t - Plane ID
+   *      uint32_t - Framebuffer ID
+   */
+  PLANE_SET_ROT_FB_ID,
+  /*
    * Op: Activate or deactivate a CRTC
    * Arg: uint32_t - CRTC ID
    *      uint32_t - 1 to enable, 0 to disable
@@ -392,6 +398,13 @@
   V2p5
 };
 
+/* Inline Rotation version */
+enum struct InlineRotationVersion {
+  UNKNOWN,
+  V1,
+  V1p1,   // Rotator FB ID needs to be set
+};
+
 /* Per CRTC Resource Info*/
 struct DRMCrtcInfo {
   bool has_src_split;
@@ -451,6 +464,7 @@
   bool has_excl_rect = false;
   QSEEDStepVersion qseed3_version;
   bool multirect_prop_present = false;
+  InlineRotationVersion inrot_version;  // inline rotation version
 };
 
 // All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index 649dda4..6ad0f65 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -149,6 +149,10 @@
   kFormatYCbCr420P010Ubwc,            //!< UBWC aligned YCbCr420P010 format.
 
   kFormatYCbCr420P010Venus,           //!< Venus aligned YCbCr420P010 format.
+                                      //!
+  kFormatYCbCr420SPVenusTile,         //!< Tiled & uncompressed YCbCr420SemiPlanarVenus format
+  kFormatYCbCr420TP10Tile,            //!< Tiled & uncompressed YCbCr420TP10 format.
+  kFormatYCbCr420P010Tile,            //!< Tiled & uncompressed YCbCr420P010 format.
 
   /* All YUV-Packed formats, Any new format will be added towards end of this group to maintain
      backward compatibility.
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index ab68986..bd598e0 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -179,6 +179,12 @@
   V2p5
 };
 
+enum InlineRotationVersion {
+  kInlineRotationNone,
+  kInlineRotationV1,
+  kInlineRotationV1p1,
+};
+
 struct HWResourceInfo {
   uint32_t hw_version = 0;
   uint32_t hw_revision = 0;
@@ -239,6 +245,7 @@
   uint32_t cache_size = 0;  // cache size in bytes
   HWQseedStepVersion pipe_qseed3_version = kQseed3v2;  // only valid when has_qseed3=true
   uint32_t min_prefill_lines = 0;
+  InlineRotationVersion inrot_version = kInlineRotationNone;
 
   void Reset() { *this = HWResourceInfo(); }
 };
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 759a1f1..91f89a2 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -186,6 +186,10 @@
       *drm_format = DRM_FORMAT_NV12;
       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
       break;
+    case kFormatYCbCr420SPVenusTile:
+      *drm_format = DRM_FORMAT_NV12;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE;
+      break;
     case kFormatYCrCb420SemiPlanar:
       *drm_format = DRM_FORMAT_NV21;
       break;
@@ -202,11 +206,21 @@
       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
         DRM_FORMAT_MOD_QCOM_DX;
       break;
+    case kFormatYCbCr420P010Tile:
+      *drm_format = DRM_FORMAT_NV12;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE |
+        DRM_FORMAT_MOD_QCOM_DX;
+      break;
     case kFormatYCbCr420TP10Ubwc:
       *drm_format = DRM_FORMAT_NV12;
       *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
         DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
       break;
+    case kFormatYCbCr420TP10Tile:
+      *drm_format = DRM_FORMAT_NV12;
+      *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE |
+        DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
+      break;
     case kFormatYCbCr422H2V1SemiPlanar:
       *drm_format = DRM_FORMAT_NV16;
       break;
@@ -257,6 +271,11 @@
     }
 
     MapBufferToFbId(input_buffer);
+
+    if (hw_rotator_session->mode == kRotatorInline && hw_rotate_info->valid &&
+        hw_rotator_session->output_buffer.planes[0].fd >= 0) {
+      MapBufferToFbId(&hw_rotator_session->output_buffer);
+    }
   }
 }
 
@@ -864,6 +883,12 @@
         if (hw_rotator_session->mode == kRotatorInline && hw_rotate_info->valid) {
           SetRect(hw_rotate_info->dst_roi, &rot_dst);
           drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION_DST_RECT, pipe_id, rot_dst);
+          if (hw_rotator_session->output_buffer.planes[0].fd >= 0) {
+            uint32_t rot_fb_id = registry_.GetFbId(hw_rotator_session->output_buffer.planes[0].fd);
+            if (rot_fb_id) {
+              drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROT_FB_ID, pipe_id, rot_fb_id);
+            }
+          }
         }
         DRMRect dst = {};
         SetRect(pipe_info->dst_roi, &dst);
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index d176f66..ae3c424 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -119,6 +119,17 @@
   return sdm_version;
 }
 
+static InlineRotationVersion GetInRotVersion(sde_drm::InlineRotationVersion drm_version) {
+  switch (drm_version) {
+    case sde_drm::InlineRotationVersion::V1:
+      return InlineRotationVersion::kInlineRotationV1;
+    case sde_drm::InlineRotationVersion::V1p1:
+      return InlineRotationVersion::kInlineRotationV1p1;
+    default:
+      return kInlineRotationNone;
+  }
+}
+
 HWResourceInfo *HWInfoDRM::hw_resource_ = nullptr;
 
 HWInfoDRM::HWInfoDRM() {
@@ -417,6 +428,7 @@
   hw_resource->max_pipe_bw = info.max_pipe_bandwidth / kKiloUnit;
   hw_resource->cache_size = info.cache_size;
   hw_resource->pipe_qseed3_version = GetQseedStepVersion(info.qseed3_version);
+  hw_resource->inrot_version = GetInRotVersion(info.inrot_version);
 }
 
 void HWInfoDRM::PopulateSupportedFmts(HWSubBlockType sub_blk_type,
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index e9839b9..84fbd80 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -293,6 +293,7 @@
       *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
       break;
     case kFormatYCbCr420SPVenusUbwc:
+    case kFormatYCbCr420SPVenusTile:
       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
       break;
@@ -330,10 +331,12 @@
       *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
       break;
     case kFormatYCbCr420TP10Ubwc:
+    case kFormatYCbCr420TP10Tile:
       *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
       break;
     case kFormatYCbCr420P010Ubwc:
+    case kFormatYCbCr420P010Tile:
       *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
       break;
diff --git a/sdm/libs/utils/formats.cpp b/sdm/libs/utils/formats.cpp
index 74f4f80..bb6ee94 100644
--- a/sdm/libs/utils/formats.cpp
+++ b/sdm/libs/utils/formats.cpp
@@ -100,6 +100,7 @@
   case kFormatYCbCr422H2V1SemiPlanar:   return "Y_CBCR_422_H2V1";
   case kFormatYCrCb422H2V1SemiPlanar:   return "Y_CRCB_422_H2V2";
   case kFormatYCbCr420SPVenusUbwc:      return "Y_CBCR_420_VENUS_UBWC";
+  case kFormatYCbCr420SPVenusTile:      return "Y_CBCR_420_VENUS_TILED";
   case kFormatYCbCr422H2V1Packed:       return "YCBYCR_422_H2V1";
   case kFormatCbYCrY422H2V1Packed:      return "CBYCRY_422_H2V1";
   case kFormatRGBA1010102:              return "RGBA_1010102";
@@ -116,6 +117,8 @@
   case kFormatYCbCr420TP10Ubwc:         return "Y_CBCR_420_TP10_UBWC";
   case kFormatYCbCr420P010Ubwc:         return "Y_CBCR_420_P010_UBWC";
   case kFormatYCbCr420P010Venus:        return "Y_CBCR_420_P010_VENUS";
+  case kFormatYCbCr420TP10Tile:         return "Y_CBCR_420_TP10_TILED";
+  case kFormatYCbCr420P010Tile:         return "Y_CBCR_420_P010_TILED";
   default:                              return "UNKNOWN";
   }
 }
@@ -123,7 +126,11 @@
 BufferLayout GetBufferLayout(LayerBufferFormat format) {
   switch (format) {
   case kFormatYCbCr420TP10Ubwc:
+  case kFormatYCbCr420TP10Tile:
     return kTPTiled;
+  case kFormatYCbCr420SPVenusTile:
+  case kFormatYCbCr420P010Tile:
+    return kUBWC;
   default:
     return (IsUBWCFormat(format) ? kUBWC : kLinear);
   }
@@ -156,6 +163,7 @@
     case kFormatYCbCr420P010:
     case kFormatYCbCr420P010Ubwc:
     case kFormatYCbCr420P010Venus:
+    case kFormatYCbCr420P010Tile:
       return 3.0f;
     case kFormatRGB565:
     case kFormatBGR565:
@@ -167,6 +175,7 @@
     case kFormatYCrCb422H2V1SemiPlanar:
     case kFormatYCbCr422H2V1SemiPlanar:
     case kFormatYCbCr420TP10Ubwc:
+    case kFormatYCbCr420TP10Tile:
     case kFormatYCbCr422H1V2SemiPlanar:
     case kFormatYCrCb422H1V2SemiPlanar:
       return 2.0f;
@@ -178,6 +187,7 @@
     case kFormatYCbCr420SemiPlanarVenus:
     case kFormatYCrCb420SemiPlanarVenus:
     case kFormatYCbCr420SPVenusUbwc:
+    case kFormatYCbCr420SPVenusTile:
       return 1.5f;
     default:
       return 0.0f;
@@ -189,18 +199,21 @@
 DisplayError GetBufferFormatTileSize(LayerBufferFormat format, FormatTileSize *tile_size) {
   switch (format) {
   case kFormatYCbCr420SPVenusUbwc:
+  case kFormatYCbCr420SPVenusTile:
     tile_size->tile_width = 32;
     tile_size->tile_height = 8;
     tile_size->uv_tile_width = 16;
     tile_size->uv_tile_height = 8;
     break;
   case kFormatYCbCr420TP10Ubwc:
+  case kFormatYCbCr420TP10Tile:
     tile_size->tile_width = 48;
     tile_size->tile_height = 4;
     tile_size->uv_tile_width = 24;
     tile_size->uv_tile_height = 4;
     break;
   case kFormatYCbCr420P010Ubwc:
+  case kFormatYCbCr420P010Tile:
     tile_size->tile_width = 32;
     tile_size->tile_height = 4;
     tile_size->uv_tile_width = 16;