Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-16 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 #include "dm_services.h"
0026 
0027 #include "dce/dce_11_0_d.h"
0028 #include "dce/dce_11_0_sh_mask.h"
0029 /* TODO: this needs to be looked at, used by Stella's workaround*/
0030 #include "gmc/gmc_8_2_d.h"
0031 #include "gmc/gmc_8_2_sh_mask.h"
0032 
0033 #include "include/logger_interface.h"
0034 #include "inc/dce_calcs.h"
0035 
0036 #include "dce/dce_mem_input.h"
0037 #include "dce110_mem_input_v.h"
0038 
0039 static void set_flip_control(
0040     struct dce_mem_input *mem_input110,
0041     bool immediate)
0042 {
0043     uint32_t value = 0;
0044 
0045     value = dm_read_reg(
0046             mem_input110->base.ctx,
0047             mmUNP_FLIP_CONTROL);
0048 
0049     set_reg_field_value(value, 1,
0050             UNP_FLIP_CONTROL,
0051             GRPH_SURFACE_UPDATE_PENDING_MODE);
0052 
0053     dm_write_reg(
0054             mem_input110->base.ctx,
0055             mmUNP_FLIP_CONTROL,
0056             value);
0057 }
0058 
0059 /* chroma part */
0060 static void program_pri_addr_c(
0061     struct dce_mem_input *mem_input110,
0062     PHYSICAL_ADDRESS_LOC address)
0063 {
0064     uint32_t value = 0;
0065     uint32_t temp = 0;
0066     /*high register MUST be programmed first*/
0067     temp = address.high_part &
0068 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
0069 
0070     set_reg_field_value(value, temp,
0071         UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
0072         GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
0073 
0074     dm_write_reg(
0075         mem_input110->base.ctx,
0076         mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
0077         value);
0078 
0079     temp = 0;
0080     value = 0;
0081     temp = address.low_part >>
0082     UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT;
0083 
0084     set_reg_field_value(value, temp,
0085         UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
0086         GRPH_PRIMARY_SURFACE_ADDRESS_C);
0087 
0088     dm_write_reg(
0089         mem_input110->base.ctx,
0090         mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
0091         value);
0092 }
0093 
0094 /* luma part */
0095 static void program_pri_addr_l(
0096     struct dce_mem_input *mem_input110,
0097     PHYSICAL_ADDRESS_LOC address)
0098 {
0099     uint32_t value = 0;
0100     uint32_t temp = 0;
0101 
0102     /*high register MUST be programmed first*/
0103     temp = address.high_part &
0104 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK;
0105 
0106     set_reg_field_value(value, temp,
0107         UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
0108         GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L);
0109 
0110     dm_write_reg(
0111         mem_input110->base.ctx,
0112         mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
0113         value);
0114 
0115     temp = 0;
0116     value = 0;
0117     temp = address.low_part >>
0118     UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
0119 
0120     set_reg_field_value(value, temp,
0121         UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
0122         GRPH_PRIMARY_SURFACE_ADDRESS_L);
0123 
0124     dm_write_reg(
0125         mem_input110->base.ctx,
0126         mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
0127         value);
0128 }
0129 
0130 static void program_addr(
0131     struct dce_mem_input *mem_input110,
0132     const struct dc_plane_address *addr)
0133 {
0134     switch (addr->type) {
0135     case PLN_ADDR_TYPE_GRAPHICS:
0136         program_pri_addr_l(
0137             mem_input110,
0138             addr->grph.addr);
0139         break;
0140     case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
0141         program_pri_addr_c(
0142             mem_input110,
0143             addr->video_progressive.chroma_addr);
0144         program_pri_addr_l(
0145             mem_input110,
0146             addr->video_progressive.luma_addr);
0147         break;
0148     default:
0149         /* not supported */
0150         BREAK_TO_DEBUGGER();
0151     }
0152 }
0153 
0154 static void enable(struct dce_mem_input *mem_input110)
0155 {
0156     uint32_t value = 0;
0157 
0158     value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
0159     set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
0160     dm_write_reg(mem_input110->base.ctx,
0161         mmUNP_GRPH_ENABLE,
0162         value);
0163 }
0164 
0165 static void program_tiling(
0166     struct dce_mem_input *mem_input110,
0167     const union dc_tiling_info *info,
0168     const enum surface_pixel_format pixel_format)
0169 {
0170     uint32_t value = 0;
0171 
0172     set_reg_field_value(value, info->gfx8.num_banks,
0173         UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
0174 
0175     set_reg_field_value(value, info->gfx8.bank_width,
0176         UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
0177 
0178     set_reg_field_value(value, info->gfx8.bank_height,
0179         UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
0180 
0181     set_reg_field_value(value, info->gfx8.tile_aspect,
0182         UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
0183 
0184     set_reg_field_value(value, info->gfx8.tile_split,
0185         UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
0186 
0187     set_reg_field_value(value, info->gfx8.tile_mode,
0188         UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
0189 
0190     set_reg_field_value(value, info->gfx8.pipe_config,
0191         UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
0192 
0193     set_reg_field_value(value, info->gfx8.array_mode,
0194         UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
0195 
0196     set_reg_field_value(value, 1,
0197         UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
0198 
0199     set_reg_field_value(value, 0,
0200         UNP_GRPH_CONTROL, GRPH_Z);
0201 
0202     dm_write_reg(
0203         mem_input110->base.ctx,
0204         mmUNP_GRPH_CONTROL,
0205         value);
0206 
0207     value = 0;
0208 
0209     set_reg_field_value(value, info->gfx8.bank_width_c,
0210         UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
0211 
0212     set_reg_field_value(value, info->gfx8.bank_height_c,
0213         UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
0214 
0215     set_reg_field_value(value, info->gfx8.tile_aspect_c,
0216         UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
0217 
0218     set_reg_field_value(value, info->gfx8.tile_split_c,
0219         UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
0220 
0221     set_reg_field_value(value, info->gfx8.tile_mode_c,
0222         UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
0223 
0224     dm_write_reg(
0225         mem_input110->base.ctx,
0226         mmUNP_GRPH_CONTROL_C,
0227         value);
0228 }
0229 
0230 static void program_size_and_rotation(
0231     struct dce_mem_input *mem_input110,
0232     enum dc_rotation_angle rotation,
0233     const struct plane_size *plane_size)
0234 {
0235     uint32_t value = 0;
0236     struct plane_size local_size = *plane_size;
0237 
0238     if (rotation == ROTATION_ANGLE_90 ||
0239         rotation == ROTATION_ANGLE_270) {
0240 
0241         swap(local_size.surface_size.x,
0242              local_size.surface_size.y);
0243         swap(local_size.surface_size.width,
0244              local_size.surface_size.height);
0245         swap(local_size.chroma_size.x,
0246              local_size.chroma_size.y);
0247         swap(local_size.chroma_size.width,
0248              local_size.chroma_size.height);
0249     }
0250 
0251     value = 0;
0252     set_reg_field_value(value, local_size.surface_pitch,
0253             UNP_GRPH_PITCH_L, GRPH_PITCH_L);
0254 
0255     dm_write_reg(
0256         mem_input110->base.ctx,
0257         mmUNP_GRPH_PITCH_L,
0258         value);
0259 
0260     value = 0;
0261     set_reg_field_value(value, local_size.chroma_pitch,
0262             UNP_GRPH_PITCH_C, GRPH_PITCH_C);
0263     dm_write_reg(
0264         mem_input110->base.ctx,
0265         mmUNP_GRPH_PITCH_C,
0266         value);
0267 
0268     value = 0;
0269     set_reg_field_value(value, 0,
0270             UNP_GRPH_X_START_L, GRPH_X_START_L);
0271     dm_write_reg(
0272         mem_input110->base.ctx,
0273         mmUNP_GRPH_X_START_L,
0274         value);
0275 
0276     value = 0;
0277     set_reg_field_value(value, 0,
0278             UNP_GRPH_X_START_C, GRPH_X_START_C);
0279     dm_write_reg(
0280         mem_input110->base.ctx,
0281         mmUNP_GRPH_X_START_C,
0282         value);
0283 
0284     value = 0;
0285     set_reg_field_value(value, 0,
0286             UNP_GRPH_Y_START_L, GRPH_Y_START_L);
0287     dm_write_reg(
0288         mem_input110->base.ctx,
0289         mmUNP_GRPH_Y_START_L,
0290         value);
0291 
0292     value = 0;
0293     set_reg_field_value(value, 0,
0294             UNP_GRPH_Y_START_C, GRPH_Y_START_C);
0295     dm_write_reg(
0296         mem_input110->base.ctx,
0297         mmUNP_GRPH_Y_START_C,
0298         value);
0299 
0300     value = 0;
0301     set_reg_field_value(value, local_size.surface_size.x +
0302             local_size.surface_size.width,
0303             UNP_GRPH_X_END_L, GRPH_X_END_L);
0304     dm_write_reg(
0305         mem_input110->base.ctx,
0306         mmUNP_GRPH_X_END_L,
0307         value);
0308 
0309     value = 0;
0310     set_reg_field_value(value, local_size.chroma_size.x +
0311             local_size.chroma_size.width,
0312             UNP_GRPH_X_END_C, GRPH_X_END_C);
0313     dm_write_reg(
0314         mem_input110->base.ctx,
0315         mmUNP_GRPH_X_END_C,
0316         value);
0317 
0318     value = 0;
0319     set_reg_field_value(value, local_size.surface_size.y +
0320             local_size.surface_size.height,
0321             UNP_GRPH_Y_END_L, GRPH_Y_END_L);
0322     dm_write_reg(
0323         mem_input110->base.ctx,
0324         mmUNP_GRPH_Y_END_L,
0325         value);
0326 
0327     value = 0;
0328     set_reg_field_value(value, local_size.chroma_size.y +
0329             local_size.chroma_size.height,
0330             UNP_GRPH_Y_END_C, GRPH_Y_END_C);
0331     dm_write_reg(
0332         mem_input110->base.ctx,
0333         mmUNP_GRPH_Y_END_C,
0334         value);
0335 
0336     value = 0;
0337     switch (rotation) {
0338     case ROTATION_ANGLE_90:
0339         set_reg_field_value(value, 3,
0340             UNP_HW_ROTATION, ROTATION_ANGLE);
0341         break;
0342     case ROTATION_ANGLE_180:
0343         set_reg_field_value(value, 2,
0344             UNP_HW_ROTATION, ROTATION_ANGLE);
0345         break;
0346     case ROTATION_ANGLE_270:
0347         set_reg_field_value(value, 1,
0348             UNP_HW_ROTATION, ROTATION_ANGLE);
0349         break;
0350     default:
0351         set_reg_field_value(value, 0,
0352             UNP_HW_ROTATION, ROTATION_ANGLE);
0353         break;
0354     }
0355 
0356     dm_write_reg(
0357         mem_input110->base.ctx,
0358         mmUNP_HW_ROTATION,
0359         value);
0360 }
0361 
0362 static void program_pixel_format(
0363     struct dce_mem_input *mem_input110,
0364     enum surface_pixel_format format)
0365 {
0366     if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
0367         uint32_t value;
0368         uint8_t grph_depth;
0369         uint8_t grph_format;
0370 
0371         value = dm_read_reg(
0372                 mem_input110->base.ctx,
0373                 mmUNP_GRPH_CONTROL);
0374 
0375         switch (format) {
0376         case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
0377             grph_depth = 0;
0378             grph_format = 0;
0379             break;
0380         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
0381             grph_depth = 1;
0382             grph_format = 1;
0383             break;
0384         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
0385         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
0386             grph_depth = 2;
0387             grph_format = 0;
0388             break;
0389         case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
0390         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
0391         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
0392             grph_depth = 2;
0393             grph_format = 1;
0394             break;
0395         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
0396         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
0397         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
0398         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
0399             grph_depth = 3;
0400             grph_format = 0;
0401             break;
0402         default:
0403             grph_depth = 2;
0404             grph_format = 0;
0405             break;
0406         }
0407 
0408         set_reg_field_value(
0409                 value,
0410                 grph_depth,
0411                 UNP_GRPH_CONTROL,
0412                 GRPH_DEPTH);
0413         set_reg_field_value(
0414                 value,
0415                 grph_format,
0416                 UNP_GRPH_CONTROL,
0417                 GRPH_FORMAT);
0418 
0419         dm_write_reg(
0420                 mem_input110->base.ctx,
0421                 mmUNP_GRPH_CONTROL,
0422                 value);
0423 
0424         value = dm_read_reg(
0425                 mem_input110->base.ctx,
0426                 mmUNP_GRPH_CONTROL_EXP);
0427 
0428         /* VIDEO FORMAT 0 */
0429         set_reg_field_value(
0430                 value,
0431                 0,
0432                 UNP_GRPH_CONTROL_EXP,
0433                 VIDEO_FORMAT);
0434         dm_write_reg(
0435                 mem_input110->base.ctx,
0436                 mmUNP_GRPH_CONTROL_EXP,
0437                 value);
0438 
0439     } else {
0440         /* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */
0441         uint32_t value;
0442         uint8_t video_format;
0443 
0444         value = dm_read_reg(
0445                 mem_input110->base.ctx,
0446                 mmUNP_GRPH_CONTROL_EXP);
0447 
0448         switch (format) {
0449         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
0450             video_format = 2;
0451             break;
0452         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
0453             video_format = 3;
0454             break;
0455         default:
0456             video_format = 0;
0457             break;
0458         }
0459 
0460         set_reg_field_value(
0461             value,
0462             video_format,
0463             UNP_GRPH_CONTROL_EXP,
0464             VIDEO_FORMAT);
0465 
0466         dm_write_reg(
0467             mem_input110->base.ctx,
0468             mmUNP_GRPH_CONTROL_EXP,
0469             value);
0470     }
0471 }
0472 
0473 static bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input)
0474 {
0475     struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0476     uint32_t value;
0477 
0478     value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE);
0479 
0480     if (get_reg_field_value(value, UNP_GRPH_UPDATE,
0481             GRPH_SURFACE_UPDATE_PENDING))
0482         return true;
0483 
0484     mem_input->current_address = mem_input->request_address;
0485     return false;
0486 }
0487 
0488 static bool dce_mem_input_v_program_surface_flip_and_addr(
0489     struct mem_input *mem_input,
0490     const struct dc_plane_address *address,
0491     bool flip_immediate)
0492 {
0493     struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0494 
0495     set_flip_control(mem_input110, flip_immediate);
0496     program_addr(mem_input110,
0497         address);
0498 
0499     mem_input->request_address = *address;
0500 
0501     return true;
0502 }
0503 
0504 /* Scatter Gather param tables */
0505 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = {
0506         {  8, 64, 64,  8,  8, 1, 4, 0, 0},
0507         { 16, 64, 32,  8, 16, 1, 8, 0, 0},
0508         { 32, 32, 32, 16, 16, 1, 8, 0, 0},
0509         { 64,  8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
0510 };
0511 
0512 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = {
0513         {  8, 512, 8, 1, 0, 1, 0, 0, 0},  /* 0 for invalid */
0514         { 16, 256, 8, 2, 0, 1, 0, 0, 0},
0515         { 32, 128, 8, 4, 0, 1, 0, 0, 0},
0516         { 64,  64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
0517 };
0518 
0519 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = {
0520         {  8, 4096, 1, 8, 0, 1, 0, 0, 0},
0521         { 16, 2048, 1, 8, 0, 1, 0, 0, 0},
0522         { 32, 1024, 1, 8, 0, 1, 0, 0, 0},
0523         { 64,  512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
0524 };
0525 
0526 /* Helper to get table entry from surface info */
0527 static const unsigned int *get_dvmm_hw_setting(
0528         union dc_tiling_info *tiling_info,
0529         enum surface_pixel_format format,
0530         bool chroma)
0531 {
0532     enum bits_per_pixel {
0533         bpp_8 = 0,
0534         bpp_16,
0535         bpp_32,
0536         bpp_64
0537     } bpp;
0538 
0539     if (format >= SURFACE_PIXEL_FORMAT_INVALID)
0540         bpp = bpp_32;
0541     else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
0542         bpp = chroma ? bpp_16 : bpp_8;
0543     else
0544         bpp = bpp_8;
0545 
0546     switch (tiling_info->gfx8.array_mode) {
0547     case DC_ARRAY_1D_TILED_THIN1:
0548     case DC_ARRAY_1D_TILED_THICK:
0549     case DC_ARRAY_PRT_TILED_THIN1:
0550         return dvmm_Hw_Setting_1DTiling[bpp];
0551     case DC_ARRAY_2D_TILED_THIN1:
0552     case DC_ARRAY_2D_TILED_THICK:
0553     case DC_ARRAY_2D_TILED_X_THICK:
0554     case DC_ARRAY_PRT_2D_TILED_THIN1:
0555     case DC_ARRAY_PRT_2D_TILED_THICK:
0556         return dvmm_Hw_Setting_2DTiling[bpp];
0557     case DC_ARRAY_LINEAR_GENERAL:
0558     case DC_ARRAY_LINEAR_ALLIGNED:
0559         return dvmm_Hw_Setting_Linear[bpp];
0560     default:
0561         return dvmm_Hw_Setting_2DTiling[bpp];
0562     }
0563 }
0564 
0565 static void dce_mem_input_v_program_pte_vm(
0566         struct mem_input *mem_input,
0567         enum surface_pixel_format format,
0568         union dc_tiling_info *tiling_info,
0569         enum dc_rotation_angle rotation)
0570 {
0571     struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0572     const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false);
0573     const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true);
0574 
0575     unsigned int page_width = 0;
0576     unsigned int page_height = 0;
0577     unsigned int page_width_chroma = 0;
0578     unsigned int page_height_chroma = 0;
0579     unsigned int temp_page_width = pte[1];
0580     unsigned int temp_page_height = pte[2];
0581     unsigned int min_pte_before_flip = 0;
0582     unsigned int min_pte_before_flip_chroma = 0;
0583     uint32_t value = 0;
0584 
0585     while ((temp_page_width >>= 1) != 0)
0586         page_width++;
0587     while ((temp_page_height >>= 1) != 0)
0588         page_height++;
0589 
0590     temp_page_width = pte_chroma[1];
0591     temp_page_height = pte_chroma[2];
0592     while ((temp_page_width >>= 1) != 0)
0593         page_width_chroma++;
0594     while ((temp_page_height >>= 1) != 0)
0595         page_height_chroma++;
0596 
0597     switch (rotation) {
0598     case ROTATION_ANGLE_90:
0599     case ROTATION_ANGLE_270:
0600         min_pte_before_flip = pte[4];
0601         min_pte_before_flip_chroma = pte_chroma[4];
0602         break;
0603     default:
0604         min_pte_before_flip = pte[3];
0605         min_pte_before_flip_chroma = pte_chroma[3];
0606         break;
0607     }
0608 
0609     value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT);
0610     /* TODO: un-hardcode requestlimit */
0611     set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L);
0612     set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C);
0613     dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value);
0614 
0615     value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL);
0616     set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH);
0617     set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT);
0618     set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP);
0619     dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value);
0620 
0621     value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL);
0622     set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK);
0623     set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING);
0624     dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value);
0625 
0626     value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C);
0627     set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C);
0628     set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C);
0629     set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C);
0630     dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value);
0631 
0632     value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C);
0633     set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C);
0634     set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C);
0635     dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value);
0636 }
0637 
0638 static void dce_mem_input_v_program_surface_config(
0639     struct mem_input *mem_input,
0640     enum surface_pixel_format format,
0641     union dc_tiling_info *tiling_info,
0642     struct plane_size *plane_size,
0643     enum dc_rotation_angle rotation,
0644     struct dc_plane_dcc_param *dcc,
0645     bool horizotal_mirror)
0646 {
0647     struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0648 
0649     enable(mem_input110);
0650     program_tiling(mem_input110, tiling_info, format);
0651     program_size_and_rotation(mem_input110, rotation, plane_size);
0652     program_pixel_format(mem_input110, format);
0653 }
0654 
0655 static void program_urgency_watermark(
0656     const struct dc_context *ctx,
0657     const uint32_t urgency_addr,
0658     const uint32_t wm_addr,
0659     struct dce_watermarks marks_low,
0660     uint32_t total_dest_line_time_ns)
0661 {
0662     /* register value */
0663     uint32_t urgency_cntl = 0;
0664     uint32_t wm_mask_cntl = 0;
0665 
0666     /*Write mask to enable reading/writing of watermark set A*/
0667     wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0668     set_reg_field_value(wm_mask_cntl,
0669             1,
0670             DPGV0_WATERMARK_MASK_CONTROL,
0671             URGENCY_WATERMARK_MASK);
0672     dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0673 
0674     urgency_cntl = dm_read_reg(ctx, urgency_addr);
0675 
0676     set_reg_field_value(
0677         urgency_cntl,
0678         marks_low.a_mark,
0679         DPGV0_PIPE_URGENCY_CONTROL,
0680         URGENCY_LOW_WATERMARK);
0681 
0682     set_reg_field_value(
0683         urgency_cntl,
0684         total_dest_line_time_ns,
0685         DPGV0_PIPE_URGENCY_CONTROL,
0686         URGENCY_HIGH_WATERMARK);
0687     dm_write_reg(ctx, urgency_addr, urgency_cntl);
0688 
0689     /*Write mask to enable reading/writing of watermark set B*/
0690     wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0691     set_reg_field_value(wm_mask_cntl,
0692             2,
0693             DPGV0_WATERMARK_MASK_CONTROL,
0694             URGENCY_WATERMARK_MASK);
0695     dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0696 
0697     urgency_cntl = dm_read_reg(ctx, urgency_addr);
0698 
0699     set_reg_field_value(urgency_cntl,
0700         marks_low.b_mark,
0701         DPGV0_PIPE_URGENCY_CONTROL,
0702         URGENCY_LOW_WATERMARK);
0703 
0704     set_reg_field_value(urgency_cntl,
0705         total_dest_line_time_ns,
0706         DPGV0_PIPE_URGENCY_CONTROL,
0707         URGENCY_HIGH_WATERMARK);
0708 
0709     dm_write_reg(ctx, urgency_addr, urgency_cntl);
0710 }
0711 
0712 static void program_urgency_watermark_l(
0713     const struct dc_context *ctx,
0714     struct dce_watermarks marks_low,
0715     uint32_t total_dest_line_time_ns)
0716 {
0717     program_urgency_watermark(
0718         ctx,
0719         mmDPGV0_PIPE_URGENCY_CONTROL,
0720         mmDPGV0_WATERMARK_MASK_CONTROL,
0721         marks_low,
0722         total_dest_line_time_ns);
0723 }
0724 
0725 static void program_urgency_watermark_c(
0726     const struct dc_context *ctx,
0727     struct dce_watermarks marks_low,
0728     uint32_t total_dest_line_time_ns)
0729 {
0730     program_urgency_watermark(
0731         ctx,
0732         mmDPGV1_PIPE_URGENCY_CONTROL,
0733         mmDPGV1_WATERMARK_MASK_CONTROL,
0734         marks_low,
0735         total_dest_line_time_ns);
0736 }
0737 
0738 static void program_stutter_watermark(
0739     const struct dc_context *ctx,
0740     const uint32_t stutter_addr,
0741     const uint32_t wm_addr,
0742     struct dce_watermarks marks)
0743 {
0744     /* register value */
0745     uint32_t stutter_cntl = 0;
0746     uint32_t wm_mask_cntl = 0;
0747 
0748     /*Write mask to enable reading/writing of watermark set A*/
0749 
0750     wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0751     set_reg_field_value(wm_mask_cntl,
0752         1,
0753         DPGV0_WATERMARK_MASK_CONTROL,
0754         STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
0755     dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0756 
0757     stutter_cntl = dm_read_reg(ctx, stutter_addr);
0758 
0759     if (ctx->dc->debug.disable_stutter) {
0760         set_reg_field_value(stutter_cntl,
0761             0,
0762             DPGV0_PIPE_STUTTER_CONTROL,
0763             STUTTER_ENABLE);
0764     } else {
0765         set_reg_field_value(stutter_cntl,
0766             1,
0767             DPGV0_PIPE_STUTTER_CONTROL,
0768             STUTTER_ENABLE);
0769     }
0770 
0771     set_reg_field_value(stutter_cntl,
0772         1,
0773         DPGV0_PIPE_STUTTER_CONTROL,
0774         STUTTER_IGNORE_FBC);
0775 
0776     /*Write watermark set A*/
0777     set_reg_field_value(stutter_cntl,
0778         marks.a_mark,
0779         DPGV0_PIPE_STUTTER_CONTROL,
0780         STUTTER_EXIT_SELF_REFRESH_WATERMARK);
0781     dm_write_reg(ctx, stutter_addr, stutter_cntl);
0782 
0783     /*Write mask to enable reading/writing of watermark set B*/
0784     wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0785     set_reg_field_value(wm_mask_cntl,
0786         2,
0787         DPGV0_WATERMARK_MASK_CONTROL,
0788         STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
0789     dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0790 
0791     stutter_cntl = dm_read_reg(ctx, stutter_addr);
0792     /*Write watermark set B*/
0793     set_reg_field_value(stutter_cntl,
0794         marks.b_mark,
0795         DPGV0_PIPE_STUTTER_CONTROL,
0796         STUTTER_EXIT_SELF_REFRESH_WATERMARK);
0797     dm_write_reg(ctx, stutter_addr, stutter_cntl);
0798 }
0799 
0800 static void program_stutter_watermark_l(
0801     const struct dc_context *ctx,
0802     struct dce_watermarks marks)
0803 {
0804     program_stutter_watermark(ctx,
0805             mmDPGV0_PIPE_STUTTER_CONTROL,
0806             mmDPGV0_WATERMARK_MASK_CONTROL,
0807             marks);
0808 }
0809 
0810 static void program_stutter_watermark_c(
0811     const struct dc_context *ctx,
0812     struct dce_watermarks marks)
0813 {
0814     program_stutter_watermark(ctx,
0815             mmDPGV1_PIPE_STUTTER_CONTROL,
0816             mmDPGV1_WATERMARK_MASK_CONTROL,
0817             marks);
0818 }
0819 
0820 static void program_nbp_watermark(
0821     const struct dc_context *ctx,
0822     const uint32_t wm_mask_ctrl_addr,
0823     const uint32_t nbp_pstate_ctrl_addr,
0824     struct dce_watermarks marks)
0825 {
0826     uint32_t value;
0827 
0828     /* Write mask to enable reading/writing of watermark set A */
0829 
0830     value = dm_read_reg(ctx, wm_mask_ctrl_addr);
0831 
0832     set_reg_field_value(
0833         value,
0834         1,
0835         DPGV0_WATERMARK_MASK_CONTROL,
0836         NB_PSTATE_CHANGE_WATERMARK_MASK);
0837     dm_write_reg(ctx, wm_mask_ctrl_addr, value);
0838 
0839     value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0840 
0841     set_reg_field_value(
0842         value,
0843         1,
0844         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0845         NB_PSTATE_CHANGE_ENABLE);
0846     set_reg_field_value(
0847         value,
0848         1,
0849         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0850         NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
0851     set_reg_field_value(
0852         value,
0853         1,
0854         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0855         NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
0856     dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0857 
0858     /* Write watermark set A */
0859     value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0860     set_reg_field_value(
0861         value,
0862         marks.a_mark,
0863         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0864         NB_PSTATE_CHANGE_WATERMARK);
0865     dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0866 
0867     /* Write mask to enable reading/writing of watermark set B */
0868     value = dm_read_reg(ctx, wm_mask_ctrl_addr);
0869     set_reg_field_value(
0870         value,
0871         2,
0872         DPGV0_WATERMARK_MASK_CONTROL,
0873         NB_PSTATE_CHANGE_WATERMARK_MASK);
0874     dm_write_reg(ctx, wm_mask_ctrl_addr, value);
0875 
0876     value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0877     set_reg_field_value(
0878         value,
0879         1,
0880         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0881         NB_PSTATE_CHANGE_ENABLE);
0882     set_reg_field_value(
0883         value,
0884         1,
0885         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0886         NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
0887     set_reg_field_value(
0888         value,
0889         1,
0890         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0891         NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
0892     dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0893 
0894     /* Write watermark set B */
0895     value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0896     set_reg_field_value(
0897         value,
0898         marks.b_mark,
0899         DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0900         NB_PSTATE_CHANGE_WATERMARK);
0901     dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0902 }
0903 
0904 static void program_nbp_watermark_l(
0905     const struct dc_context *ctx,
0906     struct dce_watermarks marks)
0907 {
0908     program_nbp_watermark(ctx,
0909             mmDPGV0_WATERMARK_MASK_CONTROL,
0910             mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0911             marks);
0912 }
0913 
0914 static void program_nbp_watermark_c(
0915     const struct dc_context *ctx,
0916     struct dce_watermarks marks)
0917 {
0918     program_nbp_watermark(ctx,
0919             mmDPGV1_WATERMARK_MASK_CONTROL,
0920             mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL,
0921             marks);
0922 }
0923 
0924 static void dce_mem_input_v_program_display_marks(
0925     struct mem_input *mem_input,
0926     struct dce_watermarks nbp,
0927     struct dce_watermarks stutter,
0928     struct dce_watermarks stutter_enter,
0929     struct dce_watermarks urgent,
0930     uint32_t total_dest_line_time_ns)
0931 {
0932     program_urgency_watermark_l(
0933         mem_input->ctx,
0934         urgent,
0935         total_dest_line_time_ns);
0936 
0937     program_nbp_watermark_l(
0938         mem_input->ctx,
0939         nbp);
0940 
0941     program_stutter_watermark_l(
0942         mem_input->ctx,
0943         stutter);
0944 
0945 }
0946 
0947 static void dce_mem_input_program_chroma_display_marks(
0948     struct mem_input *mem_input,
0949     struct dce_watermarks nbp,
0950     struct dce_watermarks stutter,
0951     struct dce_watermarks urgent,
0952     uint32_t total_dest_line_time_ns)
0953 {
0954     program_urgency_watermark_c(
0955         mem_input->ctx,
0956         urgent,
0957         total_dest_line_time_ns);
0958 
0959     program_nbp_watermark_c(
0960         mem_input->ctx,
0961         nbp);
0962 
0963     program_stutter_watermark_c(
0964         mem_input->ctx,
0965         stutter);
0966 }
0967 
0968 static void dce110_allocate_mem_input_v(
0969     struct mem_input *mi,
0970     uint32_t h_total,/* for current stream */
0971     uint32_t v_total,/* for current stream */
0972     uint32_t pix_clk_khz,/* for current stream */
0973     uint32_t total_stream_num)
0974 {
0975     uint32_t addr;
0976     uint32_t value;
0977     uint32_t pix_dur;
0978     if (pix_clk_khz != 0) {
0979         addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1;
0980         value = dm_read_reg(mi->ctx, addr);
0981         pix_dur = 1000000000ULL / pix_clk_khz;
0982         set_reg_field_value(
0983             value,
0984             pix_dur,
0985             DPGV0_PIPE_ARBITRATION_CONTROL1,
0986             PIXEL_DURATION);
0987         dm_write_reg(mi->ctx, addr, value);
0988 
0989         addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1;
0990         value = dm_read_reg(mi->ctx, addr);
0991         pix_dur = 1000000000ULL / pix_clk_khz;
0992         set_reg_field_value(
0993             value,
0994             pix_dur,
0995             DPGV1_PIPE_ARBITRATION_CONTROL1,
0996             PIXEL_DURATION);
0997         dm_write_reg(mi->ctx, addr, value);
0998 
0999         addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2;
1000         value = 0x4000800;
1001         dm_write_reg(mi->ctx, addr, value);
1002 
1003         addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2;
1004         value = 0x4000800;
1005         dm_write_reg(mi->ctx, addr, value);
1006     }
1007 
1008 }
1009 
1010 static void dce110_free_mem_input_v(
1011     struct mem_input *mi,
1012     uint32_t total_stream_num)
1013 {
1014 }
1015 
1016 static const struct mem_input_funcs dce110_mem_input_v_funcs = {
1017     .mem_input_program_display_marks =
1018             dce_mem_input_v_program_display_marks,
1019     .mem_input_program_chroma_display_marks =
1020             dce_mem_input_program_chroma_display_marks,
1021     .allocate_mem_input = dce110_allocate_mem_input_v,
1022     .free_mem_input = dce110_free_mem_input_v,
1023     .mem_input_program_surface_flip_and_addr =
1024             dce_mem_input_v_program_surface_flip_and_addr,
1025     .mem_input_program_pte_vm =
1026             dce_mem_input_v_program_pte_vm,
1027     .mem_input_program_surface_config =
1028             dce_mem_input_v_program_surface_config,
1029     .mem_input_is_flip_pending =
1030             dce_mem_input_v_is_surface_pending
1031 };
1032 /*****************************************/
1033 /* Constructor, Destructor               */
1034 /*****************************************/
1035 
1036 void dce110_mem_input_v_construct(
1037     struct dce_mem_input *dce_mi,
1038     struct dc_context *ctx)
1039 {
1040     dce_mi->base.funcs = &dce110_mem_input_v_funcs;
1041     dce_mi->base.ctx = ctx;
1042 }
1043