return 0;
 }
 
+static bool
+modifier_has_dcc(uint64_t modifier)
+{
+       return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
+}
+
+static unsigned
+modifier_gfx9_swizzle_mode(uint64_t modifier)
+{
+       if (modifier == DRM_FORMAT_MOD_LINEAR)
+               return 0;
+
+       return AMD_FMT_MOD_GET(TILE, modifier);
+}
+
+static void
+fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
+                                   union dc_tiling_info *tiling_info,
+                                   uint64_t modifier)
+{
+       unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier);
+       unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
+       unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier);
+       unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits);
+
+       fill_gfx9_tiling_info_from_device(adev, tiling_info);
+
+       if (!IS_AMD_FMT_MOD(modifier))
+               return;
+
+       tiling_info->gfx9.num_pipes = 1u << pipes_log2;
+       tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - pipes_log2);
+
+       if (adev->family >= AMDGPU_FAMILY_NV) {
+               tiling_info->gfx9.num_pkrs = 1u << pkrs_log2;
+       } else {
+               tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits;
+
+               /* for DCC we know it isn't rb aligned, so rb_per_se doesn't matter. */
+       }
+}
+
+static int
+fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
+                                         const struct amdgpu_framebuffer *afb,
+                                         const enum surface_pixel_format format,
+                                         const enum dc_rotation_angle rotation,
+                                         const struct plane_size *plane_size,
+                                         union dc_tiling_info *tiling_info,
+                                         struct dc_plane_dcc_param *dcc,
+                                         struct dc_plane_address *address,
+                                         const bool force_disable_dcc)
+{
+       const uint64_t modifier = afb->base.modifier;
+       int ret;
+
+       fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
+       tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
+
+       if (modifier_has_dcc(modifier) && !force_disable_dcc) {
+               uint64_t dcc_address = afb->address + afb->base.offsets[1];
+
+               dcc->enable = 1;
+               dcc->meta_pitch = afb->base.pitches[1];
+               dcc->independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
+
+               address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
+               address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+       }
+
+       ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static int
 fill_plane_buffer_attributes(struct amdgpu_device *adev,
                             const struct amdgpu_framebuffer *afb,
        }
 
        if (adev->family >= AMDGPU_FAMILY_AI) {
-               ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
-                                                           plane_size, tiling_info, dcc,
-                                                           address, tiling_flags,
-                                                           force_disable_dcc);
-               if (ret)
-                       return ret;
+               if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
+                       ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
+                                                                       rotation, plane_size,
+                                                                       tiling_info, dcc,
+                                                                       address,
+                                                                       force_disable_dcc);
+                       if (ret)
+                               return ret;
+               } else {
+                       ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
+                                                                   plane_size, tiling_info, dcc,
+                                                                   address, tiling_flags,
+                                                                   force_disable_dcc);
+                       if (ret)
+                               return ret;
+               }
        } else {
                fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
        }
                new_afb = (struct amdgpu_framebuffer *)new_other_state->fb;
 
                /* Tiling and DCC changes also require bandwidth updates. */
-               if (old_afb->tiling_flags != new_afb->tiling_flags)
+               if (old_afb->tiling_flags != new_afb->tiling_flags ||
+                   old_afb->base.modifier != new_afb->base.modifier)
                        return true;
        }