Merge tag 'amd-drm-next-6.1-2022-09-08' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.1-2022-09-08: amdgpu: - Mode2 reset for RDNA2 - Lots of new DC documentation - Add documentation about different asic families - DSC improvements - Aldebaran fixes - Misc spelling and grammar fixes - GFXOFF stats support for vangogh - DC frame size fixes - NBIO 7.7 updates - DCN 3.2 updates - DCN 3.1.4 Updates - SMU 13.x updates - Misc bug fixes - Rework DC register offset handling - GC 11.x updates - PSP 13.x updates - SDMA 6.x updates - GMC 11.x updates - SR-IOV updates - PSP fixes for TA unloading - DSC passthrough support - Misc code cleanups amdkfd: - ISA fixes for some GC 10.3 IPs - Misc code cleanups radeon: - Delayed work flush fix - Use time_after for some jiffies calculations drm: - DSC passthrough aux support Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220908155202.57862-1-alexander.deucher@amd.com
							
								
								
									
										8
									
								
								Documentation/gpu/amdgpu/apu-asic-info-table.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version
 | 
				
			||||||
 | 
					Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3
 | 
				
			||||||
 | 
					Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0
 | 
				
			||||||
 | 
					Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2
 | 
				
			||||||
 | 
					Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1
 | 
				
			||||||
 | 
					SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1
 | 
				
			||||||
 | 
					Ryzen 5000 series, GREEN SARDINE, DCN 2.1, 9.3, VCN 2.2, 4.1.1
 | 
				
			||||||
 | 
					Ryzen 6000 Zen, YELLOW CARP, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3
 | 
				
			||||||
		
		
			
  | 
							
								
								
									
										24
									
								
								Documentation/gpu/amdgpu/dgpu-asic-info-table.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					Product Name, Code Reference, DCN/DCE version, GC version, VCN version, SDMA version
 | 
				
			||||||
 | 
					AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series, HAINAN, --,  6, --, --
 | 
				
			||||||
 | 
					AMD Radeon HD 7800 /7900 /FireGL Series, TAHITI, DCE 6, 6, VCE 1 / UVD 3, --
 | 
				
			||||||
 | 
					AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M, OLAND, DCE 6, 6, VCE 1 / UVD 3, --
 | 
				
			||||||
 | 
					AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series, PITCAIRN, DCE 6, 6, VCE 1 / UVD 3, --
 | 
				
			||||||
 | 
					AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series, VERDE, DCE 6, 6, VCE 1 / UVD 3, --
 | 
				
			||||||
 | 
					AMD Radeon HD M280X /M380 /7700 /8950 /W5100, BONAIRE, DCE 8, 7, VCE 2 / UVD 4.2, 1
 | 
				
			||||||
 | 
					AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series, HAWAII, DCE 8, 7, VCE 2 / UVD 4.2, 1
 | 
				
			||||||
 | 
					AMD Radeon (TM) R(5|7) M315 /M340 /M360, TOPAZ, *, 8, --, 2
 | 
				
			||||||
 | 
					AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series, TONGA, DCE 10, 8, VCE 3 / UVD 5, 3
 | 
				
			||||||
 | 
					AMD Radeon (FirePro) (TM) R9 Fury Series, FIJI, DCE 10, 8, VCE 3 / UVD 6, 3
 | 
				
			||||||
 | 
					Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH, POLARIS10, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
 | 
				
			||||||
 | 
					Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series, POLARIS11, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
 | 
				
			||||||
 | 
					Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series, POLARIS12, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
 | 
				
			||||||
 | 
					Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU, VEGA10, DCE 12, 9.0.1, VCE 4.0.0 / UVD 7.0.0, 4.0.0
 | 
				
			||||||
 | 
					AMD Radeon (Pro) VII /MI50 /MI60, VEGA20, DCE 12, 9.4.0, VCE 4.1.0 / UVD 7.2.0, 4.2.0
 | 
				
			||||||
 | 
					MI100, ARCTURUS, *, 9.4.1, VCN 2.5.0, 4.2.2
 | 
				
			||||||
 | 
					MI200, ALDEBARAN, *, 9.4.2, VCN 2.6.0, 4.4.0
 | 
				
			||||||
 | 
					AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700, NAVI10, DCN 2.0.0, 10.1.10, VCN 2.0.0, 5.0.0
 | 
				
			||||||
 | 
					AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500, NAVI14, DCN 2.0.0, 10.1.1, VCN 2.0.2, 5.0.2
 | 
				
			||||||
 | 
					AMD Radeon RX 6800(XT) /6900(XT) /W6800, SIENNA_CICHLID, DCN 3.0.0, 10.3.0, VCN 3.0.0, 5.2.0
 | 
				
			||||||
 | 
					AMD Radeon RX 6700 XT / 6800M / 6700M, NAVY_FLOUNDER, DCN 3.0.0, 10.3.2, VCN 3.0.0, 5.2.2
 | 
				
			||||||
 | 
					AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M, DIMGREY_CAVEFISH, DCN 3.0.2, 10.3.4, VCN 3.0.16, 5.2.4
 | 
				
			||||||
 | 
					AMD Radeon RX 6500M /6300M /W6500M /W6300M, BEIGE_GOBY, DCN 3.0.3, 10.3.5, VCN 3.0.33, 5.2.5
 | 
				
			||||||
		
		
			
  | 
| 
						 | 
					@ -170,7 +170,7 @@ consider asking in the amdgfx and update this page.
 | 
				
			||||||
    MC
 | 
					    MC
 | 
				
			||||||
      Memory Controller
 | 
					      Memory Controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MPC
 | 
					    MPC/MPCC
 | 
				
			||||||
      Multiple pipes and plane combine
 | 
					      Multiple pipes and plane combine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MPO
 | 
					    MPO
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,6 +124,65 @@ depth format), bit-depth reduction/dithering would kick in. In OPP, we would
 | 
				
			||||||
also apply a regamma function to introduce the gamma removed earlier back.
 | 
					also apply a regamma function to introduce the gamma removed earlier back.
 | 
				
			||||||
Eventually, we output data in integer format at DIO.
 | 
					Eventually, we output data in integer format at DIO.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD Hardware Pipeline
 | 
				
			||||||
 | 
					---------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When discussing graphics on Linux, the **pipeline** term can sometimes be
 | 
				
			||||||
 | 
					overloaded with multiple meanings, so it is important to define what we mean
 | 
				
			||||||
 | 
					when we say **pipeline**. In the DCN driver, we use the term **hardware
 | 
				
			||||||
 | 
					pipeline** or **pipeline** or just **pipe** as an abstraction to indicate a
 | 
				
			||||||
 | 
					sequence of DCN blocks instantiated to address some specific configuration. DC
 | 
				
			||||||
 | 
					core treats DCN blocks as individual resources, meaning we can build a pipeline
 | 
				
			||||||
 | 
					by taking resources for all individual hardware blocks to compose one pipeline.
 | 
				
			||||||
 | 
					In actuality, we can't connect an arbitrary block from one pipe to a block from
 | 
				
			||||||
 | 
					another pipe; they are routed linearly, except for DSC, which can be
 | 
				
			||||||
 | 
					arbitrarily assigned as needed. We have this pipeline concept for trying to
 | 
				
			||||||
 | 
					optimize bandwidth utilization.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: pipeline_4k_no_split.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Additionally, let's take a look at parts of the DTN log (see
 | 
				
			||||||
 | 
					'Documentation/gpu/amdgpu/display/dc-debug.rst' for more information) since
 | 
				
			||||||
 | 
					this log can help us to see part of this pipeline behavior in real-time::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 HUBP:  format  addr_hi  width  height ...
 | 
				
			||||||
 | 
					 [ 0]:      8h      81h   3840    2160
 | 
				
			||||||
 | 
					 [ 1]:      0h       0h      0       0
 | 
				
			||||||
 | 
					 [ 2]:      0h       0h      0       0
 | 
				
			||||||
 | 
					 [ 3]:      0h       0h      0       0
 | 
				
			||||||
 | 
					 [ 4]:      0h       0h      0       0
 | 
				
			||||||
 | 
					 ...
 | 
				
			||||||
 | 
					 MPCC:  OPP  DPP ...
 | 
				
			||||||
 | 
					 [ 0]:   0h   0h ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The first thing to notice from the diagram and DTN log it is the fact that we
 | 
				
			||||||
 | 
					have different clock domains for each part of the DCN blocks. In this example,
 | 
				
			||||||
 | 
					we have just a single **pipeline** where the data flows from DCHUB to DIO, as
 | 
				
			||||||
 | 
					we intuitively expect. Nonetheless, DCN is flexible, as mentioned before, and
 | 
				
			||||||
 | 
					we can split this single pipe differently, as described in the below diagram:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: pipeline_4k_split.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now, if we inspect the DTN log again we can see some interesting changes::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 HUBP:  format  addr_hi  width  height ...
 | 
				
			||||||
 | 
					 [ 0]:      8h      81h   1920    2160 ...
 | 
				
			||||||
 | 
					 ...
 | 
				
			||||||
 | 
					 [ 4]:      0h       0h      0       0 ...
 | 
				
			||||||
 | 
					 [ 5]:      8h      81h   1920    2160 ...
 | 
				
			||||||
 | 
					 ...
 | 
				
			||||||
 | 
					 MPCC:  OPP  DPP ...
 | 
				
			||||||
 | 
					 [ 0]:   0h   0h ...
 | 
				
			||||||
 | 
					 [ 5]:   0h   5h ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					From the above example, we now split the display pipeline into two vertical
 | 
				
			||||||
 | 
					parts of 1920x2160 (i.e., 3440x2160), and as a result, we could reduce the
 | 
				
			||||||
 | 
					clock frequency in the DPP part. This is not only useful for saving power but
 | 
				
			||||||
 | 
					also to better handle the required throughput. The idea to keep in mind here is
 | 
				
			||||||
 | 
					that the pipe configuration can vary a lot according to the display
 | 
				
			||||||
 | 
					configuration, and it is the DML's responsibility to set up all required
 | 
				
			||||||
 | 
					configuration parameters for multiple scenarios supported by our hardware.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Global Sync
 | 
					Global Sync
 | 
				
			||||||
-----------
 | 
					-----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1370
									
								
								Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 56 KiB  | 
							
								
								
									
										1529
									
								
								Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 63 KiB  | 
| 
						 | 
					@ -40,3 +40,144 @@ Atomic Implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
 | 
				
			||||||
   :functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail
 | 
					   :functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Color Management Properties
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
 | 
				
			||||||
 | 
					   :doc: overview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
 | 
				
			||||||
 | 
					   :internal:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DC Color Capabilities between DCN generations
 | 
				
			||||||
 | 
					---------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DRM/KMS framework defines three CRTC color correction properties: degamma,
 | 
				
			||||||
 | 
					color transformation matrix (CTM) and gamma, and two properties for degamma and
 | 
				
			||||||
 | 
					gamma LUT sizes. AMD DC programs some of the color correction features
 | 
				
			||||||
 | 
					pre-blending but DRM/KMS has not per-plane color correction properties.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In general, the DRM CRTC color properties are programmed to DC, as follows:
 | 
				
			||||||
 | 
					CRTC gamma after blending, and CRTC degamma pre-blending. Although CTM is
 | 
				
			||||||
 | 
					programmed after blending, it is mapped to DPP hw blocks (pre-blending). Other
 | 
				
			||||||
 | 
					color caps available in the hw is not currently exposed by DRM interface and
 | 
				
			||||||
 | 
					are bypassed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h
 | 
				
			||||||
 | 
					   :doc: color-management-caps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h
 | 
				
			||||||
 | 
					   :internal:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The color pipeline has undergone major changes between DCN hardware
 | 
				
			||||||
 | 
					generations. What's possible to do before and after blending depends on
 | 
				
			||||||
 | 
					hardware capabilities, as illustrated below by the DCN 2.0 and DCN 3.0 families
 | 
				
			||||||
 | 
					schemas.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**DCN 2.0 family color caps and mapping**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: dcn2_cm_drm_current.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**DCN 3.0 family color caps and mapping**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: dcn3_cm_drm_current.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Blend Mode Properties
 | 
				
			||||||
 | 
					=====================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pixel blend mode is a DRM plane composition property of :c:type:`drm_plane` used to
 | 
				
			||||||
 | 
					describes how pixels from a foreground plane (fg) are composited with the
 | 
				
			||||||
 | 
					background plane (bg). Here, we present main concepts of DRM blend mode to help
 | 
				
			||||||
 | 
					to understand how this property is mapped to AMD DC interface. See more about
 | 
				
			||||||
 | 
					this DRM property and the alpha blending equations in :ref:`DRM Plane
 | 
				
			||||||
 | 
					Composition Properties <plane_composition_properties>`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Basically, a blend mode sets the alpha blending equation for plane
 | 
				
			||||||
 | 
					composition that fits the mode in which the alpha channel affects the state of
 | 
				
			||||||
 | 
					pixel color values and, therefore, the resulted pixel color. For
 | 
				
			||||||
 | 
					example, consider the following elements of the alpha blending equation:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- *fg.rgb*: Each of the RGB component values from the foreground's pixel.
 | 
				
			||||||
 | 
					- *fg.alpha*: Alpha component value from the foreground's pixel.
 | 
				
			||||||
 | 
					- *bg.rgb*: Each of the RGB component values from the background.
 | 
				
			||||||
 | 
					- *plane_alpha*: Plane alpha value set by the **plane "alpha" property**, see
 | 
				
			||||||
 | 
					  more in :ref:`DRM Plane Composition Properties <plane_composition_properties>`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					in the basic alpha blending equation::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					the alpha channel value of each pixel in a plane is ignored and only the plane
 | 
				
			||||||
 | 
					alpha affects the resulted pixel color values.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DRM has three blend mode to define the blend formula in the plane composition:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* **None**: Blend formula that ignores the pixel alpha.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* **Pre-multiplied**: Blend formula that assumes the pixel color values in a
 | 
				
			||||||
 | 
					  plane was already pre-multiplied by its own alpha channel before storage.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* **Coverage**: Blend formula that assumes the pixel color values were not
 | 
				
			||||||
 | 
					  pre-multiplied with the alpha channel values.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and pre-multiplied is the default pixel blend mode, that means, when no blend
 | 
				
			||||||
 | 
					mode property is created or defined, DRM considers the plane's pixels has
 | 
				
			||||||
 | 
					pre-multiplied color values. On IGT GPU tools, the kms_plane_alpha_blend test
 | 
				
			||||||
 | 
					provides a set of subtests to verify plane alpha and blend mode properties.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The DRM blend mode and its elements are then mapped by AMDGPU display manager
 | 
				
			||||||
 | 
					(DM) to program the blending configuration of the Multiple Pipe/Plane Combined
 | 
				
			||||||
 | 
					(MPC), as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
 | 
				
			||||||
 | 
					   :doc: mpc-overview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
 | 
				
			||||||
 | 
					   :functions: mpcc_blnd_cfg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Therefore, the blending configuration for a single MPCC instance on the MPC
 | 
				
			||||||
 | 
					tree is defined by :c:type:`mpcc_blnd_cfg`, where
 | 
				
			||||||
 | 
					:c:type:`pre_multiplied_alpha` is the alpha pre-multiplied mode flag used to
 | 
				
			||||||
 | 
					set :c:type:`MPCC_ALPHA_MULTIPLIED_MODE`. It controls whether alpha is
 | 
				
			||||||
 | 
					multiplied (true/false), being only true for DRM pre-multiplied blend mode.
 | 
				
			||||||
 | 
					:c:type:`mpcc_alpha_blend_mode` defines the alpha blend mode regarding pixel
 | 
				
			||||||
 | 
					alpha and plane alpha values. It sets one of the three modes for
 | 
				
			||||||
 | 
					:c:type:`MPCC_ALPHA_BLND_MODE`, as described below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
 | 
				
			||||||
 | 
					   :functions: mpcc_alpha_blend_mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DM then maps the elements of `enum mpcc_alpha_blend_mode` to those in the DRM
 | 
				
			||||||
 | 
					blend formula, as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* *MPC pixel alpha* matches *DRM fg.alpha* as the alpha component value
 | 
				
			||||||
 | 
					  from the plane's pixel
 | 
				
			||||||
 | 
					* *MPC global alpha* matches *DRM plane_alpha* when the pixel alpha should
 | 
				
			||||||
 | 
					  be ignored and, therefore, pixel values are not pre-multiplied
 | 
				
			||||||
 | 
					* *MPC global gain* assumes *MPC global alpha* value when both *DRM
 | 
				
			||||||
 | 
					  fg.alpha* and *DRM plane_alpha* participate in the blend equation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In short, *fg.alpha* is ignored by selecting
 | 
				
			||||||
 | 
					:c:type:`MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA`. On the other hand, (plane_alpha *
 | 
				
			||||||
 | 
					fg.alpha) component becomes available by selecting
 | 
				
			||||||
 | 
					:c:type:`MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN`. And the
 | 
				
			||||||
 | 
					:c:type:`MPCC_ALPHA_MULTIPLIED_MODE` defines if the pixel color values are
 | 
				
			||||||
 | 
					pre-multiplied by alpha or not.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Blend configuration flow
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The alpha blending equation is configured from DRM to DC interface by the
 | 
				
			||||||
 | 
					following path:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. When updating a :c:type:`drm_plane_state <drm_plane_state>`, DM calls
 | 
				
			||||||
 | 
					   :c:type:`fill_blending_from_plane_state()` that maps
 | 
				
			||||||
 | 
					   :c:type:`drm_plane_state <drm_plane_state>` attributes to
 | 
				
			||||||
 | 
					   :c:type:`dc_plane_info <dc_plane_info>` struct to be handled in the
 | 
				
			||||||
 | 
					   OS-agnostic component (DC).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. On DC interface, :c:type:`struct mpcc_blnd_cfg <mpcc_blnd_cfg>` programs the
 | 
				
			||||||
 | 
					   MPCC blend configuration considering the :c:type:`dc_plane_info
 | 
				
			||||||
 | 
					   <dc_plane_info>` input from DPP.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,4 +28,5 @@ table of content:
 | 
				
			||||||
   display-manager.rst
 | 
					   display-manager.rst
 | 
				
			||||||
   dc-debug.rst
 | 
					   dc-debug.rst
 | 
				
			||||||
   dcn-overview.rst
 | 
					   dcn-overview.rst
 | 
				
			||||||
 | 
					   mpo-overview.rst
 | 
				
			||||||
   dc-glossary.rst
 | 
					   dc-glossary.rst
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										435
									
								
								Documentation/gpu/amdgpu/display/mpo-cursor.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,435 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="160.5318mm"
 | 
				
			||||||
 | 
					   height="65.443306mm"
 | 
				
			||||||
 | 
					   viewBox="0 0 160.5318 65.443308"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   id="svg843"
 | 
				
			||||||
 | 
					   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
 | 
				
			||||||
 | 
					   sodipodi:docname="mpo-cursor.svg">
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs837">
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1568"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Mend"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1562"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.4,0,0,-0.4,-4,0)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="marker1837"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1835"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1580"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send-7"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1568-5"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send-7-2"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1568-5-2"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send-9"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1568-7"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send-9-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1568-7-1"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send-9-6-9"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1568-7-1-3"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     id="base"
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1.0"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0.0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:zoom="0.35"
 | 
				
			||||||
 | 
					     inkscape:cx="895.68984"
 | 
				
			||||||
 | 
					     inkscape:cy="-284.87808"
 | 
				
			||||||
 | 
					     inkscape:document-units="mm"
 | 
				
			||||||
 | 
					     inkscape:current-layer="g1433-6"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:window-width="2560"
 | 
				
			||||||
 | 
					     inkscape:window-height="1376"
 | 
				
			||||||
 | 
					     inkscape:window-x="0"
 | 
				
			||||||
 | 
					     inkscape:window-y="27"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					     fit-margin-top="0"
 | 
				
			||||||
 | 
					     fit-margin-left="0"
 | 
				
			||||||
 | 
					     fit-margin-right="0"
 | 
				
			||||||
 | 
					     fit-margin-bottom="0" />
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata840">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:label="Layer 1"
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer1"
 | 
				
			||||||
 | 
					     transform="translate(70.035531,-11.72001)">
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g1438"
 | 
				
			||||||
 | 
					       transform="matrix(0.33108827,0,0,0.33108827,-46.847588,7.8396545)">
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         y="51.228218"
 | 
				
			||||||
 | 
					         x="-69.09626"
 | 
				
			||||||
 | 
					         height="34.773811"
 | 
				
			||||||
 | 
					         width="66.523811"
 | 
				
			||||||
 | 
					         id="rect1388"
 | 
				
			||||||
 | 
					         style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text1392"
 | 
				
			||||||
 | 
					         y="73.238098"
 | 
				
			||||||
 | 
					         x="-59.718166"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           y="73.238098"
 | 
				
			||||||
 | 
					           x="-59.718166"
 | 
				
			||||||
 | 
					           id="tspan1390"
 | 
				
			||||||
 | 
					           sodipodi:role="line">Cursor</tspan></text>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g1433"
 | 
				
			||||||
 | 
					       transform="matrix(0.33108827,0,0,0.33108827,-49.701591,6.5552955)">
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         y="116.32738"
 | 
				
			||||||
 | 
					         x="-60.476192"
 | 
				
			||||||
 | 
					         height="34.773811"
 | 
				
			||||||
 | 
					         width="66.523811"
 | 
				
			||||||
 | 
					         id="rect1388-3"
 | 
				
			||||||
 | 
					         style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text1392-6"
 | 
				
			||||||
 | 
					         y="138.44888"
 | 
				
			||||||
 | 
					         x="-53.932037"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           y="138.44888"
 | 
				
			||||||
 | 
					           x="-53.932037"
 | 
				
			||||||
 | 
					           id="tspan1390-7"
 | 
				
			||||||
 | 
					           sodipodi:role="line">Plane 1</tspan></text>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g1428"
 | 
				
			||||||
 | 
					       transform="matrix(0.33108827,0,0,0.33108827,-46.847588,7.8396518)">
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         y="173.66814"
 | 
				
			||||||
 | 
					         x="-69.09626"
 | 
				
			||||||
 | 
					         height="34.773811"
 | 
				
			||||||
 | 
					         width="66.523811"
 | 
				
			||||||
 | 
					         id="rect1388-5"
 | 
				
			||||||
 | 
					         style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text1392-3"
 | 
				
			||||||
 | 
					         y="195.78964"
 | 
				
			||||||
 | 
					         x="-62.437382"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           y="195.78964"
 | 
				
			||||||
 | 
					           x="-62.437382"
 | 
				
			||||||
 | 
					           id="tspan1390-5"
 | 
				
			||||||
 | 
					           sodipodi:role="line">Plane 2</tspan></text>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g1433-6"
 | 
				
			||||||
 | 
					       transform="translate(116.41667,-9.0714256)">
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1467"
 | 
				
			||||||
 | 
					         transform="matrix(0.33108827,0,0,0.33108827,-132.72925,15.626721)">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           id="rect1388-3-2"
 | 
				
			||||||
 | 
					           width="66.523811"
 | 
				
			||||||
 | 
					           height="34.773811"
 | 
				
			||||||
 | 
					           x="-60.476192"
 | 
				
			||||||
 | 
					           y="116.32738" />
 | 
				
			||||||
 | 
					        <text
 | 
				
			||||||
 | 
					           xml:space="preserve"
 | 
				
			||||||
 | 
					           style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           x="-45.380619"
 | 
				
			||||||
 | 
					           y="138.33725"
 | 
				
			||||||
 | 
					           id="text1392-6-9"><tspan
 | 
				
			||||||
 | 
					             sodipodi:role="line"
 | 
				
			||||||
 | 
					             id="tspan1390-7-1"
 | 
				
			||||||
 | 
					             x="-45.380619"
 | 
				
			||||||
 | 
					             y="138.33725"
 | 
				
			||||||
 | 
					             style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332">CRTC</tspan></text>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1438-2"
 | 
				
			||||||
 | 
					         transform="matrix(0.33108827,0,0,0.33108827,-92.282164,27.16881)">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           y="51.228218"
 | 
				
			||||||
 | 
					           x="-69.09626"
 | 
				
			||||||
 | 
					           height="34.773811"
 | 
				
			||||||
 | 
					           width="66.523811"
 | 
				
			||||||
 | 
					           id="rect1388-7"
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					        <text
 | 
				
			||||||
 | 
					           id="text1392-0"
 | 
				
			||||||
 | 
					           y="73.238098"
 | 
				
			||||||
 | 
					           x="-59.718166"
 | 
				
			||||||
 | 
					           style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					             style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					             y="73.238098"
 | 
				
			||||||
 | 
					             x="-59.718166"
 | 
				
			||||||
 | 
					             id="tspan1390-9"
 | 
				
			||||||
 | 
					             sodipodi:role="line">Cursor</tspan></text>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1433-3"
 | 
				
			||||||
 | 
					         transform="matrix(0.33108827,0,0,0.33108827,-61.59731,5.6152398)">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           y="116.32738"
 | 
				
			||||||
 | 
					           x="-60.476192"
 | 
				
			||||||
 | 
					           height="34.773811"
 | 
				
			||||||
 | 
					           width="66.523811"
 | 
				
			||||||
 | 
					           id="rect1388-3-6"
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					        <text
 | 
				
			||||||
 | 
					           id="text1392-6-0"
 | 
				
			||||||
 | 
					           y="138.44888"
 | 
				
			||||||
 | 
					           x="-53.932037"
 | 
				
			||||||
 | 
					           style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					             style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					             y="138.44888"
 | 
				
			||||||
 | 
					             x="-53.932037"
 | 
				
			||||||
 | 
					             id="tspan1390-7-6"
 | 
				
			||||||
 | 
					             sodipodi:role="line">Plane 1</tspan></text>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1428-2"
 | 
				
			||||||
 | 
					         transform="matrix(0.33108827,0,0,0.33108827,-58.743296,6.7994816)">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           y="173.66814"
 | 
				
			||||||
 | 
					           x="-69.09626"
 | 
				
			||||||
 | 
					           height="34.773811"
 | 
				
			||||||
 | 
					           width="66.523811"
 | 
				
			||||||
 | 
					           id="rect1388-5-6"
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					        <text
 | 
				
			||||||
 | 
					           id="text1392-3-1"
 | 
				
			||||||
 | 
					           y="195.78964"
 | 
				
			||||||
 | 
					           x="-62.437382"
 | 
				
			||||||
 | 
					           style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					             style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					             y="195.78964"
 | 
				
			||||||
 | 
					             x="-62.437382"
 | 
				
			||||||
 | 
					             id="tspan1390-5-8"
 | 
				
			||||||
 | 
					             sodipodi:role="line">Plane 2</tspan></text>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1467-7"
 | 
				
			||||||
 | 
					         transform="matrix(0.33108827,0,0,0.33108827,-28.233674,5.6152398)">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           id="rect1388-3-2-9"
 | 
				
			||||||
 | 
					           width="66.523811"
 | 
				
			||||||
 | 
					           height="34.773811"
 | 
				
			||||||
 | 
					           x="-60.476192"
 | 
				
			||||||
 | 
					           y="116.32738" />
 | 
				
			||||||
 | 
					        <text
 | 
				
			||||||
 | 
					           xml:space="preserve"
 | 
				
			||||||
 | 
					           style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					           x="-45.380619"
 | 
				
			||||||
 | 
					           y="138.33725"
 | 
				
			||||||
 | 
					           id="text1392-6-9-2"><tspan
 | 
				
			||||||
 | 
					             sodipodi:role="line"
 | 
				
			||||||
 | 
					             id="tspan1390-7-1-0"
 | 
				
			||||||
 | 
					             x="-45.380619"
 | 
				
			||||||
 | 
					             y="138.33725"
 | 
				
			||||||
 | 
					             style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332">CRTC</tspan></text>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         xml:space="preserve"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:1.05120528px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.08760043"
 | 
				
			||||||
 | 
					         x="-164.26541"
 | 
				
			||||||
 | 
					         y="24.302296"
 | 
				
			||||||
 | 
					         id="text1531"><tspan
 | 
				
			||||||
 | 
					           sodipodi:role="line"
 | 
				
			||||||
 | 
					           id="tspan1529"
 | 
				
			||||||
 | 
					           x="-164.26541"
 | 
				
			||||||
 | 
					           y="24.302296"
 | 
				
			||||||
 | 
					           style="font-weight:bold;font-size:4.6720233px;stroke-width:0.08760043">DRM</tspan></text>
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         xml:space="preserve"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:1.05120528px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.08760043"
 | 
				
			||||||
 | 
					         x="-89.233742"
 | 
				
			||||||
 | 
					         y="24.341078"
 | 
				
			||||||
 | 
					         id="text1531-2"><tspan
 | 
				
			||||||
 | 
					           sodipodi:role="line"
 | 
				
			||||||
 | 
					           id="tspan1529-3"
 | 
				
			||||||
 | 
					           x="-89.233742"
 | 
				
			||||||
 | 
					           y="24.341078"
 | 
				
			||||||
 | 
					           style="font-weight:bold;font-size:4.6720233px;stroke-width:0.08760043">AMD Hardware</tspan></text>
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send)"
 | 
				
			||||||
 | 
					         d="m -164.26541,39.407343 h 20.27325 v 11.262913"
 | 
				
			||||||
 | 
					         id="path1551"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         sodipodi:nodetypes="ccc" />
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-7)"
 | 
				
			||||||
 | 
					         d="m -164.11597,80.385815 h 20.27325 v -11.26291"
 | 
				
			||||||
 | 
					         id="path1551-9"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         sodipodi:nodetypes="ccc" />
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-7-2)"
 | 
				
			||||||
 | 
					         d="m -59.24211,70.452123 h 20.273243 V 59.18921"
 | 
				
			||||||
 | 
					         id="path1551-9-8"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         sodipodi:nodetypes="ccc" />
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9)"
 | 
				
			||||||
 | 
					         d="m -163.61178,59.821549 h 9.26062"
 | 
				
			||||||
 | 
					         id="path1551-3"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         sodipodi:nodetypes="cc" />
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9-6)"
 | 
				
			||||||
 | 
					         d="m -93.426241,50.16968 h 9.260617"
 | 
				
			||||||
 | 
					         id="path1551-3-2"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         sodipodi:nodetypes="cc" />
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9-6-9)"
 | 
				
			||||||
 | 
					         d="m -59.637503,50.169684 h 9.260618"
 | 
				
			||||||
 | 
					         id="path1551-3-2-1"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         sodipodi:nodetypes="cc" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 18 KiB  | 
							
								
								
									
										242
									
								
								Documentation/gpu/amdgpu/display/mpo-overview.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,242 @@
 | 
				
			||||||
 | 
					========================
 | 
				
			||||||
 | 
					Multiplane Overlay (MPO)
 | 
				
			||||||
 | 
					========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note:: You will get more from this page if you have already read the
 | 
				
			||||||
 | 
					   'Documentation/gpu/amdgpu/display/dcn-overview.rst'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Multiplane Overlay (MPO) allows for multiple framebuffers to be composited via
 | 
				
			||||||
 | 
					fixed-function hardware in the display controller rather than using graphics or
 | 
				
			||||||
 | 
					compute shaders for composition. This can yield some power savings if it means
 | 
				
			||||||
 | 
					the graphics/compute pipelines can be put into low-power states. In summary,
 | 
				
			||||||
 | 
					MPO can bring the following benefits:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Decreased GPU and CPU workload - no composition shaders needed, no extra
 | 
				
			||||||
 | 
					  buffer copy needed, GPU can remain idle.
 | 
				
			||||||
 | 
					* Plane independent page flips - No need to be tied to global compositor
 | 
				
			||||||
 | 
					  page-flip present rate, reduced latency, independent timing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note:: Keep in mind that MPO is all about power-saving; if you want to learn
 | 
				
			||||||
 | 
					   more about power-save in the display context, check the link:
 | 
				
			||||||
 | 
					   `Power <https://gitlab.freedesktop.org/pq/color-and-hdr/-/blob/main/doc/power.rst>`__.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Multiplane Overlay is only available using the DRM atomic model. The atomic
 | 
				
			||||||
 | 
					model only uses a single userspace IOCTL for configuring the display hardware
 | 
				
			||||||
 | 
					(modesetting, page-flipping, etc) - drmModeAtomicCommit. To query hardware
 | 
				
			||||||
 | 
					resources and limitations userspace also calls into drmModeGetResources which
 | 
				
			||||||
 | 
					reports back the number of planes, CRTCs, and connectors. There are three types
 | 
				
			||||||
 | 
					of DRM planes that the driver can register and work with:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* ``DRM_PLANE_TYPE_PRIMARY``: Primary planes represent a "main" plane for a
 | 
				
			||||||
 | 
					  CRTC, primary planes are the planes operated upon by CRTC modesetting and
 | 
				
			||||||
 | 
					  flipping operations.
 | 
				
			||||||
 | 
					* ``DRM_PLANE_TYPE_CURSOR``: Cursor planes represent a "cursor" plane for a
 | 
				
			||||||
 | 
					  CRTC. Cursor planes are the planes operated upon by the cursor IOCTLs
 | 
				
			||||||
 | 
					* ``DRM_PLANE_TYPE_OVERLAY``: Overlay planes represent all non-primary,
 | 
				
			||||||
 | 
					  non-cursor planes. Some drivers refer to these types of planes as "sprites"
 | 
				
			||||||
 | 
					  internally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To illustrate how it works, let's take a look at a device that exposes the
 | 
				
			||||||
 | 
					following planes to userspace:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* 4 Primary planes (1 per CRTC).
 | 
				
			||||||
 | 
					* 4 Cursor planes (1 per CRTC).
 | 
				
			||||||
 | 
					* 1 Overlay plane (shared among CRTCs).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note:: Keep in mind that different ASICs might expose other numbers of
 | 
				
			||||||
 | 
					   planes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For this hardware example, we have 4 pipes (if you don't know what AMD pipe
 | 
				
			||||||
 | 
					means, look at 'Documentation/gpu/amdgpu/display/dcn-overview.rst', section
 | 
				
			||||||
 | 
					"AMD Hardware Pipeline"). Typically most AMD devices operate in a pipe-split
 | 
				
			||||||
 | 
					configuration for optimal single display output (e.g., 2 pipes per plane).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A typical MPO configuration from userspace - 1 primary + 1 overlay on a single
 | 
				
			||||||
 | 
					display - will see 4 pipes in use, 2 per plane.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					At least 1 pipe must be used per plane (primary and overlay), so for this
 | 
				
			||||||
 | 
					hypothetical hardware that we are using as an example, we have an absolute
 | 
				
			||||||
 | 
					limit of 4 planes across all CRTCs. Atomic commits will be rejected for display
 | 
				
			||||||
 | 
					configurations using more than 4 planes. Again, it is important to stress that
 | 
				
			||||||
 | 
					every DCN has different restrictions; here, we are just trying to provide the
 | 
				
			||||||
 | 
					concept idea.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Plane Restrictions
 | 
				
			||||||
 | 
					==================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMDGPU imposes restrictions on the use of DRM planes in the driver.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Atomic commits will be rejected for commits which do not follow these
 | 
				
			||||||
 | 
					restrictions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Overlay planes must be in ARGB8888 or XRGB8888 format
 | 
				
			||||||
 | 
					* Planes cannot be placed outside of the CRTC destination rectangle
 | 
				
			||||||
 | 
					* Planes cannot be downscaled more than 1/4x of their original size
 | 
				
			||||||
 | 
					* Planes cannot be upscaled more than 16x of their original size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Not every property is available on every plane:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Only primary planes have color-space and non-RGB format support
 | 
				
			||||||
 | 
					* Only overlay planes have alpha blending support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cursor Restrictions
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Before we start to describe some restrictions around cursor and MPO, see the
 | 
				
			||||||
 | 
					below image:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: mpo-cursor.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The image on the left side represents how DRM expects the cursor and planes to
 | 
				
			||||||
 | 
					be blended. However, AMD hardware handles cursors differently, as you can see
 | 
				
			||||||
 | 
					on the right side; basically, our cursor cannot be drawn outside its associated
 | 
				
			||||||
 | 
					plane as it is being treated as part of the plane. Another consequence of that
 | 
				
			||||||
 | 
					is that cursors inherit the color and scale from the plane.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As a result of the above behavior, do not use legacy API to set up the cursor
 | 
				
			||||||
 | 
					plane when working with MPO; otherwise, you might encounter unexpected
 | 
				
			||||||
 | 
					behavior.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In short, AMD HW has no dedicated cursor planes. A cursor is attached to
 | 
				
			||||||
 | 
					another plane and therefore inherits any scaling or color processing from its
 | 
				
			||||||
 | 
					parent plane.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use Cases
 | 
				
			||||||
 | 
					=========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Picture-in-Picture (PIP) playback - Underlay strategy
 | 
				
			||||||
 | 
					-----------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Video playback should be done using the "primary plane as underlay" MPO
 | 
				
			||||||
 | 
					strategy. This is a 2 planes configuration:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* 1 YUV DRM Primary Plane (e.g. NV12 Video)
 | 
				
			||||||
 | 
					* 1 RGBA DRM Overlay Plane (e.g. ARGB8888 desktop). The compositor should
 | 
				
			||||||
 | 
					  prepare the framebuffers for the planes as follows:
 | 
				
			||||||
 | 
					  - The overlay plane contains general desktop UI, video player controls, and video subtitles
 | 
				
			||||||
 | 
					  - Primary plane contains one or more videos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note:: Keep in mind that we could extend this configuration to more planes,
 | 
				
			||||||
 | 
					   but that is currently not supported by our driver yet (maybe if we have a
 | 
				
			||||||
 | 
					   userspace request in the future, we can change that).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See below a single-video example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: single-display-mpo.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note:: We could extend this behavior to more planes, but that is currently
 | 
				
			||||||
 | 
					   not supported by our driver.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The video buffer should be used directly for the primary plane. The video can
 | 
				
			||||||
 | 
					be scaled and positioned for the desktop using the properties: CRTC_X, CRTC_Y,
 | 
				
			||||||
 | 
					CRTC_W, and CRTC_H. The primary plane should also have the color encoding and
 | 
				
			||||||
 | 
					color range properties set based on the source content:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* ``COLOR_RANGE``, ``COLOR_ENCODING``
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The overlay plane should be the native size of the CRTC. The compositor must
 | 
				
			||||||
 | 
					draw a transparent cutout for where the video should be placed on the desktop
 | 
				
			||||||
 | 
					(i.e., set the alpha to zero). The primary plane video will be visible through
 | 
				
			||||||
 | 
					the underlay. The overlay plane's buffer may remain static while the primary
 | 
				
			||||||
 | 
					plane's framebuffer is used for standard double-buffered playback.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The compositor should create a YUV buffer matching the native size of the CRTC.
 | 
				
			||||||
 | 
					Each video buffer should be composited onto this YUV buffer for direct YUV
 | 
				
			||||||
 | 
					scanout. The primary plane should have the color encoding and color range
 | 
				
			||||||
 | 
					properties set based on the source content: ``COLOR_RANGE``,
 | 
				
			||||||
 | 
					``COLOR_ENCODING``. However, be mindful that the source color space and
 | 
				
			||||||
 | 
					encoding match for each video since it affect the entire plane.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The overlay plane should be the native size of the CRTC. The compositor must
 | 
				
			||||||
 | 
					draw a transparent cutout for where each video should be placed on the desktop
 | 
				
			||||||
 | 
					(i.e., set the alpha to zero). The primary plane videos will be visible through
 | 
				
			||||||
 | 
					the underlay. The overlay plane's buffer may remain static while compositing
 | 
				
			||||||
 | 
					operations for video playback will be done on the video buffer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This kernel interface is validated using IGT GPU Tools. The following tests can
 | 
				
			||||||
 | 
					be run to validate positioning, blending, scaling under a variety of sequences
 | 
				
			||||||
 | 
					and interactions with operations such as DPMS and S3:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- ``kms_plane@plane-panning-bottom-right-pipe-*-planes``
 | 
				
			||||||
 | 
					- ``kms_plane@plane-panning-bottom-right-suspend-pipe-*-``
 | 
				
			||||||
 | 
					- ``kms_plane@plane-panning-top-left-pipe-*-``
 | 
				
			||||||
 | 
					- ``kms_plane@plane-position-covered-pipe-*-``
 | 
				
			||||||
 | 
					- ``kms_plane@plane-position-hole-dpms-pipe-*-``
 | 
				
			||||||
 | 
					- ``kms_plane@plane-position-hole-pipe-*-``
 | 
				
			||||||
 | 
					- ``kms_plane_multiple@atomic-pipe-*-tiling-``
 | 
				
			||||||
 | 
					- ``kms_plane_scaling@pipe-*-plane-scaling``
 | 
				
			||||||
 | 
					- ``kms_plane_alpha_blend@pipe-*-alpha-basic``
 | 
				
			||||||
 | 
					- ``kms_plane_alpha_blend@pipe-*-alpha-transparant-fb``
 | 
				
			||||||
 | 
					- ``kms_plane_alpha_blend@pipe-*-alpha-opaque-fb``
 | 
				
			||||||
 | 
					- ``kms_plane_alpha_blend@pipe-*-constant-alpha-min``
 | 
				
			||||||
 | 
					- ``kms_plane_alpha_blend@pipe-*-constant-alpha-mid``
 | 
				
			||||||
 | 
					- ``kms_plane_alpha_blend@pipe-*-constant-alpha-max``
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Multiple Display MPO
 | 
				
			||||||
 | 
					--------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMDGPU supports display MPO when using multiple displays; however, this feature
 | 
				
			||||||
 | 
					behavior heavily relies on the compositor implementation. Keep in mind that
 | 
				
			||||||
 | 
					usespace can define different policies. For example, some OSes can use MPO to
 | 
				
			||||||
 | 
					protect the plane that handles the video playback; notice that we don't have
 | 
				
			||||||
 | 
					many limitations for a single display. Nonetheless, this manipulation can have
 | 
				
			||||||
 | 
					many more restrictions for a multi-display scenario. The below example shows a
 | 
				
			||||||
 | 
					video playback in the middle of two displays, and it is up to the compositor to
 | 
				
			||||||
 | 
					define a policy on how to handle it:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: multi-display-hdcp-mpo.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Let's discuss some of the hardware limitations we have when dealing with
 | 
				
			||||||
 | 
					multi-display with MPO.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Limitations
 | 
				
			||||||
 | 
					~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For simplicity's sake, for discussing the hardware limitation, this
 | 
				
			||||||
 | 
					documentation supposes an example where we have two displays and video playback
 | 
				
			||||||
 | 
					that will be moved around different displays.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* **Hardware limitations**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					From the DCN overview page, each display requires at least one pipe and each
 | 
				
			||||||
 | 
					MPO plane needs another pipe. As a result, when the video is in the middle of
 | 
				
			||||||
 | 
					the two displays, we need to use 2 pipes. See the example below where we avoid
 | 
				
			||||||
 | 
					pipe split:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 1 display (1 pipe) + MPO (1 pipe), we will use two pipes
 | 
				
			||||||
 | 
					- 2 displays (2 pipes) + MPO (1-2 pipes); we will use 4 pipes. MPO in the
 | 
				
			||||||
 | 
					  middle of both displays needs 2 pipes.
 | 
				
			||||||
 | 
					- 3 Displays (3 pipes) + MPO (1-2 pipes), we need 5 pipes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If we use MPO with multiple displays, the userspace has to decide to enable
 | 
				
			||||||
 | 
					multiple MPO by the price of limiting the number of external displays supported
 | 
				
			||||||
 | 
					or disable it in favor of multiple displays; it is a policy decision. For
 | 
				
			||||||
 | 
					example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* When ASIC has 3 pipes, AMD hardware can NOT support 2 displays with MPO
 | 
				
			||||||
 | 
					* When ASIC has 4 pipes, AMD hardware can NOT support 3 displays with MPO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Let's briefly explore how userspace can handle these two display configurations
 | 
				
			||||||
 | 
					on an ASIC that only supports three pipes. We can have:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. kernel-figure:: multi-display-hdcp-mpo-less-pipe-ex.svg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Total pipes are 3
 | 
				
			||||||
 | 
					- User lights up 2 displays (2 out of 3 pipes are used)
 | 
				
			||||||
 | 
					- User launches video (1 pipe used for MPO)
 | 
				
			||||||
 | 
					- Now, if the user moves the video in the middle of 2 displays, one part of the
 | 
				
			||||||
 | 
					  video won't be MPO since we have used 3/3 pipes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* **Scaling limitation**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MPO cannot handle scaling less than 0.25 and more than x16. For example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If 4k video (3840x2160) is playing in windowed mode, the physical size of the
 | 
				
			||||||
 | 
					window cannot be smaller than (960x540).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note:: These scaling limitations might vary from ASIC to ASIC.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* **Size Limitation**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The minimum MPO size is 12px.
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,220 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="103.08798mm"
 | 
				
			||||||
 | 
					   height="30.335283mm"
 | 
				
			||||||
 | 
					   viewBox="0 0 103.08798 30.335284"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   id="svg8"
 | 
				
			||||||
 | 
					   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
 | 
				
			||||||
 | 
					   sodipodi:docname="multi-display-hdcp-mpo-less-pipe-ex.svg">
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs2">
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1133"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1133-0"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     id="base"
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1.0"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0.0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:zoom="1.979899"
 | 
				
			||||||
 | 
					     inkscape:cx="205.69673"
 | 
				
			||||||
 | 
					     inkscape:cy="33.960031"
 | 
				
			||||||
 | 
					     inkscape:document-units="mm"
 | 
				
			||||||
 | 
					     inkscape:current-layer="layer1"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:window-width="1288"
 | 
				
			||||||
 | 
					     inkscape:window-height="1376"
 | 
				
			||||||
 | 
					     inkscape:window-x="1272"
 | 
				
			||||||
 | 
					     inkscape:window-y="27"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="0"
 | 
				
			||||||
 | 
					     fit-margin-top="0"
 | 
				
			||||||
 | 
					     fit-margin-left="0"
 | 
				
			||||||
 | 
					     fit-margin-right="0"
 | 
				
			||||||
 | 
					     fit-margin-bottom="0" />
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata5">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:label="Layer 1"
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer1"
 | 
				
			||||||
 | 
					     transform="translate(112.75816,51.721433)">
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836"
 | 
				
			||||||
 | 
					       width="48.988979"
 | 
				
			||||||
 | 
					       height="29.48851"
 | 
				
			||||||
 | 
					       x="-112.44358"
 | 
				
			||||||
 | 
					       y="-51.189243"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.38327959;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect834"
 | 
				
			||||||
 | 
					       width="14.422765"
 | 
				
			||||||
 | 
					       height="15.872559"
 | 
				
			||||||
 | 
					       x="-78.227928"
 | 
				
			||||||
 | 
					       y="-44.469936" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-71.189278"
 | 
				
			||||||
 | 
					       y="-48.114422"
 | 
				
			||||||
 | 
					       id="text844"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-71.189278"
 | 
				
			||||||
 | 
					         y="-48.114422"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846">Protected</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-71.189278"
 | 
				
			||||||
 | 
					         y="-45.584015"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan2288">MPO plane</tspan></text>
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-3"
 | 
				
			||||||
 | 
					       width="48.988979"
 | 
				
			||||||
 | 
					       height="29.48851"
 | 
				
			||||||
 | 
					       x="-58.973743"
 | 
				
			||||||
 | 
					       y="-51.406849"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.2500253;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect834-6"
 | 
				
			||||||
 | 
					       width="6.1374092"
 | 
				
			||||||
 | 
					       height="15.872559"
 | 
				
			||||||
 | 
					       x="-58.632965"
 | 
				
			||||||
 | 
					       y="-44.469936" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-107.96788"
 | 
				
			||||||
 | 
					       y="-47.033775"
 | 
				
			||||||
 | 
					       id="text844-7"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-107.96788"
 | 
				
			||||||
 | 
					         y="-47.033775"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-3">#1</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-15.20074"
 | 
				
			||||||
 | 
					       y="-46.715996"
 | 
				
			||||||
 | 
					       id="text844-7-2"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-15.20074"
 | 
				
			||||||
 | 
					         y="-46.715996"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-3-9">#2</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-88.926605"
 | 
				
			||||||
 | 
					       y="-23.173674"
 | 
				
			||||||
 | 
					       id="text844-1"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-88.926605"
 | 
				
			||||||
 | 
					         y="-23.173674"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-7">Desktop</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-33.770744"
 | 
				
			||||||
 | 
					       y="-23.819901"
 | 
				
			||||||
 | 
					       id="text844-1-0"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-33.770744"
 | 
				
			||||||
 | 
					         y="-23.819901"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-7-9">Desktop</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-75.17498"
 | 
				
			||||||
 | 
					       y="-41.219398"
 | 
				
			||||||
 | 
					       id="text844-7-2-3"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-75.17498"
 | 
				
			||||||
 | 
					         y="-41.219398"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-3-9-6">#3</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-47.142235"
 | 
				
			||||||
 | 
					       y="-48.056866"
 | 
				
			||||||
 | 
					       id="text844-0"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-47.142235"
 | 
				
			||||||
 | 
					         y="-48.056866"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan2288-2">Software</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-47.142235"
 | 
				
			||||||
 | 
					         y="-45.526459"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan2313">Composited Video</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-36.23288"
 | 
				
			||||||
 | 
					       y="-34.592064"
 | 
				
			||||||
 | 
					       id="text844-1-6"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-36.23288"
 | 
				
			||||||
 | 
					         y="-34.592064"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-7-1">Video will not be displayed</tspan></text>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 10 KiB  | 
							
								
								
									
										171
									
								
								Documentation/gpu/amdgpu/display/multi-display-hdcp-mpo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,171 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="103.08798mm"
 | 
				
			||||||
 | 
					   height="30.335283mm"
 | 
				
			||||||
 | 
					   viewBox="0 0 103.08798 30.335284"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   id="svg8"
 | 
				
			||||||
 | 
					   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
 | 
				
			||||||
 | 
					   sodipodi:docname="multi-display-hdcp-mpo.svg">
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs2">
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1133"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1133-0"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     id="base"
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1.0"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0.0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:zoom="1.979899"
 | 
				
			||||||
 | 
					     inkscape:cx="196.85789"
 | 
				
			||||||
 | 
					     inkscape:cy="33.960027"
 | 
				
			||||||
 | 
					     inkscape:document-units="mm"
 | 
				
			||||||
 | 
					     inkscape:current-layer="layer1"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:window-width="1288"
 | 
				
			||||||
 | 
					     inkscape:window-height="1376"
 | 
				
			||||||
 | 
					     inkscape:window-x="1272"
 | 
				
			||||||
 | 
					     inkscape:window-y="27"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="0"
 | 
				
			||||||
 | 
					     fit-margin-top="0"
 | 
				
			||||||
 | 
					     fit-margin-left="0"
 | 
				
			||||||
 | 
					     fit-margin-right="0"
 | 
				
			||||||
 | 
					     fit-margin-bottom="0" />
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata5">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:label="Layer 1"
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer1"
 | 
				
			||||||
 | 
					     transform="translate(112.75816,51.721433)">
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836"
 | 
				
			||||||
 | 
					       width="48.988979"
 | 
				
			||||||
 | 
					       height="29.48851"
 | 
				
			||||||
 | 
					       x="-112.44358"
 | 
				
			||||||
 | 
					       y="-51.189243"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.38327959;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect834"
 | 
				
			||||||
 | 
					       width="14.422765"
 | 
				
			||||||
 | 
					       height="15.872559"
 | 
				
			||||||
 | 
					       x="-78.227928"
 | 
				
			||||||
 | 
					       y="-44.469936" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-71.189278"
 | 
				
			||||||
 | 
					       y="-48.114422"
 | 
				
			||||||
 | 
					       id="text844"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-71.189278"
 | 
				
			||||||
 | 
					         y="-48.114422"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846">Protected</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-71.189278"
 | 
				
			||||||
 | 
					         y="-45.584015"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan2288">MPO plane</tspan></text>
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-3"
 | 
				
			||||||
 | 
					       width="48.988979"
 | 
				
			||||||
 | 
					       height="29.48851"
 | 
				
			||||||
 | 
					       x="-58.973743"
 | 
				
			||||||
 | 
					       y="-51.406849"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.2500253;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect834-6"
 | 
				
			||||||
 | 
					       width="6.1374092"
 | 
				
			||||||
 | 
					       height="15.872559"
 | 
				
			||||||
 | 
					       x="-58.632965"
 | 
				
			||||||
 | 
					       y="-44.469936" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-88.926605"
 | 
				
			||||||
 | 
					       y="-23.173674"
 | 
				
			||||||
 | 
					       id="text844-1"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-88.926605"
 | 
				
			||||||
 | 
					         y="-23.173674"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-7">Desktop</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-33.770744"
 | 
				
			||||||
 | 
					       y="-23.819901"
 | 
				
			||||||
 | 
					       id="text844-1-0"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-33.770744"
 | 
				
			||||||
 | 
					         y="-23.819901"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-7-9">Desktop</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-70.364128"
 | 
				
			||||||
 | 
					       y="-35.740372"
 | 
				
			||||||
 | 
					       id="text844-7-2-3"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-70.364128"
 | 
				
			||||||
 | 
					         y="-35.740372"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-3-9-6">Video</tspan></text>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 7.1 KiB  | 
							
								
								
									
										958
									
								
								Documentation/gpu/amdgpu/display/pipeline_4k_no_split.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,958 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="1055.4928"
 | 
				
			||||||
 | 
					   height="404.60379"
 | 
				
			||||||
 | 
					   viewBox="0 0 279.26579 107.05142"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   id="svg8"
 | 
				
			||||||
 | 
					   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
 | 
				
			||||||
 | 
					   sodipodi:docname="pipeline_4k_no_split.svg">
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs2">
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="marker8858"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path8616"
 | 
				
			||||||
 | 
					         style="fill:#aa00d4;fill-opacity:1;fill-rule:evenodd;stroke:#aa00d4;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Send"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path8622"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="matrix(-0.3,0,0,-0.3,0.69,0)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Lend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Lend"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path8592"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.8,0,0,-0.8,-10,0)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Lend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Lend"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path8610"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3-2"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6-9"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3-2-1"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6-9-9"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3-2-7"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6-9-8"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3-4"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6-5"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-0"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-3"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-1"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3-2-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6-9-1"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-0-7"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-3-4"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-6-3"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-1-0"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3-2-8"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6-9-6"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-3"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-6"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="marker8858-3"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path8616-5"
 | 
				
			||||||
 | 
					         style="fill:#00ffcc;fill-opacity:1;fill-rule:evenodd;stroke:#00ffcc;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-3-3"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-6-56"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-8-0-2"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1200-9-3-9"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-9"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-3"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-9"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-6-7"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-9-4"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-6-0"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-9-7"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-6-0-1"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-9-7-4"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-6-0-2"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-9-7-6"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-6-0-2-4"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-9-7-6-9"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-8"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-7"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow2Mend"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow2Mend-94-6-0-2-7"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1200-7-9-7-6-6"
 | 
				
			||||||
 | 
					         style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
 | 
				
			||||||
 | 
					         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
 | 
				
			||||||
 | 
					         transform="scale(-0.6)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     id="base"
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1.0"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0.0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:zoom="1.4"
 | 
				
			||||||
 | 
					     inkscape:cx="213.41584"
 | 
				
			||||||
 | 
					     inkscape:cy="301.17934"
 | 
				
			||||||
 | 
					     inkscape:document-units="mm"
 | 
				
			||||||
 | 
					     inkscape:current-layer="layer1"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:window-width="2560"
 | 
				
			||||||
 | 
					     inkscape:window-height="1376"
 | 
				
			||||||
 | 
					     inkscape:window-x="0"
 | 
				
			||||||
 | 
					     inkscape:window-y="27"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					     showguides="false"
 | 
				
			||||||
 | 
					     fit-margin-top="0"
 | 
				
			||||||
 | 
					     fit-margin-left="0"
 | 
				
			||||||
 | 
					     fit-margin-right="0"
 | 
				
			||||||
 | 
					     fit-margin-bottom="0"
 | 
				
			||||||
 | 
					     units="px"
 | 
				
			||||||
 | 
					     inkscape:snap-global="false" />
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata5">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title />
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:label="Layer 1"
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer1"
 | 
				
			||||||
 | 
					     transform="translate(349.34521,-0.81564989)">
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:1.00353587;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none"
 | 
				
			||||||
 | 
					       id="rect834"
 | 
				
			||||||
 | 
					       width="30.251244"
 | 
				
			||||||
 | 
					       height="88.477814"
 | 
				
			||||||
 | 
					       x="-317.81958"
 | 
				
			||||||
 | 
					       y="14.782127"
 | 
				
			||||||
 | 
					       ry="2.5590618e-06" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					       x="-314.73792"
 | 
				
			||||||
 | 
					       y="21.83947"
 | 
				
			||||||
 | 
					       id="text838"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan836"
 | 
				
			||||||
 | 
					         x="-314.73792"
 | 
				
			||||||
 | 
					         y="21.83947"
 | 
				
			||||||
 | 
					         style="stroke-width:0.16370411">DCHUB</tspan></text>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g2025"
 | 
				
			||||||
 | 
					       transform="translate(-2.4916954,-1.2533369)">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text838-5"
 | 
				
			||||||
 | 
					         y="31.969406"
 | 
				
			||||||
 | 
					         x="-254.53119"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="31.969406"
 | 
				
			||||||
 | 
					           x="-254.53119"
 | 
				
			||||||
 | 
					           id="tspan836-3"
 | 
				
			||||||
 | 
					           sodipodi:role="line">DPP</tspan><tspan
 | 
				
			||||||
 | 
					           id="tspan936"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="40.15461"
 | 
				
			||||||
 | 
					           x="-254.53119"
 | 
				
			||||||
 | 
					           sodipodi:role="line">(0)</tspan></text>
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="7.8154301e-07"
 | 
				
			||||||
 | 
					         y="20.596174"
 | 
				
			||||||
 | 
					         x="-269.66983"
 | 
				
			||||||
 | 
					         height="27.021315"
 | 
				
			||||||
 | 
					         width="30.696135"
 | 
				
			||||||
 | 
					         id="rect834-5"
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.1637041"
 | 
				
			||||||
 | 
					       x="-297.75696"
 | 
				
			||||||
 | 
					       y="109.44505"
 | 
				
			||||||
 | 
					       id="text1063"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan1061"
 | 
				
			||||||
 | 
					         x="-297.75696"
 | 
				
			||||||
 | 
					         y="115.23865"
 | 
				
			||||||
 | 
					         style="stroke-width:0.1637041" /></text>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g1878"
 | 
				
			||||||
 | 
					       transform="translate(-0.62971878)">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text846"
 | 
				
			||||||
 | 
					         y="30.716068"
 | 
				
			||||||
 | 
					         x="-302.27368"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="30.716068"
 | 
				
			||||||
 | 
					           x="-302.27368"
 | 
				
			||||||
 | 
					           id="tspan844"
 | 
				
			||||||
 | 
					           sodipodi:role="line">HUBP</tspan><tspan
 | 
				
			||||||
 | 
					           id="tspan863"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="38.901276"
 | 
				
			||||||
 | 
					           x="-302.27368"
 | 
				
			||||||
 | 
					           sodipodi:role="line">(0)</tspan></text>
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1853">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           id="rect1850"
 | 
				
			||||||
 | 
					           width="24.708241"
 | 
				
			||||||
 | 
					           height="17.224693"
 | 
				
			||||||
 | 
					           x="-314.41837"
 | 
				
			||||||
 | 
					           y="24.241148" />
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       transform="translate(-0.62971878,18.810271)"
 | 
				
			||||||
 | 
					       id="g1878-1">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text846-2"
 | 
				
			||||||
 | 
					         y="30.716068"
 | 
				
			||||||
 | 
					         x="-302.27368"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="30.716068"
 | 
				
			||||||
 | 
					           x="-302.27368"
 | 
				
			||||||
 | 
					           id="tspan844-7"
 | 
				
			||||||
 | 
					           sodipodi:role="line">HUBP</tspan><tspan
 | 
				
			||||||
 | 
					           id="tspan863-0"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="38.901276"
 | 
				
			||||||
 | 
					           x="-302.27368"
 | 
				
			||||||
 | 
					           sodipodi:role="line">(1)</tspan></text>
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1853-9">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           id="rect1850-3"
 | 
				
			||||||
 | 
					           width="24.708241"
 | 
				
			||||||
 | 
					           height="17.224693"
 | 
				
			||||||
 | 
					           x="-314.41837"
 | 
				
			||||||
 | 
					           y="24.241148" />
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       transform="translate(-0.62971878,57.029814)"
 | 
				
			||||||
 | 
					       id="g1878-8">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text846-7"
 | 
				
			||||||
 | 
					         y="30.716068"
 | 
				
			||||||
 | 
					         x="-302.27368"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="30.716068"
 | 
				
			||||||
 | 
					           x="-302.27368"
 | 
				
			||||||
 | 
					           id="tspan844-9"
 | 
				
			||||||
 | 
					           sodipodi:role="line">HUBP</tspan><tspan
 | 
				
			||||||
 | 
					           id="tspan863-20"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="38.901276"
 | 
				
			||||||
 | 
					           x="-302.27368"
 | 
				
			||||||
 | 
					           sodipodi:role="line">(5)</tspan></text>
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g1853-2">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           id="rect1850-37"
 | 
				
			||||||
 | 
					           width="24.708241"
 | 
				
			||||||
 | 
					           height="17.224693"
 | 
				
			||||||
 | 
					           x="-314.41837"
 | 
				
			||||||
 | 
					           y="24.241148" />
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					       x="-310.7348"
 | 
				
			||||||
 | 
					       y="72.106789"
 | 
				
			||||||
 | 
					       id="text8862-5"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan8860-9"
 | 
				
			||||||
 | 
					         x="-310.7348"
 | 
				
			||||||
 | 
					         y="72.106789"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#44aa00;stroke-width:0.26458332">...</tspan></text>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#ff0000;stroke-width:0.96187615;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94)"
 | 
				
			||||||
 | 
					       d="m -288.90777,32.862737 h 14.20296"
 | 
				
			||||||
 | 
					       id="path1171"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					       x="-264.85431"
 | 
				
			||||||
 | 
					       y="62.072891"
 | 
				
			||||||
 | 
					       id="text8862-5-8"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan8860-9-4"
 | 
				
			||||||
 | 
					         x="-264.85431"
 | 
				
			||||||
 | 
					         y="62.072891"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g2025-5"
 | 
				
			||||||
 | 
					       transform="translate(40.522337,-1.1484419)" />
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g7343"
 | 
				
			||||||
 | 
					       transform="translate(40.522337,-1.2533369)">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text838-5-6"
 | 
				
			||||||
 | 
					         y="31.969406"
 | 
				
			||||||
 | 
					         x="-254.53119"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="31.969406"
 | 
				
			||||||
 | 
					           x="-254.53119"
 | 
				
			||||||
 | 
					           id="tspan836-3-3"
 | 
				
			||||||
 | 
					           sodipodi:role="line">MPC</tspan><tspan
 | 
				
			||||||
 | 
					           id="tspan936-2"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="40.15461"
 | 
				
			||||||
 | 
					           x="-254.53119"
 | 
				
			||||||
 | 
					           sodipodi:role="line">(0)</tspan></text>
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="7.8154301e-07"
 | 
				
			||||||
 | 
					         y="20.596174"
 | 
				
			||||||
 | 
					         x="-269.66983"
 | 
				
			||||||
 | 
					         height="27.021315"
 | 
				
			||||||
 | 
					         width="30.696135"
 | 
				
			||||||
 | 
					         id="rect834-5-0"
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g7343-2"
 | 
				
			||||||
 | 
					       transform="translate(84.178583,-1.2533369)">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text838-5-6-54"
 | 
				
			||||||
 | 
					         y="31.969406"
 | 
				
			||||||
 | 
					         x="-254.53119"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="31.969406"
 | 
				
			||||||
 | 
					           x="-254.53119"
 | 
				
			||||||
 | 
					           id="tspan836-3-3-7"
 | 
				
			||||||
 | 
					           sodipodi:role="line">OPP</tspan><tspan
 | 
				
			||||||
 | 
					           id="tspan936-2-44"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="40.15461"
 | 
				
			||||||
 | 
					           x="-254.53119"
 | 
				
			||||||
 | 
					           sodipodi:role="line">(0)</tspan></text>
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="7.8154301e-07"
 | 
				
			||||||
 | 
					         y="20.596174"
 | 
				
			||||||
 | 
					         x="-269.66983"
 | 
				
			||||||
 | 
					         height="27.021315"
 | 
				
			||||||
 | 
					         width="30.696135"
 | 
				
			||||||
 | 
					         id="rect834-5-0-3"
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					       x="-221.84029"
 | 
				
			||||||
 | 
					       y="62.072891"
 | 
				
			||||||
 | 
					       id="text8862-5-8-6"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan8860-9-4-5"
 | 
				
			||||||
 | 
					         x="-221.84029"
 | 
				
			||||||
 | 
					         y="62.072891"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6)"
 | 
				
			||||||
 | 
					       d="m -240.90479,32.86192 h 10.61353"
 | 
				
			||||||
 | 
					       id="path1171-3"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0)"
 | 
				
			||||||
 | 
					       d="m -198.19009,32.86192 h 10.61353"
 | 
				
			||||||
 | 
					       id="path1171-3-8"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g7343-2-2"
 | 
				
			||||||
 | 
					       transform="translate(127.15447,-1.1484419)">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text838-5-6-54-0"
 | 
				
			||||||
 | 
					         y="65.122154"
 | 
				
			||||||
 | 
					         x="-254.32814"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           id="tspan936-2-44-8"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="65.122154"
 | 
				
			||||||
 | 
					           x="-254.32814"
 | 
				
			||||||
 | 
					           sodipodi:role="line">OPTC</tspan></text>
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="2.4256708e-06"
 | 
				
			||||||
 | 
					         y="20.805576"
 | 
				
			||||||
 | 
					         x="-269.46042"
 | 
				
			||||||
 | 
					         height="83.865906"
 | 
				
			||||||
 | 
					         width="30.277332"
 | 
				
			||||||
 | 
					         id="rect834-5-0-3-9"
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:0.97745234;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0-2)"
 | 
				
			||||||
 | 
					       d="m -154.34485,32.86192 h 10.61353"
 | 
				
			||||||
 | 
					       id="path1171-3-8-6"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
 | 
				
			||||||
 | 
					       x="-178.18404"
 | 
				
			||||||
 | 
					       y="62.072891"
 | 
				
			||||||
 | 
					       id="text8862-5-8-6-0"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan8860-9-4-5-4"
 | 
				
			||||||
 | 
					         x="-178.18404"
 | 
				
			||||||
 | 
					         y="62.072891"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:#000000;stroke:#000000;stroke-width:0.96187615;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-8)"
 | 
				
			||||||
 | 
					       d="m -335.20986,59.030276 h 14.20296"
 | 
				
			||||||
 | 
					       id="path1171-17"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					       x="-349.77686"
 | 
				
			||||||
 | 
					       y="61.404655"
 | 
				
			||||||
 | 
					       id="text838-2"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan836-7"
 | 
				
			||||||
 | 
					         x="-349.77686"
 | 
				
			||||||
 | 
					         y="61.404655"
 | 
				
			||||||
 | 
					         style="stroke-width:0.16370411">SDP</tspan></text>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291667, 1.32291667;stroke-dashoffset:0;stroke-opacity:1"
 | 
				
			||||||
 | 
					       d="M -279.04164,107.86706 V 0.89985833"
 | 
				
			||||||
 | 
					       id="path11907"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.3229167, 1.3229167;stroke-dashoffset:0;stroke-opacity:1"
 | 
				
			||||||
 | 
					       d="M -235.57438,107.86707 V 0.89985663"
 | 
				
			||||||
 | 
					       id="path11907-6-1"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291671, 1.32291671;stroke-dashoffset:0;stroke-opacity:1"
 | 
				
			||||||
 | 
					       d="M -149.96277,107.86707 V 0.89985223"
 | 
				
			||||||
 | 
					       id="path11907-6-1-0"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					       x="-257.38275"
 | 
				
			||||||
 | 
					       y="5.003336"
 | 
				
			||||||
 | 
					       id="text838-6"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan836-1"
 | 
				
			||||||
 | 
					         x="-257.38275"
 | 
				
			||||||
 | 
					         y="5.003336"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411">DPPCLK</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-257.38275"
 | 
				
			||||||
 | 
					         y="13.188541"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         id="tspan12658">535.916Mhz</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					       x="-192.85298"
 | 
				
			||||||
 | 
					       y="5.003336"
 | 
				
			||||||
 | 
					       id="text838-6-5"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan836-1-9"
 | 
				
			||||||
 | 
					         x="-192.85298"
 | 
				
			||||||
 | 
					         y="5.003336"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411">DISPCLK</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-192.85298"
 | 
				
			||||||
 | 
					         y="13.188541"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         id="tspan12662">541.275 Mhz</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					       x="-302.03766"
 | 
				
			||||||
 | 
					       y="5.003336"
 | 
				
			||||||
 | 
					       id="text838-6-5-4"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan836-1-9-9"
 | 
				
			||||||
 | 
					         x="-312.23135"
 | 
				
			||||||
 | 
					         y="5.003336"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;stroke-width:0.16370411;text-anchor:middle;text-align:center">DCFCLK</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-312.23135"
 | 
				
			||||||
 | 
					         y="13.188541"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;stroke-width:0.16370411;text-anchor:middle;text-align:center"
 | 
				
			||||||
 | 
					         id="tspan12660">506 Mhz</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					       x="-96.075348"
 | 
				
			||||||
 | 
					       y="4.568048"
 | 
				
			||||||
 | 
					       id="text838-6-5-0"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan836-1-9-91"
 | 
				
			||||||
 | 
					         x="-96.075348"
 | 
				
			||||||
 | 
					         y="4.568048"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;stroke-width:0.16370411">SymCLK</tspan></text>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g7343-2-2-7"
 | 
				
			||||||
 | 
					       transform="translate(168.61494,-1.1484419)">
 | 
				
			||||||
 | 
					      <text
 | 
				
			||||||
 | 
					         id="text838-5-6-54-0-7"
 | 
				
			||||||
 | 
					         y="65.122154"
 | 
				
			||||||
 | 
					         x="-254.32814"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					         xml:space="preserve"><tspan
 | 
				
			||||||
 | 
					           id="tspan936-2-44-8-1"
 | 
				
			||||||
 | 
					           style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					           y="65.122154"
 | 
				
			||||||
 | 
					           x="-254.32814"
 | 
				
			||||||
 | 
					           sodipodi:role="line">DIO</tspan></text>
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="2.4256708e-06"
 | 
				
			||||||
 | 
					         y="20.805576"
 | 
				
			||||||
 | 
					         x="-269.46042"
 | 
				
			||||||
 | 
					         height="83.865906"
 | 
				
			||||||
 | 
					         width="30.277332"
 | 
				
			||||||
 | 
					         id="rect834-5-0-3-9-1"
 | 
				
			||||||
 | 
					         style="fill:none;stroke:#000000;stroke-width:0.97745234;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291672, 1.32291672;stroke-dashoffset:0;stroke-opacity:1"
 | 
				
			||||||
 | 
					       d="M -108.38539,107.86707 V 0.89985092"
 | 
				
			||||||
 | 
					       id="path11907-6-1-0-5"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
 | 
				
			||||||
 | 
					       x="-143.52292"
 | 
				
			||||||
 | 
					       y="5.0467439"
 | 
				
			||||||
 | 
					       id="text838-6-5-0-9"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan836-1-9-91-7"
 | 
				
			||||||
 | 
					         x="-143.52292"
 | 
				
			||||||
 | 
					         y="5.0467439"
 | 
				
			||||||
 | 
					         style="font-size:4.93888903px;stroke-width:0.16370411">VirtualPCLK</tspan></text>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0-2-7)"
 | 
				
			||||||
 | 
					       d="m -112.24183,60.747629 h 10.61353"
 | 
				
			||||||
 | 
					       id="path1171-3-8-6-7"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 40 KiB  | 
							
								
								
									
										1062
									
								
								Documentation/gpu/amdgpu/display/pipeline_4k_split.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 44 KiB  | 
| 
						 | 
					@ -0,0 +1,339 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="112.16296mm"
 | 
				
			||||||
 | 
					   height="93.314507mm"
 | 
				
			||||||
 | 
					   viewBox="0 0 112.16296 93.314508"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   id="svg8"
 | 
				
			||||||
 | 
					   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
 | 
				
			||||||
 | 
					   sodipodi:docname="single-display-mpo-multi-video.svg">
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs2">
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1133"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1006"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1133-0"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     id="base"
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1.0"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0.0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:zoom="1.979899"
 | 
				
			||||||
 | 
					     inkscape:cx="255.95284"
 | 
				
			||||||
 | 
					     inkscape:cy="222.25473"
 | 
				
			||||||
 | 
					     inkscape:document-units="mm"
 | 
				
			||||||
 | 
					     inkscape:current-layer="layer1"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:window-width="1514"
 | 
				
			||||||
 | 
					     inkscape:window-height="1376"
 | 
				
			||||||
 | 
					     inkscape:window-x="1046"
 | 
				
			||||||
 | 
					     inkscape:window-y="27"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="0"
 | 
				
			||||||
 | 
					     fit-margin-top="0"
 | 
				
			||||||
 | 
					     fit-margin-left="0"
 | 
				
			||||||
 | 
					     fit-margin-right="0"
 | 
				
			||||||
 | 
					     fit-margin-bottom="0" />
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata5">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:label="Layer 1"
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer1"
 | 
				
			||||||
 | 
					     transform="translate(26.189925,5.2546503)">
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-2.2053311"
 | 
				
			||||||
 | 
					       y="32.839729"
 | 
				
			||||||
 | 
					       id="text844"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-2.2053313"
 | 
				
			||||||
 | 
					         y="32.839729"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846">Video Buffer (YUV)</tspan></text>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="30.867918"
 | 
				
			||||||
 | 
					       y="87.638779"
 | 
				
			||||||
 | 
					       id="text844-2"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="30.867918"
 | 
				
			||||||
 | 
					         y="87.638779"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-0">CRTC Output</tspan></text>
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.53249496;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.59748484, 0.53249495;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect969"
 | 
				
			||||||
 | 
					       width="111.63046"
 | 
				
			||||||
 | 
					       height="44.238331"
 | 
				
			||||||
 | 
					       x="-25.923677"
 | 
				
			||||||
 | 
					       y="-4.9884028" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="48.037342"
 | 
				
			||||||
 | 
					       y="45.781586"
 | 
				
			||||||
 | 
					       id="text844-2-9"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="48.037342"
 | 
				
			||||||
 | 
					         y="45.781586"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan2868">Hardware Composition</tspan></text>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
 | 
				
			||||||
 | 
					       d="m 32.66992,40.326865 v 9.760144"
 | 
				
			||||||
 | 
					       id="path989"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g4447"
 | 
				
			||||||
 | 
					       style="stroke:#000000">
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="0.23764905"
 | 
				
			||||||
 | 
					         x="-23.784248"
 | 
				
			||||||
 | 
					         height="29.48851"
 | 
				
			||||||
 | 
					         width="48.988979"
 | 
				
			||||||
 | 
					         id="rect836"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="3.8184125"
 | 
				
			||||||
 | 
					         x="-20.589451"
 | 
				
			||||||
 | 
					         height="6.9794898"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="3.8184123"
 | 
				
			||||||
 | 
					         x="-5.6613555"
 | 
				
			||||||
 | 
					         height="6.9794903"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="3.8184121"
 | 
				
			||||||
 | 
					         x="10.374816"
 | 
				
			||||||
 | 
					         height="6.9794908"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1-8"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="18.386644"
 | 
				
			||||||
 | 
					         x="-20.341679"
 | 
				
			||||||
 | 
					         height="6.9794903"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-7"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="18.386644"
 | 
				
			||||||
 | 
					         x="-5.4135842"
 | 
				
			||||||
 | 
					         height="6.9794908"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1-9"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="18.386644"
 | 
				
			||||||
 | 
					         x="10.622585"
 | 
				
			||||||
 | 
					         height="6.9794908"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1-8-2"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-2"
 | 
				
			||||||
 | 
					       width="48.988979"
 | 
				
			||||||
 | 
					       height="29.48851"
 | 
				
			||||||
 | 
					       x="31.367332"
 | 
				
			||||||
 | 
					       y="0.45039755"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-2-6-3"
 | 
				
			||||||
 | 
					       width="11.594959"
 | 
				
			||||||
 | 
					       height="6.9794898"
 | 
				
			||||||
 | 
					       x="34.56213"
 | 
				
			||||||
 | 
					       y="4.0311608"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-2-6-1-7"
 | 
				
			||||||
 | 
					       width="11.594959"
 | 
				
			||||||
 | 
					       height="6.9794903"
 | 
				
			||||||
 | 
					       x="49.490223"
 | 
				
			||||||
 | 
					       y="4.0311608"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-2-6-1-8-5"
 | 
				
			||||||
 | 
					       width="11.594959"
 | 
				
			||||||
 | 
					       height="6.9794908"
 | 
				
			||||||
 | 
					       x="65.526398"
 | 
				
			||||||
 | 
					       y="4.0311604"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-2-6-7-9"
 | 
				
			||||||
 | 
					       width="11.594959"
 | 
				
			||||||
 | 
					       height="6.9794903"
 | 
				
			||||||
 | 
					       x="34.809902"
 | 
				
			||||||
 | 
					       y="18.599392"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-2-6-1-9-2"
 | 
				
			||||||
 | 
					       width="11.594959"
 | 
				
			||||||
 | 
					       height="6.9794908"
 | 
				
			||||||
 | 
					       x="49.737995"
 | 
				
			||||||
 | 
					       y="18.599392"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836-2-6-1-8-2-2"
 | 
				
			||||||
 | 
					       width="11.594959"
 | 
				
			||||||
 | 
					       height="6.9794908"
 | 
				
			||||||
 | 
					       x="65.774162"
 | 
				
			||||||
 | 
					       y="18.599392"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g4562"
 | 
				
			||||||
 | 
					       transform="translate(0,11.22532)">
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="43.21352"
 | 
				
			||||||
 | 
					         x="5.9767256"
 | 
				
			||||||
 | 
					         height="29.48851"
 | 
				
			||||||
 | 
					         width="48.988979"
 | 
				
			||||||
 | 
					         id="rect836-97"
 | 
				
			||||||
 | 
					         style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="46.794285"
 | 
				
			||||||
 | 
					         x="9.1715231"
 | 
				
			||||||
 | 
					         height="6.9794898"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-36"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="46.794285"
 | 
				
			||||||
 | 
					         x="24.099619"
 | 
				
			||||||
 | 
					         height="6.9794903"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1-1"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="46.794285"
 | 
				
			||||||
 | 
					         x="40.135792"
 | 
				
			||||||
 | 
					         height="6.9794908"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1-8-29"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="61.362514"
 | 
				
			||||||
 | 
					         x="9.4192953"
 | 
				
			||||||
 | 
					         height="6.9794903"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-7-3"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="61.362514"
 | 
				
			||||||
 | 
					         x="24.347389"
 | 
				
			||||||
 | 
					         height="6.9794908"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1-9-1"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="61.362514"
 | 
				
			||||||
 | 
					         x="40.38356"
 | 
				
			||||||
 | 
					         height="6.9794908"
 | 
				
			||||||
 | 
					         width="11.594959"
 | 
				
			||||||
 | 
					         id="rect836-2-6-1-8-2-9"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="57.012939"
 | 
				
			||||||
 | 
					       y="33.603645"
 | 
				
			||||||
 | 
					       id="text844-4"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="57.012939"
 | 
				
			||||||
 | 
					         y="33.603645"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-7">Desktop Buffer (ARGB)</tspan></text>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 14 KiB  | 
							
								
								
									
										266
									
								
								Documentation/gpu/amdgpu/display/single-display-mpo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,266 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   width="148.71147mm"
 | 
				
			||||||
 | 
					   height="38.356358mm"
 | 
				
			||||||
 | 
					   viewBox="0 0 148.71148 38.356358"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   id="svg8"
 | 
				
			||||||
 | 
					   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
 | 
				
			||||||
 | 
					   sodipodi:docname="single-display-mpo.svg">
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs2">
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1133"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="Arrow1Send"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="Arrow1Send"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         id="path1006"
 | 
				
			||||||
 | 
					         d="M 0,0 5,-5 -12.5,0 5,5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					    <marker
 | 
				
			||||||
 | 
					       inkscape:stockid="TriangleOutL"
 | 
				
			||||||
 | 
					       orient="auto"
 | 
				
			||||||
 | 
					       refY="0"
 | 
				
			||||||
 | 
					       refX="0"
 | 
				
			||||||
 | 
					       id="TriangleOutL-6"
 | 
				
			||||||
 | 
					       style="overflow:visible"
 | 
				
			||||||
 | 
					       inkscape:isstock="true">
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:connector-curvature="0"
 | 
				
			||||||
 | 
					         id="path1133-0"
 | 
				
			||||||
 | 
					         d="M 5.77,0 -2.88,5 V -5 Z"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
 | 
				
			||||||
 | 
					         transform="scale(0.8)" />
 | 
				
			||||||
 | 
					    </marker>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     id="base"
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1.0"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0.0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:zoom="1.979899"
 | 
				
			||||||
 | 
					     inkscape:cx="266.07058"
 | 
				
			||||||
 | 
					     inkscape:cy="81.254796"
 | 
				
			||||||
 | 
					     inkscape:document-units="mm"
 | 
				
			||||||
 | 
					     inkscape:current-layer="layer1"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:window-width="1514"
 | 
				
			||||||
 | 
					     inkscape:window-height="1376"
 | 
				
			||||||
 | 
					     inkscape:window-x="1046"
 | 
				
			||||||
 | 
					     inkscape:window-y="27"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="0"
 | 
				
			||||||
 | 
					     fit-margin-top="0"
 | 
				
			||||||
 | 
					     fit-margin-left="0"
 | 
				
			||||||
 | 
					     fit-margin-right="0"
 | 
				
			||||||
 | 
					     fit-margin-bottom="0" />
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata5">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:label="Layer 1"
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer1"
 | 
				
			||||||
 | 
					     transform="translate(26.323559,-14.790568)">
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#999999;fill-opacity:1;stroke:#999999;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect836"
 | 
				
			||||||
 | 
					       width="48.988979"
 | 
				
			||||||
 | 
					       height="29.48851"
 | 
				
			||||||
 | 
					       x="4.9472256"
 | 
				
			||||||
 | 
					       y="17.075632"
 | 
				
			||||||
 | 
					       ry="0" />
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g905"
 | 
				
			||||||
 | 
					       transform="matrix(0.26082945,0,0,0.26082945,-26.950235,-0.99631462)">
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         y="67.568451"
 | 
				
			||||||
 | 
					         x="12.473214"
 | 
				
			||||||
 | 
					         height="60.854164"
 | 
				
			||||||
 | 
					         width="102.43154"
 | 
				
			||||||
 | 
					         id="rect834"
 | 
				
			||||||
 | 
					         style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <path
 | 
				
			||||||
 | 
					         inkscape:transform-center-y="-3.581986e-06"
 | 
				
			||||||
 | 
					         inkscape:transform-center-x="-3.3106064"
 | 
				
			||||||
 | 
					         d="m 73.620805,97.995537 -9.931819,5.734143 -9.931819,5.73413 0,-11.468274 0,-11.468276 9.931819,5.734139 z"
 | 
				
			||||||
 | 
					         inkscape:randomized="0"
 | 
				
			||||||
 | 
					         inkscape:rounded="0"
 | 
				
			||||||
 | 
					         inkscape:flatsided="false"
 | 
				
			||||||
 | 
					         sodipodi:arg2="1.0471976"
 | 
				
			||||||
 | 
					         sodipodi:arg1="0"
 | 
				
			||||||
 | 
					         sodipodi:r2="6.6212125"
 | 
				
			||||||
 | 
					         sodipodi:r1="13.242425"
 | 
				
			||||||
 | 
					         sodipodi:cy="97.995537"
 | 
				
			||||||
 | 
					         sodipodi:cx="60.37838"
 | 
				
			||||||
 | 
					         sodipodi:sides="3"
 | 
				
			||||||
 | 
					         id="path840"
 | 
				
			||||||
 | 
					         style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.22854495;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					         sodipodi:type="star" />
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="-10.357052"
 | 
				
			||||||
 | 
					       y="34.176075"
 | 
				
			||||||
 | 
					       id="text844"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         id="tspan842"
 | 
				
			||||||
 | 
					         x="-10.357052"
 | 
				
			||||||
 | 
					         y="34.176075"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112">Video Buffer (YUV)</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="-10.357052"
 | 
				
			||||||
 | 
					         y="36.706482"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846">DRM PRIMARY PLANE</tspan></text>
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.5216589;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect834-3"
 | 
				
			||||||
 | 
					       width="26.717165"
 | 
				
			||||||
 | 
					       height="15.872559"
 | 
				
			||||||
 | 
					       x="16.083126"
 | 
				
			||||||
 | 
					       y="23.883608" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="28.437061"
 | 
				
			||||||
 | 
					       y="49.158085"
 | 
				
			||||||
 | 
					       id="text844-6"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="28.437061"
 | 
				
			||||||
 | 
					         y="49.158085"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-5">Desktop Buffer (ARGB)</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="28.437061"
 | 
				
			||||||
 | 
					         y="51.688492"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan886">DRM OVERLAY PLANE</tspan></text>
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="g2874"
 | 
				
			||||||
 | 
					       transform="matrix(1.0858687,0,0,1.0858687,-4.5597909,-2.06277)">
 | 
				
			||||||
 | 
					      <rect
 | 
				
			||||||
 | 
					         ry="0"
 | 
				
			||||||
 | 
					         y="17.624969"
 | 
				
			||||||
 | 
					         x="71.504173"
 | 
				
			||||||
 | 
					         height="27.156607"
 | 
				
			||||||
 | 
					         width="45.115009"
 | 
				
			||||||
 | 
					         id="rect836-9"
 | 
				
			||||||
 | 
					         style="fill:#999999;fill-opacity:1;stroke:#999999;stroke-width:0.57941455;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g905-5"
 | 
				
			||||||
 | 
					         transform="matrix(0.24020349,0,0,0.24020349,78.763353,7.664402)">
 | 
				
			||||||
 | 
					        <rect
 | 
				
			||||||
 | 
					           style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           id="rect834-6"
 | 
				
			||||||
 | 
					           width="102.43154"
 | 
				
			||||||
 | 
					           height="60.854164"
 | 
				
			||||||
 | 
					           x="12.473214"
 | 
				
			||||||
 | 
					           y="67.568451" />
 | 
				
			||||||
 | 
					        <path
 | 
				
			||||||
 | 
					           sodipodi:type="star"
 | 
				
			||||||
 | 
					           style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.22854495;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           id="path840-2"
 | 
				
			||||||
 | 
					           sodipodi:sides="3"
 | 
				
			||||||
 | 
					           sodipodi:cx="60.37838"
 | 
				
			||||||
 | 
					           sodipodi:cy="97.995537"
 | 
				
			||||||
 | 
					           sodipodi:r1="13.242425"
 | 
				
			||||||
 | 
					           sodipodi:r2="6.6212125"
 | 
				
			||||||
 | 
					           sodipodi:arg1="0"
 | 
				
			||||||
 | 
					           sodipodi:arg2="1.0471976"
 | 
				
			||||||
 | 
					           inkscape:flatsided="false"
 | 
				
			||||||
 | 
					           inkscape:rounded="0"
 | 
				
			||||||
 | 
					           inkscape:randomized="0"
 | 
				
			||||||
 | 
					           d="m 73.620805,97.995537 -9.931819,5.734143 -9.931819,5.73413 0,-11.468274 0,-11.468276 9.931819,5.734139 z"
 | 
				
			||||||
 | 
					           inkscape:transform-center-x="-3.3106064"
 | 
				
			||||||
 | 
					           inkscape:transform-center-y="-3.581986e-06" />
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="97.551666"
 | 
				
			||||||
 | 
					       y="50.221046"
 | 
				
			||||||
 | 
					       id="text844-2"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="97.551666"
 | 
				
			||||||
 | 
					         y="50.221046"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-0">CRTC Output</tspan></text>
 | 
				
			||||||
 | 
					    <rect
 | 
				
			||||||
 | 
					       style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.42211887;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.26635657, 0.42211886;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					       id="rect969"
 | 
				
			||||||
 | 
					       width="81.806648"
 | 
				
			||||||
 | 
					       height="37.934238"
 | 
				
			||||||
 | 
					       x="-26.112499"
 | 
				
			||||||
 | 
					       y="15.001627" />
 | 
				
			||||||
 | 
					    <text
 | 
				
			||||||
 | 
					       xml:space="preserve"
 | 
				
			||||||
 | 
					       style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					       x="64.474419"
 | 
				
			||||||
 | 
					       y="31.883568"
 | 
				
			||||||
 | 
					       id="text844-2-9"><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="64.474419"
 | 
				
			||||||
 | 
					         y="31.883568"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan846-0-3">Hardware</tspan><tspan
 | 
				
			||||||
 | 
					         sodipodi:role="line"
 | 
				
			||||||
 | 
					         x="64.474419"
 | 
				
			||||||
 | 
					         y="34.413975"
 | 
				
			||||||
 | 
					         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
 | 
				
			||||||
 | 
					         id="tspan2868">Composition</tspan></text>
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
 | 
				
			||||||
 | 
					       d="m 57.401149,24.81643 h 9.760144"
 | 
				
			||||||
 | 
					       id="path989"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					    <path
 | 
				
			||||||
 | 
					       style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL-6)"
 | 
				
			||||||
 | 
					       d="m 57.401149,41.794278 h 9.760144"
 | 
				
			||||||
 | 
					       id="path989-6"
 | 
				
			||||||
 | 
					       inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 11 KiB  | 
| 
						 | 
					@ -32,6 +32,23 @@ unique_id
 | 
				
			||||||
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
 | 
					.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
 | 
				
			||||||
   :doc: unique_id
 | 
					   :doc: unique_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Accelerated Processing Units (APU) Info
 | 
				
			||||||
 | 
					---------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. csv-table::
 | 
				
			||||||
 | 
					   :header-rows: 1
 | 
				
			||||||
 | 
					   :widths: 3, 2, 2, 1, 1, 1
 | 
				
			||||||
 | 
					   :file: ./apu-asic-info-table.csv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Discrete GPU Info
 | 
				
			||||||
 | 
					-----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. csv-table::
 | 
				
			||||||
 | 
					   :header-rows: 1
 | 
				
			||||||
 | 
					   :widths: 3, 2, 2, 1, 1, 1
 | 
				
			||||||
 | 
					   :file: ./dgpu-asic-info-table.csv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GPU Memory Usage Information
 | 
					GPU Memory Usage Information
 | 
				
			||||||
============================
 | 
					============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,7 +72,8 @@ card's RLC (RunList Controller) firmware powers off the gfx engine
 | 
				
			||||||
dynamically when there is no workload on gfx or compute pipes. GFXOFF is on by
 | 
					dynamically when there is no workload on gfx or compute pipes. GFXOFF is on by
 | 
				
			||||||
default on supported GPUs.
 | 
					default on supported GPUs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Userspace can interact with GFXOFF through a debugfs interface:
 | 
					Userspace can interact with GFXOFF through a debugfs interface (all values in
 | 
				
			||||||
 | 
					`uint32_t`, unless otherwise noted):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``amdgpu_gfxoff``
 | 
					``amdgpu_gfxoff``
 | 
				
			||||||
-----------------
 | 
					-----------------
 | 
				
			||||||
| 
						 | 
					@ -104,3 +105,18 @@ Read it to check current GFXOFF's status of a GPU::
 | 
				
			||||||
If GFXOFF is enabled, the value will be transitioning around [0, 3], always
 | 
					If GFXOFF is enabled, the value will be transitioning around [0, 3], always
 | 
				
			||||||
getting into 0 when possible. When it's disabled, it's always at 2. Returns
 | 
					getting into 0 when possible. When it's disabled, it's always at 2. Returns
 | 
				
			||||||
``-EINVAL`` if it's not supported.
 | 
					``-EINVAL`` if it's not supported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					``amdgpu_gfxoff_count``
 | 
				
			||||||
 | 
					-----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Read it to get the total GFXOFF entry count at the time of query since system
 | 
				
			||||||
 | 
					power-up. The value is an `uint64_t` type, however, due to firmware limitations,
 | 
				
			||||||
 | 
					it can currently overflow as an `uint32_t`. *Only supported in vangogh*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					``amdgpu_gfxoff_residency``
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Write 1 to amdgpu_gfxoff_residency to start logging, and 0 to stop. Read it to
 | 
				
			||||||
 | 
					get average GFXOFF residency % multiplied by 100 during the last logging
 | 
				
			||||||
 | 
					interval. E.g. a value of 7854 means 78.54% of the time in the last logging
 | 
				
			||||||
 | 
					interval the GPU was in GFXOFF mode. *Only supported in vangogh*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -532,6 +532,8 @@ Standard Plane Properties
 | 
				
			||||||
.. kernel-doc:: drivers/gpu/drm/drm_plane.c
 | 
					.. kernel-doc:: drivers/gpu/drm/drm_plane.c
 | 
				
			||||||
   :doc: standard plane properties
 | 
					   :doc: standard plane properties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _plane_composition_properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Plane Composition Properties
 | 
					Plane Composition Properties
 | 
				
			||||||
----------------------------
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ amdgpu-y += \
 | 
				
			||||||
	vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
 | 
						vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
 | 
				
			||||||
	vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
 | 
						vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
 | 
				
			||||||
	nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
 | 
						nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
 | 
				
			||||||
	nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
 | 
						sienna_cichlid.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# add DF block
 | 
					# add DF block
 | 
				
			||||||
amdgpu-y += \
 | 
					amdgpu-y += \
 | 
				
			||||||
| 
						 | 
					@ -89,7 +89,7 @@ amdgpu-y += \
 | 
				
			||||||
	gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \
 | 
						gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \
 | 
				
			||||||
	gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \
 | 
						gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \
 | 
				
			||||||
	mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o \
 | 
						mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o \
 | 
				
			||||||
	mmhub_v3_0_1.o
 | 
						mmhub_v3_0_1.o gfxhub_v3_0_3.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# add UMC block
 | 
					# add UMC block
 | 
				
			||||||
amdgpu-y += \
 | 
					amdgpu-y += \
 | 
				
			||||||
| 
						 | 
					@ -134,7 +134,8 @@ amdgpu-y += \
 | 
				
			||||||
	gfx_v9_4_2.o \
 | 
						gfx_v9_4_2.o \
 | 
				
			||||||
	gfx_v10_0.o \
 | 
						gfx_v10_0.o \
 | 
				
			||||||
	imu_v11_0.o \
 | 
						imu_v11_0.o \
 | 
				
			||||||
	gfx_v11_0.o
 | 
						gfx_v11_0.o \
 | 
				
			||||||
 | 
						imu_v11_0_3.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# add async DMA block
 | 
					# add async DMA block
 | 
				
			||||||
amdgpu-y += \
 | 
					amdgpu-y += \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -274,6 +274,9 @@ extern int amdgpu_vcnfw_log;
 | 
				
			||||||
#define AMDGPU_RESET_VCE			(1 << 13)
 | 
					#define AMDGPU_RESET_VCE			(1 << 13)
 | 
				
			||||||
#define AMDGPU_RESET_VCE1			(1 << 14)
 | 
					#define AMDGPU_RESET_VCE1			(1 << 14)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AMDGPU_RESET_LEVEL_SOFT_RECOVERY (1 << 0)
 | 
				
			||||||
 | 
					#define AMDGPU_RESET_LEVEL_MODE2 (1 << 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* max cursor sizes (in pixels) */
 | 
					/* max cursor sizes (in pixels) */
 | 
				
			||||||
#define CIK_CURSOR_WIDTH 128
 | 
					#define CIK_CURSOR_WIDTH 128
 | 
				
			||||||
#define CIK_CURSOR_HEIGHT 128
 | 
					#define CIK_CURSOR_HEIGHT 128
 | 
				
			||||||
| 
						 | 
					@ -1060,6 +1063,9 @@ struct amdgpu_device {
 | 
				
			||||||
	uint32_t                        scpm_status;
 | 
						uint32_t                        scpm_status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct work_struct		reset_work;
 | 
						struct work_struct		reset_work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t						amdgpu_reset_level_mask;
 | 
				
			||||||
 | 
						bool                            job_hang;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
 | 
					static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1066,6 +1066,12 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
 | 
				
			||||||
	    (pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
 | 
						    (pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If ACPI_FADT_LOW_POWER_S0 is not set in the FADT, it is generally
 | 
				
			||||||
 | 
						 * risky to do any special firmware-related preparations for entering
 | 
				
			||||||
 | 
						 * S0ix even though the system is suspending to idle, so return false
 | 
				
			||||||
 | 
						 * in that case.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
 | 
						if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
 | 
				
			||||||
		dev_warn_once(adev->dev,
 | 
							dev_warn_once(adev->dev,
 | 
				
			||||||
			      "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
 | 
								      "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,6 +135,7 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)
 | 
				
			||||||
	reset_context.method = AMD_RESET_METHOD_NONE;
 | 
						reset_context.method = AMD_RESET_METHOD_NONE;
 | 
				
			||||||
	reset_context.reset_req_dev = adev;
 | 
						reset_context.reset_req_dev = adev;
 | 
				
			||||||
	clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
						clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
						clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
						amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1728,7 +1728,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
 | 
				
			||||||
	add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, user_addr);
 | 
						add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, user_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (user_addr) {
 | 
						if (user_addr) {
 | 
				
			||||||
		pr_debug("creating userptr BO for user_addr = %llu\n", user_addr);
 | 
							pr_debug("creating userptr BO for user_addr = %llx\n", user_addr);
 | 
				
			||||||
		ret = init_user_pages(*mem, user_addr, criu_resume);
 | 
							ret = init_user_pages(*mem, user_addr, criu_resume);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			goto allocate_init_user_pages_failed;
 | 
								goto allocate_init_user_pages_failed;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,7 +402,7 @@ static void amdgpu_ctx_fini(struct kref *ref)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (drm_dev_enter(&adev->ddev, &idx)) {
 | 
						if (drm_dev_enter(adev_to_drm(adev), &idx)) {
 | 
				
			||||||
		amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
 | 
							amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
 | 
				
			||||||
		drm_dev_exit(idx);
 | 
							drm_dev_exit(idx);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1042,6 +1042,157 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
 | 
				
			||||||
	return r;
 | 
						return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_debugfs_gfxoff_residency_read - Read GFXOFF residency
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @f: open file handle
 | 
				
			||||||
 | 
					 * @buf: User buffer to store read data in
 | 
				
			||||||
 | 
					 * @size: Number of bytes to read
 | 
				
			||||||
 | 
					 * @pos:  Offset to seek to
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Read the last residency value logged. It doesn't auto update, one needs to
 | 
				
			||||||
 | 
					 * stop logging before getting the current value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf,
 | 
				
			||||||
 | 
											    size_t size, loff_t *pos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = file_inode(f)->i_private;
 | 
				
			||||||
 | 
						ssize_t result = 0;
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (size & 0x3 || *pos & 0x3)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
						if (r < 0) {
 | 
				
			||||||
 | 
							pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (size) {
 | 
				
			||||||
 | 
							uint32_t value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r = amdgpu_get_gfx_off_residency(adev, &value);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r = put_user(value, (uint32_t *)buf);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result += 4;
 | 
				
			||||||
 | 
							buf += 4;
 | 
				
			||||||
 | 
							*pos += 4;
 | 
				
			||||||
 | 
							size -= 4;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = result;
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
						pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_debugfs_gfxoff_residency_write - Log GFXOFF Residency
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @f: open file handle
 | 
				
			||||||
 | 
					 * @buf: User buffer to write data from
 | 
				
			||||||
 | 
					 * @size: Number of bytes to write
 | 
				
			||||||
 | 
					 * @pos:  Offset to seek to
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Write a 32-bit non-zero to start logging; write a 32-bit zero to stop
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static ssize_t amdgpu_debugfs_gfxoff_residency_write(struct file *f, const char __user *buf,
 | 
				
			||||||
 | 
											     size_t size, loff_t *pos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = file_inode(f)->i_private;
 | 
				
			||||||
 | 
						ssize_t result = 0;
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (size & 0x3 || *pos & 0x3)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
						if (r < 0) {
 | 
				
			||||||
 | 
							pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (size) {
 | 
				
			||||||
 | 
							u32 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r = get_user(value, (uint32_t *)buf);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							amdgpu_set_gfx_off_residency(adev, value ? true : false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result += 4;
 | 
				
			||||||
 | 
							buf += 4;
 | 
				
			||||||
 | 
							*pos += 4;
 | 
				
			||||||
 | 
							size -= 4;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = result;
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
						pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_debugfs_gfxoff_count_read - Read GFXOFF entry count
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @f: open file handle
 | 
				
			||||||
 | 
					 * @buf: User buffer to store read data in
 | 
				
			||||||
 | 
					 * @size: Number of bytes to read
 | 
				
			||||||
 | 
					 * @pos:  Offset to seek to
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static ssize_t amdgpu_debugfs_gfxoff_count_read(struct file *f, char __user *buf,
 | 
				
			||||||
 | 
											size_t size, loff_t *pos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = file_inode(f)->i_private;
 | 
				
			||||||
 | 
						ssize_t result = 0;
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (size & 0x3 || *pos & 0x3)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
						if (r < 0) {
 | 
				
			||||||
 | 
							pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (size) {
 | 
				
			||||||
 | 
							u64 value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r = amdgpu_get_gfx_off_entrycount(adev, &value);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r = put_user(value, (u64 *)buf);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result += 4;
 | 
				
			||||||
 | 
							buf += 4;
 | 
				
			||||||
 | 
							*pos += 4;
 | 
				
			||||||
 | 
							size -= 4;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = result;
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
						pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF
 | 
					 * amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -1249,6 +1400,19 @@ static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = {
 | 
				
			||||||
	.llseek = default_llseek
 | 
						.llseek = default_llseek
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct file_operations amdgpu_debugfs_gfxoff_count_fops = {
 | 
				
			||||||
 | 
						.owner = THIS_MODULE,
 | 
				
			||||||
 | 
						.read = amdgpu_debugfs_gfxoff_count_read,
 | 
				
			||||||
 | 
						.llseek = default_llseek
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct file_operations amdgpu_debugfs_gfxoff_residency_fops = {
 | 
				
			||||||
 | 
						.owner = THIS_MODULE,
 | 
				
			||||||
 | 
						.read = amdgpu_debugfs_gfxoff_residency_read,
 | 
				
			||||||
 | 
						.write = amdgpu_debugfs_gfxoff_residency_write,
 | 
				
			||||||
 | 
						.llseek = default_llseek
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct file_operations *debugfs_regs[] = {
 | 
					static const struct file_operations *debugfs_regs[] = {
 | 
				
			||||||
	&amdgpu_debugfs_regs_fops,
 | 
						&amdgpu_debugfs_regs_fops,
 | 
				
			||||||
	&amdgpu_debugfs_regs2_fops,
 | 
						&amdgpu_debugfs_regs2_fops,
 | 
				
			||||||
| 
						 | 
					@ -1261,6 +1425,8 @@ static const struct file_operations *debugfs_regs[] = {
 | 
				
			||||||
	&amdgpu_debugfs_gpr_fops,
 | 
						&amdgpu_debugfs_gpr_fops,
 | 
				
			||||||
	&amdgpu_debugfs_gfxoff_fops,
 | 
						&amdgpu_debugfs_gfxoff_fops,
 | 
				
			||||||
	&amdgpu_debugfs_gfxoff_status_fops,
 | 
						&amdgpu_debugfs_gfxoff_status_fops,
 | 
				
			||||||
 | 
						&amdgpu_debugfs_gfxoff_count_fops,
 | 
				
			||||||
 | 
						&amdgpu_debugfs_gfxoff_residency_fops,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *debugfs_regs_names[] = {
 | 
					static const char *debugfs_regs_names[] = {
 | 
				
			||||||
| 
						 | 
					@ -1275,6 +1441,8 @@ static const char *debugfs_regs_names[] = {
 | 
				
			||||||
	"amdgpu_gpr",
 | 
						"amdgpu_gpr",
 | 
				
			||||||
	"amdgpu_gfxoff",
 | 
						"amdgpu_gfxoff",
 | 
				
			||||||
	"amdgpu_gfxoff_status",
 | 
						"amdgpu_gfxoff_status",
 | 
				
			||||||
 | 
						"amdgpu_gfxoff_count",
 | 
				
			||||||
 | 
						"amdgpu_gfxoff_residency",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1786,6 +1954,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
 | 
				
			||||||
		return PTR_ERR(ent);
 | 
							return PTR_ERR(ent);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						debugfs_create_u32("amdgpu_reset_level", 0600, root, &adev->amdgpu_reset_level_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Register debugfs entries for amdgpu_ttm */
 | 
						/* Register debugfs entries for amdgpu_ttm */
 | 
				
			||||||
	amdgpu_ttm_debugfs_init(adev);
 | 
						amdgpu_ttm_debugfs_init(adev);
 | 
				
			||||||
	amdgpu_debugfs_pm_init(adev);
 | 
						amdgpu_debugfs_pm_init(adev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2456,12 +2456,14 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
 | 
				
			||||||
			if (!hive->reset_domain ||
 | 
								if (!hive->reset_domain ||
 | 
				
			||||||
			    !amdgpu_reset_get_reset_domain(hive->reset_domain)) {
 | 
								    !amdgpu_reset_get_reset_domain(hive->reset_domain)) {
 | 
				
			||||||
				r = -ENOENT;
 | 
									r = -ENOENT;
 | 
				
			||||||
 | 
									amdgpu_put_xgmi_hive(hive);
 | 
				
			||||||
				goto init_failed;
 | 
									goto init_failed;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Drop the early temporary reset domain we created for device */
 | 
								/* Drop the early temporary reset domain we created for device */
 | 
				
			||||||
			amdgpu_reset_put_reset_domain(adev->reset_domain);
 | 
								amdgpu_reset_put_reset_domain(adev->reset_domain);
 | 
				
			||||||
			adev->reset_domain = hive->reset_domain;
 | 
								adev->reset_domain = hive->reset_domain;
 | 
				
			||||||
 | 
								amdgpu_put_xgmi_hive(hive);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3577,6 +3579,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 | 
				
			||||||
	INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func);
 | 
						INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adev->gfx.gfx_off_req_count = 1;
 | 
						adev->gfx.gfx_off_req_count = 1;
 | 
				
			||||||
 | 
						adev->gfx.gfx_off_residency = 0;
 | 
				
			||||||
 | 
						adev->gfx.gfx_off_entrycount = 0;
 | 
				
			||||||
	adev->pm.ac_power = power_supply_is_system_supplied() > 0;
 | 
						adev->pm.ac_power = power_supply_is_system_supplied() > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	atomic_set(&adev->throttling_logging_enabled, 1);
 | 
						atomic_set(&adev->throttling_logging_enabled, 1);
 | 
				
			||||||
| 
						 | 
					@ -3965,8 +3969,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amdgpu_gart_dummy_page_fini(adev);
 | 
						amdgpu_gart_dummy_page_fini(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (drm_dev_is_unplugged(adev_to_drm(adev)))
 | 
						amdgpu_device_unmap_mmio(adev);
 | 
				
			||||||
		amdgpu_device_unmap_mmio(adev);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4413,8 +4416,6 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
 | 
				
			||||||
retry:
 | 
					retry:
 | 
				
			||||||
	amdgpu_amdkfd_pre_reset(adev);
 | 
						amdgpu_amdkfd_pre_reset(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amdgpu_amdkfd_pre_reset(adev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (from_hypervisor)
 | 
						if (from_hypervisor)
 | 
				
			||||||
		r = amdgpu_virt_request_full_gpu(adev, true);
 | 
							r = amdgpu_virt_request_full_gpu(adev, true);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -4509,14 +4510,15 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
 | 
					bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!amdgpu_device_ip_check_soft_reset(adev)) {
 | 
					 | 
				
			||||||
		dev_info(adev->dev, "Timeout, but no hardware hang detected.\n");
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_gpu_recovery == 0)
 | 
						if (amdgpu_gpu_recovery == 0)
 | 
				
			||||||
		goto disabled;
 | 
							goto disabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!amdgpu_device_ip_check_soft_reset(adev)) {
 | 
				
			||||||
 | 
							dev_info(adev->dev,"Timeout, but no hardware hang detected.\n");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_sriov_vf(adev))
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4641,7 +4643,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
 | 
				
			||||||
		if (!need_full_reset)
 | 
							if (!need_full_reset)
 | 
				
			||||||
			need_full_reset = amdgpu_device_ip_need_full_reset(adev);
 | 
								need_full_reset = amdgpu_device_ip_need_full_reset(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!need_full_reset) {
 | 
							if (!need_full_reset && amdgpu_gpu_recovery) {
 | 
				
			||||||
			amdgpu_device_ip_pre_soft_reset(adev);
 | 
								amdgpu_device_ip_pre_soft_reset(adev);
 | 
				
			||||||
			r = amdgpu_device_ip_soft_reset(adev);
 | 
								r = amdgpu_device_ip_soft_reset(adev);
 | 
				
			||||||
			amdgpu_device_ip_post_soft_reset(adev);
 | 
								amdgpu_device_ip_post_soft_reset(adev);
 | 
				
			||||||
| 
						 | 
					@ -5039,6 +5041,7 @@ static void amdgpu_device_recheck_guilty_jobs(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* set guilty */
 | 
								/* set guilty */
 | 
				
			||||||
			drm_sched_increase_karma(s_job);
 | 
								drm_sched_increase_karma(s_job);
 | 
				
			||||||
 | 
								amdgpu_reset_prepare_hwcontext(adev, reset_context);
 | 
				
			||||||
retry:
 | 
					retry:
 | 
				
			||||||
			/* do hw reset */
 | 
								/* do hw reset */
 | 
				
			||||||
			if (amdgpu_sriov_vf(adev)) {
 | 
								if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
| 
						 | 
					@ -5148,6 +5151,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reset_context->job = job;
 | 
						reset_context->job = job;
 | 
				
			||||||
	reset_context->hive = hive;
 | 
						reset_context->hive = hive;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Build list of devices to reset.
 | 
						 * Build list of devices to reset.
 | 
				
			||||||
	 * In case we are in XGMI hive mode, resort the device list
 | 
						 * In case we are in XGMI hive mode, resort the device list
 | 
				
			||||||
| 
						 | 
					@ -5267,8 +5271,11 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 | 
				
			||||||
			amdgpu_ras_resume(adev);
 | 
								amdgpu_ras_resume(adev);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		r = amdgpu_do_asic_reset(device_list_handle, reset_context);
 | 
							r = amdgpu_do_asic_reset(device_list_handle, reset_context);
 | 
				
			||||||
		if (r && r == -EAGAIN)
 | 
							if (r && r == -EAGAIN) {
 | 
				
			||||||
 | 
								set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags);
 | 
				
			||||||
 | 
								adev->asic_reset_res = 0;
 | 
				
			||||||
			goto retry;
 | 
								goto retry;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
skip_hw_reset:
 | 
					skip_hw_reset:
 | 
				
			||||||
| 
						 | 
					@ -5524,7 +5531,8 @@ bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
 | 
				
			||||||
		~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1);
 | 
							~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1);
 | 
				
			||||||
	resource_size_t aper_limit =
 | 
						resource_size_t aper_limit =
 | 
				
			||||||
		adev->gmc.aper_base + adev->gmc.aper_size - 1;
 | 
							adev->gmc.aper_base + adev->gmc.aper_size - 1;
 | 
				
			||||||
	bool p2p_access = !(pci_p2pdma_distance_many(adev->pdev,
 | 
						bool p2p_access = !adev->gmc.xgmi.connected_to_cpu &&
 | 
				
			||||||
 | 
								  !(pci_p2pdma_distance_many(adev->pdev,
 | 
				
			||||||
					&peer_adev->dev, 1, true) < 0);
 | 
										&peer_adev->dev, 1, true) < 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size &&
 | 
						return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size &&
 | 
				
			||||||
| 
						 | 
					@ -5699,6 +5707,7 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
 | 
				
			||||||
	reset_context.reset_req_dev = adev;
 | 
						reset_context.reset_req_dev = adev;
 | 
				
			||||||
	set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
						set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
				
			||||||
	set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
 | 
						set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
						set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adev->no_hw_access = true;
 | 
						adev->no_hw_access = true;
 | 
				
			||||||
	r = amdgpu_device_pre_asic_reset(adev, &reset_context);
 | 
						r = amdgpu_device_pre_asic_reset(adev, &reset_context);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1506,6 +1506,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
 | 
							amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -1549,6 +1550,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
 | 
							amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -1633,6 +1635,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(13, 0, 5):
 | 
						case IP_VERSION(13, 0, 5):
 | 
				
			||||||
	case IP_VERSION(13, 0, 7):
 | 
						case IP_VERSION(13, 0, 7):
 | 
				
			||||||
	case IP_VERSION(13, 0, 8):
 | 
						case IP_VERSION(13, 0, 8):
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 10):
 | 
				
			||||||
		amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
 | 
							amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(13, 0, 4):
 | 
						case IP_VERSION(13, 0, 4):
 | 
				
			||||||
| 
						 | 
					@ -1682,6 +1685,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(13, 0, 5):
 | 
						case IP_VERSION(13, 0, 5):
 | 
				
			||||||
	case IP_VERSION(13, 0, 7):
 | 
						case IP_VERSION(13, 0, 7):
 | 
				
			||||||
	case IP_VERSION(13, 0, 8):
 | 
						case IP_VERSION(13, 0, 8):
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 10):
 | 
				
			||||||
		amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
 | 
							amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -1780,6 +1784,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
 | 
							amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -1823,6 +1828,7 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(6, 0, 0):
 | 
						case IP_VERSION(6, 0, 0):
 | 
				
			||||||
	case IP_VERSION(6, 0, 1):
 | 
						case IP_VERSION(6, 0, 1):
 | 
				
			||||||
	case IP_VERSION(6, 0, 2):
 | 
						case IP_VERSION(6, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(6, 0, 3):
 | 
				
			||||||
		amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
 | 
							amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -1903,7 +1909,8 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		case IP_VERSION(4, 0, 2):
 | 
							case IP_VERSION(4, 0, 2):
 | 
				
			||||||
		case IP_VERSION(4, 0, 4):
 | 
							case IP_VERSION(4, 0, 4):
 | 
				
			||||||
			amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block);
 | 
								amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block);
 | 
				
			||||||
			amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
 | 
								if (!amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
									amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			dev_err(adev->dev,
 | 
								dev_err(adev->dev,
 | 
				
			||||||
| 
						 | 
					@ -1940,6 +1947,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
 | 
							amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
 | 
				
			||||||
		adev->enable_mes = true;
 | 
							adev->enable_mes = true;
 | 
				
			||||||
		adev->enable_mes_kiq = true;
 | 
							adev->enable_mes_kiq = true;
 | 
				
			||||||
| 
						 | 
					@ -2165,6 +2173,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		adev->family = AMDGPU_FAMILY_GC_11_0_0;
 | 
							adev->family = AMDGPU_FAMILY_GC_11_0_0;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
| 
						 | 
					@ -2234,7 +2243,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(4, 3, 0):
 | 
						case IP_VERSION(4, 3, 0):
 | 
				
			||||||
	case IP_VERSION(4, 3, 1):
 | 
						case IP_VERSION(4, 3, 1):
 | 
				
			||||||
		adev->nbio.funcs = &nbio_v4_3_funcs;
 | 
							if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
								adev->nbio.funcs = &nbio_v4_3_sriov_funcs;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								adev->nbio.funcs = &nbio_v4_3_funcs;
 | 
				
			||||||
		adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg;
 | 
							adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(7, 7, 0):
 | 
						case IP_VERSION(7, 7, 0):
 | 
				
			||||||
| 
						 | 
					@ -2332,6 +2344,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(6, 0, 0):
 | 
						case IP_VERSION(6, 0, 0):
 | 
				
			||||||
	case IP_VERSION(6, 0, 1):
 | 
						case IP_VERSION(6, 0, 1):
 | 
				
			||||||
	case IP_VERSION(6, 0, 2):
 | 
						case IP_VERSION(6, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(6, 0, 3):
 | 
				
			||||||
		adev->lsdma.funcs = &lsdma_v6_0_funcs;
 | 
							adev->lsdma.funcs = &lsdma_v6_0_funcs;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2181,8 +2181,6 @@ amdgpu_pci_remove(struct pci_dev *pdev)
 | 
				
			||||||
	struct drm_device *dev = pci_get_drvdata(pdev);
 | 
						struct drm_device *dev = pci_get_drvdata(pdev);
 | 
				
			||||||
	struct amdgpu_device *adev = drm_to_adev(dev);
 | 
						struct amdgpu_device *adev = drm_to_adev(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drm_dev_unplug(dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) {
 | 
						if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) {
 | 
				
			||||||
		pm_runtime_get_sync(dev->dev);
 | 
							pm_runtime_get_sync(dev->dev);
 | 
				
			||||||
		pm_runtime_forbid(dev->dev);
 | 
							pm_runtime_forbid(dev->dev);
 | 
				
			||||||
| 
						 | 
					@ -2190,6 +2188,8 @@ amdgpu_pci_remove(struct pci_dev *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amdgpu_driver_unload_kms(dev);
 | 
						amdgpu_driver_unload_kms(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_dev_unplug(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Flush any in flight DMA operations from device.
 | 
						 * Flush any in flight DMA operations from device.
 | 
				
			||||||
	 * Clear the Bus Master Enable bit and then wait on the PCIe Device
 | 
						 * Clear the Bus Master Enable bit and then wait on the PCIe Device
 | 
				
			||||||
| 
						 | 
					@ -2563,8 +2563,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
 | 
				
			||||||
		amdgpu_device_baco_exit(drm_dev);
 | 
							amdgpu_device_baco_exit(drm_dev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ret = amdgpu_device_resume(drm_dev, false);
 | 
						ret = amdgpu_device_resume(drm_dev, false);
 | 
				
			||||||
	if (ret)
 | 
						if (ret) {
 | 
				
			||||||
 | 
							if (amdgpu_device_supports_px(drm_dev))
 | 
				
			||||||
 | 
								pci_disable_device(pdev);
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_device_supports_px(drm_dev))
 | 
						if (amdgpu_device_supports_px(drm_dev))
 | 
				
			||||||
		drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
 | 
							drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,10 +66,15 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	case CHIP_SIENNA_CICHLID:
 | 
						case CHIP_SIENNA_CICHLID:
 | 
				
			||||||
		if (strnstr(atom_ctx->vbios_version, "D603",
 | 
							if (strnstr(atom_ctx->vbios_version, "D603",
 | 
				
			||||||
 | 
							    sizeof(atom_ctx->vbios_version))) {
 | 
				
			||||||
 | 
								if (strnstr(atom_ctx->vbios_version, "D603GLXE",
 | 
				
			||||||
			    sizeof(atom_ctx->vbios_version)))
 | 
								    sizeof(atom_ctx->vbios_version)))
 | 
				
			||||||
			return true;
 | 
									return false;
 | 
				
			||||||
		else
 | 
								else
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -477,7 +477,7 @@ int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev)
 | 
				
			||||||
		kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.compute_ring[i],
 | 
							kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.compute_ring[i],
 | 
				
			||||||
					   RESET_QUEUES, 0, 0);
 | 
										   RESET_QUEUES, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adev->gfx.kiq.ring.sched.ready)
 | 
						if (adev->gfx.kiq.ring.sched.ready && !adev->job_hang)
 | 
				
			||||||
		r = amdgpu_ring_test_helper(kiq_ring);
 | 
							r = amdgpu_ring_test_helper(kiq_ring);
 | 
				
			||||||
	spin_unlock(&adev->gfx.kiq.ring_lock);
 | 
						spin_unlock(&adev->gfx.kiq.ring_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -610,6 +610,45 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
 | 
				
			||||||
	mutex_unlock(&adev->gfx.gfx_off_mutex);
 | 
						mutex_unlock(&adev->gfx.gfx_off_mutex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&adev->gfx.gfx_off_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = amdgpu_dpm_set_residency_gfxoff(adev, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&adev->gfx.gfx_off_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&adev->gfx.gfx_off_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = amdgpu_dpm_get_residency_gfxoff(adev, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&adev->gfx.gfx_off_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&adev->gfx.gfx_off_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = amdgpu_dpm_get_entrycount_gfxoff(adev, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&adev->gfx.gfx_off_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
 | 
					int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -332,10 +332,12 @@ struct amdgpu_gfx {
 | 
				
			||||||
	uint32_t                        srbm_soft_reset;
 | 
						uint32_t                        srbm_soft_reset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* gfx off */
 | 
						/* gfx off */
 | 
				
			||||||
	bool                            gfx_off_state; /* true: enabled, false: disabled */
 | 
						bool                            gfx_off_state;      /* true: enabled, false: disabled */
 | 
				
			||||||
	struct mutex                    gfx_off_mutex;
 | 
						struct mutex                    gfx_off_mutex;      /* mutex to change gfxoff state */
 | 
				
			||||||
	uint32_t                        gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
 | 
						uint32_t                        gfx_off_req_count;  /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
 | 
				
			||||||
	struct delayed_work             gfx_off_delay_work;
 | 
						struct delayed_work             gfx_off_delay_work; /* async work to set gfx block off */
 | 
				
			||||||
 | 
						uint32_t                        gfx_off_residency;  /* last logged residency */
 | 
				
			||||||
 | 
						uint64_t                        gfx_off_entrycount; /* count of times GPU has get into GFXOFF state */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* pipe reservation */
 | 
						/* pipe reservation */
 | 
				
			||||||
	struct mutex			pipe_reserve_mutex;
 | 
						struct mutex			pipe_reserve_mutex;
 | 
				
			||||||
| 
						 | 
					@ -407,6 +409,10 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
 | 
				
			||||||
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
 | 
					void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
 | 
				
			||||||
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
 | 
					int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
 | 
				
			||||||
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
 | 
					int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
 | 
				
			||||||
 | 
					void amdgpu_gfx_ras_fini(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value);
 | 
				
			||||||
 | 
					int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *residency);
 | 
				
			||||||
 | 
					int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value);
 | 
				
			||||||
int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
 | 
					int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
 | 
				
			||||||
		void *err_data,
 | 
							void *err_data,
 | 
				
			||||||
		struct amdgpu_iv_entry *entry);
 | 
							struct amdgpu_iv_entry *entry);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,9 @@ struct amdgpu_gfxhub_funcs {
 | 
				
			||||||
	void (*init)(struct amdgpu_device *adev);
 | 
						void (*init)(struct amdgpu_device *adev);
 | 
				
			||||||
	int (*get_xgmi_info)(struct amdgpu_device *adev);
 | 
						int (*get_xgmi_info)(struct amdgpu_device *adev);
 | 
				
			||||||
	void (*utcl2_harvest)(struct amdgpu_device *adev);
 | 
						void (*utcl2_harvest)(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
						void (*mode2_save_regs)(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
						void (*mode2_restore_regs)(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
						void (*halt)(struct amdgpu_device *adev);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_gfxhub {
 | 
					struct amdgpu_gfxhub {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -264,6 +264,32 @@ struct amdgpu_gmc {
 | 
				
			||||||
	u64 mall_size;
 | 
						u64 mall_size;
 | 
				
			||||||
	/* number of UMC instances */
 | 
						/* number of UMC instances */
 | 
				
			||||||
	int num_umc;
 | 
						int num_umc;
 | 
				
			||||||
 | 
						/* mode2 save restore */
 | 
				
			||||||
 | 
						u64 VM_L2_CNTL;
 | 
				
			||||||
 | 
						u64 VM_L2_CNTL2;
 | 
				
			||||||
 | 
						u64 VM_DUMMY_PAGE_FAULT_CNTL;
 | 
				
			||||||
 | 
						u64 VM_DUMMY_PAGE_FAULT_ADDR_LO32;
 | 
				
			||||||
 | 
						u64 VM_DUMMY_PAGE_FAULT_ADDR_HI32;
 | 
				
			||||||
 | 
						u64 VM_L2_PROTECTION_FAULT_CNTL;
 | 
				
			||||||
 | 
						u64 VM_L2_PROTECTION_FAULT_CNTL2;
 | 
				
			||||||
 | 
						u64 VM_L2_PROTECTION_FAULT_MM_CNTL3;
 | 
				
			||||||
 | 
						u64 VM_L2_PROTECTION_FAULT_MM_CNTL4;
 | 
				
			||||||
 | 
						u64 VM_L2_PROTECTION_FAULT_ADDR_LO32;
 | 
				
			||||||
 | 
						u64 VM_L2_PROTECTION_FAULT_ADDR_HI32;
 | 
				
			||||||
 | 
						u64 VM_DEBUG;
 | 
				
			||||||
 | 
						u64 VM_L2_MM_GROUP_RT_CLASSES;
 | 
				
			||||||
 | 
						u64 VM_L2_BANK_SELECT_RESERVED_CID;
 | 
				
			||||||
 | 
						u64 VM_L2_BANK_SELECT_RESERVED_CID2;
 | 
				
			||||||
 | 
						u64 VM_L2_CACHE_PARITY_CNTL;
 | 
				
			||||||
 | 
						u64 VM_L2_IH_LOG_CNTL;
 | 
				
			||||||
 | 
						u64 VM_CONTEXT_CNTL[16];
 | 
				
			||||||
 | 
						u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[16];
 | 
				
			||||||
 | 
						u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[16];
 | 
				
			||||||
 | 
						u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[16];
 | 
				
			||||||
 | 
						u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[16];
 | 
				
			||||||
 | 
						u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[16];
 | 
				
			||||||
 | 
						u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[16];
 | 
				
			||||||
 | 
						u64 MC_VM_MX_L1_TLB_CNTL;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
 | 
					#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&ti, 0, sizeof(struct amdgpu_task_info));
 | 
						memset(&ti, 0, sizeof(struct amdgpu_task_info));
 | 
				
			||||||
 | 
						adev->job_hang = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_gpu_recovery &&
 | 
						if (amdgpu_gpu_recovery &&
 | 
				
			||||||
	    amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) {
 | 
						    amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) {
 | 
				
			||||||
| 
						 | 
					@ -71,6 +72,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
 | 
				
			||||||
		reset_context.method = AMD_RESET_METHOD_NONE;
 | 
							reset_context.method = AMD_RESET_METHOD_NONE;
 | 
				
			||||||
		reset_context.reset_req_dev = adev;
 | 
							reset_context.reset_req_dev = adev;
 | 
				
			||||||
		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
							clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
							clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context);
 | 
							r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context);
 | 
				
			||||||
		if (r)
 | 
							if (r)
 | 
				
			||||||
| 
						 | 
					@ -82,6 +84,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exit:
 | 
					exit:
 | 
				
			||||||
 | 
						adev->job_hang = false;
 | 
				
			||||||
	drm_dev_exit(idx);
 | 
						drm_dev_exit(idx);
 | 
				
			||||||
	return DRM_GPU_SCHED_STAT_NOMINAL;
 | 
						return DRM_GPU_SCHED_STAT_NOMINAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -159,7 +162,10 @@ void amdgpu_job_free(struct amdgpu_job *job)
 | 
				
			||||||
	amdgpu_sync_free(&job->sync);
 | 
						amdgpu_sync_free(&job->sync);
 | 
				
			||||||
	amdgpu_sync_free(&job->sched_sync);
 | 
						amdgpu_sync_free(&job->sched_sync);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dma_fence_put(&job->hw_fence);
 | 
						if (!job->hw_fence.ops)
 | 
				
			||||||
 | 
							kfree(job);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							dma_fence_put(&job->hw_fence);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
 | 
					int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,6 +181,9 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
 | 
				
			||||||
	for (i = 0; i < AMDGPU_MES_MAX_SDMA_PIPES; i++) {
 | 
						for (i = 0; i < AMDGPU_MES_MAX_SDMA_PIPES; i++) {
 | 
				
			||||||
		if (adev->ip_versions[SDMA0_HWIP][0] < IP_VERSION(6, 0, 0))
 | 
							if (adev->ip_versions[SDMA0_HWIP][0] < IP_VERSION(6, 0, 0))
 | 
				
			||||||
			adev->mes.sdma_hqd_mask[i] = i ? 0 : 0x3fc;
 | 
								adev->mes.sdma_hqd_mask[i] = i ? 0 : 0x3fc;
 | 
				
			||||||
 | 
							/* zero sdma_hqd_mask for non-existent engine */
 | 
				
			||||||
 | 
							else if (adev->sdma.num_instances == 1)
 | 
				
			||||||
 | 
								adev->mes.sdma_hqd_mask[i] = i ? 0 : 0xfc;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			adev->mes.sdma_hqd_mask[i] = 0xfc;
 | 
								adev->mes.sdma_hqd_mask[i] = 0xfc;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,6 +138,7 @@ static int psp_early_init(void *handle)
 | 
				
			||||||
	case IP_VERSION(13, 0, 3):
 | 
						case IP_VERSION(13, 0, 3):
 | 
				
			||||||
	case IP_VERSION(13, 0, 5):
 | 
						case IP_VERSION(13, 0, 5):
 | 
				
			||||||
	case IP_VERSION(13, 0, 8):
 | 
						case IP_VERSION(13, 0, 8):
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 10):
 | 
				
			||||||
		psp_v13_0_set_psp_funcs(psp);
 | 
							psp_v13_0_set_psp_funcs(psp);
 | 
				
			||||||
		psp->autoload_supported = true;
 | 
							psp->autoload_supported = true;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -327,23 +328,32 @@ static int psp_init_sriov_microcode(struct psp_context *psp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (adev->ip_versions[MP0_HWIP][0]) {
 | 
						switch (adev->ip_versions[MP0_HWIP][0]) {
 | 
				
			||||||
	case IP_VERSION(9, 0, 0):
 | 
						case IP_VERSION(9, 0, 0):
 | 
				
			||||||
 | 
							adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
 | 
				
			||||||
		ret = psp_init_cap_microcode(psp, "vega10");
 | 
							ret = psp_init_cap_microcode(psp, "vega10");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(11, 0, 9):
 | 
						case IP_VERSION(11, 0, 9):
 | 
				
			||||||
 | 
							adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
 | 
				
			||||||
		ret = psp_init_cap_microcode(psp, "navi12");
 | 
							ret = psp_init_cap_microcode(psp, "navi12");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(11, 0, 7):
 | 
						case IP_VERSION(11, 0, 7):
 | 
				
			||||||
 | 
							adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
 | 
				
			||||||
		ret = psp_init_cap_microcode(psp, "sienna_cichlid");
 | 
							ret = psp_init_cap_microcode(psp, "sienna_cichlid");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(13, 0, 2):
 | 
						case IP_VERSION(13, 0, 2):
 | 
				
			||||||
 | 
							adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
 | 
				
			||||||
		ret = psp_init_cap_microcode(psp, "aldebaran");
 | 
							ret = psp_init_cap_microcode(psp, "aldebaran");
 | 
				
			||||||
		ret &= psp_init_ta_microcode(psp, "aldebaran");
 | 
							ret &= psp_init_ta_microcode(psp, "aldebaran");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 0):
 | 
				
			||||||
 | 
							adev->virt.autoload_ucode_id = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 10):
 | 
				
			||||||
 | 
							adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		BUG();
 | 
							BUG();
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -486,11 +496,14 @@ static int psp_sw_fini(void *handle)
 | 
				
			||||||
		release_firmware(psp->ta_fw);
 | 
							release_firmware(psp->ta_fw);
 | 
				
			||||||
		psp->ta_fw = NULL;
 | 
							psp->ta_fw = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (adev->psp.cap_fw) {
 | 
						if (psp->cap_fw) {
 | 
				
			||||||
		release_firmware(psp->cap_fw);
 | 
							release_firmware(psp->cap_fw);
 | 
				
			||||||
		psp->cap_fw = NULL;
 | 
							psp->cap_fw = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (psp->toc_fw) {
 | 
				
			||||||
 | 
							release_firmware(psp->toc_fw);
 | 
				
			||||||
 | 
							psp->toc_fw = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) ||
 | 
						if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) ||
 | 
				
			||||||
	    adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7))
 | 
						    adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7))
 | 
				
			||||||
		psp_sysfs_fini(adev);
 | 
							psp_sysfs_fini(adev);
 | 
				
			||||||
| 
						 | 
					@ -766,6 +779,7 @@ static bool psp_skip_tmr(struct psp_context *psp)
 | 
				
			||||||
	case IP_VERSION(11, 0, 9):
 | 
						case IP_VERSION(11, 0, 9):
 | 
				
			||||||
	case IP_VERSION(11, 0, 7):
 | 
						case IP_VERSION(11, 0, 7):
 | 
				
			||||||
	case IP_VERSION(13, 0, 2):
 | 
						case IP_VERSION(13, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 10):
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					@ -812,7 +826,7 @@ static int psp_tmr_unload(struct psp_context *psp)
 | 
				
			||||||
	struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
 | 
						struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	psp_prep_tmr_unload_cmd_buf(psp, cmd);
 | 
						psp_prep_tmr_unload_cmd_buf(psp, cmd);
 | 
				
			||||||
	DRM_INFO("free PSP TMR buffer\n");
 | 
						dev_info(psp->adev->dev, "free PSP TMR buffer\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = psp_cmd_submit_buf(psp, NULL, cmd,
 | 
						ret = psp_cmd_submit_buf(psp, NULL, cmd,
 | 
				
			||||||
				 psp->fence_buf_mc_addr);
 | 
									 psp->fence_buf_mc_addr);
 | 
				
			||||||
| 
						 | 
					@ -2401,7 +2415,7 @@ static int psp_load_smu_fw(struct psp_context *psp)
 | 
				
			||||||
static bool fw_load_skip_check(struct psp_context *psp,
 | 
					static bool fw_load_skip_check(struct psp_context *psp,
 | 
				
			||||||
			       struct amdgpu_firmware_info *ucode)
 | 
								       struct amdgpu_firmware_info *ucode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!ucode->fw)
 | 
						if (!ucode->fw || !ucode->ucode_size)
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
 | 
						if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
 | 
				
			||||||
| 
						 | 
					@ -2411,20 +2425,7 @@ static bool fw_load_skip_check(struct psp_context *psp,
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_sriov_vf(psp->adev) &&
 | 
						if (amdgpu_sriov_vf(psp->adev) &&
 | 
				
			||||||
	   (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
 | 
						    amdgpu_virt_fw_load_skip_check(psp->adev, ucode->ucode_id))
 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
 | 
					 | 
				
			||||||
	    || ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
 | 
					 | 
				
			||||||
		/*skip ucode loading in SRIOV VF */
 | 
					 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (psp->autoload_supported &&
 | 
						if (psp->autoload_supported &&
 | 
				
			||||||
| 
						 | 
					@ -2498,7 +2499,7 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Start rlc autoload after psp recieved all the gfx firmware */
 | 
							/* Start rlc autoload after psp recieved all the gfx firmware */
 | 
				
			||||||
		if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?
 | 
							if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?
 | 
				
			||||||
		    AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_G)) {
 | 
							    adev->virt.autoload_ucode_id : AMDGPU_UCODE_ID_RLC_G)) {
 | 
				
			||||||
			ret = psp_rlc_autoload_start(psp);
 | 
								ret = psp_rlc_autoload_start(psp);
 | 
				
			||||||
			if (ret) {
 | 
								if (ret) {
 | 
				
			||||||
				DRM_ERROR("Failed to start rlc autoload\n");
 | 
									DRM_ERROR("Failed to start rlc autoload\n");
 | 
				
			||||||
| 
						 | 
					@ -2641,6 +2642,9 @@ static int psp_hw_fini(void *handle)
 | 
				
			||||||
		psp_rap_terminate(psp);
 | 
							psp_rap_terminate(psp);
 | 
				
			||||||
		psp_dtm_terminate(psp);
 | 
							psp_dtm_terminate(psp);
 | 
				
			||||||
		psp_hdcp_terminate(psp);
 | 
							psp_hdcp_terminate(psp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (adev->gmc.xgmi.num_physical_nodes > 1)
 | 
				
			||||||
 | 
								psp_xgmi_terminate(psp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	psp_asd_terminate(psp);
 | 
						psp_asd_terminate(psp);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1949,6 +1949,7 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
 | 
				
			||||||
		reset_context.method = AMD_RESET_METHOD_NONE;
 | 
							reset_context.method = AMD_RESET_METHOD_NONE;
 | 
				
			||||||
		reset_context.reset_req_dev = adev;
 | 
							reset_context.reset_req_dev = adev;
 | 
				
			||||||
		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
							clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
							clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context);
 | 
							amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "amdgpu_reset.h"
 | 
					#include "amdgpu_reset.h"
 | 
				
			||||||
#include "aldebaran.h"
 | 
					#include "aldebaran.h"
 | 
				
			||||||
 | 
					#include "sienna_cichlid.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
 | 
					int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
 | 
				
			||||||
			     struct amdgpu_reset_handler *handler)
 | 
								     struct amdgpu_reset_handler *handler)
 | 
				
			||||||
| 
						 | 
					@ -36,10 +37,15 @@ int amdgpu_reset_init(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						adev->amdgpu_reset_level_mask = 0x1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (adev->ip_versions[MP1_HWIP][0]) {
 | 
						switch (adev->ip_versions[MP1_HWIP][0]) {
 | 
				
			||||||
	case IP_VERSION(13, 0, 2):
 | 
						case IP_VERSION(13, 0, 2):
 | 
				
			||||||
		ret = aldebaran_reset_init(adev);
 | 
							ret = aldebaran_reset_init(adev);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 7):
 | 
				
			||||||
 | 
							ret = sienna_cichlid_reset_init(adev);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -55,6 +61,9 @@ int amdgpu_reset_fini(struct amdgpu_device *adev)
 | 
				
			||||||
	case IP_VERSION(13, 0, 2):
 | 
						case IP_VERSION(13, 0, 2):
 | 
				
			||||||
		ret = aldebaran_reset_fini(adev);
 | 
							ret = aldebaran_reset_fini(adev);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 7):
 | 
				
			||||||
 | 
							ret = sienna_cichlid_reset_fini(adev);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -67,6 +76,12 @@ int amdgpu_reset_prepare_hwcontext(struct amdgpu_device *adev,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_reset_handler *reset_handler = NULL;
 | 
						struct amdgpu_reset_handler *reset_handler = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adev->reset_cntl && adev->reset_cntl->get_reset_handler)
 | 
						if (adev->reset_cntl && adev->reset_cntl->get_reset_handler)
 | 
				
			||||||
		reset_handler = adev->reset_cntl->get_reset_handler(
 | 
							reset_handler = adev->reset_cntl->get_reset_handler(
 | 
				
			||||||
			adev->reset_cntl, reset_context);
 | 
								adev->reset_cntl, reset_context);
 | 
				
			||||||
| 
						 | 
					@ -83,6 +98,12 @@ int amdgpu_reset_perform_reset(struct amdgpu_device *adev,
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	struct amdgpu_reset_handler *reset_handler = NULL;
 | 
						struct amdgpu_reset_handler *reset_handler = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
 | 
				
			||||||
 | 
							return -ENOSYS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adev->reset_cntl)
 | 
						if (adev->reset_cntl)
 | 
				
			||||||
		reset_handler = adev->reset_cntl->get_reset_handler(
 | 
							reset_handler = adev->reset_cntl->get_reset_handler(
 | 
				
			||||||
			adev->reset_cntl, reset_context);
 | 
								adev->reset_cntl, reset_context);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@ enum AMDGPU_RESET_FLAGS {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AMDGPU_NEED_FULL_RESET = 0,
 | 
						AMDGPU_NEED_FULL_RESET = 0,
 | 
				
			||||||
	AMDGPU_SKIP_HW_RESET = 1,
 | 
						AMDGPU_SKIP_HW_RESET = 1,
 | 
				
			||||||
 | 
						AMDGPU_SKIP_MODE2_RESET = 2,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_reset_context {
 | 
					struct amdgpu_reset_context {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,6 +405,9 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ktime_t deadline = ktime_add_us(ktime_get(), 10000);
 | 
						ktime_t deadline = ktime_add_us(ktime_get(), 10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(ring->adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_SOFT_RECOVERY))
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
 | 
						if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -390,6 +390,7 @@ union amdgpu_firmware_header {
 | 
				
			||||||
	struct rlc_firmware_header_v2_1 rlc_v2_1;
 | 
						struct rlc_firmware_header_v2_1 rlc_v2_1;
 | 
				
			||||||
	struct rlc_firmware_header_v2_2 rlc_v2_2;
 | 
						struct rlc_firmware_header_v2_2 rlc_v2_2;
 | 
				
			||||||
	struct rlc_firmware_header_v2_3 rlc_v2_3;
 | 
						struct rlc_firmware_header_v2_3 rlc_v2_3;
 | 
				
			||||||
 | 
						struct rlc_firmware_header_v2_4 rlc_v2_4;
 | 
				
			||||||
	struct sdma_firmware_header_v1_0 sdma;
 | 
						struct sdma_firmware_header_v1_0 sdma;
 | 
				
			||||||
	struct sdma_firmware_header_v1_1 sdma_v1_1;
 | 
						struct sdma_firmware_header_v1_1 sdma_v1_1;
 | 
				
			||||||
	struct sdma_firmware_header_v2_0 sdma_v2_0;
 | 
						struct sdma_firmware_header_v2_0 sdma_v2_0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,6 +161,7 @@
 | 
				
			||||||
#define AMDGPU_VCN_SW_RING_FLAG		(1 << 9)
 | 
					#define AMDGPU_VCN_SW_RING_FLAG		(1 << 9)
 | 
				
			||||||
#define AMDGPU_VCN_FW_LOGGING_FLAG	(1 << 10)
 | 
					#define AMDGPU_VCN_FW_LOGGING_FLAG	(1 << 10)
 | 
				
			||||||
#define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
 | 
					#define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
 | 
				
			||||||
 | 
					#define AMDGPU_VCN_VF_RB_SETUP_FLAG (1 << 12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER	0x00000001
 | 
					#define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER	0x00000001
 | 
				
			||||||
#define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER		0x00000001
 | 
					#define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER		0x00000001
 | 
				
			||||||
| 
						 | 
					@ -317,12 +318,24 @@ struct amdgpu_fw_shared {
 | 
				
			||||||
	struct amdgpu_fw_shared_smu_interface_info smu_interface_info;
 | 
						struct amdgpu_fw_shared_smu_interface_info smu_interface_info;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_fw_shared_rb_setup {
 | 
				
			||||||
 | 
						uint32_t is_rb_enabled_flags;
 | 
				
			||||||
 | 
						uint32_t rb_addr_lo;
 | 
				
			||||||
 | 
						uint32_t rb_addr_hi;
 | 
				
			||||||
 | 
						uint32_t  rb_size;
 | 
				
			||||||
 | 
						uint32_t  rb4_addr_lo;
 | 
				
			||||||
 | 
						uint32_t  rb4_addr_hi;
 | 
				
			||||||
 | 
						uint32_t  rb4_size;
 | 
				
			||||||
 | 
						uint32_t  reserved[6];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_vcn4_fw_shared {
 | 
					struct amdgpu_vcn4_fw_shared {
 | 
				
			||||||
	uint32_t present_flag_0;
 | 
						uint32_t present_flag_0;
 | 
				
			||||||
	uint8_t pad[12];
 | 
						uint8_t pad[12];
 | 
				
			||||||
	struct amdgpu_fw_shared_unified_queue_struct sq;
 | 
						struct amdgpu_fw_shared_unified_queue_struct sq;
 | 
				
			||||||
	uint8_t pad1[8];
 | 
						uint8_t pad1[8];
 | 
				
			||||||
	struct amdgpu_fw_shared_fw_logging fw_log;
 | 
						struct amdgpu_fw_shared_fw_logging fw_log;
 | 
				
			||||||
 | 
						struct amdgpu_fw_shared_rb_setup rb_setup;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_vcn_fwlog {
 | 
					struct amdgpu_vcn_fwlog {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -690,7 +690,6 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void amdgpu_detect_virtualization(struct amdgpu_device *adev)
 | 
					void amdgpu_detect_virtualization(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t reg;
 | 
						uint32_t reg;
 | 
				
			||||||
| 
						 | 
					@ -707,6 +706,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
 | 
				
			||||||
	case CHIP_SIENNA_CICHLID:
 | 
						case CHIP_SIENNA_CICHLID:
 | 
				
			||||||
	case CHIP_ARCTURUS:
 | 
						case CHIP_ARCTURUS:
 | 
				
			||||||
	case CHIP_ALDEBARAN:
 | 
						case CHIP_ALDEBARAN:
 | 
				
			||||||
 | 
						case CHIP_IP_DISCOVERY:
 | 
				
			||||||
		reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER);
 | 
							reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default: /* other chip doesn't support SRIOV */
 | 
						default: /* other chip doesn't support SRIOV */
 | 
				
			||||||
| 
						 | 
					@ -750,6 +750,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
 | 
				
			||||||
		case CHIP_NAVI10:
 | 
							case CHIP_NAVI10:
 | 
				
			||||||
		case CHIP_NAVI12:
 | 
							case CHIP_NAVI12:
 | 
				
			||||||
		case CHIP_SIENNA_CICHLID:
 | 
							case CHIP_SIENNA_CICHLID:
 | 
				
			||||||
 | 
							case CHIP_IP_DISCOVERY:
 | 
				
			||||||
			nv_set_virt_ops(adev);
 | 
								nv_set_virt_ops(adev);
 | 
				
			||||||
			/* try send GPU_INIT_DATA request to host */
 | 
								/* try send GPU_INIT_DATA request to host */
 | 
				
			||||||
			amdgpu_virt_request_init_data(adev);
 | 
								amdgpu_virt_request_init_data(adev);
 | 
				
			||||||
| 
						 | 
					@ -807,6 +808,60 @@ enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *ad
 | 
				
			||||||
	return mode;
 | 
						return mode;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev, uint32_t ucode_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (adev->ip_versions[MP0_HWIP][0]) {
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 0):
 | 
				
			||||||
 | 
							/* no vf autoload, white list */
 | 
				
			||||||
 | 
							if (ucode_id == AMDGPU_UCODE_ID_VCN1 ||
 | 
				
			||||||
 | 
							    ucode_id == AMDGPU_UCODE_ID_VCN)
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 10):
 | 
				
			||||||
 | 
							/* white list */
 | 
				
			||||||
 | 
							if (ucode_id == AMDGPU_UCODE_ID_CAP
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_MES
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_MES_DATA
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_MES1
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_CP_MES1_DATA
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_VCN1
 | 
				
			||||||
 | 
							|| ucode_id == AMDGPU_UCODE_ID_VCN)
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* lagacy black list */
 | 
				
			||||||
 | 
							if (ucode_id == AMDGPU_UCODE_ID_SDMA0
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SDMA1
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SDMA2
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SDMA3
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SDMA4
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SDMA5
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SDMA6
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SDMA7
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_RLC_G
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
 | 
				
			||||||
 | 
							    || ucode_id == AMDGPU_UCODE_ID_SMC)
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
 | 
					void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
 | 
				
			||||||
			struct amdgpu_video_codec_info *encode, uint32_t encode_array_size,
 | 
								struct amdgpu_video_codec_info *encode, uint32_t encode_array_size,
 | 
				
			||||||
			struct amdgpu_video_codec_info *decode, uint32_t decode_array_size)
 | 
								struct amdgpu_video_codec_info *decode, uint32_t decode_array_size)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,6 +253,9 @@ struct amdgpu_virt {
 | 
				
			||||||
	uint32_t decode_max_frame_pixels;
 | 
						uint32_t decode_max_frame_pixels;
 | 
				
			||||||
	uint32_t encode_max_dimension_pixels;
 | 
						uint32_t encode_max_dimension_pixels;
 | 
				
			||||||
	uint32_t encode_max_frame_pixels;
 | 
						uint32_t encode_max_frame_pixels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* the ucode id to signal the autoload */
 | 
				
			||||||
 | 
						uint32_t autoload_ucode_id;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_video_codec_info;
 | 
					struct amdgpu_video_codec_info;
 | 
				
			||||||
| 
						 | 
					@ -343,4 +346,6 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev,
 | 
				
			||||||
		       u32 acc_flags, u32 hwip);
 | 
							       u32 acc_flags, u32 hwip);
 | 
				
			||||||
u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
 | 
					u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
 | 
				
			||||||
		      u32 offset, u32 acc_flags, u32 hwip);
 | 
							      u32 offset, u32 acc_flags, u32 hwip);
 | 
				
			||||||
 | 
					bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
								uint32_t ucode_id);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -504,6 +504,9 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Each psp need to set the latest topology */
 | 
						/* Each psp need to set the latest topology */
 | 
				
			||||||
	ret = psp_xgmi_set_topology_info(&adev->psp,
 | 
						ret = psp_xgmi_set_topology_info(&adev->psp,
 | 
				
			||||||
					 atomic_read(&hive->number_devices),
 | 
										 atomic_read(&hive->number_devices),
 | 
				
			||||||
| 
						 | 
					@ -742,7 +745,7 @@ int amdgpu_xgmi_remove_device(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_put_xgmi_hive(hive);
 | 
							amdgpu_put_xgmi_hive(hive);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return psp_xgmi_terminate(&adev->psp);
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
 | 
					static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4274,35 +4274,45 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = &adev->firmware.ucode[AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS];
 | 
							if (adev->gfx.rlc.global_tap_delays_ucode_size_bytes) {
 | 
				
			||||||
		info->ucode_id = AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS;
 | 
								info = &adev->firmware.ucode[AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS];
 | 
				
			||||||
		info->fw = adev->gfx.rlc_fw;
 | 
								info->ucode_id = AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS;
 | 
				
			||||||
		adev->firmware.fw_size +=
 | 
								info->fw = adev->gfx.rlc_fw;
 | 
				
			||||||
			ALIGN(adev->gfx.rlc.global_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
								adev->firmware.fw_size +=
 | 
				
			||||||
 | 
									ALIGN(adev->gfx.rlc.global_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE0_TAP_DELAYS];
 | 
							if (adev->gfx.rlc.se0_tap_delays_ucode_size_bytes) {
 | 
				
			||||||
		info->ucode_id = AMDGPU_UCODE_ID_SE0_TAP_DELAYS;
 | 
								info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE0_TAP_DELAYS];
 | 
				
			||||||
		info->fw = adev->gfx.rlc_fw;
 | 
								info->ucode_id = AMDGPU_UCODE_ID_SE0_TAP_DELAYS;
 | 
				
			||||||
		adev->firmware.fw_size +=
 | 
								info->fw = adev->gfx.rlc_fw;
 | 
				
			||||||
			ALIGN(adev->gfx.rlc.se0_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
								adev->firmware.fw_size +=
 | 
				
			||||||
 | 
									ALIGN(adev->gfx.rlc.se0_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE1_TAP_DELAYS];
 | 
							if (adev->gfx.rlc.se1_tap_delays_ucode_size_bytes) {
 | 
				
			||||||
		info->ucode_id = AMDGPU_UCODE_ID_SE1_TAP_DELAYS;
 | 
								info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE1_TAP_DELAYS];
 | 
				
			||||||
		info->fw = adev->gfx.rlc_fw;
 | 
								info->ucode_id = AMDGPU_UCODE_ID_SE1_TAP_DELAYS;
 | 
				
			||||||
		adev->firmware.fw_size +=
 | 
								info->fw = adev->gfx.rlc_fw;
 | 
				
			||||||
			ALIGN(adev->gfx.rlc.se1_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
								adev->firmware.fw_size +=
 | 
				
			||||||
 | 
									ALIGN(adev->gfx.rlc.se1_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE2_TAP_DELAYS];
 | 
							if (adev->gfx.rlc.se2_tap_delays_ucode_size_bytes) {
 | 
				
			||||||
		info->ucode_id = AMDGPU_UCODE_ID_SE2_TAP_DELAYS;
 | 
								info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE2_TAP_DELAYS];
 | 
				
			||||||
		info->fw = adev->gfx.rlc_fw;
 | 
								info->ucode_id = AMDGPU_UCODE_ID_SE2_TAP_DELAYS;
 | 
				
			||||||
		adev->firmware.fw_size +=
 | 
								info->fw = adev->gfx.rlc_fw;
 | 
				
			||||||
			ALIGN(adev->gfx.rlc.se2_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
								adev->firmware.fw_size +=
 | 
				
			||||||
 | 
									ALIGN(adev->gfx.rlc.se2_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE3_TAP_DELAYS];
 | 
							if (adev->gfx.rlc.se3_tap_delays_ucode_size_bytes) {
 | 
				
			||||||
		info->ucode_id = AMDGPU_UCODE_ID_SE3_TAP_DELAYS;
 | 
								info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SE3_TAP_DELAYS];
 | 
				
			||||||
		info->fw = adev->gfx.rlc_fw;
 | 
								info->ucode_id = AMDGPU_UCODE_ID_SE3_TAP_DELAYS;
 | 
				
			||||||
		adev->firmware.fw_size +=
 | 
								info->fw = adev->gfx.rlc_fw;
 | 
				
			||||||
			ALIGN(adev->gfx.rlc.se3_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
								adev->firmware.fw_size +=
 | 
				
			||||||
 | 
									ALIGN(adev->gfx.rlc.se3_tap_delays_ucode_size_bytes, PAGE_SIZE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
 | 
							info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
 | 
				
			||||||
		info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
 | 
							info->ucode_id = AMDGPU_UCODE_ID_CP_MEC1;
 | 
				
			||||||
| 
						 | 
					@ -5971,6 +5981,9 @@ static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
 | 
				
			||||||
		WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp);
 | 
							WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->job_hang && !enable)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < adev->usec_timeout; i++) {
 | 
						for (i = 0; i < adev->usec_timeout; i++) {
 | 
				
			||||||
		if (RREG32_SOC15(GC, 0, mmCP_STAT) == 0)
 | 
							if (RREG32_SOC15(GC, 0, mmCP_STAT) == 0)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -7569,8 +7582,10 @@ static int gfx_v10_0_kiq_disable_kgq(struct amdgpu_device *adev)
 | 
				
			||||||
	for (i = 0; i < adev->gfx.num_gfx_rings; i++)
 | 
						for (i = 0; i < adev->gfx.num_gfx_rings; i++)
 | 
				
			||||||
		kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.gfx_ring[i],
 | 
							kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.gfx_ring[i],
 | 
				
			||||||
					   PREEMPT_QUEUES, 0, 0);
 | 
										   PREEMPT_QUEUES, 0, 0);
 | 
				
			||||||
 | 
						if (!adev->job_hang)
 | 
				
			||||||
	return amdgpu_ring_test_helper(kiq_ring);
 | 
							return amdgpu_ring_test_helper(kiq_ring);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,21 +73,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
 | 
				
			||||||
static const struct soc15_reg_golden golden_settings_gc_11_0[] =
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
 | 
				
			||||||
{
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
 | 
				
			||||||
	/* Pending on emulation bring up */
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct soc15_reg_golden golden_settings_gc_11_0_0[] =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* Pending on emulation bring up */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct soc15_reg_golden golden_settings_gc_rlc_spm_11_0[] =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	/* Pending on emulation bring up */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =
 | 
					static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -131,6 +120,8 @@ static void gfx_v11_0_ring_invalidate_tlbs(struct amdgpu_ring *ring,
 | 
				
			||||||
					   bool all_hub, uint8_t dst_sel);
 | 
										   bool all_hub, uint8_t dst_sel);
 | 
				
			||||||
static void gfx_v11_0_set_safe_mode(struct amdgpu_device *adev);
 | 
					static void gfx_v11_0_set_safe_mode(struct amdgpu_device *adev);
 | 
				
			||||||
static void gfx_v11_0_unset_safe_mode(struct amdgpu_device *adev);
 | 
					static void gfx_v11_0_unset_safe_mode(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					static void gfx_v11_0_update_perf_clk(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
									      bool enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gfx11_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
 | 
					static void gfx11_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -267,34 +258,10 @@ static void gfx_v11_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
 | 
				
			||||||
	adev->gfx.kiq.pmf = &gfx_v11_0_kiq_pm4_funcs;
 | 
						adev->gfx.kiq.pmf = &gfx_v11_0_kiq_pm4_funcs;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gfx_v11_0_init_spm_golden_registers(struct amdgpu_device *adev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	switch (adev->ip_versions[GC_HWIP][0]) {
 | 
					 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
					 | 
				
			||||||
		soc15_program_register_sequence(adev,
 | 
					 | 
				
			||||||
						golden_settings_gc_rlc_spm_11_0,
 | 
					 | 
				
			||||||
						(const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_11_0));
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
 | 
					static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch (adev->ip_versions[GC_HWIP][0]) {
 | 
						switch (adev->ip_versions[GC_HWIP][0]) {
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
					 | 
				
			||||||
		soc15_program_register_sequence(adev,
 | 
					 | 
				
			||||||
						golden_settings_gc_11_0,
 | 
					 | 
				
			||||||
						(const u32)ARRAY_SIZE(golden_settings_gc_11_0));
 | 
					 | 
				
			||||||
		soc15_program_register_sequence(adev,
 | 
					 | 
				
			||||||
						golden_settings_gc_11_0_0,
 | 
					 | 
				
			||||||
						(const u32)ARRAY_SIZE(golden_settings_gc_11_0_0));
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
		soc15_program_register_sequence(adev,
 | 
					 | 
				
			||||||
						golden_settings_gc_11_0,
 | 
					 | 
				
			||||||
						(const u32)ARRAY_SIZE(golden_settings_gc_11_0));
 | 
					 | 
				
			||||||
		soc15_program_register_sequence(adev,
 | 
							soc15_program_register_sequence(adev,
 | 
				
			||||||
						golden_settings_gc_11_0_1,
 | 
											golden_settings_gc_11_0_1,
 | 
				
			||||||
						(const u32)ARRAY_SIZE(golden_settings_gc_11_0_1));
 | 
											(const u32)ARRAY_SIZE(golden_settings_gc_11_0_1));
 | 
				
			||||||
| 
						 | 
					@ -302,7 +269,6 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	gfx_v11_0_init_spm_golden_registers(adev);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gfx_v11_0_write_data_to_reg(struct amdgpu_ring *ring, int eng_sel,
 | 
					static void gfx_v11_0_write_data_to_reg(struct amdgpu_ring *ring, int eng_sel,
 | 
				
			||||||
| 
						 | 
					@ -1138,7 +1104,7 @@ static const struct amdgpu_gfx_funcs gfx_v11_0_gfx_funcs = {
 | 
				
			||||||
	.read_wave_sgprs = &gfx_v11_0_read_wave_sgprs,
 | 
						.read_wave_sgprs = &gfx_v11_0_read_wave_sgprs,
 | 
				
			||||||
	.read_wave_vgprs = &gfx_v11_0_read_wave_vgprs,
 | 
						.read_wave_vgprs = &gfx_v11_0_read_wave_vgprs,
 | 
				
			||||||
	.select_me_pipe_q = &gfx_v11_0_select_me_pipe_q,
 | 
						.select_me_pipe_q = &gfx_v11_0_select_me_pipe_q,
 | 
				
			||||||
	.init_spm_golden = &gfx_v11_0_init_spm_golden_registers,
 | 
						.update_perfmon_mgcg = &gfx_v11_0_update_perf_clk,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
 | 
					static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
 | 
				
			||||||
| 
						 | 
					@ -1148,6 +1114,7 @@ static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
 | 
				
			||||||
	switch (adev->ip_versions[GC_HWIP][0]) {
 | 
						switch (adev->ip_versions[GC_HWIP][0]) {
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		adev->gfx.config.max_hw_contexts = 8;
 | 
							adev->gfx.config.max_hw_contexts = 8;
 | 
				
			||||||
		adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
 | 
							adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
 | 
				
			||||||
		adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
 | 
							adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
 | 
				
			||||||
| 
						 | 
					@ -1583,6 +1550,7 @@ static int gfx_v11_0_sw_init(void *handle)
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		adev->gfx.me.num_me = 1;
 | 
							adev->gfx.me.num_me = 1;
 | 
				
			||||||
		adev->gfx.me.num_pipe_per_me = 1;
 | 
							adev->gfx.me.num_pipe_per_me = 1;
 | 
				
			||||||
		adev->gfx.me.num_queue_per_pipe = 1;
 | 
							adev->gfx.me.num_queue_per_pipe = 1;
 | 
				
			||||||
| 
						 | 
					@ -2757,6 +2725,21 @@ static void gfx_v11_0_config_gfx_rs64(struct amdgpu_device *adev)
 | 
				
			||||||
					mec_hdr->ucode_start_addr_hi >> 2);
 | 
										mec_hdr->ucode_start_addr_hi >> 2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	soc21_grbm_select(adev, 0, 0, 0, 0);
 | 
						soc21_grbm_select(adev, 0, 0, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* reset mec pipe */
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE0_RESET, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE1_RESET, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE2_RESET, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE3_RESET, 1);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* clear mec pipe reset */
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE0_RESET, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE1_RESET, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE2_RESET, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, CP_MEC_RS64_CNTL, MEC_PIPE3_RESET, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, tmp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
 | 
					static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
 | 
				
			||||||
| 
						 | 
					@ -5182,9 +5165,12 @@ static void gfx_v11_0_update_coarse_grain_clock_gating(struct amdgpu_device *ade
 | 
				
			||||||
		data = REG_SET_FIELD(data, SDMA0_RLC_CGCG_CTRL, CGCG_INT_ENABLE, 1);
 | 
							data = REG_SET_FIELD(data, SDMA0_RLC_CGCG_CTRL, CGCG_INT_ENABLE, 1);
 | 
				
			||||||
		WREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL, data);
 | 
							WREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
 | 
							/* Some ASICs only have one SDMA instance, not need to configure SDMA1 */
 | 
				
			||||||
		data = REG_SET_FIELD(data, SDMA1_RLC_CGCG_CTRL, CGCG_INT_ENABLE, 1);
 | 
							if (adev->sdma.num_instances > 1) {
 | 
				
			||||||
		WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
 | 
								data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
 | 
				
			||||||
 | 
								data = REG_SET_FIELD(data, SDMA1_RLC_CGCG_CTRL, CGCG_INT_ENABLE, 1);
 | 
				
			||||||
 | 
								WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Program RLC_CGCG_CGLS_CTRL */
 | 
							/* Program RLC_CGCG_CGLS_CTRL */
 | 
				
			||||||
		def = data = RREG32_SOC15(GC, 0, regRLC_CGCG_CGLS_CTRL);
 | 
							def = data = RREG32_SOC15(GC, 0, regRLC_CGCG_CGLS_CTRL);
 | 
				
			||||||
| 
						 | 
					@ -5213,9 +5199,12 @@ static void gfx_v11_0_update_coarse_grain_clock_gating(struct amdgpu_device *ade
 | 
				
			||||||
		data &= ~SDMA0_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK;
 | 
							data &= ~SDMA0_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK;
 | 
				
			||||||
		WREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL, data);
 | 
							WREG32_SOC15(GC, 0, regSDMA0_RLC_CGCG_CTRL, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
 | 
							/* Some ASICs only have one SDMA instance, not need to configure SDMA1 */
 | 
				
			||||||
		data &= ~SDMA1_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK;
 | 
							if (adev->sdma.num_instances > 1) {
 | 
				
			||||||
		WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
 | 
								data = RREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL);
 | 
				
			||||||
 | 
								data &= ~SDMA1_RLC_CGCG_CTRL__CGCG_INT_ENABLE_MASK;
 | 
				
			||||||
 | 
								WREG32_SOC15(GC, 0, regSDMA1_RLC_CGCG_CTRL, data);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5328,8 +5317,7 @@ static int gfx_v11_0_set_powergating_state(void *handle,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
		gfx_v11_cntl_pg(adev, enable);
 | 
							gfx_v11_cntl_pg(adev, enable);
 | 
				
			||||||
		/* TODO: Enable this when GFXOFF is ready */
 | 
							amdgpu_gfx_off_ctrl(adev, enable);
 | 
				
			||||||
		// amdgpu_gfx_off_ctrl(adev, enable);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,6 +126,8 @@ MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/aldebaran_mec.bin");
 | 
					MODULE_FIRMWARE("amdgpu/aldebaran_mec.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/aldebaran_mec2.bin");
 | 
					MODULE_FIRMWARE("amdgpu/aldebaran_mec2.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
 | 
					MODULE_FIRMWARE("amdgpu/aldebaran_rlc.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec2.bin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define mmTCP_CHAN_STEER_0_ARCT								0x0b03
 | 
					#define mmTCP_CHAN_STEER_0_ARCT								0x0b03
 | 
				
			||||||
#define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX							0
 | 
					#define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX							0
 | 
				
			||||||
| 
						 | 
					@ -1496,7 +1498,11 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
 | 
				
			||||||
	const struct common_firmware_header *header = NULL;
 | 
						const struct common_firmware_header *header = NULL;
 | 
				
			||||||
	const struct gfx_firmware_header_v1_0 *cp_hdr;
 | 
						const struct gfx_firmware_header_v1_0 *cp_hdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
 | 
						if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
 | 
				
			||||||
 | 
							snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec.bin", chip_name);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
 | 
						err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
| 
						 | 
					@ -1509,7 +1515,11 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gfx_v9_0_load_mec2_fw_bin_support(adev)) {
 | 
						if (gfx_v9_0_load_mec2_fw_bin_support(adev)) {
 | 
				
			||||||
		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
 | 
							if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_ALDEBARAN))
 | 
				
			||||||
 | 
								snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sjt_mec2.bin", chip_name);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
 | 
							err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev);
 | 
				
			||||||
		if (!err) {
 | 
							if (!err) {
 | 
				
			||||||
			err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
 | 
								err = amdgpu_ucode_validate(adev->gfx.mec2_fw);
 | 
				
			||||||
| 
						 | 
					@ -2587,7 +2597,8 @@ static void gfx_v9_0_constants_init(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gfx_v9_0_tiling_mode_table_init(adev);
 | 
						gfx_v9_0_tiling_mode_table_init(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gfx_v9_0_setup_rb(adev);
 | 
						if (adev->gfx.num_gfx_rings)
 | 
				
			||||||
 | 
							gfx_v9_0_setup_rb(adev);
 | 
				
			||||||
	gfx_v9_0_get_cu_info(adev, &adev->gfx.cu_info);
 | 
						gfx_v9_0_get_cu_info(adev, &adev->gfx.cu_info);
 | 
				
			||||||
	adev->gfx.config.db_debug2 = RREG32_SOC15(GC, 0, mmDB_DEBUG2);
 | 
						adev->gfx.config.db_debug2 = RREG32_SOC15(GC, 0, mmDB_DEBUG2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -576,6 +576,111 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v2_1_save_regs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_CNTL2 = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2);
 | 
				
			||||||
 | 
						adev->gmc.VM_DUMMY_PAGE_FAULT_CNTL = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_CNTL);
 | 
				
			||||||
 | 
						adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_LO32 = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_LO32);
 | 
				
			||||||
 | 
						adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_HI32 = RREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_HI32);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_PROTECTION_FAULT_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_PROTECTION_FAULT_CNTL2 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL2);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL3 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL3);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL4 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL4);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_LO32 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_LO32);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_HI32 = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_HI32);
 | 
				
			||||||
 | 
						adev->gmc.VM_DEBUG = RREG32_SOC15(GC, 0, mmGCVM_DEBUG);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_MM_GROUP_RT_CLASSES = RREG32_SOC15(GC, 0, mmGCVM_L2_MM_GROUP_RT_CLASSES);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID = RREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID2 = RREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID2);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_CACHE_PARITY_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_CACHE_PARITY_CNTL);
 | 
				
			||||||
 | 
						adev->gmc.VM_L2_IH_LOG_CNTL = RREG32_SOC15(GC, 0, mmGCVM_L2_IH_LOG_CNTL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i <= 15; i++) {
 | 
				
			||||||
 | 
							adev->gmc.VM_CONTEXT_CNTL[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL, i);
 | 
				
			||||||
 | 
							adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, i * 2);
 | 
				
			||||||
 | 
							adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, i * 2);
 | 
				
			||||||
 | 
							adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, i * 2);
 | 
				
			||||||
 | 
							adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, i * 2);
 | 
				
			||||||
 | 
							adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, i * 2);
 | 
				
			||||||
 | 
							adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[i] = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, i * 2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						adev->gmc.MC_VM_MX_L1_TLB_CNTL = RREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v2_1_restore_regs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL, adev->gmc.VM_L2_CNTL);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, adev->gmc.VM_L2_CNTL2);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_CNTL, adev->gmc.VM_DUMMY_PAGE_FAULT_CNTL);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_LO32, adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_LO32);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_DUMMY_PAGE_FAULT_ADDR_HI32, adev->gmc.VM_DUMMY_PAGE_FAULT_ADDR_HI32);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL, adev->gmc.VM_L2_PROTECTION_FAULT_CNTL);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL2, adev->gmc.VM_L2_PROTECTION_FAULT_CNTL2);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL3, adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL3);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_MM_CNTL4, adev->gmc.VM_L2_PROTECTION_FAULT_MM_CNTL4);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_LO32, adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_LO32);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_ADDR_HI32, adev->gmc.VM_L2_PROTECTION_FAULT_ADDR_HI32);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_DEBUG, adev->gmc.VM_DEBUG);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_MM_GROUP_RT_CLASSES, adev->gmc.VM_L2_MM_GROUP_RT_CLASSES);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID, adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_BANK_SELECT_RESERVED_CID2, adev->gmc.VM_L2_BANK_SELECT_RESERVED_CID2);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_CACHE_PARITY_CNTL, adev->gmc.VM_L2_CACHE_PARITY_CNTL);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCVM_L2_IH_LOG_CNTL, adev->gmc.VM_L2_IH_LOG_CNTL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i <= 15; i++) {
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL, i, adev->gmc.VM_CONTEXT_CNTL[i]);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[i]);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[i]);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[i]);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[i]);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[i]);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, i * 2, adev->gmc.VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCMC_VM_FB_LOCATION_BASE, adev->gmc.vram_start >> 24);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCMC_VM_FB_LOCATION_TOP, adev->gmc.vram_end >> 24);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL, adev->gmc.MC_VM_MX_L1_TLB_CNTL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v2_1_halt(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						uint32_t tmp;
 | 
				
			||||||
 | 
						int time = 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gfxhub_v2_1_set_fault_enable_default(adev, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i <= 14; i++) {
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance, ~0);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance, ~0);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance,
 | 
				
			||||||
 | 
									    0);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance,
 | 
				
			||||||
 | 
									    0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS2);
 | 
				
			||||||
 | 
						while ((tmp & (GRBM_STATUS2__EA_BUSY_MASK |
 | 
				
			||||||
 | 
							      GRBM_STATUS2__EA_LINK_BUSY_MASK)) != 0 &&
 | 
				
			||||||
 | 
						       time) {
 | 
				
			||||||
 | 
							udelay(100);
 | 
				
			||||||
 | 
							time--;
 | 
				
			||||||
 | 
							tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!time) {
 | 
				
			||||||
 | 
							DRM_WARN("failed to wait for GRBM(EA) idle\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct amdgpu_gfxhub_funcs gfxhub_v2_1_funcs = {
 | 
					const struct amdgpu_gfxhub_funcs gfxhub_v2_1_funcs = {
 | 
				
			||||||
	.get_fb_location = gfxhub_v2_1_get_fb_location,
 | 
						.get_fb_location = gfxhub_v2_1_get_fb_location,
 | 
				
			||||||
	.get_mc_fb_offset = gfxhub_v2_1_get_mc_fb_offset,
 | 
						.get_mc_fb_offset = gfxhub_v2_1_get_mc_fb_offset,
 | 
				
			||||||
| 
						 | 
					@ -586,4 +691,7 @@ const struct amdgpu_gfxhub_funcs gfxhub_v2_1_funcs = {
 | 
				
			||||||
	.init = gfxhub_v2_1_init,
 | 
						.init = gfxhub_v2_1_init,
 | 
				
			||||||
	.get_xgmi_info = gfxhub_v2_1_get_xgmi_info,
 | 
						.get_xgmi_info = gfxhub_v2_1_get_xgmi_info,
 | 
				
			||||||
	.utcl2_harvest = gfxhub_v2_1_utcl2_harvest,
 | 
						.utcl2_harvest = gfxhub_v2_1_utcl2_harvest,
 | 
				
			||||||
 | 
						.mode2_save_regs = gfxhub_v2_1_save_regs,
 | 
				
			||||||
 | 
						.mode2_restore_regs = gfxhub_v2_1_restore_regs,
 | 
				
			||||||
 | 
						.halt = gfxhub_v2_1_halt,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										511
									
								
								drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,511 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2022 Advanced Micro Devices, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					 * all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
				
			||||||
 | 
					 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
				
			||||||
 | 
					 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
				
			||||||
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "amdgpu.h"
 | 
				
			||||||
 | 
					#include "gfxhub_v3_0_3.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gc/gc_11_0_3_offset.h"
 | 
				
			||||||
 | 
					#include "gc/gc_11_0_3_sh_mask.h"
 | 
				
			||||||
 | 
					#include "navi10_enum.h"
 | 
				
			||||||
 | 
					#include "soc15_common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define regGCVM_L2_CNTL3_DEFAULT		0x80100007
 | 
				
			||||||
 | 
					#define regGCVM_L2_CNTL4_DEFAULT		0x000000c1
 | 
				
			||||||
 | 
					#define regGCVM_L2_CNTL5_DEFAULT		0x00003fe0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *gfxhub_client_ids[] = {
 | 
				
			||||||
 | 
						"CB/DB",
 | 
				
			||||||
 | 
						"Reserved",
 | 
				
			||||||
 | 
						"GE1",
 | 
				
			||||||
 | 
						"GE2",
 | 
				
			||||||
 | 
						"CPF",
 | 
				
			||||||
 | 
						"CPC",
 | 
				
			||||||
 | 
						"CPG",
 | 
				
			||||||
 | 
						"RLC",
 | 
				
			||||||
 | 
						"TCP",
 | 
				
			||||||
 | 
						"SQC (inst)",
 | 
				
			||||||
 | 
						"SQC (data)",
 | 
				
			||||||
 | 
						"SQG",
 | 
				
			||||||
 | 
						"Reserved",
 | 
				
			||||||
 | 
						"SDMA0",
 | 
				
			||||||
 | 
						"SDMA1",
 | 
				
			||||||
 | 
						"GCR",
 | 
				
			||||||
 | 
						"SDMA2",
 | 
				
			||||||
 | 
						"SDMA3",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t gfxhub_v3_0_3_get_invalidate_req(unsigned int vmid,
 | 
				
			||||||
 | 
										       uint32_t flush_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 req = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* invalidate using legacy mode on vmid*/
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
 | 
				
			||||||
 | 
								    PER_VMID_INVALIDATE_REQ, 1 << vmid);
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type);
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
 | 
				
			||||||
 | 
						req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
 | 
				
			||||||
 | 
								    CLEAR_PROTECTION_FAULT_STATUS_ADDR,	0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return req;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					gfxhub_v3_0_3_print_l2_protection_fault_status(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										     uint32_t status)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 cid = REG_GET_FIELD(status,
 | 
				
			||||||
 | 
									GCVM_L2_PROTECTION_FAULT_STATUS, CID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev_err(adev->dev,
 | 
				
			||||||
 | 
							"GCVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
 | 
				
			||||||
 | 
							status);
 | 
				
			||||||
 | 
						dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
 | 
				
			||||||
 | 
							cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : gfxhub_client_ids[cid],
 | 
				
			||||||
 | 
							cid);
 | 
				
			||||||
 | 
						dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
 | 
				
			||||||
 | 
							REG_GET_FIELD(status,
 | 
				
			||||||
 | 
							GCVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
 | 
				
			||||||
 | 
						dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
 | 
				
			||||||
 | 
							REG_GET_FIELD(status,
 | 
				
			||||||
 | 
							GCVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
 | 
				
			||||||
 | 
						dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
 | 
				
			||||||
 | 
							REG_GET_FIELD(status,
 | 
				
			||||||
 | 
							GCVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
 | 
				
			||||||
 | 
						dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
 | 
				
			||||||
 | 
							REG_GET_FIELD(status,
 | 
				
			||||||
 | 
							GCVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
 | 
				
			||||||
 | 
						dev_err(adev->dev, "\t RW: 0x%lx\n",
 | 
				
			||||||
 | 
							REG_GET_FIELD(status,
 | 
				
			||||||
 | 
							GCVM_L2_PROTECTION_FAULT_STATUS, RW));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u64 gfxhub_v3_0_3_get_fb_location(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u64 base = RREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_BASE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						base &= GCMC_VM_FB_LOCATION_BASE__FB_BASE_MASK;
 | 
				
			||||||
 | 
						base <<= 24;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static u64 gfxhub_v3_0_3_get_mc_fb_offset(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (u64)RREG32_SOC15(GC, 0, regGCMC_VM_FB_OFFSET) << 24;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid,
 | 
				
			||||||
 | 
									uint64_t page_table_base)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
 | 
				
			||||||
 | 
								    hub->ctx_addr_distance * vmid,
 | 
				
			||||||
 | 
								    lower_32_bits(page_table_base));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
 | 
				
			||||||
 | 
								    hub->ctx_addr_distance * vmid,
 | 
				
			||||||
 | 
								    upper_32_bits(page_table_base));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_init_gart_aperture_regs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_setup_vm_pt_regs(adev, 0, pt_base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
 | 
				
			||||||
 | 
							     (u32)(adev->gmc.gart_start >> 12));
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
 | 
				
			||||||
 | 
							     (u32)(adev->gmc.gart_start >> 44));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
 | 
				
			||||||
 | 
							     (u32)(adev->gmc.gart_end >> 12));
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
 | 
				
			||||||
 | 
							     (u32)(adev->gmc.gart_end >> 44));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_init_system_aperture_regs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Disable AGP. */
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BASE, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BOT, 0x00FFFFFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Program the system aperture low logical page number. */
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR,
 | 
				
			||||||
 | 
							     adev->gmc.vram_start >> 18);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
 | 
				
			||||||
 | 
							     adev->gmc.vram_end >> 18);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Set default page address. */
 | 
				
			||||||
 | 
						value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
 | 
				
			||||||
 | 
							+ adev->vm_manager.vram_base_offset;
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
 | 
				
			||||||
 | 
							     (u32)(value >> 12));
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
 | 
				
			||||||
 | 
							     (u32)(value >> 44));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Program "protection fault". */
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
 | 
				
			||||||
 | 
							     (u32)(adev->dummy_page_addr >> 12));
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
 | 
				
			||||||
 | 
							     (u32)((u64)adev->dummy_page_addr >> 44));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_FIELD15_PREREG(GC, 0, GCVM_L2_PROTECTION_FAULT_CNTL2,
 | 
				
			||||||
 | 
							       ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_init_tlb_regs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Setup TLB control */
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
 | 
				
			||||||
 | 
								    ENABLE_ADVANCED_DRIVER_MODEL, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
 | 
				
			||||||
 | 
								    SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
 | 
				
			||||||
 | 
								    MTYPE, MTYPE_UC); /* UC, uncached */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_init_cache_regs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* These registers are not accessible to VF-SRIOV.
 | 
				
			||||||
 | 
						 * The PF will program them instead.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Setup L2 cache */
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, regGCVM_L2_CNTL);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_CACHE, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
 | 
				
			||||||
 | 
								    ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1);
 | 
				
			||||||
 | 
						/* XXX for emulation, Refer to closed source code.*/
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
 | 
				
			||||||
 | 
								    L2_PDE0_CACHE_TAG_GENERATION_MODE, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CNTL, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, regGCVM_L2_CNTL2);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CNTL2, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = regGCVM_L2_CNTL3_DEFAULT;
 | 
				
			||||||
 | 
						if (adev->gmc.translate_further) {
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 12);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
 | 
				
			||||||
 | 
									    L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 9);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
 | 
				
			||||||
 | 
									    L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CNTL3, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = regGCVM_L2_CNTL4_DEFAULT;
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CNTL4, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = regGCVM_L2_CNTL5_DEFAULT;
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CNTL5, tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_enable_system_domain(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, regGCVM_CONTEXT0_CNTL);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL,
 | 
				
			||||||
 | 
								    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_CONTEXT0_CNTL, tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_disable_identity_aperture(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* These registers are not accessible to VF-SRIOV.
 | 
				
			||||||
 | 
						 * The PF will program them instead.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32,
 | 
				
			||||||
 | 
							     0xFFFFFFFF);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32,
 | 
				
			||||||
 | 
							     0x0000000F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32,
 | 
				
			||||||
 | 
							     0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32,
 | 
				
			||||||
 | 
							     0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_setup_vmid_config(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						uint32_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i <= 14; i++) {
 | 
				
			||||||
 | 
							tmp = RREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_CNTL, i);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
 | 
				
			||||||
 | 
									    adev->vm_manager.num_level);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									PAGE_TABLE_BLOCK_SIZE,
 | 
				
			||||||
 | 
									adev->vm_manager.block_size - 9);
 | 
				
			||||||
 | 
							/* Send no-retry XNACK on fault to suppress VM fault storm. */
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
 | 
				
			||||||
 | 
									    !amdgpu_noretry);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_CNTL,
 | 
				
			||||||
 | 
									    i * hub->ctx_distance, tmp);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance, 0);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance, 0);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance,
 | 
				
			||||||
 | 
									    lower_32_bits(adev->vm_manager.max_pfn - 1));
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
 | 
				
			||||||
 | 
									    i * hub->ctx_addr_distance,
 | 
				
			||||||
 | 
									    upper_32_bits(adev->vm_manager.max_pfn - 1));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hub->vm_cntx_cntl = tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_program_invalidation(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
 | 
				
			||||||
 | 
						unsigned i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0 ; i < 18; ++i) {
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32,
 | 
				
			||||||
 | 
									    i * hub->eng_addr_distance, 0xffffffff);
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ADDR_RANGE_HI32,
 | 
				
			||||||
 | 
									    i * hub->eng_addr_distance, 0x1f);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gfxhub_v3_0_3_gart_enable(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * GCMC_VM_FB_LOCATION_BASE/TOP is NULL for VF, becuase they are
 | 
				
			||||||
 | 
							 * VF copy registers so vbios post doesn't program them, for
 | 
				
			||||||
 | 
							 * SRIOV driver need to program them
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							WREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_BASE,
 | 
				
			||||||
 | 
								     adev->gmc.vram_start >> 24);
 | 
				
			||||||
 | 
							WREG32_SOC15(GC, 0, regGCMC_VM_FB_LOCATION_TOP,
 | 
				
			||||||
 | 
								     adev->gmc.vram_end >> 24);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* GART Enable. */
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_init_gart_aperture_regs(adev);
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_init_system_aperture_regs(adev);
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_init_tlb_regs(adev);
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_init_cache_regs(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_enable_system_domain(adev);
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_disable_identity_aperture(adev);
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_setup_vmid_config(adev);
 | 
				
			||||||
 | 
						gfxhub_v3_0_3_program_invalidation(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_gart_disable(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
 | 
				
			||||||
 | 
						u32 tmp;
 | 
				
			||||||
 | 
						u32 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Disable all tables */
 | 
				
			||||||
 | 
						for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
							WREG32_SOC15_OFFSET(GC, 0, regGCVM_CONTEXT0_CNTL,
 | 
				
			||||||
 | 
									    i * hub->ctx_distance, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Setup TLB control */
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
 | 
				
			||||||
 | 
								    ENABLE_ADVANCED_DRIVER_MODEL, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Setup L2 cache */
 | 
				
			||||||
 | 
						WREG32_FIELD15_PREREG(GC, 0, GCVM_L2_CNTL, ENABLE_L2_CACHE, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_CNTL3, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * gfxhub_v3_0_3_set_fault_enable_default - update GART/VM fault handling
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @adev: amdgpu_device pointer
 | 
				
			||||||
 | 
					 * @value: true redirects VM faults to the default page
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_set_fault_enable_default(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										  bool value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* These registers are not accessible to VF-SRIOV.
 | 
				
			||||||
 | 
						 * The PF will program them instead.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT,
 | 
				
			||||||
 | 
								    value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    READ_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
								    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
 | 
				
			||||||
 | 
						if (!value) {
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
									CRASH_ON_NO_RETRY_FAULT, 1);
 | 
				
			||||||
 | 
							tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
 | 
				
			||||||
 | 
									CRASH_ON_RETRY_FAULT, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct amdgpu_vmhub_funcs gfxhub_v3_0_3_vmhub_funcs = {
 | 
				
			||||||
 | 
						.print_l2_protection_fault_status = gfxhub_v3_0_3_print_l2_protection_fault_status,
 | 
				
			||||||
 | 
						.get_invalidate_req = gfxhub_v3_0_3_get_invalidate_req,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gfxhub_v3_0_3_init(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hub->ctx0_ptb_addr_lo32 =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0,
 | 
				
			||||||
 | 
									 regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32);
 | 
				
			||||||
 | 
						hub->ctx0_ptb_addr_hi32 =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0,
 | 
				
			||||||
 | 
									 regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32);
 | 
				
			||||||
 | 
						hub->vm_inv_eng0_sem =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_SEM);
 | 
				
			||||||
 | 
						hub->vm_inv_eng0_req =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_REQ);
 | 
				
			||||||
 | 
						hub->vm_inv_eng0_ack =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0, regGCVM_INVALIDATE_ENG0_ACK);
 | 
				
			||||||
 | 
						hub->vm_context0_cntl =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0, regGCVM_CONTEXT0_CNTL);
 | 
				
			||||||
 | 
						hub->vm_l2_pro_fault_status =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0, regGCVM_L2_PROTECTION_FAULT_STATUS);
 | 
				
			||||||
 | 
						hub->vm_l2_pro_fault_cntl =
 | 
				
			||||||
 | 
							SOC15_REG_OFFSET(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hub->ctx_distance = regGCVM_CONTEXT1_CNTL - regGCVM_CONTEXT0_CNTL;
 | 
				
			||||||
 | 
						hub->ctx_addr_distance = regGCVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 -
 | 
				
			||||||
 | 
							regGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
 | 
				
			||||||
 | 
						hub->eng_distance = regGCVM_INVALIDATE_ENG1_REQ -
 | 
				
			||||||
 | 
							regGCVM_INVALIDATE_ENG0_REQ;
 | 
				
			||||||
 | 
						hub->eng_addr_distance = regGCVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 -
 | 
				
			||||||
 | 
							regGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hub->vm_cntx_cntl_vm_fault = GCVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
 | 
				
			||||||
 | 
							GCVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
 | 
				
			||||||
 | 
							GCVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
 | 
				
			||||||
 | 
							GCVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
 | 
				
			||||||
 | 
							GCVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
 | 
				
			||||||
 | 
							GCVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
 | 
				
			||||||
 | 
							GCVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hub->vmhub_funcs = &gfxhub_v3_0_3_vmhub_funcs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct amdgpu_gfxhub_funcs gfxhub_v3_0_3_funcs = {
 | 
				
			||||||
 | 
						.get_fb_location = gfxhub_v3_0_3_get_fb_location,
 | 
				
			||||||
 | 
						.get_mc_fb_offset = gfxhub_v3_0_3_get_mc_fb_offset,
 | 
				
			||||||
 | 
						.setup_vm_pt_regs = gfxhub_v3_0_3_setup_vm_pt_regs,
 | 
				
			||||||
 | 
						.gart_enable = gfxhub_v3_0_3_gart_enable,
 | 
				
			||||||
 | 
						.gart_disable = gfxhub_v3_0_3_gart_disable,
 | 
				
			||||||
 | 
						.set_fault_enable_default = gfxhub_v3_0_3_set_fault_enable_default,
 | 
				
			||||||
 | 
						.init = gfxhub_v3_0_3_init,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										29
									
								
								drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0_3.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2022 Advanced Micro Devices, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					 * all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
				
			||||||
 | 
					 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
				
			||||||
 | 
					 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
				
			||||||
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __GFXHUB_V3_0_3_H__
 | 
				
			||||||
 | 
					#define __GFXHUB_V3_0_3_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const struct amdgpu_gfxhub_funcs gfxhub_v3_0_3_funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,7 @@
 | 
				
			||||||
#include "soc15_common.h"
 | 
					#include "soc15_common.h"
 | 
				
			||||||
#include "nbio_v4_3.h"
 | 
					#include "nbio_v4_3.h"
 | 
				
			||||||
#include "gfxhub_v3_0.h"
 | 
					#include "gfxhub_v3_0.h"
 | 
				
			||||||
 | 
					#include "gfxhub_v3_0_3.h"
 | 
				
			||||||
#include "mmhub_v3_0.h"
 | 
					#include "mmhub_v3_0.h"
 | 
				
			||||||
#include "mmhub_v3_0_1.h"
 | 
					#include "mmhub_v3_0_1.h"
 | 
				
			||||||
#include "mmhub_v3_0_2.h"
 | 
					#include "mmhub_v3_0_2.h"
 | 
				
			||||||
| 
						 | 
					@ -233,7 +234,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Issue additional private vm invalidation to MMHUB */
 | 
						/* Issue additional private vm invalidation to MMHUB */
 | 
				
			||||||
	if ((vmhub != AMDGPU_GFXHUB_0) &&
 | 
						if ((vmhub != AMDGPU_GFXHUB_0) &&
 | 
				
			||||||
	    (hub->vm_l2_bank_select_reserved_cid2)) {
 | 
						    (hub->vm_l2_bank_select_reserved_cid2) &&
 | 
				
			||||||
 | 
							!amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
		inv_req = RREG32_NO_KIQ(hub->vm_l2_bank_select_reserved_cid2);
 | 
							inv_req = RREG32_NO_KIQ(hub->vm_l2_bank_select_reserved_cid2);
 | 
				
			||||||
		/* bit 25: RSERVED_CACHE_PRIVATE_INVALIDATION */
 | 
							/* bit 25: RSERVED_CACHE_PRIVATE_INVALIDATION */
 | 
				
			||||||
		inv_req |= (1 << 25);
 | 
							inv_req |= (1 << 25);
 | 
				
			||||||
| 
						 | 
					@ -590,7 +592,14 @@ static void gmc_v11_0_set_mmhub_funcs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev)
 | 
					static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	adev->gfxhub.funcs = &gfxhub_v3_0_funcs;
 | 
						switch (adev->ip_versions[GC_HWIP][0]) {
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
 | 
							adev->gfxhub.funcs = &gfxhub_v3_0_3_funcs;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							adev->gfxhub.funcs = &gfxhub_v3_0_funcs;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int gmc_v11_0_early_init(void *handle)
 | 
					static int gmc_v11_0_early_init(void *handle)
 | 
				
			||||||
| 
						 | 
					@ -640,7 +649,10 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev,
 | 
				
			||||||
	amdgpu_gmc_gart_location(adev, mc);
 | 
						amdgpu_gmc_gart_location(adev, mc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* base offset of vram pages */
 | 
						/* base offset of vram pages */
 | 
				
			||||||
	adev->vm_manager.vram_base_offset = adev->mmhub.funcs->get_mc_fb_offset(adev);
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
							adev->vm_manager.vram_base_offset = 0;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							adev->vm_manager.vram_base_offset = adev->mmhub.funcs->get_mc_fb_offset(adev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -732,6 +744,7 @@ static int gmc_v11_0_sw_init(void *handle)
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		adev->num_vmhubs = 2;
 | 
							adev->num_vmhubs = 2;
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * To fulfill 4-level page support,
 | 
							 * To fulfill 4-level page support,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,7 +105,13 @@ force_update_wptr_for_self_int(struct amdgpu_device *adev,
 | 
				
			||||||
	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
 | 
						ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
 | 
				
			||||||
				   RB_USED_INT_THRESHOLD, threshold);
 | 
									   RB_USED_INT_THRESHOLD, threshold);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WREG32_SOC15(OSSSYS, 0, regIH_RB_CNTL_RING1, ih_rb_cntl);
 | 
						if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
 | 
				
			||||||
 | 
							if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1, ih_rb_cntl))
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							WREG32_SOC15(OSSSYS, 0, regIH_RB_CNTL_RING1, ih_rb_cntl);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WREG32_SOC15(OSSSYS, 0, regIH_CNTL2, ih_cntl);
 | 
						WREG32_SOC15(OSSSYS, 0, regIH_CNTL2, ih_cntl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,7 +138,13 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev,
 | 
				
			||||||
	/* enable_intr field is only valid in ring0 */
 | 
						/* enable_intr field is only valid in ring0 */
 | 
				
			||||||
	if (ih == &adev->irq.ih)
 | 
						if (ih == &adev->irq.ih)
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
 | 
							tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
 | 
				
			||||||
	WREG32(ih_regs->ih_rb_cntl, tmp);
 | 
					
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
 | 
				
			||||||
 | 
							if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
 | 
				
			||||||
 | 
								return -ETIMEDOUT;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							WREG32(ih_regs->ih_rb_cntl, tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (enable) {
 | 
						if (enable) {
 | 
				
			||||||
		ih->enabled = true;
 | 
							ih->enabled = true;
 | 
				
			||||||
| 
						 | 
					@ -242,7 +254,15 @@ static int ih_v6_0_enable_ring(struct amdgpu_device *adev,
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
 | 
							tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
 | 
							tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	WREG32(ih_regs->ih_rb_cntl, tmp);
 | 
					
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
 | 
				
			||||||
 | 
							if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
 | 
				
			||||||
 | 
								DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
 | 
				
			||||||
 | 
								return -ETIMEDOUT;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							WREG32(ih_regs->ih_rb_cntl, tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ih == &adev->irq.ih) {
 | 
						if (ih == &adev->irq.ih) {
 | 
				
			||||||
		/* set the ih ring 0 writeback address whether it's enabled or not */
 | 
							/* set the ih ring 0 writeback address whether it's enabled or not */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,12 +26,15 @@
 | 
				
			||||||
#include "amdgpu_imu.h"
 | 
					#include "amdgpu_imu.h"
 | 
				
			||||||
#include "amdgpu_dpm.h"
 | 
					#include "amdgpu_dpm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "imu_v11_0_3.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gc/gc_11_0_0_offset.h"
 | 
					#include "gc/gc_11_0_0_offset.h"
 | 
				
			||||||
#include "gc/gc_11_0_0_sh_mask.h"
 | 
					#include "gc/gc_11_0_0_sh_mask.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_0_imu.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_0_imu.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_1_imu.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_1_imu.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_imu.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_2_imu.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_3_imu.bin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int imu_v11_0_init_microcode(struct amdgpu_device *adev)
 | 
					static int imu_v11_0_init_microcode(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -360,6 +363,9 @@ static void imu_v11_0_program_rlc_ram(struct amdgpu_device *adev)
 | 
				
			||||||
		program_imu_rlc_ram(adev, imu_rlc_ram_golden_11_0_2,
 | 
							program_imu_rlc_ram(adev, imu_rlc_ram_golden_11_0_2,
 | 
				
			||||||
				(const u32)ARRAY_SIZE(imu_rlc_ram_golden_11_0_2));
 | 
									(const u32)ARRAY_SIZE(imu_rlc_ram_golden_11_0_2));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
 | 
							imu_v11_0_3_program_rlc_ram(adev);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		BUG();
 | 
							BUG();
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										144
									
								
								drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,144 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2022 Advanced Micro Devices, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					 * all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
				
			||||||
 | 
					 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
				
			||||||
 | 
					 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
				
			||||||
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "amdgpu.h"
 | 
				
			||||||
 | 
					#include "amdgpu_imu.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gc/gc_11_0_3_offset.h"
 | 
				
			||||||
 | 
					#include "gc/gc_11_0_3_sh_mask.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct imu_rlc_ram_golden imu_rlc_ram_golden_11_0_3[] = {
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_IO_RD_COMBINE_FLUSH, 0x00055555, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_IO_WR_COMBINE_FLUSH, 0x00055555, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_DRAM_COMBINE_FLUSH, 0x00555555, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_MISC2, 0x00001ffe, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_CREDITS, 0x003f3fff, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_TAG_RESERVE1, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCC_RESERVE0, 0x00041000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCC_RESERVE1, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCD_RESERVE0, 0x00040000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_VCD_RESERVE1, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_MISC, 0x00000017, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGUS_SDP_ENABLE, 0x00000001, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_CREDITS, 0x003f3fbf, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_TAG_RESERVE0, 0x10200800, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_TAG_RESERVE1, 0x00000088, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_VCC_RESERVE0, 0x1d041040, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_VCC_RESERVE1, 0x80000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_IO_PRIORITY, 0x88888888, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_MAM_CTRL, 0x0000d800, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_ARB_FINAL, 0x000007ff, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_DRAM_PAGE_BURST, 0x20080200, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_SDP_ENABLE, 0x00000001, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL2, 0x00020000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_APT_CNTL, 0x0000000c, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_CACHEABLE_DRAM_ADDRESS_END, 0x000fffff, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCEA_MISC, 0x0c48bff0, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SA_UNIT_DISABLE, 0x00fffc01, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_PRIM_CONFIG, 0x000fffe1, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_RB_BACKEND_DISABLE, 0xffffff01, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xfffe0001, 0x40000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xfffe0001, 0x42000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x44000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x46000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x48000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_ARRAY_CONFIG, 0xffff0001, 0x4A000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCGTS_TCC_DISABLE, 0x00000001, 0x00000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_SHADER_RATE_CONFIG, 0x00000001, 0x00000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCC_GC_EDC_CONFIG, 0x00000001, 0x00000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, 0x00000500, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_SYSTEM_APERTURE_LOW_ADDR, 0x00000001, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_LOCAL_FB_ADDRESS_START, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_LOCAL_FB_ADDRESS_END, 0x000005ff, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_FB_LOCATION_BASE, 0x00006000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_FB_LOCATION_TOP, 0x000065ff, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT0_CNTL, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT1_CNTL, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_TOP_OF_DRAM_SLOT1, 0xff800000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_LOWER_TOP_OF_DRAM2, 0x00000001, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_NB_UPPER_TOP_OF_DRAM2, 0x00000fff, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, 0x00001ffc, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_MX_L1_TLB_CNTL, 0x00000551, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL, 0x00080603, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL2, 0x00000003, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL3, 0x00100003, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CNTL5, 0x00003fe0, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT0_CNTL, 0x00000001, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CONTEXT0_PER_PFVF_PTE_CACHE_FRAGMENT_SIZES, 0x00000c00, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_CONTEXT1_CNTL, 0x00000001, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_CONTEXT1_PER_PFVF_PTE_CACHE_FRAGMENT_SIZES, 0x00000c00, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x00000444, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGL2_PIPE_STEER_0, 0x54105410, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGL2_PIPE_STEER_2, 0x76323276, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGB_ADDR_CONFIG, 0x00000244, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCUTCL2_HARVEST_BYPASS_GROUPS, 0x00000006, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_APT_CNTL, 0x0000000c, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_BASE, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_BOT, 0x00000002, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCMC_VM_AGP_TOP, 0x00000000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL2, 0x00020000, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regSDMA0_UCODE_SELFLOAD_CONTROL, 0x00000210, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regSDMA1_UCODE_SELFLOAD_CONTROL, 0x00000210, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPC_PSP_DEBUG, CPC_PSP_DEBUG__GPA_OVERRIDE_MASK, 0xe0000000),
 | 
				
			||||||
 | 
						IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPG_PSP_DEBUG, CPG_PSP_DEBUG__GPA_OVERRIDE_MASK, 0xe0000000),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void program_rlc_ram_register_setting(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										     const struct imu_rlc_ram_golden *regs,
 | 
				
			||||||
 | 
										     const u32 array_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct imu_rlc_ram_golden *entry;
 | 
				
			||||||
 | 
						u32 reg, data;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < array_size; ++i) {
 | 
				
			||||||
 | 
							entry = ®s[i];
 | 
				
			||||||
 | 
							reg =  adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg;
 | 
				
			||||||
 | 
							reg |= entry->addr_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							data = entry->data;
 | 
				
			||||||
 | 
							if (entry->reg == regGCMC_VM_AGP_BASE)
 | 
				
			||||||
 | 
								data = 0x00ffffff;
 | 
				
			||||||
 | 
							else if (entry->reg == regGCMC_VM_AGP_TOP)
 | 
				
			||||||
 | 
								data = 0x0;
 | 
				
			||||||
 | 
							else if (entry->reg == regGCMC_VM_FB_LOCATION_BASE)
 | 
				
			||||||
 | 
								data = adev->gmc.vram_start >> 24;
 | 
				
			||||||
 | 
							else if (entry->reg == regGCMC_VM_FB_LOCATION_TOP)
 | 
				
			||||||
 | 
								data = adev->gmc.vram_end >> 24;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_HIGH, 0);
 | 
				
			||||||
 | 
							WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_LOW, reg);
 | 
				
			||||||
 | 
							WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_DATA, data);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						//Indicate the latest entry
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_HIGH, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_ADDR_LOW, 0);
 | 
				
			||||||
 | 
						WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_DATA, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void imu_v11_0_3_program_rlc_ram(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						program_rlc_ram_register_setting(adev,
 | 
				
			||||||
 | 
										 imu_rlc_ram_golden_11_0_3,
 | 
				
			||||||
 | 
										 (const u32)ARRAY_SIZE(imu_rlc_ram_golden_11_0_3));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2022 Advanced Micro Devices, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					 * all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
				
			||||||
 | 
					 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
				
			||||||
 | 
					 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
				
			||||||
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __IMU_V11_0_3_H__
 | 
				
			||||||
 | 
					#define __IMU_V11_0_3_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void imu_v11_0_3_program_rlc_ram(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,8 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mes_v11_0_hw_fini(void *handle);
 | 
					static int mes_v11_0_hw_fini(void *handle);
 | 
				
			||||||
static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev);
 | 
					static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev);
 | 
				
			||||||
| 
						 | 
					@ -183,6 +185,7 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes,
 | 
				
			||||||
	mes_add_queue_pkt.trap_handler_addr = input->tba_addr;
 | 
						mes_add_queue_pkt.trap_handler_addr = input->tba_addr;
 | 
				
			||||||
	mes_add_queue_pkt.tma_addr = input->tma_addr;
 | 
						mes_add_queue_pkt.tma_addr = input->tma_addr;
 | 
				
			||||||
	mes_add_queue_pkt.is_kfd_process = input->is_kfd_process;
 | 
						mes_add_queue_pkt.is_kfd_process = input->is_kfd_process;
 | 
				
			||||||
 | 
						mes_add_queue_pkt.trap_en = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mes_v11_0_submit_pkt_and_poll_completion(mes,
 | 
						return mes_v11_0_submit_pkt_and_poll_completion(mes,
 | 
				
			||||||
			&mes_add_queue_pkt, sizeof(mes_add_queue_pkt),
 | 
								&mes_add_queue_pkt, sizeof(mes_add_queue_pkt),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,6 +176,7 @@ static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
 | 
				
			||||||
	tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
 | 
						tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
 | 
				
			||||||
	WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp);
 | 
						WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = mmVM_L2_CNTL3_DEFAULT;
 | 
				
			||||||
	if (adev->gmc.translate_further) {
 | 
						if (adev->gmc.translate_further) {
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 12);
 | 
							tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 12);
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3,
 | 
							tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,17 +169,17 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
 | 
				
			||||||
	uint64_t value;
 | 
						uint64_t value;
 | 
				
			||||||
	uint32_t tmp;
 | 
						uint32_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Disable AGP. */
 | 
					 | 
				
			||||||
	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
 | 
					 | 
				
			||||||
	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
 | 
					 | 
				
			||||||
	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!amdgpu_sriov_vf(adev)) {
 | 
						if (!amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * the new L1 policy will block SRIOV guest from writing
 | 
							 * the new L1 policy will block SRIOV guest from writing
 | 
				
			||||||
		 * these regs, and they will be programed at host.
 | 
							 * these regs, and they will be programed at host.
 | 
				
			||||||
		 * so skip programing these regs.
 | 
							 * so skip programing these regs.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
							/* Disable AGP. */
 | 
				
			||||||
 | 
							WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
 | 
				
			||||||
 | 
							WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
 | 
				
			||||||
 | 
							WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Program the system aperture low logical page number. */
 | 
							/* Program the system aperture low logical page number. */
 | 
				
			||||||
		WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
 | 
							WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
 | 
				
			||||||
			     adev->gmc.vram_start >> 18);
 | 
								     adev->gmc.vram_start >> 18);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,9 +295,17 @@ static void mmhub_v9_4_disable_identity_aperture(struct amdgpu_device *adev,
 | 
				
			||||||
static void mmhub_v9_4_setup_vmid_config(struct amdgpu_device *adev, int hubid)
 | 
					static void mmhub_v9_4_setup_vmid_config(struct amdgpu_device *adev, int hubid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
 | 
						struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
 | 
				
			||||||
 | 
						unsigned int num_level, block_size;
 | 
				
			||||||
	uint32_t tmp;
 | 
						uint32_t tmp;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						num_level = adev->vm_manager.num_level;
 | 
				
			||||||
 | 
						block_size = adev->vm_manager.block_size;
 | 
				
			||||||
 | 
						if (adev->gmc.translate_further)
 | 
				
			||||||
 | 
							num_level -= 1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							block_size -= 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i <= 14; i++) {
 | 
						for (i = 0; i <= 14; i++) {
 | 
				
			||||||
		tmp = RREG32_SOC15_OFFSET(MMHUB, 0, mmVML2VC0_VM_CONTEXT1_CNTL,
 | 
							tmp = RREG32_SOC15_OFFSET(MMHUB, 0, mmVML2VC0_VM_CONTEXT1_CNTL,
 | 
				
			||||||
				hubid * MMHUB_INSTANCE_REGISTER_OFFSET + i);
 | 
									hubid * MMHUB_INSTANCE_REGISTER_OFFSET + i);
 | 
				
			||||||
| 
						 | 
					@ -305,7 +313,7 @@ static void mmhub_v9_4_setup_vmid_config(struct amdgpu_device *adev, int hubid)
 | 
				
			||||||
				    ENABLE_CONTEXT, 1);
 | 
									    ENABLE_CONTEXT, 1);
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
							tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
				
			||||||
				    PAGE_TABLE_DEPTH,
 | 
									    PAGE_TABLE_DEPTH,
 | 
				
			||||||
				    adev->vm_manager.num_level);
 | 
									    num_level);
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
							tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
				
			||||||
				    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
									    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
							tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
				
			||||||
| 
						 | 
					@ -323,7 +331,7 @@ static void mmhub_v9_4_setup_vmid_config(struct amdgpu_device *adev, int hubid)
 | 
				
			||||||
				    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
									    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
							tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
				
			||||||
				    PAGE_TABLE_BLOCK_SIZE,
 | 
									    PAGE_TABLE_BLOCK_SIZE,
 | 
				
			||||||
				    adev->vm_manager.block_size - 9);
 | 
									    block_size);
 | 
				
			||||||
		/* Send no-retry XNACK on fault to suppress VM fault storm. */
 | 
							/* Send no-retry XNACK on fault to suppress VM fault storm. */
 | 
				
			||||||
		tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
							tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT1_CNTL,
 | 
				
			||||||
				    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
 | 
									    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										140
									
								
								drivers/gpu/drm/amd/amdgpu/mmsch_v4_0.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,140 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2022 Advanced Micro Devices, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					 * all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
				
			||||||
 | 
					 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
				
			||||||
 | 
					 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
				
			||||||
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __MMSCH_V4_0_H__
 | 
				
			||||||
 | 
					#define __MMSCH_V4_0_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "amdgpu_vcn.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MMSCH_VERSION_MAJOR	4
 | 
				
			||||||
 | 
					#define MMSCH_VERSION_MINOR	0
 | 
				
			||||||
 | 
					#define MMSCH_VERSION	(MMSCH_VERSION_MAJOR << 16 | MMSCH_VERSION_MINOR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RB_ENABLED (1 << 0)
 | 
				
			||||||
 | 
					#define RB4_ENABLED (1 << 1)
 | 
				
			||||||
 | 
					#define MMSCH_DOORBELL_OFFSET 0x8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MMSCH_VF_ENGINE_STATUS__PASS 0x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MMSCH_VF_MAILBOX_RESP__OK 0x1
 | 
				
			||||||
 | 
					#define MMSCH_VF_MAILBOX_RESP__INCOMPLETE 0x2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum mmsch_v4_0_command_type {
 | 
				
			||||||
 | 
						MMSCH_COMMAND__DIRECT_REG_WRITE = 0,
 | 
				
			||||||
 | 
						MMSCH_COMMAND__DIRECT_REG_POLLING = 2,
 | 
				
			||||||
 | 
						MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE = 3,
 | 
				
			||||||
 | 
						MMSCH_COMMAND__INDIRECT_REG_WRITE = 8,
 | 
				
			||||||
 | 
						MMSCH_COMMAND__END = 0xf
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_table_info {
 | 
				
			||||||
 | 
						uint32_t init_status;
 | 
				
			||||||
 | 
						uint32_t table_offset;
 | 
				
			||||||
 | 
						uint32_t table_size;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_init_header {
 | 
				
			||||||
 | 
						uint32_t version;
 | 
				
			||||||
 | 
						uint32_t total_size;
 | 
				
			||||||
 | 
						struct mmsch_v4_0_table_info inst[AMDGPU_MAX_VCN_INSTANCES];
 | 
				
			||||||
 | 
						struct mmsch_v4_0_table_info jpegdec;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_cmd_direct_reg_header {
 | 
				
			||||||
 | 
						uint32_t reg_offset   : 28;
 | 
				
			||||||
 | 
						uint32_t command_type : 4;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_cmd_indirect_reg_header {
 | 
				
			||||||
 | 
						uint32_t reg_offset    : 20;
 | 
				
			||||||
 | 
						uint32_t reg_idx_space : 8;
 | 
				
			||||||
 | 
						uint32_t command_type  : 4;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_cmd_direct_write {
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
 | 
				
			||||||
 | 
						uint32_t reg_value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_cmd_direct_read_modify_write {
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
 | 
				
			||||||
 | 
						uint32_t write_data;
 | 
				
			||||||
 | 
						uint32_t mask_value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_cmd_direct_polling {
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
 | 
				
			||||||
 | 
						uint32_t mask_value;
 | 
				
			||||||
 | 
						uint32_t wait_value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_cmd_end {
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_direct_reg_header cmd_header;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mmsch_v4_0_cmd_indirect_write {
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_indirect_reg_header cmd_header;
 | 
				
			||||||
 | 
						uint32_t reg_value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(reg, mask, data) { \
 | 
				
			||||||
 | 
						size = sizeof(struct mmsch_v4_0_cmd_direct_read_modify_write); \
 | 
				
			||||||
 | 
						size_dw = size / 4; \
 | 
				
			||||||
 | 
						direct_rd_mod_wt.cmd_header.reg_offset = reg; \
 | 
				
			||||||
 | 
						direct_rd_mod_wt.mask_value = mask; \
 | 
				
			||||||
 | 
						direct_rd_mod_wt.write_data = data; \
 | 
				
			||||||
 | 
						memcpy((void *)table_loc, &direct_rd_mod_wt, size); \
 | 
				
			||||||
 | 
						table_loc += size_dw; \
 | 
				
			||||||
 | 
						table_size += size_dw; \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MMSCH_V4_0_INSERT_DIRECT_WT(reg, value) { \
 | 
				
			||||||
 | 
						size = sizeof(struct mmsch_v4_0_cmd_direct_write); \
 | 
				
			||||||
 | 
						size_dw = size / 4; \
 | 
				
			||||||
 | 
						direct_wt.cmd_header.reg_offset = reg; \
 | 
				
			||||||
 | 
						direct_wt.reg_value = value; \
 | 
				
			||||||
 | 
						memcpy((void *)table_loc, &direct_wt, size); \
 | 
				
			||||||
 | 
						table_loc += size_dw; \
 | 
				
			||||||
 | 
						table_size += size_dw; \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MMSCH_V4_0_INSERT_DIRECT_POLL(reg, mask, wait) { \
 | 
				
			||||||
 | 
						size = sizeof(struct mmsch_v4_0_cmd_direct_polling); \
 | 
				
			||||||
 | 
						size_dw = size / 4; \
 | 
				
			||||||
 | 
						direct_poll.cmd_header.reg_offset = reg; \
 | 
				
			||||||
 | 
						direct_poll.mask_value = mask; \
 | 
				
			||||||
 | 
						direct_poll.wait_value = wait; \
 | 
				
			||||||
 | 
						memcpy((void *)table_loc, &direct_poll, size); \
 | 
				
			||||||
 | 
						table_loc += size_dw; \
 | 
				
			||||||
 | 
						table_size += size_dw; \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MMSCH_V4_0_INSERT_END() { \
 | 
				
			||||||
 | 
						size = sizeof(struct mmsch_v4_0_cmd_end); \
 | 
				
			||||||
 | 
						size_dw = size / 4; \
 | 
				
			||||||
 | 
						memcpy((void *)table_loc, &end, size); \
 | 
				
			||||||
 | 
						table_loc += size_dw; \
 | 
				
			||||||
 | 
						table_size += size_dw; \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -290,6 +290,7 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
 | 
				
			||||||
		reset_context.method = AMD_RESET_METHOD_NONE;
 | 
							reset_context.method = AMD_RESET_METHOD_NONE;
 | 
				
			||||||
		reset_context.reset_req_dev = adev;
 | 
							reset_context.reset_req_dev = adev;
 | 
				
			||||||
		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
							clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
							clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
							amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -317,6 +317,7 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
 | 
				
			||||||
		reset_context.method = AMD_RESET_METHOD_NONE;
 | 
							reset_context.method = AMD_RESET_METHOD_NONE;
 | 
				
			||||||
		reset_context.reset_req_dev = adev;
 | 
							reset_context.reset_req_dev = adev;
 | 
				
			||||||
		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
							clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
							clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
							amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,6 +529,7 @@ static void xgpu_vi_mailbox_flr_work(struct work_struct *work)
 | 
				
			||||||
		reset_context.method = AMD_RESET_METHOD_NONE;
 | 
							reset_context.method = AMD_RESET_METHOD_NONE;
 | 
				
			||||||
		reset_context.reset_req_dev = adev;
 | 
							reset_context.reset_req_dev = adev;
 | 
				
			||||||
		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
							clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
							clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
							amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -488,3 +488,47 @@ const struct amdgpu_nbio_funcs nbio_v4_3_funcs = {
 | 
				
			||||||
	.get_rom_offset = nbio_v4_3_get_rom_offset,
 | 
						.get_rom_offset = nbio_v4_3_get_rom_offset,
 | 
				
			||||||
	.program_aspm = nbio_v4_3_program_aspm,
 | 
						.program_aspm = nbio_v4_3_program_aspm,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nbio_v4_3_sriov_ih_doorbell_range(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										bool use_doorbell, int doorbell_index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nbio_v4_3_sriov_sdma_doorbell_range(struct amdgpu_device *adev, int instance,
 | 
				
			||||||
 | 
										  bool use_doorbell, int doorbell_index,
 | 
				
			||||||
 | 
										  int doorbell_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nbio_v4_3_sriov_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell,
 | 
				
			||||||
 | 
										 int doorbell_index, int instance)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nbio_v4_3_sriov_gc_doorbell_init(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct amdgpu_nbio_funcs nbio_v4_3_sriov_funcs = {
 | 
				
			||||||
 | 
						.get_hdp_flush_req_offset = nbio_v4_3_get_hdp_flush_req_offset,
 | 
				
			||||||
 | 
						.get_hdp_flush_done_offset = nbio_v4_3_get_hdp_flush_done_offset,
 | 
				
			||||||
 | 
						.get_pcie_index_offset = nbio_v4_3_get_pcie_index_offset,
 | 
				
			||||||
 | 
						.get_pcie_data_offset = nbio_v4_3_get_pcie_data_offset,
 | 
				
			||||||
 | 
						.get_rev_id = nbio_v4_3_get_rev_id,
 | 
				
			||||||
 | 
						.mc_access_enable = nbio_v4_3_mc_access_enable,
 | 
				
			||||||
 | 
						.get_memsize = nbio_v4_3_get_memsize,
 | 
				
			||||||
 | 
						.sdma_doorbell_range = nbio_v4_3_sriov_sdma_doorbell_range,
 | 
				
			||||||
 | 
						.vcn_doorbell_range = nbio_v4_3_sriov_vcn_doorbell_range,
 | 
				
			||||||
 | 
						.gc_doorbell_init = nbio_v4_3_sriov_gc_doorbell_init,
 | 
				
			||||||
 | 
						.enable_doorbell_aperture = nbio_v4_3_enable_doorbell_aperture,
 | 
				
			||||||
 | 
						.enable_doorbell_selfring_aperture = nbio_v4_3_enable_doorbell_selfring_aperture,
 | 
				
			||||||
 | 
						.ih_doorbell_range = nbio_v4_3_sriov_ih_doorbell_range,
 | 
				
			||||||
 | 
						.update_medium_grain_clock_gating = nbio_v4_3_update_medium_grain_clock_gating,
 | 
				
			||||||
 | 
						.update_medium_grain_light_sleep = nbio_v4_3_update_medium_grain_light_sleep,
 | 
				
			||||||
 | 
						.get_clockgating_state = nbio_v4_3_get_clockgating_state,
 | 
				
			||||||
 | 
						.ih_control = nbio_v4_3_ih_control,
 | 
				
			||||||
 | 
						.init_registers = nbio_v4_3_init_registers,
 | 
				
			||||||
 | 
						.remap_hdp_registers = nbio_v4_3_remap_hdp_registers,
 | 
				
			||||||
 | 
						.get_rom_offset = nbio_v4_3_get_rom_offset,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,5 +28,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const struct nbio_hdp_flush_reg nbio_v4_3_hdp_flush_reg;
 | 
					extern const struct nbio_hdp_flush_reg nbio_v4_3_hdp_flush_reg;
 | 
				
			||||||
extern const struct amdgpu_nbio_funcs nbio_v4_3_funcs;
 | 
					extern const struct amdgpu_nbio_funcs nbio_v4_3_funcs;
 | 
				
			||||||
 | 
					extern const struct amdgpu_nbio_funcs nbio_v4_3_sriov_funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,12 +68,6 @@ static void nbio_v7_7_sdma_doorbell_range(struct amdgpu_device *adev, int instan
 | 
				
			||||||
		doorbell_range = REG_SET_FIELD(doorbell_range,
 | 
							doorbell_range = REG_SET_FIELD(doorbell_range,
 | 
				
			||||||
					       GDC0_BIF_CSDMA_DOORBELL_RANGE,
 | 
										       GDC0_BIF_CSDMA_DOORBELL_RANGE,
 | 
				
			||||||
					       SIZE, doorbell_size);
 | 
										       SIZE, doorbell_size);
 | 
				
			||||||
		doorbell_range = REG_SET_FIELD(doorbell_range,
 | 
					 | 
				
			||||||
					       GDC0_BIF_SDMA0_DOORBELL_RANGE,
 | 
					 | 
				
			||||||
					       OFFSET, doorbell_index);
 | 
					 | 
				
			||||||
		doorbell_range = REG_SET_FIELD(doorbell_range,
 | 
					 | 
				
			||||||
					       GDC0_BIF_SDMA0_DOORBELL_RANGE,
 | 
					 | 
				
			||||||
					       SIZE, doorbell_size);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		doorbell_range = REG_SET_FIELD(doorbell_range,
 | 
							doorbell_range = REG_SET_FIELD(doorbell_range,
 | 
				
			||||||
					       GDC0_BIF_SDMA0_DOORBELL_RANGE,
 | 
										       GDC0_BIF_SDMA0_DOORBELL_RANGE,
 | 
				
			||||||
| 
						 | 
					@ -247,6 +241,81 @@ static void nbio_v7_7_init_registers(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nbio_v7_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
											       bool enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t def, data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enable && !(adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def = data = RREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL);
 | 
				
			||||||
 | 
						if (enable) {
 | 
				
			||||||
 | 
							data |= (BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								 BIF0_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								 BIF0_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								 BIF0_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								 BIF0_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								 BIF0_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							data &= ~(BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								  BIF0_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								  BIF0_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								  BIF0_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								  BIF0_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK |
 | 
				
			||||||
 | 
								  BIF0_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (def != data)
 | 
				
			||||||
 | 
							WREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nbio_v7_7_update_medium_grain_light_sleep(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
											      bool enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t def, data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enable && !(adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2);
 | 
				
			||||||
 | 
						if (enable)
 | 
				
			||||||
 | 
							data |= BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							data &= ~BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (def != data)
 | 
				
			||||||
 | 
							WREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_TX_POWER_CTRL_1);
 | 
				
			||||||
 | 
						if (enable) {
 | 
				
			||||||
 | 
							data |= (BIF0_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK |
 | 
				
			||||||
 | 
								BIF0_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							data &= ~(BIF0_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK |
 | 
				
			||||||
 | 
								BIF0_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (def != data)
 | 
				
			||||||
 | 
							WREG32_SOC15(NBIO, 0, regBIF0_PCIE_TX_POWER_CTRL_1, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nbio_v7_7_get_clockgating_state(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										    u64 *flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* AMD_CG_SUPPORT_BIF_MGCG */
 | 
				
			||||||
 | 
						data = RREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL);
 | 
				
			||||||
 | 
						if (data & BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK)
 | 
				
			||||||
 | 
							*flags |= AMD_CG_SUPPORT_BIF_MGCG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* AMD_CG_SUPPORT_BIF_LS */
 | 
				
			||||||
 | 
						data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2);
 | 
				
			||||||
 | 
						if (data & BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK)
 | 
				
			||||||
 | 
							*flags |= AMD_CG_SUPPORT_BIF_LS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct amdgpu_nbio_funcs nbio_v7_7_funcs = {
 | 
					const struct amdgpu_nbio_funcs nbio_v7_7_funcs = {
 | 
				
			||||||
	.get_hdp_flush_req_offset = nbio_v7_7_get_hdp_flush_req_offset,
 | 
						.get_hdp_flush_req_offset = nbio_v7_7_get_hdp_flush_req_offset,
 | 
				
			||||||
	.get_hdp_flush_done_offset = nbio_v7_7_get_hdp_flush_done_offset,
 | 
						.get_hdp_flush_done_offset = nbio_v7_7_get_hdp_flush_done_offset,
 | 
				
			||||||
| 
						 | 
					@ -262,6 +331,9 @@ const struct amdgpu_nbio_funcs nbio_v7_7_funcs = {
 | 
				
			||||||
	.enable_doorbell_aperture = nbio_v7_7_enable_doorbell_aperture,
 | 
						.enable_doorbell_aperture = nbio_v7_7_enable_doorbell_aperture,
 | 
				
			||||||
	.enable_doorbell_selfring_aperture = nbio_v7_7_enable_doorbell_selfring_aperture,
 | 
						.enable_doorbell_selfring_aperture = nbio_v7_7_enable_doorbell_selfring_aperture,
 | 
				
			||||||
	.ih_doorbell_range = nbio_v7_7_ih_doorbell_range,
 | 
						.ih_doorbell_range = nbio_v7_7_ih_doorbell_range,
 | 
				
			||||||
 | 
						.update_medium_grain_clock_gating = nbio_v7_7_update_medium_grain_clock_gating,
 | 
				
			||||||
 | 
						.update_medium_grain_light_sleep = nbio_v7_7_update_medium_grain_light_sleep,
 | 
				
			||||||
 | 
						.get_clockgating_state = nbio_v7_7_get_clockgating_state,
 | 
				
			||||||
	.ih_control = nbio_v7_7_ih_control,
 | 
						.ih_control = nbio_v7_7_ih_control,
 | 
				
			||||||
	.init_registers = nbio_v7_7_init_registers,
 | 
						.init_registers = nbio_v7_7_init_registers,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
 | 
					MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
 | 
					MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
 | 
					MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* For large FW files the time to complete can be very long */
 | 
					/* For large FW files the time to complete can be very long */
 | 
				
			||||||
#define USBC_PD_POLLING_LIMIT_S 240
 | 
					#define USBC_PD_POLLING_LIMIT_S 240
 | 
				
			||||||
| 
						 | 
					@ -109,6 +110,7 @@ static int psp_v13_0_init_microcode(struct psp_context *psp)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(13, 0, 0):
 | 
						case IP_VERSION(13, 0, 0):
 | 
				
			||||||
	case IP_VERSION(13, 0, 7):
 | 
						case IP_VERSION(13, 0, 7):
 | 
				
			||||||
 | 
						case IP_VERSION(13, 0, 10):
 | 
				
			||||||
		err = psp_init_sos_microcode(psp, chip_name);
 | 
							err = psp_init_sos_microcode(psp, chip_name);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2002,7 +2002,6 @@ static int sdma_v4_0_sw_fini(void *handle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sdma_v4_0_hw_init(void *handle)
 | 
					static int sdma_v4_0_hw_init(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int r;
 | 
					 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adev->flags & AMD_IS_APU)
 | 
						if (adev->flags & AMD_IS_APU)
 | 
				
			||||||
| 
						 | 
					@ -2011,9 +2010,7 @@ static int sdma_v4_0_hw_init(void *handle)
 | 
				
			||||||
	if (!amdgpu_sriov_vf(adev))
 | 
						if (!amdgpu_sriov_vf(adev))
 | 
				
			||||||
		sdma_v4_0_init_golden_registers(adev);
 | 
							sdma_v4_0_init_golden_registers(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r = sdma_v4_0_start(adev);
 | 
						return sdma_v4_0_start(adev);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return r;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sdma_v4_0_hw_fini(void *handle)
 | 
					static int sdma_v4_0_hw_fini(void *handle)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1413,12 +1413,9 @@ static int sdma_v5_2_sw_fini(void *handle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sdma_v5_2_hw_init(void *handle)
 | 
					static int sdma_v5_2_hw_init(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int r;
 | 
					 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r = sdma_v5_2_start(adev);
 | 
						return sdma_v5_2_start(adev);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return r;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sdma_v5_2_hw_fini(void *handle)
 | 
					static int sdma_v5_2_hw_fini(void *handle)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/sdma_6_0_0.bin");
 | 
					MODULE_FIRMWARE("amdgpu/sdma_6_0_0.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
 | 
					MODULE_FIRMWARE("amdgpu/sdma_6_0_1.bin");
 | 
				
			||||||
MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
 | 
					MODULE_FIRMWARE("amdgpu/sdma_6_0_2.bin");
 | 
				
			||||||
 | 
					MODULE_FIRMWARE("amdgpu/sdma_6_0_3.bin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SDMA1_REG_OFFSET 0x600
 | 
					#define SDMA1_REG_OFFSET 0x600
 | 
				
			||||||
#define SDMA0_HYP_DEC_REG_START 0x5880
 | 
					#define SDMA0_HYP_DEC_REG_START 0x5880
 | 
				
			||||||
| 
						 | 
					@ -559,7 +560,8 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
 | 
				
			||||||
	for (i = 0; i < adev->sdma.num_instances; i++) {
 | 
						for (i = 0; i < adev->sdma.num_instances; i++) {
 | 
				
			||||||
		ring = &adev->sdma.instance[i].ring;
 | 
							ring = &adev->sdma.instance[i].ring;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
 | 
							if (!amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
								WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Set ring buffer size in dwords */
 | 
							/* Set ring buffer size in dwords */
 | 
				
			||||||
		rb_bufsz = order_base_2(ring->ring_size / 4);
 | 
							rb_bufsz = order_base_2(ring->ring_size / 4);
 | 
				
			||||||
| 
						 | 
					@ -593,7 +595,10 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
 | 
				
			||||||
		       lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC);
 | 
							       lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
 | 
							rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
 | 
				
			||||||
		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 0);
 | 
							if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
								rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 1);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 0);
 | 
				
			||||||
		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, F32_WPTR_POLL_ENABLE, 1);
 | 
							rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, F32_WPTR_POLL_ENABLE, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_BASE), ring->gpu_addr >> 8);
 | 
							WREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_BASE), ring->gpu_addr >> 8);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										303
									
								
								drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,303 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2021 Advanced Micro Devices, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					 * all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
				
			||||||
 | 
					 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | 
				
			||||||
 | 
					 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
				
			||||||
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "sienna_cichlid.h"
 | 
				
			||||||
 | 
					#include "amdgpu_reset.h"
 | 
				
			||||||
 | 
					#include "amdgpu_amdkfd.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dpm.h"
 | 
				
			||||||
 | 
					#include "amdgpu_job.h"
 | 
				
			||||||
 | 
					#include "amdgpu_ring.h"
 | 
				
			||||||
 | 
					#include "amdgpu_ras.h"
 | 
				
			||||||
 | 
					#include "amdgpu_psp.h"
 | 
				
			||||||
 | 
					#include "amdgpu_xgmi.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct amdgpu_reset_handler *
 | 
				
			||||||
 | 
					sienna_cichlid_get_reset_handler(struct amdgpu_reset_control *reset_ctl,
 | 
				
			||||||
 | 
								    struct amdgpu_reset_context *reset_context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_reset_handler *handler;
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (reset_context->method != AMD_RESET_METHOD_NONE) {
 | 
				
			||||||
 | 
							list_for_each_entry(handler, &reset_ctl->reset_handlers,
 | 
				
			||||||
 | 
									     handler_list) {
 | 
				
			||||||
 | 
								if (handler->reset_method == reset_context->method)
 | 
				
			||||||
 | 
									return handler;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							list_for_each_entry(handler, &reset_ctl->reset_handlers,
 | 
				
			||||||
 | 
									     handler_list) {
 | 
				
			||||||
 | 
								if (handler->reset_method == AMD_RESET_METHOD_MODE2 &&
 | 
				
			||||||
 | 
								    adev->pm.fw_version >= 0x3a5500 &&
 | 
				
			||||||
 | 
								    !amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
									reset_context->method = AMD_RESET_METHOD_MODE2;
 | 
				
			||||||
 | 
									return handler;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sienna_cichlid_mode2_suspend_ip(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
 | 
				
			||||||
 | 
						amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
 | 
				
			||||||
 | 
							if (!(adev->ip_blocks[i].version->type ==
 | 
				
			||||||
 | 
								      AMD_IP_BLOCK_TYPE_GFX ||
 | 
				
			||||||
 | 
							      adev->ip_blocks[i].version->type ==
 | 
				
			||||||
 | 
								      AMD_IP_BLOCK_TYPE_SDMA))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r = adev->ip_blocks[i].version->funcs->suspend(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (r) {
 | 
				
			||||||
 | 
								dev_err(adev->dev,
 | 
				
			||||||
 | 
									"suspend of IP block <%s> failed %d\n",
 | 
				
			||||||
 | 
									adev->ip_blocks[i].version->funcs->name, r);
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							adev->ip_blocks[i].status.hw = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					sienna_cichlid_mode2_prepare_hwcontext(struct amdgpu_reset_control *reset_ctl,
 | 
				
			||||||
 | 
									  struct amdgpu_reset_context *reset_context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r = 0;
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
							if (adev->gfxhub.funcs->mode2_save_regs)
 | 
				
			||||||
 | 
								adev->gfxhub.funcs->mode2_save_regs(adev);
 | 
				
			||||||
 | 
							if (adev->gfxhub.funcs->halt)
 | 
				
			||||||
 | 
								adev->gfxhub.funcs->halt(adev);
 | 
				
			||||||
 | 
							r = sienna_cichlid_mode2_suspend_ip(adev);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sienna_cichlid_async_reset(struct work_struct *work)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_reset_handler *handler;
 | 
				
			||||||
 | 
						struct amdgpu_reset_control *reset_ctl =
 | 
				
			||||||
 | 
							container_of(work, struct amdgpu_reset_control, reset_work);
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(handler, &reset_ctl->reset_handlers,
 | 
				
			||||||
 | 
								     handler_list) {
 | 
				
			||||||
 | 
							if (handler->reset_method == reset_ctl->active_reset) {
 | 
				
			||||||
 | 
								dev_dbg(adev->dev, "Resetting device\n");
 | 
				
			||||||
 | 
								handler->do_reset(adev);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sienna_cichlid_mode2_reset(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* disable BM */
 | 
				
			||||||
 | 
						pci_clear_master(adev->pdev);
 | 
				
			||||||
 | 
						return amdgpu_dpm_mode2_reset(adev);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					sienna_cichlid_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
 | 
				
			||||||
 | 
								      struct amdgpu_reset_context *reset_context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = sienna_cichlid_mode2_reset(adev);
 | 
				
			||||||
 | 
						if (r) {
 | 
				
			||||||
 | 
							dev_err(adev->dev,
 | 
				
			||||||
 | 
								"ASIC reset failed with error, %d ", r);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sienna_cichlid_mode2_restore_ip(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i, r;
 | 
				
			||||||
 | 
						struct psp_context *psp = &adev->psp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = psp_rlc_autoload_start(psp);
 | 
				
			||||||
 | 
						if (r) {
 | 
				
			||||||
 | 
							dev_err(adev->dev, "Failed to start rlc autoload\n");
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Reinit GFXHUB */
 | 
				
			||||||
 | 
						if (adev->gfxhub.funcs->mode2_restore_regs)
 | 
				
			||||||
 | 
							adev->gfxhub.funcs->mode2_restore_regs(adev);
 | 
				
			||||||
 | 
						adev->gfxhub.funcs->init(adev);
 | 
				
			||||||
 | 
						r = adev->gfxhub.funcs->gart_enable(adev);
 | 
				
			||||||
 | 
						if (r) {
 | 
				
			||||||
 | 
							dev_err(adev->dev, "GFXHUB gart reenable failed after reset\n");
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < adev->num_ip_blocks; i++) {
 | 
				
			||||||
 | 
							if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
 | 
				
			||||||
 | 
								r = adev->ip_blocks[i].version->funcs->resume(adev);
 | 
				
			||||||
 | 
								if (r) {
 | 
				
			||||||
 | 
									dev_err(adev->dev,
 | 
				
			||||||
 | 
										"resume of IP block <%s> failed %d\n",
 | 
				
			||||||
 | 
										adev->ip_blocks[i].version->funcs->name, r);
 | 
				
			||||||
 | 
									return r;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								adev->ip_blocks[i].status.hw = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < adev->num_ip_blocks; i++) {
 | 
				
			||||||
 | 
							if (!(adev->ip_blocks[i].version->type ==
 | 
				
			||||||
 | 
								      AMD_IP_BLOCK_TYPE_GFX ||
 | 
				
			||||||
 | 
							      adev->ip_blocks[i].version->type ==
 | 
				
			||||||
 | 
								      AMD_IP_BLOCK_TYPE_SDMA))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							r = adev->ip_blocks[i].version->funcs->resume(adev);
 | 
				
			||||||
 | 
							if (r) {
 | 
				
			||||||
 | 
								dev_err(adev->dev,
 | 
				
			||||||
 | 
									"resume of IP block <%s> failed %d\n",
 | 
				
			||||||
 | 
									adev->ip_blocks[i].version->funcs->name, r);
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->ip_blocks[i].status.hw = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < adev->num_ip_blocks; i++) {
 | 
				
			||||||
 | 
							if (!(adev->ip_blocks[i].version->type ==
 | 
				
			||||||
 | 
								      AMD_IP_BLOCK_TYPE_GFX ||
 | 
				
			||||||
 | 
							      adev->ip_blocks[i].version->type ==
 | 
				
			||||||
 | 
								      AMD_IP_BLOCK_TYPE_SDMA))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (adev->ip_blocks[i].version->funcs->late_init) {
 | 
				
			||||||
 | 
								r = adev->ip_blocks[i].version->funcs->late_init(
 | 
				
			||||||
 | 
									(void *)adev);
 | 
				
			||||||
 | 
								if (r) {
 | 
				
			||||||
 | 
									dev_err(adev->dev,
 | 
				
			||||||
 | 
										"late_init of IP block <%s> failed %d after reset\n",
 | 
				
			||||||
 | 
										adev->ip_blocks[i].version->funcs->name,
 | 
				
			||||||
 | 
										r);
 | 
				
			||||||
 | 
									return r;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							adev->ip_blocks[i].status.late_initialized = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
 | 
				
			||||||
 | 
						amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					sienna_cichlid_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,
 | 
				
			||||||
 | 
									  struct amdgpu_reset_context *reset_context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
						struct amdgpu_device *tmp_adev = (struct amdgpu_device *)reset_ctl->handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev_info(tmp_adev->dev,
 | 
				
			||||||
 | 
								"GPU reset succeeded, trying to resume\n");
 | 
				
			||||||
 | 
						r = sienna_cichlid_mode2_restore_ip(tmp_adev);
 | 
				
			||||||
 | 
						if (r)
 | 
				
			||||||
 | 
							goto end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						* Add this ASIC as tracked as reset was already
 | 
				
			||||||
 | 
						* complete successfully.
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
						amdgpu_register_gpu_instance(tmp_adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Resume RAS */
 | 
				
			||||||
 | 
						amdgpu_ras_resume(tmp_adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						amdgpu_irq_gpu_reset_resume_helper(tmp_adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r = amdgpu_ib_ring_tests(tmp_adev);
 | 
				
			||||||
 | 
						if (r) {
 | 
				
			||||||
 | 
							dev_err(tmp_adev->dev,
 | 
				
			||||||
 | 
								"ib ring test failed (%d).\n", r);
 | 
				
			||||||
 | 
							r = -EAGAIN;
 | 
				
			||||||
 | 
							goto end;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end:
 | 
				
			||||||
 | 
						if (r)
 | 
				
			||||||
 | 
							return -EAGAIN;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct amdgpu_reset_handler sienna_cichlid_mode2_handler = {
 | 
				
			||||||
 | 
						.reset_method		= AMD_RESET_METHOD_MODE2,
 | 
				
			||||||
 | 
						.prepare_env		= NULL,
 | 
				
			||||||
 | 
						.prepare_hwcontext	= sienna_cichlid_mode2_prepare_hwcontext,
 | 
				
			||||||
 | 
						.perform_reset		= sienna_cichlid_mode2_perform_reset,
 | 
				
			||||||
 | 
						.restore_hwcontext	= sienna_cichlid_mode2_restore_hwcontext,
 | 
				
			||||||
 | 
						.restore_env		= NULL,
 | 
				
			||||||
 | 
						.do_reset		= sienna_cichlid_mode2_reset,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sienna_cichlid_reset_init(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_reset_control *reset_ctl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reset_ctl = kzalloc(sizeof(*reset_ctl), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!reset_ctl)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reset_ctl->handle = adev;
 | 
				
			||||||
 | 
						reset_ctl->async_reset = sienna_cichlid_async_reset;
 | 
				
			||||||
 | 
						reset_ctl->active_reset = AMD_RESET_METHOD_NONE;
 | 
				
			||||||
 | 
						reset_ctl->get_reset_handler = sienna_cichlid_get_reset_handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&reset_ctl->reset_handlers);
 | 
				
			||||||
 | 
						INIT_WORK(&reset_ctl->reset_work, reset_ctl->async_reset);
 | 
				
			||||||
 | 
						/* Only mode2 is handled through reset control now */
 | 
				
			||||||
 | 
						amdgpu_reset_add_handler(reset_ctl, &sienna_cichlid_mode2_handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						adev->reset_cntl = reset_ctl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sienna_cichlid_reset_fini(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						kfree(adev->reset_cntl);
 | 
				
			||||||
 | 
						adev->reset_cntl = NULL;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2015 Advanced Micro Devices, Inc.
 | 
					 * Copyright 2021 Advanced Micro Devices, Inc.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 * copy of this software and associated documentation files (the "Software"),
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
| 
						 | 
					@ -19,16 +19,14 @@
 | 
				
			||||||
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
					 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
				
			||||||
 * OTHER DEALINGS IN THE SOFTWARE.
 | 
					 * OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Authors: AMD
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef DML_WRAPPER_H_
 | 
					#ifndef __SIENNA_CICHLID_H__
 | 
				
			||||||
#define DML_WRAPPER_H_
 | 
					#define __SIENNA_CICHLID_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dc.h"
 | 
					#include "amdgpu.h"
 | 
				
			||||||
#include "dml/display_mode_vba.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool dml_validate(struct dc *dc, struct dc_state *context, bool fast_validate);
 | 
					int sienna_cichlid_reset_init(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					int sienna_cichlid_reset_fini(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -179,7 +179,7 @@ void soc21_grbm_select(struct amdgpu_device *adev,
 | 
				
			||||||
	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
 | 
						grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
 | 
				
			||||||
	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
 | 
						grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WREG32(SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_CNTL), grbm_gfx_cntl);
 | 
						WREG32_SOC15(GC, 0, regGRBM_GFX_CNTL, grbm_gfx_cntl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void soc21_vga_set_state(struct amdgpu_device *adev, bool state)
 | 
					static void soc21_vga_set_state(struct amdgpu_device *adev, bool state)
 | 
				
			||||||
| 
						 | 
					@ -494,6 +494,20 @@ static void soc21_pre_asic_init(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int soc21_update_umd_stable_pstate(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										  bool enter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (enter)
 | 
				
			||||||
 | 
							amdgpu_gfx_rlc_enter_safe_mode(adev);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							amdgpu_gfx_rlc_exit_safe_mode(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->gfx.funcs->update_perfmon_mgcg)
 | 
				
			||||||
 | 
							adev->gfx.funcs->update_perfmon_mgcg(adev, !enter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct amdgpu_asic_funcs soc21_asic_funcs =
 | 
					static const struct amdgpu_asic_funcs soc21_asic_funcs =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	.read_disabled_bios = &soc21_read_disabled_bios,
 | 
						.read_disabled_bios = &soc21_read_disabled_bios,
 | 
				
			||||||
| 
						 | 
					@ -513,6 +527,7 @@ static const struct amdgpu_asic_funcs soc21_asic_funcs =
 | 
				
			||||||
	.supports_baco = &amdgpu_dpm_is_baco_supported,
 | 
						.supports_baco = &amdgpu_dpm_is_baco_supported,
 | 
				
			||||||
	.pre_asic_init = &soc21_pre_asic_init,
 | 
						.pre_asic_init = &soc21_pre_asic_init,
 | 
				
			||||||
	.query_video_codecs = &soc21_query_video_codecs,
 | 
						.query_video_codecs = &soc21_query_video_codecs,
 | 
				
			||||||
 | 
						.update_umd_stable_pstate = &soc21_update_umd_stable_pstate,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int soc21_common_early_init(void *handle)
 | 
					static int soc21_common_early_init(void *handle)
 | 
				
			||||||
| 
						 | 
					@ -567,6 +582,10 @@ static int soc21_common_early_init(void *handle)
 | 
				
			||||||
			AMD_PG_SUPPORT_JPEG |
 | 
								AMD_PG_SUPPORT_JPEG |
 | 
				
			||||||
			AMD_PG_SUPPORT_ATHUB |
 | 
								AMD_PG_SUPPORT_ATHUB |
 | 
				
			||||||
			AMD_PG_SUPPORT_MMHUB;
 | 
								AMD_PG_SUPPORT_MMHUB;
 | 
				
			||||||
 | 
							if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
								adev->cg_flags = 0;
 | 
				
			||||||
 | 
								adev->pg_flags = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
 | 
							adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
| 
						 | 
					@ -603,6 +622,8 @@ static int soc21_common_early_init(void *handle)
 | 
				
			||||||
			AMD_CG_SUPPORT_ATHUB_MGCG |
 | 
								AMD_CG_SUPPORT_ATHUB_MGCG |
 | 
				
			||||||
			AMD_CG_SUPPORT_ATHUB_LS |
 | 
								AMD_CG_SUPPORT_ATHUB_LS |
 | 
				
			||||||
			AMD_CG_SUPPORT_IH_CG |
 | 
								AMD_CG_SUPPORT_IH_CG |
 | 
				
			||||||
 | 
								AMD_CG_SUPPORT_BIF_MGCG |
 | 
				
			||||||
 | 
								AMD_CG_SUPPORT_BIF_LS |
 | 
				
			||||||
			AMD_CG_SUPPORT_VCN_MGCG |
 | 
								AMD_CG_SUPPORT_VCN_MGCG |
 | 
				
			||||||
			AMD_CG_SUPPORT_JPEG_MGCG;
 | 
								AMD_CG_SUPPORT_JPEG_MGCG;
 | 
				
			||||||
		adev->pg_flags =
 | 
							adev->pg_flags =
 | 
				
			||||||
| 
						 | 
					@ -610,6 +631,19 @@ static int soc21_common_early_init(void *handle)
 | 
				
			||||||
			AMD_PG_SUPPORT_JPEG;
 | 
								AMD_PG_SUPPORT_JPEG;
 | 
				
			||||||
		adev->external_rev_id = adev->rev_id + 0x1;
 | 
							adev->external_rev_id = adev->rev_id + 0x1;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
 | 
							adev->cg_flags = AMD_CG_SUPPORT_VCN_MGCG |
 | 
				
			||||||
 | 
								AMD_CG_SUPPORT_JPEG_MGCG;
 | 
				
			||||||
 | 
							adev->pg_flags = AMD_PG_SUPPORT_VCN |
 | 
				
			||||||
 | 
								AMD_PG_SUPPORT_VCN_DPG |
 | 
				
			||||||
 | 
								AMD_PG_SUPPORT_JPEG;
 | 
				
			||||||
 | 
							if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
								/* hypervisor control CG and PG enablement */
 | 
				
			||||||
 | 
								adev->cg_flags = 0;
 | 
				
			||||||
 | 
								adev->pg_flags = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							adev->external_rev_id = adev->rev_id + 0x20;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		/* FIXME: not supported yet */
 | 
							/* FIXME: not supported yet */
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -702,6 +736,7 @@ static int soc21_common_set_clockgating_state(void *handle,
 | 
				
			||||||
	switch (adev->ip_versions[NBIO_HWIP][0]) {
 | 
						switch (adev->ip_versions[NBIO_HWIP][0]) {
 | 
				
			||||||
	case IP_VERSION(4, 3, 0):
 | 
						case IP_VERSION(4, 3, 0):
 | 
				
			||||||
	case IP_VERSION(4, 3, 1):
 | 
						case IP_VERSION(4, 3, 1):
 | 
				
			||||||
 | 
						case IP_VERSION(7, 7, 0):
 | 
				
			||||||
		adev->nbio.funcs->update_medium_grain_clock_gating(adev,
 | 
							adev->nbio.funcs->update_medium_grain_clock_gating(adev,
 | 
				
			||||||
				state == AMD_CG_STATE_GATE);
 | 
									state == AMD_CG_STATE_GATE);
 | 
				
			||||||
		adev->nbio.funcs->update_medium_grain_light_sleep(adev,
 | 
							adev->nbio.funcs->update_medium_grain_light_sleep(adev,
 | 
				
			||||||
| 
						 | 
					@ -709,10 +744,6 @@ static int soc21_common_set_clockgating_state(void *handle,
 | 
				
			||||||
		adev->hdp.funcs->update_clock_gating(adev,
 | 
							adev->hdp.funcs->update_clock_gating(adev,
 | 
				
			||||||
				state == AMD_CG_STATE_GATE);
 | 
									state == AMD_CG_STATE_GATE);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IP_VERSION(7, 7, 0):
 | 
					 | 
				
			||||||
		adev->hdp.funcs->update_clock_gating(adev,
 | 
					 | 
				
			||||||
				state == AMD_CG_STATE_GATE);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@
 | 
				
			||||||
#include "soc15d.h"
 | 
					#include "soc15d.h"
 | 
				
			||||||
#include "soc15_hw_ip.h"
 | 
					#include "soc15_hw_ip.h"
 | 
				
			||||||
#include "vcn_v2_0.h"
 | 
					#include "vcn_v2_0.h"
 | 
				
			||||||
 | 
					#include "mmsch_v4_0.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "vcn/vcn_4_0_0_offset.h"
 | 
					#include "vcn/vcn_4_0_0_offset.h"
 | 
				
			||||||
#include "vcn/vcn_4_0_0_sh_mask.h"
 | 
					#include "vcn/vcn_4_0_0_sh_mask.h"
 | 
				
			||||||
| 
						 | 
					@ -45,6 +46,8 @@
 | 
				
			||||||
#define VCN_VID_SOC_ADDRESS_2_0							0x1fb00
 | 
					#define VCN_VID_SOC_ADDRESS_2_0							0x1fb00
 | 
				
			||||||
#define VCN1_VID_SOC_ADDRESS_3_0						0x48300
 | 
					#define VCN1_VID_SOC_ADDRESS_3_0						0x48300
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VCN_HARVEST_MMSCH								0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RDECODE_MSG_CREATE							0x00000000
 | 
					#define RDECODE_MSG_CREATE							0x00000000
 | 
				
			||||||
#define RDECODE_MESSAGE_CREATE							0x00000001
 | 
					#define RDECODE_MESSAGE_CREATE							0x00000001
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,12 +56,14 @@ static int amdgpu_ih_clientid_vcns[] = {
 | 
				
			||||||
	SOC15_IH_CLIENTID_VCN1
 | 
						SOC15_IH_CLIENTID_VCN1
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int vcn_v4_0_start_sriov(struct amdgpu_device *adev);
 | 
				
			||||||
static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev);
 | 
					static void vcn_v4_0_set_unified_ring_funcs(struct amdgpu_device *adev);
 | 
				
			||||||
static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev);
 | 
					static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev);
 | 
				
			||||||
static int vcn_v4_0_set_powergating_state(void *handle,
 | 
					static int vcn_v4_0_set_powergating_state(void *handle,
 | 
				
			||||||
        enum amd_powergating_state state);
 | 
					        enum amd_powergating_state state);
 | 
				
			||||||
static int vcn_v4_0_pause_dpg_mode(struct amdgpu_device *adev,
 | 
					static int vcn_v4_0_pause_dpg_mode(struct amdgpu_device *adev,
 | 
				
			||||||
        int inst_idx, struct dpg_pause_state *new_state);
 | 
					        int inst_idx, struct dpg_pause_state *new_state);
 | 
				
			||||||
 | 
					static void vcn_v4_0_unified_ring_set_wptr(struct amdgpu_ring *ring);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * vcn_v4_0_early_init - set function pointers
 | 
					 * vcn_v4_0_early_init - set function pointers
 | 
				
			||||||
| 
						 | 
					@ -71,6 +76,9 @@ static int vcn_v4_0_early_init(void *handle)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
							adev->vcn.harvest_config = VCN_HARVEST_MMSCH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* re-use enc ring as unified ring */
 | 
						/* re-use enc ring as unified ring */
 | 
				
			||||||
	adev->vcn.num_enc_rings = 1;
 | 
						adev->vcn.num_enc_rings = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,6 +100,7 @@ static int vcn_v4_0_sw_init(void *handle)
 | 
				
			||||||
	struct amdgpu_ring *ring;
 | 
						struct amdgpu_ring *ring;
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
	int i, r;
 | 
						int i, r;
 | 
				
			||||||
 | 
						int vcn_doorbell_index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r = amdgpu_vcn_sw_init(adev);
 | 
						r = amdgpu_vcn_sw_init(adev);
 | 
				
			||||||
	if (r)
 | 
						if (r)
 | 
				
			||||||
| 
						 | 
					@ -103,6 +112,12 @@ static int vcn_v4_0_sw_init(void *handle)
 | 
				
			||||||
	if (r)
 | 
						if (r)
 | 
				
			||||||
		return r;
 | 
							return r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
							vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 - MMSCH_DOORBELL_OFFSET;
 | 
				
			||||||
 | 
							/* get DWORD offset */
 | 
				
			||||||
 | 
							vcn_doorbell_index = vcn_doorbell_index << 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 | 
						for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 | 
				
			||||||
		volatile struct amdgpu_vcn4_fw_shared *fw_shared;
 | 
							volatile struct amdgpu_vcn4_fw_shared *fw_shared;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,7 +134,10 @@ static int vcn_v4_0_sw_init(void *handle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ring = &adev->vcn.inst[i].ring_enc[0];
 | 
							ring = &adev->vcn.inst[i].ring_enc[0];
 | 
				
			||||||
		ring->use_doorbell = true;
 | 
							ring->use_doorbell = true;
 | 
				
			||||||
		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
 | 
							if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
								ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sprintf(ring->name, "vcn_unified_%d", i);
 | 
							sprintf(ring->name, "vcn_unified_%d", i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,10 +150,19 @@ static int vcn_v4_0_sw_init(void *handle)
 | 
				
			||||||
		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
 | 
							fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
 | 
				
			||||||
		fw_shared->sq.is_enabled = 1;
 | 
							fw_shared->sq.is_enabled = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
								fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (amdgpu_vcnfw_log)
 | 
							if (amdgpu_vcnfw_log)
 | 
				
			||||||
			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
 | 
								amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
							r = amdgpu_virt_alloc_mm_table(adev);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
 | 
						if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
 | 
				
			||||||
		adev->vcn.pause_dpg_mode = vcn_v4_0_pause_dpg_mode;
 | 
							adev->vcn.pause_dpg_mode = vcn_v4_0_pause_dpg_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,6 +196,9 @@ static int vcn_v4_0_sw_fini(void *handle)
 | 
				
			||||||
		drm_dev_exit(idx);
 | 
							drm_dev_exit(idx);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev))
 | 
				
			||||||
 | 
							amdgpu_virt_free_mm_table(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r = amdgpu_vcn_suspend(adev);
 | 
						r = amdgpu_vcn_suspend(adev);
 | 
				
			||||||
	if (r)
 | 
						if (r)
 | 
				
			||||||
		return r;
 | 
							return r;
 | 
				
			||||||
| 
						 | 
					@ -191,18 +221,42 @@ static int vcn_v4_0_hw_init(void *handle)
 | 
				
			||||||
	struct amdgpu_ring *ring;
 | 
						struct amdgpu_ring *ring;
 | 
				
			||||||
	int i, r;
 | 
						int i, r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 | 
						if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
		if (adev->vcn.harvest_config & (1 << i))
 | 
							r = vcn_v4_0_start_sriov(adev);
 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ring = &adev->vcn.inst[i].ring_enc[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 | 
					 | 
				
			||||||
				((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		r = amdgpu_ring_test_helper(ring);
 | 
					 | 
				
			||||||
		if (r)
 | 
							if (r)
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 | 
				
			||||||
 | 
								if (adev->vcn.harvest_config & (1 << i))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ring = &adev->vcn.inst[i].ring_enc[0];
 | 
				
			||||||
 | 
								if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
 | 
				
			||||||
 | 
									ring->sched.ready = false;
 | 
				
			||||||
 | 
									ring->no_scheduler = true;
 | 
				
			||||||
 | 
									dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									ring->wptr = 0;
 | 
				
			||||||
 | 
									ring->wptr_old = 0;
 | 
				
			||||||
 | 
									vcn_v4_0_unified_ring_set_wptr(ring);
 | 
				
			||||||
 | 
									ring->sched.ready = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 | 
				
			||||||
 | 
								if (adev->vcn.harvest_config & (1 << i))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ring = &adev->vcn.inst[i].ring_enc[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 | 
				
			||||||
 | 
										((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i), i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								r = amdgpu_ring_test_helper(ring);
 | 
				
			||||||
 | 
								if (r)
 | 
				
			||||||
 | 
									goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
| 
						 | 
					@ -230,12 +284,14 @@ static int vcn_v4_0_hw_fini(void *handle)
 | 
				
			||||||
	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 | 
						for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 | 
				
			||||||
		if (adev->vcn.harvest_config & (1 << i))
 | 
							if (adev->vcn.harvest_config & (1 << i))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
							if (!amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
		if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
 | 
								if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
 | 
				
			||||||
                        (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
 | 
					                        (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
 | 
				
			||||||
                                RREG32_SOC15(VCN, i, regUVD_STATUS))) {
 | 
					                                RREG32_SOC15(VCN, i, regUVD_STATUS))) {
 | 
				
			||||||
                        vcn_v4_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
 | 
					                        vcn_v4_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -1107,6 +1163,214 @@ static int vcn_v4_0_start(struct amdgpu_device *adev)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int vcn_v4_0_start_sriov(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						struct amdgpu_ring *ring_enc;
 | 
				
			||||||
 | 
						uint64_t cache_addr;
 | 
				
			||||||
 | 
						uint64_t rb_enc_addr;
 | 
				
			||||||
 | 
						uint64_t ctx_addr;
 | 
				
			||||||
 | 
						uint32_t param, resp, expected;
 | 
				
			||||||
 | 
						uint32_t offset, cache_size;
 | 
				
			||||||
 | 
						uint32_t tmp, timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct amdgpu_mm_table *table = &adev->virt.mm_table;
 | 
				
			||||||
 | 
						uint32_t *table_loc;
 | 
				
			||||||
 | 
						uint32_t table_size;
 | 
				
			||||||
 | 
						uint32_t size, size_dw;
 | 
				
			||||||
 | 
						uint32_t init_status;
 | 
				
			||||||
 | 
						uint32_t enabled_vcn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_direct_write
 | 
				
			||||||
 | 
							direct_wt = { {0} };
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_direct_read_modify_write
 | 
				
			||||||
 | 
							direct_rd_mod_wt = { {0} };
 | 
				
			||||||
 | 
						struct mmsch_v4_0_cmd_end end = { {0} };
 | 
				
			||||||
 | 
						struct mmsch_v4_0_init_header header;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						volatile struct amdgpu_vcn4_fw_shared *fw_shared;
 | 
				
			||||||
 | 
						volatile struct amdgpu_fw_shared_rb_setup *rb_setup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						direct_wt.cmd_header.command_type =
 | 
				
			||||||
 | 
							MMSCH_COMMAND__DIRECT_REG_WRITE;
 | 
				
			||||||
 | 
						direct_rd_mod_wt.cmd_header.command_type =
 | 
				
			||||||
 | 
							MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
 | 
				
			||||||
 | 
						end.cmd_header.command_type =
 | 
				
			||||||
 | 
							MMSCH_COMMAND__END;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header.version = MMSCH_VERSION;
 | 
				
			||||||
 | 
						header.total_size = sizeof(struct mmsch_v4_0_init_header) >> 2;
 | 
				
			||||||
 | 
						for (i = 0; i < AMDGPU_MAX_VCN_INSTANCES; i++) {
 | 
				
			||||||
 | 
							header.inst[i].init_status = 0;
 | 
				
			||||||
 | 
							header.inst[i].table_offset = 0;
 | 
				
			||||||
 | 
							header.inst[i].table_size = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						table_loc = (uint32_t *)table->cpu_addr;
 | 
				
			||||||
 | 
						table_loc += header.total_size;
 | 
				
			||||||
 | 
						for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 | 
				
			||||||
 | 
							if (adev->vcn.harvest_config & (1 << i))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							table_size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_STATUS),
 | 
				
			||||||
 | 
								~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
 | 
				
			||||||
 | 
								MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
									regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
 | 
				
			||||||
 | 
									adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
 | 
				
			||||||
 | 
								MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
									regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
 | 
				
			||||||
 | 
									adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
 | 
				
			||||||
 | 
								offset = 0;
 | 
				
			||||||
 | 
								MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
									regUVD_VCPU_CACHE_OFFSET0),
 | 
				
			||||||
 | 
									0);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
									regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
 | 
				
			||||||
 | 
									lower_32_bits(adev->vcn.inst[i].gpu_addr));
 | 
				
			||||||
 | 
								MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
									regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
 | 
				
			||||||
 | 
									upper_32_bits(adev->vcn.inst[i].gpu_addr));
 | 
				
			||||||
 | 
								offset = cache_size;
 | 
				
			||||||
 | 
								MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
									regUVD_VCPU_CACHE_OFFSET0),
 | 
				
			||||||
 | 
									AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_VCPU_CACHE_SIZE0),
 | 
				
			||||||
 | 
								cache_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cache_addr = adev->vcn.inst[i].gpu_addr + offset;
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
 | 
				
			||||||
 | 
								lower_32_bits(cache_addr));
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
 | 
				
			||||||
 | 
								upper_32_bits(cache_addr));
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_VCPU_CACHE_OFFSET1),
 | 
				
			||||||
 | 
								0);
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_VCPU_CACHE_SIZE1),
 | 
				
			||||||
 | 
								AMDGPU_VCN_STACK_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cache_addr = adev->vcn.inst[i].gpu_addr + offset +
 | 
				
			||||||
 | 
								AMDGPU_VCN_STACK_SIZE;
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
 | 
				
			||||||
 | 
								lower_32_bits(cache_addr));
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
 | 
				
			||||||
 | 
								upper_32_bits(cache_addr));
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_VCPU_CACHE_OFFSET2),
 | 
				
			||||||
 | 
								0);
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_VCPU_CACHE_SIZE2),
 | 
				
			||||||
 | 
								AMDGPU_VCN_CONTEXT_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
 | 
				
			||||||
 | 
							rb_setup = &fw_shared->rb_setup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ring_enc = &adev->vcn.inst[i].ring_enc[0];
 | 
				
			||||||
 | 
							ring_enc->wptr = 0;
 | 
				
			||||||
 | 
							rb_enc_addr = ring_enc->gpu_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rb_setup->is_rb_enabled_flags |= RB_ENABLED;
 | 
				
			||||||
 | 
							rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr);
 | 
				
			||||||
 | 
							rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr);
 | 
				
			||||||
 | 
							rb_setup->rb_size = ring_enc->ring_size / 4;
 | 
				
			||||||
 | 
							fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
 | 
				
			||||||
 | 
								lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
 | 
				
			||||||
 | 
								upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i,
 | 
				
			||||||
 | 
								regUVD_VCPU_NONCACHE_SIZE0),
 | 
				
			||||||
 | 
								AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* add end packet */
 | 
				
			||||||
 | 
							MMSCH_V4_0_INSERT_END();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* refine header */
 | 
				
			||||||
 | 
							header.inst[i].init_status = 0;
 | 
				
			||||||
 | 
							header.inst[i].table_offset = header.total_size;
 | 
				
			||||||
 | 
							header.inst[i].table_size = table_size;
 | 
				
			||||||
 | 
							header.total_size += table_size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Update init table header in memory */
 | 
				
			||||||
 | 
						size = sizeof(struct mmsch_v4_0_init_header);
 | 
				
			||||||
 | 
						table_loc = (uint32_t *)table->cpu_addr;
 | 
				
			||||||
 | 
						memcpy((void *)table_loc, &header, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* message MMSCH (in VCN[0]) to initialize this client
 | 
				
			||||||
 | 
						 * 1, write to mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
 | 
				
			||||||
 | 
						 * of memory descriptor location
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ctx_addr = table->gpu_addr;
 | 
				
			||||||
 | 
						WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
 | 
				
			||||||
 | 
						WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 2, update vmid of descriptor */
 | 
				
			||||||
 | 
						tmp = RREG32_SOC15(VCN, 0, regMMSCH_VF_VMID);
 | 
				
			||||||
 | 
						tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
 | 
				
			||||||
 | 
						/* use domain0 for MM scheduler */
 | 
				
			||||||
 | 
						tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
 | 
				
			||||||
 | 
						WREG32_SOC15(VCN, 0, regMMSCH_VF_VMID, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 3, notify mmsch about the size of this descriptor */
 | 
				
			||||||
 | 
						size = header.total_size;
 | 
				
			||||||
 | 
						WREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_SIZE, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 4, set resp to zero */
 | 
				
			||||||
 | 
						WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 5, kick off the initialization and wait until
 | 
				
			||||||
 | 
						 * MMSCH_VF_MAILBOX_RESP becomes non-zero
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						param = 0x00000001;
 | 
				
			||||||
 | 
						WREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_HOST, param);
 | 
				
			||||||
 | 
						tmp = 0;
 | 
				
			||||||
 | 
						timeout = 1000;
 | 
				
			||||||
 | 
						resp = 0;
 | 
				
			||||||
 | 
						expected = MMSCH_VF_MAILBOX_RESP__OK;
 | 
				
			||||||
 | 
						while (resp != expected) {
 | 
				
			||||||
 | 
							resp = RREG32_SOC15(VCN, 0, regMMSCH_VF_MAILBOX_RESP);
 | 
				
			||||||
 | 
							if (resp != 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							udelay(10);
 | 
				
			||||||
 | 
							tmp = tmp + 10;
 | 
				
			||||||
 | 
							if (tmp >= timeout) {
 | 
				
			||||||
 | 
								DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
 | 
				
			||||||
 | 
									" waiting for regMMSCH_VF_MAILBOX_RESP "\
 | 
				
			||||||
 | 
									"(expected=0x%08x, readback=0x%08x)\n",
 | 
				
			||||||
 | 
									tmp, expected, resp);
 | 
				
			||||||
 | 
								return -EBUSY;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0;
 | 
				
			||||||
 | 
						init_status = ((struct mmsch_v4_0_init_header *)(table_loc))->inst[enabled_vcn].init_status;
 | 
				
			||||||
 | 
						if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE
 | 
				
			||||||
 | 
						&& init_status != MMSCH_VF_ENGINE_STATUS__PASS)
 | 
				
			||||||
 | 
							DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\
 | 
				
			||||||
 | 
								"status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * vcn_v4_0_stop_dpg_mode - VCN stop with dpg mode
 | 
					 * vcn_v4_0_stop_dpg_mode - VCN stop with dpg mode
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -1596,6 +1860,15 @@ static int vcn_v4_0_set_powergating_state(void *handle, enum amd_powergating_sta
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* for SRIOV, guest should not control VCN Power-gating
 | 
				
			||||||
 | 
						 * MMSCH FW should control Power-gating and clock-gating
 | 
				
			||||||
 | 
						 * guest should avoid touching CGC and PG
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (amdgpu_sriov_vf(adev)) {
 | 
				
			||||||
 | 
							adev->vcn.cur_state = AMD_PG_STATE_UNGATE;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(state == adev->vcn.cur_state)
 | 
						if(state == adev->vcn.cur_state)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -327,6 +327,12 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 | 
				
			||||||
		goto err_bind_process;
 | 
							goto err_bind_process;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!pdd->doorbell_index &&
 | 
				
			||||||
 | 
						    kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
 | 
				
			||||||
 | 
							err = -ENOMEM;
 | 
				
			||||||
 | 
							goto err_alloc_doorbells;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
 | 
						/* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
 | 
				
			||||||
	 * on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
 | 
						 * on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					@ -404,6 +410,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 | 
				
			||||||
	if (wptr_bo)
 | 
						if (wptr_bo)
 | 
				
			||||||
		amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
 | 
							amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
 | 
				
			||||||
err_wptr_map_gart:
 | 
					err_wptr_map_gart:
 | 
				
			||||||
 | 
					err_alloc_doorbells:
 | 
				
			||||||
err_bind_process:
 | 
					err_bind_process:
 | 
				
			||||||
err_pdd:
 | 
					err_pdd:
 | 
				
			||||||
	mutex_unlock(&p->mutex);
 | 
						mutex_unlock(&p->mutex);
 | 
				
			||||||
| 
						 | 
					@ -869,14 +876,11 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p,
 | 
				
			||||||
				void *data)
 | 
									void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct kfd_ioctl_wait_events_args *args = data;
 | 
						struct kfd_ioctl_wait_events_args *args = data;
 | 
				
			||||||
	int err;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = kfd_wait_on_events(p, args->num_events,
 | 
						return kfd_wait_on_events(p, args->num_events,
 | 
				
			||||||
			(void __user *)args->events_ptr,
 | 
								(void __user *)args->events_ptr,
 | 
				
			||||||
			(args->wait_for_all != 0),
 | 
								(args->wait_for_all != 0),
 | 
				
			||||||
			&args->timeout, &args->wait_result);
 | 
								&args->timeout, &args->wait_result);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return err;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
 | 
					static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
 | 
				
			||||||
					struct kfd_process *p, void *data)
 | 
										struct kfd_process *p, void *data)
 | 
				
			||||||
| 
						 | 
					@ -1092,6 +1096,10 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
 | 
				
			||||||
			goto err_unlock;
 | 
								goto err_unlock;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		offset = kfd_get_process_doorbells(pdd);
 | 
							offset = kfd_get_process_doorbells(pdd);
 | 
				
			||||||
 | 
							if (!offset) {
 | 
				
			||||||
 | 
								err = -ENOMEM;
 | 
				
			||||||
 | 
								goto err_unlock;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
 | 
						} else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
 | 
				
			||||||
		if (args->size != PAGE_SIZE) {
 | 
							if (args->size != PAGE_SIZE) {
 | 
				
			||||||
			err = -EINVAL;
 | 
								err = -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -2173,6 +2181,8 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		offset = kfd_get_process_doorbells(pdd);
 | 
							offset = kfd_get_process_doorbells(pdd);
 | 
				
			||||||
 | 
							if (!offset)
 | 
				
			||||||
 | 
								return -ENOMEM;
 | 
				
			||||||
	} else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
 | 
						} else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
 | 
				
			||||||
		/* MMIO BOs need remapped bus address */
 | 
							/* MMIO BOs need remapped bus address */
 | 
				
			||||||
		if (bo_bucket->size != PAGE_SIZE) {
 | 
							if (bo_bucket->size != PAGE_SIZE) {
 | 
				
			||||||
| 
						 | 
					@ -2847,7 +2857,6 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process,
 | 
				
			||||||
		      struct vm_area_struct *vma)
 | 
							      struct vm_area_struct *vma)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	phys_addr_t address;
 | 
						phys_addr_t address;
 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (vma->vm_end - vma->vm_start != PAGE_SIZE)
 | 
						if (vma->vm_end - vma->vm_start != PAGE_SIZE)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -2867,12 +2876,11 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process,
 | 
				
			||||||
		 process->pasid, (unsigned long long) vma->vm_start,
 | 
							 process->pasid, (unsigned long long) vma->vm_start,
 | 
				
			||||||
		 address, vma->vm_flags, PAGE_SIZE);
 | 
							 address, vma->vm_flags, PAGE_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = io_remap_pfn_range(vma,
 | 
						return io_remap_pfn_range(vma,
 | 
				
			||||||
				vma->vm_start,
 | 
									vma->vm_start,
 | 
				
			||||||
				address >> PAGE_SHIFT,
 | 
									address >> PAGE_SHIFT,
 | 
				
			||||||
				PAGE_SIZE,
 | 
									PAGE_SIZE,
 | 
				
			||||||
				vma->vm_page_prot);
 | 
									vma->vm_page_prot);
 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1522,6 +1522,7 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
 | 
				
			||||||
		case IP_VERSION(11, 0, 0):
 | 
							case IP_VERSION(11, 0, 0):
 | 
				
			||||||
		case IP_VERSION(11, 0, 1):
 | 
							case IP_VERSION(11, 0, 1):
 | 
				
			||||||
		case IP_VERSION(11, 0, 2):
 | 
							case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
							case IP_VERSION(11, 0, 3):
 | 
				
			||||||
			pcache_info = cache_info;
 | 
								pcache_info = cache_info;
 | 
				
			||||||
			num_of_cache_types =
 | 
								num_of_cache_types =
 | 
				
			||||||
				kfd_fill_gpu_cache_info_from_gfx_config(kdev, pcache_info);
 | 
									kfd_fill_gpu_cache_info_from_gfx_config(kdev, pcache_info);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,7 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
 | 
				
			||||||
	case IP_VERSION(6, 0, 0):
 | 
						case IP_VERSION(6, 0, 0):
 | 
				
			||||||
	case IP_VERSION(6, 0, 1):
 | 
						case IP_VERSION(6, 0, 1):
 | 
				
			||||||
	case IP_VERSION(6, 0, 2):
 | 
						case IP_VERSION(6, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(6, 0, 3):
 | 
				
			||||||
		kfd->device_info.num_sdma_queues_per_engine = 8;
 | 
							kfd->device_info.num_sdma_queues_per_engine = 8;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -103,6 +104,7 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd)
 | 
				
			||||||
	switch (sdma_version) {
 | 
						switch (sdma_version) {
 | 
				
			||||||
	case IP_VERSION(6, 0, 0):
 | 
						case IP_VERSION(6, 0, 0):
 | 
				
			||||||
	case IP_VERSION(6, 0, 2):
 | 
						case IP_VERSION(6, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(6, 0, 3):
 | 
				
			||||||
		/* Reserve 1 for paging and 1 for gfx */
 | 
							/* Reserve 1 for paging and 1 for gfx */
 | 
				
			||||||
		kfd->device_info.num_reserved_sdma_queues_per_engine = 2;
 | 
							kfd->device_info.num_reserved_sdma_queues_per_engine = 2;
 | 
				
			||||||
		/* BIT(0)=engine-0 queue-0; BIT(1)=engine-1 queue-0; BIT(2)=engine-0 queue-1; ... */
 | 
							/* BIT(0)=engine-0 queue-0; BIT(1)=engine-1 queue-0; BIT(2)=engine-0 queue-1; ... */
 | 
				
			||||||
| 
						 | 
					@ -150,6 +152,7 @@ static void kfd_device_info_set_event_interrupt_class(struct kfd_dev *kfd)
 | 
				
			||||||
	case IP_VERSION(11, 0, 0):
 | 
						case IP_VERSION(11, 0, 0):
 | 
				
			||||||
	case IP_VERSION(11, 0, 1):
 | 
						case IP_VERSION(11, 0, 1):
 | 
				
			||||||
	case IP_VERSION(11, 0, 2):
 | 
						case IP_VERSION(11, 0, 2):
 | 
				
			||||||
 | 
						case IP_VERSION(11, 0, 3):
 | 
				
			||||||
		kfd->device_info.event_interrupt_class = &event_interrupt_class_v11;
 | 
							kfd->device_info.event_interrupt_class = &event_interrupt_class_v11;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -382,12 +385,8 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
 | 
				
			||||||
				f2g = &gfx_v10_3_kfd2kgd;
 | 
									f2g = &gfx_v10_3_kfd2kgd;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case IP_VERSION(10, 3, 6):
 | 
							case IP_VERSION(10, 3, 6):
 | 
				
			||||||
			gfx_target_version = 100306;
 | 
					 | 
				
			||||||
			if (!vf)
 | 
					 | 
				
			||||||
				f2g = &gfx_v10_3_kfd2kgd;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case IP_VERSION(10, 3, 7):
 | 
							case IP_VERSION(10, 3, 7):
 | 
				
			||||||
			gfx_target_version = 100307;
 | 
								gfx_target_version = 100306;
 | 
				
			||||||
			if (!vf)
 | 
								if (!vf)
 | 
				
			||||||
				f2g = &gfx_v10_3_kfd2kgd;
 | 
									f2g = &gfx_v10_3_kfd2kgd;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -403,6 +402,11 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
 | 
				
			||||||
			gfx_target_version = 110002;
 | 
								gfx_target_version = 110002;
 | 
				
			||||||
			f2g = &gfx_v11_kfd2kgd;
 | 
								f2g = &gfx_v11_kfd2kgd;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case IP_VERSION(11, 0, 3):
 | 
				
			||||||
 | 
								/* Note: Compiler version is 11.0.1 while HW version is 11.0.3 */
 | 
				
			||||||
 | 
								gfx_target_version = 110001;
 | 
				
			||||||
 | 
								f2g = &gfx_v11_kfd2kgd;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,6 +157,8 @@ int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Calculate physical address of doorbell */
 | 
						/* Calculate physical address of doorbell */
 | 
				
			||||||
	address = kfd_get_process_doorbells(pdd);
 | 
						address = kfd_get_process_doorbells(pdd);
 | 
				
			||||||
 | 
						if (!address)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
	vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
 | 
						vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
 | 
				
			||||||
				VM_DONTDUMP | VM_PFNMAP;
 | 
									VM_DONTDUMP | VM_PFNMAP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,6 +277,13 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
 | 
					phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (!pdd->doorbell_index) {
 | 
				
			||||||
 | 
							int r = kfd_alloc_process_doorbells(pdd->dev,
 | 
				
			||||||
 | 
											    &pdd->doorbell_index);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pdd->dev->doorbell_base +
 | 
						return pdd->dev->doorbell_base +
 | 
				
			||||||
		pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
 | 
							pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1499,11 +1499,6 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
 | 
				
			||||||
	if (!pdd)
 | 
						if (!pdd)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
 | 
					 | 
				
			||||||
		pr_err("Failed to alloc doorbell for pdd\n");
 | 
					 | 
				
			||||||
		goto err_free_pdd;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (init_doorbell_bitmap(&pdd->qpd, dev)) {
 | 
						if (init_doorbell_bitmap(&pdd->qpd, dev)) {
 | 
				
			||||||
		pr_err("Failed to init doorbell for process\n");
 | 
							pr_err("Failed to init doorbell for process\n");
 | 
				
			||||||
		goto err_free_pdd;
 | 
							goto err_free_pdd;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1530,7 +1530,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
 | 
						if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
 | 
				
			||||||
		adev->dm.dc->debug.disable_dsc = true;
 | 
							adev->dm.dc->debug.disable_dsc = true;
 | 
				
			||||||
		adev->dm.dc->debug.disable_dsc_edp = true;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING)
 | 
						if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING)
 | 
				
			||||||
| 
						 | 
					@ -5604,7 +5603,8 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
 | 
				
			||||||
	dc_dsc_policy_set_enable_dsc_when_not_needed(
 | 
						dc_dsc_policy_set_enable_dsc_when_not_needed(
 | 
				
			||||||
		aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
 | 
							aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP && !dc->debug.disable_dsc_edp &&
 | 
						if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP &&
 | 
				
			||||||
 | 
						    !aconnector->dc_link->panel_config.dsc.disable_dsc_edp &&
 | 
				
			||||||
	    dc->caps.edp_dsc_support && aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE) {
 | 
						    dc->caps.edp_dsc_support && aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		apply_dsc_policy_for_edp(aconnector, sink, stream, dsc_caps, max_dsc_target_bpp_limit_override);
 | 
							apply_dsc_policy_for_edp(aconnector, sink, stream, dsc_caps, max_dsc_target_bpp_limit_override);
 | 
				
			||||||
| 
						 | 
					@ -9304,6 +9304,7 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
 | 
					 * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * @dev: The DRM device
 | 
					 * @dev: The DRM device
 | 
				
			||||||
 * @state: The atomic state to commit
 | 
					 * @state: The atomic state to commit
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -9360,9 +9361,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 | 
				
			||||||
		struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 | 
							struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Skip connectors that are disabled or part of modeset already. */
 | 
							/* Skip connectors that are disabled or part of modeset already. */
 | 
				
			||||||
		if (!old_con_state->crtc && !new_con_state->crtc)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!new_con_state->crtc)
 | 
							if (!new_con_state->crtc)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9889,8 +9887,19 @@ static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector,
 | 
				
			||||||
	return valid_vsdb_found ? i : -ENODEV;
 | 
						return valid_vsdb_found ? i : -ENODEV;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_update_freesync_caps - Update Freesync capabilities
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @connector: Connector to query.
 | 
				
			||||||
 | 
					 * @edid: EDID from monitor
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Amdgpu supports Freesync in DP and HDMI displays, and it is required to keep
 | 
				
			||||||
 | 
					 * track of some of the display information in the internal data struct used by
 | 
				
			||||||
 | 
					 * amdgpu_dm. This function checks which type of connector we need to set the
 | 
				
			||||||
 | 
					 * FreeSync parameters.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 | 
					void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 | 
				
			||||||
					struct edid *edid)
 | 
									    struct edid *edid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i = 0;
 | 
						int i = 0;
 | 
				
			||||||
	struct detailed_timing *timing;
 | 
						struct detailed_timing *timing;
 | 
				
			||||||
| 
						 | 
					@ -9903,8 +9912,8 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct drm_device *dev = connector->dev;
 | 
						struct drm_device *dev = connector->dev;
 | 
				
			||||||
	struct amdgpu_device *adev = drm_to_adev(dev);
 | 
						struct amdgpu_device *adev = drm_to_adev(dev);
 | 
				
			||||||
	bool freesync_capable = false;
 | 
					 | 
				
			||||||
	struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
 | 
						struct amdgpu_hdmi_vsdb_info vsdb_info = {0};
 | 
				
			||||||
 | 
						bool freesync_capable = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!connector->state) {
 | 
						if (!connector->state) {
 | 
				
			||||||
		DRM_ERROR("%s - Connector has no state", __func__);
 | 
							DRM_ERROR("%s - Connector has no state", __func__);
 | 
				
			||||||
| 
						 | 
					@ -9933,7 +9942,6 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 | 
				
			||||||
	if (!adev->dm.freesync_module)
 | 
						if (!adev->dm.freesync_module)
 | 
				
			||||||
		goto update;
 | 
							goto update;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT
 | 
						if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT
 | 
				
			||||||
		|| sink->sink_signal == SIGNAL_TYPE_EDP) {
 | 
							|| sink->sink_signal == SIGNAL_TYPE_EDP) {
 | 
				
			||||||
		bool edid_check_required = false;
 | 
							bool edid_check_required = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -598,6 +598,10 @@ struct amdgpu_dm_connector {
 | 
				
			||||||
	 * The 'current' sink is in dc_link->sink. */
 | 
						 * The 'current' sink is in dc_link->sink. */
 | 
				
			||||||
	struct dc_sink *dc_sink;
 | 
						struct dc_sink *dc_sink;
 | 
				
			||||||
	struct dc_link *dc_link;
 | 
						struct dc_link *dc_link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @dc_em_sink: Reference to the emulated (virtual) sink.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	struct dc_sink *dc_em_sink;
 | 
						struct dc_sink *dc_em_sink;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* DM only */
 | 
						/* DM only */
 | 
				
			||||||
| 
						 | 
					@ -610,7 +614,16 @@ struct amdgpu_dm_connector {
 | 
				
			||||||
	struct amdgpu_i2c_adapter *i2c;
 | 
						struct amdgpu_i2c_adapter *i2c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Monitor range limits */
 | 
						/* Monitor range limits */
 | 
				
			||||||
	int min_vfreq ;
 | 
						/**
 | 
				
			||||||
 | 
						 * @min_vfreq: Minimal frequency supported by the display in Hz. This
 | 
				
			||||||
 | 
						 * value is set to zero when there is no FreeSync support.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						int min_vfreq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @max_vfreq: Maximum frequency supported by the display in Hz. This
 | 
				
			||||||
 | 
						 * value is set to zero when there is no FreeSync support.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	int max_vfreq ;
 | 
						int max_vfreq ;
 | 
				
			||||||
	int pixel_clock_mhz;
 | 
						int pixel_clock_mhz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -705,11 +718,34 @@ struct dm_connector_state {
 | 
				
			||||||
	uint64_t pbn;
 | 
						uint64_t pbn;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct amdgpu_hdmi_vsdb_info - Keep track of the VSDB info
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * AMDGPU supports FreeSync over HDMI by using the VSDB section, and this
 | 
				
			||||||
 | 
					 * struct is useful to keep track of the display-specific information about
 | 
				
			||||||
 | 
					 * FreeSync.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
struct amdgpu_hdmi_vsdb_info {
 | 
					struct amdgpu_hdmi_vsdb_info {
 | 
				
			||||||
	unsigned int amd_vsdb_version;		/* VSDB version, should be used to determine which VSIF to send */
 | 
						/**
 | 
				
			||||||
	bool freesync_supported;		/* FreeSync Supported */
 | 
						 * @amd_vsdb_version: Vendor Specific Data Block Version, should be
 | 
				
			||||||
	unsigned int min_refresh_rate_hz;	/* FreeSync Minimum Refresh Rate in Hz */
 | 
						 * used to determine which Vendor Specific InfoFrame (VSIF) to send.
 | 
				
			||||||
	unsigned int max_refresh_rate_hz;	/* FreeSync Maximum Refresh Rate in Hz */
 | 
						 */
 | 
				
			||||||
 | 
						unsigned int amd_vsdb_version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @freesync_supported: FreeSync Supported.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						bool freesync_supported;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @min_refresh_rate_hz: FreeSync Minimum Refresh Rate in Hz.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						unsigned int min_refresh_rate_hz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @max_refresh_rate_hz: FreeSync Maximum Refresh Rate in Hz
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						unsigned int max_refresh_rate_hz;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,9 @@
 | 
				
			||||||
#include "modules/color/color_gamma.h"
 | 
					#include "modules/color/color_gamma.h"
 | 
				
			||||||
#include "basics/conversion.h"
 | 
					#include "basics/conversion.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/**
 | 
				
			||||||
 | 
					 * DOC: overview
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * The DC interface to HW gives us the following color management blocks
 | 
					 * The DC interface to HW gives us the following color management blocks
 | 
				
			||||||
 * per pipe (surface):
 | 
					 * per pipe (surface):
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -71,8 +73,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_DRM_LUT_VALUE 0xFFFF
 | 
					#define MAX_DRM_LUT_VALUE 0xFFFF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/**
 | 
				
			||||||
 * Initialize the color module.
 | 
					 * amdgpu_dm_init_color_mod - Initialize the color module.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * We're not using the full color module, only certain components.
 | 
					 * We're not using the full color module, only certain components.
 | 
				
			||||||
 * Only call setup functions for components that we need.
 | 
					 * Only call setup functions for components that we need.
 | 
				
			||||||
| 
						 | 
					@ -82,7 +84,14 @@ void amdgpu_dm_init_color_mod(void)
 | 
				
			||||||
	setup_x_points_distribution();
 | 
						setup_x_points_distribution();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Extracts the DRM lut and lut size from a blob. */
 | 
					/**
 | 
				
			||||||
 | 
					 * __extract_blob_lut - Extracts the DRM lut and lut size from a blob.
 | 
				
			||||||
 | 
					 * @blob: DRM color mgmt property blob
 | 
				
			||||||
 | 
					 * @size: lut size
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * DRM LUT or NULL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static const struct drm_color_lut *
 | 
					static const struct drm_color_lut *
 | 
				
			||||||
__extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
 | 
					__extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -90,13 +99,18 @@ __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
 | 
				
			||||||
	return blob ? (struct drm_color_lut *)blob->data : NULL;
 | 
						return blob ? (struct drm_color_lut *)blob->data : NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/**
 | 
				
			||||||
 * Return true if the given lut is a linear mapping of values, i.e. it acts
 | 
					 * __is_lut_linear - check if the given lut is a linear mapping of values
 | 
				
			||||||
 * like a bypass LUT.
 | 
					 * @lut: given lut to check values
 | 
				
			||||||
 | 
					 * @size: lut size
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * It is considered linear if the lut represents:
 | 
					 * It is considered linear if the lut represents:
 | 
				
			||||||
 * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in
 | 
					 * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in [0,
 | 
				
			||||||
 *                                           [0, MAX_COLOR_LUT_ENTRIES)
 | 
					 * MAX_COLOR_LUT_ENTRIES)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * True if the given lut is a linear mapping of values, i.e. it acts like a
 | 
				
			||||||
 | 
					 * bypass LUT. Otherwise, false.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
 | 
					static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -119,9 +133,13 @@ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/**
 | 
				
			||||||
 * Convert the drm_color_lut to dc_gamma. The conversion depends on the size
 | 
					 * __drm_lut_to_dc_gamma - convert the drm_color_lut to dc_gamma.
 | 
				
			||||||
 * of the lut - whether or not it's legacy.
 | 
					 * @lut: DRM lookup table for color conversion
 | 
				
			||||||
 | 
					 * @gamma: DC gamma to set entries
 | 
				
			||||||
 | 
					 * @is_legacy: legacy or atomic gamma
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The conversion depends on the size of the lut - whether or not it's legacy.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
 | 
					static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
 | 
				
			||||||
				  struct dc_gamma *gamma, bool is_legacy)
 | 
									  struct dc_gamma *gamma, bool is_legacy)
 | 
				
			||||||
| 
						 | 
					@ -154,8 +172,11 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/**
 | 
				
			||||||
 * Converts a DRM CTM to a DC CSC float matrix.
 | 
					 * __drm_ctm_to_dc_matrix - converts a DRM CTM to a DC CSC float matrix
 | 
				
			||||||
 | 
					 * @ctm: DRM color transformation matrix
 | 
				
			||||||
 | 
					 * @matrix: DC CSC float matrix
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * The matrix needs to be a 3x4 (12 entry) matrix.
 | 
					 * The matrix needs to be a 3x4 (12 entry) matrix.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
 | 
					static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
 | 
				
			||||||
| 
						 | 
					@ -189,7 +210,18 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Calculates the legacy transfer function - only for sRGB input space. */
 | 
					/**
 | 
				
			||||||
 | 
					 * __set_legacy_tf - Calculates the legacy transfer function
 | 
				
			||||||
 | 
					 * @func: transfer function
 | 
				
			||||||
 | 
					 * @lut: lookup table that defines the color space
 | 
				
			||||||
 | 
					 * @lut_size: size of respective lut
 | 
				
			||||||
 | 
					 * @has_rom: if ROM can be used for hardcoded curve
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Only for sRGB input space
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * 0 in case of success, -ENOMEM if fails
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static int __set_legacy_tf(struct dc_transfer_func *func,
 | 
					static int __set_legacy_tf(struct dc_transfer_func *func,
 | 
				
			||||||
			   const struct drm_color_lut *lut, uint32_t lut_size,
 | 
								   const struct drm_color_lut *lut, uint32_t lut_size,
 | 
				
			||||||
			   bool has_rom)
 | 
								   bool has_rom)
 | 
				
			||||||
| 
						 | 
					@ -218,7 +250,16 @@ static int __set_legacy_tf(struct dc_transfer_func *func,
 | 
				
			||||||
	return res ? 0 : -ENOMEM;
 | 
						return res ? 0 : -ENOMEM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Calculates the output transfer function based on expected input space. */
 | 
					/**
 | 
				
			||||||
 | 
					 * __set_output_tf - calculates the output transfer function based on expected input space.
 | 
				
			||||||
 | 
					 * @func: transfer function
 | 
				
			||||||
 | 
					 * @lut: lookup table that defines the color space
 | 
				
			||||||
 | 
					 * @lut_size: size of respective lut
 | 
				
			||||||
 | 
					 * @has_rom: if ROM can be used for hardcoded curve
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * 0 in case of success. -ENOMEM if fails.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static int __set_output_tf(struct dc_transfer_func *func,
 | 
					static int __set_output_tf(struct dc_transfer_func *func,
 | 
				
			||||||
			   const struct drm_color_lut *lut, uint32_t lut_size,
 | 
								   const struct drm_color_lut *lut, uint32_t lut_size,
 | 
				
			||||||
			   bool has_rom)
 | 
								   bool has_rom)
 | 
				
			||||||
| 
						 | 
					@ -262,7 +303,16 @@ static int __set_output_tf(struct dc_transfer_func *func,
 | 
				
			||||||
	return res ? 0 : -ENOMEM;
 | 
						return res ? 0 : -ENOMEM;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Caculates the input transfer function based on expected input space. */
 | 
					/**
 | 
				
			||||||
 | 
					 * __set_input_tf - calculates the input transfer function based on expected
 | 
				
			||||||
 | 
					 * input space.
 | 
				
			||||||
 | 
					 * @func: transfer function
 | 
				
			||||||
 | 
					 * @lut: lookup table that defines the color space
 | 
				
			||||||
 | 
					 * @lut_size: size of respective lut.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * 0 in case of success. -ENOMEM if fails.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static int __set_input_tf(struct dc_transfer_func *func,
 | 
					static int __set_input_tf(struct dc_transfer_func *func,
 | 
				
			||||||
			  const struct drm_color_lut *lut, uint32_t lut_size)
 | 
								  const struct drm_color_lut *lut, uint32_t lut_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -285,13 +335,14 @@ static int __set_input_tf(struct dc_transfer_func *func,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * amdgpu_dm_verify_lut_sizes
 | 
					 * amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes
 | 
				
			||||||
 * @crtc_state: the DRM CRTC state
 | 
					 * @crtc_state: the DRM CRTC state
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of
 | 
					 * Verifies that the Degamma and Gamma LUTs attached to the &crtc_state
 | 
				
			||||||
 * the expected size.
 | 
					 * are of the expected size.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns 0 on success.
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * 0 on success. -EINVAL if any lut sizes are invalid.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
 | 
					int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -327,9 +378,9 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
 | 
				
			||||||
 * of the HW blocks as long as the CRTC CTM always comes before the
 | 
					 * of the HW blocks as long as the CRTC CTM always comes before the
 | 
				
			||||||
 * CRTC RGM and after the CRTC DGM.
 | 
					 * CRTC RGM and after the CRTC DGM.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The CRTC RGM block will be placed in the RGM LUT block if it is non-linear.
 | 
					 * - The CRTC RGM block will be placed in the RGM LUT block if it is non-linear.
 | 
				
			||||||
 * The CRTC DGM block will be placed in the DGM LUT block if it is non-linear.
 | 
					 * - The CRTC DGM block will be placed in the DGM LUT block if it is non-linear.
 | 
				
			||||||
 * The CRTC CTM will be placed in the gamut remap block if it is non-linear.
 | 
					 * - The CRTC CTM will be placed in the gamut remap block if it is non-linear.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The RGM block is typically more fully featured and accurate across
 | 
					 * The RGM block is typically more fully featured and accurate across
 | 
				
			||||||
 * all ASICs - DCE can't support a custom non-linear CRTC DGM.
 | 
					 * all ASICs - DCE can't support a custom non-linear CRTC DGM.
 | 
				
			||||||
| 
						 | 
					@ -338,7 +389,8 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
 | 
				
			||||||
 * management at once we have to either restrict the usage of CRTC properties
 | 
					 * management at once we have to either restrict the usage of CRTC properties
 | 
				
			||||||
 * or blend adjustments together.
 | 
					 * or blend adjustments together.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns 0 on success.
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * 0 on success. Error code if setup fails.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 | 
					int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -393,7 +445,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 | 
				
			||||||
		if (r)
 | 
							if (r)
 | 
				
			||||||
			return r;
 | 
								return r;
 | 
				
			||||||
	} else if (has_regamma) {
 | 
						} else if (has_regamma) {
 | 
				
			||||||
		/* CRTC RGM goes into RGM LUT. */
 | 
							/* If atomic regamma, CRTC RGM goes into RGM LUT. */
 | 
				
			||||||
		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 | 
							stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 | 
				
			||||||
		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 | 
							stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -450,9 +502,10 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Update the underlying dc_stream_state's input transfer function (ITF) in
 | 
					 * Update the underlying dc_stream_state's input transfer function (ITF) in
 | 
				
			||||||
 * preparation for hardware commit. The transfer function used depends on
 | 
					 * preparation for hardware commit. The transfer function used depends on
 | 
				
			||||||
 * the prepartion done on the stream for color management.
 | 
					 * the preparation done on the stream for color management.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns 0 on success.
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * 0 on success. -ENOMEM if mem allocation fails.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 | 
					int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 | 
				
			||||||
				      struct dc_plane_state *dc_plane_state)
 | 
									      struct dc_plane_state *dc_plane_state)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3288,6 +3288,7 @@ void crtc_debugfs_init(struct drm_crtc *crtc)
 | 
				
			||||||
				   &crc_win_y_end_fops);
 | 
									   &crc_win_y_end_fops);
 | 
				
			||||||
	debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc,
 | 
						debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc,
 | 
				
			||||||
				   &crc_win_update_fops);
 | 
									   &crc_win_update_fops);
 | 
				
			||||||
 | 
						dput(dir);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry,
 | 
						debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry,
 | 
				
			||||||
			    crtc, &amdgpu_current_bpc_fops);
 | 
								    crtc, &amdgpu_current_bpc_fops);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -691,8 +691,14 @@ bool dm_helpers_dp_write_dsc_enable(
 | 
				
			||||||
		const struct dc_stream_state *stream,
 | 
							const struct dc_stream_state *stream,
 | 
				
			||||||
		bool enable)
 | 
							bool enable)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t enable_dsc = enable ? 1 : 0;
 | 
						static const uint8_t DSC_DISABLE;
 | 
				
			||||||
 | 
						static const uint8_t DSC_DECODING = 0x01;
 | 
				
			||||||
 | 
						static const uint8_t DSC_PASSTHROUGH = 0x02;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct amdgpu_dm_connector *aconnector;
 | 
						struct amdgpu_dm_connector *aconnector;
 | 
				
			||||||
 | 
						struct drm_dp_mst_port *port;
 | 
				
			||||||
 | 
						uint8_t enable_dsc = enable ? DSC_DECODING : DSC_DISABLE;
 | 
				
			||||||
 | 
						uint8_t enable_passthrough = enable ? DSC_PASSTHROUGH : DSC_DISABLE;
 | 
				
			||||||
	uint8_t ret = 0;
 | 
						uint8_t ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!stream)
 | 
						if (!stream)
 | 
				
			||||||
| 
						 | 
					@ -712,8 +718,39 @@ bool dm_helpers_dp_write_dsc_enable(
 | 
				
			||||||
				aconnector->dsc_aux, stream, enable_dsc);
 | 
									aconnector->dsc_aux, stream, enable_dsc);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1);
 | 
							port = aconnector->port;
 | 
				
			||||||
		DC_LOG_DC("Send DSC %s to MST RX\n", enable_dsc ? "enable" : "disable");
 | 
					
 | 
				
			||||||
 | 
							if (enable) {
 | 
				
			||||||
 | 
								if (port->passthrough_aux) {
 | 
				
			||||||
 | 
									ret = drm_dp_dpcd_write(port->passthrough_aux,
 | 
				
			||||||
 | 
												DP_DSC_ENABLE,
 | 
				
			||||||
 | 
												&enable_passthrough, 1);
 | 
				
			||||||
 | 
									DC_LOG_DC("Sent DSC pass-through enable to virtual dpcd port, ret = %u\n",
 | 
				
			||||||
 | 
										  ret);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ret = drm_dp_dpcd_write(aconnector->dsc_aux,
 | 
				
			||||||
 | 
											DP_DSC_ENABLE, &enable_dsc, 1);
 | 
				
			||||||
 | 
								DC_LOG_DC("Sent DSC decoding enable to %s port, ret = %u\n",
 | 
				
			||||||
 | 
									  (port->passthrough_aux) ? "remote RX" :
 | 
				
			||||||
 | 
									  "virtual dpcd",
 | 
				
			||||||
 | 
									  ret);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ret = drm_dp_dpcd_write(aconnector->dsc_aux,
 | 
				
			||||||
 | 
											DP_DSC_ENABLE, &enable_dsc, 1);
 | 
				
			||||||
 | 
								DC_LOG_DC("Sent DSC decoding disable to %s port, ret = %u\n",
 | 
				
			||||||
 | 
									  (port->passthrough_aux) ? "remote RX" :
 | 
				
			||||||
 | 
									  "virtual dpcd",
 | 
				
			||||||
 | 
									  ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (port->passthrough_aux) {
 | 
				
			||||||
 | 
									ret = drm_dp_dpcd_write(port->passthrough_aux,
 | 
				
			||||||
 | 
												DP_DSC_ENABLE,
 | 
				
			||||||
 | 
												&enable_passthrough, 1);
 | 
				
			||||||
 | 
									DC_LOG_DC("Sent DSC pass-through disable to virtual dpcd port, ret = %u\n",
 | 
				
			||||||
 | 
										  ret);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) {
 | 
						if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) {
 | 
				
			||||||
| 
						 | 
					@ -730,7 +767,7 @@ bool dm_helpers_dp_write_dsc_enable(
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (ret > 0);
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool dm_helpers_is_dp_sink_present(struct dc_link *link)
 | 
					bool dm_helpers_is_dp_sink_present(struct dc_link *link)
 | 
				
			||||||
| 
						 | 
					@ -841,6 +878,25 @@ void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigne
 | 
				
			||||||
	//amdgpu_device_gpu_recover(dc_context->driver-context, NULL);
 | 
						//amdgpu_device_gpu_recover(dc_context->driver-context, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dm_helpers_init_panel_settings(
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dc_panel_config *panel_config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Feature DSC
 | 
				
			||||||
 | 
						panel_config->dsc.disable_dsc_edp = false;
 | 
				
			||||||
 | 
						panel_config->dsc.force_dsc_edp_policy = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dm_helpers_override_panel_settings(
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dc_panel_config *panel_config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Feature DSC
 | 
				
			||||||
 | 
						if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
 | 
				
			||||||
 | 
							panel_config->dsc.disable_dsc_edp = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *dm_helpers_allocate_gpu_mem(
 | 
					void *dm_helpers_allocate_gpu_mem(
 | 
				
			||||||
		struct dc_context *ctx,
 | 
							struct dc_context *ctx,
 | 
				
			||||||
		enum dc_gpu_mem_alloc_type type,
 | 
							enum dc_gpu_mem_alloc_type type,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,7 @@
 | 
				
			||||||
#include "dm_helpers.h"
 | 
					#include "dm_helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dc_link_ddc.h"
 | 
					#include "dc_link_ddc.h"
 | 
				
			||||||
 | 
					#include "dc_link_dp.h"
 | 
				
			||||||
#include "ddc_service_types.h"
 | 
					#include "ddc_service_types.h"
 | 
				
			||||||
#include "dpcd_defs.h"
 | 
					#include "dpcd_defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1351,19 +1352,90 @@ bool pre_validate_dsc(struct drm_atomic_state *state,
 | 
				
			||||||
	return (ret == 0);
 | 
						return (ret == 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					static unsigned int kbps_from_pbn(unsigned int pbn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int kbps = pbn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kbps *= (1000000 / PEAK_FACTOR_X1000);
 | 
				
			||||||
 | 
						kbps *= 8;
 | 
				
			||||||
 | 
						kbps *= 54;
 | 
				
			||||||
 | 
						kbps /= 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return kbps;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
 | 
				
			||||||
 | 
										  struct dc_dsc_bw_range *bw_range)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dc_dsc_policy dsc_policy = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy);
 | 
				
			||||||
 | 
						dc_dsc_compute_bandwidth_range(stream->sink->ctx->dc->res_pool->dscs[0],
 | 
				
			||||||
 | 
									       stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
 | 
				
			||||||
 | 
									       dsc_policy.min_target_bpp * 16,
 | 
				
			||||||
 | 
									       dsc_policy.max_target_bpp * 16,
 | 
				
			||||||
 | 
									       &stream->sink->dsc_caps.dsc_dec_caps,
 | 
				
			||||||
 | 
									       &stream->timing, bw_range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif /* CONFIG_DRM_AMD_DC_DCN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum dc_status dm_dp_mst_is_port_support_mode(
 | 
					enum dc_status dm_dp_mst_is_port_support_mode(
 | 
				
			||||||
	struct amdgpu_dm_connector *aconnector,
 | 
						struct amdgpu_dm_connector *aconnector,
 | 
				
			||||||
	struct dc_stream_state *stream)
 | 
						struct dc_stream_state *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int bpp, pbn, branch_max_throughput_mps = 0;
 | 
						int bpp, pbn, branch_max_throughput_mps = 0;
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC_DCN)
 | 
				
			||||||
 | 
						struct dc_link_settings cur_link_settings;
 | 
				
			||||||
 | 
						unsigned int end_to_end_bw_in_kbps = 0;
 | 
				
			||||||
 | 
						unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
 | 
				
			||||||
 | 
						unsigned int max_compressed_bw_in_kbps = 0;
 | 
				
			||||||
 | 
						struct dc_dsc_bw_range bw_range = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* check if mode could be supported within fUll_pbn */
 | 
						/*
 | 
				
			||||||
	bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
 | 
						 * check if the mode could be supported if DSC pass-through is supported
 | 
				
			||||||
	pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false);
 | 
						 * AND check if there enough bandwidth available to support the mode
 | 
				
			||||||
	if (pbn > aconnector->port->full_pbn)
 | 
						 * with DSC enabled.
 | 
				
			||||||
		return DC_FAIL_BANDWIDTH_VALIDATE;
 | 
						 */
 | 
				
			||||||
 | 
						if (is_dsc_common_config_possible(stream, &bw_range) &&
 | 
				
			||||||
 | 
						    aconnector->port->passthrough_aux) {
 | 
				
			||||||
 | 
							mutex_lock(&aconnector->mst_mgr.lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cur_link_settings = stream->link->verified_link_cap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							upper_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
 | 
				
			||||||
 | 
												       &cur_link_settings
 | 
				
			||||||
 | 
												       );
 | 
				
			||||||
 | 
							down_link_bw_in_kbps = kbps_from_pbn(aconnector->port->full_pbn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* pick the bottleneck */
 | 
				
			||||||
 | 
							end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps,
 | 
				
			||||||
 | 
										    down_link_bw_in_kbps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mutex_unlock(&aconnector->mst_mgr.lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * use the maximum dsc compression bandwidth as the required
 | 
				
			||||||
 | 
							 * bandwidth for the mode
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							max_compressed_bw_in_kbps = bw_range.min_kbps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (end_to_end_bw_in_kbps < max_compressed_bw_in_kbps) {
 | 
				
			||||||
 | 
								DRM_DEBUG_DRIVER("Mode does not fit into DSC pass-through bandwidth validation\n");
 | 
				
			||||||
 | 
								return DC_FAIL_BANDWIDTH_VALIDATE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							/* check if mode could be supported within full_pbn */
 | 
				
			||||||
 | 
							bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
 | 
				
			||||||
 | 
							pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pbn > aconnector->port->full_pbn)
 | 
				
			||||||
 | 
								return DC_FAIL_BANDWIDTH_VALIDATE;
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC_DCN)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
 | 
						/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
 | 
				
			||||||
	switch (stream->timing.pixel_encoding) {
 | 
						switch (stream->timing.pixel_encoding) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
#include "dal_asic_id.h"
 | 
					#include "dal_asic_id.h"
 | 
				
			||||||
#include "amdgpu_display.h"
 | 
					#include "amdgpu_display.h"
 | 
				
			||||||
#include "amdgpu_dm_trace.h"
 | 
					#include "amdgpu_dm_trace.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_plane.h"
 | 
				
			||||||
#include "gc/gc_11_0_0_offset.h"
 | 
					#include "gc/gc_11_0_0_offset.h"
 | 
				
			||||||
#include "gc/gc_11_0_0_sh_mask.h"
 | 
					#include "gc/gc_11_0_0_sh_mask.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,12 +150,12 @@ static void add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_
 | 
				
			||||||
	*size += 1;
 | 
						*size += 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool modifier_has_dcc(uint64_t modifier)
 | 
					static bool modifier_has_dcc(uint64_t modifier)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
 | 
						return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned modifier_gfx9_swizzle_mode(uint64_t modifier)
 | 
					static unsigned modifier_gfx9_swizzle_mode(uint64_t modifier)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (modifier == DRM_FORMAT_MOD_LINEAR)
 | 
						if (modifier == DRM_FORMAT_MOD_LINEAR)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,17 +36,9 @@ int fill_dc_scaling_info(struct amdgpu_device *adev,
 | 
				
			||||||
			 const struct drm_plane_state *state,
 | 
								 const struct drm_plane_state *state,
 | 
				
			||||||
			 struct dc_scaling_info *scaling_info);
 | 
								 struct dc_scaling_info *scaling_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void get_min_max_dc_plane_scaling(struct drm_device *dev,
 | 
					 | 
				
			||||||
				  struct drm_framebuffer *fb,
 | 
					 | 
				
			||||||
				  int *min_downscale, int *max_upscale);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int dm_plane_helper_check_state(struct drm_plane_state *state,
 | 
					int dm_plane_helper_check_state(struct drm_plane_state *state,
 | 
				
			||||||
				struct drm_crtc_state *new_crtc_state);
 | 
									struct drm_crtc_state *new_crtc_state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool modifier_has_dcc(uint64_t modifier);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned int modifier_gfx9_swizzle_mode(uint64_t modifier);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int fill_plane_buffer_attributes(struct amdgpu_device *adev,
 | 
					int fill_plane_buffer_attributes(struct amdgpu_device *adev,
 | 
				
			||||||
				 const struct amdgpu_framebuffer *afb,
 | 
									 const struct amdgpu_framebuffer *afb,
 | 
				
			||||||
				 const enum surface_pixel_format format,
 | 
									 const enum surface_pixel_format format,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,25 +44,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "bios_parser_common.h"
 | 
					#include "bios_parser_common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Temporarily add in defines until ObjectID.h patch is updated in a few days */
 | 
					 | 
				
			||||||
#ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT
 | 
					 | 
				
			||||||
#define GENERIC_OBJECT_ID_BRACKET_LAYOUT          0x05
 | 
					 | 
				
			||||||
#endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1
 | 
					 | 
				
			||||||
#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1	\
 | 
					 | 
				
			||||||
	(GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
 | 
					 | 
				
			||||||
	GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
 | 
					 | 
				
			||||||
	GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
 | 
					 | 
				
			||||||
#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2
 | 
					 | 
				
			||||||
#define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2	\
 | 
					 | 
				
			||||||
	(GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
 | 
					 | 
				
			||||||
	GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
 | 
					 | 
				
			||||||
	GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
 | 
					 | 
				
			||||||
#endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DC_LOGGER \
 | 
					#define DC_LOGGER \
 | 
				
			||||||
	bp->base.ctx->logger
 | 
						bp->base.ctx->logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dc_dmub_srv.h"
 | 
					#include "dc_dmub_srv.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "logger_types.h"
 | 
				
			||||||
 | 
					#undef DC_LOGGER
 | 
				
			||||||
 | 
					#define DC_LOGGER \
 | 
				
			||||||
 | 
						clk_mgr->base.base.ctx->logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "yellow_carp_offset.h"
 | 
					#include "yellow_carp_offset.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define regCLK1_CLK_PLL_REQ			0x0237
 | 
					#define regCLK1_CLK_PLL_REQ			0x0237
 | 
				
			||||||
| 
						 | 
					@ -737,8 +742,49 @@ void dcn31_clk_mgr_construct(
 | 
				
			||||||
	clk_mgr->base.base.bw_params = &dcn31_bw_params;
 | 
						clk_mgr->base.base.bw_params = &dcn31_bw_params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
 | 
						if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dcn31_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
 | 
							dcn31_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumDispClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumSocClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "VcnClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumDfPst atesEnabled: %d\n"
 | 
				
			||||||
 | 
									   "MinGfxClk: %d\n"
 | 
				
			||||||
 | 
									   "MaxGfxClk: %d\n",
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDfPstatesEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->MinGfxClk,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->MaxGfxClk);
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i,
 | 
				
			||||||
 | 
										   smu_dpm_clks.dpm_clks->DcfClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DispClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->SocClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++)
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->SocVoltage[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n"
 | 
				
			||||||
 | 
										   "smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n"
 | 
				
			||||||
 | 
										   "smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk,
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk,
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
 | 
							if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
 | 
				
			||||||
			dcn31_clk_mgr_helper_populate_bw_params(
 | 
								dcn31_clk_mgr_helper_populate_bw_params(
 | 
				
			||||||
					&clk_mgr->base,
 | 
										&clk_mgr->base,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,13 @@
 | 
				
			||||||
#include "dc_link_dp.h"
 | 
					#include "dc_link_dp.h"
 | 
				
			||||||
#include "dcn314_smu.h"
 | 
					#include "dcn314_smu.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "logger_types.h"
 | 
				
			||||||
 | 
					#undef DC_LOGGER
 | 
				
			||||||
 | 
					#define DC_LOGGER \
 | 
				
			||||||
 | 
						clk_mgr->base.base.ctx->logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_INSTANCE                                        7
 | 
					#define MAX_INSTANCE                                        7
 | 
				
			||||||
#define MAX_SEGMENT                                         8
 | 
					#define MAX_SEGMENT                                         8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -614,7 +621,7 @@ static void dcn314_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *cl
 | 
				
			||||||
		bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
 | 
							bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk;
 | 
				
			||||||
		bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio(
 | 
							bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio(
 | 
				
			||||||
			clock_table->DfPstateTable[min_pstate].WckRatio);
 | 
								clock_table->DfPstateTable[min_pstate].WckRatio);
 | 
				
			||||||
	};
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Make sure to include at least one entry at highest pstate */
 | 
						/* Make sure to include at least one entry at highest pstate */
 | 
				
			||||||
	if (max_pstate != min_pstate || i == 0) {
 | 
						if (max_pstate != min_pstate || i == 0) {
 | 
				
			||||||
| 
						 | 
					@ -775,7 +782,48 @@ void dcn314_clk_mgr_construct(
 | 
				
			||||||
	clk_mgr->base.base.bw_params = &dcn314_bw_params;
 | 
						clk_mgr->base.base.bw_params = &dcn314_bw_params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
 | 
						if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dcn314_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
 | 
							dcn314_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
 | 
				
			||||||
 | 
							DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumDispClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumSocClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "VcnClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumDfPst atesEnabled: %d\n"
 | 
				
			||||||
 | 
									   "MinGfxClk: %d\n"
 | 
				
			||||||
 | 
									   "MaxGfxClk: %d\n",
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDfPstatesEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->MinGfxClk,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->MaxGfxClk);
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i,
 | 
				
			||||||
 | 
										   smu_dpm_clks.dpm_clks->DcfClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DispClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->SocClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++)
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->SocVoltage[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n"
 | 
				
			||||||
 | 
										   "smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n"
 | 
				
			||||||
 | 
										   "smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk,
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk,
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ctx->dc_bios && ctx->dc_bios->integrated_info && ctx->dc->config.use_default_clock_table == false) {
 | 
							if (ctx->dc_bios && ctx->dc_bios->integrated_info && ctx->dc->config.use_default_clock_table == false) {
 | 
				
			||||||
			dcn314_clk_mgr_helper_populate_bw_params(
 | 
								dcn314_clk_mgr_helper_populate_bw_params(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dc_dmub_srv.h"
 | 
					#include "dc_dmub_srv.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "logger_types.h"
 | 
				
			||||||
 | 
					#undef DC_LOGGER
 | 
				
			||||||
 | 
					#define DC_LOGGER \
 | 
				
			||||||
 | 
						clk_mgr->base.base.ctx->logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dc_link_dp.h"
 | 
					#include "dc_link_dp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TO_CLK_MGR_DCN315(clk_mgr)\
 | 
					#define TO_CLK_MGR_DCN315(clk_mgr)\
 | 
				
			||||||
| 
						 | 
					@ -507,7 +512,7 @@ static void dcn315_clk_mgr_helper_populate_bw_params(
 | 
				
			||||||
		bw_params->clk_table.entries[i].dispclk_mhz = clock_table->DispClocks[i];
 | 
							bw_params->clk_table.entries[i].dispclk_mhz = clock_table->DispClocks[i];
 | 
				
			||||||
		bw_params->clk_table.entries[i].dppclk_mhz = clock_table->DppClocks[i];
 | 
							bw_params->clk_table.entries[i].dppclk_mhz = clock_table->DppClocks[i];
 | 
				
			||||||
		bw_params->clk_table.entries[i].wck_ratio = 1;
 | 
							bw_params->clk_table.entries[i].wck_ratio = 1;
 | 
				
			||||||
	};
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Make sure to include at least one entry and highest pstate */
 | 
						/* Make sure to include at least one entry and highest pstate */
 | 
				
			||||||
	if (max_pstate != min_pstate || i == 0) {
 | 
						if (max_pstate != min_pstate || i == 0) {
 | 
				
			||||||
| 
						 | 
					@ -666,7 +671,48 @@ void dcn315_clk_mgr_construct(
 | 
				
			||||||
	clk_mgr->base.base.bw_params = &dcn315_bw_params;
 | 
						clk_mgr->base.base.bw_params = &dcn315_bw_params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
 | 
						if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
 | 
				
			||||||
 | 
							int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dcn315_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
 | 
							dcn315_get_dpm_table_from_smu(&clk_mgr->base, &smu_dpm_clks);
 | 
				
			||||||
 | 
							DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumDispClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumSocClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "VcnClkLevelsEnabled: %d\n"
 | 
				
			||||||
 | 
									   "NumDfPst atesEnabled: %d\n"
 | 
				
			||||||
 | 
									   "MinGfxClk: %d\n"
 | 
				
			||||||
 | 
									   "MaxGfxClk: %d\n",
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->VcnClkLevelsEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->NumDfPstatesEnabled,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->MinGfxClk,
 | 
				
			||||||
 | 
									   smu_dpm_clks.dpm_clks->MaxGfxClk);
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumDcfClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->DcfClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i,
 | 
				
			||||||
 | 
										   smu_dpm_clks.dpm_clks->DcfClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumDispClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->DispClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DispClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < smu_dpm_clks.dpm_clks->NumSocClkLevelsEnabled; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocClocks[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->SocClocks[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++)
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks->SocVoltage[%d] = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->SocVoltage[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < NUM_DF_PSTATE_LEVELS; i++) {
 | 
				
			||||||
 | 
								DC_LOG_SMU("smu_dpm_clks.dpm_clks.DfPstateTable[%d].FClk = %d\n"
 | 
				
			||||||
 | 
										   "smu_dpm_clks.dpm_clks->DfPstateTable[%d].MemClk= %d\n"
 | 
				
			||||||
 | 
										   "smu_dpm_clks.dpm_clks->DfPstateTable[%d].Voltage = %d\n",
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].FClk,
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].MemClk,
 | 
				
			||||||
 | 
										   i, smu_dpm_clks.dpm_clks->DfPstateTable[i].Voltage);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
 | 
							if (ctx->dc_bios && ctx->dc_bios->integrated_info) {
 | 
				
			||||||
			dcn315_clk_mgr_helper_populate_bw_params(
 | 
								dcn315_clk_mgr_helper_populate_bw_params(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -638,14 +638,17 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * dc_stream_get_crc() - Get CRC values for the given stream.
 | 
					 * dc_stream_get_crc() - Get CRC values for the given stream.
 | 
				
			||||||
 * @dc: DC object
 | 
					 *
 | 
				
			||||||
 | 
					 * @dc: DC object.
 | 
				
			||||||
 * @stream: The DC stream state of the stream to get CRCs from.
 | 
					 * @stream: The DC stream state of the stream to get CRCs from.
 | 
				
			||||||
 * @r_cr: CRC value for the first of the 3 channels stored here.
 | 
					 * @r_cr: CRC value for the red component.
 | 
				
			||||||
 * @g_y:  CRC value for the second of the 3 channels stored here.
 | 
					 * @g_y:  CRC value for the green component.
 | 
				
			||||||
 * @b_cb: CRC value for the third of the 3 channels stored here.
 | 
					 * @b_cb: CRC value for the blue component.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * dc_stream_configure_crc needs to be called beforehand to enable CRCs.
 | 
					 * dc_stream_configure_crc needs to be called beforehand to enable CRCs.
 | 
				
			||||||
 * Return false if stream is not found, or if CRCs are not enabled.
 | 
					 *
 | 
				
			||||||
 | 
					 * Return:
 | 
				
			||||||
 | 
					 * false if stream is not found, or if CRCs are not enabled.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
 | 
					bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
 | 
				
			||||||
		       uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
 | 
							       uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
 | 
				
			||||||
| 
						 | 
					@ -1094,7 +1097,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
 | 
				
			||||||
				dc->current_state->stream_count != context->stream_count)
 | 
									dc->current_state->stream_count != context->stream_count)
 | 
				
			||||||
			should_disable = true;
 | 
								should_disable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe) {
 | 
							if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe &&
 | 
				
			||||||
 | 
									!dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe) {
 | 
				
			||||||
			struct pipe_ctx *old_pipe, *new_pipe;
 | 
								struct pipe_ctx *old_pipe, *new_pipe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 | 
								old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 | 
				
			||||||
| 
						 | 
					@ -1177,7 +1181,11 @@ static void disable_vbios_mode_if_required(
 | 
				
			||||||
						pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;
 | 
											pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (pix_clk_100hz != requested_pix_clk_100hz) {
 | 
										if (pix_clk_100hz != requested_pix_clk_100hz) {
 | 
				
			||||||
						core_link_disable_stream(pipe);
 | 
											if (dc->hwss.update_phy_state)
 | 
				
			||||||
 | 
												dc->hwss.update_phy_state(dc->current_state,
 | 
				
			||||||
 | 
														pipe, TX_OFF_SYMCLK_OFF);
 | 
				
			||||||
 | 
											else
 | 
				
			||||||
 | 
												core_link_disable_stream(pipe);
 | 
				
			||||||
						pipe->stream->dpms_off = false;
 | 
											pipe->stream->dpms_off = false;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					@ -3060,7 +3068,11 @@ static void commit_planes_do_stream_update(struct dc *dc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (stream_update->dpms_off) {
 | 
								if (stream_update->dpms_off) {
 | 
				
			||||||
				if (*stream_update->dpms_off) {
 | 
									if (*stream_update->dpms_off) {
 | 
				
			||||||
					core_link_disable_stream(pipe_ctx);
 | 
										if (dc->hwss.update_phy_state)
 | 
				
			||||||
 | 
											dc->hwss.update_phy_state(dc->current_state,
 | 
				
			||||||
 | 
													pipe_ctx, TX_OFF_SYMCLK_ON);
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
											core_link_disable_stream(pipe_ctx);
 | 
				
			||||||
					/* for dpms, keep acquired resources*/
 | 
										/* for dpms, keep acquired resources*/
 | 
				
			||||||
					if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
 | 
										if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
 | 
				
			||||||
						pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
 | 
											pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
 | 
				
			||||||
| 
						 | 
					@ -3071,7 +3083,11 @@ static void commit_planes_do_stream_update(struct dc *dc,
 | 
				
			||||||
					if (get_seamless_boot_stream_count(context) == 0)
 | 
										if (get_seamless_boot_stream_count(context) == 0)
 | 
				
			||||||
						dc->hwss.prepare_bandwidth(dc, dc->current_state);
 | 
											dc->hwss.prepare_bandwidth(dc, dc->current_state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					core_link_enable_stream(dc->current_state, pipe_ctx);
 | 
										if (dc->hwss.update_phy_state)
 | 
				
			||||||
 | 
											dc->hwss.update_phy_state(dc->current_state,
 | 
				
			||||||
 | 
													pipe_ctx, TX_ON_SYMCLK_ON);
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
											core_link_enable_stream(dc->current_state, pipe_ctx);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3098,11 +3114,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_state *stream)
 | 
					static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_state *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1)
 | 
						if ((stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1
 | 
				
			||||||
		return true;
 | 
								|| stream->link->psr_settings.psr_version == DC_PSR_VERSION_1)
 | 
				
			||||||
 | 
								&& stream->ctx->dce_version >= DCN_VERSION_3_1)
 | 
				
			||||||
	if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1 &&
 | 
					 | 
				
			||||||
	    dc->debug.enable_sw_cntl_psr)
 | 
					 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
| 
						 | 
					@ -3318,10 +3332,6 @@ static void commit_planes_for_stream(struct dc *dc,
 | 
				
			||||||
		if (dc->hwss.program_front_end_for_ctx)
 | 
							if (dc->hwss.program_front_end_for_ctx)
 | 
				
			||||||
			dc->hwss.program_front_end_for_ctx(dc, context);
 | 
								dc->hwss.program_front_end_for_ctx(dc, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (update_type != UPDATE_TYPE_FAST)
 | 
					 | 
				
			||||||
			if (dc->hwss.commit_subvp_config)
 | 
					 | 
				
			||||||
				dc->hwss.commit_subvp_config(dc, context);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
 | 
							if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
 | 
				
			||||||
			dc->hwss.interdependent_update_lock(dc, context, false);
 | 
								dc->hwss.interdependent_update_lock(dc, context, false);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
| 
						 | 
					@ -3329,16 +3339,15 @@ static void commit_planes_for_stream(struct dc *dc,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		dc->hwss.post_unlock_program_front_end(dc, context);
 | 
							dc->hwss.post_unlock_program_front_end(dc, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (update_type != UPDATE_TYPE_FAST)
 | 
				
			||||||
 | 
								if (dc->hwss.commit_subvp_config)
 | 
				
			||||||
 | 
									dc->hwss.commit_subvp_config(dc, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Since phantom pipe programming is moved to post_unlock_program_front_end,
 | 
							/* Since phantom pipe programming is moved to post_unlock_program_front_end,
 | 
				
			||||||
		 * move the SubVP lock to after the phantom pipes have been setup
 | 
							 * move the SubVP lock to after the phantom pipes have been setup
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
 | 
							if (dc->hwss.subvp_pipe_control_lock)
 | 
				
			||||||
			if (dc->hwss.subvp_pipe_control_lock)
 | 
								dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
 | 
				
			||||||
				dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			if (dc->hwss.subvp_pipe_control_lock)
 | 
					 | 
				
			||||||
				dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3462,10 +3471,6 @@ static void commit_planes_for_stream(struct dc *dc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (update_type != UPDATE_TYPE_FAST)
 | 
					 | 
				
			||||||
		if (dc->hwss.commit_subvp_config)
 | 
					 | 
				
			||||||
			dc->hwss.commit_subvp_config(dc, context);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
 | 
						if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
 | 
				
			||||||
		dc->hwss.interdependent_update_lock(dc, context, false);
 | 
							dc->hwss.interdependent_update_lock(dc, context, false);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -3503,6 +3508,10 @@ static void commit_planes_for_stream(struct dc *dc,
 | 
				
			||||||
	if (update_type != UPDATE_TYPE_FAST)
 | 
						if (update_type != UPDATE_TYPE_FAST)
 | 
				
			||||||
		dc->hwss.post_unlock_program_front_end(dc, context);
 | 
							dc->hwss.post_unlock_program_front_end(dc, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (update_type != UPDATE_TYPE_FAST)
 | 
				
			||||||
 | 
							if (dc->hwss.commit_subvp_config)
 | 
				
			||||||
 | 
								dc->hwss.commit_subvp_config(dc, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Since phantom pipe programming is moved to post_unlock_program_front_end,
 | 
						/* Since phantom pipe programming is moved to post_unlock_program_front_end,
 | 
				
			||||||
	 * move the SubVP lock to after the phantom pipes have been setup
 | 
						 * move the SubVP lock to after the phantom pipes have been setup
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					@ -3543,8 +3552,10 @@ static bool commit_minimal_transition_state(struct dc *dc,
 | 
				
			||||||
	if (!transition_context)
 | 
						if (!transition_context)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tmp_policy = dc->debug.pipe_split_policy;
 | 
						if (!dc->config.is_vmin_only_asic) {
 | 
				
			||||||
	dc->debug.pipe_split_policy = MPC_SPLIT_AVOID;
 | 
							tmp_policy = dc->debug.pipe_split_policy;
 | 
				
			||||||
 | 
							dc->debug.pipe_split_policy = MPC_SPLIT_AVOID;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dc_resource_state_copy_construct(transition_base_context, transition_context);
 | 
						dc_resource_state_copy_construct(transition_base_context, transition_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3570,7 +3581,8 @@ static bool commit_minimal_transition_state(struct dc *dc,
 | 
				
			||||||
	dc_release_state(transition_context);
 | 
						dc_release_state(transition_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//restore previous pipe split policy
 | 
						//restore previous pipe split policy
 | 
				
			||||||
	dc->debug.pipe_split_policy = tmp_policy;
 | 
						if (!dc->config.is_vmin_only_asic)
 | 
				
			||||||
 | 
							dc->debug.pipe_split_policy = tmp_policy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret != DC_OK) {
 | 
						if (ret != DC_OK) {
 | 
				
			||||||
		//this should never happen
 | 
							//this should never happen
 | 
				
			||||||
| 
						 | 
					@ -4275,8 +4287,8 @@ void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *****************************************************************************
 | 
					 *****************************************************************************
 | 
				
			||||||
 * Function: dc_is_dmub_outbox_supported -
 | 
					 * Function: dc_is_dmub_outbox_supported -
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 * @brief 
 | 
					 * @brief
 | 
				
			||||||
 *      Checks whether DMUB FW supports outbox notifications, if supported
 | 
					 *      Checks whether DMUB FW supports outbox notifications, if supported
 | 
				
			||||||
 *		DM should register outbox interrupt prior to actually enabling interrupts
 | 
					 *		DM should register outbox interrupt prior to actually enabling interrupts
 | 
				
			||||||
 *		via dc_enable_dmub_outbox
 | 
					 *		via dc_enable_dmub_outbox
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,6 +402,44 @@ void get_hdr_visual_confirm_color(
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void get_subvp_visual_confirm_color(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							struct pipe_ctx *pipe_ctx,
 | 
				
			||||||
 | 
							struct tg_color *color)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t color_value = MAX_TG_COLOR_VALUE;
 | 
				
			||||||
 | 
						bool enable_subvp = false;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < dc->res_pool->pipe_count; i++) {
 | 
				
			||||||
 | 
							struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pipe->stream && pipe->stream->mall_stream_config.paired_stream &&
 | 
				
			||||||
 | 
									pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
 | 
				
			||||||
 | 
								/* SubVP enable - red */
 | 
				
			||||||
 | 
								color->color_r_cr = color_value;
 | 
				
			||||||
 | 
								enable_subvp = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (pipe_ctx->stream == pipe->stream)
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enable_subvp && pipe_ctx->stream->mall_stream_config.type == SUBVP_NONE) {
 | 
				
			||||||
 | 
							color->color_r_cr = 0;
 | 
				
			||||||
 | 
							if (pipe_ctx->stream->ignore_msa_timing_param == 1)
 | 
				
			||||||
 | 
								/* SubVP enable and DRR on - green */
 | 
				
			||||||
 | 
								color->color_g_y = color_value;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								/* SubVP enable and No DRR - blue */
 | 
				
			||||||
 | 
								color->color_b_cb = color_value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void get_surface_tile_visual_confirm_color(
 | 
					void get_surface_tile_visual_confirm_color(
 | 
				
			||||||
		struct pipe_ctx *pipe_ctx,
 | 
							struct pipe_ctx *pipe_ctx,
 | 
				
			||||||
		struct tg_color *color)
 | 
							struct tg_color *color)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1311,6 +1311,14 @@ static bool detect_link_and_local_sink(struct dc_link *link,
 | 
				
			||||||
				sink->edid_caps.audio_modes[i].sample_rate,
 | 
									sink->edid_caps.audio_modes[i].sample_rate,
 | 
				
			||||||
				sink->edid_caps.audio_modes[i].sample_size);
 | 
									sink->edid_caps.audio_modes[i].sample_size);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (link->connector_signal == SIGNAL_TYPE_EDP) {
 | 
				
			||||||
 | 
								// Init dc_panel_config
 | 
				
			||||||
 | 
								dm_helpers_init_panel_settings(dc_ctx, &link->panel_config);
 | 
				
			||||||
 | 
								// Override dc_panel_config if system has specific settings
 | 
				
			||||||
 | 
								dm_helpers_override_panel_settings(dc_ctx, &link->panel_config);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* From Connected-to-Disconnected. */
 | 
							/* From Connected-to-Disconnected. */
 | 
				
			||||||
		link->type = dc_connection_none;
 | 
							link->type = dc_connection_none;
 | 
				
			||||||
| 
						 | 
					@ -2069,11 +2077,7 @@ static enum dc_status enable_link_edp(
 | 
				
			||||||
		struct dc_state *state,
 | 
							struct dc_state *state,
 | 
				
			||||||
		struct pipe_ctx *pipe_ctx)
 | 
							struct pipe_ctx *pipe_ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum dc_status status;
 | 
						return enable_link_dp(state, pipe_ctx);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	status = enable_link_dp(state, pipe_ctx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return status;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum dc_status enable_link_dp_mst(
 | 
					static enum dc_status enable_link_dp_mst(
 | 
				
			||||||
| 
						 | 
					@ -4295,18 +4299,6 @@ void core_link_enable_stream(
 | 
				
			||||||
		if (pipe_ctx->stream->dpms_off)
 | 
							if (pipe_ctx->stream->dpms_off)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Have to setup DSC before DIG FE and BE are connected (which happens before the
 | 
					 | 
				
			||||||
		 * link training). This is to make sure the bandwidth sent to DIG BE won't be
 | 
					 | 
				
			||||||
		 * bigger than what the link and/or DIG BE can handle. VBID[6]/CompressedStream_flag
 | 
					 | 
				
			||||||
		 * will be automatically set at a later time when the video is enabled
 | 
					 | 
				
			||||||
		 * (DP_VID_STREAM_EN = 1).
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (pipe_ctx->stream->timing.flags.DSC) {
 | 
					 | 
				
			||||||
			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
 | 
					 | 
				
			||||||
					dc_is_virtual_signal(pipe_ctx->stream->signal))
 | 
					 | 
				
			||||||
				dp_set_dsc_enable(pipe_ctx, true);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		status = enable_link(state, pipe_ctx);
 | 
							status = enable_link(state, pipe_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (status != DC_OK) {
 | 
							if (status != DC_OK) {
 | 
				
			||||||
| 
						 | 
					@ -4736,7 +4728,7 @@ bool dc_link_should_enable_fec(const struct dc_link *link)
 | 
				
			||||||
	else if (link->connector_signal == SIGNAL_TYPE_EDP
 | 
						else if (link->connector_signal == SIGNAL_TYPE_EDP
 | 
				
			||||||
			&& (link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.
 | 
								&& (link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.
 | 
				
			||||||
			 dsc_support.DSC_SUPPORT == false
 | 
								 dsc_support.DSC_SUPPORT == false
 | 
				
			||||||
				|| link->dc->debug.disable_dsc_edp
 | 
									|| link->panel_config.dsc.disable_dsc_edp
 | 
				
			||||||
				|| !link->dc->caps.edp_dsc_support))
 | 
									|| !link->dc->caps.edp_dsc_support))
 | 
				
			||||||
		force_disable = true;
 | 
							force_disable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3743,7 +3743,7 @@ static bool decide_edp_link_settings_with_dsc(struct dc_link *link,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned int policy = 0;
 | 
						unsigned int policy = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	policy = link->ctx->dc->debug.force_dsc_edp_policy;
 | 
						policy = link->panel_config.dsc.force_dsc_edp_policy;
 | 
				
			||||||
	if (max_link_rate == LINK_RATE_UNKNOWN)
 | 
						if (max_link_rate == LINK_RATE_UNKNOWN)
 | 
				
			||||||
		max_link_rate = link->verified_link_cap.link_rate;
 | 
							max_link_rate = link->verified_link_cap.link_rate;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -3909,7 +3909,7 @@ bool decide_link_settings(struct dc_stream_state *stream,
 | 
				
			||||||
		if (stream->timing.flags.DSC) {
 | 
							if (stream->timing.flags.DSC) {
 | 
				
			||||||
			enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN;
 | 
								enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (link->ctx->dc->debug.force_dsc_edp_policy) {
 | 
								if (link->panel_config.dsc.force_dsc_edp_policy) {
 | 
				
			||||||
				/* calculate link max link rate cap*/
 | 
									/* calculate link max link rate cap*/
 | 
				
			||||||
				struct dc_link_settings tmp_link_setting;
 | 
									struct dc_link_settings tmp_link_setting;
 | 
				
			||||||
				struct dc_crtc_timing tmp_timing = stream->timing;
 | 
									struct dc_crtc_timing tmp_timing = stream->timing;
 | 
				
			||||||
| 
						 | 
					@ -4519,7 +4519,11 @@ void dc_link_dp_handle_link_loss(struct dc_link *link)
 | 
				
			||||||
		pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
 | 
							pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
 | 
				
			||||||
		if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
 | 
							if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
 | 
				
			||||||
				pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
 | 
									pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
 | 
				
			||||||
			core_link_disable_stream(pipe_ctx);
 | 
								if (link->dc->hwss.update_phy_state)
 | 
				
			||||||
 | 
									link->dc->hwss.update_phy_state(link->dc->current_state,
 | 
				
			||||||
 | 
											pipe_ctx, TX_OFF_SYMCLK_OFF);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									core_link_disable_stream(pipe_ctx);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4527,7 +4531,11 @@ void dc_link_dp_handle_link_loss(struct dc_link *link)
 | 
				
			||||||
		pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
 | 
							pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
 | 
				
			||||||
		if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
 | 
							if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
 | 
				
			||||||
				pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
 | 
									pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
 | 
				
			||||||
			core_link_enable_stream(link->dc->current_state, pipe_ctx);
 | 
								if (link->dc->hwss.update_phy_state)
 | 
				
			||||||
 | 
									link->dc->hwss.update_phy_state(link->dc->current_state,
 | 
				
			||||||
 | 
											pipe_ctx, TX_ON_SYMCLK_ON);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									core_link_enable_stream(link->dc->current_state, pipe_ctx);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5024,6 +5032,10 @@ static void determine_lttpr_mode(struct dc_link *link)
 | 
				
			||||||
	bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
 | 
						bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
 | 
				
			||||||
	bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
 | 
						bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (link->ctx->dc->debug.lttpr_mode_override != 0) {
 | 
				
			||||||
 | 
							link->lttpr_mode = link->ctx->dc->debug.lttpr_mode_override;
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
 | 
						if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
 | 
				
			||||||
			link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
 | 
								link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
 | 
				
			||||||
| 
						 | 
					@ -5267,6 +5279,7 @@ static bool retrieve_link_cap(struct dc_link *link)
 | 
				
			||||||
	union dp_downstream_port_present ds_port = { 0 };
 | 
						union dp_downstream_port_present ds_port = { 0 };
 | 
				
			||||||
	enum dc_status status = DC_ERROR_UNEXPECTED;
 | 
						enum dc_status status = DC_ERROR_UNEXPECTED;
 | 
				
			||||||
	uint32_t read_dpcd_retry_cnt = 3;
 | 
						uint32_t read_dpcd_retry_cnt = 3;
 | 
				
			||||||
 | 
						uint32_t aux_channel_retry_cnt = 0;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	struct dp_sink_hw_fw_revision dp_hw_fw_revision;
 | 
						struct dp_sink_hw_fw_revision dp_hw_fw_revision;
 | 
				
			||||||
	const uint32_t post_oui_delay = 30; // 30ms
 | 
						const uint32_t post_oui_delay = 30; // 30ms
 | 
				
			||||||
| 
						 | 
					@ -5294,21 +5307,43 @@ static bool retrieve_link_cap(struct dc_link *link)
 | 
				
			||||||
		status = wa_try_to_wake_dprx(link, timeout_ms);
 | 
							status = wa_try_to_wake_dprx(link, timeout_ms);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (status != DC_OK && aux_channel_retry_cnt < 10) {
 | 
				
			||||||
 | 
							status = core_link_read_dpcd(link, DP_SET_POWER,
 | 
				
			||||||
 | 
									&dpcd_power_state, sizeof(dpcd_power_state));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Delay 1 ms if AUX CH is in power down state. Based on spec
 | 
				
			||||||
 | 
							 * section 2.3.1.2, if AUX CH may be powered down due to
 | 
				
			||||||
 | 
							 * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
 | 
				
			||||||
 | 
							 * signal and may need up to 1 ms before being able to reply.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) {
 | 
				
			||||||
 | 
								udelay(1000);
 | 
				
			||||||
 | 
								aux_channel_retry_cnt++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If aux channel is not active, return false and trigger another detect*/
 | 
				
			||||||
 | 
						if (status != DC_OK) {
 | 
				
			||||||
 | 
							dpcd_power_state = DP_SET_POWER_D0;
 | 
				
			||||||
 | 
							status = core_link_write_dpcd(
 | 
				
			||||||
 | 
									link,
 | 
				
			||||||
 | 
									DP_SET_POWER,
 | 
				
			||||||
 | 
									&dpcd_power_state,
 | 
				
			||||||
 | 
									sizeof(dpcd_power_state));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dpcd_power_state = DP_SET_POWER_D3;
 | 
				
			||||||
 | 
							status = core_link_write_dpcd(
 | 
				
			||||||
 | 
									link,
 | 
				
			||||||
 | 
									DP_SET_POWER,
 | 
				
			||||||
 | 
									&dpcd_power_state,
 | 
				
			||||||
 | 
									sizeof(dpcd_power_state));
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	is_lttpr_present = dp_retrieve_lttpr_cap(link);
 | 
						is_lttpr_present = dp_retrieve_lttpr_cap(link);
 | 
				
			||||||
	/* Read DP tunneling information. */
 | 
						/* Read DP tunneling information. */
 | 
				
			||||||
	status = dpcd_get_tunneling_device_data(link);
 | 
						status = dpcd_get_tunneling_device_data(link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = core_link_read_dpcd(link, DP_SET_POWER,
 | 
					 | 
				
			||||||
			&dpcd_power_state, sizeof(dpcd_power_state));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Delay 1 ms if AUX CH is in power down state. Based on spec
 | 
					 | 
				
			||||||
	 * section 2.3.1.2, if AUX CH may be powered down due to
 | 
					 | 
				
			||||||
	 * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
 | 
					 | 
				
			||||||
	 * signal and may need up to 1 ms before being able to reply.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
 | 
					 | 
				
			||||||
		udelay(1000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dpcd_set_source_specific_data(link);
 | 
						dpcd_set_source_specific_data(link);
 | 
				
			||||||
	/* Sink may need to configure internals based on vendor, so allow some
 | 
						/* Sink may need to configure internals based on vendor, so allow some
 | 
				
			||||||
	 * time before proceeding with possibly vendor specific transactions
 | 
						 * time before proceeding with possibly vendor specific transactions
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1904,9 +1904,6 @@ bool dc_is_stream_unchanged(
 | 
				
			||||||
	if (memcmp(&old_stream->audio_info, &stream->audio_info, sizeof(stream->audio_info)) != 0)
 | 
						if (memcmp(&old_stream->audio_info, &stream->audio_info, sizeof(stream->audio_info)) != 0)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (old_stream->odm_2to1_policy_applied != stream->odm_2to1_policy_applied)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ struct aux_payload;
 | 
				
			||||||
struct set_config_cmd_payload;
 | 
					struct set_config_cmd_payload;
 | 
				
			||||||
struct dmub_notification;
 | 
					struct dmub_notification;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DC_VER "3.2.198"
 | 
					#define DC_VER "3.2.201"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_SURFACES 3
 | 
					#define MAX_SURFACES 3
 | 
				
			||||||
#define MAX_PLANES 6
 | 
					#define MAX_PLANES 6
 | 
				
			||||||
| 
						 | 
					@ -118,7 +118,26 @@ struct dc_plane_cap {
 | 
				
			||||||
	uint32_t min_height;
 | 
						uint32_t min_height;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Color management caps (DPP and MPC)
 | 
					/**
 | 
				
			||||||
 | 
					 * DOC: color-management-caps
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * **Color management caps (DPP and MPC)**
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Modules/color calculates various color operations which are translated to
 | 
				
			||||||
 | 
					 * abstracted HW. DCE 5-12 had almost no important changes, but starting with
 | 
				
			||||||
 | 
					 * DCN1, every new generation comes with fairly major differences in color
 | 
				
			||||||
 | 
					 * pipeline. Therefore, we abstract color pipe capabilities so modules/DM can
 | 
				
			||||||
 | 
					 * decide mapping to HW block based on logical capabilities.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct rom_curve_caps - predefined transfer function caps for degamma and regamma
 | 
				
			||||||
 | 
					 * @srgb: RGB color space transfer func
 | 
				
			||||||
 | 
					 * @bt2020: BT.2020 transfer func
 | 
				
			||||||
 | 
					 * @gamma2_2: standard gamma
 | 
				
			||||||
 | 
					 * @pq: perceptual quantizer transfer function
 | 
				
			||||||
 | 
					 * @hlg: hybrid log–gamma transfer function
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
struct rom_curve_caps {
 | 
					struct rom_curve_caps {
 | 
				
			||||||
	uint16_t srgb : 1;
 | 
						uint16_t srgb : 1;
 | 
				
			||||||
	uint16_t bt2020 : 1;
 | 
						uint16_t bt2020 : 1;
 | 
				
			||||||
| 
						 | 
					@ -127,36 +146,68 @@ struct rom_curve_caps {
 | 
				
			||||||
	uint16_t hlg : 1;
 | 
						uint16_t hlg : 1;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct dpp_color_caps - color pipeline capabilities for display pipe and
 | 
				
			||||||
 | 
					 * plane blocks
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @dcn_arch: all DCE generations treated the same
 | 
				
			||||||
 | 
					 * @input_lut_shared: shared with DGAM. Input LUT is different than most LUTs,
 | 
				
			||||||
 | 
					 * just plain 256-entry lookup
 | 
				
			||||||
 | 
					 * @icsc: input color space conversion
 | 
				
			||||||
 | 
					 * @dgam_ram: programmable degamma LUT
 | 
				
			||||||
 | 
					 * @post_csc: post color space conversion, before gamut remap
 | 
				
			||||||
 | 
					 * @gamma_corr: degamma correction
 | 
				
			||||||
 | 
					 * @hw_3d_lut: 3D LUT support. It implies a shaper LUT before. It may be shared
 | 
				
			||||||
 | 
					 * with MPC by setting mpc:shared_3d_lut flag
 | 
				
			||||||
 | 
					 * @ogam_ram: programmable out/blend gamma LUT
 | 
				
			||||||
 | 
					 * @ocsc: output color space conversion
 | 
				
			||||||
 | 
					 * @dgam_rom_for_yuv: pre-defined degamma LUT for YUV planes
 | 
				
			||||||
 | 
					 * @dgam_rom_caps: pre-definied curve caps for degamma 1D LUT
 | 
				
			||||||
 | 
					 * @ogam_rom_caps: pre-definied curve caps for regamma 1D LUT
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note: hdr_mult and gamut remap (CTM) are always available in DPP (in that order)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
struct dpp_color_caps {
 | 
					struct dpp_color_caps {
 | 
				
			||||||
	uint16_t dcn_arch : 1; // all DCE generations treated the same
 | 
						uint16_t dcn_arch : 1;
 | 
				
			||||||
	// input lut is different than most LUTs, just plain 256-entry lookup
 | 
						uint16_t input_lut_shared : 1;
 | 
				
			||||||
	uint16_t input_lut_shared : 1; // shared with DGAM
 | 
					 | 
				
			||||||
	uint16_t icsc : 1;
 | 
						uint16_t icsc : 1;
 | 
				
			||||||
	uint16_t dgam_ram : 1;
 | 
						uint16_t dgam_ram : 1;
 | 
				
			||||||
	uint16_t post_csc : 1; // before gamut remap
 | 
						uint16_t post_csc : 1;
 | 
				
			||||||
	uint16_t gamma_corr : 1;
 | 
						uint16_t gamma_corr : 1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// hdr_mult and gamut remap always available in DPP (in that order)
 | 
					 | 
				
			||||||
	// 3d lut implies shaper LUT,
 | 
					 | 
				
			||||||
	// it may be shared with MPC - check MPC:shared_3d_lut flag
 | 
					 | 
				
			||||||
	uint16_t hw_3d_lut : 1;
 | 
						uint16_t hw_3d_lut : 1;
 | 
				
			||||||
	uint16_t ogam_ram : 1; // blnd gam
 | 
						uint16_t ogam_ram : 1;
 | 
				
			||||||
	uint16_t ocsc : 1;
 | 
						uint16_t ocsc : 1;
 | 
				
			||||||
	uint16_t dgam_rom_for_yuv : 1;
 | 
						uint16_t dgam_rom_for_yuv : 1;
 | 
				
			||||||
	struct rom_curve_caps dgam_rom_caps;
 | 
						struct rom_curve_caps dgam_rom_caps;
 | 
				
			||||||
	struct rom_curve_caps ogam_rom_caps;
 | 
						struct rom_curve_caps ogam_rom_caps;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct mpc_color_caps - color pipeline capabilities for multiple pipe and
 | 
				
			||||||
 | 
					 * plane combined blocks
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @gamut_remap: color transformation matrix
 | 
				
			||||||
 | 
					 * @ogam_ram: programmable out gamma LUT
 | 
				
			||||||
 | 
					 * @ocsc: output color space conversion matrix
 | 
				
			||||||
 | 
					 * @num_3dluts: MPC 3D LUT; always assumes a preceding shaper LUT
 | 
				
			||||||
 | 
					 * @shared_3d_lut: shared 3D LUT flag. Can be either DPP or MPC, but single
 | 
				
			||||||
 | 
					 * instance
 | 
				
			||||||
 | 
					 * @ogam_rom_caps: pre-definied curve caps for regamma 1D LUT
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
struct mpc_color_caps {
 | 
					struct mpc_color_caps {
 | 
				
			||||||
	uint16_t gamut_remap : 1;
 | 
						uint16_t gamut_remap : 1;
 | 
				
			||||||
	uint16_t ogam_ram : 1;
 | 
						uint16_t ogam_ram : 1;
 | 
				
			||||||
	uint16_t ocsc : 1;
 | 
						uint16_t ocsc : 1;
 | 
				
			||||||
	uint16_t num_3dluts : 3; //3d lut always assumes a preceding shaper LUT
 | 
						uint16_t num_3dluts : 3;
 | 
				
			||||||
	uint16_t shared_3d_lut:1; //can be in either DPP or MPC, but single instance
 | 
						uint16_t shared_3d_lut:1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct rom_curve_caps ogam_rom_caps;
 | 
						struct rom_curve_caps ogam_rom_caps;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct dc_color_caps - color pipes capabilities for DPP and MPC hw blocks
 | 
				
			||||||
 | 
					 * @dpp: color pipes caps for DPP
 | 
				
			||||||
 | 
					 * @mpc: color pipes caps for MPC
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
struct dc_color_caps {
 | 
					struct dc_color_caps {
 | 
				
			||||||
	struct dpp_color_caps dpp;
 | 
						struct dpp_color_caps dpp;
 | 
				
			||||||
	struct mpc_color_caps mpc;
 | 
						struct mpc_color_caps mpc;
 | 
				
			||||||
| 
						 | 
					@ -350,6 +401,7 @@ struct dc_config {
 | 
				
			||||||
	uint8_t  vblank_alignment_max_frame_time_diff;
 | 
						uint8_t  vblank_alignment_max_frame_time_diff;
 | 
				
			||||||
	bool is_asymmetric_memory;
 | 
						bool is_asymmetric_memory;
 | 
				
			||||||
	bool is_single_rank_dimm;
 | 
						bool is_single_rank_dimm;
 | 
				
			||||||
 | 
						bool is_vmin_only_asic;
 | 
				
			||||||
	bool use_pipe_ctx_sync_logic;
 | 
						bool use_pipe_ctx_sync_logic;
 | 
				
			||||||
	bool ignore_dpref_ss;
 | 
						bool ignore_dpref_ss;
 | 
				
			||||||
	bool enable_mipi_converter_optimization;
 | 
						bool enable_mipi_converter_optimization;
 | 
				
			||||||
| 
						 | 
					@ -365,6 +417,7 @@ enum visual_confirm {
 | 
				
			||||||
	VISUAL_CONFIRM_SWAPCHAIN = 6,
 | 
						VISUAL_CONFIRM_SWAPCHAIN = 6,
 | 
				
			||||||
	VISUAL_CONFIRM_FAMS = 7,
 | 
						VISUAL_CONFIRM_FAMS = 7,
 | 
				
			||||||
	VISUAL_CONFIRM_SWIZZLE = 9,
 | 
						VISUAL_CONFIRM_SWIZZLE = 9,
 | 
				
			||||||
 | 
						VISUAL_CONFIRM_SUBVP = 14,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum dc_psr_power_opts {
 | 
					enum dc_psr_power_opts {
 | 
				
			||||||
| 
						 | 
					@ -386,9 +439,31 @@ enum dcc_option {
 | 
				
			||||||
	DCC_HALF_REQ_DISALBE = 2,
 | 
						DCC_HALF_REQ_DISALBE = 2,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * enum pipe_split_policy - Pipe split strategy supported by DCN
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This enum is used to define the pipe split policy supported by DCN. By
 | 
				
			||||||
 | 
					 * default, DC favors MPC_SPLIT_DYNAMIC.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
enum pipe_split_policy {
 | 
					enum pipe_split_policy {
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @MPC_SPLIT_DYNAMIC: DC will automatically decide how to split the
 | 
				
			||||||
 | 
						 * pipe in order to bring the best trade-off between performance and
 | 
				
			||||||
 | 
						 * power consumption. This is the recommended option.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	MPC_SPLIT_DYNAMIC = 0,
 | 
						MPC_SPLIT_DYNAMIC = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @MPC_SPLIT_DYNAMIC: Avoid pipe split, which means that DC will not
 | 
				
			||||||
 | 
						 * try any sort of split optimization.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	MPC_SPLIT_AVOID = 1,
 | 
						MPC_SPLIT_AVOID = 1,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @MPC_SPLIT_DYNAMIC: With this option, DC will only try to optimize
 | 
				
			||||||
 | 
						 * the pipe utilization when using a single display; if the user
 | 
				
			||||||
 | 
						 * connects to a second display, DC will avoid pipe split.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	MPC_SPLIT_AVOID_MULT_DISP = 2,
 | 
						MPC_SPLIT_AVOID_MULT_DISP = 2,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -623,6 +698,14 @@ struct dc_state;
 | 
				
			||||||
struct resource_pool;
 | 
					struct resource_pool;
 | 
				
			||||||
struct dce_hwseq;
 | 
					struct dce_hwseq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct dc_debug_options - DC debug struct
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This struct provides a simple mechanism for developers to change some
 | 
				
			||||||
 | 
					 * configurations, enable/disable features, and activate extra debug options.
 | 
				
			||||||
 | 
					 * This can be very handy to narrow down whether some specific feature is
 | 
				
			||||||
 | 
					 * causing an issue or not.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
struct dc_debug_options {
 | 
					struct dc_debug_options {
 | 
				
			||||||
	bool native422_support;
 | 
						bool native422_support;
 | 
				
			||||||
	bool disable_dsc;
 | 
						bool disable_dsc;
 | 
				
			||||||
| 
						 | 
					@ -642,6 +725,11 @@ struct dc_debug_options {
 | 
				
			||||||
	bool disable_stutter;
 | 
						bool disable_stutter;
 | 
				
			||||||
	bool use_max_lb;
 | 
						bool use_max_lb;
 | 
				
			||||||
	enum dcc_option disable_dcc;
 | 
						enum dcc_option disable_dcc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @pipe_split_policy: Define which pipe split policy is used by the
 | 
				
			||||||
 | 
						 * display core.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	enum pipe_split_policy pipe_split_policy;
 | 
						enum pipe_split_policy pipe_split_policy;
 | 
				
			||||||
	bool force_single_disp_pipe_split;
 | 
						bool force_single_disp_pipe_split;
 | 
				
			||||||
	bool voltage_align_fclk;
 | 
						bool voltage_align_fclk;
 | 
				
			||||||
| 
						 | 
					@ -715,8 +803,6 @@ struct dc_debug_options {
 | 
				
			||||||
	bool validate_dml_output;
 | 
						bool validate_dml_output;
 | 
				
			||||||
	bool enable_dmcub_surface_flip;
 | 
						bool enable_dmcub_surface_flip;
 | 
				
			||||||
	bool usbc_combo_phy_reset_wa;
 | 
						bool usbc_combo_phy_reset_wa;
 | 
				
			||||||
	bool disable_dsc_edp;
 | 
					 | 
				
			||||||
	unsigned int  force_dsc_edp_policy;
 | 
					 | 
				
			||||||
	bool enable_dram_clock_change_one_display_vactive;
 | 
						bool enable_dram_clock_change_one_display_vactive;
 | 
				
			||||||
	/* TODO - remove once tested */
 | 
						/* TODO - remove once tested */
 | 
				
			||||||
	bool legacy_dp2_lt;
 | 
						bool legacy_dp2_lt;
 | 
				
			||||||
| 
						 | 
					@ -740,7 +826,6 @@ struct dc_debug_options {
 | 
				
			||||||
	int crb_alloc_policy_min_disp_count;
 | 
						int crb_alloc_policy_min_disp_count;
 | 
				
			||||||
	bool disable_z10;
 | 
						bool disable_z10;
 | 
				
			||||||
	bool enable_z9_disable_interface;
 | 
						bool enable_z9_disable_interface;
 | 
				
			||||||
	bool enable_sw_cntl_psr;
 | 
					 | 
				
			||||||
	union dpia_debug_options dpia_debug;
 | 
						union dpia_debug_options dpia_debug;
 | 
				
			||||||
	bool disable_fixed_vs_aux_timeout_wa;
 | 
						bool disable_fixed_vs_aux_timeout_wa;
 | 
				
			||||||
	bool force_disable_subvp;
 | 
						bool force_disable_subvp;
 | 
				
			||||||
| 
						 | 
					@ -759,6 +844,7 @@ struct dc_debug_options {
 | 
				
			||||||
	bool exit_idle_opt_for_cursor_updates;
 | 
						bool exit_idle_opt_for_cursor_updates;
 | 
				
			||||||
	bool enable_single_display_2to1_odm_policy;
 | 
						bool enable_single_display_2to1_odm_policy;
 | 
				
			||||||
	bool enable_dp_dig_pixel_rate_div_policy;
 | 
						bool enable_dp_dig_pixel_rate_div_policy;
 | 
				
			||||||
 | 
						enum lttpr_mode lttpr_mode_override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gpu_info_soc_bounding_box_v1_0;
 | 
					struct gpu_info_soc_bounding_box_v1_0;
 | 
				
			||||||
| 
						 | 
					@ -814,6 +900,17 @@ struct dc {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t *dcn_reg_offsets;
 | 
						uint32_t *dcn_reg_offsets;
 | 
				
			||||||
	uint32_t *nbio_reg_offsets;
 | 
						uint32_t *nbio_reg_offsets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Scratch memory */
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * For matching clock_limits table in driver with table
 | 
				
			||||||
 | 
								 * from PMFW.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
 | 
				
			||||||
 | 
							} update_bw_bounding_box;
 | 
				
			||||||
 | 
						} scratch;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum frame_buffer_mode {
 | 
					enum frame_buffer_mode {
 | 
				
			||||||
| 
						 | 
					@ -1085,6 +1182,7 @@ struct dc_plane_state {
 | 
				
			||||||
	/* private to dc_surface.c */
 | 
						/* private to dc_surface.c */
 | 
				
			||||||
	enum dc_irq_source irq_source;
 | 
						enum dc_irq_source irq_source;
 | 
				
			||||||
	struct kref refcount;
 | 
						struct kref refcount;
 | 
				
			||||||
 | 
						struct tg_color visual_confirm_color;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dc_plane_info {
 | 
					struct dc_plane_info {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -323,11 +323,13 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru
 | 
				
			||||||
	struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data;
 | 
						struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data;
 | 
				
			||||||
	int i = 0;
 | 
						int i = 0;
 | 
				
			||||||
	int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it.
 | 
						int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it.
 | 
				
			||||||
	uint8_t visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
 | 
						uint8_t visual_confirm_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dc == NULL)
 | 
						if (dc == NULL)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Format command.
 | 
						// Format command.
 | 
				
			||||||
	cmd.fw_assisted_mclk_switch.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
 | 
						cmd.fw_assisted_mclk_switch.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
 | 
				
			||||||
	cmd.fw_assisted_mclk_switch.header.sub_type = DMUB_CMD__FAMS_SETUP_FW_CTRL;
 | 
						cmd.fw_assisted_mclk_switch.header.sub_type = DMUB_CMD__FAMS_SETUP_FW_CTRL;
 | 
				
			||||||
| 
						 | 
					@ -387,6 +389,37 @@ void dc_dmub_srv_query_caps_cmd(struct dmub_srv *dmub)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pipe_ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						union dmub_rb_cmd cmd = { 0 };
 | 
				
			||||||
 | 
						enum dmub_status status;
 | 
				
			||||||
 | 
						unsigned int panel_inst = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&cmd, 0, sizeof(cmd));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Prepare fw command
 | 
				
			||||||
 | 
						cmd.visual_confirm_color.header.type = DMUB_CMD__GET_VISUAL_CONFIRM_COLOR;
 | 
				
			||||||
 | 
						cmd.visual_confirm_color.header.sub_type = 0;
 | 
				
			||||||
 | 
						cmd.visual_confirm_color.header.ret_status = 1;
 | 
				
			||||||
 | 
						cmd.visual_confirm_color.header.payload_bytes = sizeof(struct dmub_cmd_visual_confirm_color_data);
 | 
				
			||||||
 | 
						cmd.visual_confirm_color.visual_confirm_color_data.visual_confirm_color.panel_inst = panel_inst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Send command to fw
 | 
				
			||||||
 | 
						status = dmub_srv_cmd_with_reply_data(dc->ctx->dmub_srv->dmub, &cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(status == DMUB_STATUS_OK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If command was processed, copy feature caps to dmub srv
 | 
				
			||||||
 | 
						if (status == DMUB_STATUS_OK &&
 | 
				
			||||||
 | 
							cmd.visual_confirm_color.header.ret_status == 0) {
 | 
				
			||||||
 | 
							memcpy(&dc->ctx->dmub_srv->dmub->visual_confirm_color,
 | 
				
			||||||
 | 
								&cmd.visual_confirm_color.visual_confirm_color_data,
 | 
				
			||||||
 | 
								sizeof(struct dmub_visual_confirm_color));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DRM_AMD_DC_DCN
 | 
					#ifdef CONFIG_DRM_AMD_DC_DCN
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * ***********************************************************************************************
 | 
					 * ***********************************************************************************************
 | 
				
			||||||
| 
						 | 
					@ -601,7 +634,7 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
 | 
				
			||||||
			&cmd->fw_assisted_mclk_switch_v2.config_data.pipe_data[cmd_pipe_index];
 | 
								&cmd->fw_assisted_mclk_switch_v2.config_data.pipe_data[cmd_pipe_index];
 | 
				
			||||||
	struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing;
 | 
						struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing;
 | 
				
			||||||
	struct dc_crtc_timing *phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing;
 | 
						struct dc_crtc_timing *phantom_timing = &subvp_pipe->stream->mall_stream_config.paired_stream->timing;
 | 
				
			||||||
	uint32_t out_num, out_den;
 | 
						uint32_t out_num_stream, out_den_stream, out_num_plane, out_den_plane, out_num, out_den;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe_data->mode = SUBVP;
 | 
						pipe_data->mode = SUBVP;
 | 
				
			||||||
	pipe_data->pipe_config.subvp_data.pix_clk_100hz = subvp_pipe->stream->timing.pix_clk_100hz;
 | 
						pipe_data->pipe_config.subvp_data.pix_clk_100hz = subvp_pipe->stream->timing.pix_clk_100hz;
 | 
				
			||||||
| 
						 | 
					@ -618,11 +651,16 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
 | 
				
			||||||
	/* Calculate the scaling factor from the src and dst height.
 | 
						/* Calculate the scaling factor from the src and dst height.
 | 
				
			||||||
	 * e.g. If 3840x2160 being downscaled to 1920x1080, the scaling factor is 1/2.
 | 
						 * e.g. If 3840x2160 being downscaled to 1920x1080, the scaling factor is 1/2.
 | 
				
			||||||
	 * Reduce the fraction 1080/2160 = 1/2 for the "scaling factor"
 | 
						 * Reduce the fraction 1080/2160 = 1/2 for the "scaling factor"
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Make sure to combine stream and plane scaling together.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	reduce_fraction(subvp_pipe->stream->src.height, subvp_pipe->stream->dst.height, &out_num, &out_den);
 | 
						reduce_fraction(subvp_pipe->stream->src.height, subvp_pipe->stream->dst.height,
 | 
				
			||||||
	// TODO: Uncomment below lines once DMCUB include headers are promoted
 | 
								&out_num_stream, &out_den_stream);
 | 
				
			||||||
	//pipe_data->pipe_config.subvp_data.scale_factor_numerator = out_num;
 | 
						reduce_fraction(subvp_pipe->plane_state->src_rect.height, subvp_pipe->plane_state->dst_rect.height,
 | 
				
			||||||
	//pipe_data->pipe_config.subvp_data.scale_factor_denominator = out_den;
 | 
								&out_num_plane, &out_den_plane);
 | 
				
			||||||
 | 
						reduce_fraction(out_num_stream * out_num_plane, out_den_stream * out_den_plane, &out_num, &out_den);
 | 
				
			||||||
 | 
						pipe_data->pipe_config.subvp_data.scale_factor_numerator = out_num;
 | 
				
			||||||
 | 
						pipe_data->pipe_config.subvp_data.scale_factor_denominator = out_den;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Prefetch lines is equal to VACTIVE + BP + VSYNC
 | 
						// Prefetch lines is equal to VACTIVE + BP + VSYNC
 | 
				
			||||||
	pipe_data->pipe_config.subvp_data.prefetch_lines =
 | 
						pipe_data->pipe_config.subvp_data.prefetch_lines =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||