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

drm/amd/display: Add DMCUB source files and changes for DCN32/321

DMCUB is the display engine microcontroller which aids in modesetting
and other display related features.

Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Aurabindo Pillai and committed by
Alex Deucher
ac2e555e 4f29f9cf

+859 -2
+31
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
··· 250 250 dm_helpers_dmub_outbox_interrupt_control(dc->ctx, enable); 251 251 } 252 252 253 + void dc_dmub_srv_query_caps_cmd(struct dmub_srv *dmub) 254 + { 255 + union dmub_rb_cmd cmd = { 0 }; 256 + enum dmub_status status; 257 + 258 + if (!dmub) { 259 + return; 260 + } 261 + 262 + memset(&cmd, 0, sizeof(cmd)); 263 + 264 + /* Prepare fw command */ 265 + cmd.query_feature_caps.header.type = DMUB_CMD__QUERY_FEATURE_CAPS; 266 + cmd.query_feature_caps.header.sub_type = 0; 267 + cmd.query_feature_caps.header.ret_status = 1; 268 + cmd.query_feature_caps.header.payload_bytes = sizeof(struct dmub_cmd_query_feature_caps_data); 269 + 270 + /* Send command to fw */ 271 + status = dmub_srv_cmd_with_reply_data(dmub, &cmd); 272 + 273 + ASSERT(status == DMUB_STATUS_OK); 274 + 275 + /* If command was processed, copy feature caps to dmub srv */ 276 + if (status == DMUB_STATUS_OK && 277 + cmd.query_feature_caps.header.ret_status == 0) { 278 + memcpy(&dmub->feature_caps, 279 + &cmd.query_feature_caps.query_feature_caps_data, 280 + sizeof(struct dmub_feature_caps)); 281 + } 282 + } 283 + 253 284 bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmub_diagnostic_data *diag_data) 254 285 { 255 286 if (!dc_dmub_srv || !dc_dmub_srv->dmub || !diag_data)
+2
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
··· 68 68 69 69 void dc_dmub_trace_event_control(struct dc *dc, bool enable); 70 70 71 + void dc_dmub_srv_query_caps_cmd(struct dmub_srv *dmub); 72 + 71 73 void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dmub_srv); 72 74 void dc_dmub_srv_wait_for_inbox0_ack(struct dc_dmub_srv *dmub_srv); 73 75 void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_data_register data);
+6
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
··· 246 246 bool dpia_supported; 247 247 bool disable_dpia; 248 248 bool usb4_cm_version; 249 + bool fw_in_system_memory; 249 250 }; 250 251 251 252 /** ··· 311 310 const struct dmub_window *cw0, 312 311 const struct dmub_window *cw1); 313 312 313 + void (*backdoor_load_zfb_mode)(struct dmub_srv *dmub, 314 + const struct dmub_window *cw0, 315 + const struct dmub_window *cw1); 314 316 void (*setup_windows)(struct dmub_srv *dmub, 315 317 const struct dmub_window *cw2, 316 318 const struct dmub_window *cw3, ··· 369 365 370 366 uint32_t (*get_gpint_dataout)(struct dmub_srv *dmub); 371 367 368 + void (*configure_dmub_in_system_memory)(struct dmub_srv *dmub); 372 369 void (*clear_inbox0_ack_register)(struct dmub_srv *dmub); 373 370 uint32_t (*read_inbox0_ack_register)(struct dmub_srv *dmub); 374 371 void (*send_inbox0_cmd)(struct dmub_srv *dmub, union dmub_inbox0_data_register data); ··· 417 412 /* private: internal use only */ 418 413 const struct dmub_srv_common_regs *regs; 419 414 const struct dmub_srv_dcn31_regs *regs_dcn31; 415 + const struct dmub_srv_dcn32_regs *regs_dcn32; 420 416 421 417 struct dmub_srv_base_funcs funcs; 422 418 struct dmub_srv_hw_funcs hw_funcs;
+25 -1
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
··· 641 641 * Command type used for all panel control commands. 642 642 */ 643 643 DMUB_CMD__PANEL_CNTL = 74, 644 - 644 + /** 645 + * Command type used for <TODO:description> 646 + */ 647 + DMUB_CMD__CAB_FOR_SS = 75, 645 648 /** 646 649 * Command type used for interfacing with DPIA. 647 650 */ ··· 881 878 uint8_t reserved2; /**< Reserved bits */ 882 879 }; 883 880 881 + /** 882 + * enum dmub_cmd_cab_type - TODO: 883 + */ 884 + enum dmub_cmd_cab_type { 885 + DMUB_CMD__CAB_NO_IDLE_OPTIMIZATION = 0, 886 + DMUB_CMD__CAB_NO_DCN_REQ = 1, 887 + DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB = 2, 888 + }; 889 + 890 + /** 891 + * struct dmub_rb_cmd_cab_for_ss - TODO: 892 + */ 893 + struct dmub_rb_cmd_cab_for_ss { 894 + struct dmub_cmd_header header; 895 + uint8_t cab_alloc_ways; /* total number of ways */ 896 + uint8_t debug_bits; /* debug bits */ 897 + }; 884 898 /** 885 899 * enum dmub_cmd_idle_opt_type - Idle optimization command type. 886 900 */ ··· 2713 2693 * Definition of a DMUB_CMD__MALL command. 2714 2694 */ 2715 2695 struct dmub_rb_cmd_mall mall; 2696 + /** 2697 + * Definition of a DMUB_CMD__CAB command. 2698 + */ 2699 + struct dmub_rb_cmd_cab_for_ss cab; 2716 2700 /** 2717 2701 * Definition of a DMUB_CMD__IDLE_OPT_DCN_RESTORE command. 2718 2702 */
+1
drivers/gpu/drm/amd/display/dmub/src/Makefile
··· 23 23 DMUB = dmub_srv.o dmub_srv_stat.o dmub_reg.o dmub_dcn20.o dmub_dcn21.o 24 24 DMUB += dmub_dcn30.o dmub_dcn301.o dmub_dcn302.o dmub_dcn303.o 25 25 DMUB += dmub_dcn31.o dmub_dcn315.o dmub_dcn316.o 26 + DMUB += dmub_dcn32.o 26 27 27 28 AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB)) 28 29
+488
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c
··· 1 + /* 2 + * Copyright 2022 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 "../dmub_srv.h" 27 + #include "dmub_reg.h" 28 + #include "dmub_dcn32.h" 29 + 30 + #include "dcn/dcn_3_2_0_offset.h" 31 + #include "dcn/dcn_3_2_0_sh_mask.h" 32 + 33 + #define DCN_BASE__INST0_SEG2 0x000034C0 34 + 35 + #define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg 36 + #define CTX dmub 37 + #define REGS dmub->regs_dcn32 38 + #define REG_OFFSET_EXP(reg_name) (BASE(reg##reg_name##_BASE_IDX) + reg##reg_name) 39 + 40 + const struct dmub_srv_dcn32_regs dmub_srv_dcn32_regs = { 41 + #define DMUB_SR(reg) REG_OFFSET_EXP(reg), 42 + { DMUB_DCN32_REGS() }, 43 + #undef DMUB_SR 44 + 45 + #define DMUB_SF(reg, field) FD_MASK(reg, field), 46 + { DMUB_DCN32_FIELDS() }, 47 + #undef DMUB_SF 48 + 49 + #define DMUB_SF(reg, field) FD_SHIFT(reg, field), 50 + { DMUB_DCN32_FIELDS() }, 51 + #undef DMUB_SF 52 + }; 53 + 54 + static void dmub_dcn32_get_fb_base_offset(struct dmub_srv *dmub, 55 + uint64_t *fb_base, 56 + uint64_t *fb_offset) 57 + { 58 + uint32_t tmp; 59 + 60 + if (dmub->fb_base || dmub->fb_offset) { 61 + *fb_base = dmub->fb_base; 62 + *fb_offset = dmub->fb_offset; 63 + return; 64 + } 65 + 66 + REG_GET(DCN_VM_FB_LOCATION_BASE, FB_BASE, &tmp); 67 + *fb_base = (uint64_t)tmp << 24; 68 + 69 + REG_GET(DCN_VM_FB_OFFSET, FB_OFFSET, &tmp); 70 + *fb_offset = (uint64_t)tmp << 24; 71 + } 72 + 73 + static inline void dmub_dcn32_translate_addr(const union dmub_addr *addr_in, 74 + uint64_t fb_base, 75 + uint64_t fb_offset, 76 + union dmub_addr *addr_out) 77 + { 78 + addr_out->quad_part = addr_in->quad_part - fb_base + fb_offset; 79 + } 80 + 81 + void dmub_dcn32_reset(struct dmub_srv *dmub) 82 + { 83 + union dmub_gpint_data_register cmd; 84 + const uint32_t timeout = 30; 85 + uint32_t in_reset, scratch, i; 86 + 87 + REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); 88 + 89 + if (in_reset == 0) { 90 + cmd.bits.status = 1; 91 + cmd.bits.command_code = DMUB_GPINT__STOP_FW; 92 + cmd.bits.param = 0; 93 + 94 + dmub->hw_funcs.set_gpint(dmub, cmd); 95 + 96 + /** 97 + * Timeout covers both the ACK and the wait 98 + * for remaining work to finish. 99 + * 100 + * This is mostly bound by the PHY disable sequence. 101 + * Each register check will be greater than 1us, so 102 + * don't bother using udelay. 103 + */ 104 + 105 + for (i = 0; i < timeout; ++i) { 106 + if (dmub->hw_funcs.is_gpint_acked(dmub, cmd)) 107 + break; 108 + } 109 + 110 + for (i = 0; i < timeout; ++i) { 111 + scratch = dmub->hw_funcs.get_gpint_response(dmub); 112 + if (scratch == DMUB_GPINT__STOP_FW_RESPONSE) 113 + break; 114 + } 115 + 116 + /* Clear the GPINT command manually so we don't reset again. */ 117 + cmd.all = 0; 118 + dmub->hw_funcs.set_gpint(dmub, cmd); 119 + 120 + /* Force reset in case we timed out, DMCUB is likely hung. */ 121 + } 122 + 123 + REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1); 124 + REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); 125 + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); 126 + REG_WRITE(DMCUB_INBOX1_RPTR, 0); 127 + REG_WRITE(DMCUB_INBOX1_WPTR, 0); 128 + REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); 129 + REG_WRITE(DMCUB_OUTBOX1_WPTR, 0); 130 + REG_WRITE(DMCUB_SCRATCH0, 0); 131 + } 132 + 133 + void dmub_dcn32_reset_release(struct dmub_srv *dmub) 134 + { 135 + REG_WRITE(DMCUB_GPINT_DATAIN1, 0); 136 + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 0); 137 + REG_WRITE(DMCUB_SCRATCH15, dmub->psp_version & 0x001100FF); 138 + REG_UPDATE_2(DMCUB_CNTL, DMCUB_ENABLE, 1, DMCUB_TRACEPORT_EN, 1); 139 + REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 0); 140 + } 141 + 142 + void dmub_dcn32_backdoor_load(struct dmub_srv *dmub, 143 + const struct dmub_window *cw0, 144 + const struct dmub_window *cw1) 145 + { 146 + union dmub_addr offset; 147 + uint64_t fb_base, fb_offset; 148 + 149 + dmub_dcn32_get_fb_base_offset(dmub, &fb_base, &fb_offset); 150 + 151 + REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); 152 + 153 + dmub_dcn32_translate_addr(&cw0->offset, fb_base, fb_offset, &offset); 154 + 155 + REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part); 156 + REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part); 157 + REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base); 158 + REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0, 159 + DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top, 160 + DMCUB_REGION3_CW0_ENABLE, 1); 161 + 162 + dmub_dcn32_translate_addr(&cw1->offset, fb_base, fb_offset, &offset); 163 + 164 + REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part); 165 + REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part); 166 + REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base); 167 + REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0, 168 + DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, 169 + DMCUB_REGION3_CW1_ENABLE, 1); 170 + 171 + REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID, 172 + 0x20); 173 + } 174 + 175 + void dmub_dcn32_backdoor_load_zfb_mode(struct dmub_srv *dmub, 176 + const struct dmub_window *cw0, 177 + const struct dmub_window *cw1) 178 + { 179 + union dmub_addr offset; 180 + 181 + REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); 182 + 183 + offset = cw0->offset; 184 + 185 + REG_WRITE(DMCUB_REGION3_CW0_OFFSET, offset.u.low_part); 186 + REG_WRITE(DMCUB_REGION3_CW0_OFFSET_HIGH, offset.u.high_part); 187 + REG_WRITE(DMCUB_REGION3_CW0_BASE_ADDRESS, cw0->region.base); 188 + REG_SET_2(DMCUB_REGION3_CW0_TOP_ADDRESS, 0, 189 + DMCUB_REGION3_CW0_TOP_ADDRESS, cw0->region.top, 190 + DMCUB_REGION3_CW0_ENABLE, 1); 191 + 192 + offset = cw1->offset; 193 + 194 + REG_WRITE(DMCUB_REGION3_CW1_OFFSET, offset.u.low_part); 195 + REG_WRITE(DMCUB_REGION3_CW1_OFFSET_HIGH, offset.u.high_part); 196 + REG_WRITE(DMCUB_REGION3_CW1_BASE_ADDRESS, cw1->region.base); 197 + REG_SET_2(DMCUB_REGION3_CW1_TOP_ADDRESS, 0, 198 + DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, 199 + DMCUB_REGION3_CW1_ENABLE, 1); 200 + 201 + REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID, 202 + 0x20); 203 + } 204 + 205 + void dmub_dcn32_setup_windows(struct dmub_srv *dmub, 206 + const struct dmub_window *cw2, 207 + const struct dmub_window *cw3, 208 + const struct dmub_window *cw4, 209 + const struct dmub_window *cw5, 210 + const struct dmub_window *cw6) 211 + { 212 + union dmub_addr offset; 213 + 214 + offset = cw3->offset; 215 + 216 + REG_WRITE(DMCUB_REGION3_CW3_OFFSET, offset.u.low_part); 217 + REG_WRITE(DMCUB_REGION3_CW3_OFFSET_HIGH, offset.u.high_part); 218 + REG_WRITE(DMCUB_REGION3_CW3_BASE_ADDRESS, cw3->region.base); 219 + REG_SET_2(DMCUB_REGION3_CW3_TOP_ADDRESS, 0, 220 + DMCUB_REGION3_CW3_TOP_ADDRESS, cw3->region.top, 221 + DMCUB_REGION3_CW3_ENABLE, 1); 222 + 223 + offset = cw4->offset; 224 + 225 + REG_WRITE(DMCUB_REGION3_CW4_OFFSET, offset.u.low_part); 226 + REG_WRITE(DMCUB_REGION3_CW4_OFFSET_HIGH, offset.u.high_part); 227 + REG_WRITE(DMCUB_REGION3_CW4_BASE_ADDRESS, cw4->region.base); 228 + REG_SET_2(DMCUB_REGION3_CW4_TOP_ADDRESS, 0, 229 + DMCUB_REGION3_CW4_TOP_ADDRESS, cw4->region.top, 230 + DMCUB_REGION3_CW4_ENABLE, 1); 231 + 232 + offset = cw5->offset; 233 + 234 + REG_WRITE(DMCUB_REGION3_CW5_OFFSET, offset.u.low_part); 235 + REG_WRITE(DMCUB_REGION3_CW5_OFFSET_HIGH, offset.u.high_part); 236 + REG_WRITE(DMCUB_REGION3_CW5_BASE_ADDRESS, cw5->region.base); 237 + REG_SET_2(DMCUB_REGION3_CW5_TOP_ADDRESS, 0, 238 + DMCUB_REGION3_CW5_TOP_ADDRESS, cw5->region.top, 239 + DMCUB_REGION3_CW5_ENABLE, 1); 240 + 241 + REG_WRITE(DMCUB_REGION5_OFFSET, offset.u.low_part); 242 + REG_WRITE(DMCUB_REGION5_OFFSET_HIGH, offset.u.high_part); 243 + REG_SET_2(DMCUB_REGION5_TOP_ADDRESS, 0, 244 + DMCUB_REGION5_TOP_ADDRESS, 245 + cw5->region.top - cw5->region.base - 1, 246 + DMCUB_REGION5_ENABLE, 1); 247 + 248 + offset = cw6->offset; 249 + 250 + REG_WRITE(DMCUB_REGION3_CW6_OFFSET, offset.u.low_part); 251 + REG_WRITE(DMCUB_REGION3_CW6_OFFSET_HIGH, offset.u.high_part); 252 + REG_WRITE(DMCUB_REGION3_CW6_BASE_ADDRESS, cw6->region.base); 253 + REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0, 254 + DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top, 255 + DMCUB_REGION3_CW6_ENABLE, 1); 256 + } 257 + 258 + void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub, 259 + const struct dmub_region *inbox1) 260 + { 261 + REG_WRITE(DMCUB_INBOX1_BASE_ADDRESS, inbox1->base); 262 + REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base); 263 + } 264 + 265 + uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub) 266 + { 267 + return REG_READ(DMCUB_INBOX1_RPTR); 268 + } 269 + 270 + void dmub_dcn32_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset) 271 + { 272 + REG_WRITE(DMCUB_INBOX1_WPTR, wptr_offset); 273 + } 274 + 275 + void dmub_dcn32_setup_out_mailbox(struct dmub_srv *dmub, 276 + const struct dmub_region *outbox1) 277 + { 278 + REG_WRITE(DMCUB_OUTBOX1_BASE_ADDRESS, outbox1->base); 279 + REG_WRITE(DMCUB_OUTBOX1_SIZE, outbox1->top - outbox1->base); 280 + } 281 + 282 + uint32_t dmub_dcn32_get_outbox1_wptr(struct dmub_srv *dmub) 283 + { 284 + /** 285 + * outbox1 wptr register is accessed without locks (dal & dc) 286 + * and to be called only by dmub_srv_stat_get_notification() 287 + */ 288 + return REG_READ(DMCUB_OUTBOX1_WPTR); 289 + } 290 + 291 + void dmub_dcn32_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset) 292 + { 293 + /** 294 + * outbox1 rptr register is accessed without locks (dal & dc) 295 + * and to be called only by dmub_srv_stat_get_notification() 296 + */ 297 + REG_WRITE(DMCUB_OUTBOX1_RPTR, rptr_offset); 298 + } 299 + 300 + bool dmub_dcn32_is_hw_init(struct dmub_srv *dmub) 301 + { 302 + uint32_t is_hw_init; 303 + 304 + REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_hw_init); 305 + 306 + return is_hw_init != 0; 307 + } 308 + 309 + bool dmub_dcn32_is_supported(struct dmub_srv *dmub) 310 + { 311 + uint32_t supported = 0; 312 + 313 + REG_GET(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE, &supported); 314 + 315 + return supported; 316 + } 317 + 318 + void dmub_dcn32_set_gpint(struct dmub_srv *dmub, 319 + union dmub_gpint_data_register reg) 320 + { 321 + REG_WRITE(DMCUB_GPINT_DATAIN1, reg.all); 322 + } 323 + 324 + bool dmub_dcn32_is_gpint_acked(struct dmub_srv *dmub, 325 + union dmub_gpint_data_register reg) 326 + { 327 + union dmub_gpint_data_register test; 328 + 329 + reg.bits.status = 0; 330 + test.all = REG_READ(DMCUB_GPINT_DATAIN1); 331 + 332 + return test.all == reg.all; 333 + } 334 + 335 + uint32_t dmub_dcn32_get_gpint_response(struct dmub_srv *dmub) 336 + { 337 + return REG_READ(DMCUB_SCRATCH7); 338 + } 339 + 340 + uint32_t dmub_dcn32_get_gpint_dataout(struct dmub_srv *dmub) 341 + { 342 + uint32_t dataout = REG_READ(DMCUB_GPINT_DATAOUT); 343 + 344 + REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 0); 345 + 346 + REG_WRITE(DMCUB_GPINT_DATAOUT, 0); 347 + REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 1); 348 + REG_UPDATE(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK, 0); 349 + 350 + REG_UPDATE(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN, 1); 351 + 352 + return dataout; 353 + } 354 + 355 + union dmub_fw_boot_status dmub_dcn32_get_fw_boot_status(struct dmub_srv *dmub) 356 + { 357 + union dmub_fw_boot_status status; 358 + 359 + status.all = REG_READ(DMCUB_SCRATCH0); 360 + return status; 361 + } 362 + 363 + void dmub_dcn32_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params) 364 + { 365 + union dmub_fw_boot_options boot_options = {0}; 366 + 367 + boot_options.bits.z10_disable = params->disable_z10; 368 + 369 + REG_WRITE(DMCUB_SCRATCH14, boot_options.all); 370 + } 371 + 372 + void dmub_dcn32_skip_dmub_panel_power_sequence(struct dmub_srv *dmub, bool skip) 373 + { 374 + union dmub_fw_boot_options boot_options; 375 + boot_options.all = REG_READ(DMCUB_SCRATCH14); 376 + boot_options.bits.skip_phy_init_panel_sequence = skip; 377 + REG_WRITE(DMCUB_SCRATCH14, boot_options.all); 378 + } 379 + 380 + void dmub_dcn32_setup_outbox0(struct dmub_srv *dmub, 381 + const struct dmub_region *outbox0) 382 + { 383 + REG_WRITE(DMCUB_OUTBOX0_BASE_ADDRESS, outbox0->base); 384 + 385 + REG_WRITE(DMCUB_OUTBOX0_SIZE, outbox0->top - outbox0->base); 386 + } 387 + 388 + uint32_t dmub_dcn32_get_outbox0_wptr(struct dmub_srv *dmub) 389 + { 390 + return REG_READ(DMCUB_OUTBOX0_WPTR); 391 + } 392 + 393 + void dmub_dcn32_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset) 394 + { 395 + REG_WRITE(DMCUB_OUTBOX0_RPTR, rptr_offset); 396 + } 397 + 398 + uint32_t dmub_dcn32_get_current_time(struct dmub_srv *dmub) 399 + { 400 + return REG_READ(DMCUB_TIMER_CURRENT); 401 + } 402 + 403 + void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) 404 + { 405 + uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset; 406 + uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; 407 + 408 + if (!dmub || !diag_data) 409 + return; 410 + 411 + memset(diag_data, 0, sizeof(*diag_data)); 412 + 413 + diag_data->dmcub_version = dmub->fw_version; 414 + 415 + diag_data->scratch[0] = REG_READ(DMCUB_SCRATCH0); 416 + diag_data->scratch[1] = REG_READ(DMCUB_SCRATCH1); 417 + diag_data->scratch[2] = REG_READ(DMCUB_SCRATCH2); 418 + diag_data->scratch[3] = REG_READ(DMCUB_SCRATCH3); 419 + diag_data->scratch[4] = REG_READ(DMCUB_SCRATCH4); 420 + diag_data->scratch[5] = REG_READ(DMCUB_SCRATCH5); 421 + diag_data->scratch[6] = REG_READ(DMCUB_SCRATCH6); 422 + diag_data->scratch[7] = REG_READ(DMCUB_SCRATCH7); 423 + diag_data->scratch[8] = REG_READ(DMCUB_SCRATCH8); 424 + diag_data->scratch[9] = REG_READ(DMCUB_SCRATCH9); 425 + diag_data->scratch[10] = REG_READ(DMCUB_SCRATCH10); 426 + diag_data->scratch[11] = REG_READ(DMCUB_SCRATCH11); 427 + diag_data->scratch[12] = REG_READ(DMCUB_SCRATCH12); 428 + diag_data->scratch[13] = REG_READ(DMCUB_SCRATCH13); 429 + diag_data->scratch[14] = REG_READ(DMCUB_SCRATCH14); 430 + diag_data->scratch[15] = REG_READ(DMCUB_SCRATCH15); 431 + 432 + diag_data->undefined_address_fault_addr = REG_READ(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR); 433 + diag_data->inst_fetch_fault_addr = REG_READ(DMCUB_INST_FETCH_FAULT_ADDR); 434 + diag_data->data_write_fault_addr = REG_READ(DMCUB_DATA_WRITE_FAULT_ADDR); 435 + 436 + diag_data->inbox1_rptr = REG_READ(DMCUB_INBOX1_RPTR); 437 + diag_data->inbox1_wptr = REG_READ(DMCUB_INBOX1_WPTR); 438 + diag_data->inbox1_size = REG_READ(DMCUB_INBOX1_SIZE); 439 + 440 + diag_data->inbox0_rptr = REG_READ(DMCUB_INBOX0_RPTR); 441 + diag_data->inbox0_wptr = REG_READ(DMCUB_INBOX0_WPTR); 442 + diag_data->inbox0_size = REG_READ(DMCUB_INBOX0_SIZE); 443 + 444 + REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_dmub_enabled); 445 + diag_data->is_dmcub_enabled = is_dmub_enabled; 446 + 447 + REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &is_soft_reset); 448 + diag_data->is_dmcub_soft_reset = is_soft_reset; 449 + 450 + REG_GET(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS, &is_sec_reset); 451 + diag_data->is_dmcub_secure_reset = is_sec_reset; 452 + 453 + REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); 454 + diag_data->is_traceport_en = is_traceport_enabled; 455 + 456 + REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); 457 + diag_data->is_cw0_enabled = is_cw0_enabled; 458 + 459 + REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); 460 + diag_data->is_cw6_enabled = is_cw6_enabled; 461 + } 462 + void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub) 463 + { 464 + /* DMCUB_REGION3_TMR_AXI_SPACE values: 465 + * 0b011 (0x3) - FB physical address 466 + * 0b100 (0x4) - GPU virtual address 467 + * 468 + * Default value is 0x3 (FB Physical address for TMR). When programming 469 + * DMUB to be in system memory, change to 0x4. The system memory allocated 470 + * is accessible by both GPU and CPU, so we use GPU virtual address. 471 + */ 472 + REG_WRITE(DMCUB_REGION3_TMR_AXI_SPACE, 0x4); 473 + } 474 + 475 + void dmub_dcn32_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data) 476 + { 477 + REG_WRITE(DMCUB_INBOX0_WPTR, data.inbox0_cmd_common.all); 478 + } 479 + 480 + void dmub_dcn32_clear_inbox0_ack_register(struct dmub_srv *dmub) 481 + { 482 + REG_WRITE(DMCUB_SCRATCH17, 0); 483 + } 484 + 485 + uint32_t dmub_dcn32_read_inbox0_ack_register(struct dmub_srv *dmub) 486 + { 487 + return REG_READ(DMCUB_SCRATCH17); 488 + }
+256
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h
··· 1 + /* 2 + * Copyright 2022 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 _DMUB_DCN32_H_ 27 + #define _DMUB_DCN32_H_ 28 + 29 + #include "dmub_dcn31.h" 30 + 31 + struct dmub_srv; 32 + 33 + /* DCN32 register definitions. */ 34 + 35 + #define DMUB_DCN32_REGS() \ 36 + DMUB_SR(DMCUB_CNTL) \ 37 + DMUB_SR(DMCUB_CNTL2) \ 38 + DMUB_SR(DMCUB_SEC_CNTL) \ 39 + DMUB_SR(DMCUB_INBOX0_SIZE) \ 40 + DMUB_SR(DMCUB_INBOX0_RPTR) \ 41 + DMUB_SR(DMCUB_INBOX0_WPTR) \ 42 + DMUB_SR(DMCUB_INBOX1_BASE_ADDRESS) \ 43 + DMUB_SR(DMCUB_INBOX1_SIZE) \ 44 + DMUB_SR(DMCUB_INBOX1_RPTR) \ 45 + DMUB_SR(DMCUB_INBOX1_WPTR) \ 46 + DMUB_SR(DMCUB_OUTBOX0_BASE_ADDRESS) \ 47 + DMUB_SR(DMCUB_OUTBOX0_SIZE) \ 48 + DMUB_SR(DMCUB_OUTBOX0_RPTR) \ 49 + DMUB_SR(DMCUB_OUTBOX0_WPTR) \ 50 + DMUB_SR(DMCUB_OUTBOX1_BASE_ADDRESS) \ 51 + DMUB_SR(DMCUB_OUTBOX1_SIZE) \ 52 + DMUB_SR(DMCUB_OUTBOX1_RPTR) \ 53 + DMUB_SR(DMCUB_OUTBOX1_WPTR) \ 54 + DMUB_SR(DMCUB_REGION3_CW0_OFFSET) \ 55 + DMUB_SR(DMCUB_REGION3_CW1_OFFSET) \ 56 + DMUB_SR(DMCUB_REGION3_CW2_OFFSET) \ 57 + DMUB_SR(DMCUB_REGION3_CW3_OFFSET) \ 58 + DMUB_SR(DMCUB_REGION3_CW4_OFFSET) \ 59 + DMUB_SR(DMCUB_REGION3_CW5_OFFSET) \ 60 + DMUB_SR(DMCUB_REGION3_CW6_OFFSET) \ 61 + DMUB_SR(DMCUB_REGION3_CW7_OFFSET) \ 62 + DMUB_SR(DMCUB_REGION3_CW0_OFFSET_HIGH) \ 63 + DMUB_SR(DMCUB_REGION3_CW1_OFFSET_HIGH) \ 64 + DMUB_SR(DMCUB_REGION3_CW2_OFFSET_HIGH) \ 65 + DMUB_SR(DMCUB_REGION3_CW3_OFFSET_HIGH) \ 66 + DMUB_SR(DMCUB_REGION3_CW4_OFFSET_HIGH) \ 67 + DMUB_SR(DMCUB_REGION3_CW5_OFFSET_HIGH) \ 68 + DMUB_SR(DMCUB_REGION3_CW6_OFFSET_HIGH) \ 69 + DMUB_SR(DMCUB_REGION3_CW7_OFFSET_HIGH) \ 70 + DMUB_SR(DMCUB_REGION3_CW0_BASE_ADDRESS) \ 71 + DMUB_SR(DMCUB_REGION3_CW1_BASE_ADDRESS) \ 72 + DMUB_SR(DMCUB_REGION3_CW2_BASE_ADDRESS) \ 73 + DMUB_SR(DMCUB_REGION3_CW3_BASE_ADDRESS) \ 74 + DMUB_SR(DMCUB_REGION3_CW4_BASE_ADDRESS) \ 75 + DMUB_SR(DMCUB_REGION3_CW5_BASE_ADDRESS) \ 76 + DMUB_SR(DMCUB_REGION3_CW6_BASE_ADDRESS) \ 77 + DMUB_SR(DMCUB_REGION3_CW7_BASE_ADDRESS) \ 78 + DMUB_SR(DMCUB_REGION3_CW0_TOP_ADDRESS) \ 79 + DMUB_SR(DMCUB_REGION3_CW1_TOP_ADDRESS) \ 80 + DMUB_SR(DMCUB_REGION3_CW2_TOP_ADDRESS) \ 81 + DMUB_SR(DMCUB_REGION3_CW3_TOP_ADDRESS) \ 82 + DMUB_SR(DMCUB_REGION3_CW4_TOP_ADDRESS) \ 83 + DMUB_SR(DMCUB_REGION3_CW5_TOP_ADDRESS) \ 84 + DMUB_SR(DMCUB_REGION3_CW6_TOP_ADDRESS) \ 85 + DMUB_SR(DMCUB_REGION3_CW7_TOP_ADDRESS) \ 86 + DMUB_SR(DMCUB_REGION4_OFFSET) \ 87 + DMUB_SR(DMCUB_REGION4_OFFSET_HIGH) \ 88 + DMUB_SR(DMCUB_REGION4_TOP_ADDRESS) \ 89 + DMUB_SR(DMCUB_REGION5_OFFSET) \ 90 + DMUB_SR(DMCUB_REGION5_OFFSET_HIGH) \ 91 + DMUB_SR(DMCUB_REGION5_TOP_ADDRESS) \ 92 + DMUB_SR(DMCUB_SCRATCH0) \ 93 + DMUB_SR(DMCUB_SCRATCH1) \ 94 + DMUB_SR(DMCUB_SCRATCH2) \ 95 + DMUB_SR(DMCUB_SCRATCH3) \ 96 + DMUB_SR(DMCUB_SCRATCH4) \ 97 + DMUB_SR(DMCUB_SCRATCH5) \ 98 + DMUB_SR(DMCUB_SCRATCH6) \ 99 + DMUB_SR(DMCUB_SCRATCH7) \ 100 + DMUB_SR(DMCUB_SCRATCH8) \ 101 + DMUB_SR(DMCUB_SCRATCH9) \ 102 + DMUB_SR(DMCUB_SCRATCH10) \ 103 + DMUB_SR(DMCUB_SCRATCH11) \ 104 + DMUB_SR(DMCUB_SCRATCH12) \ 105 + DMUB_SR(DMCUB_SCRATCH13) \ 106 + DMUB_SR(DMCUB_SCRATCH14) \ 107 + DMUB_SR(DMCUB_SCRATCH15) \ 108 + DMUB_SR(DMCUB_SCRATCH16) \ 109 + DMUB_SR(DMCUB_SCRATCH17) \ 110 + DMUB_SR(DMCUB_GPINT_DATAIN1) \ 111 + DMUB_SR(DMCUB_GPINT_DATAOUT) \ 112 + DMUB_SR(CC_DC_PIPE_DIS) \ 113 + DMUB_SR(MMHUBBUB_SOFT_RESET) \ 114 + DMUB_SR(DCN_VM_FB_LOCATION_BASE) \ 115 + DMUB_SR(DCN_VM_FB_OFFSET) \ 116 + DMUB_SR(DMCUB_TIMER_CURRENT) \ 117 + DMUB_SR(DMCUB_INST_FETCH_FAULT_ADDR) \ 118 + DMUB_SR(DMCUB_UNDEFINED_ADDRESS_FAULT_ADDR) \ 119 + DMUB_SR(DMCUB_DATA_WRITE_FAULT_ADDR) \ 120 + DMUB_SR(DMCUB_REGION3_TMR_AXI_SPACE) \ 121 + DMUB_SR(DMCUB_INTERRUPT_ENABLE) \ 122 + DMUB_SR(DMCUB_INTERRUPT_ACK) 123 + 124 + #define DMUB_DCN32_FIELDS() \ 125 + DMUB_SF(DMCUB_CNTL, DMCUB_ENABLE) \ 126 + DMUB_SF(DMCUB_CNTL, DMCUB_TRACEPORT_EN) \ 127 + DMUB_SF(DMCUB_CNTL2, DMCUB_SOFT_RESET) \ 128 + DMUB_SF(DMCUB_SEC_CNTL, DMCUB_SEC_RESET) \ 129 + DMUB_SF(DMCUB_SEC_CNTL, DMCUB_MEM_UNIT_ID) \ 130 + DMUB_SF(DMCUB_SEC_CNTL, DMCUB_SEC_RESET_STATUS) \ 131 + DMUB_SF(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_TOP_ADDRESS) \ 132 + DMUB_SF(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE) \ 133 + DMUB_SF(DMCUB_REGION3_CW1_TOP_ADDRESS, DMCUB_REGION3_CW1_TOP_ADDRESS) \ 134 + DMUB_SF(DMCUB_REGION3_CW1_TOP_ADDRESS, DMCUB_REGION3_CW1_ENABLE) \ 135 + DMUB_SF(DMCUB_REGION3_CW2_TOP_ADDRESS, DMCUB_REGION3_CW2_TOP_ADDRESS) \ 136 + DMUB_SF(DMCUB_REGION3_CW2_TOP_ADDRESS, DMCUB_REGION3_CW2_ENABLE) \ 137 + DMUB_SF(DMCUB_REGION3_CW3_TOP_ADDRESS, DMCUB_REGION3_CW3_TOP_ADDRESS) \ 138 + DMUB_SF(DMCUB_REGION3_CW3_TOP_ADDRESS, DMCUB_REGION3_CW3_ENABLE) \ 139 + DMUB_SF(DMCUB_REGION3_CW4_TOP_ADDRESS, DMCUB_REGION3_CW4_TOP_ADDRESS) \ 140 + DMUB_SF(DMCUB_REGION3_CW4_TOP_ADDRESS, DMCUB_REGION3_CW4_ENABLE) \ 141 + DMUB_SF(DMCUB_REGION3_CW5_TOP_ADDRESS, DMCUB_REGION3_CW5_TOP_ADDRESS) \ 142 + DMUB_SF(DMCUB_REGION3_CW5_TOP_ADDRESS, DMCUB_REGION3_CW5_ENABLE) \ 143 + DMUB_SF(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_TOP_ADDRESS) \ 144 + DMUB_SF(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE) \ 145 + DMUB_SF(DMCUB_REGION3_CW7_TOP_ADDRESS, DMCUB_REGION3_CW7_TOP_ADDRESS) \ 146 + DMUB_SF(DMCUB_REGION3_CW7_TOP_ADDRESS, DMCUB_REGION3_CW7_ENABLE) \ 147 + DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_TOP_ADDRESS) \ 148 + DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \ 149 + DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_TOP_ADDRESS) \ 150 + DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_ENABLE) \ 151 + DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \ 152 + DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) \ 153 + DMUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE) \ 154 + DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \ 155 + DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \ 156 + DMUB_SF(DMCUB_REGION3_TMR_AXI_SPACE, DMCUB_REGION3_TMR_AXI_SPACE) \ 157 + DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN) \ 158 + DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) 159 + 160 + struct dmub_srv_dcn32_reg_offset { 161 + #define DMUB_SR(reg) uint32_t reg; 162 + DMUB_DCN32_REGS() 163 + DMCUB_INTERNAL_REGS() 164 + #undef DMUB_SR 165 + }; 166 + 167 + struct dmub_srv_dcn32_reg_shift { 168 + #define DMUB_SF(reg, field) uint8_t reg##__##field; 169 + DMUB_DCN32_FIELDS() 170 + #undef DMUB_SF 171 + }; 172 + 173 + struct dmub_srv_dcn32_reg_mask { 174 + #define DMUB_SF(reg, field) uint32_t reg##__##field; 175 + DMUB_DCN32_FIELDS() 176 + #undef DMUB_SF 177 + }; 178 + 179 + struct dmub_srv_dcn32_regs { 180 + const struct dmub_srv_dcn32_reg_offset offset; 181 + const struct dmub_srv_dcn32_reg_mask mask; 182 + const struct dmub_srv_dcn32_reg_shift shift; 183 + }; 184 + 185 + extern const struct dmub_srv_dcn32_regs dmub_srv_dcn32_regs; 186 + 187 + void dmub_dcn32_reset(struct dmub_srv *dmub); 188 + 189 + void dmub_dcn32_reset_release(struct dmub_srv *dmub); 190 + 191 + void dmub_dcn32_backdoor_load(struct dmub_srv *dmub, 192 + const struct dmub_window *cw0, 193 + const struct dmub_window *cw1); 194 + 195 + void dmub_dcn32_backdoor_load_zfb_mode(struct dmub_srv *dmub, 196 + const struct dmub_window *cw0, 197 + const struct dmub_window *cw1); 198 + 199 + void dmub_dcn32_setup_windows(struct dmub_srv *dmub, 200 + const struct dmub_window *cw2, 201 + const struct dmub_window *cw3, 202 + const struct dmub_window *cw4, 203 + const struct dmub_window *cw5, 204 + const struct dmub_window *cw6); 205 + 206 + void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub, 207 + const struct dmub_region *inbox1); 208 + 209 + uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub); 210 + 211 + void dmub_dcn32_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset); 212 + 213 + void dmub_dcn32_setup_out_mailbox(struct dmub_srv *dmub, 214 + const struct dmub_region *outbox1); 215 + 216 + uint32_t dmub_dcn32_get_outbox1_wptr(struct dmub_srv *dmub); 217 + 218 + void dmub_dcn32_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); 219 + 220 + bool dmub_dcn32_is_hw_init(struct dmub_srv *dmub); 221 + 222 + bool dmub_dcn32_is_supported(struct dmub_srv *dmub); 223 + 224 + void dmub_dcn32_set_gpint(struct dmub_srv *dmub, 225 + union dmub_gpint_data_register reg); 226 + 227 + bool dmub_dcn32_is_gpint_acked(struct dmub_srv *dmub, 228 + union dmub_gpint_data_register reg); 229 + 230 + uint32_t dmub_dcn32_get_gpint_response(struct dmub_srv *dmub); 231 + 232 + uint32_t dmub_dcn32_get_gpint_dataout(struct dmub_srv *dmub); 233 + 234 + void dmub_dcn32_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params); 235 + 236 + void dmub_dcn32_skip_dmub_panel_power_sequence(struct dmub_srv *dmub, bool skip); 237 + 238 + union dmub_fw_boot_status dmub_dcn32_get_fw_boot_status(struct dmub_srv *dmub); 239 + 240 + void dmub_dcn32_setup_outbox0(struct dmub_srv *dmub, 241 + const struct dmub_region *outbox0); 242 + 243 + uint32_t dmub_dcn32_get_outbox0_wptr(struct dmub_srv *dmub); 244 + 245 + void dmub_dcn32_set_outbox0_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); 246 + 247 + uint32_t dmub_dcn32_get_current_time(struct dmub_srv *dmub); 248 + 249 + void dmub_dcn32_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); 250 + 251 + void dmub_dcn32_configure_dmub_in_system_memory(struct dmub_srv *dmub); 252 + void dmub_dcn32_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data); 253 + void dmub_dcn32_clear_inbox0_ack_register(struct dmub_srv *dmub); 254 + uint32_t dmub_dcn32_read_inbox0_ack_register(struct dmub_srv *dmub); 255 + 256 + #endif /* _DMUB_DCN32_H_ */
+50 -1
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
··· 34 34 #include "dmub_dcn31.h" 35 35 #include "dmub_dcn315.h" 36 36 #include "dmub_dcn316.h" 37 + #include "dmub_dcn32.h" 37 38 #include "os_types.h" 38 39 /* 39 40 * Note: the DMUB service is standalone. No additional headers should be ··· 258 257 funcs->get_diagnostic_data = dmub_dcn31_get_diagnostic_data; 259 258 funcs->should_detect = dmub_dcn31_should_detect; 260 259 funcs->get_current_time = dmub_dcn31_get_current_time; 260 + 261 + break; 262 + 263 + case DMUB_ASIC_DCN32: 264 + case DMUB_ASIC_DCN321: 265 + dmub->regs_dcn32 = &dmub_srv_dcn32_regs; 266 + funcs->configure_dmub_in_system_memory = dmub_dcn32_configure_dmub_in_system_memory; 267 + funcs->send_inbox0_cmd = dmub_dcn32_send_inbox0_cmd; 268 + funcs->clear_inbox0_ack_register = dmub_dcn32_clear_inbox0_ack_register; 269 + funcs->read_inbox0_ack_register = dmub_dcn32_read_inbox0_ack_register; 270 + funcs->reset = dmub_dcn32_reset; 271 + funcs->reset_release = dmub_dcn32_reset_release; 272 + funcs->backdoor_load = dmub_dcn32_backdoor_load; 273 + funcs->backdoor_load_zfb_mode = dmub_dcn32_backdoor_load_zfb_mode; 274 + funcs->setup_windows = dmub_dcn32_setup_windows; 275 + funcs->setup_mailbox = dmub_dcn32_setup_mailbox; 276 + funcs->get_inbox1_rptr = dmub_dcn32_get_inbox1_rptr; 277 + funcs->set_inbox1_wptr = dmub_dcn32_set_inbox1_wptr; 278 + funcs->setup_out_mailbox = dmub_dcn32_setup_out_mailbox; 279 + funcs->get_outbox1_wptr = dmub_dcn32_get_outbox1_wptr; 280 + funcs->set_outbox1_rptr = dmub_dcn32_set_outbox1_rptr; 281 + funcs->is_supported = dmub_dcn32_is_supported; 282 + funcs->is_hw_init = dmub_dcn32_is_hw_init; 283 + funcs->set_gpint = dmub_dcn32_set_gpint; 284 + funcs->is_gpint_acked = dmub_dcn32_is_gpint_acked; 285 + funcs->get_gpint_response = dmub_dcn32_get_gpint_response; 286 + funcs->get_gpint_dataout = dmub_dcn32_get_gpint_dataout; 287 + funcs->get_fw_status = dmub_dcn32_get_fw_boot_status; 288 + funcs->enable_dmub_boot_options = dmub_dcn32_enable_dmub_boot_options; 289 + funcs->skip_dmub_panel_power_sequence = dmub_dcn32_skip_dmub_panel_power_sequence; 290 + 291 + /* outbox0 call stacks */ 292 + funcs->setup_outbox0 = dmub_dcn32_setup_outbox0; 293 + funcs->get_outbox0_wptr = dmub_dcn32_get_outbox0_wptr; 294 + funcs->set_outbox0_rptr = dmub_dcn32_set_outbox0_rptr; 295 + funcs->get_current_time = dmub_dcn32_get_current_time; 296 + funcs->get_diagnostic_data = dmub_dcn32_get_diagnostic_data; 261 297 262 298 break; 263 299 ··· 539 501 cw1.region.base = DMUB_CW1_BASE; 540 502 cw1.region.top = cw1.region.base + stack_fb->size - 1; 541 503 504 + if (params->fw_in_system_memory && dmub->hw_funcs.configure_dmub_in_system_memory) 505 + dmub->hw_funcs.configure_dmub_in_system_memory(dmub); 506 + 542 507 if (params->load_inst_const && dmub->hw_funcs.backdoor_load) { 543 508 /** 544 509 * Read back all the instruction memory so we don't hang the ··· 549 508 * flushed yet. This only occurs in backdoor loading. 550 509 */ 551 510 dmub_flush_buffer_mem(inst_fb); 552 - dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); 511 + 512 + if (params->fw_in_system_memory && dmub->hw_funcs.backdoor_load_zfb_mode) 513 + dmub->hw_funcs.backdoor_load_zfb_mode(dmub, &cw0, &cw1); 514 + else 515 + dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); 553 516 } 554 517 555 518 cw2.offset.quad_part = data_fb->gpu_addr; ··· 627 582 /* Report to DMUB what features are supported by current driver */ 628 583 if (dmub->hw_funcs.enable_dmub_boot_options) 629 584 dmub->hw_funcs.enable_dmub_boot_options(dmub, params); 585 + 586 + if (dmub->hw_funcs.skip_dmub_panel_power_sequence) 587 + dmub->hw_funcs.skip_dmub_panel_power_sequence(dmub, 588 + params->skip_panel_power_sequence); 630 589 631 590 if (dmub->hw_funcs.reset_release) 632 591 dmub->hw_funcs.reset_release(dmub);