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

drm/amd/display: Add support for DCN302 (v2)

- add DCN302 resource, irq service, dmub loader,
- handle DC_VERSION_DCN_3_02
- define DCN302 power gating functions
- handle DCN302 in GPIO files
- define I2C regs
- add CONFIG_DRM_AMD_DC_DCN3_02 guard

v2: rebase fixes (Alex)

Signed-off-by: Joshua Aberback <joshua.aberback@amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Bhawanpreet Lakha and committed by
Alex Deucher
36d26912 4da67839

+2753 -1
+7
drivers/gpu/drm/amd/display/Kconfig
··· 34 34 Choose this option if you want to have 35 35 Van Gogh support for display engine 36 36 37 + config DRM_AMD_DC_DCN3_02 38 + bool "DCN 3.02 family" 39 + depends on DRM_AMD_DC_DCN3_0 40 + help 41 + Choose this option if you want to have 42 + Dimgrey_cavefish support for display engine 43 + 37 44 config DRM_AMD_DC_HDCP 38 45 bool "Enable HDCP support in DC" 39 46 depends on DRM_AMD_DC
+5
drivers/gpu/drm/amd/display/dc/Makefile
··· 40 40 DC_LIBS += dcn301 41 41 endif 42 42 43 + ifdef CONFIG_DRM_AMD_DC_DCN3_02 44 + DC_LIBS += dcn302 45 + 46 + endif 47 + 43 48 DC_LIBS += dce120 44 49 45 50 DC_LIBS += dce112
+5
drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
··· 83 83 *h = dal_cmd_tbl_helper_dce112_get_table2(); 84 84 return true; 85 85 #endif 86 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 87 + case DCN_VERSION_3_02: 88 + *h = dal_cmd_tbl_helper_dce112_get_table2(); 89 + return true; 90 + #endif 86 91 default: 87 92 /* Unsupported DCE */ 88 93 BREAK_TO_DEBUGGER();
+6
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
··· 186 186 dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 187 187 break; 188 188 } 189 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 190 + if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) { 191 + dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 192 + break; 193 + } 194 + #endif 189 195 #endif 190 196 dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 191 197 break;
+13
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 61 61 #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 62 62 #include "../dcn301/dcn301_resource.h" 63 63 #endif 64 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 65 + #include "../dcn302/dcn302_resource.h" 66 + #endif 64 67 65 68 #define DC_LOGGER_INIT(logger) 66 69 ··· 134 131 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 135 132 if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) 136 133 dc_version = DCN_VERSION_3_0; 134 + #endif 135 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 136 + if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) 137 + dc_version = DCN_VERSION_3_02; 137 138 #endif 138 139 break; 139 140 ··· 230 223 case DCN_VERSION_3_01: 231 224 res_pool = dcn301_create_resource_pool(init_data, dc); 232 225 break; 226 + #endif 227 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 228 + case DCN_VERSION_3_02: 229 + res_pool = dcn302_create_resource_pool(init_data, dc); 230 + break; 231 + 233 232 #endif 234 233 default: 235 234 break;
+20
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
··· 125 125 SRII(PIXEL_RATE_CNTL, OTG, 3) 126 126 #endif 127 127 128 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 129 + #define CS_COMMON_REG_LIST_DCN3_02(index, pllid) \ 130 + SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ 131 + SRII(PHASE, DP_DTO, 0),\ 132 + SRII(PHASE, DP_DTO, 1),\ 133 + SRII(PHASE, DP_DTO, 2),\ 134 + SRII(PHASE, DP_DTO, 3),\ 135 + SRII(PHASE, DP_DTO, 4),\ 136 + SRII(MODULO, DP_DTO, 0),\ 137 + SRII(MODULO, DP_DTO, 1),\ 138 + SRII(MODULO, DP_DTO, 2),\ 139 + SRII(MODULO, DP_DTO, 3),\ 140 + SRII(MODULO, DP_DTO, 4),\ 141 + SRII(PIXEL_RATE_CNTL, OTG, 0),\ 142 + SRII(PIXEL_RATE_CNTL, OTG, 1),\ 143 + SRII(PIXEL_RATE_CNTL, OTG, 2),\ 144 + SRII(PIXEL_RATE_CNTL, OTG, 3),\ 145 + SRII(PIXEL_RATE_CNTL, OTG, 4) 146 + 147 + #endif 128 148 #define CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\ 129 149 CS_SF(DP_DTO0_PHASE, DP_DTO0_PHASE, mask_sh),\ 130 150 CS_SF(DP_DTO0_MODULO, DP_DTO0_MODULO, mask_sh),\
+134
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
··· 426 426 SR(AZALIA_CONTROLLER_CLOCK_GATING) 427 427 #endif 428 428 429 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 430 + #define HWSEQ_DCN302_REG_LIST()\ 431 + HWSEQ_DCN_REG_LIST(), \ 432 + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \ 433 + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 1), \ 434 + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 2), \ 435 + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 3), \ 436 + HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 4), \ 437 + SR(MICROSECOND_TIME_BASE_DIV), \ 438 + SR(MILLISECOND_TIME_BASE_DIV), \ 439 + SR(DISPCLK_FREQ_CHANGE_CNTL), \ 440 + SR(RBBMIF_TIMEOUT_DIS), \ 441 + SR(RBBMIF_TIMEOUT_DIS_2), \ 442 + SR(DCHUBBUB_CRC_CTRL), \ 443 + SR(DPP_TOP0_DPP_CRC_CTRL), \ 444 + SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ 445 + SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ 446 + SR(MPC_CRC_CTRL), \ 447 + SR(MPC_CRC_RESULT_GB), \ 448 + SR(MPC_CRC_RESULT_C), \ 449 + SR(MPC_CRC_RESULT_AR), \ 450 + SR(DOMAIN0_PG_CONFIG), \ 451 + SR(DOMAIN1_PG_CONFIG), \ 452 + SR(DOMAIN2_PG_CONFIG), \ 453 + SR(DOMAIN3_PG_CONFIG), \ 454 + SR(DOMAIN4_PG_CONFIG), \ 455 + SR(DOMAIN5_PG_CONFIG), \ 456 + SR(DOMAIN6_PG_CONFIG), \ 457 + SR(DOMAIN7_PG_CONFIG), \ 458 + SR(DOMAIN8_PG_CONFIG), \ 459 + SR(DOMAIN9_PG_CONFIG), \ 460 + SR(DOMAIN16_PG_CONFIG), \ 461 + SR(DOMAIN17_PG_CONFIG), \ 462 + SR(DOMAIN18_PG_CONFIG), \ 463 + SR(DOMAIN19_PG_CONFIG), \ 464 + SR(DOMAIN20_PG_CONFIG), \ 465 + SR(DOMAIN0_PG_STATUS), \ 466 + SR(DOMAIN1_PG_STATUS), \ 467 + SR(DOMAIN2_PG_STATUS), \ 468 + SR(DOMAIN3_PG_STATUS), \ 469 + SR(DOMAIN4_PG_STATUS), \ 470 + SR(DOMAIN5_PG_STATUS), \ 471 + SR(DOMAIN6_PG_STATUS), \ 472 + SR(DOMAIN7_PG_STATUS), \ 473 + SR(DOMAIN8_PG_STATUS), \ 474 + SR(DOMAIN9_PG_STATUS), \ 475 + SR(DOMAIN16_PG_STATUS), \ 476 + SR(DOMAIN17_PG_STATUS), \ 477 + SR(DOMAIN18_PG_STATUS), \ 478 + SR(DOMAIN19_PG_STATUS), \ 479 + SR(DOMAIN20_PG_STATUS), \ 480 + SR(D1VGA_CONTROL), \ 481 + SR(D2VGA_CONTROL), \ 482 + SR(D3VGA_CONTROL), \ 483 + SR(D4VGA_CONTROL), \ 484 + SR(D5VGA_CONTROL), \ 485 + SR(D6VGA_CONTROL), \ 486 + SR(DC_IP_REQUEST_CNTL), \ 487 + SR(AZALIA_AUDIO_DTO), \ 488 + SR(AZALIA_CONTROLLER_CLOCK_GATING) 489 + 490 + #endif 491 + 492 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 493 + 494 + #define HWSEQ_PIXEL_RATE_REG_LIST_302(blk) \ 495 + SRII(PIXEL_RATE_CNTL, blk, 0), \ 496 + SRII(PIXEL_RATE_CNTL, blk, 1),\ 497 + SRII(PIXEL_RATE_CNTL, blk, 2),\ 498 + SRII(PIXEL_RATE_CNTL, blk, 3), \ 499 + SRII(PIXEL_RATE_CNTL, blk, 4) 500 + 501 + #define HWSEQ_PHYPLL_REG_LIST_302(blk) \ 502 + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ 503 + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\ 504 + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\ 505 + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \ 506 + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4) 507 + #endif 508 + 429 509 struct dce_hwseq_registers { 430 510 uint32_t DCFE_CLOCK_CONTROL[6]; 431 511 uint32_t DCFEV_CLOCK_CONTROL; ··· 891 811 HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON_OVRD, mask_sh),\ 892 812 HWS_SF(, PANEL_PWRSEQ0_STATE, PANEL_PWRSEQ_TARGET_STATE_R, mask_sh),\ 893 813 HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) 814 + #endif 815 + 816 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 817 + #define HWSEQ_DCN302_MASK_SH_LIST(mask_sh)\ 818 + HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ 819 + HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ 820 + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \ 821 + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \ 822 + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \ 823 + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \ 824 + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \ 825 + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \ 826 + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \ 827 + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \ 828 + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \ 829 + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \ 830 + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \ 831 + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \ 832 + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \ 833 + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \ 834 + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \ 835 + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \ 836 + HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, mask_sh), \ 837 + HWS_SF(, DOMAIN8_PG_CONFIG, DOMAIN8_POWER_GATE, mask_sh), \ 838 + HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, mask_sh), \ 839 + HWS_SF(, DOMAIN9_PG_CONFIG, DOMAIN9_POWER_GATE, mask_sh), \ 840 + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \ 841 + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \ 842 + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \ 843 + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \ 844 + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \ 845 + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \ 846 + HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, mask_sh), \ 847 + HWS_SF(, DOMAIN19_PG_CONFIG, DOMAIN19_POWER_GATE, mask_sh), \ 848 + HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, mask_sh), \ 849 + HWS_SF(, DOMAIN20_PG_CONFIG, DOMAIN20_POWER_GATE, mask_sh), \ 850 + HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \ 851 + HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \ 852 + HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \ 853 + HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \ 854 + HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \ 855 + HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ 856 + HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ 857 + HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ 858 + HWS_SF(, DOMAIN8_PG_STATUS, DOMAIN8_PGFSM_PWR_STATUS, mask_sh), \ 859 + HWS_SF(, DOMAIN9_PG_STATUS, DOMAIN9_PGFSM_PWR_STATUS, mask_sh), \ 860 + HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \ 861 + HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ 862 + HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ 863 + HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN19_PGFSM_PWR_STATUS, mask_sh), \ 864 + HWS_SF(, DOMAIN20_PG_STATUS, DOMAIN20_PGFSM_PWR_STATUS, mask_sh), \ 865 + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ 866 + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) 867 + 894 868 #endif 895 869 896 870 #define HWSEQ_REG_FIELD_LIST(type) \
+17
drivers/gpu/drm/amd/display/dc/dcn302/Makefile
··· 1 + # 2 + # (c) Copyright 2020 Advanced Micro Devices, Inc. All the rights reserved 3 + # 4 + # All rights reserved. This notice is intended as a precaution against 5 + # inadvertent publication and does not imply publication or any waiver 6 + # of confidentiality. The year included in the foregoing notice is the 7 + # year of creation of the work. 8 + # 9 + # Authors: AMD 10 + # 11 + # Makefile for dcn302. 12 + 13 + DCN3_02 = dcn302_init.o dcn302_hwseq.o dcn302_resource.o 14 + 15 + AMD_DAL_DCN3_02 = $(addprefix $(AMDDALPATH)/dc/dcn302/,$(DCN3_02)) 16 + 17 + AMD_DISPLAY_FILES += $(AMD_DAL_DCN3_02)
+41
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_dccg.h
··· 1 + /* 2 + * Copyright 2020 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 __DCN302_DCCG_H__ 27 + #define __DCN302_DCCG_H__ 28 + 29 + #include "dcn30/dcn30_dccg.h" 30 + 31 + 32 + #define DCCG_REG_LIST_DCN3_02() \ 33 + DCCG_COMMON_REG_LIST_DCN_BASE(),\ 34 + DCCG_SRII(DTO_PARAM, DPPCLK, 4) 35 + 36 + #define DCCG_MASK_SH_LIST_DCN3_02(mask_sh) \ 37 + DCCG_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ 38 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 4, mask_sh),\ 39 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 4, mask_sh) 40 + 41 + #endif //__DCN302_DCCG_H__
+233
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.c
··· 1 + /* 2 + * Copyright 2020 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 "dcn302_hwseq.h" 27 + 28 + #include "dce/dce_hwseq.h" 29 + 30 + #include "reg_helper.h" 31 + #include "dc.h" 32 + 33 + #define DC_LOGGER_INIT(logger) 34 + 35 + #define CTX \ 36 + hws->ctx 37 + #define REG(reg)\ 38 + hws->regs->reg 39 + 40 + #undef FN 41 + #define FN(reg_name, field_name) \ 42 + hws->shifts->field_name, hws->masks->field_name 43 + 44 + 45 + void dcn302_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on) 46 + { 47 + uint32_t power_gate = power_on ? 0 : 1; 48 + uint32_t pwr_status = power_on ? 0 : 2; 49 + 50 + if (hws->ctx->dc->debug.disable_dpp_power_gate) 51 + return; 52 + if (REG(DOMAIN1_PG_CONFIG) == 0) 53 + return; 54 + 55 + switch (dpp_inst) { 56 + case 0: /* DPP0 */ 57 + REG_UPDATE(DOMAIN1_PG_CONFIG, 58 + DOMAIN1_POWER_GATE, power_gate); 59 + 60 + REG_WAIT(DOMAIN1_PG_STATUS, 61 + DOMAIN1_PGFSM_PWR_STATUS, pwr_status, 62 + 1, 1000); 63 + break; 64 + case 1: /* DPP1 */ 65 + REG_UPDATE(DOMAIN3_PG_CONFIG, 66 + DOMAIN3_POWER_GATE, power_gate); 67 + 68 + REG_WAIT(DOMAIN3_PG_STATUS, 69 + DOMAIN3_PGFSM_PWR_STATUS, pwr_status, 70 + 1, 1000); 71 + break; 72 + case 2: /* DPP2 */ 73 + REG_UPDATE(DOMAIN5_PG_CONFIG, 74 + DOMAIN5_POWER_GATE, power_gate); 75 + 76 + REG_WAIT(DOMAIN5_PG_STATUS, 77 + DOMAIN5_PGFSM_PWR_STATUS, pwr_status, 78 + 1, 1000); 79 + break; 80 + case 3: /* DPP3 */ 81 + REG_UPDATE(DOMAIN7_PG_CONFIG, 82 + DOMAIN7_POWER_GATE, power_gate); 83 + 84 + REG_WAIT(DOMAIN7_PG_STATUS, 85 + DOMAIN7_PGFSM_PWR_STATUS, pwr_status, 86 + 1, 1000); 87 + break; 88 + case 4: /* DPP4 */ 89 + /* 90 + * Do not power gate DPP4, should be left at HW default, power on permanently. 91 + * PG on Pipe4 is De-featured, attempting to put it to PG state may result in hard 92 + * reset. 93 + * REG_UPDATE(DOMAIN9_PG_CONFIG, 94 + * DOMAIN9_POWER_GATE, power_gate); 95 + * 96 + * REG_WAIT(DOMAIN9_PG_STATUS, 97 + * DOMAIN9_PGFSM_PWR_STATUS, pwr_status, 98 + * 1, 1000); 99 + */ 100 + break; 101 + default: 102 + BREAK_TO_DEBUGGER(); 103 + break; 104 + } 105 + } 106 + 107 + void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on) 108 + { 109 + uint32_t power_gate = power_on ? 0 : 1; 110 + uint32_t pwr_status = power_on ? 0 : 2; 111 + 112 + if (hws->ctx->dc->debug.disable_hubp_power_gate) 113 + return; 114 + if (REG(DOMAIN0_PG_CONFIG) == 0) 115 + return; 116 + 117 + switch (hubp_inst) { 118 + case 0: /* DCHUBP0 */ 119 + REG_UPDATE(DOMAIN0_PG_CONFIG, 120 + DOMAIN0_POWER_GATE, power_gate); 121 + 122 + REG_WAIT(DOMAIN0_PG_STATUS, 123 + DOMAIN0_PGFSM_PWR_STATUS, pwr_status, 124 + 1, 1000); 125 + break; 126 + case 1: /* DCHUBP1 */ 127 + REG_UPDATE(DOMAIN2_PG_CONFIG, 128 + DOMAIN2_POWER_GATE, power_gate); 129 + 130 + REG_WAIT(DOMAIN2_PG_STATUS, 131 + DOMAIN2_PGFSM_PWR_STATUS, pwr_status, 132 + 1, 1000); 133 + break; 134 + case 2: /* DCHUBP2 */ 135 + REG_UPDATE(DOMAIN4_PG_CONFIG, 136 + DOMAIN4_POWER_GATE, power_gate); 137 + 138 + REG_WAIT(DOMAIN4_PG_STATUS, 139 + DOMAIN4_PGFSM_PWR_STATUS, pwr_status, 140 + 1, 1000); 141 + break; 142 + case 3: /* DCHUBP3 */ 143 + REG_UPDATE(DOMAIN6_PG_CONFIG, 144 + DOMAIN6_POWER_GATE, power_gate); 145 + 146 + REG_WAIT(DOMAIN6_PG_STATUS, 147 + DOMAIN6_PGFSM_PWR_STATUS, pwr_status, 148 + 1, 1000); 149 + break; 150 + case 4: /* DCHUBP4 */ 151 + /* 152 + * Do not power gate DCHUB4, should be left at HW default, power on permanently. 153 + * PG on Pipe4 is De-featured, attempting to put it to PG state may result in hard 154 + * reset. 155 + * REG_UPDATE(DOMAIN8_PG_CONFIG, 156 + * DOMAIN8_POWER_GATE, power_gate); 157 + * 158 + * REG_WAIT(DOMAIN8_PG_STATUS, 159 + * DOMAIN8_PGFSM_PWR_STATUS, pwr_status, 160 + * 1, 1000); 161 + */ 162 + break; 163 + default: 164 + BREAK_TO_DEBUGGER(); 165 + break; 166 + } 167 + } 168 + 169 + void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on) 170 + { 171 + uint32_t power_gate = power_on ? 0 : 1; 172 + uint32_t pwr_status = power_on ? 0 : 2; 173 + uint32_t org_ip_request_cntl = 0; 174 + 175 + if (hws->ctx->dc->debug.disable_dsc_power_gate) 176 + return; 177 + 178 + if (REG(DOMAIN16_PG_CONFIG) == 0) 179 + return; 180 + 181 + REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 182 + if (org_ip_request_cntl == 0) 183 + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 184 + 185 + switch (dsc_inst) { 186 + case 0: /* DSC0 */ 187 + REG_UPDATE(DOMAIN16_PG_CONFIG, 188 + DOMAIN16_POWER_GATE, power_gate); 189 + 190 + REG_WAIT(DOMAIN16_PG_STATUS, 191 + DOMAIN16_PGFSM_PWR_STATUS, pwr_status, 192 + 1, 1000); 193 + break; 194 + case 1: /* DSC1 */ 195 + REG_UPDATE(DOMAIN17_PG_CONFIG, 196 + DOMAIN17_POWER_GATE, power_gate); 197 + 198 + REG_WAIT(DOMAIN17_PG_STATUS, 199 + DOMAIN17_PGFSM_PWR_STATUS, pwr_status, 200 + 1, 1000); 201 + break; 202 + case 2: /* DSC2 */ 203 + REG_UPDATE(DOMAIN18_PG_CONFIG, 204 + DOMAIN18_POWER_GATE, power_gate); 205 + 206 + REG_WAIT(DOMAIN18_PG_STATUS, 207 + DOMAIN18_PGFSM_PWR_STATUS, pwr_status, 208 + 1, 1000); 209 + break; 210 + case 3: /* DSC3 */ 211 + REG_UPDATE(DOMAIN19_PG_CONFIG, 212 + DOMAIN19_POWER_GATE, power_gate); 213 + 214 + REG_WAIT(DOMAIN19_PG_STATUS, 215 + DOMAIN19_PGFSM_PWR_STATUS, pwr_status, 216 + 1, 1000); 217 + break; 218 + case 4: /* DSC4 */ 219 + REG_UPDATE(DOMAIN20_PG_CONFIG, 220 + DOMAIN20_POWER_GATE, power_gate); 221 + 222 + REG_WAIT(DOMAIN20_PG_STATUS, 223 + DOMAIN20_PGFSM_PWR_STATUS, pwr_status, 224 + 1, 1000); 225 + break; 226 + default: 227 + BREAK_TO_DEBUGGER(); 228 + break; 229 + } 230 + 231 + if (org_ip_request_cntl == 0) 232 + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); 233 + }
+35
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_hwseq.h
··· 1 + /* 2 + * Copyright 2020 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_DCN302_H__ 27 + #define __DC_HWSS_DCN302_H__ 28 + 29 + #include "hw_sequencer_private.h" 30 + 31 + void dcn302_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on); 32 + void dcn302_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on); 33 + void dcn302_dsc_pg_control(struct dce_hwseq *hws, unsigned int dsc_inst, bool power_on); 34 + 35 + #endif /* __DC_HWSS_DCN302_H__ */
+39
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_init.c
··· 1 + /* 2 + * Copyright 2020 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 "dcn302_hwseq.h" 27 + 28 + #include "dcn30/dcn30_init.h" 29 + 30 + #include "dc.h" 31 + 32 + void dcn302_hw_sequencer_construct(struct dc *dc) 33 + { 34 + dcn30_hw_sequencer_construct(dc); 35 + 36 + dc->hwseq->funcs.dpp_pg_control = dcn302_dpp_pg_control; 37 + dc->hwseq->funcs.hubp_pg_control = dcn302_hubp_pg_control; 38 + dc->hwseq->funcs.dsc_pg_control = dcn302_dsc_pg_control; 39 + }
+33
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_init.h
··· 1 + /* 2 + * Copyright 2020 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_DCN302_INIT_H__ 27 + #define __DC_DCN302_INIT_H__ 28 + 29 + struct dc; 30 + 31 + void dcn302_hw_sequencer_construct(struct dc *dc); 32 + 33 + #endif /* __DC_DCN302_INIT_H__ */
+1619
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
··· 1 + /* 2 + * Copyright 2020 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 "dcn302_init.h" 27 + #include "dcn302_resource.h" 28 + #include "dcn302_dccg.h" 29 + #include "irq/dcn302/irq_service_dcn302.h" 30 + 31 + #include "dcn30/dcn30_dio_link_encoder.h" 32 + #include "dcn30/dcn30_dio_stream_encoder.h" 33 + #include "dcn30/dcn30_dwb.h" 34 + #include "dcn30/dcn30_dpp.h" 35 + #include "dcn30/dcn30_hubbub.h" 36 + #include "dcn30/dcn30_hubp.h" 37 + #include "dcn30/dcn30_mmhubbub.h" 38 + #include "dcn30/dcn30_mpc.h" 39 + #include "dcn30/dcn30_opp.h" 40 + #include "dcn30/dcn30_optc.h" 41 + #include "dcn30/dcn30_resource.h" 42 + 43 + #include "dcn20/dcn20_dsc.h" 44 + #include "dcn20/dcn20_resource.h" 45 + 46 + #include "dcn10/dcn10_resource.h" 47 + 48 + #include "dce/dce_abm.h" 49 + #include "dce/dce_audio.h" 50 + #include "dce/dce_aux.h" 51 + #include "dce/dce_clock_source.h" 52 + #include "dce/dce_hwseq.h" 53 + #include "dce/dce_i2c_hw.h" 54 + #include "dce/dce_panel_cntl.h" 55 + #include "dce/dmub_abm.h" 56 + 57 + #include "hw_sequencer_private.h" 58 + #include "reg_helper.h" 59 + #include "resource.h" 60 + #include "vm_helper.h" 61 + 62 + #include "dimgrey_cavefish_ip_offset.h" 63 + #include "dcn/dcn_3_0_0_offset.h" 64 + #include "dcn/dcn_3_0_0_sh_mask.h" 65 + #include "dcn/dpcs_3_0_0_offset.h" 66 + #include "dcn/dpcs_3_0_0_sh_mask.h" 67 + #include "nbio/nbio_7_4_offset.h" 68 + 69 + #define DC_LOGGER_INIT(logger) 70 + 71 + struct gpu_info_voltage_scaling_v1_0 { 72 + int state; 73 + uint32_t dscclk_mhz; 74 + uint32_t dcfclk_mhz; 75 + uint32_t socclk_mhz; 76 + uint32_t dram_speed_mts; 77 + uint32_t fabricclk_mhz; 78 + uint32_t dispclk_mhz; 79 + uint32_t phyclk_mhz; 80 + uint32_t dppclk_mhz; 81 + }; 82 + 83 + struct gpu_info_soc_bounding_box_v1_0 { 84 + uint32_t sr_exit_time_us; 85 + uint32_t sr_enter_plus_exit_time_us; 86 + uint32_t urgent_latency_us; 87 + uint32_t urgent_latency_pixel_data_only_us; 88 + uint32_t urgent_latency_pixel_mixed_with_vm_data_us; 89 + uint32_t urgent_latency_vm_data_only_us; 90 + uint32_t writeback_latency_us; 91 + uint32_t ideal_dram_bw_after_urgent_percent; 92 + // PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly 93 + uint32_t pct_ideal_dram_sdp_bw_after_urgent_pixel_only; 94 + uint32_t pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm; 95 + uint32_t pct_ideal_dram_sdp_bw_after_urgent_vm_only; 96 + uint32_t max_avg_sdp_bw_use_normal_percent; 97 + uint32_t max_avg_dram_bw_use_normal_percent; 98 + unsigned int max_request_size_bytes; 99 + uint32_t downspread_percent; 100 + uint32_t dram_page_open_time_ns; 101 + uint32_t dram_rw_turnaround_time_ns; 102 + uint32_t dram_return_buffer_per_channel_bytes; 103 + uint32_t dram_channel_width_bytes; 104 + uint32_t fabric_datapath_to_dcn_data_return_bytes; 105 + uint32_t dcn_downspread_percent; 106 + uint32_t dispclk_dppclk_vco_speed_mhz; 107 + uint32_t dfs_vco_period_ps; 108 + unsigned int urgent_out_of_order_return_per_channel_pixel_only_bytes; 109 + unsigned int urgent_out_of_order_return_per_channel_pixel_and_vm_bytes; 110 + unsigned int urgent_out_of_order_return_per_channel_vm_only_bytes; 111 + unsigned int round_trip_ping_latency_dcfclk_cycles; 112 + unsigned int urgent_out_of_order_return_per_channel_bytes; 113 + unsigned int channel_interleave_bytes; 114 + unsigned int num_banks; 115 + unsigned int num_chans; 116 + unsigned int vmm_page_size_bytes; 117 + uint32_t dram_clock_change_latency_us; 118 + uint32_t writeback_dram_clock_change_latency_us; 119 + unsigned int return_bus_width_bytes; 120 + unsigned int voltage_override; 121 + uint32_t xfc_bus_transport_time_us; 122 + uint32_t xfc_xbuf_latency_tolerance_us; 123 + int use_urgent_burst_bw; 124 + unsigned int num_states; 125 + struct gpu_info_voltage_scaling_v1_0 clock_limits[8]; 126 + }; 127 + 128 + struct _vcs_dpi_ip_params_st dcn3_02_ip = { 129 + .use_min_dcfclk = 0, 130 + .clamp_min_dcfclk = 0, 131 + .odm_capable = 1, 132 + .gpuvm_enable = 1, 133 + .hostvm_enable = 0, 134 + .gpuvm_max_page_table_levels = 4, 135 + .hostvm_max_page_table_levels = 4, 136 + .hostvm_cached_page_table_levels = 0, 137 + .pte_group_size_bytes = 2048, 138 + .num_dsc = 5, 139 + .rob_buffer_size_kbytes = 184, 140 + .det_buffer_size_kbytes = 184, 141 + .dpte_buffer_size_in_pte_reqs_luma = 64, 142 + .dpte_buffer_size_in_pte_reqs_chroma = 34, 143 + .pde_proc_buffer_size_64k_reqs = 48, 144 + .dpp_output_buffer_pixels = 2560, 145 + .opp_output_buffer_lines = 1, 146 + .pixel_chunk_size_kbytes = 8, 147 + .pte_enable = 1, 148 + .max_page_table_levels = 2, 149 + .pte_chunk_size_kbytes = 2, // ? 150 + .meta_chunk_size_kbytes = 2, 151 + .writeback_chunk_size_kbytes = 8, 152 + .line_buffer_size_bits = 789504, 153 + .is_line_buffer_bpp_fixed = 0, // ? 154 + .line_buffer_fixed_bpp = 0, // ? 155 + .dcc_supported = true, 156 + .writeback_interface_buffer_size_kbytes = 90, 157 + .writeback_line_buffer_buffer_size = 0, 158 + .max_line_buffer_lines = 12, 159 + .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 160 + .writeback_chroma_buffer_size_kbytes = 8, 161 + .writeback_chroma_line_buffer_width_pixels = 4, 162 + .writeback_max_hscl_ratio = 1, 163 + .writeback_max_vscl_ratio = 1, 164 + .writeback_min_hscl_ratio = 1, 165 + .writeback_min_vscl_ratio = 1, 166 + .writeback_max_hscl_taps = 1, 167 + .writeback_max_vscl_taps = 1, 168 + .writeback_line_buffer_luma_buffer_size = 0, 169 + .writeback_line_buffer_chroma_buffer_size = 14643, 170 + .cursor_buffer_size = 8, 171 + .cursor_chunk_size = 2, 172 + .max_num_otg = 5, 173 + .max_num_dpp = 5, 174 + .max_num_wb = 1, 175 + .max_dchub_pscl_bw_pix_per_clk = 4, 176 + .max_pscl_lb_bw_pix_per_clk = 2, 177 + .max_lb_vscl_bw_pix_per_clk = 4, 178 + .max_vscl_hscl_bw_pix_per_clk = 4, 179 + .max_hscl_ratio = 6, 180 + .max_vscl_ratio = 6, 181 + .hscl_mults = 4, 182 + .vscl_mults = 4, 183 + .max_hscl_taps = 8, 184 + .max_vscl_taps = 8, 185 + .dispclk_ramp_margin_percent = 1, 186 + .underscan_factor = 1.11, 187 + .min_vblank_lines = 32, 188 + .dppclk_delay_subtotal = 46, 189 + .dynamic_metadata_vm_enabled = true, 190 + .dppclk_delay_scl_lb_only = 16, 191 + .dppclk_delay_scl = 50, 192 + .dppclk_delay_cnvc_formatter = 27, 193 + .dppclk_delay_cnvc_cursor = 6, 194 + .dispclk_delay_subtotal = 119, 195 + .dcfclk_cstate_latency = 5.2, // SRExitTime 196 + .max_inter_dcn_tile_repeaters = 8, 197 + .max_num_hdmi_frl_outputs = 1, 198 + .odm_combine_4to1_supported = true, 199 + 200 + .xfc_supported = false, 201 + .xfc_fill_bw_overhead_percent = 10.0, 202 + .xfc_fill_constant_bytes = 0, 203 + .gfx7_compat_tiling_supported = 0, 204 + .number_of_cursors = 1, 205 + }; 206 + 207 + struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = { 208 + .clock_limits = { 209 + { 210 + .state = 0, 211 + .dispclk_mhz = 562.0, 212 + .dppclk_mhz = 300.0, 213 + .phyclk_mhz = 300.0, 214 + .phyclk_d18_mhz = 667.0, 215 + .dscclk_mhz = 405.6, 216 + }, 217 + }, 218 + 219 + .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */ 220 + .num_states = 1, 221 + .sr_exit_time_us = 5.20, 222 + .sr_enter_plus_exit_time_us = 9.60, 223 + .urgent_latency_us = 4.0, 224 + .urgent_latency_pixel_data_only_us = 4.0, 225 + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, 226 + .urgent_latency_vm_data_only_us = 4.0, 227 + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 228 + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 229 + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 230 + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, 231 + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, 232 + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, 233 + .max_avg_sdp_bw_use_normal_percent = 60.0, 234 + .max_avg_dram_bw_use_normal_percent = 40.0, 235 + .writeback_latency_us = 12.0, 236 + .max_request_size_bytes = 256, 237 + .fabric_datapath_to_dcn_data_return_bytes = 64, 238 + .dcn_downspread_percent = 0.5, 239 + .downspread_percent = 0.38, 240 + .dram_page_open_time_ns = 50.0, 241 + .dram_rw_turnaround_time_ns = 17.5, 242 + .dram_return_buffer_per_channel_bytes = 8192, 243 + .round_trip_ping_latency_dcfclk_cycles = 156, 244 + .urgent_out_of_order_return_per_channel_bytes = 4096, 245 + .channel_interleave_bytes = 256, 246 + .num_banks = 8, 247 + .gpuvm_min_page_size_bytes = 4096, 248 + .hostvm_min_page_size_bytes = 4096, 249 + .dram_clock_change_latency_us = 350, 250 + .dummy_pstate_latency_us = 5, 251 + .writeback_dram_clock_change_latency_us = 23.0, 252 + .return_bus_width_bytes = 64, 253 + .dispclk_dppclk_vco_speed_mhz = 3650, 254 + .xfc_bus_transport_time_us = 20, // ? 255 + .xfc_xbuf_latency_tolerance_us = 4, // ? 256 + .use_urgent_burst_bw = 1, // ? 257 + .do_urgent_latency_adjustment = true, 258 + .urgent_latency_adjustment_fabric_clock_component_us = 1.0, 259 + .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, 260 + }; 261 + 262 + static const struct dc_debug_options debug_defaults_drv = { 263 + .disable_dmcu = true, 264 + .force_abm_enable = false, 265 + .timing_trace = false, 266 + .clock_trace = true, 267 + .disable_pplib_clock_request = true, 268 + .pipe_split_policy = MPC_SPLIT_DYNAMIC, 269 + .force_single_disp_pipe_split = false, 270 + .disable_dcc = DCC_ENABLE, 271 + .vsr_support = true, 272 + .performance_trace = false, 273 + .max_downscale_src_width = 7680,/*upto 8K*/ 274 + .disable_pplib_wm_range = false, 275 + .scl_reset_length10 = true, 276 + .sanity_checks = false, 277 + .underflow_assert_delay_us = 0xFFFFFFFF, 278 + .dwb_fi_phase = -1, // -1 = disable, 279 + .dmub_command_table = true, 280 + }; 281 + 282 + static const struct dc_debug_options debug_defaults_diags = { 283 + .disable_dmcu = true, 284 + .force_abm_enable = false, 285 + .timing_trace = true, 286 + .clock_trace = true, 287 + .disable_dpp_power_gate = true, 288 + .disable_hubp_power_gate = true, 289 + .disable_clock_gate = true, 290 + .disable_pplib_clock_request = true, 291 + .disable_pplib_wm_range = true, 292 + .disable_stutter = false, 293 + .scl_reset_length10 = true, 294 + .dwb_fi_phase = -1, // -1 = disable 295 + .dmub_command_table = true, 296 + .enable_tri_buf = true, 297 + }; 298 + 299 + enum dcn302_clk_src_array_id { 300 + DCN302_CLK_SRC_PLL0, 301 + DCN302_CLK_SRC_PLL1, 302 + DCN302_CLK_SRC_PLL2, 303 + DCN302_CLK_SRC_PLL3, 304 + DCN302_CLK_SRC_PLL4, 305 + DCN302_CLK_SRC_TOTAL 306 + }; 307 + 308 + static const struct resource_caps res_cap_dcn302 = { 309 + .num_timing_generator = 5, 310 + .num_opp = 5, 311 + .num_video_plane = 5, 312 + .num_audio = 5, 313 + .num_stream_encoder = 5, 314 + .num_dwb = 1, 315 + .num_ddc = 5, 316 + .num_vmid = 16, 317 + .num_mpc_3dlut = 2, 318 + .num_dsc = 5, 319 + }; 320 + 321 + static const struct dc_plane_cap plane_cap = { 322 + .type = DC_PLANE_TYPE_DCN_UNIVERSAL, 323 + .blends_with_above = true, 324 + .blends_with_below = true, 325 + .per_pixel_alpha = true, 326 + .pixel_format_support = { 327 + .argb8888 = true, 328 + .nv12 = true, 329 + .fp16 = true, 330 + .p010 = false, 331 + .ayuv = false, 332 + }, 333 + .max_upscale_factor = { 334 + .argb8888 = 16000, 335 + .nv12 = 16000, 336 + .fp16 = 16000 337 + }, 338 + .max_downscale_factor = { 339 + .argb8888 = 600, 340 + .nv12 = 600, 341 + .fp16 = 600 342 + }, 343 + 16, 344 + 16 345 + }; 346 + 347 + /* NBIO */ 348 + #define NBIO_BASE_INNER(seg) \ 349 + NBIO_BASE__INST0_SEG ## seg 350 + 351 + #define NBIO_BASE(seg) \ 352 + NBIO_BASE_INNER(seg) 353 + 354 + #define NBIO_SR(reg_name)\ 355 + .reg_name = NBIO_BASE(mm ## reg_name ## _BASE_IDX) + \ 356 + mm ## reg_name 357 + 358 + /* DCN */ 359 + #undef BASE_INNER 360 + #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg 361 + 362 + #define BASE(seg) BASE_INNER(seg) 363 + 364 + #define SR(reg_name)\ 365 + .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name 366 + 367 + #define SF(reg_name, field_name, post_fix)\ 368 + .field_name = reg_name ## __ ## field_name ## post_fix 369 + 370 + #define SRI(reg_name, block, id)\ 371 + .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + mm ## block ## id ## _ ## reg_name 372 + 373 + #define SRI2(reg_name, block, id)\ 374 + .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name 375 + 376 + #define SRII(reg_name, block, id)\ 377 + .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 378 + mm ## block ## id ## _ ## reg_name 379 + 380 + #define DCCG_SRII(reg_name, block, id)\ 381 + .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 382 + mm ## block ## id ## _ ## reg_name 383 + 384 + #define VUPDATE_SRII(reg_name, block, id)\ 385 + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ 386 + mm ## reg_name ## _ ## block ## id 387 + 388 + #define SRII_DWB(reg_name, temp_name, block, id)\ 389 + .reg_name[id] = BASE(mm ## block ## id ## _ ## temp_name ## _BASE_IDX) + \ 390 + mm ## block ## id ## _ ## temp_name 391 + 392 + #define SRII_MPC_RMU(reg_name, block, id)\ 393 + .RMU##_##reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 394 + mm ## block ## id ## _ ## reg_name 395 + 396 + static const struct dcn_hubbub_registers hubbub_reg = { 397 + HUBBUB_REG_LIST_DCN30(0) 398 + }; 399 + 400 + static const struct dcn_hubbub_shift hubbub_shift = { 401 + HUBBUB_MASK_SH_LIST_DCN30(__SHIFT) 402 + }; 403 + 404 + static const struct dcn_hubbub_mask hubbub_mask = { 405 + HUBBUB_MASK_SH_LIST_DCN30(_MASK) 406 + }; 407 + 408 + #define vmid_regs(id)\ 409 + [id] = { DCN20_VMID_REG_LIST(id) } 410 + 411 + static const struct dcn_vmid_registers vmid_regs[] = { 412 + vmid_regs(0), 413 + vmid_regs(1), 414 + vmid_regs(2), 415 + vmid_regs(3), 416 + vmid_regs(4), 417 + vmid_regs(5), 418 + vmid_regs(6), 419 + vmid_regs(7), 420 + vmid_regs(8), 421 + vmid_regs(9), 422 + vmid_regs(10), 423 + vmid_regs(11), 424 + vmid_regs(12), 425 + vmid_regs(13), 426 + vmid_regs(14), 427 + vmid_regs(15) 428 + }; 429 + 430 + static const struct dcn20_vmid_shift vmid_shifts = { 431 + DCN20_VMID_MASK_SH_LIST(__SHIFT) 432 + }; 433 + 434 + static const struct dcn20_vmid_mask vmid_masks = { 435 + DCN20_VMID_MASK_SH_LIST(_MASK) 436 + }; 437 + 438 + static struct hubbub *dcn302_hubbub_create(struct dc_context *ctx) 439 + { 440 + int i; 441 + 442 + struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), GFP_KERNEL); 443 + 444 + if (!hubbub3) 445 + return NULL; 446 + 447 + hubbub3_construct(hubbub3, ctx, &hubbub_reg, &hubbub_shift, &hubbub_mask); 448 + 449 + for (i = 0; i < res_cap_dcn302.num_vmid; i++) { 450 + struct dcn20_vmid *vmid = &hubbub3->vmid[i]; 451 + 452 + vmid->ctx = ctx; 453 + 454 + vmid->regs = &vmid_regs[i]; 455 + vmid->shifts = &vmid_shifts; 456 + vmid->masks = &vmid_masks; 457 + } 458 + 459 + return &hubbub3->base; 460 + } 461 + 462 + #define vpg_regs(id)\ 463 + [id] = { VPG_DCN3_REG_LIST(id) } 464 + 465 + static const struct dcn30_vpg_registers vpg_regs[] = { 466 + vpg_regs(0), 467 + vpg_regs(1), 468 + vpg_regs(2), 469 + vpg_regs(3), 470 + vpg_regs(4), 471 + vpg_regs(5) 472 + }; 473 + 474 + static const struct dcn30_vpg_shift vpg_shift = { 475 + DCN3_VPG_MASK_SH_LIST(__SHIFT) 476 + }; 477 + 478 + static const struct dcn30_vpg_mask vpg_mask = { 479 + DCN3_VPG_MASK_SH_LIST(_MASK) 480 + }; 481 + 482 + static struct vpg *dcn302_vpg_create(struct dc_context *ctx, uint32_t inst) 483 + { 484 + struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); 485 + 486 + if (!vpg3) 487 + return NULL; 488 + 489 + vpg3_construct(vpg3, ctx, inst, &vpg_regs[inst], &vpg_shift, &vpg_mask); 490 + 491 + return &vpg3->base; 492 + } 493 + 494 + #define afmt_regs(id)\ 495 + [id] = { AFMT_DCN3_REG_LIST(id) } 496 + 497 + static const struct dcn30_afmt_registers afmt_regs[] = { 498 + afmt_regs(0), 499 + afmt_regs(1), 500 + afmt_regs(2), 501 + afmt_regs(3), 502 + afmt_regs(4), 503 + afmt_regs(5) 504 + }; 505 + 506 + static const struct dcn30_afmt_shift afmt_shift = { 507 + DCN3_AFMT_MASK_SH_LIST(__SHIFT) 508 + }; 509 + 510 + static const struct dcn30_afmt_mask afmt_mask = { 511 + DCN3_AFMT_MASK_SH_LIST(_MASK) 512 + }; 513 + 514 + static struct afmt *dcn302_afmt_create(struct dc_context *ctx, uint32_t inst) 515 + { 516 + struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); 517 + 518 + if (!afmt3) 519 + return NULL; 520 + 521 + afmt3_construct(afmt3, ctx, inst, &afmt_regs[inst], &afmt_shift, &afmt_mask); 522 + 523 + return &afmt3->base; 524 + } 525 + 526 + #define audio_regs(id)\ 527 + [id] = { AUD_COMMON_REG_LIST(id) } 528 + 529 + static const struct dce_audio_registers audio_regs[] = { 530 + audio_regs(0), 531 + audio_regs(1), 532 + audio_regs(2), 533 + audio_regs(3), 534 + audio_regs(4), 535 + audio_regs(5), 536 + audio_regs(6) 537 + }; 538 + 539 + #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ 540 + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ 541 + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\ 542 + AUD_COMMON_MASK_SH_LIST_BASE(mask_sh) 543 + 544 + static const struct dce_audio_shift audio_shift = { 545 + DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT) 546 + }; 547 + 548 + static const struct dce_audio_mask audio_mask = { 549 + DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) 550 + }; 551 + 552 + static struct audio *dcn302_create_audio(struct dc_context *ctx, unsigned int inst) 553 + { 554 + return dce_audio_create(ctx, inst, &audio_regs[inst], &audio_shift, &audio_mask); 555 + } 556 + 557 + #define stream_enc_regs(id)\ 558 + [id] = { SE_DCN3_REG_LIST(id) } 559 + 560 + static const struct dcn10_stream_enc_registers stream_enc_regs[] = { 561 + stream_enc_regs(0), 562 + stream_enc_regs(1), 563 + stream_enc_regs(2), 564 + stream_enc_regs(3), 565 + stream_enc_regs(4) 566 + }; 567 + 568 + static const struct dcn10_stream_encoder_shift se_shift = { 569 + SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 570 + }; 571 + 572 + static const struct dcn10_stream_encoder_mask se_mask = { 573 + SE_COMMON_MASK_SH_LIST_DCN30(_MASK) 574 + }; 575 + 576 + static struct stream_encoder *dcn302_stream_encoder_create(enum engine_id eng_id, struct dc_context *ctx) 577 + { 578 + struct dcn10_stream_encoder *enc1; 579 + struct vpg *vpg; 580 + struct afmt *afmt; 581 + int vpg_inst; 582 + int afmt_inst; 583 + 584 + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ 585 + if (eng_id <= ENGINE_ID_DIGE) { 586 + vpg_inst = eng_id; 587 + afmt_inst = eng_id; 588 + } else 589 + return NULL; 590 + 591 + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); 592 + vpg = dcn302_vpg_create(ctx, vpg_inst); 593 + afmt = dcn302_afmt_create(ctx, afmt_inst); 594 + 595 + if (!enc1 || !vpg || !afmt) 596 + return NULL; 597 + 598 + dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id], 599 + &se_shift, &se_mask); 600 + 601 + return &enc1->base; 602 + } 603 + 604 + #define clk_src_regs(index, pllid)\ 605 + [index] = { CS_COMMON_REG_LIST_DCN3_02(index, pllid) } 606 + 607 + static const struct dce110_clk_src_regs clk_src_regs[] = { 608 + clk_src_regs(0, A), 609 + clk_src_regs(1, B), 610 + clk_src_regs(2, C), 611 + clk_src_regs(3, D), 612 + clk_src_regs(4, E) 613 + }; 614 + 615 + static const struct dce110_clk_src_shift cs_shift = { 616 + CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT) 617 + }; 618 + 619 + static const struct dce110_clk_src_mask cs_mask = { 620 + CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK) 621 + }; 622 + 623 + static struct clock_source *dcn302_clock_source_create(struct dc_context *ctx, struct dc_bios *bios, 624 + enum clock_source_id id, const struct dce110_clk_src_regs *regs, bool dp_clk_src) 625 + { 626 + struct dce110_clk_src *clk_src = kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); 627 + 628 + if (!clk_src) 629 + return NULL; 630 + 631 + if (dcn3_clk_src_construct(clk_src, ctx, bios, id, regs, &cs_shift, &cs_mask)) { 632 + clk_src->base.dp_clk_src = dp_clk_src; 633 + return &clk_src->base; 634 + } 635 + 636 + BREAK_TO_DEBUGGER(); 637 + return NULL; 638 + } 639 + 640 + static const struct dce_hwseq_registers hwseq_reg = { 641 + HWSEQ_DCN302_REG_LIST() 642 + }; 643 + 644 + static const struct dce_hwseq_shift hwseq_shift = { 645 + HWSEQ_DCN302_MASK_SH_LIST(__SHIFT) 646 + }; 647 + 648 + static const struct dce_hwseq_mask hwseq_mask = { 649 + HWSEQ_DCN302_MASK_SH_LIST(_MASK) 650 + }; 651 + 652 + static struct dce_hwseq *dcn302_hwseq_create(struct dc_context *ctx) 653 + { 654 + struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); 655 + 656 + if (hws) { 657 + hws->ctx = ctx; 658 + hws->regs = &hwseq_reg; 659 + hws->shifts = &hwseq_shift; 660 + hws->masks = &hwseq_mask; 661 + } 662 + return hws; 663 + } 664 + 665 + #define hubp_regs(id)\ 666 + [id] = { HUBP_REG_LIST_DCN30(id) } 667 + 668 + static const struct dcn_hubp2_registers hubp_regs[] = { 669 + hubp_regs(0), 670 + hubp_regs(1), 671 + hubp_regs(2), 672 + hubp_regs(3), 673 + hubp_regs(4) 674 + }; 675 + 676 + static const struct dcn_hubp2_shift hubp_shift = { 677 + HUBP_MASK_SH_LIST_DCN30(__SHIFT) 678 + }; 679 + 680 + static const struct dcn_hubp2_mask hubp_mask = { 681 + HUBP_MASK_SH_LIST_DCN30(_MASK) 682 + }; 683 + 684 + static struct hubp *dcn302_hubp_create(struct dc_context *ctx, uint32_t inst) 685 + { 686 + struct dcn20_hubp *hubp2 = kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); 687 + 688 + if (!hubp2) 689 + return NULL; 690 + 691 + if (hubp3_construct(hubp2, ctx, inst, &hubp_regs[inst], &hubp_shift, &hubp_mask)) 692 + return &hubp2->base; 693 + 694 + BREAK_TO_DEBUGGER(); 695 + kfree(hubp2); 696 + return NULL; 697 + } 698 + 699 + #define dpp_regs(id)\ 700 + [id] = { DPP_REG_LIST_DCN30(id) } 701 + 702 + static const struct dcn3_dpp_registers dpp_regs[] = { 703 + dpp_regs(0), 704 + dpp_regs(1), 705 + dpp_regs(2), 706 + dpp_regs(3), 707 + dpp_regs(4) 708 + }; 709 + 710 + static const struct dcn3_dpp_shift tf_shift = { 711 + DPP_REG_LIST_SH_MASK_DCN30(__SHIFT) 712 + }; 713 + 714 + static const struct dcn3_dpp_mask tf_mask = { 715 + DPP_REG_LIST_SH_MASK_DCN30(_MASK) 716 + }; 717 + 718 + static struct dpp *dcn302_dpp_create(struct dc_context *ctx, uint32_t inst) 719 + { 720 + struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); 721 + 722 + if (!dpp) 723 + return NULL; 724 + 725 + if (dpp3_construct(dpp, ctx, inst, &dpp_regs[inst], &tf_shift, &tf_mask)) 726 + return &dpp->base; 727 + 728 + BREAK_TO_DEBUGGER(); 729 + kfree(dpp); 730 + return NULL; 731 + } 732 + 733 + #define opp_regs(id)\ 734 + [id] = { OPP_REG_LIST_DCN30(id) } 735 + 736 + static const struct dcn20_opp_registers opp_regs[] = { 737 + opp_regs(0), 738 + opp_regs(1), 739 + opp_regs(2), 740 + opp_regs(3), 741 + opp_regs(4) 742 + }; 743 + 744 + static const struct dcn20_opp_shift opp_shift = { 745 + OPP_MASK_SH_LIST_DCN20(__SHIFT) 746 + }; 747 + 748 + static const struct dcn20_opp_mask opp_mask = { 749 + OPP_MASK_SH_LIST_DCN20(_MASK) 750 + }; 751 + 752 + static struct output_pixel_processor *dcn302_opp_create(struct dc_context *ctx, uint32_t inst) 753 + { 754 + struct dcn20_opp *opp = kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); 755 + 756 + if (!opp) { 757 + BREAK_TO_DEBUGGER(); 758 + return NULL; 759 + } 760 + 761 + dcn20_opp_construct(opp, ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask); 762 + return &opp->base; 763 + } 764 + 765 + #define optc_regs(id)\ 766 + [id] = { OPTC_COMMON_REG_LIST_DCN3_0(id) } 767 + 768 + static const struct dcn_optc_registers optc_regs[] = { 769 + optc_regs(0), 770 + optc_regs(1), 771 + optc_regs(2), 772 + optc_regs(3), 773 + optc_regs(4) 774 + }; 775 + 776 + static const struct dcn_optc_shift optc_shift = { 777 + OPTC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 778 + }; 779 + 780 + static const struct dcn_optc_mask optc_mask = { 781 + OPTC_COMMON_MASK_SH_LIST_DCN30(_MASK) 782 + }; 783 + 784 + static struct timing_generator *dcn302_timing_generator_create(struct dc_context *ctx, uint32_t instance) 785 + { 786 + struct optc *tgn10 = kzalloc(sizeof(struct optc), GFP_KERNEL); 787 + 788 + if (!tgn10) 789 + return NULL; 790 + 791 + tgn10->base.inst = instance; 792 + tgn10->base.ctx = ctx; 793 + 794 + tgn10->tg_regs = &optc_regs[instance]; 795 + tgn10->tg_shift = &optc_shift; 796 + tgn10->tg_mask = &optc_mask; 797 + 798 + dcn30_timing_generator_init(tgn10); 799 + 800 + return &tgn10->base; 801 + } 802 + 803 + static const struct dcn30_mpc_registers mpc_regs = { 804 + MPC_REG_LIST_DCN3_0(0), 805 + MPC_REG_LIST_DCN3_0(1), 806 + MPC_REG_LIST_DCN3_0(2), 807 + MPC_REG_LIST_DCN3_0(3), 808 + MPC_REG_LIST_DCN3_0(4), 809 + MPC_OUT_MUX_REG_LIST_DCN3_0(0), 810 + MPC_OUT_MUX_REG_LIST_DCN3_0(1), 811 + MPC_OUT_MUX_REG_LIST_DCN3_0(2), 812 + MPC_OUT_MUX_REG_LIST_DCN3_0(3), 813 + MPC_OUT_MUX_REG_LIST_DCN3_0(4), 814 + MPC_RMU_GLOBAL_REG_LIST_DCN3AG, 815 + MPC_RMU_REG_LIST_DCN3AG(0), 816 + MPC_RMU_REG_LIST_DCN3AG(1), 817 + MPC_RMU_REG_LIST_DCN3AG(2), 818 + MPC_DWB_MUX_REG_LIST_DCN3_0(0), 819 + }; 820 + 821 + static const struct dcn30_mpc_shift mpc_shift = { 822 + MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 823 + }; 824 + 825 + static const struct dcn30_mpc_mask mpc_mask = { 826 + MPC_COMMON_MASK_SH_LIST_DCN30(_MASK) 827 + }; 828 + 829 + static struct mpc *dcn302_mpc_create(struct dc_context *ctx, int num_mpcc, int num_rmu) 830 + { 831 + struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL); 832 + 833 + if (!mpc30) 834 + return NULL; 835 + 836 + dcn30_mpc_construct(mpc30, ctx, &mpc_regs, &mpc_shift, &mpc_mask, num_mpcc, num_rmu); 837 + 838 + return &mpc30->base; 839 + } 840 + 841 + #define dsc_regsDCN20(id)\ 842 + [id] = { DSC_REG_LIST_DCN20(id) } 843 + 844 + static const struct dcn20_dsc_registers dsc_regs[] = { 845 + dsc_regsDCN20(0), 846 + dsc_regsDCN20(1), 847 + dsc_regsDCN20(2), 848 + dsc_regsDCN20(3), 849 + dsc_regsDCN20(4) 850 + }; 851 + 852 + static const struct dcn20_dsc_shift dsc_shift = { 853 + DSC_REG_LIST_SH_MASK_DCN20(__SHIFT) 854 + }; 855 + 856 + static const struct dcn20_dsc_mask dsc_mask = { 857 + DSC_REG_LIST_SH_MASK_DCN20(_MASK) 858 + }; 859 + 860 + static struct display_stream_compressor *dcn302_dsc_create(struct dc_context *ctx, uint32_t inst) 861 + { 862 + struct dcn20_dsc *dsc = kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); 863 + 864 + if (!dsc) { 865 + BREAK_TO_DEBUGGER(); 866 + return NULL; 867 + } 868 + 869 + dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask); 870 + return &dsc->base; 871 + } 872 + 873 + #define dwbc_regs_dcn3(id)\ 874 + [id] = { DWBC_COMMON_REG_LIST_DCN30(id) } 875 + 876 + static const struct dcn30_dwbc_registers dwbc30_regs[] = { 877 + dwbc_regs_dcn3(0) 878 + }; 879 + 880 + static const struct dcn30_dwbc_shift dwbc30_shift = { 881 + DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 882 + }; 883 + 884 + static const struct dcn30_dwbc_mask dwbc30_mask = { 885 + DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK) 886 + }; 887 + 888 + static bool dcn302_dwbc_create(struct dc_context *ctx, struct resource_pool *pool) 889 + { 890 + int i; 891 + uint32_t pipe_count = pool->res_cap->num_dwb; 892 + 893 + for (i = 0; i < pipe_count; i++) { 894 + struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), GFP_KERNEL); 895 + 896 + if (!dwbc30) { 897 + dm_error("DC: failed to create dwbc30!\n"); 898 + return false; 899 + } 900 + 901 + dcn30_dwbc_construct(dwbc30, ctx, &dwbc30_regs[i], &dwbc30_shift, &dwbc30_mask, i); 902 + 903 + pool->dwbc[i] = &dwbc30->base; 904 + } 905 + return true; 906 + } 907 + 908 + #define mcif_wb_regs_dcn3(id)\ 909 + [id] = { MCIF_WB_COMMON_REG_LIST_DCN30(id) } 910 + 911 + static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = { 912 + mcif_wb_regs_dcn3(0) 913 + }; 914 + 915 + static const struct dcn30_mmhubbub_shift mcif_wb30_shift = { 916 + MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 917 + }; 918 + 919 + static const struct dcn30_mmhubbub_mask mcif_wb30_mask = { 920 + MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK) 921 + }; 922 + 923 + static bool dcn302_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) 924 + { 925 + int i; 926 + uint32_t pipe_count = pool->res_cap->num_dwb; 927 + 928 + for (i = 0; i < pipe_count; i++) { 929 + struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), GFP_KERNEL); 930 + 931 + if (!mcif_wb30) { 932 + dm_error("DC: failed to create mcif_wb30!\n"); 933 + return false; 934 + } 935 + 936 + dcn30_mmhubbub_construct(mcif_wb30, ctx, &mcif_wb30_regs[i], &mcif_wb30_shift, &mcif_wb30_mask, i); 937 + 938 + pool->mcif_wb[i] = &mcif_wb30->base; 939 + } 940 + return true; 941 + } 942 + 943 + #define aux_engine_regs(id)\ 944 + [id] = {\ 945 + AUX_COMMON_REG_LIST0(id), \ 946 + .AUXN_IMPCAL = 0, \ 947 + .AUXP_IMPCAL = 0, \ 948 + .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \ 949 + } 950 + 951 + static const struct dce110_aux_registers aux_engine_regs[] = { 952 + aux_engine_regs(0), 953 + aux_engine_regs(1), 954 + aux_engine_regs(2), 955 + aux_engine_regs(3), 956 + aux_engine_regs(4) 957 + }; 958 + 959 + static const struct dce110_aux_registers_shift aux_shift = { 960 + DCN_AUX_MASK_SH_LIST(__SHIFT) 961 + }; 962 + 963 + static const struct dce110_aux_registers_mask aux_mask = { 964 + DCN_AUX_MASK_SH_LIST(_MASK) 965 + }; 966 + 967 + static struct dce_aux *dcn302_aux_engine_create(struct dc_context *ctx, uint32_t inst) 968 + { 969 + struct aux_engine_dce110 *aux_engine = kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); 970 + 971 + if (!aux_engine) 972 + return NULL; 973 + 974 + dce110_aux_engine_construct(aux_engine, ctx, inst, SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 975 + &aux_engine_regs[inst], &aux_mask, &aux_shift, ctx->dc->caps.extended_aux_timeout_support); 976 + 977 + return &aux_engine->base; 978 + } 979 + 980 + #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) } 981 + 982 + static const struct dce_i2c_registers i2c_hw_regs[] = { 983 + i2c_inst_regs(1), 984 + i2c_inst_regs(2), 985 + i2c_inst_regs(3), 986 + i2c_inst_regs(4), 987 + i2c_inst_regs(5) 988 + }; 989 + 990 + static const struct dce_i2c_shift i2c_shifts = { 991 + I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT) 992 + }; 993 + 994 + static const struct dce_i2c_mask i2c_masks = { 995 + I2C_COMMON_MASK_SH_LIST_DCN2(_MASK) 996 + }; 997 + 998 + static struct dce_i2c_hw *dcn302_i2c_hw_create(struct dc_context *ctx, uint32_t inst) 999 + { 1000 + struct dce_i2c_hw *dce_i2c_hw = kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); 1001 + 1002 + if (!dce_i2c_hw) 1003 + return NULL; 1004 + 1005 + dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); 1006 + 1007 + return dce_i2c_hw; 1008 + } 1009 + 1010 + static const struct encoder_feature_support link_enc_feature = { 1011 + .max_hdmi_deep_color = COLOR_DEPTH_121212, 1012 + .max_hdmi_pixel_clock = 600000, 1013 + .hdmi_ycbcr420_supported = true, 1014 + .dp_ycbcr420_supported = true, 1015 + .fec_supported = true, 1016 + .flags.bits.IS_HBR2_CAPABLE = true, 1017 + .flags.bits.IS_HBR3_CAPABLE = true, 1018 + .flags.bits.IS_TPS3_CAPABLE = true, 1019 + .flags.bits.IS_TPS4_CAPABLE = true 1020 + }; 1021 + 1022 + #define link_regs(id, phyid)\ 1023 + [id] = {\ 1024 + LE_DCN3_REG_LIST(id), \ 1025 + UNIPHY_DCN2_REG_LIST(phyid), \ 1026 + DPCS_DCN2_REG_LIST(id), \ 1027 + } 1028 + 1029 + static const struct dcn10_link_enc_registers link_enc_regs[] = { 1030 + link_regs(0, A), 1031 + link_regs(1, B), 1032 + link_regs(2, C), 1033 + link_regs(3, D), 1034 + link_regs(4, E) 1035 + }; 1036 + 1037 + static const struct dcn10_link_enc_shift le_shift = { 1038 + LINK_ENCODER_MASK_SH_LIST_DCN30(__SHIFT), 1039 + DPCS_DCN2_MASK_SH_LIST(__SHIFT) 1040 + }; 1041 + 1042 + static const struct dcn10_link_enc_mask le_mask = { 1043 + LINK_ENCODER_MASK_SH_LIST_DCN30(_MASK), 1044 + DPCS_DCN2_MASK_SH_LIST(_MASK) 1045 + }; 1046 + 1047 + #define aux_regs(id)\ 1048 + [id] = { DCN2_AUX_REG_LIST(id) } 1049 + 1050 + static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { 1051 + aux_regs(0), 1052 + aux_regs(1), 1053 + aux_regs(2), 1054 + aux_regs(3), 1055 + aux_regs(4) 1056 + }; 1057 + 1058 + #define hpd_regs(id)\ 1059 + [id] = { HPD_REG_LIST(id) } 1060 + 1061 + static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { 1062 + hpd_regs(0), 1063 + hpd_regs(1), 1064 + hpd_regs(2), 1065 + hpd_regs(3), 1066 + hpd_regs(4) 1067 + }; 1068 + 1069 + static struct link_encoder *dcn302_link_encoder_create(const struct encoder_init_data *enc_init_data) 1070 + { 1071 + struct dcn20_link_encoder *enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); 1072 + 1073 + if (!enc20) 1074 + return NULL; 1075 + 1076 + dcn30_link_encoder_construct(enc20, enc_init_data, &link_enc_feature, 1077 + &link_enc_regs[enc_init_data->transmitter], &link_enc_aux_regs[enc_init_data->channel - 1], 1078 + &link_enc_hpd_regs[enc_init_data->hpd_source], &le_shift, &le_mask); 1079 + 1080 + return &enc20->enc10.base; 1081 + } 1082 + 1083 + static const struct dce_panel_cntl_registers panel_cntl_regs[] = { 1084 + { DCN_PANEL_CNTL_REG_LIST() } 1085 + }; 1086 + 1087 + static const struct dce_panel_cntl_shift panel_cntl_shift = { 1088 + DCE_PANEL_CNTL_MASK_SH_LIST(__SHIFT) 1089 + }; 1090 + 1091 + static const struct dce_panel_cntl_mask panel_cntl_mask = { 1092 + DCE_PANEL_CNTL_MASK_SH_LIST(_MASK) 1093 + }; 1094 + 1095 + static struct panel_cntl *dcn302_panel_cntl_create(const struct panel_cntl_init_data *init_data) 1096 + { 1097 + struct dce_panel_cntl *panel_cntl = kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); 1098 + 1099 + if (!panel_cntl) 1100 + return NULL; 1101 + 1102 + dce_panel_cntl_construct(panel_cntl, init_data, &panel_cntl_regs[init_data->inst], 1103 + &panel_cntl_shift, &panel_cntl_mask); 1104 + 1105 + return &panel_cntl->base; 1106 + } 1107 + 1108 + static void read_dce_straps(struct dc_context *ctx, struct resource_straps *straps) 1109 + { 1110 + generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX), 1111 + FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); 1112 + } 1113 + 1114 + static const struct resource_create_funcs res_create_funcs = { 1115 + .read_dce_straps = read_dce_straps, 1116 + .create_audio = dcn302_create_audio, 1117 + .create_stream_encoder = dcn302_stream_encoder_create, 1118 + .create_hwseq = dcn302_hwseq_create, 1119 + }; 1120 + 1121 + static const struct resource_create_funcs res_create_maximus_funcs = { 1122 + .read_dce_straps = NULL, 1123 + .create_audio = NULL, 1124 + .create_stream_encoder = NULL, 1125 + .create_hwseq = dcn302_hwseq_create, 1126 + }; 1127 + 1128 + static bool is_soc_bounding_box_valid(struct dc *dc) 1129 + { 1130 + uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; 1131 + 1132 + if (ASICREV_IS_DIMGREY_CAVEFISH_P(hw_internal_rev)) 1133 + return true; 1134 + 1135 + return false; 1136 + } 1137 + 1138 + static bool init_soc_bounding_box(struct dc *dc, struct resource_pool *pool) 1139 + { 1140 + struct _vcs_dpi_soc_bounding_box_st *loaded_bb = &dcn3_02_soc; 1141 + struct _vcs_dpi_ip_params_st *loaded_ip = &dcn3_02_ip; 1142 + 1143 + DC_LOGGER_INIT(dc->ctx->logger); 1144 + 1145 + if (!is_soc_bounding_box_valid(dc)) { 1146 + DC_LOG_ERROR("%s: not valid soc bounding box/n", __func__); 1147 + return false; 1148 + } 1149 + 1150 + loaded_ip->max_num_otg = pool->pipe_count; 1151 + loaded_ip->max_num_dpp = pool->pipe_count; 1152 + loaded_ip->clamp_min_dcfclk = dc->config.clamp_min_dcfclk; 1153 + dcn20_patch_bounding_box(dc, loaded_bb); 1154 + return true; 1155 + } 1156 + 1157 + static void dcn302_resource_destruct(struct resource_pool *pool) 1158 + { 1159 + unsigned int i; 1160 + 1161 + for (i = 0; i < pool->stream_enc_count; i++) { 1162 + if (pool->stream_enc[i] != NULL) { 1163 + if (pool->stream_enc[i]->vpg != NULL) { 1164 + kfree(DCN30_VPG_FROM_VPG(pool->stream_enc[i]->vpg)); 1165 + pool->stream_enc[i]->vpg = NULL; 1166 + } 1167 + if (pool->stream_enc[i]->afmt != NULL) { 1168 + kfree(DCN30_AFMT_FROM_AFMT(pool->stream_enc[i]->afmt)); 1169 + pool->stream_enc[i]->afmt = NULL; 1170 + } 1171 + kfree(DCN10STRENC_FROM_STRENC(pool->stream_enc[i])); 1172 + pool->stream_enc[i] = NULL; 1173 + } 1174 + } 1175 + 1176 + for (i = 0; i < pool->res_cap->num_dsc; i++) { 1177 + if (pool->dscs[i] != NULL) 1178 + dcn20_dsc_destroy(&pool->dscs[i]); 1179 + } 1180 + 1181 + if (pool->mpc != NULL) { 1182 + kfree(TO_DCN20_MPC(pool->mpc)); 1183 + pool->mpc = NULL; 1184 + } 1185 + 1186 + if (pool->hubbub != NULL) { 1187 + kfree(pool->hubbub); 1188 + pool->hubbub = NULL; 1189 + } 1190 + 1191 + for (i = 0; i < pool->pipe_count; i++) { 1192 + if (pool->dpps[i] != NULL) { 1193 + kfree(TO_DCN20_DPP(pool->dpps[i])); 1194 + pool->dpps[i] = NULL; 1195 + } 1196 + 1197 + if (pool->hubps[i] != NULL) { 1198 + kfree(TO_DCN20_HUBP(pool->hubps[i])); 1199 + pool->hubps[i] = NULL; 1200 + } 1201 + 1202 + if (pool->irqs != NULL) 1203 + dal_irq_service_destroy(&pool->irqs); 1204 + } 1205 + 1206 + for (i = 0; i < pool->res_cap->num_ddc; i++) { 1207 + if (pool->engines[i] != NULL) 1208 + dce110_engine_destroy(&pool->engines[i]); 1209 + if (pool->hw_i2cs[i] != NULL) { 1210 + kfree(pool->hw_i2cs[i]); 1211 + pool->hw_i2cs[i] = NULL; 1212 + } 1213 + if (pool->sw_i2cs[i] != NULL) { 1214 + kfree(pool->sw_i2cs[i]); 1215 + pool->sw_i2cs[i] = NULL; 1216 + } 1217 + } 1218 + 1219 + for (i = 0; i < pool->res_cap->num_opp; i++) { 1220 + if (pool->opps[i] != NULL) 1221 + pool->opps[i]->funcs->opp_destroy(&pool->opps[i]); 1222 + } 1223 + 1224 + for (i = 0; i < pool->res_cap->num_timing_generator; i++) { 1225 + if (pool->timing_generators[i] != NULL) { 1226 + kfree(DCN10TG_FROM_TG(pool->timing_generators[i])); 1227 + pool->timing_generators[i] = NULL; 1228 + } 1229 + } 1230 + 1231 + for (i = 0; i < pool->res_cap->num_dwb; i++) { 1232 + if (pool->dwbc[i] != NULL) { 1233 + kfree(TO_DCN30_DWBC(pool->dwbc[i])); 1234 + pool->dwbc[i] = NULL; 1235 + } 1236 + if (pool->mcif_wb[i] != NULL) { 1237 + kfree(TO_DCN30_MMHUBBUB(pool->mcif_wb[i])); 1238 + pool->mcif_wb[i] = NULL; 1239 + } 1240 + } 1241 + 1242 + for (i = 0; i < pool->audio_count; i++) { 1243 + if (pool->audios[i]) 1244 + dce_aud_destroy(&pool->audios[i]); 1245 + } 1246 + 1247 + for (i = 0; i < pool->clk_src_count; i++) { 1248 + if (pool->clock_sources[i] != NULL) 1249 + dcn20_clock_source_destroy(&pool->clock_sources[i]); 1250 + } 1251 + 1252 + if (pool->dp_clock_source != NULL) 1253 + dcn20_clock_source_destroy(&pool->dp_clock_source); 1254 + 1255 + for (i = 0; i < pool->res_cap->num_mpc_3dlut; i++) { 1256 + if (pool->mpc_lut[i] != NULL) { 1257 + dc_3dlut_func_release(pool->mpc_lut[i]); 1258 + pool->mpc_lut[i] = NULL; 1259 + } 1260 + if (pool->mpc_shaper[i] != NULL) { 1261 + dc_transfer_func_release(pool->mpc_shaper[i]); 1262 + pool->mpc_shaper[i] = NULL; 1263 + } 1264 + } 1265 + 1266 + for (i = 0; i < pool->pipe_count; i++) { 1267 + if (pool->multiple_abms[i] != NULL) 1268 + dce_abm_destroy(&pool->multiple_abms[i]); 1269 + } 1270 + 1271 + if (pool->dccg != NULL) 1272 + dcn_dccg_destroy(&pool->dccg); 1273 + } 1274 + 1275 + static void dcn302_destroy_resource_pool(struct resource_pool **pool) 1276 + { 1277 + dcn302_resource_destruct(*pool); 1278 + kfree(*pool); 1279 + *pool = NULL; 1280 + } 1281 + 1282 + static struct resource_funcs dcn302_res_pool_funcs = { 1283 + .destroy = dcn302_destroy_resource_pool, 1284 + .link_enc_create = dcn302_link_encoder_create, 1285 + .panel_cntl_create = dcn302_panel_cntl_create, 1286 + .validate_bandwidth = dcn30_validate_bandwidth, 1287 + .calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg, 1288 + .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, 1289 + .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, 1290 + .add_stream_to_ctx = dcn30_add_stream_to_ctx, 1291 + .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, 1292 + .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, 1293 + .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, 1294 + .set_mcif_arb_params = dcn30_set_mcif_arb_params, 1295 + .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, 1296 + .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, 1297 + .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, 1298 + .update_bw_bounding_box = dcn30_update_bw_bounding_box, 1299 + .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, 1300 + }; 1301 + 1302 + static struct dc_cap_funcs cap_funcs = { 1303 + .get_dcc_compression_cap = dcn20_get_dcc_compression_cap 1304 + }; 1305 + 1306 + static const struct bios_registers bios_regs = { 1307 + NBIO_SR(BIOS_SCRATCH_3), 1308 + NBIO_SR(BIOS_SCRATCH_6) 1309 + }; 1310 + 1311 + static const struct dccg_registers dccg_regs = { 1312 + DCCG_REG_LIST_DCN3_02() 1313 + }; 1314 + 1315 + static const struct dccg_shift dccg_shift = { 1316 + DCCG_MASK_SH_LIST_DCN3_02(__SHIFT) 1317 + }; 1318 + 1319 + static const struct dccg_mask dccg_mask = { 1320 + DCCG_MASK_SH_LIST_DCN3_02(_MASK) 1321 + }; 1322 + 1323 + #define abm_regs(id)\ 1324 + [id] = { ABM_DCN301_REG_LIST(id) } 1325 + 1326 + static const struct dce_abm_registers abm_regs[] = { 1327 + abm_regs(0), 1328 + abm_regs(1), 1329 + abm_regs(2), 1330 + abm_regs(3), 1331 + abm_regs(4) 1332 + }; 1333 + 1334 + static const struct dce_abm_shift abm_shift = { 1335 + ABM_MASK_SH_LIST_DCN301(__SHIFT) 1336 + }; 1337 + 1338 + static const struct dce_abm_mask abm_mask = { 1339 + ABM_MASK_SH_LIST_DCN301(_MASK) 1340 + }; 1341 + 1342 + static bool dcn302_resource_construct( 1343 + uint8_t num_virtual_links, 1344 + struct dc *dc, 1345 + struct resource_pool *pool) 1346 + { 1347 + int i; 1348 + struct dc_context *ctx = dc->ctx; 1349 + struct irq_service_init_data init_data; 1350 + 1351 + ctx->dc_bios->regs = &bios_regs; 1352 + 1353 + pool->res_cap = &res_cap_dcn302; 1354 + 1355 + pool->funcs = &dcn302_res_pool_funcs; 1356 + 1357 + /************************************************* 1358 + * Resource + asic cap harcoding * 1359 + *************************************************/ 1360 + pool->underlay_pipe_index = NO_UNDERLAY_PIPE; 1361 + pool->pipe_count = pool->res_cap->num_timing_generator; 1362 + pool->mpcc_count = pool->res_cap->num_timing_generator; 1363 + dc->caps.max_downscale_ratio = 600; 1364 + dc->caps.i2c_speed_in_khz = 100; 1365 + dc->caps.max_cursor_size = 256; 1366 + dc->caps.dmdata_alloc_size = 2048; 1367 + 1368 + dc->caps.max_slave_planes = 1; 1369 + dc->caps.post_blend_color_processing = true; 1370 + dc->caps.force_dp_tps4_for_cp2520 = true; 1371 + dc->caps.extended_aux_timeout_support = true; 1372 + dc->caps.dmcub_support = true; 1373 + 1374 + /* Color pipeline capabilities */ 1375 + dc->caps.color.dpp.dcn_arch = 1; 1376 + dc->caps.color.dpp.input_lut_shared = 0; 1377 + dc->caps.color.dpp.icsc = 1; 1378 + dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr 1379 + dc->caps.color.dpp.dgam_rom_caps.srgb = 1; 1380 + dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1; 1381 + dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1; 1382 + dc->caps.color.dpp.dgam_rom_caps.pq = 1; 1383 + dc->caps.color.dpp.dgam_rom_caps.hlg = 1; 1384 + dc->caps.color.dpp.post_csc = 1; 1385 + dc->caps.color.dpp.gamma_corr = 1; 1386 + 1387 + dc->caps.color.dpp.hw_3d_lut = 1; 1388 + dc->caps.color.dpp.ogam_ram = 1; 1389 + // no OGAM ROM on DCN3 1390 + dc->caps.color.dpp.ogam_rom_caps.srgb = 0; 1391 + dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0; 1392 + dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0; 1393 + dc->caps.color.dpp.ogam_rom_caps.pq = 0; 1394 + dc->caps.color.dpp.ogam_rom_caps.hlg = 0; 1395 + dc->caps.color.dpp.ocsc = 0; 1396 + 1397 + dc->caps.color.mpc.gamut_remap = 1; 1398 + dc->caps.color.mpc.num_3dluts = pool->res_cap->num_mpc_3dlut; //3 1399 + dc->caps.color.mpc.ogam_ram = 1; 1400 + dc->caps.color.mpc.ogam_rom_caps.srgb = 0; 1401 + dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0; 1402 + dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0; 1403 + dc->caps.color.mpc.ogam_rom_caps.pq = 0; 1404 + dc->caps.color.mpc.ogam_rom_caps.hlg = 0; 1405 + dc->caps.color.mpc.ocsc = 1; 1406 + 1407 + if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) 1408 + dc->debug = debug_defaults_drv; 1409 + else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) 1410 + dc->debug = debug_defaults_diags; 1411 + else 1412 + dc->debug = debug_defaults_diags; 1413 + 1414 + // Init the vm_helper 1415 + if (dc->vm_helper) 1416 + vm_helper_init(dc->vm_helper, 16); 1417 + 1418 + /************************************************* 1419 + * Create resources * 1420 + *************************************************/ 1421 + 1422 + /* Clock Sources for Pixel Clock*/ 1423 + pool->clock_sources[DCN302_CLK_SRC_PLL0] = 1424 + dcn302_clock_source_create(ctx, ctx->dc_bios, 1425 + CLOCK_SOURCE_COMBO_PHY_PLL0, 1426 + &clk_src_regs[0], false); 1427 + pool->clock_sources[DCN302_CLK_SRC_PLL1] = 1428 + dcn302_clock_source_create(ctx, ctx->dc_bios, 1429 + CLOCK_SOURCE_COMBO_PHY_PLL1, 1430 + &clk_src_regs[1], false); 1431 + pool->clock_sources[DCN302_CLK_SRC_PLL2] = 1432 + dcn302_clock_source_create(ctx, ctx->dc_bios, 1433 + CLOCK_SOURCE_COMBO_PHY_PLL2, 1434 + &clk_src_regs[2], false); 1435 + pool->clock_sources[DCN302_CLK_SRC_PLL3] = 1436 + dcn302_clock_source_create(ctx, ctx->dc_bios, 1437 + CLOCK_SOURCE_COMBO_PHY_PLL3, 1438 + &clk_src_regs[3], false); 1439 + pool->clock_sources[DCN302_CLK_SRC_PLL4] = 1440 + dcn302_clock_source_create(ctx, ctx->dc_bios, 1441 + CLOCK_SOURCE_COMBO_PHY_PLL4, 1442 + &clk_src_regs[4], false); 1443 + 1444 + pool->clk_src_count = DCN302_CLK_SRC_TOTAL; 1445 + 1446 + /* todo: not reuse phy_pll registers */ 1447 + pool->dp_clock_source = 1448 + dcn302_clock_source_create(ctx, ctx->dc_bios, 1449 + CLOCK_SOURCE_ID_DP_DTO, 1450 + &clk_src_regs[0], true); 1451 + 1452 + for (i = 0; i < pool->clk_src_count; i++) { 1453 + if (pool->clock_sources[i] == NULL) { 1454 + dm_error("DC: failed to create clock sources!\n"); 1455 + BREAK_TO_DEBUGGER(); 1456 + goto create_fail; 1457 + } 1458 + } 1459 + 1460 + /* DCCG */ 1461 + pool->dccg = dccg30_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask); 1462 + if (pool->dccg == NULL) { 1463 + dm_error("DC: failed to create dccg!\n"); 1464 + BREAK_TO_DEBUGGER(); 1465 + goto create_fail; 1466 + } 1467 + 1468 + /* PP Lib and SMU interfaces */ 1469 + init_soc_bounding_box(dc, pool); 1470 + 1471 + /* DML */ 1472 + dml_init_instance(&dc->dml, &dcn3_02_soc, &dcn3_02_ip, DML_PROJECT_DCN30); 1473 + 1474 + /* IRQ */ 1475 + init_data.ctx = dc->ctx; 1476 + pool->irqs = dal_irq_service_dcn302_create(&init_data); 1477 + if (!pool->irqs) 1478 + goto create_fail; 1479 + 1480 + /* HUBBUB */ 1481 + pool->hubbub = dcn302_hubbub_create(ctx); 1482 + if (pool->hubbub == NULL) { 1483 + BREAK_TO_DEBUGGER(); 1484 + dm_error("DC: failed to create hubbub!\n"); 1485 + goto create_fail; 1486 + } 1487 + 1488 + /* HUBPs, DPPs, OPPs and TGs */ 1489 + for (i = 0; i < pool->pipe_count; i++) { 1490 + pool->hubps[i] = dcn302_hubp_create(ctx, i); 1491 + if (pool->hubps[i] == NULL) { 1492 + BREAK_TO_DEBUGGER(); 1493 + dm_error("DC: failed to create hubps!\n"); 1494 + goto create_fail; 1495 + } 1496 + 1497 + pool->dpps[i] = dcn302_dpp_create(ctx, i); 1498 + if (pool->dpps[i] == NULL) { 1499 + BREAK_TO_DEBUGGER(); 1500 + dm_error("DC: failed to create dpps!\n"); 1501 + goto create_fail; 1502 + } 1503 + } 1504 + 1505 + for (i = 0; i < pool->res_cap->num_opp; i++) { 1506 + pool->opps[i] = dcn302_opp_create(ctx, i); 1507 + if (pool->opps[i] == NULL) { 1508 + BREAK_TO_DEBUGGER(); 1509 + dm_error("DC: failed to create output pixel processor!\n"); 1510 + goto create_fail; 1511 + } 1512 + } 1513 + 1514 + for (i = 0; i < pool->res_cap->num_timing_generator; i++) { 1515 + pool->timing_generators[i] = dcn302_timing_generator_create(ctx, i); 1516 + if (pool->timing_generators[i] == NULL) { 1517 + BREAK_TO_DEBUGGER(); 1518 + dm_error("DC: failed to create tg!\n"); 1519 + goto create_fail; 1520 + } 1521 + } 1522 + pool->timing_generator_count = i; 1523 + 1524 + /* ABMs */ 1525 + for (i = 0; i < pool->res_cap->num_timing_generator; i++) { 1526 + pool->multiple_abms[i] = dmub_abm_create(ctx, &abm_regs[i], &abm_shift, &abm_mask); 1527 + if (pool->multiple_abms[i] == NULL) { 1528 + dm_error("DC: failed to create abm for pipe %d!\n", i); 1529 + BREAK_TO_DEBUGGER(); 1530 + goto create_fail; 1531 + } 1532 + } 1533 + 1534 + /* MPC and DSC */ 1535 + pool->mpc = dcn302_mpc_create(ctx, pool->mpcc_count, pool->res_cap->num_mpc_3dlut); 1536 + if (pool->mpc == NULL) { 1537 + BREAK_TO_DEBUGGER(); 1538 + dm_error("DC: failed to create mpc!\n"); 1539 + goto create_fail; 1540 + } 1541 + 1542 + for (i = 0; i < pool->res_cap->num_dsc; i++) { 1543 + pool->dscs[i] = dcn302_dsc_create(ctx, i); 1544 + if (pool->dscs[i] == NULL) { 1545 + BREAK_TO_DEBUGGER(); 1546 + dm_error("DC: failed to create display stream compressor %d!\n", i); 1547 + goto create_fail; 1548 + } 1549 + } 1550 + 1551 + /* DWB and MMHUBBUB */ 1552 + if (!dcn302_dwbc_create(ctx, pool)) { 1553 + BREAK_TO_DEBUGGER(); 1554 + dm_error("DC: failed to create dwbc!\n"); 1555 + goto create_fail; 1556 + } 1557 + 1558 + if (!dcn302_mmhubbub_create(ctx, pool)) { 1559 + BREAK_TO_DEBUGGER(); 1560 + dm_error("DC: failed to create mcif_wb!\n"); 1561 + goto create_fail; 1562 + } 1563 + 1564 + /* AUX and I2C */ 1565 + for (i = 0; i < pool->res_cap->num_ddc; i++) { 1566 + pool->engines[i] = dcn302_aux_engine_create(ctx, i); 1567 + if (pool->engines[i] == NULL) { 1568 + BREAK_TO_DEBUGGER(); 1569 + dm_error("DC:failed to create aux engine!!\n"); 1570 + goto create_fail; 1571 + } 1572 + pool->hw_i2cs[i] = dcn302_i2c_hw_create(ctx, i); 1573 + if (pool->hw_i2cs[i] == NULL) { 1574 + BREAK_TO_DEBUGGER(); 1575 + dm_error("DC:failed to create hw i2c!!\n"); 1576 + goto create_fail; 1577 + } 1578 + pool->sw_i2cs[i] = NULL; 1579 + } 1580 + 1581 + /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */ 1582 + if (!resource_construct(num_virtual_links, dc, pool, 1583 + (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? 1584 + &res_create_funcs : &res_create_maximus_funcs))) 1585 + goto create_fail; 1586 + 1587 + /* HW Sequencer and Plane caps */ 1588 + dcn302_hw_sequencer_construct(dc); 1589 + 1590 + dc->caps.max_planes = pool->pipe_count; 1591 + 1592 + for (i = 0; i < dc->caps.max_planes; ++i) 1593 + dc->caps.planes[i] = plane_cap; 1594 + 1595 + dc->cap_funcs = cap_funcs; 1596 + 1597 + return true; 1598 + 1599 + create_fail: 1600 + 1601 + dcn302_resource_destruct(pool); 1602 + 1603 + return false; 1604 + } 1605 + 1606 + struct resource_pool *dcn302_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc) 1607 + { 1608 + struct resource_pool *pool = kzalloc(sizeof(struct resource_pool), GFP_KERNEL); 1609 + 1610 + if (!pool) 1611 + return NULL; 1612 + 1613 + if (dcn302_resource_construct(init_data->num_virtual_links, dc, pool)) 1614 + return pool; 1615 + 1616 + BREAK_TO_DEBUGGER(); 1617 + kfree(pool); 1618 + return NULL; 1619 + }
+33
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.h
··· 1 + /* 2 + * Copyright 2020 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 _DCN302_RESOURCE_H_ 27 + #define _DCN302_RESOURCE_H_ 28 + 29 + #include "core_types.h" 30 + 31 + struct resource_pool *dcn302_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc); 32 + 33 + #endif /* _DCN302_RESOURCE_H_ */
+3
drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
··· 117 117 #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 118 118 case DCN_VERSION_3_01: 119 119 #endif 120 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 121 + case DCN_VERSION_3_02: 122 + #endif 120 123 dal_hw_factory_dcn30_init(factory); 121 124 return true; 122 125 #endif
+3
drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
··· 112 112 #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 113 113 case DCN_VERSION_3_01: 114 114 #endif 115 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 116 + case DCN_VERSION_3_02: 117 + #endif 115 118 dal_hw_translate_dcn30_init(translate); 116 119 return true; 117 120 #endif
+10
drivers/gpu/drm/amd/display/dc/irq/Makefile
··· 104 104 105 105 AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN3) 106 106 endif 107 + ifdef CONFIG_DRM_AMD_DC_DCN3_02 108 + ############################################################################### 109 + # DCN 3_02 110 + ############################################################################### 111 + IRQ_DCN3_02 = irq_service_dcn302.o 112 + 113 + AMD_DAL_IRQ_DCN3_02 = $(addprefix $(AMDDALPATH)/dc/irq/dcn302/,$(IRQ_DCN3_02)) 114 + 115 + AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN3_02) 116 + endif
+344
drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c
··· 1 + /* 2 + * Copyright 2020 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 "irq_service_dcn302.h" 29 + 30 + #include "../dce110/irq_service_dce110.h" 31 + 32 + #include "dimgrey_cavefish_ip_offset.h" 33 + #include "dcn/dcn_3_0_0_offset.h" 34 + #include "dcn/dcn_3_0_0_sh_mask.h" 35 + 36 + #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" 37 + 38 + static enum dc_irq_source to_dal_irq_source_dcn302(struct irq_service *irq_service, uint32_t src_id, uint32_t ext_id) 39 + { 40 + switch (src_id) { 41 + case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP: 42 + return DC_IRQ_SOURCE_VBLANK1; 43 + case DCN_1_0__SRCID__DC_D2_OTG_VSTARTUP: 44 + return DC_IRQ_SOURCE_VBLANK2; 45 + case DCN_1_0__SRCID__DC_D3_OTG_VSTARTUP: 46 + return DC_IRQ_SOURCE_VBLANK3; 47 + case DCN_1_0__SRCID__DC_D4_OTG_VSTARTUP: 48 + return DC_IRQ_SOURCE_VBLANK4; 49 + case DCN_1_0__SRCID__DC_D5_OTG_VSTARTUP: 50 + return DC_IRQ_SOURCE_VBLANK5; 51 + case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP: 52 + return DC_IRQ_SOURCE_VBLANK6; 53 + case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT: 54 + return DC_IRQ_SOURCE_PFLIP1; 55 + case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT: 56 + return DC_IRQ_SOURCE_PFLIP2; 57 + case DCN_1_0__SRCID__HUBP2_FLIP_INTERRUPT: 58 + return DC_IRQ_SOURCE_PFLIP3; 59 + case DCN_1_0__SRCID__HUBP3_FLIP_INTERRUPT: 60 + return DC_IRQ_SOURCE_PFLIP4; 61 + case DCN_1_0__SRCID__HUBP4_FLIP_INTERRUPT: 62 + return DC_IRQ_SOURCE_PFLIP5; 63 + case DCN_1_0__SRCID__HUBP5_FLIP_INTERRUPT: 64 + return DC_IRQ_SOURCE_PFLIP6; 65 + case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT: 66 + return DC_IRQ_SOURCE_VUPDATE1; 67 + case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT: 68 + return DC_IRQ_SOURCE_VUPDATE2; 69 + case DCN_1_0__SRCID__OTG2_IHC_V_UPDATE_NO_LOCK_INTERRUPT: 70 + return DC_IRQ_SOURCE_VUPDATE3; 71 + case DCN_1_0__SRCID__OTG3_IHC_V_UPDATE_NO_LOCK_INTERRUPT: 72 + return DC_IRQ_SOURCE_VUPDATE4; 73 + case DCN_1_0__SRCID__OTG4_IHC_V_UPDATE_NO_LOCK_INTERRUPT: 74 + return DC_IRQ_SOURCE_VUPDATE5; 75 + case DCN_1_0__SRCID__OTG5_IHC_V_UPDATE_NO_LOCK_INTERRUPT: 76 + return DC_IRQ_SOURCE_VUPDATE6; 77 + 78 + case DCN_1_0__SRCID__DC_HPD1_INT: 79 + /* generic src_id for all HPD and HPDRX interrupts */ 80 + switch (ext_id) { 81 + case DCN_1_0__CTXID__DC_HPD1_INT: 82 + return DC_IRQ_SOURCE_HPD1; 83 + case DCN_1_0__CTXID__DC_HPD2_INT: 84 + return DC_IRQ_SOURCE_HPD2; 85 + case DCN_1_0__CTXID__DC_HPD3_INT: 86 + return DC_IRQ_SOURCE_HPD3; 87 + case DCN_1_0__CTXID__DC_HPD4_INT: 88 + return DC_IRQ_SOURCE_HPD4; 89 + case DCN_1_0__CTXID__DC_HPD5_INT: 90 + return DC_IRQ_SOURCE_HPD5; 91 + case DCN_1_0__CTXID__DC_HPD6_INT: 92 + return DC_IRQ_SOURCE_HPD6; 93 + case DCN_1_0__CTXID__DC_HPD1_RX_INT: 94 + return DC_IRQ_SOURCE_HPD1RX; 95 + case DCN_1_0__CTXID__DC_HPD2_RX_INT: 96 + return DC_IRQ_SOURCE_HPD2RX; 97 + case DCN_1_0__CTXID__DC_HPD3_RX_INT: 98 + return DC_IRQ_SOURCE_HPD3RX; 99 + case DCN_1_0__CTXID__DC_HPD4_RX_INT: 100 + return DC_IRQ_SOURCE_HPD4RX; 101 + case DCN_1_0__CTXID__DC_HPD5_RX_INT: 102 + return DC_IRQ_SOURCE_HPD5RX; 103 + case DCN_1_0__CTXID__DC_HPD6_RX_INT: 104 + return DC_IRQ_SOURCE_HPD6RX; 105 + default: 106 + return DC_IRQ_SOURCE_INVALID; 107 + } 108 + break; 109 + 110 + default: 111 + return DC_IRQ_SOURCE_INVALID; 112 + } 113 + } 114 + 115 + static bool hpd_ack(struct irq_service *irq_service, const struct irq_source_info *info) 116 + { 117 + uint32_t addr = info->status_reg; 118 + uint32_t value = dm_read_reg(irq_service->ctx, addr); 119 + uint32_t current_status = get_reg_field_value(value, HPD0_DC_HPD_INT_STATUS, DC_HPD_SENSE_DELAYED); 120 + 121 + dal_irq_service_ack_generic(irq_service, info); 122 + 123 + value = dm_read_reg(irq_service->ctx, info->enable_reg); 124 + 125 + set_reg_field_value(value, current_status ? 0 : 1, HPD0_DC_HPD_INT_CONTROL, DC_HPD_INT_POLARITY); 126 + 127 + dm_write_reg(irq_service->ctx, info->enable_reg, value); 128 + 129 + return true; 130 + } 131 + 132 + static const struct irq_source_info_funcs hpd_irq_info_funcs = { 133 + .set = NULL, 134 + .ack = hpd_ack 135 + }; 136 + 137 + static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = { 138 + .set = NULL, 139 + .ack = NULL 140 + }; 141 + 142 + static const struct irq_source_info_funcs pflip_irq_info_funcs = { 143 + .set = NULL, 144 + .ack = NULL 145 + }; 146 + 147 + static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { 148 + .set = NULL, 149 + .ack = NULL 150 + }; 151 + 152 + static const struct irq_source_info_funcs vblank_irq_info_funcs = { 153 + .set = NULL, 154 + .ack = NULL 155 + }; 156 + 157 + #undef BASE_INNER 158 + #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg 159 + 160 + /* compile time expand base address. */ 161 + #define BASE(seg) BASE_INNER(seg) 162 + 163 + #define SRI(reg_name, block, id)\ 164 + BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 165 + mm ## block ## id ## _ ## reg_name 166 + 167 + 168 + #define IRQ_REG_ENTRY(block, reg_num, reg1, mask1, reg2, mask2)\ 169 + .enable_reg = SRI(reg1, block, reg_num),\ 170 + .enable_mask = block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\ 171 + .enable_value = {\ 172 + block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\ 173 + ~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK \ 174 + },\ 175 + .ack_reg = SRI(reg2, block, reg_num),\ 176 + .ack_mask = block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\ 177 + .ack_value = block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \ 178 + 179 + 180 + 181 + #define hpd_int_entry(reg_num)\ 182 + [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ 183 + IRQ_REG_ENTRY(HPD, reg_num,\ 184 + DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\ 185 + DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\ 186 + .status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\ 187 + .funcs = &hpd_irq_info_funcs\ 188 + } 189 + 190 + #define hpd_rx_int_entry(reg_num)\ 191 + [DC_IRQ_SOURCE_HPD1RX + reg_num] = {\ 192 + IRQ_REG_ENTRY(HPD, reg_num,\ 193 + DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\ 194 + DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\ 195 + .status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num),\ 196 + .funcs = &hpd_rx_irq_info_funcs\ 197 + } 198 + #define pflip_int_entry(reg_num)\ 199 + [DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\ 200 + IRQ_REG_ENTRY(HUBPREQ, reg_num,\ 201 + DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK,\ 202 + DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_CLEAR),\ 203 + .funcs = &pflip_irq_info_funcs\ 204 + } 205 + 206 + /* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic 207 + * of DCE's DC_IRQ_SOURCE_VUPDATEx. 208 + */ 209 + #define vupdate_no_lock_int_entry(reg_num)\ 210 + [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ 211 + IRQ_REG_ENTRY(OTG, reg_num,\ 212 + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ 213 + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ 214 + .funcs = &vupdate_no_lock_irq_info_funcs\ 215 + } 216 + 217 + #define vblank_int_entry(reg_num)\ 218 + [DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\ 219 + IRQ_REG_ENTRY(OTG, reg_num,\ 220 + OTG_GLOBAL_SYNC_STATUS, VSTARTUP_INT_EN,\ 221 + OTG_GLOBAL_SYNC_STATUS, VSTARTUP_EVENT_CLEAR),\ 222 + .funcs = &vblank_irq_info_funcs\ 223 + } 224 + 225 + #define dummy_irq_entry() { .funcs = &dummy_irq_info_funcs } 226 + 227 + #define i2c_int_entry(reg_num) \ 228 + [DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry() 229 + 230 + #define dp_sink_int_entry(reg_num) \ 231 + [DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry() 232 + 233 + #define gpio_pad_int_entry(reg_num) \ 234 + [DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry() 235 + 236 + #define dc_underflow_int_entry(reg_num) \ 237 + [DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry() 238 + 239 + static const struct irq_source_info_funcs dummy_irq_info_funcs = { 240 + .set = dal_irq_service_dummy_set, 241 + .ack = dal_irq_service_dummy_ack 242 + }; 243 + 244 + static const struct irq_source_info irq_source_info_dcn302[DAL_IRQ_SOURCES_NUMBER] = { 245 + [DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(), 246 + hpd_int_entry(0), 247 + hpd_int_entry(1), 248 + hpd_int_entry(2), 249 + hpd_int_entry(3), 250 + hpd_int_entry(4), 251 + hpd_rx_int_entry(0), 252 + hpd_rx_int_entry(1), 253 + hpd_rx_int_entry(2), 254 + hpd_rx_int_entry(3), 255 + hpd_rx_int_entry(4), 256 + i2c_int_entry(1), 257 + i2c_int_entry(2), 258 + i2c_int_entry(3), 259 + i2c_int_entry(4), 260 + i2c_int_entry(5), 261 + dp_sink_int_entry(1), 262 + dp_sink_int_entry(2), 263 + dp_sink_int_entry(3), 264 + dp_sink_int_entry(4), 265 + dp_sink_int_entry(5), 266 + [DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(), 267 + pflip_int_entry(0), 268 + pflip_int_entry(1), 269 + pflip_int_entry(2), 270 + pflip_int_entry(3), 271 + pflip_int_entry(4), 272 + [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(), 273 + gpio_pad_int_entry(0), 274 + gpio_pad_int_entry(1), 275 + gpio_pad_int_entry(2), 276 + gpio_pad_int_entry(3), 277 + gpio_pad_int_entry(4), 278 + gpio_pad_int_entry(5), 279 + gpio_pad_int_entry(6), 280 + gpio_pad_int_entry(7), 281 + gpio_pad_int_entry(8), 282 + gpio_pad_int_entry(9), 283 + gpio_pad_int_entry(10), 284 + gpio_pad_int_entry(11), 285 + gpio_pad_int_entry(12), 286 + gpio_pad_int_entry(13), 287 + gpio_pad_int_entry(14), 288 + gpio_pad_int_entry(15), 289 + gpio_pad_int_entry(16), 290 + gpio_pad_int_entry(17), 291 + gpio_pad_int_entry(18), 292 + gpio_pad_int_entry(19), 293 + gpio_pad_int_entry(20), 294 + gpio_pad_int_entry(21), 295 + gpio_pad_int_entry(22), 296 + gpio_pad_int_entry(23), 297 + gpio_pad_int_entry(24), 298 + gpio_pad_int_entry(25), 299 + gpio_pad_int_entry(26), 300 + gpio_pad_int_entry(27), 301 + gpio_pad_int_entry(28), 302 + gpio_pad_int_entry(29), 303 + gpio_pad_int_entry(30), 304 + dc_underflow_int_entry(1), 305 + dc_underflow_int_entry(2), 306 + dc_underflow_int_entry(3), 307 + dc_underflow_int_entry(4), 308 + dc_underflow_int_entry(5), 309 + [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(), 310 + [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(), 311 + vupdate_no_lock_int_entry(0), 312 + vupdate_no_lock_int_entry(1), 313 + vupdate_no_lock_int_entry(2), 314 + vupdate_no_lock_int_entry(3), 315 + vupdate_no_lock_int_entry(4), 316 + vblank_int_entry(0), 317 + vblank_int_entry(1), 318 + vblank_int_entry(2), 319 + vblank_int_entry(3), 320 + vblank_int_entry(4), 321 + }; 322 + 323 + static const struct irq_service_funcs irq_service_funcs_dcn302 = { 324 + .to_dal_irq_source = to_dal_irq_source_dcn302 325 + }; 326 + 327 + static void dcn302_irq_construct(struct irq_service *irq_service, struct irq_service_init_data *init_data) 328 + { 329 + dal_irq_service_construct(irq_service, init_data); 330 + 331 + irq_service->info = irq_source_info_dcn302; 332 + irq_service->funcs = &irq_service_funcs_dcn302; 333 + } 334 + 335 + struct irq_service *dal_irq_service_dcn302_create(struct irq_service_init_data *init_data) 336 + { 337 + struct irq_service *irq_service = kzalloc(sizeof(*irq_service), GFP_KERNEL); 338 + 339 + if (!irq_service) 340 + return NULL; 341 + 342 + dcn302_irq_construct(irq_service, init_data); 343 + return irq_service; 344 + }
+33
drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.h
··· 1 + /* 2 + * Copyright 2020 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 __DAL_IRQ_SERVICE_DCN302_H__ 27 + #define __DAL_IRQ_SERVICE_DCN302_H__ 28 + 29 + #include "../irq_service.h" 30 + 31 + struct irq_service *dal_irq_service_dcn302_create(struct irq_service_init_data *init_data); 32 + 33 + #endif /* __DAL_IRQ_SERVICE_DCN302_H__ */
+3
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
··· 94 94 #ifdef CONFIG_DRM_AMD_DC_DCN3_01 95 95 DMUB_ASIC_DCN301, 96 96 #endif 97 + #ifdef CONFIG_DRM_AMD_DC_DCN3_02 98 + DMUB_ASIC_DCN302, 99 + #endif 97 100 DMUB_ASIC_MAX, 98 101 }; 99 102
+3
drivers/gpu/drm/amd/display/dmub/src/Makefile
··· 24 24 ifdef CONFIG_DRM_AMD_DC_DCN3_0 25 25 DMUB += dmub_dcn30.o dmub_dcn301.o 26 26 endif 27 + ifdef CONFIG_DRM_AMD_DC_DCN3_02 28 + DMUB += dmub_dcn302.o 29 + endif 27 30 28 31 AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB)) 29 32
+55
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.c
··· 1 + /* 2 + * Copyright 2020 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_dcn302.h" 29 + 30 + #include "dimgrey_cavefish_ip_offset.h" 31 + #include "dcn/dcn_3_0_0_offset.h" 32 + #include "dcn/dcn_3_0_0_sh_mask.h" 33 + 34 + #define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg 35 + #define CTX dmub 36 + #define REGS dmub->regs 37 + 38 + /* Registers. */ 39 + 40 + const struct dmub_srv_common_regs dmub_srv_dcn302_regs = { 41 + #define DMUB_SR(reg) REG_OFFSET(reg), 42 + { DMUB_COMMON_REGS() }, 43 + #undef DMUB_SR 44 + 45 + #define DMUB_SF(reg, field) FD_MASK(reg, field), 46 + { DMUB_COMMON_FIELDS() }, 47 + #undef DMUB_SF 48 + 49 + #define DMUB_SF(reg, field) FD_SHIFT(reg, field), 50 + { DMUB_COMMON_FIELDS() }, 51 + #undef DMUB_SF 52 + }; 53 + 54 + /* Shared functions. */ 55 +
+37
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.h
··· 1 + /* 2 + * Copyright 2020 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_DCN302_H_ 27 + #define _DMUB_DCN302_H_ 28 + 29 + #include "dmub_dcn20.h" 30 + 31 + /* Registers. */ 32 + 33 + extern const struct dmub_srv_common_regs dmub_srv_dcn302_regs; 34 + 35 + /* Hardware functions. */ 36 + 37 + #endif /* _DMUB_DCN302_H_ */
+14
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
··· 33 33 #ifdef CONFIG_DRM_AMD_DC_DCN3_01 34 34 #include "dmub_dcn301.h" 35 35 #endif 36 + #ifdef CONFIG_DRM_AMD_DC_DCN3_02 37 + #include "dmub_dcn302.h" 38 + #endif 36 39 #include "os_types.h" 37 40 /* 38 41 * Note: the DMUB service is standalone. No additional headers should be ··· 148 145 #ifdef CONFIG_DRM_AMD_DC_DCN3_01 149 146 case DMUB_ASIC_DCN301: 150 147 #endif 148 + #ifdef CONFIG_DRM_AMD_DC_DCN3_02 149 + case DMUB_ASIC_DCN302: 150 + #endif 151 151 dmub->regs = &dmub_srv_dcn20_regs; 152 152 153 153 funcs->reset = dmub_dcn20_reset; ··· 184 178 #ifdef CONFIG_DRM_AMD_DC_DCN3_01 185 179 if (asic == DMUB_ASIC_DCN301) { 186 180 dmub->regs = &dmub_srv_dcn301_regs; 181 + 182 + funcs->backdoor_load = dmub_dcn30_backdoor_load; 183 + funcs->setup_windows = dmub_dcn30_setup_windows; 184 + } 185 + #endif 186 + #ifdef CONFIG_DRM_AMD_DC_DCN3_02 187 + if (asic == DMUB_ASIC_DCN302) { 188 + dmub->regs = &dmub_srv_dcn302_regs; 187 189 188 190 funcs->backdoor_load = dmub_dcn30_backdoor_load; 189 191 funcs->setup_windows = dmub_dcn30_setup_windows;
+5 -1
drivers/gpu/drm/amd/display/include/dal_asic_id.h
··· 195 195 NV_NAVI12_P_A0 = 10, 196 196 NV_NAVI14_M_A0 = 20, 197 197 NV_SIENNA_CICHLID_P_A0 = 40, 198 + NV_DIMGREY_CAVEFISH_P_A0 = 60, 198 199 NV_UNKNOWN = 0xFF 199 200 }; 200 201 ··· 204 203 #define ASICREV_IS_NAVI14_M(eChipRev) ((eChipRev >= NV_NAVI14_M_A0) && (eChipRev < NV_UNKNOWN)) 205 204 #define ASICREV_IS_RENOIR(eChipRev) ((eChipRev >= RENOIR_A0) && (eChipRev < RAVEN1_F0)) 206 205 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 207 - #define ASICREV_IS_SIENNA_CICHLID_P(eChipRev) ((eChipRev >= NV_SIENNA_CICHLID_P_A0)) 206 + #define ASICREV_IS_SIENNA_CICHLID_P(eChipRev) ((eChipRev >= NV_SIENNA_CICHLID_P_A0) && (eChipRev < NV_DIMGREY_CAVEFISH_P_A0)) 207 + #endif 208 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 209 + #define ASICREV_IS_DIMGREY_CAVEFISH_P(eChipRev) ((eChipRev >= NV_DIMGREY_CAVEFISH_P_A0) && (eChipRev < NV_UNKNOWN)) 208 210 #endif 209 211 #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 210 212 #define FAMILY_VGH 144
+3
drivers/gpu/drm/amd/display/include/dal_types.h
··· 57 57 #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 58 58 DCN_VERSION_3_01, 59 59 #endif 60 + #if defined(CONFIG_DRM_AMD_DC_DCN3_02) 61 + DCN_VERSION_3_02, 62 + #endif 60 63 DCN_VERSION_MAX 61 64 }; 62 65