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

drm/amd/display: Add dcn3.01 support to DC (v2)

Update dc for vangogh support.

v2: fix compilation without DCN 301 set.

Signed-off-by: Roman Li <Roman.Li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Roman Li and committed by
Alex Deucher
3a83e4e6 ac0dc4c5

+5232 -33
+9
drivers/gpu/drm/amd/display/Kconfig
··· 25 25 Choose this option if you want to have 26 26 sienna_cichlid support for display engine 27 27 28 + config DRM_AMD_DC_DCN3_01 29 + bool "DCN 3.01 family" 30 + depends on DRM_AMD_DC && X86 31 + depends on DRM_AMD_DC_DCN 32 + depends on DRM_AMD_DC_DCN3_0 33 + help 34 + Choose this option if you want to have 35 + Van Gogh support for display engine 36 + 28 37 config DRM_AMD_DC_HDCP 29 38 bool "Enable HDCP support in DC" 30 39 depends on DRM_AMD_DC
+4
drivers/gpu/drm/amd/display/dc/Makefile
··· 36 36 DC_LIBS += dcn30 37 37 endif 38 38 39 + ifdef CONFIG_DRM_AMD_DC_DCN3_01 40 + DC_LIBS += dcn301 41 + endif 42 + 39 43 DC_LIBS += dce120 40 44 41 45 DC_LIBS += dce112
+187
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
··· 1743 1743 return BP_RESULT_OK; 1744 1744 } 1745 1745 1746 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 1747 + static enum bp_result get_integrated_info_v2_1( 1748 + struct bios_parser *bp, 1749 + struct integrated_info *info) 1750 + { 1751 + struct atom_integrated_system_info_v2_1 *info_v2_1; 1752 + uint32_t i; 1753 + 1754 + info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1, 1755 + DATA_TABLES(integratedsysteminfo)); 1756 + 1757 + if (info_v2_1 == NULL) 1758 + return BP_RESULT_BADBIOSTABLE; 1759 + 1760 + info->gpu_cap_info = 1761 + le32_to_cpu(info_v2_1->gpucapinfo); 1762 + /* 1763 + * system_config: Bit[0] = 0 : PCIE power gating disabled 1764 + * = 1 : PCIE power gating enabled 1765 + * Bit[1] = 0 : DDR-PLL shut down disabled 1766 + * = 1 : DDR-PLL shut down enabled 1767 + * Bit[2] = 0 : DDR-PLL power down disabled 1768 + * = 1 : DDR-PLL power down enabled 1769 + */ 1770 + info->system_config = le32_to_cpu(info_v2_1->system_config); 1771 + info->cpu_cap_info = le32_to_cpu(info_v2_1->cpucapinfo); 1772 + info->memory_type = info_v2_1->memorytype; 1773 + info->ma_channel_number = info_v2_1->umachannelnumber; 1774 + info->dp_ss_control = 1775 + le16_to_cpu(info_v2_1->reserved1); 1776 + 1777 + for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 1778 + info->ext_disp_conn_info.gu_id[i] = 1779 + info_v2_1->extdispconninfo.guid[i]; 1780 + } 1781 + 1782 + for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 1783 + info->ext_disp_conn_info.path[i].device_connector_id = 1784 + object_id_from_bios_object_id( 1785 + le16_to_cpu(info_v2_1->extdispconninfo.path[i].connectorobjid)); 1786 + 1787 + info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 1788 + object_id_from_bios_object_id( 1789 + le16_to_cpu( 1790 + info_v2_1->extdispconninfo.path[i].ext_encoder_objid)); 1791 + 1792 + info->ext_disp_conn_info.path[i].device_tag = 1793 + le16_to_cpu( 1794 + info_v2_1->extdispconninfo.path[i].device_tag); 1795 + info->ext_disp_conn_info.path[i].device_acpi_enum = 1796 + le16_to_cpu( 1797 + info_v2_1->extdispconninfo.path[i].device_acpi_enum); 1798 + info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 1799 + info_v2_1->extdispconninfo.path[i].auxddclut_index; 1800 + info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 1801 + info_v2_1->extdispconninfo.path[i].hpdlut_index; 1802 + info->ext_disp_conn_info.path[i].channel_mapping.raw = 1803 + info_v2_1->extdispconninfo.path[i].channelmapping; 1804 + info->ext_disp_conn_info.path[i].caps = 1805 + le16_to_cpu(info_v2_1->extdispconninfo.path[i].caps); 1806 + } 1807 + 1808 + info->ext_disp_conn_info.checksum = 1809 + info_v2_1->extdispconninfo.checksum; 1810 + info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr; 1811 + info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum; 1812 + for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) { 1813 + info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index = 1814 + info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1815 + info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val = 1816 + info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1817 + } 1818 + info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum; 1819 + for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) { 1820 + info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1821 + info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1822 + info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1823 + info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1824 + } 1825 + info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr; 1826 + info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum; 1827 + for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) { 1828 + info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index = 1829 + info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1830 + info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val = 1831 + info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1832 + } 1833 + info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum; 1834 + for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) { 1835 + info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1836 + info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1837 + info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1838 + info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1839 + } 1840 + info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr; 1841 + info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum; 1842 + for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) { 1843 + info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index = 1844 + info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1845 + info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val = 1846 + info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1847 + } 1848 + info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum; 1849 + for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) { 1850 + info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1851 + info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1852 + info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1853 + info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1854 + } 1855 + info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr; 1856 + info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum; 1857 + for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) { 1858 + info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index = 1859 + info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1860 + info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val = 1861 + info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1862 + } 1863 + info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum; 1864 + for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) { 1865 + info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1866 + info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1867 + info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1868 + info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1869 + } 1870 + 1871 + info->edp1_info.edp_backlight_pwm_hz = 1872 + le16_to_cpu(info_v2_1->edp1_info.edp_backlight_pwm_hz); 1873 + info->edp1_info.edp_ss_percentage = 1874 + le16_to_cpu(info_v2_1->edp1_info.edp_ss_percentage); 1875 + info->edp1_info.edp_ss_rate_10hz = 1876 + le16_to_cpu(info_v2_1->edp1_info.edp_ss_rate_10hz); 1877 + info->edp1_info.edp_pwr_on_off_delay = 1878 + info_v2_1->edp1_info.edp_pwr_on_off_delay; 1879 + info->edp1_info.edp_pwr_on_vary_bl_to_blon = 1880 + info_v2_1->edp1_info.edp_pwr_on_vary_bl_to_blon; 1881 + info->edp1_info.edp_pwr_down_bloff_to_vary_bloff = 1882 + info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff; 1883 + info->edp1_info.edp_panel_bpc = 1884 + info_v2_1->edp1_info.edp_panel_bpc; 1885 + info->edp1_info.edp_bootup_bl_level = 1886 + 1887 + info->edp2_info.edp_backlight_pwm_hz = 1888 + le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz); 1889 + info->edp2_info.edp_ss_percentage = 1890 + le16_to_cpu(info_v2_1->edp2_info.edp_ss_percentage); 1891 + info->edp2_info.edp_ss_rate_10hz = 1892 + le16_to_cpu(info_v2_1->edp2_info.edp_ss_rate_10hz); 1893 + info->edp2_info.edp_pwr_on_off_delay = 1894 + info_v2_1->edp2_info.edp_pwr_on_off_delay; 1895 + info->edp2_info.edp_pwr_on_vary_bl_to_blon = 1896 + info_v2_1->edp2_info.edp_pwr_on_vary_bl_to_blon; 1897 + info->edp2_info.edp_pwr_down_bloff_to_vary_bloff = 1898 + info_v2_1->edp2_info.edp_pwr_down_bloff_to_vary_bloff; 1899 + info->edp2_info.edp_panel_bpc = 1900 + info_v2_1->edp2_info.edp_panel_bpc; 1901 + info->edp2_info.edp_bootup_bl_level = 1902 + info_v2_1->edp2_info.edp_bootup_bl_level; 1903 + 1904 + return BP_RESULT_OK; 1905 + } 1906 + #endif 1746 1907 1747 1908 /* 1748 1909 * construct_integrated_info ··· 1936 1775 1937 1776 get_atom_data_table_revision(header, &revision); 1938 1777 1778 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 1779 + switch (revision.major) { 1780 + case 1: 1781 + switch (revision.minor) { 1782 + case 11: 1783 + case 12: 1784 + result = get_integrated_info_v11(bp, info); 1785 + break; 1786 + default: 1787 + return result; 1788 + } 1789 + break; 1790 + case 2: 1791 + switch (revision.minor) { 1792 + case 1: 1793 + result = get_integrated_info_v2_1(bp, info); 1794 + break; 1795 + default: 1796 + return result; 1797 + } 1798 + break; 1799 + default: 1800 + return result; 1801 + } 1802 + #else 1939 1803 /* Don't need to check major revision as they are all 1 */ 1940 1804 switch (revision.minor) { 1941 1805 case 11: ··· 1970 1784 default: 1971 1785 return result; 1972 1786 } 1787 + #endif 1973 1788 } 1974 1789 1975 1790 if (result != BP_RESULT_OK)
+5 -1
drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
··· 78 78 *h = dal_cmd_tbl_helper_dce112_get_table2(); 79 79 return true; 80 80 #endif 81 - 81 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 82 + case DCN_VERSION_3_01: 83 + *h = dal_cmd_tbl_helper_dce112_get_table2(); 84 + return true; 85 + #endif 82 86 default: 83 87 /* Unsupported DCE */ 84 88 BREAK_TO_DEBUGGER();
+10
drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
··· 125 125 126 126 AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) 127 127 endif 128 + ifdef CONFIG_DRM_AMD_DC_DCN3_01 129 + ############################################################################### 130 + # DCN301 131 + ############################################################################### 132 + CLK_MGR_DCN301 = vg_clk_mgr.o dcn301_smu.o 133 + 134 + AMD_DAL_CLK_MGR_DCN301 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301)) 135 + 136 + AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301) 137 + endif
+20 -1
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
··· 42 42 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 43 43 #include "dcn30/dcn30_clk_mgr.h" 44 44 #endif 45 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 46 + #include "dcn301/vg_clk_mgr.h" 47 + #endif 45 48 46 49 47 50 int clk_mgr_helper_get_active_display_cnt( ··· 191 188 break; 192 189 #endif /* Family RV and NV*/ 193 190 191 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 192 + case FAMILY_VGH: 193 + if (ASICREV_IS_VANGOGH(asic_id.hw_internal_rev)) 194 + vg_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); 195 + break; 196 + #endif 194 197 default: 195 198 ASSERT(0); /* Unknown Asic */ 196 199 break; ··· 214 205 case FAMILY_NV: 215 206 if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { 216 207 dcn3_clk_mgr_destroy(clk_mgr); 217 - break; 218 208 } 209 + break; 210 + 211 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 212 + case FAMILY_VGH: 213 + if (ASICREV_IS_VANGOGH(clk_mgr_base->ctx->asic_id.hw_internal_rev)) 214 + vg_clk_mgr_destroy(clk_mgr); 215 + break; 216 + #endif 217 + 218 + default: 219 + break; 219 220 } 220 221 #endif 221 222
+241
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.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 "core_types.h" 27 + #include "clk_mgr_internal.h" 28 + #include "reg_helper.h" 29 + #include <linux/delay.h> 30 + 31 + #include "dcn301_smu.h" 32 + 33 + #include "vangogh_ip_offset.h" 34 + 35 + #include "mp/mp_11_5_0_offset.h" 36 + #include "mp/mp_11_5_0_sh_mask.h" 37 + 38 + #define REG(reg_name) \ 39 + (MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) 40 + 41 + #define FN(reg_name, field) \ 42 + FD(reg_name##__##field) 43 + 44 + #define VBIOSSMC_MSG_GetSmuVersion 0x2 45 + #define VBIOSSMC_MSG_SetDispclkFreq 0x4 46 + #define VBIOSSMC_MSG_SetDprefclkFreq 0x5 47 + #define VBIOSSMC_MSG_SetDppclkFreq 0x6 48 + #define VBIOSSMC_MSG_SetHardMinDcfclkByFreq 0x7 49 + #define VBIOSSMC_MSG_SetMinDeepSleepDcfclk 0x8 50 + //#define VBIOSSMC_MSG_SetPhyclkVoltageByFreq 0xA 51 + #define VBIOSSMC_MSG_GetFclkFrequency 0xA 52 + //#define VBIOSSMC_MSG_SetDisplayCount 0xC 53 + //#define VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown 0xD 54 + #define VBIOSSMC_MSG_UpdatePmeRestore 0xD 55 + #define VBIOSSMC_MSG_SetVbiosDramAddrHigh 0xE //Used for WM table txfr 56 + #define VBIOSSMC_MSG_SetVbiosDramAddrLow 0xF 57 + #define VBIOSSMC_MSG_TransferTableSmu2Dram 0x10 58 + #define VBIOSSMC_MSG_TransferTableDram2Smu 0x11 59 + #define VBIOSSMC_MSG_SetDisplayIdleOptimizations 0x12 60 + 61 + #define VBIOSSMC_Status_BUSY 0x0 62 + #define VBIOSSMC_Result_OK 0x1 63 + #define VBIOSSMC_Result_Failed 0xFF 64 + #define VBIOSSMC_Result_UnknownCmd 0xFE 65 + #define VBIOSSMC_Result_CmdRejectedPrereq 0xFD 66 + #define VBIOSSMC_Result_CmdRejectedBusy 0xFC 67 + 68 + /* 69 + * Function to be used instead of REG_WAIT macro because the wait ends when 70 + * the register is NOT EQUAL to zero, and because the translation in msg_if.h 71 + * won't work with REG_WAIT. 72 + */ 73 + static uint32_t dcn301_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, unsigned int delay_us, unsigned int max_retries) 74 + { 75 + uint32_t res_val = VBIOSSMC_Status_BUSY; 76 + 77 + do { 78 + res_val = REG_READ(MP1_SMN_C2PMSG_91); 79 + if (res_val != VBIOSSMC_Status_BUSY) 80 + break; 81 + 82 + if (delay_us >= 1000) 83 + msleep(delay_us/1000); 84 + else if (delay_us > 0) 85 + udelay(delay_us); 86 + } while (max_retries--); 87 + 88 + return res_val; 89 + } 90 + 91 + int dcn301_smu_send_msg_with_param( 92 + struct clk_mgr_internal *clk_mgr, 93 + unsigned int msg_id, unsigned int param) 94 + { 95 + uint32_t result; 96 + 97 + /* First clear response register */ 98 + REG_WRITE(MP1_SMN_C2PMSG_91, VBIOSSMC_Status_BUSY); 99 + 100 + /* Set the parameter register for the SMU message, unit is Mhz */ 101 + REG_WRITE(MP1_SMN_C2PMSG_83, param); 102 + 103 + /* Trigger the message transaction by writing the message ID */ 104 + REG_WRITE(MP1_SMN_C2PMSG_67, msg_id); 105 + 106 + result = dcn301_smu_wait_for_response(clk_mgr, 10, 1000); 107 + 108 + ASSERT(result == VBIOSSMC_Result_OK); 109 + 110 + /* Actual dispclk set is returned in the parameter register */ 111 + return REG_READ(MP1_SMN_C2PMSG_83); 112 + } 113 + 114 + int dcn301_smu_get_smu_version(struct clk_mgr_internal *clk_mgr) 115 + { 116 + return dcn301_smu_send_msg_with_param( 117 + clk_mgr, 118 + VBIOSSMC_MSG_GetSmuVersion, 119 + 0); 120 + } 121 + 122 + 123 + int dcn301_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz) 124 + { 125 + int actual_dispclk_set_mhz = -1; 126 + 127 + /* Unit of SMU msg parameter is Mhz */ 128 + actual_dispclk_set_mhz = dcn301_smu_send_msg_with_param( 129 + clk_mgr, 130 + VBIOSSMC_MSG_SetDispclkFreq, 131 + requested_dispclk_khz / 1000); 132 + 133 + return actual_dispclk_set_mhz * 1000; 134 + } 135 + 136 + int dcn301_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr) 137 + { 138 + int actual_dprefclk_set_mhz = -1; 139 + 140 + actual_dprefclk_set_mhz = dcn301_smu_send_msg_with_param( 141 + clk_mgr, 142 + VBIOSSMC_MSG_SetDprefclkFreq, 143 + clk_mgr->base.dprefclk_khz / 1000); 144 + 145 + /* TODO: add code for programing DP DTO, currently this is down by command table */ 146 + 147 + return actual_dprefclk_set_mhz * 1000; 148 + } 149 + 150 + int dcn301_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz) 151 + { 152 + int actual_dcfclk_set_mhz = -1; 153 + 154 + actual_dcfclk_set_mhz = dcn301_smu_send_msg_with_param( 155 + clk_mgr, 156 + VBIOSSMC_MSG_SetHardMinDcfclkByFreq, 157 + requested_dcfclk_khz / 1000); 158 + 159 + return actual_dcfclk_set_mhz * 1000; 160 + } 161 + 162 + int dcn301_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz) 163 + { 164 + int actual_min_ds_dcfclk_mhz = -1; 165 + 166 + actual_min_ds_dcfclk_mhz = dcn301_smu_send_msg_with_param( 167 + clk_mgr, 168 + VBIOSSMC_MSG_SetMinDeepSleepDcfclk, 169 + requested_min_ds_dcfclk_khz / 1000); 170 + 171 + return actual_min_ds_dcfclk_mhz * 1000; 172 + } 173 + 174 + int dcn301_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz) 175 + { 176 + int actual_dppclk_set_mhz = -1; 177 + 178 + actual_dppclk_set_mhz = dcn301_smu_send_msg_with_param( 179 + clk_mgr, 180 + VBIOSSMC_MSG_SetDppclkFreq, 181 + requested_dpp_khz / 1000); 182 + 183 + return actual_dppclk_set_mhz * 1000; 184 + } 185 + 186 + void dcn301_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info) 187 + { 188 + //TODO: Work with smu team to define optimization options. 189 + 190 + dcn301_smu_send_msg_with_param( 191 + clk_mgr, 192 + VBIOSSMC_MSG_SetDisplayIdleOptimizations, 193 + idle_info); 194 + } 195 + 196 + void dcn301_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable) 197 + { 198 + union display_idle_optimization_u idle_info = { 0 }; 199 + 200 + if (enable) { 201 + idle_info.idle_info.df_request_disabled = 1; 202 + idle_info.idle_info.phy_ref_clk_off = 1; 203 + } 204 + 205 + dcn301_smu_send_msg_with_param( 206 + clk_mgr, 207 + VBIOSSMC_MSG_SetDisplayIdleOptimizations, 208 + idle_info.data); 209 + } 210 + 211 + void dcn301_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr) 212 + { 213 + dcn301_smu_send_msg_with_param( 214 + clk_mgr, 215 + VBIOSSMC_MSG_UpdatePmeRestore, 216 + 0); 217 + } 218 + 219 + void dcn301_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high) 220 + { 221 + dcn301_smu_send_msg_with_param(clk_mgr, 222 + VBIOSSMC_MSG_SetVbiosDramAddrHigh, addr_high); 223 + } 224 + 225 + void dcn301_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low) 226 + { 227 + dcn301_smu_send_msg_with_param(clk_mgr, 228 + VBIOSSMC_MSG_SetVbiosDramAddrLow, addr_low); 229 + } 230 + 231 + void dcn301_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr) 232 + { 233 + dcn301_smu_send_msg_with_param(clk_mgr, 234 + VBIOSSMC_MSG_TransferTableSmu2Dram, TABLE_DPMCLOCKS); 235 + } 236 + 237 + void dcn301_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr) 238 + { 239 + dcn301_smu_send_msg_with_param(clk_mgr, 240 + VBIOSSMC_MSG_TransferTableDram2Smu, TABLE_WATERMARKS); 241 + }
+164
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.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_DC_301_SMU_H_ 27 + #define DAL_DC_301_SMU_H_ 28 + 29 + #define SMU13_DRIVER_IF_VERSION 2 30 + 31 + typedef struct { 32 + uint32_t fclk; 33 + uint32_t memclk; 34 + uint32_t voltage; 35 + } df_pstate_t; 36 + 37 + typedef struct { 38 + uint32_t vclk; 39 + uint32_t dclk; 40 + } vcn_clk_t; 41 + 42 + typedef enum { 43 + DSPCLK_DCFCLK = 0, 44 + DSPCLK_DISPCLK, 45 + DSPCLK_PIXCLK, 46 + DSPCLK_PHYCLK, 47 + DSPCLK_COUNT, 48 + } DSPCLK_e; 49 + 50 + typedef struct { 51 + uint16_t Freq; // in MHz 52 + uint16_t Vid; // min voltage in SVI2 VID 53 + } DisplayClockTable_t; 54 + 55 + typedef struct { 56 + uint16_t MinClock; // This is either DCFCLK or SOCCLK (in MHz) 57 + uint16_t MaxClock; // This is either DCFCLK or SOCCLK (in MHz) 58 + uint16_t MinMclk; 59 + uint16_t MaxMclk; 60 + 61 + uint8_t WmSetting; 62 + uint8_t WmType; // Used for normal pstate change or memory retraining 63 + uint8_t Padding[2]; 64 + } WatermarkRowGeneric_t; 65 + 66 + 67 + #define NUM_WM_RANGES 4 68 + 69 + typedef enum { 70 + WM_SOCCLK = 0, 71 + WM_DCFCLK, 72 + WM_COUNT, 73 + } WM_CLOCK_e; 74 + 75 + typedef struct { 76 + // Watermarks 77 + WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES]; 78 + 79 + uint32_t MmHubPadding[7]; // SMU internal use 80 + } Watermarks_t; 81 + 82 + 83 + #define TABLE_WATERMARKS 1 84 + #define TABLE_DPMCLOCKS 4 // Called by Driver 85 + 86 + 87 + #define VG_NUM_DCFCLK_DPM_LEVELS 7 88 + #define VG_NUM_DISPCLK_DPM_LEVELS 7 89 + #define VG_NUM_DPPCLK_DPM_LEVELS 7 90 + #define VG_NUM_SOCCLK_DPM_LEVELS 7 91 + #define VG_NUM_ISPICLK_DPM_LEVELS 7 92 + #define VG_NUM_ISPXCLK_DPM_LEVELS 7 93 + #define VG_NUM_VCN_DPM_LEVELS 5 94 + #define VG_NUM_FCLK_DPM_LEVELS 4 95 + #define VG_NUM_SOC_VOLTAGE_LEVELS 8 96 + 97 + // copy from vgh/vangogh/pmfw_driver_if.h 98 + struct vg_dpm_clocks { 99 + uint32_t DcfClocks[VG_NUM_DCFCLK_DPM_LEVELS]; 100 + uint32_t DispClocks[VG_NUM_DISPCLK_DPM_LEVELS]; 101 + uint32_t DppClocks[VG_NUM_DPPCLK_DPM_LEVELS]; 102 + uint32_t SocClocks[VG_NUM_SOCCLK_DPM_LEVELS]; 103 + uint32_t IspiClocks[VG_NUM_ISPICLK_DPM_LEVELS]; 104 + uint32_t IspxClocks[VG_NUM_ISPXCLK_DPM_LEVELS]; 105 + vcn_clk_t VcnClocks[VG_NUM_VCN_DPM_LEVELS]; 106 + 107 + uint32_t SocVoltage[VG_NUM_SOC_VOLTAGE_LEVELS]; 108 + 109 + df_pstate_t DfPstateTable[VG_NUM_FCLK_DPM_LEVELS]; 110 + 111 + uint32_t MinGfxClk; 112 + uint32_t MaxGfxClk; 113 + 114 + uint8_t NumDfPstatesEnabled; 115 + uint8_t NumDcfclkLevelsEnabled; 116 + uint8_t NumDispClkLevelsEnabled; //applies to both dispclk and dppclk 117 + uint8_t NumSocClkLevelsEnabled; 118 + 119 + uint8_t IspClkLevelsEnabled; //applies to both ispiclk and ispxclk 120 + uint8_t VcnClkLevelsEnabled; //applies to both vclk/dclk 121 + uint8_t spare[2]; 122 + }; 123 + 124 + struct smu_dpm_clks { 125 + struct vg_dpm_clocks *dpm_clks; 126 + union large_integer mc_address; 127 + }; 128 + 129 + struct watermarks { 130 + // Watermarks 131 + WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES]; 132 + 133 + uint32_t MmHubPadding[7]; // SMU internal use 134 + }; 135 + 136 + 137 + struct display_idle_optimization { 138 + unsigned int df_request_disabled : 1; 139 + unsigned int phy_ref_clk_off : 1; 140 + unsigned int s0i2_rdy : 1; 141 + unsigned int reserved : 29; 142 + }; 143 + 144 + union display_idle_optimization_u { 145 + struct display_idle_optimization idle_info; 146 + uint32_t data; 147 + }; 148 + 149 + 150 + int dcn301_smu_get_smu_version(struct clk_mgr_internal *clk_mgr); 151 + int dcn301_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz); 152 + int dcn301_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr); 153 + int dcn301_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_dcfclk_khz); 154 + int dcn301_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz); 155 + int dcn301_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz); 156 + void dcn301_smu_set_display_idle_optimization(struct clk_mgr_internal *clk_mgr, uint32_t idle_info); 157 + void dcn301_smu_enable_phy_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable); 158 + void dcn301_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr); 159 + void dcn301_smu_set_dram_addr_high(struct clk_mgr_internal *clk_mgr, uint32_t addr_high); 160 + void dcn301_smu_set_dram_addr_low(struct clk_mgr_internal *clk_mgr, uint32_t addr_low); 161 + void dcn301_smu_transfer_dpm_table_smu_2_dram(struct clk_mgr_internal *clk_mgr); 162 + void dcn301_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr); 163 + 164 + #endif /* DAL_DC_301_SMU_H_ */
+834
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.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 "dccg.h" 27 + #include "clk_mgr_internal.h" 28 + 29 + // For dce12_get_dp_ref_freq_khz 30 + #include "dce100/dce_clk_mgr.h" 31 + 32 + // For dcn20_update_clocks_update_dpp_dto 33 + #include "dcn20/dcn20_clk_mgr.h" 34 + 35 + #include "vg_clk_mgr.h" 36 + 37 + #include "dcn301_smu.h" 38 + #include "reg_helper.h" 39 + #include "core_types.h" 40 + #include "dm_helpers.h" 41 + 42 + #include "atomfirmware.h" 43 + #include "vangogh_ip_offset.h" 44 + #include "clk/clk_11_5_0_offset.h" 45 + #include "clk/clk_11_5_0_sh_mask.h" 46 + 47 + /* Constants */ 48 + 49 + #define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 Training Counter Requirement doc */ 50 + 51 + /* Macros */ 52 + 53 + #define REG(reg_name) \ 54 + (CLK_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) 55 + 56 + /* TODO: evaluate how to lower or disable all dcn clocks in screen off case */ 57 + int vg_get_active_display_cnt_wa( 58 + struct dc *dc, 59 + struct dc_state *context) 60 + { 61 + int i, display_count; 62 + bool tmds_present = false; 63 + 64 + display_count = 0; 65 + for (i = 0; i < context->stream_count; i++) { 66 + const struct dc_stream_state *stream = context->streams[i]; 67 + 68 + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || 69 + stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || 70 + stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) 71 + tmds_present = true; 72 + } 73 + 74 + for (i = 0; i < dc->link_count; i++) { 75 + const struct dc_link *link = dc->links[i]; 76 + 77 + /* 78 + * Only notify active stream or virtual stream. 79 + * Need to notify virtual stream to work around 80 + * headless case. HPD does not fire when system is in 81 + * S0i2. 82 + */ 83 + /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */ 84 + if (link->connector_signal == SIGNAL_TYPE_VIRTUAL || 85 + link->link_enc->funcs->is_dig_enabled(link->link_enc)) 86 + display_count++; 87 + } 88 + 89 + /* WA for hang on HDMI after display off back back on*/ 90 + if (display_count == 0 && tmds_present) 91 + display_count = 1; 92 + 93 + return display_count; 94 + } 95 + 96 + void vg_update_clocks(struct clk_mgr *clk_mgr_base, 97 + struct dc_state *context, 98 + bool safe_to_lower) 99 + { 100 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 101 + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; 102 + struct dc *dc = clk_mgr_base->ctx->dc; 103 + int display_count; 104 + bool update_dppclk = false; 105 + bool update_dispclk = false; 106 + bool dpp_clock_lowered = false; 107 + 108 + if (dc->work_arounds.skip_clock_update) 109 + return; 110 + 111 + /* 112 + * if it is safe to lower, but we are already in the lower state, we don't have to do anything 113 + * also if safe to lower is false, we just go in the higher state 114 + */ 115 + if (safe_to_lower) { 116 + /* check that we're not already in lower */ 117 + if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { 118 + 119 + display_count = vg_get_active_display_cnt_wa(dc, context); 120 + /* if we can go lower, go lower */ 121 + if (display_count == 0) { 122 + union display_idle_optimization_u idle_info = { 0 }; 123 + 124 + idle_info.idle_info.df_request_disabled = 1; 125 + idle_info.idle_info.phy_ref_clk_off = 1; 126 + 127 + dcn301_smu_set_display_idle_optimization(clk_mgr, idle_info.data); 128 + /* update power state */ 129 + clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER; 130 + } 131 + } 132 + } else { 133 + /* check that we're not already in D0 */ 134 + if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) { 135 + union display_idle_optimization_u idle_info = { 0 }; 136 + 137 + dcn301_smu_set_display_idle_optimization(clk_mgr, idle_info.data); 138 + /* update power state */ 139 + clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_MISSION_MODE; 140 + } 141 + } 142 + 143 + if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr_base->clks.dcfclk_khz)) { 144 + clk_mgr_base->clks.dcfclk_khz = new_clocks->dcfclk_khz; 145 + dcn301_smu_set_hard_min_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_khz); 146 + } 147 + 148 + if (should_set_clock(safe_to_lower, 149 + new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) { 150 + clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; 151 + dcn301_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz); 152 + } 153 + 154 + // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow. 155 + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { 156 + if (new_clocks->dppclk_khz < 100000) 157 + new_clocks->dppclk_khz = 100000; 158 + } 159 + 160 + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { 161 + if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) 162 + dpp_clock_lowered = true; 163 + clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz; 164 + update_dppclk = true; 165 + } 166 + 167 + if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { 168 + clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; 169 + dcn301_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); 170 + 171 + update_dispclk = true; 172 + } 173 + 174 + if (dpp_clock_lowered) { 175 + // increase per DPP DTO before lowering global dppclk 176 + dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); 177 + dcn301_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz); 178 + } else { 179 + // increase global DPPCLK before lowering per DPP DTO 180 + if (update_dppclk || update_dispclk) 181 + dcn301_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz); 182 + // always update dtos unless clock is lowered and not safe to lower 183 + if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz) 184 + dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); 185 + } 186 + } 187 + 188 + 189 + static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr) 190 + { 191 + /* get FbMult value */ 192 + struct fixed31_32 pll_req; 193 + unsigned int fbmult_frac_val = 0; 194 + unsigned int fbmult_int_val = 0; 195 + 196 + 197 + /* 198 + * Register value of fbmult is in 8.16 format, we are converting to 31.32 199 + * to leverage the fix point operations available in driver 200 + */ 201 + 202 + REG_GET(CLK1_0_CLK1_CLK_PLL_REQ, FbMult_frac, &fbmult_frac_val); /* 16 bit fractional part*/ 203 + REG_GET(CLK1_0_CLK1_CLK_PLL_REQ, FbMult_int, &fbmult_int_val); /* 8 bit integer part */ 204 + 205 + pll_req = dc_fixpt_from_int(fbmult_int_val); 206 + 207 + /* 208 + * since fractional part is only 16 bit in register definition but is 32 bit 209 + * in our fix point definiton, need to shift left by 16 to obtain correct value 210 + */ 211 + pll_req.value |= fbmult_frac_val << 16; 212 + 213 + /* multiply by REFCLK period */ 214 + pll_req = dc_fixpt_mul_int(pll_req, clk_mgr->dfs_ref_freq_khz); 215 + 216 + /* integer part is now VCO frequency in kHz */ 217 + return dc_fixpt_floor(pll_req); 218 + } 219 + 220 + static void vg_dump_clk_registers_internal(struct dcn301_clk_internal *internal, struct clk_mgr *clk_mgr_base) 221 + { 222 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 223 + 224 + internal->CLK1_CLK3_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK3_CURRENT_CNT); 225 + internal->CLK1_CLK3_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK3_BYPASS_CNTL); 226 + 227 + internal->CLK1_CLK3_DS_CNTL = REG_READ(CLK1_0_CLK1_CLK3_DS_CNTL); //dcf deep sleep divider 228 + internal->CLK1_CLK3_ALLOW_DS = REG_READ(CLK1_0_CLK1_CLK3_ALLOW_DS); 229 + 230 + internal->CLK1_CLK1_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK1_CURRENT_CNT); 231 + internal->CLK1_CLK1_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK1_BYPASS_CNTL); 232 + 233 + internal->CLK1_CLK2_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK2_CURRENT_CNT); 234 + internal->CLK1_CLK2_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK2_BYPASS_CNTL); 235 + 236 + internal->CLK1_CLK0_CURRENT_CNT = REG_READ(CLK1_0_CLK1_CLK0_CURRENT_CNT); 237 + internal->CLK1_CLK0_BYPASS_CNTL = REG_READ(CLK1_0_CLK1_CLK0_BYPASS_CNTL); 238 + } 239 + 240 + /* This function collect raw clk register values */ 241 + static void vg_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass, 242 + struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info) 243 + { 244 + struct dcn301_clk_internal internal = {0}; 245 + char *bypass_clks[5] = {"0x0 DFS", "0x1 REFCLK", "0x2 ERROR", "0x3 400 FCH", "0x4 600 FCH"}; 246 + unsigned int chars_printed = 0; 247 + unsigned int remaining_buffer = log_info->bufSize; 248 + 249 + vg_dump_clk_registers_internal(&internal, clk_mgr_base); 250 + 251 + regs_and_bypass->dcfclk = internal.CLK1_CLK3_CURRENT_CNT / 10; 252 + regs_and_bypass->dcf_deep_sleep_divider = internal.CLK1_CLK3_DS_CNTL / 10; 253 + regs_and_bypass->dcf_deep_sleep_allow = internal.CLK1_CLK3_ALLOW_DS; 254 + regs_and_bypass->dprefclk = internal.CLK1_CLK2_CURRENT_CNT / 10; 255 + regs_and_bypass->dispclk = internal.CLK1_CLK0_CURRENT_CNT / 10; 256 + regs_and_bypass->dppclk = internal.CLK1_CLK1_CURRENT_CNT / 10; 257 + 258 + regs_and_bypass->dppclk_bypass = internal.CLK1_CLK1_BYPASS_CNTL & 0x0007; 259 + if (regs_and_bypass->dppclk_bypass < 0 || regs_and_bypass->dppclk_bypass > 4) 260 + regs_and_bypass->dppclk_bypass = 0; 261 + regs_and_bypass->dcfclk_bypass = internal.CLK1_CLK3_BYPASS_CNTL & 0x0007; 262 + if (regs_and_bypass->dcfclk_bypass < 0 || regs_and_bypass->dcfclk_bypass > 4) 263 + regs_and_bypass->dcfclk_bypass = 0; 264 + regs_and_bypass->dispclk_bypass = internal.CLK1_CLK0_BYPASS_CNTL & 0x0007; 265 + if (regs_and_bypass->dispclk_bypass < 0 || regs_and_bypass->dispclk_bypass > 4) 266 + regs_and_bypass->dispclk_bypass = 0; 267 + regs_and_bypass->dprefclk_bypass = internal.CLK1_CLK2_BYPASS_CNTL & 0x0007; 268 + if (regs_and_bypass->dprefclk_bypass < 0 || regs_and_bypass->dprefclk_bypass > 4) 269 + regs_and_bypass->dprefclk_bypass = 0; 270 + 271 + if (log_info->enabled) { 272 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "clk_type,clk_value,deepsleep_cntl,deepsleep_allow,bypass\n"); 273 + remaining_buffer -= chars_printed; 274 + *log_info->sum_chars_printed += chars_printed; 275 + log_info->pBuf += chars_printed; 276 + 277 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dcfclk,%d,%d,%d,%s\n", 278 + regs_and_bypass->dcfclk, 279 + regs_and_bypass->dcf_deep_sleep_divider, 280 + regs_and_bypass->dcf_deep_sleep_allow, 281 + bypass_clks[(int) regs_and_bypass->dcfclk_bypass]); 282 + remaining_buffer -= chars_printed; 283 + *log_info->sum_chars_printed += chars_printed; 284 + log_info->pBuf += chars_printed; 285 + 286 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dprefclk,%d,N/A,N/A,%s\n", 287 + regs_and_bypass->dprefclk, 288 + bypass_clks[(int) regs_and_bypass->dprefclk_bypass]); 289 + remaining_buffer -= chars_printed; 290 + *log_info->sum_chars_printed += chars_printed; 291 + log_info->pBuf += chars_printed; 292 + 293 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "dispclk,%d,N/A,N/A,%s\n", 294 + regs_and_bypass->dispclk, 295 + bypass_clks[(int) regs_and_bypass->dispclk_bypass]); 296 + remaining_buffer -= chars_printed; 297 + *log_info->sum_chars_printed += chars_printed; 298 + log_info->pBuf += chars_printed; 299 + 300 + //split 301 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "SPLIT\n"); 302 + remaining_buffer -= chars_printed; 303 + *log_info->sum_chars_printed += chars_printed; 304 + log_info->pBuf += chars_printed; 305 + 306 + // REGISTER VALUES 307 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "reg_name,value,clk_type\n"); 308 + remaining_buffer -= chars_printed; 309 + *log_info->sum_chars_printed += chars_printed; 310 + log_info->pBuf += chars_printed; 311 + 312 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_CURRENT_CNT,%d,dcfclk\n", 313 + internal.CLK1_CLK3_CURRENT_CNT); 314 + remaining_buffer -= chars_printed; 315 + *log_info->sum_chars_printed += chars_printed; 316 + log_info->pBuf += chars_printed; 317 + 318 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_DS_CNTL,%d,dcf_deep_sleep_divider\n", 319 + internal.CLK1_CLK3_DS_CNTL); 320 + remaining_buffer -= chars_printed; 321 + *log_info->sum_chars_printed += chars_printed; 322 + log_info->pBuf += chars_printed; 323 + 324 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_ALLOW_DS,%d,dcf_deep_sleep_allow\n", 325 + internal.CLK1_CLK3_ALLOW_DS); 326 + remaining_buffer -= chars_printed; 327 + *log_info->sum_chars_printed += chars_printed; 328 + log_info->pBuf += chars_printed; 329 + 330 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK2_CURRENT_CNT,%d,dprefclk\n", 331 + internal.CLK1_CLK2_CURRENT_CNT); 332 + remaining_buffer -= chars_printed; 333 + *log_info->sum_chars_printed += chars_printed; 334 + log_info->pBuf += chars_printed; 335 + 336 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK0_CURRENT_CNT,%d,dispclk\n", 337 + internal.CLK1_CLK0_CURRENT_CNT); 338 + remaining_buffer -= chars_printed; 339 + *log_info->sum_chars_printed += chars_printed; 340 + log_info->pBuf += chars_printed; 341 + 342 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK1_CURRENT_CNT,%d,dppclk\n", 343 + internal.CLK1_CLK1_CURRENT_CNT); 344 + remaining_buffer -= chars_printed; 345 + *log_info->sum_chars_printed += chars_printed; 346 + log_info->pBuf += chars_printed; 347 + 348 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK3_BYPASS_CNTL,%d,dcfclk_bypass\n", 349 + internal.CLK1_CLK3_BYPASS_CNTL); 350 + remaining_buffer -= chars_printed; 351 + *log_info->sum_chars_printed += chars_printed; 352 + log_info->pBuf += chars_printed; 353 + 354 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK2_BYPASS_CNTL,%d,dprefclk_bypass\n", 355 + internal.CLK1_CLK2_BYPASS_CNTL); 356 + remaining_buffer -= chars_printed; 357 + *log_info->sum_chars_printed += chars_printed; 358 + log_info->pBuf += chars_printed; 359 + 360 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK0_BYPASS_CNTL,%d,dispclk_bypass\n", 361 + internal.CLK1_CLK0_BYPASS_CNTL); 362 + remaining_buffer -= chars_printed; 363 + *log_info->sum_chars_printed += chars_printed; 364 + log_info->pBuf += chars_printed; 365 + 366 + chars_printed = snprintf_count(log_info->pBuf, remaining_buffer, "CLK1_CLK1_BYPASS_CNTL,%d,dppclk_bypass\n", 367 + internal.CLK1_CLK1_BYPASS_CNTL); 368 + remaining_buffer -= chars_printed; 369 + *log_info->sum_chars_printed += chars_printed; 370 + log_info->pBuf += chars_printed; 371 + } 372 + } 373 + 374 + /* This function produce translated logical clk state values*/ 375 + void vg_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s) 376 + { 377 + 378 + struct clk_state_registers_and_bypass sb = { 0 }; 379 + struct clk_log_info log_info = { 0 }; 380 + 381 + vg_dump_clk_registers(&sb, clk_mgr_base, &log_info); 382 + 383 + s->dprefclk_khz = sb.dprefclk * 1000; 384 + } 385 + 386 + void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base) 387 + { 388 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 389 + 390 + dcn301_smu_enable_pme_wa(clk_mgr); 391 + } 392 + 393 + void vg_init_clocks(struct clk_mgr *clk_mgr) 394 + { 395 + memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); 396 + // Assumption is that boot state always supports pstate 397 + clk_mgr->clks.p_state_change_support = true; 398 + clk_mgr->clks.prev_p_state_change_support = true; 399 + clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; 400 + } 401 + 402 + static void vg_build_watermark_ranges(struct clk_bw_params *bw_params, struct watermarks *table) 403 + { 404 + int i, num_valid_sets; 405 + 406 + num_valid_sets = 0; 407 + 408 + for (i = 0; i < WM_SET_COUNT; i++) { 409 + /* skip empty entries, the smu array has no holes*/ 410 + if (!bw_params->wm_table.entries[i].valid) 411 + continue; 412 + 413 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmSetting = bw_params->wm_table.entries[i].wm_inst; 414 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType = bw_params->wm_table.entries[i].wm_type; 415 + /* We will not select WM based on fclk, so leave it as unconstrained */ 416 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0; 417 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF; 418 + 419 + if (table->WatermarkRow[WM_DCFCLK][num_valid_sets].WmType == WM_TYPE_PSTATE_CHG) { 420 + if (i == 0) 421 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk = 0; 422 + else { 423 + /* add 1 to make it non-overlapping with next lvl */ 424 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinMclk = 425 + bw_params->clk_table.entries[i - 1].dcfclk_mhz + 1; 426 + } 427 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxMclk = 428 + bw_params->clk_table.entries[i].dcfclk_mhz; 429 + 430 + } else { 431 + /* unconstrained for memory retraining */ 432 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MinClock = 0; 433 + table->WatermarkRow[WM_DCFCLK][num_valid_sets].MaxClock = 0xFFFF; 434 + 435 + /* Modify previous watermark range to cover up to max */ 436 + table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF; 437 + } 438 + num_valid_sets++; 439 + } 440 + 441 + ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */ 442 + 443 + /* modify the min and max to make sure we cover the whole range*/ 444 + table->WatermarkRow[WM_DCFCLK][0].MinMclk = 0; 445 + table->WatermarkRow[WM_DCFCLK][0].MinClock = 0; 446 + table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxMclk = 0xFFFF; 447 + table->WatermarkRow[WM_DCFCLK][num_valid_sets - 1].MaxClock = 0xFFFF; 448 + 449 + /* This is for writeback only, does not matter currently as no writeback support*/ 450 + table->WatermarkRow[WM_SOCCLK][0].WmSetting = WM_A; 451 + table->WatermarkRow[WM_SOCCLK][0].MinClock = 0; 452 + table->WatermarkRow[WM_SOCCLK][0].MaxClock = 0xFFFF; 453 + table->WatermarkRow[WM_SOCCLK][0].MinMclk = 0; 454 + table->WatermarkRow[WM_SOCCLK][0].MaxMclk = 0xFFFF; 455 + } 456 + 457 + 458 + void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base) 459 + { 460 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 461 + struct watermarks *table = clk_mgr_base->smu_wm_set.wm_set; 462 + 463 + if (!clk_mgr->smu_ver) 464 + return; 465 + 466 + if (!table || clk_mgr_base->smu_wm_set.mc_address.quad_part == 0) 467 + return; 468 + 469 + memset(table, 0, sizeof(*table)); 470 + 471 + vg_build_watermark_ranges(clk_mgr_base->bw_params, table); 472 + 473 + dcn301_smu_set_dram_addr_high(clk_mgr, 474 + clk_mgr_base->smu_wm_set.mc_address.high_part); 475 + dcn301_smu_set_dram_addr_low(clk_mgr, 476 + clk_mgr_base->smu_wm_set.mc_address.low_part); 477 + dcn301_smu_transfer_wm_table_dram_2_smu(clk_mgr); 478 + } 479 + 480 + static bool vg_are_clock_states_equal(struct dc_clocks *a, 481 + struct dc_clocks *b) 482 + { 483 + if (a->dispclk_khz != b->dispclk_khz) 484 + return false; 485 + else if (a->dppclk_khz != b->dppclk_khz) 486 + return false; 487 + else if (a->dcfclk_khz != b->dcfclk_khz) 488 + return false; 489 + else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz) 490 + return false; 491 + 492 + return true; 493 + } 494 + 495 + 496 + static struct clk_mgr_funcs vg_funcs = { 497 + .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, 498 + .update_clocks = vg_update_clocks, 499 + .init_clocks = vg_init_clocks, 500 + .enable_pme_wa = vg_enable_pme_wa, 501 + .are_clock_states_equal = vg_are_clock_states_equal, 502 + .notify_wm_ranges = vg_notify_wm_ranges 503 + }; 504 + 505 + static struct clk_bw_params vg_bw_params = { 506 + .vram_type = Ddr4MemType, 507 + .num_channels = 1, 508 + .clk_table = { 509 + .entries = { 510 + { 511 + .voltage = 0, 512 + .dcfclk_mhz = 400, 513 + .fclk_mhz = 400, 514 + .memclk_mhz = 800, 515 + .socclk_mhz = 0, 516 + }, 517 + { 518 + .voltage = 0, 519 + .dcfclk_mhz = 483, 520 + .fclk_mhz = 800, 521 + .memclk_mhz = 1600, 522 + .socclk_mhz = 0, 523 + }, 524 + { 525 + .voltage = 0, 526 + .dcfclk_mhz = 602, 527 + .fclk_mhz = 1067, 528 + .memclk_mhz = 1067, 529 + .socclk_mhz = 0, 530 + }, 531 + { 532 + .voltage = 0, 533 + .dcfclk_mhz = 738, 534 + .fclk_mhz = 1333, 535 + .memclk_mhz = 1600, 536 + .socclk_mhz = 0, 537 + }, 538 + }, 539 + 540 + .num_entries = 4, 541 + }, 542 + 543 + }; 544 + 545 + static struct wm_table ddr4_wm_table = { 546 + .entries = { 547 + { 548 + .wm_inst = WM_A, 549 + .wm_type = WM_TYPE_PSTATE_CHG, 550 + .pstate_latency_us = 11.72, 551 + .sr_exit_time_us = 6.09, 552 + .sr_enter_plus_exit_time_us = 7.14, 553 + .valid = true, 554 + }, 555 + { 556 + .wm_inst = WM_B, 557 + .wm_type = WM_TYPE_PSTATE_CHG, 558 + .pstate_latency_us = 11.72, 559 + .sr_exit_time_us = 10.12, 560 + .sr_enter_plus_exit_time_us = 11.48, 561 + .valid = true, 562 + }, 563 + { 564 + .wm_inst = WM_C, 565 + .wm_type = WM_TYPE_PSTATE_CHG, 566 + .pstate_latency_us = 11.72, 567 + .sr_exit_time_us = 10.12, 568 + .sr_enter_plus_exit_time_us = 11.48, 569 + .valid = true, 570 + }, 571 + { 572 + .wm_inst = WM_D, 573 + .wm_type = WM_TYPE_PSTATE_CHG, 574 + .pstate_latency_us = 11.72, 575 + .sr_exit_time_us = 10.12, 576 + .sr_enter_plus_exit_time_us = 11.48, 577 + .valid = true, 578 + }, 579 + } 580 + }; 581 + 582 + static struct wm_table lpddr5_wm_table = { 583 + .entries = { 584 + { 585 + .wm_inst = WM_A, 586 + .wm_type = WM_TYPE_PSTATE_CHG, 587 + .pstate_latency_us = 11.65333, 588 + .sr_exit_time_us = 5.32, 589 + .sr_enter_plus_exit_time_us = 6.38, 590 + .valid = true, 591 + }, 592 + { 593 + .wm_inst = WM_B, 594 + .wm_type = WM_TYPE_PSTATE_CHG, 595 + .pstate_latency_us = 11.65333, 596 + .sr_exit_time_us = 9.82, 597 + .sr_enter_plus_exit_time_us = 11.196, 598 + .valid = true, 599 + }, 600 + { 601 + .wm_inst = WM_C, 602 + .wm_type = WM_TYPE_PSTATE_CHG, 603 + .pstate_latency_us = 11.65333, 604 + .sr_exit_time_us = 9.89, 605 + .sr_enter_plus_exit_time_us = 11.24, 606 + .valid = true, 607 + }, 608 + { 609 + .wm_inst = WM_D, 610 + .wm_type = WM_TYPE_PSTATE_CHG, 611 + .pstate_latency_us = 11.65333, 612 + .sr_exit_time_us = 9.748, 613 + .sr_enter_plus_exit_time_us = 11.102, 614 + .valid = true, 615 + }, 616 + } 617 + }; 618 + 619 + 620 + static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_table, 621 + unsigned int voltage) 622 + { 623 + int i; 624 + 625 + for (i = 0; i < VG_NUM_SOC_VOLTAGE_LEVELS; i++) { 626 + if (clock_table->SocVoltage[i] == voltage) 627 + return clock_table->DcfClocks[i]; 628 + } 629 + 630 + ASSERT(0); 631 + return 0; 632 + } 633 + 634 + static void vg_clk_mgr_helper_populate_bw_params( 635 + struct clk_mgr_internal *clk_mgr, 636 + struct integrated_info *bios_info, 637 + const struct vg_dpm_clocks *clock_table) 638 + { 639 + int i, j; 640 + struct clk_bw_params *bw_params = clk_mgr->base.bw_params; 641 + 642 + j = -1; 643 + 644 + ASSERT(VG_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL); 645 + 646 + /* Find lowest DPM, FCLK is filled in reverse order*/ 647 + 648 + for (i = VG_NUM_FCLK_DPM_LEVELS - 1; i >= 0; i--) { 649 + if (clock_table->DfPstateTable[i].fclk != 0) { 650 + j = i; 651 + break; 652 + } 653 + } 654 + 655 + if (j == -1) { 656 + /* clock table is all 0s, just use our own hardcode */ 657 + ASSERT(0); 658 + return; 659 + } 660 + 661 + bw_params->clk_table.num_entries = j + 1; 662 + 663 + for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { 664 + bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk; 665 + bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; 666 + bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; 667 + bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage); 668 + } 669 + 670 + bw_params->vram_type = bios_info->memory_type; 671 + bw_params->num_channels = bios_info->ma_channel_number; 672 + 673 + for (i = 0; i < WM_SET_COUNT; i++) { 674 + bw_params->wm_table.entries[i].wm_inst = i; 675 + 676 + if (i >= bw_params->clk_table.num_entries) { 677 + bw_params->wm_table.entries[i].valid = false; 678 + continue; 679 + } 680 + 681 + bw_params->wm_table.entries[i].wm_type = WM_TYPE_PSTATE_CHG; 682 + bw_params->wm_table.entries[i].valid = true; 683 + } 684 + 685 + if (bw_params->vram_type == LpDdr4MemType) { 686 + /* 687 + * WM set D will be re-purposed for memory retraining 688 + */ 689 + bw_params->wm_table.entries[WM_D].pstate_latency_us = LPDDR_MEM_RETRAIN_LATENCY; 690 + bw_params->wm_table.entries[WM_D].wm_inst = WM_D; 691 + bw_params->wm_table.entries[WM_D].wm_type = WM_TYPE_RETRAINING; 692 + bw_params->wm_table.entries[WM_D].valid = true; 693 + } 694 + 695 + } 696 + 697 + /* Temporary Place holder until we can get them from fuse */ 698 + static struct vg_dpm_clocks dummy_clocks = { 699 + .DcfClocks = { 201, 403, 403, 403, 403, 403, 403 }, 700 + .SocClocks = { 400, 600, 600, 600, 600, 600, 600 }, 701 + .SocVoltage = { 2800, 2860, 2860, 2860, 2860, 2860, 2860, 2860 }, 702 + .DfPstateTable = { 703 + { .fclk = 400, .memclk = 400, .voltage = 2800 }, 704 + { .fclk = 400, .memclk = 400, .voltage = 2800 }, 705 + { .fclk = 400, .memclk = 400, .voltage = 2800 }, 706 + { .fclk = 400, .memclk = 400, .voltage = 2800 } 707 + } 708 + }; 709 + 710 + static struct watermarks dummy_wms = { 0 }; 711 + 712 + static void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr, 713 + struct smu_dpm_clks *smu_dpm_clks) 714 + { 715 + struct vg_dpm_clocks *table = smu_dpm_clks->dpm_clks; 716 + 717 + if (!clk_mgr->smu_ver) 718 + return; 719 + 720 + if (!table || smu_dpm_clks->mc_address.quad_part == 0) 721 + return; 722 + 723 + memset(table, 0, sizeof(*table)); 724 + 725 + dcn301_smu_set_dram_addr_high(clk_mgr, 726 + smu_dpm_clks->mc_address.high_part); 727 + dcn301_smu_set_dram_addr_low(clk_mgr, 728 + smu_dpm_clks->mc_address.low_part); 729 + dcn301_smu_transfer_dpm_table_smu_2_dram(clk_mgr); 730 + } 731 + 732 + void vg_clk_mgr_construct( 733 + struct dc_context *ctx, 734 + struct clk_mgr_internal *clk_mgr, 735 + struct pp_smu_funcs *pp_smu, 736 + struct dccg *dccg) 737 + { 738 + struct smu_dpm_clks smu_dpm_clks = { 0 }; 739 + 740 + clk_mgr->base.ctx = ctx; 741 + clk_mgr->base.funcs = &vg_funcs; 742 + 743 + clk_mgr->pp_smu = pp_smu; 744 + 745 + clk_mgr->dccg = dccg; 746 + clk_mgr->dfs_bypass_disp_clk = 0; 747 + 748 + clk_mgr->dprefclk_ss_percentage = 0; 749 + clk_mgr->dprefclk_ss_divider = 1000; 750 + clk_mgr->ss_on_dprefclk = false; 751 + clk_mgr->dfs_ref_freq_khz = 48000; 752 + 753 + clk_mgr->base.smu_wm_set.wm_set = (struct watermarks *)dm_helpers_allocate_gpu_mem( 754 + clk_mgr->base.ctx, 755 + DC_MEM_ALLOC_TYPE_FRAME_BUFFER, 756 + sizeof(struct watermarks), 757 + &clk_mgr->base.smu_wm_set.mc_address.quad_part); 758 + 759 + if (clk_mgr->base.smu_wm_set.wm_set == 0) { 760 + clk_mgr->base.smu_wm_set.wm_set = &dummy_wms; 761 + clk_mgr->base.smu_wm_set.mc_address.quad_part = 0; 762 + } 763 + ASSERT(clk_mgr->base.smu_wm_set.wm_set); 764 + 765 + smu_dpm_clks.dpm_clks = (struct vg_dpm_clocks *)dm_helpers_allocate_gpu_mem( 766 + clk_mgr->base.ctx, 767 + DC_MEM_ALLOC_TYPE_FRAME_BUFFER, 768 + sizeof(struct vg_dpm_clocks), 769 + &smu_dpm_clks.mc_address.quad_part); 770 + 771 + if (smu_dpm_clks.dpm_clks == NULL) { 772 + smu_dpm_clks.dpm_clks = &dummy_clocks; 773 + smu_dpm_clks.mc_address.quad_part = 0; 774 + } 775 + 776 + ASSERT(smu_dpm_clks.dpm_clks); 777 + 778 + if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { 779 + vg_funcs.update_clocks = dcn2_update_clocks_fpga; 780 + clk_mgr->base.dentist_vco_freq_khz = 3600000; 781 + } else { 782 + struct clk_log_info log_info = {0}; 783 + 784 + clk_mgr->smu_ver = dcn301_smu_get_smu_version(clk_mgr); 785 + 786 + if (clk_mgr->smu_ver) 787 + clk_mgr->smu_present = true; 788 + 789 + /* TODO: Check we get what we expect during bringup */ 790 + clk_mgr->base.dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr); 791 + 792 + /* in case we don't get a value from the register, use default */ 793 + if (clk_mgr->base.dentist_vco_freq_khz == 0) 794 + clk_mgr->base.dentist_vco_freq_khz = 3600000; 795 + 796 + if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) { 797 + vg_bw_params.wm_table = lpddr5_wm_table; 798 + } else { 799 + vg_bw_params.wm_table = ddr4_wm_table; 800 + } 801 + /* Saved clocks configured at boot for debug purposes */ 802 + vg_dump_clk_registers(&clk_mgr->base.boot_snapshot, &clk_mgr->base, &log_info); 803 + } 804 + 805 + clk_mgr->base.dprefclk_khz = 600000; 806 + dce_clock_read_ss_info(clk_mgr); 807 + 808 + clk_mgr->base.bw_params = &vg_bw_params; 809 + 810 + vg_get_dpm_table_from_smu(clk_mgr, &smu_dpm_clks); 811 + if (ctx->dc_bios && ctx->dc_bios->integrated_info) { 812 + vg_clk_mgr_helper_populate_bw_params( 813 + clk_mgr, 814 + ctx->dc_bios->integrated_info, 815 + smu_dpm_clks.dpm_clks); 816 + } 817 + 818 + if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0) 819 + dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, 820 + smu_dpm_clks.dpm_clks); 821 + /* 822 + if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver) { 823 + enable powerfeatures when displaycount goes to 0 824 + dcn301_smu_enable_phy_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn); 825 + } 826 + */ 827 + } 828 + 829 + void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr) 830 + { 831 + if (clk_mgr->base.smu_wm_set.wm_set && clk_mgr->base.smu_wm_set.mc_address.quad_part != 0) 832 + dm_helpers_free_gpu_mem(clk_mgr->base.ctx, DC_MEM_ALLOC_TYPE_FRAME_BUFFER, 833 + clk_mgr->base.smu_wm_set.wm_set); 834 + }
+43
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.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 __VG_CLK_MGR_H__ 27 + #define __VG_CLK_MGR_H__ 28 + 29 + int vg_get_active_display_cnt_wa( 30 + struct dc *dc, 31 + struct dc_state *context); 32 + 33 + void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base); 34 + 35 + void vg_clk_mgr_construct(struct dc_context *ctx, 36 + struct clk_mgr_internal *clk_mgr, 37 + struct pp_smu_funcs *pp_smu, 38 + struct dccg *dccg); 39 + 40 + void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr); 41 + 42 + void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base); 43 + #endif //__VG_CLK_MGR_H__
+14
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 58 58 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 59 59 #include "../dcn30/dcn30_resource.h" 60 60 #endif 61 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 62 + #include "../dcn301/dcn301_resource.h" 63 + #endif 61 64 62 65 #define DC_LOGGER_INIT(logger) 63 66 ··· 133 130 dc_version = DCN_VERSION_3_0; 134 131 #endif 135 132 break; 133 + 134 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 135 + case FAMILY_VGH: 136 + dc_version = DCN_VERSION_3_01; 137 + break; 138 + #endif 136 139 default: 137 140 dc_version = DCE_VERSION_UNKNOWN; 138 141 break; ··· 219 210 break; 220 211 #endif 221 212 213 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 214 + case DCN_VERSION_3_01: 215 + res_pool = dcn301_create_resource_pool(init_data, dc); 216 + break; 217 + #endif 222 218 default: 223 219 break; 224 220 }
+17 -1
drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
··· 82 82 SR(DC_ABM1_ACE_THRES_12), \ 83 83 NBIO_SR(BIOS_SCRATCH_2) 84 84 85 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 86 + #define ABM_DCN301_REG_LIST(id)\ 87 + ABM_COMMON_REG_LIST_DCE_BASE(), \ 88 + SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ 89 + SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \ 90 + SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \ 91 + SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \ 92 + SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \ 93 + SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \ 94 + SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \ 95 + SRI(BL1_PWM_USER_LEVEL, ABM, id), \ 96 + SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \ 97 + SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \ 98 + NBIO_SR(BIOS_SCRATCH_2) 99 + #endif 100 + 85 101 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 86 102 #define ABM_DCN30_REG_LIST(id)\ 87 103 ABM_COMMON_REG_LIST_DCE_BASE(), \ ··· 189 173 190 174 #define ABM_MASK_SH_LIST_DCN20(mask_sh) ABM_MASK_SH_LIST_DCE110(mask_sh) 191 175 192 - #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 176 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) || defined(CONFIG_DRM_AMD_DC_DCN3_01) 193 177 #define ABM_MASK_SH_LIST_DCN301(mask_sh) ABM_MASK_SH_LIST_DCN10(mask_sh) 194 178 #endif 195 179
+18
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
··· 1554 1554 return ret; 1555 1555 } 1556 1556 #endif 1557 + 1558 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 1559 + bool dcn301_clk_src_construct( 1560 + struct dce110_clk_src *clk_src, 1561 + struct dc_context *ctx, 1562 + struct dc_bios *bios, 1563 + enum clock_source_id id, 1564 + const struct dce110_clk_src_regs *regs, 1565 + const struct dce110_clk_src_shift *cs_shift, 1566 + const struct dce110_clk_src_mask *cs_mask) 1567 + { 1568 + bool ret = dce112_clk_src_construct(clk_src, ctx, bios, id, regs, cs_shift, cs_mask); 1569 + 1570 + clk_src->base.funcs = &dcn3_clk_src_funcs; 1571 + 1572 + return ret; 1573 + } 1574 + #endif
+29
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
··· 108 108 SRII(PIXEL_RATE_CNTL, OTG, 3) 109 109 #endif 110 110 111 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 112 + #define CS_COMMON_REG_LIST_DCN3_01(index, pllid) \ 113 + SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ 114 + SRII(PHASE, DP_DTO, 0),\ 115 + SRII(PHASE, DP_DTO, 1),\ 116 + SRII(PHASE, DP_DTO, 2),\ 117 + SRII(PHASE, DP_DTO, 3),\ 118 + SRII(MODULO, DP_DTO, 0),\ 119 + SRII(MODULO, DP_DTO, 1),\ 120 + SRII(MODULO, DP_DTO, 2),\ 121 + SRII(MODULO, DP_DTO, 3),\ 122 + SRII(PIXEL_RATE_CNTL, OTG, 0),\ 123 + SRII(PIXEL_RATE_CNTL, OTG, 1),\ 124 + SRII(PIXEL_RATE_CNTL, OTG, 2),\ 125 + SRII(PIXEL_RATE_CNTL, OTG, 3) 126 + #endif 127 + 111 128 #define CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\ 112 129 CS_SF(DP_DTO0_PHASE, DP_DTO0_PHASE, mask_sh),\ 113 130 CS_SF(DP_DTO0_MODULO, DP_DTO0_MODULO, mask_sh),\ ··· 249 232 const struct dce110_clk_src_mask *cs_mask); 250 233 #endif 251 234 235 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 236 + bool dcn301_clk_src_construct( 237 + struct dce110_clk_src *clk_src, 238 + struct dc_context *ctx, 239 + struct dc_bios *bios, 240 + enum clock_source_id id, 241 + const struct dce110_clk_src_regs *regs, 242 + const struct dce110_clk_src_shift *cs_shift, 243 + const struct dce110_clk_src_mask *cs_mask); 244 + #endif 245 + 252 246 /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ 253 247 struct pixel_rate_range_table_entry { 254 248 unsigned int range_min_khz; ··· 274 246 const struct pixel_rate_range_table_entry *look_up_in_video_optimized_rate_tlb( 275 247 unsigned int pixel_rate_khz); 276 248 #endif 249 + 277 250 #endif
+163 -28
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
··· 224 224 SR(VGA_TEST_CONTROL), \ 225 225 SR(DC_IP_REQUEST_CNTL) 226 226 227 - #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 228 - #define HWSEQ_DCN30_REG_LIST()\ 229 - HWSEQ_DCN2_REG_LIST(),\ 230 - HWSEQ_DCN_REG_LIST(), \ 231 - HWSEQ_PIXEL_RATE_REG_LIST_3(OTG), \ 232 - HWSEQ_PHYPLL_REG_LIST_3(OTG), \ 233 - SR(MICROSECOND_TIME_BASE_DIV), \ 234 - SR(MILLISECOND_TIME_BASE_DIV), \ 235 - SR(DISPCLK_FREQ_CHANGE_CNTL), \ 236 - SR(RBBMIF_TIMEOUT_DIS), \ 237 - SR(RBBMIF_TIMEOUT_DIS_2), \ 238 - SR(DCHUBBUB_CRC_CTRL), \ 239 - SR(DPP_TOP0_DPP_CRC_CTRL), \ 240 - SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ 241 - SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ 242 - SR(MPC_CRC_CTRL), \ 243 - SR(MPC_CRC_RESULT_GB), \ 244 - SR(MPC_CRC_RESULT_C), \ 245 - SR(MPC_CRC_RESULT_AR), \ 246 - SR(AZALIA_AUDIO_DTO), \ 247 - SR(AZALIA_CONTROLLER_CLOCK_GATING) 248 - #endif 249 227 #define HWSEQ_DCN2_REG_LIST()\ 250 228 HWSEQ_DCN_REG_LIST(), \ 251 229 HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \ ··· 338 360 SR(D5VGA_CONTROL), \ 339 361 SR(D6VGA_CONTROL), \ 340 362 SR(DC_IP_REQUEST_CNTL) 363 + 364 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 365 + #define HWSEQ_DCN30_REG_LIST()\ 366 + HWSEQ_DCN2_REG_LIST(),\ 367 + HWSEQ_DCN_REG_LIST(), \ 368 + HWSEQ_PIXEL_RATE_REG_LIST_3(OTG), \ 369 + HWSEQ_PHYPLL_REG_LIST_3(OTG), \ 370 + SR(MICROSECOND_TIME_BASE_DIV), \ 371 + SR(MILLISECOND_TIME_BASE_DIV), \ 372 + SR(DISPCLK_FREQ_CHANGE_CNTL), \ 373 + SR(RBBMIF_TIMEOUT_DIS), \ 374 + SR(RBBMIF_TIMEOUT_DIS_2), \ 375 + SR(DCHUBBUB_CRC_CTRL), \ 376 + SR(DPP_TOP0_DPP_CRC_CTRL), \ 377 + SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ 378 + SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ 379 + SR(MPC_CRC_CTRL), \ 380 + SR(MPC_CRC_RESULT_GB), \ 381 + SR(MPC_CRC_RESULT_C), \ 382 + SR(MPC_CRC_RESULT_AR), \ 383 + SR(AZALIA_AUDIO_DTO), \ 384 + SR(AZALIA_CONTROLLER_CLOCK_GATING) 385 + #endif 386 + 387 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 388 + #define HWSEQ_DCN301_REG_LIST()\ 389 + SR(REFCLK_CNTL), \ 390 + SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ 391 + SR(DIO_MEM_PWR_CTRL), \ 392 + SR(DCCG_GATE_DISABLE_CNTL), \ 393 + SR(DCCG_GATE_DISABLE_CNTL2), \ 394 + SR(DCFCLK_CNTL),\ 395 + SR(DCFCLK_CNTL), \ 396 + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ 397 + SRII(PIXEL_RATE_CNTL, OTG, 0), \ 398 + SRII(PIXEL_RATE_CNTL, OTG, 1),\ 399 + SRII(PIXEL_RATE_CNTL, OTG, 2),\ 400 + SRII(PIXEL_RATE_CNTL, OTG, 3),\ 401 + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 0),\ 402 + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 1),\ 403 + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 2),\ 404 + SRII(PHYPLL_PIXEL_RATE_CNTL, OTG, 3),\ 405 + SR(MICROSECOND_TIME_BASE_DIV), \ 406 + SR(MILLISECOND_TIME_BASE_DIV), \ 407 + SR(DISPCLK_FREQ_CHANGE_CNTL), \ 408 + SR(RBBMIF_TIMEOUT_DIS), \ 409 + SR(RBBMIF_TIMEOUT_DIS_2), \ 410 + SR(DCHUBBUB_CRC_CTRL), \ 411 + SR(DPP_TOP0_DPP_CRC_CTRL), \ 412 + SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ 413 + SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ 414 + SR(MPC_CRC_CTRL), \ 415 + SR(MPC_CRC_RESULT_GB), \ 416 + SR(MPC_CRC_RESULT_C), \ 417 + SR(MPC_CRC_RESULT_AR), \ 418 + SR(DOMAIN0_PG_CONFIG), \ 419 + SR(DOMAIN1_PG_CONFIG), \ 420 + SR(DOMAIN2_PG_CONFIG), \ 421 + SR(DOMAIN3_PG_CONFIG), \ 422 + SR(DOMAIN4_PG_CONFIG), \ 423 + SR(DOMAIN5_PG_CONFIG), \ 424 + SR(DOMAIN6_PG_CONFIG), \ 425 + SR(DOMAIN7_PG_CONFIG), \ 426 + SR(DOMAIN16_PG_CONFIG), \ 427 + SR(DOMAIN17_PG_CONFIG), \ 428 + SR(DOMAIN18_PG_CONFIG), \ 429 + SR(DOMAIN0_PG_STATUS), \ 430 + SR(DOMAIN1_PG_STATUS), \ 431 + SR(DOMAIN2_PG_STATUS), \ 432 + SR(DOMAIN3_PG_STATUS), \ 433 + SR(DOMAIN4_PG_STATUS), \ 434 + SR(DOMAIN5_PG_STATUS), \ 435 + SR(DOMAIN6_PG_STATUS), \ 436 + SR(DOMAIN7_PG_STATUS), \ 437 + SR(DOMAIN16_PG_STATUS), \ 438 + SR(DOMAIN17_PG_STATUS), \ 439 + SR(DOMAIN18_PG_STATUS), \ 440 + SR(D1VGA_CONTROL), \ 441 + SR(D2VGA_CONTROL), \ 442 + SR(D3VGA_CONTROL), \ 443 + SR(D4VGA_CONTROL), \ 444 + SR(D5VGA_CONTROL), \ 445 + SR(D6VGA_CONTROL), \ 446 + SR(DC_IP_REQUEST_CNTL), \ 447 + SR(AZALIA_AUDIO_DTO), \ 448 + SR(AZALIA_CONTROLLER_CLOCK_GATING) 449 + #endif 341 450 342 451 struct dce_hwseq_registers { 343 452 uint32_t DCFE_CLOCK_CONTROL[6]; ··· 663 598 HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ 664 599 HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh) 665 600 666 - #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 667 - #define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\ 668 - HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \ 669 - HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) 670 - #endif 671 - 672 601 #define HWSEQ_DCN2_MASK_SH_LIST(mask_sh)\ 673 602 HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ 674 603 HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ ··· 761 702 HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ 762 703 HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ 763 704 HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh) 705 + 706 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 707 + #define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\ 708 + HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \ 709 + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) 710 + #endif 711 + 712 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 713 + #define HWSEQ_DCN301_MASK_SH_LIST(mask_sh)\ 714 + HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ 715 + HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ 716 + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \ 717 + HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \ 718 + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \ 719 + HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \ 720 + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \ 721 + HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \ 722 + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \ 723 + HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \ 724 + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \ 725 + HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \ 726 + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \ 727 + HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \ 728 + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \ 729 + HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \ 730 + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \ 731 + HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \ 732 + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, mask_sh), \ 733 + HWS_SF(, DOMAIN16_PG_CONFIG, DOMAIN16_POWER_GATE, mask_sh), \ 734 + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, mask_sh), \ 735 + HWS_SF(, DOMAIN17_PG_CONFIG, DOMAIN17_POWER_GATE, mask_sh), \ 736 + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, mask_sh), \ 737 + HWS_SF(, DOMAIN18_PG_CONFIG, DOMAIN18_POWER_GATE, mask_sh), \ 738 + HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \ 739 + HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \ 740 + HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \ 741 + HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \ 742 + HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \ 743 + HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \ 744 + HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ 745 + HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ 746 + HWS_SF(, DOMAIN16_PG_STATUS, DOMAIN16_PGFSM_PWR_STATUS, mask_sh), \ 747 + HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ 748 + HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ 749 + HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ 750 + HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_BLON, mask_sh),\ 751 + HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON, mask_sh),\ 752 + HWS_SF(, PANEL_PWRSEQ0_CNTL, PANEL_DIGON_OVRD, mask_sh),\ 753 + HWS_SF(, PANEL_PWRSEQ0_STATE, PANEL_PWRSEQ_TARGET_STATE_R, mask_sh),\ 754 + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) 755 + #endif 764 756 765 757 #define HWSEQ_REG_FIELD_LIST(type) \ 766 758 type DCFE_CLOCK_ENABLE; \ ··· 927 817 type D4VGA_MODE_ENABLE; \ 928 818 type AZALIA_AUDIO_DTO_MODULE; 929 819 820 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 821 + #define HWSEQ_DCN3_REG_FIELD_LIST(type) \ 822 + type HPO_HDMISTREAMCLK_GATE_DIS; 823 + #endif 824 + 825 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 826 + #define HWSEQ_DCN301_REG_FIELD_LIST(type) \ 827 + type PANEL_BLON;\ 828 + type PANEL_DIGON;\ 829 + type PANEL_DIGON_OVRD;\ 830 + type PANEL_PWRSEQ_TARGET_STATE_R; 831 + #endif 832 + 930 833 struct dce_hwseq_shift { 931 834 HWSEQ_REG_FIELD_LIST(uint8_t) 932 835 HWSEQ_DCN_REG_FIELD_LIST(uint8_t) 836 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 837 + HWSEQ_DCN3_REG_FIELD_LIST(uint8_t) 838 + #endif 839 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 840 + HWSEQ_DCN301_REG_FIELD_LIST(uint8_t) 841 + #endif 933 842 }; 934 843 935 844 struct dce_hwseq_mask { 936 845 HWSEQ_REG_FIELD_LIST(uint32_t) 937 846 HWSEQ_DCN_REG_FIELD_LIST(uint32_t) 847 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 848 + HWSEQ_DCN3_REG_FIELD_LIST(uint32_t) 849 + #endif 850 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 851 + HWSEQ_DCN301_REG_FIELD_LIST(uint32_t) 852 + #endif 938 853 }; 939 854 940 855
+11
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
··· 384 384 DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value); 385 385 } 386 386 387 + void hubbub3_force_pstate_change_control(struct hubbub *hubbub, 388 + bool force, bool allow) 389 + { 390 + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 391 + 392 + REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 393 + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, allow, 394 + DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, force); 395 + } 396 + 387 397 static const struct hubbub_funcs hubbub30_funcs = { 388 398 .update_dchub = hubbub2_update_dchub, 389 399 .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx, ··· 407 397 .allow_self_refresh_control = hubbub1_allow_self_refresh_control, 408 398 .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, 409 399 .force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes, 400 + .force_pstate_change_control = hubbub3_force_pstate_change_control, 410 401 }; 411 402 412 403 void hubbub3_construct(struct dcn20_hubbub *hubbub3,
+3
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.h
··· 116 116 unsigned int refclk_mhz, 117 117 bool safe_to_lower); 118 118 119 + void hubbub3_force_pstate_change_control(struct hubbub *hubbub, 120 + bool force, bool allow); 121 + 119 122 #endif
+5
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h
··· 251 251 const struct dcn_hubp2_shift *hubp_shift, 252 252 const struct dcn_hubp2_mask *hubp_mask); 253 253 254 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 255 + void hubp3_set_vm_system_aperture_settings(struct hubp *hubp, 256 + struct vm_system_aperture_param *apt); 257 + #endif 258 + 254 259 bool hubp3_program_surface_flip_and_addr( 255 260 struct hubp *hubp, 256 261 const struct dc_plane_address *address,
+47
drivers/gpu/drm/amd/display/dc/dcn301/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 dcn30. 12 + 13 + DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \ 14 + dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o 15 + 16 + ifdef CONFIG_X86 17 + CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -msse 18 + endif 19 + 20 + ifdef CONFIG_PPC64 21 + CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec 22 + endif 23 + 24 + ifdef CONFIG_ARM64 25 + CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mgeneral-regs-only 26 + endif 27 + 28 + ifdef CONFIG_CC_IS_GCC 29 + ifeq ($(call cc-ifversion, -lt, 0701, y), y) 30 + IS_OLD_GCC = 1 31 + endif 32 + endif 33 + 34 + ifdef CONFIG_X86 35 + ifdef IS_OLD_GCC 36 + # Stack alignment mismatch, proceed with caution. 37 + # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 38 + # (8B stack alignment). 39 + CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mpreferred-stack-boundary=4 40 + else 41 + CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -msse2 42 + endif 43 + endif 44 + 45 + AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301)) 46 + 47 + AMD_DISPLAY_FILES += $(AMD_DAL_DCN301)
+75
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dccg.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 "reg_helper.h" 27 + #include "core_types.h" 28 + #include "dcn301_dccg.h" 29 + 30 + #define TO_DCN_DCCG(dccg)\ 31 + container_of(dccg, struct dcn_dccg, base) 32 + 33 + #define REG(reg) \ 34 + (dccg_dcn->regs->reg) 35 + 36 + #undef FN 37 + #define FN(reg_name, field_name) \ 38 + dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name 39 + 40 + #define CTX \ 41 + dccg_dcn->base.ctx 42 + #define DC_LOGGER \ 43 + dccg->ctx->logger 44 + 45 + static const struct dccg_funcs dccg301_funcs = { 46 + .update_dpp_dto = dccg2_update_dpp_dto, 47 + .get_dccg_ref_freq = dccg2_get_dccg_ref_freq, 48 + .dccg_init = dccg2_init 49 + }; 50 + 51 + struct dccg *dccg301_create( 52 + struct dc_context *ctx, 53 + const struct dccg_registers *regs, 54 + const struct dccg_shift *dccg_shift, 55 + const struct dccg_mask *dccg_mask) 56 + { 57 + struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); 58 + struct dccg *base; 59 + 60 + if (dccg_dcn == NULL) { 61 + BREAK_TO_DEBUGGER(); 62 + return NULL; 63 + } 64 + 65 + base = &dccg_dcn->base; 66 + base->ctx = ctx; 67 + base->funcs = &dccg301_funcs; 68 + 69 + dccg_dcn->regs = regs; 70 + dccg_dcn->dccg_shift = dccg_shift; 71 + dccg_dcn->dccg_mask = dccg_mask; 72 + 73 + return &dccg_dcn->base; 74 + } 75 +
+65
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_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 __DCN301_DCCG_H__ 27 + #define __DCN301_DCCG_H__ 28 + 29 + #include "dcn20/dcn20_dccg.h" 30 + 31 + #define DCCG_REG_LIST_DCN301() \ 32 + SR(DPPCLK_DTO_CTRL),\ 33 + DCCG_SRII(DTO_PARAM, DPPCLK, 0),\ 34 + DCCG_SRII(DTO_PARAM, DPPCLK, 1),\ 35 + DCCG_SRII(DTO_PARAM, DPPCLK, 2),\ 36 + DCCG_SRII(DTO_PARAM, DPPCLK, 3),\ 37 + SR(REFCLK_CNTL) 38 + 39 + #define DCCG_MASK_SH_LIST_DCN301(mask_sh) \ 40 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 0, mask_sh),\ 41 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 0, mask_sh),\ 42 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 1, mask_sh),\ 43 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 1, mask_sh),\ 44 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 2, mask_sh),\ 45 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 2, mask_sh),\ 46 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 3, mask_sh),\ 47 + DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 3, mask_sh),\ 48 + DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_PHASE, mask_sh),\ 49 + DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_MODULO, mask_sh),\ 50 + DCCG_SF(REFCLK_CNTL, REFCLK_CLOCK_EN, mask_sh),\ 51 + DCCG_SF(REFCLK_CNTL, REFCLK_SRC_SEL, mask_sh) 52 + 53 + struct dccg *dccg301_create( 54 + struct dc_context *ctx, 55 + const struct dccg_registers *regs, 56 + const struct dccg_shift *dccg_shift, 57 + const struct dccg_mask *dccg_mask); 58 + 59 + struct dccg *dccg301_create( 60 + struct dc_context *ctx, 61 + const struct dccg_registers *regs, 62 + const struct dccg_shift *dccg_shift, 63 + const struct dccg_mask *dccg_mask); 64 + 65 + #endif //__DCN301_DCCG_H__
+81
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.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 + #include "dm_services.h" 26 + #include "dcn301_hubbub.h" 27 + #include "reg_helper.h" 28 + 29 + #define REG(reg)\ 30 + hubbub1->regs->reg 31 + #define DC_LOGGER \ 32 + hubbub1->base.ctx->logger 33 + #define CTX \ 34 + hubbub1->base.ctx 35 + 36 + #undef FN 37 + #define FN(reg_name, field_name) \ 38 + hubbub1->shifts->field_name, hubbub1->masks->field_name 39 + 40 + #define REG(reg)\ 41 + hubbub1->regs->reg 42 + 43 + #define CTX \ 44 + hubbub1->base.ctx 45 + 46 + #undef FN 47 + #define FN(reg_name, field_name) \ 48 + hubbub1->shifts->field_name, hubbub1->masks->field_name 49 + 50 + 51 + static const struct hubbub_funcs hubbub301_funcs = { 52 + .update_dchub = hubbub2_update_dchub, 53 + .init_dchub_sys_ctx = hubbub21_init_dchub, 54 + .init_vm_ctx = hubbub2_init_vm_ctx, 55 + .dcc_support_swizzle = hubbub3_dcc_support_swizzle, 56 + .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, 57 + .get_dcc_compression_cap = hubbub3_get_dcc_compression_cap, 58 + .wm_read_state = hubbub21_wm_read_state, 59 + .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, 60 + .program_watermarks = hubbub3_program_watermarks, 61 + .allow_self_refresh_control = hubbub1_allow_self_refresh_control, 62 + .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, 63 + .force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes, 64 + .force_pstate_change_control = hubbub3_force_pstate_change_control, 65 + }; 66 + 67 + void hubbub301_construct(struct dcn20_hubbub *hubbub3, 68 + struct dc_context *ctx, 69 + const struct dcn_hubbub_registers *hubbub_regs, 70 + const struct dcn_hubbub_shift *hubbub_shift, 71 + const struct dcn_hubbub_mask *hubbub_mask) 72 + { 73 + hubbub3->base.ctx = ctx; 74 + hubbub3->base.funcs = &hubbub301_funcs; 75 + hubbub3->regs = hubbub_regs; 76 + hubbub3->shifts = hubbub_shift; 77 + hubbub3->masks = hubbub_mask; 78 + 79 + hubbub3->debug_test_index_pstate = 0xB; 80 + hubbub3->detile_buf_size = 184 * 1024; /* 184KB for DCN3 */ 81 + }
+60
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.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 + #ifndef DAL_DC_DCN301_DCN301_HUBBUB_H_ 26 + #define DAL_DC_DCN301_DCN301_HUBBUB_H_ 27 + 28 + #include "dcn30/dcn30_hubbub.h" 29 + 30 + 31 + #define HUBBUB_REG_LIST_DCN301(id)\ 32 + HUBBUB_REG_LIST_DCN30(id), \ 33 + HUBBUB_HVM_REG_LIST() 34 + 35 + 36 + #define HUBBUB_MASK_SH_LIST_DCN301(mask_sh)\ 37 + HUBBUB_MASK_SH_LIST_DCN30(mask_sh), \ 38 + HUBBUB_SF(DCHVM_CTRL0, HOSTVM_INIT_REQ, mask_sh), \ 39 + HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_PWR_REQ_DIS, mask_sh), \ 40 + HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_FORCE_REQ, mask_sh), \ 41 + HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_POWER_STATUS, mask_sh), \ 42 + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_R_GATE_DIS, mask_sh), \ 43 + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_G_GATE_DIS, mask_sh), \ 44 + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_R_GATE_DIS, mask_sh), \ 45 + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_G_GATE_DIS, mask_sh), \ 46 + HUBBUB_SF(DCHVM_CLK_CTRL, TR_REQ_REQCLKREQ_MODE, mask_sh), \ 47 + HUBBUB_SF(DCHVM_CLK_CTRL, TW_RSP_COMPCLKREQ_MODE, mask_sh), \ 48 + HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, mask_sh), \ 49 + HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, mask_sh), \ 50 + HUBBUB_SF(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, mask_sh), \ 51 + HUBBUB_SF(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, mask_sh) 52 + 53 + void hubbub301_construct(struct dcn20_hubbub *hubbub3, 54 + struct dc_context *ctx, 55 + const struct dcn_hubbub_registers *hubbub_regs, 56 + const struct dcn_hubbub_shift *hubbub_shift, 57 + const struct dcn_hubbub_mask *hubbub_mask); 58 + 59 + 60 + #endif /* DAL_DC_DCN301_DCN301_HUBBUB_H_ */
+42
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_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 "core_types.h" 27 + #include "dce/dce_hwseq.h" 28 + #include "dcn301_hwseq.h" 29 + #include "reg_helper.h" 30 + 31 + #define DC_LOGGER_INIT(logger) 32 + 33 + #define CTX \ 34 + hws->ctx 35 + #define REG(reg)\ 36 + hws->regs->reg 37 + 38 + #undef FN 39 + #define FN(reg_name, field_name) \ 40 + hws->shifts->field_name, hws->masks->field_name 41 + 42 +
+32
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_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_DCN301_H__ 27 + #define __DC_HWSS_DCN301_H__ 28 + 29 + #include "hw_sequencer_private.h" 30 + 31 + 32 + #endif /* __DC_HWSS_DCN301_H__ */
+145
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_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 "dce110/dce110_hw_sequencer.h" 27 + #include "dcn10/dcn10_hw_sequencer.h" 28 + #include "dcn20/dcn20_hwseq.h" 29 + #include "dcn21/dcn21_hwseq.h" 30 + #include "dcn30/dcn30_hwseq.h" 31 + #include "dcn301_hwseq.h" 32 + 33 + static const struct hw_sequencer_funcs dcn301_funcs = { 34 + .program_gamut_remap = dcn10_program_gamut_remap, 35 + .init_hw = dcn10_init_hw, 36 + .power_down_on_boot = dcn10_power_down_on_boot, 37 + .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 38 + .apply_ctx_for_surface = NULL, 39 + .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, 40 + .disconnect_pipes = dcn10_disconnect_pipes, 41 + .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, 42 + .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, 43 + .update_plane_addr = dcn20_update_plane_addr, 44 + .update_dchub = dcn10_update_dchub, 45 + .update_pending_status = dcn10_update_pending_status, 46 + .program_output_csc = dcn20_program_output_csc, 47 + .enable_accelerated_mode = dce110_enable_accelerated_mode, 48 + .enable_timing_synchronization = dcn10_enable_timing_synchronization, 49 + .enable_per_frame_crtc_position_reset = dcn10_enable_per_frame_crtc_position_reset, 50 + .update_info_frame = dcn30_update_info_frame, 51 + .send_immediate_sdp_message = dcn10_send_immediate_sdp_message, 52 + .enable_stream = dcn20_enable_stream, 53 + .disable_stream = dce110_disable_stream, 54 + .unblank_stream = dcn20_unblank_stream, 55 + #ifdef FREESYNC_POWER_OPTIMIZE 56 + .are_streams_coarse_grain_aligned = dcn20_are_streams_coarse_grain_aligned, 57 + #endif 58 + .blank_stream = dce110_blank_stream, 59 + .enable_audio_stream = dce110_enable_audio_stream, 60 + .disable_audio_stream = dce110_disable_audio_stream, 61 + .disable_plane = dcn20_disable_plane, 62 + .pipe_control_lock = dcn20_pipe_control_lock, 63 + .interdependent_update_lock = dcn10_lock_all_pipes, 64 + .cursor_lock = dcn10_cursor_lock, 65 + .prepare_bandwidth = dcn20_prepare_bandwidth, 66 + .optimize_bandwidth = dcn20_optimize_bandwidth, 67 + .update_bandwidth = dcn20_update_bandwidth, 68 + .set_drr = dcn10_set_drr, 69 + .get_position = dcn10_get_position, 70 + .set_static_screen_control = dcn10_set_static_screen_control, 71 + .setup_stereo = dcn10_setup_stereo, 72 + .set_avmute = dcn30_set_avmute, 73 + .log_hw_state = dcn10_log_hw_state, 74 + .get_hw_state = dcn10_get_hw_state, 75 + .clear_status_bits = dcn10_clear_status_bits, 76 + .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, 77 + .edp_power_control = dce110_edp_power_control, 78 + .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, 79 + .set_cursor_position = dcn10_set_cursor_position, 80 + .set_cursor_attribute = dcn10_set_cursor_attribute, 81 + .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, 82 + .setup_periodic_interrupt = dcn10_setup_periodic_interrupt, 83 + .set_clock = dcn10_set_clock, 84 + .get_clock = dcn10_get_clock, 85 + .program_triplebuffer = dcn20_program_triple_buffer, 86 + .enable_writeback = dcn30_enable_writeback, 87 + .disable_writeback = dcn30_disable_writeback, 88 + .update_writeback = dcn30_update_writeback, 89 + .mmhubbub_warmup = dcn30_mmhubbub_warmup, 90 + .dmdata_status_done = dcn20_dmdata_status_done, 91 + .program_dmdata_engine = dcn30_program_dmdata_engine, 92 + .set_dmdata_attributes = dcn20_set_dmdata_attributes, 93 + .init_sys_ctx = dcn20_init_sys_ctx, 94 + .init_vm_ctx = dcn20_init_vm_ctx, 95 + .set_flip_control_gsl = dcn20_set_flip_control_gsl, 96 + .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, 97 + .calc_vupdate_position = dcn10_calc_vupdate_position, 98 + .set_backlight_level = dcn21_set_backlight_level, 99 + .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, 100 + .set_pipe = dcn21_set_pipe, 101 + }; 102 + 103 + static const struct hwseq_private_funcs dcn301_private_funcs = { 104 + .init_pipes = dcn10_init_pipes, 105 + .update_plane_addr = dcn20_update_plane_addr, 106 + .plane_atomic_disconnect = dcn10_plane_atomic_disconnect, 107 + .update_mpcc = dcn20_update_mpcc, 108 + .set_input_transfer_func = dcn30_set_input_transfer_func, 109 + .set_output_transfer_func = dcn30_set_output_transfer_func, 110 + .power_down = dce110_power_down, 111 + .enable_display_power_gating = dcn10_dummy_display_power_gating, 112 + .blank_pixel_data = dcn20_blank_pixel_data, 113 + .reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap, 114 + .enable_stream_timing = dcn20_enable_stream_timing, 115 + .edp_backlight_control = dce110_edp_backlight_control, 116 + .disable_stream_gating = dcn20_disable_stream_gating, 117 + .enable_stream_gating = dcn20_enable_stream_gating, 118 + .setup_vupdate_interrupt = dcn20_setup_vupdate_interrupt, 119 + .did_underflow_occur = dcn10_did_underflow_occur, 120 + .init_blank = dcn20_init_blank, 121 + .disable_vga = dcn20_disable_vga, 122 + .bios_golden_init = dcn10_bios_golden_init, 123 + .plane_atomic_disable = dcn20_plane_atomic_disable, 124 + .plane_atomic_power_down = dcn10_plane_atomic_power_down, 125 + .enable_power_gating_plane = dcn20_enable_power_gating_plane, 126 + .dpp_pg_control = dcn20_dpp_pg_control, 127 + .hubp_pg_control = dcn20_hubp_pg_control, 128 + .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, 129 + .update_odm = dcn20_update_odm, 130 + .dsc_pg_control = dcn20_dsc_pg_control, 131 + .get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color, 132 + .get_hdr_visual_confirm_color = dcn10_get_hdr_visual_confirm_color, 133 + .set_hdr_multiplier = dcn10_set_hdr_multiplier, 134 + .verify_allow_pstate_change_high = dcn10_verify_allow_pstate_change_high, 135 + .wait_for_blank_complete = dcn20_wait_for_blank_complete, 136 + .dccg_init = dcn20_dccg_init, 137 + .set_blend_lut = dcn30_set_blend_lut, 138 + .set_shaper_3dlut = dcn20_set_shaper_3dlut, 139 + }; 140 + 141 + void dcn301_hw_sequencer_construct(struct dc *dc) 142 + { 143 + dc->hwss = dcn301_funcs; 144 + dc->hwseq->funcs = dcn301_private_funcs; 145 + }
+33
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_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_DCN30_INIT_H__ 27 + #define __DC_DCN30_INIT_H__ 28 + 29 + struct dc; 30 + 31 + void dcn301_hw_sequencer_construct(struct dc *dc); 32 + 33 + #endif /* __DC_DCN30_INIT_H__ */
+218
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.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 "reg_helper.h" 27 + #include "core_types.h" 28 + #include "dc_dmub_srv.h" 29 + #include "dcn301_panel_cntl.h" 30 + #include "atom.h" 31 + 32 + #define TO_DCN301_PANEL_CNTL(panel_cntl)\ 33 + container_of(panel_cntl, struct dcn301_panel_cntl, base) 34 + 35 + #define CTX \ 36 + dcn301_panel_cntl->base.ctx 37 + 38 + #define DC_LOGGER \ 39 + dcn301_panel_cntl->base.ctx->logger 40 + 41 + #define REG(reg)\ 42 + dcn301_panel_cntl->regs->reg 43 + 44 + #undef FN 45 + #define FN(reg_name, field_name) \ 46 + dcn301_panel_cntl->shift->field_name, dcn301_panel_cntl->mask->field_name 47 + 48 + static unsigned int dcn301_get_16_bit_backlight_from_pwm(struct panel_cntl *panel_cntl) 49 + { 50 + uint64_t current_backlight; 51 + uint32_t round_result; 52 + uint32_t bl_period, bl_int_count; 53 + uint32_t bl_pwm, fractional_duty_cycle_en; 54 + uint32_t bl_period_mask, bl_pwm_mask; 55 + struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); 56 + 57 + REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period); 58 + REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count); 59 + 60 + REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &bl_pwm); 61 + REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en); 62 + 63 + if (bl_int_count == 0) 64 + bl_int_count = 16; 65 + 66 + bl_period_mask = (1 << bl_int_count) - 1; 67 + bl_period &= bl_period_mask; 68 + 69 + bl_pwm_mask = bl_period_mask << (16 - bl_int_count); 70 + 71 + if (fractional_duty_cycle_en == 0) 72 + bl_pwm &= bl_pwm_mask; 73 + else 74 + bl_pwm &= 0xFFFF; 75 + 76 + current_backlight = (uint64_t)bl_pwm << (1 + bl_int_count); 77 + 78 + if (bl_period == 0) 79 + bl_period = 0xFFFF; 80 + 81 + current_backlight = div_u64(current_backlight, bl_period); 82 + current_backlight = (current_backlight + 1) >> 1; 83 + 84 + current_backlight = (uint64_t)(current_backlight) * bl_period; 85 + 86 + round_result = (uint32_t)(current_backlight & 0xFFFFFFFF); 87 + 88 + round_result = (round_result >> (bl_int_count-1)) & 1; 89 + 90 + current_backlight >>= bl_int_count; 91 + current_backlight += round_result; 92 + 93 + return (uint32_t)(current_backlight); 94 + } 95 + 96 + uint32_t dcn301_panel_cntl_hw_init(struct panel_cntl *panel_cntl) 97 + { 98 + struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); 99 + uint32_t value; 100 + uint32_t current_backlight; 101 + 102 + /* It must not be 0, so we have to restore them 103 + * Bios bug w/a - period resets to zero, 104 + * restoring to cache values which is always correct 105 + */ 106 + REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value); 107 + 108 + if (value == 0 || value == 1) { 109 + if (panel_cntl->stored_backlight_registers.BL_PWM_CNTL != 0) { 110 + REG_WRITE(BL_PWM_CNTL, 111 + panel_cntl->stored_backlight_registers.BL_PWM_CNTL); 112 + REG_WRITE(BL_PWM_CNTL2, 113 + panel_cntl->stored_backlight_registers.BL_PWM_CNTL2); 114 + REG_WRITE(BL_PWM_PERIOD_CNTL, 115 + panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL); 116 + REG_UPDATE(PWRSEQ_REF_DIV, 117 + BL_PWM_REF_DIV, 118 + panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV); 119 + } else { 120 + /* TODO: Note: This should not really happen since VBIOS 121 + * should have initialized PWM registers on boot. 122 + */ 123 + REG_WRITE(BL_PWM_CNTL, 0xC000FA00); 124 + REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0); 125 + } 126 + } else { 127 + panel_cntl->stored_backlight_registers.BL_PWM_CNTL = 128 + REG_READ(BL_PWM_CNTL); 129 + panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 = 130 + REG_READ(BL_PWM_CNTL2); 131 + panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 132 + REG_READ(BL_PWM_PERIOD_CNTL); 133 + 134 + REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV, 135 + &panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV); 136 + } 137 + 138 + // Enable the backlight output 139 + REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1); 140 + 141 + // Unlock group 2 backlight registers 142 + REG_UPDATE(BL_PWM_GRP1_REG_LOCK, 143 + BL_PWM_GRP1_REG_LOCK, 0); 144 + 145 + current_backlight = dcn301_get_16_bit_backlight_from_pwm(panel_cntl); 146 + 147 + return current_backlight; 148 + } 149 + 150 + void dcn301_panel_cntl_destroy(struct panel_cntl **panel_cntl) 151 + { 152 + struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(*panel_cntl); 153 + 154 + kfree(dcn301_panel_cntl); 155 + *panel_cntl = NULL; 156 + } 157 + 158 + bool dcn301_is_panel_backlight_on(struct panel_cntl *panel_cntl) 159 + { 160 + struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); 161 + uint32_t value; 162 + 163 + REG_GET(PWRSEQ_CNTL, PANEL_BLON, &value); 164 + 165 + return value; 166 + } 167 + 168 + bool dcn301_is_panel_powered_on(struct panel_cntl *panel_cntl) 169 + { 170 + struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); 171 + uint32_t pwr_seq_state, dig_on, dig_on_ovrd; 172 + 173 + REG_GET(PWRSEQ_STATE, PANEL_PWRSEQ_TARGET_STATE_R, &pwr_seq_state); 174 + 175 + REG_GET_2(PWRSEQ_CNTL, PANEL_DIGON, &dig_on, PANEL_DIGON_OVRD, &dig_on_ovrd); 176 + 177 + return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1); 178 + } 179 + 180 + void dcn301_store_backlight_level(struct panel_cntl *panel_cntl) 181 + { 182 + struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); 183 + 184 + panel_cntl->stored_backlight_registers.BL_PWM_CNTL = 185 + REG_READ(BL_PWM_CNTL); 186 + panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 = 187 + REG_READ(BL_PWM_CNTL2); 188 + panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 189 + REG_READ(BL_PWM_PERIOD_CNTL); 190 + 191 + REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV, 192 + &panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV); 193 + } 194 + 195 + static const struct panel_cntl_funcs dcn301_link_panel_cntl_funcs = { 196 + .destroy = dcn301_panel_cntl_destroy, 197 + .hw_init = dcn301_panel_cntl_hw_init, 198 + .is_panel_backlight_on = dcn301_is_panel_backlight_on, 199 + .is_panel_powered_on = dcn301_is_panel_powered_on, 200 + .store_backlight_level = dcn301_store_backlight_level, 201 + .get_current_backlight = dcn301_get_16_bit_backlight_from_pwm, 202 + }; 203 + 204 + void dcn301_panel_cntl_construct( 205 + struct dcn301_panel_cntl *dcn301_panel_cntl, 206 + const struct panel_cntl_init_data *init_data, 207 + const struct dce_panel_cntl_registers *regs, 208 + const struct dcn301_panel_cntl_shift *shift, 209 + const struct dcn301_panel_cntl_mask *mask) 210 + { 211 + dcn301_panel_cntl->regs = regs; 212 + dcn301_panel_cntl->shift = shift; 213 + dcn301_panel_cntl->mask = mask; 214 + 215 + dcn301_panel_cntl->base.funcs = &dcn301_link_panel_cntl_funcs; 216 + dcn301_panel_cntl->base.ctx = init_data->ctx; 217 + dcn301_panel_cntl->base.inst = init_data->inst; 218 + }
+97
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.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_PANEL_CNTL__DCN301_H__ 27 + #define __DC_PANEL_CNTL__DCN301_H__ 28 + 29 + #include "panel_cntl.h" 30 + #include "dce/dce_panel_cntl.h" 31 + 32 + 33 + #define DCN301_PANEL_CNTL_REG_LIST(id)\ 34 + SRIR(PWRSEQ_CNTL, CNTL, PANEL_PWRSEQ, id), \ 35 + SRIR(PWRSEQ_STATE, STATE, PANEL_PWRSEQ, id), \ 36 + SRIR(PWRSEQ_REF_DIV, REF_DIV, PANEL_PWRSEQ, id), \ 37 + SRIR(BL_PWM_CNTL, CNTL, BL_PWM, id), \ 38 + SRIR(BL_PWM_CNTL2, CNTL2, BL_PWM, id), \ 39 + SRIR(BL_PWM_PERIOD_CNTL, PERIOD_CNTL, BL_PWM, id), \ 40 + SRIR(BL_PWM_GRP1_REG_LOCK, GRP1_REG_LOCK, BL_PWM, id) 41 + 42 + #define DCN301_PANEL_CNTL_SF(reg_name, field_name, post_fix)\ 43 + .field_name = reg_name ## __ ## field_name ## post_fix 44 + 45 + #define DCN301_PANEL_CNTL_MASK_SH_LIST(mask_sh) \ 46 + DCN301_PANEL_CNTL_SF(PANEL_PWRSEQ0_CNTL, PANEL_BLON, mask_sh),\ 47 + DCN301_PANEL_CNTL_SF(PANEL_PWRSEQ0_CNTL, PANEL_DIGON, mask_sh),\ 48 + DCN301_PANEL_CNTL_SF(PANEL_PWRSEQ0_CNTL, PANEL_DIGON_OVRD, mask_sh),\ 49 + DCN301_PANEL_CNTL_SF(PANEL_PWRSEQ0_STATE, PANEL_PWRSEQ_TARGET_STATE_R, mask_sh), \ 50 + DCN301_PANEL_CNTL_SF(PANEL_PWRSEQ0_REF_DIV, BL_PWM_REF_DIV, mask_sh), \ 51 + DCN301_PANEL_CNTL_SF(BL_PWM0_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \ 52 + DCN301_PANEL_CNTL_SF(BL_PWM0_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \ 53 + DCN301_PANEL_CNTL_SF(BL_PWM0_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \ 54 + DCN301_PANEL_CNTL_SF(BL_PWM0_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \ 55 + DCN301_PANEL_CNTL_SF(BL_PWM0_CNTL, BL_PWM_EN, mask_sh), \ 56 + DCN301_PANEL_CNTL_SF(BL_PWM0_GRP1_REG_LOCK, BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, mask_sh), \ 57 + DCN301_PANEL_CNTL_SF(BL_PWM0_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, mask_sh), \ 58 + DCN301_PANEL_CNTL_SF(BL_PWM0_GRP1_REG_LOCK, BL_PWM_GRP1_REG_UPDATE_PENDING, mask_sh) 59 + 60 + #define DCN301_PANEL_CNTL_REG_FIELD_LIST(type) \ 61 + type PANEL_BLON;\ 62 + type PANEL_DIGON;\ 63 + type PANEL_DIGON_OVRD;\ 64 + type PANEL_PWRSEQ_TARGET_STATE_R; \ 65 + type BL_PWM_EN; \ 66 + type BL_ACTIVE_INT_FRAC_CNT; \ 67 + type BL_PWM_FRACTIONAL_EN; \ 68 + type BL_PWM_PERIOD; \ 69 + type BL_PWM_PERIOD_BITCNT; \ 70 + type BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN; \ 71 + type BL_PWM_GRP1_REG_LOCK; \ 72 + type BL_PWM_GRP1_REG_UPDATE_PENDING; \ 73 + type BL_PWM_REF_DIV 74 + 75 + struct dcn301_panel_cntl_shift { 76 + DCN301_PANEL_CNTL_REG_FIELD_LIST(uint8_t); 77 + }; 78 + 79 + struct dcn301_panel_cntl_mask { 80 + DCN301_PANEL_CNTL_REG_FIELD_LIST(uint32_t); 81 + }; 82 + 83 + struct dcn301_panel_cntl { 84 + struct panel_cntl base; 85 + const struct dce_panel_cntl_registers *regs; 86 + const struct dcn301_panel_cntl_shift *shift; 87 + const struct dcn301_panel_cntl_mask *mask; 88 + }; 89 + 90 + void dcn301_panel_cntl_construct( 91 + struct dcn301_panel_cntl *panel_cntl, 92 + const struct panel_cntl_init_data *init_data, 93 + const struct dce_panel_cntl_registers *regs, 94 + const struct dcn301_panel_cntl_shift *shift, 95 + const struct dcn301_panel_cntl_mask *mask); 96 + 97 + #endif /* __DC_PANEL_CNTL__DCN301_H__ */
+2011
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_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 + 27 + #include "dm_services.h" 28 + #include "dc.h" 29 + 30 + #include "dcn301_init.h" 31 + 32 + #include "resource.h" 33 + #include "include/irq_service_interface.h" 34 + #include "dcn30/dcn30_resource.h" 35 + #include "dcn301_resource.h" 36 + 37 + #include "dcn20/dcn20_resource.h" 38 + 39 + #include "dcn10/dcn10_ipp.h" 40 + #include "dcn301/dcn301_hubbub.h" 41 + #include "dcn30/dcn30_mpc.h" 42 + #include "dcn30/dcn30_hubp.h" 43 + #include "irq/dcn30/irq_service_dcn30.h" 44 + #include "dcn30/dcn30_dpp.h" 45 + #include "dcn30/dcn30_optc.h" 46 + #include "dcn20/dcn20_hwseq.h" 47 + #include "dcn30/dcn30_hwseq.h" 48 + #include "dce110/dce110_hw_sequencer.h" 49 + #include "dcn30/dcn30_opp.h" 50 + #include "dcn20/dcn20_dsc.h" 51 + #include "dcn30/dcn30_vpg.h" 52 + #include "dcn30/dcn30_afmt.h" 53 + #include "dce/dce_clock_source.h" 54 + #include "dce/dce_audio.h" 55 + #include "dce/dce_hwseq.h" 56 + #include "clk_mgr.h" 57 + #include "virtual/virtual_stream_encoder.h" 58 + #include "dce110/dce110_resource.h" 59 + #include "dml/display_mode_vba.h" 60 + #include "dcn301/dcn301_dccg.h" 61 + #include "dcn10/dcn10_resource.h" 62 + #include "dcn30/dcn30_dio_stream_encoder.h" 63 + #include "dcn301/dcn301_dio_link_encoder.h" 64 + #include "dcn301_panel_cntl.h" 65 + 66 + #include "vangogh_ip_offset.h" 67 + 68 + #include "dcn30/dcn30_dwb.h" 69 + #include "dcn30/dcn30_mmhubbub.h" 70 + 71 + #include "dcn/dcn_3_0_1_offset.h" 72 + #include "dcn/dcn_3_0_1_sh_mask.h" 73 + 74 + #include "nbio/nbio_7_2_0_offset.h" 75 + 76 + #include "reg_helper.h" 77 + #include "dce/dmub_abm.h" 78 + #include "dce/dce_aux.h" 79 + #include "dce/dce_i2c.h" 80 + 81 + #include "dml/dcn30/display_mode_vba_30.h" 82 + #include "vm_helper.h" 83 + #include "dcn20/dcn20_vmid.h" 84 + #include "amdgpu_socbb.h" 85 + 86 + #define TO_DCN301_RES_POOL(pool)\ 87 + container_of(pool, struct dcn301_resource_pool, base) 88 + 89 + #define DC_LOGGER_INIT(logger) 90 + 91 + struct _vcs_dpi_ip_params_st dcn3_01_ip = { 92 + .odm_capable = 1, 93 + .gpuvm_enable = 1, 94 + .hostvm_enable = 1, 95 + .gpuvm_max_page_table_levels = 1, 96 + .hostvm_max_page_table_levels = 2, 97 + .hostvm_cached_page_table_levels = 0, 98 + .pte_group_size_bytes = 2048, 99 + .num_dsc = 3, 100 + .rob_buffer_size_kbytes = 184, 101 + .det_buffer_size_kbytes = 184, 102 + .dpte_buffer_size_in_pte_reqs_luma = 64, 103 + .dpte_buffer_size_in_pte_reqs_chroma = 32, 104 + .pde_proc_buffer_size_64k_reqs = 48, 105 + .dpp_output_buffer_pixels = 2560, 106 + .opp_output_buffer_lines = 1, 107 + .pixel_chunk_size_kbytes = 8, 108 + .meta_chunk_size_kbytes = 2, 109 + .writeback_chunk_size_kbytes = 8, 110 + .line_buffer_size_bits = 789504, 111 + .is_line_buffer_bpp_fixed = 0, // ? 112 + .line_buffer_fixed_bpp = 48, // ? 113 + .dcc_supported = true, 114 + .writeback_interface_buffer_size_kbytes = 90, 115 + .writeback_line_buffer_buffer_size = 656640, 116 + .max_line_buffer_lines = 12, 117 + .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 118 + .writeback_chroma_buffer_size_kbytes = 8, 119 + .writeback_chroma_line_buffer_width_pixels = 4, 120 + .writeback_max_hscl_ratio = 1, 121 + .writeback_max_vscl_ratio = 1, 122 + .writeback_min_hscl_ratio = 1, 123 + .writeback_min_vscl_ratio = 1, 124 + .writeback_max_hscl_taps = 1, 125 + .writeback_max_vscl_taps = 1, 126 + .writeback_line_buffer_luma_buffer_size = 0, 127 + .writeback_line_buffer_chroma_buffer_size = 14643, 128 + .cursor_buffer_size = 8, 129 + .cursor_chunk_size = 2, 130 + .max_num_otg = 4, 131 + .max_num_dpp = 4, 132 + .max_num_wb = 1, 133 + .max_dchub_pscl_bw_pix_per_clk = 4, 134 + .max_pscl_lb_bw_pix_per_clk = 2, 135 + .max_lb_vscl_bw_pix_per_clk = 4, 136 + .max_vscl_hscl_bw_pix_per_clk = 4, 137 + .max_hscl_ratio = 6, 138 + .max_vscl_ratio = 6, 139 + .hscl_mults = 4, 140 + .vscl_mults = 4, 141 + .max_hscl_taps = 8, 142 + .max_vscl_taps = 8, 143 + .dispclk_ramp_margin_percent = 1, 144 + .underscan_factor = 1.11, 145 + .min_vblank_lines = 32, 146 + .dppclk_delay_subtotal = 46, 147 + .dynamic_metadata_vm_enabled = true, 148 + .dppclk_delay_scl_lb_only = 16, 149 + .dppclk_delay_scl = 50, 150 + .dppclk_delay_cnvc_formatter = 27, 151 + .dppclk_delay_cnvc_cursor = 6, 152 + .dispclk_delay_subtotal = 119, 153 + .dcfclk_cstate_latency = 5.2, // SRExitTime 154 + .max_inter_dcn_tile_repeaters = 8, 155 + .max_num_hdmi_frl_outputs = 0, 156 + .odm_combine_4to1_supported = true, 157 + 158 + .xfc_supported = false, 159 + .xfc_fill_bw_overhead_percent = 10.0, 160 + .xfc_fill_constant_bytes = 0, 161 + .gfx7_compat_tiling_supported = 0, 162 + .number_of_cursors = 1, 163 + }; 164 + 165 + struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = { 166 + .clock_limits = { 167 + /*TODO: fill out defaults once wm plociy is settled*/ 168 + { 169 + .state = 0, 170 + .dcfclk_mhz = 810.0, 171 + .fabricclk_mhz = 1200.0, 172 + .dispclk_mhz = 1015.0, 173 + .dppclk_mhz = 1015.0, 174 + .phyclk_mhz = 810.0, 175 + .socclk_mhz = 1000.0, 176 + .dscclk_mhz = 338.0, 177 + .dram_speed_mts = 4266.0, 178 + }, 179 + { 180 + .state = 1, 181 + .dcfclk_mhz = 810.0, 182 + .fabricclk_mhz = 1200.0, 183 + .dispclk_mhz = 1015.0, 184 + .dppclk_mhz = 1015.0, 185 + .phyclk_mhz = 810.0, 186 + .socclk_mhz = 1000.0, 187 + .dscclk_mhz = 338.0, 188 + .dram_speed_mts = 4266.0, 189 + } 190 + }, 191 + 192 + .sr_exit_time_us = 9.0, 193 + .sr_enter_plus_exit_time_us = 11.0, 194 + .urgent_latency_us = 4.0, 195 + .urgent_latency_pixel_data_only_us = 4.0, 196 + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, 197 + .urgent_latency_vm_data_only_us = 4.0, 198 + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, 199 + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, 200 + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, 201 + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, 202 + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0, 203 + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, 204 + .max_avg_sdp_bw_use_normal_percent = 60.0, 205 + .max_avg_dram_bw_use_normal_percent = 60.0, 206 + .writeback_latency_us = 12.0, 207 + .max_request_size_bytes = 256, 208 + .dram_channel_width_bytes = 4, 209 + .fabric_datapath_to_dcn_data_return_bytes = 32, 210 + .dcn_downspread_percent = 0.5, 211 + .downspread_percent = 0.38, 212 + .dram_page_open_time_ns = 50.0, 213 + .dram_rw_turnaround_time_ns = 17.5, 214 + .dram_return_buffer_per_channel_bytes = 8192, 215 + .round_trip_ping_latency_dcfclk_cycles = 191, 216 + .urgent_out_of_order_return_per_channel_bytes = 4096, 217 + .channel_interleave_bytes = 256, 218 + .num_banks = 8, 219 + .num_chans = 4, 220 + .gpuvm_min_page_size_bytes = 4096, 221 + .hostvm_min_page_size_bytes = 4096, 222 + .dram_clock_change_latency_us = 23.84, 223 + .writeback_dram_clock_change_latency_us = 23.0, 224 + .return_bus_width_bytes = 64, 225 + .dispclk_dppclk_vco_speed_mhz = 3550, 226 + .xfc_bus_transport_time_us = 20, // ? 227 + .xfc_xbuf_latency_tolerance_us = 4, // ? 228 + .use_urgent_burst_bw = 1, // ? 229 + .num_states = 2, 230 + .do_urgent_latency_adjustment = false, 231 + .urgent_latency_adjustment_fabric_clock_component_us = 0, 232 + .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, 233 + }; 234 + 235 + enum dcn301_clk_src_array_id { 236 + DCN301_CLK_SRC_PLL0, 237 + DCN301_CLK_SRC_PLL1, 238 + DCN301_CLK_SRC_PLL2, 239 + DCN301_CLK_SRC_PLL3, 240 + DCN301_CLK_SRC_TOTAL 241 + }; 242 + 243 + /* begin ********************* 244 + * macros to expend register list macro defined in HW object header file 245 + */ 246 + 247 + /* DCN */ 248 + /* TODO awful hack. fixup dcn20_dwb.h */ 249 + #undef BASE_INNER 250 + #define BASE_INNER(seg) DCN_BASE__INST0_SEG ## seg 251 + 252 + #define BASE(seg) BASE_INNER(seg) 253 + 254 + #define SR(reg_name)\ 255 + .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \ 256 + mm ## reg_name 257 + 258 + #define SRI(reg_name, block, id)\ 259 + .reg_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 260 + mm ## block ## id ## _ ## reg_name 261 + 262 + #define SRI2(reg_name, block, id)\ 263 + .reg_name = BASE(mm ## reg_name ## _BASE_IDX) + \ 264 + mm ## reg_name 265 + 266 + #define SRIR(var_name, reg_name, block, id)\ 267 + .var_name = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 268 + mm ## block ## id ## _ ## reg_name 269 + 270 + #define SRII(reg_name, block, id)\ 271 + .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 272 + mm ## block ## id ## _ ## reg_name 273 + 274 + #define SRII2(reg_name_pre, reg_name_post, id)\ 275 + .reg_name_pre ## _ ## reg_name_post[id] = BASE(mm ## reg_name_pre \ 276 + ## id ## _ ## reg_name_post ## _BASE_IDX) + \ 277 + mm ## reg_name_pre ## id ## _ ## reg_name_post 278 + 279 + #define SRII_MPC_RMU(reg_name, block, id)\ 280 + .RMU##_##reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 281 + mm ## block ## id ## _ ## reg_name 282 + 283 + #define SRII_DWB(reg_name, temp_name, block, id)\ 284 + .reg_name[id] = BASE(mm ## block ## id ## _ ## temp_name ## _BASE_IDX) + \ 285 + mm ## block ## id ## _ ## temp_name 286 + 287 + #define DCCG_SRII(reg_name, block, id)\ 288 + .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ 289 + mm ## block ## id ## _ ## reg_name 290 + 291 + #define VUPDATE_SRII(reg_name, block, id)\ 292 + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ 293 + mm ## reg_name ## _ ## block ## id 294 + 295 + /* NBIO */ 296 + #define NBIO_BASE_INNER(seg) \ 297 + NBIO_BASE__INST0_SEG ## seg 298 + 299 + #define NBIO_BASE(seg) \ 300 + NBIO_BASE_INNER(seg) 301 + 302 + #define NBIO_SR(reg_name)\ 303 + .reg_name = NBIO_BASE(regBIF_BX0_ ## reg_name ## _BASE_IDX) + \ 304 + regBIF_BX0_ ## reg_name 305 + 306 + /* MMHUB */ 307 + #define MMHUB_BASE_INNER(seg) \ 308 + MMHUB_BASE__INST0_SEG ## seg 309 + 310 + #define MMHUB_BASE(seg) \ 311 + MMHUB_BASE_INNER(seg) 312 + 313 + #define MMHUB_SR(reg_name)\ 314 + .reg_name = MMHUB_BASE(regMM ## reg_name ## _BASE_IDX) + \ 315 + regMM ## reg_name 316 + 317 + /* CLOCK */ 318 + #define CLK_BASE_INNER(seg) \ 319 + CLK_BASE__INST0_SEG ## seg 320 + 321 + #define CLK_BASE(seg) \ 322 + CLK_BASE_INNER(seg) 323 + 324 + #define CLK_SRI(reg_name, block, inst)\ 325 + .reg_name = CLK_BASE(mm ## block ## _ ## inst ## _ ## reg_name ## _BASE_IDX) + \ 326 + mm ## block ## _ ## inst ## _ ## reg_name 327 + 328 + static const struct bios_registers bios_regs = { 329 + NBIO_SR(BIOS_SCRATCH_3), 330 + NBIO_SR(BIOS_SCRATCH_6) 331 + }; 332 + 333 + #define clk_src_regs(index, pllid)\ 334 + [index] = {\ 335 + CS_COMMON_REG_LIST_DCN3_01(index, pllid),\ 336 + } 337 + 338 + static const struct dce110_clk_src_regs clk_src_regs[] = { 339 + clk_src_regs(0, A), 340 + clk_src_regs(1, B), 341 + clk_src_regs(2, C), 342 + clk_src_regs(3, D) 343 + }; 344 + 345 + static const struct dce110_clk_src_shift cs_shift = { 346 + CS_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT) 347 + }; 348 + 349 + static const struct dce110_clk_src_mask cs_mask = { 350 + CS_COMMON_MASK_SH_LIST_DCN2_0(_MASK) 351 + }; 352 + 353 + #define abm_regs(id)\ 354 + [id] = {\ 355 + ABM_DCN301_REG_LIST(id)\ 356 + } 357 + 358 + static const struct dce_abm_registers abm_regs[] = { 359 + abm_regs(0), 360 + abm_regs(1), 361 + abm_regs(2), 362 + abm_regs(3), 363 + }; 364 + 365 + static const struct dce_abm_shift abm_shift = { 366 + ABM_MASK_SH_LIST_DCN301(__SHIFT) 367 + }; 368 + 369 + static const struct dce_abm_mask abm_mask = { 370 + ABM_MASK_SH_LIST_DCN301(_MASK) 371 + }; 372 + 373 + #define audio_regs(id)\ 374 + [id] = {\ 375 + AUD_COMMON_REG_LIST(id)\ 376 + } 377 + 378 + static const struct dce_audio_registers audio_regs[] = { 379 + audio_regs(0), 380 + audio_regs(1), 381 + audio_regs(2), 382 + audio_regs(3), 383 + audio_regs(4), 384 + audio_regs(5), 385 + audio_regs(6) 386 + }; 387 + 388 + #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ 389 + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\ 390 + SF(AZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh),\ 391 + AUD_COMMON_MASK_SH_LIST_BASE(mask_sh) 392 + 393 + static const struct dce_audio_shift audio_shift = { 394 + DCE120_AUD_COMMON_MASK_SH_LIST(__SHIFT) 395 + }; 396 + 397 + static const struct dce_audio_mask audio_mask = { 398 + DCE120_AUD_COMMON_MASK_SH_LIST(_MASK) 399 + }; 400 + 401 + #define vpg_regs(id)\ 402 + [id] = {\ 403 + VPG_DCN3_REG_LIST(id)\ 404 + } 405 + 406 + static const struct dcn30_vpg_registers vpg_regs[] = { 407 + vpg_regs(0), 408 + vpg_regs(1), 409 + vpg_regs(2), 410 + vpg_regs(3), 411 + }; 412 + 413 + static const struct dcn30_vpg_shift vpg_shift = { 414 + DCN3_VPG_MASK_SH_LIST(__SHIFT) 415 + }; 416 + 417 + static const struct dcn30_vpg_mask vpg_mask = { 418 + DCN3_VPG_MASK_SH_LIST(_MASK) 419 + }; 420 + 421 + #define afmt_regs(id)\ 422 + [id] = {\ 423 + AFMT_DCN3_REG_LIST(id)\ 424 + } 425 + 426 + static const struct dcn30_afmt_registers afmt_regs[] = { 427 + afmt_regs(0), 428 + afmt_regs(1), 429 + afmt_regs(2), 430 + afmt_regs(3), 431 + }; 432 + 433 + static const struct dcn30_afmt_shift afmt_shift = { 434 + DCN3_AFMT_MASK_SH_LIST(__SHIFT) 435 + }; 436 + 437 + static const struct dcn30_afmt_mask afmt_mask = { 438 + DCN3_AFMT_MASK_SH_LIST(_MASK) 439 + }; 440 + 441 + #define stream_enc_regs(id)\ 442 + [id] = {\ 443 + SE_DCN3_REG_LIST(id)\ 444 + } 445 + 446 + static const struct dcn10_stream_enc_registers stream_enc_regs[] = { 447 + stream_enc_regs(0), 448 + stream_enc_regs(1), 449 + stream_enc_regs(2), 450 + stream_enc_regs(3), 451 + }; 452 + 453 + static const struct dcn10_stream_encoder_shift se_shift = { 454 + SE_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 455 + }; 456 + 457 + static const struct dcn10_stream_encoder_mask se_mask = { 458 + SE_COMMON_MASK_SH_LIST_DCN30(_MASK) 459 + }; 460 + 461 + 462 + #define aux_regs(id)\ 463 + [id] = {\ 464 + DCN2_AUX_REG_LIST(id)\ 465 + } 466 + 467 + static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { 468 + aux_regs(0), 469 + aux_regs(1), 470 + aux_regs(2), 471 + aux_regs(3), 472 + }; 473 + 474 + #define hpd_regs(id)\ 475 + [id] = {\ 476 + HPD_REG_LIST(id)\ 477 + } 478 + 479 + static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { 480 + hpd_regs(0), 481 + hpd_regs(1), 482 + hpd_regs(2), 483 + hpd_regs(3), 484 + }; 485 + 486 + #define link_regs(id, phyid)\ 487 + [id] = {\ 488 + LE_DCN301_REG_LIST(id), \ 489 + UNIPHY_DCN2_REG_LIST(phyid), \ 490 + } 491 + 492 + static const struct dce110_aux_registers_shift aux_shift = { 493 + DCN_AUX_MASK_SH_LIST(__SHIFT) 494 + }; 495 + 496 + static const struct dce110_aux_registers_mask aux_mask = { 497 + DCN_AUX_MASK_SH_LIST(_MASK) 498 + }; 499 + 500 + static const struct dcn10_link_enc_registers link_enc_regs[] = { 501 + link_regs(0, A), 502 + link_regs(1, B), 503 + link_regs(2, C), 504 + link_regs(3, D), 505 + }; 506 + 507 + static const struct dcn10_link_enc_shift le_shift = { 508 + LINK_ENCODER_MASK_SH_LIST_DCN301(__SHIFT) 509 + }; 510 + 511 + static const struct dcn10_link_enc_mask le_mask = { 512 + LINK_ENCODER_MASK_SH_LIST_DCN301(_MASK) 513 + }; 514 + 515 + #define panel_cntl_regs(id)\ 516 + [id] = {\ 517 + DCN301_PANEL_CNTL_REG_LIST(id),\ 518 + } 519 + 520 + static const struct dce_panel_cntl_registers panel_cntl_regs[] = { 521 + panel_cntl_regs(0), 522 + panel_cntl_regs(1), 523 + }; 524 + 525 + static const struct dcn301_panel_cntl_shift panel_cntl_shift = { 526 + DCN301_PANEL_CNTL_MASK_SH_LIST(__SHIFT) 527 + }; 528 + 529 + static const struct dcn301_panel_cntl_mask panel_cntl_mask = { 530 + DCN301_PANEL_CNTL_MASK_SH_LIST(_MASK) 531 + }; 532 + 533 + #define dpp_regs(id)\ 534 + [id] = {\ 535 + DPP_REG_LIST_DCN30(id),\ 536 + } 537 + 538 + static const struct dcn3_dpp_registers dpp_regs[] = { 539 + dpp_regs(0), 540 + dpp_regs(1), 541 + dpp_regs(2), 542 + dpp_regs(3), 543 + }; 544 + 545 + static const struct dcn3_dpp_shift tf_shift = { 546 + DPP_REG_LIST_SH_MASK_DCN30(__SHIFT) 547 + }; 548 + 549 + static const struct dcn3_dpp_mask tf_mask = { 550 + DPP_REG_LIST_SH_MASK_DCN30(_MASK) 551 + }; 552 + 553 + #define opp_regs(id)\ 554 + [id] = {\ 555 + OPP_REG_LIST_DCN30(id),\ 556 + } 557 + 558 + static const struct dcn20_opp_registers opp_regs[] = { 559 + opp_regs(0), 560 + opp_regs(1), 561 + opp_regs(2), 562 + opp_regs(3), 563 + }; 564 + 565 + static const struct dcn20_opp_shift opp_shift = { 566 + OPP_MASK_SH_LIST_DCN20(__SHIFT) 567 + }; 568 + 569 + static const struct dcn20_opp_mask opp_mask = { 570 + OPP_MASK_SH_LIST_DCN20(_MASK) 571 + }; 572 + 573 + #define aux_engine_regs(id)\ 574 + [id] = {\ 575 + AUX_COMMON_REG_LIST0(id), \ 576 + .AUXN_IMPCAL = 0, \ 577 + .AUXP_IMPCAL = 0, \ 578 + .AUX_RESET_MASK = DP_AUX0_AUX_CONTROL__AUX_RESET_MASK, \ 579 + } 580 + 581 + static const struct dce110_aux_registers aux_engine_regs[] = { 582 + aux_engine_regs(0), 583 + aux_engine_regs(1), 584 + aux_engine_regs(2), 585 + aux_engine_regs(3), 586 + }; 587 + 588 + #define dwbc_regs_dcn3(id)\ 589 + [id] = {\ 590 + DWBC_COMMON_REG_LIST_DCN30(id),\ 591 + } 592 + 593 + static const struct dcn30_dwbc_registers dwbc30_regs[] = { 594 + dwbc_regs_dcn3(0), 595 + }; 596 + 597 + static const struct dcn30_dwbc_shift dwbc30_shift = { 598 + DWBC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 599 + }; 600 + 601 + static const struct dcn30_dwbc_mask dwbc30_mask = { 602 + DWBC_COMMON_MASK_SH_LIST_DCN30(_MASK) 603 + }; 604 + 605 + #define mcif_wb_regs_dcn3(id)\ 606 + [id] = {\ 607 + MCIF_WB_COMMON_REG_LIST_DCN30(id),\ 608 + } 609 + 610 + static const struct dcn30_mmhubbub_registers mcif_wb30_regs[] = { 611 + mcif_wb_regs_dcn3(0) 612 + }; 613 + 614 + static const struct dcn30_mmhubbub_shift mcif_wb30_shift = { 615 + MCIF_WB_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 616 + }; 617 + 618 + static const struct dcn30_mmhubbub_mask mcif_wb30_mask = { 619 + MCIF_WB_COMMON_MASK_SH_LIST_DCN30(_MASK) 620 + }; 621 + 622 + #define dsc_regsDCN20(id)\ 623 + [id] = {\ 624 + DSC_REG_LIST_DCN20(id)\ 625 + } 626 + 627 + static const struct dcn20_dsc_registers dsc_regs[] = { 628 + dsc_regsDCN20(0), 629 + dsc_regsDCN20(1), 630 + dsc_regsDCN20(2), 631 + }; 632 + 633 + static const struct dcn20_dsc_shift dsc_shift = { 634 + DSC_REG_LIST_SH_MASK_DCN20(__SHIFT) 635 + }; 636 + 637 + static const struct dcn20_dsc_mask dsc_mask = { 638 + DSC_REG_LIST_SH_MASK_DCN20(_MASK) 639 + }; 640 + 641 + static const struct dcn30_mpc_registers mpc_regs = { 642 + MPC_REG_LIST_DCN3_0(0), 643 + MPC_REG_LIST_DCN3_0(1), 644 + MPC_REG_LIST_DCN3_0(2), 645 + MPC_REG_LIST_DCN3_0(3), 646 + MPC_OUT_MUX_REG_LIST_DCN3_0(0), 647 + MPC_OUT_MUX_REG_LIST_DCN3_0(1), 648 + MPC_OUT_MUX_REG_LIST_DCN3_0(2), 649 + MPC_OUT_MUX_REG_LIST_DCN3_0(3), 650 + MPC_RMU_GLOBAL_REG_LIST_DCN3AG, 651 + MPC_RMU_REG_LIST_DCN3AG(0), 652 + MPC_RMU_REG_LIST_DCN3AG(1), 653 + MPC_DWB_MUX_REG_LIST_DCN3_0(0), 654 + }; 655 + 656 + static const struct dcn30_mpc_shift mpc_shift = { 657 + MPC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 658 + }; 659 + 660 + static const struct dcn30_mpc_mask mpc_mask = { 661 + MPC_COMMON_MASK_SH_LIST_DCN30(_MASK) 662 + }; 663 + 664 + #define optc_regs(id)\ 665 + [id] = {OPTC_COMMON_REG_LIST_DCN3_0(id)} 666 + 667 + 668 + static const struct dcn_optc_registers optc_regs[] = { 669 + optc_regs(0), 670 + optc_regs(1), 671 + optc_regs(2), 672 + optc_regs(3), 673 + }; 674 + 675 + static const struct dcn_optc_shift optc_shift = { 676 + OPTC_COMMON_MASK_SH_LIST_DCN30(__SHIFT) 677 + }; 678 + 679 + static const struct dcn_optc_mask optc_mask = { 680 + OPTC_COMMON_MASK_SH_LIST_DCN30(_MASK) 681 + }; 682 + 683 + #define hubp_regs(id)\ 684 + [id] = {\ 685 + HUBP_REG_LIST_DCN30(id)\ 686 + } 687 + 688 + static const struct dcn_hubp2_registers hubp_regs[] = { 689 + hubp_regs(0), 690 + hubp_regs(1), 691 + hubp_regs(2), 692 + hubp_regs(3), 693 + }; 694 + 695 + static const struct dcn_hubp2_shift hubp_shift = { 696 + HUBP_MASK_SH_LIST_DCN30(__SHIFT) 697 + }; 698 + 699 + static const struct dcn_hubp2_mask hubp_mask = { 700 + HUBP_MASK_SH_LIST_DCN30(_MASK) 701 + }; 702 + 703 + static const struct dcn_hubbub_registers hubbub_reg = { 704 + HUBBUB_REG_LIST_DCN301(0) 705 + }; 706 + 707 + static const struct dcn_hubbub_shift hubbub_shift = { 708 + HUBBUB_MASK_SH_LIST_DCN301(__SHIFT) 709 + }; 710 + 711 + static const struct dcn_hubbub_mask hubbub_mask = { 712 + HUBBUB_MASK_SH_LIST_DCN301(_MASK) 713 + }; 714 + 715 + static const struct dccg_registers dccg_regs = { 716 + DCCG_REG_LIST_DCN301() 717 + }; 718 + 719 + static const struct dccg_shift dccg_shift = { 720 + DCCG_MASK_SH_LIST_DCN301(__SHIFT) 721 + }; 722 + 723 + static const struct dccg_mask dccg_mask = { 724 + DCCG_MASK_SH_LIST_DCN301(_MASK) 725 + }; 726 + 727 + static const struct dce_hwseq_registers hwseq_reg = { 728 + HWSEQ_DCN301_REG_LIST() 729 + }; 730 + 731 + static const struct dce_hwseq_shift hwseq_shift = { 732 + HWSEQ_DCN301_MASK_SH_LIST(__SHIFT) 733 + }; 734 + 735 + static const struct dce_hwseq_mask hwseq_mask = { 736 + HWSEQ_DCN301_MASK_SH_LIST(_MASK) 737 + }; 738 + #define vmid_regs(id)\ 739 + [id] = {\ 740 + DCN20_VMID_REG_LIST(id)\ 741 + } 742 + 743 + static const struct dcn_vmid_registers vmid_regs[] = { 744 + vmid_regs(0), 745 + vmid_regs(1), 746 + vmid_regs(2), 747 + vmid_regs(3), 748 + vmid_regs(4), 749 + vmid_regs(5), 750 + vmid_regs(6), 751 + vmid_regs(7), 752 + vmid_regs(8), 753 + vmid_regs(9), 754 + vmid_regs(10), 755 + vmid_regs(11), 756 + vmid_regs(12), 757 + vmid_regs(13), 758 + vmid_regs(14), 759 + vmid_regs(15) 760 + }; 761 + 762 + static const struct dcn20_vmid_shift vmid_shifts = { 763 + DCN20_VMID_MASK_SH_LIST(__SHIFT) 764 + }; 765 + 766 + static const struct dcn20_vmid_mask vmid_masks = { 767 + DCN20_VMID_MASK_SH_LIST(_MASK) 768 + }; 769 + 770 + static const struct resource_caps res_cap_dcn301 = { 771 + .num_timing_generator = 4, 772 + .num_opp = 4, 773 + .num_video_plane = 4, 774 + .num_audio = 4, 775 + .num_stream_encoder = 4, 776 + .num_pll = 4, 777 + .num_dwb = 1, 778 + .num_ddc = 4, 779 + .num_vmid = 16, 780 + .num_mpc_3dlut = 2, 781 + .num_dsc = 3, 782 + }; 783 + 784 + static const struct dc_plane_cap plane_cap = { 785 + .type = DC_PLANE_TYPE_DCN_UNIVERSAL, 786 + .blends_with_above = true, 787 + .blends_with_below = true, 788 + .per_pixel_alpha = true, 789 + 790 + .pixel_format_support = { 791 + .argb8888 = true, 792 + .nv12 = true, 793 + .fp16 = true, 794 + .p010 = false, 795 + .ayuv = false, 796 + }, 797 + 798 + .max_upscale_factor = { 799 + .argb8888 = 16000, 800 + .nv12 = 16000, 801 + .fp16 = 16000 802 + }, 803 + 804 + .max_downscale_factor = { 805 + .argb8888 = 600, 806 + .nv12 = 600, 807 + .fp16 = 600 808 + }, 809 + 64, 810 + 64 811 + }; 812 + 813 + static const struct dc_debug_options debug_defaults_drv = { 814 + .disable_dmcu = true, 815 + .force_abm_enable = false, 816 + .timing_trace = false, 817 + .clock_trace = true, 818 + .disable_dpp_power_gate = true, 819 + .disable_hubp_power_gate = true, 820 + .disable_clock_gate = true, 821 + .disable_pplib_clock_request = true, 822 + .disable_pplib_wm_range = true, 823 + .disable_stutter = true, 824 + .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, 825 + .force_single_disp_pipe_split = false, 826 + .disable_dcc = DCC_ENABLE, 827 + .vsr_support = true, 828 + .performance_trace = false, 829 + .max_downscale_src_width = 7680,/*upto 8K*/ 830 + .scl_reset_length10 = true, 831 + .sanity_checks = false, 832 + .underflow_assert_delay_us = 0xFFFFFFFF, 833 + .dwb_fi_phase = -1, // -1 = disable 834 + .dmub_command_table = true, 835 + }; 836 + 837 + static const struct dc_debug_options debug_defaults_diags = { 838 + .disable_dmcu = true, 839 + .force_abm_enable = false, 840 + .timing_trace = true, 841 + .clock_trace = true, 842 + .disable_dpp_power_gate = true, 843 + .disable_hubp_power_gate = true, 844 + .disable_clock_gate = true, 845 + .disable_pplib_clock_request = true, 846 + .disable_pplib_wm_range = true, 847 + .disable_stutter = true, 848 + .scl_reset_length10 = true, 849 + .dwb_fi_phase = -1, // -1 = disable 850 + .dmub_command_table = true, 851 + }; 852 + 853 + void dcn301_dpp_destroy(struct dpp **dpp) 854 + { 855 + kfree(TO_DCN20_DPP(*dpp)); 856 + *dpp = NULL; 857 + } 858 + 859 + struct dpp *dcn301_dpp_create( 860 + struct dc_context *ctx, 861 + uint32_t inst) 862 + { 863 + struct dcn3_dpp *dpp = 864 + kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); 865 + 866 + if (!dpp) 867 + return NULL; 868 + 869 + if (dpp3_construct(dpp, ctx, inst, 870 + &dpp_regs[inst], &tf_shift, &tf_mask)) 871 + return &dpp->base; 872 + 873 + BREAK_TO_DEBUGGER(); 874 + kfree(dpp); 875 + return NULL; 876 + } 877 + struct output_pixel_processor *dcn301_opp_create( 878 + struct dc_context *ctx, uint32_t inst) 879 + { 880 + struct dcn20_opp *opp = 881 + kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); 882 + 883 + if (!opp) { 884 + BREAK_TO_DEBUGGER(); 885 + return NULL; 886 + } 887 + 888 + dcn20_opp_construct(opp, ctx, inst, 889 + &opp_regs[inst], &opp_shift, &opp_mask); 890 + return &opp->base; 891 + } 892 + 893 + struct dce_aux *dcn301_aux_engine_create( 894 + struct dc_context *ctx, 895 + uint32_t inst) 896 + { 897 + struct aux_engine_dce110 *aux_engine = 898 + kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); 899 + 900 + if (!aux_engine) 901 + return NULL; 902 + 903 + dce110_aux_engine_construct(aux_engine, ctx, inst, 904 + SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 905 + &aux_engine_regs[inst], 906 + &aux_mask, 907 + &aux_shift, 908 + ctx->dc->caps.extended_aux_timeout_support); 909 + 910 + return &aux_engine->base; 911 + } 912 + #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) } 913 + 914 + static const struct dce_i2c_registers i2c_hw_regs[] = { 915 + i2c_inst_regs(1), 916 + i2c_inst_regs(2), 917 + i2c_inst_regs(3), 918 + i2c_inst_regs(4), 919 + }; 920 + 921 + static const struct dce_i2c_shift i2c_shifts = { 922 + I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT) 923 + }; 924 + 925 + static const struct dce_i2c_mask i2c_masks = { 926 + I2C_COMMON_MASK_SH_LIST_DCN2(_MASK) 927 + }; 928 + 929 + struct dce_i2c_hw *dcn301_i2c_hw_create( 930 + struct dc_context *ctx, 931 + uint32_t inst) 932 + { 933 + struct dce_i2c_hw *dce_i2c_hw = 934 + kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); 935 + 936 + if (!dce_i2c_hw) 937 + return NULL; 938 + 939 + dcn2_i2c_hw_construct(dce_i2c_hw, ctx, inst, 940 + &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks); 941 + 942 + return dce_i2c_hw; 943 + } 944 + static struct mpc *dcn301_mpc_create( 945 + struct dc_context *ctx, 946 + int num_mpcc, 947 + int num_rmu) 948 + { 949 + struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), 950 + GFP_KERNEL); 951 + 952 + if (!mpc30) 953 + return NULL; 954 + 955 + dcn30_mpc_construct(mpc30, ctx, 956 + &mpc_regs, 957 + &mpc_shift, 958 + &mpc_mask, 959 + num_mpcc, 960 + num_rmu); 961 + 962 + return &mpc30->base; 963 + } 964 + 965 + struct hubbub *dcn301_hubbub_create(struct dc_context *ctx) 966 + { 967 + int i; 968 + 969 + struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), 970 + GFP_KERNEL); 971 + 972 + if (!hubbub3) 973 + return NULL; 974 + 975 + hubbub301_construct(hubbub3, ctx, 976 + &hubbub_reg, 977 + &hubbub_shift, 978 + &hubbub_mask); 979 + 980 + 981 + for (i = 0; i < res_cap_dcn301.num_vmid; i++) { 982 + struct dcn20_vmid *vmid = &hubbub3->vmid[i]; 983 + 984 + vmid->ctx = ctx; 985 + 986 + vmid->regs = &vmid_regs[i]; 987 + vmid->shifts = &vmid_shifts; 988 + vmid->masks = &vmid_masks; 989 + } 990 + 991 + hubbub3->num_vmid = res_cap_dcn301.num_vmid; 992 + 993 + return &hubbub3->base; 994 + } 995 + 996 + struct timing_generator *dcn301_timing_generator_create( 997 + struct dc_context *ctx, 998 + uint32_t instance) 999 + { 1000 + struct optc *tgn10 = 1001 + kzalloc(sizeof(struct optc), GFP_KERNEL); 1002 + 1003 + if (!tgn10) 1004 + return NULL; 1005 + 1006 + tgn10->base.inst = instance; 1007 + tgn10->base.ctx = ctx; 1008 + 1009 + tgn10->tg_regs = &optc_regs[instance]; 1010 + tgn10->tg_shift = &optc_shift; 1011 + tgn10->tg_mask = &optc_mask; 1012 + 1013 + dcn30_timing_generator_init(tgn10); 1014 + 1015 + return &tgn10->base; 1016 + } 1017 + 1018 + static const struct encoder_feature_support link_enc_feature = { 1019 + .max_hdmi_deep_color = COLOR_DEPTH_121212, 1020 + .max_hdmi_pixel_clock = 600000, 1021 + .hdmi_ycbcr420_supported = true, 1022 + .dp_ycbcr420_supported = true, 1023 + .fec_supported = true, 1024 + .flags.bits.IS_HBR2_CAPABLE = true, 1025 + .flags.bits.IS_HBR3_CAPABLE = true, 1026 + .flags.bits.IS_TPS3_CAPABLE = true, 1027 + .flags.bits.IS_TPS4_CAPABLE = true 1028 + }; 1029 + 1030 + struct link_encoder *dcn301_link_encoder_create( 1031 + const struct encoder_init_data *enc_init_data) 1032 + { 1033 + struct dcn20_link_encoder *enc20 = 1034 + kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); 1035 + 1036 + if (!enc20) 1037 + return NULL; 1038 + 1039 + dcn301_link_encoder_construct(enc20, 1040 + enc_init_data, 1041 + &link_enc_feature, 1042 + &link_enc_regs[enc_init_data->transmitter], 1043 + &link_enc_aux_regs[enc_init_data->channel - 1], 1044 + &link_enc_hpd_regs[enc_init_data->hpd_source], 1045 + &le_shift, 1046 + &le_mask); 1047 + 1048 + return &enc20->enc10.base; 1049 + } 1050 + 1051 + struct panel_cntl *dcn301_panel_cntl_create(const struct panel_cntl_init_data *init_data) 1052 + { 1053 + struct dcn301_panel_cntl *panel_cntl = 1054 + kzalloc(sizeof(struct dcn301_panel_cntl), GFP_KERNEL); 1055 + 1056 + if (!panel_cntl) 1057 + return NULL; 1058 + 1059 + dcn301_panel_cntl_construct(panel_cntl, 1060 + init_data, 1061 + &panel_cntl_regs[init_data->inst], 1062 + &panel_cntl_shift, 1063 + &panel_cntl_mask); 1064 + 1065 + return &panel_cntl->base; 1066 + } 1067 + 1068 + 1069 + #define CTX ctx 1070 + 1071 + #define REG(reg_name) \ 1072 + (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) 1073 + 1074 + static uint32_t read_pipe_fuses(struct dc_context *ctx) 1075 + { 1076 + uint32_t value = REG_READ(CC_DC_PIPE_DIS); 1077 + /* RV1 support max 4 pipes */ 1078 + value = value & 0xf; 1079 + return value; 1080 + } 1081 + 1082 + 1083 + static void read_dce_straps( 1084 + struct dc_context *ctx, 1085 + struct resource_straps *straps) 1086 + { 1087 + generic_reg_get(ctx, mmDC_PINSTRAPS + BASE(mmDC_PINSTRAPS_BASE_IDX), 1088 + FN(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO), &straps->dc_pinstraps_audio); 1089 + 1090 + } 1091 + 1092 + static struct audio *dcn301_create_audio( 1093 + struct dc_context *ctx, unsigned int inst) 1094 + { 1095 + return dce_audio_create(ctx, inst, 1096 + &audio_regs[inst], &audio_shift, &audio_mask); 1097 + } 1098 + 1099 + static struct vpg *dcn301_vpg_create( 1100 + struct dc_context *ctx, 1101 + uint32_t inst) 1102 + { 1103 + struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); 1104 + 1105 + if (!vpg3) 1106 + return NULL; 1107 + 1108 + vpg3_construct(vpg3, ctx, inst, 1109 + &vpg_regs[inst], 1110 + &vpg_shift, 1111 + &vpg_mask); 1112 + 1113 + return &vpg3->base; 1114 + } 1115 + 1116 + static struct afmt *dcn301_afmt_create( 1117 + struct dc_context *ctx, 1118 + uint32_t inst) 1119 + { 1120 + struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); 1121 + 1122 + if (!afmt3) 1123 + return NULL; 1124 + 1125 + afmt3_construct(afmt3, ctx, inst, 1126 + &afmt_regs[inst], 1127 + &afmt_shift, 1128 + &afmt_mask); 1129 + 1130 + return &afmt3->base; 1131 + } 1132 + 1133 + struct stream_encoder *dcn301_stream_encoder_create( 1134 + enum engine_id eng_id, 1135 + struct dc_context *ctx) 1136 + { 1137 + struct dcn10_stream_encoder *enc1; 1138 + struct vpg *vpg; 1139 + struct afmt *afmt; 1140 + int vpg_inst; 1141 + int afmt_inst; 1142 + 1143 + /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ 1144 + if (eng_id <= ENGINE_ID_DIGF) { 1145 + vpg_inst = eng_id; 1146 + afmt_inst = eng_id; 1147 + } else 1148 + return NULL; 1149 + 1150 + enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); 1151 + vpg = dcn301_vpg_create(ctx, vpg_inst); 1152 + afmt = dcn301_afmt_create(ctx, afmt_inst); 1153 + 1154 + if (!enc1 || !vpg || !afmt) 1155 + return NULL; 1156 + 1157 + dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, 1158 + eng_id, vpg, afmt, 1159 + &stream_enc_regs[eng_id], 1160 + &se_shift, &se_mask); 1161 + 1162 + return &enc1->base; 1163 + } 1164 + 1165 + struct dce_hwseq *dcn301_hwseq_create( 1166 + struct dc_context *ctx) 1167 + { 1168 + struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); 1169 + 1170 + if (hws) { 1171 + hws->ctx = ctx; 1172 + hws->regs = &hwseq_reg; 1173 + hws->shifts = &hwseq_shift; 1174 + hws->masks = &hwseq_mask; 1175 + } 1176 + return hws; 1177 + } 1178 + static const struct resource_create_funcs res_create_funcs = { 1179 + .read_dce_straps = read_dce_straps, 1180 + .create_audio = dcn301_create_audio, 1181 + .create_stream_encoder = dcn301_stream_encoder_create, 1182 + .create_hwseq = dcn301_hwseq_create, 1183 + }; 1184 + 1185 + static const struct resource_create_funcs res_create_maximus_funcs = { 1186 + .read_dce_straps = NULL, 1187 + .create_audio = NULL, 1188 + .create_stream_encoder = NULL, 1189 + .create_hwseq = dcn301_hwseq_create, 1190 + }; 1191 + 1192 + static void dcn301_pp_smu_destroy(struct pp_smu_funcs **pp_smu); 1193 + 1194 + static void dcn301_destruct(struct dcn301_resource_pool *pool) 1195 + { 1196 + unsigned int i; 1197 + 1198 + for (i = 0; i < pool->base.stream_enc_count; i++) { 1199 + if (pool->base.stream_enc[i] != NULL) { 1200 + if (pool->base.stream_enc[i]->vpg != NULL) { 1201 + kfree(DCN30_VPG_FROM_VPG(pool->base.stream_enc[i]->vpg)); 1202 + pool->base.stream_enc[i]->vpg = NULL; 1203 + } 1204 + if (pool->base.stream_enc[i]->afmt != NULL) { 1205 + kfree(DCN30_AFMT_FROM_AFMT(pool->base.stream_enc[i]->afmt)); 1206 + pool->base.stream_enc[i]->afmt = NULL; 1207 + } 1208 + kfree(DCN10STRENC_FROM_STRENC(pool->base.stream_enc[i])); 1209 + pool->base.stream_enc[i] = NULL; 1210 + } 1211 + } 1212 + 1213 + for (i = 0; i < pool->base.res_cap->num_dsc; i++) { 1214 + if (pool->base.dscs[i] != NULL) 1215 + dcn20_dsc_destroy(&pool->base.dscs[i]); 1216 + } 1217 + 1218 + if (pool->base.mpc != NULL) { 1219 + kfree(TO_DCN20_MPC(pool->base.mpc)); 1220 + pool->base.mpc = NULL; 1221 + } 1222 + if (pool->base.hubbub != NULL) { 1223 + kfree(pool->base.hubbub); 1224 + pool->base.hubbub = NULL; 1225 + } 1226 + for (i = 0; i < pool->base.pipe_count; i++) { 1227 + if (pool->base.dpps[i] != NULL) 1228 + dcn301_dpp_destroy(&pool->base.dpps[i]); 1229 + 1230 + if (pool->base.ipps[i] != NULL) 1231 + pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); 1232 + 1233 + if (pool->base.hubps[i] != NULL) { 1234 + kfree(TO_DCN20_HUBP(pool->base.hubps[i])); 1235 + pool->base.hubps[i] = NULL; 1236 + } 1237 + 1238 + if (pool->base.irqs != NULL) { 1239 + dal_irq_service_destroy(&pool->base.irqs); 1240 + } 1241 + } 1242 + 1243 + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 1244 + if (pool->base.engines[i] != NULL) 1245 + dce110_engine_destroy(&pool->base.engines[i]); 1246 + if (pool->base.hw_i2cs[i] != NULL) { 1247 + kfree(pool->base.hw_i2cs[i]); 1248 + pool->base.hw_i2cs[i] = NULL; 1249 + } 1250 + if (pool->base.sw_i2cs[i] != NULL) { 1251 + kfree(pool->base.sw_i2cs[i]); 1252 + pool->base.sw_i2cs[i] = NULL; 1253 + } 1254 + } 1255 + 1256 + for (i = 0; i < pool->base.res_cap->num_opp; i++) { 1257 + if (pool->base.opps[i] != NULL) 1258 + pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]); 1259 + } 1260 + 1261 + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { 1262 + if (pool->base.timing_generators[i] != NULL) { 1263 + kfree(DCN10TG_FROM_TG(pool->base.timing_generators[i])); 1264 + pool->base.timing_generators[i] = NULL; 1265 + } 1266 + } 1267 + 1268 + for (i = 0; i < pool->base.res_cap->num_dwb; i++) { 1269 + if (pool->base.dwbc[i] != NULL) { 1270 + kfree(TO_DCN30_DWBC(pool->base.dwbc[i])); 1271 + pool->base.dwbc[i] = NULL; 1272 + } 1273 + if (pool->base.mcif_wb[i] != NULL) { 1274 + kfree(TO_DCN30_MMHUBBUB(pool->base.mcif_wb[i])); 1275 + pool->base.mcif_wb[i] = NULL; 1276 + } 1277 + } 1278 + 1279 + for (i = 0; i < pool->base.audio_count; i++) { 1280 + if (pool->base.audios[i]) 1281 + dce_aud_destroy(&pool->base.audios[i]); 1282 + } 1283 + 1284 + for (i = 0; i < pool->base.clk_src_count; i++) { 1285 + if (pool->base.clock_sources[i] != NULL) { 1286 + dcn20_clock_source_destroy(&pool->base.clock_sources[i]); 1287 + pool->base.clock_sources[i] = NULL; 1288 + } 1289 + } 1290 + 1291 + for (i = 0; i < pool->base.res_cap->num_mpc_3dlut; i++) { 1292 + if (pool->base.mpc_lut[i] != NULL) { 1293 + dc_3dlut_func_release(pool->base.mpc_lut[i]); 1294 + pool->base.mpc_lut[i] = NULL; 1295 + } 1296 + if (pool->base.mpc_shaper[i] != NULL) { 1297 + dc_transfer_func_release(pool->base.mpc_shaper[i]); 1298 + pool->base.mpc_shaper[i] = NULL; 1299 + } 1300 + } 1301 + 1302 + if (pool->base.dp_clock_source != NULL) { 1303 + dcn20_clock_source_destroy(&pool->base.dp_clock_source); 1304 + pool->base.dp_clock_source = NULL; 1305 + } 1306 + 1307 + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { 1308 + if (pool->base.multiple_abms[i] != NULL) 1309 + dce_abm_destroy(&pool->base.multiple_abms[i]); 1310 + } 1311 + 1312 + if (pool->base.dccg != NULL) 1313 + dcn_dccg_destroy(&pool->base.dccg); 1314 + 1315 + if (pool->base.pp_smu != NULL) 1316 + dcn301_pp_smu_destroy(&pool->base.pp_smu); 1317 + } 1318 + 1319 + struct hubp *dcn301_hubp_create( 1320 + struct dc_context *ctx, 1321 + uint32_t inst) 1322 + { 1323 + struct dcn20_hubp *hubp2 = 1324 + kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); 1325 + 1326 + if (!hubp2) 1327 + return NULL; 1328 + 1329 + if (hubp3_construct(hubp2, ctx, inst, 1330 + &hubp_regs[inst], &hubp_shift, &hubp_mask)) 1331 + return &hubp2->base; 1332 + 1333 + BREAK_TO_DEBUGGER(); 1334 + kfree(hubp2); 1335 + return NULL; 1336 + } 1337 + 1338 + bool dcn301_dwbc_create(struct dc_context *ctx, struct resource_pool *pool) 1339 + { 1340 + int i; 1341 + uint32_t pipe_count = pool->res_cap->num_dwb; 1342 + 1343 + for (i = 0; i < pipe_count; i++) { 1344 + struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), 1345 + GFP_KERNEL); 1346 + 1347 + if (!dwbc30) { 1348 + dm_error("DC: failed to create dwbc30!\n"); 1349 + return false; 1350 + } 1351 + 1352 + dcn30_dwbc_construct(dwbc30, ctx, 1353 + &dwbc30_regs[i], 1354 + &dwbc30_shift, 1355 + &dwbc30_mask, 1356 + i); 1357 + 1358 + pool->dwbc[i] = &dwbc30->base; 1359 + } 1360 + return true; 1361 + } 1362 + 1363 + bool dcn301_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) 1364 + { 1365 + int i; 1366 + uint32_t pipe_count = pool->res_cap->num_dwb; 1367 + 1368 + for (i = 0; i < pipe_count; i++) { 1369 + struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), 1370 + GFP_KERNEL); 1371 + 1372 + if (!mcif_wb30) { 1373 + dm_error("DC: failed to create mcif_wb30!\n"); 1374 + return false; 1375 + } 1376 + 1377 + dcn30_mmhubbub_construct(mcif_wb30, ctx, 1378 + &mcif_wb30_regs[i], 1379 + &mcif_wb30_shift, 1380 + &mcif_wb30_mask, 1381 + i); 1382 + 1383 + pool->mcif_wb[i] = &mcif_wb30->base; 1384 + } 1385 + return true; 1386 + } 1387 + 1388 + static struct display_stream_compressor *dcn301_dsc_create( 1389 + struct dc_context *ctx, uint32_t inst) 1390 + { 1391 + struct dcn20_dsc *dsc = 1392 + kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); 1393 + 1394 + if (!dsc) { 1395 + BREAK_TO_DEBUGGER(); 1396 + return NULL; 1397 + } 1398 + 1399 + dsc2_construct(dsc, ctx, inst, &dsc_regs[inst], &dsc_shift, &dsc_mask); 1400 + return &dsc->base; 1401 + } 1402 + 1403 + 1404 + static void dcn301_destroy_resource_pool(struct resource_pool **pool) 1405 + { 1406 + struct dcn301_resource_pool *dcn301_pool = TO_DCN301_RES_POOL(*pool); 1407 + 1408 + dcn301_destruct(dcn301_pool); 1409 + kfree(dcn301_pool); 1410 + *pool = NULL; 1411 + } 1412 + 1413 + static struct clock_source *dcn301_clock_source_create( 1414 + struct dc_context *ctx, 1415 + struct dc_bios *bios, 1416 + enum clock_source_id id, 1417 + const struct dce110_clk_src_regs *regs, 1418 + bool dp_clk_src) 1419 + { 1420 + struct dce110_clk_src *clk_src = 1421 + kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); 1422 + 1423 + if (!clk_src) 1424 + return NULL; 1425 + 1426 + if (dcn301_clk_src_construct(clk_src, ctx, bios, id, 1427 + regs, &cs_shift, &cs_mask)) { 1428 + clk_src->base.dp_clk_src = dp_clk_src; 1429 + return &clk_src->base; 1430 + } 1431 + 1432 + BREAK_TO_DEBUGGER(); 1433 + return NULL; 1434 + } 1435 + 1436 + static struct dc_cap_funcs cap_funcs = { 1437 + .get_dcc_compression_cap = dcn20_get_dcc_compression_cap 1438 + }; 1439 + 1440 + #define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) 1441 + #define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) 1442 + 1443 + static bool is_soc_bounding_box_valid(struct dc *dc) 1444 + { 1445 + uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; 1446 + 1447 + if (ASICREV_IS_VANGOGH(hw_internal_rev)) 1448 + return true; 1449 + 1450 + return false; 1451 + } 1452 + 1453 + static bool init_soc_bounding_box(struct dc *dc, 1454 + struct dcn301_resource_pool *pool) 1455 + { 1456 + const struct gpu_info_soc_bounding_box_v1_0 *bb = dc->soc_bounding_box; 1457 + struct _vcs_dpi_soc_bounding_box_st *loaded_bb = &dcn3_01_soc; 1458 + struct _vcs_dpi_ip_params_st *loaded_ip = &dcn3_01_ip; 1459 + 1460 + DC_LOGGER_INIT(dc->ctx->logger); 1461 + 1462 + if (!bb && !is_soc_bounding_box_valid(dc)) { 1463 + DC_LOG_ERROR("%s: not valid soc bounding box/n", __func__); 1464 + return false; 1465 + } 1466 + 1467 + if (bb && !is_soc_bounding_box_valid(dc)) { 1468 + int i; 1469 + 1470 + dcn3_01_soc.sr_exit_time_us = 1471 + fixed16_to_double_to_cpu(bb->sr_exit_time_us); 1472 + dcn3_01_soc.sr_enter_plus_exit_time_us = 1473 + fixed16_to_double_to_cpu(bb->sr_enter_plus_exit_time_us); 1474 + dcn3_01_soc.urgent_latency_us = 1475 + fixed16_to_double_to_cpu(bb->urgent_latency_us); 1476 + dcn3_01_soc.urgent_latency_pixel_data_only_us = 1477 + fixed16_to_double_to_cpu(bb->urgent_latency_pixel_data_only_us); 1478 + dcn3_01_soc.urgent_latency_pixel_mixed_with_vm_data_us = 1479 + fixed16_to_double_to_cpu(bb->urgent_latency_pixel_mixed_with_vm_data_us); 1480 + dcn3_01_soc.urgent_latency_vm_data_only_us = 1481 + fixed16_to_double_to_cpu(bb->urgent_latency_vm_data_only_us); 1482 + dcn3_01_soc.urgent_out_of_order_return_per_channel_pixel_only_bytes = 1483 + le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_only_bytes); 1484 + dcn3_01_soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 1485 + le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes); 1486 + dcn3_01_soc.urgent_out_of_order_return_per_channel_vm_only_bytes = 1487 + le32_to_cpu(bb->urgent_out_of_order_return_per_channel_vm_only_bytes); 1488 + dcn3_01_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 1489 + fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_only); 1490 + dcn3_01_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 1491 + fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm); 1492 + dcn3_01_soc.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 1493 + fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_vm_only); 1494 + dcn3_01_soc.max_avg_sdp_bw_use_normal_percent = 1495 + fixed16_to_double_to_cpu(bb->max_avg_sdp_bw_use_normal_percent); 1496 + dcn3_01_soc.max_avg_dram_bw_use_normal_percent = 1497 + fixed16_to_double_to_cpu(bb->max_avg_dram_bw_use_normal_percent); 1498 + dcn3_01_soc.writeback_latency_us = 1499 + fixed16_to_double_to_cpu(bb->writeback_latency_us); 1500 + dcn3_01_soc.ideal_dram_bw_after_urgent_percent = 1501 + fixed16_to_double_to_cpu(bb->ideal_dram_bw_after_urgent_percent); 1502 + dcn3_01_soc.max_request_size_bytes = 1503 + le32_to_cpu(bb->max_request_size_bytes); 1504 + dcn3_01_soc.dram_channel_width_bytes = 1505 + le32_to_cpu(bb->dram_channel_width_bytes); 1506 + dcn3_01_soc.fabric_datapath_to_dcn_data_return_bytes = 1507 + le32_to_cpu(bb->fabric_datapath_to_dcn_data_return_bytes); 1508 + dcn3_01_soc.dcn_downspread_percent = 1509 + fixed16_to_double_to_cpu(bb->dcn_downspread_percent); 1510 + dcn3_01_soc.downspread_percent = 1511 + fixed16_to_double_to_cpu(bb->downspread_percent); 1512 + dcn3_01_soc.dram_page_open_time_ns = 1513 + fixed16_to_double_to_cpu(bb->dram_page_open_time_ns); 1514 + dcn3_01_soc.dram_rw_turnaround_time_ns = 1515 + fixed16_to_double_to_cpu(bb->dram_rw_turnaround_time_ns); 1516 + dcn3_01_soc.dram_return_buffer_per_channel_bytes = 1517 + le32_to_cpu(bb->dram_return_buffer_per_channel_bytes); 1518 + dcn3_01_soc.round_trip_ping_latency_dcfclk_cycles = 1519 + le32_to_cpu(bb->round_trip_ping_latency_dcfclk_cycles); 1520 + dcn3_01_soc.urgent_out_of_order_return_per_channel_bytes = 1521 + le32_to_cpu(bb->urgent_out_of_order_return_per_channel_bytes); 1522 + dcn3_01_soc.channel_interleave_bytes = 1523 + le32_to_cpu(bb->channel_interleave_bytes); 1524 + dcn3_01_soc.num_banks = 1525 + le32_to_cpu(bb->num_banks); 1526 + dcn3_01_soc.num_chans = 1527 + le32_to_cpu(bb->num_chans); 1528 + dcn3_01_soc.gpuvm_min_page_size_bytes = 1529 + le32_to_cpu(bb->vmm_page_size_bytes); 1530 + dcn3_01_soc.dram_clock_change_latency_us = 1531 + fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us); 1532 + dcn3_01_soc.writeback_dram_clock_change_latency_us = 1533 + fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us); 1534 + dcn3_01_soc.return_bus_width_bytes = 1535 + le32_to_cpu(bb->return_bus_width_bytes); 1536 + dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = 1537 + le32_to_cpu(bb->dispclk_dppclk_vco_speed_mhz); 1538 + dcn3_01_soc.xfc_bus_transport_time_us = 1539 + le32_to_cpu(bb->xfc_bus_transport_time_us); 1540 + dcn3_01_soc.xfc_xbuf_latency_tolerance_us = 1541 + le32_to_cpu(bb->xfc_xbuf_latency_tolerance_us); 1542 + dcn3_01_soc.use_urgent_burst_bw = 1543 + le32_to_cpu(bb->use_urgent_burst_bw); 1544 + dcn3_01_soc.num_states = 1545 + le32_to_cpu(bb->num_states); 1546 + 1547 + for (i = 0; i < dcn3_01_soc.num_states; i++) { 1548 + dcn3_01_soc.clock_limits[i].state = 1549 + le32_to_cpu(bb->clock_limits[i].state); 1550 + dcn3_01_soc.clock_limits[i].dcfclk_mhz = 1551 + fixed16_to_double_to_cpu(bb->clock_limits[i].dcfclk_mhz); 1552 + dcn3_01_soc.clock_limits[i].fabricclk_mhz = 1553 + fixed16_to_double_to_cpu(bb->clock_limits[i].fabricclk_mhz); 1554 + dcn3_01_soc.clock_limits[i].dispclk_mhz = 1555 + fixed16_to_double_to_cpu(bb->clock_limits[i].dispclk_mhz); 1556 + dcn3_01_soc.clock_limits[i].dppclk_mhz = 1557 + fixed16_to_double_to_cpu(bb->clock_limits[i].dppclk_mhz); 1558 + dcn3_01_soc.clock_limits[i].phyclk_mhz = 1559 + fixed16_to_double_to_cpu(bb->clock_limits[i].phyclk_mhz); 1560 + dcn3_01_soc.clock_limits[i].socclk_mhz = 1561 + fixed16_to_double_to_cpu(bb->clock_limits[i].socclk_mhz); 1562 + dcn3_01_soc.clock_limits[i].dscclk_mhz = 1563 + fixed16_to_double_to_cpu(bb->clock_limits[i].dscclk_mhz); 1564 + dcn3_01_soc.clock_limits[i].dram_speed_mts = 1565 + fixed16_to_double_to_cpu(bb->clock_limits[i].dram_speed_mts); 1566 + } 1567 + } 1568 + 1569 + if (pool->base.pp_smu) { 1570 + struct pp_smu_nv_clock_table max_clocks = {0}; 1571 + unsigned int uclk_states[8] = {0}; 1572 + unsigned int num_states = 0; 1573 + enum pp_smu_status status; 1574 + bool clock_limits_available = false; 1575 + bool uclk_states_available = false; 1576 + 1577 + if (pool->base.pp_smu->nv_funcs.get_uclk_dpm_states) { 1578 + status = (pool->base.pp_smu->nv_funcs.get_uclk_dpm_states) 1579 + (&pool->base.pp_smu->nv_funcs.pp_smu, uclk_states, &num_states); 1580 + 1581 + uclk_states_available = (status == PP_SMU_RESULT_OK); 1582 + } 1583 + 1584 + if (pool->base.pp_smu->nv_funcs.get_maximum_sustainable_clocks) { 1585 + status = (*pool->base.pp_smu->nv_funcs.get_maximum_sustainable_clocks) 1586 + (&pool->base.pp_smu->nv_funcs.pp_smu, &max_clocks); 1587 + /* SMU cannot set DCF clock to anything equal to or higher than SOC clock 1588 + */ 1589 + if (max_clocks.dcfClockInKhz >= max_clocks.socClockInKhz) 1590 + max_clocks.dcfClockInKhz = max_clocks.socClockInKhz - 1000; 1591 + clock_limits_available = (status == PP_SMU_RESULT_OK); 1592 + } 1593 + 1594 + if (clock_limits_available && uclk_states_available && num_states) 1595 + dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states); 1596 + else if (clock_limits_available) 1597 + dcn20_cap_soc_clocks(loaded_bb, max_clocks); 1598 + } 1599 + 1600 + loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; 1601 + loaded_ip->max_num_dpp = pool->base.pipe_count; 1602 + dcn20_patch_bounding_box(dc, loaded_bb); 1603 + 1604 + return true; 1605 + } 1606 + 1607 + static void set_wm_ranges( 1608 + struct pp_smu_funcs *pp_smu, 1609 + struct _vcs_dpi_soc_bounding_box_st *loaded_bb) 1610 + { 1611 + struct pp_smu_wm_range_sets ranges = {0}; 1612 + int i; 1613 + 1614 + ranges.num_reader_wm_sets = 0; 1615 + 1616 + if (loaded_bb->num_states == 1) { 1617 + ranges.reader_wm_sets[0].wm_inst = 0; 1618 + ranges.reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; 1619 + ranges.reader_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; 1620 + ranges.reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; 1621 + ranges.reader_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; 1622 + 1623 + ranges.num_reader_wm_sets = 1; 1624 + } else if (loaded_bb->num_states > 1) { 1625 + for (i = 0; i < 4 && i < loaded_bb->num_states; i++) { 1626 + ranges.reader_wm_sets[i].wm_inst = i; 1627 + ranges.reader_wm_sets[i].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; 1628 + ranges.reader_wm_sets[i].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; 1629 + ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0; 1630 + ranges.reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16; 1631 + 1632 + ranges.num_reader_wm_sets = i + 1; 1633 + } 1634 + 1635 + ranges.reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; 1636 + ranges.reader_wm_sets[ranges.num_reader_wm_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; 1637 + } 1638 + 1639 + ranges.num_writer_wm_sets = 1; 1640 + 1641 + ranges.writer_wm_sets[0].wm_inst = 0; 1642 + ranges.writer_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; 1643 + ranges.writer_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; 1644 + ranges.writer_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; 1645 + ranges.writer_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; 1646 + 1647 + /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ 1648 + pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges); 1649 + } 1650 + 1651 + static struct pp_smu_funcs *dcn301_pp_smu_create(struct dc_context *ctx) 1652 + { 1653 + struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); 1654 + 1655 + if (!pp_smu) 1656 + return pp_smu; 1657 + 1658 + if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && !IS_DIAG_DC(ctx->dce_environment)) { 1659 + dm_pp_get_funcs(ctx, pp_smu); 1660 + 1661 + /* TODO: update once we have n21 smu*/ 1662 + if (pp_smu->ctx.ver != PP_SMU_VER_NV) 1663 + pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs)); 1664 + } 1665 + 1666 + return pp_smu; 1667 + } 1668 + 1669 + static void dcn301_pp_smu_destroy(struct pp_smu_funcs **pp_smu) 1670 + { 1671 + if (pp_smu && *pp_smu) { 1672 + kfree(*pp_smu); 1673 + *pp_smu = NULL; 1674 + } 1675 + } 1676 + 1677 + static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) 1678 + { 1679 + dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 1680 + dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; 1681 + } 1682 + 1683 + static struct resource_funcs dcn301_res_pool_funcs = { 1684 + .destroy = dcn301_destroy_resource_pool, 1685 + .link_enc_create = dcn301_link_encoder_create, 1686 + .panel_cntl_create = dcn301_panel_cntl_create, 1687 + .validate_bandwidth = dcn30_validate_bandwidth, 1688 + .calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg, 1689 + .populate_dml_pipes = dcn30_populate_dml_pipes_from_context, 1690 + .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, 1691 + .add_stream_to_ctx = dcn30_add_stream_to_ctx, 1692 + .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, 1693 + .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, 1694 + .set_mcif_arb_params = dcn30_set_mcif_arb_params, 1695 + .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, 1696 + .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, 1697 + .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, 1698 + .update_bw_bounding_box = dcn301_update_bw_bounding_box 1699 + }; 1700 + 1701 + static bool dcn301_resource_construct( 1702 + uint8_t num_virtual_links, 1703 + struct dc *dc, 1704 + struct dcn301_resource_pool *pool) 1705 + { 1706 + int i, j; 1707 + struct dc_context *ctx = dc->ctx; 1708 + struct irq_service_init_data init_data; 1709 + uint32_t pipe_fuses = read_pipe_fuses(ctx); 1710 + uint32_t num_pipes = 0; 1711 + 1712 + DC_LOGGER_INIT(dc->ctx->logger); 1713 + 1714 + ctx->dc_bios->regs = &bios_regs; 1715 + 1716 + pool->base.res_cap = &res_cap_dcn301; 1717 + 1718 + pool->base.funcs = &dcn301_res_pool_funcs; 1719 + 1720 + /************************************************* 1721 + * Resource + asic cap harcoding * 1722 + *************************************************/ 1723 + pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1724 + pool->base.pipe_count = pool->base.res_cap->num_timing_generator; 1725 + pool->base.mpcc_count = pool->base.res_cap->num_timing_generator; 1726 + dc->caps.max_downscale_ratio = 600; 1727 + dc->caps.i2c_speed_in_khz = 100; 1728 + dc->caps.max_cursor_size = 256; 1729 + dc->caps.dmdata_alloc_size = 2048; 1730 + dc->caps.max_slave_planes = 1; 1731 + dc->caps.is_apu = true; 1732 + dc->caps.post_blend_color_processing = true; 1733 + dc->caps.force_dp_tps4_for_cp2520 = true; 1734 + dc->caps.extended_aux_timeout_support = true; 1735 + #ifdef CONFIG_DRM_AMD_DC_DMUB 1736 + dc->caps.dmcub_support = true; 1737 + #endif 1738 + 1739 + /* Color pipeline capabilities */ 1740 + dc->caps.color.dpp.dcn_arch = 1; 1741 + dc->caps.color.dpp.input_lut_shared = 0; 1742 + dc->caps.color.dpp.icsc = 1; 1743 + dc->caps.color.dpp.dgam_ram = 0; // must use gamma_corr 1744 + dc->caps.color.dpp.dgam_rom_caps.srgb = 1; 1745 + dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1; 1746 + dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 1; 1747 + dc->caps.color.dpp.dgam_rom_caps.pq = 1; 1748 + dc->caps.color.dpp.dgam_rom_caps.hlg = 1; 1749 + dc->caps.color.dpp.post_csc = 1; 1750 + dc->caps.color.dpp.gamma_corr = 1; 1751 + 1752 + dc->caps.color.dpp.hw_3d_lut = 1; 1753 + dc->caps.color.dpp.ogam_ram = 1; 1754 + // no OGAM ROM on DCN301 1755 + dc->caps.color.dpp.ogam_rom_caps.srgb = 0; 1756 + dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0; 1757 + dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0; 1758 + dc->caps.color.dpp.ogam_rom_caps.pq = 0; 1759 + dc->caps.color.dpp.ogam_rom_caps.hlg = 0; 1760 + dc->caps.color.dpp.ocsc = 0; 1761 + 1762 + dc->caps.color.mpc.gamut_remap = 1; 1763 + dc->caps.color.mpc.num_3dluts = pool->base.res_cap->num_mpc_3dlut; //2 1764 + dc->caps.color.mpc.ogam_ram = 1; 1765 + dc->caps.color.mpc.ogam_rom_caps.srgb = 0; 1766 + dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0; 1767 + dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0; 1768 + dc->caps.color.mpc.ogam_rom_caps.pq = 0; 1769 + dc->caps.color.mpc.ogam_rom_caps.hlg = 0; 1770 + dc->caps.color.mpc.ocsc = 1; 1771 + 1772 + if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) 1773 + dc->debug = debug_defaults_drv; 1774 + else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { 1775 + dc->debug = debug_defaults_diags; 1776 + } else 1777 + dc->debug = debug_defaults_diags; 1778 + // Init the vm_helper 1779 + if (dc->vm_helper) 1780 + vm_helper_init(dc->vm_helper, 16); 1781 + 1782 + /************************************************* 1783 + * Create resources * 1784 + *************************************************/ 1785 + 1786 + /* Clock Sources for Pixel Clock*/ 1787 + pool->base.clock_sources[DCN301_CLK_SRC_PLL0] = 1788 + dcn301_clock_source_create(ctx, ctx->dc_bios, 1789 + CLOCK_SOURCE_COMBO_PHY_PLL0, 1790 + &clk_src_regs[0], false); 1791 + pool->base.clock_sources[DCN301_CLK_SRC_PLL1] = 1792 + dcn301_clock_source_create(ctx, ctx->dc_bios, 1793 + CLOCK_SOURCE_COMBO_PHY_PLL1, 1794 + &clk_src_regs[1], false); 1795 + pool->base.clock_sources[DCN301_CLK_SRC_PLL2] = 1796 + dcn301_clock_source_create(ctx, ctx->dc_bios, 1797 + CLOCK_SOURCE_COMBO_PHY_PLL2, 1798 + &clk_src_regs[2], false); 1799 + pool->base.clock_sources[DCN301_CLK_SRC_PLL3] = 1800 + dcn301_clock_source_create(ctx, ctx->dc_bios, 1801 + CLOCK_SOURCE_COMBO_PHY_PLL3, 1802 + &clk_src_regs[3], false); 1803 + 1804 + pool->base.clk_src_count = DCN301_CLK_SRC_TOTAL; 1805 + 1806 + /* todo: not reuse phy_pll registers */ 1807 + pool->base.dp_clock_source = 1808 + dcn301_clock_source_create(ctx, ctx->dc_bios, 1809 + CLOCK_SOURCE_ID_DP_DTO, 1810 + &clk_src_regs[0], true); 1811 + 1812 + for (i = 0; i < pool->base.clk_src_count; i++) { 1813 + if (pool->base.clock_sources[i] == NULL) { 1814 + dm_error("DC: failed to create clock sources!\n"); 1815 + BREAK_TO_DEBUGGER(); 1816 + goto create_fail; 1817 + } 1818 + } 1819 + 1820 + /* DCCG */ 1821 + pool->base.dccg = dccg301_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask); 1822 + if (pool->base.dccg == NULL) { 1823 + dm_error("DC: failed to create dccg!\n"); 1824 + BREAK_TO_DEBUGGER(); 1825 + goto create_fail; 1826 + } 1827 + 1828 + /* PP Lib and SMU interfaces */ 1829 + pool->base.pp_smu = dcn301_pp_smu_create(ctx); 1830 + init_soc_bounding_box(dc, pool); 1831 + if (!dc->debug.disable_pplib_wm_range && pool->base.pp_smu->nv_funcs.set_wm_ranges) 1832 + set_wm_ranges(pool->base.pp_smu, &dcn3_01_soc); 1833 + 1834 + num_pipes = dcn3_01_ip.max_num_dpp; 1835 + 1836 + for (i = 0; i < dcn3_01_ip.max_num_dpp; i++) 1837 + if (pipe_fuses & 1 << i) 1838 + num_pipes--; 1839 + dcn3_01_ip.max_num_dpp = num_pipes; 1840 + dcn3_01_ip.max_num_otg = num_pipes; 1841 + 1842 + 1843 + dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30); 1844 + 1845 + /* IRQ */ 1846 + init_data.ctx = dc->ctx; 1847 + pool->base.irqs = dal_irq_service_dcn30_create(&init_data); 1848 + if (!pool->base.irqs) 1849 + goto create_fail; 1850 + 1851 + /* HUBBUB */ 1852 + pool->base.hubbub = dcn301_hubbub_create(ctx); 1853 + if (pool->base.hubbub == NULL) { 1854 + BREAK_TO_DEBUGGER(); 1855 + dm_error("DC: failed to create hubbub!\n"); 1856 + goto create_fail; 1857 + } 1858 + 1859 + j = 0; 1860 + /* HUBPs, DPPs, OPPs and TGs */ 1861 + for (i = 0; i < pool->base.pipe_count; i++) { 1862 + 1863 + /* if pipe is disabled, skip instance of HW pipe, 1864 + * i.e, skip ASIC register instance 1865 + */ 1866 + if ((pipe_fuses & (1 << i)) != 0) { 1867 + DC_LOG_DEBUG("%s: fusing pipe %d\n", __func__, i); 1868 + continue; 1869 + } 1870 + 1871 + pool->base.hubps[j] = dcn301_hubp_create(ctx, i); 1872 + if (pool->base.hubps[j] == NULL) { 1873 + BREAK_TO_DEBUGGER(); 1874 + dm_error( 1875 + "DC: failed to create hubps!\n"); 1876 + goto create_fail; 1877 + } 1878 + 1879 + pool->base.dpps[j] = dcn301_dpp_create(ctx, i); 1880 + if (pool->base.dpps[j] == NULL) { 1881 + BREAK_TO_DEBUGGER(); 1882 + dm_error( 1883 + "DC: failed to create dpps!\n"); 1884 + goto create_fail; 1885 + } 1886 + 1887 + pool->base.opps[j] = dcn301_opp_create(ctx, i); 1888 + if (pool->base.opps[j] == NULL) { 1889 + BREAK_TO_DEBUGGER(); 1890 + dm_error( 1891 + "DC: failed to create output pixel processor!\n"); 1892 + goto create_fail; 1893 + } 1894 + 1895 + pool->base.timing_generators[j] = dcn301_timing_generator_create(ctx, i); 1896 + if (pool->base.timing_generators[j] == NULL) { 1897 + BREAK_TO_DEBUGGER(); 1898 + dm_error("DC: failed to create tg!\n"); 1899 + goto create_fail; 1900 + } 1901 + j++; 1902 + } 1903 + pool->base.timing_generator_count = j; 1904 + pool->base.pipe_count = j; 1905 + pool->base.mpcc_count = j; 1906 + 1907 + /* ABM (or ABMs for NV2x) */ 1908 + /* TODO: */ 1909 + for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { 1910 + pool->base.multiple_abms[i] = dce_abm_create(ctx, 1911 + &abm_regs[i], 1912 + &abm_shift, 1913 + &abm_mask); 1914 + if (pool->base.multiple_abms[i] == NULL) { 1915 + dm_error("DC: failed to create abm for pipe %d!\n", i); 1916 + BREAK_TO_DEBUGGER(); 1917 + goto create_fail; 1918 + } 1919 + } 1920 + 1921 + /* MPC and DSC */ 1922 + pool->base.mpc = dcn301_mpc_create(ctx, pool->base.mpcc_count, pool->base.res_cap->num_mpc_3dlut); 1923 + if (pool->base.mpc == NULL) { 1924 + BREAK_TO_DEBUGGER(); 1925 + dm_error("DC: failed to create mpc!\n"); 1926 + goto create_fail; 1927 + } 1928 + 1929 + for (i = 0; i < pool->base.res_cap->num_dsc; i++) { 1930 + pool->base.dscs[i] = dcn301_dsc_create(ctx, i); 1931 + if (pool->base.dscs[i] == NULL) { 1932 + BREAK_TO_DEBUGGER(); 1933 + dm_error("DC: failed to create display stream compressor %d!\n", i); 1934 + goto create_fail; 1935 + } 1936 + } 1937 + 1938 + /* DWB and MMHUBBUB */ 1939 + if (!dcn301_dwbc_create(ctx, &pool->base)) { 1940 + BREAK_TO_DEBUGGER(); 1941 + dm_error("DC: failed to create dwbc!\n"); 1942 + goto create_fail; 1943 + } 1944 + 1945 + if (!dcn301_mmhubbub_create(ctx, &pool->base)) { 1946 + BREAK_TO_DEBUGGER(); 1947 + dm_error("DC: failed to create mcif_wb!\n"); 1948 + goto create_fail; 1949 + } 1950 + 1951 + /* AUX and I2C */ 1952 + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { 1953 + pool->base.engines[i] = dcn301_aux_engine_create(ctx, i); 1954 + if (pool->base.engines[i] == NULL) { 1955 + BREAK_TO_DEBUGGER(); 1956 + dm_error( 1957 + "DC:failed to create aux engine!!\n"); 1958 + goto create_fail; 1959 + } 1960 + pool->base.hw_i2cs[i] = dcn301_i2c_hw_create(ctx, i); 1961 + if (pool->base.hw_i2cs[i] == NULL) { 1962 + BREAK_TO_DEBUGGER(); 1963 + dm_error( 1964 + "DC:failed to create hw i2c!!\n"); 1965 + goto create_fail; 1966 + } 1967 + pool->base.sw_i2cs[i] = NULL; 1968 + } 1969 + 1970 + /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */ 1971 + if (!resource_construct(num_virtual_links, dc, &pool->base, 1972 + (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? 1973 + &res_create_funcs : &res_create_maximus_funcs))) 1974 + goto create_fail; 1975 + 1976 + /* HW Sequencer and Plane caps */ 1977 + dcn301_hw_sequencer_construct(dc); 1978 + 1979 + dc->caps.max_planes = pool->base.pipe_count; 1980 + 1981 + for (i = 0; i < dc->caps.max_planes; ++i) 1982 + dc->caps.planes[i] = plane_cap; 1983 + 1984 + dc->cap_funcs = cap_funcs; 1985 + 1986 + return true; 1987 + 1988 + create_fail: 1989 + 1990 + dcn301_destruct(pool); 1991 + 1992 + return false; 1993 + } 1994 + 1995 + struct resource_pool *dcn301_create_resource_pool( 1996 + const struct dc_init_data *init_data, 1997 + struct dc *dc) 1998 + { 1999 + struct dcn301_resource_pool *pool = 2000 + kzalloc(sizeof(struct dcn301_resource_pool), GFP_KERNEL); 2001 + 2002 + if (!pool) 2003 + return NULL; 2004 + 2005 + if (dcn301_resource_construct(init_data->num_virtual_links, dc, pool)) 2006 + return &pool->base; 2007 + 2008 + BREAK_TO_DEBUGGER(); 2009 + kfree(pool); 2010 + return NULL; 2011 + }
+42
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_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 _DCN301_RESOURCE_H_ 27 + #define _DCN301_RESOURCE_H_ 28 + 29 + #include "core_types.h" 30 + 31 + struct dc; 32 + struct resource_pool; 33 + struct _vcs_dpi_display_pipe_params_st; 34 + 35 + struct dcn301_resource_pool { 36 + struct resource_pool base; 37 + }; 38 + struct resource_pool *dcn301_create_resource_pool( 39 + const struct dc_init_data *init_data, 40 + struct dc *dc); 41 + 42 + #endif /* _DCN301_RESOURCE_H_ */
+25 -1
drivers/gpu/drm/amd/display/dc/dm_pp_smu.h
··· 278 278 enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp, 279 279 struct dpm_clocks *clock_table); 280 280 }; 281 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 282 + struct pp_smu_funcs_vgh { 283 + struct pp_smu pp_smu; 281 284 285 + /* 286 + * reader and writer WM's are sent together as part of one table 287 + * 288 + * PPSMC_MSG_SetDriverDramAddrHigh 289 + * PPSMC_MSG_SetDriverDramAddrLow 290 + * PPSMC_MSG_TransferTableDram2Smu 291 + * 292 + */ 293 + // TODO: Check whether this is moved to DAL, and remove as needed 294 + enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp, 295 + struct pp_smu_wm_range_sets *ranges); 296 + 297 + // TODO: Check whether this is moved to DAL, and remove as needed 298 + enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp, 299 + struct dpm_clocks *clock_table); 300 + 301 + enum pp_smu_status (*notify_smu_timeout) (struct pp_smu *pp); 302 + }; 303 + #endif 282 304 struct pp_smu_funcs { 283 305 struct pp_smu ctx; 284 306 union { 285 307 struct pp_smu_funcs_rv rv_funcs; 286 308 struct pp_smu_funcs_nv nv_funcs; 287 309 struct pp_smu_funcs_rn rn_funcs; 288 - 310 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 311 + struct pp_smu_funcs_vgh vgh_funcs; 312 + #endif 289 313 }; 290 314 }; 291 315
+3
drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
··· 114 114 #endif 115 115 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 116 116 case DCN_VERSION_3_0: 117 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 118 + case DCN_VERSION_3_01: 119 + #endif 117 120 dal_hw_factory_dcn30_init(factory); 118 121 return true; 119 122 #endif
+3
drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
··· 109 109 #endif 110 110 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 111 111 case DCN_VERSION_3_0: 112 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 113 + case DCN_VERSION_3_01: 114 + #endif 112 115 dal_hw_translate_dcn30_init(translate); 113 116 return true; 114 117 #endif
+33
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
··· 62 62 }; 63 63 64 64 #endif 65 + 66 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 67 + struct dcn301_clk_internal { 68 + int dummy; 69 + uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk 70 + uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk 71 + uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk 72 + uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk 73 + uint32_t CLK1_CLK3_DS_CNTL; //dcf_deep_sleep_divider 74 + uint32_t CLK1_CLK3_ALLOW_DS; //dcf_deep_sleep_allow 75 + 76 + uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass 77 + uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass 78 + uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass 79 + uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass 80 + }; 81 + 82 + #endif 83 + 65 84 /* Will these bw structures be ASIC specific? */ 66 85 67 86 #define MAX_NUM_DPM_LVL 8 ··· 281 262 #endif 282 263 }; 283 264 265 + #ifdef CONFIG_DRM_AMD_DC_DCN3_01 266 + struct dpm_clocks; 267 + struct wartermarks; 268 + 269 + struct smu_watermark_set { 270 + struct watermarks *wm_set; 271 + union large_integer mc_address; 272 + }; 273 + 274 + #endif 275 + 284 276 struct clk_mgr { 285 277 struct dc_context *ctx; 286 278 struct clk_mgr_funcs *funcs; ··· 305 275 struct clk_state_registers_and_bypass boot_snapshot; 306 276 struct clk_bw_params *bw_params; 307 277 struct pp_smu_wm_range_sets ranges; 278 + #ifdef CONFIG_DRM_AMD_DC_DCN3_01 279 + struct smu_watermark_set smu_wm_set; 280 + #endif 308 281 }; 309 282 310 283 /* forward declarations */
+4
drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
··· 152 152 void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub); 153 153 154 154 void (*force_wm_propagate_to_pipes)(struct hubbub *hubbub); 155 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 156 + 157 + void (*force_pstate_change_control)(struct hubbub *hubbub, bool force, bool allow); 158 + #endif 155 159 }; 156 160 157 161 struct hubbub {
+5
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
··· 187 187 struct _vcs_dpi_display_rq_regs_st *dml_rq_regs, 188 188 struct _vcs_dpi_display_dlg_regs_st *dml_dlg_attr, 189 189 struct _vcs_dpi_display_ttu_regs_st *dml_ttu_attr); 190 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 191 + void (*set_unbounded_requesting)( 192 + struct hubp *hubp, 193 + bool enable); 194 + #endif 190 195 191 196 }; 192 197
+3
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
··· 91 91 #ifdef CONFIG_DRM_AMD_DC_DCN3_0 92 92 DMUB_ASIC_DCN30, 93 93 #endif 94 + #ifdef CONFIG_DRM_AMD_DC_DCN3_01 95 + DMUB_ASIC_DCN301, 96 + #endif 94 97 DMUB_ASIC_MAX, 95 98 }; 96 99
+1 -1
drivers/gpu/drm/amd/display/dmub/src/Makefile
··· 22 22 23 23 DMUB = dmub_srv.o dmub_reg.o dmub_dcn20.o dmub_dcn21.o 24 24 ifdef CONFIG_DRM_AMD_DC_DCN3_0 25 - DMUB += dmub_dcn30.o 25 + DMUB += dmub_dcn30.o dmub_dcn301.o 26 26 endif 27 27 28 28 AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB))
+55
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.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_dcn301.h" 29 + 30 + #include "dcn/dcn_3_0_1_offset.h" 31 + #include "dcn/dcn_3_0_1_sh_mask.h" 32 + #include "vangogh_ip_offset.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_dcn301_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_dcn301.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_DCN301_H_ 27 + #define _DMUB_DCN301_H_ 28 + 29 + #include "dmub_dcn20.h" 30 + 31 + /* Registers. */ 32 + 33 + extern const struct dmub_srv_common_regs dmub_srv_dcn301_regs; 34 + 35 + /* Hardware functions. */ 36 + 37 + #endif /* _DMUB_DCN301_H_ */
+14
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
··· 30 30 #ifdef CONFIG_DRM_AMD_DC_DCN3_0 31 31 #include "dmub_dcn30.h" 32 32 #endif 33 + #ifdef CONFIG_DRM_AMD_DC_DCN3_01 34 + #include "dmub_dcn301.h" 35 + #endif 33 36 #include "os_types.h" 34 37 /* 35 38 * Note: the DMUB service is standalone. No additional headers should be ··· 142 139 #ifdef CONFIG_DRM_AMD_DC_DCN3_0 143 140 case DMUB_ASIC_DCN30: 144 141 #endif 142 + #ifdef CONFIG_DRM_AMD_DC_DCN3_01 143 + case DMUB_ASIC_DCN301: 144 + #endif 145 145 dmub->regs = &dmub_srv_dcn20_regs; 146 146 147 147 funcs->reset = dmub_dcn20_reset; ··· 171 165 dmub->regs = &dmub_srv_dcn30_regs; 172 166 173 167 funcs->is_auto_load_done = dmub_dcn30_is_auto_load_done; 168 + funcs->backdoor_load = dmub_dcn30_backdoor_load; 169 + funcs->setup_windows = dmub_dcn30_setup_windows; 170 + } 171 + #endif 172 + #ifdef CONFIG_DRM_AMD_DC_DCN3_01 173 + if (asic == DMUB_ASIC_DCN301) { 174 + dmub->regs = &dmub_srv_dcn301_regs; 175 + 174 176 funcs->backdoor_load = dmub_dcn30_backdoor_load; 175 177 funcs->setup_windows = dmub_dcn30_setup_windows; 176 178 }
+10
drivers/gpu/drm/amd/display/include/dal_asic_id.h
··· 205 205 #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 206 206 #define ASICREV_IS_SIENNA_CICHLID_P(eChipRev) ((eChipRev >= NV_SIENNA_CICHLID_P_A0)) 207 207 #endif 208 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 209 + #define FAMILY_VGH 144 210 + #define DEVICE_ID_VGH_163F 0x163F 211 + #define VANGOGH_A0 0x01 212 + #define VANGOGH_UNKNOWN 0xFF 213 + 214 + #ifndef ASICREV_IS_VANGOGH 215 + #define ASICREV_IS_VANGOGH(eChipRev) ((eChipRev >= VANGOGH_A0) && (eChipRev < VANGOGH_UNKNOWN)) 216 + #endif 217 + #endif 208 218 209 219 /* 210 220 * ASIC chip ID
+5
drivers/gpu/drm/amd/display/include/dal_types.h
··· 51 51 DCN_VERSION_1_01, 52 52 DCN_VERSION_2_0, 53 53 DCN_VERSION_2_1, 54 + #if defined(CONFIG_DRM_AMD_DC_DCN3_0) 54 55 DCN_VERSION_3_0, 56 + #endif 57 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 58 + DCN_VERSION_3_01, 59 + #endif 55 60 DCN_VERSION_MAX 56 61 }; 57 62
+17
drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
··· 284 284 struct i2c_reg_info reg_settings_6g[3]; 285 285 }; 286 286 287 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 288 + struct edp_info { 289 + uint16_t edp_backlight_pwm_hz; 290 + uint16_t edp_ss_percentage; 291 + uint16_t edp_ss_rate_10hz; 292 + uint8_t edp_pwr_on_off_delay; 293 + uint8_t edp_pwr_on_vary_bl_to_blon; 294 + uint8_t edp_pwr_down_bloff_to_vary_bloff; 295 + uint8_t edp_panel_bpc; 296 + uint8_t edp_bootup_bl_level; 297 + }; 298 + #endif 287 299 288 300 /* V6 */ 289 301 struct integrated_info { ··· 415 403 struct i2c_reg_info dp3_ext_hdmi_6g_reg_settings[3]; 416 404 /* V11 */ 417 405 uint32_t dp_ss_control; 406 + #if defined(CONFIG_DRM_AMD_DC_DCN3_01) 407 + /* V2.1 */ 408 + struct edp_info edp1_info; 409 + struct edp_info edp2_info; 410 + #endif 418 411 }; 419 412 420 413 /**