Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu/display: Add core dc support for DCN

Core display support for DCN.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Harry Wentland and committed by
Alex Deucher
70ccab60 74c49c7a

+11467
+10
drivers/gpu/drm/amd/display/dc/dcn10/Makefile
··· 1 + # 2 + # Makefile for DCN. 3 + 4 + DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ 5 + dcn10_transform.o dcn10_opp.o dcn10_timing_generator.o \ 6 + dcn10_mem_input.o dcn10_mpc.o 7 + 8 + AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) 9 + 10 + AMD_DISPLAY_FILES += $(AMD_DAL_DCN10)
+1866
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 1 + /* 2 + * Copyright 2016 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 "dm_services.h" 27 + #include "dc.h" 28 + #include "core_dc.h" 29 + #include "core_types.h" 30 + #include "core_status.h" 31 + #include "resource.h" 32 + #include "hw_sequencer.h" 33 + #include "dcn10_hw_sequencer.h" 34 + #include "dce110/dce110_hw_sequencer.h" 35 + #include "abm.h" 36 + 37 + #include "dcn10/dcn10_transform.h" 38 + #include "dcn10/dcn10_mpc.h" 39 + #include "dcn10/dcn10_timing_generator.h" 40 + 41 + #include "mem_input.h" 42 + #include "timing_generator.h" 43 + #include "opp.h" 44 + #include "ipp.h" 45 + 46 + #include "dc_bios_types.h" 47 + 48 + #include "raven1/DCN/dcn_1_0_offset.h" 49 + #include "raven1/DCN/dcn_1_0_sh_mask.h" 50 + #include "vega10/soc15ip.h" 51 + 52 + #include "custom_float.h" 53 + 54 + 55 + struct dcn10_hwseq_reg_offsets { 56 + uint32_t dchubp; 57 + uint32_t dpp; 58 + uint32_t otg; 59 + uint32_t vtg; 60 + uint32_t fmt; 61 + }; 62 + 63 + /* TODO: move to resource */ 64 + static const struct dcn10_hwseq_reg_offsets reg_offsets[] = { 65 + { 66 + .dchubp = (mmHUBP0_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL), 67 + .dpp = (mmCM0_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL), 68 + .otg = (mmOTG0_OTG_CONTROL - mmOTG0_OTG_CONTROL), 69 + .vtg = (mmVTG0_CONTROL - mmVTG0_CONTROL), 70 + .fmt = (mmFMT0_FMT_BIT_DEPTH_CONTROL - 71 + mmFMT0_FMT_BIT_DEPTH_CONTROL), 72 + }, 73 + { 74 + .dchubp = (mmHUBP1_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL), 75 + .dpp = (mmCM1_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL), 76 + .otg = (mmOTG1_OTG_CONTROL - mmOTG0_OTG_CONTROL), 77 + .vtg = (mmVTG1_CONTROL - mmVTG0_CONTROL), 78 + .fmt = (mmFMT1_FMT_BIT_DEPTH_CONTROL - 79 + mmFMT0_FMT_BIT_DEPTH_CONTROL), 80 + }, 81 + { 82 + .dchubp = (mmHUBP2_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL), 83 + .dpp = (mmCM2_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL), 84 + .otg = (mmOTG2_OTG_CONTROL - mmOTG0_OTG_CONTROL), 85 + .vtg = (mmVTG2_CONTROL - mmVTG0_CONTROL), 86 + .fmt = (mmFMT2_FMT_BIT_DEPTH_CONTROL - 87 + mmFMT0_FMT_BIT_DEPTH_CONTROL), 88 + }, 89 + { 90 + .dchubp = (mmHUBP3_DCHUBP_CNTL - mmHUBP0_DCHUBP_CNTL), 91 + .dpp = (mmCM3_CM_DGAM_CONTROL - mmCM0_CM_DGAM_CONTROL), 92 + .otg = (mmOTG3_OTG_CONTROL - mmOTG0_OTG_CONTROL), 93 + .vtg = (mmVTG3_CONTROL - mmVTG0_CONTROL), 94 + .fmt = (mmFMT3_FMT_BIT_DEPTH_CONTROL - 95 + mmFMT0_FMT_BIT_DEPTH_CONTROL), 96 + } 97 + }; 98 + 99 + #define HWSEQ_REG_UPDATE_N(reg_name, n, ...) \ 100 + generic_reg_update_soc15(ctx, inst_offset, reg_name, n, __VA_ARGS__) 101 + 102 + #define HWSEQ_REG_SET_N(reg_name, n, ...) \ 103 + generic_reg_set_soc15(ctx, inst_offset, reg_name, n, __VA_ARGS__) 104 + 105 + #define HWSEQ_REG_UPDATE(reg, field, val) \ 106 + HWSEQ_REG_UPDATE_N(reg, 1, FD(reg##__##field), val) 107 + 108 + #define HWSEQ_REG_UPDATE_2(reg, field1, val1, field2, val2) \ 109 + HWSEQ_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2) 110 + 111 + #define HWSEQ_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \ 112 + HWSEQ_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3) 113 + 114 + 115 + #define HWSEQ_REG_SET(reg, field, val) \ 116 + HWSEQ_REG_SET_N(reg, 1, FD(reg##__##field), val) 117 + 118 + /* TODO should be moved to OTG */ 119 + static void lock_otg_master_update( 120 + struct dc_context *ctx, 121 + uint8_t inst) 122 + { 123 + uint32_t inst_offset = reg_offsets[inst].otg; 124 + 125 + HWSEQ_REG_UPDATE(OTG0_OTG_GLOBAL_CONTROL0, 126 + OTG_MASTER_UPDATE_LOCK_SEL, inst); 127 + 128 + /* unlock master locker */ 129 + HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK, 130 + OTG_MASTER_UPDATE_LOCK, 1); 131 + 132 + /* wait for unlock happens */ 133 + if (!wait_reg(ctx, inst_offset, OTG0_OTG_MASTER_UPDATE_LOCK, UPDATE_LOCK_STATUS, 1)) 134 + BREAK_TO_DEBUGGER(); 135 + 136 + } 137 + 138 + static bool unlock_master_tg_and_wait( 139 + struct dc_context *ctx, 140 + uint8_t inst) 141 + { 142 + uint32_t inst_offset = reg_offsets[inst].otg; 143 + 144 + HWSEQ_REG_UPDATE(OTG0_OTG_GLOBAL_SYNC_STATUS, 145 + VUPDATE_NO_LOCK_EVENT_CLEAR, 1); 146 + HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, 0); 147 + 148 + if (!wait_reg(ctx, inst_offset, OTG0_OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_OCCURRED, 1)) { 149 + dm_logger_write(ctx->logger, LOG_ERROR, 150 + "wait for VUPDATE_NO_LOCK_EVENT_OCCURRED failed\n"); 151 + BREAK_TO_DEBUGGER(); 152 + return false; 153 + } 154 + return true; 155 + } 156 + 157 + /* TODO: should be moved to OTG ? */ 158 + static void unlock_otg_master( 159 + struct dc_context *ctx, 160 + uint8_t inst) 161 + { 162 + uint32_t inst_offset = reg_offsets[inst].otg; 163 + 164 + /* unlock master locker */ 165 + HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK, 166 + OTG_MASTER_UPDATE_LOCK, 0); 167 + } 168 + 169 + 170 + static void wait_no_outstanding_request( 171 + struct dc_context *ctx, 172 + uint8_t plane_id) 173 + { 174 + uint32_t inst_offset = reg_offsets[plane_id].dchubp; 175 + 176 + if (!wait_reg(ctx, inst_offset, HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, 1)) 177 + BREAK_TO_DEBUGGER(); 178 + } 179 + 180 + static void disable_clocks( 181 + struct dc_context *ctx, 182 + uint8_t plane_id) 183 + { 184 + uint32_t inst_offset = reg_offsets[plane_id].dchubp; 185 + 186 + generic_reg_update_soc15(ctx, inst_offset, HUBP0_HUBP_CLK_CNTL, 1, 187 + FD(HUBP0_HUBP_CLK_CNTL__HUBP_CLOCK_ENABLE), 0); 188 + 189 + inst_offset = reg_offsets[plane_id].dpp; 190 + generic_reg_update_soc15(ctx, inst_offset, DPP_TOP0_DPP_CONTROL, 1, 191 + FD(DPP_TOP0_DPP_CONTROL__DPP_CLOCK_ENABLE), 0); 192 + } 193 + 194 + /* TODO: This is one time program during system boot up, 195 + * this should be done within BIOS or CAIL 196 + */ 197 + static void dchubp_map_fb_to_mc(struct dc_context *ctx) 198 + { 199 + /* TODO: do not know where to program 200 + * DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB 201 + */ 202 + /* 203 + * TODO: For real ASIC, FB_OFFSET may be need change to the same value 204 + * as FB_BASE. Need re-visit this for real ASIC. 205 + */ 206 + dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_BASE, 0, 0x80); 207 + dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_OFFSET, 0, 0); 208 + dm_write_reg_soc15(ctx, mmDCHUBBUB_SDPIF_FB_TOP, 0, 0xFF); 209 + 210 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_CFG0, 7, 211 + FD(DCHUBBUB_SDPIF_CFG0__SDPIF_DATA_RESPONSE_STATUS_CLEAR), 0, 212 + FD(DCHUBBUB_SDPIF_CFG0__SDPIF_REQ_CREDIT_ERROR_CLEAR), 0, 213 + FD(DCHUBBUB_SDPIF_CFG0__SDPIF_FLUSH_REQ_CREDIT_EN), 0, 214 + FD(DCHUBBUB_SDPIF_CFG0__SDPIF_REQ_CREDIT_EN), 0, 215 + FD(DCHUBBUB_SDPIF_CFG0__SDPIF_PORT_CONTROL), 1, 216 + FD(DCHUBBUB_SDPIF_CFG0__SDPIF_UNIT_ID_BITMASK), 0xd3, 217 + FD(DCHUBBUB_SDPIF_CFG0__SDPIF_CREDIT_DISCONNECT_DELAY), 0xc); 218 + 219 + 220 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_CFG1, 4, 221 + FD(DCHUBBUB_SDPIF_CFG1__SDPIF_INSIDE_FB_IO), 0, 222 + FD(DCHUBBUB_SDPIF_CFG1__SDPIF_INSIDE_FB_VC), 6, 223 + FD(DCHUBBUB_SDPIF_CFG1__SDPIF_OUTSIDE_FB_IO), 1, 224 + FD(DCHUBBUB_SDPIF_CFG1__SDPIF_OUTSIDE_FB_VC), 6); 225 + 226 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_FB_BASE, 1, 227 + FD(DCHUBBUB_SDPIF_FB_BASE__SDPIF_FB_BASE), 0x000080); 228 + 229 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_FB_TOP, 1, 230 + FD(DCHUBBUB_SDPIF_FB_TOP__SDPIF_FB_TOP), 0x0000ff); 231 + 232 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_BOT, 1, 233 + FD(DCHUBBUB_SDPIF_AGP_BOT__SDPIF_AGP_BOT), 0x0000040); 234 + 235 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_TOP, 1, 236 + FD(DCHUBBUB_SDPIF_AGP_TOP__SDPIF_AGP_TOP), 0x00001ff); 237 + 238 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_AGP_BASE, 1, 239 + FD(DCHUBBUB_SDPIF_AGP_BASE__SDPIF_AGP_BASE), 0x0000080); 240 + 241 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_APER_TOP, 1, 242 + FD(DCHUBBUB_SDPIF_APER_TOP__SDPIF_APER_TOP), 0x00007ff); 243 + 244 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_APER_DEF_0, 1, 245 + FD(DCHUBBUB_SDPIF_APER_DEF_0__SDPIF_APER_DEF_0), 0xdeadbeef); 246 + 247 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_0, 2, 248 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_0__SDPIF_MARC_EN_0), 0, 249 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_0__SDPIF_MARC_RELOC_LO_0), 0x90000); 250 + 251 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_0, 1, 252 + FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_0__SDPIF_MARC_LENGTH_LO_0), 0x10000); 253 + 254 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_1, 1, 255 + FD(DCHUBBUB_SDPIF_MARC_BASE_LO_1__SDPIF_MARC_BASE_LO_1), 0x10000); 256 + 257 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_1, 2, 258 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_1__SDPIF_MARC_EN_1), 0, 259 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_1__SDPIF_MARC_RELOC_LO_1), 0xa0000); 260 + 261 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_1, 1, 262 + FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_1__SDPIF_MARC_LENGTH_LO_1), 0x10000); 263 + 264 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_2, 1, 265 + FD(DCHUBBUB_SDPIF_MARC_BASE_LO_2__SDPIF_MARC_BASE_LO_2), 0x20000); 266 + 267 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_2, 2, 268 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_2__SDPIF_MARC_EN_2), 0, 269 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_2__SDPIF_MARC_RELOC_LO_2), 0xb0000); 270 + 271 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_2, 1, 272 + FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_2__SDPIF_MARC_LENGTH_LO_2), 0x10000); 273 + 274 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_BASE_LO_3, 1, 275 + FD(DCHUBBUB_SDPIF_MARC_BASE_LO_3__SDPIF_MARC_BASE_LO_3), 0x30000); 276 + 277 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_RELOC_LO_3, 2, 278 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_3__SDPIF_MARC_EN_3), 0, 279 + FD(DCHUBBUB_SDPIF_MARC_RELOC_LO_3__SDPIF_MARC_RELOC_LO_3), 0xc0000); 280 + 281 + generic_reg_set_soc15(ctx, 0, DCHUBBUB_SDPIF_MARC_LENGTH_LO_3, 1, 282 + FD(DCHUBBUB_SDPIF_MARC_LENGTH_LO_3__SDPIF_MARC_LENGTH_LO_3), 0x10000); 283 + 284 + /* TODO: Is DCN_VM_SYSTEM_APERTURE address one time programming? 285 + * Are all 4 hubp programmed with the same address? 286 + */ 287 + dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000); 288 + dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0); 289 + dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000); 290 + dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0); 291 + dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000); 292 + dm_write_reg_soc15(ctx, mmHUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0); 293 + 294 + dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000); 295 + dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0); 296 + dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000); 297 + dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0); 298 + dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000); 299 + dm_write_reg_soc15(ctx, mmHUBPREQ1_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0); 300 + 301 + dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000); 302 + dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0); 303 + dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000); 304 + dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0); 305 + dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000); 306 + dm_write_reg_soc15(ctx, mmHUBPREQ2_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0); 307 + 308 + dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 0x80000); 309 + dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 0); 310 + dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 0x100000); 311 + dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 0); 312 + dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 0x80000); 313 + dm_write_reg_soc15(ctx, mmHUBPREQ3_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 0); 314 + } 315 + 316 + /* TODO: This is one time program during system boot up, 317 + * this should be done within BIOS 318 + */ 319 + static void dchubup_setup_timer(struct dc_context *ctx) 320 + { 321 + dm_write_reg_soc15(ctx, mmREFCLK_CNTL, 0, 0); 322 + 323 + generic_reg_update_soc15(ctx, 0, DCHUBBUB_GLOBAL_TIMER_CNTL, 1, 324 + FD(DCHUBBUB_GLOBAL_TIMER_CNTL__DCHUBBUB_GLOBAL_TIMER_ENABLE), 1); 325 + } 326 + 327 + /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG 328 + * VTG is within DCHUBBUB which is commond block share by each pipe HUBP. 329 + * VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG 330 + */ 331 + static void select_vtg( 332 + struct dc_context *ctx, 333 + uint8_t plane_id, 334 + uint8_t inst) 335 + { 336 + uint32_t inst_offset = reg_offsets[plane_id].dchubp; 337 + 338 + HWSEQ_REG_UPDATE(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, inst); 339 + } 340 + 341 + static void enable_dcfclk( 342 + struct dc_context *ctx, 343 + uint8_t plane_id, 344 + uint32_t requested_pix_clk, 345 + bool dppclk_div) 346 + { 347 + uint32_t inst_offset = reg_offsets[plane_id].dchubp; 348 + 349 + HWSEQ_REG_UPDATE(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, 1); 350 + } 351 + 352 + static void enable_dppclk( 353 + struct dc_context *ctx, 354 + uint8_t plane_id, 355 + uint32_t requested_pix_clk, 356 + bool dppclk_div) 357 + { 358 + uint32_t inst_offset = reg_offsets[plane_id].dpp; 359 + 360 + dm_logger_write(ctx->logger, LOG_SURFACE, 361 + "dppclk_rate_control for pipe %d programed to %d\n", 362 + plane_id, 363 + dppclk_div); 364 + 365 + /* TODO: find condition for DPP clock to DISPCLK or 1/2 DISPCLK */ 366 + if (dppclk_div) { 367 + /* 1/2 DISPCLK*/ 368 + HWSEQ_REG_UPDATE_2(DPP_TOP0_DPP_CONTROL, 369 + DPPCLK_RATE_CONTROL, 1, 370 + DPP_CLOCK_ENABLE, 1); 371 + } else { 372 + /* DISPCLK */ 373 + HWSEQ_REG_UPDATE_2(DPP_TOP0_DPP_CONTROL, 374 + DPPCLK_RATE_CONTROL, 0, 375 + DPP_CLOCK_ENABLE, 1); 376 + } 377 + } 378 + 379 + static void enable_power_gating_plane( 380 + struct dc_context *ctx, 381 + bool enable) 382 + { 383 + uint32_t inst_offset = 0; /* each register only has one instance */ 384 + bool force_on = 1; /* disable power gating */ 385 + 386 + if (enable) 387 + force_on = 0; 388 + 389 + /* DCHUBP0/1/2/3 */ 390 + HWSEQ_REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, force_on); 391 + HWSEQ_REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on); 392 + HWSEQ_REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on); 393 + HWSEQ_REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on); 394 + 395 + /* DPP0/1/2/3 */ 396 + HWSEQ_REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on); 397 + HWSEQ_REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on); 398 + HWSEQ_REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on); 399 + HWSEQ_REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on); 400 + 401 + if (ctx->dc->debug.disable_clock_gate) { 402 + /* probably better to just write entire register to 0xffff to 403 + * ensure all clock gating is disabled 404 + */ 405 + HWSEQ_REG_UPDATE_3(DCCG_GATE_DISABLE_CNTL, 406 + DISPCLK_R_DCCG_GATE_DISABLE, 1, 407 + DPREFCLK_R_DCCG_GATE_DISABLE, 1, 408 + REFCLK_R_DIG_GATE_DISABLE, 1); 409 + HWSEQ_REG_UPDATE(DCFCLK_CNTL, 410 + DCFCLK_GATE_DIS, 1); 411 + } 412 + 413 + } 414 + 415 + static void dpp_pg_control( 416 + struct dc_context *ctx, 417 + unsigned int dpp_inst, 418 + bool power_on) 419 + { 420 + uint32_t inst_offset = 0; 421 + uint32_t power_gate = power_on ? 0 : 1; 422 + uint32_t pwr_status = power_on ? 0 : 2; 423 + 424 + if (ctx->dc->debug.disable_dpp_power_gate) 425 + return; 426 + 427 + switch (dpp_inst) { 428 + case 0: /* DPP0 */ 429 + HWSEQ_REG_UPDATE(DOMAIN1_PG_CONFIG, 430 + DOMAIN1_POWER_GATE, power_gate); 431 + 432 + wait_reg(ctx, 0, DOMAIN1_PG_STATUS, 433 + DOMAIN1_PGFSM_PWR_STATUS, pwr_status); 434 + break; 435 + case 1: /* DPP1 */ 436 + HWSEQ_REG_UPDATE(DOMAIN3_PG_CONFIG, 437 + DOMAIN3_POWER_GATE, power_gate); 438 + 439 + wait_reg(ctx, 0, DOMAIN3_PG_STATUS, 440 + DOMAIN3_PGFSM_PWR_STATUS, pwr_status); 441 + break; 442 + case 2: /* DPP2 */ 443 + HWSEQ_REG_UPDATE(DOMAIN5_PG_CONFIG, 444 + DOMAIN5_POWER_GATE, power_gate); 445 + 446 + wait_reg(ctx, 0, DOMAIN5_PG_STATUS, 447 + DOMAIN5_PGFSM_PWR_STATUS, pwr_status); 448 + break; 449 + case 3: /* DPP3 */ 450 + HWSEQ_REG_UPDATE(DOMAIN7_PG_CONFIG, 451 + DOMAIN7_POWER_GATE, power_gate); 452 + 453 + wait_reg(ctx, 0, DOMAIN7_PG_STATUS, 454 + DOMAIN7_PGFSM_PWR_STATUS, pwr_status); 455 + break; 456 + default: 457 + BREAK_TO_DEBUGGER(); 458 + break; 459 + } 460 + } 461 + 462 + static void hubp_pg_control( 463 + struct dc_context *ctx, 464 + unsigned int hubp_inst, 465 + bool power_on) 466 + { 467 + uint32_t inst_offset = 0; 468 + uint32_t power_gate = power_on ? 0 : 1; 469 + uint32_t pwr_status = power_on ? 0 : 2; 470 + 471 + if (ctx->dc->debug.disable_hubp_power_gate) 472 + return; 473 + 474 + switch (hubp_inst) { 475 + case 0: /* DCHUBP0 */ 476 + HWSEQ_REG_UPDATE(DOMAIN0_PG_CONFIG, 477 + DOMAIN0_POWER_GATE, power_gate); 478 + 479 + wait_reg(ctx, 0, DOMAIN0_PG_STATUS, 480 + DOMAIN0_PGFSM_PWR_STATUS, pwr_status); 481 + break; 482 + case 1: /* DCHUBP1 */ 483 + HWSEQ_REG_UPDATE(DOMAIN2_PG_CONFIG, 484 + DOMAIN2_POWER_GATE, power_gate); 485 + 486 + wait_reg(ctx, 0, DOMAIN2_PG_STATUS, 487 + DOMAIN2_PGFSM_PWR_STATUS, pwr_status); 488 + break; 489 + case 2: /* DCHUBP2 */ 490 + HWSEQ_REG_UPDATE(DOMAIN4_PG_CONFIG, 491 + DOMAIN4_POWER_GATE, power_gate); 492 + 493 + wait_reg(ctx, 0, DOMAIN4_PG_STATUS, 494 + DOMAIN4_PGFSM_PWR_STATUS, pwr_status); 495 + break; 496 + case 3: /* DCHUBP3 */ 497 + HWSEQ_REG_UPDATE(DOMAIN6_PG_CONFIG, 498 + DOMAIN6_POWER_GATE, power_gate); 499 + 500 + wait_reg(ctx, 0, DOMAIN6_PG_STATUS, 501 + DOMAIN6_PGFSM_PWR_STATUS, pwr_status); 502 + break; 503 + default: 504 + BREAK_TO_DEBUGGER(); 505 + break; 506 + } 507 + } 508 + 509 + static void power_on_plane( 510 + struct dc_context *ctx, 511 + uint8_t plane_id, 512 + uint8_t inst) 513 + { 514 + uint32_t inst_offset = 0; 515 + 516 + /* disable clock power gating */ 517 + 518 + /* DCCG_GATE_DISABLE_CNTL only has one instance */ 519 + HWSEQ_REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL, 520 + DISPCLK_DCCG_GATE_DISABLE, 1, 521 + DPPCLK_GATE_DISABLE, 1); 522 + /* DCFCLK_CNTL only has one instance */ 523 + HWSEQ_REG_UPDATE(DCFCLK_CNTL, 524 + DCFCLK_GATE_DIS, 1); 525 + 526 + HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, 527 + IP_REQUEST_EN, 1); 528 + dpp_pg_control(ctx, plane_id, true); 529 + hubp_pg_control(ctx, plane_id, true); 530 + HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, 531 + IP_REQUEST_EN, 0); 532 + 533 + if (ctx->dc->debug.disable_clock_gate) { 534 + HWSEQ_REG_UPDATE(DCCG_GATE_DISABLE_CNTL, 535 + DISPCLK_DCCG_GATE_DISABLE, 0); 536 + } else { 537 + /* DCCG_GATE_DISABLE_CNTL only has one instance. inst_offset = 0 */ 538 + HWSEQ_REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL, 539 + DISPCLK_DCCG_GATE_DISABLE, 0, 540 + DPPCLK_GATE_DISABLE, 0); 541 + /* DCFCLK_CNTL only has one instance. inst_offset = 0 */ 542 + HWSEQ_REG_UPDATE(DCFCLK_CNTL, 543 + DCFCLK_GATE_DIS, 0); 544 + } 545 + } 546 + 547 + /* fully check bios enabledisplaypowergating table. dal only need dce init 548 + * other power, clock gate register will be handle by dal itself. 549 + * further may be put within init_hw 550 + */ 551 + static bool dcn10_enable_display_power_gating( 552 + struct core_dc *dc, 553 + uint8_t controller_id, 554 + struct dc_bios *dcb, 555 + enum pipe_gating_control power_gating) 556 + { 557 + /* TODOFPGA */ 558 + #if 0 559 + if (power_gating != PIPE_GATING_CONTROL_ENABLE) 560 + dce110_init_pte(ctx); 561 + #endif 562 + 563 + return true; 564 + } 565 + 566 + static void bios_golden_init(struct core_dc *dc) 567 + { 568 + struct dc_bios *bp = dc->ctx->dc_bios; 569 + int i; 570 + 571 + /* initialize dcn global */ 572 + bp->funcs->enable_disp_power_gating(bp, 573 + CONTROLLER_ID_D0, ASIC_PIPE_INIT); 574 + 575 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 576 + /* initialize dcn per pipe */ 577 + bp->funcs->enable_disp_power_gating(bp, 578 + CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE); 579 + } 580 + } 581 + 582 + static void init_hw(struct core_dc *dc) 583 + { 584 + int i; 585 + struct dc_bios *bp; 586 + struct transform *xfm; 587 + struct abm *abm; 588 + 589 + bp = dc->ctx->dc_bios; 590 + 591 + if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 592 + /* TODO: this will be moved to Diag or BIOS */ 593 + dchubup_setup_timer(dc->ctx); 594 + 595 + /* TODO: dchubp_map_fb_to_mc will be moved to dchub interface 596 + * between dc and kmd 597 + */ 598 + dchubp_map_fb_to_mc(dc->ctx); 599 + 600 + enable_power_gating_plane(dc->ctx, true); 601 + return; 602 + } 603 + /* end of FPGA. Below if real ASIC */ 604 + 605 + bios_golden_init(dc); 606 + 607 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 608 + xfm = dc->res_pool->transforms[i]; 609 + xfm->funcs->transform_reset(xfm); 610 + 611 + /* TODOFPGA: may need later */ 612 + #if 0 613 + xfm->funcs->transform_power_up(xfm); 614 + dc->hwss.enable_display_pipe_clock_gating( 615 + dc->ctx, 616 + true); 617 + #endif 618 + } 619 + /* TODOFPGA: light sleep */ 620 + #if 0 621 + dc->hwss.clock_gating_power_up(dc->ctx, false); 622 + #endif 623 + 624 + for (i = 0; i < dc->link_count; i++) { 625 + /* Power up AND update implementation according to the 626 + * required signal (which may be different from the 627 + * default signal on connector). 628 + */ 629 + struct core_link *link = dc->links[i]; 630 + 631 + link->link_enc->funcs->hw_init(link->link_enc); 632 + } 633 + 634 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 635 + struct timing_generator *tg = 636 + dc->res_pool->timing_generators[i]; 637 + 638 + tg->funcs->disable_vga(tg); 639 + 640 + /* Blank controller using driver code instead of 641 + * command table. 642 + */ 643 + tg->funcs->set_blank(tg, true); 644 + hwss_wait_for_blank_complete(tg); 645 + } 646 + 647 + for (i = 0; i < dc->res_pool->audio_count; i++) { 648 + struct audio *audio = dc->res_pool->audios[i]; 649 + 650 + audio->funcs->hw_init(audio); 651 + } 652 + 653 + abm = dc->res_pool->abm; 654 + if (abm != NULL) { 655 + abm->funcs->init_backlight(abm); 656 + abm->funcs->abm_init(abm); 657 + } 658 + 659 + /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ 660 + generic_reg_set_soc15(dc->ctx, 0, DIO_MEM_PWR_CTRL, 7, 661 + FD(DIO_MEM_PWR_CTRL__HDMI0_MEM_PWR_FORCE), 0, 662 + FD(DIO_MEM_PWR_CTRL__HDMI1_MEM_PWR_FORCE), 0, 663 + FD(DIO_MEM_PWR_CTRL__HDMI2_MEM_PWR_FORCE), 0, 664 + FD(DIO_MEM_PWR_CTRL__HDMI3_MEM_PWR_FORCE), 0, 665 + FD(DIO_MEM_PWR_CTRL__HDMI4_MEM_PWR_FORCE), 0, 666 + FD(DIO_MEM_PWR_CTRL__HDMI5_MEM_PWR_FORCE), 0, 667 + FD(DIO_MEM_PWR_CTRL__HDMI6_MEM_PWR_FORCE), 0); 668 + 669 + /* This power gating should be one-time program for DAL. 670 + * It can only change by registry key 671 + * TODO: new task will for this. 672 + * if power gating is disable, power_on_plane and power_off_plane 673 + * should be skip. Otherwise, hand will be met in power_off_plane 674 + */ 675 + 676 + enable_power_gating_plane(dc->ctx, true); 677 + } 678 + 679 + static enum dc_status dcn10_prog_pixclk_crtc_otg( 680 + struct pipe_ctx *pipe_ctx, 681 + struct validate_context *context, 682 + struct core_dc *dc) 683 + { 684 + struct core_stream *stream = pipe_ctx->stream; 685 + enum dc_color_space color_space; 686 + struct tg_color black_color = {0}; 687 + bool enableStereo = stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_NONE ? 688 + false:true; 689 + bool rightEyePolarity = stream->public.timing.flags.RIGHT_EYE_3D_POLARITY; 690 + 691 + 692 + /* by upper caller loop, pipe0 is parent pipe and be called first. 693 + * back end is set up by for pipe0. Other children pipe share back end 694 + * with pipe 0. No program is needed. 695 + */ 696 + if (pipe_ctx->top_pipe != NULL) 697 + return DC_OK; 698 + 699 + /* TODO check if timing_changed, disable stream if timing changed */ 700 + 701 + /* HW program guide assume display already disable 702 + * by unplug sequence. OTG assume stop. 703 + */ 704 + pipe_ctx->tg->funcs->enable_optc_clock(pipe_ctx->tg, true); 705 + 706 + if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 707 + pipe_ctx->clock_source, 708 + &pipe_ctx->pix_clk_params, 709 + &pipe_ctx->pll_settings)) { 710 + BREAK_TO_DEBUGGER(); 711 + return DC_ERROR_UNEXPECTED; 712 + } 713 + pipe_ctx->tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset; 714 + pipe_ctx->tg->dlg_otg_param.vstartup_start = pipe_ctx->pipe_dlg_param.vstartup_start; 715 + pipe_ctx->tg->dlg_otg_param.vupdate_offset = pipe_ctx->pipe_dlg_param.vupdate_offset; 716 + pipe_ctx->tg->dlg_otg_param.vupdate_width = pipe_ctx->pipe_dlg_param.vupdate_width; 717 + 718 + pipe_ctx->tg->dlg_otg_param.signal = pipe_ctx->stream->signal; 719 + 720 + pipe_ctx->tg->funcs->program_timing( 721 + pipe_ctx->tg, 722 + &stream->public.timing, 723 + true); 724 + 725 + pipe_ctx->opp->funcs->opp_set_stereo_polarity( 726 + pipe_ctx->opp, 727 + enableStereo, 728 + rightEyePolarity); 729 + 730 + #if 0 /* move to after enable_crtc */ 731 + /* TODO: OPP FMT, ABM. etc. should be done here. */ 732 + /* or FPGA now. instance 0 only. TODO: move to opp.c */ 733 + 734 + inst_offset = reg_offsets[pipe_ctx->tg->inst].fmt; 735 + 736 + pipe_ctx->opp->funcs->opp_program_fmt( 737 + pipe_ctx->opp, 738 + &stream->bit_depth_params, 739 + &stream->clamping); 740 + #endif 741 + /* program otg blank color */ 742 + color_space = stream->public.output_color_space; 743 + color_space_to_black_color(dc, color_space, &black_color); 744 + pipe_ctx->tg->funcs->set_blank_color( 745 + pipe_ctx->tg, 746 + &black_color); 747 + 748 + pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); 749 + hwss_wait_for_blank_complete(pipe_ctx->tg); 750 + 751 + /* VTG is within DCHUB command block. DCFCLK is always on */ 752 + if (false == pipe_ctx->tg->funcs->enable_crtc(pipe_ctx->tg)) { 753 + BREAK_TO_DEBUGGER(); 754 + return DC_ERROR_UNEXPECTED; 755 + } 756 + 757 + /* TODO program crtc source select for non-virtual signal*/ 758 + /* TODO program FMT */ 759 + /* TODO setup link_enc */ 760 + /* TODO set stream attributes */ 761 + /* TODO program audio */ 762 + /* TODO enable stream if timing changed */ 763 + /* TODO unblank stream if DP */ 764 + 765 + return DC_OK; 766 + } 767 + 768 + static void reset_back_end_for_pipe( 769 + struct core_dc *dc, 770 + struct pipe_ctx *pipe_ctx, 771 + struct validate_context *context) 772 + { 773 + int i; 774 + struct dc_bios *bp; 775 + 776 + bp = dc->ctx->dc_bios; 777 + 778 + if (pipe_ctx->stream_enc == NULL) { 779 + pipe_ctx->stream = NULL; 780 + return; 781 + } 782 + 783 + /* TODOFPGA break core_link_disable_stream into 2 functions: 784 + * disable_stream and disable_link. disable_link will disable PHYPLL 785 + * which is used by otg. Move disable_link after disable_crtc 786 + */ 787 + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) 788 + core_link_disable_stream(pipe_ctx); 789 + 790 + /* by upper caller loop, parent pipe: pipe0, will be reset last. 791 + * back end share by all pipes and will be disable only when disable 792 + * parent pipe. 793 + */ 794 + if (pipe_ctx->top_pipe == NULL) { 795 + pipe_ctx->tg->funcs->disable_crtc(pipe_ctx->tg); 796 + 797 + pipe_ctx->tg->funcs->enable_optc_clock(pipe_ctx->tg, false); 798 + } 799 + 800 + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) 801 + resource_unreference_clock_source( 802 + &context->res_ctx, dc->res_pool, 803 + &pipe_ctx->clock_source); 804 + 805 + for (i = 0; i < dc->res_pool->pipe_count; i++) 806 + if (&dc->current_context->res_ctx.pipe_ctx[i] == pipe_ctx) 807 + break; 808 + 809 + if (i == dc->res_pool->pipe_count) 810 + return; 811 + 812 + pipe_ctx->stream = NULL; 813 + } 814 + 815 + static void reset_front_end_for_pipe( 816 + struct core_dc *dc, 817 + struct pipe_ctx *pipe_ctx, 818 + struct validate_context *context) 819 + { 820 + struct dcn10_mpc *mpc = TO_DCN10_MPC(dc->res_pool->mpc); 821 + struct mpc_tree_cfg *tree_cfg = NULL; 822 + 823 + if (!pipe_ctx->surface) 824 + return; 825 + 826 + lock_otg_master_update(dc->ctx, pipe_ctx->tg->inst); 827 + 828 + /* TODO: build stream pipes group id. For now, use stream otg 829 + * id as pipe group id 830 + */ 831 + tree_cfg = &context->res_ctx.mpc_tree[pipe_ctx->mpc_idx]; 832 + 833 + if (pipe_ctx->top_pipe == NULL) 834 + dcn10_delete_mpc_tree(mpc, tree_cfg); 835 + else { 836 + if (dcn10_remove_dpp(mpc, tree_cfg, pipe_ctx->pipe_idx)) 837 + pipe_ctx->top_pipe->bottom_pipe = NULL; 838 + else { 839 + dm_logger_write(dc->ctx->logger, LOG_RESOURCE, 840 + "%s: failed to find dpp to be removed!\n", 841 + __func__); 842 + } 843 + } 844 + 845 + pipe_ctx->top_pipe = NULL; 846 + pipe_ctx->bottom_pipe = NULL; 847 + pipe_ctx->mpc_idx = -1; 848 + 849 + unlock_master_tg_and_wait(dc->ctx, pipe_ctx->tg->inst); 850 + 851 + pipe_ctx->mi->funcs->disable_request(pipe_ctx->mi); 852 + 853 + wait_no_outstanding_request(dc->ctx, pipe_ctx->pipe_idx); 854 + 855 + wait_mpcc_idle(mpc, pipe_ctx->pipe_idx); 856 + 857 + disable_clocks(dc->ctx, pipe_ctx->pipe_idx); 858 + 859 + pipe_ctx->xfm->funcs->transform_reset(pipe_ctx->xfm); 860 + 861 + dm_logger_write(dc->ctx->logger, LOG_DC, 862 + "Reset front end for pipe %d\n", 863 + pipe_ctx->pipe_idx); 864 + 865 + pipe_ctx->surface = NULL; 866 + } 867 + 868 + static void reset_hw_ctx(struct core_dc *dc, 869 + struct validate_context *context, 870 + void (*reset)(struct core_dc *dc, 871 + struct pipe_ctx *pipe_ctx, 872 + struct validate_context *context)) 873 + { 874 + int i; 875 + 876 + for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) { 877 + struct pipe_ctx *pipe_ctx_old = 878 + &dc->current_context->res_ctx.pipe_ctx[i]; 879 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 880 + 881 + if (!pipe_ctx_old->stream) 882 + continue; 883 + 884 + if (!pipe_ctx->stream || 885 + pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 886 + reset(dc, pipe_ctx_old, dc->current_context); 887 + } 888 + } 889 + 890 + static void reset_hw_ctx_wrap( 891 + struct core_dc *dc, 892 + struct validate_context *context) 893 + { 894 + /* Reset Front End*/ 895 + reset_hw_ctx(dc, context, reset_front_end_for_pipe); 896 + /* Reset Back End*/ 897 + reset_hw_ctx(dc, context, reset_back_end_for_pipe); 898 + 899 + memcpy(context->res_ctx.mpc_tree, 900 + dc->current_context->res_ctx.mpc_tree, 901 + sizeof(struct mpc_tree_cfg) * dc->res_pool->pipe_count); 902 + } 903 + 904 + static bool patch_address_for_sbs_tb_stereo(struct pipe_ctx *pipe_ctx, 905 + PHYSICAL_ADDRESS_LOC *addr) 906 + { 907 + struct core_surface *surface = pipe_ctx->surface; 908 + bool sec_split = pipe_ctx->top_pipe && 909 + pipe_ctx->top_pipe->surface == pipe_ctx->surface; 910 + if (sec_split && surface->public.address.type == PLN_ADDR_TYPE_GRPH_STEREO && 911 + (pipe_ctx->stream->public.timing.timing_3d_format == 912 + TIMING_3D_FORMAT_SIDE_BY_SIDE || 913 + pipe_ctx->stream->public.timing.timing_3d_format == 914 + TIMING_3D_FORMAT_TOP_AND_BOTTOM)) { 915 + *addr = surface->public.address.grph_stereo.left_addr; 916 + surface->public.address.grph_stereo.left_addr =\ 917 + surface->public.address.grph_stereo.right_addr; 918 + return true; 919 + } 920 + return false; 921 + } 922 + 923 + static void update_plane_addr(const struct core_dc *dc, struct pipe_ctx *pipe_ctx) 924 + { 925 + bool addr_patched = false; 926 + PHYSICAL_ADDRESS_LOC addr; 927 + struct core_surface *surface = pipe_ctx->surface; 928 + 929 + if (surface == NULL) 930 + return; 931 + addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr); 932 + pipe_ctx->mi->funcs->mem_input_program_surface_flip_and_addr( 933 + pipe_ctx->mi, 934 + &surface->public.address, 935 + surface->public.flip_immediate); 936 + surface->status.requested_address = surface->public.address; 937 + if (addr_patched) 938 + pipe_ctx->surface->public.address.grph_stereo.left_addr = addr; 939 + } 940 + 941 + static bool dcn10_set_input_transfer_func( 942 + struct pipe_ctx *pipe_ctx, 943 + const struct core_surface *surface) 944 + { 945 + struct input_pixel_processor *ipp = pipe_ctx->ipp; 946 + const struct core_transfer_func *tf = NULL; 947 + bool result = true; 948 + 949 + if (ipp == NULL) 950 + return false; 951 + 952 + if (surface->public.in_transfer_func) 953 + tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func); 954 + 955 + if (tf == NULL) 956 + ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 957 + else if (tf->public.type == TF_TYPE_PREDEFINED) { 958 + switch (tf->public.tf) { 959 + case TRANSFER_FUNCTION_SRGB: 960 + ipp->funcs->ipp_set_degamma(ipp, 961 + IPP_DEGAMMA_MODE_HW_sRGB); 962 + break; 963 + case TRANSFER_FUNCTION_BT709: 964 + ipp->funcs->ipp_set_degamma(ipp, 965 + IPP_DEGAMMA_MODE_HW_xvYCC); 966 + break; 967 + case TRANSFER_FUNCTION_LINEAR: 968 + ipp->funcs->ipp_set_degamma(ipp, 969 + IPP_DEGAMMA_MODE_BYPASS); 970 + break; 971 + case TRANSFER_FUNCTION_PQ: 972 + result = false; 973 + break; 974 + default: 975 + result = false; 976 + break; 977 + } 978 + } else if (tf->public.type == TF_TYPE_BYPASS) { 979 + ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 980 + } else { 981 + /*TF_TYPE_DISTRIBUTED_POINTS*/ 982 + result = false; 983 + } 984 + 985 + return result; 986 + } 987 + /*modify the method to handle rgb for arr_points*/ 988 + static bool convert_to_custom_float( 989 + struct pwl_result_data *rgb_resulted, 990 + struct curve_points *arr_points, 991 + uint32_t hw_points_num) 992 + { 993 + struct custom_float_format fmt; 994 + 995 + struct pwl_result_data *rgb = rgb_resulted; 996 + 997 + uint32_t i = 0; 998 + 999 + fmt.exponenta_bits = 6; 1000 + fmt.mantissa_bits = 12; 1001 + fmt.sign = false; 1002 + 1003 + if (!convert_to_custom_float_format( 1004 + arr_points[0].x, 1005 + &fmt, 1006 + &arr_points[0].custom_float_x)) { 1007 + BREAK_TO_DEBUGGER(); 1008 + return false; 1009 + } 1010 + 1011 + if (!convert_to_custom_float_format( 1012 + arr_points[0].offset, 1013 + &fmt, 1014 + &arr_points[0].custom_float_offset)) { 1015 + BREAK_TO_DEBUGGER(); 1016 + return false; 1017 + } 1018 + 1019 + if (!convert_to_custom_float_format( 1020 + arr_points[0].slope, 1021 + &fmt, 1022 + &arr_points[0].custom_float_slope)) { 1023 + BREAK_TO_DEBUGGER(); 1024 + return false; 1025 + } 1026 + 1027 + fmt.mantissa_bits = 10; 1028 + fmt.sign = false; 1029 + 1030 + if (!convert_to_custom_float_format( 1031 + arr_points[1].x, 1032 + &fmt, 1033 + &arr_points[1].custom_float_x)) { 1034 + BREAK_TO_DEBUGGER(); 1035 + return false; 1036 + } 1037 + 1038 + if (!convert_to_custom_float_format( 1039 + arr_points[1].y, 1040 + &fmt, 1041 + &arr_points[1].custom_float_y)) { 1042 + BREAK_TO_DEBUGGER(); 1043 + return false; 1044 + } 1045 + 1046 + if (!convert_to_custom_float_format( 1047 + arr_points[1].slope, 1048 + &fmt, 1049 + &arr_points[1].custom_float_slope)) { 1050 + BREAK_TO_DEBUGGER(); 1051 + return false; 1052 + } 1053 + 1054 + fmt.mantissa_bits = 12; 1055 + fmt.sign = true; 1056 + 1057 + while (i != hw_points_num) { 1058 + if (!convert_to_custom_float_format( 1059 + rgb->red, 1060 + &fmt, 1061 + &rgb->red_reg)) { 1062 + BREAK_TO_DEBUGGER(); 1063 + return false; 1064 + } 1065 + 1066 + if (!convert_to_custom_float_format( 1067 + rgb->green, 1068 + &fmt, 1069 + &rgb->green_reg)) { 1070 + BREAK_TO_DEBUGGER(); 1071 + return false; 1072 + } 1073 + 1074 + if (!convert_to_custom_float_format( 1075 + rgb->blue, 1076 + &fmt, 1077 + &rgb->blue_reg)) { 1078 + BREAK_TO_DEBUGGER(); 1079 + return false; 1080 + } 1081 + 1082 + if (!convert_to_custom_float_format( 1083 + rgb->delta_red, 1084 + &fmt, 1085 + &rgb->delta_red_reg)) { 1086 + BREAK_TO_DEBUGGER(); 1087 + return false; 1088 + } 1089 + 1090 + if (!convert_to_custom_float_format( 1091 + rgb->delta_green, 1092 + &fmt, 1093 + &rgb->delta_green_reg)) { 1094 + BREAK_TO_DEBUGGER(); 1095 + return false; 1096 + } 1097 + 1098 + if (!convert_to_custom_float_format( 1099 + rgb->delta_blue, 1100 + &fmt, 1101 + &rgb->delta_blue_reg)) { 1102 + BREAK_TO_DEBUGGER(); 1103 + return false; 1104 + } 1105 + 1106 + ++rgb; 1107 + ++i; 1108 + } 1109 + 1110 + return true; 1111 + } 1112 + #define MAX_REGIONS_NUMBER 34 1113 + #define MAX_LOW_POINT 25 1114 + #define NUMBER_SEGMENTS 32 1115 + 1116 + static bool dcn10_translate_regamma_to_hw_format(const struct dc_transfer_func 1117 + *output_tf, struct pwl_params *regamma_params) 1118 + { 1119 + struct curve_points *arr_points; 1120 + struct pwl_result_data *rgb_resulted; 1121 + struct pwl_result_data *rgb; 1122 + struct pwl_result_data *rgb_plus_1; 1123 + struct fixed31_32 y_r; 1124 + struct fixed31_32 y_g; 1125 + struct fixed31_32 y_b; 1126 + struct fixed31_32 y1_min; 1127 + struct fixed31_32 y3_max; 1128 + 1129 + int32_t segment_start, segment_end; 1130 + int32_t i; 1131 + uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points; 1132 + 1133 + if (output_tf == NULL || regamma_params == NULL || 1134 + output_tf->type == TF_TYPE_BYPASS) 1135 + return false; 1136 + 1137 + arr_points = regamma_params->arr_points; 1138 + rgb_resulted = regamma_params->rgb_resulted; 1139 + hw_points = 0; 1140 + 1141 + memset(regamma_params, 0, sizeof(struct pwl_params)); 1142 + memset(seg_distr, 0, sizeof(seg_distr)); 1143 + 1144 + if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 1145 + /* 32 segments 1146 + * segments are from 2^-25 to 2^7 1147 + */ 1148 + for (i = 0; i < 32 ; i++) 1149 + seg_distr[i] = 3; 1150 + 1151 + segment_start = -25; 1152 + segment_end = 7; 1153 + } else { 1154 + /* 10 segments 1155 + * segment is from 2^-10 to 2^0 1156 + * There are less than 256 points, for optimization 1157 + */ 1158 + seg_distr[0] = 3; 1159 + seg_distr[1] = 4; 1160 + seg_distr[2] = 4; 1161 + seg_distr[3] = 4; 1162 + seg_distr[4] = 4; 1163 + seg_distr[5] = 4; 1164 + seg_distr[6] = 4; 1165 + seg_distr[7] = 4; 1166 + seg_distr[8] = 5; 1167 + seg_distr[9] = 5; 1168 + 1169 + segment_start = -10; 1170 + segment_end = 0; 1171 + } 1172 + 1173 + for (i = segment_end - segment_start; i < MAX_REGIONS_NUMBER ; i++) 1174 + seg_distr[i] = -1; 1175 + 1176 + for (k = 0; k < MAX_REGIONS_NUMBER; k++) { 1177 + if (seg_distr[k] != -1) 1178 + hw_points += (1 << seg_distr[k]); 1179 + } 1180 + 1181 + j = 0; 1182 + for (k = 0; k < (segment_end - segment_start); k++) { 1183 + increment = NUMBER_SEGMENTS / (1 << seg_distr[k]); 1184 + start_index = (segment_start + k + MAX_LOW_POINT) * NUMBER_SEGMENTS; 1185 + for (i = start_index; i < start_index + NUMBER_SEGMENTS; i += increment) { 1186 + if (j == hw_points - 1) 1187 + break; 1188 + rgb_resulted[j].red = output_tf->tf_pts.red[i]; 1189 + rgb_resulted[j].green = output_tf->tf_pts.green[i]; 1190 + rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 1191 + j++; 1192 + } 1193 + } 1194 + 1195 + /* last point */ 1196 + start_index = (segment_end + MAX_LOW_POINT) * NUMBER_SEGMENTS; 1197 + rgb_resulted[hw_points - 1].red = 1198 + output_tf->tf_pts.red[start_index]; 1199 + rgb_resulted[hw_points - 1].green = 1200 + output_tf->tf_pts.green[start_index]; 1201 + rgb_resulted[hw_points - 1].blue = 1202 + output_tf->tf_pts.blue[start_index]; 1203 + 1204 + arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 1205 + dal_fixed31_32_from_int(segment_start)); 1206 + arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 1207 + dal_fixed31_32_from_int(segment_end)); 1208 + arr_points[2].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 1209 + dal_fixed31_32_from_int(segment_end)); 1210 + 1211 + y_r = rgb_resulted[0].red; 1212 + y_g = rgb_resulted[0].green; 1213 + y_b = rgb_resulted[0].blue; 1214 + 1215 + y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); 1216 + 1217 + arr_points[0].y = y1_min; 1218 + arr_points[0].slope = dal_fixed31_32_div( 1219 + arr_points[0].y, 1220 + arr_points[0].x); 1221 + y_r = rgb_resulted[hw_points - 1].red; 1222 + y_g = rgb_resulted[hw_points - 1].green; 1223 + y_b = rgb_resulted[hw_points - 1].blue; 1224 + 1225 + /* see comment above, m_arrPoints[1].y should be the Y value for the 1226 + * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 1227 + */ 1228 + y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); 1229 + 1230 + arr_points[1].y = y3_max; 1231 + arr_points[2].y = y3_max; 1232 + 1233 + arr_points[1].slope = dal_fixed31_32_zero; 1234 + arr_points[2].slope = dal_fixed31_32_zero; 1235 + 1236 + if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 1237 + /* for PQ, we want to have a straight line from last HW X point, 1238 + * and the slope to be such that we hit 1.0 at 10000 nits. 1239 + */ 1240 + const struct fixed31_32 end_value = 1241 + dal_fixed31_32_from_int(125); 1242 + 1243 + arr_points[1].slope = dal_fixed31_32_div( 1244 + dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 1245 + dal_fixed31_32_sub(end_value, arr_points[1].x)); 1246 + arr_points[2].slope = dal_fixed31_32_div( 1247 + dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 1248 + dal_fixed31_32_sub(end_value, arr_points[1].x)); 1249 + } 1250 + 1251 + regamma_params->hw_points_num = hw_points; 1252 + 1253 + i = 1; 1254 + for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) { 1255 + if (seg_distr[k] != -1) { 1256 + regamma_params->arr_curve_points[k].segments_num = 1257 + seg_distr[k]; 1258 + regamma_params->arr_curve_points[i].offset = 1259 + regamma_params->arr_curve_points[k]. 1260 + offset + (1 << seg_distr[k]); 1261 + } 1262 + i++; 1263 + } 1264 + 1265 + if (seg_distr[k] != -1) 1266 + regamma_params->arr_curve_points[k].segments_num = 1267 + seg_distr[k]; 1268 + 1269 + rgb = rgb_resulted; 1270 + rgb_plus_1 = rgb_resulted + 1; 1271 + 1272 + i = 1; 1273 + 1274 + while (i != hw_points + 1) { 1275 + if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) 1276 + rgb_plus_1->red = rgb->red; 1277 + if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) 1278 + rgb_plus_1->green = rgb->green; 1279 + if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) 1280 + rgb_plus_1->blue = rgb->blue; 1281 + 1282 + rgb->delta_red = dal_fixed31_32_sub( 1283 + rgb_plus_1->red, 1284 + rgb->red); 1285 + rgb->delta_green = dal_fixed31_32_sub( 1286 + rgb_plus_1->green, 1287 + rgb->green); 1288 + rgb->delta_blue = dal_fixed31_32_sub( 1289 + rgb_plus_1->blue, 1290 + rgb->blue); 1291 + 1292 + ++rgb_plus_1; 1293 + ++rgb; 1294 + ++i; 1295 + } 1296 + 1297 + convert_to_custom_float(rgb_resulted, arr_points, hw_points); 1298 + 1299 + return true; 1300 + } 1301 + 1302 + static bool dcn10_set_output_transfer_func( 1303 + struct pipe_ctx *pipe_ctx, 1304 + const struct core_surface *surface, 1305 + const struct core_stream *stream) 1306 + { 1307 + struct output_pixel_processor *opp = pipe_ctx->opp; 1308 + 1309 + opp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 1310 + 1311 + if (stream->public.out_transfer_func && 1312 + stream->public.out_transfer_func->type == 1313 + TF_TYPE_PREDEFINED && 1314 + stream->public.out_transfer_func->tf == 1315 + TRANSFER_FUNCTION_SRGB) { 1316 + opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB); 1317 + } else if (dcn10_translate_regamma_to_hw_format( 1318 + stream->public.out_transfer_func, &opp->regamma_params)) { 1319 + opp->funcs->opp_program_regamma_pwl(opp, &opp->regamma_params); 1320 + opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER); 1321 + } else { 1322 + opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS); 1323 + } 1324 + 1325 + return true; 1326 + } 1327 + 1328 + static void dcn10_pipe_control_lock( 1329 + struct core_dc *dc, 1330 + struct pipe_ctx *pipe, 1331 + bool lock) 1332 + { 1333 + struct dce_hwseq *hws = hws = dc->hwseq; 1334 + 1335 + /* use TG master update lock to lock everything on the TG 1336 + * therefore only top pipe need to lock 1337 + */ 1338 + if (pipe->top_pipe) 1339 + return; 1340 + 1341 + if (lock) 1342 + dcn10_lock(pipe->tg); 1343 + else 1344 + dcn10_unlock(pipe->tg); 1345 + } 1346 + 1347 + static bool wait_for_reset_trigger_to_occur( 1348 + struct dc_context *dc_ctx, 1349 + struct timing_generator *tg) 1350 + { 1351 + bool rc = false; 1352 + 1353 + /* To avoid endless loop we wait at most 1354 + * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 1355 + const uint32_t frames_to_wait_on_triggered_reset = 10; 1356 + int i; 1357 + 1358 + for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 1359 + 1360 + if (!tg->funcs->is_counter_moving(tg)) { 1361 + DC_ERROR("TG counter is not moving!\n"); 1362 + break; 1363 + } 1364 + 1365 + if (tg->funcs->did_triggered_reset_occur(tg)) { 1366 + rc = true; 1367 + /* usually occurs at i=1 */ 1368 + DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 1369 + i); 1370 + break; 1371 + } 1372 + 1373 + /* Wait for one frame. */ 1374 + tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 1375 + tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 1376 + } 1377 + 1378 + if (false == rc) 1379 + DC_ERROR("GSL: Timeout on reset trigger!\n"); 1380 + 1381 + return rc; 1382 + } 1383 + 1384 + static void dcn10_enable_timing_synchronization( 1385 + struct core_dc *dc, 1386 + int group_index, 1387 + int group_size, 1388 + struct pipe_ctx *grouped_pipes[]) 1389 + { 1390 + struct dc_context *dc_ctx = dc->ctx; 1391 + int i; 1392 + 1393 + DC_SYNC_INFO("Setting up OTG reset trigger\n"); 1394 + 1395 + for (i = 1; i < group_size; i++) 1396 + grouped_pipes[i]->tg->funcs->enable_reset_trigger( 1397 + grouped_pipes[i]->tg, grouped_pipes[0]->tg->inst); 1398 + 1399 + 1400 + DC_SYNC_INFO("Waiting for trigger\n"); 1401 + 1402 + /* Need to get only check 1 pipe for having reset as all the others are 1403 + * synchronized. Look at last pipe programmed to reset. 1404 + */ 1405 + wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[1]->tg); 1406 + for (i = 1; i < group_size; i++) 1407 + grouped_pipes[i]->tg->funcs->disable_reset_trigger( 1408 + grouped_pipes[i]->tg); 1409 + 1410 + DC_SYNC_INFO("Sync complete\n"); 1411 + } 1412 + 1413 + static void dcn10_power_on_fe( 1414 + struct core_dc *dc, 1415 + struct pipe_ctx *pipe_ctx, 1416 + struct validate_context *context) 1417 + { 1418 + struct dc_surface *dc_surface = &pipe_ctx->surface->public; 1419 + 1420 + /* power up DCHUP and DPP from pseudo code pipe_move.c */ 1421 + /*TODO: function: power_on_plane. If already power up, skip 1422 + */ 1423 + { 1424 + power_on_plane(dc->ctx, 1425 + pipe_ctx->pipe_idx, pipe_ctx->tg->inst); 1426 + 1427 + /* enable DCFCLK current DCHUB */ 1428 + enable_dcfclk(dc->ctx, 1429 + pipe_ctx->pipe_idx, 1430 + pipe_ctx->pix_clk_params.requested_pix_clk, 1431 + context->dppclk_div); 1432 + 1433 + if (dc_surface) { 1434 + dm_logger_write(dc->ctx->logger, LOG_DC, 1435 + "Pipe:%d 0x%x: addr hi:0x%x, " 1436 + "addr low:0x%x, " 1437 + "src: %d, %d, %d," 1438 + " %d; dst: %d, %d, %d, %d;\n", 1439 + pipe_ctx->pipe_idx, 1440 + dc_surface, 1441 + dc_surface->address.grph.addr.high_part, 1442 + dc_surface->address.grph.addr.low_part, 1443 + dc_surface->src_rect.x, 1444 + dc_surface->src_rect.y, 1445 + dc_surface->src_rect.width, 1446 + dc_surface->src_rect.height, 1447 + dc_surface->dst_rect.x, 1448 + dc_surface->dst_rect.y, 1449 + dc_surface->dst_rect.width, 1450 + dc_surface->dst_rect.height); 1451 + 1452 + dm_logger_write(dc->ctx->logger, LOG_HW_SET_MODE, 1453 + "Pipe %d: width, height, x, y\n" 1454 + "viewport:%d, %d, %d, %d\n" 1455 + "recout: %d, %d, %d, %d\n", 1456 + pipe_ctx->pipe_idx, 1457 + pipe_ctx->scl_data.viewport.width, 1458 + pipe_ctx->scl_data.viewport.height, 1459 + pipe_ctx->scl_data.viewport.x, 1460 + pipe_ctx->scl_data.viewport.y, 1461 + pipe_ctx->scl_data.recout.width, 1462 + pipe_ctx->scl_data.recout.height, 1463 + pipe_ctx->scl_data.recout.x, 1464 + pipe_ctx->scl_data.recout.y); 1465 + } 1466 + } 1467 + 1468 + } 1469 + 1470 + static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 1471 + { 1472 + struct xfm_grph_csc_adjustment adjust; 1473 + memset(&adjust, 0, sizeof(adjust)); 1474 + adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 1475 + 1476 + 1477 + if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) { 1478 + adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 1479 + adjust.temperature_matrix[0] = 1480 + pipe_ctx->stream-> 1481 + public.gamut_remap_matrix.matrix[0]; 1482 + adjust.temperature_matrix[1] = 1483 + pipe_ctx->stream-> 1484 + public.gamut_remap_matrix.matrix[1]; 1485 + adjust.temperature_matrix[2] = 1486 + pipe_ctx->stream-> 1487 + public.gamut_remap_matrix.matrix[2]; 1488 + adjust.temperature_matrix[3] = 1489 + pipe_ctx->stream-> 1490 + public.gamut_remap_matrix.matrix[4]; 1491 + adjust.temperature_matrix[4] = 1492 + pipe_ctx->stream-> 1493 + public.gamut_remap_matrix.matrix[5]; 1494 + adjust.temperature_matrix[5] = 1495 + pipe_ctx->stream-> 1496 + public.gamut_remap_matrix.matrix[6]; 1497 + adjust.temperature_matrix[6] = 1498 + pipe_ctx->stream-> 1499 + public.gamut_remap_matrix.matrix[8]; 1500 + adjust.temperature_matrix[7] = 1501 + pipe_ctx->stream-> 1502 + public.gamut_remap_matrix.matrix[9]; 1503 + adjust.temperature_matrix[8] = 1504 + pipe_ctx->stream-> 1505 + public.gamut_remap_matrix.matrix[10]; 1506 + } 1507 + 1508 + pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust); 1509 + } 1510 + 1511 + static void update_dchubp_dpp( 1512 + struct core_dc *dc, 1513 + struct pipe_ctx *pipe_ctx, 1514 + struct validate_context *context) 1515 + { 1516 + struct mem_input *mi = pipe_ctx->mi; 1517 + struct input_pixel_processor *ipp = pipe_ctx->ipp; 1518 + struct core_surface *surface = pipe_ctx->surface; 1519 + union plane_size size = surface->public.plane_size; 1520 + struct mpc_tree_cfg *tree_cfg = NULL; 1521 + struct default_adjustment ocsc = {0}; 1522 + enum dc_color_space color_space; 1523 + struct tg_color black_color = {0}; 1524 + struct dcn10_mpc *mpc = TO_DCN10_MPC(dc->res_pool->mpc); 1525 + 1526 + /* depends on DML calculation, DPP clock value may change dynamically */ 1527 + enable_dppclk( 1528 + dc->ctx, 1529 + pipe_ctx->pipe_idx, 1530 + pipe_ctx->pix_clk_params.requested_pix_clk, 1531 + context->dppclk_div); 1532 + 1533 + select_vtg(dc->ctx, pipe_ctx->pipe_idx, pipe_ctx->tg->inst); 1534 + 1535 + update_plane_addr(dc, pipe_ctx); 1536 + 1537 + mi->funcs->mem_input_setup( 1538 + mi, 1539 + &pipe_ctx->dlg_regs, 1540 + &pipe_ctx->ttu_regs, 1541 + &pipe_ctx->rq_regs, 1542 + &pipe_ctx->pipe_dlg_param); 1543 + 1544 + size.grph.surface_size = pipe_ctx->scl_data.viewport; 1545 + 1546 + if (dc->public.config.gpu_vm_support) 1547 + mi->funcs->mem_input_program_pte_vm( 1548 + pipe_ctx->mi, 1549 + surface->public.format, 1550 + &surface->public.tiling_info, 1551 + surface->public.rotation); 1552 + 1553 + ipp->funcs->ipp_setup(ipp, 1554 + surface->public.format, 1555 + 1, 1556 + IPP_OUTPUT_FORMAT_12_BIT_FIX); 1557 + 1558 + /* mpc TODO un-hardcode object ids 1559 + * for pseudo code pipe_move.c : 1560 + * add_plane_mpcc(added_plane_inst, mpcc_inst, ...); 1561 + * Do we want to cache the tree_cfg? 1562 + */ 1563 + 1564 + /* TODO: build stream pipes group id. For now, use stream otg 1565 + * id as pipe group id 1566 + */ 1567 + pipe_ctx->mpc_idx = pipe_ctx->tg->inst; 1568 + tree_cfg = &context->res_ctx.mpc_tree[pipe_ctx->mpc_idx]; 1569 + /* enable when bottom pipe is present and 1570 + * it does not share a surface with current pipe 1571 + */ 1572 + if (pipe_ctx->bottom_pipe && surface != pipe_ctx->bottom_pipe->surface) { 1573 + pipe_ctx->scl_data.lb_params.alpha_en = 1; 1574 + tree_cfg->mode = TOP_BLND; 1575 + } else { 1576 + pipe_ctx->scl_data.lb_params.alpha_en = 0; 1577 + tree_cfg->mode = TOP_PASSTHRU; 1578 + } 1579 + if (!pipe_ctx->top_pipe) { 1580 + /* primary pipe, set mpc tree index 0 only */ 1581 + tree_cfg->num_pipes = 1; 1582 + tree_cfg->opp_id = pipe_ctx->tg->inst; 1583 + tree_cfg->dpp[0] = pipe_ctx->pipe_idx; 1584 + tree_cfg->mpcc[0] = pipe_ctx->pipe_idx; 1585 + dcn10_set_mpc_tree(mpc, tree_cfg); 1586 + } else { 1587 + /* TODO: add position is hard code to 1 for now 1588 + * If more than 2 pipes are supported, calculate position 1589 + */ 1590 + dcn10_add_dpp(mpc, tree_cfg, 1591 + pipe_ctx->pipe_idx, pipe_ctx->pipe_idx, 1); 1592 + } 1593 + 1594 + color_space = pipe_ctx->stream->public.output_color_space; 1595 + color_space_to_black_color(dc, color_space, &black_color); 1596 + dcn10_set_mpc_background_color(mpc, pipe_ctx->pipe_idx, &black_color); 1597 + 1598 + pipe_ctx->scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; 1599 + /* scaler configuration */ 1600 + pipe_ctx->xfm->funcs->transform_set_scaler( 1601 + pipe_ctx->xfm, &pipe_ctx->scl_data); 1602 + 1603 + /*gamut remap*/ 1604 + program_gamut_remap(pipe_ctx); 1605 + 1606 + /*TODO add adjustments parameters*/ 1607 + ocsc.out_color_space = pipe_ctx->stream->public.output_color_space; 1608 + pipe_ctx->opp->funcs->opp_set_csc_default(pipe_ctx->opp, &ocsc); 1609 + 1610 + mi->funcs->mem_input_program_surface_config( 1611 + mi, 1612 + surface->public.format, 1613 + &surface->public.tiling_info, 1614 + &size, 1615 + surface->public.rotation, 1616 + &surface->public.dcc, 1617 + surface->public.horizontal_mirror, 1618 + surface->public.visible); 1619 + 1620 + /* Only support one plane for now. */ 1621 + pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, !surface->public.visible); 1622 + 1623 + } 1624 + 1625 + static void program_all_pipe_in_tree( 1626 + struct core_dc *dc, 1627 + struct pipe_ctx *pipe_ctx, 1628 + struct validate_context *context) 1629 + { 1630 + unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000; 1631 + 1632 + if (pipe_ctx->surface->public.visible || pipe_ctx->top_pipe == NULL) { 1633 + dcn10_power_on_fe(dc, pipe_ctx, context); 1634 + 1635 + /* lock otg_master_update to process all pipes associated with 1636 + * this OTG. this is done only one time. 1637 + */ 1638 + if (pipe_ctx->top_pipe == NULL) { 1639 + /* watermark is for all pipes */ 1640 + pipe_ctx->mi->funcs->program_watermarks( 1641 + pipe_ctx->mi, &context->watermarks, ref_clk_mhz); 1642 + lock_otg_master_update(dc->ctx, pipe_ctx->tg->inst); 1643 + } 1644 + pipe_ctx->tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset; 1645 + pipe_ctx->tg->dlg_otg_param.vstartup_start = pipe_ctx->pipe_dlg_param.vstartup_start; 1646 + pipe_ctx->tg->dlg_otg_param.vupdate_offset = pipe_ctx->pipe_dlg_param.vupdate_offset; 1647 + pipe_ctx->tg->dlg_otg_param.vupdate_width = pipe_ctx->pipe_dlg_param.vupdate_width; 1648 + pipe_ctx->tg->dlg_otg_param.signal = pipe_ctx->stream->signal; 1649 + pipe_ctx->tg->funcs->program_global_sync( 1650 + pipe_ctx->tg); 1651 + update_dchubp_dpp(dc, pipe_ctx, context); 1652 + } 1653 + 1654 + if (pipe_ctx->bottom_pipe != NULL) 1655 + program_all_pipe_in_tree(dc, pipe_ctx->bottom_pipe, context); 1656 + } 1657 + 1658 + static void dcn10_pplib_apply_display_requirements( 1659 + struct core_dc *dc, 1660 + struct validate_context *context) 1661 + { 1662 + struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 1663 + 1664 + pp_display_cfg->all_displays_in_sync = false;/*todo*/ 1665 + pp_display_cfg->nb_pstate_switch_disable = false; 1666 + pp_display_cfg->min_engine_clock_khz = context->dcfclk_khz; 1667 + pp_display_cfg->min_memory_clock_khz = context->fclk_khz; 1668 + pp_display_cfg->min_engine_clock_deep_sleep_khz = context->dcfclk_deep_sleep_khz; 1669 + pp_display_cfg->min_dcfc_deep_sleep_clock_khz = context->dcfclk_deep_sleep_khz; 1670 + pp_display_cfg->avail_mclk_switch_time_us = 1671 + context->dram_ccm_us > 0 ? context->dram_ccm_us : 0; 1672 + pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 1673 + context->min_active_dram_ccm_us > 0 ? context->min_active_dram_ccm_us : 0; 1674 + pp_display_cfg->min_dcfclock_khz = context->dcfclk_khz; 1675 + pp_display_cfg->disp_clk_khz = context->dispclk_khz; 1676 + dce110_fill_display_configs(context, pp_display_cfg); 1677 + 1678 + if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( 1679 + struct dm_pp_display_configuration)) != 0) 1680 + dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); 1681 + 1682 + dc->prev_display_config = *pp_display_cfg; 1683 + } 1684 + 1685 + static void dcn10_apply_ctx_for_surface( 1686 + struct core_dc *dc, 1687 + struct core_surface *surface, 1688 + struct validate_context *context) 1689 + { 1690 + int i; 1691 + 1692 + memcpy(context->res_ctx.mpc_tree, 1693 + dc->current_context->res_ctx.mpc_tree, 1694 + sizeof(struct mpc_tree_cfg) * dc->res_pool->pipe_count); 1695 + 1696 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 1697 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1698 + 1699 + if (!pipe_ctx->surface) 1700 + continue; 1701 + 1702 + /* looking for top pipe to program */ 1703 + if (!pipe_ctx->top_pipe) 1704 + program_all_pipe_in_tree(dc, pipe_ctx, context); 1705 + } 1706 + 1707 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 1708 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1709 + 1710 + if (!pipe_ctx->surface || pipe_ctx->top_pipe) 1711 + continue; 1712 + 1713 + /* unlock master update lock */ 1714 + unlock_otg_master(dc->ctx, pipe_ctx->tg->inst); 1715 + } 1716 + 1717 + /* reset unused pipe */ 1718 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 1719 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1720 + struct pipe_ctx *old_pipe_ctx = 1721 + &dc->current_context->res_ctx.pipe_ctx[i]; 1722 + 1723 + if ((!pipe_ctx->surface && old_pipe_ctx->surface) 1724 + || (!pipe_ctx->stream && old_pipe_ctx->stream)) 1725 + reset_front_end_for_pipe(dc, 1726 + old_pipe_ctx, dc->current_context); 1727 + } 1728 + } 1729 + 1730 + static void dcn10_set_bandwidth( 1731 + struct core_dc *dc, 1732 + struct validate_context *context, 1733 + bool decrease_allowed) 1734 + { 1735 + struct dm_pp_clock_for_voltage_req clock; 1736 + 1737 + if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) 1738 + return; 1739 + 1740 + if (decrease_allowed || context->dispclk_khz > dc->current_context->dispclk_khz) { 1741 + dc->res_pool->display_clock->funcs->set_clock( 1742 + dc->res_pool->display_clock, 1743 + context->dispclk_khz); 1744 + dc->current_context->dispclk_khz = context->dispclk_khz; 1745 + } 1746 + if (decrease_allowed || context->dcfclk_khz > dc->current_context->dcfclk_khz) { 1747 + clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; 1748 + clock.clocks_in_khz = context->dcfclk_khz; 1749 + dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 1750 + } 1751 + if (decrease_allowed || context->fclk_khz > dc->current_context->fclk_khz) { 1752 + clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; 1753 + clock.clocks_in_khz = context->fclk_khz; 1754 + dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 1755 + dc->current_context->fclk_khz = clock.clocks_in_khz ; 1756 + } 1757 + dcn10_pplib_apply_display_requirements(dc, context); 1758 + } 1759 + 1760 + static void dcn10_power_down_fe(struct core_dc *dc, struct pipe_ctx *pipe) 1761 + { 1762 + struct dc_context *ctx = dc->ctx; 1763 + uint32_t inst_offset = 0; 1764 + 1765 + HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, 1766 + IP_REQUEST_EN, 1); 1767 + dpp_pg_control(ctx, pipe->pipe_idx, false); 1768 + hubp_pg_control(ctx, pipe->pipe_idx, false); 1769 + HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, 1770 + IP_REQUEST_EN, 0); 1771 + 1772 + if (pipe->xfm) 1773 + pipe->xfm->funcs->transform_reset(pipe->xfm); 1774 + memset(&pipe->scl_data, 0, sizeof(pipe->scl_data)); 1775 + } 1776 + 1777 + static void set_drr(struct pipe_ctx **pipe_ctx, 1778 + int num_pipes, int vmin, int vmax) 1779 + { 1780 + int i = 0; 1781 + struct drr_params params = {0}; 1782 + 1783 + params.vertical_total_max = vmax; 1784 + params.vertical_total_min = vmin; 1785 + 1786 + /* TODO: If multiple pipes are to be supported, you need 1787 + * some GSL stuff 1788 + */ 1789 + for (i = 0; i < num_pipes; i++) { 1790 + pipe_ctx[i]->tg->funcs->set_drr(pipe_ctx[i]->tg, &params); 1791 + } 1792 + } 1793 + 1794 + static void get_position(struct pipe_ctx **pipe_ctx, 1795 + int num_pipes, 1796 + struct crtc_position *position) 1797 + { 1798 + int i = 0; 1799 + 1800 + /* TODO: handle pipes > 1 1801 + */ 1802 + for (i = 0; i < num_pipes; i++) 1803 + pipe_ctx[i]->tg->funcs->get_position(pipe_ctx[i]->tg, position); 1804 + } 1805 + 1806 + static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 1807 + int num_pipes, const struct dc_static_screen_events *events) 1808 + { 1809 + unsigned int i; 1810 + unsigned int value = 0; 1811 + 1812 + if (events->surface_update) 1813 + value |= 0x80; 1814 + if (events->cursor_update) 1815 + value |= 0x2; 1816 + 1817 + for (i = 0; i < num_pipes; i++) 1818 + pipe_ctx[i]->tg->funcs-> 1819 + set_static_screen_control(pipe_ctx[i]->tg, value); 1820 + } 1821 + 1822 + static void set_plane_config( 1823 + const struct core_dc *dc, 1824 + struct pipe_ctx *pipe_ctx, 1825 + struct resource_context *res_ctx) 1826 + { 1827 + /* TODO */ 1828 + program_gamut_remap(pipe_ctx); 1829 + } 1830 + 1831 + static const struct hw_sequencer_funcs dcn10_funcs = { 1832 + .init_hw = init_hw, 1833 + .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 1834 + .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, 1835 + .set_plane_config = set_plane_config, 1836 + .update_plane_addr = update_plane_addr, 1837 + .update_pending_status = dce110_update_pending_status, 1838 + .set_input_transfer_func = dcn10_set_input_transfer_func, 1839 + .set_output_transfer_func = dcn10_set_output_transfer_func, 1840 + .power_down = dce110_power_down, 1841 + .enable_accelerated_mode = dce110_enable_accelerated_mode, 1842 + .enable_timing_synchronization = dcn10_enable_timing_synchronization, 1843 + .update_info_frame = dce110_update_info_frame, 1844 + .enable_stream = dce110_enable_stream, 1845 + .disable_stream = dce110_disable_stream, 1846 + .unblank_stream = dce110_unblank_stream, 1847 + .enable_display_pipe_clock_gating = NULL, /* TODOFPGA */ 1848 + .enable_display_power_gating = dcn10_enable_display_power_gating, 1849 + .power_down_front_end = dcn10_power_down_fe, 1850 + .power_on_front_end = dcn10_power_on_fe, 1851 + .pipe_control_lock = dcn10_pipe_control_lock, 1852 + .set_bandwidth = dcn10_set_bandwidth, 1853 + .reset_hw_ctx_wrap = reset_hw_ctx_wrap, 1854 + .prog_pixclk_crtc_otg = dcn10_prog_pixclk_crtc_otg, 1855 + .set_drr = set_drr, 1856 + .get_position = get_position, 1857 + .set_static_screen_control = set_static_screen_control 1858 + }; 1859 + 1860 + 1861 + bool dcn10_hw_sequencer_construct(struct core_dc *dc) 1862 + { 1863 + dc->hwss = dcn10_funcs; 1864 + return true; 1865 + } 1866 +
+38
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
··· 1 + /* 2 + * Copyright 2016 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 + #ifndef __DC_HWSS_DCN10_H__ 27 + #define __DC_HWSS_DCN10_H__ 28 + 29 + #include "core_types.h" 30 + 31 + struct core_dc; 32 + 33 + bool dcn10_hw_sequencer_construct(struct core_dc *dc); 34 + extern void fill_display_configs( 35 + const struct validate_context *context, 36 + struct dm_pp_display_configuration *pp_display_cfg); 37 + 38 + #endif /* __DC_HWSS_DCN10_H__ */
+883
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
··· 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 "dm_services.h" 27 + #include "dcn10_ipp.h" 28 + #include "reg_helper.h" 29 + 30 + #define REG(reg) \ 31 + (ippn10->regs->reg) 32 + 33 + #undef FN 34 + #define FN(reg_name, field_name) \ 35 + ippn10->ipp_shift->field_name, ippn10->ipp_mask->field_name 36 + 37 + #define CTX \ 38 + ippn10->base.ctx 39 + 40 + 41 + struct dcn10_input_csc_matrix { 42 + enum dc_color_space color_space; 43 + uint32_t regval[12]; 44 + }; 45 + 46 + static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = { 47 + {COLOR_SPACE_SRGB, 48 + {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, 49 + {COLOR_SPACE_SRGB_LIMITED, 50 + {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, 51 + {COLOR_SPACE_YCBCR601, 52 + {0x2cdd, 0x2000, 0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef, 53 + 0, 0x2000, 0x38b4, 0xe3a6} }, 54 + {COLOR_SPACE_YCBCR601_LIMITED, 55 + {0x3353, 0x2568, 0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108, 56 + 0, 0x2568, 0x40de, 0xdd3a} }, 57 + {COLOR_SPACE_YCBCR709, 58 + {0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0, 59 + 0x2000, 0x3b61, 0xe24f} }, 60 + 61 + {COLOR_SPACE_YCBCR709_LIMITED, 62 + {0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0, 63 + 0x2568, 0x43ee, 0xdbb2} } 64 + }; 65 + 66 + enum dcn10_input_csc_select { 67 + INPUT_CSC_SELECT_BYPASS = 0, 68 + INPUT_CSC_SELECT_ICSC, 69 + INPUT_CSC_SELECT_COMA 70 + }; 71 + 72 + static void dcn10_program_input_csc( 73 + struct input_pixel_processor *ipp, 74 + enum dc_color_space color_space, 75 + enum dcn10_input_csc_select select) 76 + { 77 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 78 + int i; 79 + int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix); 80 + const uint32_t *regval = NULL; 81 + uint32_t selection = 1; 82 + 83 + if (select == INPUT_CSC_SELECT_BYPASS) { 84 + REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0); 85 + return; 86 + } 87 + 88 + for (i = 0; i < arr_size; i++) 89 + if (dcn10_input_csc_matrix[i].color_space == color_space) { 90 + regval = dcn10_input_csc_matrix[i].regval; 91 + break; 92 + } 93 + 94 + if (regval == NULL) { 95 + BREAK_TO_DEBUGGER(); 96 + return; 97 + } 98 + 99 + if (select == INPUT_CSC_SELECT_COMA) 100 + selection = 2; 101 + REG_SET(CM_ICSC_CONTROL, 0, 102 + CM_ICSC_MODE, selection); 103 + 104 + if (select == INPUT_CSC_SELECT_ICSC) { 105 + /*R*/ 106 + REG_SET_2(CM_ICSC_C11_C12, 0, 107 + CM_ICSC_C11, regval[0], 108 + CM_ICSC_C12, regval[1]); 109 + regval += 2; 110 + REG_SET_2(CM_ICSC_C13_C14, 0, 111 + CM_ICSC_C13, regval[0], 112 + CM_ICSC_C14, regval[1]); 113 + /*G*/ 114 + regval += 2; 115 + REG_SET_2(CM_ICSC_C21_C22, 0, 116 + CM_ICSC_C21, regval[0], 117 + CM_ICSC_C22, regval[1]); 118 + regval += 2; 119 + REG_SET_2(CM_ICSC_C23_C24, 0, 120 + CM_ICSC_C23, regval[0], 121 + CM_ICSC_C24, regval[1]); 122 + /*B*/ 123 + regval += 2; 124 + REG_SET_2(CM_ICSC_C31_C32, 0, 125 + CM_ICSC_C31, regval[0], 126 + CM_ICSC_C32, regval[1]); 127 + regval += 2; 128 + REG_SET_2(CM_ICSC_C33_C34, 0, 129 + CM_ICSC_C33, regval[0], 130 + CM_ICSC_C34, regval[1]); 131 + } else { 132 + /*R*/ 133 + REG_SET_2(CM_COMA_C11_C12, 0, 134 + CM_COMA_C11, regval[0], 135 + CM_COMA_C12, regval[1]); 136 + regval += 2; 137 + REG_SET_2(CM_COMA_C13_C14, 0, 138 + CM_COMA_C13, regval[0], 139 + CM_COMA_C14, regval[1]); 140 + /*G*/ 141 + regval += 2; 142 + REG_SET_2(CM_COMA_C21_C22, 0, 143 + CM_COMA_C21, regval[0], 144 + CM_COMA_C22, regval[1]); 145 + regval += 2; 146 + REG_SET_2(CM_COMA_C23_C24, 0, 147 + CM_COMA_C23, regval[0], 148 + CM_COMA_C24, regval[1]); 149 + /*B*/ 150 + regval += 2; 151 + REG_SET_2(CM_COMA_C31_C32, 0, 152 + CM_COMA_C31, regval[0], 153 + CM_COMA_C32, regval[1]); 154 + regval += 2; 155 + REG_SET_2(CM_COMA_C33_C34, 0, 156 + CM_COMA_C33, regval[0], 157 + CM_COMA_C34, regval[1]); 158 + } 159 + } 160 + 161 + /*program de gamma RAM B*/ 162 + static void dcn10_ipp_program_degamma_lutb_settings( 163 + struct input_pixel_processor *ipp, 164 + const struct pwl_params *params) 165 + { 166 + const struct gamma_curve *curve; 167 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 168 + 169 + REG_SET_2(CM_DGAM_RAMB_START_CNTL_B, 0, 170 + CM_DGAM_RAMB_EXP_REGION_START_B, params->arr_points[0].custom_float_x, 171 + CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_B, 0); 172 + 173 + REG_SET_2(CM_DGAM_RAMB_START_CNTL_G, 0, 174 + CM_DGAM_RAMB_EXP_REGION_START_G, params->arr_points[0].custom_float_x, 175 + CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_G, 0); 176 + 177 + REG_SET_2(CM_DGAM_RAMB_START_CNTL_R, 0, 178 + CM_DGAM_RAMB_EXP_REGION_START_R, params->arr_points[0].custom_float_x, 179 + CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_R, 0); 180 + 181 + REG_SET(CM_DGAM_RAMB_SLOPE_CNTL_B, 0, 182 + CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B, params->arr_points[0].custom_float_slope); 183 + 184 + REG_SET(CM_DGAM_RAMB_SLOPE_CNTL_G, 0, 185 + CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_G, params->arr_points[0].custom_float_slope); 186 + 187 + REG_SET(CM_DGAM_RAMB_SLOPE_CNTL_R, 0, 188 + CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_R, params->arr_points[0].custom_float_slope); 189 + 190 + REG_SET(CM_DGAM_RAMB_END_CNTL1_B, 0, 191 + CM_DGAM_RAMB_EXP_REGION_END_B, params->arr_points[1].custom_float_x); 192 + 193 + REG_SET_2(CM_DGAM_RAMB_END_CNTL2_B, 0, 194 + CM_DGAM_RAMB_EXP_REGION_END_SLOPE_B, params->arr_points[1].custom_float_y, 195 + CM_DGAM_RAMB_EXP_REGION_END_BASE_B, params->arr_points[2].custom_float_slope); 196 + 197 + REG_SET(CM_DGAM_RAMB_END_CNTL1_G, 0, 198 + CM_DGAM_RAMB_EXP_REGION_END_G, params->arr_points[1].custom_float_x); 199 + 200 + REG_SET_2(CM_DGAM_RAMB_END_CNTL2_G, 0, 201 + CM_DGAM_RAMB_EXP_REGION_END_SLOPE_G, params->arr_points[1].custom_float_y, 202 + CM_DGAM_RAMB_EXP_REGION_END_BASE_G, params->arr_points[2].custom_float_slope); 203 + 204 + REG_SET(CM_DGAM_RAMB_END_CNTL1_R, 0, 205 + CM_DGAM_RAMB_EXP_REGION_END_R, params->arr_points[1].custom_float_x); 206 + 207 + REG_SET_2(CM_DGAM_RAMB_END_CNTL2_R, 0, 208 + CM_DGAM_RAMB_EXP_REGION_END_SLOPE_R, params->arr_points[1].custom_float_y, 209 + CM_DGAM_RAMB_EXP_REGION_END_BASE_R, params->arr_points[2].custom_float_slope); 210 + 211 + curve = params->arr_curve_points; 212 + REG_SET_4(CM_DGAM_RAMB_REGION_0_1, 0, 213 + CM_DGAM_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset, 214 + CM_DGAM_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 215 + CM_DGAM_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset, 216 + CM_DGAM_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 217 + 218 + curve += 2; 219 + REG_SET_4(CM_DGAM_RAMB_REGION_2_3, 0, 220 + CM_DGAM_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset, 221 + CM_DGAM_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 222 + CM_DGAM_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset, 223 + CM_DGAM_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 224 + 225 + curve += 2; 226 + REG_SET_4(CM_DGAM_RAMB_REGION_4_5, 0, 227 + CM_DGAM_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset, 228 + CM_DGAM_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 229 + CM_DGAM_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset, 230 + CM_DGAM_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 231 + 232 + curve += 2; 233 + REG_SET_4(CM_DGAM_RAMB_REGION_6_7, 0, 234 + CM_DGAM_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset, 235 + CM_DGAM_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 236 + CM_DGAM_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset, 237 + CM_DGAM_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 238 + 239 + curve += 2; 240 + REG_SET_4(CM_DGAM_RAMB_REGION_8_9, 0, 241 + CM_DGAM_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset, 242 + CM_DGAM_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 243 + CM_DGAM_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset, 244 + CM_DGAM_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 245 + 246 + curve += 2; 247 + REG_SET_4(CM_DGAM_RAMB_REGION_10_11, 0, 248 + CM_DGAM_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset, 249 + CM_DGAM_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 250 + CM_DGAM_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset, 251 + CM_DGAM_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 252 + 253 + curve += 2; 254 + REG_SET_4(CM_DGAM_RAMB_REGION_12_13, 0, 255 + CM_DGAM_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset, 256 + CM_DGAM_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 257 + CM_DGAM_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset, 258 + CM_DGAM_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 259 + 260 + curve += 2; 261 + REG_SET_4(CM_DGAM_RAMB_REGION_14_15, 0, 262 + CM_DGAM_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset, 263 + CM_DGAM_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 264 + CM_DGAM_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset, 265 + CM_DGAM_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 266 + } 267 + 268 + /*program de gamma RAM A*/ 269 + static void dcn10_ipp_program_degamma_luta_settings( 270 + struct input_pixel_processor *ipp, 271 + const struct pwl_params *params) 272 + { 273 + const struct gamma_curve *curve; 274 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 275 + 276 + REG_SET_2(CM_DGAM_RAMA_START_CNTL_B, 0, 277 + CM_DGAM_RAMA_EXP_REGION_START_B, params->arr_points[0].custom_float_x, 278 + CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_B, 0); 279 + 280 + REG_SET_2(CM_DGAM_RAMA_START_CNTL_G, 0, 281 + CM_DGAM_RAMA_EXP_REGION_START_G, params->arr_points[0].custom_float_x, 282 + CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_G, 0); 283 + 284 + REG_SET_2(CM_DGAM_RAMA_START_CNTL_R, 0, 285 + CM_DGAM_RAMA_EXP_REGION_START_R, params->arr_points[0].custom_float_x, 286 + CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_R, 0); 287 + 288 + REG_SET(CM_DGAM_RAMA_SLOPE_CNTL_B, 0, 289 + CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B, params->arr_points[0].custom_float_slope); 290 + 291 + REG_SET(CM_DGAM_RAMA_SLOPE_CNTL_G, 0, 292 + CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_G, params->arr_points[0].custom_float_slope); 293 + 294 + REG_SET(CM_DGAM_RAMA_SLOPE_CNTL_R, 0, 295 + CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_R, params->arr_points[0].custom_float_slope); 296 + 297 + REG_SET(CM_DGAM_RAMA_END_CNTL1_B, 0, 298 + CM_DGAM_RAMA_EXP_REGION_END_B, params->arr_points[1].custom_float_x); 299 + 300 + REG_SET_2(CM_DGAM_RAMA_END_CNTL2_B, 0, 301 + CM_DGAM_RAMA_EXP_REGION_END_SLOPE_B, params->arr_points[1].custom_float_y, 302 + CM_DGAM_RAMA_EXP_REGION_END_BASE_B, params->arr_points[2].custom_float_slope); 303 + 304 + REG_SET(CM_DGAM_RAMA_END_CNTL1_G, 0, 305 + CM_DGAM_RAMA_EXP_REGION_END_G, params->arr_points[1].custom_float_x); 306 + 307 + REG_SET_2(CM_DGAM_RAMA_END_CNTL2_G, 0, 308 + CM_DGAM_RAMA_EXP_REGION_END_SLOPE_G, params->arr_points[1].custom_float_y, 309 + CM_DGAM_RAMA_EXP_REGION_END_BASE_G, params->arr_points[2].custom_float_slope); 310 + 311 + REG_SET(CM_DGAM_RAMA_END_CNTL1_R, 0, 312 + CM_DGAM_RAMA_EXP_REGION_END_R, params->arr_points[1].custom_float_x); 313 + 314 + REG_SET_2(CM_DGAM_RAMA_END_CNTL2_R, 0, 315 + CM_DGAM_RAMA_EXP_REGION_END_SLOPE_R, params->arr_points[1].custom_float_y, 316 + CM_DGAM_RAMA_EXP_REGION_END_BASE_R, params->arr_points[2].custom_float_slope); 317 + 318 + curve = params->arr_curve_points; 319 + REG_SET_4(CM_DGAM_RAMA_REGION_0_1, 0, 320 + CM_DGAM_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 321 + CM_DGAM_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 322 + CM_DGAM_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 323 + CM_DGAM_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 324 + 325 + curve += 2; 326 + REG_SET_4(CM_DGAM_RAMA_REGION_2_3, 0, 327 + CM_DGAM_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset, 328 + CM_DGAM_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 329 + CM_DGAM_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset, 330 + CM_DGAM_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 331 + 332 + curve += 2; 333 + REG_SET_4(CM_DGAM_RAMA_REGION_4_5, 0, 334 + CM_DGAM_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset, 335 + CM_DGAM_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 336 + CM_DGAM_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset, 337 + CM_DGAM_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 338 + 339 + curve += 2; 340 + REG_SET_4(CM_DGAM_RAMA_REGION_6_7, 0, 341 + CM_DGAM_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset, 342 + CM_DGAM_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 343 + CM_DGAM_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset, 344 + CM_DGAM_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 345 + 346 + curve += 2; 347 + REG_SET_4(CM_DGAM_RAMA_REGION_8_9, 0, 348 + CM_DGAM_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset, 349 + CM_DGAM_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 350 + CM_DGAM_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset, 351 + CM_DGAM_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 352 + 353 + curve += 2; 354 + REG_SET_4(CM_DGAM_RAMA_REGION_10_11, 0, 355 + CM_DGAM_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset, 356 + CM_DGAM_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 357 + CM_DGAM_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset, 358 + CM_DGAM_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 359 + 360 + curve += 2; 361 + REG_SET_4(CM_DGAM_RAMA_REGION_12_13, 0, 362 + CM_DGAM_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset, 363 + CM_DGAM_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 364 + CM_DGAM_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset, 365 + CM_DGAM_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 366 + 367 + curve += 2; 368 + REG_SET_4(CM_DGAM_RAMA_REGION_14_15, 0, 369 + CM_DGAM_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset, 370 + CM_DGAM_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 371 + CM_DGAM_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset, 372 + CM_DGAM_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 373 + } 374 + 375 + static void ipp_power_on_degamma_lut( 376 + struct input_pixel_processor *ipp, 377 + bool power_on) 378 + { 379 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 380 + 381 + REG_SET(CM_MEM_PWR_CTRL, 0, 382 + SHARED_MEM_PWR_DIS, power_on == true ? 0:1); 383 + 384 + } 385 + 386 + static void ipp_program_degamma_lut( 387 + struct input_pixel_processor *ipp, 388 + const struct pwl_result_data *rgb, 389 + uint32_t num, 390 + bool is_ram_a) 391 + { 392 + uint32_t i; 393 + 394 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 395 + REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, 0); 396 + REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, 397 + CM_DGAM_LUT_WRITE_EN_MASK, 7); 398 + REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL, 399 + is_ram_a == true ? 0:1); 400 + 401 + REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0); 402 + for (i = 0 ; i < num; i++) { 403 + REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg); 404 + REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg); 405 + REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg); 406 + 407 + REG_SET(CM_DGAM_LUT_DATA, 0, 408 + CM_DGAM_LUT_DATA, rgb[i].delta_red_reg); 409 + REG_SET(CM_DGAM_LUT_DATA, 0, 410 + CM_DGAM_LUT_DATA, rgb[i].delta_green_reg); 411 + REG_SET(CM_DGAM_LUT_DATA, 0, 412 + CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg); 413 + 414 + } 415 + 416 + } 417 + 418 + static void dcn10_ipp_enable_cm_block( 419 + struct input_pixel_processor *ipp) 420 + { 421 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 422 + 423 + REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 1); 424 + REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0); 425 + } 426 + 427 + 428 + static void dcn10_ipp_full_bypass(struct input_pixel_processor *ipp) 429 + { 430 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 431 + 432 + /* Input pixel format: ARGB8888 */ 433 + REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, 434 + CNVC_SURFACE_PIXEL_FORMAT, 0x8); 435 + 436 + /* Zero expansion */ 437 + REG_SET_3(FORMAT_CONTROL, 0, 438 + CNVC_BYPASS, 0, 439 + ALPHA_EN, 0, 440 + FORMAT_EXPANSION_MODE, 0); 441 + 442 + /* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */ 443 + REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1); 444 + 445 + /* Setting degamma bypass for now */ 446 + REG_SET(CM_DGAM_CONTROL, 0, CM_DGAM_LUT_MODE, 0); 447 + REG_SET(CM_IGAM_CONTROL, 0, CM_IGAM_LUT_MODE, 0); 448 + } 449 + 450 + static void dcn10_ipp_set_degamma( 451 + struct input_pixel_processor *ipp, 452 + enum ipp_degamma_mode mode) 453 + { 454 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 455 + dcn10_ipp_enable_cm_block(ipp); 456 + 457 + switch (mode) { 458 + case IPP_DEGAMMA_MODE_BYPASS: 459 + /* Setting de gamma bypass for now */ 460 + REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0); 461 + break; 462 + case IPP_DEGAMMA_MODE_HW_sRGB: 463 + REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1); 464 + break; 465 + case IPP_DEGAMMA_MODE_HW_xvYCC: 466 + REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2); 467 + break; 468 + default: 469 + BREAK_TO_DEBUGGER(); 470 + break; 471 + } 472 + } 473 + 474 + static bool dcn10_cursor_program_control( 475 + struct dcn10_ipp *ippn10, 476 + bool pixel_data_invert, 477 + enum dc_cursor_color_format color_format) 478 + { 479 + REG_SET_2(CURSOR_SETTINS, 0, 480 + /* no shift of the cursor HDL schedule */ 481 + CURSOR0_DST_Y_OFFSET, 0, 482 + /* used to shift the cursor chunk request deadline */ 483 + CURSOR0_CHUNK_HDL_ADJUST, 3); 484 + 485 + REG_UPDATE_2(CURSOR0_CONTROL, 486 + CUR0_MODE, color_format, 487 + CUR0_INVERT_MODE, 0); 488 + 489 + if (color_format == CURSOR_MODE_MONO) { 490 + /* todo: clarify what to program these to */ 491 + REG_UPDATE(CURSOR0_COLOR0, 492 + CUR0_COLOR0, 0x00000000); 493 + REG_UPDATE(CURSOR0_COLOR1, 494 + CUR0_COLOR1, 0xFFFFFFFF); 495 + } 496 + 497 + /* TODO: Fixed vs float */ 498 + 499 + REG_UPDATE_3(FORMAT_CONTROL, 500 + CNVC_BYPASS, 0, 501 + ALPHA_EN, 1, 502 + FORMAT_EXPANSION_MODE, 0); 503 + 504 + REG_UPDATE(CURSOR0_CONTROL, 505 + CUR0_EXPANSION_MODE, 0); 506 + 507 + if (0 /*attributes->attribute_flags.bits.MIN_MAX_INVERT*/) { 508 + REG_UPDATE(CURSOR0_CONTROL, 509 + CUR0_MAX, 510 + 0 /* TODO */); 511 + REG_UPDATE(CURSOR0_CONTROL, 512 + CUR0_MIN, 513 + 0 /* TODO */); 514 + } 515 + 516 + return true; 517 + } 518 + 519 + enum cursor_pitch { 520 + CURSOR_PITCH_64_PIXELS = 0, 521 + CURSOR_PITCH_128_PIXELS, 522 + CURSOR_PITCH_256_PIXELS 523 + }; 524 + 525 + enum cursor_lines_per_chunk { 526 + CURSOR_LINE_PER_CHUNK_2 = 1, 527 + CURSOR_LINE_PER_CHUNK_4, 528 + CURSOR_LINE_PER_CHUNK_8, 529 + CURSOR_LINE_PER_CHUNK_16 530 + }; 531 + 532 + static enum cursor_pitch dcn10_get_cursor_pitch( 533 + unsigned int pitch) 534 + { 535 + enum cursor_pitch hw_pitch; 536 + 537 + switch (pitch) { 538 + case 64: 539 + hw_pitch = CURSOR_PITCH_64_PIXELS; 540 + break; 541 + case 128: 542 + hw_pitch = CURSOR_PITCH_128_PIXELS; 543 + break; 544 + case 256: 545 + hw_pitch = CURSOR_PITCH_256_PIXELS; 546 + break; 547 + default: 548 + DC_ERR("Invalid cursor pitch of %d. " 549 + "Only 64/128/256 is supported on DCN.\n", pitch); 550 + hw_pitch = CURSOR_PITCH_64_PIXELS; 551 + break; 552 + } 553 + return hw_pitch; 554 + } 555 + 556 + static enum cursor_lines_per_chunk dcn10_get_lines_per_chunk( 557 + unsigned int cur_width, 558 + enum dc_cursor_color_format format) 559 + { 560 + enum cursor_lines_per_chunk line_per_chunk; 561 + 562 + if (format == CURSOR_MODE_MONO) 563 + /* impl B. expansion in CUR Buffer reader */ 564 + line_per_chunk = CURSOR_LINE_PER_CHUNK_16; 565 + else if (cur_width <= 32) 566 + line_per_chunk = CURSOR_LINE_PER_CHUNK_16; 567 + else if (cur_width <= 64) 568 + line_per_chunk = CURSOR_LINE_PER_CHUNK_8; 569 + else if (cur_width <= 128) 570 + line_per_chunk = CURSOR_LINE_PER_CHUNK_4; 571 + else 572 + line_per_chunk = CURSOR_LINE_PER_CHUNK_2; 573 + 574 + return line_per_chunk; 575 + } 576 + 577 + static void dcn10_cursor_set_attributes( 578 + struct input_pixel_processor *ipp, 579 + const struct dc_cursor_attributes *attr) 580 + { 581 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 582 + enum cursor_pitch hw_pitch = dcn10_get_cursor_pitch(attr->pitch); 583 + enum cursor_lines_per_chunk lpc = dcn10_get_lines_per_chunk( 584 + attr->width, attr->color_format); 585 + 586 + ippn10->curs_attr = *attr; 587 + 588 + REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH, 589 + CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part); 590 + REG_UPDATE(CURSOR_SURFACE_ADDRESS, 591 + CURSOR_SURFACE_ADDRESS, attr->address.low_part); 592 + 593 + REG_UPDATE_2(CURSOR_SIZE, 594 + CURSOR_WIDTH, attr->width, 595 + CURSOR_HEIGHT, attr->height); 596 + 597 + REG_UPDATE_3(CURSOR_CONTROL, 598 + CURSOR_MODE, attr->color_format, 599 + CURSOR_PITCH, hw_pitch, 600 + CURSOR_LINES_PER_CHUNK, lpc); 601 + 602 + dcn10_cursor_program_control(ippn10, 603 + attr->attribute_flags.bits.INVERT_PIXEL_DATA, 604 + attr->color_format); 605 + } 606 + 607 + static void dcn10_cursor_set_position( 608 + struct input_pixel_processor *ipp, 609 + const struct dc_cursor_position *pos, 610 + const struct dc_cursor_mi_param *param) 611 + { 612 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 613 + int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; 614 + uint32_t cur_en = pos->enable ? 1 : 0; 615 + uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; 616 + 617 + dst_x_offset *= param->ref_clk_khz; 618 + dst_x_offset /= param->pixel_clk_khz; 619 + 620 + ASSERT(param->h_scale_ratio.value); 621 + 622 + if (param->h_scale_ratio.value) 623 + dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div( 624 + dal_fixed31_32_from_int(dst_x_offset), 625 + param->h_scale_ratio)); 626 + 627 + if (src_x_offset >= (int)param->viewport_width) 628 + cur_en = 0; /* not visible beyond right edge*/ 629 + 630 + if (src_x_offset + (int)ippn10->curs_attr.width < 0) 631 + cur_en = 0; /* not visible beyond left edge*/ 632 + 633 + if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) 634 + dcn10_cursor_set_attributes(ipp, &ippn10->curs_attr); 635 + REG_UPDATE(CURSOR_CONTROL, 636 + CURSOR_ENABLE, cur_en); 637 + REG_UPDATE(CURSOR0_CONTROL, 638 + CUR0_ENABLE, cur_en); 639 + 640 + REG_SET_2(CURSOR_POSITION, 0, 641 + CURSOR_X_POSITION, pos->x, 642 + CURSOR_Y_POSITION, pos->y); 643 + 644 + REG_SET_2(CURSOR_HOT_SPOT, 0, 645 + CURSOR_HOT_SPOT_X, pos->x_hotspot, 646 + CURSOR_HOT_SPOT_Y, pos->y_hotspot); 647 + 648 + REG_SET(CURSOR_DST_OFFSET, 0, 649 + CURSOR_DST_X_OFFSET, dst_x_offset); 650 + /* TODO Handle surface pixel formats other than 4:4:4 */ 651 + } 652 + 653 + enum pixel_format_description { 654 + PIXEL_FORMAT_FIXED = 0, 655 + PIXEL_FORMAT_FIXED16, 656 + PIXEL_FORMAT_FLOAT 657 + 658 + }; 659 + 660 + static void dcn10_setup_format_flags(enum surface_pixel_format input_format,\ 661 + enum pixel_format_description *fmt) 662 + { 663 + 664 + if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F || 665 + input_format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) 666 + *fmt = PIXEL_FORMAT_FLOAT; 667 + else if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616) 668 + *fmt = PIXEL_FORMAT_FIXED16; 669 + else 670 + *fmt = PIXEL_FORMAT_FIXED; 671 + } 672 + 673 + static void dcn10_ipp_set_degamma_format_float(struct input_pixel_processor *ipp, 674 + bool is_float) 675 + { 676 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 677 + 678 + if (is_float) { 679 + REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3); 680 + REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, 1); 681 + } else { 682 + REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 2); 683 + REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, 0); 684 + } 685 + } 686 + 687 + 688 + static void dcn10_ipp_cnv_setup ( 689 + struct input_pixel_processor *ipp, 690 + enum surface_pixel_format input_format, 691 + enum expansion_mode mode, 692 + enum ipp_output_format cnv_out_format) 693 + { 694 + uint32_t pixel_format; 695 + uint32_t alpha_en; 696 + enum pixel_format_description fmt ; 697 + enum dc_color_space color_space; 698 + enum dcn10_input_csc_select select; 699 + bool is_float; 700 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 701 + bool force_disable_cursor = false; 702 + 703 + dcn10_setup_format_flags(input_format, &fmt); 704 + alpha_en = 1; 705 + pixel_format = 0; 706 + color_space = COLOR_SPACE_SRGB; 707 + select = INPUT_CSC_SELECT_BYPASS; 708 + is_float = false; 709 + 710 + switch (fmt) { 711 + case PIXEL_FORMAT_FIXED: 712 + case PIXEL_FORMAT_FIXED16: 713 + /*when output is float then FORMAT_CONTROL__OUTPUT_FP=1*/ 714 + REG_SET_3(FORMAT_CONTROL, 0, 715 + CNVC_BYPASS, 0, 716 + FORMAT_EXPANSION_MODE, mode, 717 + OUTPUT_FP, 0); 718 + break; 719 + case PIXEL_FORMAT_FLOAT: 720 + REG_SET_3(FORMAT_CONTROL, 0, 721 + CNVC_BYPASS, 0, 722 + FORMAT_EXPANSION_MODE, mode, 723 + OUTPUT_FP, 1); 724 + is_float = true; 725 + break; 726 + default: 727 + 728 + break; 729 + } 730 + 731 + dcn10_ipp_set_degamma_format_float(ipp, is_float); 732 + 733 + switch (input_format) { 734 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 735 + pixel_format = 1; 736 + break; 737 + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 738 + pixel_format = 3; 739 + alpha_en = 0; 740 + break; 741 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 742 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 743 + pixel_format = 8; 744 + break; 745 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 746 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 747 + pixel_format = 10; 748 + break; 749 + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: 750 + force_disable_cursor = false; 751 + pixel_format = 65; 752 + color_space = COLOR_SPACE_YCBCR709; 753 + select = INPUT_CSC_SELECT_ICSC; 754 + break; 755 + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: 756 + force_disable_cursor = true; 757 + pixel_format = 64; 758 + color_space = COLOR_SPACE_YCBCR709; 759 + select = INPUT_CSC_SELECT_ICSC; 760 + break; 761 + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: 762 + force_disable_cursor = true; 763 + pixel_format = 67; 764 + color_space = COLOR_SPACE_YCBCR709; 765 + select = INPUT_CSC_SELECT_ICSC; 766 + break; 767 + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: 768 + force_disable_cursor = true; 769 + pixel_format = 66; 770 + color_space = COLOR_SPACE_YCBCR709; 771 + select = INPUT_CSC_SELECT_ICSC; 772 + break; 773 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 774 + pixel_format = 22; 775 + break; 776 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 777 + pixel_format = 24; 778 + break; 779 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 780 + pixel_format = 25; 781 + break; 782 + default: 783 + break; 784 + } 785 + REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, 786 + CNVC_SURFACE_PIXEL_FORMAT, pixel_format); 787 + REG_UPDATE(FORMAT_CONTROL, ALPHA_EN, alpha_en); 788 + 789 + dcn10_program_input_csc(ipp, color_space, select); 790 + 791 + if (force_disable_cursor) { 792 + REG_UPDATE(CURSOR_CONTROL, 793 + CURSOR_ENABLE, 0); 794 + REG_UPDATE(CURSOR0_CONTROL, 795 + CUR0_ENABLE, 0); 796 + } 797 + } 798 + 799 + 800 + static bool dcn10_degamma_ram_inuse(struct input_pixel_processor *ipp, 801 + bool *ram_a_inuse) 802 + { 803 + bool ret = false; 804 + uint32_t status_reg = 0; 805 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 806 + 807 + status_reg = (REG_READ(CM_IGAM_LUT_RW_CONTROL) & 0x0F00) >>16; 808 + if (status_reg == 9) { 809 + *ram_a_inuse = true; 810 + ret = true; 811 + } else if (status_reg == 10) { 812 + *ram_a_inuse = false; 813 + ret = true; 814 + } 815 + return ret; 816 + } 817 + 818 + static void dcn10_degamma_ram_select(struct input_pixel_processor *ipp, 819 + bool use_ram_a) 820 + { 821 + struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 822 + 823 + if (use_ram_a) 824 + REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3); 825 + else 826 + REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 4); 827 + 828 + } 829 + 830 + static void dcn10_ipp_set_degamma_pwl(struct input_pixel_processor *ipp, 831 + const struct pwl_params *params) 832 + { 833 + bool is_ram_a = true; 834 + 835 + ipp_power_on_degamma_lut(ipp, true); 836 + dcn10_ipp_enable_cm_block(ipp); 837 + dcn10_degamma_ram_inuse(ipp, &is_ram_a); 838 + if (is_ram_a == true) 839 + dcn10_ipp_program_degamma_lutb_settings(ipp, params); 840 + else 841 + dcn10_ipp_program_degamma_luta_settings(ipp, params); 842 + 843 + ipp_program_degamma_lut(ipp, params->rgb_resulted, 844 + params->hw_points_num, !is_ram_a); 845 + dcn10_degamma_ram_select(ipp, !is_ram_a); 846 + } 847 + 848 + /*****************************************/ 849 + /* Constructor, Destructor */ 850 + /*****************************************/ 851 + 852 + static void dcn10_ipp_destroy(struct input_pixel_processor **ipp) 853 + { 854 + dm_free(TO_DCN10_IPP(*ipp)); 855 + *ipp = NULL; 856 + } 857 + 858 + static const struct ipp_funcs dcn10_ipp_funcs = { 859 + .ipp_cursor_set_attributes = dcn10_cursor_set_attributes, 860 + .ipp_cursor_set_position = dcn10_cursor_set_position, 861 + .ipp_set_degamma = dcn10_ipp_set_degamma, 862 + .ipp_full_bypass = dcn10_ipp_full_bypass, 863 + .ipp_setup = dcn10_ipp_cnv_setup, 864 + .ipp_program_degamma_pwl = dcn10_ipp_set_degamma_pwl, 865 + .ipp_destroy = dcn10_ipp_destroy 866 + }; 867 + 868 + void dcn10_ipp_construct( 869 + struct dcn10_ipp *ippn10, 870 + struct dc_context *ctx, 871 + int inst, 872 + const struct dcn10_ipp_registers *regs, 873 + const struct dcn10_ipp_shift *ipp_shift, 874 + const struct dcn10_ipp_mask *ipp_mask) 875 + { 876 + ippn10->base.ctx = ctx; 877 + ippn10->base.inst = inst; 878 + ippn10->base.funcs = &dcn10_ipp_funcs; 879 + 880 + ippn10->regs = regs; 881 + ippn10->ipp_shift = ipp_shift; 882 + ippn10->ipp_mask = ipp_mask; 883 + }
+549
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h
··· 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 + #ifndef _DCN10_IPP_H_ 27 + #define _DCN10_IPP_H_ 28 + 29 + #include "ipp.h" 30 + 31 + #define TO_DCN10_IPP(ipp)\ 32 + container_of(ipp, struct dcn10_ipp, base) 33 + 34 + #define IPP_DCN10_REG_LIST(id) \ 35 + SRI(CM_ICSC_CONTROL, CM, id), \ 36 + SRI(CM_ICSC_C11_C12, CM, id), \ 37 + SRI(CM_ICSC_C13_C14, CM, id), \ 38 + SRI(CM_ICSC_C21_C22, CM, id), \ 39 + SRI(CM_ICSC_C23_C24, CM, id), \ 40 + SRI(CM_ICSC_C31_C32, CM, id), \ 41 + SRI(CM_ICSC_C33_C34, CM, id), \ 42 + SRI(CM_COMA_C11_C12, CM, id), \ 43 + SRI(CM_COMA_C13_C14, CM, id), \ 44 + SRI(CM_COMA_C21_C22, CM, id), \ 45 + SRI(CM_COMA_C23_C24, CM, id), \ 46 + SRI(CM_COMA_C31_C32, CM, id), \ 47 + SRI(CM_COMA_C33_C34, CM, id), \ 48 + SRI(CM_DGAM_RAMB_START_CNTL_B, CM, id), \ 49 + SRI(CM_DGAM_RAMB_START_CNTL_G, CM, id), \ 50 + SRI(CM_DGAM_RAMB_START_CNTL_R, CM, id), \ 51 + SRI(CM_DGAM_RAMB_SLOPE_CNTL_B, CM, id), \ 52 + SRI(CM_DGAM_RAMB_SLOPE_CNTL_G, CM, id), \ 53 + SRI(CM_DGAM_RAMB_SLOPE_CNTL_R, CM, id), \ 54 + SRI(CM_DGAM_RAMB_END_CNTL1_B, CM, id), \ 55 + SRI(CM_DGAM_RAMB_END_CNTL2_B, CM, id), \ 56 + SRI(CM_DGAM_RAMB_END_CNTL1_G, CM, id), \ 57 + SRI(CM_DGAM_RAMB_END_CNTL2_G, CM, id), \ 58 + SRI(CM_DGAM_RAMB_END_CNTL1_R, CM, id), \ 59 + SRI(CM_DGAM_RAMB_END_CNTL2_R, CM, id), \ 60 + SRI(CM_DGAM_RAMB_REGION_0_1, CM, id), \ 61 + SRI(CM_DGAM_RAMB_REGION_2_3, CM, id), \ 62 + SRI(CM_DGAM_RAMB_REGION_4_5, CM, id), \ 63 + SRI(CM_DGAM_RAMB_REGION_6_7, CM, id), \ 64 + SRI(CM_DGAM_RAMB_REGION_8_9, CM, id), \ 65 + SRI(CM_DGAM_RAMB_REGION_10_11, CM, id), \ 66 + SRI(CM_DGAM_RAMB_REGION_12_13, CM, id), \ 67 + SRI(CM_DGAM_RAMB_REGION_14_15, CM, id), \ 68 + SRI(CM_DGAM_RAMA_START_CNTL_B, CM, id), \ 69 + SRI(CM_DGAM_RAMA_START_CNTL_G, CM, id), \ 70 + SRI(CM_DGAM_RAMA_START_CNTL_R, CM, id), \ 71 + SRI(CM_DGAM_RAMA_SLOPE_CNTL_B, CM, id), \ 72 + SRI(CM_DGAM_RAMA_SLOPE_CNTL_G, CM, id), \ 73 + SRI(CM_DGAM_RAMA_SLOPE_CNTL_R, CM, id), \ 74 + SRI(CM_DGAM_RAMA_END_CNTL1_B, CM, id), \ 75 + SRI(CM_DGAM_RAMA_END_CNTL2_B, CM, id), \ 76 + SRI(CM_DGAM_RAMA_END_CNTL1_G, CM, id), \ 77 + SRI(CM_DGAM_RAMA_END_CNTL2_G, CM, id), \ 78 + SRI(CM_DGAM_RAMA_END_CNTL1_R, CM, id), \ 79 + SRI(CM_DGAM_RAMA_END_CNTL2_R, CM, id), \ 80 + SRI(CM_DGAM_RAMA_REGION_0_1, CM, id), \ 81 + SRI(CM_DGAM_RAMA_REGION_2_3, CM, id), \ 82 + SRI(CM_DGAM_RAMA_REGION_4_5, CM, id), \ 83 + SRI(CM_DGAM_RAMA_REGION_6_7, CM, id), \ 84 + SRI(CM_DGAM_RAMA_REGION_8_9, CM, id), \ 85 + SRI(CM_DGAM_RAMA_REGION_10_11, CM, id), \ 86 + SRI(CM_DGAM_RAMA_REGION_12_13, CM, id), \ 87 + SRI(CM_DGAM_RAMA_REGION_14_15, CM, id), \ 88 + SRI(CM_MEM_PWR_CTRL, CM, id), \ 89 + SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \ 90 + SRI(CM_DGAM_LUT_WRITE_EN_MASK, CM, id), \ 91 + SRI(CM_DGAM_LUT_INDEX, CM, id), \ 92 + SRI(CM_DGAM_LUT_DATA, CM, id), \ 93 + SRI(CM_CONTROL, CM, id), \ 94 + SRI(CM_DGAM_CONTROL, CM, id), \ 95 + SRI(CM_IGAM_CONTROL, CM, id), \ 96 + SRI(DPP_CONTROL, DPP_TOP, id), \ 97 + SRI(CURSOR_SETTINS, HUBPREQ, id), \ 98 + SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \ 99 + SRI(CURSOR0_CONTROL, CNVC_CUR, id), \ 100 + SRI(CURSOR0_COLOR0, CNVC_CUR, id), \ 101 + SRI(CURSOR0_COLOR1, CNVC_CUR, id), \ 102 + SRI(FORMAT_CONTROL, CNVC_CFG, id), \ 103 + SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \ 104 + SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \ 105 + SRI(CURSOR_SIZE, CURSOR, id), \ 106 + SRI(CURSOR_CONTROL, CURSOR, id), \ 107 + SRI(CURSOR_POSITION, CURSOR, id), \ 108 + SRI(CURSOR_HOT_SPOT, CURSOR, id), \ 109 + SRI(CURSOR_DST_OFFSET, CURSOR, id) 110 + 111 + #define IPP_SF(reg_name, field_name, post_fix)\ 112 + .field_name = reg_name ## __ ## field_name ## post_fix 113 + 114 + #define IPP_DCN10_MASK_SH_LIST(mask_sh) \ 115 + IPP_SF(CM0_CM_ICSC_CONTROL, CM_ICSC_MODE, mask_sh), \ 116 + IPP_SF(CM0_CM_ICSC_C11_C12, CM_ICSC_C11, mask_sh), \ 117 + IPP_SF(CM0_CM_ICSC_C11_C12, CM_ICSC_C12, mask_sh), \ 118 + IPP_SF(CM0_CM_ICSC_C13_C14, CM_ICSC_C13, mask_sh), \ 119 + IPP_SF(CM0_CM_ICSC_C13_C14, CM_ICSC_C14, mask_sh), \ 120 + IPP_SF(CM0_CM_ICSC_C21_C22, CM_ICSC_C21, mask_sh), \ 121 + IPP_SF(CM0_CM_ICSC_C21_C22, CM_ICSC_C22, mask_sh), \ 122 + IPP_SF(CM0_CM_ICSC_C23_C24, CM_ICSC_C23, mask_sh), \ 123 + IPP_SF(CM0_CM_ICSC_C23_C24, CM_ICSC_C24, mask_sh), \ 124 + IPP_SF(CM0_CM_ICSC_C31_C32, CM_ICSC_C31, mask_sh), \ 125 + IPP_SF(CM0_CM_ICSC_C31_C32, CM_ICSC_C32, mask_sh), \ 126 + IPP_SF(CM0_CM_ICSC_C33_C34, CM_ICSC_C33, mask_sh), \ 127 + IPP_SF(CM0_CM_ICSC_C33_C34, CM_ICSC_C34, mask_sh), \ 128 + IPP_SF(CM0_CM_COMA_C11_C12, CM_COMA_C11, mask_sh), \ 129 + IPP_SF(CM0_CM_COMA_C11_C12, CM_COMA_C12, mask_sh), \ 130 + IPP_SF(CM0_CM_COMA_C13_C14, CM_COMA_C13, mask_sh), \ 131 + IPP_SF(CM0_CM_COMA_C13_C14, CM_COMA_C14, mask_sh), \ 132 + IPP_SF(CM0_CM_COMA_C21_C22, CM_COMA_C21, mask_sh), \ 133 + IPP_SF(CM0_CM_COMA_C21_C22, CM_COMA_C22, mask_sh), \ 134 + IPP_SF(CM0_CM_COMA_C23_C24, CM_COMA_C23, mask_sh), \ 135 + IPP_SF(CM0_CM_COMA_C23_C24, CM_COMA_C24, mask_sh), \ 136 + IPP_SF(CM0_CM_COMA_C31_C32, CM_COMA_C31, mask_sh), \ 137 + IPP_SF(CM0_CM_COMA_C31_C32, CM_COMA_C32, mask_sh), \ 138 + IPP_SF(CM0_CM_COMA_C33_C34, CM_COMA_C33, mask_sh), \ 139 + IPP_SF(CM0_CM_COMA_C33_C34, CM_COMA_C34, mask_sh), \ 140 + IPP_SF(CM0_CM_DGAM_RAMB_START_CNTL_B, CM_DGAM_RAMB_EXP_REGION_START_B, mask_sh), \ 141 + IPP_SF(CM0_CM_DGAM_RAMB_START_CNTL_B, CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_B, mask_sh), \ 142 + IPP_SF(CM0_CM_DGAM_RAMB_START_CNTL_G, CM_DGAM_RAMB_EXP_REGION_START_G, mask_sh), \ 143 + IPP_SF(CM0_CM_DGAM_RAMB_START_CNTL_G, CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_G, mask_sh), \ 144 + IPP_SF(CM0_CM_DGAM_RAMB_START_CNTL_R, CM_DGAM_RAMB_EXP_REGION_START_R, mask_sh), \ 145 + IPP_SF(CM0_CM_DGAM_RAMB_START_CNTL_R, CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_R, mask_sh), \ 146 + IPP_SF(CM0_CM_DGAM_RAMB_SLOPE_CNTL_B, CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B, mask_sh), \ 147 + IPP_SF(CM0_CM_DGAM_RAMB_SLOPE_CNTL_G, CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_G, mask_sh), \ 148 + IPP_SF(CM0_CM_DGAM_RAMB_SLOPE_CNTL_R, CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_R, mask_sh), \ 149 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL1_B, CM_DGAM_RAMB_EXP_REGION_END_B, mask_sh), \ 150 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL2_B, CM_DGAM_RAMB_EXP_REGION_END_SLOPE_B, mask_sh), \ 151 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL2_B, CM_DGAM_RAMB_EXP_REGION_END_BASE_B, mask_sh), \ 152 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL1_G, CM_DGAM_RAMB_EXP_REGION_END_G, mask_sh), \ 153 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL2_G, CM_DGAM_RAMB_EXP_REGION_END_SLOPE_G, mask_sh), \ 154 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL2_G, CM_DGAM_RAMB_EXP_REGION_END_BASE_G, mask_sh), \ 155 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL1_R, CM_DGAM_RAMB_EXP_REGION_END_R, mask_sh), \ 156 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL2_R, CM_DGAM_RAMB_EXP_REGION_END_SLOPE_R, mask_sh), \ 157 + IPP_SF(CM0_CM_DGAM_RAMB_END_CNTL2_R, CM_DGAM_RAMB_EXP_REGION_END_BASE_R, mask_sh), \ 158 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_0_1, CM_DGAM_RAMB_EXP_REGION0_LUT_OFFSET, mask_sh), \ 159 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_0_1, CM_DGAM_RAMB_EXP_REGION0_NUM_SEGMENTS, mask_sh), \ 160 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_0_1, CM_DGAM_RAMB_EXP_REGION1_LUT_OFFSET, mask_sh), \ 161 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_0_1, CM_DGAM_RAMB_EXP_REGION1_NUM_SEGMENTS, mask_sh), \ 162 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_2_3, CM_DGAM_RAMB_EXP_REGION2_LUT_OFFSET, mask_sh), \ 163 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_2_3, CM_DGAM_RAMB_EXP_REGION2_NUM_SEGMENTS, mask_sh), \ 164 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_2_3, CM_DGAM_RAMB_EXP_REGION3_LUT_OFFSET, mask_sh), \ 165 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_2_3, CM_DGAM_RAMB_EXP_REGION3_NUM_SEGMENTS, mask_sh), \ 166 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_4_5, CM_DGAM_RAMB_EXP_REGION4_LUT_OFFSET, mask_sh), \ 167 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_4_5, CM_DGAM_RAMB_EXP_REGION4_NUM_SEGMENTS, mask_sh), \ 168 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_4_5, CM_DGAM_RAMB_EXP_REGION5_LUT_OFFSET, mask_sh), \ 169 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_4_5, CM_DGAM_RAMB_EXP_REGION5_NUM_SEGMENTS, mask_sh), \ 170 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_6_7, CM_DGAM_RAMB_EXP_REGION6_LUT_OFFSET, mask_sh), \ 171 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_6_7, CM_DGAM_RAMB_EXP_REGION6_NUM_SEGMENTS, mask_sh), \ 172 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_6_7, CM_DGAM_RAMB_EXP_REGION7_LUT_OFFSET, mask_sh), \ 173 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_6_7, CM_DGAM_RAMB_EXP_REGION7_NUM_SEGMENTS, mask_sh), \ 174 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_8_9, CM_DGAM_RAMB_EXP_REGION8_LUT_OFFSET, mask_sh), \ 175 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_8_9, CM_DGAM_RAMB_EXP_REGION8_NUM_SEGMENTS, mask_sh), \ 176 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_8_9, CM_DGAM_RAMB_EXP_REGION9_LUT_OFFSET, mask_sh), \ 177 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_8_9, CM_DGAM_RAMB_EXP_REGION9_NUM_SEGMENTS, mask_sh), \ 178 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_10_11, CM_DGAM_RAMB_EXP_REGION10_LUT_OFFSET, mask_sh), \ 179 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_10_11, CM_DGAM_RAMB_EXP_REGION10_NUM_SEGMENTS, mask_sh), \ 180 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_10_11, CM_DGAM_RAMB_EXP_REGION11_LUT_OFFSET, mask_sh), \ 181 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_10_11, CM_DGAM_RAMB_EXP_REGION11_NUM_SEGMENTS, mask_sh), \ 182 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_12_13, CM_DGAM_RAMB_EXP_REGION12_LUT_OFFSET, mask_sh), \ 183 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_12_13, CM_DGAM_RAMB_EXP_REGION12_NUM_SEGMENTS, mask_sh), \ 184 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_12_13, CM_DGAM_RAMB_EXP_REGION13_LUT_OFFSET, mask_sh), \ 185 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_12_13, CM_DGAM_RAMB_EXP_REGION13_NUM_SEGMENTS, mask_sh), \ 186 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_14_15, CM_DGAM_RAMB_EXP_REGION14_LUT_OFFSET, mask_sh), \ 187 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_14_15, CM_DGAM_RAMB_EXP_REGION14_NUM_SEGMENTS, mask_sh), \ 188 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_14_15, CM_DGAM_RAMB_EXP_REGION15_LUT_OFFSET, mask_sh), \ 189 + IPP_SF(CM0_CM_DGAM_RAMB_REGION_14_15, CM_DGAM_RAMB_EXP_REGION15_NUM_SEGMENTS, mask_sh), \ 190 + IPP_SF(CM0_CM_DGAM_RAMA_START_CNTL_B, CM_DGAM_RAMA_EXP_REGION_START_B, mask_sh), \ 191 + IPP_SF(CM0_CM_DGAM_RAMA_START_CNTL_B, CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_B, mask_sh), \ 192 + IPP_SF(CM0_CM_DGAM_RAMA_START_CNTL_G, CM_DGAM_RAMA_EXP_REGION_START_G, mask_sh), \ 193 + IPP_SF(CM0_CM_DGAM_RAMA_START_CNTL_G, CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_G, mask_sh), \ 194 + IPP_SF(CM0_CM_DGAM_RAMA_START_CNTL_R, CM_DGAM_RAMA_EXP_REGION_START_R, mask_sh), \ 195 + IPP_SF(CM0_CM_DGAM_RAMA_START_CNTL_R, CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_R, mask_sh), \ 196 + IPP_SF(CM0_CM_DGAM_RAMA_SLOPE_CNTL_B, CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B, mask_sh), \ 197 + IPP_SF(CM0_CM_DGAM_RAMA_SLOPE_CNTL_G, CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_G, mask_sh), \ 198 + IPP_SF(CM0_CM_DGAM_RAMA_SLOPE_CNTL_R, CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_R, mask_sh), \ 199 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL1_B, CM_DGAM_RAMA_EXP_REGION_END_B, mask_sh), \ 200 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL2_B, CM_DGAM_RAMA_EXP_REGION_END_SLOPE_B, mask_sh), \ 201 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL2_B, CM_DGAM_RAMA_EXP_REGION_END_BASE_B, mask_sh), \ 202 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL1_G, CM_DGAM_RAMA_EXP_REGION_END_G, mask_sh), \ 203 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL2_G, CM_DGAM_RAMA_EXP_REGION_END_SLOPE_G, mask_sh), \ 204 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL2_G, CM_DGAM_RAMA_EXP_REGION_END_BASE_G, mask_sh), \ 205 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL1_R, CM_DGAM_RAMA_EXP_REGION_END_R, mask_sh), \ 206 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL2_R, CM_DGAM_RAMA_EXP_REGION_END_SLOPE_R, mask_sh), \ 207 + IPP_SF(CM0_CM_DGAM_RAMA_END_CNTL2_R, CM_DGAM_RAMA_EXP_REGION_END_BASE_R, mask_sh), \ 208 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_0_1, CM_DGAM_RAMA_EXP_REGION0_LUT_OFFSET, mask_sh), \ 209 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_0_1, CM_DGAM_RAMA_EXP_REGION0_NUM_SEGMENTS, mask_sh), \ 210 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_0_1, CM_DGAM_RAMA_EXP_REGION1_LUT_OFFSET, mask_sh), \ 211 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_0_1, CM_DGAM_RAMA_EXP_REGION1_NUM_SEGMENTS, mask_sh), \ 212 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_2_3, CM_DGAM_RAMA_EXP_REGION2_LUT_OFFSET, mask_sh), \ 213 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_2_3, CM_DGAM_RAMA_EXP_REGION2_NUM_SEGMENTS, mask_sh), \ 214 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_2_3, CM_DGAM_RAMA_EXP_REGION3_LUT_OFFSET, mask_sh), \ 215 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_2_3, CM_DGAM_RAMA_EXP_REGION3_NUM_SEGMENTS, mask_sh), \ 216 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_4_5, CM_DGAM_RAMA_EXP_REGION4_LUT_OFFSET, mask_sh), \ 217 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_4_5, CM_DGAM_RAMA_EXP_REGION4_NUM_SEGMENTS, mask_sh), \ 218 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_4_5, CM_DGAM_RAMA_EXP_REGION5_LUT_OFFSET, mask_sh), \ 219 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_4_5, CM_DGAM_RAMA_EXP_REGION5_NUM_SEGMENTS, mask_sh), \ 220 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_6_7, CM_DGAM_RAMA_EXP_REGION6_LUT_OFFSET, mask_sh), \ 221 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_6_7, CM_DGAM_RAMA_EXP_REGION6_NUM_SEGMENTS, mask_sh), \ 222 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_6_7, CM_DGAM_RAMA_EXP_REGION7_LUT_OFFSET, mask_sh), \ 223 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_6_7, CM_DGAM_RAMA_EXP_REGION7_NUM_SEGMENTS, mask_sh), \ 224 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_8_9, CM_DGAM_RAMA_EXP_REGION8_LUT_OFFSET, mask_sh), \ 225 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_8_9, CM_DGAM_RAMA_EXP_REGION8_NUM_SEGMENTS, mask_sh), \ 226 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_8_9, CM_DGAM_RAMA_EXP_REGION9_LUT_OFFSET, mask_sh), \ 227 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_8_9, CM_DGAM_RAMA_EXP_REGION9_NUM_SEGMENTS, mask_sh), \ 228 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_10_11, CM_DGAM_RAMA_EXP_REGION10_LUT_OFFSET, mask_sh), \ 229 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_10_11, CM_DGAM_RAMA_EXP_REGION10_NUM_SEGMENTS, mask_sh), \ 230 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_10_11, CM_DGAM_RAMA_EXP_REGION11_LUT_OFFSET, mask_sh), \ 231 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_10_11, CM_DGAM_RAMA_EXP_REGION11_NUM_SEGMENTS, mask_sh), \ 232 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_12_13, CM_DGAM_RAMA_EXP_REGION12_LUT_OFFSET, mask_sh), \ 233 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_12_13, CM_DGAM_RAMA_EXP_REGION12_NUM_SEGMENTS, mask_sh), \ 234 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_12_13, CM_DGAM_RAMA_EXP_REGION13_LUT_OFFSET, mask_sh), \ 235 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_12_13, CM_DGAM_RAMA_EXP_REGION13_NUM_SEGMENTS, mask_sh), \ 236 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_14_15, CM_DGAM_RAMA_EXP_REGION14_LUT_OFFSET, mask_sh), \ 237 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_14_15, CM_DGAM_RAMA_EXP_REGION14_NUM_SEGMENTS, mask_sh), \ 238 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_14_15, CM_DGAM_RAMA_EXP_REGION15_LUT_OFFSET, mask_sh), \ 239 + IPP_SF(CM0_CM_DGAM_RAMA_REGION_14_15, CM_DGAM_RAMA_EXP_REGION15_NUM_SEGMENTS, mask_sh), \ 240 + IPP_SF(CM0_CM_MEM_PWR_CTRL, SHARED_MEM_PWR_DIS, mask_sh), \ 241 + IPP_SF(CM0_CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, mask_sh), \ 242 + IPP_SF(CM0_CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_EN_MASK, mask_sh), \ 243 + IPP_SF(CM0_CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL, mask_sh), \ 244 + IPP_SF(CM0_CM_DGAM_LUT_INDEX, CM_DGAM_LUT_INDEX, mask_sh), \ 245 + IPP_SF(CM0_CM_DGAM_LUT_DATA, CM_DGAM_LUT_DATA, mask_sh), \ 246 + IPP_SF(DPP_TOP0_DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \ 247 + IPP_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \ 248 + IPP_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \ 249 + IPP_SF(CNVC_CFG0_FORMAT_CONTROL, CNVC_BYPASS, mask_sh), \ 250 + IPP_SF(CNVC_CFG0_FORMAT_CONTROL, ALPHA_EN, mask_sh), \ 251 + IPP_SF(CNVC_CFG0_FORMAT_CONTROL, FORMAT_EXPANSION_MODE, mask_sh), \ 252 + IPP_SF(CM0_CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, mask_sh), \ 253 + IPP_SF(CM0_CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, mask_sh), \ 254 + IPP_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \ 255 + IPP_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \ 256 + IPP_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \ 257 + IPP_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_INVERT_MODE, mask_sh), \ 258 + IPP_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \ 259 + IPP_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh), \ 260 + IPP_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \ 261 + IPP_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MAX, mask_sh), \ 262 + IPP_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MIN, mask_sh), \ 263 + IPP_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \ 264 + IPP_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \ 265 + IPP_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \ 266 + IPP_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \ 267 + IPP_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ 268 + IPP_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ 269 + IPP_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ 270 + IPP_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \ 271 + IPP_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \ 272 + IPP_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \ 273 + IPP_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \ 274 + IPP_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \ 275 + IPP_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \ 276 + IPP_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh), \ 277 + IPP_SF(CM0_CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, mask_sh), \ 278 + IPP_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh) 279 + 280 + #define IPP_DCN10_REG_FIELD_LIST(type) \ 281 + type CM_ICSC_MODE; \ 282 + type CM_ICSC_C11; \ 283 + type CM_ICSC_C12; \ 284 + type CM_ICSC_C13; \ 285 + type CM_ICSC_C14; \ 286 + type CM_ICSC_C21; \ 287 + type CM_ICSC_C22; \ 288 + type CM_ICSC_C23; \ 289 + type CM_ICSC_C24; \ 290 + type CM_ICSC_C31; \ 291 + type CM_ICSC_C32; \ 292 + type CM_ICSC_C33; \ 293 + type CM_ICSC_C34; \ 294 + type CM_COMA_C11; \ 295 + type CM_COMA_C12; \ 296 + type CM_COMA_C13; \ 297 + type CM_COMA_C14; \ 298 + type CM_COMA_C21; \ 299 + type CM_COMA_C22; \ 300 + type CM_COMA_C23; \ 301 + type CM_COMA_C24; \ 302 + type CM_COMA_C31; \ 303 + type CM_COMA_C32; \ 304 + type CM_COMA_C33; \ 305 + type CM_COMA_C34; \ 306 + type CM_DGAM_RAMB_EXP_REGION_START_B; \ 307 + type CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_B; \ 308 + type CM_DGAM_RAMB_EXP_REGION_START_G; \ 309 + type CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_G; \ 310 + type CM_DGAM_RAMB_EXP_REGION_START_R; \ 311 + type CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_R; \ 312 + type CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; \ 313 + type CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_G; \ 314 + type CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_R; \ 315 + type CM_DGAM_RAMB_EXP_REGION_END_B; \ 316 + type CM_DGAM_RAMB_EXP_REGION_END_SLOPE_B; \ 317 + type CM_DGAM_RAMB_EXP_REGION_END_BASE_B; \ 318 + type CM_DGAM_RAMB_EXP_REGION_END_G; \ 319 + type CM_DGAM_RAMB_EXP_REGION_END_SLOPE_G; \ 320 + type CM_DGAM_RAMB_EXP_REGION_END_BASE_G; \ 321 + type CM_DGAM_RAMB_EXP_REGION_END_R; \ 322 + type CM_DGAM_RAMB_EXP_REGION_END_SLOPE_R; \ 323 + type CM_DGAM_RAMB_EXP_REGION_END_BASE_R; \ 324 + type CM_DGAM_RAMB_EXP_REGION0_LUT_OFFSET; \ 325 + type CM_DGAM_RAMB_EXP_REGION0_NUM_SEGMENTS; \ 326 + type CM_DGAM_RAMB_EXP_REGION1_LUT_OFFSET; \ 327 + type CM_DGAM_RAMB_EXP_REGION1_NUM_SEGMENTS; \ 328 + type CM_DGAM_RAMB_EXP_REGION2_LUT_OFFSET; \ 329 + type CM_DGAM_RAMB_EXP_REGION2_NUM_SEGMENTS; \ 330 + type CM_DGAM_RAMB_EXP_REGION3_LUT_OFFSET; \ 331 + type CM_DGAM_RAMB_EXP_REGION3_NUM_SEGMENTS; \ 332 + type CM_DGAM_RAMB_EXP_REGION4_LUT_OFFSET; \ 333 + type CM_DGAM_RAMB_EXP_REGION4_NUM_SEGMENTS; \ 334 + type CM_DGAM_RAMB_EXP_REGION5_LUT_OFFSET; \ 335 + type CM_DGAM_RAMB_EXP_REGION5_NUM_SEGMENTS; \ 336 + type CM_DGAM_RAMB_EXP_REGION6_LUT_OFFSET; \ 337 + type CM_DGAM_RAMB_EXP_REGION6_NUM_SEGMENTS; \ 338 + type CM_DGAM_RAMB_EXP_REGION7_LUT_OFFSET; \ 339 + type CM_DGAM_RAMB_EXP_REGION7_NUM_SEGMENTS; \ 340 + type CM_DGAM_RAMB_EXP_REGION8_LUT_OFFSET; \ 341 + type CM_DGAM_RAMB_EXP_REGION8_NUM_SEGMENTS; \ 342 + type CM_DGAM_RAMB_EXP_REGION9_LUT_OFFSET; \ 343 + type CM_DGAM_RAMB_EXP_REGION9_NUM_SEGMENTS; \ 344 + type CM_DGAM_RAMB_EXP_REGION10_LUT_OFFSET; \ 345 + type CM_DGAM_RAMB_EXP_REGION10_NUM_SEGMENTS; \ 346 + type CM_DGAM_RAMB_EXP_REGION11_LUT_OFFSET; \ 347 + type CM_DGAM_RAMB_EXP_REGION11_NUM_SEGMENTS; \ 348 + type CM_DGAM_RAMB_EXP_REGION12_LUT_OFFSET; \ 349 + type CM_DGAM_RAMB_EXP_REGION12_NUM_SEGMENTS; \ 350 + type CM_DGAM_RAMB_EXP_REGION13_LUT_OFFSET; \ 351 + type CM_DGAM_RAMB_EXP_REGION13_NUM_SEGMENTS; \ 352 + type CM_DGAM_RAMB_EXP_REGION14_LUT_OFFSET; \ 353 + type CM_DGAM_RAMB_EXP_REGION14_NUM_SEGMENTS; \ 354 + type CM_DGAM_RAMB_EXP_REGION15_LUT_OFFSET; \ 355 + type CM_DGAM_RAMB_EXP_REGION15_NUM_SEGMENTS; \ 356 + type CM_DGAM_RAMA_EXP_REGION_START_B; \ 357 + type CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_B; \ 358 + type CM_DGAM_RAMA_EXP_REGION_START_G; \ 359 + type CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_G; \ 360 + type CM_DGAM_RAMA_EXP_REGION_START_R; \ 361 + type CM_DGAM_RAMA_EXP_REGION_START_SEGMENT_R; \ 362 + type CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B; \ 363 + type CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_G; \ 364 + type CM_DGAM_RAMA_EXP_REGION_LINEAR_SLOPE_R; \ 365 + type CM_DGAM_RAMA_EXP_REGION_END_B; \ 366 + type CM_DGAM_RAMA_EXP_REGION_END_SLOPE_B; \ 367 + type CM_DGAM_RAMA_EXP_REGION_END_BASE_B; \ 368 + type CM_DGAM_RAMA_EXP_REGION_END_G; \ 369 + type CM_DGAM_RAMA_EXP_REGION_END_SLOPE_G; \ 370 + type CM_DGAM_RAMA_EXP_REGION_END_BASE_G; \ 371 + type CM_DGAM_RAMA_EXP_REGION_END_R; \ 372 + type CM_DGAM_RAMA_EXP_REGION_END_SLOPE_R; \ 373 + type CM_DGAM_RAMA_EXP_REGION_END_BASE_R; \ 374 + type CM_DGAM_RAMA_EXP_REGION0_LUT_OFFSET; \ 375 + type CM_DGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; \ 376 + type CM_DGAM_RAMA_EXP_REGION1_LUT_OFFSET; \ 377 + type CM_DGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; \ 378 + type CM_DGAM_RAMA_EXP_REGION2_LUT_OFFSET; \ 379 + type CM_DGAM_RAMA_EXP_REGION2_NUM_SEGMENTS; \ 380 + type CM_DGAM_RAMA_EXP_REGION3_LUT_OFFSET; \ 381 + type CM_DGAM_RAMA_EXP_REGION3_NUM_SEGMENTS; \ 382 + type CM_DGAM_RAMA_EXP_REGION4_LUT_OFFSET; \ 383 + type CM_DGAM_RAMA_EXP_REGION4_NUM_SEGMENTS; \ 384 + type CM_DGAM_RAMA_EXP_REGION5_LUT_OFFSET; \ 385 + type CM_DGAM_RAMA_EXP_REGION5_NUM_SEGMENTS; \ 386 + type CM_DGAM_RAMA_EXP_REGION6_LUT_OFFSET; \ 387 + type CM_DGAM_RAMA_EXP_REGION6_NUM_SEGMENTS; \ 388 + type CM_DGAM_RAMA_EXP_REGION7_LUT_OFFSET; \ 389 + type CM_DGAM_RAMA_EXP_REGION7_NUM_SEGMENTS; \ 390 + type CM_DGAM_RAMA_EXP_REGION8_LUT_OFFSET; \ 391 + type CM_DGAM_RAMA_EXP_REGION8_NUM_SEGMENTS; \ 392 + type CM_DGAM_RAMA_EXP_REGION9_LUT_OFFSET; \ 393 + type CM_DGAM_RAMA_EXP_REGION9_NUM_SEGMENTS; \ 394 + type CM_DGAM_RAMA_EXP_REGION10_LUT_OFFSET; \ 395 + type CM_DGAM_RAMA_EXP_REGION10_NUM_SEGMENTS; \ 396 + type CM_DGAM_RAMA_EXP_REGION11_LUT_OFFSET; \ 397 + type CM_DGAM_RAMA_EXP_REGION11_NUM_SEGMENTS; \ 398 + type CM_DGAM_RAMA_EXP_REGION12_LUT_OFFSET; \ 399 + type CM_DGAM_RAMA_EXP_REGION12_NUM_SEGMENTS; \ 400 + type CM_DGAM_RAMA_EXP_REGION13_LUT_OFFSET; \ 401 + type CM_DGAM_RAMA_EXP_REGION13_NUM_SEGMENTS; \ 402 + type CM_DGAM_RAMA_EXP_REGION14_LUT_OFFSET; \ 403 + type CM_DGAM_RAMA_EXP_REGION14_NUM_SEGMENTS; \ 404 + type CM_DGAM_RAMA_EXP_REGION15_LUT_OFFSET; \ 405 + type CM_DGAM_RAMA_EXP_REGION15_NUM_SEGMENTS; \ 406 + type SHARED_MEM_PWR_DIS; \ 407 + type CM_IGAM_LUT_HOST_EN; \ 408 + type CM_DGAM_LUT_WRITE_EN_MASK; \ 409 + type CM_DGAM_LUT_WRITE_SEL; \ 410 + type CM_DGAM_LUT_INDEX; \ 411 + type CM_DGAM_LUT_DATA; \ 412 + type DPP_CLOCK_ENABLE; \ 413 + type CM_BYPASS_EN; \ 414 + type CNVC_SURFACE_PIXEL_FORMAT; \ 415 + type CNVC_BYPASS; \ 416 + type ALPHA_EN; \ 417 + type FORMAT_EXPANSION_MODE; \ 418 + type CM_DGAM_LUT_MODE; \ 419 + type CM_IGAM_LUT_MODE; \ 420 + type CURSOR0_DST_Y_OFFSET; \ 421 + type CURSOR0_CHUNK_HDL_ADJUST; \ 422 + type CUR0_MODE; \ 423 + type CUR0_INVERT_MODE; \ 424 + type CUR0_COLOR0; \ 425 + type CUR0_COLOR1; \ 426 + type CUR0_EXPANSION_MODE; \ 427 + type CUR0_MAX; \ 428 + type CUR0_MIN; \ 429 + type CURSOR_SURFACE_ADDRESS_HIGH; \ 430 + type CURSOR_SURFACE_ADDRESS; \ 431 + type CURSOR_WIDTH; \ 432 + type CURSOR_HEIGHT; \ 433 + type CURSOR_MODE; \ 434 + type CURSOR_PITCH; \ 435 + type CURSOR_LINES_PER_CHUNK; \ 436 + type CURSOR_ENABLE; \ 437 + type CUR0_ENABLE; \ 438 + type CURSOR_X_POSITION; \ 439 + type CURSOR_Y_POSITION; \ 440 + type CURSOR_HOT_SPOT_X; \ 441 + type CURSOR_HOT_SPOT_Y; \ 442 + type CURSOR_DST_X_OFFSET; \ 443 + type CM_IGAM_INPUT_FORMAT; \ 444 + type OUTPUT_FP 445 + 446 + struct dcn10_ipp_shift { 447 + IPP_DCN10_REG_FIELD_LIST(uint8_t); 448 + }; 449 + 450 + struct dcn10_ipp_mask { 451 + IPP_DCN10_REG_FIELD_LIST(uint32_t); 452 + }; 453 + 454 + struct dcn10_ipp_registers { 455 + uint32_t CM_ICSC_CONTROL; 456 + uint32_t CM_ICSC_C11_C12; 457 + uint32_t CM_ICSC_C13_C14; 458 + uint32_t CM_ICSC_C21_C22; 459 + uint32_t CM_ICSC_C23_C24; 460 + uint32_t CM_ICSC_C31_C32; 461 + uint32_t CM_ICSC_C33_C34; 462 + uint32_t CM_COMA_C11_C12; 463 + uint32_t CM_COMA_C13_C14; 464 + uint32_t CM_COMA_C21_C22; 465 + uint32_t CM_COMA_C23_C24; 466 + uint32_t CM_COMA_C31_C32; 467 + uint32_t CM_COMA_C33_C34; 468 + uint32_t CM_DGAM_RAMB_START_CNTL_B; 469 + uint32_t CM_DGAM_RAMB_START_CNTL_G; 470 + uint32_t CM_DGAM_RAMB_START_CNTL_R; 471 + uint32_t CM_DGAM_RAMB_SLOPE_CNTL_B; 472 + uint32_t CM_DGAM_RAMB_SLOPE_CNTL_G; 473 + uint32_t CM_DGAM_RAMB_SLOPE_CNTL_R; 474 + uint32_t CM_DGAM_RAMB_END_CNTL1_B; 475 + uint32_t CM_DGAM_RAMB_END_CNTL2_B; 476 + uint32_t CM_DGAM_RAMB_END_CNTL1_G; 477 + uint32_t CM_DGAM_RAMB_END_CNTL2_G; 478 + uint32_t CM_DGAM_RAMB_END_CNTL1_R; 479 + uint32_t CM_DGAM_RAMB_END_CNTL2_R; 480 + uint32_t CM_DGAM_RAMB_REGION_0_1; 481 + uint32_t CM_DGAM_RAMB_REGION_2_3; 482 + uint32_t CM_DGAM_RAMB_REGION_4_5; 483 + uint32_t CM_DGAM_RAMB_REGION_6_7; 484 + uint32_t CM_DGAM_RAMB_REGION_8_9; 485 + uint32_t CM_DGAM_RAMB_REGION_10_11; 486 + uint32_t CM_DGAM_RAMB_REGION_12_13; 487 + uint32_t CM_DGAM_RAMB_REGION_14_15; 488 + uint32_t CM_DGAM_RAMA_START_CNTL_B; 489 + uint32_t CM_DGAM_RAMA_START_CNTL_G; 490 + uint32_t CM_DGAM_RAMA_START_CNTL_R; 491 + uint32_t CM_DGAM_RAMA_SLOPE_CNTL_B; 492 + uint32_t CM_DGAM_RAMA_SLOPE_CNTL_G; 493 + uint32_t CM_DGAM_RAMA_SLOPE_CNTL_R; 494 + uint32_t CM_DGAM_RAMA_END_CNTL1_B; 495 + uint32_t CM_DGAM_RAMA_END_CNTL2_B; 496 + uint32_t CM_DGAM_RAMA_END_CNTL1_G; 497 + uint32_t CM_DGAM_RAMA_END_CNTL2_G; 498 + uint32_t CM_DGAM_RAMA_END_CNTL1_R; 499 + uint32_t CM_DGAM_RAMA_END_CNTL2_R; 500 + uint32_t CM_DGAM_RAMA_REGION_0_1; 501 + uint32_t CM_DGAM_RAMA_REGION_2_3; 502 + uint32_t CM_DGAM_RAMA_REGION_4_5; 503 + uint32_t CM_DGAM_RAMA_REGION_6_7; 504 + uint32_t CM_DGAM_RAMA_REGION_8_9; 505 + uint32_t CM_DGAM_RAMA_REGION_10_11; 506 + uint32_t CM_DGAM_RAMA_REGION_12_13; 507 + uint32_t CM_DGAM_RAMA_REGION_14_15; 508 + uint32_t CM_MEM_PWR_CTRL; 509 + uint32_t CM_IGAM_LUT_RW_CONTROL; 510 + uint32_t CM_DGAM_LUT_WRITE_EN_MASK; 511 + uint32_t CM_DGAM_LUT_INDEX; 512 + uint32_t CM_DGAM_LUT_DATA; 513 + uint32_t CM_CONTROL; 514 + uint32_t CM_DGAM_CONTROL; 515 + uint32_t CM_IGAM_CONTROL; 516 + uint32_t DPP_CONTROL; 517 + uint32_t CURSOR_SETTINS; 518 + uint32_t CNVC_SURFACE_PIXEL_FORMAT; 519 + uint32_t CURSOR0_CONTROL; 520 + uint32_t CURSOR0_COLOR0; 521 + uint32_t CURSOR0_COLOR1; 522 + uint32_t FORMAT_CONTROL; 523 + uint32_t CURSOR_SURFACE_ADDRESS_HIGH; 524 + uint32_t CURSOR_SURFACE_ADDRESS; 525 + uint32_t CURSOR_SIZE; 526 + uint32_t CURSOR_CONTROL; 527 + uint32_t CURSOR_POSITION; 528 + uint32_t CURSOR_HOT_SPOT; 529 + uint32_t CURSOR_DST_OFFSET; 530 + }; 531 + 532 + struct dcn10_ipp { 533 + struct input_pixel_processor base; 534 + 535 + const struct dcn10_ipp_registers *regs; 536 + const struct dcn10_ipp_shift *ipp_shift; 537 + const struct dcn10_ipp_mask *ipp_mask; 538 + 539 + struct dc_cursor_attributes curs_attr; 540 + }; 541 + 542 + void dcn10_ipp_construct(struct dcn10_ipp *ippn10, 543 + struct dc_context *ctx, 544 + int inst, 545 + const struct dcn10_ipp_registers *regs, 546 + const struct dcn10_ipp_shift *ipp_shift, 547 + const struct dcn10_ipp_mask *ipp_mask); 548 + 549 + #endif /* _DCN10_IPP_H_ */
+1102
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c
··· 1 + /* 2 + * Copyright 2012-15 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 + #include "dm_services.h" 26 + #include "dce_calcs.h" 27 + #include "dcn10_mem_input.h" 28 + #include "reg_helper.h" 29 + #include "basics/conversion.h" 30 + 31 + #define REG(reg)\ 32 + mi->mi_regs->reg 33 + 34 + #define CTX \ 35 + mi->base.ctx 36 + 37 + #undef FN 38 + #define FN(reg_name, field_name) \ 39 + mi->mi_shift->field_name, mi->mi_mask->field_name 40 + 41 + static void set_blank(struct dcn10_mem_input *mi, bool blank) 42 + { 43 + uint32_t blank_en = blank ? 1 : 0; 44 + 45 + REG_UPDATE_2(DCHUBP_CNTL, 46 + HUBP_BLANK_EN, blank_en, 47 + HUBP_TTU_DISABLE, blank_en); 48 + } 49 + 50 + 51 + static void disable_request(struct mem_input *mem_input) 52 + { 53 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 54 + 55 + /* To disable the requestors, set blank_en to 1 */ 56 + set_blank(mi, true); 57 + } 58 + 59 + static void vready_workaround(struct mem_input *mem_input, 60 + struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) 61 + { 62 + uint32_t value = 0; 63 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 64 + 65 + /* set HBUBREQ_DEBUG_DB[12] = 1 */ 66 + value = REG_READ(HUBPREQ_DEBUG_DB); 67 + 68 + /* hack mode disable */ 69 + value |= 0x100; 70 + value &= ~0x1000; 71 + 72 + if ((pipe_dest->vstartup_start - 2*(pipe_dest->vready_offset+pipe_dest->vupdate_width 73 + + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) { 74 + /* if (eco_fix_needed(otg_global_sync_timing) 75 + * set HBUBREQ_DEBUG_DB[12] = 1 */ 76 + value |= 0x1000; 77 + } 78 + 79 + REG_WRITE(HUBPREQ_DEBUG_DB, value); 80 + } 81 + 82 + static void program_tiling( 83 + struct dcn10_mem_input *mi, 84 + const union dc_tiling_info *info, 85 + const enum surface_pixel_format pixel_format) 86 + { 87 + REG_UPDATE_6(DCSURF_ADDR_CONFIG, 88 + NUM_PIPES, log_2(info->gfx9.num_pipes), 89 + NUM_BANKS, log_2(info->gfx9.num_banks), 90 + PIPE_INTERLEAVE, info->gfx9.pipe_interleave, 91 + NUM_SE, log_2(info->gfx9.num_shader_engines), 92 + NUM_RB_PER_SE, log_2(info->gfx9.num_rb_per_se), 93 + MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags)); 94 + 95 + REG_UPDATE_4(DCSURF_TILING_CONFIG, 96 + SW_MODE, info->gfx9.swizzle, 97 + META_LINEAR, info->gfx9.meta_linear, 98 + RB_ALIGNED, info->gfx9.rb_aligned, 99 + PIPE_ALIGNED, info->gfx9.pipe_aligned); 100 + } 101 + 102 + static void program_size_and_rotation( 103 + struct dcn10_mem_input *mi, 104 + enum dc_rotation_angle rotation, 105 + enum surface_pixel_format format, 106 + const union plane_size *plane_size, 107 + struct dc_plane_dcc_param *dcc, 108 + bool horizontal_mirror) 109 + { 110 + uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c, mirror; 111 + 112 + /* Program data and meta surface pitch (calculation from addrlib) 113 + * 444 or 420 luma 114 + */ 115 + if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { 116 + pitch = plane_size->video.luma_pitch - 1; 117 + meta_pitch = dcc->video.meta_pitch_l - 1; 118 + pitch_c = plane_size->video.chroma_pitch - 1; 119 + meta_pitch_c = dcc->video.meta_pitch_c - 1; 120 + } else { 121 + pitch = plane_size->grph.surface_pitch - 1; 122 + meta_pitch = dcc->grph.meta_pitch - 1; 123 + pitch_c = 0; 124 + meta_pitch_c = 0; 125 + } 126 + 127 + if (!dcc->enable) { 128 + meta_pitch = 0; 129 + meta_pitch_c = 0; 130 + } 131 + 132 + REG_UPDATE_2(DCSURF_SURFACE_PITCH, 133 + PITCH, pitch, META_PITCH, meta_pitch); 134 + 135 + if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 136 + REG_UPDATE_2(DCSURF_SURFACE_PITCH_C, 137 + PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c); 138 + 139 + if (horizontal_mirror) 140 + mirror = 1; 141 + else 142 + mirror = 0; 143 + 144 + 145 + /* Program rotation angle and horz mirror - no mirror */ 146 + if (rotation == ROTATION_ANGLE_0) 147 + REG_UPDATE_2(DCSURF_SURFACE_CONFIG, 148 + ROTATION_ANGLE, 0, 149 + H_MIRROR_EN, mirror); 150 + else if (rotation == ROTATION_ANGLE_90) 151 + REG_UPDATE_2(DCSURF_SURFACE_CONFIG, 152 + ROTATION_ANGLE, 1, 153 + H_MIRROR_EN, mirror); 154 + else if (rotation == ROTATION_ANGLE_180) 155 + REG_UPDATE_2(DCSURF_SURFACE_CONFIG, 156 + ROTATION_ANGLE, 2, 157 + H_MIRROR_EN, mirror); 158 + else if (rotation == ROTATION_ANGLE_270) 159 + REG_UPDATE_2(DCSURF_SURFACE_CONFIG, 160 + ROTATION_ANGLE, 3, 161 + H_MIRROR_EN, mirror); 162 + } 163 + 164 + static void program_pixel_format( 165 + struct dcn10_mem_input *mi, 166 + enum surface_pixel_format format) 167 + { 168 + uint32_t red_bar = 3; 169 + uint32_t blue_bar = 2; 170 + 171 + /* swap for ABGR format */ 172 + if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 173 + || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 174 + || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS 175 + || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) { 176 + red_bar = 2; 177 + blue_bar = 3; 178 + } 179 + 180 + REG_UPDATE_2(HUBPRET_CONTROL, 181 + CROSSBAR_SRC_CB_B, blue_bar, 182 + CROSSBAR_SRC_CR_R, red_bar); 183 + 184 + /* Mapping is same as ipp programming (cnvc) */ 185 + 186 + switch (format) { 187 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 188 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 189 + SURFACE_PIXEL_FORMAT, 1); 190 + break; 191 + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 192 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 193 + SURFACE_PIXEL_FORMAT, 3); 194 + break; 195 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 196 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 197 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 198 + SURFACE_PIXEL_FORMAT, 8); 199 + break; 200 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 201 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 202 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: 203 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 204 + SURFACE_PIXEL_FORMAT, 10); 205 + break; 206 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 207 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 208 + SURFACE_PIXEL_FORMAT, 22); 209 + break; 210 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 211 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/ 212 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 213 + SURFACE_PIXEL_FORMAT, 24); 214 + break; 215 + 216 + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: 217 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 218 + SURFACE_PIXEL_FORMAT, 65); 219 + break; 220 + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: 221 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 222 + SURFACE_PIXEL_FORMAT, 64); 223 + break; 224 + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: 225 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 226 + SURFACE_PIXEL_FORMAT, 67); 227 + break; 228 + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: 229 + REG_UPDATE(DCSURF_SURFACE_CONFIG, 230 + SURFACE_PIXEL_FORMAT, 66); 231 + break; 232 + default: 233 + BREAK_TO_DEBUGGER(); 234 + break; 235 + } 236 + 237 + /* don't see the need of program the xbar in DCN 1.0 */ 238 + } 239 + 240 + static bool mem_input_program_surface_flip_and_addr( 241 + struct mem_input *mem_input, 242 + const struct dc_plane_address *address, 243 + bool flip_immediate) 244 + { 245 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 246 + 247 + /* program flip type */ 248 + 249 + REG_UPDATE(DCSURF_FLIP_CONTROL, 250 + SURFACE_FLIP_TYPE, flip_immediate); 251 + 252 + /* REG_UPDATE(FLIP_CONTROL, SURFACE_UPDATE_LOCK, 1); */ 253 + 254 + 255 + /* program high first and then the low addr, order matters! */ 256 + switch (address->type) { 257 + case PLN_ADDR_TYPE_GRAPHICS: 258 + if (address->grph.addr.quad_part == 0) 259 + break; 260 + 261 + if (address->grph.meta_addr.quad_part != 0) { 262 + 263 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 264 + PRIMARY_META_SURFACE_ADDRESS_HIGH, 265 + address->grph.meta_addr.high_part); 266 + 267 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 268 + PRIMARY_META_SURFACE_ADDRESS, 269 + address->grph.meta_addr.low_part); 270 + } 271 + 272 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 273 + PRIMARY_SURFACE_ADDRESS_HIGH, 274 + address->grph.addr.high_part); 275 + 276 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS, 277 + PRIMARY_SURFACE_ADDRESS, 278 + address->grph.addr.low_part); 279 + 280 + 281 + /* DCN1.0 does not support const color 282 + * TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1 283 + * base on address->grph.dcc_const_color 284 + * x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma 285 + * x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma 286 + */ 287 + break; 288 + case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: 289 + if (address->video_progressive.luma_addr.quad_part == 0 290 + || address->video_progressive.chroma_addr.quad_part == 0) 291 + break; 292 + 293 + if (address->video_progressive.luma_meta_addr.quad_part != 0) { 294 + 295 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 296 + PRIMARY_META_SURFACE_ADDRESS_HIGH, 297 + address->video_progressive.luma_meta_addr.high_part); 298 + 299 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 300 + PRIMARY_META_SURFACE_ADDRESS, 301 + address->video_progressive.luma_meta_addr.low_part); 302 + 303 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 304 + PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 305 + address->video_progressive.chroma_meta_addr.high_part); 306 + 307 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 308 + PRIMARY_META_SURFACE_ADDRESS_C, 309 + address->video_progressive.chroma_meta_addr.low_part); 310 + } 311 + 312 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 313 + PRIMARY_SURFACE_ADDRESS_HIGH, 314 + address->video_progressive.luma_addr.high_part); 315 + 316 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS, 317 + PRIMARY_SURFACE_ADDRESS, 318 + address->video_progressive.luma_addr.low_part); 319 + 320 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 321 + PRIMARY_SURFACE_ADDRESS_HIGH_C, 322 + address->video_progressive.chroma_addr.high_part); 323 + 324 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 325 + PRIMARY_SURFACE_ADDRESS_C, 326 + address->video_progressive.chroma_addr.low_part); 327 + 328 + break; 329 + case PLN_ADDR_TYPE_GRPH_STEREO: 330 + if (address->grph_stereo.left_addr.quad_part == 0) 331 + break; 332 + if (address->grph_stereo.right_addr.quad_part == 0) 333 + break; 334 + if (address->grph_stereo.right_meta_addr.quad_part != 0) { 335 + 336 + REG_UPDATE(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 337 + SECONDARY_META_SURFACE_ADDRESS_HIGH, 338 + address->grph_stereo.right_meta_addr.high_part); 339 + 340 + REG_UPDATE(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 341 + SECONDARY_META_SURFACE_ADDRESS, 342 + address->grph_stereo.right_meta_addr.low_part); 343 + } 344 + if (address->grph_stereo.left_meta_addr.quad_part != 0) { 345 + 346 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 347 + PRIMARY_META_SURFACE_ADDRESS_HIGH, 348 + address->grph_stereo.left_meta_addr.high_part); 349 + 350 + REG_UPDATE(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 351 + PRIMARY_META_SURFACE_ADDRESS, 352 + address->grph_stereo.left_meta_addr.low_part); 353 + } 354 + 355 + REG_UPDATE(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 356 + SECONDARY_SURFACE_ADDRESS_HIGH, 357 + address->grph_stereo.right_addr.high_part); 358 + 359 + REG_UPDATE(DCSURF_SECONDARY_SURFACE_ADDRESS, 360 + SECONDARY_SURFACE_ADDRESS, 361 + address->grph_stereo.right_addr.low_part); 362 + 363 + 364 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 365 + PRIMARY_SURFACE_ADDRESS_HIGH, 366 + address->grph_stereo.left_addr.high_part); 367 + 368 + REG_UPDATE(DCSURF_PRIMARY_SURFACE_ADDRESS, 369 + PRIMARY_SURFACE_ADDRESS, 370 + address->grph_stereo.left_addr.low_part); 371 + break; 372 + default: 373 + BREAK_TO_DEBUGGER(); 374 + break; 375 + } 376 + /* REG_UPDATE(FLIP_CONTROL, SURFACE_UPDATE_LOCK, 0); */ 377 + 378 + mem_input->request_address = *address; 379 + 380 + if (flip_immediate) 381 + mem_input->current_address = *address; 382 + 383 + return true; 384 + } 385 + 386 + static void program_control(struct dcn10_mem_input *mi, 387 + struct dc_plane_dcc_param *dcc) 388 + { 389 + uint32_t dcc_en = dcc->enable ? 1 : 0; 390 + uint32_t dcc_ind_64b_blk = dcc->grph.independent_64b_blks ? 1 : 0; 391 + 392 + REG_UPDATE_2(DCSURF_SURFACE_CONTROL, 393 + PRIMARY_SURFACE_DCC_EN, dcc_en, 394 + PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); 395 + 396 + } 397 + 398 + static void mem_input_program_surface_config( 399 + struct mem_input *mem_input, 400 + enum surface_pixel_format format, 401 + union dc_tiling_info *tiling_info, 402 + union plane_size *plane_size, 403 + enum dc_rotation_angle rotation, 404 + struct dc_plane_dcc_param *dcc, 405 + bool horizontal_mirror, 406 + bool visible) 407 + { 408 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 409 + 410 + program_control(mi, dcc); 411 + program_tiling(mi, tiling_info, format); 412 + program_size_and_rotation( 413 + mi, rotation, format, plane_size, dcc, horizontal_mirror); 414 + program_pixel_format(mi, format); 415 + 416 + set_blank(mi, !visible); 417 + } 418 + 419 + static void program_requestor( 420 + struct mem_input *mem_input, 421 + struct _vcs_dpi_display_rq_regs_st *rq_regs) 422 + { 423 + 424 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 425 + 426 + REG_UPDATE(HUBPRET_CONTROL, 427 + DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); 428 + REG_SET_4(DCN_EXPANSION_MODE, 0, 429 + DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode, 430 + PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode, 431 + MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode, 432 + CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode); 433 + REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0, 434 + CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size, 435 + MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size, 436 + META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size, 437 + MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size, 438 + DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size, 439 + MPTE_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size, 440 + SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height, 441 + PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear); 442 + REG_SET_8(DCHUBP_REQ_SIZE_CONFIG_C, 0, 443 + CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size, 444 + MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size, 445 + META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size, 446 + MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size, 447 + DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size, 448 + MPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.mpte_group_size, 449 + SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height, 450 + PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear); 451 + } 452 + 453 + 454 + static void program_deadline( 455 + struct mem_input *mem_input, 456 + struct _vcs_dpi_display_dlg_regs_st *dlg_attr, 457 + struct _vcs_dpi_display_ttu_regs_st *ttu_attr) 458 + { 459 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 460 + 461 + /* DLG - Per hubp */ 462 + REG_SET_2(BLANK_OFFSET_0, 0, 463 + REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end, 464 + DLG_V_BLANK_END, dlg_attr->dlg_vblank_end); 465 + 466 + REG_SET(BLANK_OFFSET_1, 0, 467 + MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start); 468 + 469 + REG_SET(DST_DIMENSIONS, 0, 470 + REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal); 471 + 472 + REG_SET_2(DST_AFTER_SCALER, 0, 473 + REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler, 474 + DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler); 475 + 476 + REG_SET_2(PREFETCH_SETTINS, 0, 477 + DST_Y_PREFETCH, dlg_attr->dst_y_prefetch, 478 + VRATIO_PREFETCH, dlg_attr->vratio_prefetch); 479 + 480 + REG_SET_2(VBLANK_PARAMETERS_0, 0, 481 + DST_Y_PER_VM_VBLANK, dlg_attr->dst_y_per_vm_vblank, 482 + DST_Y_PER_ROW_VBLANK, dlg_attr->dst_y_per_row_vblank); 483 + 484 + REG_SET(REF_FREQ_TO_PIX_FREQ, 0, 485 + REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq); 486 + 487 + /* DLG - Per luma/chroma */ 488 + REG_SET(VBLANK_PARAMETERS_1, 0, 489 + REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l); 490 + 491 + REG_SET(VBLANK_PARAMETERS_3, 0, 492 + REFCYC_PER_META_CHUNK_VBLANK_L, dlg_attr->refcyc_per_meta_chunk_vblank_l); 493 + 494 + REG_SET(NOM_PARAMETERS_0, 0, 495 + DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l); 496 + 497 + REG_SET(NOM_PARAMETERS_1, 0, 498 + REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l); 499 + 500 + REG_SET(NOM_PARAMETERS_4, 0, 501 + DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l); 502 + 503 + REG_SET(NOM_PARAMETERS_5, 0, 504 + REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l); 505 + 506 + REG_SET_2(PER_LINE_DELIVERY_PRE, 0, 507 + REFCYC_PER_LINE_DELIVERY_PRE_L, dlg_attr->refcyc_per_line_delivery_pre_l, 508 + REFCYC_PER_LINE_DELIVERY_PRE_C, dlg_attr->refcyc_per_line_delivery_pre_c); 509 + 510 + REG_SET_2(PER_LINE_DELIVERY, 0, 511 + REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l, 512 + REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c); 513 + 514 + REG_SET(PREFETCH_SETTINS_C, 0, 515 + VRATIO_PREFETCH_C, dlg_attr->vratio_prefetch_c); 516 + 517 + REG_SET(VBLANK_PARAMETERS_2, 0, 518 + REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c); 519 + 520 + REG_SET(VBLANK_PARAMETERS_4, 0, 521 + REFCYC_PER_META_CHUNK_VBLANK_C, dlg_attr->refcyc_per_meta_chunk_vblank_c); 522 + 523 + REG_SET(NOM_PARAMETERS_2, 0, 524 + DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c); 525 + 526 + REG_SET(NOM_PARAMETERS_3, 0, 527 + REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c); 528 + 529 + REG_SET(NOM_PARAMETERS_6, 0, 530 + DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c); 531 + 532 + REG_SET(NOM_PARAMETERS_7, 0, 533 + REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c); 534 + 535 + /* TTU - per hubp */ 536 + REG_SET_2(DCN_TTU_QOS_WM, 0, 537 + QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm, 538 + QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm); 539 + 540 + REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0, 541 + MIN_TTU_VBLANK, ttu_attr->min_ttu_vblank, 542 + QoS_LEVEL_FLIP, ttu_attr->qos_level_flip); 543 + 544 + /* TTU - per luma/chroma */ 545 + /* Assumed surf0 is luma and 1 is chroma */ 546 + 547 + REG_SET_3(DCN_SURF0_TTU_CNTL0, 0, 548 + REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l, 549 + QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l, 550 + QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l); 551 + 552 + REG_SET(DCN_SURF0_TTU_CNTL1, 0, 553 + REFCYC_PER_REQ_DELIVERY_PRE, 554 + ttu_attr->refcyc_per_req_delivery_pre_l); 555 + 556 + REG_SET_3(DCN_SURF1_TTU_CNTL0, 0, 557 + REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c, 558 + QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c, 559 + QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c); 560 + 561 + REG_SET(DCN_SURF1_TTU_CNTL1, 0, 562 + REFCYC_PER_REQ_DELIVERY_PRE, 563 + ttu_attr->refcyc_per_req_delivery_pre_c); 564 + } 565 + 566 + static void mem_input_setup( 567 + struct mem_input *mem_input, 568 + struct _vcs_dpi_display_dlg_regs_st *dlg_attr, 569 + struct _vcs_dpi_display_ttu_regs_st *ttu_attr, 570 + struct _vcs_dpi_display_rq_regs_st *rq_regs, 571 + struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) 572 + { 573 + /* otg is locked when this func is called. Register are double buffered. 574 + * disable the requestors is not needed 575 + */ 576 + /* disable_request(mem_input); */ 577 + program_requestor(mem_input, rq_regs); 578 + program_deadline(mem_input, dlg_attr, ttu_attr); 579 + vready_workaround(mem_input, pipe_dest); 580 + } 581 + 582 + static uint32_t convert_and_clamp( 583 + uint32_t wm_ns, 584 + uint32_t refclk_mhz, 585 + uint32_t clamp_value) 586 + { 587 + uint32_t ret_val = 0; 588 + ret_val = wm_ns * refclk_mhz; 589 + ret_val /= 1000; 590 + 591 + if (ret_val > clamp_value) 592 + ret_val = clamp_value; 593 + 594 + return ret_val; 595 + } 596 + 597 + static void program_watermarks( 598 + struct mem_input *mem_input, 599 + struct dcn_watermark_set *watermarks, 600 + unsigned int refclk_mhz) 601 + { 602 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 603 + /* 604 + * Need to clamp to max of the register values (i.e. no wrap) 605 + * for dcn1, all wm registers are 21-bit wide 606 + */ 607 + uint32_t prog_wm_value; 608 + 609 + /* Repeat for water mark set A, B, C and D. */ 610 + /* clock state A */ 611 + prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 612 + refclk_mhz, 0x1fffff); 613 + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 614 + 615 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 616 + "URGENCY_WATERMARK_A calculated =%d\n" 617 + "HW register value = 0x%x\n", 618 + watermarks->a.urgent_ns, prog_wm_value); 619 + 620 + prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, 621 + refclk_mhz, 0x1fffff); 622 + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); 623 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 624 + "PTE_META_URGENCY_WATERMARK_A calculated =%d\n" 625 + "HW register value = 0x%x\n", 626 + watermarks->a.pte_meta_urgent_ns, prog_wm_value); 627 + 628 + 629 + prog_wm_value = convert_and_clamp( 630 + watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, 631 + refclk_mhz, 0x1fffff); 632 + 633 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); 634 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 635 + "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" 636 + "HW register value = 0x%x\n", 637 + watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 638 + 639 + 640 + prog_wm_value = convert_and_clamp( 641 + watermarks->a.cstate_pstate.cstate_exit_ns, 642 + refclk_mhz, 0x1fffff); 643 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 644 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 645 + "SR_EXIT_WATERMARK_A calculated =%d\n" 646 + "HW register value = 0x%x\n", 647 + watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); 648 + 649 + 650 + prog_wm_value = convert_and_clamp( 651 + watermarks->a.cstate_pstate.pstate_change_ns, 652 + refclk_mhz, 0x1fffff); 653 + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 654 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 655 + "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 656 + "HW register value = 0x%x\n\n", 657 + watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 658 + 659 + 660 + /* clock state B */ 661 + prog_wm_value = convert_and_clamp( 662 + watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); 663 + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); 664 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 665 + "URGENCY_WATERMARK_B calculated =%d\n" 666 + "HW register value = 0x%x\n", 667 + watermarks->b.urgent_ns, prog_wm_value); 668 + 669 + 670 + prog_wm_value = convert_and_clamp( 671 + watermarks->b.pte_meta_urgent_ns, 672 + refclk_mhz, 0x1fffff); 673 + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); 674 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 675 + "PTE_META_URGENCY_WATERMARK_B calculated =%d\n" 676 + "HW register value = 0x%x\n", 677 + watermarks->b.pte_meta_urgent_ns, prog_wm_value); 678 + 679 + 680 + prog_wm_value = convert_and_clamp( 681 + watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 682 + refclk_mhz, 0x1fffff); 683 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 684 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 685 + "SR_ENTER_WATERMARK_B calculated =%d\n" 686 + "HW register value = 0x%x\n", 687 + watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 688 + 689 + 690 + prog_wm_value = convert_and_clamp( 691 + watermarks->b.cstate_pstate.cstate_exit_ns, 692 + refclk_mhz, 0x1fffff); 693 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); 694 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 695 + "SR_EXIT_WATERMARK_B calculated =%d\n" 696 + "HW register value = 0x%x\n", 697 + watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 698 + 699 + prog_wm_value = convert_and_clamp( 700 + watermarks->b.cstate_pstate.pstate_change_ns, 701 + refclk_mhz, 0x1fffff); 702 + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 703 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 704 + "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" 705 + "HW register value = 0x%x\n", 706 + watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 707 + 708 + /* clock state C */ 709 + prog_wm_value = convert_and_clamp( 710 + watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); 711 + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); 712 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 713 + "URGENCY_WATERMARK_C calculated =%d\n" 714 + "HW register value = 0x%x\n", 715 + watermarks->c.urgent_ns, prog_wm_value); 716 + 717 + 718 + prog_wm_value = convert_and_clamp( 719 + watermarks->c.pte_meta_urgent_ns, 720 + refclk_mhz, 0x1fffff); 721 + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); 722 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 723 + "PTE_META_URGENCY_WATERMARK_C calculated =%d\n" 724 + "HW register value = 0x%x\n", 725 + watermarks->c.pte_meta_urgent_ns, prog_wm_value); 726 + 727 + 728 + prog_wm_value = convert_and_clamp( 729 + watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 730 + refclk_mhz, 0x1fffff); 731 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 732 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 733 + "SR_ENTER_WATERMARK_C calculated =%d\n" 734 + "HW register value = 0x%x\n", 735 + watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 736 + 737 + 738 + prog_wm_value = convert_and_clamp( 739 + watermarks->c.cstate_pstate.cstate_exit_ns, 740 + refclk_mhz, 0x1fffff); 741 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); 742 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 743 + "SR_EXIT_WATERMARK_C calculated =%d\n" 744 + "HW register value = 0x%x\n", 745 + watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 746 + 747 + 748 + prog_wm_value = convert_and_clamp( 749 + watermarks->c.cstate_pstate.pstate_change_ns, 750 + refclk_mhz, 0x1fffff); 751 + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 752 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 753 + "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" 754 + "HW register value = 0x%x\n", 755 + watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 756 + 757 + /* clock state D */ 758 + prog_wm_value = convert_and_clamp( 759 + watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); 760 + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); 761 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 762 + "URGENCY_WATERMARK_D calculated =%d\n" 763 + "HW register value = 0x%x\n", 764 + watermarks->d.urgent_ns, prog_wm_value); 765 + 766 + prog_wm_value = convert_and_clamp( 767 + watermarks->d.pte_meta_urgent_ns, 768 + refclk_mhz, 0x1fffff); 769 + REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); 770 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 771 + "PTE_META_URGENCY_WATERMARK_D calculated =%d\n" 772 + "HW register value = 0x%x\n", 773 + watermarks->d.pte_meta_urgent_ns, prog_wm_value); 774 + 775 + 776 + prog_wm_value = convert_and_clamp( 777 + watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 778 + refclk_mhz, 0x1fffff); 779 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 780 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 781 + "SR_ENTER_WATERMARK_D calculated =%d\n" 782 + "HW register value = 0x%x\n", 783 + watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 784 + 785 + 786 + prog_wm_value = convert_and_clamp( 787 + watermarks->d.cstate_pstate.cstate_exit_ns, 788 + refclk_mhz, 0x1fffff); 789 + REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); 790 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 791 + "SR_EXIT_WATERMARK_D calculated =%d\n" 792 + "HW register value = 0x%x\n", 793 + watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 794 + 795 + 796 + prog_wm_value = convert_and_clamp( 797 + watermarks->d.cstate_pstate.pstate_change_ns, 798 + refclk_mhz, 0x1fffff); 799 + REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 800 + dm_logger_write(mem_input->ctx->logger, LOG_HW_MARKS, 801 + "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 802 + "HW register value = 0x%x\n\n", 803 + watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 804 + 805 + REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 806 + DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 807 + REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 808 + DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 0); 809 + REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL, 810 + DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 811 + REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 812 + DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 68); 813 + 814 + #if 0 815 + REG_UPDATE_2(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, 816 + DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1, 817 + DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); 818 + #endif 819 + } 820 + 821 + static void mem_input_program_display_marks( 822 + struct mem_input *mem_input, 823 + struct bw_watermarks nbp, 824 + struct bw_watermarks stutter, 825 + struct bw_watermarks urgent, 826 + uint32_t total_dest_line_time_ns) 827 + { 828 + /* only for dce 829 + * dcn use only program_watermarks 830 + */ 831 + } 832 + 833 + bool mem_input_is_flip_pending(struct mem_input *mem_input) 834 + { 835 + uint32_t update_pending = 0; 836 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 837 + 838 + REG_GET(DCSURF_FLIP_CONTROL, 839 + SURFACE_UPDATE_PENDING, &update_pending); 840 + 841 + if (update_pending) 842 + return true; 843 + 844 + mem_input->current_address = mem_input->request_address; 845 + return false; 846 + } 847 + 848 + static void mem_input_update_dchub( 849 + struct mem_input *mem_input, 850 + struct dchub_init_data *dh_data) 851 + { 852 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 853 + /* TODO: port code from dal2 */ 854 + switch (dh_data->fb_mode) { 855 + case FRAME_BUFFER_MODE_ZFB_ONLY: 856 + /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/ 857 + REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP, 858 + SDPIF_FB_TOP, 0); 859 + 860 + REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE, 861 + SDPIF_FB_BASE, 0x0FFFF); 862 + 863 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 864 + SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 865 + 866 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 867 + SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 868 + 869 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 870 + SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 871 + dh_data->zfb_size_in_byte - 1) >> 22); 872 + break; 873 + case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL: 874 + /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 875 + 876 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 877 + SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 878 + 879 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 880 + SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 881 + 882 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 883 + SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 884 + dh_data->zfb_size_in_byte - 1) >> 22); 885 + break; 886 + case FRAME_BUFFER_MODE_LOCAL_ONLY: 887 + /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 888 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 889 + SDPIF_AGP_BASE, 0); 890 + 891 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 892 + SDPIF_AGP_BOT, 0X03FFFF); 893 + 894 + REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 895 + SDPIF_AGP_TOP, 0); 896 + break; 897 + default: 898 + break; 899 + } 900 + 901 + dh_data->dchub_initialzied = true; 902 + dh_data->dchub_info_valid = false; 903 + } 904 + 905 + struct vm_system_aperture_param { 906 + PHYSICAL_ADDRESS_LOC sys_default; 907 + PHYSICAL_ADDRESS_LOC sys_low; 908 + PHYSICAL_ADDRESS_LOC sys_high; 909 + }; 910 + 911 + static void read_vm_system_aperture_settings(struct dcn10_mem_input *mi, 912 + struct vm_system_aperture_param *apt) 913 + { 914 + PHYSICAL_ADDRESS_LOC physical_page_number; 915 + uint32_t logical_addr_low; 916 + uint32_t logical_addr_high; 917 + 918 + REG_GET(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 919 + PHYSICAL_PAGE_NUMBER_MSB, &physical_page_number.high_part); 920 + REG_GET(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 921 + PHYSICAL_PAGE_NUMBER_LSB, &physical_page_number.low_part); 922 + 923 + REG_GET(MC_VM_SYSTEM_APERTURE_LOW_ADDR, 924 + LOGICAL_ADDR, &logical_addr_low); 925 + 926 + REG_GET(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 927 + LOGICAL_ADDR, &logical_addr_high); 928 + 929 + apt->sys_default.quad_part = physical_page_number.quad_part << 12; 930 + apt->sys_low.quad_part = (int64_t)logical_addr_low << 18; 931 + apt->sys_high.quad_part = (int64_t)logical_addr_high << 18; 932 + } 933 + 934 + static void set_vm_system_aperture_settings(struct dcn10_mem_input *mi, 935 + struct vm_system_aperture_param *apt) 936 + { 937 + PHYSICAL_ADDRESS_LOC mc_vm_apt_default; 938 + PHYSICAL_ADDRESS_LOC mc_vm_apt_low; 939 + PHYSICAL_ADDRESS_LOC mc_vm_apt_high; 940 + 941 + mc_vm_apt_default.quad_part = apt->sys_default.quad_part >> 12; 942 + mc_vm_apt_low.quad_part = apt->sys_low.quad_part >> 12; 943 + mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12; 944 + 945 + REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 946 + MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, 1, /* 1 = system physical memory */ 947 + MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part); 948 + REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 949 + MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part); 950 + 951 + REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0, 952 + MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mc_vm_apt_low.high_part); 953 + REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0, 954 + MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mc_vm_apt_low.low_part); 955 + 956 + REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0, 957 + MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, mc_vm_apt_high.high_part); 958 + REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0, 959 + MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part); 960 + } 961 + 962 + struct vm_context0_param { 963 + PHYSICAL_ADDRESS_LOC pte_base; 964 + PHYSICAL_ADDRESS_LOC pte_start; 965 + PHYSICAL_ADDRESS_LOC pte_end; 966 + PHYSICAL_ADDRESS_LOC fault_default; 967 + }; 968 + 969 + /* Temporary read settings, future will get values from kmd directly */ 970 + static void read_vm_context0_settings(struct dcn10_mem_input *mi, 971 + struct vm_context0_param *vm0) 972 + { 973 + PHYSICAL_ADDRESS_LOC fb_base; 974 + PHYSICAL_ADDRESS_LOC fb_offset; 975 + uint32_t fb_base_value; 976 + uint32_t fb_offset_value; 977 + 978 + REG_GET(DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, &fb_base_value); 979 + REG_GET(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, &fb_offset_value); 980 + 981 + REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, 982 + PAGE_DIRECTORY_ENTRY_HI32, &vm0->pte_base.high_part); 983 + REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, 984 + PAGE_DIRECTORY_ENTRY_LO32, &vm0->pte_base.low_part); 985 + 986 + REG_GET(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, 987 + LOGICAL_PAGE_NUMBER_HI4, &vm0->pte_start.high_part); 988 + REG_GET(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, 989 + LOGICAL_PAGE_NUMBER_LO32, &vm0->pte_start.low_part); 990 + 991 + REG_GET(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, 992 + LOGICAL_PAGE_NUMBER_HI4, &vm0->pte_end.high_part); 993 + REG_GET(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, 994 + LOGICAL_PAGE_NUMBER_LO32, &vm0->pte_end.low_part); 995 + 996 + REG_GET(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, 997 + PHYSICAL_PAGE_ADDR_HI4, &vm0->fault_default.high_part); 998 + REG_GET(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, 999 + PHYSICAL_PAGE_ADDR_LO32, &vm0->fault_default.low_part); 1000 + 1001 + /* 1002 + * The values in VM_CONTEXT0_PAGE_TABLE_BASE_ADDR is in UMA space. 1003 + * Therefore we need to do 1004 + * DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 1005 + * - DCHUBBUB_SDPIF_FB_OFFSET + DCHUBBUB_SDPIF_FB_BASE 1006 + */ 1007 + fb_base.quad_part = (uint64_t)fb_base_value << 24; 1008 + fb_offset.quad_part = (uint64_t)fb_offset_value << 24; 1009 + vm0->pte_base.quad_part += fb_base.quad_part; 1010 + vm0->pte_base.quad_part -= fb_offset.quad_part; 1011 + } 1012 + 1013 + static void set_vm_context0_settings(struct dcn10_mem_input *mi, 1014 + const struct vm_context0_param *vm0) 1015 + { 1016 + /* pte base */ 1017 + REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0, 1018 + VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part); 1019 + REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, 0, 1020 + VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, vm0->pte_base.low_part); 1021 + 1022 + /* pte start */ 1023 + REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, 0, 1024 + VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, vm0->pte_start.high_part); 1025 + REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, 0, 1026 + VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, vm0->pte_start.low_part); 1027 + 1028 + /* pte end */ 1029 + REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, 0, 1030 + VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->pte_end.high_part); 1031 + REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, 0, 1032 + VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part); 1033 + 1034 + /* fault handling */ 1035 + REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0, 1036 + VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->fault_default.high_part); 1037 + /* VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, 0 */ 1038 + REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0, 1039 + VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part); 1040 + } 1041 + 1042 + void dcn_mem_input_program_pte_vm(struct mem_input *mem_input, 1043 + enum surface_pixel_format format, 1044 + union dc_tiling_info *tiling_info, 1045 + enum dc_rotation_angle rotation) 1046 + { 1047 + struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 1048 + struct vm_system_aperture_param apt = { {{ 0 } } }; 1049 + struct vm_context0_param vm0 = { { { 0 } } }; 1050 + 1051 + 1052 + read_vm_system_aperture_settings(mi, &apt); 1053 + read_vm_context0_settings(mi, &vm0); 1054 + 1055 + set_vm_system_aperture_settings(mi, &apt); 1056 + set_vm_context0_settings(mi, &vm0); 1057 + 1058 + /* control: enable VM PTE*/ 1059 + REG_SET_2(DCN_VM_MX_L1_TLB_CNTL, 0, 1060 + ENABLE_L1_TLB, 1, 1061 + SYSTEM_ACCESS_MODE, 3); 1062 + } 1063 + 1064 + static struct mem_input_funcs dcn10_mem_input_funcs = { 1065 + .mem_input_program_display_marks = mem_input_program_display_marks, 1066 + .allocate_mem_input = NULL, 1067 + .free_mem_input = NULL, 1068 + .disable_request = disable_request, 1069 + .mem_input_program_surface_flip_and_addr = 1070 + mem_input_program_surface_flip_and_addr, 1071 + .mem_input_program_surface_config = 1072 + mem_input_program_surface_config, 1073 + .mem_input_is_flip_pending = mem_input_is_flip_pending, 1074 + .mem_input_setup = mem_input_setup, 1075 + .program_watermarks = program_watermarks, 1076 + .mem_input_update_dchub = mem_input_update_dchub, 1077 + .mem_input_program_pte_vm = dcn_mem_input_program_pte_vm, 1078 + }; 1079 + 1080 + 1081 + /*****************************************/ 1082 + /* Constructor, Destructor */ 1083 + /*****************************************/ 1084 + 1085 + bool dcn10_mem_input_construct( 1086 + struct dcn10_mem_input *mi, 1087 + struct dc_context *ctx, 1088 + uint32_t inst, 1089 + const struct dcn_mi_registers *mi_regs, 1090 + const struct dcn_mi_shift *mi_shift, 1091 + const struct dcn_mi_mask *mi_mask) 1092 + { 1093 + mi->base.funcs = &dcn10_mem_input_funcs; 1094 + mi->base.ctx = ctx; 1095 + mi->mi_regs = mi_regs; 1096 + mi->mi_shift = mi_shift; 1097 + mi->mi_mask = mi_mask; 1098 + mi->base.inst = inst; 1099 + 1100 + return true; 1101 + } 1102 +
+553
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h
··· 1 + /* Copyright 2012-15 Advanced Micro Devices, Inc. 2 + * 3 + * Permission is hereby granted, free of charge, to any person obtaining a 4 + * copy of this software and associated documentation files (the "Software"), 5 + * to deal in the Software without restriction, including without limitation 6 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 + * and/or sell copies of the Software, and to permit persons to whom the 8 + * Software is furnished to do so, subject to the following conditions: 9 + * 10 + * The above copyright notice and this permission notice shall be included in 11 + * all copies or substantial portions of the Software. 12 + * 13 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 + * OTHER DEALINGS IN THE SOFTWARE. 20 + * 21 + * Authors: AMD 22 + * 23 + */ 24 + 25 + #ifndef __DC_MEM_INPUT_DCN10_H__ 26 + #define __DC_MEM_INPUT_DCN10_H__ 27 + 28 + #include "mem_input.h" 29 + 30 + #define TO_DCN10_MEM_INPUT(mi)\ 31 + container_of(mi, struct dcn10_mem_input, base) 32 + 33 + 34 + #define MI_DCN10_REG_LIST(id)\ 35 + SRI(DCHUBP_CNTL, HUBP, id),\ 36 + SRI(HUBPREQ_DEBUG_DB, HUBP, id),\ 37 + SRI(DCSURF_ADDR_CONFIG, HUBP, id),\ 38 + SRI(DCSURF_TILING_CONFIG, HUBP, id),\ 39 + SRI(DCSURF_SURFACE_PITCH, HUBPREQ, id),\ 40 + SRI(DCSURF_SURFACE_PITCH_C, HUBPREQ, id),\ 41 + SRI(DCSURF_SURFACE_CONFIG, HUBP, id),\ 42 + SRI(DCSURF_FLIP_CONTROL, HUBPREQ, id),\ 43 + SRI(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, HUBPREQ, id),\ 44 + SRI(DCSURF_PRIMARY_SURFACE_ADDRESS, HUBPREQ, id),\ 45 + SRI(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, HUBPREQ, id),\ 46 + SRI(DCSURF_SECONDARY_SURFACE_ADDRESS, HUBPREQ, id),\ 47 + SRI(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, HUBPREQ, id),\ 48 + SRI(DCSURF_PRIMARY_META_SURFACE_ADDRESS, HUBPREQ, id),\ 49 + SRI(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, HUBPREQ, id),\ 50 + SRI(DCSURF_SECONDARY_META_SURFACE_ADDRESS, HUBPREQ, id),\ 51 + SRI(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, HUBPREQ, id),\ 52 + SRI(DCSURF_PRIMARY_SURFACE_ADDRESS_C, HUBPREQ, id),\ 53 + SRI(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, HUBPREQ, id),\ 54 + SRI(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, HUBPREQ, id),\ 55 + SRI(DCSURF_SURFACE_CONTROL, HUBPREQ, id),\ 56 + SRI(HUBPRET_CONTROL, HUBPRET, id),\ 57 + SRI(DCN_EXPANSION_MODE, HUBPREQ, id),\ 58 + SRI(DCHUBP_REQ_SIZE_CONFIG, HUBP, id),\ 59 + SRI(DCHUBP_REQ_SIZE_CONFIG_C, HUBP, id),\ 60 + SRI(BLANK_OFFSET_0, HUBPREQ, id),\ 61 + SRI(BLANK_OFFSET_1, HUBPREQ, id),\ 62 + SRI(DST_DIMENSIONS, HUBPREQ, id),\ 63 + SRI(DST_AFTER_SCALER, HUBPREQ, id),\ 64 + SRI(PREFETCH_SETTINS, HUBPREQ, id),\ 65 + SRI(VBLANK_PARAMETERS_0, HUBPREQ, id),\ 66 + SRI(REF_FREQ_TO_PIX_FREQ, HUBPREQ, id),\ 67 + SRI(VBLANK_PARAMETERS_1, HUBPREQ, id),\ 68 + SRI(VBLANK_PARAMETERS_3, HUBPREQ, id),\ 69 + SRI(NOM_PARAMETERS_0, HUBPREQ, id),\ 70 + SRI(NOM_PARAMETERS_1, HUBPREQ, id),\ 71 + SRI(NOM_PARAMETERS_4, HUBPREQ, id),\ 72 + SRI(NOM_PARAMETERS_5, HUBPREQ, id),\ 73 + SRI(PER_LINE_DELIVERY_PRE, HUBPREQ, id),\ 74 + SRI(PER_LINE_DELIVERY, HUBPREQ, id),\ 75 + SRI(PREFETCH_SETTINS_C, HUBPREQ, id),\ 76 + SRI(VBLANK_PARAMETERS_2, HUBPREQ, id),\ 77 + SRI(VBLANK_PARAMETERS_4, HUBPREQ, id),\ 78 + SRI(NOM_PARAMETERS_2, HUBPREQ, id),\ 79 + SRI(NOM_PARAMETERS_3, HUBPREQ, id),\ 80 + SRI(NOM_PARAMETERS_6, HUBPREQ, id),\ 81 + SRI(NOM_PARAMETERS_7, HUBPREQ, id),\ 82 + SRI(DCN_TTU_QOS_WM, HUBPREQ, id),\ 83 + SRI(DCN_GLOBAL_TTU_CNTL, HUBPREQ, id),\ 84 + SRI(DCN_SURF0_TTU_CNTL0, HUBPREQ, id),\ 85 + SRI(DCN_SURF0_TTU_CNTL1, HUBPREQ, id),\ 86 + SRI(DCN_SURF1_TTU_CNTL0, HUBPREQ, id),\ 87 + SRI(DCN_SURF1_TTU_CNTL1, HUBPREQ, id),\ 88 + SRI(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, HUBPREQ, id),\ 89 + SRI(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, HUBPREQ, id),\ 90 + SRI(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, HUBPREQ, id),\ 91 + SRI(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, HUBPREQ, id),\ 92 + SRI(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, HUBPREQ, id),\ 93 + SRI(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, HUBPREQ, id),\ 94 + SRI(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, HUBPREQ, id),\ 95 + SRI(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, HUBPREQ, id),\ 96 + SRI(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id),\ 97 + SRI(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, HUBPREQ, id),\ 98 + SRI(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, HUBPREQ, id),\ 99 + SRI(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, HUBPREQ, id),\ 100 + SRI(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, HUBPREQ, id),\ 101 + SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\ 102 + SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\ 103 + SR(DCHUBBUB_SDPIF_FB_TOP),\ 104 + SR(DCHUBBUB_SDPIF_FB_BASE),\ 105 + SR(DCHUBBUB_SDPIF_FB_OFFSET),\ 106 + SR(DCHUBBUB_SDPIF_AGP_BASE),\ 107 + SR(DCHUBBUB_SDPIF_AGP_BOT),\ 108 + SR(DCHUBBUB_SDPIF_AGP_TOP),\ 109 + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\ 110 + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\ 111 + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\ 112 + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\ 113 + SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\ 114 + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\ 115 + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\ 116 + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\ 117 + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\ 118 + SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\ 119 + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\ 120 + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\ 121 + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\ 122 + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\ 123 + SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\ 124 + SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\ 125 + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\ 126 + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\ 127 + SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D),\ 128 + SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\ 129 + SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\ 130 + SR(DCHUBBUB_ARB_SAT_LEVEL),\ 131 + SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\ 132 + /* todo: get these from GVM instead of reading registers ourselves */\ 133 + GC_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\ 134 + GC_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\ 135 + GC_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32),\ 136 + GC_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32),\ 137 + GC_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32),\ 138 + GC_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32),\ 139 + GC_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32),\ 140 + GC_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32),\ 141 + GC_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB),\ 142 + GC_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB),\ 143 + GC_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\ 144 + GC_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR) 145 + 146 + struct dcn_mi_registers { 147 + uint32_t DCHUBP_CNTL; 148 + uint32_t HUBPREQ_DEBUG_DB; 149 + uint32_t DCSURF_ADDR_CONFIG; 150 + uint32_t DCSURF_TILING_CONFIG; 151 + uint32_t DCSURF_SURFACE_PITCH; 152 + uint32_t DCSURF_SURFACE_PITCH_C; 153 + uint32_t DCSURF_SURFACE_CONFIG; 154 + uint32_t DCSURF_FLIP_CONTROL; 155 + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; 156 + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS; 157 + uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH; 158 + uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS; 159 + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH; 160 + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS; 161 + uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH; 162 + uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS; 163 + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; 164 + uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C; 165 + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C; 166 + uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_C; 167 + uint32_t DCSURF_SURFACE_CONTROL; 168 + uint32_t HUBPRET_CONTROL; 169 + uint32_t DCN_EXPANSION_MODE; 170 + uint32_t DCHUBP_REQ_SIZE_CONFIG; 171 + uint32_t DCHUBP_REQ_SIZE_CONFIG_C; 172 + uint32_t BLANK_OFFSET_0; 173 + uint32_t BLANK_OFFSET_1; 174 + uint32_t DST_DIMENSIONS; 175 + uint32_t DST_AFTER_SCALER; 176 + uint32_t PREFETCH_SETTINS; 177 + uint32_t VBLANK_PARAMETERS_0; 178 + uint32_t REF_FREQ_TO_PIX_FREQ; 179 + uint32_t VBLANK_PARAMETERS_1; 180 + uint32_t VBLANK_PARAMETERS_3; 181 + uint32_t NOM_PARAMETERS_0; 182 + uint32_t NOM_PARAMETERS_1; 183 + uint32_t NOM_PARAMETERS_4; 184 + uint32_t NOM_PARAMETERS_5; 185 + uint32_t PER_LINE_DELIVERY_PRE; 186 + uint32_t PER_LINE_DELIVERY; 187 + uint32_t PREFETCH_SETTINS_C; 188 + uint32_t VBLANK_PARAMETERS_2; 189 + uint32_t VBLANK_PARAMETERS_4; 190 + uint32_t NOM_PARAMETERS_2; 191 + uint32_t NOM_PARAMETERS_3; 192 + uint32_t NOM_PARAMETERS_6; 193 + uint32_t NOM_PARAMETERS_7; 194 + uint32_t DCN_TTU_QOS_WM; 195 + uint32_t DCN_GLOBAL_TTU_CNTL; 196 + uint32_t DCN_SURF0_TTU_CNTL0; 197 + uint32_t DCN_SURF0_TTU_CNTL1; 198 + uint32_t DCN_SURF1_TTU_CNTL0; 199 + uint32_t DCN_SURF1_TTU_CNTL1; 200 + uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB; 201 + uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB; 202 + uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB; 203 + uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB; 204 + uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB; 205 + uint32_t DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB; 206 + uint32_t DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB; 207 + uint32_t DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB; 208 + uint32_t DCN_VM_MX_L1_TLB_CNTL; 209 + uint32_t DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB; 210 + uint32_t DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB; 211 + uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB; 212 + uint32_t DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB; 213 + uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB; 214 + uint32_t DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB; 215 + uint32_t DCHUBBUB_SDPIF_FB_TOP; 216 + uint32_t DCHUBBUB_SDPIF_FB_BASE; 217 + uint32_t DCHUBBUB_SDPIF_FB_OFFSET; 218 + uint32_t DCHUBBUB_SDPIF_AGP_BASE; 219 + uint32_t DCHUBBUB_SDPIF_AGP_BOT; 220 + uint32_t DCHUBBUB_SDPIF_AGP_TOP; 221 + uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A; 222 + uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A; 223 + uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A; 224 + uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A; 225 + uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A; 226 + uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B; 227 + uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B; 228 + uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B; 229 + uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B; 230 + uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B; 231 + uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C; 232 + uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C; 233 + uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C; 234 + uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C; 235 + uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C; 236 + uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D; 237 + uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D; 238 + uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D; 239 + uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D; 240 + uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D; 241 + uint32_t DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL; 242 + uint32_t DCHUBBUB_ARB_SAT_LEVEL; 243 + uint32_t DCHUBBUB_ARB_DF_REQ_OUTSTAND; 244 + 245 + /* GC registers. read only. temporary hack */ 246 + uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32; 247 + uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; 248 + uint32_t VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32; 249 + uint32_t VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32; 250 + uint32_t VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32; 251 + uint32_t VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32; 252 + uint32_t VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32; 253 + uint32_t VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32; 254 + uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB; 255 + uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB; 256 + uint32_t MC_VM_SYSTEM_APERTURE_LOW_ADDR; 257 + uint32_t MC_VM_SYSTEM_APERTURE_HIGH_ADDR; 258 + }; 259 + 260 + #define MI_SF(reg_name, field_name, post_fix)\ 261 + .field_name = reg_name ## __ ## field_name ## post_fix 262 + 263 + #define MI_DCN10_MASK_SH_LIST(mask_sh)\ 264 + MI_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\ 265 + MI_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\ 266 + MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\ 267 + MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_BANKS, mask_sh),\ 268 + MI_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\ 269 + MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_SE, mask_sh),\ 270 + MI_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_RB_PER_SE, mask_sh),\ 271 + MI_SF(HUBP0_DCSURF_ADDR_CONFIG, MAX_COMPRESSED_FRAGS, mask_sh),\ 272 + MI_SF(HUBP0_DCSURF_TILING_CONFIG, SW_MODE, mask_sh),\ 273 + MI_SF(HUBP0_DCSURF_TILING_CONFIG, META_LINEAR, mask_sh),\ 274 + MI_SF(HUBP0_DCSURF_TILING_CONFIG, RB_ALIGNED, mask_sh),\ 275 + MI_SF(HUBP0_DCSURF_TILING_CONFIG, PIPE_ALIGNED, mask_sh),\ 276 + MI_SF(HUBPREQ0_DCSURF_SURFACE_PITCH, PITCH, mask_sh),\ 277 + MI_SF(HUBPREQ0_DCSURF_SURFACE_PITCH, META_PITCH, mask_sh),\ 278 + MI_SF(HUBPREQ0_DCSURF_SURFACE_PITCH_C, PITCH_C, mask_sh),\ 279 + MI_SF(HUBPREQ0_DCSURF_SURFACE_PITCH_C, META_PITCH_C, mask_sh),\ 280 + MI_SF(HUBP0_DCSURF_SURFACE_CONFIG, ROTATION_ANGLE, mask_sh),\ 281 + MI_SF(HUBP0_DCSURF_SURFACE_CONFIG, H_MIRROR_EN, mask_sh),\ 282 + MI_SF(HUBP0_DCSURF_SURFACE_CONFIG, SURFACE_PIXEL_FORMAT, mask_sh),\ 283 + MI_SF(HUBPREQ0_DCSURF_FLIP_CONTROL, SURFACE_FLIP_TYPE, mask_sh),\ 284 + MI_SF(HUBPREQ0_DCSURF_FLIP_CONTROL, SURFACE_UPDATE_PENDING, mask_sh),\ 285 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, PRIMARY_SURFACE_ADDRESS_HIGH, mask_sh),\ 286 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS, PRIMARY_SURFACE_ADDRESS, mask_sh),\ 287 + MI_SF(HUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, SECONDARY_SURFACE_ADDRESS_HIGH, mask_sh),\ 288 + MI_SF(HUBPREQ0_DCSURF_SECONDARY_SURFACE_ADDRESS, SECONDARY_SURFACE_ADDRESS, mask_sh),\ 289 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, PRIMARY_META_SURFACE_ADDRESS_HIGH, mask_sh),\ 290 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS, PRIMARY_META_SURFACE_ADDRESS, mask_sh),\ 291 + MI_SF(HUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, SECONDARY_META_SURFACE_ADDRESS_HIGH, mask_sh),\ 292 + MI_SF(HUBPREQ0_DCSURF_SECONDARY_META_SURFACE_ADDRESS, SECONDARY_META_SURFACE_ADDRESS, mask_sh),\ 293 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, PRIMARY_SURFACE_ADDRESS_HIGH_C, mask_sh),\ 294 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS_C, PRIMARY_SURFACE_ADDRESS_C, mask_sh),\ 295 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, PRIMARY_META_SURFACE_ADDRESS_HIGH_C, mask_sh),\ 296 + MI_SF(HUBPREQ0_DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, PRIMARY_META_SURFACE_ADDRESS_C, mask_sh),\ 297 + MI_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_EN, mask_sh),\ 298 + MI_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\ 299 + MI_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\ 300 + MI_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\ 301 + MI_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\ 302 + MI_SF(HUBPREQ0_DCN_EXPANSION_MODE, DRQ_EXPANSION_MODE, mask_sh),\ 303 + MI_SF(HUBPREQ0_DCN_EXPANSION_MODE, PRQ_EXPANSION_MODE, mask_sh),\ 304 + MI_SF(HUBPREQ0_DCN_EXPANSION_MODE, MRQ_EXPANSION_MODE, mask_sh),\ 305 + MI_SF(HUBPREQ0_DCN_EXPANSION_MODE, CRQ_EXPANSION_MODE, mask_sh),\ 306 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, CHUNK_SIZE, mask_sh),\ 307 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MIN_CHUNK_SIZE, mask_sh),\ 308 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, META_CHUNK_SIZE, mask_sh),\ 309 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MIN_META_CHUNK_SIZE, mask_sh),\ 310 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, DPTE_GROUP_SIZE, mask_sh),\ 311 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\ 312 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, SWATH_HEIGHT, mask_sh),\ 313 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, PTE_ROW_HEIGHT_LINEAR, mask_sh),\ 314 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, CHUNK_SIZE_C, mask_sh),\ 315 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MIN_CHUNK_SIZE_C, mask_sh),\ 316 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, META_CHUNK_SIZE_C, mask_sh),\ 317 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MIN_META_CHUNK_SIZE_C, mask_sh),\ 318 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, DPTE_GROUP_SIZE_C, mask_sh),\ 319 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh),\ 320 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, SWATH_HEIGHT_C, mask_sh),\ 321 + MI_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, PTE_ROW_HEIGHT_LINEAR_C, mask_sh),\ 322 + MI_SF(HUBPREQ0_BLANK_OFFSET_0, REFCYC_H_BLANK_END, mask_sh),\ 323 + MI_SF(HUBPREQ0_BLANK_OFFSET_0, DLG_V_BLANK_END, mask_sh),\ 324 + MI_SF(HUBPREQ0_BLANK_OFFSET_1, MIN_DST_Y_NEXT_START, mask_sh),\ 325 + MI_SF(HUBPREQ0_DST_DIMENSIONS, REFCYC_PER_HTOTAL, mask_sh),\ 326 + MI_SF(HUBPREQ0_DST_AFTER_SCALER, REFCYC_X_AFTER_SCALER, mask_sh),\ 327 + MI_SF(HUBPREQ0_DST_AFTER_SCALER, DST_Y_AFTER_SCALER, mask_sh),\ 328 + MI_SF(HUBPREQ0_PREFETCH_SETTINS, DST_Y_PREFETCH, mask_sh),\ 329 + MI_SF(HUBPREQ0_PREFETCH_SETTINS, VRATIO_PREFETCH, mask_sh),\ 330 + MI_SF(HUBPREQ0_VBLANK_PARAMETERS_0, DST_Y_PER_VM_VBLANK, mask_sh),\ 331 + MI_SF(HUBPREQ0_VBLANK_PARAMETERS_0, DST_Y_PER_ROW_VBLANK, mask_sh),\ 332 + MI_SF(HUBPREQ0_REF_FREQ_TO_PIX_FREQ, REF_FREQ_TO_PIX_FREQ, mask_sh),\ 333 + MI_SF(HUBPREQ0_VBLANK_PARAMETERS_1, REFCYC_PER_PTE_GROUP_VBLANK_L, mask_sh),\ 334 + MI_SF(HUBPREQ0_VBLANK_PARAMETERS_3, REFCYC_PER_META_CHUNK_VBLANK_L, mask_sh),\ 335 + MI_SF(HUBPREQ0_NOM_PARAMETERS_0, DST_Y_PER_PTE_ROW_NOM_L, mask_sh),\ 336 + MI_SF(HUBPREQ0_NOM_PARAMETERS_1, REFCYC_PER_PTE_GROUP_NOM_L, mask_sh),\ 337 + MI_SF(HUBPREQ0_NOM_PARAMETERS_4, DST_Y_PER_META_ROW_NOM_L, mask_sh),\ 338 + MI_SF(HUBPREQ0_NOM_PARAMETERS_5, REFCYC_PER_META_CHUNK_NOM_L, mask_sh),\ 339 + MI_SF(HUBPREQ0_PER_LINE_DELIVERY_PRE, REFCYC_PER_LINE_DELIVERY_PRE_L, mask_sh),\ 340 + MI_SF(HUBPREQ0_PER_LINE_DELIVERY_PRE, REFCYC_PER_LINE_DELIVERY_PRE_C, mask_sh),\ 341 + MI_SF(HUBPREQ0_PER_LINE_DELIVERY, REFCYC_PER_LINE_DELIVERY_L, mask_sh),\ 342 + MI_SF(HUBPREQ0_PER_LINE_DELIVERY, REFCYC_PER_LINE_DELIVERY_C, mask_sh),\ 343 + MI_SF(HUBPREQ0_PREFETCH_SETTINS_C, VRATIO_PREFETCH_C, mask_sh),\ 344 + MI_SF(HUBPREQ0_VBLANK_PARAMETERS_2, REFCYC_PER_PTE_GROUP_VBLANK_C, mask_sh),\ 345 + MI_SF(HUBPREQ0_VBLANK_PARAMETERS_4, REFCYC_PER_META_CHUNK_VBLANK_C, mask_sh),\ 346 + MI_SF(HUBPREQ0_NOM_PARAMETERS_2, DST_Y_PER_PTE_ROW_NOM_C, mask_sh),\ 347 + MI_SF(HUBPREQ0_NOM_PARAMETERS_3, REFCYC_PER_PTE_GROUP_NOM_C, mask_sh),\ 348 + MI_SF(HUBPREQ0_NOM_PARAMETERS_6, DST_Y_PER_META_ROW_NOM_C, mask_sh),\ 349 + MI_SF(HUBPREQ0_NOM_PARAMETERS_7, REFCYC_PER_META_CHUNK_NOM_C, mask_sh),\ 350 + MI_SF(HUBPREQ0_DCN_TTU_QOS_WM, QoS_LEVEL_LOW_WM, mask_sh),\ 351 + MI_SF(HUBPREQ0_DCN_TTU_QOS_WM, QoS_LEVEL_HIGH_WM, mask_sh),\ 352 + MI_SF(HUBPREQ0_DCN_GLOBAL_TTU_CNTL, MIN_TTU_VBLANK, mask_sh),\ 353 + MI_SF(HUBPREQ0_DCN_GLOBAL_TTU_CNTL, QoS_LEVEL_FLIP, mask_sh),\ 354 + MI_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, REFCYC_PER_REQ_DELIVERY, mask_sh),\ 355 + MI_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_LEVEL_FIXED, mask_sh),\ 356 + MI_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\ 357 + MI_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\ 358 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, mask_sh),\ 359 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, mask_sh),\ 360 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, mask_sh),\ 361 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, mask_sh),\ 362 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, mask_sh),\ 363 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, mask_sh),\ 364 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, mask_sh),\ 365 + MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, mask_sh),\ 366 + MI_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, mask_sh),\ 367 + MI_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, mask_sh),\ 368 + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\ 369 + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\ 370 + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\ 371 + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mask_sh),\ 372 + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mask_sh),\ 373 + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, mask_sh),\ 374 + MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mask_sh),\ 375 + MI_SF(DCHUBBUB_SDPIF_FB_TOP, SDPIF_FB_TOP, mask_sh),\ 376 + MI_SF(DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh),\ 377 + MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\ 378 + MI_SF(DCHUBBUB_SDPIF_AGP_BASE, SDPIF_AGP_BASE, mask_sh),\ 379 + MI_SF(DCHUBBUB_SDPIF_AGP_BOT, SDPIF_AGP_BOT, mask_sh),\ 380 + MI_SF(DCHUBBUB_SDPIF_AGP_TOP, SDPIF_AGP_TOP, mask_sh),\ 381 + MI_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh),\ 382 + MI_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh),\ 383 + MI_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh),\ 384 + MI_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh),\ 385 + /* todo: get these from GVM instead of reading registers ourselves */\ 386 + MI_SF(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\ 387 + MI_SF(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\ 388 + MI_SF(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, LOGICAL_PAGE_NUMBER_HI4, mask_sh),\ 389 + MI_SF(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, LOGICAL_PAGE_NUMBER_LO32, mask_sh),\ 390 + MI_SF(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, PHYSICAL_PAGE_ADDR_HI4, mask_sh),\ 391 + MI_SF(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\ 392 + MI_SF(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\ 393 + MI_SF(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\ 394 + MI_SF(MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh) 395 + 396 + #define DCN_MI_REG_FIELD_LIST(type) \ 397 + type HUBP_BLANK_EN;\ 398 + type HUBP_TTU_DISABLE;\ 399 + type NUM_PIPES;\ 400 + type NUM_BANKS;\ 401 + type PIPE_INTERLEAVE;\ 402 + type NUM_SE;\ 403 + type NUM_RB_PER_SE;\ 404 + type MAX_COMPRESSED_FRAGS;\ 405 + type SW_MODE;\ 406 + type META_LINEAR;\ 407 + type RB_ALIGNED;\ 408 + type PIPE_ALIGNED;\ 409 + type PITCH;\ 410 + type META_PITCH;\ 411 + type PITCH_C;\ 412 + type META_PITCH_C;\ 413 + type ROTATION_ANGLE;\ 414 + type H_MIRROR_EN;\ 415 + type SURFACE_PIXEL_FORMAT;\ 416 + type SURFACE_FLIP_TYPE;\ 417 + type SURFACE_UPDATE_PENDING;\ 418 + type PRIMARY_SURFACE_ADDRESS_HIGH;\ 419 + type PRIMARY_SURFACE_ADDRESS;\ 420 + type SECONDARY_SURFACE_ADDRESS_HIGH;\ 421 + type SECONDARY_SURFACE_ADDRESS;\ 422 + type PRIMARY_META_SURFACE_ADDRESS_HIGH;\ 423 + type PRIMARY_META_SURFACE_ADDRESS;\ 424 + type SECONDARY_META_SURFACE_ADDRESS_HIGH;\ 425 + type SECONDARY_META_SURFACE_ADDRESS;\ 426 + type PRIMARY_SURFACE_ADDRESS_HIGH_C;\ 427 + type PRIMARY_SURFACE_ADDRESS_C;\ 428 + type PRIMARY_META_SURFACE_ADDRESS_HIGH_C;\ 429 + type PRIMARY_META_SURFACE_ADDRESS_C;\ 430 + type PRIMARY_SURFACE_DCC_EN;\ 431 + type PRIMARY_SURFACE_DCC_IND_64B_BLK;\ 432 + type DET_BUF_PLANE1_BASE_ADDRESS;\ 433 + type CROSSBAR_SRC_CB_B;\ 434 + type CROSSBAR_SRC_CR_R;\ 435 + type DRQ_EXPANSION_MODE;\ 436 + type PRQ_EXPANSION_MODE;\ 437 + type MRQ_EXPANSION_MODE;\ 438 + type CRQ_EXPANSION_MODE;\ 439 + type CHUNK_SIZE;\ 440 + type MIN_CHUNK_SIZE;\ 441 + type META_CHUNK_SIZE;\ 442 + type MIN_META_CHUNK_SIZE;\ 443 + type DPTE_GROUP_SIZE;\ 444 + type MPTE_GROUP_SIZE;\ 445 + type SWATH_HEIGHT;\ 446 + type PTE_ROW_HEIGHT_LINEAR;\ 447 + type CHUNK_SIZE_C;\ 448 + type MIN_CHUNK_SIZE_C;\ 449 + type META_CHUNK_SIZE_C;\ 450 + type MIN_META_CHUNK_SIZE_C;\ 451 + type DPTE_GROUP_SIZE_C;\ 452 + type MPTE_GROUP_SIZE_C;\ 453 + type SWATH_HEIGHT_C;\ 454 + type PTE_ROW_HEIGHT_LINEAR_C;\ 455 + type REFCYC_H_BLANK_END;\ 456 + type DLG_V_BLANK_END;\ 457 + type MIN_DST_Y_NEXT_START;\ 458 + type REFCYC_PER_HTOTAL;\ 459 + type REFCYC_X_AFTER_SCALER;\ 460 + type DST_Y_AFTER_SCALER;\ 461 + type DST_Y_PREFETCH;\ 462 + type VRATIO_PREFETCH;\ 463 + type DST_Y_PER_VM_VBLANK;\ 464 + type DST_Y_PER_ROW_VBLANK;\ 465 + type REF_FREQ_TO_PIX_FREQ;\ 466 + type REFCYC_PER_PTE_GROUP_VBLANK_L;\ 467 + type REFCYC_PER_META_CHUNK_VBLANK_L;\ 468 + type DST_Y_PER_PTE_ROW_NOM_L;\ 469 + type REFCYC_PER_PTE_GROUP_NOM_L;\ 470 + type DST_Y_PER_META_ROW_NOM_L;\ 471 + type REFCYC_PER_META_CHUNK_NOM_L;\ 472 + type REFCYC_PER_LINE_DELIVERY_PRE_L;\ 473 + type REFCYC_PER_LINE_DELIVERY_PRE_C;\ 474 + type REFCYC_PER_LINE_DELIVERY_L;\ 475 + type REFCYC_PER_LINE_DELIVERY_C;\ 476 + type VRATIO_PREFETCH_C;\ 477 + type REFCYC_PER_PTE_GROUP_VBLANK_C;\ 478 + type REFCYC_PER_META_CHUNK_VBLANK_C;\ 479 + type DST_Y_PER_PTE_ROW_NOM_C;\ 480 + type REFCYC_PER_PTE_GROUP_NOM_C;\ 481 + type DST_Y_PER_META_ROW_NOM_C;\ 482 + type REFCYC_PER_META_CHUNK_NOM_C;\ 483 + type QoS_LEVEL_LOW_WM;\ 484 + type QoS_LEVEL_HIGH_WM;\ 485 + type MIN_TTU_VBLANK;\ 486 + type QoS_LEVEL_FLIP;\ 487 + type REFCYC_PER_REQ_DELIVERY;\ 488 + type QoS_LEVEL_FIXED;\ 489 + type QoS_RAMP_DISABLE;\ 490 + type REFCYC_PER_REQ_DELIVERY_PRE;\ 491 + type VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB;\ 492 + type VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB;\ 493 + type VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB;\ 494 + type VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB;\ 495 + type VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;\ 496 + type VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;\ 497 + type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\ 498 + type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\ 499 + type ENABLE_L1_TLB;\ 500 + type SYSTEM_ACCESS_MODE;\ 501 + type MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM;\ 502 + type MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;\ 503 + type MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;\ 504 + type MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB;\ 505 + type MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB;\ 506 + type MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB;\ 507 + type MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB;\ 508 + type SDPIF_FB_TOP;\ 509 + type SDPIF_FB_BASE;\ 510 + type SDPIF_FB_OFFSET;\ 511 + type SDPIF_AGP_BASE;\ 512 + type SDPIF_AGP_BOT;\ 513 + type SDPIF_AGP_TOP;\ 514 + type DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST;\ 515 + type DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE;\ 516 + type DCHUBBUB_ARB_SAT_LEVEL;\ 517 + type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\ 518 + /* todo: get these from GVM instead of reading registers ourselves */\ 519 + type PAGE_DIRECTORY_ENTRY_HI32;\ 520 + type PAGE_DIRECTORY_ENTRY_LO32;\ 521 + type LOGICAL_PAGE_NUMBER_HI4;\ 522 + type LOGICAL_PAGE_NUMBER_LO32;\ 523 + type PHYSICAL_PAGE_ADDR_HI4;\ 524 + type PHYSICAL_PAGE_ADDR_LO32;\ 525 + type PHYSICAL_PAGE_NUMBER_MSB;\ 526 + type PHYSICAL_PAGE_NUMBER_LSB;\ 527 + type LOGICAL_ADDR 528 + 529 + struct dcn_mi_shift { 530 + DCN_MI_REG_FIELD_LIST(uint8_t); 531 + }; 532 + 533 + struct dcn_mi_mask { 534 + DCN_MI_REG_FIELD_LIST(uint32_t); 535 + }; 536 + 537 + struct dcn10_mem_input { 538 + struct mem_input base; 539 + const struct dcn_mi_registers *mi_regs; 540 + const struct dcn_mi_shift *mi_shift; 541 + const struct dcn_mi_mask *mi_mask; 542 + }; 543 + 544 + bool dcn10_mem_input_construct( 545 + struct dcn10_mem_input *mi, 546 + struct dc_context *ctx, 547 + uint32_t inst, 548 + const struct dcn_mi_registers *mi_regs, 549 + const struct dcn_mi_shift *mi_shift, 550 + const struct dcn_mi_mask *mi_mask); 551 + 552 + 553 + #endif
+376
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
··· 1 + /* 2 + * Copyright 2012-15 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 "reg_helper.h" 27 + #include "dcn10_mpc.h" 28 + 29 + #define REG(reg)\ 30 + mpc->mpc_regs->reg 31 + 32 + #define CTX \ 33 + mpc->base.ctx 34 + 35 + #undef FN 36 + #define FN(reg_name, field_name) \ 37 + mpc->mpc_shift->field_name, mpc->mpc_mask->field_name 38 + 39 + /* Internal function to set mpc output mux */ 40 + static void set_output_mux(struct dcn10_mpc *mpc, 41 + uint8_t opp_id, 42 + uint8_t mpcc_id) 43 + { 44 + if (mpcc_id != 0xf) 45 + REG_UPDATE(OPP_PIPE_CONTROL[opp_id], 46 + OPP_PIPE_CLOCK_EN, 1); 47 + 48 + REG_SET(MUX[opp_id], 0, 49 + MPC_OUT_MUX, mpcc_id); 50 + 51 + /* TODO: Move to post when ready. 52 + if (mpcc_id == 0xf) { 53 + MPCC_REG_UPDATE(OPP_PIPE0_OPP_PIPE_CONTROL, 54 + OPP_PIPE_CLOCK_EN, 0); 55 + } 56 + */ 57 + } 58 + 59 + static void set_blend_mode(struct dcn10_mpc *mpc, 60 + enum blend_mode mode, 61 + uint8_t mpcc_id) 62 + { 63 + /* Enable per-pixel alpha on this pipe */ 64 + if (mode == TOP_BLND) 65 + REG_UPDATE_3(MPCC_CONTROL[mpcc_id], 66 + MPCC_ALPHA_BLND_MODE, 0, 67 + MPCC_ALPHA_MULTIPLIED_MODE, 0, 68 + MPCC_BLND_ACTIVE_OVERLAP_ONLY, 0); 69 + else 70 + REG_UPDATE_3(MPCC_CONTROL[mpcc_id], 71 + MPCC_ALPHA_BLND_MODE, 0, 72 + MPCC_ALPHA_MULTIPLIED_MODE, 1, 73 + MPCC_BLND_ACTIVE_OVERLAP_ONLY, 1); 74 + } 75 + 76 + void dcn10_set_mpc_background_color(struct dcn10_mpc *mpc, 77 + unsigned int mpcc_inst, 78 + struct tg_color *bg_color) 79 + { 80 + /* mpc color is 12 bit. tg_color is 10 bit */ 81 + /* todo: might want to use 16 bit to represent color and have each 82 + * hw block translate to correct color depth. 83 + */ 84 + uint32_t bg_r_cr = bg_color->color_r_cr << 2; 85 + uint32_t bg_g_y = bg_color->color_g_y << 2; 86 + uint32_t bg_b_cb = bg_color->color_b_cb << 2; 87 + 88 + REG_SET(MPCC_BG_R_CR[mpcc_inst], 0, 89 + MPCC_BG_R_CR, bg_r_cr); 90 + REG_SET(MPCC_BG_G_Y[mpcc_inst], 0, 91 + MPCC_BG_G_Y, bg_g_y); 92 + REG_SET(MPCC_BG_B_CB[mpcc_inst], 0, 93 + MPCC_BG_B_CB, bg_b_cb); 94 + } 95 + 96 + /* This function programs MPC tree configuration 97 + * Assume it is the initial time to setup MPC tree_configure, means 98 + * the instance of dpp/mpcc/opp specified in structure tree_cfg are 99 + * in idle status. 100 + * Before invoke this function, ensure that master lock of OPTC specified 101 + * by opp_id is set. 102 + * 103 + * tree_cfg[in] - new MPC_TREE_CFG 104 + */ 105 + 106 + void dcn10_set_mpc_tree(struct dcn10_mpc *mpc, 107 + struct mpc_tree_cfg *tree_cfg) 108 + { 109 + int i; 110 + 111 + for (i = 0; i < tree_cfg->num_pipes; i++) { 112 + uint8_t mpcc_inst = tree_cfg->mpcc[i]; 113 + 114 + REG_SET(MPCC_OPP_ID[mpcc_inst], 0, 115 + MPCC_OPP_ID, tree_cfg->opp_id); 116 + 117 + REG_SET(MPCC_TOP_SEL[mpcc_inst], 0, 118 + MPCC_TOP_SEL, tree_cfg->dpp[i]); 119 + 120 + if (i == tree_cfg->num_pipes-1) { 121 + REG_SET(MPCC_BOT_SEL[mpcc_inst], 0, 122 + MPCC_BOT_SEL, 0xF); 123 + 124 + /* MPCC_CONTROL->MPCC_MODE */ 125 + REG_UPDATE(MPCC_CONTROL[mpcc_inst], 126 + MPCC_MODE, tree_cfg->mode); 127 + } else { 128 + REG_SET(MPCC_BOT_SEL[mpcc_inst], 0, 129 + MPCC_BOT_SEL, tree_cfg->dpp[i+1]); 130 + 131 + /* MPCC_CONTROL->MPCC_MODE */ 132 + REG_UPDATE(MPCC_CONTROL[mpcc_inst], 133 + MPCC_MODE, 3); 134 + } 135 + 136 + if (i == 0) 137 + set_output_mux( 138 + mpc, tree_cfg->opp_id, mpcc_inst); 139 + 140 + set_blend_mode(mpc, tree_cfg->mode, mpcc_inst); 141 + } 142 + } 143 + 144 + void dcn10_set_mpc_passthrough(struct dcn10_mpc *mpc, 145 + uint8_t dpp_idx, 146 + uint8_t mpcc_idx, 147 + uint8_t opp_idx) 148 + { 149 + struct mpc_tree_cfg tree_cfg = { 0 }; 150 + 151 + tree_cfg.num_pipes = 1; 152 + tree_cfg.opp_id = opp_idx; 153 + tree_cfg.mode = TOP_PASSTHRU; 154 + /* TODO: FPGA bring up one MPC has only 1 DPP and 1 MPCC 155 + * For blend case, need fill mode DPP and cascade MPCC 156 + */ 157 + tree_cfg.dpp[0] = dpp_idx; 158 + tree_cfg.mpcc[0] = mpcc_idx; 159 + dcn10_set_mpc_tree(mpc, &tree_cfg); 160 + } 161 + 162 + /* 163 + * This is the function to remove current MPC tree specified by tree_cfg 164 + * Before invoke this function, ensure that master lock of OPTC specified 165 + * by opp_id is set. 166 + * 167 + *tree_cfg[in/out] - current MPC_TREE_CFG 168 + */ 169 + void dcn10_delete_mpc_tree(struct dcn10_mpc *mpc, 170 + struct mpc_tree_cfg *tree_cfg) 171 + { 172 + int i; 173 + 174 + for (i = 0; i < tree_cfg->num_pipes; i++) { 175 + uint8_t mpcc_inst = tree_cfg->mpcc[i]; 176 + 177 + REG_SET(MPCC_OPP_ID[mpcc_inst], 0, 178 + MPCC_OPP_ID, 0xf); 179 + 180 + REG_SET(MPCC_TOP_SEL[mpcc_inst], 0, 181 + MPCC_TOP_SEL, 0xf); 182 + 183 + REG_SET(MPCC_BOT_SEL[mpcc_inst], 0, 184 + MPCC_BOT_SEL, 0xF); 185 + 186 + /* add remove dpp/mpcc pair into pending list 187 + * TODO FPGA AddToPendingList if empty from pseudo code 188 + */ 189 + tree_cfg->dpp[i] = 0xf; 190 + tree_cfg->mpcc[i] = 0xf; 191 + } 192 + set_output_mux(mpc, tree_cfg->opp_id, 0xf); 193 + tree_cfg->opp_id = 0xf; 194 + tree_cfg->num_pipes = 0; 195 + } 196 + 197 + /* TODO FPGA: how to handle DPP? 198 + * Function to remove one of pipe from MPC configure tree by dpp idx 199 + * Before invoke this function, ensure that master lock of OPTC specified 200 + * by opp_id is set 201 + * This function can be invoke multiple times to remove more than 1 dpps. 202 + * 203 + * tree_cfg[in/out] - current MPC_TREE_CFG 204 + * idx[in] - index of dpp from tree_cfg to be removed. 205 + */ 206 + bool dcn10_remove_dpp(struct dcn10_mpc *mpc, 207 + struct mpc_tree_cfg *tree_cfg, 208 + uint8_t idx) 209 + { 210 + int i; 211 + bool found = false; 212 + 213 + /* find dpp_idx from dpp array of tree_cfg */ 214 + for (i = 0; i < tree_cfg->num_pipes; i++) { 215 + if (tree_cfg->dpp[i] == idx) { 216 + found = true; 217 + break; 218 + } 219 + } 220 + 221 + if (found) { 222 + /* add remove dpp/mpcc pair into pending list */ 223 + 224 + /* TODO FPGA AddToPendingList if empty from pseudo code 225 + * AddToPendingList(tree_cfg->dpp[i],tree_cfg->mpcc[i]); 226 + */ 227 + uint8_t mpcc_inst = tree_cfg->mpcc[i]; 228 + 229 + REG_SET(MPCC_OPP_ID[mpcc_inst], 0, 230 + MPCC_OPP_ID, 0xf); 231 + 232 + REG_SET(MPCC_TOP_SEL[mpcc_inst], 0, 233 + MPCC_TOP_SEL, 0xf); 234 + 235 + REG_SET(MPCC_BOT_SEL[mpcc_inst], 0, 236 + MPCC_BOT_SEL, 0xF); 237 + 238 + if (i == 0) { 239 + if (tree_cfg->num_pipes > 1) 240 + set_output_mux(mpc, 241 + tree_cfg->opp_id, tree_cfg->mpcc[i+1]); 242 + else 243 + set_output_mux(mpc, tree_cfg->opp_id, 0xf); 244 + } else if (i == tree_cfg->num_pipes-1) { 245 + mpcc_inst = tree_cfg->mpcc[i - 1]; 246 + 247 + REG_SET(MPCC_BOT_SEL[mpcc_inst], 0, 248 + MPCC_BOT_SEL, 0xF); 249 + 250 + REG_UPDATE(MPCC_CONTROL[mpcc_inst], 251 + MPCC_MODE, tree_cfg->mode); 252 + } else { 253 + mpcc_inst = tree_cfg->mpcc[i - 1]; 254 + 255 + REG_SET(MPCC_BOT_SEL[mpcc_inst], 0, 256 + MPCC_BOT_SEL, tree_cfg->mpcc[i+1]); 257 + } 258 + set_blend_mode(mpc, tree_cfg->mode, mpcc_inst); 259 + 260 + /* update tree_cfg structure */ 261 + while (i < tree_cfg->num_pipes - 1) { 262 + tree_cfg->dpp[i] = tree_cfg->dpp[i+1]; 263 + tree_cfg->mpcc[i] = tree_cfg->mpcc[i+1]; 264 + i++; 265 + } 266 + tree_cfg->num_pipes--; 267 + } 268 + return found; 269 + } 270 + 271 + /* TODO FPGA: how to handle DPP? 272 + * Function to add DPP/MPCC pair into MPC configure tree by position. 273 + * Before invoke this function, ensure that master lock of OPTC specified 274 + * by opp_id is set 275 + * This function can be invoke multiple times to add more than 1 pipes. 276 + * 277 + * tree_cfg[in/out] - current MPC_TREE_CFG 278 + * dpp_idx[in] - index of an idle dpp insatnce to be added. 279 + * mpcc_idx[in] - index of an idle mpcc instance to be added. 280 + * poistion[in] - position of dpp/mpcc pair to be added into current tree_cfg 281 + * 0 means insert to the most top layer of MPC tree 282 + */ 283 + void dcn10_add_dpp(struct dcn10_mpc *mpc, 284 + struct mpc_tree_cfg *tree_cfg, 285 + uint8_t dpp_idx, 286 + uint8_t mpcc_idx, 287 + uint8_t position) 288 + { 289 + uint8_t temp; 290 + uint8_t temp1; 291 + 292 + REG_SET(MPCC_OPP_ID[mpcc_idx], 0, 293 + MPCC_OPP_ID, tree_cfg->opp_id); 294 + 295 + REG_SET(MPCC_TOP_SEL[mpcc_idx], 0, 296 + MPCC_TOP_SEL, dpp_idx); 297 + 298 + if (position == 0) { 299 + /* idle dpp/mpcc is added to the top layer of tree */ 300 + REG_SET(MPCC_BOT_SEL[mpcc_idx], 0, 301 + MPCC_BOT_SEL, tree_cfg->mpcc[0]); 302 + REG_UPDATE(MPCC_CONTROL[mpcc_idx], 303 + MPCC_MODE, 3); 304 + 305 + /* opp will get new output. from new added mpcc */ 306 + set_output_mux(mpc, tree_cfg->opp_id, mpcc_idx); 307 + 308 + set_blend_mode(mpc, tree_cfg->mode, mpcc_idx); 309 + 310 + } else if (position == tree_cfg->num_pipes) { 311 + /* idle dpp/mpcc is added to the bottom layer of tree */ 312 + 313 + /* get instance of previous bottom mpcc, set to middle layer */ 314 + temp = tree_cfg->mpcc[tree_cfg->num_pipes - 1]; 315 + 316 + REG_SET(MPCC_BOT_SEL[temp], 0, 317 + MPCC_BOT_SEL, mpcc_idx); 318 + 319 + REG_UPDATE(MPCC_CONTROL[temp], 320 + MPCC_MODE, 3); 321 + 322 + /* mpcc_idx become new bottom mpcc*/ 323 + REG_SET(MPCC_BOT_SEL[mpcc_idx], 0, 324 + MPCC_BOT_SEL, 0xf); 325 + 326 + REG_UPDATE(MPCC_CONTROL[mpcc_idx], 327 + MPCC_MODE, tree_cfg->mode); 328 + 329 + set_blend_mode(mpc, tree_cfg->mode, mpcc_idx); 330 + } else { 331 + /* idle dpp/mpcc is added to middle of tree */ 332 + temp = tree_cfg->mpcc[position - 1]; 333 + temp1 = tree_cfg->mpcc[position]; 334 + 335 + /* new mpcc instance temp1 is added right after temp*/ 336 + REG_SET(MPCC_BOT_SEL[temp], 0, 337 + MPCC_BOT_SEL, mpcc_idx); 338 + 339 + /* mpcc_idx connect previous temp+1 to new mpcc */ 340 + REG_SET(MPCC_BOT_SEL[mpcc_idx], 0, 341 + MPCC_BOT_SEL, temp1); 342 + 343 + /* temp TODO: may not need*/ 344 + REG_UPDATE(MPCC_CONTROL[temp], 345 + MPCC_MODE, 3); 346 + 347 + set_blend_mode(mpc, tree_cfg->mode, temp); 348 + } 349 + 350 + /* update tree_cfg structure */ 351 + temp = tree_cfg->num_pipes - 1; 352 + 353 + /* 354 + * iterating from the last mpc/dpp pair to the one being added, shift 355 + * them down one position 356 + */ 357 + while (temp > position) { 358 + tree_cfg->dpp[temp + 1] = tree_cfg->dpp[temp]; 359 + tree_cfg->mpcc[temp + 1] = tree_cfg->mpcc[temp]; 360 + temp--; 361 + } 362 + 363 + /* insert the new mpc/dpp pair into the tree_cfg*/ 364 + tree_cfg->dpp[position] = dpp_idx; 365 + tree_cfg->mpcc[position] = mpcc_idx; 366 + tree_cfg->num_pipes++; 367 + } 368 + 369 + void wait_mpcc_idle(struct dcn10_mpc *mpc, 370 + uint8_t mpcc_id) 371 + { 372 + REG_WAIT(MPCC_STATUS[mpcc_id], 373 + MPCC_IDLE, 1, 374 + 1000, 1000); 375 + } 376 +
+135
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
··· 1 + /* Copyright 2012-15 Advanced Micro Devices, Inc. 2 + * 3 + * Permission is hereby granted, free of charge, to any person obtaining a 4 + * copy of this software and associated documentation files (the "Software"), 5 + * to deal in the Software without restriction, including without limitation 6 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 + * and/or sell copies of the Software, and to permit persons to whom the 8 + * Software is furnished to do so, subject to the following conditions: 9 + * 10 + * The above copyright notice and this permission notice shall be included in 11 + * all copies or substantial portions of the Software. 12 + * 13 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 + * OTHER DEALINGS IN THE SOFTWARE. 20 + * 21 + * Authors: AMD 22 + * 23 + */ 24 + 25 + #ifndef __DC_MPC_DCN10_H__ 26 + #define __DC_MPC_DCN10_H__ 27 + 28 + #include "mpc.h" 29 + 30 + #define TO_DCN10_MPC(mpc_base)\ 31 + container_of(mpc_base, struct dcn10_mpc, base) 32 + 33 + #define MAX_MPCC 4 34 + #define MAX_MPC_OUT 4 35 + #define MAX_OPP 4 36 + 37 + #define MPC_COMMON_REG_LIST_DCN1_0(inst) \ 38 + SRII(MPCC_TOP_SEL, MPCC, inst),\ 39 + SRII(MPCC_BOT_SEL, MPCC, inst),\ 40 + SRII(MPCC_CONTROL, MPCC, inst),\ 41 + SRII(MPCC_STATUS, MPCC, inst),\ 42 + SRII(MPCC_OPP_ID, MPCC, inst),\ 43 + SRII(MPCC_BG_G_Y, MPCC, inst),\ 44 + SRII(MPCC_BG_R_CR, MPCC, inst),\ 45 + SRII(MPCC_BG_B_CB, MPCC, inst),\ 46 + SRII(MPCC_BG_B_CB, MPCC, inst),\ 47 + SRII(MUX, MPC_OUT, inst),\ 48 + SRII(OPP_PIPE_CONTROL, OPP_PIPE, inst) 49 + 50 + struct dcn_mpc_registers { 51 + uint32_t MPCC_TOP_SEL[MAX_MPCC]; 52 + uint32_t MPCC_BOT_SEL[MAX_MPCC]; 53 + uint32_t MPCC_CONTROL[MAX_MPCC]; 54 + uint32_t MPCC_STATUS[MAX_MPCC]; 55 + uint32_t MPCC_OPP_ID[MAX_MPCC]; 56 + uint32_t MPCC_BG_G_Y[MAX_MPCC]; 57 + uint32_t MPCC_BG_R_CR[MAX_MPCC]; 58 + uint32_t MPCC_BG_B_CB[MAX_MPCC]; 59 + uint32_t MUX[MAX_MPC_OUT]; 60 + uint32_t OPP_PIPE_CONTROL[MAX_OPP]; 61 + }; 62 + 63 + #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ 64 + SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ 65 + SF(MPCC0_MPCC_BOT_SEL, MPCC_BOT_SEL, mask_sh),\ 66 + SF(MPCC0_MPCC_CONTROL, MPCC_MODE, mask_sh),\ 67 + SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_BLND_MODE, mask_sh),\ 68 + SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_MULTIPLIED_MODE, mask_sh),\ 69 + SF(MPCC0_MPCC_CONTROL, MPCC_BLND_ACTIVE_OVERLAP_ONLY, mask_sh),\ 70 + SF(MPCC0_MPCC_STATUS, MPCC_IDLE, mask_sh),\ 71 + SF(MPCC0_MPCC_OPP_ID, MPCC_OPP_ID, mask_sh),\ 72 + SF(MPCC0_MPCC_BG_G_Y, MPCC_BG_G_Y, mask_sh),\ 73 + SF(MPCC0_MPCC_BG_R_CR, MPCC_BG_R_CR, mask_sh),\ 74 + SF(MPCC0_MPCC_BG_B_CB, MPCC_BG_B_CB, mask_sh),\ 75 + SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\ 76 + SF(OPP_PIPE0_OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh) 77 + 78 + #define MPC_REG_FIELD_LIST(type) \ 79 + type MPCC_TOP_SEL;\ 80 + type MPCC_BOT_SEL;\ 81 + type MPCC_MODE;\ 82 + type MPCC_ALPHA_BLND_MODE;\ 83 + type MPCC_ALPHA_MULTIPLIED_MODE;\ 84 + type MPCC_BLND_ACTIVE_OVERLAP_ONLY;\ 85 + type MPCC_IDLE;\ 86 + type MPCC_OPP_ID;\ 87 + type MPCC_BG_G_Y;\ 88 + type MPCC_BG_R_CR;\ 89 + type MPCC_BG_B_CB;\ 90 + type MPC_OUT_MUX;\ 91 + type OPP_PIPE_CLOCK_EN;\ 92 + 93 + struct dcn_mpc_shift { 94 + MPC_REG_FIELD_LIST(uint8_t) 95 + }; 96 + 97 + struct dcn_mpc_mask { 98 + MPC_REG_FIELD_LIST(uint32_t) 99 + }; 100 + 101 + struct dcn10_mpc { 102 + struct mpc base; 103 + const struct dcn_mpc_registers *mpc_regs; 104 + const struct dcn_mpc_shift *mpc_shift; 105 + const struct dcn_mpc_mask *mpc_mask; 106 + }; 107 + 108 + void dcn10_set_mpc_passthrough(struct dcn10_mpc *mpc, 109 + uint8_t dpp_idx, 110 + uint8_t mpcc_idx, 111 + uint8_t opp_idx); 112 + 113 + void dcn10_delete_mpc_tree(struct dcn10_mpc *mpc, 114 + struct mpc_tree_cfg *tree_cfg); 115 + 116 + bool dcn10_remove_dpp(struct dcn10_mpc *mpc, 117 + struct mpc_tree_cfg *tree_cfg, 118 + uint8_t idx); 119 + 120 + void dcn10_add_dpp(struct dcn10_mpc *mpc, 121 + struct mpc_tree_cfg *tree_cfg, 122 + uint8_t dpp_idx, 123 + uint8_t mpcc_idx, 124 + uint8_t position); 125 + 126 + void wait_mpcc_idle(struct dcn10_mpc *mpc, 127 + uint8_t mpcc_id); 128 + 129 + void dcn10_set_mpc_tree(struct dcn10_mpc *mpc, 130 + struct mpc_tree_cfg *tree_cfg); 131 + 132 + void dcn10_set_mpc_background_color(struct dcn10_mpc *mpc, 133 + unsigned int mpcc_inst, 134 + struct tg_color *bg_color); 135 + #endif
+801
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
··· 1 + /* 2 + * Copyright 2012-15 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 "dm_services.h" 27 + #include "dcn10_opp.h" 28 + #include "reg_helper.h" 29 + 30 + #define REG(reg) \ 31 + (oppn10->regs->reg) 32 + 33 + #undef FN 34 + #define FN(reg_name, field_name) \ 35 + oppn10->opp_shift->field_name, oppn10->opp_mask->field_name 36 + 37 + #define CTX \ 38 + oppn10->base.ctx 39 + 40 + static void opp_set_regamma_mode( 41 + struct output_pixel_processor *opp, 42 + enum opp_regamma mode) 43 + { 44 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 45 + uint32_t re_mode = 0; 46 + uint32_t obuf_bypass = 0; /* need for pipe split */ 47 + uint32_t obuf_hupscale = 0; 48 + 49 + switch (mode) { 50 + case OPP_REGAMMA_BYPASS: 51 + re_mode = 0; 52 + break; 53 + case OPP_REGAMMA_SRGB: 54 + re_mode = 1; 55 + break; 56 + case OPP_REGAMMA_3_6: 57 + re_mode = 2; 58 + break; 59 + case OPP_REGAMMA_USER: 60 + re_mode = oppn10->is_write_to_ram_a_safe ? 3 : 4; 61 + oppn10->is_write_to_ram_a_safe = !oppn10->is_write_to_ram_a_safe; 62 + break; 63 + default: 64 + break; 65 + } 66 + 67 + REG_SET(CM_RGAM_CONTROL, 0, CM_RGAM_LUT_MODE, re_mode); 68 + REG_UPDATE_2(OBUF_CONTROL, 69 + OBUF_BYPASS, obuf_bypass, 70 + OBUF_H_2X_UPSCALE_EN, obuf_hupscale); 71 + } 72 + 73 + /************* FORMATTER ************/ 74 + 75 + /** 76 + * set_truncation 77 + * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp 78 + * 2) enable truncation 79 + * 3) HW remove 12bit FMT support for DCE11 power saving reason. 80 + */ 81 + static void set_truncation( 82 + struct dcn10_opp *oppn10, 83 + const struct bit_depth_reduction_params *params) 84 + { 85 + REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, 86 + FMT_TRUNCATE_EN, params->flags.TRUNCATE_ENABLED, 87 + FMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH, 88 + FMT_TRUNCATE_MODE, params->flags.TRUNCATE_MODE); 89 + } 90 + 91 + static void set_spatial_dither( 92 + struct dcn10_opp *oppn10, 93 + const struct bit_depth_reduction_params *params) 94 + { 95 + /*Disable spatial (random) dithering*/ 96 + REG_UPDATE_7(FMT_BIT_DEPTH_CONTROL, 97 + FMT_SPATIAL_DITHER_EN, 0, 98 + FMT_SPATIAL_DITHER_MODE, 0, 99 + FMT_SPATIAL_DITHER_DEPTH, 0, 100 + FMT_TEMPORAL_DITHER_EN, 0, 101 + FMT_HIGHPASS_RANDOM_ENABLE, 0, 102 + FMT_FRAME_RANDOM_ENABLE, 0, 103 + FMT_RGB_RANDOM_ENABLE, 0); 104 + 105 + 106 + /* only use FRAME_COUNTER_MAX if frameRandom == 1*/ 107 + if (params->flags.FRAME_RANDOM == 1) { 108 + if (params->flags.SPATIAL_DITHER_DEPTH == 0 || params->flags.SPATIAL_DITHER_DEPTH == 1) { 109 + REG_UPDATE_2(FMT_CONTROL, 110 + FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15, 111 + FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2); 112 + } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) { 113 + REG_UPDATE_2(FMT_CONTROL, 114 + FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3, 115 + FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1); 116 + } else { 117 + return; 118 + } 119 + } else { 120 + REG_UPDATE_2(FMT_CONTROL, 121 + FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0, 122 + FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0); 123 + } 124 + 125 + /*Set seed for random values for 126 + * spatial dithering for R,G,B channels*/ 127 + 128 + REG_SET(FMT_DITHER_RAND_R_SEED, 0, 129 + FMT_RAND_R_SEED, params->r_seed_value); 130 + 131 + REG_SET(FMT_DITHER_RAND_G_SEED, 0, 132 + FMT_RAND_G_SEED, params->g_seed_value); 133 + 134 + REG_SET(FMT_DITHER_RAND_B_SEED, 0, 135 + FMT_RAND_B_SEED, params->b_seed_value); 136 + 137 + /* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero 138 + * offset for the R/Cr channel, lower 4LSB 139 + * is forced to zeros. Typically set to 0 140 + * RGB and 0x80000 YCbCr. 141 + */ 142 + /* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero 143 + * offset for the G/Y channel, lower 4LSB is 144 + * forced to zeros. Typically set to 0 RGB 145 + * and 0x80000 YCbCr. 146 + */ 147 + /* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero 148 + * offset for the B/Cb channel, lower 4LSB is 149 + * forced to zeros. Typically set to 0 RGB and 150 + * 0x80000 YCbCr. 151 + */ 152 + 153 + REG_UPDATE_6(FMT_BIT_DEPTH_CONTROL, 154 + /*Enable spatial dithering*/ 155 + FMT_SPATIAL_DITHER_EN, params->flags.SPATIAL_DITHER_ENABLED, 156 + /* Set spatial dithering mode 157 + * (default is Seed patterrn AAAA...) 158 + */ 159 + FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE, 160 + /*Set spatial dithering bit depth*/ 161 + FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH, 162 + /*Disable High pass filter*/ 163 + FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM, 164 + /*Reset only at startup*/ 165 + FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM, 166 + /*Set RGB data dithered with x^28+x^3+1*/ 167 + FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM); 168 + } 169 + 170 + static void opp_program_bit_depth_reduction( 171 + struct output_pixel_processor *opp, 172 + const struct bit_depth_reduction_params *params) 173 + { 174 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 175 + 176 + set_truncation(oppn10, params); 177 + set_spatial_dither(oppn10, params); 178 + /* TODO 179 + * set_temporal_dither(oppn10, params); 180 + */ 181 + } 182 + 183 + /** 184 + * set_pixel_encoding 185 + * 186 + * Set Pixel Encoding 187 + * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly 188 + * 1: YCbCr 4:2:2 189 + */ 190 + static void set_pixel_encoding( 191 + struct dcn10_opp *oppn10, 192 + const struct clamping_and_pixel_encoding_params *params) 193 + { 194 + switch (params->pixel_encoding) { 195 + 196 + case PIXEL_ENCODING_RGB: 197 + case PIXEL_ENCODING_YCBCR444: 198 + REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 0); 199 + break; 200 + case PIXEL_ENCODING_YCBCR422: 201 + REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 1); 202 + break; 203 + case PIXEL_ENCODING_YCBCR420: 204 + REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 2); 205 + break; 206 + default: 207 + break; 208 + } 209 + } 210 + 211 + /** 212 + * Set Clamping 213 + * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping) 214 + * 1 for 8 bpc 215 + * 2 for 10 bpc 216 + * 3 for 12 bpc 217 + * 7 for programable 218 + * 2) Enable clamp if Limited range requested 219 + */ 220 + static void opp_set_clamping( 221 + struct dcn10_opp *oppn10, 222 + const struct clamping_and_pixel_encoding_params *params) 223 + { 224 + REG_UPDATE_2(FMT_CLAMP_CNTL, 225 + FMT_CLAMP_DATA_EN, 0, 226 + FMT_CLAMP_COLOR_FORMAT, 0); 227 + 228 + switch (params->clamping_level) { 229 + case CLAMPING_FULL_RANGE: 230 + REG_UPDATE_2(FMT_CLAMP_CNTL, 231 + FMT_CLAMP_DATA_EN, 1, 232 + FMT_CLAMP_COLOR_FORMAT, 0); 233 + break; 234 + case CLAMPING_LIMITED_RANGE_8BPC: 235 + REG_UPDATE_2(FMT_CLAMP_CNTL, 236 + FMT_CLAMP_DATA_EN, 1, 237 + FMT_CLAMP_COLOR_FORMAT, 1); 238 + break; 239 + case CLAMPING_LIMITED_RANGE_10BPC: 240 + REG_UPDATE_2(FMT_CLAMP_CNTL, 241 + FMT_CLAMP_DATA_EN, 1, 242 + FMT_CLAMP_COLOR_FORMAT, 2); 243 + 244 + break; 245 + case CLAMPING_LIMITED_RANGE_12BPC: 246 + REG_UPDATE_2(FMT_CLAMP_CNTL, 247 + FMT_CLAMP_DATA_EN, 1, 248 + FMT_CLAMP_COLOR_FORMAT, 3); 249 + break; 250 + case CLAMPING_LIMITED_RANGE_PROGRAMMABLE: 251 + /* TODO */ 252 + default: 253 + break; 254 + } 255 + 256 + } 257 + 258 + static void opp_set_dyn_expansion( 259 + struct output_pixel_processor *opp, 260 + enum dc_color_space color_sp, 261 + enum dc_color_depth color_dpth, 262 + enum signal_type signal) 263 + { 264 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 265 + 266 + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, 267 + FMT_DYNAMIC_EXP_EN, 0, 268 + FMT_DYNAMIC_EXP_MODE, 0); 269 + 270 + /*00 - 10-bit -> 12-bit dynamic expansion*/ 271 + /*01 - 8-bit -> 12-bit dynamic expansion*/ 272 + if (signal == SIGNAL_TYPE_HDMI_TYPE_A || 273 + signal == SIGNAL_TYPE_DISPLAY_PORT || 274 + signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { 275 + switch (color_dpth) { 276 + case COLOR_DEPTH_888: 277 + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, 278 + FMT_DYNAMIC_EXP_EN, 1, 279 + FMT_DYNAMIC_EXP_MODE, 1); 280 + break; 281 + case COLOR_DEPTH_101010: 282 + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, 283 + FMT_DYNAMIC_EXP_EN, 1, 284 + FMT_DYNAMIC_EXP_MODE, 0); 285 + break; 286 + case COLOR_DEPTH_121212: 287 + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, 288 + FMT_DYNAMIC_EXP_EN, 1,/*otherwise last two bits are zero*/ 289 + FMT_DYNAMIC_EXP_MODE, 0); 290 + break; 291 + default: 292 + break; 293 + } 294 + } 295 + } 296 + 297 + static void opp_program_clamping_and_pixel_encoding( 298 + struct output_pixel_processor *opp, 299 + const struct clamping_and_pixel_encoding_params *params) 300 + { 301 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 302 + 303 + opp_set_clamping(oppn10, params); 304 + set_pixel_encoding(oppn10, params); 305 + } 306 + 307 + static void opp_program_fmt( 308 + struct output_pixel_processor *opp, 309 + struct bit_depth_reduction_params *fmt_bit_depth, 310 + struct clamping_and_pixel_encoding_params *clamping) 311 + { 312 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 313 + 314 + if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420) 315 + REG_UPDATE(FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, 0); 316 + 317 + /* dithering is affected by <CrtcSourceSelect>, hence should be 318 + * programmed afterwards */ 319 + opp_program_bit_depth_reduction( 320 + opp, 321 + fmt_bit_depth); 322 + 323 + opp_program_clamping_and_pixel_encoding( 324 + opp, 325 + clamping); 326 + 327 + return; 328 + } 329 + 330 + static void opp_set_output_csc_default( 331 + struct output_pixel_processor *opp, 332 + const struct default_adjustment *default_adjust) 333 + { 334 + 335 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 336 + uint32_t ocsc_mode = 0; 337 + 338 + if (default_adjust != NULL) { 339 + switch (default_adjust->out_color_space) { 340 + case COLOR_SPACE_SRGB: 341 + ocsc_mode = 0; 342 + break; 343 + case COLOR_SPACE_SRGB_LIMITED: 344 + ocsc_mode = 1; 345 + break; 346 + case COLOR_SPACE_YCBCR601: 347 + case COLOR_SPACE_YCBCR601_LIMITED: 348 + ocsc_mode = 2; 349 + break; 350 + case COLOR_SPACE_YCBCR709: 351 + case COLOR_SPACE_YCBCR709_LIMITED: 352 + ocsc_mode = 3; 353 + break; 354 + case COLOR_SPACE_UNKNOWN: 355 + default: 356 + break; 357 + } 358 + } 359 + 360 + REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); 361 + 362 + } 363 + /*program re gamma RAM B*/ 364 + static void opp_program_regamma_lutb_settings( 365 + struct output_pixel_processor *opp, 366 + const struct pwl_params *params) 367 + { 368 + const struct gamma_curve *curve; 369 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 370 + 371 + REG_SET_2(CM_RGAM_RAMB_START_CNTL_B, 0, 372 + CM_RGAM_RAMB_EXP_REGION_START_B, params->arr_points[0].custom_float_x, 373 + CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B, 0); 374 + REG_SET_2(CM_RGAM_RAMB_START_CNTL_G, 0, 375 + CM_RGAM_RAMB_EXP_REGION_START_G, params->arr_points[0].custom_float_x, 376 + CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_G, 0); 377 + REG_SET_2(CM_RGAM_RAMB_START_CNTL_R, 0, 378 + CM_RGAM_RAMB_EXP_REGION_START_R, params->arr_points[0].custom_float_x, 379 + CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_R, 0); 380 + 381 + REG_SET(CM_RGAM_RAMB_SLOPE_CNTL_B, 0, 382 + CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B, params->arr_points[0].custom_float_slope); 383 + REG_SET(CM_RGAM_RAMB_SLOPE_CNTL_G, 0, 384 + CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_G, params->arr_points[0].custom_float_slope); 385 + REG_SET(CM_RGAM_RAMB_SLOPE_CNTL_R, 0, 386 + CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_R, params->arr_points[0].custom_float_slope); 387 + 388 + REG_SET(CM_RGAM_RAMB_END_CNTL1_B, 0, 389 + CM_RGAM_RAMB_EXP_REGION_END_B, params->arr_points[1].custom_float_x); 390 + REG_SET_2(CM_RGAM_RAMB_END_CNTL2_B, 0, 391 + CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B, params->arr_points[1].custom_float_slope, 392 + CM_RGAM_RAMB_EXP_REGION_END_BASE_B, params->arr_points[1].custom_float_y); 393 + 394 + REG_SET(CM_RGAM_RAMB_END_CNTL1_G, 0, 395 + CM_RGAM_RAMB_EXP_REGION_END_G, params->arr_points[1].custom_float_x); 396 + REG_SET_2(CM_RGAM_RAMB_END_CNTL2_G, 0, 397 + CM_RGAM_RAMB_EXP_REGION_END_SLOPE_G, params->arr_points[1].custom_float_slope, 398 + CM_RGAM_RAMB_EXP_REGION_END_BASE_G, params->arr_points[1].custom_float_y); 399 + 400 + REG_SET(CM_RGAM_RAMB_END_CNTL1_R, 0, 401 + CM_RGAM_RAMB_EXP_REGION_END_R, params->arr_points[1].custom_float_x); 402 + REG_SET_2(CM_RGAM_RAMB_END_CNTL2_R, 0, 403 + CM_RGAM_RAMB_EXP_REGION_END_SLOPE_R, params->arr_points[1].custom_float_slope, 404 + CM_RGAM_RAMB_EXP_REGION_END_BASE_R, params->arr_points[1].custom_float_y); 405 + 406 + curve = params->arr_curve_points; 407 + REG_SET_4(CM_RGAM_RAMB_REGION_0_1, 0, 408 + CM_RGAM_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset, 409 + CM_RGAM_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 410 + CM_RGAM_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset, 411 + CM_RGAM_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 412 + 413 + curve += 2; 414 + REG_SET_4(CM_RGAM_RAMB_REGION_2_3, 0, 415 + CM_RGAM_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset, 416 + CM_RGAM_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 417 + CM_RGAM_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset, 418 + CM_RGAM_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 419 + 420 + curve += 2; 421 + REG_SET_4(CM_RGAM_RAMB_REGION_4_5, 0, 422 + CM_RGAM_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset, 423 + CM_RGAM_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 424 + CM_RGAM_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset, 425 + CM_RGAM_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 426 + 427 + curve += 2; 428 + REG_SET_4(CM_RGAM_RAMB_REGION_6_7, 0, 429 + CM_RGAM_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset, 430 + CM_RGAM_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 431 + CM_RGAM_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset, 432 + CM_RGAM_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 433 + 434 + curve += 2; 435 + REG_SET_4(CM_RGAM_RAMB_REGION_8_9, 0, 436 + CM_RGAM_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset, 437 + CM_RGAM_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 438 + CM_RGAM_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset, 439 + CM_RGAM_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 440 + 441 + curve += 2; 442 + REG_SET_4(CM_RGAM_RAMB_REGION_10_11, 0, 443 + CM_RGAM_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset, 444 + CM_RGAM_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 445 + CM_RGAM_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset, 446 + CM_RGAM_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 447 + 448 + curve += 2; 449 + REG_SET_4(CM_RGAM_RAMB_REGION_12_13, 0, 450 + CM_RGAM_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset, 451 + CM_RGAM_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 452 + CM_RGAM_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset, 453 + CM_RGAM_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 454 + 455 + curve += 2; 456 + REG_SET_4(CM_RGAM_RAMB_REGION_14_15, 0, 457 + CM_RGAM_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset, 458 + CM_RGAM_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 459 + CM_RGAM_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset, 460 + CM_RGAM_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 461 + 462 + curve += 2; 463 + REG_SET_4(CM_RGAM_RAMB_REGION_16_17, 0, 464 + CM_RGAM_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset, 465 + CM_RGAM_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 466 + CM_RGAM_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset, 467 + CM_RGAM_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 468 + 469 + curve += 2; 470 + REG_SET_4(CM_RGAM_RAMB_REGION_18_19, 0, 471 + CM_RGAM_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset, 472 + CM_RGAM_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 473 + CM_RGAM_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset, 474 + CM_RGAM_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 475 + 476 + curve += 2; 477 + REG_SET_4(CM_RGAM_RAMB_REGION_20_21, 0, 478 + CM_RGAM_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset, 479 + CM_RGAM_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 480 + CM_RGAM_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset, 481 + CM_RGAM_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 482 + 483 + curve += 2; 484 + REG_SET_4(CM_RGAM_RAMB_REGION_22_23, 0, 485 + CM_RGAM_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset, 486 + CM_RGAM_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 487 + CM_RGAM_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset, 488 + CM_RGAM_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 489 + 490 + curve += 2; 491 + REG_SET_4(CM_RGAM_RAMB_REGION_24_25, 0, 492 + CM_RGAM_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset, 493 + CM_RGAM_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 494 + CM_RGAM_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset, 495 + CM_RGAM_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 496 + 497 + curve += 2; 498 + REG_SET_4(CM_RGAM_RAMB_REGION_26_27, 0, 499 + CM_RGAM_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset, 500 + CM_RGAM_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 501 + CM_RGAM_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset, 502 + CM_RGAM_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 503 + 504 + curve += 2; 505 + REG_SET_4(CM_RGAM_RAMB_REGION_28_29, 0, 506 + CM_RGAM_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset, 507 + CM_RGAM_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 508 + CM_RGAM_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset, 509 + CM_RGAM_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 510 + 511 + curve += 2; 512 + REG_SET_4(CM_RGAM_RAMB_REGION_30_31, 0, 513 + CM_RGAM_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset, 514 + CM_RGAM_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 515 + CM_RGAM_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset, 516 + CM_RGAM_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 517 + 518 + curve += 2; 519 + REG_SET_4(CM_RGAM_RAMB_REGION_32_33, 0, 520 + CM_RGAM_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset, 521 + CM_RGAM_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 522 + CM_RGAM_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset, 523 + CM_RGAM_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 524 + 525 + } 526 + 527 + /*program re gamma RAM A*/ 528 + static void opp_program_regamma_luta_settings( 529 + struct output_pixel_processor *opp, 530 + const struct pwl_params *params) 531 + { 532 + const struct gamma_curve *curve; 533 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 534 + 535 + REG_SET_2(CM_RGAM_RAMA_START_CNTL_B, 0, 536 + CM_RGAM_RAMA_EXP_REGION_START_B, params->arr_points[0].custom_float_x, 537 + CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_B, 0); 538 + REG_SET_2(CM_RGAM_RAMA_START_CNTL_G, 0, 539 + CM_RGAM_RAMA_EXP_REGION_START_G, params->arr_points[0].custom_float_x, 540 + CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_G, 0); 541 + REG_SET_2(CM_RGAM_RAMA_START_CNTL_R, 0, 542 + CM_RGAM_RAMA_EXP_REGION_START_R, params->arr_points[0].custom_float_x, 543 + CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_R, 0); 544 + 545 + REG_SET(CM_RGAM_RAMA_SLOPE_CNTL_B, 0, 546 + CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B, params->arr_points[0].custom_float_slope); 547 + REG_SET(CM_RGAM_RAMA_SLOPE_CNTL_G, 0, 548 + CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_G, params->arr_points[0].custom_float_slope); 549 + REG_SET(CM_RGAM_RAMA_SLOPE_CNTL_R, 0, 550 + CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_R, params->arr_points[0].custom_float_slope); 551 + 552 + REG_SET(CM_RGAM_RAMA_END_CNTL1_B, 0, 553 + CM_RGAM_RAMA_EXP_REGION_END_B, params->arr_points[1].custom_float_x); 554 + REG_SET_2(CM_RGAM_RAMA_END_CNTL2_B, 0, 555 + CM_RGAM_RAMA_EXP_REGION_END_SLOPE_B, params->arr_points[1].custom_float_slope, 556 + CM_RGAM_RAMA_EXP_REGION_END_BASE_B, params->arr_points[1].custom_float_y); 557 + 558 + REG_SET(CM_RGAM_RAMA_END_CNTL1_G, 0, 559 + CM_RGAM_RAMA_EXP_REGION_END_G, params->arr_points[1].custom_float_x); 560 + REG_SET_2(CM_RGAM_RAMA_END_CNTL2_G, 0, 561 + CM_RGAM_RAMA_EXP_REGION_END_SLOPE_G, params->arr_points[1].custom_float_slope, 562 + CM_RGAM_RAMA_EXP_REGION_END_BASE_G, params->arr_points[1].custom_float_y); 563 + 564 + REG_SET(CM_RGAM_RAMA_END_CNTL1_R, 0, 565 + CM_RGAM_RAMA_EXP_REGION_END_R, params->arr_points[1].custom_float_x); 566 + REG_SET_2(CM_RGAM_RAMA_END_CNTL2_R, 0, 567 + CM_RGAM_RAMA_EXP_REGION_END_SLOPE_R, params->arr_points[1].custom_float_slope, 568 + CM_RGAM_RAMA_EXP_REGION_END_BASE_R, params->arr_points[1].custom_float_y); 569 + 570 + curve = params->arr_curve_points; 571 + REG_SET_4(CM_RGAM_RAMA_REGION_0_1, 0, 572 + CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 573 + CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 574 + CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 575 + CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 576 + 577 + curve += 2; 578 + REG_SET_4(CM_RGAM_RAMA_REGION_2_3, 0, 579 + CM_RGAM_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset, 580 + CM_RGAM_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 581 + CM_RGAM_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset, 582 + CM_RGAM_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 583 + 584 + curve += 2; 585 + REG_SET_4(CM_RGAM_RAMA_REGION_4_5, 0, 586 + CM_RGAM_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset, 587 + CM_RGAM_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 588 + CM_RGAM_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset, 589 + CM_RGAM_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 590 + 591 + curve += 2; 592 + REG_SET_4(CM_RGAM_RAMA_REGION_6_7, 0, 593 + CM_RGAM_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset, 594 + CM_RGAM_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 595 + CM_RGAM_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset, 596 + CM_RGAM_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 597 + 598 + curve += 2; 599 + REG_SET_4(CM_RGAM_RAMA_REGION_8_9, 0, 600 + CM_RGAM_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset, 601 + CM_RGAM_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 602 + CM_RGAM_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset, 603 + CM_RGAM_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 604 + 605 + curve += 2; 606 + REG_SET_4(CM_RGAM_RAMA_REGION_10_11, 0, 607 + CM_RGAM_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset, 608 + CM_RGAM_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 609 + CM_RGAM_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset, 610 + CM_RGAM_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 611 + 612 + curve += 2; 613 + REG_SET_4(CM_RGAM_RAMA_REGION_12_13, 0, 614 + CM_RGAM_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset, 615 + CM_RGAM_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 616 + CM_RGAM_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset, 617 + CM_RGAM_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 618 + 619 + curve += 2; 620 + REG_SET_4(CM_RGAM_RAMA_REGION_14_15, 0, 621 + CM_RGAM_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset, 622 + CM_RGAM_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 623 + CM_RGAM_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset, 624 + CM_RGAM_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 625 + 626 + curve += 2; 627 + REG_SET_4(CM_RGAM_RAMA_REGION_16_17, 0, 628 + CM_RGAM_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset, 629 + CM_RGAM_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 630 + CM_RGAM_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset, 631 + CM_RGAM_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 632 + 633 + curve += 2; 634 + REG_SET_4(CM_RGAM_RAMA_REGION_18_19, 0, 635 + CM_RGAM_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset, 636 + CM_RGAM_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 637 + CM_RGAM_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset, 638 + CM_RGAM_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 639 + 640 + curve += 2; 641 + REG_SET_4(CM_RGAM_RAMA_REGION_20_21, 0, 642 + CM_RGAM_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset, 643 + CM_RGAM_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 644 + CM_RGAM_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset, 645 + CM_RGAM_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 646 + 647 + curve += 2; 648 + REG_SET_4(CM_RGAM_RAMA_REGION_22_23, 0, 649 + CM_RGAM_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset, 650 + CM_RGAM_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 651 + CM_RGAM_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset, 652 + CM_RGAM_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 653 + 654 + curve += 2; 655 + REG_SET_4(CM_RGAM_RAMA_REGION_24_25, 0, 656 + CM_RGAM_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset, 657 + CM_RGAM_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 658 + CM_RGAM_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset, 659 + CM_RGAM_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 660 + 661 + curve += 2; 662 + REG_SET_4(CM_RGAM_RAMA_REGION_26_27, 0, 663 + CM_RGAM_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset, 664 + CM_RGAM_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 665 + CM_RGAM_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset, 666 + CM_RGAM_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 667 + 668 + curve += 2; 669 + REG_SET_4(CM_RGAM_RAMA_REGION_28_29, 0, 670 + CM_RGAM_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset, 671 + CM_RGAM_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 672 + CM_RGAM_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset, 673 + CM_RGAM_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 674 + 675 + curve += 2; 676 + REG_SET_4(CM_RGAM_RAMA_REGION_30_31, 0, 677 + CM_RGAM_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset, 678 + CM_RGAM_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 679 + CM_RGAM_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset, 680 + CM_RGAM_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 681 + 682 + curve += 2; 683 + REG_SET_4(CM_RGAM_RAMA_REGION_32_33, 0, 684 + CM_RGAM_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset, 685 + CM_RGAM_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 686 + CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset, 687 + CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 688 + } 689 + 690 + static void opp_configure_regamma_lut( 691 + struct output_pixel_processor *opp, 692 + bool is_ram_a) 693 + { 694 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 695 + 696 + REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK, 697 + CM_RGAM_LUT_WRITE_EN_MASK, 7); 698 + REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK, 699 + CM_RGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 700 + REG_SET(CM_RGAM_LUT_INDEX, 0, CM_RGAM_LUT_INDEX, 0); 701 + } 702 + 703 + static void opp_power_on_regamma_lut( 704 + struct output_pixel_processor *opp, 705 + bool power_on) 706 + { 707 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 708 + REG_SET(CM_MEM_PWR_CTRL, 0, 709 + RGAM_MEM_PWR_FORCE, power_on == true ? 0:1); 710 + 711 + } 712 + 713 + static void opp_program_regamma_lut( 714 + struct output_pixel_processor *opp, 715 + const struct pwl_result_data *rgb, 716 + uint32_t num) 717 + { 718 + uint32_t i; 719 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 720 + for (i = 0 ; i < num; i++) { 721 + REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg); 722 + REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].green_reg); 723 + REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].blue_reg); 724 + 725 + REG_SET(CM_RGAM_LUT_DATA, 0, 726 + CM_RGAM_LUT_DATA, rgb[i].delta_red_reg); 727 + REG_SET(CM_RGAM_LUT_DATA, 0, 728 + CM_RGAM_LUT_DATA, rgb[i].delta_green_reg); 729 + REG_SET(CM_RGAM_LUT_DATA, 0, 730 + CM_RGAM_LUT_DATA, rgb[i].delta_blue_reg); 731 + 732 + } 733 + 734 + } 735 + 736 + static bool opp_set_regamma_pwl( 737 + struct output_pixel_processor *opp, const struct pwl_params *params) 738 + { 739 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 740 + 741 + opp_power_on_regamma_lut(opp, true); 742 + opp_configure_regamma_lut(opp, oppn10->is_write_to_ram_a_safe); 743 + 744 + if (oppn10->is_write_to_ram_a_safe) 745 + opp_program_regamma_luta_settings(opp, params); 746 + else 747 + opp_program_regamma_lutb_settings(opp, params); 748 + 749 + opp_program_regamma_lut( 750 + opp, params->rgb_resulted, params->hw_points_num); 751 + 752 + return true; 753 + } 754 + 755 + static void opp_set_stereo_polarity( 756 + struct output_pixel_processor *opp, 757 + bool enable, bool rightEyePolarity) 758 + { 759 + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); 760 + 761 + REG_UPDATE(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, enable); 762 + } 763 + 764 + /*****************************************/ 765 + /* Constructor, Destructor */ 766 + /*****************************************/ 767 + 768 + static void dcn10_opp_destroy(struct output_pixel_processor **opp) 769 + { 770 + dm_free(TO_DCN10_OPP(*opp)); 771 + *opp = NULL; 772 + } 773 + 774 + static struct opp_funcs dcn10_opp_funcs = { 775 + .opp_power_on_regamma_lut = opp_power_on_regamma_lut, 776 + .opp_set_csc_adjustment = NULL, 777 + .opp_set_csc_default = opp_set_output_csc_default, 778 + .opp_set_dyn_expansion = opp_set_dyn_expansion, 779 + .opp_program_regamma_pwl = opp_set_regamma_pwl, 780 + .opp_set_regamma_mode = opp_set_regamma_mode, 781 + .opp_program_fmt = opp_program_fmt, 782 + .opp_program_bit_depth_reduction = opp_program_bit_depth_reduction, 783 + .opp_set_stereo_polarity = opp_set_stereo_polarity, 784 + .opp_destroy = dcn10_opp_destroy 785 + }; 786 + 787 + void dcn10_opp_construct(struct dcn10_opp *oppn10, 788 + struct dc_context *ctx, 789 + uint32_t inst, 790 + const struct dcn10_opp_registers *regs, 791 + const struct dcn10_opp_shift *opp_shift, 792 + const struct dcn10_opp_mask *opp_mask) 793 + { 794 + oppn10->base.ctx = ctx; 795 + oppn10->base.inst = inst; 796 + oppn10->base.funcs = &dcn10_opp_funcs; 797 + 798 + oppn10->regs = regs; 799 + oppn10->opp_shift = opp_shift; 800 + oppn10->opp_mask = opp_mask; 801 + }
+622
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
··· 1 + /* Copyright 2012-15 Advanced Micro Devices, Inc. 2 + * 3 + * Permission is hereby granted, free of charge, to any person obtaining a 4 + * copy of this software and associated documentation files (the "Software"), 5 + * to deal in the Software without restriction, including without limitation 6 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 + * and/or sell copies of the Software, and to permit persons to whom the 8 + * Software is furnished to do so, subject to the following conditions: 9 + * 10 + * The above copyright notice and this permission notice shall be included in 11 + * all copies or substantial portions of the Software. 12 + * 13 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 + * OTHER DEALINGS IN THE SOFTWARE. 20 + * 21 + * Authors: AMD 22 + * 23 + */ 24 + 25 + #ifndef __DC_OPP_DCN10_H__ 26 + #define __DC_OPP_DCN10_H__ 27 + 28 + #include "opp.h" 29 + 30 + #define TO_DCN10_OPP(opp)\ 31 + container_of(opp, struct dcn10_opp, base) 32 + 33 + #define OPP_SF(reg_name, field_name, post_fix)\ 34 + .field_name = reg_name ## __ ## field_name ## post_fix 35 + 36 + #define OPP_DCN10_REG_LIST(id) \ 37 + SRI(CM_RGAM_LUT_WRITE_EN_MASK, CM, id), \ 38 + SRI(CM_RGAM_CONTROL, CM, id), \ 39 + SRI(OBUF_CONTROL, DSCL, id), \ 40 + SRI(FMT_BIT_DEPTH_CONTROL, FMT, id), \ 41 + SRI(FMT_CONTROL, FMT, id), \ 42 + SRI(FMT_DITHER_RAND_R_SEED, FMT, id), \ 43 + SRI(FMT_DITHER_RAND_G_SEED, FMT, id), \ 44 + SRI(FMT_DITHER_RAND_B_SEED, FMT, id), \ 45 + SRI(FMT_CLAMP_CNTL, FMT, id), \ 46 + SRI(FMT_DYNAMIC_EXP_CNTL, FMT, id), \ 47 + SRI(FMT_MAP420_MEMORY_CONTROL, FMT, id), \ 48 + SRI(CM_OCSC_CONTROL, CM, id), \ 49 + SRI(CM_RGAM_RAMB_START_CNTL_B, CM, id), \ 50 + SRI(CM_RGAM_RAMB_START_CNTL_G, CM, id), \ 51 + SRI(CM_RGAM_RAMB_START_CNTL_R, CM, id), \ 52 + SRI(CM_RGAM_RAMB_SLOPE_CNTL_B, CM, id), \ 53 + SRI(CM_RGAM_RAMB_SLOPE_CNTL_G, CM, id), \ 54 + SRI(CM_RGAM_RAMB_SLOPE_CNTL_R, CM, id), \ 55 + SRI(CM_RGAM_RAMB_END_CNTL1_B, CM, id), \ 56 + SRI(CM_RGAM_RAMB_END_CNTL2_B, CM, id), \ 57 + SRI(CM_RGAM_RAMB_END_CNTL1_G, CM, id), \ 58 + SRI(CM_RGAM_RAMB_END_CNTL2_G, CM, id), \ 59 + SRI(CM_RGAM_RAMB_END_CNTL1_R, CM, id), \ 60 + SRI(CM_RGAM_RAMB_END_CNTL2_R, CM, id), \ 61 + SRI(CM_RGAM_RAMB_REGION_0_1, CM, id), \ 62 + SRI(CM_RGAM_RAMB_REGION_2_3, CM, id), \ 63 + SRI(CM_RGAM_RAMB_REGION_4_5, CM, id), \ 64 + SRI(CM_RGAM_RAMB_REGION_6_7, CM, id), \ 65 + SRI(CM_RGAM_RAMB_REGION_8_9, CM, id), \ 66 + SRI(CM_RGAM_RAMB_REGION_10_11, CM, id), \ 67 + SRI(CM_RGAM_RAMB_REGION_12_13, CM, id), \ 68 + SRI(CM_RGAM_RAMB_REGION_14_15, CM, id), \ 69 + SRI(CM_RGAM_RAMB_REGION_16_17, CM, id), \ 70 + SRI(CM_RGAM_RAMB_REGION_18_19, CM, id), \ 71 + SRI(CM_RGAM_RAMB_REGION_20_21, CM, id), \ 72 + SRI(CM_RGAM_RAMB_REGION_22_23, CM, id), \ 73 + SRI(CM_RGAM_RAMB_REGION_24_25, CM, id), \ 74 + SRI(CM_RGAM_RAMB_REGION_26_27, CM, id), \ 75 + SRI(CM_RGAM_RAMB_REGION_28_29, CM, id), \ 76 + SRI(CM_RGAM_RAMB_REGION_30_31, CM, id), \ 77 + SRI(CM_RGAM_RAMB_REGION_32_33, CM, id), \ 78 + SRI(CM_RGAM_RAMA_START_CNTL_B, CM, id), \ 79 + SRI(CM_RGAM_RAMA_START_CNTL_G, CM, id), \ 80 + SRI(CM_RGAM_RAMA_START_CNTL_R, CM, id), \ 81 + SRI(CM_RGAM_RAMA_SLOPE_CNTL_B, CM, id), \ 82 + SRI(CM_RGAM_RAMA_SLOPE_CNTL_G, CM, id), \ 83 + SRI(CM_RGAM_RAMA_SLOPE_CNTL_R, CM, id), \ 84 + SRI(CM_RGAM_RAMA_END_CNTL1_B, CM, id), \ 85 + SRI(CM_RGAM_RAMA_END_CNTL2_B, CM, id), \ 86 + SRI(CM_RGAM_RAMA_END_CNTL1_G, CM, id), \ 87 + SRI(CM_RGAM_RAMA_END_CNTL2_G, CM, id), \ 88 + SRI(CM_RGAM_RAMA_END_CNTL1_R, CM, id), \ 89 + SRI(CM_RGAM_RAMA_END_CNTL2_R, CM, id), \ 90 + SRI(CM_RGAM_RAMA_REGION_0_1, CM, id), \ 91 + SRI(CM_RGAM_RAMA_REGION_2_3, CM, id), \ 92 + SRI(CM_RGAM_RAMA_REGION_4_5, CM, id), \ 93 + SRI(CM_RGAM_RAMA_REGION_6_7, CM, id), \ 94 + SRI(CM_RGAM_RAMA_REGION_8_9, CM, id), \ 95 + SRI(CM_RGAM_RAMA_REGION_10_11, CM, id), \ 96 + SRI(CM_RGAM_RAMA_REGION_12_13, CM, id), \ 97 + SRI(CM_RGAM_RAMA_REGION_14_15, CM, id), \ 98 + SRI(CM_RGAM_RAMA_REGION_16_17, CM, id), \ 99 + SRI(CM_RGAM_RAMA_REGION_18_19, CM, id), \ 100 + SRI(CM_RGAM_RAMA_REGION_20_21, CM, id), \ 101 + SRI(CM_RGAM_RAMA_REGION_22_23, CM, id), \ 102 + SRI(CM_RGAM_RAMA_REGION_24_25, CM, id), \ 103 + SRI(CM_RGAM_RAMA_REGION_26_27, CM, id), \ 104 + SRI(CM_RGAM_RAMA_REGION_28_29, CM, id), \ 105 + SRI(CM_RGAM_RAMA_REGION_30_31, CM, id), \ 106 + SRI(CM_RGAM_RAMA_REGION_32_33, CM, id), \ 107 + SRI(CM_RGAM_LUT_INDEX, CM, id), \ 108 + SRI(CM_MEM_PWR_CTRL, CM, id), \ 109 + SRI(CM_RGAM_LUT_DATA, CM, id) 110 + 111 + #define OPP_DCN10_MASK_SH_LIST(mask_sh) \ 112 + OPP_SF(CM0_CM_RGAM_CONTROL, CM_RGAM_LUT_MODE, mask_sh), \ 113 + OPP_SF(DSCL0_OBUF_CONTROL, OBUF_BYPASS, mask_sh), \ 114 + OPP_SF(DSCL0_OBUF_CONTROL, OBUF_H_2X_UPSCALE_EN, mask_sh), \ 115 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh), \ 116 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH, mask_sh), \ 117 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE, mask_sh), \ 118 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_EN, mask_sh), \ 119 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_MODE, mask_sh), \ 120 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_DEPTH, mask_sh), \ 121 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN, mask_sh), \ 122 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_HIGHPASS_RANDOM_ENABLE, mask_sh), \ 123 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_FRAME_RANDOM_ENABLE, mask_sh), \ 124 + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_RGB_RANDOM_ENABLE, mask_sh), \ 125 + OPP_SF(FMT0_FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh), \ 126 + OPP_SF(FMT0_FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh), \ 127 + OPP_SF(FMT0_FMT_DITHER_RAND_R_SEED, FMT_RAND_R_SEED, mask_sh), \ 128 + OPP_SF(FMT0_FMT_DITHER_RAND_G_SEED, FMT_RAND_G_SEED, mask_sh), \ 129 + OPP_SF(FMT0_FMT_DITHER_RAND_B_SEED, FMT_RAND_B_SEED, mask_sh), \ 130 + OPP_SF(FMT0_FMT_CONTROL, FMT_PIXEL_ENCODING, mask_sh), \ 131 + OPP_SF(FMT0_FMT_CLAMP_CNTL, FMT_CLAMP_DATA_EN, mask_sh), \ 132 + OPP_SF(FMT0_FMT_CLAMP_CNTL, FMT_CLAMP_COLOR_FORMAT, mask_sh), \ 133 + OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN, mask_sh), \ 134 + OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE, mask_sh), \ 135 + OPP_SF(FMT0_FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, mask_sh), \ 136 + OPP_SF(CM0_CM_OCSC_CONTROL, CM_OCSC_MODE, mask_sh), \ 137 + OPP_SF(CM0_CM_RGAM_RAMB_START_CNTL_B, CM_RGAM_RAMB_EXP_REGION_START_B, mask_sh), \ 138 + OPP_SF(CM0_CM_RGAM_RAMB_START_CNTL_B, CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B, mask_sh), \ 139 + OPP_SF(CM0_CM_RGAM_RAMB_START_CNTL_G, CM_RGAM_RAMB_EXP_REGION_START_G, mask_sh), \ 140 + OPP_SF(CM0_CM_RGAM_RAMB_START_CNTL_G, CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_G, mask_sh), \ 141 + OPP_SF(CM0_CM_RGAM_RAMB_START_CNTL_R, CM_RGAM_RAMB_EXP_REGION_START_R, mask_sh), \ 142 + OPP_SF(CM0_CM_RGAM_RAMB_START_CNTL_R, CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_R, mask_sh), \ 143 + OPP_SF(CM0_CM_RGAM_RAMB_SLOPE_CNTL_B, CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B, mask_sh), \ 144 + OPP_SF(CM0_CM_RGAM_RAMB_SLOPE_CNTL_G, CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_G, mask_sh), \ 145 + OPP_SF(CM0_CM_RGAM_RAMB_SLOPE_CNTL_R, CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_R, mask_sh), \ 146 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL1_B, CM_RGAM_RAMB_EXP_REGION_END_B, mask_sh), \ 147 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL2_B, CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B, mask_sh), \ 148 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL2_B, CM_RGAM_RAMB_EXP_REGION_END_BASE_B, mask_sh), \ 149 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL1_G, CM_RGAM_RAMB_EXP_REGION_END_G, mask_sh), \ 150 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL2_G, CM_RGAM_RAMB_EXP_REGION_END_SLOPE_G, mask_sh), \ 151 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL2_G, CM_RGAM_RAMB_EXP_REGION_END_BASE_G, mask_sh), \ 152 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL1_R, CM_RGAM_RAMB_EXP_REGION_END_R, mask_sh), \ 153 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL2_R, CM_RGAM_RAMB_EXP_REGION_END_SLOPE_R, mask_sh), \ 154 + OPP_SF(CM0_CM_RGAM_RAMB_END_CNTL2_R, CM_RGAM_RAMB_EXP_REGION_END_BASE_R, mask_sh), \ 155 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_0_1, CM_RGAM_RAMB_EXP_REGION0_LUT_OFFSET, mask_sh), \ 156 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_0_1, CM_RGAM_RAMB_EXP_REGION0_NUM_SEGMENTS, mask_sh), \ 157 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_0_1, CM_RGAM_RAMB_EXP_REGION1_LUT_OFFSET, mask_sh), \ 158 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_0_1, CM_RGAM_RAMB_EXP_REGION1_NUM_SEGMENTS, mask_sh), \ 159 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_2_3, CM_RGAM_RAMB_EXP_REGION2_LUT_OFFSET, mask_sh), \ 160 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_2_3, CM_RGAM_RAMB_EXP_REGION2_NUM_SEGMENTS, mask_sh), \ 161 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_2_3, CM_RGAM_RAMB_EXP_REGION3_LUT_OFFSET, mask_sh), \ 162 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_2_3, CM_RGAM_RAMB_EXP_REGION3_NUM_SEGMENTS, mask_sh), \ 163 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_4_5, CM_RGAM_RAMB_EXP_REGION4_LUT_OFFSET, mask_sh), \ 164 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_4_5, CM_RGAM_RAMB_EXP_REGION4_NUM_SEGMENTS, mask_sh), \ 165 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_4_5, CM_RGAM_RAMB_EXP_REGION5_LUT_OFFSET, mask_sh), \ 166 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_4_5, CM_RGAM_RAMB_EXP_REGION5_NUM_SEGMENTS, mask_sh), \ 167 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_6_7, CM_RGAM_RAMB_EXP_REGION6_LUT_OFFSET, mask_sh), \ 168 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_6_7, CM_RGAM_RAMB_EXP_REGION6_NUM_SEGMENTS, mask_sh), \ 169 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_6_7, CM_RGAM_RAMB_EXP_REGION7_LUT_OFFSET, mask_sh), \ 170 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_6_7, CM_RGAM_RAMB_EXP_REGION7_NUM_SEGMENTS, mask_sh), \ 171 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_8_9, CM_RGAM_RAMB_EXP_REGION8_LUT_OFFSET, mask_sh), \ 172 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_8_9, CM_RGAM_RAMB_EXP_REGION8_NUM_SEGMENTS, mask_sh), \ 173 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_8_9, CM_RGAM_RAMB_EXP_REGION9_LUT_OFFSET, mask_sh), \ 174 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_8_9, CM_RGAM_RAMB_EXP_REGION9_NUM_SEGMENTS, mask_sh), \ 175 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_10_11, CM_RGAM_RAMB_EXP_REGION10_LUT_OFFSET, mask_sh), \ 176 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_10_11, CM_RGAM_RAMB_EXP_REGION10_NUM_SEGMENTS, mask_sh), \ 177 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_10_11, CM_RGAM_RAMB_EXP_REGION11_LUT_OFFSET, mask_sh), \ 178 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_10_11, CM_RGAM_RAMB_EXP_REGION11_NUM_SEGMENTS, mask_sh), \ 179 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_12_13, CM_RGAM_RAMB_EXP_REGION12_LUT_OFFSET, mask_sh), \ 180 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_12_13, CM_RGAM_RAMB_EXP_REGION12_NUM_SEGMENTS, mask_sh), \ 181 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_12_13, CM_RGAM_RAMB_EXP_REGION13_LUT_OFFSET, mask_sh), \ 182 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_12_13, CM_RGAM_RAMB_EXP_REGION13_NUM_SEGMENTS, mask_sh), \ 183 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_14_15, CM_RGAM_RAMB_EXP_REGION14_LUT_OFFSET, mask_sh), \ 184 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_14_15, CM_RGAM_RAMB_EXP_REGION14_NUM_SEGMENTS, mask_sh), \ 185 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_14_15, CM_RGAM_RAMB_EXP_REGION15_LUT_OFFSET, mask_sh), \ 186 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_14_15, CM_RGAM_RAMB_EXP_REGION15_NUM_SEGMENTS, mask_sh), \ 187 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_16_17, CM_RGAM_RAMB_EXP_REGION16_LUT_OFFSET, mask_sh), \ 188 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_16_17, CM_RGAM_RAMB_EXP_REGION16_NUM_SEGMENTS, mask_sh), \ 189 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_16_17, CM_RGAM_RAMB_EXP_REGION17_LUT_OFFSET, mask_sh), \ 190 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_16_17, CM_RGAM_RAMB_EXP_REGION17_NUM_SEGMENTS, mask_sh), \ 191 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_18_19, CM_RGAM_RAMB_EXP_REGION18_LUT_OFFSET, mask_sh), \ 192 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_18_19, CM_RGAM_RAMB_EXP_REGION18_NUM_SEGMENTS, mask_sh), \ 193 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_18_19, CM_RGAM_RAMB_EXP_REGION19_LUT_OFFSET, mask_sh), \ 194 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_18_19, CM_RGAM_RAMB_EXP_REGION19_NUM_SEGMENTS, mask_sh), \ 195 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_20_21, CM_RGAM_RAMB_EXP_REGION20_LUT_OFFSET, mask_sh), \ 196 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_20_21, CM_RGAM_RAMB_EXP_REGION20_NUM_SEGMENTS, mask_sh), \ 197 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_20_21, CM_RGAM_RAMB_EXP_REGION21_LUT_OFFSET, mask_sh), \ 198 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_20_21, CM_RGAM_RAMB_EXP_REGION21_NUM_SEGMENTS, mask_sh), \ 199 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_22_23, CM_RGAM_RAMB_EXP_REGION22_LUT_OFFSET, mask_sh), \ 200 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_22_23, CM_RGAM_RAMB_EXP_REGION22_NUM_SEGMENTS, mask_sh), \ 201 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_22_23, CM_RGAM_RAMB_EXP_REGION23_LUT_OFFSET, mask_sh), \ 202 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_22_23, CM_RGAM_RAMB_EXP_REGION23_NUM_SEGMENTS, mask_sh), \ 203 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_24_25, CM_RGAM_RAMB_EXP_REGION24_LUT_OFFSET, mask_sh), \ 204 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_24_25, CM_RGAM_RAMB_EXP_REGION24_NUM_SEGMENTS, mask_sh), \ 205 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_24_25, CM_RGAM_RAMB_EXP_REGION25_LUT_OFFSET, mask_sh), \ 206 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_24_25, CM_RGAM_RAMB_EXP_REGION25_NUM_SEGMENTS, mask_sh), \ 207 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_26_27, CM_RGAM_RAMB_EXP_REGION26_LUT_OFFSET, mask_sh), \ 208 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_26_27, CM_RGAM_RAMB_EXP_REGION26_NUM_SEGMENTS, mask_sh), \ 209 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_26_27, CM_RGAM_RAMB_EXP_REGION27_LUT_OFFSET, mask_sh), \ 210 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_26_27, CM_RGAM_RAMB_EXP_REGION27_NUM_SEGMENTS, mask_sh), \ 211 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_28_29, CM_RGAM_RAMB_EXP_REGION28_LUT_OFFSET, mask_sh), \ 212 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_28_29, CM_RGAM_RAMB_EXP_REGION28_NUM_SEGMENTS, mask_sh), \ 213 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_28_29, CM_RGAM_RAMB_EXP_REGION29_LUT_OFFSET, mask_sh), \ 214 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_28_29, CM_RGAM_RAMB_EXP_REGION29_NUM_SEGMENTS, mask_sh), \ 215 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_30_31, CM_RGAM_RAMB_EXP_REGION30_LUT_OFFSET, mask_sh), \ 216 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_30_31, CM_RGAM_RAMB_EXP_REGION30_NUM_SEGMENTS, mask_sh), \ 217 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_30_31, CM_RGAM_RAMB_EXP_REGION31_LUT_OFFSET, mask_sh), \ 218 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_30_31, CM_RGAM_RAMB_EXP_REGION31_NUM_SEGMENTS, mask_sh), \ 219 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_32_33, CM_RGAM_RAMB_EXP_REGION32_LUT_OFFSET, mask_sh), \ 220 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_32_33, CM_RGAM_RAMB_EXP_REGION32_NUM_SEGMENTS, mask_sh), \ 221 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_32_33, CM_RGAM_RAMB_EXP_REGION33_LUT_OFFSET, mask_sh), \ 222 + OPP_SF(CM0_CM_RGAM_RAMB_REGION_32_33, CM_RGAM_RAMB_EXP_REGION33_NUM_SEGMENTS, mask_sh), \ 223 + OPP_SF(CM0_CM_RGAM_RAMA_START_CNTL_B, CM_RGAM_RAMA_EXP_REGION_START_B, mask_sh), \ 224 + OPP_SF(CM0_CM_RGAM_RAMA_START_CNTL_B, CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_B, mask_sh), \ 225 + OPP_SF(CM0_CM_RGAM_RAMA_START_CNTL_G, CM_RGAM_RAMA_EXP_REGION_START_G, mask_sh), \ 226 + OPP_SF(CM0_CM_RGAM_RAMA_START_CNTL_G, CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_G, mask_sh), \ 227 + OPP_SF(CM0_CM_RGAM_RAMA_START_CNTL_R, CM_RGAM_RAMA_EXP_REGION_START_R, mask_sh), \ 228 + OPP_SF(CM0_CM_RGAM_RAMA_START_CNTL_R, CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_R, mask_sh), \ 229 + OPP_SF(CM0_CM_RGAM_RAMA_SLOPE_CNTL_B, CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B, mask_sh), \ 230 + OPP_SF(CM0_CM_RGAM_RAMA_SLOPE_CNTL_G, CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_G, mask_sh), \ 231 + OPP_SF(CM0_CM_RGAM_RAMA_SLOPE_CNTL_R, CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_R, mask_sh), \ 232 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL1_B, CM_RGAM_RAMA_EXP_REGION_END_B, mask_sh), \ 233 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL2_B, CM_RGAM_RAMA_EXP_REGION_END_SLOPE_B, mask_sh), \ 234 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL2_B, CM_RGAM_RAMA_EXP_REGION_END_BASE_B, mask_sh), \ 235 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL1_G, CM_RGAM_RAMA_EXP_REGION_END_G, mask_sh), \ 236 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL2_G, CM_RGAM_RAMA_EXP_REGION_END_SLOPE_G, mask_sh), \ 237 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL2_G, CM_RGAM_RAMA_EXP_REGION_END_BASE_G, mask_sh), \ 238 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL1_R, CM_RGAM_RAMA_EXP_REGION_END_R, mask_sh), \ 239 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL2_R, CM_RGAM_RAMA_EXP_REGION_END_SLOPE_R, mask_sh), \ 240 + OPP_SF(CM0_CM_RGAM_RAMA_END_CNTL2_R, CM_RGAM_RAMA_EXP_REGION_END_BASE_R, mask_sh), \ 241 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_0_1, CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET, mask_sh), \ 242 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_0_1, CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS, mask_sh), \ 243 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_0_1, CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET, mask_sh), \ 244 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_0_1, CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS, mask_sh), \ 245 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_2_3, CM_RGAM_RAMA_EXP_REGION2_LUT_OFFSET, mask_sh), \ 246 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_2_3, CM_RGAM_RAMA_EXP_REGION2_NUM_SEGMENTS, mask_sh), \ 247 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_2_3, CM_RGAM_RAMA_EXP_REGION3_LUT_OFFSET, mask_sh), \ 248 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_2_3, CM_RGAM_RAMA_EXP_REGION3_NUM_SEGMENTS, mask_sh), \ 249 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_4_5, CM_RGAM_RAMA_EXP_REGION4_LUT_OFFSET, mask_sh), \ 250 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_4_5, CM_RGAM_RAMA_EXP_REGION4_NUM_SEGMENTS, mask_sh), \ 251 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_4_5, CM_RGAM_RAMA_EXP_REGION5_LUT_OFFSET, mask_sh), \ 252 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_4_5, CM_RGAM_RAMA_EXP_REGION5_NUM_SEGMENTS, mask_sh), \ 253 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_6_7, CM_RGAM_RAMA_EXP_REGION6_LUT_OFFSET, mask_sh), \ 254 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_6_7, CM_RGAM_RAMA_EXP_REGION6_NUM_SEGMENTS, mask_sh), \ 255 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_6_7, CM_RGAM_RAMA_EXP_REGION7_LUT_OFFSET, mask_sh), \ 256 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_6_7, CM_RGAM_RAMA_EXP_REGION7_NUM_SEGMENTS, mask_sh), \ 257 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_8_9, CM_RGAM_RAMA_EXP_REGION8_LUT_OFFSET, mask_sh), \ 258 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_8_9, CM_RGAM_RAMA_EXP_REGION8_NUM_SEGMENTS, mask_sh), \ 259 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_8_9, CM_RGAM_RAMA_EXP_REGION9_LUT_OFFSET, mask_sh), \ 260 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_8_9, CM_RGAM_RAMA_EXP_REGION9_NUM_SEGMENTS, mask_sh), \ 261 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_10_11, CM_RGAM_RAMA_EXP_REGION10_LUT_OFFSET, mask_sh), \ 262 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_10_11, CM_RGAM_RAMA_EXP_REGION10_NUM_SEGMENTS, mask_sh), \ 263 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_10_11, CM_RGAM_RAMA_EXP_REGION11_LUT_OFFSET, mask_sh), \ 264 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_10_11, CM_RGAM_RAMA_EXP_REGION11_NUM_SEGMENTS, mask_sh), \ 265 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_12_13, CM_RGAM_RAMA_EXP_REGION12_LUT_OFFSET, mask_sh), \ 266 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_12_13, CM_RGAM_RAMA_EXP_REGION12_NUM_SEGMENTS, mask_sh), \ 267 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_12_13, CM_RGAM_RAMA_EXP_REGION13_LUT_OFFSET, mask_sh), \ 268 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_12_13, CM_RGAM_RAMA_EXP_REGION13_NUM_SEGMENTS, mask_sh), \ 269 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_14_15, CM_RGAM_RAMA_EXP_REGION14_LUT_OFFSET, mask_sh), \ 270 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_14_15, CM_RGAM_RAMA_EXP_REGION14_NUM_SEGMENTS, mask_sh), \ 271 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_14_15, CM_RGAM_RAMA_EXP_REGION15_LUT_OFFSET, mask_sh), \ 272 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_14_15, CM_RGAM_RAMA_EXP_REGION15_NUM_SEGMENTS, mask_sh), \ 273 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_16_17, CM_RGAM_RAMA_EXP_REGION16_LUT_OFFSET, mask_sh), \ 274 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_16_17, CM_RGAM_RAMA_EXP_REGION16_NUM_SEGMENTS, mask_sh), \ 275 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_16_17, CM_RGAM_RAMA_EXP_REGION17_LUT_OFFSET, mask_sh), \ 276 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_16_17, CM_RGAM_RAMA_EXP_REGION17_NUM_SEGMENTS, mask_sh), \ 277 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_18_19, CM_RGAM_RAMA_EXP_REGION18_LUT_OFFSET, mask_sh), \ 278 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_18_19, CM_RGAM_RAMA_EXP_REGION18_NUM_SEGMENTS, mask_sh), \ 279 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_18_19, CM_RGAM_RAMA_EXP_REGION19_LUT_OFFSET, mask_sh), \ 280 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_18_19, CM_RGAM_RAMA_EXP_REGION19_NUM_SEGMENTS, mask_sh), \ 281 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_20_21, CM_RGAM_RAMA_EXP_REGION20_LUT_OFFSET, mask_sh), \ 282 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_20_21, CM_RGAM_RAMA_EXP_REGION20_NUM_SEGMENTS, mask_sh), \ 283 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_20_21, CM_RGAM_RAMA_EXP_REGION21_LUT_OFFSET, mask_sh), \ 284 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_20_21, CM_RGAM_RAMA_EXP_REGION21_NUM_SEGMENTS, mask_sh), \ 285 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_22_23, CM_RGAM_RAMA_EXP_REGION22_LUT_OFFSET, mask_sh), \ 286 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_22_23, CM_RGAM_RAMA_EXP_REGION22_NUM_SEGMENTS, mask_sh), \ 287 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_22_23, CM_RGAM_RAMA_EXP_REGION23_LUT_OFFSET, mask_sh), \ 288 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_22_23, CM_RGAM_RAMA_EXP_REGION23_NUM_SEGMENTS, mask_sh), \ 289 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_24_25, CM_RGAM_RAMA_EXP_REGION24_LUT_OFFSET, mask_sh), \ 290 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_24_25, CM_RGAM_RAMA_EXP_REGION24_NUM_SEGMENTS, mask_sh), \ 291 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_24_25, CM_RGAM_RAMA_EXP_REGION25_LUT_OFFSET, mask_sh), \ 292 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_24_25, CM_RGAM_RAMA_EXP_REGION25_NUM_SEGMENTS, mask_sh), \ 293 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_26_27, CM_RGAM_RAMA_EXP_REGION26_LUT_OFFSET, mask_sh), \ 294 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_26_27, CM_RGAM_RAMA_EXP_REGION26_NUM_SEGMENTS, mask_sh), \ 295 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_26_27, CM_RGAM_RAMA_EXP_REGION27_LUT_OFFSET, mask_sh), \ 296 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_26_27, CM_RGAM_RAMA_EXP_REGION27_NUM_SEGMENTS, mask_sh), \ 297 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_28_29, CM_RGAM_RAMA_EXP_REGION28_LUT_OFFSET, mask_sh), \ 298 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_28_29, CM_RGAM_RAMA_EXP_REGION28_NUM_SEGMENTS, mask_sh), \ 299 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_28_29, CM_RGAM_RAMA_EXP_REGION29_LUT_OFFSET, mask_sh), \ 300 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_28_29, CM_RGAM_RAMA_EXP_REGION29_NUM_SEGMENTS, mask_sh), \ 301 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_30_31, CM_RGAM_RAMA_EXP_REGION30_LUT_OFFSET, mask_sh), \ 302 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_30_31, CM_RGAM_RAMA_EXP_REGION30_NUM_SEGMENTS, mask_sh), \ 303 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_30_31, CM_RGAM_RAMA_EXP_REGION31_LUT_OFFSET, mask_sh), \ 304 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_30_31, CM_RGAM_RAMA_EXP_REGION31_NUM_SEGMENTS, mask_sh), \ 305 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_32_33, CM_RGAM_RAMA_EXP_REGION32_LUT_OFFSET, mask_sh), \ 306 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_32_33, CM_RGAM_RAMA_EXP_REGION32_NUM_SEGMENTS, mask_sh), \ 307 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_32_33, CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET, mask_sh), \ 308 + OPP_SF(CM0_CM_RGAM_RAMA_REGION_32_33, CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS, mask_sh), \ 309 + OPP_SF(CM0_CM_RGAM_LUT_WRITE_EN_MASK, CM_RGAM_LUT_WRITE_EN_MASK, mask_sh), \ 310 + OPP_SF(CM0_CM_RGAM_LUT_WRITE_EN_MASK, CM_RGAM_LUT_WRITE_SEL, mask_sh), \ 311 + OPP_SF(CM0_CM_RGAM_LUT_INDEX, CM_RGAM_LUT_INDEX, mask_sh), \ 312 + OPP_SF(CM0_CM_MEM_PWR_CTRL, RGAM_MEM_PWR_FORCE, mask_sh), \ 313 + OPP_SF(CM0_CM_RGAM_LUT_DATA, CM_RGAM_LUT_DATA, mask_sh), \ 314 + OPP_SF(FMT0_FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, mask_sh) 315 + 316 + #define OPP_DCN10_REG_FIELD_LIST(type) \ 317 + type CM_RGAM_LUT_MODE; \ 318 + type OBUF_BYPASS; \ 319 + type OBUF_H_2X_UPSCALE_EN; \ 320 + type FMT_TRUNCATE_EN; \ 321 + type FMT_TRUNCATE_DEPTH; \ 322 + type FMT_TRUNCATE_MODE; \ 323 + type FMT_SPATIAL_DITHER_EN; \ 324 + type FMT_SPATIAL_DITHER_MODE; \ 325 + type FMT_SPATIAL_DITHER_DEPTH; \ 326 + type FMT_TEMPORAL_DITHER_EN; \ 327 + type FMT_HIGHPASS_RANDOM_ENABLE; \ 328 + type FMT_FRAME_RANDOM_ENABLE; \ 329 + type FMT_RGB_RANDOM_ENABLE; \ 330 + type FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX; \ 331 + type FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP; \ 332 + type FMT_RAND_R_SEED; \ 333 + type FMT_RAND_G_SEED; \ 334 + type FMT_RAND_B_SEED; \ 335 + type FMT_PIXEL_ENCODING; \ 336 + type FMT_CLAMP_DATA_EN; \ 337 + type FMT_CLAMP_COLOR_FORMAT; \ 338 + type FMT_DYNAMIC_EXP_EN; \ 339 + type FMT_DYNAMIC_EXP_MODE; \ 340 + type FMT_MAP420MEM_PWR_FORCE; \ 341 + type CM_OCSC_MODE; \ 342 + type CM_RGAM_RAMB_EXP_REGION_START_B; \ 343 + type CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; \ 344 + type CM_RGAM_RAMB_EXP_REGION_START_G; \ 345 + type CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_G; \ 346 + type CM_RGAM_RAMB_EXP_REGION_START_R; \ 347 + type CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_R; \ 348 + type CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; \ 349 + type CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_G; \ 350 + type CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_R; \ 351 + type CM_RGAM_RAMB_EXP_REGION_END_B; \ 352 + type CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; \ 353 + type CM_RGAM_RAMB_EXP_REGION_END_BASE_B; \ 354 + type CM_RGAM_RAMB_EXP_REGION_END_G; \ 355 + type CM_RGAM_RAMB_EXP_REGION_END_SLOPE_G; \ 356 + type CM_RGAM_RAMB_EXP_REGION_END_BASE_G; \ 357 + type CM_RGAM_RAMB_EXP_REGION_END_R; \ 358 + type CM_RGAM_RAMB_EXP_REGION_END_SLOPE_R; \ 359 + type CM_RGAM_RAMB_EXP_REGION_END_BASE_R; \ 360 + type CM_RGAM_RAMB_EXP_REGION0_LUT_OFFSET; \ 361 + type CM_RGAM_RAMB_EXP_REGION0_NUM_SEGMENTS; \ 362 + type CM_RGAM_RAMB_EXP_REGION1_LUT_OFFSET; \ 363 + type CM_RGAM_RAMB_EXP_REGION1_NUM_SEGMENTS; \ 364 + type CM_RGAM_RAMB_EXP_REGION2_LUT_OFFSET; \ 365 + type CM_RGAM_RAMB_EXP_REGION2_NUM_SEGMENTS; \ 366 + type CM_RGAM_RAMB_EXP_REGION3_LUT_OFFSET; \ 367 + type CM_RGAM_RAMB_EXP_REGION3_NUM_SEGMENTS; \ 368 + type CM_RGAM_RAMB_EXP_REGION4_LUT_OFFSET; \ 369 + type CM_RGAM_RAMB_EXP_REGION4_NUM_SEGMENTS; \ 370 + type CM_RGAM_RAMB_EXP_REGION5_LUT_OFFSET; \ 371 + type CM_RGAM_RAMB_EXP_REGION5_NUM_SEGMENTS; \ 372 + type CM_RGAM_RAMB_EXP_REGION6_LUT_OFFSET; \ 373 + type CM_RGAM_RAMB_EXP_REGION6_NUM_SEGMENTS; \ 374 + type CM_RGAM_RAMB_EXP_REGION7_LUT_OFFSET; \ 375 + type CM_RGAM_RAMB_EXP_REGION7_NUM_SEGMENTS; \ 376 + type CM_RGAM_RAMB_EXP_REGION8_LUT_OFFSET; \ 377 + type CM_RGAM_RAMB_EXP_REGION8_NUM_SEGMENTS; \ 378 + type CM_RGAM_RAMB_EXP_REGION9_LUT_OFFSET; \ 379 + type CM_RGAM_RAMB_EXP_REGION9_NUM_SEGMENTS; \ 380 + type CM_RGAM_RAMB_EXP_REGION10_LUT_OFFSET; \ 381 + type CM_RGAM_RAMB_EXP_REGION10_NUM_SEGMENTS; \ 382 + type CM_RGAM_RAMB_EXP_REGION11_LUT_OFFSET; \ 383 + type CM_RGAM_RAMB_EXP_REGION11_NUM_SEGMENTS; \ 384 + type CM_RGAM_RAMB_EXP_REGION12_LUT_OFFSET; \ 385 + type CM_RGAM_RAMB_EXP_REGION12_NUM_SEGMENTS; \ 386 + type CM_RGAM_RAMB_EXP_REGION13_LUT_OFFSET; \ 387 + type CM_RGAM_RAMB_EXP_REGION13_NUM_SEGMENTS; \ 388 + type CM_RGAM_RAMB_EXP_REGION14_LUT_OFFSET; \ 389 + type CM_RGAM_RAMB_EXP_REGION14_NUM_SEGMENTS; \ 390 + type CM_RGAM_RAMB_EXP_REGION15_LUT_OFFSET; \ 391 + type CM_RGAM_RAMB_EXP_REGION15_NUM_SEGMENTS; \ 392 + type CM_RGAM_RAMB_EXP_REGION16_LUT_OFFSET; \ 393 + type CM_RGAM_RAMB_EXP_REGION16_NUM_SEGMENTS; \ 394 + type CM_RGAM_RAMB_EXP_REGION17_LUT_OFFSET; \ 395 + type CM_RGAM_RAMB_EXP_REGION17_NUM_SEGMENTS; \ 396 + type CM_RGAM_RAMB_EXP_REGION18_LUT_OFFSET; \ 397 + type CM_RGAM_RAMB_EXP_REGION18_NUM_SEGMENTS; \ 398 + type CM_RGAM_RAMB_EXP_REGION19_LUT_OFFSET; \ 399 + type CM_RGAM_RAMB_EXP_REGION19_NUM_SEGMENTS; \ 400 + type CM_RGAM_RAMB_EXP_REGION20_LUT_OFFSET; \ 401 + type CM_RGAM_RAMB_EXP_REGION20_NUM_SEGMENTS; \ 402 + type CM_RGAM_RAMB_EXP_REGION21_LUT_OFFSET; \ 403 + type CM_RGAM_RAMB_EXP_REGION21_NUM_SEGMENTS; \ 404 + type CM_RGAM_RAMB_EXP_REGION22_LUT_OFFSET; \ 405 + type CM_RGAM_RAMB_EXP_REGION22_NUM_SEGMENTS; \ 406 + type CM_RGAM_RAMB_EXP_REGION23_LUT_OFFSET; \ 407 + type CM_RGAM_RAMB_EXP_REGION23_NUM_SEGMENTS; \ 408 + type CM_RGAM_RAMB_EXP_REGION24_LUT_OFFSET; \ 409 + type CM_RGAM_RAMB_EXP_REGION24_NUM_SEGMENTS; \ 410 + type CM_RGAM_RAMB_EXP_REGION25_LUT_OFFSET; \ 411 + type CM_RGAM_RAMB_EXP_REGION25_NUM_SEGMENTS; \ 412 + type CM_RGAM_RAMB_EXP_REGION26_LUT_OFFSET; \ 413 + type CM_RGAM_RAMB_EXP_REGION26_NUM_SEGMENTS; \ 414 + type CM_RGAM_RAMB_EXP_REGION27_LUT_OFFSET; \ 415 + type CM_RGAM_RAMB_EXP_REGION27_NUM_SEGMENTS; \ 416 + type CM_RGAM_RAMB_EXP_REGION28_LUT_OFFSET; \ 417 + type CM_RGAM_RAMB_EXP_REGION28_NUM_SEGMENTS; \ 418 + type CM_RGAM_RAMB_EXP_REGION29_LUT_OFFSET; \ 419 + type CM_RGAM_RAMB_EXP_REGION29_NUM_SEGMENTS; \ 420 + type CM_RGAM_RAMB_EXP_REGION30_LUT_OFFSET; \ 421 + type CM_RGAM_RAMB_EXP_REGION30_NUM_SEGMENTS; \ 422 + type CM_RGAM_RAMB_EXP_REGION31_LUT_OFFSET; \ 423 + type CM_RGAM_RAMB_EXP_REGION31_NUM_SEGMENTS; \ 424 + type CM_RGAM_RAMB_EXP_REGION32_LUT_OFFSET; \ 425 + type CM_RGAM_RAMB_EXP_REGION32_NUM_SEGMENTS; \ 426 + type CM_RGAM_RAMB_EXP_REGION33_LUT_OFFSET; \ 427 + type CM_RGAM_RAMB_EXP_REGION33_NUM_SEGMENTS; \ 428 + type CM_RGAM_RAMA_EXP_REGION_START_B; \ 429 + type CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_B; \ 430 + type CM_RGAM_RAMA_EXP_REGION_START_G; \ 431 + type CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_G; \ 432 + type CM_RGAM_RAMA_EXP_REGION_START_R; \ 433 + type CM_RGAM_RAMA_EXP_REGION_START_SEGMENT_R; \ 434 + type CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B; \ 435 + type CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_G; \ 436 + type CM_RGAM_RAMA_EXP_REGION_LINEAR_SLOPE_R; \ 437 + type CM_RGAM_RAMA_EXP_REGION_END_B; \ 438 + type CM_RGAM_RAMA_EXP_REGION_END_SLOPE_B; \ 439 + type CM_RGAM_RAMA_EXP_REGION_END_BASE_B; \ 440 + type CM_RGAM_RAMA_EXP_REGION_END_G; \ 441 + type CM_RGAM_RAMA_EXP_REGION_END_SLOPE_G; \ 442 + type CM_RGAM_RAMA_EXP_REGION_END_BASE_G; \ 443 + type CM_RGAM_RAMA_EXP_REGION_END_R; \ 444 + type CM_RGAM_RAMA_EXP_REGION_END_SLOPE_R; \ 445 + type CM_RGAM_RAMA_EXP_REGION_END_BASE_R; \ 446 + type CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; \ 447 + type CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; \ 448 + type CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; \ 449 + type CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; \ 450 + type CM_RGAM_RAMA_EXP_REGION2_LUT_OFFSET; \ 451 + type CM_RGAM_RAMA_EXP_REGION2_NUM_SEGMENTS; \ 452 + type CM_RGAM_RAMA_EXP_REGION3_LUT_OFFSET; \ 453 + type CM_RGAM_RAMA_EXP_REGION3_NUM_SEGMENTS; \ 454 + type CM_RGAM_RAMA_EXP_REGION4_LUT_OFFSET; \ 455 + type CM_RGAM_RAMA_EXP_REGION4_NUM_SEGMENTS; \ 456 + type CM_RGAM_RAMA_EXP_REGION5_LUT_OFFSET; \ 457 + type CM_RGAM_RAMA_EXP_REGION5_NUM_SEGMENTS; \ 458 + type CM_RGAM_RAMA_EXP_REGION6_LUT_OFFSET; \ 459 + type CM_RGAM_RAMA_EXP_REGION6_NUM_SEGMENTS; \ 460 + type CM_RGAM_RAMA_EXP_REGION7_LUT_OFFSET; \ 461 + type CM_RGAM_RAMA_EXP_REGION7_NUM_SEGMENTS; \ 462 + type CM_RGAM_RAMA_EXP_REGION8_LUT_OFFSET; \ 463 + type CM_RGAM_RAMA_EXP_REGION8_NUM_SEGMENTS; \ 464 + type CM_RGAM_RAMA_EXP_REGION9_LUT_OFFSET; \ 465 + type CM_RGAM_RAMA_EXP_REGION9_NUM_SEGMENTS; \ 466 + type CM_RGAM_RAMA_EXP_REGION10_LUT_OFFSET; \ 467 + type CM_RGAM_RAMA_EXP_REGION10_NUM_SEGMENTS; \ 468 + type CM_RGAM_RAMA_EXP_REGION11_LUT_OFFSET; \ 469 + type CM_RGAM_RAMA_EXP_REGION11_NUM_SEGMENTS; \ 470 + type CM_RGAM_RAMA_EXP_REGION12_LUT_OFFSET; \ 471 + type CM_RGAM_RAMA_EXP_REGION12_NUM_SEGMENTS; \ 472 + type CM_RGAM_RAMA_EXP_REGION13_LUT_OFFSET; \ 473 + type CM_RGAM_RAMA_EXP_REGION13_NUM_SEGMENTS; \ 474 + type CM_RGAM_RAMA_EXP_REGION14_LUT_OFFSET; \ 475 + type CM_RGAM_RAMA_EXP_REGION14_NUM_SEGMENTS; \ 476 + type CM_RGAM_RAMA_EXP_REGION15_LUT_OFFSET; \ 477 + type CM_RGAM_RAMA_EXP_REGION15_NUM_SEGMENTS; \ 478 + type CM_RGAM_RAMA_EXP_REGION16_LUT_OFFSET; \ 479 + type CM_RGAM_RAMA_EXP_REGION16_NUM_SEGMENTS; \ 480 + type CM_RGAM_RAMA_EXP_REGION17_LUT_OFFSET; \ 481 + type CM_RGAM_RAMA_EXP_REGION17_NUM_SEGMENTS; \ 482 + type CM_RGAM_RAMA_EXP_REGION18_LUT_OFFSET; \ 483 + type CM_RGAM_RAMA_EXP_REGION18_NUM_SEGMENTS; \ 484 + type CM_RGAM_RAMA_EXP_REGION19_LUT_OFFSET; \ 485 + type CM_RGAM_RAMA_EXP_REGION19_NUM_SEGMENTS; \ 486 + type CM_RGAM_RAMA_EXP_REGION20_LUT_OFFSET; \ 487 + type CM_RGAM_RAMA_EXP_REGION20_NUM_SEGMENTS; \ 488 + type CM_RGAM_RAMA_EXP_REGION21_LUT_OFFSET; \ 489 + type CM_RGAM_RAMA_EXP_REGION21_NUM_SEGMENTS; \ 490 + type CM_RGAM_RAMA_EXP_REGION22_LUT_OFFSET; \ 491 + type CM_RGAM_RAMA_EXP_REGION22_NUM_SEGMENTS; \ 492 + type CM_RGAM_RAMA_EXP_REGION23_LUT_OFFSET; \ 493 + type CM_RGAM_RAMA_EXP_REGION23_NUM_SEGMENTS; \ 494 + type CM_RGAM_RAMA_EXP_REGION24_LUT_OFFSET; \ 495 + type CM_RGAM_RAMA_EXP_REGION24_NUM_SEGMENTS; \ 496 + type CM_RGAM_RAMA_EXP_REGION25_LUT_OFFSET; \ 497 + type CM_RGAM_RAMA_EXP_REGION25_NUM_SEGMENTS; \ 498 + type CM_RGAM_RAMA_EXP_REGION26_LUT_OFFSET; \ 499 + type CM_RGAM_RAMA_EXP_REGION26_NUM_SEGMENTS; \ 500 + type CM_RGAM_RAMA_EXP_REGION27_LUT_OFFSET; \ 501 + type CM_RGAM_RAMA_EXP_REGION27_NUM_SEGMENTS; \ 502 + type CM_RGAM_RAMA_EXP_REGION28_LUT_OFFSET; \ 503 + type CM_RGAM_RAMA_EXP_REGION28_NUM_SEGMENTS; \ 504 + type CM_RGAM_RAMA_EXP_REGION29_LUT_OFFSET; \ 505 + type CM_RGAM_RAMA_EXP_REGION29_NUM_SEGMENTS; \ 506 + type CM_RGAM_RAMA_EXP_REGION30_LUT_OFFSET; \ 507 + type CM_RGAM_RAMA_EXP_REGION30_NUM_SEGMENTS; \ 508 + type CM_RGAM_RAMA_EXP_REGION31_LUT_OFFSET; \ 509 + type CM_RGAM_RAMA_EXP_REGION31_NUM_SEGMENTS; \ 510 + type CM_RGAM_RAMA_EXP_REGION32_LUT_OFFSET; \ 511 + type CM_RGAM_RAMA_EXP_REGION32_NUM_SEGMENTS; \ 512 + type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \ 513 + type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \ 514 + type CM_RGAM_LUT_WRITE_EN_MASK; \ 515 + type CM_RGAM_LUT_WRITE_SEL; \ 516 + type CM_RGAM_LUT_INDEX; \ 517 + type RGAM_MEM_PWR_FORCE; \ 518 + type CM_RGAM_LUT_DATA; \ 519 + type FMT_STEREOSYNC_OVERRIDE 520 + 521 + struct dcn10_opp_shift { 522 + OPP_DCN10_REG_FIELD_LIST(uint8_t); 523 + }; 524 + 525 + struct dcn10_opp_mask { 526 + OPP_DCN10_REG_FIELD_LIST(uint32_t); 527 + }; 528 + 529 + struct dcn10_opp_registers { 530 + uint32_t CM_RGAM_LUT_WRITE_EN_MASK; 531 + uint32_t CM_RGAM_CONTROL; 532 + uint32_t OBUF_CONTROL; 533 + uint32_t FMT_BIT_DEPTH_CONTROL; 534 + uint32_t FMT_CONTROL; 535 + uint32_t FMT_DITHER_RAND_R_SEED; 536 + uint32_t FMT_DITHER_RAND_G_SEED; 537 + uint32_t FMT_DITHER_RAND_B_SEED; 538 + uint32_t FMT_CLAMP_CNTL; 539 + uint32_t FMT_DYNAMIC_EXP_CNTL; 540 + uint32_t FMT_MAP420_MEMORY_CONTROL; 541 + uint32_t CM_OCSC_CONTROL; 542 + uint32_t CM_RGAM_RAMB_START_CNTL_B; 543 + uint32_t CM_RGAM_RAMB_START_CNTL_G; 544 + uint32_t CM_RGAM_RAMB_START_CNTL_R; 545 + uint32_t CM_RGAM_RAMB_SLOPE_CNTL_B; 546 + uint32_t CM_RGAM_RAMB_SLOPE_CNTL_G; 547 + uint32_t CM_RGAM_RAMB_SLOPE_CNTL_R; 548 + uint32_t CM_RGAM_RAMB_END_CNTL1_B; 549 + uint32_t CM_RGAM_RAMB_END_CNTL2_B; 550 + uint32_t CM_RGAM_RAMB_END_CNTL1_G; 551 + uint32_t CM_RGAM_RAMB_END_CNTL2_G; 552 + uint32_t CM_RGAM_RAMB_END_CNTL1_R; 553 + uint32_t CM_RGAM_RAMB_END_CNTL2_R; 554 + uint32_t CM_RGAM_RAMB_REGION_0_1; 555 + uint32_t CM_RGAM_RAMB_REGION_2_3; 556 + uint32_t CM_RGAM_RAMB_REGION_4_5; 557 + uint32_t CM_RGAM_RAMB_REGION_6_7; 558 + uint32_t CM_RGAM_RAMB_REGION_8_9; 559 + uint32_t CM_RGAM_RAMB_REGION_10_11; 560 + uint32_t CM_RGAM_RAMB_REGION_12_13; 561 + uint32_t CM_RGAM_RAMB_REGION_14_15; 562 + uint32_t CM_RGAM_RAMB_REGION_16_17; 563 + uint32_t CM_RGAM_RAMB_REGION_18_19; 564 + uint32_t CM_RGAM_RAMB_REGION_20_21; 565 + uint32_t CM_RGAM_RAMB_REGION_22_23; 566 + uint32_t CM_RGAM_RAMB_REGION_24_25; 567 + uint32_t CM_RGAM_RAMB_REGION_26_27; 568 + uint32_t CM_RGAM_RAMB_REGION_28_29; 569 + uint32_t CM_RGAM_RAMB_REGION_30_31; 570 + uint32_t CM_RGAM_RAMB_REGION_32_33; 571 + uint32_t CM_RGAM_RAMA_START_CNTL_B; 572 + uint32_t CM_RGAM_RAMA_START_CNTL_G; 573 + uint32_t CM_RGAM_RAMA_START_CNTL_R; 574 + uint32_t CM_RGAM_RAMA_SLOPE_CNTL_B; 575 + uint32_t CM_RGAM_RAMA_SLOPE_CNTL_G; 576 + uint32_t CM_RGAM_RAMA_SLOPE_CNTL_R; 577 + uint32_t CM_RGAM_RAMA_END_CNTL1_B; 578 + uint32_t CM_RGAM_RAMA_END_CNTL2_B; 579 + uint32_t CM_RGAM_RAMA_END_CNTL1_G; 580 + uint32_t CM_RGAM_RAMA_END_CNTL2_G; 581 + uint32_t CM_RGAM_RAMA_END_CNTL1_R; 582 + uint32_t CM_RGAM_RAMA_END_CNTL2_R; 583 + uint32_t CM_RGAM_RAMA_REGION_0_1; 584 + uint32_t CM_RGAM_RAMA_REGION_2_3; 585 + uint32_t CM_RGAM_RAMA_REGION_4_5; 586 + uint32_t CM_RGAM_RAMA_REGION_6_7; 587 + uint32_t CM_RGAM_RAMA_REGION_8_9; 588 + uint32_t CM_RGAM_RAMA_REGION_10_11; 589 + uint32_t CM_RGAM_RAMA_REGION_12_13; 590 + uint32_t CM_RGAM_RAMA_REGION_14_15; 591 + uint32_t CM_RGAM_RAMA_REGION_16_17; 592 + uint32_t CM_RGAM_RAMA_REGION_18_19; 593 + uint32_t CM_RGAM_RAMA_REGION_20_21; 594 + uint32_t CM_RGAM_RAMA_REGION_22_23; 595 + uint32_t CM_RGAM_RAMA_REGION_24_25; 596 + uint32_t CM_RGAM_RAMA_REGION_26_27; 597 + uint32_t CM_RGAM_RAMA_REGION_28_29; 598 + uint32_t CM_RGAM_RAMA_REGION_30_31; 599 + uint32_t CM_RGAM_RAMA_REGION_32_33; 600 + uint32_t CM_RGAM_LUT_INDEX; 601 + uint32_t CM_MEM_PWR_CTRL; 602 + uint32_t CM_RGAM_LUT_DATA; 603 + }; 604 + 605 + struct dcn10_opp { 606 + struct output_pixel_processor base; 607 + 608 + const struct dcn10_opp_registers *regs; 609 + const struct dcn10_opp_shift *opp_shift; 610 + const struct dcn10_opp_mask *opp_mask; 611 + 612 + bool is_write_to_ram_a_safe; 613 + }; 614 + 615 + void dcn10_opp_construct(struct dcn10_opp *oppn10, 616 + struct dc_context *ctx, 617 + uint32_t inst, 618 + const struct dcn10_opp_registers *regs, 619 + const struct dcn10_opp_shift *opp_shift, 620 + const struct dcn10_opp_mask *opp_mask); 621 + 622 + #endif
+1475
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
··· 1 + /* 2 + * Copyright 2016 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 "dm_services.h" 27 + #include "dc.h" 28 + 29 + #include "resource.h" 30 + #include "include/irq_service_interface.h" 31 + #include "dcn10/dcn10_resource.h" 32 + 33 + #include "dcn10/dcn10_ipp.h" 34 + #include "dcn10/dcn10_mpc.h" 35 + #include "irq/dcn10/irq_service_dcn10.h" 36 + #include "dcn10/dcn10_transform.h" 37 + #include "dcn10/dcn10_timing_generator.h" 38 + #include "dcn10/dcn10_hw_sequencer.h" 39 + #include "dce110/dce110_hw_sequencer.h" 40 + #include "dcn10/dcn10_opp.h" 41 + #include "dce/dce_link_encoder.h" 42 + #include "dce/dce_stream_encoder.h" 43 + #include "dce/dce_clocks.h" 44 + #include "dce/dce_clock_source.h" 45 + #include "dcn10/dcn10_mem_input.h" 46 + #include "dce/dce_audio.h" 47 + #include "dce/dce_hwseq.h" 48 + #include "../virtual/virtual_stream_encoder.h" 49 + #include "dce110/dce110_resource.h" 50 + 51 + #include "vega10/soc15ip.h" 52 + 53 + #include "raven1/DCN/dcn_1_0_offset.h" 54 + #include "raven1/DCN/dcn_1_0_sh_mask.h" 55 + 56 + #include "raven1/NBIO/nbio_7_0_offset.h" 57 + 58 + #include "raven1/MMHUB/mmhub_9_1_offset.h" 59 + #include "raven1/MMHUB/mmhub_9_1_sh_mask.h" 60 + 61 + #include "reg_helper.h" 62 + #include "dce/dce_abm.h" 63 + #include "dce/dce_dmcu.h" 64 + 65 + #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL 66 + #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f 67 + #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 68 + #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f 69 + #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 70 + #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f 71 + #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 72 + #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f 73 + #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 74 + #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f 75 + #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 76 + #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x260f 77 + #define mmDP5_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 78 + #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x270f 79 + #define mmDP6_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 80 + #endif 81 + 82 + 83 + enum dcn10_clk_src_array_id { 84 + DCN10_CLK_SRC_PLL0, 85 + DCN10_CLK_SRC_PLL1, 86 + DCN10_CLK_SRC_PLL2, 87 + DCN10_CLK_SRC_PLL3, 88 + DCN10_CLK_SRC_TOTAL 89 + }; 90 + 91 + /* begin ********************* 92 + * macros to expend register list macro defined in HW object header file */ 93 + 94 + /* DCN */ 95 + #define BASE_INNER(seg) \ 96 + DCE_BASE__INST0_SEG ## seg 97 + 98 + #define BASE(seg) \ 99 + BASE_INNER(seg) 100 + 101 + #define SR(reg_name)\ 102 + .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \ 103 + mm ## reg_name 104 + 105 + #define SRI(reg_name, block, id)\ 106 + .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 107 + mm ## block ## id ## _ ## reg_name 108 + 109 + 110 + #define SRII(reg_name, block, id)\ 111 + .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 112 + mm ## block ## id ## _ ## reg_name 113 + 114 + /* NBIO */ 115 + #define NBIO_BASE_INNER(seg) \ 116 + NBIF_BASE__INST0_SEG ## seg 117 + 118 + #define NBIO_BASE(seg) \ 119 + NBIO_BASE_INNER(seg) 120 + 121 + #define NBIO_SR(reg_name)\ 122 + .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \ 123 + mm ## reg_name 124 + 125 + /* GC */ 126 + #define GC_BASE_INNER(seg) \ 127 + GC_BASE__INST0_SEG ## seg 128 + 129 + #define GC_BASE(seg) \ 130 + GC_BASE_INNER(seg) 131 + 132 + #define GC_SR(reg_name)\ 133 + .reg_name = GC_BASE(mm ## reg_name ## _BASE_IDX) + \ 134 + mm ## reg_name 135 + 136 + /* macros to expend register list macro defined in HW object header file 137 + * end *********************/ 138 + 139 + static const struct dce_disp_clk_registers disp_clk_regs = { 140 + CLK_DCN10_REG_LIST() 141 + }; 142 + 143 + static const struct dce_disp_clk_shift disp_clk_shift = { 144 + CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) 145 + }; 146 + 147 + static const struct dce_disp_clk_mask disp_clk_mask = { 148 + CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) 149 + }; 150 + 151 + static const struct dce_dmcu_registers dmcu_regs = { 152 + DMCU_DCN10_REG_LIST() 153 + }; 154 + 155 + static const struct dce_dmcu_shift dmcu_shift = { 156 + DMCU_MASK_SH_LIST_DCN10(__SHIFT) 157 + }; 158 + 159 + static const struct dce_dmcu_mask dmcu_mask = { 160 + DMCU_MASK_SH_LIST_DCN10(_MASK) 161 + }; 162 + 163 + static const struct dce_abm_registers abm_regs = { 164 + ABM_DCN10_REG_LIST(0) 165 + }; 166 + 167 + static const struct dce_abm_shift abm_shift = { 168 + ABM_MASK_SH_LIST_DCN10(__SHIFT) 169 + }; 170 + 171 + static const struct dce_abm_mask abm_mask = { 172 + ABM_MASK_SH_LIST_DCN10(_MASK) 173 + }; 174 + 175 + #define stream_enc_regs(id)\ 176 + [id] = {\ 177 + SE_DCN_REG_LIST(id),\ 178 + .TMDS_CNTL = 0,\ 179 + .AFMT_AVI_INFO0 = 0,\ 180 + .AFMT_AVI_INFO1 = 0,\ 181 + .AFMT_AVI_INFO2 = 0,\ 182 + .AFMT_AVI_INFO3 = 0,\ 183 + } 184 + 185 + static const struct dce110_stream_enc_registers stream_enc_regs[] = { 186 + stream_enc_regs(0), 187 + stream_enc_regs(1), 188 + stream_enc_regs(2), 189 + stream_enc_regs(3), 190 + }; 191 + 192 + static const struct dce_stream_encoder_shift se_shift = { 193 + SE_COMMON_MASK_SH_LIST_DCN10(__SHIFT) 194 + }; 195 + 196 + static const struct dce_stream_encoder_mask se_mask = { 197 + SE_COMMON_MASK_SH_LIST_DCN10(_MASK), 198 + .AFMT_GENERIC0_UPDATE = 0, 199 + .AFMT_GENERIC2_UPDATE = 0, 200 + .DP_DYN_RANGE = 0, 201 + .DP_YCBCR_RANGE = 0, 202 + .HDMI_AVI_INFO_SEND = 0, 203 + .HDMI_AVI_INFO_CONT = 0, 204 + .HDMI_AVI_INFO_LINE = 0, 205 + .DP_SEC_AVI_ENABLE = 0, 206 + .AFMT_AVI_INFO_VERSION = 0 207 + }; 208 + 209 + #define audio_regs(id)\ 210 + [id] = {\ 211 + AUD_COMMON_REG_LIST(id)\ 212 + } 213 + 214 + static const struct dce_audio_registers audio_regs[] = { 215 + audio_regs(0), 216 + audio_regs(1), 217 + audio_regs(2), 218 + audio_regs(3), 219 + }; 220 + 221 + #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ 222 + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ 223 + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\ 224 + AUD_COMMON_MASK_SH_LIST_BASE(mask_sh) 225 + 226 + static const struct dce_audio_shift audio_shift = { 227 + DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT) 228 + }; 229 + 230 + static const struct dce_aduio_mask audio_mask = { 231 + DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) 232 + }; 233 + 234 + #define aux_regs(id)\ 235 + [id] = {\ 236 + AUX_REG_LIST(id)\ 237 + } 238 + 239 + static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = { 240 + aux_regs(0), 241 + aux_regs(1), 242 + aux_regs(2), 243 + aux_regs(3), 244 + aux_regs(4), 245 + aux_regs(5) 246 + }; 247 + 248 + #define hpd_regs(id)\ 249 + [id] = {\ 250 + HPD_REG_LIST(id)\ 251 + } 252 + 253 + static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = { 254 + hpd_regs(0), 255 + hpd_regs(1), 256 + hpd_regs(2), 257 + hpd_regs(3), 258 + hpd_regs(4), 259 + hpd_regs(5) 260 + }; 261 + 262 + #define link_regs(id)\ 263 + [id] = {\ 264 + LE_DCN10_REG_LIST(id), \ 265 + SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ 266 + } 267 + 268 + static const struct dce110_link_enc_registers link_enc_regs[] = { 269 + link_regs(0), 270 + link_regs(1), 271 + link_regs(2), 272 + link_regs(3), 273 + link_regs(4), 274 + link_regs(5), 275 + link_regs(6), 276 + }; 277 + 278 + #define ipp_regs(id)\ 279 + [id] = {\ 280 + IPP_DCN10_REG_LIST(id),\ 281 + } 282 + 283 + static const struct dcn10_ipp_registers ipp_regs[] = { 284 + ipp_regs(0), 285 + ipp_regs(1), 286 + ipp_regs(2), 287 + ipp_regs(3), 288 + }; 289 + 290 + static const struct dcn10_ipp_shift ipp_shift = { 291 + IPP_DCN10_MASK_SH_LIST(__SHIFT) 292 + }; 293 + 294 + static const struct dcn10_ipp_mask ipp_mask = { 295 + IPP_DCN10_MASK_SH_LIST(_MASK), 296 + }; 297 + 298 + #define opp_regs(id)\ 299 + [id] = {\ 300 + OPP_DCN10_REG_LIST(id),\ 301 + } 302 + 303 + static const struct dcn10_opp_registers opp_regs[] = { 304 + opp_regs(0), 305 + opp_regs(1), 306 + opp_regs(2), 307 + opp_regs(3), 308 + }; 309 + 310 + static const struct dcn10_opp_shift opp_shift = { 311 + OPP_DCN10_MASK_SH_LIST(__SHIFT) 312 + }; 313 + 314 + static const struct dcn10_opp_mask opp_mask = { 315 + OPP_DCN10_MASK_SH_LIST(_MASK), 316 + }; 317 + 318 + #define tf_regs(id)\ 319 + [id] = {\ 320 + TF_REG_LIST_DCN(id),\ 321 + } 322 + 323 + static const struct dcn_transform_registers tf_regs[] = { 324 + tf_regs(0), 325 + tf_regs(1), 326 + tf_regs(2), 327 + tf_regs(3), 328 + }; 329 + 330 + static const struct dcn_transform_shift tf_shift = { 331 + TF_REG_LIST_SH_MASK_DCN(__SHIFT) 332 + }; 333 + 334 + static const struct dcn_transform_mask tf_mask = { 335 + TF_REG_LIST_SH_MASK_DCN(_MASK), 336 + }; 337 + 338 + 339 + static const struct dcn_mpc_registers mpc_regs = { 340 + MPC_COMMON_REG_LIST_DCN1_0(0), 341 + MPC_COMMON_REG_LIST_DCN1_0(1), 342 + MPC_COMMON_REG_LIST_DCN1_0(2), 343 + MPC_COMMON_REG_LIST_DCN1_0(3), 344 + }; 345 + 346 + static const struct dcn_mpc_shift mpc_shift = { 347 + MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) 348 + }; 349 + 350 + static const struct dcn_mpc_mask mpc_mask = { 351 + MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK), 352 + }; 353 + 354 + #define tg_regs(id)\ 355 + [id] = {TG_COMMON_REG_LIST_DCN1_0(id)} 356 + 357 + static const struct dcn_tg_registers tg_regs[] = { 358 + tg_regs(0), 359 + tg_regs(1), 360 + tg_regs(2), 361 + tg_regs(3), 362 + }; 363 + 364 + static const struct dcn_tg_shift tg_shift = { 365 + TG_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) 366 + }; 367 + 368 + static const struct dcn_tg_mask tg_mask = { 369 + TG_COMMON_MASK_SH_LIST_DCN1_0(_MASK) 370 + }; 371 + 372 + 373 + static const struct bios_registers bios_regs = { 374 + NBIO_SR(BIOS_SCRATCH_6) 375 + }; 376 + 377 + #define mi_regs(id)\ 378 + [id] = {\ 379 + MI_DCN10_REG_LIST(id)\ 380 + } 381 + 382 + 383 + static const struct dcn_mi_registers mi_regs[] = { 384 + mi_regs(0), 385 + mi_regs(1), 386 + mi_regs(2), 387 + mi_regs(3), 388 + }; 389 + 390 + static const struct dcn_mi_shift mi_shift = { 391 + MI_DCN10_MASK_SH_LIST(__SHIFT) 392 + }; 393 + 394 + static const struct dcn_mi_mask mi_mask = { 395 + MI_DCN10_MASK_SH_LIST(_MASK) 396 + }; 397 + 398 + #define clk_src_regs(index, pllid)\ 399 + [index] = {\ 400 + CS_COMMON_REG_LIST_DCN1_0(index, pllid),\ 401 + } 402 + 403 + static const struct dce110_clk_src_regs clk_src_regs[] = { 404 + clk_src_regs(0, A), 405 + clk_src_regs(1, B), 406 + clk_src_regs(2, C), 407 + clk_src_regs(3, D) 408 + }; 409 + 410 + static const struct dce110_clk_src_shift cs_shift = { 411 + CS_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) 412 + }; 413 + 414 + static const struct dce110_clk_src_mask cs_mask = { 415 + CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK) 416 + }; 417 + 418 + 419 + static const struct resource_caps res_cap = { 420 + .num_timing_generator = 4, 421 + .num_video_plane = 4, 422 + .num_audio = 4, 423 + .num_stream_encoder = 4, 424 + .num_pll = 4, 425 + }; 426 + 427 + static const struct dc_debug debug_defaults_drv = { 428 + .disable_dcc = false, 429 + .disable_dpp_power_gate = false, 430 + .disable_hubp_power_gate = false, 431 + .disable_dmcu = true, 432 + .force_abm_enable = false, 433 + .timing_trace = false, 434 + .disable_pplib_clock_request = true, 435 + .disable_pplib_wm_range = true, 436 + #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 437 + .use_dml_wm = false, 438 + .use_max_voltage = true 439 + #endif 440 + }; 441 + 442 + static const struct dc_debug debug_defaults_diags = { 443 + .disable_dpp_power_gate = false, 444 + .disable_hubp_power_gate = false, 445 + .disable_clock_gate = true, 446 + .disable_dmcu = true, 447 + .force_abm_enable = false, 448 + .timing_trace = true, 449 + #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 450 + .disable_pplib_clock_request = true, 451 + .disable_pplib_wm_range = true, 452 + .use_dml_wm = false, 453 + .use_max_voltage = false 454 + #endif 455 + }; 456 + 457 + static void dcn10_transform_destroy(struct transform **xfm) 458 + { 459 + dm_free(TO_DCN10_TRANSFORM(*xfm)); 460 + *xfm = NULL; 461 + } 462 + 463 + static struct transform *dcn10_transform_create( 464 + struct dc_context *ctx, 465 + uint32_t inst) 466 + { 467 + struct dcn10_transform *transform = 468 + dm_alloc(sizeof(struct dcn10_transform)); 469 + 470 + if (!transform) 471 + return NULL; 472 + 473 + if (dcn10_transform_construct(transform, ctx, 474 + &tf_regs[inst], &tf_shift, &tf_mask)) 475 + return &transform->base; 476 + 477 + BREAK_TO_DEBUGGER(); 478 + dm_free(transform); 479 + return NULL; 480 + } 481 + 482 + static struct input_pixel_processor *dcn10_ipp_create( 483 + struct dc_context *ctx, uint32_t inst) 484 + { 485 + struct dcn10_ipp *ipp = 486 + dm_alloc(sizeof(struct dcn10_ipp)); 487 + 488 + if (!ipp) { 489 + BREAK_TO_DEBUGGER(); 490 + return NULL; 491 + } 492 + 493 + dcn10_ipp_construct(ipp, ctx, inst, 494 + &ipp_regs[inst], &ipp_shift, &ipp_mask); 495 + return &ipp->base; 496 + } 497 + 498 + 499 + static struct output_pixel_processor *dcn10_opp_create( 500 + struct dc_context *ctx, uint32_t inst) 501 + { 502 + struct dcn10_opp *opp = 503 + dm_alloc(sizeof(struct dcn10_opp)); 504 + 505 + if (!opp) { 506 + BREAK_TO_DEBUGGER(); 507 + return NULL; 508 + } 509 + 510 + dcn10_opp_construct(opp, ctx, inst, 511 + &opp_regs[inst], &opp_shift, &opp_mask); 512 + return &opp->base; 513 + } 514 + 515 + static struct mpc *dcn10_mpc_create( 516 + struct dc_context *ctx) 517 + { 518 + struct dcn10_mpc *mpc = dm_alloc(sizeof(struct dcn10_mpc)); 519 + 520 + if (!mpc) 521 + return NULL; 522 + 523 + mpc->base.ctx = ctx; 524 + mpc->mpc_regs = &mpc_regs; 525 + mpc->mpc_shift = &mpc_shift; 526 + mpc->mpc_mask = &mpc_mask; 527 + 528 + return &mpc->base; 529 + } 530 + 531 + static void dcn10_mpc_destroy(struct mpc **mpc_base) 532 + { 533 + if (*mpc_base) 534 + dm_free(TO_DCN10_MPC(*mpc_base)); 535 + 536 + *mpc_base = NULL; 537 + } 538 + 539 + static struct timing_generator *dcn10_timing_generator_create( 540 + struct dc_context *ctx, 541 + uint32_t instance) 542 + { 543 + struct dcn10_timing_generator *tgn10 = 544 + dm_alloc(sizeof(struct dcn10_timing_generator)); 545 + 546 + if (!tgn10) 547 + return NULL; 548 + 549 + tgn10->base.inst = instance; 550 + tgn10->base.ctx = ctx; 551 + 552 + tgn10->tg_regs = &tg_regs[instance]; 553 + tgn10->tg_shift = &tg_shift; 554 + tgn10->tg_mask = &tg_mask; 555 + 556 + dcn10_timing_generator_init(tgn10); 557 + 558 + return &tgn10->base; 559 + } 560 + 561 + static const struct encoder_feature_support link_enc_feature = { 562 + .max_hdmi_deep_color = COLOR_DEPTH_121212, 563 + .max_hdmi_pixel_clock = 600000, 564 + .ycbcr420_supported = true, 565 + .flags.bits.IS_HBR2_CAPABLE = true, 566 + .flags.bits.IS_HBR3_CAPABLE = true, 567 + .flags.bits.IS_TPS3_CAPABLE = true, 568 + .flags.bits.IS_TPS4_CAPABLE = true, 569 + .flags.bits.IS_YCBCR_CAPABLE = true 570 + }; 571 + 572 + struct link_encoder *dcn10_link_encoder_create( 573 + const struct encoder_init_data *enc_init_data) 574 + { 575 + struct dce110_link_encoder *enc110 = 576 + dm_alloc(sizeof(struct dce110_link_encoder)); 577 + 578 + if (!enc110) 579 + return NULL; 580 + 581 + if (dce110_link_encoder_construct( 582 + enc110, 583 + enc_init_data, 584 + &link_enc_feature, 585 + &link_enc_regs[enc_init_data->transmitter], 586 + &link_enc_aux_regs[enc_init_data->channel - 1], 587 + &link_enc_hpd_regs[enc_init_data->hpd_source])) { 588 + 589 + return &enc110->base; 590 + } 591 + 592 + BREAK_TO_DEBUGGER(); 593 + dm_free(enc110); 594 + return NULL; 595 + } 596 + 597 + struct clock_source *dcn10_clock_source_create( 598 + struct dc_context *ctx, 599 + struct dc_bios *bios, 600 + enum clock_source_id id, 601 + const struct dce110_clk_src_regs *regs, 602 + bool dp_clk_src) 603 + { 604 + struct dce110_clk_src *clk_src = 605 + dm_alloc(sizeof(struct dce110_clk_src)); 606 + 607 + if (!clk_src) 608 + return NULL; 609 + 610 + if (dce110_clk_src_construct(clk_src, ctx, bios, id, 611 + regs, &cs_shift, &cs_mask)) { 612 + clk_src->base.dp_clk_src = dp_clk_src; 613 + return &clk_src->base; 614 + } 615 + 616 + BREAK_TO_DEBUGGER(); 617 + return NULL; 618 + } 619 + 620 + static void read_dce_straps( 621 + struct dc_context *ctx, 622 + struct resource_straps *straps) 623 + { 624 + /* TODO: Registers are missing */ 625 + /*REG_GET_2(CC_DC_HDMI_STRAPS, 626 + HDMI_DISABLE, &straps->hdmi_disable, 627 + AUDIO_STREAM_NUMBER, &straps->audio_stream_number); 628 + 629 + REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);*/ 630 + } 631 + 632 + static struct audio *create_audio( 633 + struct dc_context *ctx, unsigned int inst) 634 + { 635 + return dce_audio_create(ctx, inst, 636 + &audio_regs[inst], &audio_shift, &audio_mask); 637 + } 638 + 639 + static struct stream_encoder *dcn10_stream_encoder_create( 640 + enum engine_id eng_id, 641 + struct dc_context *ctx) 642 + { 643 + struct dce110_stream_encoder *enc110 = 644 + dm_alloc(sizeof(struct dce110_stream_encoder)); 645 + 646 + if (!enc110) 647 + return NULL; 648 + 649 + if (dce110_stream_encoder_construct( 650 + enc110, ctx, ctx->dc_bios, eng_id, 651 + &stream_enc_regs[eng_id], &se_shift, &se_mask)) 652 + return &enc110->base; 653 + 654 + BREAK_TO_DEBUGGER(); 655 + dm_free(enc110); 656 + return NULL; 657 + } 658 + 659 + static const struct dce_hwseq_registers hwseq_reg = { 660 + HWSEQ_DCN1_REG_LIST() 661 + }; 662 + 663 + static const struct dce_hwseq_shift hwseq_shift = { 664 + HWSEQ_DCN1_MASK_SH_LIST(__SHIFT) 665 + }; 666 + 667 + static const struct dce_hwseq_mask hwseq_mask = { 668 + HWSEQ_DCN1_MASK_SH_LIST(_MASK) 669 + }; 670 + 671 + static struct dce_hwseq *dcn10_hwseq_create( 672 + struct dc_context *ctx) 673 + { 674 + struct dce_hwseq *hws = dm_alloc(sizeof(struct dce_hwseq)); 675 + 676 + if (hws) { 677 + hws->ctx = ctx; 678 + hws->regs = &hwseq_reg; 679 + hws->shifts = &hwseq_shift; 680 + hws->masks = &hwseq_mask; 681 + } 682 + return hws; 683 + } 684 + 685 + static const struct resource_create_funcs res_create_funcs = { 686 + .read_dce_straps = read_dce_straps, 687 + .create_audio = create_audio, 688 + .create_stream_encoder = dcn10_stream_encoder_create, 689 + .create_hwseq = dcn10_hwseq_create, 690 + }; 691 + 692 + static const struct resource_create_funcs res_create_maximus_funcs = { 693 + .read_dce_straps = NULL, 694 + .create_audio = NULL, 695 + .create_stream_encoder = NULL, 696 + .create_hwseq = dcn10_hwseq_create, 697 + }; 698 + 699 + void dcn10_clock_source_destroy(struct clock_source **clk_src) 700 + { 701 + dm_free(TO_DCE110_CLK_SRC(*clk_src)); 702 + *clk_src = NULL; 703 + } 704 + 705 + static void destruct(struct dcn10_resource_pool *pool) 706 + { 707 + unsigned int i; 708 + 709 + for (i = 0; i < pool->base.stream_enc_count; i++) { 710 + if (pool->base.stream_enc[i] != NULL) { 711 + /* TODO: free dcn version of stream encoder once implemented 712 + * rather than using virtual stream encoder 713 + */ 714 + dm_free(pool->base.stream_enc[i]); 715 + pool->base.stream_enc[i] = NULL; 716 + } 717 + } 718 + 719 + for (i = 0; i < pool->base.pipe_count; i++) { 720 + if (pool->base.opps[i] != NULL) 721 + pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]); 722 + 723 + if (pool->base.transforms[i] != NULL) 724 + dcn10_transform_destroy(&pool->base.transforms[i]); 725 + 726 + if (pool->base.ipps[i] != NULL) 727 + pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); 728 + 729 + if (pool->base.mis[i] != NULL) { 730 + dm_free(TO_DCN10_MEM_INPUT(pool->base.mis[i])); 731 + pool->base.mis[i] = NULL; 732 + } 733 + 734 + if (pool->base.irqs != NULL) { 735 + dal_irq_service_destroy(&pool->base.irqs); 736 + } 737 + 738 + if (pool->base.timing_generators[i] != NULL) { 739 + dm_free(DCN10TG_FROM_TG(pool->base.timing_generators[i])); 740 + pool->base.timing_generators[i] = NULL; 741 + } 742 + } 743 + 744 + for (i = 0; i < pool->base.stream_enc_count; i++) { 745 + if (pool->base.stream_enc[i] != NULL) 746 + dm_free(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i])); 747 + } 748 + 749 + for (i = 0; i < pool->base.audio_count; i++) { 750 + if (pool->base.audios[i]) 751 + dce_aud_destroy(&pool->base.audios[i]); 752 + } 753 + 754 + for (i = 0; i < pool->base.clk_src_count; i++) { 755 + if (pool->base.clock_sources[i] != NULL) { 756 + dcn10_clock_source_destroy(&pool->base.clock_sources[i]); 757 + pool->base.clock_sources[i] = NULL; 758 + } 759 + } 760 + 761 + if (pool->base.dp_clock_source != NULL) { 762 + dcn10_clock_source_destroy(&pool->base.dp_clock_source); 763 + pool->base.dp_clock_source = NULL; 764 + } 765 + 766 + if (pool->base.mpc != NULL) 767 + dcn10_mpc_destroy(&pool->base.mpc); 768 + 769 + if (pool->base.abm != NULL) 770 + dce_abm_destroy(&pool->base.abm); 771 + 772 + if (pool->base.dmcu != NULL) 773 + dce_dmcu_destroy(&pool->base.dmcu); 774 + 775 + if (pool->base.display_clock != NULL) 776 + dce_disp_clk_destroy(&pool->base.display_clock); 777 + } 778 + 779 + static struct mem_input *dcn10_mem_input_create( 780 + struct dc_context *ctx, 781 + uint32_t inst) 782 + { 783 + struct dcn10_mem_input *mem_inputn10 = 784 + dm_alloc(sizeof(struct dcn10_mem_input)); 785 + 786 + if (!mem_inputn10) 787 + return NULL; 788 + 789 + if (dcn10_mem_input_construct(mem_inputn10, ctx, inst, 790 + &mi_regs[inst], &mi_shift, &mi_mask)) 791 + return &mem_inputn10->base; 792 + 793 + BREAK_TO_DEBUGGER(); 794 + dm_free(mem_inputn10); 795 + return NULL; 796 + } 797 + 798 + static void get_pixel_clock_parameters( 799 + const struct pipe_ctx *pipe_ctx, 800 + struct pixel_clk_params *pixel_clk_params) 801 + { 802 + const struct core_stream *stream = pipe_ctx->stream; 803 + pixel_clk_params->requested_pix_clk = stream->public.timing.pix_clk_khz; 804 + pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id; 805 + pixel_clk_params->signal_type = pipe_ctx->stream->signal; 806 + pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1; 807 + /* TODO: un-hardcode*/ 808 + pixel_clk_params->requested_sym_clk = LINK_RATE_LOW * 809 + LINK_RATE_REF_FREQ_IN_KHZ; 810 + pixel_clk_params->flags.ENABLE_SS = 0; 811 + pixel_clk_params->color_depth = 812 + stream->public.timing.display_color_depth; 813 + pixel_clk_params->flags.DISPLAY_BLANKED = 1; 814 + pixel_clk_params->pixel_encoding = stream->public.timing.pixel_encoding; 815 + 816 + if (stream->public.timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) 817 + pixel_clk_params->color_depth = COLOR_DEPTH_888; 818 + 819 + if (stream->public.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) 820 + pixel_clk_params->requested_pix_clk /= 2; 821 + 822 + if (stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING || 823 + stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_SW_FRAME_PACKING || 824 + stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA) 825 + pixel_clk_params->requested_pix_clk *= 2; 826 + } 827 + 828 + static void build_clamping_params(struct core_stream *stream) 829 + { 830 + stream->clamping.clamping_level = CLAMPING_FULL_RANGE; 831 + stream->clamping.c_depth = stream->public.timing.display_color_depth; 832 + stream->clamping.pixel_encoding = stream->public.timing.pixel_encoding; 833 + } 834 + 835 + static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx) 836 + { 837 + 838 + get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->pix_clk_params); 839 + 840 + pipe_ctx->clock_source->funcs->get_pix_clk_dividers( 841 + pipe_ctx->clock_source, 842 + &pipe_ctx->pix_clk_params, 843 + &pipe_ctx->pll_settings); 844 + 845 + pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->public.timing.pixel_encoding; 846 + 847 + resource_build_bit_depth_reduction_params(pipe_ctx->stream, 848 + &pipe_ctx->stream->bit_depth_params); 849 + build_clamping_params(pipe_ctx->stream); 850 + 851 + return DC_OK; 852 + } 853 + 854 + static enum dc_status validate_mapped_resource( 855 + const struct core_dc *dc, 856 + struct validate_context *context) 857 + { 858 + enum dc_status status = DC_OK; 859 + uint8_t i, j; 860 + 861 + for (i = 0; i < context->stream_count; i++) { 862 + struct core_stream *stream = context->streams[i]; 863 + struct core_link *link = stream->sink->link; 864 + 865 + if (resource_is_stream_unchanged(dc->current_context, stream)) { 866 + if (stream != NULL && dc->current_context->streams[i] != NULL) { 867 + /* todo: shouldn't have to copy missing parameter here */ 868 + resource_build_bit_depth_reduction_params(stream, 869 + &stream->bit_depth_params); 870 + stream->clamping.pixel_encoding = 871 + stream->public.timing.pixel_encoding; 872 + 873 + resource_build_bit_depth_reduction_params(stream, 874 + &stream->bit_depth_params); 875 + build_clamping_params(stream); 876 + 877 + continue; 878 + } 879 + } 880 + 881 + for (j = 0; j < dc->res_pool->pipe_count ; j++) { 882 + struct pipe_ctx *pipe_ctx = 883 + &context->res_ctx.pipe_ctx[j]; 884 + 885 + if (context->res_ctx.pipe_ctx[j].stream != stream) 886 + continue; 887 + 888 + 889 + if (!pipe_ctx->tg->funcs->validate_timing( 890 + pipe_ctx->tg, &stream->public.timing)) 891 + return DC_FAIL_CONTROLLER_VALIDATE; 892 + 893 + status = build_pipe_hw_param(pipe_ctx); 894 + 895 + if (status != DC_OK) 896 + return status; 897 + 898 + if (!link->link_enc->funcs->validate_output_with_stream( 899 + link->link_enc, pipe_ctx)) 900 + return DC_FAIL_ENC_VALIDATE; 901 + 902 + /* TODO: validate audio ASIC caps, encoder */ 903 + 904 + status = dc_link_validate_mode_timing( 905 + stream, link, &stream->public.timing); 906 + 907 + if (status != DC_OK) 908 + return status; 909 + 910 + 911 + /* do not need to validate non root pipes */ 912 + break; 913 + } 914 + } 915 + 916 + return DC_OK; 917 + } 918 + 919 + enum dc_status dcn10_validate_with_context( 920 + const struct core_dc *dc, 921 + const struct dc_validation_set set[], 922 + int set_count, 923 + struct validate_context *context) 924 + { 925 + enum dc_status result = DC_OK; 926 + int i; 927 + 928 + if (set_count == 0) 929 + return result; 930 + 931 + for (i = 0; i < set_count; i++) { 932 + context->streams[i] = DC_STREAM_TO_CORE(set[i].stream); 933 + dc_stream_retain(&context->streams[i]->public); 934 + context->stream_count++; 935 + } 936 + 937 + result = resource_map_pool_resources(dc, context); 938 + if (result != DC_OK) 939 + return result; 940 + 941 + result = resource_map_phy_clock_resources(dc, context); 942 + if (result != DC_OK) 943 + return result; 944 + 945 + result = validate_mapped_resource(dc, context); 946 + if (result != DC_OK) 947 + return result; 948 + 949 + if (!resource_validate_attach_surfaces(set, set_count, 950 + dc->current_context, context, dc->res_pool)) 951 + return DC_FAIL_ATTACH_SURFACES; 952 + 953 + result = resource_build_scaling_params_for_context(dc, context); 954 + if (result != DC_OK) 955 + return result; 956 + 957 + if (!dcn_validate_bandwidth(dc, context)) 958 + return DC_FAIL_BANDWIDTH_VALIDATE; 959 + 960 + return result; 961 + } 962 + 963 + enum dc_status dcn10_validate_guaranteed( 964 + const struct core_dc *dc, 965 + const struct dc_stream *dc_stream, 966 + struct validate_context *context) 967 + { 968 + enum dc_status result = DC_ERROR_UNEXPECTED; 969 + 970 + context->streams[0] = DC_STREAM_TO_CORE(dc_stream); 971 + dc_stream_retain(&context->streams[0]->public); 972 + context->stream_count++; 973 + 974 + result = resource_map_pool_resources(dc, context); 975 + 976 + if (result == DC_OK) 977 + result = resource_map_phy_clock_resources(dc, context); 978 + 979 + if (result == DC_OK) 980 + result = validate_mapped_resource(dc, context); 981 + 982 + if (result == DC_OK) { 983 + validate_guaranteed_copy_streams( 984 + context, dc->public.caps.max_streams); 985 + result = resource_build_scaling_params_for_context(dc, context); 986 + } 987 + if (result == DC_OK && !dcn_validate_bandwidth(dc, context)) 988 + return DC_FAIL_BANDWIDTH_VALIDATE; 989 + 990 + return result; 991 + } 992 + 993 + static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer( 994 + struct validate_context *context, 995 + const struct resource_pool *pool, 996 + struct core_stream *stream) 997 + { 998 + struct resource_context *res_ctx = &context->res_ctx; 999 + struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream); 1000 + struct pipe_ctx *idle_pipe = find_idle_secondary_pipe(res_ctx, pool); 1001 + 1002 + if (!head_pipe) 1003 + ASSERT(0); 1004 + 1005 + if (!idle_pipe) 1006 + return false; 1007 + 1008 + idle_pipe->stream = head_pipe->stream; 1009 + idle_pipe->tg = head_pipe->tg; 1010 + 1011 + idle_pipe->mi = pool->mis[idle_pipe->pipe_idx]; 1012 + idle_pipe->ipp = pool->ipps[idle_pipe->pipe_idx]; 1013 + idle_pipe->xfm = pool->transforms[idle_pipe->pipe_idx]; 1014 + idle_pipe->opp = pool->opps[idle_pipe->pipe_idx]; 1015 + 1016 + return idle_pipe; 1017 + } 1018 + 1019 + enum dcc_control { 1020 + dcc_control__256_256_xxx, 1021 + dcc_control__128_128_xxx, 1022 + dcc_control__256_64_64, 1023 + }; 1024 + 1025 + enum segment_order { 1026 + segment_order__na, 1027 + segment_order__contiguous, 1028 + segment_order__non_contiguous, 1029 + }; 1030 + 1031 + static bool dcc_support_pixel_format( 1032 + enum surface_pixel_format format, 1033 + unsigned int *bytes_per_element) 1034 + { 1035 + /* DML: get_bytes_per_element */ 1036 + switch (format) { 1037 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 1038 + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 1039 + *bytes_per_element = 2; 1040 + return true; 1041 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 1042 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 1043 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 1044 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 1045 + *bytes_per_element = 4; 1046 + return true; 1047 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 1048 + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 1049 + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 1050 + *bytes_per_element = 8; 1051 + return true; 1052 + default: 1053 + return false; 1054 + } 1055 + } 1056 + 1057 + static bool dcc_support_swizzle( 1058 + enum swizzle_mode_values swizzle, 1059 + unsigned int bytes_per_element, 1060 + enum segment_order *segment_order_horz, 1061 + enum segment_order *segment_order_vert) 1062 + { 1063 + bool standard_swizzle = false; 1064 + bool display_swizzle = false; 1065 + 1066 + switch (swizzle) { 1067 + case DC_SW_4KB_S: 1068 + case DC_SW_64KB_S: 1069 + case DC_SW_VAR_S: 1070 + case DC_SW_4KB_S_X: 1071 + case DC_SW_64KB_S_X: 1072 + case DC_SW_VAR_S_X: 1073 + standard_swizzle = true; 1074 + break; 1075 + case DC_SW_4KB_D: 1076 + case DC_SW_64KB_D: 1077 + case DC_SW_VAR_D: 1078 + case DC_SW_4KB_D_X: 1079 + case DC_SW_64KB_D_X: 1080 + case DC_SW_VAR_D_X: 1081 + display_swizzle = true; 1082 + break; 1083 + default: 1084 + break; 1085 + }; 1086 + 1087 + if (bytes_per_element == 1 && standard_swizzle) { 1088 + *segment_order_horz = segment_order__contiguous; 1089 + *segment_order_vert = segment_order__na; 1090 + return true; 1091 + } 1092 + if (bytes_per_element == 2 && standard_swizzle) { 1093 + *segment_order_horz = segment_order__non_contiguous; 1094 + *segment_order_vert = segment_order__contiguous; 1095 + return true; 1096 + } 1097 + if (bytes_per_element == 4 && standard_swizzle) { 1098 + *segment_order_horz = segment_order__non_contiguous; 1099 + *segment_order_vert = segment_order__contiguous; 1100 + return true; 1101 + } 1102 + if (bytes_per_element == 8 && standard_swizzle) { 1103 + *segment_order_horz = segment_order__na; 1104 + *segment_order_vert = segment_order__contiguous; 1105 + return true; 1106 + } 1107 + if (bytes_per_element == 8 && display_swizzle) { 1108 + *segment_order_horz = segment_order__contiguous; 1109 + *segment_order_vert = segment_order__non_contiguous; 1110 + return true; 1111 + } 1112 + 1113 + return false; 1114 + } 1115 + 1116 + static void get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height, 1117 + unsigned int bytes_per_element) 1118 + { 1119 + /* copied from DML. might want to refactor DML to leverage from DML */ 1120 + /* DML : get_blk256_size */ 1121 + if (bytes_per_element == 1) { 1122 + *blk256_width = 16; 1123 + *blk256_height = 16; 1124 + } else if (bytes_per_element == 2) { 1125 + *blk256_width = 16; 1126 + *blk256_height = 8; 1127 + } else if (bytes_per_element == 4) { 1128 + *blk256_width = 8; 1129 + *blk256_height = 8; 1130 + } else if (bytes_per_element == 8) { 1131 + *blk256_width = 8; 1132 + *blk256_height = 4; 1133 + } 1134 + } 1135 + 1136 + static void det_request_size( 1137 + unsigned int height, 1138 + unsigned int width, 1139 + unsigned int bpe, 1140 + bool *req128_horz_wc, 1141 + bool *req128_vert_wc) 1142 + { 1143 + unsigned int detile_buf_size = 164 * 1024; /* 164KB for DCN1.0 */ 1144 + 1145 + unsigned int blk256_height = 0; 1146 + unsigned int blk256_width = 0; 1147 + unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc; 1148 + 1149 + get_blk256_size(&blk256_width, &blk256_height, bpe); 1150 + 1151 + swath_bytes_horz_wc = height * blk256_height * bpe; 1152 + swath_bytes_vert_wc = width * blk256_width * bpe; 1153 + 1154 + *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ? 1155 + false : /* full 256B request */ 1156 + true; /* half 128b request */ 1157 + 1158 + *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ? 1159 + false : /* full 256B request */ 1160 + true; /* half 128b request */ 1161 + } 1162 + 1163 + static bool get_dcc_compression_cap(const struct dc *dc, 1164 + const struct dc_dcc_surface_param *input, 1165 + struct dc_surface_dcc_cap *output) 1166 + { 1167 + /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */ 1168 + enum dcc_control dcc_control; 1169 + unsigned int bpe; 1170 + enum segment_order segment_order_horz, segment_order_vert; 1171 + bool req128_horz_wc, req128_vert_wc; 1172 + 1173 + memset(output, 0, sizeof(*output)); 1174 + 1175 + if (dc->debug.disable_dcc) 1176 + return false; 1177 + 1178 + if (!dcc_support_pixel_format(input->format, 1179 + &bpe)) 1180 + return false; 1181 + 1182 + if (!dcc_support_swizzle(input->swizzle_mode, bpe, 1183 + &segment_order_horz, &segment_order_vert)) 1184 + return false; 1185 + 1186 + det_request_size(input->surface_size.height, input->surface_size.width, 1187 + bpe, &req128_horz_wc, &req128_vert_wc); 1188 + 1189 + if (!req128_horz_wc && !req128_vert_wc) { 1190 + dcc_control = dcc_control__256_256_xxx; 1191 + } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) { 1192 + if (!req128_horz_wc) 1193 + dcc_control = dcc_control__256_256_xxx; 1194 + else if (segment_order_horz == segment_order__contiguous) 1195 + dcc_control = dcc_control__128_128_xxx; 1196 + else 1197 + dcc_control = dcc_control__256_64_64; 1198 + } else if (input->scan == SCAN_DIRECTION_VERTICAL) { 1199 + if (!req128_vert_wc) 1200 + dcc_control = dcc_control__256_256_xxx; 1201 + else if (segment_order_vert == segment_order__contiguous) 1202 + dcc_control = dcc_control__128_128_xxx; 1203 + else 1204 + dcc_control = dcc_control__256_64_64; 1205 + } else { 1206 + if ((req128_horz_wc && 1207 + segment_order_horz == segment_order__non_contiguous) || 1208 + (req128_vert_wc && 1209 + segment_order_vert == segment_order__non_contiguous)) 1210 + /* access_dir not known, must use most constraining */ 1211 + dcc_control = dcc_control__256_64_64; 1212 + else 1213 + /* reg128 is true for either horz and vert 1214 + * but segment_order is contiguous 1215 + */ 1216 + dcc_control = dcc_control__128_128_xxx; 1217 + } 1218 + 1219 + switch (dcc_control) { 1220 + case dcc_control__256_256_xxx: 1221 + output->grph.rgb.max_uncompressed_blk_size = 256; 1222 + output->grph.rgb.max_compressed_blk_size = 256; 1223 + output->grph.rgb.independent_64b_blks = false; 1224 + break; 1225 + case dcc_control__128_128_xxx: 1226 + output->grph.rgb.max_uncompressed_blk_size = 128; 1227 + output->grph.rgb.max_compressed_blk_size = 128; 1228 + output->grph.rgb.independent_64b_blks = false; 1229 + break; 1230 + case dcc_control__256_64_64: 1231 + output->grph.rgb.max_uncompressed_blk_size = 256; 1232 + output->grph.rgb.max_compressed_blk_size = 64; 1233 + output->grph.rgb.independent_64b_blks = true; 1234 + break; 1235 + } 1236 + output->capable = true; 1237 + output->const_color_support = false; 1238 + 1239 + return true; 1240 + } 1241 + 1242 + 1243 + static void dcn10_destroy_resource_pool(struct resource_pool **pool) 1244 + { 1245 + struct dcn10_resource_pool *dcn10_pool = TO_DCN10_RES_POOL(*pool); 1246 + 1247 + destruct(dcn10_pool); 1248 + dm_free(dcn10_pool); 1249 + *pool = NULL; 1250 + } 1251 + 1252 + 1253 + static struct dc_cap_funcs cap_funcs = { 1254 + .get_dcc_compression_cap = get_dcc_compression_cap 1255 + }; 1256 + 1257 + static struct resource_funcs dcn10_res_pool_funcs = { 1258 + .destroy = dcn10_destroy_resource_pool, 1259 + .link_enc_create = dcn10_link_encoder_create, 1260 + .validate_with_context = dcn10_validate_with_context, 1261 + .validate_guaranteed = dcn10_validate_guaranteed, 1262 + .validate_bandwidth = dcn_validate_bandwidth, 1263 + .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer, 1264 + }; 1265 + 1266 + static bool construct( 1267 + uint8_t num_virtual_links, 1268 + struct core_dc *dc, 1269 + struct dcn10_resource_pool *pool) 1270 + { 1271 + int i; 1272 + struct dc_context *ctx = dc->ctx; 1273 + 1274 + ctx->dc_bios->regs = &bios_regs; 1275 + 1276 + pool->base.res_cap = &res_cap; 1277 + pool->base.funcs = &dcn10_res_pool_funcs; 1278 + 1279 + /* 1280 + * TODO fill in from actual raven resource when we create 1281 + * more than virtual encoder 1282 + */ 1283 + 1284 + /************************************************* 1285 + * Resource + asic cap harcoding * 1286 + *************************************************/ 1287 + pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1288 + 1289 + /* TODO: Hardcode to correct number of functional controllers */ 1290 + pool->base.pipe_count = 4; 1291 + dc->public.caps.max_downscale_ratio = 200; 1292 + dc->public.caps.i2c_speed_in_khz = 100; 1293 + dc->public.caps.max_cursor_size = 256; 1294 + 1295 + if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) 1296 + dc->public.debug = debug_defaults_drv; 1297 + else 1298 + dc->public.debug = debug_defaults_diags; 1299 + 1300 + /************************************************* 1301 + * Create resources * 1302 + *************************************************/ 1303 + 1304 + pool->base.clock_sources[DCN10_CLK_SRC_PLL0] = 1305 + dcn10_clock_source_create(ctx, ctx->dc_bios, 1306 + CLOCK_SOURCE_COMBO_PHY_PLL0, 1307 + &clk_src_regs[0], false); 1308 + pool->base.clock_sources[DCN10_CLK_SRC_PLL1] = 1309 + dcn10_clock_source_create(ctx, ctx->dc_bios, 1310 + CLOCK_SOURCE_COMBO_PHY_PLL1, 1311 + &clk_src_regs[1], false); 1312 + pool->base.clock_sources[DCN10_CLK_SRC_PLL2] = 1313 + dcn10_clock_source_create(ctx, ctx->dc_bios, 1314 + CLOCK_SOURCE_COMBO_PHY_PLL2, 1315 + &clk_src_regs[2], false); 1316 + pool->base.clock_sources[DCN10_CLK_SRC_PLL3] = 1317 + dcn10_clock_source_create(ctx, ctx->dc_bios, 1318 + CLOCK_SOURCE_COMBO_PHY_PLL3, 1319 + &clk_src_regs[3], false); 1320 + 1321 + pool->base.clk_src_count = DCN10_CLK_SRC_TOTAL; 1322 + 1323 + pool->base.dp_clock_source = 1324 + dcn10_clock_source_create(ctx, ctx->dc_bios, 1325 + CLOCK_SOURCE_ID_DP_DTO, 1326 + /* todo: not reuse phy_pll registers */ 1327 + &clk_src_regs[0], true); 1328 + 1329 + for (i = 0; i < pool->base.clk_src_count; i++) { 1330 + if (pool->base.clock_sources[i] == NULL) { 1331 + dm_error("DC: failed to create clock sources!\n"); 1332 + BREAK_TO_DEBUGGER(); 1333 + goto clock_source_create_fail; 1334 + } 1335 + } 1336 + 1337 + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 1338 + pool->base.display_clock = dce120_disp_clk_create(ctx, 1339 + &disp_clk_regs, 1340 + &disp_clk_shift, 1341 + &disp_clk_mask); 1342 + if (pool->base.display_clock == NULL) { 1343 + dm_error("DC: failed to create display clock!\n"); 1344 + BREAK_TO_DEBUGGER(); 1345 + goto disp_clk_create_fail; 1346 + } 1347 + } 1348 + 1349 + pool->base.dmcu = dcn10_dmcu_create(ctx, 1350 + &dmcu_regs, 1351 + &dmcu_shift, 1352 + &dmcu_mask); 1353 + if (pool->base.dmcu == NULL) { 1354 + dm_error("DC: failed to create dmcu!\n"); 1355 + BREAK_TO_DEBUGGER(); 1356 + goto res_create_fail; 1357 + } 1358 + 1359 + pool->base.abm = dce_abm_create(ctx, 1360 + &abm_regs, 1361 + &abm_shift, 1362 + &abm_mask); 1363 + if (pool->base.abm == NULL) { 1364 + dm_error("DC: failed to create abm!\n"); 1365 + BREAK_TO_DEBUGGER(); 1366 + goto res_create_fail; 1367 + } 1368 + 1369 + dml_init_instance(&dc->dml, DML_PROJECT_RAVEN1); 1370 + dc->dcn_ip = dcn10_ip_defaults; 1371 + dc->dcn_soc = dcn10_soc_defaults; 1372 + if (!dc->public.debug.disable_pplib_clock_request) 1373 + dcn_bw_update_from_pplib(dc); 1374 + dcn_bw_sync_calcs_and_dml(dc); 1375 + if (!dc->public.debug.disable_pplib_wm_range) 1376 + dcn_bw_notify_pplib_of_wm_ranges(dc); 1377 + 1378 + { 1379 + #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1380 + struct irq_service_init_data init_data; 1381 + init_data.ctx = dc->ctx; 1382 + pool->base.irqs = dal_irq_service_dcn10_create(&init_data); 1383 + if (!pool->base.irqs) 1384 + goto irqs_create_fail; 1385 + #endif 1386 + } 1387 + 1388 + /* mem input -> ipp -> transform -> opp -> TG */ 1389 + for (i = 0; i < pool->base.pipe_count; i++) { 1390 + pool->base.mis[i] = dcn10_mem_input_create(ctx, i); 1391 + if (pool->base.mis[i] == NULL) { 1392 + BREAK_TO_DEBUGGER(); 1393 + dm_error( 1394 + "DC: failed to create memory input!\n"); 1395 + goto mi_create_fail; 1396 + } 1397 + 1398 + pool->base.ipps[i] = dcn10_ipp_create(ctx, i); 1399 + if (pool->base.ipps[i] == NULL) { 1400 + BREAK_TO_DEBUGGER(); 1401 + dm_error( 1402 + "DC: failed to create input pixel processor!\n"); 1403 + goto ipp_create_fail; 1404 + } 1405 + 1406 + pool->base.transforms[i] = dcn10_transform_create(ctx, i); 1407 + if (pool->base.transforms[i] == NULL) { 1408 + BREAK_TO_DEBUGGER(); 1409 + dm_error( 1410 + "DC: failed to create transform!\n"); 1411 + goto transform_create_fail; 1412 + } 1413 + 1414 + pool->base.opps[i] = dcn10_opp_create(ctx, i); 1415 + if (pool->base.opps[i] == NULL) { 1416 + BREAK_TO_DEBUGGER(); 1417 + dm_error( 1418 + "DC: failed to create output pixel processor!\n"); 1419 + goto opp_create_fail; 1420 + } 1421 + 1422 + pool->base.timing_generators[i] = dcn10_timing_generator_create( 1423 + ctx, i); 1424 + if (pool->base.timing_generators[i] == NULL) { 1425 + BREAK_TO_DEBUGGER(); 1426 + dm_error("DC: failed to create tg!\n"); 1427 + goto otg_create_fail; 1428 + } 1429 + } 1430 + 1431 + pool->base.mpc = dcn10_mpc_create(ctx); 1432 + 1433 + if (!resource_construct(num_virtual_links, dc, &pool->base, 1434 + (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? 1435 + &res_create_funcs : &res_create_maximus_funcs))) 1436 + goto res_create_fail; 1437 + 1438 + dcn10_hw_sequencer_construct(dc); 1439 + dc->public.caps.max_surfaces = pool->base.pipe_count; 1440 + 1441 + dc->public.cap_funcs = cap_funcs; 1442 + 1443 + return true; 1444 + 1445 + disp_clk_create_fail: 1446 + otg_create_fail: 1447 + opp_create_fail: 1448 + transform_create_fail: 1449 + ipp_create_fail: 1450 + mi_create_fail: 1451 + irqs_create_fail: 1452 + res_create_fail: 1453 + clock_source_create_fail: 1454 + 1455 + destruct(pool); 1456 + 1457 + return false; 1458 + } 1459 + 1460 + struct resource_pool *dcn10_create_resource_pool( 1461 + uint8_t num_virtual_links, 1462 + struct core_dc *dc) 1463 + { 1464 + struct dcn10_resource_pool *pool = 1465 + dm_alloc(sizeof(struct dcn10_resource_pool)); 1466 + 1467 + if (!pool) 1468 + return NULL; 1469 + 1470 + if (construct(num_virtual_links, dc, pool)) 1471 + return &pool->base; 1472 + 1473 + BREAK_TO_DEBUGGER(); 1474 + return NULL; 1475 + }
+47
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.h
··· 1 + /* 2 + * Copyright 2016 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 + #ifndef __DC_RESOURCE_DCN10_H__ 27 + #define __DC_RESOURCE_DCN10_H__ 28 + 29 + #include "core_types.h" 30 + 31 + #define TO_DCN10_RES_POOL(pool)\ 32 + container_of(pool, struct dcn10_resource_pool, base) 33 + 34 + struct core_dc; 35 + struct resource_pool; 36 + struct _vcs_dpi_display_pipe_params_st; 37 + 38 + struct dcn10_resource_pool { 39 + struct resource_pool base; 40 + }; 41 + struct resource_pool *dcn10_create_resource_pool( 42 + uint8_t num_virtual_links, 43 + struct core_dc *dc); 44 + 45 + 46 + #endif /* __DC_RESOURCE_DCN10_H__ */ 47 +
+1202
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
··· 1 + /* 2 + * Copyright 2012-15 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 "reg_helper.h" 27 + #include "dcn10_timing_generator.h" 28 + 29 + #define REG(reg)\ 30 + tgn10->tg_regs->reg 31 + 32 + #define CTX \ 33 + tgn10->base.ctx 34 + 35 + #undef FN 36 + #define FN(reg_name, field_name) \ 37 + tgn10->tg_shift->field_name, tgn10->tg_mask->field_name 38 + 39 + #define STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN 0x100 40 + 41 + /** 42 + * apply_front_porch_workaround TODO FPGA still need? 43 + * 44 + * This is a workaround for a bug that has existed since R5xx and has not been 45 + * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive. 46 + */ 47 + static void tg_apply_front_porch_workaround( 48 + struct timing_generator *tg, 49 + struct dc_crtc_timing *timing) 50 + { 51 + if (timing->flags.INTERLACE == 1) { 52 + if (timing->v_front_porch < 2) 53 + timing->v_front_porch = 2; 54 + } else { 55 + if (timing->v_front_porch < 1) 56 + timing->v_front_porch = 1; 57 + } 58 + } 59 + 60 + static void dcn10_program_global_sync( 61 + struct timing_generator *tg) 62 + { 63 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 64 + 65 + if (tg->dlg_otg_param.vstartup_start == 0) { 66 + BREAK_TO_DEBUGGER(); 67 + return; 68 + } 69 + 70 + REG_SET(OTG_VSTARTUP_PARAM, 0, 71 + VSTARTUP_START, tg->dlg_otg_param.vstartup_start); 72 + 73 + REG_SET_2(OTG_VUPDATE_PARAM, 0, 74 + VUPDATE_OFFSET, tg->dlg_otg_param.vupdate_offset, 75 + VUPDATE_WIDTH, tg->dlg_otg_param.vupdate_width); 76 + 77 + REG_SET(OTG_VREADY_PARAM, 0, 78 + VREADY_OFFSET, tg->dlg_otg_param.vready_offset); 79 + } 80 + 81 + struct crtc_stereo_flags { 82 + uint8_t PROGRAM_STEREO :1; 83 + uint8_t PROGRAM_POLARITY :1; 84 + uint8_t RIGHT_EYE_POLARITY :1; 85 + uint8_t FRAME_PACKED :1; 86 + uint8_t DISABLE_STEREO_DP_SYNC :1; 87 + }; 88 + 89 + static void dcn10_enable_stereo(struct timing_generator *tg, 90 + const struct crtc_stereo_flags *flags, 91 + const struct dc_crtc_timing *timing) 92 + { 93 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 94 + 95 + uint32_t active_width = timing->h_addressable; 96 + uint32_t space1_size = timing->v_total - timing->v_addressable; 97 + 98 + if (flags) { 99 + uint32_t stereo_en = flags->FRAME_PACKED == 0 ? 1 : 0; 100 + 101 + if (flags->PROGRAM_STEREO) 102 + REG_UPDATE_3(OTG_STEREO_CONTROL, 103 + OTG_STEREO_EN, stereo_en, 104 + OTG_STEREO_SYNC_OUTPUT_LINE_NUM, 0, 105 + OTG_STEREO_SYNC_OUTPUT_POLARITY, 0); 106 + 107 + if (flags->PROGRAM_POLARITY) 108 + REG_UPDATE(OTG_STEREO_CONTROL, 109 + OTG_STEREO_EYE_FLAG_POLARITY, 110 + flags->RIGHT_EYE_POLARITY == 0 ? 0:1); 111 + 112 + if (flags->DISABLE_STEREO_DP_SYNC) 113 + REG_UPDATE(OTG_STEREO_CONTROL, 114 + OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1); 115 + 116 + if (flags->PROGRAM_STEREO && flags->FRAME_PACKED) 117 + REG_UPDATE_3(OTG_3D_STRUCTURE_CONTROL, 118 + OTG_3D_STRUCTURE_EN, 1, 119 + OTG_3D_STRUCTURE_V_UPDATE_MODE, 1, 120 + OTG_3D_STRUCTURE_STEREO_SEL_OVR, 1); 121 + 122 + } 123 + 124 + REG_UPDATE(OPPBUF_CONTROL, 125 + OPPBUF_ACTIVE_WIDTH, active_width); 126 + 127 + REG_UPDATE(OPPBUF_3D_PARAMETERS_0, 128 + OPPBUF_3D_VACT_SPACE1_SIZE, space1_size); 129 + 130 + return; 131 + } 132 + 133 + static void dcn10_disable_stereo(struct timing_generator *tg) 134 + { 135 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 136 + 137 + REG_SET(OTG_STEREO_CONTROL, 0, 138 + OTG_STEREO_EN, 0); 139 + 140 + REG_SET_3(OTG_3D_STRUCTURE_CONTROL, 0, 141 + OTG_3D_STRUCTURE_EN, 0, 142 + OTG_3D_STRUCTURE_V_UPDATE_MODE, 0, 143 + OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); 144 + 145 + REG_UPDATE(OPPBUF_CONTROL, 146 + OPPBUF_ACTIVE_WIDTH, 0); 147 + REG_UPDATE(OPPBUF_3D_PARAMETERS_0, 148 + OPPBUF_3D_VACT_SPACE1_SIZE, 0); 149 + return; 150 + } 151 + 152 + static bool is_frame_alternate_stereo(enum dc_timing_3d_format fmt) 153 + { 154 + bool ret = false; 155 + if (fmt == TIMING_3D_FORMAT_FRAME_ALTERNATE || 156 + fmt == TIMING_3D_FORMAT_INBAND_FA || 157 + fmt == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA || 158 + fmt == TIMING_3D_FORMAT_SIDEBAND_FA) 159 + ret = true; 160 + return ret; 161 + } 162 + 163 + static void dcn10_do_stereo(struct timing_generator *tg, 164 + const struct dc_crtc_timing *dc_crtc_timing) 165 + { 166 + struct crtc_stereo_flags stereo_flags = {0}; 167 + if (dc_crtc_timing->timing_3d_format == TIMING_3D_FORMAT_NONE || 168 + dc_crtc_timing->timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE || 169 + dc_crtc_timing->timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM) 170 + dcn10_disable_stereo(tg); 171 + else { 172 + stereo_flags.PROGRAM_STEREO = 1; 173 + stereo_flags.PROGRAM_POLARITY = 1; 174 + stereo_flags.DISABLE_STEREO_DP_SYNC = 0; 175 + stereo_flags.RIGHT_EYE_POLARITY = 176 + dc_crtc_timing->flags.RIGHT_EYE_3D_POLARITY; 177 + if (dc_crtc_timing->timing_3d_format == 178 + TIMING_3D_FORMAT_HW_FRAME_PACKING) 179 + stereo_flags.FRAME_PACKED = 1; 180 + 181 + if (is_frame_alternate_stereo( 182 + dc_crtc_timing->timing_3d_format) || 183 + dc_crtc_timing->timing_3d_format == 184 + TIMING_3D_FORMAT_HW_FRAME_PACKING) 185 + dcn10_enable_stereo(tg, &stereo_flags, dc_crtc_timing); 186 + } 187 + } 188 + 189 + /** 190 + * program_timing_generator used by mode timing set 191 + * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition. 192 + * Including SYNC. Call BIOS command table to program Timings. 193 + */ 194 + static void tg_program_timing_generator( 195 + struct timing_generator *tg, 196 + const struct dc_crtc_timing *dc_crtc_timing) 197 + { 198 + struct dc_crtc_timing patched_crtc_timing; 199 + uint32_t vesa_sync_start; 200 + uint32_t asic_blank_end; 201 + uint32_t asic_blank_start; 202 + uint32_t v_total; 203 + uint32_t v_sync_end; 204 + uint32_t v_init, v_fp2; 205 + uint32_t h_sync_polarity, v_sync_polarity; 206 + uint32_t interlace_factor; 207 + uint32_t start_point = 0; 208 + uint32_t field_num = 0; 209 + uint32_t h_div_2; 210 + 211 + 212 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 213 + 214 + patched_crtc_timing = *dc_crtc_timing; 215 + tg_apply_front_porch_workaround(tg, &patched_crtc_timing); 216 + 217 + /* Load horizontal timing */ 218 + 219 + /* CRTC_H_TOTAL = vesa.h_total - 1 */ 220 + REG_SET(OTG_H_TOTAL, 0, 221 + OTG_H_TOTAL, patched_crtc_timing.h_total - 1); 222 + 223 + /* h_sync_start = 0, h_sync_end = vesa.h_sync_width */ 224 + REG_UPDATE_2(OTG_H_SYNC_A, 225 + OTG_H_SYNC_A_START, 0, 226 + OTG_H_SYNC_A_END, patched_crtc_timing.h_sync_width); 227 + 228 + /* asic_h_blank_end = HsyncWidth + HbackPorch = 229 + * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart - 230 + * vesa.h_left_border 231 + */ 232 + vesa_sync_start = patched_crtc_timing.h_addressable + 233 + patched_crtc_timing.h_border_right + 234 + patched_crtc_timing.h_front_porch; 235 + 236 + asic_blank_end = patched_crtc_timing.h_total - 237 + vesa_sync_start - 238 + patched_crtc_timing.h_border_left; 239 + 240 + /* h_blank_start = v_blank_end + v_active */ 241 + asic_blank_start = asic_blank_end + 242 + patched_crtc_timing.h_border_left + 243 + patched_crtc_timing.h_addressable + 244 + patched_crtc_timing.h_border_right; 245 + 246 + REG_UPDATE_2(OTG_H_BLANK_START_END, 247 + OTG_H_BLANK_START, asic_blank_start, 248 + OTG_H_BLANK_END, asic_blank_end); 249 + 250 + /* h_sync polarity */ 251 + h_sync_polarity = patched_crtc_timing.flags.HSYNC_POSITIVE_POLARITY ? 252 + 0 : 1; 253 + 254 + REG_UPDATE(OTG_H_SYNC_A_CNTL, 255 + OTG_H_SYNC_A_POL, h_sync_polarity); 256 + 257 + /* Load vertical timing */ 258 + 259 + /* CRTC_V_TOTAL = v_total - 1 */ 260 + if (patched_crtc_timing.flags.INTERLACE) { 261 + interlace_factor = 2; 262 + v_total = 2 * patched_crtc_timing.v_total; 263 + } else { 264 + interlace_factor = 1; 265 + v_total = patched_crtc_timing.v_total - 1; 266 + } 267 + REG_SET(OTG_V_TOTAL, 0, 268 + OTG_V_TOTAL, v_total); 269 + 270 + /* v_sync_start = 0, v_sync_end = v_sync_width */ 271 + v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor; 272 + 273 + REG_UPDATE_2(OTG_V_SYNC_A, 274 + OTG_V_SYNC_A_START, 0, 275 + OTG_V_SYNC_A_END, v_sync_end); 276 + 277 + vesa_sync_start = patched_crtc_timing.v_addressable + 278 + patched_crtc_timing.v_border_bottom + 279 + patched_crtc_timing.v_front_porch; 280 + 281 + asic_blank_end = (patched_crtc_timing.v_total - 282 + vesa_sync_start - 283 + patched_crtc_timing.v_border_top) 284 + * interlace_factor; 285 + 286 + /* v_blank_start = v_blank_end + v_active */ 287 + asic_blank_start = asic_blank_end + 288 + (patched_crtc_timing.v_border_top + 289 + patched_crtc_timing.v_addressable + 290 + patched_crtc_timing.v_border_bottom) 291 + * interlace_factor; 292 + 293 + REG_UPDATE_2(OTG_V_BLANK_START_END, 294 + OTG_V_BLANK_START, asic_blank_start, 295 + OTG_V_BLANK_END, asic_blank_end); 296 + 297 + 298 + /* v_sync polarity */ 299 + v_sync_polarity = patched_crtc_timing.flags.VSYNC_POSITIVE_POLARITY ? 300 + 0 : 1; 301 + 302 + REG_UPDATE(OTG_V_SYNC_A_CNTL, 303 + OTG_V_SYNC_A_POL, v_sync_polarity); 304 + 305 + v_init = asic_blank_start; 306 + if (tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT || 307 + tg->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT_MST || 308 + tg->dlg_otg_param.signal == SIGNAL_TYPE_EDP) { 309 + v_init = asic_blank_start; 310 + start_point = 1; 311 + if (patched_crtc_timing.flags.INTERLACE == 1) 312 + field_num = 1; 313 + } 314 + if (v_init < 0) 315 + v_init = 0; 316 + v_fp2 = 0; 317 + if (tg->dlg_otg_param.vstartup_start > asic_blank_end) 318 + v_fp2 = tg->dlg_otg_param.vstartup_start > asic_blank_end; 319 + 320 + /* Interlace */ 321 + if (patched_crtc_timing.flags.INTERLACE == 1) { 322 + REG_UPDATE(OTG_INTERLACE_CONTROL, 323 + OTG_INTERLACE_ENABLE, 1); 324 + v_init = v_init / 2; 325 + if ((tg->dlg_otg_param.vstartup_start/2)*2 > asic_blank_end) 326 + v_fp2 = v_fp2 / 2; 327 + } 328 + else 329 + REG_UPDATE(OTG_INTERLACE_CONTROL, 330 + OTG_INTERLACE_ENABLE, 0); 331 + 332 + 333 + /* VTG enable set to 0 first VInit */ 334 + REG_UPDATE(CONTROL, 335 + VTG0_ENABLE, 0); 336 + 337 + REG_UPDATE_2(CONTROL, 338 + VTG0_FP2, v_fp2, 339 + VTG0_VCOUNT_INIT, v_init); 340 + 341 + /* original code is using VTG offset to address OTG reg, seems wrong */ 342 + REG_UPDATE_2(OTG_CONTROL, 343 + OTG_START_POINT_CNTL, start_point, 344 + OTG_FIELD_NUMBER_CNTL, field_num); 345 + 346 + dcn10_program_global_sync(tg); 347 + 348 + /* TODO 349 + * patched_crtc_timing.flags.HORZ_COUNT_BY_TWO == 1 350 + * program_horz_count_by_2 351 + * for DVI 30bpp mode, 0 otherwise 352 + * program_horz_count_by_2(tg, &patched_crtc_timing); 353 + */ 354 + 355 + /* Enable stereo - only when we need to pack 3D frame. Other types 356 + * of stereo handled in explicit call 357 + */ 358 + h_div_2 = (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ? 359 + 1 : 0; 360 + 361 + REG_UPDATE(OTG_H_TIMING_CNTL, 362 + OTG_H_TIMING_DIV_BY2, h_div_2); 363 + 364 + /* Enable crtc stereo frame pack tested... todo more 365 + */ 366 + dcn10_do_stereo(tg, &patched_crtc_timing); 367 + } 368 + 369 + /** tg_program_blanking 370 + * Only programmed part of OTG_H, OTG_V register for set_plane_config 371 + * Assume other OTG registers are programmed by video mode set already. 372 + * This function is for underlay. DCN will have new sequence. 373 + * This function will be removed. Need remove it from set_plane_config 374 + */ 375 + 376 + static void tg_program_timing(struct timing_generator *tg, 377 + const struct dc_crtc_timing *timing, 378 + bool use_vbios) 379 + { 380 + tg_program_timing_generator(tg, timing); 381 + } 382 + 383 + /** 384 + * unblank_crtc 385 + * Call ASIC Control Object to UnBlank CRTC. 386 + */ 387 + static void tg_unblank_crtc(struct timing_generator *tg) 388 + { 389 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 390 + 391 + REG_UPDATE_2(OTG_BLANK_CONTROL, 392 + OTG_BLANK_DATA_EN, 0, 393 + OTG_BLANK_DE_MODE, 0); 394 + } 395 + 396 + /** 397 + * blank_crtc 398 + * Call ASIC Control Object to Blank CRTC. 399 + */ 400 + 401 + static void tg_blank_crtc(struct timing_generator *tg) 402 + { 403 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 404 + 405 + REG_UPDATE_2(OTG_BLANK_CONTROL, 406 + OTG_BLANK_DATA_EN, 1, 407 + OTG_BLANK_DE_MODE, 0); 408 + 409 + /* todo: why are we waiting for BLANK_DATA_EN? shouldn't we be waiting 410 + * for status? 411 + */ 412 + REG_WAIT(OTG_BLANK_CONTROL, 413 + OTG_BLANK_DATA_EN, 1, 414 + 20000, 200000); 415 + 416 + REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL, 417 + OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 0); 418 + } 419 + 420 + static void tg_set_blank(struct timing_generator *tg, 421 + bool enable_blanking) 422 + { 423 + if (enable_blanking) 424 + tg_blank_crtc(tg); 425 + else 426 + tg_unblank_crtc(tg); 427 + } 428 + 429 + static bool tg_is_blanked(struct timing_generator *tg) 430 + { 431 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 432 + uint32_t blank_en; 433 + uint32_t blank_state; 434 + 435 + REG_GET_2(OTG_BLANK_CONTROL, 436 + OTG_BLANK_DATA_EN, &blank_en, 437 + OTG_CURRENT_BLANK_STATE, &blank_state); 438 + 439 + return blank_en && blank_state; 440 + } 441 + 442 + static void enable_optc_clock(struct timing_generator *tg, bool enable) 443 + { 444 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 445 + 446 + if (enable) { 447 + REG_UPDATE(OPTC_INPUT_CLOCK_CONTROL, 448 + OPTC_INPUT_CLK_EN, 1); 449 + 450 + REG_WAIT(OPTC_INPUT_CLOCK_CONTROL, 451 + OPTC_INPUT_CLK_ON, 1, 452 + 20000, 200000); 453 + 454 + /* Enable clock */ 455 + REG_UPDATE(OTG_CLOCK_CONTROL, 456 + OTG_CLOCK_EN, 1); 457 + 458 + REG_WAIT(OTG_CLOCK_CONTROL, 459 + OTG_CLOCK_ON, 1, 460 + 20000, 200000); 461 + } else { 462 + REG_UPDATE_2(OTG_CLOCK_CONTROL, 463 + OTG_CLOCK_GATE_DIS, 0, 464 + OTG_CLOCK_EN, 0); 465 + 466 + REG_WAIT(OTG_CLOCK_CONTROL, 467 + OTG_CLOCK_ON, 0, 468 + 20000, 200000); 469 + 470 + REG_UPDATE_2(OPTC_INPUT_CLOCK_CONTROL, 471 + OPTC_INPUT_CLK_GATE_DIS, 0, 472 + OPTC_INPUT_CLK_EN, 0); 473 + 474 + REG_WAIT(OPTC_INPUT_CLOCK_CONTROL, 475 + OPTC_INPUT_CLK_ON, 0, 476 + 20000, 200000); 477 + } 478 + } 479 + 480 + /** 481 + * Enable CRTC 482 + * Enable CRTC - call ASIC Control Object to enable Timing generator. 483 + */ 484 + static bool tg_enable_crtc(struct timing_generator *tg) 485 + { 486 + /* TODO FPGA wait for answer 487 + * OTG_MASTER_UPDATE_MODE != CRTC_MASTER_UPDATE_MODE 488 + * OTG_MASTER_UPDATE_LOCK != CRTC_MASTER_UPDATE_LOCK 489 + */ 490 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 491 + 492 + /* opp instance for OTG. For DCN1.0, ODM is remoed. 493 + * OPP and OPTC should 1:1 mapping 494 + */ 495 + REG_UPDATE(OPTC_DATA_SOURCE_SELECT, 496 + OPTC_SRC_SEL, tg->inst); 497 + 498 + /* VTG enable first is for HW workaround */ 499 + REG_UPDATE(CONTROL, 500 + VTG0_ENABLE, 1); 501 + 502 + /* Enable CRTC */ 503 + REG_UPDATE_2(OTG_CONTROL, 504 + OTG_DISABLE_POINT_CNTL, 3, 505 + OTG_MASTER_EN, 1); 506 + 507 + return true; 508 + } 509 + 510 + /* disable_crtc - call ASIC Control Object to disable Timing generator. */ 511 + static bool tg_disable_crtc(struct timing_generator *tg) 512 + { 513 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 514 + 515 + /* disable otg request until end of the first line 516 + * in the vertical blank region 517 + */ 518 + REG_UPDATE_2(OTG_CONTROL, 519 + OTG_DISABLE_POINT_CNTL, 3, 520 + OTG_MASTER_EN, 0); 521 + 522 + REG_UPDATE(CONTROL, 523 + VTG0_ENABLE, 0); 524 + 525 + /* CRTC disabled, so disable clock. */ 526 + REG_WAIT(OTG_CLOCK_CONTROL, 527 + OTG_BUSY, 0, 528 + 2000, 20000); 529 + 530 + return true; 531 + } 532 + 533 + 534 + static void tg_program_blank_color( 535 + struct timing_generator *tg, 536 + const struct tg_color *black_color) 537 + { 538 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 539 + 540 + REG_SET_3(OTG_BLACK_COLOR, 0, 541 + OTG_BLACK_COLOR_B_CB, black_color->color_b_cb, 542 + OTG_BLACK_COLOR_G_Y, black_color->color_g_y, 543 + OTG_BLACK_COLOR_R_CR, black_color->color_r_cr); 544 + } 545 + 546 + /** 547 + * dcn10_dcn10_timing_generator_disable_vga 548 + * Turn OFF VGA Mode and Timing - DxVGA_CONTROL 549 + * VGA Mode and VGA Timing is used by VBIOS on CRT Monitors; 550 + */ 551 + /* TODO FPGA FPGA setup is done by Diag which does not enable VGA mode. 552 + * VGA is disable by ASIC default. This function is not needed for 553 + * FPGA story. 554 + * usage: 555 + * init_hw within dc.c 556 + * disable_vga_and_power_gate_all_controllers within dce110_hw_sequencer.c 557 + * We may move init_hw into DC specific so that we can remove 558 + * .disable_vga from upper layer stack 559 + */ 560 + static void dcn10_timing_generator_disable_vga( 561 + struct timing_generator *tg) 562 + { 563 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 564 + 565 + switch (tgn10->base.inst) { 566 + case 0: 567 + REG_WRITE(D1VGA_CONTROL, 0); 568 + break; 569 + case 1: 570 + REG_WRITE(D2VGA_CONTROL, 0); 571 + break; 572 + case 2: 573 + REG_WRITE(D2VGA_CONTROL, 0); 574 + break; 575 + case 3: 576 + REG_WRITE(D4VGA_CONTROL, 0); 577 + break; 578 + default: 579 + break; 580 + } 581 + } 582 + 583 + static bool tg_validate_timing( 584 + struct timing_generator *tg, 585 + const struct dc_crtc_timing *timing) 586 + { 587 + uint32_t interlace_factor; 588 + uint32_t v_blank; 589 + uint32_t h_blank; 590 + uint32_t min_v_blank; 591 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 592 + 593 + ASSERT(timing != NULL); 594 + 595 + interlace_factor = timing->flags.INTERLACE ? 2 : 1; 596 + v_blank = (timing->v_total - timing->v_addressable - 597 + timing->v_border_top - timing->v_border_bottom) * 598 + interlace_factor; 599 + 600 + h_blank = (timing->h_total - timing->h_addressable - 601 + timing->h_border_right - 602 + timing->h_border_left); 603 + 604 + if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE && 605 + timing->timing_3d_format != TIMING_3D_FORMAT_HW_FRAME_PACKING && 606 + timing->timing_3d_format != TIMING_3D_FORMAT_TOP_AND_BOTTOM && 607 + timing->timing_3d_format != TIMING_3D_FORMAT_SIDE_BY_SIDE && 608 + timing->timing_3d_format != TIMING_3D_FORMAT_FRAME_ALTERNATE) 609 + return false; 610 + 611 + /* Temporarily blocking interlacing mode until it's supported */ 612 + if (timing->flags.INTERLACE == 1) 613 + return false; 614 + 615 + /* Check maximum number of pixels supported by Timing Generator 616 + * (Currently will never fail, in order to fail needs display which 617 + * needs more than 8192 horizontal and 618 + * more than 8192 vertical total pixels) 619 + */ 620 + if (timing->h_total > tgn10->max_h_total || 621 + timing->v_total > tgn10->max_v_total) 622 + return false; 623 + 624 + 625 + if (h_blank < tgn10->min_h_blank) 626 + return false; 627 + 628 + if (timing->h_sync_width < tgn10->min_h_sync_width || 629 + timing->v_sync_width < tgn10->min_v_sync_width) 630 + return false; 631 + 632 + min_v_blank = timing->flags.INTERLACE?tgn10->min_v_blank_interlace:tgn10->min_v_blank; 633 + 634 + if (v_blank < min_v_blank) 635 + return false; 636 + 637 + return true; 638 + 639 + } 640 + 641 + /* 642 + * get_vblank_counter 643 + * 644 + * @brief 645 + * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which 646 + * holds the counter of frames. 647 + * 648 + * @param 649 + * struct timing_generator *tg - [in] timing generator which controls the 650 + * desired CRTC 651 + * 652 + * @return 653 + * Counter of frames, which should equal to number of vblanks. 654 + */ 655 + static uint32_t tg_get_vblank_counter(struct timing_generator *tg) 656 + { 657 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 658 + uint32_t frame_count; 659 + 660 + REG_GET(OTG_STATUS_FRAME_COUNT, 661 + OTG_FRAME_COUNT, &frame_count); 662 + 663 + return frame_count; 664 + } 665 + 666 + void dcn10_lock(struct timing_generator *tg) 667 + { 668 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 669 + 670 + REG_SET(OTG_MASTER_UPDATE_LOCK, 0, 671 + OTG_MASTER_UPDATE_LOCK, 1); 672 + } 673 + 674 + void dcn10_unlock(struct timing_generator *tg) 675 + { 676 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 677 + 678 + REG_SET(OTG_MASTER_UPDATE_LOCK, 0, 679 + OTG_MASTER_UPDATE_LOCK, 0); 680 + 681 + /* why are we waiting here? */ 682 + REG_WAIT(OTG_DOUBLE_BUFFER_CONTROL, 683 + OTG_UPDATE_PENDING, 0, 684 + 20000, 200000); 685 + } 686 + 687 + static void dcn10_get_position(struct timing_generator *tg, 688 + struct crtc_position *position) 689 + { 690 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 691 + 692 + REG_GET_2(OTG_STATUS_POSITION, 693 + OTG_HORZ_COUNT, &position->horizontal_count, 694 + OTG_VERT_COUNT, &position->vertical_count); 695 + 696 + REG_GET(OTG_NOM_VERT_POSITION, 697 + OTG_VERT_COUNT_NOM, &position->nominal_vcount); 698 + } 699 + 700 + bool dcn10_is_counter_moving(struct timing_generator *tg) 701 + { 702 + struct crtc_position position1, position2; 703 + 704 + tg->funcs->get_position(tg, &position1); 705 + tg->funcs->get_position(tg, &position2); 706 + 707 + if (position1.horizontal_count == position2.horizontal_count && 708 + position1.vertical_count == position2.vertical_count) 709 + return false; 710 + else 711 + return true; 712 + } 713 + 714 + static bool dcn10_did_triggered_reset_occur( 715 + struct timing_generator *tg) 716 + { 717 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 718 + uint32_t occurred; 719 + 720 + REG_GET(OTG_FORCE_COUNT_NOW_CNTL, 721 + OTG_FORCE_COUNT_NOW_OCCURRED, &occurred); 722 + 723 + return occurred != 0; 724 + } 725 + 726 + static void dcn10_enable_reset_trigger(struct timing_generator *tg, int source_tg_inst) 727 + { 728 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 729 + uint32_t falling_edge; 730 + 731 + REG_GET(OTG_V_SYNC_A_CNTL, 732 + OTG_V_SYNC_A_POL, &falling_edge); 733 + 734 + if (falling_edge) 735 + REG_SET_3(OTG_TRIGA_CNTL, 0, 736 + /* vsync signal from selected OTG pipe based 737 + * on OTG_TRIG_SOURCE_PIPE_SELECT setting 738 + */ 739 + OTG_TRIGA_SOURCE_SELECT, 20, 740 + OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst, 741 + /* always detect falling edge */ 742 + OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, 1); 743 + else 744 + REG_SET_3(OTG_TRIGA_CNTL, 0, 745 + /* vsync signal from selected OTG pipe based 746 + * on OTG_TRIG_SOURCE_PIPE_SELECT setting 747 + */ 748 + OTG_TRIGA_SOURCE_SELECT, 20, 749 + OTG_TRIGA_SOURCE_PIPE_SELECT, source_tg_inst, 750 + /* always detect rising edge */ 751 + OTG_TRIGA_RISING_EDGE_DETECT_CNTL, 1); 752 + 753 + REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0, 754 + /* force H count to H_TOTAL and V count to V_TOTAL in 755 + * progressive mode and V_TOTAL-1 in interlaced mode 756 + */ 757 + OTG_FORCE_COUNT_NOW_MODE, 2); 758 + } 759 + 760 + static void dcn10_disable_reset_trigger(struct timing_generator *tg) 761 + { 762 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 763 + 764 + REG_WRITE(OTG_TRIGA_CNTL, 0); 765 + 766 + REG_SET(OTG_FORCE_COUNT_NOW_CNTL, 0, 767 + OTG_FORCE_COUNT_NOW_CLEAR, 1); 768 + } 769 + 770 + static void dcn10_wait_for_state(struct timing_generator *tg, 771 + enum crtc_state state) 772 + { 773 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 774 + 775 + switch (state) { 776 + case CRTC_STATE_VBLANK: 777 + REG_WAIT(OTG_STATUS, 778 + OTG_V_BLANK, 1, 779 + 100, 100000); /* 1 vupdate at 10hz */ 780 + break; 781 + 782 + case CRTC_STATE_VACTIVE: 783 + REG_WAIT(OTG_STATUS, 784 + OTG_V_ACTIVE_DISP, 1, 785 + 100, 100000); /* 1 vupdate at 10hz */ 786 + break; 787 + 788 + default: 789 + break; 790 + } 791 + } 792 + 793 + static void set_early_control( 794 + struct timing_generator *tg, 795 + uint32_t early_cntl) 796 + { 797 + /* asic design change, do not need this control 798 + * empty for share caller logic 799 + */ 800 + } 801 + 802 + 803 + static void set_static_screen_control( 804 + struct timing_generator *tg, 805 + uint32_t value) 806 + { 807 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 808 + 809 + /* Bit 8 is no longer applicable in RV for PSR case, 810 + * set bit 8 to 0 if given 811 + */ 812 + if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN) 813 + != 0) 814 + value = value & 815 + ~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN; 816 + 817 + REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0, 818 + OTG_STATIC_SCREEN_EVENT_MASK, value, 819 + OTG_STATIC_SCREEN_FRAME_COUNT, 2); 820 + } 821 + 822 + 823 + /** 824 + ***************************************************************************** 825 + * Function: set_drr 826 + * 827 + * @brief 828 + * Program dynamic refresh rate registers m_OTGx_OTG_V_TOTAL_*. 829 + * 830 + ***************************************************************************** 831 + */ 832 + void dcn10_timing_generator_set_drr( 833 + struct timing_generator *tg, 834 + const struct drr_params *params) 835 + { 836 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 837 + 838 + if (params != NULL && 839 + params->vertical_total_max > 0 && 840 + params->vertical_total_min > 0) { 841 + 842 + REG_SET(OTG_V_TOTAL_MAX, 0, 843 + OTG_V_TOTAL_MAX, params->vertical_total_max - 1); 844 + 845 + REG_SET(OTG_V_TOTAL_MIN, 0, 846 + OTG_V_TOTAL_MIN, params->vertical_total_min - 1); 847 + 848 + REG_UPDATE_5(OTG_V_TOTAL_CONTROL, 849 + OTG_V_TOTAL_MIN_SEL, 1, 850 + OTG_V_TOTAL_MAX_SEL, 1, 851 + OTG_FORCE_LOCK_ON_EVENT, 0, 852 + OTG_SET_V_TOTAL_MIN_MASK_EN, 0, 853 + OTG_SET_V_TOTAL_MIN_MASK, 0); 854 + } else { 855 + REG_SET(OTG_V_TOTAL_MIN, 0, 856 + OTG_V_TOTAL_MIN, 0); 857 + 858 + REG_SET(OTG_V_TOTAL_MAX, 0, 859 + OTG_V_TOTAL_MAX, 0); 860 + 861 + REG_UPDATE_4(OTG_V_TOTAL_CONTROL, 862 + OTG_SET_V_TOTAL_MIN_MASK, 0, 863 + OTG_V_TOTAL_MIN_SEL, 0, 864 + OTG_V_TOTAL_MAX_SEL, 0, 865 + OTG_FORCE_LOCK_ON_EVENT, 0); 866 + } 867 + } 868 + 869 + static void dcn10_timing_generator_set_test_pattern( 870 + struct timing_generator *tg, 871 + /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode' 872 + * because this is not DP-specific (which is probably somewhere in DP 873 + * encoder) */ 874 + enum controller_dp_test_pattern test_pattern, 875 + enum dc_color_depth color_depth) 876 + { 877 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 878 + enum test_pattern_color_format bit_depth; 879 + enum test_pattern_dyn_range dyn_range; 880 + enum test_pattern_mode mode; 881 + uint32_t pattern_mask; 882 + uint32_t pattern_data; 883 + /* color ramp generator mixes 16-bits color */ 884 + uint32_t src_bpc = 16; 885 + /* requested bpc */ 886 + uint32_t dst_bpc; 887 + uint32_t index; 888 + /* RGB values of the color bars. 889 + * Produce two RGB colors: RGB0 - white (all Fs) 890 + * and RGB1 - black (all 0s) 891 + * (three RGB components for two colors) 892 + */ 893 + uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 894 + 0x0000, 0x0000}; 895 + /* dest color (converted to the specified color format) */ 896 + uint16_t dst_color[6]; 897 + uint32_t inc_base; 898 + 899 + /* translate to bit depth */ 900 + switch (color_depth) { 901 + case COLOR_DEPTH_666: 902 + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; 903 + break; 904 + case COLOR_DEPTH_888: 905 + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 906 + break; 907 + case COLOR_DEPTH_101010: 908 + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; 909 + break; 910 + case COLOR_DEPTH_121212: 911 + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; 912 + break; 913 + default: 914 + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 915 + break; 916 + } 917 + 918 + switch (test_pattern) { 919 + case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: 920 + case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: 921 + { 922 + dyn_range = (test_pattern == 923 + CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? 924 + TEST_PATTERN_DYN_RANGE_CEA : 925 + TEST_PATTERN_DYN_RANGE_VESA); 926 + mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; 927 + 928 + REG_UPDATE_2(OTG_TEST_PATTERN_PARAMETERS, 929 + OTG_TEST_PATTERN_VRES, 6, 930 + OTG_TEST_PATTERN_HRES, 6); 931 + 932 + REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL, 933 + OTG_TEST_PATTERN_EN, 1, 934 + OTG_TEST_PATTERN_MODE, mode, 935 + OTG_TEST_PATTERN_DYNAMIC_RANGE, dyn_range, 936 + OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth); 937 + } 938 + break; 939 + 940 + case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: 941 + case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: 942 + { 943 + mode = (test_pattern == 944 + CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? 945 + TEST_PATTERN_MODE_VERTICALBARS : 946 + TEST_PATTERN_MODE_HORIZONTALBARS); 947 + 948 + switch (bit_depth) { 949 + case TEST_PATTERN_COLOR_FORMAT_BPC_6: 950 + dst_bpc = 6; 951 + break; 952 + case TEST_PATTERN_COLOR_FORMAT_BPC_8: 953 + dst_bpc = 8; 954 + break; 955 + case TEST_PATTERN_COLOR_FORMAT_BPC_10: 956 + dst_bpc = 10; 957 + break; 958 + default: 959 + dst_bpc = 8; 960 + break; 961 + } 962 + 963 + /* adjust color to the required colorFormat */ 964 + for (index = 0; index < 6; index++) { 965 + /* dst = 2^dstBpc * src / 2^srcBpc = src >> 966 + * (srcBpc - dstBpc); 967 + */ 968 + dst_color[index] = 969 + src_color[index] >> (src_bpc - dst_bpc); 970 + /* CRTC_TEST_PATTERN_DATA has 16 bits, 971 + * lowest 6 are hardwired to ZERO 972 + * color bits should be left aligned aligned to MSB 973 + * XXXXXXXXXX000000 for 10 bit, 974 + * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6 975 + */ 976 + dst_color[index] <<= (16 - dst_bpc); 977 + } 978 + 979 + REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0); 980 + 981 + /* We have to write the mask before data, similar to pipeline. 982 + * For example, for 8 bpc, if we want RGB0 to be magenta, 983 + * and RGB1 to be cyan, 984 + * we need to make 7 writes: 985 + * MASK DATA 986 + * 000001 00000000 00000000 set mask to R0 987 + * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0 988 + * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0 989 + * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1 990 + * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1 991 + * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1 992 + * 100000 11111111 00000000 B1 255, 0xFF00 993 + * 994 + * we will make a loop of 6 in which we prepare the mask, 995 + * then write, then prepare the color for next write. 996 + * first iteration will write mask only, 997 + * but each next iteration color prepared in 998 + * previous iteration will be written within new mask, 999 + * the last component will written separately, 1000 + * mask is not changing between 6th and 7th write 1001 + * and color will be prepared by last iteration 1002 + */ 1003 + 1004 + /* write color, color values mask in CRTC_TEST_PATTERN_MASK 1005 + * is B1, G1, R1, B0, G0, R0 1006 + */ 1007 + pattern_data = 0; 1008 + for (index = 0; index < 6; index++) { 1009 + /* prepare color mask, first write PATTERN_DATA 1010 + * will have all zeros 1011 + */ 1012 + pattern_mask = (1 << index); 1013 + 1014 + /* write color component */ 1015 + REG_SET_2(OTG_TEST_PATTERN_COLOR, 0, 1016 + OTG_TEST_PATTERN_MASK, pattern_mask, 1017 + OTG_TEST_PATTERN_DATA, pattern_data); 1018 + 1019 + /* prepare next color component, 1020 + * will be written in the next iteration 1021 + */ 1022 + pattern_data = dst_color[index]; 1023 + } 1024 + /* write last color component, 1025 + * it's been already prepared in the loop 1026 + */ 1027 + REG_SET_2(OTG_TEST_PATTERN_COLOR, 0, 1028 + OTG_TEST_PATTERN_MASK, pattern_mask, 1029 + OTG_TEST_PATTERN_DATA, pattern_data); 1030 + 1031 + /* enable test pattern */ 1032 + REG_UPDATE_4(OTG_TEST_PATTERN_CONTROL, 1033 + OTG_TEST_PATTERN_EN, 1, 1034 + OTG_TEST_PATTERN_MODE, mode, 1035 + OTG_TEST_PATTERN_DYNAMIC_RANGE, 0, 1036 + OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth); 1037 + } 1038 + break; 1039 + 1040 + case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: 1041 + { 1042 + mode = (bit_depth == 1043 + TEST_PATTERN_COLOR_FORMAT_BPC_10 ? 1044 + TEST_PATTERN_MODE_DUALRAMP_RGB : 1045 + TEST_PATTERN_MODE_SINGLERAMP_RGB); 1046 + 1047 + switch (bit_depth) { 1048 + case TEST_PATTERN_COLOR_FORMAT_BPC_6: 1049 + dst_bpc = 6; 1050 + break; 1051 + case TEST_PATTERN_COLOR_FORMAT_BPC_8: 1052 + dst_bpc = 8; 1053 + break; 1054 + case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1055 + dst_bpc = 10; 1056 + break; 1057 + default: 1058 + dst_bpc = 8; 1059 + break; 1060 + } 1061 + 1062 + /* increment for the first ramp for one color gradation 1063 + * 1 gradation for 6-bit color is 2^10 1064 + * gradations in 16-bit color 1065 + */ 1066 + inc_base = (src_bpc - dst_bpc); 1067 + 1068 + switch (bit_depth) { 1069 + case TEST_PATTERN_COLOR_FORMAT_BPC_6: 1070 + { 1071 + REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS, 1072 + OTG_TEST_PATTERN_INC0, inc_base, 1073 + OTG_TEST_PATTERN_INC1, 0, 1074 + OTG_TEST_PATTERN_HRES, 6, 1075 + OTG_TEST_PATTERN_VRES, 6, 1076 + OTG_TEST_PATTERN_RAMP0_OFFSET, 0); 1077 + } 1078 + break; 1079 + case TEST_PATTERN_COLOR_FORMAT_BPC_8: 1080 + { 1081 + REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS, 1082 + OTG_TEST_PATTERN_INC0, inc_base, 1083 + OTG_TEST_PATTERN_INC1, 0, 1084 + OTG_TEST_PATTERN_HRES, 8, 1085 + OTG_TEST_PATTERN_VRES, 6, 1086 + OTG_TEST_PATTERN_RAMP0_OFFSET, 0); 1087 + } 1088 + break; 1089 + case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1090 + { 1091 + REG_UPDATE_5(OTG_TEST_PATTERN_PARAMETERS, 1092 + OTG_TEST_PATTERN_INC0, inc_base, 1093 + OTG_TEST_PATTERN_INC1, inc_base + 2, 1094 + OTG_TEST_PATTERN_HRES, 8, 1095 + OTG_TEST_PATTERN_VRES, 5, 1096 + OTG_TEST_PATTERN_RAMP0_OFFSET, 384 << 6); 1097 + } 1098 + break; 1099 + default: 1100 + break; 1101 + } 1102 + 1103 + REG_WRITE(OTG_TEST_PATTERN_COLOR, 0); 1104 + 1105 + /* enable test pattern */ 1106 + REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0); 1107 + 1108 + REG_SET_4(OTG_TEST_PATTERN_CONTROL, 0, 1109 + OTG_TEST_PATTERN_EN, 1, 1110 + OTG_TEST_PATTERN_MODE, mode, 1111 + OTG_TEST_PATTERN_DYNAMIC_RANGE, 0, 1112 + OTG_TEST_PATTERN_COLOR_FORMAT, bit_depth); 1113 + } 1114 + break; 1115 + case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: 1116 + { 1117 + REG_WRITE(OTG_TEST_PATTERN_CONTROL, 0); 1118 + REG_WRITE(OTG_TEST_PATTERN_COLOR, 0); 1119 + REG_WRITE(OTG_TEST_PATTERN_PARAMETERS, 0); 1120 + } 1121 + break; 1122 + default: 1123 + break; 1124 + 1125 + } 1126 + } 1127 + 1128 + void dcn10_timing_generator_get_crtc_scanoutpos( 1129 + struct timing_generator *tg, 1130 + uint32_t *v_blank_start, 1131 + uint32_t *v_blank_end, 1132 + uint32_t *h_position, 1133 + uint32_t *v_position) 1134 + { 1135 + struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 1136 + struct crtc_position position; 1137 + 1138 + REG_GET_2(OTG_V_BLANK_START_END, 1139 + OTG_V_BLANK_START, v_blank_start, 1140 + OTG_V_BLANK_END, v_blank_end); 1141 + 1142 + dcn10_get_position(tg, &position); 1143 + 1144 + *h_position = position.horizontal_count; 1145 + *v_position = position.vertical_count; 1146 + } 1147 + 1148 + static struct timing_generator_funcs dcn10_tg_funcs = { 1149 + .validate_timing = tg_validate_timing, 1150 + .program_timing = tg_program_timing, 1151 + .program_global_sync = dcn10_program_global_sync, 1152 + .enable_crtc = tg_enable_crtc, 1153 + .disable_crtc = tg_disable_crtc, 1154 + /* used by enable_timing_synchronization. Not need for FPGA */ 1155 + .is_counter_moving = dcn10_is_counter_moving, 1156 + /* never be called */ 1157 + .get_position = dcn10_get_position, 1158 + .get_frame_count = tg_get_vblank_counter, 1159 + .get_scanoutpos = dcn10_timing_generator_get_crtc_scanoutpos, 1160 + .set_early_control = set_early_control, 1161 + /* used by enable_timing_synchronization. Not need for FPGA */ 1162 + .wait_for_state = dcn10_wait_for_state, 1163 + .set_blank = tg_set_blank, 1164 + .is_blanked = tg_is_blanked, 1165 + /* never be called */ 1166 + .set_colors = NULL, 1167 + /* this function will be called by .progam_scaler. dcn and dce 1168 + * scaler top level functions are different. .program_scaler is 1169 + * not need for dcn. within program_scaler, dcn will return 1170 + * early before set_overscan_blank_color is reached 1171 + */ 1172 + .set_overscan_blank_color = NULL, 1173 + .set_blank_color = tg_program_blank_color, 1174 + /* dcn10_timing_generator_disable_vga */ 1175 + .disable_vga = dcn10_timing_generator_disable_vga, 1176 + .did_triggered_reset_occur = dcn10_did_triggered_reset_occur, 1177 + .enable_reset_trigger = dcn10_enable_reset_trigger, 1178 + .disable_reset_trigger = dcn10_disable_reset_trigger, 1179 + .lock = dcn10_lock, 1180 + .unlock = dcn10_unlock, 1181 + /* dcn10_timing_generator_enable_advanced_request*/ 1182 + .enable_advanced_request = NULL, 1183 + .enable_optc_clock = enable_optc_clock, 1184 + .set_drr = dcn10_timing_generator_set_drr, 1185 + .set_static_screen_control = set_static_screen_control, 1186 + .set_test_pattern = dcn10_timing_generator_set_test_pattern 1187 + }; 1188 + 1189 + void dcn10_timing_generator_init(struct dcn10_timing_generator *tgn10) 1190 + { 1191 + tgn10->base.funcs = &dcn10_tg_funcs; 1192 + 1193 + tgn10->max_h_total = tgn10->tg_mask->OTG_H_TOTAL + 1; 1194 + tgn10->max_v_total = tgn10->tg_mask->OTG_V_TOTAL + 1; 1195 + 1196 + tgn10->min_h_blank = 32; 1197 + tgn10->min_v_blank = 3; 1198 + tgn10->min_v_blank_interlace = 5; 1199 + tgn10->min_h_sync_width = 8; 1200 + tgn10->min_v_sync_width = 1; 1201 + } 1202 +
+335
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
··· 1 + /* 2 + * Copyright 2012-15 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 + #ifndef __DC_TIMING_GENERATOR_DCN10_H__ 27 + #define __DC_TIMING_GENERATOR_DCN10_H__ 28 + 29 + #include "timing_generator.h" 30 + 31 + #define DCN10TG_FROM_TG(tg)\ 32 + container_of(tg, struct dcn10_timing_generator, base) 33 + 34 + #define TG_COMMON_REG_LIST_DCN1_0(inst) \ 35 + SRI(OTG_VSTARTUP_PARAM, OTG, inst),\ 36 + SRI(OTG_VUPDATE_PARAM, OTG, inst),\ 37 + SRI(OTG_VREADY_PARAM, OTG, inst),\ 38 + SRI(OTG_BLANK_CONTROL, OTG, inst),\ 39 + SRI(OTG_MASTER_UPDATE_LOCK, OTG, inst),\ 40 + SRI(OTG_DOUBLE_BUFFER_CONTROL, OTG, inst),\ 41 + SRI(OTG_H_TOTAL, OTG, inst),\ 42 + SRI(OTG_H_BLANK_START_END, OTG, inst),\ 43 + SRI(OTG_H_SYNC_A, OTG, inst),\ 44 + SRI(OTG_H_SYNC_A_CNTL, OTG, inst),\ 45 + SRI(OTG_H_TIMING_CNTL, OTG, inst),\ 46 + SRI(OTG_V_TOTAL, OTG, inst),\ 47 + SRI(OTG_V_BLANK_START_END, OTG, inst),\ 48 + SRI(OTG_V_SYNC_A, OTG, inst),\ 49 + SRI(OTG_V_SYNC_A_CNTL, OTG, inst),\ 50 + SRI(OTG_INTERLACE_CONTROL, OTG, inst),\ 51 + SRI(OTG_CONTROL, OTG, inst),\ 52 + SRI(OTG_STEREO_CONTROL, OTG, inst),\ 53 + SRI(OTG_3D_STRUCTURE_CONTROL, OTG, inst),\ 54 + SRI(OTG_V_TOTAL_MAX, OTG, inst),\ 55 + SRI(OTG_V_TOTAL_MIN, OTG, inst),\ 56 + SRI(OTG_V_TOTAL_CONTROL, OTG, inst),\ 57 + SRI(OTG_TRIGA_CNTL, OTG, inst),\ 58 + SRI(OTG_FORCE_COUNT_NOW_CNTL, OTG, inst),\ 59 + SRI(OTG_STATIC_SCREEN_CONTROL, OTG, inst),\ 60 + SRI(OTG_STATUS_FRAME_COUNT, OTG, inst),\ 61 + SRI(OTG_STATUS, OTG, inst),\ 62 + SRI(OTG_STATUS_POSITION, OTG, inst),\ 63 + SRI(OTG_NOM_VERT_POSITION, OTG, inst),\ 64 + SRI(OTG_BLACK_COLOR, OTG, inst),\ 65 + SRI(OTG_TEST_PATTERN_PARAMETERS, OTG, inst),\ 66 + SRI(OTG_TEST_PATTERN_CONTROL, OTG, inst),\ 67 + SRI(OTG_TEST_PATTERN_COLOR, OTG, inst),\ 68 + SRI(OTG_CLOCK_CONTROL, OTG, inst),\ 69 + SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\ 70 + SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\ 71 + SRI(OPPBUF_CONTROL, OPPBUF, inst),\ 72 + SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\ 73 + SRI(CONTROL, VTG, inst),\ 74 + SR(D1VGA_CONTROL),\ 75 + SR(D2VGA_CONTROL),\ 76 + SR(D3VGA_CONTROL),\ 77 + SR(D4VGA_CONTROL),\ 78 + 79 + struct dcn_tg_registers { 80 + uint32_t OTG_VSTARTUP_PARAM; 81 + uint32_t OTG_VUPDATE_PARAM; 82 + uint32_t OTG_VREADY_PARAM; 83 + uint32_t OTG_BLANK_CONTROL; 84 + uint32_t OTG_MASTER_UPDATE_LOCK; 85 + uint32_t OTG_DOUBLE_BUFFER_CONTROL; 86 + uint32_t OTG_H_TOTAL; 87 + uint32_t OTG_H_BLANK_START_END; 88 + uint32_t OTG_H_SYNC_A; 89 + uint32_t OTG_H_SYNC_A_CNTL; 90 + uint32_t OTG_H_TIMING_CNTL; 91 + uint32_t OTG_V_TOTAL; 92 + uint32_t OTG_V_BLANK_START_END; 93 + uint32_t OTG_V_SYNC_A; 94 + uint32_t OTG_V_SYNC_A_CNTL; 95 + uint32_t OTG_INTERLACE_CONTROL; 96 + uint32_t OTG_CONTROL; 97 + uint32_t OTG_STEREO_CONTROL; 98 + uint32_t OTG_3D_STRUCTURE_CONTROL; 99 + uint32_t OTG_V_TOTAL_MAX; 100 + uint32_t OTG_V_TOTAL_MIN; 101 + uint32_t OTG_V_TOTAL_CONTROL; 102 + uint32_t OTG_TRIGA_CNTL; 103 + uint32_t OTG_FORCE_COUNT_NOW_CNTL; 104 + uint32_t OTG_STATIC_SCREEN_CONTROL; 105 + uint32_t OTG_STATUS_FRAME_COUNT; 106 + uint32_t OTG_STATUS; 107 + uint32_t OTG_STATUS_POSITION; 108 + uint32_t OTG_NOM_VERT_POSITION; 109 + uint32_t OTG_BLACK_COLOR; 110 + uint32_t OTG_TEST_PATTERN_PARAMETERS; 111 + uint32_t OTG_TEST_PATTERN_CONTROL; 112 + uint32_t OTG_TEST_PATTERN_COLOR; 113 + uint32_t OTG_CLOCK_CONTROL; 114 + uint32_t OPTC_INPUT_CLOCK_CONTROL; 115 + uint32_t OPTC_DATA_SOURCE_SELECT; 116 + uint32_t OPPBUF_CONTROL; 117 + uint32_t OPPBUF_3D_PARAMETERS_0; 118 + uint32_t CONTROL; 119 + /*todo: move VGA to HWSS */ 120 + uint32_t D1VGA_CONTROL; 121 + uint32_t D2VGA_CONTROL; 122 + uint32_t D3VGA_CONTROL; 123 + uint32_t D4VGA_CONTROL; 124 + }; 125 + 126 + #define TG_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ 127 + SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\ 128 + SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_OFFSET, mask_sh),\ 129 + SF(OTG0_OTG_VUPDATE_PARAM, VUPDATE_WIDTH, mask_sh),\ 130 + SF(OTG0_OTG_VREADY_PARAM, VREADY_OFFSET, mask_sh),\ 131 + SF(OTG0_OTG_BLANK_CONTROL, OTG_BLANK_DATA_EN, mask_sh),\ 132 + SF(OTG0_OTG_BLANK_CONTROL, OTG_BLANK_DE_MODE, mask_sh),\ 133 + SF(OTG0_OTG_BLANK_CONTROL, OTG_CURRENT_BLANK_STATE, mask_sh),\ 134 + SF(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, mask_sh),\ 135 + SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_UPDATE_PENDING, mask_sh),\ 136 + SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_BLANK_DATA_DOUBLE_BUFFER_EN, mask_sh),\ 137 + SF(OTG0_OTG_H_TOTAL, OTG_H_TOTAL, mask_sh),\ 138 + SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_START, mask_sh),\ 139 + SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_END, mask_sh),\ 140 + SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_START, mask_sh),\ 141 + SF(OTG0_OTG_H_SYNC_A, OTG_H_SYNC_A_END, mask_sh),\ 142 + SF(OTG0_OTG_H_SYNC_A_CNTL, OTG_H_SYNC_A_POL, mask_sh),\ 143 + SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_BY2, mask_sh),\ 144 + SF(OTG0_OTG_V_TOTAL, OTG_V_TOTAL, mask_sh),\ 145 + SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_START, mask_sh),\ 146 + SF(OTG0_OTG_V_BLANK_START_END, OTG_V_BLANK_END, mask_sh),\ 147 + SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_START, mask_sh),\ 148 + SF(OTG0_OTG_V_SYNC_A, OTG_V_SYNC_A_END, mask_sh),\ 149 + SF(OTG0_OTG_V_SYNC_A_CNTL, OTG_V_SYNC_A_POL, mask_sh),\ 150 + SF(OTG0_OTG_INTERLACE_CONTROL, OTG_INTERLACE_ENABLE, mask_sh),\ 151 + SF(OTG0_OTG_CONTROL, OTG_MASTER_EN, mask_sh),\ 152 + SF(OTG0_OTG_CONTROL, OTG_START_POINT_CNTL, mask_sh),\ 153 + SF(OTG0_OTG_CONTROL, OTG_DISABLE_POINT_CNTL, mask_sh),\ 154 + SF(OTG0_OTG_CONTROL, OTG_FIELD_NUMBER_CNTL, mask_sh),\ 155 + SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EN, mask_sh),\ 156 + SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_LINE_NUM, mask_sh),\ 157 + SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_POLARITY, mask_sh),\ 158 + SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EYE_FLAG_POLARITY, mask_sh),\ 159 + SF(OTG0_OTG_STEREO_CONTROL, OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, mask_sh),\ 160 + SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_EN, mask_sh),\ 161 + SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_V_UPDATE_MODE, mask_sh),\ 162 + SF(OTG0_OTG_3D_STRUCTURE_CONTROL, OTG_3D_STRUCTURE_STEREO_SEL_OVR, mask_sh),\ 163 + SF(OTG0_OTG_V_TOTAL_MAX, OTG_V_TOTAL_MAX, mask_sh),\ 164 + SF(OTG0_OTG_V_TOTAL_MIN, OTG_V_TOTAL_MIN, mask_sh),\ 165 + SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MIN_SEL, mask_sh),\ 166 + SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_V_TOTAL_MAX_SEL, mask_sh),\ 167 + SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_FORCE_LOCK_ON_EVENT, mask_sh),\ 168 + SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK_EN, mask_sh),\ 169 + SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK, mask_sh),\ 170 + SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_CLEAR, mask_sh),\ 171 + SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_MODE, mask_sh),\ 172 + SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_OCCURRED, mask_sh),\ 173 + SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_SELECT, mask_sh),\ 174 + SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_SOURCE_PIPE_SELECT, mask_sh),\ 175 + SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_RISING_EDGE_DETECT_CNTL, mask_sh),\ 176 + SF(OTG0_OTG_TRIGA_CNTL, OTG_TRIGA_FALLING_EDGE_DETECT_CNTL, mask_sh),\ 177 + SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_EVENT_MASK, mask_sh),\ 178 + SF(OTG0_OTG_STATIC_SCREEN_CONTROL, OTG_STATIC_SCREEN_FRAME_COUNT, mask_sh),\ 179 + SF(OTG0_OTG_STATUS_FRAME_COUNT, OTG_FRAME_COUNT, mask_sh),\ 180 + SF(OTG0_OTG_STATUS, OTG_V_BLANK, mask_sh),\ 181 + SF(OTG0_OTG_STATUS, OTG_V_ACTIVE_DISP, mask_sh),\ 182 + SF(OTG0_OTG_STATUS_POSITION, OTG_HORZ_COUNT, mask_sh),\ 183 + SF(OTG0_OTG_STATUS_POSITION, OTG_VERT_COUNT, mask_sh),\ 184 + SF(OTG0_OTG_NOM_VERT_POSITION, OTG_VERT_COUNT_NOM, mask_sh),\ 185 + SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_B_CB, mask_sh),\ 186 + SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_G_Y, mask_sh),\ 187 + SF(OTG0_OTG_BLACK_COLOR, OTG_BLACK_COLOR_R_CR, mask_sh),\ 188 + SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_INC0, mask_sh),\ 189 + SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_INC1, mask_sh),\ 190 + SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_VRES, mask_sh),\ 191 + SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_HRES, mask_sh),\ 192 + SF(OTG0_OTG_TEST_PATTERN_PARAMETERS, OTG_TEST_PATTERN_RAMP0_OFFSET, mask_sh),\ 193 + SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_EN, mask_sh),\ 194 + SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_MODE, mask_sh),\ 195 + SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_DYNAMIC_RANGE, mask_sh),\ 196 + SF(OTG0_OTG_TEST_PATTERN_CONTROL, OTG_TEST_PATTERN_COLOR_FORMAT, mask_sh),\ 197 + SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_MASK, mask_sh),\ 198 + SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_DATA, mask_sh),\ 199 + SF(OTG0_OTG_CLOCK_CONTROL, OTG_BUSY, mask_sh),\ 200 + SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\ 201 + SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\ 202 + SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\ 203 + SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\ 204 + SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\ 205 + SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_GATE_DIS, mask_sh),\ 206 + SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SRC_SEL, mask_sh),\ 207 + SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\ 208 + SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh),\ 209 + SF(VTG0_CONTROL, VTG0_ENABLE, mask_sh),\ 210 + SF(VTG0_CONTROL, VTG0_FP2, mask_sh),\ 211 + SF(VTG0_CONTROL, VTG0_VCOUNT_INIT, mask_sh),\ 212 + 213 + #define TG_REG_FIELD_LIST(type) \ 214 + type VSTARTUP_START;\ 215 + type VUPDATE_OFFSET;\ 216 + type VUPDATE_WIDTH;\ 217 + type VREADY_OFFSET;\ 218 + type OTG_BLANK_DATA_EN;\ 219 + type OTG_BLANK_DE_MODE;\ 220 + type OTG_CURRENT_BLANK_STATE;\ 221 + type OTG_MASTER_UPDATE_LOCK;\ 222 + type OTG_UPDATE_PENDING;\ 223 + type OTG_BLANK_DATA_DOUBLE_BUFFER_EN;\ 224 + type OTG_H_TOTAL;\ 225 + type OTG_H_BLANK_START;\ 226 + type OTG_H_BLANK_END;\ 227 + type OTG_H_SYNC_A_START;\ 228 + type OTG_H_SYNC_A_END;\ 229 + type OTG_H_SYNC_A_POL;\ 230 + type OTG_H_TIMING_DIV_BY2;\ 231 + type OTG_V_TOTAL;\ 232 + type OTG_V_BLANK_START;\ 233 + type OTG_V_BLANK_END;\ 234 + type OTG_V_SYNC_A_START;\ 235 + type OTG_V_SYNC_A_END;\ 236 + type OTG_V_SYNC_A_POL;\ 237 + type OTG_INTERLACE_ENABLE;\ 238 + type OTG_MASTER_EN;\ 239 + type OTG_START_POINT_CNTL;\ 240 + type OTG_DISABLE_POINT_CNTL;\ 241 + type OTG_FIELD_NUMBER_CNTL;\ 242 + type OTG_STEREO_EN;\ 243 + type OTG_STEREO_SYNC_OUTPUT_LINE_NUM;\ 244 + type OTG_STEREO_SYNC_OUTPUT_POLARITY;\ 245 + type OTG_STEREO_EYE_FLAG_POLARITY;\ 246 + type OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP;\ 247 + type OTG_3D_STRUCTURE_EN;\ 248 + type OTG_3D_STRUCTURE_V_UPDATE_MODE;\ 249 + type OTG_3D_STRUCTURE_STEREO_SEL_OVR;\ 250 + type OTG_V_TOTAL_MAX;\ 251 + type OTG_V_TOTAL_MIN;\ 252 + type OTG_V_TOTAL_MIN_SEL;\ 253 + type OTG_V_TOTAL_MAX_SEL;\ 254 + type OTG_FORCE_LOCK_ON_EVENT;\ 255 + type OTG_SET_V_TOTAL_MIN_MASK_EN;\ 256 + type OTG_SET_V_TOTAL_MIN_MASK;\ 257 + type OTG_FORCE_COUNT_NOW_CLEAR;\ 258 + type OTG_FORCE_COUNT_NOW_MODE;\ 259 + type OTG_FORCE_COUNT_NOW_OCCURRED;\ 260 + type OTG_TRIGA_SOURCE_SELECT;\ 261 + type OTG_TRIGA_SOURCE_PIPE_SELECT;\ 262 + type OTG_TRIGA_RISING_EDGE_DETECT_CNTL;\ 263 + type OTG_TRIGA_FALLING_EDGE_DETECT_CNTL;\ 264 + type OTG_STATIC_SCREEN_EVENT_MASK;\ 265 + type OTG_STATIC_SCREEN_FRAME_COUNT;\ 266 + type OTG_FRAME_COUNT;\ 267 + type OTG_V_BLANK;\ 268 + type OTG_V_ACTIVE_DISP;\ 269 + type OTG_HORZ_COUNT;\ 270 + type OTG_VERT_COUNT;\ 271 + type OTG_VERT_COUNT_NOM;\ 272 + type OTG_BLACK_COLOR_B_CB;\ 273 + type OTG_BLACK_COLOR_G_Y;\ 274 + type OTG_BLACK_COLOR_R_CR;\ 275 + type OTG_TEST_PATTERN_INC0;\ 276 + type OTG_TEST_PATTERN_INC1;\ 277 + type OTG_TEST_PATTERN_VRES;\ 278 + type OTG_TEST_PATTERN_HRES;\ 279 + type OTG_TEST_PATTERN_RAMP0_OFFSET;\ 280 + type OTG_TEST_PATTERN_EN;\ 281 + type OTG_TEST_PATTERN_MODE;\ 282 + type OTG_TEST_PATTERN_DYNAMIC_RANGE;\ 283 + type OTG_TEST_PATTERN_COLOR_FORMAT;\ 284 + type OTG_TEST_PATTERN_MASK;\ 285 + type OTG_TEST_PATTERN_DATA;\ 286 + type OTG_BUSY;\ 287 + type OTG_CLOCK_EN;\ 288 + type OTG_CLOCK_ON;\ 289 + type OTG_CLOCK_GATE_DIS;\ 290 + type OPTC_INPUT_CLK_EN;\ 291 + type OPTC_INPUT_CLK_ON;\ 292 + type OPTC_INPUT_CLK_GATE_DIS;\ 293 + type OPTC_SRC_SEL;\ 294 + type OPPBUF_ACTIVE_WIDTH;\ 295 + type OPPBUF_3D_VACT_SPACE1_SIZE;\ 296 + type VTG0_ENABLE;\ 297 + type VTG0_FP2;\ 298 + type VTG0_VCOUNT_INIT;\ 299 + 300 + struct dcn_tg_shift { 301 + TG_REG_FIELD_LIST(uint8_t) 302 + }; 303 + 304 + struct dcn_tg_mask { 305 + TG_REG_FIELD_LIST(uint32_t) 306 + }; 307 + 308 + struct dcn10_timing_generator { 309 + struct timing_generator base; 310 + 311 + const struct dcn_tg_registers *tg_regs; 312 + const struct dcn_tg_shift *tg_shift; 313 + const struct dcn_tg_mask *tg_mask; 314 + 315 + enum controller_id controller_id; 316 + 317 + uint32_t max_h_total; 318 + uint32_t max_v_total; 319 + 320 + uint32_t min_h_blank; 321 + 322 + uint32_t min_h_sync_width; 323 + uint32_t min_v_sync_width; 324 + uint32_t min_v_blank; 325 + uint32_t min_v_blank_interlace; 326 + }; 327 + 328 + void dcn10_timing_generator_init(struct dcn10_timing_generator *tg); 329 + 330 + void dcn10_timing_generator_set_drr(struct timing_generator *tg, 331 + const struct drr_params *params); 332 + 333 + void dcn10_unlock(struct timing_generator *tg); 334 + void dcn10_lock(struct timing_generator *tg); 335 + #endif /* __DC_TIMING_GENERATOR_DCN10_H__ */
+1057
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_transform.c
··· 1 + /* 2 + * Copyright 2016 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 "dm_services.h" 27 + 28 + #include "core_types.h" 29 + 30 + #include "include/grph_object_id.h" 31 + #include "include/fixed31_32.h" 32 + #include "include/logger_interface.h" 33 + 34 + #include "reg_helper.h" 35 + #include "dcn10_transform.h" 36 + #include "basics/conversion.h" 37 + 38 + #define NUM_PHASES 64 39 + #define HORZ_MAX_TAPS 8 40 + #define VERT_MAX_TAPS 8 41 + 42 + #define BLACK_OFFSET_RGB_Y 0x0 43 + #define BLACK_OFFSET_CBCR 0x8000 44 + 45 + #define REG(reg)\ 46 + xfm->tf_regs->reg 47 + 48 + #define CTX \ 49 + xfm->base.ctx 50 + 51 + #undef FN 52 + #define FN(reg_name, field_name) \ 53 + xfm->tf_shift->field_name, xfm->tf_mask->field_name 54 + 55 + 56 + enum dcn10_coef_filter_type_sel { 57 + SCL_COEF_LUMA_VERT_FILTER = 0, 58 + SCL_COEF_LUMA_HORZ_FILTER = 1, 59 + SCL_COEF_CHROMA_VERT_FILTER = 2, 60 + SCL_COEF_CHROMA_HORZ_FILTER = 3, 61 + SCL_COEF_ALPHA_VERT_FILTER = 4, 62 + SCL_COEF_ALPHA_HORZ_FILTER = 5 63 + }; 64 + 65 + enum lb_memory_config { 66 + /* Enable all 3 pieces of memory */ 67 + LB_MEMORY_CONFIG_0 = 0, 68 + 69 + /* Enable only the first piece of memory */ 70 + LB_MEMORY_CONFIG_1 = 1, 71 + 72 + /* Enable only the second piece of memory */ 73 + LB_MEMORY_CONFIG_2 = 2, 74 + 75 + /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the 76 + * last piece of chroma memory used for the luma storage 77 + */ 78 + LB_MEMORY_CONFIG_3 = 3 79 + }; 80 + 81 + enum dscl_autocal_mode { 82 + AUTOCAL_MODE_OFF = 0, 83 + 84 + /* Autocal calculate the scaling ratio and initial phase and the 85 + * DSCL_MODE_SEL must be set to 1 86 + */ 87 + AUTOCAL_MODE_AUTOSCALE = 1, 88 + /* Autocal perform auto centering without replication and the 89 + * DSCL_MODE_SEL must be set to 0 90 + */ 91 + AUTOCAL_MODE_AUTOCENTER = 2, 92 + /* Autocal perform auto centering and auto replication and the 93 + * DSCL_MODE_SEL must be set to 0 94 + */ 95 + AUTOCAL_MODE_AUTOREPLICATE = 3 96 + }; 97 + 98 + enum dscl_mode_sel { 99 + DSCL_MODE_SCALING_444_BYPASS = 0, 100 + DSCL_MODE_SCALING_444_RGB_ENABLE = 1, 101 + DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2, 102 + DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3, 103 + DSCL_MODE_SCALING_420_LUMA_BYPASS = 4, 104 + DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5, 105 + DSCL_MODE_DSCL_BYPASS = 6 106 + }; 107 + 108 + enum gamut_remap_select { 109 + GAMUT_REMAP_BYPASS = 0, 110 + GAMUT_REMAP_COEFF, 111 + GAMUT_REMAP_COMA_COEFF, 112 + GAMUT_REMAP_COMB_COEFF 113 + }; 114 + 115 + static void transform_set_overscan( 116 + struct dcn10_transform *xfm, 117 + const struct scaler_data *data) 118 + { 119 + uint32_t left = data->recout.x; 120 + uint32_t top = data->recout.y; 121 + 122 + int right = data->h_active - data->recout.x - data->recout.width; 123 + int bottom = data->v_active - data->recout.y - data->recout.height; 124 + 125 + if (right < 0) { 126 + BREAK_TO_DEBUGGER(); 127 + right = 0; 128 + } 129 + if (bottom < 0) { 130 + BREAK_TO_DEBUGGER(); 131 + bottom = 0; 132 + } 133 + 134 + REG_SET_2(DSCL_EXT_OVERSCAN_LEFT_RIGHT, 0, 135 + EXT_OVERSCAN_LEFT, left, 136 + EXT_OVERSCAN_RIGHT, right); 137 + 138 + REG_SET_2(DSCL_EXT_OVERSCAN_TOP_BOTTOM, 0, 139 + EXT_OVERSCAN_BOTTOM, bottom, 140 + EXT_OVERSCAN_TOP, top); 141 + } 142 + 143 + static void transform_set_otg_blank( 144 + struct dcn10_transform *xfm, const struct scaler_data *data) 145 + { 146 + uint32_t h_blank_start = data->h_active; 147 + uint32_t h_blank_end = 0; 148 + uint32_t v_blank_start = data->v_active; 149 + uint32_t v_blank_end = 0; 150 + 151 + REG_SET_2(OTG_H_BLANK, 0, 152 + OTG_H_BLANK_START, h_blank_start, 153 + OTG_H_BLANK_END, h_blank_end); 154 + 155 + REG_SET_2(OTG_V_BLANK, 0, 156 + OTG_V_BLANK_START, v_blank_start, 157 + OTG_V_BLANK_END, v_blank_end); 158 + } 159 + 160 + static enum dscl_mode_sel get_dscl_mode(const struct scaler_data *data) 161 + { 162 + const long long one = dal_fixed31_32_one.value; 163 + bool ycbcr = false; 164 + bool format420 = false; 165 + 166 + if (data->format == PIXEL_FORMAT_FP16) 167 + return DSCL_MODE_DSCL_BYPASS; 168 + 169 + if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN 170 + && data->format <= PIXEL_FORMAT_VIDEO_END) 171 + ycbcr = true; 172 + 173 + if (data->format == PIXEL_FORMAT_420BPP12 || 174 + data->format == PIXEL_FORMAT_420BPP15) 175 + format420 = true; 176 + 177 + if (data->ratios.horz.value == one 178 + && data->ratios.vert.value == one 179 + && data->ratios.horz_c.value == one 180 + && data->ratios.vert_c.value == one) 181 + return DSCL_MODE_SCALING_444_BYPASS; 182 + 183 + if (!format420) { 184 + if (ycbcr) 185 + return DSCL_MODE_SCALING_444_YCBCR_ENABLE; 186 + else 187 + return DSCL_MODE_SCALING_444_RGB_ENABLE; 188 + } 189 + if (data->ratios.horz.value == one && data->ratios.vert.value == one) 190 + return DSCL_MODE_SCALING_420_LUMA_BYPASS; 191 + if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one) 192 + return DSCL_MODE_SCALING_420_CHROMA_BYPASS; 193 + 194 + return DSCL_MODE_SCALING_420_YCBCR_ENABLE; 195 + } 196 + 197 + static int get_pixel_depth_val(enum lb_pixel_depth depth) 198 + { 199 + if (depth == LB_PIXEL_DEPTH_30BPP) 200 + return 0; /* 10 bpc */ 201 + else if (depth == LB_PIXEL_DEPTH_24BPP) 202 + return 1; /* 8 bpc */ 203 + else if (depth == LB_PIXEL_DEPTH_18BPP) 204 + return 2; /* 6 bpc */ 205 + else if (depth == LB_PIXEL_DEPTH_36BPP) 206 + return 3; /* 12 bpc */ 207 + else { 208 + ASSERT(0); 209 + return -1; /* Unsupported */ 210 + } 211 + } 212 + 213 + static void transform_set_lb( 214 + struct dcn10_transform *xfm, 215 + const struct line_buffer_params *lb_params, 216 + enum lb_memory_config mem_size_config) 217 + { 218 + uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); 219 + uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; 220 + REG_SET_7(LB_DATA_FORMAT, 0, 221 + PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */ 222 + PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */ 223 + PIXEL_REDUCE_MODE, 1, /* Pixel reduction mode: Rounding */ 224 + DYNAMIC_PIXEL_DEPTH, dyn_pix_depth, /* Dynamic expansion pixel depth */ 225 + DITHER_EN, 0, /* Dithering enable: Disabled */ 226 + INTERLEAVE_EN, lb_params->interleave_en, /* Interleave source enable */ 227 + ALPHA_EN, lb_params->alpha_en); /* Alpha enable */ 228 + 229 + REG_SET_2(LB_MEMORY_CTRL, 0, 230 + MEMORY_CONFIG, mem_size_config, 231 + LB_MAX_PARTITIONS, 63); 232 + } 233 + 234 + static void transform_set_scaler_filter( 235 + struct dcn10_transform *xfm, 236 + uint32_t taps, 237 + enum dcn10_coef_filter_type_sel filter_type, 238 + const uint16_t *filter) 239 + { 240 + const int tap_pairs = (taps + 1) / 2; 241 + int phase; 242 + int pair; 243 + uint16_t odd_coef, even_coef; 244 + 245 + REG_SET_3(SCL_COEF_RAM_TAP_SELECT, 0, 246 + SCL_COEF_RAM_TAP_PAIR_IDX, 0, 247 + SCL_COEF_RAM_PHASE, 0, 248 + SCL_COEF_RAM_FILTER_TYPE, filter_type); 249 + 250 + for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { 251 + for (pair = 0; pair < tap_pairs; pair++) { 252 + even_coef = filter[phase * taps + 2 * pair]; 253 + if ((pair * 2 + 1) < taps) 254 + odd_coef = filter[phase * taps + 2 * pair + 1]; 255 + else 256 + odd_coef = 0; 257 + 258 + REG_SET_4(SCL_COEF_RAM_TAP_DATA, 0, 259 + /* Even tap coefficient (bits 1:0 fixed to 0) */ 260 + SCL_COEF_RAM_EVEN_TAP_COEF, even_coef, 261 + /* Write/read control for even coefficient */ 262 + SCL_COEF_RAM_EVEN_TAP_COEF_EN, 1, 263 + /* Odd tap coefficient (bits 1:0 fixed to 0) */ 264 + SCL_COEF_RAM_ODD_TAP_COEF, odd_coef, 265 + /* Write/read control for odd coefficient */ 266 + SCL_COEF_RAM_ODD_TAP_COEF_EN, 1); 267 + } 268 + } 269 + 270 + } 271 + 272 + #if 0 273 + bool transform_set_pixel_storage_depth( 274 + struct transform *xfm, 275 + enum lb_pixel_depth depth, 276 + const struct bit_depth_reduction_params *bit_depth_params) 277 + { 278 + struct dcn10_transform *xfm110 = TO_DCN10_TRANSFORM(xfm); 279 + bool ret = true; 280 + uint32_t value; 281 + enum dc_color_depth color_depth; 282 + 283 + value = dm_read_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT)); 284 + switch (depth) { 285 + case LB_PIXEL_DEPTH_18BPP: 286 + color_depth = COLOR_DEPTH_666; 287 + set_reg_field_value(value, 2, LB_DATA_FORMAT, PIXEL_DEPTH); 288 + set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 289 + break; 290 + case LB_PIXEL_DEPTH_24BPP: 291 + color_depth = COLOR_DEPTH_888; 292 + set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_DEPTH); 293 + set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 294 + break; 295 + case LB_PIXEL_DEPTH_30BPP: 296 + color_depth = COLOR_DEPTH_101010; 297 + set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_DEPTH); 298 + set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 299 + break; 300 + case LB_PIXEL_DEPTH_36BPP: 301 + color_depth = COLOR_DEPTH_121212; 302 + set_reg_field_value(value, 3, LB_DATA_FORMAT, PIXEL_DEPTH); 303 + set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); 304 + break; 305 + default: 306 + ret = false; 307 + break; 308 + } 309 + 310 + if (ret == true) { 311 + set_denormalization(xfm110, color_depth); 312 + ret = program_bit_depth_reduction(xfm110, color_depth, 313 + bit_depth_params); 314 + 315 + set_reg_field_value(value, 0, LB_DATA_FORMAT, ALPHA_EN); 316 + dm_write_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT), value); 317 + if (!(xfm110->lb_pixel_depth_supported & depth)) { 318 + /* We should use unsupported capabilities 319 + * unless it is required by w/a 320 + */ 321 + dm_logger_write(xfm->ctx->logger, LOG_WARNING, 322 + "%s: Capability not supported", 323 + __func__); 324 + } 325 + } 326 + 327 + return ret; 328 + } 329 + #endif 330 + 331 + static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) 332 + { 333 + if (taps == 8) 334 + return get_filter_8tap_64p(ratio); 335 + else if (taps == 7) 336 + return get_filter_7tap_64p(ratio); 337 + else if (taps == 6) 338 + return get_filter_6tap_64p(ratio); 339 + else if (taps == 5) 340 + return get_filter_5tap_64p(ratio); 341 + else if (taps == 4) 342 + return get_filter_4tap_64p(ratio); 343 + else if (taps == 3) 344 + return get_filter_3tap_64p(ratio); 345 + else if (taps == 2) 346 + return filter_2tap_64p; 347 + else if (taps == 1) 348 + return NULL; 349 + else { 350 + /* should never happen, bug */ 351 + BREAK_TO_DEBUGGER(); 352 + return NULL; 353 + } 354 + } 355 + 356 + static void transform_set_scl_filter( 357 + struct dcn10_transform *xfm, 358 + const struct scaler_data *scl_data, 359 + bool chroma_coef_mode) 360 + { 361 + bool h_2tap_hardcode_coef_en = false; 362 + bool v_2tap_hardcode_coef_en = false; 363 + bool h_2tap_sharp_en = false; 364 + bool v_2tap_sharp_en = false; 365 + uint32_t h_2tap_sharp_factor = scl_data->sharpness.horz; 366 + uint32_t v_2tap_sharp_factor = scl_data->sharpness.vert; 367 + bool coef_ram_current; 368 + const uint16_t *filter_h = NULL; 369 + const uint16_t *filter_v = NULL; 370 + const uint16_t *filter_h_c = NULL; 371 + const uint16_t *filter_v_c = NULL; 372 + 373 + h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3 374 + && scl_data->taps.h_taps_c < 3 375 + && (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1); 376 + v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3 377 + && scl_data->taps.v_taps_c < 3 378 + && (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1); 379 + 380 + h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0; 381 + v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0; 382 + 383 + REG_UPDATE_6(DSCL_2TAP_CONTROL, 384 + SCL_H_2TAP_HARDCODE_COEF_EN, h_2tap_hardcode_coef_en, 385 + SCL_H_2TAP_SHARP_EN, h_2tap_sharp_en, 386 + SCL_H_2TAP_SHARP_FACTOR, h_2tap_sharp_factor, 387 + SCL_V_2TAP_HARDCODE_COEF_EN, v_2tap_hardcode_coef_en, 388 + SCL_V_2TAP_SHARP_EN, v_2tap_sharp_en, 389 + SCL_V_2TAP_SHARP_FACTOR, v_2tap_sharp_factor); 390 + 391 + if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) { 392 + bool filter_updated = false; 393 + 394 + filter_h = get_filter_coeffs_64p( 395 + scl_data->taps.h_taps, scl_data->ratios.horz); 396 + filter_v = get_filter_coeffs_64p( 397 + scl_data->taps.v_taps, scl_data->ratios.vert); 398 + 399 + filter_updated = (filter_h && (filter_h != xfm->filter_h)) 400 + || (filter_v && (filter_v != xfm->filter_v)); 401 + 402 + if (chroma_coef_mode) { 403 + filter_h_c = get_filter_coeffs_64p( 404 + scl_data->taps.h_taps_c, scl_data->ratios.horz_c); 405 + filter_v_c = get_filter_coeffs_64p( 406 + scl_data->taps.v_taps_c, scl_data->ratios.vert_c); 407 + filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c)) 408 + || (filter_v_c && (filter_v_c != xfm->filter_v_c)); 409 + } 410 + 411 + if (filter_updated) { 412 + uint32_t scl_mode = REG_READ(SCL_MODE); 413 + 414 + if (!h_2tap_hardcode_coef_en && filter_h) { 415 + transform_set_scaler_filter( 416 + xfm, scl_data->taps.h_taps, 417 + SCL_COEF_LUMA_HORZ_FILTER, filter_h); 418 + } 419 + xfm->filter_h = filter_h; 420 + if (!v_2tap_hardcode_coef_en && filter_v) { 421 + transform_set_scaler_filter( 422 + xfm, scl_data->taps.v_taps, 423 + SCL_COEF_LUMA_VERT_FILTER, filter_v); 424 + } 425 + xfm->filter_v = filter_v; 426 + if (chroma_coef_mode) { 427 + if (!h_2tap_hardcode_coef_en && filter_h_c) { 428 + transform_set_scaler_filter( 429 + xfm, scl_data->taps.h_taps_c, 430 + SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c); 431 + } 432 + if (!v_2tap_hardcode_coef_en && filter_v_c) { 433 + transform_set_scaler_filter( 434 + xfm, scl_data->taps.v_taps_c, 435 + SCL_COEF_CHROMA_VERT_FILTER, filter_v_c); 436 + } 437 + } 438 + xfm->filter_h_c = filter_h_c; 439 + xfm->filter_v_c = filter_v_c; 440 + 441 + coef_ram_current = get_reg_field_value_ex( 442 + scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT, 443 + xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT); 444 + 445 + /* Swap coefficient RAM and set chroma coefficient mode */ 446 + REG_SET_2(SCL_MODE, scl_mode, 447 + SCL_COEF_RAM_SELECT, !coef_ram_current, 448 + SCL_CHROMA_COEF_MODE, chroma_coef_mode); 449 + } 450 + } 451 + } 452 + 453 + static void transform_set_viewport( 454 + struct dcn10_transform *xfm, 455 + const struct rect *viewport, 456 + const struct rect *viewport_c) 457 + { 458 + REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0, 459 + PRI_VIEWPORT_WIDTH, viewport->width, 460 + PRI_VIEWPORT_HEIGHT, viewport->height); 461 + 462 + REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0, 463 + PRI_VIEWPORT_X_START, viewport->x, 464 + PRI_VIEWPORT_Y_START, viewport->y); 465 + 466 + /*for stereo*/ 467 + REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0, 468 + SEC_VIEWPORT_WIDTH, viewport->width, 469 + SEC_VIEWPORT_HEIGHT, viewport->height); 470 + 471 + REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0, 472 + SEC_VIEWPORT_X_START, viewport->x, 473 + SEC_VIEWPORT_Y_START, viewport->y); 474 + 475 + /* DC supports NV12 only at the moment */ 476 + REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0, 477 + PRI_VIEWPORT_WIDTH_C, viewport_c->width, 478 + PRI_VIEWPORT_HEIGHT_C, viewport_c->height); 479 + 480 + REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0, 481 + PRI_VIEWPORT_X_START_C, viewport_c->x, 482 + PRI_VIEWPORT_Y_START_C, viewport_c->y); 483 + } 484 + 485 + static int get_lb_depth_bpc(enum lb_pixel_depth depth) 486 + { 487 + if (depth == LB_PIXEL_DEPTH_30BPP) 488 + return 10; 489 + else if (depth == LB_PIXEL_DEPTH_24BPP) 490 + return 8; 491 + else if (depth == LB_PIXEL_DEPTH_18BPP) 492 + return 6; 493 + else if (depth == LB_PIXEL_DEPTH_36BPP) 494 + return 12; 495 + else { 496 + BREAK_TO_DEBUGGER(); 497 + return -1; /* Unsupported */ 498 + } 499 + } 500 + 501 + static void calc_lb_num_partitions( 502 + const struct scaler_data *scl_data, 503 + enum lb_memory_config lb_config, 504 + int *num_part_y, 505 + int *num_part_c) 506 + { 507 + int line_size = scl_data->viewport.width < scl_data->recout.width ? 508 + scl_data->viewport.width : scl_data->recout.width; 509 + int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ? 510 + scl_data->viewport_c.width : scl_data->recout.width; 511 + int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth); 512 + int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */ 513 + int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */ 514 + int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */ 515 + int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a; 516 + 517 + if (lb_config == LB_MEMORY_CONFIG_1) { 518 + lb_memory_size = 816; 519 + lb_memory_size_c = 816; 520 + lb_memory_size_a = 984; 521 + } else if (lb_config == LB_MEMORY_CONFIG_2) { 522 + lb_memory_size = 1088; 523 + lb_memory_size_c = 1088; 524 + lb_memory_size_a = 1312; 525 + } else if (lb_config == LB_MEMORY_CONFIG_3) { 526 + lb_memory_size = 816 + 1088 + 848 + 848 + 848; 527 + lb_memory_size_c = 816 + 1088; 528 + lb_memory_size_a = 984 + 1312 + 456; 529 + } else { 530 + lb_memory_size = 816 + 1088 + 848; 531 + lb_memory_size_c = 816 + 1088 + 848; 532 + lb_memory_size_a = 984 + 1312 + 456; 533 + } 534 + *num_part_y = lb_memory_size / memory_line_size_y; 535 + *num_part_c = lb_memory_size_c / memory_line_size_c; 536 + num_partitions_a = lb_memory_size_a / memory_line_size_a; 537 + 538 + if (scl_data->lb_params.alpha_en 539 + && (num_partitions_a < *num_part_y)) 540 + *num_part_y = num_partitions_a; 541 + 542 + if (*num_part_y > 64) 543 + *num_part_y = 64; 544 + if (*num_part_c > 64) 545 + *num_part_c = 64; 546 + 547 + } 548 + 549 + static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) 550 + { 551 + if (ceil_vratio > 2) 552 + return vtaps <= (num_partitions - ceil_vratio + 2); 553 + else 554 + return vtaps <= num_partitions; 555 + } 556 + 557 + /*find first match configuration which meets the min required lb size*/ 558 + static enum lb_memory_config find_lb_memory_config(const struct scaler_data *scl_data) 559 + { 560 + int num_part_y, num_part_c; 561 + int vtaps = scl_data->taps.v_taps; 562 + int vtaps_c = scl_data->taps.v_taps_c; 563 + int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); 564 + int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); 565 + 566 + calc_lb_num_partitions( 567 + scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); 568 + 569 + if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 570 + && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 571 + return LB_MEMORY_CONFIG_1; 572 + 573 + calc_lb_num_partitions( 574 + scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); 575 + 576 + if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 577 + && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 578 + return LB_MEMORY_CONFIG_2; 579 + 580 + if (scl_data->format == PIXEL_FORMAT_420BPP12 581 + || scl_data->format == PIXEL_FORMAT_420BPP15) { 582 + calc_lb_num_partitions( 583 + scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); 584 + 585 + if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 586 + && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 587 + return LB_MEMORY_CONFIG_3; 588 + } 589 + 590 + calc_lb_num_partitions( 591 + scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); 592 + 593 + /*Ensure we can support the requested number of vtaps*/ 594 + ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 595 + && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)); 596 + 597 + return LB_MEMORY_CONFIG_0; 598 + } 599 + 600 + void transform_set_scaler_auto_scale( 601 + struct transform *xfm_base, 602 + const struct scaler_data *scl_data) 603 + { 604 + enum lb_memory_config lb_config; 605 + struct dcn10_transform *xfm = TO_DCN10_TRANSFORM(xfm_base); 606 + enum dscl_mode_sel dscl_mode = get_dscl_mode(scl_data); 607 + bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN 608 + && scl_data->format <= PIXEL_FORMAT_VIDEO_END; 609 + 610 + transform_set_overscan(xfm, scl_data); 611 + 612 + transform_set_otg_blank(xfm, scl_data); 613 + 614 + REG_UPDATE(SCL_MODE, DSCL_MODE, get_dscl_mode(scl_data)); 615 + 616 + transform_set_viewport(xfm, &scl_data->viewport, &scl_data->viewport_c); 617 + 618 + if (dscl_mode == DSCL_MODE_DSCL_BYPASS) 619 + return; 620 + 621 + lb_config = find_lb_memory_config(scl_data); 622 + transform_set_lb(xfm, &scl_data->lb_params, lb_config); 623 + 624 + if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) 625 + return; 626 + 627 + /* TODO: v_min */ 628 + REG_SET_3(DSCL_AUTOCAL, 0, 629 + AUTOCAL_MODE, AUTOCAL_MODE_AUTOSCALE, 630 + AUTOCAL_NUM_PIPE, 0, 631 + AUTOCAL_PIPE_ID, 0); 632 + 633 + /* Black offsets */ 634 + if (ycbcr) 635 + REG_SET_2(SCL_BLACK_OFFSET, 0, 636 + SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 637 + SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); 638 + else 639 + 640 + REG_SET_2(SCL_BLACK_OFFSET, 0, 641 + SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 642 + SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); 643 + 644 + REG_SET_4(SCL_TAP_CONTROL, 0, 645 + SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, 646 + SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, 647 + SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, 648 + SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); 649 + 650 + transform_set_scl_filter(xfm, scl_data, ycbcr); 651 + } 652 + 653 + /* Program gamut remap in bypass mode */ 654 + void transform_set_gamut_remap_bypass(struct dcn10_transform *xfm) 655 + { 656 + REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 657 + CM_GAMUT_REMAP_MODE, 0); 658 + /* Gamut remap in bypass */ 659 + } 660 + 661 + static void transform_set_recout( 662 + struct dcn10_transform *xfm, const struct rect *recout) 663 + { 664 + REG_SET_2(RECOUT_START, 0, 665 + /* First pixel of RECOUT */ 666 + RECOUT_START_X, recout->x, 667 + /* First line of RECOUT */ 668 + RECOUT_START_Y, recout->y); 669 + 670 + REG_SET_2(RECOUT_SIZE, 0, 671 + /* Number of RECOUT horizontal pixels */ 672 + RECOUT_WIDTH, recout->width, 673 + /* Number of RECOUT vertical lines */ 674 + RECOUT_HEIGHT, recout->height 675 + - xfm->base.ctx->dc->debug.surface_visual_confirm * 2); 676 + } 677 + 678 + static void transform_set_manual_ratio_init( 679 + struct dcn10_transform *xfm, const struct scaler_data *data) 680 + { 681 + uint32_t init_frac = 0; 682 + uint32_t init_int = 0; 683 + 684 + REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0, 685 + SCL_H_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.horz) << 5); 686 + 687 + REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0, 688 + SCL_V_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.vert) << 5); 689 + 690 + REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0, 691 + SCL_H_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.horz_c) << 5); 692 + 693 + REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0, 694 + SCL_V_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.vert_c) << 5); 695 + 696 + /* 697 + * 0.24 format for fraction, first five bits zeroed 698 + */ 699 + init_frac = dal_fixed31_32_u0d19(data->inits.h) << 5; 700 + init_int = dal_fixed31_32_floor(data->inits.h); 701 + REG_SET_2(SCL_HORZ_FILTER_INIT, 0, 702 + SCL_H_INIT_FRAC, init_frac, 703 + SCL_H_INIT_INT, init_int); 704 + 705 + init_frac = dal_fixed31_32_u0d19(data->inits.h_c) << 5; 706 + init_int = dal_fixed31_32_floor(data->inits.h_c); 707 + REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0, 708 + SCL_H_INIT_FRAC_C, init_frac, 709 + SCL_H_INIT_INT_C, init_int); 710 + 711 + init_frac = dal_fixed31_32_u0d19(data->inits.v) << 5; 712 + init_int = dal_fixed31_32_floor(data->inits.v); 713 + REG_SET_2(SCL_VERT_FILTER_INIT, 0, 714 + SCL_V_INIT_FRAC, init_frac, 715 + SCL_V_INIT_INT, init_int); 716 + 717 + init_frac = dal_fixed31_32_u0d19(data->inits.v_bot) << 5; 718 + init_int = dal_fixed31_32_floor(data->inits.v_bot); 719 + REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0, 720 + SCL_V_INIT_FRAC_BOT, init_frac, 721 + SCL_V_INIT_INT_BOT, init_int); 722 + 723 + init_frac = dal_fixed31_32_u0d19(data->inits.v_c) << 5; 724 + init_int = dal_fixed31_32_floor(data->inits.v_c); 725 + REG_SET_2(SCL_VERT_FILTER_INIT_C, 0, 726 + SCL_V_INIT_FRAC_C, init_frac, 727 + SCL_V_INIT_INT_C, init_int); 728 + 729 + init_frac = dal_fixed31_32_u0d19(data->inits.v_c_bot) << 5; 730 + init_int = dal_fixed31_32_floor(data->inits.v_c_bot); 731 + REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0, 732 + SCL_V_INIT_FRAC_BOT_C, init_frac, 733 + SCL_V_INIT_INT_BOT_C, init_int); 734 + } 735 + 736 + /* Main function to program scaler and line buffer in manual scaling mode */ 737 + static void transform_set_scaler_manual_scale( 738 + struct transform *xfm_base, 739 + const struct scaler_data *scl_data) 740 + { 741 + enum lb_memory_config lb_config; 742 + struct dcn10_transform *xfm = TO_DCN10_TRANSFORM(xfm_base); 743 + enum dscl_mode_sel dscl_mode = get_dscl_mode(scl_data); 744 + bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN 745 + && scl_data->format <= PIXEL_FORMAT_VIDEO_END; 746 + 747 + /* Recout */ 748 + transform_set_recout(xfm, &scl_data->recout); 749 + 750 + /* MPC Size */ 751 + REG_SET_2(MPC_SIZE, 0, 752 + /* Number of horizontal pixels of MPC */ 753 + MPC_WIDTH, scl_data->h_active, 754 + /* Number of vertical lines of MPC */ 755 + MPC_HEIGHT, scl_data->v_active); 756 + 757 + /* SCL mode */ 758 + REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); 759 + 760 + /* Viewport */ 761 + transform_set_viewport(xfm, &scl_data->viewport, &scl_data->viewport_c); 762 + 763 + if (dscl_mode == DSCL_MODE_DSCL_BYPASS) 764 + return; 765 + /* LB */ 766 + lb_config = find_lb_memory_config(scl_data); 767 + transform_set_lb(xfm, &scl_data->lb_params, lb_config); 768 + 769 + if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) 770 + return; 771 + 772 + /* Autocal off */ 773 + REG_SET_3(DSCL_AUTOCAL, 0, 774 + AUTOCAL_MODE, AUTOCAL_MODE_OFF, 775 + AUTOCAL_NUM_PIPE, 0, 776 + AUTOCAL_PIPE_ID, 0); 777 + 778 + /* Black offsets */ 779 + if (ycbcr) 780 + REG_SET_2(SCL_BLACK_OFFSET, 0, 781 + SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 782 + SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); 783 + else 784 + 785 + REG_SET_2(SCL_BLACK_OFFSET, 0, 786 + SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, 787 + SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); 788 + 789 + /* Manually calculate scale ratio and init values */ 790 + transform_set_manual_ratio_init(xfm, scl_data); 791 + 792 + /* HTaps/VTaps */ 793 + REG_SET_4(SCL_TAP_CONTROL, 0, 794 + SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, 795 + SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, 796 + SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, 797 + SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); 798 + 799 + transform_set_scl_filter(xfm, scl_data, ycbcr); 800 + } 801 + 802 + #define IDENTITY_RATIO(ratio) (dal_fixed31_32_u2d19(ratio) == (1 << 19)) 803 + 804 + 805 + static bool transform_get_optimal_number_of_taps( 806 + struct transform *xfm, 807 + struct scaler_data *scl_data, 808 + const struct scaling_taps *in_taps) 809 + { 810 + uint32_t pixel_width; 811 + 812 + if (scl_data->viewport.width > scl_data->recout.width) 813 + pixel_width = scl_data->recout.width; 814 + else 815 + pixel_width = scl_data->viewport.width; 816 + 817 + /* TODO: add lb check */ 818 + 819 + /* No support for programming ratio of 4, drop to 3.99999.. */ 820 + if (scl_data->ratios.horz.value == (4ll << 32)) 821 + scl_data->ratios.horz.value--; 822 + if (scl_data->ratios.vert.value == (4ll << 32)) 823 + scl_data->ratios.vert.value--; 824 + if (scl_data->ratios.horz_c.value == (4ll << 32)) 825 + scl_data->ratios.horz_c.value--; 826 + if (scl_data->ratios.vert_c.value == (4ll << 32)) 827 + scl_data->ratios.vert_c.value--; 828 + 829 + /* Set default taps if none are provided */ 830 + if (in_taps->h_taps == 0) 831 + scl_data->taps.h_taps = 4; 832 + else 833 + scl_data->taps.h_taps = in_taps->h_taps; 834 + if (in_taps->v_taps == 0) 835 + scl_data->taps.v_taps = 4; 836 + else 837 + scl_data->taps.v_taps = in_taps->v_taps; 838 + if (in_taps->v_taps_c == 0) 839 + scl_data->taps.v_taps_c = 2; 840 + else 841 + scl_data->taps.v_taps_c = in_taps->v_taps_c; 842 + if (in_taps->h_taps_c == 0) 843 + scl_data->taps.h_taps_c = 2; 844 + /* Only 1 and even h_taps_c are supported by hw */ 845 + else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1) 846 + scl_data->taps.h_taps_c = in_taps->h_taps_c - 1; 847 + else 848 + scl_data->taps.h_taps_c = in_taps->h_taps_c; 849 + 850 + if (IDENTITY_RATIO(scl_data->ratios.horz)) 851 + scl_data->taps.h_taps = 1; 852 + if (IDENTITY_RATIO(scl_data->ratios.vert)) 853 + scl_data->taps.v_taps = 1; 854 + if (IDENTITY_RATIO(scl_data->ratios.horz_c)) 855 + scl_data->taps.h_taps_c = 1; 856 + if (IDENTITY_RATIO(scl_data->ratios.vert_c)) 857 + scl_data->taps.v_taps_c = 1; 858 + 859 + return true; 860 + } 861 + 862 + static void transform_reset(struct transform *xfm_base) 863 + { 864 + struct dcn10_transform *xfm = TO_DCN10_TRANSFORM(xfm_base); 865 + 866 + xfm->filter_h_c = NULL; 867 + xfm->filter_v_c = NULL; 868 + xfm->filter_h = NULL; 869 + xfm->filter_v = NULL; 870 + 871 + /* set boundary mode to 0 */ 872 + REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0); 873 + } 874 + 875 + static void program_gamut_remap( 876 + struct dcn10_transform *xfm, 877 + const uint16_t *regval, 878 + enum gamut_remap_select select) 879 + { 880 + uint16_t selection = 0; 881 + 882 + if (regval == NULL || select == GAMUT_REMAP_BYPASS) { 883 + REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 884 + CM_GAMUT_REMAP_MODE, 0); 885 + return; 886 + } 887 + switch (select) { 888 + case GAMUT_REMAP_COEFF: 889 + selection = 1; 890 + break; 891 + case GAMUT_REMAP_COMA_COEFF: 892 + selection = 2; 893 + break; 894 + case GAMUT_REMAP_COMB_COEFF: 895 + selection = 3; 896 + break; 897 + default: 898 + break; 899 + } 900 + 901 + 902 + if (select == GAMUT_REMAP_COEFF) { 903 + 904 + REG_SET_2(CM_GAMUT_REMAP_C11_C12, 0, 905 + CM_GAMUT_REMAP_C11, regval[0], 906 + CM_GAMUT_REMAP_C12, regval[1]); 907 + regval += 2; 908 + REG_SET_2(CM_GAMUT_REMAP_C13_C14, 0, 909 + CM_GAMUT_REMAP_C13, regval[0], 910 + CM_GAMUT_REMAP_C14, regval[1]); 911 + regval += 2; 912 + REG_SET_2(CM_GAMUT_REMAP_C21_C22, 0, 913 + CM_GAMUT_REMAP_C21, regval[0], 914 + CM_GAMUT_REMAP_C22, regval[1]); 915 + regval += 2; 916 + REG_SET_2(CM_GAMUT_REMAP_C23_C24, 0, 917 + CM_GAMUT_REMAP_C23, regval[0], 918 + CM_GAMUT_REMAP_C24, regval[1]); 919 + regval += 2; 920 + REG_SET_2(CM_GAMUT_REMAP_C31_C32, 0, 921 + CM_GAMUT_REMAP_C31, regval[0], 922 + CM_GAMUT_REMAP_C32, regval[1]); 923 + regval += 2; 924 + REG_SET_2(CM_GAMUT_REMAP_C33_C34, 0, 925 + CM_GAMUT_REMAP_C33, regval[0], 926 + CM_GAMUT_REMAP_C34, regval[1]); 927 + 928 + } else if (select == GAMUT_REMAP_COMA_COEFF) { 929 + REG_SET_2(CM_COMA_C11_C12, 0, 930 + CM_COMA_C11, regval[0], 931 + CM_COMA_C12, regval[1]); 932 + regval += 2; 933 + REG_SET_2(CM_COMA_C13_C14, 0, 934 + CM_COMA_C13, regval[0], 935 + CM_COMA_C14, regval[1]); 936 + regval += 2; 937 + REG_SET_2(CM_COMA_C21_C22, 0, 938 + CM_COMA_C21, regval[0], 939 + CM_COMA_C22, regval[1]); 940 + regval += 2; 941 + REG_SET_2(CM_COMA_C23_C24, 0, 942 + CM_COMA_C23, regval[0], 943 + CM_COMA_C24, regval[1]); 944 + regval += 2; 945 + REG_SET_2(CM_COMA_C31_C32, 0, 946 + CM_COMA_C31, regval[0], 947 + CM_COMA_C32, regval[1]); 948 + regval += 2; 949 + REG_SET_2(CM_COMA_C33_C34, 0, 950 + CM_COMA_C33, regval[0], 951 + CM_COMA_C34, regval[1]); 952 + 953 + } else { 954 + REG_SET_2(CM_COMB_C11_C12, 0, 955 + CM_COMB_C11, regval[0], 956 + CM_COMB_C12, regval[1]); 957 + regval += 2; 958 + REG_SET_2(CM_COMB_C13_C14, 0, 959 + CM_COMB_C13, regval[0], 960 + CM_COMB_C14, regval[1]); 961 + regval += 2; 962 + REG_SET_2(CM_COMB_C21_C22, 0, 963 + CM_COMB_C21, regval[0], 964 + CM_COMB_C22, regval[1]); 965 + regval += 2; 966 + REG_SET_2(CM_COMB_C23_C24, 0, 967 + CM_COMB_C23, regval[0], 968 + CM_COMB_C24, regval[1]); 969 + regval += 2; 970 + REG_SET_2(CM_COMB_C31_C32, 0, 971 + CM_COMB_C31, regval[0], 972 + CM_COMB_C32, regval[1]); 973 + regval += 2; 974 + REG_SET_2(CM_COMB_C33_C34, 0, 975 + CM_COMB_C33, regval[0], 976 + CM_COMB_C34, regval[1]); 977 + } 978 + 979 + REG_SET( 980 + CM_GAMUT_REMAP_CONTROL, 0, 981 + CM_GAMUT_REMAP_MODE, selection); 982 + 983 + } 984 + 985 + static void dcn_transform_set_gamut_remap( 986 + struct transform *xfm, 987 + const struct xfm_grph_csc_adjustment *adjust) 988 + { 989 + struct dcn10_transform *dcn_xfm = TO_DCN10_TRANSFORM(xfm); 990 + 991 + if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 992 + /* Bypass if type is bypass or hw */ 993 + program_gamut_remap(dcn_xfm, NULL, GAMUT_REMAP_BYPASS); 994 + else { 995 + struct fixed31_32 arr_matrix[12]; 996 + uint16_t arr_reg_val[12]; 997 + 998 + arr_matrix[0] = adjust->temperature_matrix[0]; 999 + arr_matrix[1] = adjust->temperature_matrix[1]; 1000 + arr_matrix[2] = adjust->temperature_matrix[2]; 1001 + arr_matrix[3] = dal_fixed31_32_zero; 1002 + 1003 + arr_matrix[4] = adjust->temperature_matrix[3]; 1004 + arr_matrix[5] = adjust->temperature_matrix[4]; 1005 + arr_matrix[6] = adjust->temperature_matrix[5]; 1006 + arr_matrix[7] = dal_fixed31_32_zero; 1007 + 1008 + arr_matrix[8] = adjust->temperature_matrix[6]; 1009 + arr_matrix[9] = adjust->temperature_matrix[7]; 1010 + arr_matrix[10] = adjust->temperature_matrix[8]; 1011 + arr_matrix[11] = dal_fixed31_32_zero; 1012 + 1013 + convert_float_matrix( 1014 + arr_reg_val, arr_matrix, 12); 1015 + 1016 + program_gamut_remap(dcn_xfm, arr_reg_val, GAMUT_REMAP_COEFF); 1017 + } 1018 + } 1019 + 1020 + static struct transform_funcs dcn10_transform_funcs = { 1021 + 1022 + .transform_reset = transform_reset, 1023 + .transform_set_scaler = transform_set_scaler_manual_scale, 1024 + .transform_get_optimal_number_of_taps = 1025 + transform_get_optimal_number_of_taps, 1026 + .transform_set_gamut_remap = dcn_transform_set_gamut_remap 1027 + }; 1028 + 1029 + /*****************************************/ 1030 + /* Constructor, Destructor */ 1031 + /*****************************************/ 1032 + 1033 + bool dcn10_transform_construct( 1034 + struct dcn10_transform *xfm, 1035 + struct dc_context *ctx, 1036 + const struct dcn_transform_registers *tf_regs, 1037 + const struct dcn_transform_shift *tf_shift, 1038 + const struct dcn_transform_mask *tf_mask) 1039 + { 1040 + xfm->base.ctx = ctx; 1041 + 1042 + xfm->base.funcs = &dcn10_transform_funcs; 1043 + 1044 + xfm->tf_regs = tf_regs; 1045 + xfm->tf_shift = tf_shift; 1046 + xfm->tf_mask = tf_mask; 1047 + 1048 + xfm->lb_pixel_depth_supported = 1049 + LB_PIXEL_DEPTH_18BPP | 1050 + LB_PIXEL_DEPTH_24BPP | 1051 + LB_PIXEL_DEPTH_30BPP; 1052 + 1053 + xfm->lb_bits_per_entry = LB_BITS_PER_ENTRY; 1054 + xfm->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/ 1055 + 1056 + return true; 1057 + }
+416
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_transform.h
··· 1 + /* Copyright 2016 Advanced Micro Devices, Inc. 2 + * 3 + * Permission is hereby granted, free of charge, to any person obtaining a 4 + * copy of this software and associated documentation files (the "Software"), 5 + * to deal in the Software without restriction, including without limitation 6 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 + * and/or sell copies of the Software, and to permit persons to whom the 8 + * Software is furnished to do so, subject to the following conditions: 9 + * 10 + * The above copyright notice and this permission notice shall be included in 11 + * all copies or substantial portions of the Software. 12 + * 13 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 + * OTHER DEALINGS IN THE SOFTWARE. 20 + * 21 + * Authors: AMD 22 + * 23 + */ 24 + 25 + #ifndef __DAL_TRANSFORM_DCN10_H__ 26 + #define __DAL_TRANSFORM_DCN10_H__ 27 + 28 + #include "transform.h" 29 + 30 + #define TO_DCN10_TRANSFORM(transform)\ 31 + container_of(transform, struct dcn10_transform, base) 32 + 33 + /* TODO: Use correct number of taps. Using polaris values for now */ 34 + #define LB_TOTAL_NUMBER_OF_ENTRIES 5124 35 + #define LB_BITS_PER_ENTRY 144 36 + 37 + #define TF_SF(reg_name, field_name, post_fix)\ 38 + .field_name = reg_name ## __ ## field_name ## post_fix 39 + 40 + #define TF_REG_LIST_DCN(id) \ 41 + SRI(DSCL_EXT_OVERSCAN_LEFT_RIGHT, DSCL, id), \ 42 + SRI(DSCL_EXT_OVERSCAN_TOP_BOTTOM, DSCL, id), \ 43 + SRI(OTG_H_BLANK, DSCL, id), \ 44 + SRI(OTG_V_BLANK, DSCL, id), \ 45 + SRI(SCL_MODE, DSCL, id), \ 46 + SRI(LB_DATA_FORMAT, DSCL, id), \ 47 + SRI(LB_MEMORY_CTRL, DSCL, id), \ 48 + SRI(DSCL_AUTOCAL, DSCL, id), \ 49 + SRI(SCL_BLACK_OFFSET, DSCL, id), \ 50 + SRI(DSCL_CONTROL, DSCL, id), \ 51 + SRI(SCL_TAP_CONTROL, DSCL, id), \ 52 + SRI(SCL_COEF_RAM_TAP_SELECT, DSCL, id), \ 53 + SRI(SCL_COEF_RAM_TAP_DATA, DSCL, id), \ 54 + SRI(DSCL_2TAP_CONTROL, DSCL, id), \ 55 + SRI(DCSURF_PRI_VIEWPORT_DIMENSION, HUBP, id), \ 56 + SRI(DCSURF_PRI_VIEWPORT_START, HUBP, id), \ 57 + SRI(DCSURF_SEC_VIEWPORT_DIMENSION, HUBP, id), \ 58 + SRI(DCSURF_SEC_VIEWPORT_START, HUBP, id), \ 59 + SRI(DCSURF_PRI_VIEWPORT_DIMENSION_C, HUBP, id), \ 60 + SRI(DCSURF_PRI_VIEWPORT_START_C, HUBP, id), \ 61 + SRI(CM_GAMUT_REMAP_CONTROL, CM, id), \ 62 + SRI(MPC_SIZE, DSCL, id), \ 63 + SRI(SCL_HORZ_FILTER_SCALE_RATIO, DSCL, id), \ 64 + SRI(SCL_VERT_FILTER_SCALE_RATIO, DSCL, id), \ 65 + SRI(SCL_HORZ_FILTER_SCALE_RATIO_C, DSCL, id), \ 66 + SRI(SCL_VERT_FILTER_SCALE_RATIO_C, DSCL, id), \ 67 + SRI(SCL_HORZ_FILTER_INIT, DSCL, id), \ 68 + SRI(SCL_HORZ_FILTER_INIT_C, DSCL, id), \ 69 + SRI(SCL_VERT_FILTER_INIT, DSCL, id), \ 70 + SRI(SCL_VERT_FILTER_INIT_BOT, DSCL, id), \ 71 + SRI(SCL_VERT_FILTER_INIT_C, DSCL, id), \ 72 + SRI(SCL_VERT_FILTER_INIT_BOT_C, DSCL, id), \ 73 + SRI(RECOUT_START, DSCL, id), \ 74 + SRI(RECOUT_SIZE, DSCL, id), \ 75 + SRI(CM_GAMUT_REMAP_CONTROL, CM, id),\ 76 + SRI(CM_GAMUT_REMAP_C11_C12, CM, id),\ 77 + SRI(CM_GAMUT_REMAP_C13_C14, CM, id),\ 78 + SRI(CM_GAMUT_REMAP_C21_C22, CM, id),\ 79 + SRI(CM_GAMUT_REMAP_C23_C24, CM, id),\ 80 + SRI(CM_GAMUT_REMAP_C31_C32, CM, id),\ 81 + SRI(CM_GAMUT_REMAP_C33_C34, CM, id),\ 82 + SRI(CM_COMA_C11_C12, CM, id),\ 83 + SRI(CM_COMA_C13_C14, CM, id),\ 84 + SRI(CM_COMA_C21_C22, CM, id),\ 85 + SRI(CM_COMA_C23_C24, CM, id),\ 86 + SRI(CM_COMA_C31_C32, CM, id),\ 87 + SRI(CM_COMA_C33_C34, CM, id),\ 88 + SRI(CM_COMB_C11_C12, CM, id),\ 89 + SRI(CM_COMB_C13_C14, CM, id),\ 90 + SRI(CM_COMB_C21_C22, CM, id),\ 91 + SRI(CM_COMB_C23_C24, CM, id),\ 92 + SRI(CM_COMB_C31_C32, CM, id),\ 93 + SRI(CM_COMB_C33_C34, CM, id) 94 + 95 + 96 + 97 + #define TF_REG_LIST_SH_MASK_DCN(mask_sh)\ 98 + TF_SF(DSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT, mask_sh),\ 99 + TF_SF(DSCL0_DSCL_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT, mask_sh),\ 100 + TF_SF(DSCL0_DSCL_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM, mask_sh),\ 101 + TF_SF(DSCL0_DSCL_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP, mask_sh),\ 102 + TF_SF(DSCL0_OTG_H_BLANK, OTG_H_BLANK_START, mask_sh),\ 103 + TF_SF(DSCL0_OTG_H_BLANK, OTG_H_BLANK_END, mask_sh),\ 104 + TF_SF(DSCL0_OTG_V_BLANK, OTG_V_BLANK_START, mask_sh),\ 105 + TF_SF(DSCL0_OTG_V_BLANK, OTG_V_BLANK_END, mask_sh),\ 106 + TF_SF(DSCL0_LB_DATA_FORMAT, PIXEL_DEPTH, mask_sh),\ 107 + TF_SF(DSCL0_LB_DATA_FORMAT, PIXEL_EXPAN_MODE, mask_sh),\ 108 + TF_SF(DSCL0_LB_DATA_FORMAT, PIXEL_REDUCE_MODE, mask_sh),\ 109 + TF_SF(DSCL0_LB_DATA_FORMAT, DYNAMIC_PIXEL_DEPTH, mask_sh),\ 110 + TF_SF(DSCL0_LB_DATA_FORMAT, DITHER_EN, mask_sh),\ 111 + TF_SF(DSCL0_LB_DATA_FORMAT, INTERLEAVE_EN, mask_sh),\ 112 + TF_SF(DSCL0_LB_DATA_FORMAT, ALPHA_EN, mask_sh),\ 113 + TF_SF(DSCL0_LB_MEMORY_CTRL, MEMORY_CONFIG, mask_sh),\ 114 + TF_SF(DSCL0_LB_MEMORY_CTRL, LB_MAX_PARTITIONS, mask_sh),\ 115 + TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_MODE, mask_sh),\ 116 + TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_NUM_PIPE, mask_sh),\ 117 + TF_SF(DSCL0_DSCL_AUTOCAL, AUTOCAL_PIPE_ID, mask_sh),\ 118 + TF_SF(DSCL0_SCL_BLACK_OFFSET, SCL_BLACK_OFFSET_RGB_Y, mask_sh),\ 119 + TF_SF(DSCL0_SCL_BLACK_OFFSET, SCL_BLACK_OFFSET_CBCR, mask_sh),\ 120 + TF_SF(DSCL0_DSCL_CONTROL, SCL_BOUNDARY_MODE, mask_sh),\ 121 + TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_V_NUM_TAPS, mask_sh),\ 122 + TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_H_NUM_TAPS, mask_sh),\ 123 + TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_V_NUM_TAPS_C, mask_sh),\ 124 + TF_SF(DSCL0_SCL_TAP_CONTROL, SCL_H_NUM_TAPS_C, mask_sh),\ 125 + TF_SF(DSCL0_SCL_COEF_RAM_TAP_SELECT, SCL_COEF_RAM_TAP_PAIR_IDX, mask_sh),\ 126 + TF_SF(DSCL0_SCL_COEF_RAM_TAP_SELECT, SCL_COEF_RAM_PHASE, mask_sh),\ 127 + TF_SF(DSCL0_SCL_COEF_RAM_TAP_SELECT, SCL_COEF_RAM_FILTER_TYPE, mask_sh),\ 128 + TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_EVEN_TAP_COEF, mask_sh),\ 129 + TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_EVEN_TAP_COEF_EN, mask_sh),\ 130 + TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_ODD_TAP_COEF, mask_sh),\ 131 + TF_SF(DSCL0_SCL_COEF_RAM_TAP_DATA, SCL_COEF_RAM_ODD_TAP_COEF_EN, mask_sh),\ 132 + TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_H_2TAP_HARDCODE_COEF_EN, mask_sh),\ 133 + TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_H_2TAP_SHARP_EN, mask_sh),\ 134 + TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_H_2TAP_SHARP_FACTOR, mask_sh),\ 135 + TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_V_2TAP_HARDCODE_COEF_EN, mask_sh),\ 136 + TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_V_2TAP_SHARP_EN, mask_sh),\ 137 + TF_SF(DSCL0_DSCL_2TAP_CONTROL, SCL_V_2TAP_SHARP_FACTOR, mask_sh),\ 138 + TF_SF(DSCL0_SCL_MODE, SCL_COEF_RAM_SELECT, mask_sh),\ 139 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_WIDTH, mask_sh),\ 140 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT, mask_sh),\ 141 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_START, PRI_VIEWPORT_X_START, mask_sh),\ 142 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_START, PRI_VIEWPORT_Y_START, mask_sh),\ 143 + TF_SF(HUBP0_DCSURF_SEC_VIEWPORT_DIMENSION, SEC_VIEWPORT_WIDTH, mask_sh),\ 144 + TF_SF(HUBP0_DCSURF_SEC_VIEWPORT_DIMENSION, SEC_VIEWPORT_HEIGHT, mask_sh),\ 145 + TF_SF(HUBP0_DCSURF_SEC_VIEWPORT_START, SEC_VIEWPORT_X_START, mask_sh),\ 146 + TF_SF(HUBP0_DCSURF_SEC_VIEWPORT_START, SEC_VIEWPORT_Y_START, mask_sh),\ 147 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_C, PRI_VIEWPORT_WIDTH_C, mask_sh),\ 148 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_C, PRI_VIEWPORT_HEIGHT_C, mask_sh),\ 149 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_START_C, PRI_VIEWPORT_X_START_C, mask_sh),\ 150 + TF_SF(HUBP0_DCSURF_PRI_VIEWPORT_START_C, PRI_VIEWPORT_Y_START_C, mask_sh),\ 151 + TF_SF(DSCL0_SCL_MODE, DSCL_MODE, mask_sh),\ 152 + TF_SF(DSCL0_RECOUT_START, RECOUT_START_X, mask_sh),\ 153 + TF_SF(DSCL0_RECOUT_START, RECOUT_START_Y, mask_sh),\ 154 + TF_SF(DSCL0_RECOUT_SIZE, RECOUT_WIDTH, mask_sh),\ 155 + TF_SF(DSCL0_RECOUT_SIZE, RECOUT_HEIGHT, mask_sh),\ 156 + TF_SF(DSCL0_MPC_SIZE, MPC_WIDTH, mask_sh),\ 157 + TF_SF(DSCL0_MPC_SIZE, MPC_HEIGHT, mask_sh),\ 158 + TF_SF(DSCL0_SCL_HORZ_FILTER_SCALE_RATIO, SCL_H_SCALE_RATIO, mask_sh),\ 159 + TF_SF(DSCL0_SCL_VERT_FILTER_SCALE_RATIO, SCL_V_SCALE_RATIO, mask_sh),\ 160 + TF_SF(DSCL0_SCL_HORZ_FILTER_SCALE_RATIO_C, SCL_H_SCALE_RATIO_C, mask_sh),\ 161 + TF_SF(DSCL0_SCL_VERT_FILTER_SCALE_RATIO_C, SCL_V_SCALE_RATIO_C, mask_sh),\ 162 + TF_SF(DSCL0_SCL_HORZ_FILTER_INIT, SCL_H_INIT_FRAC, mask_sh),\ 163 + TF_SF(DSCL0_SCL_HORZ_FILTER_INIT, SCL_H_INIT_INT, mask_sh),\ 164 + TF_SF(DSCL0_SCL_HORZ_FILTER_INIT_C, SCL_H_INIT_FRAC_C, mask_sh),\ 165 + TF_SF(DSCL0_SCL_HORZ_FILTER_INIT_C, SCL_H_INIT_INT_C, mask_sh),\ 166 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT, SCL_V_INIT_FRAC, mask_sh),\ 167 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT, SCL_V_INIT_INT, mask_sh),\ 168 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT, SCL_V_INIT_FRAC_BOT, mask_sh),\ 169 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT, SCL_V_INIT_INT_BOT, mask_sh),\ 170 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT_C, SCL_V_INIT_FRAC_C, mask_sh),\ 171 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT_C, SCL_V_INIT_INT_C, mask_sh),\ 172 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT_C, SCL_V_INIT_FRAC_BOT_C, mask_sh),\ 173 + TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT_C, SCL_V_INIT_INT_BOT_C, mask_sh),\ 174 + TF_SF(DSCL0_SCL_MODE, SCL_CHROMA_COEF_MODE, mask_sh),\ 175 + TF_SF(DSCL0_SCL_MODE, SCL_COEF_RAM_SELECT_CURRENT, mask_sh),\ 176 + TF_SF(CM0_CM_GAMUT_REMAP_CONTROL, CM_GAMUT_REMAP_MODE, mask_sh),\ 177 + TF_SF(CM0_CM_GAMUT_REMAP_C11_C12, CM_GAMUT_REMAP_C11, mask_sh),\ 178 + TF_SF(CM0_CM_GAMUT_REMAP_C11_C12, CM_GAMUT_REMAP_C12, mask_sh),\ 179 + TF_SF(CM0_CM_GAMUT_REMAP_C13_C14, CM_GAMUT_REMAP_C13, mask_sh),\ 180 + TF_SF(CM0_CM_GAMUT_REMAP_C13_C14, CM_GAMUT_REMAP_C14, mask_sh),\ 181 + TF_SF(CM0_CM_GAMUT_REMAP_C21_C22, CM_GAMUT_REMAP_C21, mask_sh),\ 182 + TF_SF(CM0_CM_GAMUT_REMAP_C21_C22, CM_GAMUT_REMAP_C22, mask_sh),\ 183 + TF_SF(CM0_CM_GAMUT_REMAP_C23_C24, CM_GAMUT_REMAP_C23, mask_sh),\ 184 + TF_SF(CM0_CM_GAMUT_REMAP_C23_C24, CM_GAMUT_REMAP_C24, mask_sh),\ 185 + TF_SF(CM0_CM_GAMUT_REMAP_C31_C32, CM_GAMUT_REMAP_C31, mask_sh),\ 186 + TF_SF(CM0_CM_GAMUT_REMAP_C31_C32, CM_GAMUT_REMAP_C32, mask_sh),\ 187 + TF_SF(CM0_CM_GAMUT_REMAP_C33_C34, CM_GAMUT_REMAP_C33, mask_sh),\ 188 + TF_SF(CM0_CM_GAMUT_REMAP_C33_C34, CM_GAMUT_REMAP_C34, mask_sh),\ 189 + TF_SF(CM0_CM_COMA_C11_C12, CM_COMA_C11, mask_sh),\ 190 + TF_SF(CM0_CM_COMA_C11_C12, CM_COMA_C12, mask_sh),\ 191 + TF_SF(CM0_CM_COMA_C13_C14, CM_COMA_C13, mask_sh),\ 192 + TF_SF(CM0_CM_COMA_C13_C14, CM_COMA_C14, mask_sh),\ 193 + TF_SF(CM0_CM_COMA_C21_C22, CM_COMA_C21, mask_sh),\ 194 + TF_SF(CM0_CM_COMA_C21_C22, CM_COMA_C22, mask_sh),\ 195 + TF_SF(CM0_CM_COMA_C23_C24, CM_COMA_C23, mask_sh),\ 196 + TF_SF(CM0_CM_COMA_C23_C24, CM_COMA_C24, mask_sh),\ 197 + TF_SF(CM0_CM_COMA_C31_C32, CM_COMA_C31, mask_sh),\ 198 + TF_SF(CM0_CM_COMA_C31_C32, CM_COMA_C32, mask_sh),\ 199 + TF_SF(CM0_CM_COMA_C33_C34, CM_COMA_C33, mask_sh),\ 200 + TF_SF(CM0_CM_COMA_C33_C34, CM_COMA_C34, mask_sh),\ 201 + TF_SF(CM0_CM_COMB_C11_C12, CM_COMB_C11, mask_sh),\ 202 + TF_SF(CM0_CM_COMB_C11_C12, CM_COMB_C12, mask_sh),\ 203 + TF_SF(CM0_CM_COMB_C13_C14, CM_COMB_C13, mask_sh),\ 204 + TF_SF(CM0_CM_COMB_C13_C14, CM_COMB_C14, mask_sh),\ 205 + TF_SF(CM0_CM_COMB_C21_C22, CM_COMB_C21, mask_sh),\ 206 + TF_SF(CM0_CM_COMB_C21_C22, CM_COMB_C22, mask_sh),\ 207 + TF_SF(CM0_CM_COMB_C23_C24, CM_COMB_C23, mask_sh),\ 208 + TF_SF(CM0_CM_COMB_C23_C24, CM_COMB_C24, mask_sh),\ 209 + TF_SF(CM0_CM_COMB_C31_C32, CM_COMB_C31, mask_sh),\ 210 + TF_SF(CM0_CM_COMB_C33_C34, CM_COMB_C33, mask_sh),\ 211 + TF_SF(CM0_CM_COMB_C31_C32, CM_COMB_C32, mask_sh),\ 212 + TF_SF(CM0_CM_COMB_C33_C34, CM_COMB_C34, mask_sh) 213 + 214 + 215 + #define TF_REG_FIELD_LIST(type) \ 216 + type EXT_OVERSCAN_LEFT; \ 217 + type EXT_OVERSCAN_RIGHT; \ 218 + type EXT_OVERSCAN_BOTTOM; \ 219 + type EXT_OVERSCAN_TOP; \ 220 + type OTG_H_BLANK_START; \ 221 + type OTG_H_BLANK_END; \ 222 + type OTG_V_BLANK_START; \ 223 + type OTG_V_BLANK_END; \ 224 + type PIXEL_DEPTH; \ 225 + type PIXEL_EXPAN_MODE; \ 226 + type PIXEL_REDUCE_MODE; \ 227 + type DYNAMIC_PIXEL_DEPTH; \ 228 + type DITHER_EN; \ 229 + type INTERLEAVE_EN; \ 230 + type ALPHA_EN; \ 231 + type MEMORY_CONFIG; \ 232 + type LB_MAX_PARTITIONS; \ 233 + type AUTOCAL_MODE; \ 234 + type AUTOCAL_NUM_PIPE; \ 235 + type AUTOCAL_PIPE_ID; \ 236 + type SCL_BLACK_OFFSET_RGB_Y; \ 237 + type SCL_BLACK_OFFSET_CBCR; \ 238 + type SCL_BOUNDARY_MODE; \ 239 + type SCL_V_NUM_TAPS; \ 240 + type SCL_H_NUM_TAPS; \ 241 + type SCL_V_NUM_TAPS_C; \ 242 + type SCL_H_NUM_TAPS_C; \ 243 + type SCL_COEF_RAM_TAP_PAIR_IDX; \ 244 + type SCL_COEF_RAM_PHASE; \ 245 + type SCL_COEF_RAM_FILTER_TYPE; \ 246 + type SCL_COEF_RAM_EVEN_TAP_COEF; \ 247 + type SCL_COEF_RAM_EVEN_TAP_COEF_EN; \ 248 + type SCL_COEF_RAM_ODD_TAP_COEF; \ 249 + type SCL_COEF_RAM_ODD_TAP_COEF_EN; \ 250 + type SCL_H_2TAP_HARDCODE_COEF_EN; \ 251 + type SCL_H_2TAP_SHARP_EN; \ 252 + type SCL_H_2TAP_SHARP_FACTOR; \ 253 + type SCL_V_2TAP_HARDCODE_COEF_EN; \ 254 + type SCL_V_2TAP_SHARP_EN; \ 255 + type SCL_V_2TAP_SHARP_FACTOR; \ 256 + type SCL_COEF_RAM_SELECT; \ 257 + type PRI_VIEWPORT_WIDTH; \ 258 + type PRI_VIEWPORT_HEIGHT; \ 259 + type PRI_VIEWPORT_X_START; \ 260 + type PRI_VIEWPORT_Y_START; \ 261 + type SEC_VIEWPORT_WIDTH; \ 262 + type SEC_VIEWPORT_HEIGHT; \ 263 + type SEC_VIEWPORT_X_START; \ 264 + type SEC_VIEWPORT_Y_START; \ 265 + type PRI_VIEWPORT_WIDTH_C; \ 266 + type PRI_VIEWPORT_HEIGHT_C; \ 267 + type PRI_VIEWPORT_X_START_C; \ 268 + type PRI_VIEWPORT_Y_START_C; \ 269 + type DSCL_MODE; \ 270 + type RECOUT_START_X; \ 271 + type RECOUT_START_Y; \ 272 + type RECOUT_WIDTH; \ 273 + type RECOUT_HEIGHT; \ 274 + type MPC_WIDTH; \ 275 + type MPC_HEIGHT; \ 276 + type SCL_H_SCALE_RATIO; \ 277 + type SCL_V_SCALE_RATIO; \ 278 + type SCL_H_SCALE_RATIO_C; \ 279 + type SCL_V_SCALE_RATIO_C; \ 280 + type SCL_H_INIT_FRAC; \ 281 + type SCL_H_INIT_INT; \ 282 + type SCL_H_INIT_FRAC_C; \ 283 + type SCL_H_INIT_INT_C; \ 284 + type SCL_V_INIT_FRAC; \ 285 + type SCL_V_INIT_INT; \ 286 + type SCL_V_INIT_FRAC_BOT; \ 287 + type SCL_V_INIT_INT_BOT; \ 288 + type SCL_V_INIT_FRAC_C; \ 289 + type SCL_V_INIT_INT_C; \ 290 + type SCL_V_INIT_FRAC_BOT_C; \ 291 + type SCL_V_INIT_INT_BOT_C; \ 292 + type SCL_CHROMA_COEF_MODE; \ 293 + type SCL_COEF_RAM_SELECT_CURRENT; \ 294 + type CM_GAMUT_REMAP_MODE; \ 295 + type CM_GAMUT_REMAP_C11; \ 296 + type CM_GAMUT_REMAP_C12; \ 297 + type CM_GAMUT_REMAP_C13; \ 298 + type CM_GAMUT_REMAP_C14; \ 299 + type CM_GAMUT_REMAP_C21; \ 300 + type CM_GAMUT_REMAP_C22; \ 301 + type CM_GAMUT_REMAP_C23; \ 302 + type CM_GAMUT_REMAP_C24; \ 303 + type CM_GAMUT_REMAP_C31; \ 304 + type CM_GAMUT_REMAP_C32; \ 305 + type CM_GAMUT_REMAP_C33; \ 306 + type CM_GAMUT_REMAP_C34; \ 307 + type CM_COMA_C11; \ 308 + type CM_COMA_C12; \ 309 + type CM_COMA_C13; \ 310 + type CM_COMA_C14; \ 311 + type CM_COMA_C21; \ 312 + type CM_COMA_C22; \ 313 + type CM_COMA_C23; \ 314 + type CM_COMA_C24; \ 315 + type CM_COMA_C31; \ 316 + type CM_COMA_C32; \ 317 + type CM_COMA_C33; \ 318 + type CM_COMA_C34; \ 319 + type CM_COMB_C11; \ 320 + type CM_COMB_C12; \ 321 + type CM_COMB_C13; \ 322 + type CM_COMB_C14; \ 323 + type CM_COMB_C21; \ 324 + type CM_COMB_C22; \ 325 + type CM_COMB_C23; \ 326 + type CM_COMB_C24; \ 327 + type CM_COMB_C31; \ 328 + type CM_COMB_C32; \ 329 + type CM_COMB_C33; \ 330 + type CM_COMB_C34 331 + 332 + struct dcn_transform_shift { 333 + TF_REG_FIELD_LIST(uint8_t); 334 + }; 335 + 336 + struct dcn_transform_mask { 337 + TF_REG_FIELD_LIST(uint32_t); 338 + }; 339 + 340 + struct dcn_transform_registers { 341 + uint32_t DSCL_EXT_OVERSCAN_LEFT_RIGHT; 342 + uint32_t DSCL_EXT_OVERSCAN_TOP_BOTTOM; 343 + uint32_t OTG_H_BLANK; 344 + uint32_t OTG_V_BLANK; 345 + uint32_t SCL_MODE; 346 + uint32_t LB_DATA_FORMAT; 347 + uint32_t LB_MEMORY_CTRL; 348 + uint32_t DSCL_AUTOCAL; 349 + uint32_t SCL_BLACK_OFFSET; 350 + uint32_t DSCL_CONTROL; 351 + uint32_t SCL_TAP_CONTROL; 352 + uint32_t SCL_COEF_RAM_TAP_SELECT; 353 + uint32_t SCL_COEF_RAM_TAP_DATA; 354 + uint32_t DSCL_2TAP_CONTROL; 355 + uint32_t DCSURF_PRI_VIEWPORT_DIMENSION; 356 + uint32_t DCSURF_PRI_VIEWPORT_START; 357 + uint32_t DCSURF_SEC_VIEWPORT_DIMENSION; 358 + uint32_t DCSURF_SEC_VIEWPORT_START; 359 + uint32_t DCSURF_PRI_VIEWPORT_DIMENSION_C; 360 + uint32_t DCSURF_PRI_VIEWPORT_START_C; 361 + uint32_t MPC_SIZE; 362 + uint32_t SCL_HORZ_FILTER_SCALE_RATIO; 363 + uint32_t SCL_VERT_FILTER_SCALE_RATIO; 364 + uint32_t SCL_HORZ_FILTER_SCALE_RATIO_C; 365 + uint32_t SCL_VERT_FILTER_SCALE_RATIO_C; 366 + uint32_t SCL_HORZ_FILTER_INIT; 367 + uint32_t SCL_HORZ_FILTER_INIT_C; 368 + uint32_t SCL_VERT_FILTER_INIT; 369 + uint32_t SCL_VERT_FILTER_INIT_BOT; 370 + uint32_t SCL_VERT_FILTER_INIT_C; 371 + uint32_t SCL_VERT_FILTER_INIT_BOT_C; 372 + uint32_t RECOUT_START; 373 + uint32_t RECOUT_SIZE; 374 + uint32_t CM_GAMUT_REMAP_CONTROL; 375 + uint32_t CM_GAMUT_REMAP_C11_C12; 376 + uint32_t CM_GAMUT_REMAP_C13_C14; 377 + uint32_t CM_GAMUT_REMAP_C21_C22; 378 + uint32_t CM_GAMUT_REMAP_C23_C24; 379 + uint32_t CM_GAMUT_REMAP_C31_C32; 380 + uint32_t CM_GAMUT_REMAP_C33_C34; 381 + uint32_t CM_COMA_C11_C12; 382 + uint32_t CM_COMA_C13_C14; 383 + uint32_t CM_COMA_C21_C22; 384 + uint32_t CM_COMA_C23_C24; 385 + uint32_t CM_COMA_C31_C32; 386 + uint32_t CM_COMA_C33_C34; 387 + uint32_t CM_COMB_C11_C12; 388 + uint32_t CM_COMB_C13_C14; 389 + uint32_t CM_COMB_C21_C22; 390 + uint32_t CM_COMB_C23_C24; 391 + uint32_t CM_COMB_C31_C32; 392 + uint32_t CM_COMB_C33_C34; 393 + }; 394 + 395 + struct dcn10_transform { 396 + struct transform base; 397 + 398 + const struct dcn_transform_registers *tf_regs; 399 + const struct dcn_transform_shift *tf_shift; 400 + const struct dcn_transform_mask *tf_mask; 401 + 402 + const uint16_t *filter_v; 403 + const uint16_t *filter_h; 404 + const uint16_t *filter_v_c; 405 + const uint16_t *filter_h_c; 406 + int lb_pixel_depth_supported; 407 + int lb_memory_size; 408 + int lb_bits_per_entry; 409 + }; 410 + 411 + bool dcn10_transform_construct(struct dcn10_transform *xfm110, 412 + struct dc_context *ctx, 413 + const struct dcn_transform_registers *tf_regs, 414 + const struct dcn_transform_shift *tf_shift, 415 + const struct dcn_transform_mask *tf_mask); 416 + #endif