30
30
#include "dc.h"
31
31
#include "dc/inc/core_types.h"
32
32
#include "dal_asic_id.h"
33
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
34
+ #include "dmub/inc/dmub_srv.h"
35
+ #include "dc/inc/hw/dmcu.h"
36
+ #include "dc/inc/hw/abm.h"
37
+ #endif
33
38
34
39
#include "vid.h"
35
40
#include "amdgpu.h"
87
92
#include "modules/power/power_helpers.h"
88
93
#include "modules/inc/mod_info_packet.h"
89
94
95
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
96
+ #define FIRMWARE_RENOIR_DMUB "amdgpu/renoir_dmcub.bin"
97
+ MODULE_FIRMWARE (FIRMWARE_RENOIR_DMUB );
98
+ #endif
90
99
#define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin"
91
100
MODULE_FIRMWARE (FIRMWARE_RAVEN_DMCU );
92
101
@@ -667,12 +676,149 @@ void amdgpu_dm_audio_eld_notify(struct amdgpu_device *adev, int pin)
667
676
}
668
677
}
669
678
679
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
680
+ static int dm_dmub_hw_init (struct amdgpu_device * adev )
681
+ {
682
+ const unsigned int psp_header_bytes = 0x100 ;
683
+ const unsigned int psp_footer_bytes = 0x100 ;
684
+ const struct dmcub_firmware_header_v1_0 * hdr ;
685
+ struct dmub_srv * dmub_srv = adev -> dm .dmub_srv ;
686
+ const struct firmware * dmub_fw = adev -> dm .dmub_fw ;
687
+ struct dmcu * dmcu = adev -> dm .dc -> res_pool -> dmcu ;
688
+ struct abm * abm = adev -> dm .dc -> res_pool -> abm ;
689
+ struct dmub_srv_region_params region_params ;
690
+ struct dmub_srv_region_info region_info ;
691
+ struct dmub_srv_fb_params fb_params ;
692
+ struct dmub_srv_fb_info fb_info ;
693
+ struct dmub_srv_hw_params hw_params ;
694
+ enum dmub_status status ;
695
+ const unsigned char * fw_inst_const , * fw_bss_data ;
696
+ uint32_t i ;
697
+ int r ;
698
+ bool has_hw_support ;
699
+
700
+ if (!dmub_srv )
701
+ /* DMUB isn't supported on the ASIC. */
702
+ return 0 ;
703
+
704
+ if (!dmub_fw ) {
705
+ /* Firmware required for DMUB support. */
706
+ DRM_ERROR ("No firmware provided for DMUB.\n" );
707
+ return - EINVAL ;
708
+ }
709
+
710
+ status = dmub_srv_has_hw_support (dmub_srv , & has_hw_support );
711
+ if (status != DMUB_STATUS_OK ) {
712
+ DRM_ERROR ("Error checking HW support for DMUB: %d\n" , status );
713
+ return - EINVAL ;
714
+ }
715
+
716
+ if (!has_hw_support ) {
717
+ DRM_INFO ("DMUB unsupported on ASIC\n" );
718
+ return 0 ;
719
+ }
720
+
721
+ hdr = (const struct dmcub_firmware_header_v1_0 * )dmub_fw -> data ;
722
+
723
+ /* Calculate the size of all the regions for the DMUB service. */
724
+ memset (& region_params , 0 , sizeof (region_params ));
725
+
726
+ region_params .inst_const_size = le32_to_cpu (hdr -> inst_const_bytes ) -
727
+ psp_header_bytes - psp_footer_bytes ;
728
+ region_params .bss_data_size = le32_to_cpu (hdr -> bss_data_bytes );
729
+ region_params .vbios_size = adev -> dm .dc -> ctx -> dc_bios -> bios_size ;
730
+
731
+ status = dmub_srv_calc_region_info (dmub_srv , & region_params ,
732
+ & region_info );
733
+
734
+ if (status != DMUB_STATUS_OK ) {
735
+ DRM_ERROR ("Error calculating DMUB region info: %d\n" , status );
736
+ return - EINVAL ;
737
+ }
738
+
739
+ /*
740
+ * Allocate a framebuffer based on the total size of all the regions.
741
+ * TODO: Move this into GART.
742
+ */
743
+ r = amdgpu_bo_create_kernel (adev , region_info .fb_size , PAGE_SIZE ,
744
+ AMDGPU_GEM_DOMAIN_VRAM , & adev -> dm .dmub_bo ,
745
+ & adev -> dm .dmub_bo_gpu_addr ,
746
+ & adev -> dm .dmub_bo_cpu_addr );
747
+ if (r )
748
+ return r ;
749
+
750
+ /* Rebase the regions on the framebuffer address. */
751
+ memset (& fb_params , 0 , sizeof (fb_params ));
752
+ fb_params .cpu_addr = adev -> dm .dmub_bo_cpu_addr ;
753
+ fb_params .gpu_addr = adev -> dm .dmub_bo_gpu_addr ;
754
+ fb_params .region_info = & region_info ;
755
+
756
+ status = dmub_srv_calc_fb_info (dmub_srv , & fb_params , & fb_info );
757
+ if (status != DMUB_STATUS_OK ) {
758
+ DRM_ERROR ("Error calculating DMUB FB info: %d\n" , status );
759
+ return - EINVAL ;
760
+ }
761
+
762
+ fw_inst_const = dmub_fw -> data +
763
+ le32_to_cpu (hdr -> header .ucode_array_offset_bytes ) +
764
+ psp_header_bytes ;
765
+
766
+ fw_bss_data = dmub_fw -> data +
767
+ le32_to_cpu (hdr -> header .ucode_array_offset_bytes ) +
768
+ le32_to_cpu (hdr -> inst_const_bytes );
769
+
770
+ /* Copy firmware and bios info into FB memory. */
771
+ memcpy (fb_info .fb [DMUB_WINDOW_0_INST_CONST ].cpu_addr , fw_inst_const ,
772
+ region_params .inst_const_size );
773
+ memcpy (fb_info .fb [DMUB_WINDOW_2_BSS_DATA ].cpu_addr , fw_bss_data ,
774
+ region_params .bss_data_size );
775
+ memcpy (fb_info .fb [DMUB_WINDOW_3_VBIOS ].cpu_addr ,
776
+ adev -> dm .dc -> ctx -> dc_bios -> bios , region_params .vbios_size );
777
+
778
+ /* Initialize hardware. */
779
+ memset (& hw_params , 0 , sizeof (hw_params ));
780
+ hw_params .fb_base = adev -> gmc .fb_start ;
781
+ hw_params .fb_offset = adev -> gmc .aper_base ;
782
+
783
+ if (dmcu )
784
+ hw_params .psp_version = dmcu -> psp_version ;
785
+
786
+ for (i = 0 ; i < fb_info .num_fb ; ++ i )
787
+ hw_params .fb [i ] = & fb_info .fb [i ];
788
+
789
+ status = dmub_srv_hw_init (dmub_srv , & hw_params );
790
+ if (status != DMUB_STATUS_OK ) {
791
+ DRM_ERROR ("Error initializing DMUB HW: %d\n" , status );
792
+ return - EINVAL ;
793
+ }
794
+
795
+ /* Wait for firmware load to finish. */
796
+ status = dmub_srv_wait_for_auto_load (dmub_srv , 100000 );
797
+ if (status != DMUB_STATUS_OK )
798
+ DRM_WARN ("Wait for DMUB auto-load failed: %d\n" , status );
799
+
800
+ /* Init DMCU and ABM if available. */
801
+ if (dmcu && abm ) {
802
+ dmcu -> funcs -> dmcu_init (dmcu );
803
+ abm -> dmcu_is_running = dmcu -> funcs -> is_dmcu_initialized (dmcu );
804
+ }
805
+
806
+ DRM_INFO ("DMUB hardware initialized: version=0x%08X\n" ,
807
+ adev -> dm .dmcub_fw_version );
808
+
809
+ return 0 ;
810
+ }
811
+
812
+ #endif
670
813
static int amdgpu_dm_init (struct amdgpu_device * adev )
671
814
{
672
815
struct dc_init_data init_data ;
673
816
#ifdef CONFIG_DRM_AMD_DC_HDCP
674
817
struct dc_callback_init init_params ;
675
818
#endif
819
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
820
+ int r ;
821
+ #endif
676
822
677
823
adev -> dm .ddev = adev -> ddev ;
678
824
adev -> dm .adev = adev ;
@@ -749,6 +895,14 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
749
895
750
896
dc_hardware_init (adev -> dm .dc );
751
897
898
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
899
+ r = dm_dmub_hw_init (adev );
900
+ if (r ) {
901
+ DRM_ERROR ("DMUB interface failed to initialize: status=%d\n" , r );
902
+ goto error ;
903
+ }
904
+
905
+ #endif
752
906
adev -> dm .freesync_module = mod_freesync_create (adev -> dm .dc );
753
907
if (!adev -> dm .freesync_module ) {
754
908
DRM_ERROR (
@@ -821,6 +975,12 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
821
975
if (adev -> dm .dc )
822
976
dc_deinit_callbacks (adev -> dm .dc );
823
977
#endif
978
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
979
+ if (adev -> dm .dmub_bo )
980
+ amdgpu_bo_free_kernel (& adev -> dm .dmub_bo ,
981
+ & adev -> dm .dmub_bo_gpu_addr ,
982
+ & adev -> dm .dmub_bo_cpu_addr );
983
+ #endif
824
984
825
985
/* DC Destroy TODO: Replace destroy DAL */
826
986
if (adev -> dm .dc )
@@ -932,9 +1092,104 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
932
1092
return 0 ;
933
1093
}
934
1094
1095
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
1096
+ static uint32_t amdgpu_dm_dmub_reg_read (void * ctx , uint32_t address )
1097
+ {
1098
+ struct amdgpu_device * adev = ctx ;
1099
+
1100
+ return dm_read_reg (adev -> dm .dc -> ctx , address );
1101
+ }
1102
+
1103
+ static void amdgpu_dm_dmub_reg_write (void * ctx , uint32_t address ,
1104
+ uint32_t value )
1105
+ {
1106
+ struct amdgpu_device * adev = ctx ;
1107
+
1108
+ return dm_write_reg (adev -> dm .dc -> ctx , address , value );
1109
+ }
1110
+
1111
+ static int dm_dmub_sw_init (struct amdgpu_device * adev )
1112
+ {
1113
+ struct dmub_srv_create_params create_params ;
1114
+ const struct dmcub_firmware_header_v1_0 * hdr ;
1115
+ const char * fw_name_dmub ;
1116
+ enum dmub_asic dmub_asic ;
1117
+ enum dmub_status status ;
1118
+ int r ;
1119
+
1120
+ switch (adev -> asic_type ) {
1121
+ case CHIP_RENOIR :
1122
+ dmub_asic = DMUB_ASIC_DCN21 ;
1123
+ fw_name_dmub = FIRMWARE_RENOIR_DMUB ;
1124
+ break ;
1125
+
1126
+ default :
1127
+ /* ASIC doesn't support DMUB. */
1128
+ return 0 ;
1129
+ }
1130
+
1131
+ adev -> dm .dmub_srv = kzalloc (sizeof (* adev -> dm .dmub_srv ), GFP_KERNEL );
1132
+ if (!adev -> dm .dmub_srv ) {
1133
+ DRM_ERROR ("Failed to allocate DMUB service!\n" );
1134
+ return - ENOMEM ;
1135
+ }
1136
+
1137
+ memset (& create_params , 0 , sizeof (create_params ));
1138
+ create_params .user_ctx = adev ;
1139
+ create_params .funcs .reg_read = amdgpu_dm_dmub_reg_read ;
1140
+ create_params .funcs .reg_write = amdgpu_dm_dmub_reg_write ;
1141
+ create_params .asic = dmub_asic ;
1142
+
1143
+ status = dmub_srv_create (adev -> dm .dmub_srv , & create_params );
1144
+ if (status != DMUB_STATUS_OK ) {
1145
+ DRM_ERROR ("Error creating DMUB service: %d\n" , status );
1146
+ return - EINVAL ;
1147
+ }
1148
+
1149
+ r = request_firmware_direct (& adev -> dm .dmub_fw , fw_name_dmub , adev -> dev );
1150
+ if (r ) {
1151
+ DRM_ERROR ("DMUB firmware loading failed: %d\n" , r );
1152
+ return 0 ;
1153
+ }
1154
+
1155
+ r = amdgpu_ucode_validate (adev -> dm .dmub_fw );
1156
+ if (r ) {
1157
+ DRM_ERROR ("Couldn't validate DMUB firmware: %d\n" , r );
1158
+ return 0 ;
1159
+ }
1160
+
1161
+ if (adev -> firmware .load_type != AMDGPU_FW_LOAD_PSP ) {
1162
+ DRM_WARN ("Only PSP firmware loading is supported for DMUB\n" );
1163
+ return 0 ;
1164
+ }
1165
+
1166
+ hdr = (const struct dmcub_firmware_header_v1_0 * )adev -> dm .dmub_fw -> data ;
1167
+ adev -> firmware .ucode [AMDGPU_UCODE_ID_DMCUB ].ucode_id =
1168
+ AMDGPU_UCODE_ID_DMCUB ;
1169
+ adev -> firmware .ucode [AMDGPU_UCODE_ID_DMCUB ].fw = adev -> dm .dmub_fw ;
1170
+ adev -> firmware .fw_size +=
1171
+ ALIGN (le32_to_cpu (hdr -> inst_const_bytes ), PAGE_SIZE );
1172
+
1173
+ adev -> dm .dmcub_fw_version = le32_to_cpu (hdr -> header .ucode_version );
1174
+
1175
+ DRM_INFO ("Loading DMUB firmware via PSP: version=0x%08X\n" ,
1176
+ adev -> dm .dmcub_fw_version );
1177
+
1178
+ return 0 ;
1179
+ }
1180
+
1181
+ #endif
935
1182
static int dm_sw_init (void * handle )
936
1183
{
937
1184
struct amdgpu_device * adev = (struct amdgpu_device * )handle ;
1185
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
1186
+ int r ;
1187
+
1188
+ r = dm_dmub_sw_init (adev );
1189
+ if (r )
1190
+ return r ;
1191
+
1192
+ #endif
938
1193
939
1194
return load_dmcu_fw (adev );
940
1195
}
@@ -943,6 +1198,18 @@ static int dm_sw_fini(void *handle)
943
1198
{
944
1199
struct amdgpu_device * adev = (struct amdgpu_device * )handle ;
945
1200
1201
+ #ifdef CONFIG_DRM_AMD_DC_DMUB
1202
+ if (adev -> dm .dmub_srv ) {
1203
+ dmub_srv_destroy (adev -> dm .dmub_srv );
1204
+ adev -> dm .dmub_srv = NULL ;
1205
+ }
1206
+
1207
+ if (adev -> dm .dmub_fw ) {
1208
+ release_firmware (adev -> dm .dmub_fw );
1209
+ adev -> dm .dmub_fw = NULL ;
1210
+ }
1211
+
1212
+ #endif
946
1213
if (adev -> dm .fw_dmcu ) {
947
1214
release_firmware (adev -> dm .fw_dmcu );
948
1215
adev -> dm .fw_dmcu = NULL ;
0 commit comments