linux/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c
<<
>>
Prefs
   1/*
   2 * Copyright 2017 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26#include "../display_mode_lib.h"
  27#include "../display_mode_vba.h"
  28#include "../dml_inline_defs.h"
  29#include "display_rq_dlg_calc_31.h"
  30
  31static bool CalculateBytePerPixelAnd256BBlockSizes(
  32                enum source_format_class SourcePixelFormat,
  33                enum dm_swizzle_mode SurfaceTiling,
  34                unsigned int *BytePerPixelY,
  35                unsigned int *BytePerPixelC,
  36                double *BytePerPixelDETY,
  37                double *BytePerPixelDETC,
  38                unsigned int *BlockHeight256BytesY,
  39                unsigned int *BlockHeight256BytesC,
  40                unsigned int *BlockWidth256BytesY,
  41                unsigned int *BlockWidth256BytesC)
  42{
  43        if (SourcePixelFormat == dm_444_64) {
  44                *BytePerPixelDETY = 8;
  45                *BytePerPixelDETC = 0;
  46                *BytePerPixelY = 8;
  47                *BytePerPixelC = 0;
  48        } else if (SourcePixelFormat == dm_444_32 || SourcePixelFormat == dm_rgbe) {
  49                *BytePerPixelDETY = 4;
  50                *BytePerPixelDETC = 0;
  51                *BytePerPixelY = 4;
  52                *BytePerPixelC = 0;
  53        } else if (SourcePixelFormat == dm_444_16) {
  54                *BytePerPixelDETY = 2;
  55                *BytePerPixelDETC = 0;
  56                *BytePerPixelY = 2;
  57                *BytePerPixelC = 0;
  58        } else if (SourcePixelFormat == dm_444_8) {
  59                *BytePerPixelDETY = 1;
  60                *BytePerPixelDETC = 0;
  61                *BytePerPixelY = 1;
  62                *BytePerPixelC = 0;
  63        } else if (SourcePixelFormat == dm_rgbe_alpha) {
  64                *BytePerPixelDETY = 4;
  65                *BytePerPixelDETC = 1;
  66                *BytePerPixelY = 4;
  67                *BytePerPixelC = 1;
  68        } else if (SourcePixelFormat == dm_420_8) {
  69                *BytePerPixelDETY = 1;
  70                *BytePerPixelDETC = 2;
  71                *BytePerPixelY = 1;
  72                *BytePerPixelC = 2;
  73        } else if (SourcePixelFormat == dm_420_12) {
  74                *BytePerPixelDETY = 2;
  75                *BytePerPixelDETC = 4;
  76                *BytePerPixelY = 2;
  77                *BytePerPixelC = 4;
  78        } else {
  79                *BytePerPixelDETY = 4.0 / 3;
  80                *BytePerPixelDETC = 8.0 / 3;
  81                *BytePerPixelY = 2;
  82                *BytePerPixelC = 4;
  83        }
  84
  85        if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32 || SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_8 || SourcePixelFormat == dm_mono_16
  86                        || SourcePixelFormat == dm_mono_8 || SourcePixelFormat == dm_rgbe)) {
  87                if (SurfaceTiling == dm_sw_linear) {
  88                        *BlockHeight256BytesY = 1;
  89                } else if (SourcePixelFormat == dm_444_64) {
  90                        *BlockHeight256BytesY = 4;
  91                } else if (SourcePixelFormat == dm_444_8) {
  92                        *BlockHeight256BytesY = 16;
  93                } else {
  94                        *BlockHeight256BytesY = 8;
  95                }
  96                *BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
  97                *BlockHeight256BytesC = 0;
  98                *BlockWidth256BytesC = 0;
  99        } else {
 100                if (SurfaceTiling == dm_sw_linear) {
 101                        *BlockHeight256BytesY = 1;
 102                        *BlockHeight256BytesC = 1;
 103                } else if (SourcePixelFormat == dm_rgbe_alpha) {
 104                        *BlockHeight256BytesY = 8;
 105                        *BlockHeight256BytesC = 16;
 106                } else if (SourcePixelFormat == dm_420_8) {
 107                        *BlockHeight256BytesY = 16;
 108                        *BlockHeight256BytesC = 8;
 109                } else {
 110                        *BlockHeight256BytesY = 8;
 111                        *BlockHeight256BytesC = 8;
 112                }
 113                *BlockWidth256BytesY = 256U / *BytePerPixelY / *BlockHeight256BytesY;
 114                *BlockWidth256BytesC = 256U / *BytePerPixelC / *BlockHeight256BytesC;
 115        }
 116        return true;
 117}
 118
 119static bool is_dual_plane(enum source_format_class source_format)
 120{
 121        bool ret_val = 0;
 122
 123        if ((source_format == dm_420_12) || (source_format == dm_420_8) || (source_format == dm_420_10) || (source_format == dm_rgbe_alpha))
 124                ret_val = 1;
 125
 126        return ret_val;
 127}
 128
 129static double get_refcyc_per_delivery(
 130                struct display_mode_lib *mode_lib,
 131                double refclk_freq_in_mhz,
 132                double pclk_freq_in_mhz,
 133                unsigned int odm_combine,
 134                unsigned int recout_width,
 135                unsigned int hactive,
 136                double vratio,
 137                double hscale_pixel_rate,
 138                unsigned int delivery_width,
 139                unsigned int req_per_swath_ub)
 140{
 141        double refcyc_per_delivery = 0.0;
 142
 143        if (vratio <= 1.0) {
 144                if (odm_combine)
 145                        refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) ((unsigned int) odm_combine * 2)
 146                                        * dml_min((double) recout_width, (double) hactive / ((unsigned int) odm_combine * 2)) / pclk_freq_in_mhz / (double) req_per_swath_ub;
 147                else
 148                        refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width / pclk_freq_in_mhz / (double) req_per_swath_ub;
 149        } else {
 150                refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width / (double) hscale_pixel_rate / (double) req_per_swath_ub;
 151        }
 152
 153#ifdef __DML_RQ_DLG_CALC_DEBUG__
 154        dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
 155        dml_print("DML_DLG: %s: pclk_freq_in_mhz   = %3.2f\n", __func__, pclk_freq_in_mhz);
 156        dml_print("DML_DLG: %s: recout_width       = %d\n", __func__, recout_width);
 157        dml_print("DML_DLG: %s: vratio             = %3.2f\n", __func__, vratio);
 158        dml_print("DML_DLG: %s: req_per_swath_ub   = %d\n", __func__, req_per_swath_ub);
 159        dml_print("DML_DLG: %s: hscale_pixel_rate  = %3.2f\n", __func__, hscale_pixel_rate);
 160        dml_print("DML_DLG: %s: delivery_width     = %d\n", __func__, delivery_width);
 161        dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery);
 162#endif
 163
 164        return refcyc_per_delivery;
 165
 166}
 167
 168static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size)
 169{
 170        if (tile_size == dm_256k_tile)
 171                return (256 * 1024);
 172        else if (tile_size == dm_64k_tile)
 173                return (64 * 1024);
 174        else
 175                return (4 * 1024);
 176}
 177
 178static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, display_data_rq_regs_st *rq_regs, const display_data_rq_sizing_params_st rq_sizing)
 179{
 180        print__data_rq_sizing_params_st(mode_lib, rq_sizing);
 181
 182        rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
 183
 184        if (rq_sizing.min_chunk_bytes == 0)
 185                rq_regs->min_chunk_size = 0;
 186        else
 187                rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1;
 188
 189        rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10;
 190        if (rq_sizing.min_meta_chunk_bytes == 0)
 191                rq_regs->min_meta_chunk_size = 0;
 192        else
 193                rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1;
 194
 195        rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6;
 196        rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6;
 197}
 198
 199static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_rq_params_st rq_param)
 200{
 201        unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
 202        unsigned int detile_buf_plane1_addr = 0;
 203
 204        extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
 205
 206        rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height), 1) - 3;
 207
 208        if (rq_param.yuv420) {
 209                extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
 210                rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height), 1) - 3;
 211        }
 212
 213        rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
 214        rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
 215
 216        // FIXME: take the max between luma, chroma chunk size?
 217        // okay for now, as we are setting chunk_bytes to 8kb anyways
 218        if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024 || (rq_param.yuv420 && rq_param.sizing.rq_c.chunk_bytes >= 32 * 1024)) { //32kb
 219                rq_regs->drq_expansion_mode = 0;
 220        } else {
 221                rq_regs->drq_expansion_mode = 2;
 222        }
 223        rq_regs->prq_expansion_mode = 1;
 224        rq_regs->mrq_expansion_mode = 1;
 225        rq_regs->crq_expansion_mode = 1;
 226
 227        // Note: detile_buf_plane1_addr is in unit of 1KB
 228        if (rq_param.yuv420) {
 229                if ((double) rq_param.misc.rq_l.stored_swath_bytes / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) {
 230                        detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 1024.0); // half to chroma
 231#ifdef __DML_RQ_DLG_CALC_DEBUG__
 232                                        dml_print("DML_DLG: %s: detile_buf_plane1_addr = %0d (1/2 to chroma)\n", __func__, detile_buf_plane1_addr);
 233#endif
 234                } else {
 235                        detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), 1024, 0) / 1024.0; // 2/3 to luma
 236#ifdef __DML_RQ_DLG_CALC_DEBUG__
 237                                        dml_print("DML_DLG: %s: detile_buf_plane1_addr = %0d (1/3 chroma)\n", __func__, detile_buf_plane1_addr);
 238#endif
 239                }
 240        }
 241        rq_regs->plane1_base_address = detile_buf_plane1_addr;
 242
 243#ifdef __DML_RQ_DLG_CALC_DEBUG__
 244        dml_print("DML_DLG: %s: detile_buf_size_in_bytes = %0d\n", __func__, detile_buf_size_in_bytes);
 245        dml_print("DML_DLG: %s: detile_buf_plane1_addr = %0d\n", __func__, detile_buf_plane1_addr);
 246        dml_print("DML_DLG: %s: plane1_base_address = %0d\n", __func__, rq_regs->plane1_base_address);
 247        dml_print("DML_DLG: %s: rq_l.stored_swath_bytes = %0d\n", __func__, rq_param.misc.rq_l.stored_swath_bytes);
 248        dml_print("DML_DLG: %s: rq_c.stored_swath_bytes = %0d\n", __func__, rq_param.misc.rq_c.stored_swath_bytes);
 249        dml_print("DML_DLG: %s: rq_l.swath_height = %0d\n", __func__, rq_param.dlg.rq_l.swath_height);
 250        dml_print("DML_DLG: %s: rq_c.swath_height = %0d\n", __func__, rq_param.dlg.rq_c.swath_height);
 251#endif
 252}
 253
 254static void handle_det_buf_split(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_source_params_st pipe_src_param)
 255{
 256        unsigned int total_swath_bytes = 0;
 257        unsigned int swath_bytes_l = 0;
 258        unsigned int swath_bytes_c = 0;
 259        unsigned int full_swath_bytes_packed_l = 0;
 260        unsigned int full_swath_bytes_packed_c = 0;
 261        bool req128_l = 0;
 262        bool req128_c = 0;
 263        bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
 264        bool surf_vert = (pipe_src_param.source_scan == dm_vert);
 265        unsigned int log2_swath_height_l = 0;
 266        unsigned int log2_swath_height_c = 0;
 267        unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
 268
 269        full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes;
 270        full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes;
 271
 272#ifdef __DML_RQ_DLG_CALC_DEBUG__
 273        dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n", __func__, full_swath_bytes_packed_l);
 274        dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n", __func__, full_swath_bytes_packed_c);
 275#endif
 276
 277        if (rq_param->yuv420_10bpc) {
 278                full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2.0 / 3.0, 256, 1) + 256;
 279                full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2.0 / 3.0, 256, 1) + 256;
 280#ifdef __DML_RQ_DLG_CALC_DEBUG__
 281                dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d (3-2 packing)\n", __func__, full_swath_bytes_packed_l);
 282                dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d (3-2 packing)\n", __func__, full_swath_bytes_packed_c);
 283#endif
 284        }
 285
 286        if (rq_param->yuv420)
 287                total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c;
 288        else
 289                total_swath_bytes = 2 * full_swath_bytes_packed_l;
 290
 291#ifdef __DML_RQ_DLG_CALC_DEBUG__
 292        dml_print("DML_DLG: %s: total_swath_bytes = %0d\n", __func__, total_swath_bytes);
 293        dml_print("DML_DLG: %s: detile_buf_size_in_bytes = %0d\n", __func__, detile_buf_size_in_bytes);
 294#endif
 295
 296        if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request
 297                req128_l = 0;
 298                req128_c = 0;
 299                swath_bytes_l = full_swath_bytes_packed_l;
 300                swath_bytes_c = full_swath_bytes_packed_c;
 301        } else if (!rq_param->yuv420) {
 302                req128_l = 1;
 303                req128_c = 0;
 304                swath_bytes_c = full_swath_bytes_packed_c;
 305                swath_bytes_l = full_swath_bytes_packed_l / 2;
 306        } else if ((double) full_swath_bytes_packed_l / (double) full_swath_bytes_packed_c < 1.5) {
 307                req128_l = 0;
 308                req128_c = 1;
 309                swath_bytes_l = full_swath_bytes_packed_l;
 310                swath_bytes_c = full_swath_bytes_packed_c / 2;
 311
 312                total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c;
 313
 314                if (total_swath_bytes > detile_buf_size_in_bytes) {
 315                        req128_l = 1;
 316                        swath_bytes_l = full_swath_bytes_packed_l / 2;
 317                }
 318        } else {
 319                req128_l = 1;
 320                req128_c = 0;
 321                swath_bytes_l = full_swath_bytes_packed_l / 2;
 322                swath_bytes_c = full_swath_bytes_packed_c;
 323
 324                total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c;
 325
 326                if (total_swath_bytes > detile_buf_size_in_bytes) {
 327                        req128_c = 1;
 328                        swath_bytes_c = full_swath_bytes_packed_c / 2;
 329                }
 330        }
 331
 332        if (rq_param->yuv420)
 333                total_swath_bytes = 2 * swath_bytes_l + 2 * swath_bytes_c;
 334        else
 335                total_swath_bytes = 2 * swath_bytes_l;
 336
 337        rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l;
 338        rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c;
 339
 340#ifdef __DML_RQ_DLG_CALC_DEBUG__
 341        dml_print("DML_DLG: %s: total_swath_bytes = %0d\n", __func__, total_swath_bytes);
 342        dml_print("DML_DLG: %s: rq_l.stored_swath_bytes = %0d\n", __func__, rq_param->misc.rq_l.stored_swath_bytes);
 343        dml_print("DML_DLG: %s: rq_c.stored_swath_bytes = %0d\n", __func__, rq_param->misc.rq_c.stored_swath_bytes);
 344#endif
 345        if (surf_linear) {
 346                log2_swath_height_l = 0;
 347                log2_swath_height_c = 0;
 348        } else {
 349                unsigned int swath_height_l;
 350                unsigned int swath_height_c;
 351
 352                if (!surf_vert) {
 353                        swath_height_l = rq_param->misc.rq_l.blk256_height;
 354                        swath_height_c = rq_param->misc.rq_c.blk256_height;
 355                } else {
 356                        swath_height_l = rq_param->misc.rq_l.blk256_width;
 357                        swath_height_c = rq_param->misc.rq_c.blk256_width;
 358                }
 359
 360                if (swath_height_l > 0)
 361                        log2_swath_height_l = dml_log2(swath_height_l);
 362
 363                if (req128_l && log2_swath_height_l > 0)
 364                        log2_swath_height_l -= 1;
 365
 366                if (swath_height_c > 0)
 367                        log2_swath_height_c = dml_log2(swath_height_c);
 368
 369                if (req128_c && log2_swath_height_c > 0)
 370                        log2_swath_height_c -= 1;
 371        }
 372
 373        rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
 374        rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
 375
 376#ifdef __DML_RQ_DLG_CALC_DEBUG__
 377        dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l);
 378        dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c);
 379        dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n", __func__, full_swath_bytes_packed_l);
 380        dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n", __func__, full_swath_bytes_packed_c);
 381        dml_print("DML_DLG: %s: swath_height luma = %0d\n", __func__, rq_param->dlg.rq_l.swath_height);
 382        dml_print("DML_DLG: %s: swath_height chroma = %0d\n", __func__, rq_param->dlg.rq_c.swath_height);
 383#endif
 384}
 385
 386static void get_meta_and_pte_attr(
 387                struct display_mode_lib *mode_lib,
 388                display_data_rq_dlg_params_st *rq_dlg_param,
 389                display_data_rq_misc_params_st *rq_misc_param,
 390                display_data_rq_sizing_params_st *rq_sizing_param,
 391                unsigned int vp_width,
 392                unsigned int vp_height,
 393                unsigned int data_pitch,
 394                unsigned int meta_pitch,
 395                unsigned int source_format,
 396                unsigned int tiling,
 397                unsigned int macro_tile_size,
 398                unsigned int source_scan,
 399                unsigned int hostvm_enable,
 400                unsigned int is_chroma,
 401                unsigned int surface_height)
 402{
 403        bool surf_linear = (tiling == dm_sw_linear);
 404        bool surf_vert = (source_scan == dm_vert);
 405
 406        unsigned int bytes_per_element;
 407        unsigned int bytes_per_element_y;
 408        unsigned int bytes_per_element_c;
 409
 410        unsigned int blk256_width = 0;
 411        unsigned int blk256_height = 0;
 412
 413        unsigned int blk256_width_y = 0;
 414        unsigned int blk256_height_y = 0;
 415        unsigned int blk256_width_c = 0;
 416        unsigned int blk256_height_c = 0;
 417        unsigned int log2_bytes_per_element;
 418        unsigned int log2_blk256_width;
 419        unsigned int log2_blk256_height;
 420        unsigned int blk_bytes;
 421        unsigned int log2_blk_bytes;
 422        unsigned int log2_blk_height;
 423        unsigned int log2_blk_width;
 424        unsigned int log2_meta_req_bytes;
 425        unsigned int log2_meta_req_height;
 426        unsigned int log2_meta_req_width;
 427        unsigned int meta_req_width;
 428        unsigned int meta_req_height;
 429        unsigned int log2_meta_row_height;
 430        unsigned int meta_row_width_ub;
 431        unsigned int log2_meta_chunk_bytes;
 432        unsigned int log2_meta_chunk_height;
 433
 434        //full sized meta chunk width in unit of data elements
 435        unsigned int log2_meta_chunk_width;
 436        unsigned int log2_min_meta_chunk_bytes;
 437        unsigned int min_meta_chunk_width;
 438        unsigned int meta_chunk_width;
 439        unsigned int meta_chunk_per_row_int;
 440        unsigned int meta_row_remainder;
 441        unsigned int meta_chunk_threshold;
 442        unsigned int meta_blk_height;
 443        unsigned int meta_surface_bytes;
 444        unsigned int vmpg_bytes;
 445        unsigned int meta_pte_req_per_frame_ub;
 446        unsigned int meta_pte_bytes_per_frame_ub;
 447        const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.gpuvm_min_page_size_bytes);
 448        const bool dual_plane_en = is_dual_plane((enum source_format_class) (source_format));
 449        const unsigned int dpte_buf_in_pte_reqs =
 450                        dual_plane_en ? (is_chroma ? mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma : mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma) : (mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma
 451                                                        + mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma);
 452
 453        unsigned int log2_vmpg_height = 0;
 454        unsigned int log2_vmpg_width = 0;
 455        unsigned int log2_dpte_req_height_ptes = 0;
 456        unsigned int log2_dpte_req_height = 0;
 457        unsigned int log2_dpte_req_width = 0;
 458        unsigned int log2_dpte_row_height_linear = 0;
 459        unsigned int log2_dpte_row_height = 0;
 460        unsigned int log2_dpte_group_width = 0;
 461        unsigned int dpte_row_width_ub = 0;
 462        unsigned int dpte_req_height = 0;
 463        unsigned int dpte_req_width = 0;
 464        unsigned int dpte_group_width = 0;
 465        unsigned int log2_dpte_group_bytes = 0;
 466        unsigned int log2_dpte_group_length = 0;
 467        double byte_per_pixel_det_y;
 468        double byte_per_pixel_det_c;
 469
 470        CalculateBytePerPixelAnd256BBlockSizes(
 471                        (enum source_format_class) (source_format),
 472                        (enum dm_swizzle_mode) (tiling),
 473                        &bytes_per_element_y,
 474                        &bytes_per_element_c,
 475                        &byte_per_pixel_det_y,
 476                        &byte_per_pixel_det_c,
 477                        &blk256_height_y,
 478                        &blk256_height_c,
 479                        &blk256_width_y,
 480                        &blk256_width_c);
 481
 482        if (!is_chroma) {
 483                blk256_width = blk256_width_y;
 484                blk256_height = blk256_height_y;
 485                bytes_per_element = bytes_per_element_y;
 486        } else {
 487                blk256_width = blk256_width_c;
 488                blk256_height = blk256_height_c;
 489                bytes_per_element = bytes_per_element_c;
 490        }
 491
 492        log2_bytes_per_element = dml_log2(bytes_per_element);
 493
 494        dml_print("DML_DLG: %s: surf_linear        = %d\n", __func__, surf_linear);
 495        dml_print("DML_DLG: %s: surf_vert          = %d\n", __func__, surf_vert);
 496        dml_print("DML_DLG: %s: blk256_width       = %d\n", __func__, blk256_width);
 497        dml_print("DML_DLG: %s: blk256_height      = %d\n", __func__, blk256_height);
 498
 499        log2_blk256_width = dml_log2((double) blk256_width);
 500        log2_blk256_height = dml_log2((double) blk256_height);
 501        blk_bytes = surf_linear ? 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
 502        log2_blk_bytes = dml_log2((double) blk_bytes);
 503        log2_blk_height = 0;
 504        log2_blk_width = 0;
 505
 506        // remember log rule
 507        // "+" in log is multiply
 508        // "-" in log is divide
 509        // "/2" is like square root
 510        // blk is vertical biased
 511        if (tiling != dm_sw_linear)
 512                log2_blk_height = log2_blk256_height + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
 513        else
 514                log2_blk_height = 0;    // blk height of 1
 515
 516        log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
 517
 518        if (!surf_vert) {
 519                int unsigned temp;
 520
 521                temp = dml_round_to_multiple(vp_width - 1, blk256_width, 1) + blk256_width;
 522                if (data_pitch < blk256_width) {
 523                        dml_print("WARNING: DML_DLG: %s: swath_size calculation ignoring data_pitch=%u < blk256_width=%u\n", __func__, data_pitch, blk256_width);
 524                } else {
 525                        if (temp > data_pitch) {
 526                                if (data_pitch >= vp_width)
 527                                        temp = data_pitch;
 528                                else
 529                                        dml_print("WARNING: DML_DLG: %s: swath_size calculation ignoring data_pitch=%u < vp_width=%u\n", __func__, data_pitch, vp_width);
 530                        }
 531                }
 532                rq_dlg_param->swath_width_ub = temp;
 533                rq_dlg_param->req_per_swath_ub = temp >> log2_blk256_width;
 534        } else {
 535                int unsigned temp;
 536
 537                temp = dml_round_to_multiple(vp_height - 1, blk256_height, 1) + blk256_height;
 538                if (surface_height < blk256_height) {
 539                        dml_print("WARNING: DML_DLG: %s swath_size calculation ignored surface_height=%u < blk256_height=%u\n", __func__, surface_height, blk256_height);
 540                } else {
 541                        if (temp > surface_height) {
 542                                if (surface_height >= vp_height)
 543                                        temp = surface_height;
 544                                else
 545                                        dml_print("WARNING: DML_DLG: %s swath_size calculation ignored surface_height=%u < vp_height=%u\n", __func__, surface_height, vp_height);
 546                        }
 547                }
 548                rq_dlg_param->swath_width_ub = temp;
 549                rq_dlg_param->req_per_swath_ub = temp >> log2_blk256_height;
 550        }
 551
 552        if (!surf_vert)
 553                rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height * bytes_per_element;
 554        else
 555                rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width * bytes_per_element;
 556
 557        rq_misc_param->blk256_height = blk256_height;
 558        rq_misc_param->blk256_width = blk256_width;
 559
 560        // -------
 561        // meta
 562        // -------
 563        log2_meta_req_bytes = 6;        // meta request is 64b and is 8x8byte meta element
 564
 565        // each 64b meta request for dcn is 8x8 meta elements and
 566        // a meta element covers one 256b block of the data surface.
 567        log2_meta_req_height = log2_blk256_height + 3;  // meta req is 8x8 byte, each byte represent 1 blk256
 568        log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element - log2_meta_req_height;
 569        meta_req_width = 1 << log2_meta_req_width;
 570        meta_req_height = 1 << log2_meta_req_height;
 571        log2_meta_row_height = 0;
 572        meta_row_width_ub = 0;
 573
 574        // the dimensions of a meta row are meta_row_width x meta_row_height in elements.
 575        // calculate upper bound of the meta_row_width
 576        if (!surf_vert) {
 577                log2_meta_row_height = log2_meta_req_height;
 578                meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1) + meta_req_width;
 579                rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width;
 580        } else {
 581                log2_meta_row_height = log2_meta_req_width;
 582                meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1) + meta_req_height;
 583                rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height;
 584        }
 585        rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
 586
 587        rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
 588
 589        log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
 590        log2_meta_chunk_height = log2_meta_row_height;
 591
 592        //full sized meta chunk width in unit of data elements
 593        log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element - log2_meta_chunk_height;
 594        log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes);
 595        min_meta_chunk_width = 1 << (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element - log2_meta_chunk_height);
 596        meta_chunk_width = 1 << log2_meta_chunk_width;
 597        meta_chunk_per_row_int = (unsigned int) (meta_row_width_ub / meta_chunk_width);
 598        meta_row_remainder = meta_row_width_ub % meta_chunk_width;
 599        meta_chunk_threshold = 0;
 600        meta_blk_height = blk256_height * 64;
 601        meta_surface_bytes = meta_pitch * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height) * bytes_per_element / 256;
 602        vmpg_bytes = mode_lib->soc.gpuvm_min_page_size_bytes;
 603        meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes, 8 * vmpg_bytes, 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes);
 604        meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64;   //64B mpte request
 605        rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub;
 606
 607        dml_print("DML_DLG: %s: meta_blk_height             = %d\n", __func__, meta_blk_height);
 608        dml_print("DML_DLG: %s: meta_surface_bytes          = %d\n", __func__, meta_surface_bytes);
 609        dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub   = %d\n", __func__, meta_pte_req_per_frame_ub);
 610        dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n", __func__, meta_pte_bytes_per_frame_ub);
 611
 612        if (!surf_vert)
 613                meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
 614        else
 615                meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height;
 616
 617        if (meta_row_remainder <= meta_chunk_threshold)
 618                rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
 619        else
 620                rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
 621
 622        // ------
 623        // dpte
 624        // ------
 625        if (surf_linear) {
 626                log2_vmpg_height = 0;   // one line high
 627        } else {
 628                log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
 629        }
 630        log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
 631
 632        // only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4.
 633        if (surf_linear) { //one 64B PTE request returns 8 PTEs
 634                log2_dpte_req_height_ptes = 0;
 635                log2_dpte_req_width = log2_vmpg_width + 3;
 636                log2_dpte_req_height = 0;
 637        } else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size
 638                //one 64B req gives 8x1 PTEs for 4KB tile
 639                log2_dpte_req_height_ptes = 0;
 640                log2_dpte_req_width = log2_blk_width + 3;
 641                log2_dpte_req_height = log2_blk_height + 0;
 642        } else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB
 643                //two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB
 644                log2_dpte_req_height_ptes = 4;
 645                log2_dpte_req_width = log2_blk256_width + 4;            // log2_64KB_width
 646                log2_dpte_req_height = log2_blk256_height + 4;          // log2_64KB_height
 647        } else { //64KB page size and must 64KB tile block
 648                 //one 64B req gives 8x1 PTEs for 64KB tile
 649                log2_dpte_req_height_ptes = 0;
 650                log2_dpte_req_width = log2_blk_width + 3;
 651                log2_dpte_req_height = log2_blk_height + 0;
 652        }
 653
 654        // The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
 655        // log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
 656        // That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
 657        //log2_dpte_req_height    = log2_vmpg_height + log2_dpte_req_height_ptes;
 658        //log2_dpte_req_width     = log2_vmpg_width + log2_dpte_req_width_ptes;
 659        dpte_req_height = 1 << log2_dpte_req_height;
 660        dpte_req_width = 1 << log2_dpte_req_width;
 661
 662        // calculate pitch dpte row buffer can hold
 663        // round the result down to a power of two.
 664        if (surf_linear) {
 665                unsigned int dpte_row_height;
 666
 667                log2_dpte_row_height_linear = dml_floor(dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch), 1);
 668
 669                dml_print("DML_DLG: %s: is_chroma                   = %d\n", __func__, is_chroma);
 670                dml_print("DML_DLG: %s: dpte_buf_in_pte_reqs        = %d\n", __func__, dpte_buf_in_pte_reqs);
 671                dml_print("DML_DLG: %s: log2_dpte_row_height_linear = %d\n", __func__, log2_dpte_row_height_linear);
 672
 673                ASSERT(log2_dpte_row_height_linear >= 3);
 674
 675                if (log2_dpte_row_height_linear > 7)
 676                        log2_dpte_row_height_linear = 7;
 677
 678                log2_dpte_row_height = log2_dpte_row_height_linear;
 679                // For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
 680                // the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
 681                dpte_row_height = 1 << log2_dpte_row_height;
 682                dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1, dpte_req_width, 1) + dpte_req_width;
 683                rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
 684        } else {
 685                // the upper bound of the dpte_row_width without dependency on viewport position follows.
 686                // for tiled mode, row height is the same as req height and row store up to vp size upper bound
 687                if (!surf_vert) {
 688                        log2_dpte_row_height = log2_dpte_req_height;
 689                        dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1) + dpte_req_width;
 690                        rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
 691                } else {
 692                        log2_dpte_row_height = (log2_blk_width < log2_dpte_req_width) ? log2_blk_width : log2_dpte_req_width;
 693                        dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1) + dpte_req_height;
 694                        rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height;
 695                }
 696        }
 697        if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB
 698                rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request
 699        else
 700                rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request
 701
 702        rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
 703
 704        // the dpte_group_bytes is reduced for the specific case of vertical
 705        // access of a tile surface that has dpte request of 8x1 ptes.
 706        if (hostvm_enable)
 707                rq_sizing_param->dpte_group_bytes = 512;
 708        else {
 709                if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group
 710                        rq_sizing_param->dpte_group_bytes = 512;
 711                else
 712                        rq_sizing_param->dpte_group_bytes = 2048;
 713        }
 714
 715        //since pte request size is 64byte, the number of data pte requests per full sized group is as follows.
 716        log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes);
 717        log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests
 718
 719        // full sized data pte group width in elements
 720        if (!surf_vert)
 721                log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
 722        else
 723                log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
 724
 725        //But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B
 726        if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB
 727                log2_dpte_group_width = log2_dpte_group_width - 1;
 728
 729        dpte_group_width = 1 << log2_dpte_group_width;
 730
 731        // since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
 732        // the upper bound for the dpte groups per row is as follows.
 733        rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width, 1);
 734}
 735
 736static void get_surf_rq_param(
 737                struct display_mode_lib *mode_lib,
 738                display_data_rq_sizing_params_st *rq_sizing_param,
 739                display_data_rq_dlg_params_st *rq_dlg_param,
 740                display_data_rq_misc_params_st *rq_misc_param,
 741                const display_pipe_params_st pipe_param,
 742                bool is_chroma,
 743                bool is_alpha)
 744{
 745        bool mode_422 = 0;
 746        unsigned int vp_width = 0;
 747        unsigned int vp_height = 0;
 748        unsigned int data_pitch = 0;
 749        unsigned int meta_pitch = 0;
 750        unsigned int surface_height = 0;
 751        unsigned int ppe = mode_422 ? 2 : 1;
 752
 753        // FIXME check if ppe apply for both luma and chroma in 422 case
 754        if (is_chroma | is_alpha) {
 755                vp_width = pipe_param.src.viewport_width_c / ppe;
 756                vp_height = pipe_param.src.viewport_height_c;
 757                data_pitch = pipe_param.src.data_pitch_c;
 758                meta_pitch = pipe_param.src.meta_pitch_c;
 759                surface_height = pipe_param.src.surface_height_y / 2.0;
 760        } else {
 761                vp_width = pipe_param.src.viewport_width / ppe;
 762                vp_height = pipe_param.src.viewport_height;
 763                data_pitch = pipe_param.src.data_pitch;
 764                meta_pitch = pipe_param.src.meta_pitch;
 765                surface_height = pipe_param.src.surface_height_y;
 766        }
 767
 768        if (pipe_param.dest.odm_combine) {
 769                unsigned int access_dir;
 770                unsigned int full_src_vp_width;
 771                unsigned int hactive_odm;
 772                unsigned int src_hactive_odm;
 773
 774                access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
 775                hactive_odm = pipe_param.dest.hactive / ((unsigned int) pipe_param.dest.odm_combine * 2);
 776                if (is_chroma) {
 777                        full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width;
 778                        src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_odm;
 779                } else {
 780                        full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width;
 781                        src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio * hactive_odm;
 782                }
 783
 784                if (access_dir == 0) {
 785                        vp_width = dml_min(full_src_vp_width, src_hactive_odm);
 786                        dml_print("DML_DLG: %s: vp_width = %d\n", __func__, vp_width);
 787                } else {
 788                        vp_height = dml_min(full_src_vp_width, src_hactive_odm);
 789                        dml_print("DML_DLG: %s: vp_height = %d\n", __func__, vp_height);
 790
 791                }
 792                dml_print("DML_DLG: %s: full_src_vp_width = %d\n", __func__, full_src_vp_width);
 793                dml_print("DML_DLG: %s: hactive_odm = %d\n", __func__, hactive_odm);
 794                dml_print("DML_DLG: %s: src_hactive_odm = %d\n", __func__, src_hactive_odm);
 795        }
 796
 797        rq_sizing_param->chunk_bytes = 8192;
 798
 799        if (is_alpha) {
 800                rq_sizing_param->chunk_bytes = 4096;
 801        }
 802
 803        if (rq_sizing_param->chunk_bytes == 64 * 1024)
 804                rq_sizing_param->min_chunk_bytes = 0;
 805        else
 806                rq_sizing_param->min_chunk_bytes = 1024;
 807
 808        rq_sizing_param->meta_chunk_bytes = 2048;
 809        rq_sizing_param->min_meta_chunk_bytes = 256;
 810
 811        if (pipe_param.src.hostvm)
 812                rq_sizing_param->mpte_group_bytes = 512;
 813        else
 814                rq_sizing_param->mpte_group_bytes = 2048;
 815
 816        get_meta_and_pte_attr(
 817                        mode_lib,
 818                        rq_dlg_param,
 819                        rq_misc_param,
 820                        rq_sizing_param,
 821                        vp_width,
 822                        vp_height,
 823                        data_pitch,
 824                        meta_pitch,
 825                        pipe_param.src.source_format,
 826                        pipe_param.src.sw_mode,
 827                        pipe_param.src.macro_tile_size,
 828                        pipe_param.src.source_scan,
 829                        pipe_param.src.hostvm,
 830                        is_chroma,
 831                        surface_height);
 832}
 833
 834static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_params_st pipe_param)
 835{
 836        // get param for luma surface
 837        rq_param->yuv420 = pipe_param.src.source_format == dm_420_8 || pipe_param.src.source_format == dm_420_10 || pipe_param.src.source_format == dm_rgbe_alpha
 838                        || pipe_param.src.source_format == dm_420_12;
 839
 840        rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10;
 841
 842        rq_param->rgbe_alpha = (pipe_param.src.source_format == dm_rgbe_alpha) ? 1 : 0;
 843
 844        get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_l), &(rq_param->dlg.rq_l), &(rq_param->misc.rq_l), pipe_param, 0, 0);
 845
 846        if (is_dual_plane((enum source_format_class) (pipe_param.src.source_format))) {
 847                // get param for chroma surface
 848                get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_c), &(rq_param->dlg.rq_c), &(rq_param->misc.rq_c), pipe_param, 1, rq_param->rgbe_alpha);
 849        }
 850
 851        // calculate how to split the det buffer space between luma and chroma
 852        handle_det_buf_split(mode_lib, rq_param, pipe_param.src);
 853        print__rq_params_st(mode_lib, *rq_param);
 854}
 855
 856void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_pipe_params_st pipe_param)
 857{
 858        display_rq_params_st rq_param = {0};
 859
 860        memset(rq_regs, 0, sizeof(*rq_regs));
 861        dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param);
 862        extract_rq_regs(mode_lib, rq_regs, rq_param);
 863
 864        print__rq_regs_st(mode_lib, *rq_regs);
 865}
 866
 867static void calculate_ttu_cursor(
 868                struct display_mode_lib *mode_lib,
 869                double *refcyc_per_req_delivery_pre_cur,
 870                double *refcyc_per_req_delivery_cur,
 871                double refclk_freq_in_mhz,
 872                double ref_freq_to_pix_freq,
 873                double hscale_pixel_rate_l,
 874                double hscl_ratio,
 875                double vratio_pre_l,
 876                double vratio_l,
 877                unsigned int cur_width,
 878                enum cursor_bpp cur_bpp)
 879{
 880        unsigned int cur_src_width = cur_width;
 881        unsigned int cur_req_size = 0;
 882        unsigned int cur_req_width = 0;
 883        double cur_width_ub = 0.0;
 884        double cur_req_per_width = 0.0;
 885        double hactive_cur = 0.0;
 886
 887        ASSERT(cur_src_width <= 256);
 888
 889        *refcyc_per_req_delivery_pre_cur = 0.0;
 890        *refcyc_per_req_delivery_cur = 0.0;
 891        if (cur_src_width > 0) {
 892                unsigned int cur_bit_per_pixel = 0;
 893
 894                if (cur_bpp == dm_cur_2bit) {
 895                        cur_req_size = 64; // byte
 896                        cur_bit_per_pixel = 2;
 897                } else { // 32bit
 898                        cur_bit_per_pixel = 32;
 899                        if (cur_src_width >= 1 && cur_src_width <= 16)
 900                                cur_req_size = 64;
 901                        else if (cur_src_width >= 17 && cur_src_width <= 31)
 902                                cur_req_size = 128;
 903                        else
 904                                cur_req_size = 256;
 905                }
 906
 907                cur_req_width = (double) cur_req_size / ((double) cur_bit_per_pixel / 8.0);
 908                cur_width_ub = dml_ceil((double) cur_src_width / (double) cur_req_width, 1) * (double) cur_req_width;
 909                cur_req_per_width = cur_width_ub / (double) cur_req_width;
 910                hactive_cur = (double) cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor
 911
 912                if (vratio_pre_l <= 1.0) {
 913                        *refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq / (double) cur_req_per_width;
 914                } else {
 915                        *refcyc_per_req_delivery_pre_cur = (double) refclk_freq_in_mhz * (double) cur_src_width / hscale_pixel_rate_l / (double) cur_req_per_width;
 916                }
 917
 918                ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13));
 919
 920                if (vratio_l <= 1.0) {
 921                        *refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq / (double) cur_req_per_width;
 922                } else {
 923                        *refcyc_per_req_delivery_cur = (double) refclk_freq_in_mhz * (double) cur_src_width / hscale_pixel_rate_l / (double) cur_req_per_width;
 924                }
 925
 926                dml_print("DML_DLG: %s: cur_req_width                     = %d\n", __func__, cur_req_width);
 927                dml_print("DML_DLG: %s: cur_width_ub                      = %3.2f\n", __func__, cur_width_ub);
 928                dml_print("DML_DLG: %s: cur_req_per_width                 = %3.2f\n", __func__, cur_req_per_width);
 929                dml_print("DML_DLG: %s: hactive_cur                       = %3.2f\n", __func__, hactive_cur);
 930                dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur   = %3.2f\n", __func__, *refcyc_per_req_delivery_pre_cur);
 931                dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur       = %3.2f\n", __func__, *refcyc_per_req_delivery_cur);
 932
 933                ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
 934        }
 935}
 936
 937// Note: currently taken in as is.
 938// Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
 939static void dml_rq_dlg_get_dlg_params(
 940                struct display_mode_lib *mode_lib,
 941                const display_e2e_pipe_params_st *e2e_pipe_param,
 942                const unsigned int num_pipes,
 943                const unsigned int pipe_idx,
 944                display_dlg_regs_st *disp_dlg_regs,
 945                display_ttu_regs_st *disp_ttu_regs,
 946                const display_rq_dlg_params_st rq_dlg_param,
 947                const display_dlg_sys_params_st dlg_sys_param,
 948                const bool cstate_en,
 949                const bool pstate_en,
 950                const bool vm_en,
 951                const bool ignore_viewport_pos,
 952                const bool immediate_flip_support)
 953{
 954        const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
 955        const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest;
 956        const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout;
 957        const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg;
 958        const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth;
 959        const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps;
 960        unsigned int pipe_index_in_combine[DC__NUM_PIPES__MAX];
 961
 962        // -------------------------
 963        // Section 1.15.2.1: OTG dependent Params
 964        // -------------------------
 965        // Timing
 966        unsigned int htotal = dst->htotal;
 967        unsigned int hblank_end = dst->hblank_end;
 968        unsigned int vblank_start = dst->vblank_start;
 969        unsigned int vblank_end = dst->vblank_end;
 970
 971        double dppclk_freq_in_mhz = clks->dppclk_mhz;
 972        double refclk_freq_in_mhz = clks->refclk_mhz;
 973        double pclk_freq_in_mhz = dst->pixel_rate_mhz;
 974        bool interlaced = dst->interlaced;
 975        double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
 976        double min_ttu_vblank;
 977        unsigned int dlg_vblank_start;
 978        bool dual_plane;
 979        bool mode_422;
 980        unsigned int access_dir;
 981        unsigned int vp_height_l;
 982        unsigned int vp_width_l;
 983        unsigned int vp_height_c;
 984        unsigned int vp_width_c;
 985
 986        // Scaling
 987        unsigned int htaps_l;
 988        unsigned int htaps_c;
 989        double hratio_l;
 990        double hratio_c;
 991        double vratio_l;
 992        double vratio_c;
 993        bool scl_enable;
 994
 995        unsigned int swath_width_ub_l;
 996        unsigned int dpte_groups_per_row_ub_l;
 997        unsigned int swath_width_ub_c;
 998        unsigned int dpte_groups_per_row_ub_c;
 999
1000        unsigned int meta_chunks_per_row_ub_l;
1001        unsigned int meta_chunks_per_row_ub_c;
1002        unsigned int vupdate_offset;
1003        unsigned int vupdate_width;
1004        unsigned int vready_offset;
1005
1006        unsigned int dppclk_delay_subtotal;
1007        unsigned int dispclk_delay_subtotal;
1008
1009        unsigned int vstartup_start;
1010        unsigned int dst_x_after_scaler;
1011        unsigned int dst_y_after_scaler;
1012        double dst_y_prefetch;
1013        double dst_y_per_vm_vblank;
1014        double dst_y_per_row_vblank;
1015        double dst_y_per_vm_flip;
1016        double dst_y_per_row_flip;
1017        double max_dst_y_per_vm_vblank;
1018        double max_dst_y_per_row_vblank;
1019        double vratio_pre_l;
1020        double vratio_pre_c;
1021        unsigned int req_per_swath_ub_l;
1022        unsigned int req_per_swath_ub_c;
1023        unsigned int meta_row_height_l;
1024        unsigned int meta_row_height_c;
1025        unsigned int swath_width_pixels_ub_l;
1026        unsigned int swath_width_pixels_ub_c;
1027        unsigned int scaler_rec_in_width_l;
1028        unsigned int scaler_rec_in_width_c;
1029        unsigned int dpte_row_height_l;
1030        unsigned int dpte_row_height_c;
1031        double hscale_pixel_rate_l;
1032        double hscale_pixel_rate_c;
1033        double min_hratio_fact_l;
1034        double min_hratio_fact_c;
1035        double refcyc_per_line_delivery_pre_l;
1036        double refcyc_per_line_delivery_pre_c;
1037        double refcyc_per_line_delivery_l;
1038        double refcyc_per_line_delivery_c;
1039
1040        double refcyc_per_req_delivery_pre_l;
1041        double refcyc_per_req_delivery_pre_c;
1042        double refcyc_per_req_delivery_l;
1043        double refcyc_per_req_delivery_c;
1044
1045        unsigned int full_recout_width;
1046        double refcyc_per_req_delivery_pre_cur0;
1047        double refcyc_per_req_delivery_cur0;
1048        double refcyc_per_req_delivery_pre_cur1;
1049        double refcyc_per_req_delivery_cur1;
1050        int unsigned vba__min_dst_y_next_start = get_min_dst_y_next_start(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // FROM VBA
1051        int unsigned vba__vready_after_vcount0 = get_vready_at_or_after_vsync(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
1052
1053        float vba__refcyc_per_line_delivery_pre_l = get_refcyc_per_line_delivery_pre_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1054        float vba__refcyc_per_line_delivery_l = get_refcyc_per_line_delivery_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1055
1056        float vba__refcyc_per_req_delivery_pre_l = get_refcyc_per_req_delivery_pre_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;  // From VBA
1057        float vba__refcyc_per_req_delivery_l = get_refcyc_per_req_delivery_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;  // From VBA
1058
1059        memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
1060        memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
1061
1062        dml_print("DML_DLG: %s: cstate_en = %d\n", __func__, cstate_en);
1063        dml_print("DML_DLG: %s: pstate_en = %d\n", __func__, pstate_en);
1064        dml_print("DML_DLG: %s: vm_en     = %d\n", __func__, vm_en);
1065        dml_print("DML_DLG: %s: ignore_viewport_pos  = %d\n", __func__, ignore_viewport_pos);
1066        dml_print("DML_DLG: %s: immediate_flip_support  = %d\n", __func__, immediate_flip_support);
1067
1068        dml_print("DML_DLG: %s: dppclk_freq_in_mhz     = %3.2f\n", __func__, dppclk_freq_in_mhz);
1069        dml_print("DML_DLG: %s: refclk_freq_in_mhz     = %3.2f\n", __func__, refclk_freq_in_mhz);
1070        dml_print("DML_DLG: %s: pclk_freq_in_mhz       = %3.2f\n", __func__, pclk_freq_in_mhz);
1071        dml_print("DML_DLG: %s: interlaced             = %d\n", __func__, interlaced); ASSERT(ref_freq_to_pix_freq < 4.0);
1072
1073        disp_dlg_regs->ref_freq_to_pix_freq = (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
1074        disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal * dml_pow(2, 8));
1075        disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end;     // 15 bits
1076
1077        //set_prefetch_mode(mode_lib, cstate_en, pstate_en, ignore_viewport_pos, immediate_flip_support);
1078        min_ttu_vblank = get_min_ttu_vblank_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);       // From VBA
1079
1080        dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
1081
1082        disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start) * dml_pow(2, 2));
1083        ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int)dml_pow(2, 18));
1084
1085        dml_print("DML_DLG: %s: min_ttu_vblank (us)         = %3.2f\n", __func__, min_ttu_vblank);
1086        dml_print("DML_DLG: %s: min_dst_y_next_start        = 0x%0x\n", __func__, disp_dlg_regs->min_dst_y_next_start);
1087        dml_print("DML_DLG: %s: dlg_vblank_start            = 0x%0x\n", __func__, dlg_vblank_start);
1088        dml_print("DML_DLG: %s: ref_freq_to_pix_freq        = %3.2f\n", __func__, ref_freq_to_pix_freq);
1089        dml_print("DML_DLG: %s: vba__min_dst_y_next_start   = 0x%0x\n", __func__, vba__min_dst_y_next_start);
1090
1091        //old_impl_vs_vba_impl("min_dst_y_next_start", dlg_vblank_start, vba__min_dst_y_next_start);
1092
1093        // -------------------------
1094        // Section 1.15.2.2: Prefetch, Active and TTU
1095        // -------------------------
1096        // Prefetch Calc
1097        // Source
1098        dual_plane = is_dual_plane((enum source_format_class) (src->source_format));
1099        mode_422 = 0;
1100        access_dir = (src->source_scan == dm_vert);     // vp access direction: horizontal or vertical accessed
1101        vp_height_l = src->viewport_height;
1102        vp_width_l = src->viewport_width;
1103        vp_height_c = src->viewport_height_c;
1104        vp_width_c = src->viewport_width_c;
1105
1106        // Scaling
1107        htaps_l = taps->htaps;
1108        htaps_c = taps->htaps_c;
1109        hratio_l = scl->hscl_ratio;
1110        hratio_c = scl->hscl_ratio_c;
1111        vratio_l = scl->vscl_ratio;
1112        vratio_c = scl->vscl_ratio_c;
1113        scl_enable = scl->scl_enable;
1114
1115        swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
1116        dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
1117        swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
1118        dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub;
1119
1120        meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub;
1121        meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub;
1122        vupdate_offset = dst->vupdate_offset;
1123        vupdate_width = dst->vupdate_width;
1124        vready_offset = dst->vready_offset;
1125
1126        dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
1127        dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
1128
1129        if (scl_enable)
1130                dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl;
1131        else
1132                dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only;
1133
1134        dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor;
1135
1136        if (dout->dsc_enable) {
1137                double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // FROM VBA
1138                dispclk_delay_subtotal += dsc_delay;
1139        }
1140
1141        vstartup_start = dst->vstartup_start;
1142        if (interlaced) {
1143                if (vstartup_start / 2.0 - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal <= vblank_end / 2.0)
1144                        disp_dlg_regs->vready_after_vcount0 = 1;
1145                else
1146                        disp_dlg_regs->vready_after_vcount0 = 0;
1147        } else {
1148                if (vstartup_start - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal <= vblank_end)
1149                        disp_dlg_regs->vready_after_vcount0 = 1;
1150                else
1151                        disp_dlg_regs->vready_after_vcount0 = 0;
1152        }
1153
1154        dml_print("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, disp_dlg_regs->vready_after_vcount0);
1155        dml_print("DML_DLG: %s: vba__vready_after_vcount0 = %d\n", __func__, vba__vready_after_vcount0);
1156        //old_impl_vs_vba_impl("vready_after_vcount0", disp_dlg_regs->vready_after_vcount0, vba__vready_after_vcount0);
1157
1158        if (interlaced)
1159                vstartup_start = vstartup_start / 2;
1160
1161        dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
1162        dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); // From VBA
1163
1164        // do some adjustment on the dst_after scaler to account for odm combine mode
1165        dml_print("DML_DLG: %s: input dst_x_after_scaler   = %d\n", __func__, dst_x_after_scaler);
1166        dml_print("DML_DLG: %s: input dst_y_after_scaler   = %d\n", __func__, dst_y_after_scaler);
1167
1168        // need to figure out which side of odm combine we're in
1169        if (dst->odm_combine) {
1170                // figure out which pipes go together
1171                bool visited[DC__NUM_PIPES__MAX];
1172                unsigned int i, j, k;
1173
1174                for (k = 0; k < num_pipes; ++k) {
1175                        visited[k] = false;
1176                        pipe_index_in_combine[k] = 0;
1177                }
1178
1179                for (i = 0; i < num_pipes; i++) {
1180                        if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) {
1181
1182                                unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp;
1183                                unsigned int grp_idx = 0;
1184
1185                                for (j = i; j < num_pipes; j++) {
1186                                        if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp && e2e_pipe_param[j].pipe.src.is_hsplit && !visited[j]) {
1187                                                pipe_index_in_combine[j] = grp_idx;
1188                                                dml_print("DML_DLG: %s: pipe[%d] is in grp %d idx %d\n", __func__, j, grp, grp_idx);
1189                                                grp_idx++;
1190                                                visited[j] = true;
1191                                        }
1192                                }
1193                        }
1194                }
1195
1196        }
1197
1198        if (dst->odm_combine == dm_odm_combine_mode_disabled) {
1199                disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end * ref_freq_to_pix_freq);
1200        } else {
1201                unsigned int odm_combine_factor = (dst->odm_combine == dm_odm_combine_mode_2to1 ? 2 : 4); // TODO: We should really check that 4to1 is supported before setting it to 4
1202                unsigned int odm_pipe_index = pipe_index_in_combine[pipe_idx];
1203                disp_dlg_regs->refcyc_h_blank_end = (unsigned int) (((double) hblank_end + odm_pipe_index * (double) dst->hactive / odm_combine_factor) * ref_freq_to_pix_freq);
1204        } ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int)dml_pow(2, 13));
1205
1206        dml_print("DML_DLG: %s: htotal                     = %d\n", __func__, htotal);
1207        dml_print("DML_DLG: %s: dst_x_after_scaler[%d]     = %d\n", __func__, pipe_idx, dst_x_after_scaler);
1208        dml_print("DML_DLG: %s: dst_y_after_scaler[%d]     = %d\n", __func__, pipe_idx, dst_y_after_scaler);
1209
1210        dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);        // From VBA
1211        dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);        // From VBA
1212        dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);        // From VBA
1213        dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);        // From VBA
1214        dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);        // From VBA
1215
1216        max_dst_y_per_vm_vblank = 32.0;        //U5.2
1217        max_dst_y_per_row_vblank = 16.0;        //U4.2
1218
1219        // magic!
1220        if (htotal <= 75) {
1221                max_dst_y_per_vm_vblank = 100.0;
1222                max_dst_y_per_row_vblank = 100.0;
1223        }
1224
1225        dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch);
1226        dml_print("DML_DLG: %s: dst_y_per_vm_flip    = %3.2f\n", __func__, dst_y_per_vm_flip);
1227        dml_print("DML_DLG: %s: dst_y_per_row_flip   = %3.2f\n", __func__, dst_y_per_row_flip);
1228        dml_print("DML_DLG: %s: dst_y_per_vm_vblank  = %3.2f\n", __func__, dst_y_per_vm_vblank);
1229        dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank);
1230
1231        ASSERT(dst_y_per_vm_vblank < max_dst_y_per_vm_vblank); ASSERT(dst_y_per_row_vblank < max_dst_y_per_row_vblank);
1232
1233        ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
1234
1235        vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);    // From VBA
1236        vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);    // From VBA
1237
1238        dml_print("DML_DLG: %s: vratio_pre_l = %3.2f\n", __func__, vratio_pre_l);
1239        dml_print("DML_DLG: %s: vratio_pre_c = %3.2f\n", __func__, vratio_pre_c);
1240
1241        // Active
1242        req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
1243        req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
1244        meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
1245        meta_row_height_c = rq_dlg_param.rq_c.meta_row_height;
1246        swath_width_pixels_ub_l = 0;
1247        swath_width_pixels_ub_c = 0;
1248        scaler_rec_in_width_l = 0;
1249        scaler_rec_in_width_c = 0;
1250        dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height;
1251        dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height;
1252
1253        if (mode_422) {
1254                swath_width_pixels_ub_l = swath_width_ub_l * 2;  // *2 for 2 pixel per element
1255                swath_width_pixels_ub_c = swath_width_ub_c * 2;
1256        } else {
1257                swath_width_pixels_ub_l = swath_width_ub_l * 1;
1258                swath_width_pixels_ub_c = swath_width_ub_c * 1;
1259        }
1260
1261        hscale_pixel_rate_l = 0.;
1262        hscale_pixel_rate_c = 0.;
1263        min_hratio_fact_l = 1.0;
1264        min_hratio_fact_c = 1.0;
1265
1266        if (hratio_l <= 1)
1267                min_hratio_fact_l = 2.0;
1268        else if (htaps_l <= 6) {
1269                if ((hratio_l * 2.0) > 4.0)
1270                        min_hratio_fact_l = 4.0;
1271                else
1272                        min_hratio_fact_l = hratio_l * 2.0;
1273        } else {
1274                if (hratio_l > 4.0)
1275                        min_hratio_fact_l = 4.0;
1276                else
1277                        min_hratio_fact_l = hratio_l;
1278        }
1279
1280        hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
1281
1282        dml_print("DML_DLG: %s: hratio_l = %3.2f\n", __func__, hratio_l);
1283        dml_print("DML_DLG: %s: min_hratio_fact_l = %3.2f\n", __func__, min_hratio_fact_l);
1284        dml_print("DML_DLG: %s: hscale_pixel_rate_l = %3.2f\n", __func__, hscale_pixel_rate_l);
1285
1286        if (hratio_c <= 1)
1287                min_hratio_fact_c = 2.0;
1288        else if (htaps_c <= 6) {
1289                if ((hratio_c * 2.0) > 4.0)
1290                        min_hratio_fact_c = 4.0;
1291                else
1292                        min_hratio_fact_c = hratio_c * 2.0;
1293        } else {
1294                if (hratio_c > 4.0)
1295                        min_hratio_fact_c = 4.0;
1296                else
1297                        min_hratio_fact_c = hratio_c;
1298        }
1299
1300        hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
1301
1302        refcyc_per_line_delivery_pre_l = 0.;
1303        refcyc_per_line_delivery_pre_c = 0.;
1304        refcyc_per_line_delivery_l = 0.;
1305        refcyc_per_line_delivery_c = 0.;
1306
1307        refcyc_per_req_delivery_pre_l = 0.;
1308        refcyc_per_req_delivery_pre_c = 0.;
1309        refcyc_per_req_delivery_l = 0.;
1310        refcyc_per_req_delivery_c = 0.;
1311
1312        full_recout_width = 0;
1313        // In ODM
1314        if (src->is_hsplit) {
1315                // This "hack"  is only allowed (and valid) for MPC combine. In ODM
1316                // combine, you MUST specify the full_recout_width...according to Oswin
1317                if (dst->full_recout_width == 0 && !dst->odm_combine) {
1318                        dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n", __func__);
1319                        full_recout_width = dst->recout_width * 2; // assume half split for dcn1
1320                } else
1321                        full_recout_width = dst->full_recout_width;
1322        } else
1323                full_recout_width = dst->recout_width;
1324
1325        // As of DCN2, mpc_combine and odm_combine are mutually exclusive
1326        refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(
1327                        mode_lib,
1328                        refclk_freq_in_mhz,
1329                        pclk_freq_in_mhz,
1330                        dst->odm_combine,
1331                        full_recout_width,
1332                        dst->hactive,
1333                        vratio_pre_l,
1334                        hscale_pixel_rate_l,
1335                        swath_width_pixels_ub_l,
1336                        1); // per line
1337
1338        refcyc_per_line_delivery_l = get_refcyc_per_delivery(
1339                        mode_lib,
1340                        refclk_freq_in_mhz,
1341                        pclk_freq_in_mhz,
1342                        dst->odm_combine,
1343                        full_recout_width,
1344                        dst->hactive,
1345                        vratio_l,
1346                        hscale_pixel_rate_l,
1347                        swath_width_pixels_ub_l,
1348                        1); // per line
1349
1350        dml_print("DML_DLG: %s: full_recout_width              = %d\n", __func__, full_recout_width);
1351        dml_print("DML_DLG: %s: hscale_pixel_rate_l            = %3.2f\n", __func__, hscale_pixel_rate_l);
1352        dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n", __func__, refcyc_per_line_delivery_pre_l);
1353        dml_print("DML_DLG: %s: refcyc_per_line_delivery_l     = %3.2f\n", __func__, refcyc_per_line_delivery_l);
1354        dml_print("DML_DLG: %s: vba__refcyc_per_line_delivery_pre_l = %3.2f\n", __func__, vba__refcyc_per_line_delivery_pre_l);
1355        dml_print("DML_DLG: %s: vba__refcyc_per_line_delivery_l     = %3.2f\n", __func__, vba__refcyc_per_line_delivery_l);
1356
1357        //old_impl_vs_vba_impl("refcyc_per_line_delivery_pre_l", refcyc_per_line_delivery_pre_l, vba__refcyc_per_line_delivery_pre_l);
1358        //old_impl_vs_vba_impl("refcyc_per_line_delivery_l", refcyc_per_line_delivery_l, vba__refcyc_per_line_delivery_l);
1359
1360        if (dual_plane) {
1361                float vba__refcyc_per_line_delivery_pre_c = get_refcyc_per_line_delivery_pre_c_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1362                float vba__refcyc_per_line_delivery_c = get_refcyc_per_line_delivery_c_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1363
1364                refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(
1365                                mode_lib,
1366                                refclk_freq_in_mhz,
1367                                pclk_freq_in_mhz,
1368                                dst->odm_combine,
1369                                full_recout_width,
1370                                dst->hactive,
1371                                vratio_pre_c,
1372                                hscale_pixel_rate_c,
1373                                swath_width_pixels_ub_c,
1374                                1); // per line
1375
1376                refcyc_per_line_delivery_c = get_refcyc_per_delivery(
1377                                mode_lib,
1378                                refclk_freq_in_mhz,
1379                                pclk_freq_in_mhz,
1380                                dst->odm_combine,
1381                                full_recout_width,
1382                                dst->hactive,
1383                                vratio_c,
1384                                hscale_pixel_rate_c,
1385                                swath_width_pixels_ub_c,
1386                                1); // per line
1387
1388                dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n", __func__, refcyc_per_line_delivery_pre_c);
1389                dml_print("DML_DLG: %s: refcyc_per_line_delivery_c     = %3.2f\n", __func__, refcyc_per_line_delivery_c);
1390                dml_print("DML_DLG: %s: vba__refcyc_per_line_delivery_pre_c = %3.2f\n", __func__, vba__refcyc_per_line_delivery_pre_c);
1391                dml_print("DML_DLG: %s: vba__refcyc_per_line_delivery_c     = %3.2f\n", __func__, vba__refcyc_per_line_delivery_c);
1392
1393                //old_impl_vs_vba_impl("refcyc_per_line_delivery_pre_c", refcyc_per_line_delivery_pre_c, vba__refcyc_per_line_delivery_pre_c);
1394                //old_impl_vs_vba_impl("refcyc_per_line_delivery_c", refcyc_per_line_delivery_c, vba__refcyc_per_line_delivery_c);
1395        }
1396
1397        if (src->dynamic_metadata_enable && src->gpuvm)
1398                disp_dlg_regs->refcyc_per_vm_dmdata = get_refcyc_per_vm_dmdata_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1399
1400        disp_dlg_regs->dmdata_dl_delta = get_dmdata_dl_delta_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1401
1402        // TTU - Luma / Chroma
1403        if (access_dir) {  // vertical access
1404                scaler_rec_in_width_l = vp_height_l;
1405                scaler_rec_in_width_c = vp_height_c;
1406        } else {
1407                scaler_rec_in_width_l = vp_width_l;
1408                scaler_rec_in_width_c = vp_width_c;
1409        }
1410
1411        refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(
1412                        mode_lib,
1413                        refclk_freq_in_mhz,
1414                        pclk_freq_in_mhz,
1415                        dst->odm_combine,
1416                        full_recout_width,
1417                        dst->hactive,
1418                        vratio_pre_l,
1419                        hscale_pixel_rate_l,
1420                        scaler_rec_in_width_l,
1421                        req_per_swath_ub_l);  // per req
1422
1423        refcyc_per_req_delivery_l = get_refcyc_per_delivery(
1424                        mode_lib,
1425                        refclk_freq_in_mhz,
1426                        pclk_freq_in_mhz,
1427                        dst->odm_combine,
1428                        full_recout_width,
1429                        dst->hactive,
1430                        vratio_l,
1431                        hscale_pixel_rate_l,
1432                        scaler_rec_in_width_l,
1433                        req_per_swath_ub_l);  // per req
1434
1435        dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n", __func__, refcyc_per_req_delivery_pre_l);
1436        dml_print("DML_DLG: %s: refcyc_per_req_delivery_l     = %3.2f\n", __func__, refcyc_per_req_delivery_l);
1437        dml_print("DML_DLG: %s: vba__refcyc_per_req_delivery_pre_l = %3.2f\n", __func__, vba__refcyc_per_req_delivery_pre_l);
1438        dml_print("DML_DLG: %s: vba__refcyc_per_req_delivery_l     = %3.2f\n", __func__, vba__refcyc_per_req_delivery_l);
1439
1440        //old_impl_vs_vba_impl("refcyc_per_req_delivery_pre_l", refcyc_per_req_delivery_pre_l, vba__refcyc_per_req_delivery_pre_l);
1441        //old_impl_vs_vba_impl("refcyc_per_req_delivery_l", refcyc_per_req_delivery_l, vba__refcyc_per_req_delivery_l);
1442
1443        ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13)); ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
1444
1445        if (dual_plane) {
1446                float vba__refcyc_per_req_delivery_pre_c = get_refcyc_per_req_delivery_pre_c_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;  // From VBA
1447                float vba__refcyc_per_req_delivery_c = get_refcyc_per_req_delivery_c_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;  // From VBA
1448
1449                refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(
1450                                mode_lib,
1451                                refclk_freq_in_mhz,
1452                                pclk_freq_in_mhz,
1453                                dst->odm_combine,
1454                                full_recout_width,
1455                                dst->hactive,
1456                                vratio_pre_c,
1457                                hscale_pixel_rate_c,
1458                                scaler_rec_in_width_c,
1459                                req_per_swath_ub_c);  // per req
1460                refcyc_per_req_delivery_c = get_refcyc_per_delivery(
1461                                mode_lib,
1462                                refclk_freq_in_mhz,
1463                                pclk_freq_in_mhz,
1464                                dst->odm_combine,
1465                                full_recout_width,
1466                                dst->hactive,
1467                                vratio_c,
1468                                hscale_pixel_rate_c,
1469                                scaler_rec_in_width_c,
1470                                req_per_swath_ub_c);  // per req
1471
1472                dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n", __func__, refcyc_per_req_delivery_pre_c);
1473                dml_print("DML_DLG: %s: refcyc_per_req_delivery_c     = %3.2f\n", __func__, refcyc_per_req_delivery_c);
1474                dml_print("DML_DLG: %s: vba__refcyc_per_req_delivery_pre_c = %3.2f\n", __func__, vba__refcyc_per_req_delivery_pre_c);
1475                dml_print("DML_DLG: %s: vba__refcyc_per_req_delivery_c     = %3.2f\n", __func__, vba__refcyc_per_req_delivery_c);
1476
1477                //old_impl_vs_vba_impl("refcyc_per_req_delivery_pre_c", refcyc_per_req_delivery_pre_c, vba__refcyc_per_req_delivery_pre_c);
1478                //old_impl_vs_vba_impl("refcyc_per_req_delivery_c", refcyc_per_req_delivery_c, vba__refcyc_per_req_delivery_c);
1479
1480                ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13)); ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
1481        }
1482
1483        // TTU - Cursor
1484        refcyc_per_req_delivery_pre_cur0 = 0.0;
1485        refcyc_per_req_delivery_cur0 = 0.0;
1486
1487        ASSERT(src->num_cursors <= 1);
1488
1489        if (src->num_cursors > 0) {
1490                float vba__refcyc_per_req_delivery_pre_cur0;
1491                float vba__refcyc_per_req_delivery_cur0;
1492
1493                calculate_ttu_cursor(
1494                                mode_lib,
1495                                &refcyc_per_req_delivery_pre_cur0,
1496                                &refcyc_per_req_delivery_cur0,
1497                                refclk_freq_in_mhz,
1498                                ref_freq_to_pix_freq,
1499                                hscale_pixel_rate_l,
1500                                scl->hscl_ratio,
1501                                vratio_pre_l,
1502                                vratio_l,
1503                                src->cur0_src_width,
1504                                (enum cursor_bpp) (src->cur0_bpp));
1505
1506                vba__refcyc_per_req_delivery_pre_cur0 = get_refcyc_per_cursor_req_delivery_pre_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1507                vba__refcyc_per_req_delivery_cur0 = get_refcyc_per_cursor_req_delivery_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; // From VBA
1508
1509                dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f\n", __func__, refcyc_per_req_delivery_pre_cur0);
1510                dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur0     = %3.2f\n", __func__, refcyc_per_req_delivery_cur0);
1511                dml_print("DML_DLG: %s: vba__refcyc_per_req_delivery_pre_cur0 = %3.2f\n", __func__, vba__refcyc_per_req_delivery_pre_cur0);
1512                dml_print("DML_DLG: %s: vba__refcyc_per_req_delivery_cur0     = %3.2f\n", __func__, vba__refcyc_per_req_delivery_cur0);
1513
1514                //old_impl_vs_vba_impl("refcyc_per_req_delivery_pre_cur0", refcyc_per_req_delivery_pre_cur0, vba__refcyc_per_req_delivery_pre_cur0);
1515                //old_impl_vs_vba_impl("refcyc_per_req_delivery_cur0", refcyc_per_req_delivery_cur0, vba__refcyc_per_req_delivery_cur0);
1516        }
1517
1518        refcyc_per_req_delivery_pre_cur1 = 0.0;
1519        refcyc_per_req_delivery_cur1 = 0.0;
1520
1521        // TTU - Misc
1522        // all hard-coded
1523
1524        // Assignment to register structures
1525        disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line
1526        ASSERT(disp_dlg_regs->dst_y_after_scaler < (unsigned int)8);
1527        disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq;       // in terms of refclk
1528        ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int)dml_pow(2, 13));
1529        disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
1530        disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
1531        disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
1532        disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2));
1533        disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2));
1534
1535        disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
1536        disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
1537
1538        dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_vblank  = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_vblank);
1539        dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_vblank = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_vblank);
1540        dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_vm_flip    = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_vm_flip);
1541        dml_print("DML_DLG: %s: disp_dlg_regs->dst_y_per_row_flip   = 0x%x\n", __func__, disp_dlg_regs->dst_y_per_row_flip);
1542
1543        // hack for FPGA
1544        if (mode_lib->project == DML_PROJECT_DCN31_FPGA) {
1545                if (disp_dlg_regs->vratio_prefetch >= (unsigned int) dml_pow(2, 22)) {
1546                        disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 22) - 1;
1547                        dml_print("vratio_prefetch exceed the max value, the register field is [21:0]\n");
1548                }
1549        }
1550
1551        disp_dlg_regs->refcyc_per_pte_group_vblank_l = (unsigned int) (dst_y_per_row_vblank * (double) htotal * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
1552        ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int)dml_pow(2, 13));
1553
1554        if (dual_plane) {
1555                disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank * (double) htotal * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c);
1556                ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int)dml_pow(2, 13));
1557        }
1558
1559        disp_dlg_regs->refcyc_per_meta_chunk_vblank_l = (unsigned int) (dst_y_per_row_vblank * (double) htotal * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
1560        ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int)dml_pow(2, 13));
1561
1562        disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0.  assigned to be the same as _l for now
1563
1564        disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l;
1565        disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l;
1566
1567        if (dual_plane) {
1568                disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c;
1569                disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c;
1570        }
1571
1572        disp_dlg_regs->refcyc_per_vm_group_vblank = get_refcyc_per_vm_group_vblank_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;            // From VBA
1573        disp_dlg_regs->refcyc_per_vm_group_flip = get_refcyc_per_vm_group_flip_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;            // From VBA
1574        disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10); // From VBA
1575        disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10);   // From VBA
1576
1577        // Clamp to max for now
1578        if (disp_dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int) dml_pow(2, 23))
1579                disp_dlg_regs->refcyc_per_vm_group_vblank = dml_pow(2, 23) - 1;
1580
1581        if (disp_dlg_regs->refcyc_per_vm_group_flip >= (unsigned int) dml_pow(2, 23))
1582                disp_dlg_regs->refcyc_per_vm_group_flip = dml_pow(2, 23) - 1;
1583
1584        if (disp_dlg_regs->refcyc_per_vm_req_vblank >= (unsigned int) dml_pow(2, 23))
1585                disp_dlg_regs->refcyc_per_vm_req_vblank = dml_pow(2, 23) - 1;
1586
1587        if (disp_dlg_regs->refcyc_per_vm_req_flip >= (unsigned int) dml_pow(2, 23))
1588                disp_dlg_regs->refcyc_per_vm_req_flip = dml_pow(2, 23) - 1;
1589
1590        disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l / (double) vratio_l * dml_pow(2, 2));
1591        ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int)dml_pow(2, 17));
1592        if (dual_plane) {
1593                disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c / (double) vratio_c * dml_pow(2, 2));
1594                if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) {
1595                        dml_print(
1596                                        "DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n",
1597                                        __func__,
1598                                        disp_dlg_regs->dst_y_per_pte_row_nom_c,
1599                                        (unsigned int) dml_pow(2, 17) - 1);
1600                }
1601        }
1602
1603        disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l / (double) vratio_l * dml_pow(2, 2));
1604        ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int)dml_pow(2, 17));
1605
1606        disp_dlg_regs->dst_y_per_meta_row_nom_c = (unsigned int) ((double) meta_row_height_c / (double) vratio_c * dml_pow(2, 2));
1607        ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_c < (unsigned int)dml_pow(2, 17));
1608
1609        disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
1610                        / (double) dpte_groups_per_row_ub_l);
1611        if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
1612                disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
1613        disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
1614                        / (double) meta_chunks_per_row_ub_l);
1615        if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
1616                disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
1617
1618        if (dual_plane) {
1619                disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq
1620                                / (double) dpte_groups_per_row_ub_c);
1621                if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
1622                        disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
1623
1624                // TODO: Is this the right calculation? Does htotal need to be halved?
1625                disp_dlg_regs->refcyc_per_meta_chunk_nom_c = (unsigned int) ((double) meta_row_height_c / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq
1626                                / (double) meta_chunks_per_row_ub_c);
1627                if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23))
1628                        disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1;
1629        }
1630
1631        disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l, 1);
1632        disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l, 1);
1633        ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int)dml_pow(2, 13)); ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int)dml_pow(2, 13));
1634
1635        disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c, 1);
1636        disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c, 1);
1637        ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int)dml_pow(2, 13)); ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int)dml_pow(2, 13));
1638
1639        disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
1640        disp_dlg_regs->dst_y_offset_cur0 = 0;
1641        disp_dlg_regs->chunk_hdl_adjust_cur1 = 3;
1642        disp_dlg_regs->dst_y_offset_cur1 = 0;
1643
1644        disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
1645
1646        disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l * dml_pow(2, 10));
1647        disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l * dml_pow(2, 10));
1648        disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10));
1649        disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c * dml_pow(2, 10));
1650        disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
1651        disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10));
1652        disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 = (unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10));
1653        disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1 * dml_pow(2, 10));
1654
1655        disp_ttu_regs->qos_level_low_wm = 0;
1656        ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
1657
1658        disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal * ref_freq_to_pix_freq);
1659        ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14));
1660
1661        disp_ttu_regs->qos_level_flip = 14;
1662        disp_ttu_regs->qos_level_fixed_l = 8;
1663        disp_ttu_regs->qos_level_fixed_c = 8;
1664        disp_ttu_regs->qos_level_fixed_cur0 = 8;
1665        disp_ttu_regs->qos_ramp_disable_l = 0;
1666        disp_ttu_regs->qos_ramp_disable_c = 0;
1667        disp_ttu_regs->qos_ramp_disable_cur0 = 0;
1668
1669        disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz;
1670        ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24));
1671
1672        print__ttu_regs_st(mode_lib, *disp_ttu_regs);
1673        print__dlg_regs_st(mode_lib, *disp_dlg_regs);
1674}
1675
1676void dml31_rq_dlg_get_dlg_reg(
1677                struct display_mode_lib *mode_lib,
1678                display_dlg_regs_st *dlg_regs,
1679                display_ttu_regs_st *ttu_regs,
1680                display_e2e_pipe_params_st *e2e_pipe_param,
1681                const unsigned int num_pipes,
1682                const unsigned int pipe_idx,
1683                const bool cstate_en,
1684                const bool pstate_en,
1685                const bool vm_en,
1686                const bool ignore_viewport_pos,
1687                const bool immediate_flip_support)
1688{
1689        display_rq_params_st rq_param = {0};
1690        display_dlg_sys_params_st dlg_sys_param = {0};
1691
1692        // Get watermark and Tex.
1693        dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes);
1694        dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib, e2e_pipe_param, num_pipes);
1695        dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes);
1696        dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes);
1697        dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes);
1698        dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes);
1699        dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib, e2e_pipe_param, num_pipes);
1700        dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, e2e_pipe_param, num_pipes);
1701
1702        print__dlg_sys_params_st(mode_lib, dlg_sys_param);
1703
1704        // system parameter calculation done
1705
1706        dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx);
1707        dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe);
1708        dml_rq_dlg_get_dlg_params(
1709                        mode_lib,
1710                        e2e_pipe_param,
1711                        num_pipes,
1712                        pipe_idx,
1713                        dlg_regs,
1714                        ttu_regs,
1715                        rq_param.dlg,
1716                        dlg_sys_param,
1717                        cstate_en,
1718                        pstate_en,
1719                        vm_en,
1720                        ignore_viewport_pos,
1721                        immediate_flip_support);
1722        dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx);
1723}
1724
1725