mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/amd/dc: Add dc display driver (v2)
Supported DCE versions: 8.0, 10.0, 11.0, 11.2 v2: rebase against 4.11 Signed-off-by: Harry Wentland <harry.wentland@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									9c5b2b0d40
								
							
						
					
					
						commit
						4562236b3b
					
				
					 315 changed files with 99491 additions and 37 deletions
				
			
		| 
						 | 
					@ -41,3 +41,4 @@ config DRM_AMDGPU_GART_DEBUGFS
 | 
				
			||||||
	  pages. Uses more memory for housekeeping, enable only for debugging.
 | 
						  pages. Uses more memory for housekeeping, enable only for debugging.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source "drivers/gpu/drm/amd/acp/Kconfig"
 | 
					source "drivers/gpu/drm/amd/acp/Kconfig"
 | 
				
			||||||
 | 
					source "drivers/gpu/drm/amd/display/Kconfig"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,13 +3,19 @@
 | 
				
			||||||
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 | 
					# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FULL_AMD_PATH=$(src)/..
 | 
					FULL_AMD_PATH=$(src)/..
 | 
				
			||||||
 | 
					DISPLAY_FOLDER_NAME=display
 | 
				
			||||||
 | 
					FULL_AMD_DISPLAY_PATH = $(FULL_AMD_PATH)/$(DISPLAY_FOLDER_NAME)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
 | 
					ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
 | 
				
			||||||
	-I$(FULL_AMD_PATH)/include \
 | 
						-I$(FULL_AMD_PATH)/include \
 | 
				
			||||||
	-I$(FULL_AMD_PATH)/amdgpu \
 | 
						-I$(FULL_AMD_PATH)/amdgpu \
 | 
				
			||||||
	-I$(FULL_AMD_PATH)/scheduler \
 | 
						-I$(FULL_AMD_PATH)/scheduler \
 | 
				
			||||||
	-I$(FULL_AMD_PATH)/powerplay/inc \
 | 
						-I$(FULL_AMD_PATH)/powerplay/inc \
 | 
				
			||||||
	-I$(FULL_AMD_PATH)/acp/include
 | 
						-I$(FULL_AMD_PATH)/acp/include \
 | 
				
			||||||
 | 
						-I$(FULL_AMD_DISPLAY_PATH) \
 | 
				
			||||||
 | 
						-I$(FULL_AMD_DISPLAY_PATH)/include \
 | 
				
			||||||
 | 
						-I$(FULL_AMD_DISPLAY_PATH)/dc \
 | 
				
			||||||
 | 
						-I$(FULL_AMD_DISPLAY_PATH)/amdgpu_dm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
amdgpu-y := amdgpu_drv.o
 | 
					amdgpu-y := amdgpu_drv.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,4 +138,13 @@ include $(FULL_AMD_PATH)/powerplay/Makefile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
amdgpu-y += $(AMD_POWERPLAY_FILES)
 | 
					amdgpu-y += $(AMD_POWERPLAY_FILES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifneq ($(CONFIG_DRM_AMD_DC),)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RELATIVE_AMD_DISPLAY_PATH = ../$(DISPLAY_FOLDER_NAME)
 | 
				
			||||||
 | 
					include $(FULL_AMD_DISPLAY_PATH)/Makefile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					amdgpu-y += $(AMD_DISPLAY_FILES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o
 | 
					obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,6 +66,7 @@
 | 
				
			||||||
#include "amdgpu_vce.h"
 | 
					#include "amdgpu_vce.h"
 | 
				
			||||||
#include "amdgpu_vcn.h"
 | 
					#include "amdgpu_vcn.h"
 | 
				
			||||||
#include "amdgpu_mn.h"
 | 
					#include "amdgpu_mn.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gpu_scheduler.h"
 | 
					#include "gpu_scheduler.h"
 | 
				
			||||||
#include "amdgpu_virt.h"
 | 
					#include "amdgpu_virt.h"
 | 
				
			||||||
| 
						 | 
					@ -101,6 +102,7 @@ extern int amdgpu_vm_fragment_size;
 | 
				
			||||||
extern int amdgpu_vm_fault_stop;
 | 
					extern int amdgpu_vm_fault_stop;
 | 
				
			||||||
extern int amdgpu_vm_debug;
 | 
					extern int amdgpu_vm_debug;
 | 
				
			||||||
extern int amdgpu_vm_update_mode;
 | 
					extern int amdgpu_vm_update_mode;
 | 
				
			||||||
 | 
					extern int amdgpu_dc;
 | 
				
			||||||
extern int amdgpu_sched_jobs;
 | 
					extern int amdgpu_sched_jobs;
 | 
				
			||||||
extern int amdgpu_sched_hw_submission;
 | 
					extern int amdgpu_sched_hw_submission;
 | 
				
			||||||
extern int amdgpu_no_evict;
 | 
					extern int amdgpu_no_evict;
 | 
				
			||||||
| 
						 | 
					@ -1507,6 +1509,7 @@ struct amdgpu_device {
 | 
				
			||||||
	/* display */
 | 
						/* display */
 | 
				
			||||||
	bool				enable_virtual_display;
 | 
						bool				enable_virtual_display;
 | 
				
			||||||
	struct amdgpu_mode_info		mode_info;
 | 
						struct amdgpu_mode_info		mode_info;
 | 
				
			||||||
 | 
						/* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
 | 
				
			||||||
	struct work_struct		hotplug_work;
 | 
						struct work_struct		hotplug_work;
 | 
				
			||||||
	struct amdgpu_irq_src		crtc_irq;
 | 
						struct amdgpu_irq_src		crtc_irq;
 | 
				
			||||||
	struct amdgpu_irq_src		pageflip_irq;
 | 
						struct amdgpu_irq_src		pageflip_irq;
 | 
				
			||||||
| 
						 | 
					@ -1563,6 +1566,9 @@ struct amdgpu_device {
 | 
				
			||||||
	/* GDS */
 | 
						/* GDS */
 | 
				
			||||||
	struct amdgpu_gds		gds;
 | 
						struct amdgpu_gds		gds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* display related functionality */
 | 
				
			||||||
 | 
						struct amdgpu_display_manager dm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct amdgpu_ip_block          ip_blocks[AMDGPU_MAX_IP_NUM];
 | 
						struct amdgpu_ip_block          ip_blocks[AMDGPU_MAX_IP_NUM];
 | 
				
			||||||
	int				num_ip_blocks;
 | 
						int				num_ip_blocks;
 | 
				
			||||||
	struct mutex	mn_lock;
 | 
						struct mutex	mn_lock;
 | 
				
			||||||
| 
						 | 
					@ -1624,6 +1630,9 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
 | 
				
			||||||
u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
 | 
					u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
 | 
				
			||||||
void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
 | 
					void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);
 | 
				
			||||||
 | 
					bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Registers read & write functions.
 | 
					 * Registers read & write functions.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1884,5 +1893,11 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
 | 
				
			||||||
			   uint64_t addr, struct amdgpu_bo **bo,
 | 
								   uint64_t addr, struct amdgpu_bo **bo,
 | 
				
			||||||
			   struct amdgpu_bo_va_mapping **mapping);
 | 
								   struct amdgpu_bo_va_mapping **mapping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
					int amdgpu_dm_display_resume(struct amdgpu_device *adev );
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline int amdgpu_dm_display_resume(struct amdgpu_device *adev) { return 0; }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "amdgpu_object.h"
 | 
					#include "amdgpu_object.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@
 | 
				
			||||||
#include <linux/debugfs.h>
 | 
					#include <linux/debugfs.h>
 | 
				
			||||||
#include <drm/drmP.h>
 | 
					#include <drm/drmP.h>
 | 
				
			||||||
#include <drm/drm_crtc_helper.h>
 | 
					#include <drm/drm_crtc_helper.h>
 | 
				
			||||||
 | 
					#include <drm/drm_atomic_helper.h>
 | 
				
			||||||
#include <drm/amdgpu_drm.h>
 | 
					#include <drm/amdgpu_drm.h>
 | 
				
			||||||
#include <linux/vgaarb.h>
 | 
					#include <linux/vgaarb.h>
 | 
				
			||||||
#include <linux/vga_switcheroo.h>
 | 
					#include <linux/vga_switcheroo.h>
 | 
				
			||||||
| 
						 | 
					@ -1973,6 +1974,41 @@ static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (asic_type) {
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
						case CHIP_BONAIRE:
 | 
				
			||||||
 | 
						case CHIP_HAWAII:
 | 
				
			||||||
 | 
						case CHIP_CARRIZO:
 | 
				
			||||||
 | 
						case CHIP_STONEY:
 | 
				
			||||||
 | 
						case CHIP_POLARIS11:
 | 
				
			||||||
 | 
						case CHIP_POLARIS10:
 | 
				
			||||||
 | 
						case CHIP_TONGA:
 | 
				
			||||||
 | 
						case CHIP_FIJI:
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC_PRE_VEGA)
 | 
				
			||||||
 | 
							return amdgpu_dc != 0;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							return amdgpu_dc > 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_device_has_dc_support - check if dc is supported
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @adev: amdgpu_device_pointer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns true for supported, false for not supported
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool amdgpu_device_has_dc_support(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return amdgpu_device_asic_has_dc_support(adev->asic_type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * amdgpu_device_init - initialize the driver
 | 
					 * amdgpu_device_init - initialize the driver
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -2168,7 +2204,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 | 
				
			||||||
			goto failed;
 | 
								goto failed;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/* init i2c buses */
 | 
							/* init i2c buses */
 | 
				
			||||||
		amdgpu_atombios_i2c_init(adev);
 | 
							if (!amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_atombios_i2c_init(adev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Fence driver */
 | 
						/* Fence driver */
 | 
				
			||||||
| 
						 | 
					@ -2296,7 +2333,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
 | 
				
			||||||
	adev->accel_working = false;
 | 
						adev->accel_working = false;
 | 
				
			||||||
	cancel_delayed_work_sync(&adev->late_init_work);
 | 
						cancel_delayed_work_sync(&adev->late_init_work);
 | 
				
			||||||
	/* free i2c buses */
 | 
						/* free i2c buses */
 | 
				
			||||||
	amdgpu_i2c_fini(adev);
 | 
						if (!amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
							amdgpu_i2c_fini(adev);
 | 
				
			||||||
	amdgpu_atombios_fini(adev);
 | 
						amdgpu_atombios_fini(adev);
 | 
				
			||||||
	kfree(adev->bios);
 | 
						kfree(adev->bios);
 | 
				
			||||||
	adev->bios = NULL;
 | 
						adev->bios = NULL;
 | 
				
			||||||
| 
						 | 
					@ -2346,12 +2384,14 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drm_kms_helper_poll_disable(dev);
 | 
						drm_kms_helper_poll_disable(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* turn off display hw */
 | 
						if (!amdgpu_device_has_dc_support(adev)) {
 | 
				
			||||||
	drm_modeset_lock_all(dev);
 | 
							/* turn off display hw */
 | 
				
			||||||
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
							drm_modeset_lock_all(dev);
 | 
				
			||||||
		drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
 | 
							list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
								drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							drm_modeset_unlock_all(dev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	drm_modeset_unlock_all(dev);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amdgpu_amdkfd_suspend(adev);
 | 
						amdgpu_amdkfd_suspend(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2494,13 +2534,25 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* blat the mode back in */
 | 
						/* blat the mode back in */
 | 
				
			||||||
	if (fbcon) {
 | 
						if (fbcon) {
 | 
				
			||||||
		drm_helper_resume_force_mode(dev);
 | 
							if (!amdgpu_device_has_dc_support(adev)) {
 | 
				
			||||||
		/* turn on display hw */
 | 
								/* pre DCE11 */
 | 
				
			||||||
		drm_modeset_lock_all(dev);
 | 
								drm_helper_resume_force_mode(dev);
 | 
				
			||||||
		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
					
 | 
				
			||||||
			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
 | 
								/* turn on display hw */
 | 
				
			||||||
 | 
								drm_modeset_lock_all(dev);
 | 
				
			||||||
 | 
								list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
									drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								drm_modeset_unlock_all(dev);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * There is no equivalent atomic helper to turn on
 | 
				
			||||||
 | 
								 * display, so we defined our own function for this,
 | 
				
			||||||
 | 
								 * once suspend resume is supported by the atomic
 | 
				
			||||||
 | 
								 * framework this will be reworked
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								amdgpu_dm_display_resume(adev);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		drm_modeset_unlock_all(dev);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drm_kms_helper_poll_enable(dev);
 | 
						drm_kms_helper_poll_enable(dev);
 | 
				
			||||||
| 
						 | 
					@ -2517,7 +2569,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
 | 
				
			||||||
#ifdef CONFIG_PM
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
	dev->dev->power.disable_depth++;
 | 
						dev->dev->power.disable_depth++;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	drm_helper_hpd_irq_event(dev);
 | 
						if (!amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
							drm_helper_hpd_irq_event(dev);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							drm_kms_helper_hotplug_event(dev);
 | 
				
			||||||
#ifdef CONFIG_PM
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
	dev->dev->power.disable_depth--;
 | 
						dev->dev->power.disable_depth--;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -2814,6 +2869,7 @@ int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int amdgpu_gpu_reset(struct amdgpu_device *adev)
 | 
					int amdgpu_gpu_reset(struct amdgpu_device *adev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct drm_atomic_state *state = NULL;
 | 
				
			||||||
	int i, r;
 | 
						int i, r;
 | 
				
			||||||
	int resched;
 | 
						int resched;
 | 
				
			||||||
	bool need_full_reset, vram_lost = false;
 | 
						bool need_full_reset, vram_lost = false;
 | 
				
			||||||
| 
						 | 
					@ -2827,6 +2883,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* block TTM */
 | 
						/* block TTM */
 | 
				
			||||||
	resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
 | 
						resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
 | 
				
			||||||
 | 
						/* store modesetting */
 | 
				
			||||||
 | 
						if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
							state = drm_atomic_helper_suspend(adev->ddev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* block scheduler */
 | 
						/* block scheduler */
 | 
				
			||||||
	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
 | 
						for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
 | 
				
			||||||
| 
						 | 
					@ -2944,7 +3003,11 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drm_helper_resume_force_mode(adev->ddev);
 | 
						if (amdgpu_device_has_dc_support(adev)) {
 | 
				
			||||||
 | 
							r = drm_atomic_helper_resume(adev->ddev, state);
 | 
				
			||||||
 | 
							amdgpu_dm_display_resume(adev);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							drm_helper_resume_force_mode(adev->ddev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
 | 
						ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
 | 
				
			||||||
	if (r) {
 | 
						if (r) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -429,7 +429,7 @@ struct amdgpu_pm {
 | 
				
			||||||
	uint32_t                fw_version;
 | 
						uint32_t                fw_version;
 | 
				
			||||||
	uint32_t                pcie_gen_mask;
 | 
						uint32_t                pcie_gen_mask;
 | 
				
			||||||
	uint32_t                pcie_mlw_mask;
 | 
						uint32_t                pcie_mlw_mask;
 | 
				
			||||||
	struct amd_pp_display_configuration pm_display_cfg;/* set by DAL */
 | 
						struct amd_pp_display_configuration pm_display_cfg;/* set by dc */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define R600_SSTU_DFLT                               0
 | 
					#define R600_SSTU_DFLT                               0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,6 +103,7 @@ int amdgpu_vm_debug = 0;
 | 
				
			||||||
int amdgpu_vram_page_split = 512;
 | 
					int amdgpu_vram_page_split = 512;
 | 
				
			||||||
int amdgpu_vm_update_mode = -1;
 | 
					int amdgpu_vm_update_mode = -1;
 | 
				
			||||||
int amdgpu_exp_hw_support = 0;
 | 
					int amdgpu_exp_hw_support = 0;
 | 
				
			||||||
 | 
					int amdgpu_dc = -1;
 | 
				
			||||||
int amdgpu_sched_jobs = 32;
 | 
					int amdgpu_sched_jobs = 32;
 | 
				
			||||||
int amdgpu_sched_hw_submission = 2;
 | 
					int amdgpu_sched_hw_submission = 2;
 | 
				
			||||||
int amdgpu_no_evict = 0;
 | 
					int amdgpu_no_evict = 0;
 | 
				
			||||||
| 
						 | 
					@ -207,6 +208,9 @@ module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
 | 
				
			||||||
MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
 | 
					MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
 | 
				
			||||||
module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
 | 
					module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODULE_PARM_DESC(dc, "Display Core driver (1 = enable, 0 = disable, -1 = auto (default))");
 | 
				
			||||||
 | 
					module_param_named(dc, amdgpu_dc, int, 0444);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)");
 | 
					MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)");
 | 
				
			||||||
module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444);
 | 
					module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,11 +42,6 @@
 | 
				
			||||||
   this contains a helper + a amdgpu fb
 | 
					   this contains a helper + a amdgpu fb
 | 
				
			||||||
   the helper contains a pointer to amdgpu framebuffer baseclass.
 | 
					   the helper contains a pointer to amdgpu framebuffer baseclass.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
struct amdgpu_fbdev {
 | 
					 | 
				
			||||||
	struct drm_fb_helper helper;
 | 
					 | 
				
			||||||
	struct amdgpu_framebuffer rfb;
 | 
					 | 
				
			||||||
	struct amdgpu_device *adev;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
amdgpufb_open(struct fb_info *info, int user)
 | 
					amdgpufb_open(struct fb_info *info, int user)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/pm_runtime.h>
 | 
					#include <linux/pm_runtime.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DRM_AMD_DC
 | 
				
			||||||
 | 
					#include "amdgpu_dm_irq.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define AMDGPU_WAIT_IDLE_TIMEOUT 200
 | 
					#define AMDGPU_WAIT_IDLE_TIMEOUT 200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -221,15 +225,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_init(&adev->irq.lock);
 | 
						spin_lock_init(&adev->irq.lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!adev->enable_virtual_display)
 | 
					 | 
				
			||||||
		/* Disable vblank irqs aggressively for power-saving */
 | 
					 | 
				
			||||||
		adev->ddev->vblank_disable_immediate = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc);
 | 
					 | 
				
			||||||
	if (r) {
 | 
					 | 
				
			||||||
		return r;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* enable msi */
 | 
						/* enable msi */
 | 
				
			||||||
	adev->irq.msi_enabled = false;
 | 
						adev->irq.msi_enabled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -241,7 +236,21 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_WORK(&adev->hotplug_work, amdgpu_hotplug_work_func);
 | 
						if (!amdgpu_device_has_dc_support(adev)) {
 | 
				
			||||||
 | 
							if (!adev->enable_virtual_display)
 | 
				
			||||||
 | 
								/* Disable vblank irqs aggressively for power-saving */
 | 
				
			||||||
 | 
								/* XXX: can this be enabled for DC? */
 | 
				
			||||||
 | 
								adev->ddev->vblank_disable_immediate = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc);
 | 
				
			||||||
 | 
							if (r)
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* pre DCE11 */
 | 
				
			||||||
 | 
							INIT_WORK(&adev->hotplug_work,
 | 
				
			||||||
 | 
									amdgpu_hotplug_work_func);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_WORK(&adev->reset_work, amdgpu_irq_reset_work_func);
 | 
						INIT_WORK(&adev->reset_work, amdgpu_irq_reset_work_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adev->irq.installed = true;
 | 
						adev->irq.installed = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1034,7 +1034,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
 | 
				
			||||||
	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 | 
						DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 | 
				
			||||||
	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 | 
						DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 | 
				
			||||||
	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 | 
						DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 | 
				
			||||||
	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 | 
						DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW)
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms);
 | 
					const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,11 +38,15 @@
 | 
				
			||||||
#include <drm/drm_crtc_helper.h>
 | 
					#include <drm/drm_crtc_helper.h>
 | 
				
			||||||
#include <drm/drm_fb_helper.h>
 | 
					#include <drm/drm_fb_helper.h>
 | 
				
			||||||
#include <drm/drm_plane_helper.h>
 | 
					#include <drm/drm_plane_helper.h>
 | 
				
			||||||
 | 
					#include <drm/drm_fb_helper.h>
 | 
				
			||||||
#include <linux/i2c.h>
 | 
					#include <linux/i2c.h>
 | 
				
			||||||
#include <linux/i2c-algo-bit.h>
 | 
					#include <linux/i2c-algo-bit.h>
 | 
				
			||||||
#include <linux/hrtimer.h>
 | 
					#include <linux/hrtimer.h>
 | 
				
			||||||
#include "amdgpu_irq.h"
 | 
					#include "amdgpu_irq.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <drm/drm_dp_mst_helper.h>
 | 
				
			||||||
 | 
					#include "modules/inc/mod_freesync.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_bo;
 | 
					struct amdgpu_bo;
 | 
				
			||||||
struct amdgpu_device;
 | 
					struct amdgpu_device;
 | 
				
			||||||
struct amdgpu_encoder;
 | 
					struct amdgpu_encoder;
 | 
				
			||||||
| 
						 | 
					@ -292,6 +296,27 @@ struct amdgpu_display_funcs {
 | 
				
			||||||
			      uint16_t connector_object_id,
 | 
								      uint16_t connector_object_id,
 | 
				
			||||||
			      struct amdgpu_hpd *hpd,
 | 
								      struct amdgpu_hpd *hpd,
 | 
				
			||||||
			      struct amdgpu_router *router);
 | 
								      struct amdgpu_router *router);
 | 
				
			||||||
 | 
						/* it is used to enter or exit into free sync mode */
 | 
				
			||||||
 | 
						int (*notify_freesync)(struct drm_device *dev, void *data,
 | 
				
			||||||
 | 
								       struct drm_file *filp);
 | 
				
			||||||
 | 
						/* it is used to allow enablement of freesync mode */
 | 
				
			||||||
 | 
						int (*set_freesync_property)(struct drm_connector *connector,
 | 
				
			||||||
 | 
									     struct drm_property *property,
 | 
				
			||||||
 | 
									     uint64_t val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_framebuffer {
 | 
				
			||||||
 | 
						struct drm_framebuffer base;
 | 
				
			||||||
 | 
						struct drm_gem_object *obj;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_fbdev {
 | 
				
			||||||
 | 
						struct drm_fb_helper helper;
 | 
				
			||||||
 | 
						struct amdgpu_framebuffer rfb;
 | 
				
			||||||
 | 
						struct list_head fbdev_list;
 | 
				
			||||||
 | 
						struct amdgpu_device *adev;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_mode_info {
 | 
					struct amdgpu_mode_info {
 | 
				
			||||||
| 
						 | 
					@ -400,6 +425,11 @@ struct amdgpu_crtc {
 | 
				
			||||||
	/* for virtual dce */
 | 
						/* for virtual dce */
 | 
				
			||||||
	struct hrtimer vblank_timer;
 | 
						struct hrtimer vblank_timer;
 | 
				
			||||||
	enum amdgpu_interrupt_state vsync_timer_enabled;
 | 
						enum amdgpu_interrupt_state vsync_timer_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int otg_inst;
 | 
				
			||||||
 | 
						uint32_t flip_flags;
 | 
				
			||||||
 | 
						/* After Set Mode target will be non-NULL */
 | 
				
			||||||
 | 
						struct dc_target *target;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_encoder_atom_dig {
 | 
					struct amdgpu_encoder_atom_dig {
 | 
				
			||||||
| 
						 | 
					@ -489,6 +519,19 @@ enum amdgpu_connector_dither {
 | 
				
			||||||
	AMDGPU_FMT_DITHER_ENABLE = 1,
 | 
						AMDGPU_FMT_DITHER_ENABLE = 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_dm_dp_aux {
 | 
				
			||||||
 | 
						struct drm_dp_aux aux;
 | 
				
			||||||
 | 
						uint32_t link_index;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_i2c_adapter {
 | 
				
			||||||
 | 
						struct i2c_adapter base;
 | 
				
			||||||
 | 
						struct amdgpu_display_manager *dm;
 | 
				
			||||||
 | 
						uint32_t link_index;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TO_DM_AUX(x) container_of((x), struct amdgpu_dm_dp_aux, aux)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_connector {
 | 
					struct amdgpu_connector {
 | 
				
			||||||
	struct drm_connector base;
 | 
						struct drm_connector base;
 | 
				
			||||||
	uint32_t connector_id;
 | 
						uint32_t connector_id;
 | 
				
			||||||
| 
						 | 
					@ -500,6 +543,14 @@ struct amdgpu_connector {
 | 
				
			||||||
	/* we need to mind the EDID between detect
 | 
						/* we need to mind the EDID between detect
 | 
				
			||||||
	   and get modes due to analog/digital/tvencoder */
 | 
						   and get modes due to analog/digital/tvencoder */
 | 
				
			||||||
	struct edid *edid;
 | 
						struct edid *edid;
 | 
				
			||||||
 | 
						/* number of modes generated from EDID at 'dc_sink' */
 | 
				
			||||||
 | 
						int num_modes;
 | 
				
			||||||
 | 
						/* The 'old' sink - before an HPD.
 | 
				
			||||||
 | 
						 * The 'current' sink is in dc_link->sink. */
 | 
				
			||||||
 | 
						const struct dc_sink *dc_sink;
 | 
				
			||||||
 | 
						const struct dc_link *dc_link;
 | 
				
			||||||
 | 
						const struct dc_sink *dc_em_sink;
 | 
				
			||||||
 | 
						const struct dc_target *target;
 | 
				
			||||||
	void *con_priv;
 | 
						void *con_priv;
 | 
				
			||||||
	bool dac_load_detect;
 | 
						bool dac_load_detect;
 | 
				
			||||||
	bool detected_by_load; /* if the connection status was determined by load */
 | 
						bool detected_by_load; /* if the connection status was determined by load */
 | 
				
			||||||
| 
						 | 
					@ -510,11 +561,39 @@ struct amdgpu_connector {
 | 
				
			||||||
	enum amdgpu_connector_audio audio;
 | 
						enum amdgpu_connector_audio audio;
 | 
				
			||||||
	enum amdgpu_connector_dither dither;
 | 
						enum amdgpu_connector_dither dither;
 | 
				
			||||||
	unsigned pixelclock_for_modeset;
 | 
						unsigned pixelclock_for_modeset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_mgr mst_mgr;
 | 
				
			||||||
 | 
						struct amdgpu_dm_dp_aux dm_dp_aux;
 | 
				
			||||||
 | 
						struct drm_dp_mst_port *port;
 | 
				
			||||||
 | 
						struct amdgpu_connector *mst_port;
 | 
				
			||||||
 | 
						struct amdgpu_encoder *mst_encoder;
 | 
				
			||||||
 | 
						struct semaphore mst_sem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO see if we can merge with ddc_bus or make a dm_connector */
 | 
				
			||||||
 | 
						struct amdgpu_i2c_adapter *i2c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Monitor range limits */
 | 
				
			||||||
 | 
						int min_vfreq ;
 | 
				
			||||||
 | 
						int max_vfreq ;
 | 
				
			||||||
 | 
						int pixel_clock_mhz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*freesync caps*/
 | 
				
			||||||
 | 
						struct mod_freesync_caps caps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct mutex hpd_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct amdgpu_framebuffer {
 | 
					/* TODO: start to use this struct and remove same field from base one */
 | 
				
			||||||
	struct drm_framebuffer base;
 | 
					struct amdgpu_mst_connector {
 | 
				
			||||||
	struct drm_gem_object *obj;
 | 
						struct amdgpu_connector base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_mgr mst_mgr;
 | 
				
			||||||
 | 
						struct amdgpu_dm_dp_aux dm_dp_aux;
 | 
				
			||||||
 | 
						struct drm_dp_mst_port *port;
 | 
				
			||||||
 | 
						struct amdgpu_connector *mst_port;
 | 
				
			||||||
 | 
						bool is_mst_connector;
 | 
				
			||||||
 | 
						struct amdgpu_encoder *mst_encoder;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \
 | 
					#define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1467,7 +1467,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
 | 
				
			||||||
			list_for_each_entry(crtc,
 | 
								list_for_each_entry(crtc,
 | 
				
			||||||
					    &ddev->mode_config.crtc_list, head) {
 | 
										    &ddev->mode_config.crtc_list, head) {
 | 
				
			||||||
				amdgpu_crtc = to_amdgpu_crtc(crtc);
 | 
									amdgpu_crtc = to_amdgpu_crtc(crtc);
 | 
				
			||||||
				if (crtc->enabled) {
 | 
									if (amdgpu_crtc->enabled) {
 | 
				
			||||||
					adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
 | 
										adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
 | 
				
			||||||
					adev->pm.dpm.new_active_crtc_count++;
 | 
										adev->pm.dpm.new_active_crtc_count++;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,7 @@
 | 
				
			||||||
#include "oss/oss_2_0_d.h"
 | 
					#include "oss/oss_2_0_d.h"
 | 
				
			||||||
#include "oss/oss_2_0_sh_mask.h"
 | 
					#include "oss/oss_2_0_sh_mask.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "amdgpu_dm.h"
 | 
				
			||||||
#include "amdgpu_amdkfd.h"
 | 
					#include "amdgpu_amdkfd.h"
 | 
				
			||||||
#include "amdgpu_powerplay.h"
 | 
					#include "amdgpu_powerplay.h"
 | 
				
			||||||
#include "dce_virtual.h"
 | 
					#include "dce_virtual.h"
 | 
				
			||||||
| 
						 | 
					@ -1900,6 +1901,10 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
							amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
				
			||||||
		if (adev->enable_virtual_display)
 | 
							if (adev->enable_virtual_display)
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
							else if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_ip_block_add(adev, &dm_ip_block);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_v8_2_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_v8_2_ip_block);
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &gfx_v7_2_ip_block);
 | 
							amdgpu_ip_block_add(adev, &gfx_v7_2_ip_block);
 | 
				
			||||||
| 
						 | 
					@ -1914,6 +1919,10 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
							amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
				
			||||||
		if (adev->enable_virtual_display)
 | 
							if (adev->enable_virtual_display)
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
							else if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_ip_block_add(adev, &dm_ip_block);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_v8_5_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_v8_5_ip_block);
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &gfx_v7_3_ip_block);
 | 
							amdgpu_ip_block_add(adev, &gfx_v7_3_ip_block);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,6 +77,7 @@
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include "dce_virtual.h"
 | 
					#include "dce_virtual.h"
 | 
				
			||||||
#include "mxgpu_vi.h"
 | 
					#include "mxgpu_vi.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Indirect registers accessor
 | 
					 * Indirect registers accessor
 | 
				
			||||||
| 
						 | 
					@ -1496,6 +1497,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
							amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
				
			||||||
		if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
 | 
							if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
							else if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_ip_block_add(adev, &dm_ip_block);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_v10_1_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_v10_1_ip_block);
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
							amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
				
			||||||
| 
						 | 
					@ -1512,6 +1517,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
							amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
				
			||||||
		if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
 | 
							if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
							else if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_ip_block_add(adev, &dm_ip_block);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_v10_0_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_v10_0_ip_block);
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
							amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
				
			||||||
| 
						 | 
					@ -1530,6 +1539,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
							amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
				
			||||||
		if (adev->enable_virtual_display)
 | 
							if (adev->enable_virtual_display)
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
							else if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_ip_block_add(adev, &dm_ip_block);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_v11_2_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_v11_2_ip_block);
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
							amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
				
			||||||
| 
						 | 
					@ -1544,6 +1557,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
							amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
				
			||||||
		if (adev->enable_virtual_display)
 | 
							if (adev->enable_virtual_display)
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
							else if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_ip_block_add(adev, &dm_ip_block);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_v11_0_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_v11_0_ip_block);
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
							amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block);
 | 
				
			||||||
| 
						 | 
					@ -1561,6 +1578,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
							amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block);
 | 
				
			||||||
		if (adev->enable_virtual_display)
 | 
							if (adev->enable_virtual_display)
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_virtual_ip_block);
 | 
				
			||||||
 | 
					#if defined(CONFIG_DRM_AMD_DC)
 | 
				
			||||||
 | 
							else if (amdgpu_device_has_dc_support(adev))
 | 
				
			||||||
 | 
								amdgpu_ip_block_add(adev, &dm_ip_block);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			amdgpu_ip_block_add(adev, &dce_v11_0_ip_block);
 | 
								amdgpu_ip_block_add(adev, &dce_v11_0_ip_block);
 | 
				
			||||||
		amdgpu_ip_block_add(adev, &gfx_v8_1_ip_block);
 | 
							amdgpu_ip_block_add(adev, &gfx_v8_1_ip_block);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										28
									
								
								drivers/gpu/drm/amd/display/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								drivers/gpu/drm/amd/display/Kconfig
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					menu "Display Engine Configuration"
 | 
				
			||||||
 | 
						depends on DRM && DRM_AMDGPU
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config DRM_AMD_DC
 | 
				
			||||||
 | 
						bool "AMD DC - Enable new display engine"
 | 
				
			||||||
 | 
						default y
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Choose this option if you want to use the new display engine
 | 
				
			||||||
 | 
						  support for AMDGPU. This adds required support for Vega and
 | 
				
			||||||
 | 
						  Raven ASICs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config DRM_AMD_DC_PRE_VEGA
 | 
				
			||||||
 | 
						bool "DC support for Polaris and older ASICs"
 | 
				
			||||||
 | 
						default n
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Choose this option to enable the new DC support for older asics
 | 
				
			||||||
 | 
						  by default. This includes Polaris, Carrizo, Tonga, Bonaire,
 | 
				
			||||||
 | 
						  and Hawaii.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config DEBUG_KERNEL_DC
 | 
				
			||||||
 | 
						bool "Enable kgdb break in DC"
 | 
				
			||||||
 | 
						depends on DRM_AMD_DC
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Choose this option
 | 
				
			||||||
 | 
						  if you want to hit
 | 
				
			||||||
 | 
						  kdgb_break in assert.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmenu
 | 
				
			||||||
							
								
								
									
										22
									
								
								drivers/gpu/drm/amd/display/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								drivers/gpu/drm/amd/display/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for the DAL (Display Abstract Layer), which is a  sub-component
 | 
				
			||||||
 | 
					# of the AMDGPU drm driver.
 | 
				
			||||||
 | 
					# It provides the HW control for display related functionalities.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMDDALPATH = $(RELATIVE_AMD_DISPLAY_PATH)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					subdir-ccflags-y += -I$(AMDDALPATH)/ -I$(AMDDALPATH)/include
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/
 | 
				
			||||||
 | 
					subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/hw
 | 
				
			||||||
 | 
					subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/inc
 | 
				
			||||||
 | 
					subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/freesync
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#TODO: remove when Timing Sync feature is complete
 | 
				
			||||||
 | 
					subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DAL_LIBS = amdgpu_dm dc	modules/freesync
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/,$(DAL_LIBS)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(AMD_DAL)
 | 
				
			||||||
							
								
								
									
										17
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for the 'dm' sub-component of DAL.
 | 
				
			||||||
 | 
					# It provides the control and status of dm blocks.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMDGPUDM = amdgpu_dm_types.o amdgpu_dm.o amdgpu_dm_irq.o amdgpu_dm_mst_types.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifneq ($(CONFIG_DRM_AMD_DC),)
 | 
				
			||||||
 | 
					AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMDGPU_DM = $(addprefix $(AMDDALPATH)/amdgpu_dm/,$(AMDGPUDM))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMDGPU_DM)
 | 
				
			||||||
							
								
								
									
										1564
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1564
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										171
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,171 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __AMDGPU_DM_H__
 | 
				
			||||||
 | 
					#define __AMDGPU_DM_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					#include "linux/switch.h"
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This file contains the definition for amdgpu_display_manager
 | 
				
			||||||
 | 
					 * and its API for amdgpu driver's use.
 | 
				
			||||||
 | 
					 * This component provides all the display related functionality
 | 
				
			||||||
 | 
					 * and this is the only component that calls DAL API.
 | 
				
			||||||
 | 
					 * The API contained here intended for amdgpu driver use.
 | 
				
			||||||
 | 
					 * The API that is called directly from KMS framework is located
 | 
				
			||||||
 | 
					 * in amdgpu_dm_kms.h file
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AMDGPU_DM_MAX_DISPLAY_INDEX 31
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					#include "include/amdgpu_dal_power_if.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_irq.h"
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "irq_types.h"
 | 
				
			||||||
 | 
					#include "signal_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Forward declarations */
 | 
				
			||||||
 | 
					struct amdgpu_device;
 | 
				
			||||||
 | 
					struct drm_device;
 | 
				
			||||||
 | 
					struct amdgpu_dm_irq_handler_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_dm_prev_state {
 | 
				
			||||||
 | 
						struct drm_framebuffer *fb;
 | 
				
			||||||
 | 
						int32_t x;
 | 
				
			||||||
 | 
						int32_t y;
 | 
				
			||||||
 | 
						struct drm_display_mode mode;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct common_irq_params {
 | 
				
			||||||
 | 
						struct amdgpu_device *adev;
 | 
				
			||||||
 | 
						enum dc_irq_source irq_src;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct irq_list_head {
 | 
				
			||||||
 | 
						struct list_head head;
 | 
				
			||||||
 | 
						/* In case this interrupt needs post-processing, 'work' will be queued*/
 | 
				
			||||||
 | 
						struct work_struct work;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_display_manager {
 | 
				
			||||||
 | 
						struct dal *dal;
 | 
				
			||||||
 | 
						struct dc *dc;
 | 
				
			||||||
 | 
						struct cgs_device *cgs_device;
 | 
				
			||||||
 | 
						/* lock to be used when DAL is called from SYNC IRQ context */
 | 
				
			||||||
 | 
						spinlock_t dal_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct amdgpu_device *adev;	/*AMD base driver*/
 | 
				
			||||||
 | 
						struct drm_device *ddev;	/*DRM base driver*/
 | 
				
			||||||
 | 
						u16 display_indexes_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct amdgpu_dm_prev_state prev_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * 'irq_source_handler_table' holds a list of handlers
 | 
				
			||||||
 | 
						 * per (DAL) IRQ source.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Each IRQ source may need to be handled at different contexts.
 | 
				
			||||||
 | 
						 * By 'context' we mean, for example:
 | 
				
			||||||
 | 
						 * - The ISR context, which is the direct interrupt handler.
 | 
				
			||||||
 | 
						 * - The 'deferred' context - this is the post-processing of the
 | 
				
			||||||
 | 
						 *	interrupt, but at a lower priority.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Note that handlers are called in the same order as they were
 | 
				
			||||||
 | 
						 * registered (FIFO).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct irq_list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
 | 
				
			||||||
 | 
						struct list_head irq_handler_list_high_tab[DAL_IRQ_SOURCES_NUMBER];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct common_irq_params
 | 
				
			||||||
 | 
						pflip_params[DC_IRQ_SOURCE_PFLIP_LAST - DC_IRQ_SOURCE_PFLIP_FIRST + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct common_irq_params
 | 
				
			||||||
 | 
						vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* this spin lock synchronizes access to 'irq_handler_list_table' */
 | 
				
			||||||
 | 
						spinlock_t irq_handler_list_table_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Timer-related data. */
 | 
				
			||||||
 | 
						struct list_head timer_handler_list;
 | 
				
			||||||
 | 
						struct workqueue_struct *timer_workqueue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Use dal_mutex for any activity which is NOT syncronized by
 | 
				
			||||||
 | 
						 * DRM mode setting locks.
 | 
				
			||||||
 | 
						 * For example: amdgpu_dm_hpd_low_irq() calls into DAL *without*
 | 
				
			||||||
 | 
						 * DRM mode setting locks being acquired. This is where dal_mutex
 | 
				
			||||||
 | 
						 * is acquired before calling into DAL. */
 | 
				
			||||||
 | 
						struct mutex dal_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct backlight_device *backlight_dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const struct dc_link *backlight_link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct work_struct mst_hotplug_work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct mod_freesync *freesync_module;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* basic init/fini API */
 | 
				
			||||||
 | 
					int amdgpu_dm_init(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_fini(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_destroy(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* initializes drm_device display related structures, based on the information
 | 
				
			||||||
 | 
					 * provided by DAL. The drm strcutures are: drm_crtc, drm_connector,
 | 
				
			||||||
 | 
					 * drm_encoder, drm_mode_config
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns 0 on success
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int amdgpu_dm_initialize_drm_device(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* removes and deallocates the drm structures, created by the above function */
 | 
				
			||||||
 | 
					void amdgpu_dm_destroy_drm_device(
 | 
				
			||||||
 | 
						struct amdgpu_display_manager *dm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Locking/Mutex */
 | 
				
			||||||
 | 
					bool amdgpu_dm_acquire_dal_lock(struct amdgpu_display_manager *dm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool amdgpu_dm_release_dal_lock(struct amdgpu_display_manager *dm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Register "Backlight device" accessible by user-mode. */
 | 
				
			||||||
 | 
					void amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const struct amdgpu_ip_block_version dm_ip_block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_update_connector_after_detect(
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_connector *amdgpu_dm_find_first_crct_matching_connector(
 | 
				
			||||||
 | 
						struct drm_atomic_state *state,
 | 
				
			||||||
 | 
						struct drm_crtc *crtc,
 | 
				
			||||||
 | 
						bool from_state_var);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __AMDGPU_DM_H__ */
 | 
				
			||||||
							
								
								
									
										484
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										484
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,484 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/string.h>
 | 
				
			||||||
 | 
					#include <linux/acpi.h>
 | 
				
			||||||
 | 
					#include <linux/version.h>
 | 
				
			||||||
 | 
					#include <linux/i2c.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <drm/drmP.h>
 | 
				
			||||||
 | 
					#include <drm/drm_crtc_helper.h>
 | 
				
			||||||
 | 
					#include <drm/amdgpu_drm.h>
 | 
				
			||||||
 | 
					#include <drm/drm_edid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "amdgpu.h"
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_irq.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* dm_helpers_parse_edid_caps
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Parse edid caps
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @edid:	[in] pointer to edid
 | 
				
			||||||
 | 
					 *  edid_caps:	[in] pointer to edid caps
 | 
				
			||||||
 | 
					 * @return
 | 
				
			||||||
 | 
					 *	void
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					enum dc_edid_status dm_helpers_parse_edid_caps(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_edid *edid,
 | 
				
			||||||
 | 
							struct dc_edid_caps *edid_caps)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct edid *edid_buf = (struct edid *) edid->raw_edid;
 | 
				
			||||||
 | 
						struct cea_sad *sads;
 | 
				
			||||||
 | 
						int sad_count = -1;
 | 
				
			||||||
 | 
						int sadb_count = -1;
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
						int j = 0;
 | 
				
			||||||
 | 
						uint8_t *sadb = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum dc_edid_status result = EDID_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!edid_caps || !edid)
 | 
				
			||||||
 | 
							return EDID_BAD_INPUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!drm_edid_is_valid(edid_buf))
 | 
				
			||||||
 | 
							result = EDID_BAD_CHECKSUM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						edid_caps->manufacturer_id = (uint16_t) edid_buf->mfg_id[0] |
 | 
				
			||||||
 | 
										((uint16_t) edid_buf->mfg_id[1])<<8;
 | 
				
			||||||
 | 
						edid_caps->product_id = (uint16_t) edid_buf->prod_code[0] |
 | 
				
			||||||
 | 
										((uint16_t) edid_buf->prod_code[1])<<8;
 | 
				
			||||||
 | 
						edid_caps->serial_number = edid_buf->serial;
 | 
				
			||||||
 | 
						edid_caps->manufacture_week = edid_buf->mfg_week;
 | 
				
			||||||
 | 
						edid_caps->manufacture_year = edid_buf->mfg_year;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* One of the four detailed_timings stores the monitor name. It's
 | 
				
			||||||
 | 
						 * stored in an array of length 13. */
 | 
				
			||||||
 | 
						for (i = 0; i < 4; i++) {
 | 
				
			||||||
 | 
							if (edid_buf->detailed_timings[i].data.other_data.type == 0xfc) {
 | 
				
			||||||
 | 
								while (j < 13 && edid_buf->detailed_timings[i].data.other_data.data.str.str[j]) {
 | 
				
			||||||
 | 
									if (edid_buf->detailed_timings[i].data.other_data.data.str.str[j] == '\n')
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									edid_caps->display_name[j] =
 | 
				
			||||||
 | 
										edid_buf->detailed_timings[i].data.other_data.data.str.str[j];
 | 
				
			||||||
 | 
									j++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						edid_caps->edid_hdmi = drm_detect_hdmi_monitor(
 | 
				
			||||||
 | 
								(struct edid *) edid->raw_edid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
 | 
				
			||||||
 | 
						if (sad_count <= 0) {
 | 
				
			||||||
 | 
							DRM_INFO("SADs count is: %d, don't need to read it\n",
 | 
				
			||||||
 | 
									sad_count);
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						edid_caps->audio_mode_count = sad_count < DC_MAX_AUDIO_DESC_COUNT ? sad_count : DC_MAX_AUDIO_DESC_COUNT;
 | 
				
			||||||
 | 
						for (i = 0; i < edid_caps->audio_mode_count; ++i) {
 | 
				
			||||||
 | 
							struct cea_sad *sad = &sads[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							edid_caps->audio_modes[i].format_code = sad->format;
 | 
				
			||||||
 | 
							edid_caps->audio_modes[i].channel_count = sad->channels;
 | 
				
			||||||
 | 
							edid_caps->audio_modes[i].sample_rate = sad->freq;
 | 
				
			||||||
 | 
							edid_caps->audio_modes[i].sample_size = sad->byte2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, &sadb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sadb_count < 0) {
 | 
				
			||||||
 | 
							DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sadb_count);
 | 
				
			||||||
 | 
							sadb_count = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sadb_count)
 | 
				
			||||||
 | 
							edid_caps->speaker_flags = sadb[0];
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kfree(sads);
 | 
				
			||||||
 | 
						kfree(sadb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct amdgpu_connector *get_connector_for_sink(
 | 
				
			||||||
 | 
						struct drm_device *dev,
 | 
				
			||||||
 | 
						const struct dc_sink *sink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_connector *connector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
							struct amdgpu_connector *aconnector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
							if (aconnector->dc_sink == sink)
 | 
				
			||||||
 | 
								return aconnector;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct amdgpu_connector *get_connector_for_link(
 | 
				
			||||||
 | 
						struct drm_device *dev,
 | 
				
			||||||
 | 
						const struct dc_link *link)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_connector *connector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
							struct amdgpu_connector *aconnector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
							if (aconnector->dc_link == link)
 | 
				
			||||||
 | 
								return aconnector;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void get_payload_table(
 | 
				
			||||||
 | 
							struct amdgpu_connector *aconnector,
 | 
				
			||||||
 | 
							struct dp_mst_stream_allocation_table *proposed_table)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_mgr *mst_mgr =
 | 
				
			||||||
 | 
								&aconnector->mst_port->mst_mgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&mst_mgr->payload_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						proposed_table->stream_count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* number of active streams */
 | 
				
			||||||
 | 
						for (i = 0; i < mst_mgr->max_payloads; i++) {
 | 
				
			||||||
 | 
							if (mst_mgr->payloads[i].num_slots == 0)
 | 
				
			||||||
 | 
								break; /* end of vcp_id table */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ASSERT(mst_mgr->payloads[i].payload_state !=
 | 
				
			||||||
 | 
									DP_PAYLOAD_DELETE_LOCAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (mst_mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL ||
 | 
				
			||||||
 | 
								mst_mgr->payloads[i].payload_state ==
 | 
				
			||||||
 | 
										DP_PAYLOAD_REMOTE) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								struct dp_mst_stream_allocation *sa =
 | 
				
			||||||
 | 
										&proposed_table->stream_allocations[
 | 
				
			||||||
 | 
											proposed_table->stream_count];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sa->slot_count = mst_mgr->payloads[i].num_slots;
 | 
				
			||||||
 | 
								sa->vcp_id = mst_mgr->proposed_vcpis[i]->vcpi;
 | 
				
			||||||
 | 
								proposed_table->stream_count++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&mst_mgr->payload_lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Writes payload allocation table in immediate downstream device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dm_helpers_dp_mst_write_payload_allocation_table(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_stream *stream,
 | 
				
			||||||
 | 
							struct dp_mst_stream_allocation_table *proposed_table,
 | 
				
			||||||
 | 
							bool enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector;
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_mgr *mst_mgr;
 | 
				
			||||||
 | 
						struct drm_dp_mst_port *mst_port;
 | 
				
			||||||
 | 
						int slots = 0;
 | 
				
			||||||
 | 
						bool ret;
 | 
				
			||||||
 | 
						int clock;
 | 
				
			||||||
 | 
						int bpp = 0;
 | 
				
			||||||
 | 
						int pbn = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aconnector = get_connector_for_sink(dev, stream->sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector || !aconnector->mst_port)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mst_mgr = &aconnector->mst_port->mst_mgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!mst_mgr->mst_state)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mst_port = aconnector->port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enable) {
 | 
				
			||||||
 | 
							clock = stream->timing.pix_clk_khz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (stream->timing.display_color_depth) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case COLOR_DEPTH_666:
 | 
				
			||||||
 | 
								bpp = 6;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case COLOR_DEPTH_888:
 | 
				
			||||||
 | 
								bpp = 8;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case COLOR_DEPTH_101010:
 | 
				
			||||||
 | 
								bpp = 10;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case COLOR_DEPTH_121212:
 | 
				
			||||||
 | 
								bpp = 12;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case COLOR_DEPTH_141414:
 | 
				
			||||||
 | 
								bpp = 14;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case COLOR_DEPTH_161616:
 | 
				
			||||||
 | 
								bpp = 16;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								ASSERT(bpp != 0);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bpp = bpp * 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* TODO need to know link rate */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pbn = drm_dp_calc_pbn_mode(clock, bpp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							slots = drm_dp_find_vcpi_slots(mst_mgr, pbn);
 | 
				
			||||||
 | 
							ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, pbn, slots);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!ret)
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							drm_dp_mst_reset_vcpi_slots(mst_mgr, mst_port);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = drm_dp_update_payload_part1(mst_mgr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
 | 
				
			||||||
 | 
						 * AUX message. The sequence is slot 1-63 allocated sequence for each
 | 
				
			||||||
 | 
						 * stream. AMD ASIC stream slot allocation should follow the same
 | 
				
			||||||
 | 
						 * sequence. copy DRM MST allocation to dc */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get_payload_table(aconnector, proposed_table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Polls for ACT (allocation change trigger) handled and sends
 | 
				
			||||||
 | 
					 * ALLOCATE_PAYLOAD message.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dm_helpers_dp_mst_poll_for_allocation_change_trigger(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_stream *stream)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector;
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_mgr *mst_mgr;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aconnector = get_connector_for_sink(dev, stream->sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector || !aconnector->mst_port)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mst_mgr = &aconnector->mst_port->mst_mgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!mst_mgr->mst_state)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = drm_dp_check_act_status(mst_mgr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_helpers_dp_mst_send_payload_allocation(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_stream *stream,
 | 
				
			||||||
 | 
							bool enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector;
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_mgr *mst_mgr;
 | 
				
			||||||
 | 
						struct drm_dp_mst_port *mst_port;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aconnector = get_connector_for_sink(dev, stream->sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector || !aconnector->mst_port)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mst_port = aconnector->port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mst_mgr = &aconnector->mst_port->mst_mgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!mst_mgr->mst_state)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = drm_dp_update_payload_part2(mst_mgr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!enable)
 | 
				
			||||||
 | 
							drm_dp_mst_deallocate_vcpi(mst_mgr, mst_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_helpers_dp_mst_start_top_mgr(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_link *link,
 | 
				
			||||||
 | 
							bool boot)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = get_connector_for_link(dev, link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector) {
 | 
				
			||||||
 | 
								DRM_ERROR("Failed to found connector for link!");
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (boot) {
 | 
				
			||||||
 | 
							DRM_INFO("DM_MST: Differing MST start on aconnector: %p [id: %d]\n",
 | 
				
			||||||
 | 
										aconnector, aconnector->base.base.id);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_INFO("DM_MST: starting TM on aconnector: %p [id: %d]\n",
 | 
				
			||||||
 | 
								aconnector, aconnector->base.base.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true) == 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dm_helpers_dp_mst_stop_top_mgr(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_link *link)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = get_connector_for_link(dev, link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector) {
 | 
				
			||||||
 | 
								DRM_ERROR("Failed to found connector for link!");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_INFO("DM_MST: stopping TM on aconnector: %p [id: %d]\n",
 | 
				
			||||||
 | 
								aconnector, aconnector->base.base.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (aconnector->mst_mgr.mst_state == true)
 | 
				
			||||||
 | 
							drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_helpers_dp_read_dpcd(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_link *link,
 | 
				
			||||||
 | 
							uint32_t address,
 | 
				
			||||||
 | 
							uint8_t *data,
 | 
				
			||||||
 | 
							uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = get_connector_for_link(dev, link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector) {
 | 
				
			||||||
 | 
							DRM_ERROR("Failed to found connector for link!");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address,
 | 
				
			||||||
 | 
								data, size) > 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_helpers_dp_write_dpcd(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_link *link,
 | 
				
			||||||
 | 
							uint32_t address,
 | 
				
			||||||
 | 
							const uint8_t *data,
 | 
				
			||||||
 | 
							uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = get_connector_for_link(dev, link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector) {
 | 
				
			||||||
 | 
							DRM_ERROR("Failed to found connector for link!");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return drm_dp_dpcd_write(&aconnector->dm_dp_aux.aux,
 | 
				
			||||||
 | 
								address, (uint8_t *)data, size) > 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_helpers_submit_i2c(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_link *link,
 | 
				
			||||||
 | 
							struct i2c_command *cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = get_connector_for_link(dev, link);
 | 
				
			||||||
 | 
						struct i2c_msg *msgs;
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
						int num = cmd->number_of_payloads;
 | 
				
			||||||
 | 
						bool result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!aconnector) {
 | 
				
			||||||
 | 
							DRM_ERROR("Failed to found connector for link!");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msgs = kzalloc(num * sizeof(struct i2c_msg), GFP_KERNEL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!msgs)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < num; i++) {
 | 
				
			||||||
 | 
							msgs[i].flags = cmd->payloads[i].write ? I2C_M_RD : 0;
 | 
				
			||||||
 | 
							msgs[i].addr = cmd->payloads[i].address;
 | 
				
			||||||
 | 
							msgs[i].len = cmd->payloads[i].length;
 | 
				
			||||||
 | 
							msgs[i].buf = cmd->payloads[i].data;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result = i2c_transfer(&aconnector->i2c->base, msgs, num) == num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kfree(msgs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										829
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										829
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,829 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <drm/drmP.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services_types.h"
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "amdgpu.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_irq.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Private declarations.
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct handler_common_data {
 | 
				
			||||||
 | 
						struct list_head list;
 | 
				
			||||||
 | 
						interrupt_handler handler;
 | 
				
			||||||
 | 
						void *handler_arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* DM which this handler belongs to */
 | 
				
			||||||
 | 
						struct amdgpu_display_manager *dm;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_dm_irq_handler_data {
 | 
				
			||||||
 | 
						struct handler_common_data hcd;
 | 
				
			||||||
 | 
						/* DAL irq source which registered for this interrupt. */
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_dm_timer_handler_data {
 | 
				
			||||||
 | 
						struct handler_common_data hcd;
 | 
				
			||||||
 | 
						struct delayed_work d_work;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DM_IRQ_TABLE_LOCK(adev, flags) \
 | 
				
			||||||
 | 
						spin_lock_irqsave(&adev->dm.irq_handler_list_table_lock, flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DM_IRQ_TABLE_UNLOCK(adev, flags) \
 | 
				
			||||||
 | 
						spin_unlock_irqrestore(&adev->dm.irq_handler_list_table_lock, flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Private functions.
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void init_handler_common_data(
 | 
				
			||||||
 | 
						struct handler_common_data *hcd,
 | 
				
			||||||
 | 
						void (*ih)(void *),
 | 
				
			||||||
 | 
						void *args,
 | 
				
			||||||
 | 
						struct amdgpu_display_manager *dm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						hcd->handler = ih;
 | 
				
			||||||
 | 
						hcd->handler_arg = args;
 | 
				
			||||||
 | 
						hcd->dm = dm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * dm_irq_work_func - Handle an IRQ outside of the interrupt handler proper.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @work: work struct
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void dm_irq_work_func(struct work_struct *work)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct list_head *entry;
 | 
				
			||||||
 | 
						struct irq_list_head *irq_list_head =
 | 
				
			||||||
 | 
							container_of(work, struct irq_list_head, work);
 | 
				
			||||||
 | 
						struct list_head *handler_list = &irq_list_head->head;
 | 
				
			||||||
 | 
						struct amdgpu_dm_irq_handler_data *handler_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each(entry, handler_list) {
 | 
				
			||||||
 | 
							handler_data =
 | 
				
			||||||
 | 
								list_entry(
 | 
				
			||||||
 | 
									entry,
 | 
				
			||||||
 | 
									struct amdgpu_dm_irq_handler_data,
 | 
				
			||||||
 | 
									hcd.list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DRM_DEBUG_KMS("DM_IRQ: work_func: for dal_src=%d\n",
 | 
				
			||||||
 | 
									handler_data->irq_source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DRM_DEBUG_KMS("DM_IRQ: schedule_work: for dal_src=%d\n",
 | 
				
			||||||
 | 
								handler_data->irq_source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							handler_data->hcd.handler(handler_data->hcd.handler_arg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Call a DAL subcomponent which registered for interrupt notification
 | 
				
			||||||
 | 
						 * at INTERRUPT_LOW_IRQ_CONTEXT.
 | 
				
			||||||
 | 
						 * (The most common use is HPD interrupt) */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Remove a handler and return a pointer to hander list from which the
 | 
				
			||||||
 | 
					 * handler was removed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static struct list_head *remove_irq_handler(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						void *ih,
 | 
				
			||||||
 | 
						const struct dc_interrupt_params *int_params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct list_head *hnd_list;
 | 
				
			||||||
 | 
						struct list_head *entry, *tmp;
 | 
				
			||||||
 | 
						struct amdgpu_dm_irq_handler_data *handler;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
						bool handler_removed = false;
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irq_source = int_params->irq_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (int_params->int_context) {
 | 
				
			||||||
 | 
						case INTERRUPT_HIGH_IRQ_CONTEXT:
 | 
				
			||||||
 | 
							hnd_list = &adev->dm.irq_handler_list_high_tab[irq_source];
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case INTERRUPT_LOW_IRQ_CONTEXT:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_safe(entry, tmp, hnd_list) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							handler = list_entry(entry, struct amdgpu_dm_irq_handler_data,
 | 
				
			||||||
 | 
									hcd.list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ih == handler) {
 | 
				
			||||||
 | 
								/* Found our handler. Remove it from the list. */
 | 
				
			||||||
 | 
								list_del(&handler->hcd.list);
 | 
				
			||||||
 | 
								handler_removed = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (handler_removed == false) {
 | 
				
			||||||
 | 
							/* Not necessarily an error - caller may not
 | 
				
			||||||
 | 
							 * know the context. */
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kfree(handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS(
 | 
				
			||||||
 | 
						"DM_IRQ: removed irq handler: %p for: dal_src=%d, irq context=%d\n",
 | 
				
			||||||
 | 
							ih, int_params->irq_source, int_params->int_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return hnd_list;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* If 'handler_in == NULL' then remove ALL handlers. */
 | 
				
			||||||
 | 
					static void remove_timer_handler(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						struct amdgpu_dm_timer_handler_data *handler_in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_dm_timer_handler_data *handler_temp;
 | 
				
			||||||
 | 
						struct list_head *handler_list;
 | 
				
			||||||
 | 
						struct list_head *entry, *tmp;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
						bool handler_removed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handler_list = &adev->dm.timer_handler_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_safe(entry, tmp, handler_list) {
 | 
				
			||||||
 | 
							/* Note that list_for_each_safe() guarantees that
 | 
				
			||||||
 | 
							 * handler_temp is NOT null. */
 | 
				
			||||||
 | 
							handler_temp = list_entry(entry,
 | 
				
			||||||
 | 
									struct amdgpu_dm_timer_handler_data, hcd.list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (handler_in == NULL || handler_in == handler_temp) {
 | 
				
			||||||
 | 
								list_del(&handler_temp->hcd.list);
 | 
				
			||||||
 | 
								DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								DRM_DEBUG_KMS("DM_IRQ: removing timer handler: %p\n",
 | 
				
			||||||
 | 
										handler_temp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (handler_in == NULL) {
 | 
				
			||||||
 | 
									/* Since it is still in the queue, it must
 | 
				
			||||||
 | 
									 * be cancelled. */
 | 
				
			||||||
 | 
									cancel_delayed_work_sync(&handler_temp->d_work);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								kfree(handler_temp);
 | 
				
			||||||
 | 
								handler_removed = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (handler_in == NULL) {
 | 
				
			||||||
 | 
								/* Remove ALL handlers. */
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (handler_in == handler_temp) {
 | 
				
			||||||
 | 
								/* Remove a SPECIFIC handler.
 | 
				
			||||||
 | 
								 * Found our handler - we can stop here. */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (handler_in != NULL && handler_removed == false) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n",
 | 
				
			||||||
 | 
									handler_in);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * dm_timer_work_func - Handle a timer.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @work: work struct
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void dm_timer_work_func(
 | 
				
			||||||
 | 
						struct work_struct *work)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_dm_timer_handler_data *handler_data =
 | 
				
			||||||
 | 
							container_of(work, struct amdgpu_dm_timer_handler_data,
 | 
				
			||||||
 | 
									d_work.work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("DM_IRQ: work_func: handler_data=%p\n", handler_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Call a DAL subcomponent which registered for timer notification. */
 | 
				
			||||||
 | 
						handler_data->hcd.handler(handler_data->hcd.handler_arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We support only "single shot" timers. That means we must delete
 | 
				
			||||||
 | 
						 * the handler after it was called. */
 | 
				
			||||||
 | 
						remove_timer_handler(handler_data->hcd.dm->adev, handler_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool validate_irq_registration_params(
 | 
				
			||||||
 | 
						struct dc_interrupt_params *int_params,
 | 
				
			||||||
 | 
						void (*ih)(void *))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (NULL == int_params || NULL == ih) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: invalid input!\n");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (int_params->int_context >= INTERRUPT_CONTEXT_NUMBER) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: invalid context: %d!\n",
 | 
				
			||||||
 | 
									int_params->int_context);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!DAL_VALID_IRQ_SRC_NUM(int_params->irq_source)) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: invalid irq_source: %d!\n",
 | 
				
			||||||
 | 
									int_params->irq_source);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool validate_irq_unregistration_params(
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source,
 | 
				
			||||||
 | 
						irq_handler_idx handler_idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (DAL_INVALID_IRQ_HANDLER_IDX == handler_idx) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: invalid handler_idx==NULL!\n");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!DAL_VALID_IRQ_SRC_NUM(irq_source)) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: invalid irq_source:%d!\n", irq_source);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Public functions.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note: caller is responsible for input validation.
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *amdgpu_dm_irq_register_interrupt(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						struct dc_interrupt_params *int_params,
 | 
				
			||||||
 | 
						void (*ih)(void *),
 | 
				
			||||||
 | 
						void *handler_args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct list_head *hnd_list;
 | 
				
			||||||
 | 
						struct amdgpu_dm_irq_handler_data *handler_data;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == validate_irq_registration_params(int_params, ih))
 | 
				
			||||||
 | 
							return DAL_INVALID_IRQ_HANDLER_IDX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handler_data = kzalloc(sizeof(*handler_data), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!handler_data) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n");
 | 
				
			||||||
 | 
							return DAL_INVALID_IRQ_HANDLER_IDX;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(handler_data, 0, sizeof(*handler_data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						init_handler_common_data(&handler_data->hcd, ih, handler_args,
 | 
				
			||||||
 | 
								&adev->dm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irq_source = int_params->irq_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handler_data->irq_source = irq_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Lock the list, add the handler. */
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (int_params->int_context) {
 | 
				
			||||||
 | 
						case INTERRUPT_HIGH_IRQ_CONTEXT:
 | 
				
			||||||
 | 
							hnd_list = &adev->dm.irq_handler_list_high_tab[irq_source];
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case INTERRUPT_LOW_IRQ_CONTEXT:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_add_tail(&handler_data->hcd.list, hnd_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* This pointer will be stored by code which requested interrupt
 | 
				
			||||||
 | 
						 * registration.
 | 
				
			||||||
 | 
						 * The same pointer will be needed in order to unregister the
 | 
				
			||||||
 | 
						 * interrupt. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS(
 | 
				
			||||||
 | 
							"DM_IRQ: added irq handler: %p for: dal_src=%d, irq context=%d\n",
 | 
				
			||||||
 | 
							handler_data,
 | 
				
			||||||
 | 
							irq_source,
 | 
				
			||||||
 | 
							int_params->int_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return handler_data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_irq_unregister_interrupt(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source,
 | 
				
			||||||
 | 
						void *ih)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct list_head *handler_list;
 | 
				
			||||||
 | 
						struct dc_interrupt_params int_params;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == validate_irq_unregistration_params(irq_source, ih))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&int_params, 0, sizeof(int_params));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int_params.irq_source = irq_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < INTERRUPT_CONTEXT_NUMBER; i++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int_params.int_context = i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							handler_list = remove_irq_handler(adev, ih, &int_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (handler_list != NULL)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (handler_list == NULL) {
 | 
				
			||||||
 | 
							/* If we got here, it means we searched all irq contexts
 | 
				
			||||||
 | 
							 * for this irq source, but the handler was not found. */
 | 
				
			||||||
 | 
							DRM_ERROR(
 | 
				
			||||||
 | 
							"DM_IRQ: failed to find irq handler:%p for irq_source:%d!\n",
 | 
				
			||||||
 | 
								ih, irq_source);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_init(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int src;
 | 
				
			||||||
 | 
						struct irq_list_head *lh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("DM_IRQ\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_init(&adev->dm.irq_handler_list_table_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
 | 
				
			||||||
 | 
							/* low context handler list init */
 | 
				
			||||||
 | 
							lh = &adev->dm.irq_handler_list_low_tab[src];
 | 
				
			||||||
 | 
							INIT_LIST_HEAD(&lh->head);
 | 
				
			||||||
 | 
							INIT_WORK(&lh->work, dm_irq_work_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* high context handler init */
 | 
				
			||||||
 | 
							INIT_LIST_HEAD(&adev->dm.irq_handler_list_high_tab[src]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&adev->dm.timer_handler_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* allocate and initialize the workqueue for DM timer */
 | 
				
			||||||
 | 
						adev->dm.timer_workqueue = create_singlethread_workqueue(
 | 
				
			||||||
 | 
								"dm_timer_queue");
 | 
				
			||||||
 | 
						if (adev->dm.timer_workqueue == NULL) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: unable to create timer queue!\n");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_irq_register_timer(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						struct dc_timer_interrupt_params *int_params,
 | 
				
			||||||
 | 
						interrupt_handler ih,
 | 
				
			||||||
 | 
						void *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long jf_delay;
 | 
				
			||||||
 | 
						struct list_head *handler_list;
 | 
				
			||||||
 | 
						struct amdgpu_dm_timer_handler_data *handler_data;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handler_data = kzalloc(sizeof(*handler_data), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!handler_data) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: failed to allocate timer handler!\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(handler_data, 0, sizeof(*handler_data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						init_handler_common_data(&handler_data->hcd, ih, args, &adev->dm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_DELAYED_WORK(&handler_data->d_work, dm_timer_work_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Lock the list, add the handler. */
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						handler_list = &adev->dm.timer_handler_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_add_tail(&handler_data->hcd.list, handler_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						jf_delay = usecs_to_jiffies(int_params->micro_sec_interval);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						queue_delayed_work(adev->dm.timer_workqueue, &handler_data->d_work,
 | 
				
			||||||
 | 
								jf_delay);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("DM_IRQ: added handler:%p with micro_sec_interval=%u\n",
 | 
				
			||||||
 | 
								handler_data, int_params->micro_sec_interval);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DM IRQ and timer resource release */
 | 
				
			||||||
 | 
					void amdgpu_dm_irq_fini(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int src;
 | 
				
			||||||
 | 
						struct irq_list_head *lh;
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* The handler was removed from the table,
 | 
				
			||||||
 | 
							 * it means it is safe to flush all the 'work'
 | 
				
			||||||
 | 
							 * (because no code can schedule a new one). */
 | 
				
			||||||
 | 
							lh = &adev->dm.irq_handler_list_low_tab[src];
 | 
				
			||||||
 | 
							flush_work(&lh->work);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Cancel ALL timers and release handlers (if any). */
 | 
				
			||||||
 | 
						remove_timer_handler(adev, NULL);
 | 
				
			||||||
 | 
						/* Release the queue itself. */
 | 
				
			||||||
 | 
						destroy_workqueue(adev->dm.timer_workqueue);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_suspend(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int src;
 | 
				
			||||||
 | 
						struct list_head *hnd_list_h;
 | 
				
			||||||
 | 
						struct list_head *hnd_list_l;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("DM_IRQ: suspend\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* disable HW interrupt */
 | 
				
			||||||
 | 
						for (src = DC_IRQ_SOURCE_HPD1; src < DAL_IRQ_SOURCES_NUMBER; src++) {
 | 
				
			||||||
 | 
							hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
 | 
				
			||||||
 | 
							hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
 | 
				
			||||||
 | 
							if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
 | 
				
			||||||
 | 
								dc_interrupt_set(adev->dm.dc, src, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
							flush_work(&adev->dm.irq_handler_list_low_tab[src].work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int src;
 | 
				
			||||||
 | 
						struct list_head *hnd_list_h, *hnd_list_l;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("DM_IRQ: early resume\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* re-enable short pulse interrupts HW interrupt */
 | 
				
			||||||
 | 
						for (src = DC_IRQ_SOURCE_HPD1RX; src < DC_IRQ_SOURCE_HPD6RX + 1; src++) {
 | 
				
			||||||
 | 
							hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
 | 
				
			||||||
 | 
							hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
 | 
				
			||||||
 | 
							if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
 | 
				
			||||||
 | 
								dc_interrupt_set(adev->dm.dc, src, true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_resume(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int src;
 | 
				
			||||||
 | 
						struct list_head *hnd_list_h, *hnd_list_l;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("DM_IRQ: resume\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* re-enable HW interrupt */
 | 
				
			||||||
 | 
						for (src = DC_IRQ_SOURCE_HPD1; src < DAL_IRQ_SOURCES_NUMBER; src++) {
 | 
				
			||||||
 | 
							hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
 | 
				
			||||||
 | 
							hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
 | 
				
			||||||
 | 
							if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
 | 
				
			||||||
 | 
								dc_interrupt_set(adev->dm.dc, src, true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_schedule_work - schedule all work items registered for the
 | 
				
			||||||
 | 
					 * "irq_source".
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void amdgpu_dm_irq_schedule_work(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
						struct work_struct *work = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!list_empty(&adev->dm.irq_handler_list_low_tab[irq_source].head))
 | 
				
			||||||
 | 
							work = &adev->dm.irq_handler_list_low_tab[irq_source].work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (work) {
 | 
				
			||||||
 | 
							if (!schedule_work(work))
 | 
				
			||||||
 | 
								DRM_INFO("amdgpu_dm_irq_schedule_work FAILED src %d\n",
 | 
				
			||||||
 | 
											irq_source);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** amdgpu_dm_irq_immediate_work
 | 
				
			||||||
 | 
					 *  Callback high irq work immediately, don't send to work queue
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void amdgpu_dm_irq_immediate_work(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_dm_irq_handler_data *handler_data;
 | 
				
			||||||
 | 
						struct list_head *entry;
 | 
				
			||||||
 | 
						unsigned long irq_table_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each(
 | 
				
			||||||
 | 
							entry,
 | 
				
			||||||
 | 
							&adev->dm.irq_handler_list_high_tab[irq_source]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							handler_data =
 | 
				
			||||||
 | 
								list_entry(
 | 
				
			||||||
 | 
									entry,
 | 
				
			||||||
 | 
									struct amdgpu_dm_irq_handler_data,
 | 
				
			||||||
 | 
									hcd.list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Call a subcomponent which registered for immediate
 | 
				
			||||||
 | 
							 * interrupt notification */
 | 
				
			||||||
 | 
							handler_data->hcd.handler(handler_data->hcd.handler_arg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_handler
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Generic IRQ handler, calls all registered high irq work immediately, and
 | 
				
			||||||
 | 
					 * schedules work for low irq
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_handler(
 | 
				
			||||||
 | 
							struct amdgpu_device *adev,
 | 
				
			||||||
 | 
							struct amdgpu_irq_src *source,
 | 
				
			||||||
 | 
							struct amdgpu_iv_entry *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum dc_irq_source src =
 | 
				
			||||||
 | 
							dc_interrupt_to_irq_source(
 | 
				
			||||||
 | 
								adev->dm.dc,
 | 
				
			||||||
 | 
								entry->src_id,
 | 
				
			||||||
 | 
								entry->src_data[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_interrupt_ack(adev->dm.dc, src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Call high irq work immediately */
 | 
				
			||||||
 | 
						amdgpu_dm_irq_immediate_work(adev, src);
 | 
				
			||||||
 | 
						/*Schedule low_irq work */
 | 
				
			||||||
 | 
						amdgpu_dm_irq_schedule_work(adev, src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static enum dc_irq_source amdgpu_dm_hpd_to_dal_irq_source(unsigned type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case AMDGPU_HPD_1:
 | 
				
			||||||
 | 
							return DC_IRQ_SOURCE_HPD1;
 | 
				
			||||||
 | 
						case AMDGPU_HPD_2:
 | 
				
			||||||
 | 
							return DC_IRQ_SOURCE_HPD2;
 | 
				
			||||||
 | 
						case AMDGPU_HPD_3:
 | 
				
			||||||
 | 
							return DC_IRQ_SOURCE_HPD3;
 | 
				
			||||||
 | 
						case AMDGPU_HPD_4:
 | 
				
			||||||
 | 
							return DC_IRQ_SOURCE_HPD4;
 | 
				
			||||||
 | 
						case AMDGPU_HPD_5:
 | 
				
			||||||
 | 
							return DC_IRQ_SOURCE_HPD5;
 | 
				
			||||||
 | 
						case AMDGPU_HPD_6:
 | 
				
			||||||
 | 
							return DC_IRQ_SOURCE_HPD6;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return DC_IRQ_SOURCE_INVALID;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int amdgpu_dm_set_hpd_irq_state(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										struct amdgpu_irq_src *source,
 | 
				
			||||||
 | 
										unsigned type,
 | 
				
			||||||
 | 
										enum amdgpu_interrupt_state state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum dc_irq_source src = amdgpu_dm_hpd_to_dal_irq_source(type);
 | 
				
			||||||
 | 
						bool st = (state == AMDGPU_IRQ_STATE_ENABLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_interrupt_set(adev->dm.dc, src, st);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int dm_irq_state(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						struct amdgpu_irq_src *source,
 | 
				
			||||||
 | 
						unsigned crtc_id,
 | 
				
			||||||
 | 
						enum amdgpu_interrupt_state state,
 | 
				
			||||||
 | 
						const enum irq_type dal_irq_type,
 | 
				
			||||||
 | 
						const char *func)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool st;
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc_id];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!acrtc) {
 | 
				
			||||||
 | 
							DRM_ERROR(
 | 
				
			||||||
 | 
								"%s: crtc is NULL at id :%d\n",
 | 
				
			||||||
 | 
						 		func,
 | 
				
			||||||
 | 
						 		crtc_id);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irq_source = dal_irq_type + acrtc->otg_inst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						st = (state == AMDGPU_IRQ_STATE_ENABLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_interrupt_set(adev->dm.dc, irq_source, st);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int amdgpu_dm_set_pflip_irq_state(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										struct amdgpu_irq_src *source,
 | 
				
			||||||
 | 
										unsigned crtc_id,
 | 
				
			||||||
 | 
										enum amdgpu_interrupt_state state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dm_irq_state(
 | 
				
			||||||
 | 
							adev,
 | 
				
			||||||
 | 
							source,
 | 
				
			||||||
 | 
							crtc_id,
 | 
				
			||||||
 | 
							state,
 | 
				
			||||||
 | 
							IRQ_TYPE_PFLIP,
 | 
				
			||||||
 | 
							__func__);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int amdgpu_dm_set_crtc_irq_state(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										struct amdgpu_irq_src *source,
 | 
				
			||||||
 | 
										unsigned crtc_id,
 | 
				
			||||||
 | 
										enum amdgpu_interrupt_state state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dm_irq_state(
 | 
				
			||||||
 | 
							adev,
 | 
				
			||||||
 | 
							source,
 | 
				
			||||||
 | 
							crtc_id,
 | 
				
			||||||
 | 
							state,
 | 
				
			||||||
 | 
							IRQ_TYPE_VUPDATE,
 | 
				
			||||||
 | 
							__func__);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct amdgpu_irq_src_funcs dm_crtc_irq_funcs = {
 | 
				
			||||||
 | 
						.set = amdgpu_dm_set_crtc_irq_state,
 | 
				
			||||||
 | 
						.process = amdgpu_dm_irq_handler,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct amdgpu_irq_src_funcs dm_pageflip_irq_funcs = {
 | 
				
			||||||
 | 
						.set = amdgpu_dm_set_pflip_irq_state,
 | 
				
			||||||
 | 
						.process = amdgpu_dm_irq_handler,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct amdgpu_irq_src_funcs dm_hpd_irq_funcs = {
 | 
				
			||||||
 | 
						.set = amdgpu_dm_set_hpd_irq_state,
 | 
				
			||||||
 | 
						.process = amdgpu_dm_irq_handler,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
 | 
				
			||||||
 | 
						adev->crtc_irq.funcs = &dm_crtc_irq_funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
 | 
				
			||||||
 | 
						adev->pageflip_irq.funcs = &dm_pageflip_irq_funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
 | 
				
			||||||
 | 
						adev->hpd_irq.funcs = &dm_hpd_irq_funcs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * amdgpu_dm_hpd_init - hpd setup callback.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @adev: amdgpu_device pointer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Setup the hpd pins used by the card (evergreen+).
 | 
				
			||||||
 | 
					 * Enable the pin, set the polarity, and enable the hpd interrupts.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct drm_connector *connector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
							struct amdgpu_connector *amdgpu_connector =
 | 
				
			||||||
 | 
									to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const struct dc_link *dc_link = amdgpu_connector->dc_link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd) {
 | 
				
			||||||
 | 
								dc_interrupt_set(adev->dm.dc,
 | 
				
			||||||
 | 
										dc_link->irq_source_hpd,
 | 
				
			||||||
 | 
										true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd_rx) {
 | 
				
			||||||
 | 
								dc_interrupt_set(adev->dm.dc,
 | 
				
			||||||
 | 
										dc_link->irq_source_hpd_rx,
 | 
				
			||||||
 | 
										true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_hpd_fini - hpd tear down callback.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @adev: amdgpu_device pointer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Tear down the hpd pins used by the card (evergreen+).
 | 
				
			||||||
 | 
					 * Disable the hpd interrupts.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_device *dev = adev->ddev;
 | 
				
			||||||
 | 
						struct drm_connector *connector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
							struct amdgpu_connector *amdgpu_connector =
 | 
				
			||||||
 | 
									to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
							const struct dc_link *dc_link = amdgpu_connector->dc_link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dc_interrupt_set(adev->dm.dc, dc_link->irq_source_hpd, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd_rx) {
 | 
				
			||||||
 | 
								dc_interrupt_set(adev->dm.dc,
 | 
				
			||||||
 | 
										dc_link->irq_source_hpd_rx,
 | 
				
			||||||
 | 
										false);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										122
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,122 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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 __AMDGPU_DM_IRQ_H__
 | 
				
			||||||
 | 
					#define __AMDGPU_DM_IRQ_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "irq_types.h" /* DAL irq definitions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Display Manager IRQ-related interfaces (for use by DAL).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_init - Initialize internal structures of 'amdgpu_dm_irq'.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function should be called exactly once - during DM initialization.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 *	0 - success
 | 
				
			||||||
 | 
					 *	non-zero - error
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_init(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_fini - deallocate internal structures of 'amdgpu_dm_irq'.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function should be called exactly once - during DM destruction.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void amdgpu_dm_irq_fini(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_register_interrupt - register irq handler for Display block.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @adev: AMD DRM device
 | 
				
			||||||
 | 
					 * @int_params: parameters for the irq
 | 
				
			||||||
 | 
					 * @ih: pointer to the irq hander function
 | 
				
			||||||
 | 
					 * @handler_args: arguments which will be passed to ih
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns:
 | 
				
			||||||
 | 
					 * 	IRQ Handler Index on success.
 | 
				
			||||||
 | 
					 * 	NULL on failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Cannot be called from an interrupt handler.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void *amdgpu_dm_irq_register_interrupt(
 | 
				
			||||||
 | 
							struct amdgpu_device *adev,
 | 
				
			||||||
 | 
							struct dc_interrupt_params *int_params,
 | 
				
			||||||
 | 
							void (*ih)(void *),
 | 
				
			||||||
 | 
							void *handler_args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_unregister_interrupt - unregister handler which was registered
 | 
				
			||||||
 | 
					 *	by amdgpu_dm_irq_register_interrupt().
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @adev: AMD DRM device.
 | 
				
			||||||
 | 
					 * @ih_index: irq handler index which was returned by
 | 
				
			||||||
 | 
					 *	amdgpu_dm_irq_register_interrupt
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void amdgpu_dm_irq_unregister_interrupt(
 | 
				
			||||||
 | 
							struct amdgpu_device *adev,
 | 
				
			||||||
 | 
							enum dc_irq_source irq_source,
 | 
				
			||||||
 | 
							void *ih_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_irq_register_timer(
 | 
				
			||||||
 | 
						struct amdgpu_device *adev,
 | 
				
			||||||
 | 
						struct dc_timer_interrupt_params *int_params,
 | 
				
			||||||
 | 
						interrupt_handler ih,
 | 
				
			||||||
 | 
						void *args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_handler
 | 
				
			||||||
 | 
					 * Generic IRQ handler, calls all registered high irq work immediately, and
 | 
				
			||||||
 | 
					 * schedules work for low irq
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_handler(
 | 
				
			||||||
 | 
							struct amdgpu_device *adev,
 | 
				
			||||||
 | 
							struct amdgpu_irq_src *source,
 | 
				
			||||||
 | 
							struct amdgpu_iv_entry *entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_hpd_init(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					void amdgpu_dm_hpd_fini(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_suspend - disable ASIC interrupt during suspend.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_suspend(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_resume_early - enable HPDRX ASIC interrupts during resume.
 | 
				
			||||||
 | 
					 * amdgpu_dm_irq_resume - enable ASIC interrupt during resume.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					int amdgpu_dm_irq_resume(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __AMDGPU_DM_IRQ_H__ */
 | 
				
			||||||
							
								
								
									
										443
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										443
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,443 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/version.h>
 | 
				
			||||||
 | 
					#include <drm/drm_atomic_helper.h>
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "amdgpu.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_types.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_mst_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					#include "dm_helpers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* #define TRACE_DPCD */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef TRACE_DPCD
 | 
				
			||||||
 | 
					#define SIDE_BAND_MSG(address) (address >= DP_SIDEBAND_MSG_DOWN_REQ_BASE && address < DP_SINK_COUNT_ESI)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline char *side_band_msg_type_to_str(uint32_t address)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char str[10] = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (address < DP_SIDEBAND_MSG_UP_REP_BASE)
 | 
				
			||||||
 | 
							strcpy(str, "DOWN_REQ");
 | 
				
			||||||
 | 
						else if (address < DP_SIDEBAND_MSG_DOWN_REP_BASE)
 | 
				
			||||||
 | 
							strcpy(str, "UP_REP");
 | 
				
			||||||
 | 
						else if (address < DP_SIDEBAND_MSG_UP_REQ_BASE)
 | 
				
			||||||
 | 
							strcpy(str, "DOWN_REP");
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							strcpy(str, "UP_REQ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return str;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void log_dpcd(uint8_t type,
 | 
				
			||||||
 | 
							uint32_t address,
 | 
				
			||||||
 | 
							uint8_t *data,
 | 
				
			||||||
 | 
							uint32_t size,
 | 
				
			||||||
 | 
							bool res)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("Op: %s, addr: %04x, SideBand Msg: %s, Op res: %s\n",
 | 
				
			||||||
 | 
								(type == DP_AUX_NATIVE_READ) ||
 | 
				
			||||||
 | 
								(type == DP_AUX_I2C_READ) ?
 | 
				
			||||||
 | 
										"Read" : "Write",
 | 
				
			||||||
 | 
								address,
 | 
				
			||||||
 | 
								SIDE_BAND_MSG(address) ?
 | 
				
			||||||
 | 
										side_band_msg_type_to_str(address) : "Nop",
 | 
				
			||||||
 | 
								res ? "OK" : "Fail");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (res) {
 | 
				
			||||||
 | 
							print_hex_dump(KERN_INFO, "Body: ", DUMP_PREFIX_NONE, 16, 1, data, size, false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pci_dev *pdev = to_pci_dev(aux->dev);
 | 
				
			||||||
 | 
						struct drm_device *drm_dev = pci_get_drvdata(pdev);
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = drm_dev->dev_private;
 | 
				
			||||||
 | 
						struct dc *dc = adev->dm.dc;
 | 
				
			||||||
 | 
						bool res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (msg->request) {
 | 
				
			||||||
 | 
						case DP_AUX_NATIVE_READ:
 | 
				
			||||||
 | 
							res = dc_read_dpcd(
 | 
				
			||||||
 | 
								dc,
 | 
				
			||||||
 | 
								TO_DM_AUX(aux)->link_index,
 | 
				
			||||||
 | 
								msg->address,
 | 
				
			||||||
 | 
								msg->buffer,
 | 
				
			||||||
 | 
								msg->size);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DP_AUX_NATIVE_WRITE:
 | 
				
			||||||
 | 
							res = dc_write_dpcd(
 | 
				
			||||||
 | 
								dc,
 | 
				
			||||||
 | 
								TO_DM_AUX(aux)->link_index,
 | 
				
			||||||
 | 
								msg->address,
 | 
				
			||||||
 | 
								msg->buffer,
 | 
				
			||||||
 | 
								msg->size);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef TRACE_DPCD
 | 
				
			||||||
 | 
						log_dpcd(msg->request,
 | 
				
			||||||
 | 
								msg->address,
 | 
				
			||||||
 | 
								msg->buffer,
 | 
				
			||||||
 | 
								msg->size,
 | 
				
			||||||
 | 
								res);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return msg->size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static enum drm_connector_status
 | 
				
			||||||
 | 
					dm_dp_mst_detect(struct drm_connector *connector, bool force)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
						struct amdgpu_connector *master = aconnector->mst_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum drm_connector_status status =
 | 
				
			||||||
 | 
							drm_dp_mst_detect_port(
 | 
				
			||||||
 | 
								connector,
 | 
				
			||||||
 | 
								&master->mst_mgr,
 | 
				
			||||||
 | 
								aconnector->port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * we do not want to make this connector connected until we have edid on
 | 
				
			||||||
 | 
						 * it
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (status == connector_status_connected &&
 | 
				
			||||||
 | 
							!aconnector->port->cached_edid)
 | 
				
			||||||
 | 
							status = connector_status_disconnected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					dm_dp_mst_connector_destroy(struct drm_connector *connector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
						struct amdgpu_encoder *amdgpu_encoder = amdgpu_connector->mst_encoder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_encoder_cleanup(&amdgpu_encoder->base);
 | 
				
			||||||
 | 
						kfree(amdgpu_encoder);
 | 
				
			||||||
 | 
						drm_connector_cleanup(connector);
 | 
				
			||||||
 | 
						kfree(amdgpu_connector);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
 | 
				
			||||||
 | 
						.detect = dm_dp_mst_detect,
 | 
				
			||||||
 | 
						.fill_modes = drm_helper_probe_single_connector_modes,
 | 
				
			||||||
 | 
						.destroy = dm_dp_mst_connector_destroy,
 | 
				
			||||||
 | 
						.reset = amdgpu_dm_connector_funcs_reset,
 | 
				
			||||||
 | 
						.atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state,
 | 
				
			||||||
 | 
						.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 | 
				
			||||||
 | 
						.atomic_set_property = amdgpu_dm_connector_atomic_set_property
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dm_dp_mst_get_modes(struct drm_connector *connector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = drm_add_edid_modes(&aconnector->base, aconnector->edid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_edid_to_eld(&aconnector->base, aconnector->edid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct drm_encoder *dm_mst_best_encoder(struct drm_connector *connector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &amdgpu_connector->mst_encoder->base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct drm_connector_helper_funcs dm_dp_mst_connector_helper_funcs = {
 | 
				
			||||||
 | 
						.get_modes = dm_dp_mst_get_modes,
 | 
				
			||||||
 | 
						.mode_valid = amdgpu_dm_connector_mode_valid,
 | 
				
			||||||
 | 
						.best_encoder = dm_mst_best_encoder,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct amdgpu_encoder *
 | 
				
			||||||
 | 
					dm_dp_create_fake_mst_encoder(struct amdgpu_connector *connector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_device *dev = connector->base.dev;
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = dev->dev_private;
 | 
				
			||||||
 | 
						struct amdgpu_encoder *amdgpu_encoder;
 | 
				
			||||||
 | 
						struct drm_encoder *encoder;
 | 
				
			||||||
 | 
						const struct drm_connector_helper_funcs *connector_funcs =
 | 
				
			||||||
 | 
							connector->base.helper_private;
 | 
				
			||||||
 | 
						struct drm_encoder *enc_master =
 | 
				
			||||||
 | 
							connector_funcs->best_encoder(&connector->base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS("enc master is %p\n", enc_master);
 | 
				
			||||||
 | 
						amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!amdgpu_encoder)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						encoder = &amdgpu_encoder->base;
 | 
				
			||||||
 | 
						encoder->possible_crtcs = amdgpu_dm_get_encoder_crtc_mask(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_encoder_init(
 | 
				
			||||||
 | 
							dev,
 | 
				
			||||||
 | 
							&amdgpu_encoder->base,
 | 
				
			||||||
 | 
							NULL,
 | 
				
			||||||
 | 
							DRM_MODE_ENCODER_DPMST,
 | 
				
			||||||
 | 
							NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_encoder_helper_add(encoder, &amdgpu_dm_encoder_helper_funcs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return amdgpu_encoder;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct drm_connector *dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 | 
				
			||||||
 | 
												 struct drm_dp_mst_port *port,
 | 
				
			||||||
 | 
												 const char *pathprop)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_connector *master = container_of(mgr, struct amdgpu_connector, mst_mgr);
 | 
				
			||||||
 | 
						struct drm_device *dev = master->base.dev;
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = dev->dev_private;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector;
 | 
				
			||||||
 | 
						struct drm_connector *connector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
 | 
				
			||||||
 | 
						list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
							aconnector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
							if (aconnector->mst_port == master
 | 
				
			||||||
 | 
									&& !aconnector->port) {
 | 
				
			||||||
 | 
								DRM_INFO("DM_MST: reusing connector: %p [id: %d] [master: %p]\n",
 | 
				
			||||||
 | 
											aconnector, connector->base.id, aconnector->mst_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								aconnector->port = port;
 | 
				
			||||||
 | 
								drm_mode_connector_set_path_property(connector, pathprop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								drm_modeset_unlock(&dev->mode_config.connection_mutex);
 | 
				
			||||||
 | 
								return &aconnector->base;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						drm_modeset_unlock(&dev->mode_config.connection_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (!aconnector)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						connector = &aconnector->base;
 | 
				
			||||||
 | 
						aconnector->port = port;
 | 
				
			||||||
 | 
						aconnector->mst_port = master;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (drm_connector_init(
 | 
				
			||||||
 | 
							dev,
 | 
				
			||||||
 | 
							connector,
 | 
				
			||||||
 | 
							&dm_dp_mst_connector_funcs,
 | 
				
			||||||
 | 
							DRM_MODE_CONNECTOR_DisplayPort)) {
 | 
				
			||||||
 | 
							kfree(aconnector);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						drm_connector_helper_add(connector, &dm_dp_mst_connector_helper_funcs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						amdgpu_dm_connector_init_helper(
 | 
				
			||||||
 | 
							&adev->dm,
 | 
				
			||||||
 | 
							aconnector,
 | 
				
			||||||
 | 
							DRM_MODE_CONNECTOR_DisplayPort,
 | 
				
			||||||
 | 
							master->dc_link,
 | 
				
			||||||
 | 
							master->connector_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * TODO: understand why this one is needed
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						drm_object_attach_property(
 | 
				
			||||||
 | 
							&connector->base,
 | 
				
			||||||
 | 
							dev->mode_config.path_property,
 | 
				
			||||||
 | 
							0);
 | 
				
			||||||
 | 
						drm_object_attach_property(
 | 
				
			||||||
 | 
							&connector->base,
 | 
				
			||||||
 | 
							dev->mode_config.tile_property,
 | 
				
			||||||
 | 
							0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_mode_connector_set_path_property(connector, pathprop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Initialize connector state before adding the connectror to drm and
 | 
				
			||||||
 | 
						 * framebuffer lists
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						amdgpu_dm_connector_funcs_reset(connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
 | 
				
			||||||
 | 
								aconnector, connector->base.id, aconnector->mst_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_DEBUG_KMS(":%d\n", connector->base.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return connector;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dm_dp_destroy_mst_connector(
 | 
				
			||||||
 | 
						struct drm_dp_mst_topology_mgr *mgr,
 | 
				
			||||||
 | 
						struct drm_connector *connector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
 | 
				
			||||||
 | 
									aconnector, connector->base.id, aconnector->mst_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						aconnector->port = NULL;
 | 
				
			||||||
 | 
						if (aconnector->dc_sink) {
 | 
				
			||||||
 | 
							amdgpu_dm_remove_sink_from_freesync_module(connector);
 | 
				
			||||||
 | 
							dc_link_remove_remote_sink(aconnector->dc_link, aconnector->dc_sink);
 | 
				
			||||||
 | 
							dc_sink_release(aconnector->dc_sink);
 | 
				
			||||||
 | 
							aconnector->dc_sink = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (aconnector->edid) {
 | 
				
			||||||
 | 
							kfree(aconnector->edid);
 | 
				
			||||||
 | 
							aconnector->edid = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_mode_connector_update_edid_property(
 | 
				
			||||||
 | 
								&aconnector->base,
 | 
				
			||||||
 | 
								NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_connector *master = container_of(mgr, struct amdgpu_connector, mst_mgr);
 | 
				
			||||||
 | 
						struct drm_device *dev = master->base.dev;
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = dev->dev_private;
 | 
				
			||||||
 | 
						struct drm_connector *connector;
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector;
 | 
				
			||||||
 | 
						struct edid *edid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_modeset_lock_all(dev);
 | 
				
			||||||
 | 
						list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 | 
				
			||||||
 | 
							aconnector = to_amdgpu_connector(connector);
 | 
				
			||||||
 | 
							if (aconnector->port &&
 | 
				
			||||||
 | 
									aconnector->port->pdt != DP_PEER_DEVICE_NONE &&
 | 
				
			||||||
 | 
									aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING &&
 | 
				
			||||||
 | 
									!aconnector->dc_sink) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * This is plug in case, where port has been created but
 | 
				
			||||||
 | 
								 * sink hasn't been created yet
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (!aconnector->edid) {
 | 
				
			||||||
 | 
									struct dc_sink_init_data init_params = {
 | 
				
			||||||
 | 
											.link = aconnector->dc_link,
 | 
				
			||||||
 | 
											.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST};
 | 
				
			||||||
 | 
									edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (!edid) {
 | 
				
			||||||
 | 
										drm_mode_connector_update_edid_property(
 | 
				
			||||||
 | 
											&aconnector->base,
 | 
				
			||||||
 | 
											NULL);
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									aconnector->edid = edid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									aconnector->dc_sink = dc_link_add_remote_sink(
 | 
				
			||||||
 | 
										aconnector->dc_link,
 | 
				
			||||||
 | 
										(uint8_t *)edid,
 | 
				
			||||||
 | 
										(edid->extensions + 1) * EDID_LENGTH,
 | 
				
			||||||
 | 
										&init_params);
 | 
				
			||||||
 | 
									if (aconnector->dc_sink)
 | 
				
			||||||
 | 
										amdgpu_dm_add_sink_to_freesync_module(
 | 
				
			||||||
 | 
												connector,
 | 
				
			||||||
 | 
												edid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									dm_restore_drm_connector_state(connector->dev, connector);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
									edid = aconnector->edid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								DRM_DEBUG_KMS("edid retrieved %p\n", edid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								drm_mode_connector_update_edid_property(
 | 
				
			||||||
 | 
									&aconnector->base,
 | 
				
			||||||
 | 
									aconnector->edid);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						drm_modeset_unlock_all(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						schedule_work(&adev->dm.mst_hotplug_work);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dm_dp_mst_register_connector(struct drm_connector *connector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_device *dev = connector->dev;
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = dev->dev_private;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_modeset_lock_all(dev);
 | 
				
			||||||
 | 
						if (adev->mode_info.rfbdev) {
 | 
				
			||||||
 | 
							/*Do not add if already registered in past*/
 | 
				
			||||||
 | 
							for (i = 0; i < adev->mode_info.rfbdev->helper.connector_count; i++) {
 | 
				
			||||||
 | 
								if (adev->mode_info.rfbdev->helper.connector_info[i]->connector
 | 
				
			||||||
 | 
										== connector) {
 | 
				
			||||||
 | 
									drm_modeset_unlock_all(dev);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_modeset_unlock_all(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_connector_register(connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
 | 
				
			||||||
 | 
						.add_connector = dm_dp_add_mst_connector,
 | 
				
			||||||
 | 
						.destroy_connector = dm_dp_destroy_mst_connector,
 | 
				
			||||||
 | 
						.hotplug = dm_dp_mst_hotplug,
 | 
				
			||||||
 | 
						.register_connector = dm_dp_mst_register_connector
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_initialize_mst_connector(
 | 
				
			||||||
 | 
						struct amdgpu_display_manager *dm,
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						aconnector->dm_dp_aux.aux.name = "dmdc";
 | 
				
			||||||
 | 
						aconnector->dm_dp_aux.aux.dev = dm->adev->dev;
 | 
				
			||||||
 | 
						aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer;
 | 
				
			||||||
 | 
						aconnector->dm_dp_aux.link_index = aconnector->connector_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm_dp_aux_register(&aconnector->dm_dp_aux.aux);
 | 
				
			||||||
 | 
						aconnector->mst_mgr.cbs = &dm_mst_cbs;
 | 
				
			||||||
 | 
						drm_dp_mst_topology_mgr_init(
 | 
				
			||||||
 | 
							&aconnector->mst_mgr,
 | 
				
			||||||
 | 
							dm->adev->ddev,
 | 
				
			||||||
 | 
							&aconnector->dm_dp_aux.aux,
 | 
				
			||||||
 | 
							16,
 | 
				
			||||||
 | 
							4,
 | 
				
			||||||
 | 
							aconnector->connector_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										36
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_AMDGPU_DM_MST_TYPES_H__
 | 
				
			||||||
 | 
					#define __DAL_AMDGPU_DM_MST_TYPES_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_display_manager;
 | 
				
			||||||
 | 
					struct amdgpu_connector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_initialize_mst_connector(
 | 
				
			||||||
 | 
						struct amdgpu_display_manager *dm,
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										463
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										463
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,463 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/string.h>
 | 
				
			||||||
 | 
					#include <linux/acpi.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <drm/drmP.h>
 | 
				
			||||||
 | 
					#include <drm/drm_crtc_helper.h>
 | 
				
			||||||
 | 
					#include <drm/amdgpu_drm.h>
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "amdgpu.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_irq.h"
 | 
				
			||||||
 | 
					#include "amdgpu_dm_types.h"
 | 
				
			||||||
 | 
					#include "amdgpu_pm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define dm_alloc(size) kzalloc(size, GFP_KERNEL)
 | 
				
			||||||
 | 
					#define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
 | 
				
			||||||
 | 
					#define dm_free(ptr) kfree(ptr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * IRQ Interfaces.
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_register_timer_interrupt(
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dc_timer_interrupt_params *int_params,
 | 
				
			||||||
 | 
						interrupt_handler ih,
 | 
				
			||||||
 | 
						void *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!adev || !int_params) {
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: invalid input!\n");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (int_params->int_context != INTERRUPT_LOW_IRQ_CONTEXT) {
 | 
				
			||||||
 | 
							/* only low irq ctx is supported. */
 | 
				
			||||||
 | 
							DRM_ERROR("DM_IRQ: invalid context: %d!\n",
 | 
				
			||||||
 | 
									int_params->int_context);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						amdgpu_dm_irq_register_timer(adev, int_params, ih, args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_isr_acquire_lock(struct dc_context *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_isr_release_lock(struct dc_context *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * End-of-IRQ Interfaces.
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_get_platform_info(struct dc_context *ctx,
 | 
				
			||||||
 | 
								struct platform_info_params *params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO*/
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_write_persistent_data(struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_sink *sink,
 | 
				
			||||||
 | 
							const char *module_name,
 | 
				
			||||||
 | 
							const char *key_name,
 | 
				
			||||||
 | 
							void *params,
 | 
				
			||||||
 | 
							unsigned int size,
 | 
				
			||||||
 | 
							struct persistent_data_flag *flag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO implement*/
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_read_persistent_data(struct dc_context *ctx,
 | 
				
			||||||
 | 
									const struct dc_sink *sink,
 | 
				
			||||||
 | 
									const char *module_name,
 | 
				
			||||||
 | 
									const char *key_name,
 | 
				
			||||||
 | 
									void *params,
 | 
				
			||||||
 | 
									unsigned int size,
 | 
				
			||||||
 | 
									struct persistent_data_flag *flag)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO implement*/
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dm_delay_in_microseconds(struct dc_context *ctx,
 | 
				
			||||||
 | 
										unsigned int microSeconds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO implement*/
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**** power component interfaces ****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_pre_dce_clock_change(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							struct dm_pp_gpu_clock_range *requested_state,
 | 
				
			||||||
 | 
							struct dm_pp_gpu_clock_range *actual_state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO*/
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_apply_safe_state(
 | 
				
			||||||
 | 
							const struct dc_context *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							/* TODO: Does this require PreModeChange event to PPLIB? */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_apply_display_requirements(
 | 
				
			||||||
 | 
							const struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dm_pp_display_configuration *pp_display_cfg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							memset(&adev->pm.pm_display_cfg, 0,
 | 
				
			||||||
 | 
									sizeof(adev->pm.pm_display_cfg));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.cpu_cc6_disable =
 | 
				
			||||||
 | 
								pp_display_cfg->cpu_cc6_disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.cpu_pstate_disable =
 | 
				
			||||||
 | 
								pp_display_cfg->cpu_pstate_disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.cpu_pstate_separation_time =
 | 
				
			||||||
 | 
								pp_display_cfg->cpu_pstate_separation_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.nb_pstate_switch_disable =
 | 
				
			||||||
 | 
								pp_display_cfg->nb_pstate_switch_disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.num_display =
 | 
				
			||||||
 | 
									pp_display_cfg->display_count;
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.num_path_including_non_display =
 | 
				
			||||||
 | 
									pp_display_cfg->display_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.min_core_set_clock =
 | 
				
			||||||
 | 
									pp_display_cfg->min_engine_clock_khz/10;
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.min_core_set_clock_in_sr =
 | 
				
			||||||
 | 
									pp_display_cfg->min_engine_clock_deep_sleep_khz/10;
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.min_mem_set_clock =
 | 
				
			||||||
 | 
									pp_display_cfg->min_memory_clock_khz/10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.multi_monitor_in_sync =
 | 
				
			||||||
 | 
									pp_display_cfg->all_displays_in_sync;
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.min_vblank_time =
 | 
				
			||||||
 | 
									pp_display_cfg->avail_mclk_switch_time_us;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.display_clk =
 | 
				
			||||||
 | 
									pp_display_cfg->disp_clk_khz/10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.dce_tolerable_mclk_in_active_latency =
 | 
				
			||||||
 | 
									pp_display_cfg->avail_mclk_switch_time_in_disp_active_us;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.crtc_index = pp_display_cfg->crtc_index;
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.line_time_in_us =
 | 
				
			||||||
 | 
									pp_display_cfg->line_time_in_us;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.vrefresh = pp_display_cfg->disp_configs[0].v_refresh;
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.crossfire_display_index = -1;
 | 
				
			||||||
 | 
							adev->pm.pm_display_cfg.min_bus_bandwidth = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* TODO: complete implementation of
 | 
				
			||||||
 | 
							 * amd_powerplay_display_configuration_change().
 | 
				
			||||||
 | 
							 * Follow example of:
 | 
				
			||||||
 | 
							 * PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c
 | 
				
			||||||
 | 
							 * PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */
 | 
				
			||||||
 | 
							amd_powerplay_display_configuration_change(
 | 
				
			||||||
 | 
									adev->powerplay.pp_handle,
 | 
				
			||||||
 | 
									&adev->pm.pm_display_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* TODO: replace by a separate call to 'apply display cfg'? */
 | 
				
			||||||
 | 
							amdgpu_pm_compute_clocks(adev);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_service_get_system_clocks_range(
 | 
				
			||||||
 | 
							const struct dc_context *ctx,
 | 
				
			||||||
 | 
							struct dm_pp_gpu_clock_range *sys_clks)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Default values, in case PPLib is not compiled-in. */
 | 
				
			||||||
 | 
						sys_clks->mclk.max_khz = 800000;
 | 
				
			||||||
 | 
						sys_clks->mclk.min_khz = 800000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sys_clks->sclk.max_khz = 600000;
 | 
				
			||||||
 | 
						sys_clks->sclk.min_khz = 300000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adev->pm.dpm_enabled) {
 | 
				
			||||||
 | 
							sys_clks->mclk.max_khz = amdgpu_dpm_get_mclk(adev, false);
 | 
				
			||||||
 | 
							sys_clks->mclk.min_khz = amdgpu_dpm_get_mclk(adev, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sys_clks->sclk.max_khz = amdgpu_dpm_get_sclk(adev, false);
 | 
				
			||||||
 | 
							sys_clks->sclk.min_khz = amdgpu_dpm_get_sclk(adev, true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void get_default_clock_levels(
 | 
				
			||||||
 | 
							enum dm_pp_clock_type clk_type,
 | 
				
			||||||
 | 
							struct dm_pp_clock_levels *clks)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t disp_clks_in_khz[6] = {
 | 
				
			||||||
 | 
								300000, 400000, 496560, 626090, 685720, 757900 };
 | 
				
			||||||
 | 
						uint32_t sclks_in_khz[6] = {
 | 
				
			||||||
 | 
								300000, 360000, 423530, 514290, 626090, 720000 };
 | 
				
			||||||
 | 
						uint32_t mclks_in_khz[2] = { 333000, 800000 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (clk_type) {
 | 
				
			||||||
 | 
						case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
 | 
				
			||||||
 | 
							clks->num_levels = 6;
 | 
				
			||||||
 | 
							memmove(clks->clocks_in_khz, disp_clks_in_khz,
 | 
				
			||||||
 | 
									sizeof(disp_clks_in_khz));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DM_PP_CLOCK_TYPE_ENGINE_CLK:
 | 
				
			||||||
 | 
							clks->num_levels = 6;
 | 
				
			||||||
 | 
							memmove(clks->clocks_in_khz, sclks_in_khz,
 | 
				
			||||||
 | 
									sizeof(sclks_in_khz));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DM_PP_CLOCK_TYPE_MEMORY_CLK:
 | 
				
			||||||
 | 
							clks->num_levels = 2;
 | 
				
			||||||
 | 
							memmove(clks->clocks_in_khz, mclks_in_khz,
 | 
				
			||||||
 | 
									sizeof(mclks_in_khz));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							clks->num_levels = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static enum amd_pp_clock_type dc_to_pp_clock_type(
 | 
				
			||||||
 | 
							enum dm_pp_clock_type dm_pp_clk_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum amd_pp_clock_type amd_pp_clk_type = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (dm_pp_clk_type) {
 | 
				
			||||||
 | 
						case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
 | 
				
			||||||
 | 
							amd_pp_clk_type = amd_pp_disp_clock;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DM_PP_CLOCK_TYPE_ENGINE_CLK:
 | 
				
			||||||
 | 
							amd_pp_clk_type = amd_pp_sys_clock;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DM_PP_CLOCK_TYPE_MEMORY_CLK:
 | 
				
			||||||
 | 
							amd_pp_clk_type = amd_pp_mem_clock;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n",
 | 
				
			||||||
 | 
									dm_pp_clk_type);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return amd_pp_clk_type;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void pp_to_dc_clock_levels(
 | 
				
			||||||
 | 
							const struct amd_pp_clocks *pp_clks,
 | 
				
			||||||
 | 
							struct dm_pp_clock_levels *dc_clks,
 | 
				
			||||||
 | 
							enum dm_pp_clock_type dc_clk_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pp_clks->count > DM_PP_MAX_CLOCK_LEVELS) {
 | 
				
			||||||
 | 
							DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n",
 | 
				
			||||||
 | 
									DC_DECODE_PP_CLOCK_TYPE(dc_clk_type),
 | 
				
			||||||
 | 
									pp_clks->count,
 | 
				
			||||||
 | 
									DM_PP_MAX_CLOCK_LEVELS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dc_clks->num_levels = DM_PP_MAX_CLOCK_LEVELS;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							dc_clks->num_levels = pp_clks->count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_INFO("DM_PPLIB: values for %s clock\n",
 | 
				
			||||||
 | 
								DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < dc_clks->num_levels; i++) {
 | 
				
			||||||
 | 
							DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->clock[i]);
 | 
				
			||||||
 | 
							/* translate 10kHz to kHz */
 | 
				
			||||||
 | 
							dc_clks->clocks_in_khz[i] = pp_clks->clock[i] * 10;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_get_clock_levels_by_type(
 | 
				
			||||||
 | 
							const struct dc_context *ctx,
 | 
				
			||||||
 | 
							enum dm_pp_clock_type clk_type,
 | 
				
			||||||
 | 
							struct dm_pp_clock_levels *dc_clks)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct amdgpu_device *adev = ctx->driver_context;
 | 
				
			||||||
 | 
						void *pp_handle = adev->powerplay.pp_handle;
 | 
				
			||||||
 | 
						struct amd_pp_clocks pp_clks = { 0 };
 | 
				
			||||||
 | 
						struct amd_pp_simple_clock_info validation_clks = { 0 };
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (amd_powerplay_get_clock_by_type(pp_handle,
 | 
				
			||||||
 | 
								dc_to_pp_clock_type(clk_type), &pp_clks)) {
 | 
				
			||||||
 | 
							/* Error in pplib. Provide default values. */
 | 
				
			||||||
 | 
							get_default_clock_levels(clk_type, dc_clks);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (amd_powerplay_get_display_mode_validation_clocks(pp_handle,
 | 
				
			||||||
 | 
								&validation_clks)) {
 | 
				
			||||||
 | 
							/* Error in pplib. Provide default values. */
 | 
				
			||||||
 | 
							DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
 | 
				
			||||||
 | 
							validation_clks.engine_max_clock = 72000;
 | 
				
			||||||
 | 
							validation_clks.memory_max_clock = 80000;
 | 
				
			||||||
 | 
							validation_clks.level = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRM_INFO("DM_PPLIB: Validation clocks:\n");
 | 
				
			||||||
 | 
						DRM_INFO("DM_PPLIB:    engine_max_clock: %d\n",
 | 
				
			||||||
 | 
								validation_clks.engine_max_clock);
 | 
				
			||||||
 | 
						DRM_INFO("DM_PPLIB:    memory_max_clock: %d\n",
 | 
				
			||||||
 | 
								validation_clks.memory_max_clock);
 | 
				
			||||||
 | 
						DRM_INFO("DM_PPLIB:    level           : %d\n",
 | 
				
			||||||
 | 
								validation_clks.level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Translate 10 kHz to kHz. */
 | 
				
			||||||
 | 
						validation_clks.engine_max_clock *= 10;
 | 
				
			||||||
 | 
						validation_clks.memory_max_clock *= 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Determine the highest non-boosted level from the Validation Clocks */
 | 
				
			||||||
 | 
						if (clk_type == DM_PP_CLOCK_TYPE_ENGINE_CLK) {
 | 
				
			||||||
 | 
							for (i = 0; i < dc_clks->num_levels; i++) {
 | 
				
			||||||
 | 
								if (dc_clks->clocks_in_khz[i] > validation_clks.engine_max_clock) {
 | 
				
			||||||
 | 
									/* This clock is higher the validation clock.
 | 
				
			||||||
 | 
									 * Than means the previous one is the highest
 | 
				
			||||||
 | 
									 * non-boosted one. */
 | 
				
			||||||
 | 
									DRM_INFO("DM_PPLIB: reducing engine clock level from %d to %d\n",
 | 
				
			||||||
 | 
											dc_clks->num_levels, i + 1);
 | 
				
			||||||
 | 
									dc_clks->num_levels = i;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (clk_type == DM_PP_CLOCK_TYPE_MEMORY_CLK) {
 | 
				
			||||||
 | 
							for (i = 0; i < dc_clks->num_levels; i++) {
 | 
				
			||||||
 | 
								if (dc_clks->clocks_in_khz[i] > validation_clks.memory_max_clock) {
 | 
				
			||||||
 | 
									DRM_INFO("DM_PPLIB: reducing memory clock level from %d to %d\n",
 | 
				
			||||||
 | 
											dc_clks->num_levels, i + 1);
 | 
				
			||||||
 | 
									dc_clks->num_levels = i;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_get_clock_levels_by_type_with_latency(
 | 
				
			||||||
 | 
						const struct dc_context *ctx,
 | 
				
			||||||
 | 
						enum dm_pp_clock_type clk_type,
 | 
				
			||||||
 | 
						struct dm_pp_clock_levels_with_latency *clk_level_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: to be implemented */
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_get_clock_levels_by_type_with_voltage(
 | 
				
			||||||
 | 
						const struct dc_context *ctx,
 | 
				
			||||||
 | 
						enum dm_pp_clock_type clk_type,
 | 
				
			||||||
 | 
						struct dm_pp_clock_levels_with_voltage *clk_level_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: to be implemented */
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_notify_wm_clock_changes(
 | 
				
			||||||
 | 
						const struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: to be implemented */
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_apply_power_level_change_request(
 | 
				
			||||||
 | 
						const struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dm_pp_power_level_change_request *level_change_req)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: to be implemented */
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_apply_clock_for_voltage_request(
 | 
				
			||||||
 | 
						const struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dm_pp_clock_for_voltage_req *clock_for_voltage_req)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: to be implemented */
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dm_pp_get_static_clocks(
 | 
				
			||||||
 | 
						const struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dm_pp_static_clock_info *static_clk_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: to be implemented */
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**** end of power component interfaces ****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Calls to notification */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_notify_setmode_complete(struct dc_context *ctx,
 | 
				
			||||||
 | 
						uint32_t h_total,
 | 
				
			||||||
 | 
						uint32_t v_total,
 | 
				
			||||||
 | 
						uint32_t h_active,
 | 
				
			||||||
 | 
						uint32_t v_active,
 | 
				
			||||||
 | 
						uint32_t pix_clk_in_khz)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*TODO*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/* End of calls to notification */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long dm_get_pid(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return current->pid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long dm_get_tgid(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return current->tgid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3150
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3150
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										101
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,101 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-13 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __AMDGPU_DM_TYPES_H__
 | 
				
			||||||
 | 
					#define __AMDGPU_DM_TYPES_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <drm/drmP.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_framebuffer;
 | 
				
			||||||
 | 
					struct amdgpu_display_manager;
 | 
				
			||||||
 | 
					struct dc_validation_set;
 | 
				
			||||||
 | 
					struct dc_surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*TODO Jodan Hersen use the one in amdgpu_dm*/
 | 
				
			||||||
 | 
					int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
 | 
				
			||||||
 | 
								struct amdgpu_crtc *amdgpu_crtc,
 | 
				
			||||||
 | 
								uint32_t link_index);
 | 
				
			||||||
 | 
					int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
 | 
				
			||||||
 | 
								struct amdgpu_connector *amdgpu_connector,
 | 
				
			||||||
 | 
								uint32_t link_index,
 | 
				
			||||||
 | 
								struct amdgpu_encoder *amdgpu_encoder);
 | 
				
			||||||
 | 
					int amdgpu_dm_encoder_init(
 | 
				
			||||||
 | 
						struct drm_device *dev,
 | 
				
			||||||
 | 
						struct amdgpu_encoder *aencoder,
 | 
				
			||||||
 | 
						uint32_t link_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc);
 | 
				
			||||||
 | 
					void amdgpu_dm_connector_destroy(struct drm_connector *connector);
 | 
				
			||||||
 | 
					void amdgpu_dm_encoder_destroy(struct drm_encoder *encoder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_connector_get_modes(struct drm_connector *connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_atomic_commit(
 | 
				
			||||||
 | 
						struct drm_device *dev,
 | 
				
			||||||
 | 
						struct drm_atomic_state *state,
 | 
				
			||||||
 | 
						bool async);
 | 
				
			||||||
 | 
					int amdgpu_dm_atomic_check(struct drm_device *dev,
 | 
				
			||||||
 | 
									struct drm_atomic_state *state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int dm_create_validation_set_for_target(
 | 
				
			||||||
 | 
						struct drm_connector *connector,
 | 
				
			||||||
 | 
						struct drm_display_mode *mode,
 | 
				
			||||||
 | 
						struct dc_validation_set *val_set);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector);
 | 
				
			||||||
 | 
					struct drm_connector_state *amdgpu_dm_connector_atomic_duplicate_state(
 | 
				
			||||||
 | 
						struct drm_connector *connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_connector_atomic_set_property(
 | 
				
			||||||
 | 
						struct drm_connector *connector,
 | 
				
			||||||
 | 
						struct drm_connector_state *state,
 | 
				
			||||||
 | 
						struct drm_property *property,
 | 
				
			||||||
 | 
						uint64_t val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_get_encoder_crtc_mask(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_connector_init_helper(
 | 
				
			||||||
 | 
						struct amdgpu_display_manager *dm,
 | 
				
			||||||
 | 
						struct amdgpu_connector *aconnector,
 | 
				
			||||||
 | 
						int connector_type,
 | 
				
			||||||
 | 
						const struct dc_link *link,
 | 
				
			||||||
 | 
						int link_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int amdgpu_dm_connector_mode_valid(
 | 
				
			||||||
 | 
						struct drm_connector *connector,
 | 
				
			||||||
 | 
						struct drm_display_mode *mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dm_restore_drm_connector_state(struct drm_device *dev, struct drm_connector *connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_add_sink_to_freesync_module(
 | 
				
			||||||
 | 
							struct drm_connector *connector,
 | 
				
			||||||
 | 
							struct edid *edid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_dm_remove_sink_from_freesync_module(
 | 
				
			||||||
 | 
							struct drm_connector *connector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif		/* __AMDGPU_DM_TYPES_H__ */
 | 
				
			||||||
							
								
								
									
										28
									
								
								drivers/gpu/drm/amd/display/dc/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								drivers/gpu/drm/amd/display/dc/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for Display Core (dc) component.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DC_LIBS = basics bios calcs dce \
 | 
				
			||||||
 | 
					gpio gpu i2caux irq virtual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DC_LIBS += dce112
 | 
				
			||||||
 | 
					DC_LIBS += dce110
 | 
				
			||||||
 | 
					DC_LIBS += dce100
 | 
				
			||||||
 | 
					DC_LIBS += dce80
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LIBS)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(AMD_DC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DISPLAY_CORE = dc.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_target.o dc_sink.o dc_stream.o \
 | 
				
			||||||
 | 
					dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_CORE = $(addprefix $(AMDDALPATH)/dc/core/,$(DISPLAY_CORE))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DM_REG_UPDATE = $(addprefix $(AMDDALPATH)/dc/,dc_helper.o)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DISPLAY_CORE)
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DM_REG_UPDATE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								drivers/gpu/drm/amd/display/dc/basics/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								drivers/gpu/drm/amd/display/dc/basics/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for the 'utils' sub-component of DAL.
 | 
				
			||||||
 | 
					# It provides the general basic services required by other DAL
 | 
				
			||||||
 | 
					# subcomponents.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BASICS = conversion.o fixpt31_32.o fixpt32_32.o grph_object_id.o \
 | 
				
			||||||
 | 
						logger.o log_helpers.o register_logger.o signal_types.o vector.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DAL_BASICS)
 | 
				
			||||||
							
								
								
									
										223
									
								
								drivers/gpu/drm/amd/display/dc/basics/conversion.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								drivers/gpu/drm/amd/display/dc/basics/conversion.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,223 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DIVIDER 10000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* S2D13 value in [-3.00...0.9999] */
 | 
				
			||||||
 | 
					#define S2D13_MIN (-3 * DIVIDER)
 | 
				
			||||||
 | 
					#define S2D13_MAX (3 * DIVIDER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t fixed_point_to_int_frac(
 | 
				
			||||||
 | 
						struct fixed31_32 arg,
 | 
				
			||||||
 | 
						uint8_t integer_bits,
 | 
				
			||||||
 | 
						uint8_t fractional_bits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int32_t numerator;
 | 
				
			||||||
 | 
						int32_t divisor = 1 << fractional_bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint16_t result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint16_t d = (uint16_t)dal_fixed31_32_floor(
 | 
				
			||||||
 | 
							dal_fixed31_32_abs(
 | 
				
			||||||
 | 
								arg));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
 | 
				
			||||||
 | 
							numerator = (uint16_t)dal_fixed31_32_floor(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul_int(
 | 
				
			||||||
 | 
									arg,
 | 
				
			||||||
 | 
									divisor));
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							numerator = dal_fixed31_32_floor(
 | 
				
			||||||
 | 
								dal_fixed31_32_sub(
 | 
				
			||||||
 | 
									dal_fixed31_32_from_int(
 | 
				
			||||||
 | 
										1LL << integer_bits),
 | 
				
			||||||
 | 
									dal_fixed31_32_recip(
 | 
				
			||||||
 | 
										dal_fixed31_32_from_int(
 | 
				
			||||||
 | 
											divisor))));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (numerator >= 0)
 | 
				
			||||||
 | 
							result = (uint16_t)numerator;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							result = (uint16_t)(
 | 
				
			||||||
 | 
							(1 << (integer_bits + fractional_bits + 1)) + numerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((result != 0) && dal_fixed31_32_lt(
 | 
				
			||||||
 | 
							arg, dal_fixed31_32_zero))
 | 
				
			||||||
 | 
							result |= 1 << (integer_bits + fractional_bits);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					* convert_float_matrix
 | 
				
			||||||
 | 
					* This converts a double into HW register spec defined format S2D13.
 | 
				
			||||||
 | 
					* @param :
 | 
				
			||||||
 | 
					* @return None
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					void convert_float_matrix(
 | 
				
			||||||
 | 
						uint16_t *matrix,
 | 
				
			||||||
 | 
						struct fixed31_32 *flt,
 | 
				
			||||||
 | 
						uint32_t buffer_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct fixed31_32 min_2_13 =
 | 
				
			||||||
 | 
							dal_fixed31_32_from_fraction(S2D13_MIN, DIVIDER);
 | 
				
			||||||
 | 
						const struct fixed31_32 max_2_13 =
 | 
				
			||||||
 | 
							dal_fixed31_32_from_fraction(S2D13_MAX, DIVIDER);
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < buffer_size; ++i) {
 | 
				
			||||||
 | 
							uint32_t reg_value =
 | 
				
			||||||
 | 
									fixed_point_to_int_frac(
 | 
				
			||||||
 | 
										dal_fixed31_32_clamp(
 | 
				
			||||||
 | 
											flt[i],
 | 
				
			||||||
 | 
											min_2_13,
 | 
				
			||||||
 | 
											max_2_13),
 | 
				
			||||||
 | 
											2,
 | 
				
			||||||
 | 
											13);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							matrix[i] = (uint16_t)reg_value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void calculate_adjustments_common(
 | 
				
			||||||
 | 
						const struct fixed31_32 *ideal_matrix,
 | 
				
			||||||
 | 
						const struct dc_csc_adjustments *adjustments,
 | 
				
			||||||
 | 
						struct fixed31_32 *matrix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct fixed31_32 sin_hue =
 | 
				
			||||||
 | 
							dal_fixed31_32_sin(adjustments->hue);
 | 
				
			||||||
 | 
						const struct fixed31_32 cos_hue =
 | 
				
			||||||
 | 
							dal_fixed31_32_cos(adjustments->hue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const struct fixed31_32 multiplier =
 | 
				
			||||||
 | 
							dal_fixed31_32_mul(
 | 
				
			||||||
 | 
								adjustments->contrast,
 | 
				
			||||||
 | 
								adjustments->saturation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[0] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							ideal_matrix[0],
 | 
				
			||||||
 | 
							adjustments->contrast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[1] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							ideal_matrix[1],
 | 
				
			||||||
 | 
							adjustments->contrast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[2] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							ideal_matrix[2],
 | 
				
			||||||
 | 
							adjustments->contrast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[4] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							multiplier,
 | 
				
			||||||
 | 
							dal_fixed31_32_add(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[8],
 | 
				
			||||||
 | 
									sin_hue),
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[4],
 | 
				
			||||||
 | 
									cos_hue)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[5] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							multiplier,
 | 
				
			||||||
 | 
							dal_fixed31_32_add(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[9],
 | 
				
			||||||
 | 
									sin_hue),
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[5],
 | 
				
			||||||
 | 
									cos_hue)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[6] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							multiplier,
 | 
				
			||||||
 | 
							dal_fixed31_32_add(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[10],
 | 
				
			||||||
 | 
									sin_hue),
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[6],
 | 
				
			||||||
 | 
									cos_hue)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[7] = ideal_matrix[7];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[8] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							multiplier,
 | 
				
			||||||
 | 
							dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[8],
 | 
				
			||||||
 | 
									cos_hue),
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[4],
 | 
				
			||||||
 | 
									sin_hue)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[9] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							multiplier,
 | 
				
			||||||
 | 
							dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[9],
 | 
				
			||||||
 | 
									cos_hue),
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[5],
 | 
				
			||||||
 | 
									sin_hue)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[10] = dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							multiplier,
 | 
				
			||||||
 | 
							dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[10],
 | 
				
			||||||
 | 
									cos_hue),
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(
 | 
				
			||||||
 | 
									ideal_matrix[6],
 | 
				
			||||||
 | 
									sin_hue)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[11] = ideal_matrix[11];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void calculate_adjustments(
 | 
				
			||||||
 | 
						const struct fixed31_32 *ideal_matrix,
 | 
				
			||||||
 | 
						const struct dc_csc_adjustments *adjustments,
 | 
				
			||||||
 | 
						struct fixed31_32 *matrix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						calculate_adjustments_common(ideal_matrix, adjustments, matrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[3] = dal_fixed31_32_add(
 | 
				
			||||||
 | 
							ideal_matrix[3],
 | 
				
			||||||
 | 
							dal_fixed31_32_mul(
 | 
				
			||||||
 | 
								adjustments->brightness,
 | 
				
			||||||
 | 
								dal_fixed31_32_from_fraction(86, 100)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void calculate_adjustments_y_only(
 | 
				
			||||||
 | 
						const struct fixed31_32 *ideal_matrix,
 | 
				
			||||||
 | 
						const struct dc_csc_adjustments *adjustments,
 | 
				
			||||||
 | 
						struct fixed31_32 *matrix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						calculate_adjustments_common(ideal_matrix, adjustments, matrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						matrix[3] = dal_fixed31_32_add(
 | 
				
			||||||
 | 
							ideal_matrix[3],
 | 
				
			||||||
 | 
							adjustments->brightness);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										51
									
								
								drivers/gpu/drm/amd/display/dc/basics/conversion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								drivers/gpu/drm/amd/display/dc/basics/conversion.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,51 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_CONVERSION_H__
 | 
				
			||||||
 | 
					#define __DAL_CONVERSION_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/fixed31_32.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t fixed_point_to_int_frac(
 | 
				
			||||||
 | 
						struct fixed31_32 arg,
 | 
				
			||||||
 | 
						uint8_t integer_bits,
 | 
				
			||||||
 | 
						uint8_t fractional_bits);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void convert_float_matrix(
 | 
				
			||||||
 | 
						uint16_t *matrix,
 | 
				
			||||||
 | 
						struct fixed31_32 *flt,
 | 
				
			||||||
 | 
						uint32_t buffer_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void calculate_adjustments(
 | 
				
			||||||
 | 
						const struct fixed31_32 *ideal_matrix,
 | 
				
			||||||
 | 
						const struct dc_csc_adjustments *adjustments,
 | 
				
			||||||
 | 
						struct fixed31_32 *matrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void calculate_adjustments_y_only(
 | 
				
			||||||
 | 
						const struct fixed31_32 *ideal_matrix,
 | 
				
			||||||
 | 
						const struct dc_csc_adjustments *adjustments,
 | 
				
			||||||
 | 
						struct fixed31_32 *matrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										691
									
								
								drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										691
									
								
								drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,691 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/fixed31_32.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint64_t abs_i64(
 | 
				
			||||||
 | 
						int64_t arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (arg > 0)
 | 
				
			||||||
 | 
							return (uint64_t)arg;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return (uint64_t)(-arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * @brief
 | 
				
			||||||
 | 
					 * result = dividend / divisor
 | 
				
			||||||
 | 
					 * *remainder = dividend % divisor
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline uint64_t complete_integer_division_u64(
 | 
				
			||||||
 | 
						uint64_t dividend,
 | 
				
			||||||
 | 
						uint64_t divisor,
 | 
				
			||||||
 | 
						uint64_t *remainder)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(divisor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result = div64_u64_rem(dividend, divisor, remainder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BITS_PER_FRACTIONAL_PART \
 | 
				
			||||||
 | 
						32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FRACTIONAL_PART_MASK \
 | 
				
			||||||
 | 
						((1ULL << BITS_PER_FRACTIONAL_PART) - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GET_INTEGER_PART(x) \
 | 
				
			||||||
 | 
						((x) >> BITS_PER_FRACTIONAL_PART)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GET_FRACTIONAL_PART(x) \
 | 
				
			||||||
 | 
						(FRACTIONAL_PART_MASK & (x))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_from_fraction(
 | 
				
			||||||
 | 
						int64_t numerator,
 | 
				
			||||||
 | 
						int64_t denominator)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool arg1_negative = numerator < 0;
 | 
				
			||||||
 | 
						bool arg2_negative = denominator < 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg1_value = arg1_negative ? -numerator : numerator;
 | 
				
			||||||
 | 
						uint64_t arg2_value = arg2_negative ? -denominator : denominator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t remainder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* determine integer part */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t res_value = complete_integer_division_u64(
 | 
				
			||||||
 | 
							arg1_value, arg2_value, &remainder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(res_value <= LONG_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* determine fractional part */
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint32_t i = BITS_PER_FRACTIONAL_PART;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							do {
 | 
				
			||||||
 | 
								remainder <<= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								res_value <<= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (remainder >= arg2_value) {
 | 
				
			||||||
 | 
									res_value |= 1;
 | 
				
			||||||
 | 
									remainder -= arg2_value;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} while (--i != 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* round up LSB */
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint64_t summand = (remainder << 1) >= arg2_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ASSERT(res_value <= LLONG_MAX - summand);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							res_value += summand;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = (int64_t)res_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg1_negative ^ arg2_negative)
 | 
				
			||||||
 | 
							res.value = -res.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_from_int(
 | 
				
			||||||
 | 
						int64_t arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT((LONG_MIN <= arg) && (arg <= LONG_MAX));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg << BITS_PER_FRACTIONAL_PART;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_neg(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = -arg.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_abs(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (arg.value < 0)
 | 
				
			||||||
 | 
							return dal_fixed31_32_neg(arg);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return arg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed31_32_lt(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value < arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed31_32_le(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value <= arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed31_32_eq(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value == arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_min(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (arg1.value <= arg2.value)
 | 
				
			||||||
 | 
							return arg1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return arg2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_max(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (arg1.value <= arg2.value)
 | 
				
			||||||
 | 
							return arg2;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return arg1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_clamp(
 | 
				
			||||||
 | 
						struct fixed31_32 arg,
 | 
				
			||||||
 | 
						struct fixed31_32 min_value,
 | 
				
			||||||
 | 
						struct fixed31_32 max_value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dal_fixed31_32_le(arg, min_value))
 | 
				
			||||||
 | 
							return min_value;
 | 
				
			||||||
 | 
						else if (dal_fixed31_32_le(max_value, arg))
 | 
				
			||||||
 | 
							return max_value;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return arg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_shl(
 | 
				
			||||||
 | 
						struct fixed31_32 arg,
 | 
				
			||||||
 | 
						uint8_t shift)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
 | 
				
			||||||
 | 
							((arg.value < 0) && (arg.value >= LLONG_MIN >> shift)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg.value << shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_shr(
 | 
				
			||||||
 | 
						struct fixed31_32 arg,
 | 
				
			||||||
 | 
						uint8_t shift)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(shift < 64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg.value >> shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_add(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
 | 
				
			||||||
 | 
							((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg1.value + arg2.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_sub_int(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						int32_t arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dal_fixed31_32_sub(
 | 
				
			||||||
 | 
							arg1,
 | 
				
			||||||
 | 
							dal_fixed31_32_from_int(arg2));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_sub(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
 | 
				
			||||||
 | 
							((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg1.value - arg2.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_mul_int(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						int32_t arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							arg1,
 | 
				
			||||||
 | 
							dal_fixed31_32_from_int(arg2));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_mul(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool arg1_negative = arg1.value < 0;
 | 
				
			||||||
 | 
						bool arg2_negative = arg2.value < 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg1_value = arg1_negative ? -arg1.value : arg1.value;
 | 
				
			||||||
 | 
						uint64_t arg2_value = arg2_negative ? -arg2.value : arg2.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg1_int = GET_INTEGER_PART(arg1_value);
 | 
				
			||||||
 | 
						uint64_t arg2_int = GET_INTEGER_PART(arg2_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg1_fra = GET_FRACTIONAL_PART(arg1_value);
 | 
				
			||||||
 | 
						uint64_t arg2_fra = GET_FRACTIONAL_PART(arg2_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg1_int * arg2_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(res.value <= LONG_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value <<= BITS_PER_FRACTIONAL_PART;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg1_int * arg2_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg2_int * arg1_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg1_fra * arg2_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = (tmp >> BITS_PER_FRACTIONAL_PART) +
 | 
				
			||||||
 | 
							(tmp >= (uint64_t)dal_fixed31_32_half.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg1_negative ^ arg2_negative)
 | 
				
			||||||
 | 
							res.value = -res.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_sqr(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg_value = abs_i64(arg.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg_int = GET_INTEGER_PART(arg_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg_fra = GET_FRACTIONAL_PART(arg_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg_int * arg_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(res.value <= LONG_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value <<= BITS_PER_FRACTIONAL_PART;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg_int * arg_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg_fra * arg_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = (tmp >> BITS_PER_FRACTIONAL_PART) +
 | 
				
			||||||
 | 
							(tmp >= (uint64_t)dal_fixed31_32_half.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_div_int(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						int64_t arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dal_fixed31_32_from_fraction(
 | 
				
			||||||
 | 
							arg1.value,
 | 
				
			||||||
 | 
							dal_fixed31_32_from_int(arg2).value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_div(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dal_fixed31_32_from_fraction(
 | 
				
			||||||
 | 
							arg1.value,
 | 
				
			||||||
 | 
							arg2.value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_recip(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * @note
 | 
				
			||||||
 | 
						 * Good idea to use Newton's method
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(arg.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dal_fixed31_32_from_fraction(
 | 
				
			||||||
 | 
							dal_fixed31_32_one.value,
 | 
				
			||||||
 | 
							arg.value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_sinc(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 square;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct fixed31_32 res = dal_fixed31_32_one;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int32_t n = 27;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct fixed31_32 arg_norm = arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dal_fixed31_32_le(
 | 
				
			||||||
 | 
							dal_fixed31_32_two_pi,
 | 
				
			||||||
 | 
							dal_fixed31_32_abs(arg))) {
 | 
				
			||||||
 | 
							arg_norm = dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								arg_norm,
 | 
				
			||||||
 | 
								dal_fixed31_32_mul_int(
 | 
				
			||||||
 | 
									dal_fixed31_32_two_pi,
 | 
				
			||||||
 | 
									(int32_t)div64_s64(
 | 
				
			||||||
 | 
										arg_norm.value,
 | 
				
			||||||
 | 
										dal_fixed31_32_two_pi.value)));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						square = dal_fixed31_32_sqr(arg_norm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							res = dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								dal_fixed31_32_one,
 | 
				
			||||||
 | 
								dal_fixed31_32_div_int(
 | 
				
			||||||
 | 
									dal_fixed31_32_mul(
 | 
				
			||||||
 | 
										square,
 | 
				
			||||||
 | 
										res),
 | 
				
			||||||
 | 
									n * (n - 1)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							n -= 2;
 | 
				
			||||||
 | 
						} while (n > 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg.value != arg_norm.value)
 | 
				
			||||||
 | 
							res = dal_fixed31_32_div(
 | 
				
			||||||
 | 
								dal_fixed31_32_mul(res, arg_norm),
 | 
				
			||||||
 | 
								arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_sin(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dal_fixed31_32_mul(
 | 
				
			||||||
 | 
							arg,
 | 
				
			||||||
 | 
							dal_fixed31_32_sinc(arg));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_cos(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO implement argument normalization */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const struct fixed31_32 square = dal_fixed31_32_sqr(arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct fixed31_32 res = dal_fixed31_32_one;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int32_t n = 26;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							res = dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								dal_fixed31_32_one,
 | 
				
			||||||
 | 
								dal_fixed31_32_div_int(
 | 
				
			||||||
 | 
									dal_fixed31_32_mul(
 | 
				
			||||||
 | 
										square,
 | 
				
			||||||
 | 
										res),
 | 
				
			||||||
 | 
									n * (n - 1)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							n -= 2;
 | 
				
			||||||
 | 
						} while (n != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * @brief
 | 
				
			||||||
 | 
					 * result = exp(arg),
 | 
				
			||||||
 | 
					 * where abs(arg) < 1
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Calculated as Taylor series.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static struct fixed31_32 fixed31_32_exp_from_taylor_series(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t n = 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct fixed31_32 res = dal_fixed31_32_from_fraction(
 | 
				
			||||||
 | 
							n + 2,
 | 
				
			||||||
 | 
							n + 1);
 | 
				
			||||||
 | 
						/* TODO find correct res */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(dal_fixed31_32_lt(arg, dal_fixed31_32_one));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
							res = dal_fixed31_32_add(
 | 
				
			||||||
 | 
								dal_fixed31_32_one,
 | 
				
			||||||
 | 
								dal_fixed31_32_div_int(
 | 
				
			||||||
 | 
									dal_fixed31_32_mul(
 | 
				
			||||||
 | 
										arg,
 | 
				
			||||||
 | 
										res),
 | 
				
			||||||
 | 
									n));
 | 
				
			||||||
 | 
						while (--n != 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dal_fixed31_32_add(
 | 
				
			||||||
 | 
							dal_fixed31_32_one,
 | 
				
			||||||
 | 
							dal_fixed31_32_mul(
 | 
				
			||||||
 | 
								arg,
 | 
				
			||||||
 | 
								res));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_exp(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * @brief
 | 
				
			||||||
 | 
						 * Main equation is:
 | 
				
			||||||
 | 
						 * exp(x) = exp(r + m * ln(2)) = (1 << m) * exp(r),
 | 
				
			||||||
 | 
						 * where m = round(x / ln(2)), r = x - m * ln(2)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dal_fixed31_32_le(
 | 
				
			||||||
 | 
							dal_fixed31_32_ln2_div_2,
 | 
				
			||||||
 | 
							dal_fixed31_32_abs(arg))) {
 | 
				
			||||||
 | 
							int32_t m = dal_fixed31_32_round(
 | 
				
			||||||
 | 
								dal_fixed31_32_div(
 | 
				
			||||||
 | 
									arg,
 | 
				
			||||||
 | 
									dal_fixed31_32_ln2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct fixed31_32 r = dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								arg,
 | 
				
			||||||
 | 
								dal_fixed31_32_mul_int(
 | 
				
			||||||
 | 
									dal_fixed31_32_ln2,
 | 
				
			||||||
 | 
									m));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ASSERT(m != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ASSERT(dal_fixed31_32_lt(
 | 
				
			||||||
 | 
								dal_fixed31_32_abs(r),
 | 
				
			||||||
 | 
								dal_fixed31_32_one));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (m > 0)
 | 
				
			||||||
 | 
								return dal_fixed31_32_shl(
 | 
				
			||||||
 | 
									fixed31_32_exp_from_taylor_series(r),
 | 
				
			||||||
 | 
									(uint8_t)m);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return dal_fixed31_32_div_int(
 | 
				
			||||||
 | 
									fixed31_32_exp_from_taylor_series(r),
 | 
				
			||||||
 | 
									1LL << -m);
 | 
				
			||||||
 | 
						} else if (arg.value != 0)
 | 
				
			||||||
 | 
							return fixed31_32_exp_from_taylor_series(arg);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return dal_fixed31_32_one;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_log(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed31_32 res = dal_fixed31_32_neg(dal_fixed31_32_one);
 | 
				
			||||||
 | 
						/* TODO improve 1st estimation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct fixed31_32 error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(arg.value > 0);
 | 
				
			||||||
 | 
						/* TODO if arg is negative, return NaN */
 | 
				
			||||||
 | 
						/* TODO if arg is zero, return -INF */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							struct fixed31_32 res1 = dal_fixed31_32_add(
 | 
				
			||||||
 | 
								dal_fixed31_32_sub(
 | 
				
			||||||
 | 
									res,
 | 
				
			||||||
 | 
									dal_fixed31_32_one),
 | 
				
			||||||
 | 
								dal_fixed31_32_div(
 | 
				
			||||||
 | 
									arg,
 | 
				
			||||||
 | 
									dal_fixed31_32_exp(res)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							error = dal_fixed31_32_sub(
 | 
				
			||||||
 | 
								res,
 | 
				
			||||||
 | 
								res1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							res = res1;
 | 
				
			||||||
 | 
							/* TODO determine max_allowed_error based on quality of exp() */
 | 
				
			||||||
 | 
						} while (abs_i64(error.value) > 100ULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed31_32 dal_fixed31_32_pow(
 | 
				
			||||||
 | 
						struct fixed31_32 arg1,
 | 
				
			||||||
 | 
						struct fixed31_32 arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dal_fixed31_32_exp(
 | 
				
			||||||
 | 
							dal_fixed31_32_mul(
 | 
				
			||||||
 | 
								dal_fixed31_32_log(arg1),
 | 
				
			||||||
 | 
								arg2));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t dal_fixed31_32_floor(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t arg_value = abs_i64(arg.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg.value >= 0)
 | 
				
			||||||
 | 
							return (int32_t)GET_INTEGER_PART(arg_value);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return -(int32_t)GET_INTEGER_PART(arg_value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t dal_fixed31_32_round(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t arg_value = abs_i64(arg.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const int64_t summand = dal_fixed31_32_half.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(LLONG_MAX - (int64_t)arg_value >= summand);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg_value += summand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg.value >= 0)
 | 
				
			||||||
 | 
							return (int32_t)GET_INTEGER_PART(arg_value);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return -(int32_t)GET_INTEGER_PART(arg_value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t dal_fixed31_32_ceil(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t arg_value = abs_i64(arg.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const int64_t summand = dal_fixed31_32_one.value -
 | 
				
			||||||
 | 
							dal_fixed31_32_epsilon.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(LLONG_MAX - (int64_t)arg_value >= summand);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg_value += summand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg.value >= 0)
 | 
				
			||||||
 | 
							return (int32_t)GET_INTEGER_PART(arg_value);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return -(int32_t)GET_INTEGER_PART(arg_value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* this function is a generic helper to translate fixed point value to
 | 
				
			||||||
 | 
					 * specified integer format that will consist of integer_bits integer part and
 | 
				
			||||||
 | 
					 * fractional_bits fractional part. For example it is used in
 | 
				
			||||||
 | 
					 * dal_fixed31_32_u2d19 to receive 2 bits integer part and 19 bits fractional
 | 
				
			||||||
 | 
					 * part in 32 bits. It is used in hw programming (scaler)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t ux_dy(
 | 
				
			||||||
 | 
						int64_t value,
 | 
				
			||||||
 | 
						uint32_t integer_bits,
 | 
				
			||||||
 | 
						uint32_t fractional_bits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* 1. create mask of integer part */
 | 
				
			||||||
 | 
						uint32_t result = (1 << integer_bits) - 1;
 | 
				
			||||||
 | 
						/* 2. mask out fractional part */
 | 
				
			||||||
 | 
						uint32_t fractional_part = FRACTIONAL_PART_MASK & value;
 | 
				
			||||||
 | 
						/* 3. shrink fixed point integer part to be of integer_bits width*/
 | 
				
			||||||
 | 
						result &= GET_INTEGER_PART(value);
 | 
				
			||||||
 | 
						/* 4. make space for fractional part to be filled in after integer */
 | 
				
			||||||
 | 
						result <<= fractional_bits;
 | 
				
			||||||
 | 
						/* 5. shrink fixed point fractional part to of fractional_bits width*/
 | 
				
			||||||
 | 
						fractional_part >>= BITS_PER_FRACTIONAL_PART - fractional_bits;
 | 
				
			||||||
 | 
						/* 6. merge the result */
 | 
				
			||||||
 | 
						return result | fractional_part;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_fixed31_32_u2d19(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ux_dy(arg.value, 2, 19);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_fixed31_32_u0d19(
 | 
				
			||||||
 | 
						struct fixed31_32 arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return ux_dy(arg.value, 0, 19);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										221
									
								
								drivers/gpu/drm/amd/display/dc/basics/fixpt32_32.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								drivers/gpu/drm/amd/display/dc/basics/fixpt32_32.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,221 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/fixed32_32.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint64_t u64_div(uint64_t n, uint64_t d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i = 0;
 | 
				
			||||||
 | 
						uint64_t r;
 | 
				
			||||||
 | 
						uint64_t q = div64_u64_rem(n, d, &r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < 32; ++i) {
 | 
				
			||||||
 | 
							uint64_t sbit = q & (1ULL<<63);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r <<= 1;
 | 
				
			||||||
 | 
							r |= sbit ? 1 : 0;
 | 
				
			||||||
 | 
							q <<= 1;
 | 
				
			||||||
 | 
							if (r >= d) {
 | 
				
			||||||
 | 
								r -= d;
 | 
				
			||||||
 | 
								q |= 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (2*r >= d)
 | 
				
			||||||
 | 
							q += 1;
 | 
				
			||||||
 | 
						return q;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_from_fraction(uint32_t n, uint32_t d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fx.value = u64_div((uint64_t)n << 32, (uint64_t)d << 32);
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_from_int(uint32_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fx.value = (uint64_t)value<<32;
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_add(
 | 
				
			||||||
 | 
						struct fixed32_32 lhs,
 | 
				
			||||||
 | 
						struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx = {lhs.value + rhs.value};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(fx.value >= rhs.value);
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_add_int(struct fixed32_32 lhs, uint32_t rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx = {lhs.value + ((uint64_t)rhs << 32)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(fx.value >= (uint64_t)rhs << 32);
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_sub(
 | 
				
			||||||
 | 
						struct fixed32_32 lhs,
 | 
				
			||||||
 | 
						struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(lhs.value >= rhs.value);
 | 
				
			||||||
 | 
						fx.value = lhs.value - rhs.value;
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_sub_int(struct fixed32_32 lhs, uint32_t rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(lhs.value >= ((uint64_t)rhs<<32));
 | 
				
			||||||
 | 
						fx.value = lhs.value - ((uint64_t)rhs<<32);
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_mul(
 | 
				
			||||||
 | 
						struct fixed32_32 lhs,
 | 
				
			||||||
 | 
						struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
						uint64_t lhs_int = lhs.value>>32;
 | 
				
			||||||
 | 
						uint64_t lhs_frac = (uint32_t)lhs.value;
 | 
				
			||||||
 | 
						uint64_t rhs_int = rhs.value>>32;
 | 
				
			||||||
 | 
						uint64_t rhs_frac = (uint32_t)rhs.value;
 | 
				
			||||||
 | 
						uint64_t ahbh = lhs_int * rhs_int;
 | 
				
			||||||
 | 
						uint64_t ahbl = lhs_int * rhs_frac;
 | 
				
			||||||
 | 
						uint64_t albh = lhs_frac * rhs_int;
 | 
				
			||||||
 | 
						uint64_t albl = lhs_frac * rhs_frac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT((ahbh>>32) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fx.value = (ahbh<<32) + ahbl + albh + (albl>>32);
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_mul_int(struct fixed32_32 lhs, uint32_t rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
						uint64_t lhsi = (lhs.value>>32) * (uint64_t)rhs;
 | 
				
			||||||
 | 
						uint64_t lhsf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT((lhsi>>32) == 0);
 | 
				
			||||||
 | 
						lhsf = ((uint32_t)lhs.value) * (uint64_t)rhs;
 | 
				
			||||||
 | 
						ASSERT((lhsi<<32) + lhsf >= lhsf);
 | 
				
			||||||
 | 
						fx.value = (lhsi<<32) + lhsf;
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_div(
 | 
				
			||||||
 | 
						struct fixed32_32 lhs,
 | 
				
			||||||
 | 
						struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fx.value = u64_div(lhs.value, rhs.value);
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_div_int(struct fixed32_32 lhs, uint32_t rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct fixed32_32 fx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fx.value = u64_div(lhs.value, (uint64_t)rhs << 32);
 | 
				
			||||||
 | 
						return fx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_min(
 | 
				
			||||||
 | 
						struct fixed32_32 lhs,
 | 
				
			||||||
 | 
						struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (lhs.value < rhs.value) ? lhs : rhs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fixed32_32 dal_fixed32_32_max(
 | 
				
			||||||
 | 
						struct fixed32_32 lhs,
 | 
				
			||||||
 | 
						struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (lhs.value > rhs.value) ? lhs : rhs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed32_32_gt(struct fixed32_32 lhs, struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return lhs.value > rhs.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool dal_fixed32_32_gt_int(struct fixed32_32 lhs, uint32_t rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return lhs.value > ((uint64_t)rhs<<32);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed32_32_lt(struct fixed32_32 lhs, struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return lhs.value < rhs.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed32_32_le(struct fixed32_32 lhs, struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return lhs.value <= rhs.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed32_32_lt_int(struct fixed32_32 lhs, uint32_t rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return lhs.value < ((uint64_t)rhs<<32);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed32_32_le_int(struct fixed32_32 lhs, uint32_t rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return lhs.value <= ((uint64_t)rhs<<32);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_fixed32_32_ceil(struct fixed32_32 v)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ASSERT((uint32_t)v.value ? (v.value >> 32) + 1 >= 1 : true);
 | 
				
			||||||
 | 
						return (v.value>>32) + ((uint32_t)v.value ? 1 : 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_fixed32_32_floor(struct fixed32_32 v)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return v.value>>32;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_fixed32_32_round(struct fixed32_32 v)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ASSERT(v.value + (1ULL<<31) >= (1ULL<<31));
 | 
				
			||||||
 | 
						return (v.value + (1ULL<<31))>>32;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_fixed32_32_eq(struct fixed32_32 lhs, struct fixed32_32 rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return lhs.value == rhs.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										134
									
								
								drivers/gpu/drm/amd/display/dc/basics/grph_object_id.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								drivers/gpu/drm/amd/display/dc/basics/grph_object_id.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,134 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/grph_object_id.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_graphics_object_id_is_valid(struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool rc = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id.type) {
 | 
				
			||||||
 | 
						case OBJECT_TYPE_UNKNOWN:
 | 
				
			||||||
 | 
							rc = false;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case OBJECT_TYPE_GPU:
 | 
				
			||||||
 | 
						case OBJECT_TYPE_ENGINE:
 | 
				
			||||||
 | 
							/* do NOT check for id.id == 0 */
 | 
				
			||||||
 | 
							if (id.enum_id == ENUM_ID_UNKNOWN)
 | 
				
			||||||
 | 
								rc = false;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							if (id.id == 0 || id.enum_id == ENUM_ID_UNKNOWN)
 | 
				
			||||||
 | 
								rc = false;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_graphics_object_id_is_equal(
 | 
				
			||||||
 | 
						struct graphics_object_id id1,
 | 
				
			||||||
 | 
						struct graphics_object_id id2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (false == dal_graphics_object_id_is_valid(id1)) {
 | 
				
			||||||
 | 
							dm_output_to_console(
 | 
				
			||||||
 | 
							"%s: Warning: comparing invalid object 'id1'!\n", __func__);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == dal_graphics_object_id_is_valid(id2)) {
 | 
				
			||||||
 | 
							dm_output_to_console(
 | 
				
			||||||
 | 
							"%s: Warning: comparing invalid object 'id2'!\n", __func__);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (id1.id == id2.id && id1.enum_id == id2.enum_id
 | 
				
			||||||
 | 
							&& id1.type == id2.type)
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Based on internal data members memory layout */
 | 
				
			||||||
 | 
					uint32_t dal_graphics_object_id_to_uint(struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t object_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						object_id = id.id + (id.enum_id << 0x8) + (id.type << 0xc);
 | 
				
			||||||
 | 
						return object_id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * ******* get specific ID - internal safe cast into specific type *******
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum controller_id dal_graphics_object_id_get_controller_id(
 | 
				
			||||||
 | 
						struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (id.type == OBJECT_TYPE_CONTROLLER)
 | 
				
			||||||
 | 
							return id.id;
 | 
				
			||||||
 | 
						return CONTROLLER_ID_UNDEFINED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum clock_source_id dal_graphics_object_id_get_clock_source_id(
 | 
				
			||||||
 | 
						struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (id.type == OBJECT_TYPE_CLOCK_SOURCE)
 | 
				
			||||||
 | 
							return id.id;
 | 
				
			||||||
 | 
						return CLOCK_SOURCE_ID_UNDEFINED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum encoder_id dal_graphics_object_id_get_encoder_id(
 | 
				
			||||||
 | 
						struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (id.type == OBJECT_TYPE_ENCODER)
 | 
				
			||||||
 | 
							return id.id;
 | 
				
			||||||
 | 
						return ENCODER_ID_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum connector_id dal_graphics_object_id_get_connector_id(
 | 
				
			||||||
 | 
						struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (id.type == OBJECT_TYPE_CONNECTOR)
 | 
				
			||||||
 | 
							return id.id;
 | 
				
			||||||
 | 
						return CONNECTOR_ID_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum audio_id dal_graphics_object_id_get_audio_id(struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (id.type == OBJECT_TYPE_AUDIO)
 | 
				
			||||||
 | 
							return id.id;
 | 
				
			||||||
 | 
						return AUDIO_ID_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum engine_id dal_graphics_object_id_get_engine_id(
 | 
				
			||||||
 | 
						struct graphics_object_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (id.type == OBJECT_TYPE_ENGINE)
 | 
				
			||||||
 | 
							return id.id;
 | 
				
			||||||
 | 
						return ENGINE_ID_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										100
									
								
								drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,100 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-16 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					#include "logger.h"
 | 
				
			||||||
 | 
					#include "include/logger_interface.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_signal_type_info {
 | 
				
			||||||
 | 
						enum signal_type type;
 | 
				
			||||||
 | 
						char name[MAX_NAME_LEN];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct dc_signal_type_info signal_type_info_tbl[] = {
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_NONE,             "NC"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_DVI_SINGLE_LINK,  "DVI"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_DVI_DUAL_LINK,    "DDVI"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_HDMI_TYPE_A,      "HDMIA"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_LVDS,             "LVDS"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_RGB,              "VGA"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_DISPLAY_PORT,     "DP"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_DISPLAY_PORT_MST, "MST"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_EDP,              "eDP"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_WIRELESS,         "Wireless"},
 | 
				
			||||||
 | 
							{SIGNAL_TYPE_VIRTUAL,          "Virtual"}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_conn_log(struct dc_context *ctx,
 | 
				
			||||||
 | 
							const struct dc_link *link,
 | 
				
			||||||
 | 
							uint8_t *hex_data,
 | 
				
			||||||
 | 
							int hex_data_count,
 | 
				
			||||||
 | 
							enum dc_log_type event,
 | 
				
			||||||
 | 
							const char *msg,
 | 
				
			||||||
 | 
							...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						va_list args;
 | 
				
			||||||
 | 
						struct log_entry entry = { 0 };
 | 
				
			||||||
 | 
						enum signal_type signal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (link->local_sink)
 | 
				
			||||||
 | 
							signal = link->local_sink->sink_signal;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							signal = link->connector_signal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (link->type == dc_connection_mst_branch)
 | 
				
			||||||
 | 
							signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_logger_open(ctx->logger, &entry, event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < NUM_ELEMENTS(signal_type_info_tbl); i++)
 | 
				
			||||||
 | 
							if (signal == signal_type_info_tbl[i].type)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_logger_append(&entry, "[%s][ConnIdx:%d] ",
 | 
				
			||||||
 | 
								signal_type_info_tbl[i].name,
 | 
				
			||||||
 | 
								link->link_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(args, msg);
 | 
				
			||||||
 | 
						entry.buf_offset += dm_log_to_buffer(
 | 
				
			||||||
 | 
							&entry.buf[entry.buf_offset],
 | 
				
			||||||
 | 
							LOG_MAX_LINE_SIZE - entry.buf_offset,
 | 
				
			||||||
 | 
							msg, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (entry.buf[strlen(entry.buf) - 1] == '\n') {
 | 
				
			||||||
 | 
							entry.buf[strlen(entry.buf) - 1] = '\0';
 | 
				
			||||||
 | 
							entry.buf_offset--;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hex_data)
 | 
				
			||||||
 | 
							for (i = 0; i < hex_data_count; i++)
 | 
				
			||||||
 | 
								dm_logger_append(&entry, "%2.2X ", hex_data[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_logger_append(&entry, "^\n");
 | 
				
			||||||
 | 
						dm_logger_close(&entry);
 | 
				
			||||||
 | 
						va_end(args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										457
									
								
								drivers/gpu/drm/amd/display/dc/basics/logger.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										457
									
								
								drivers/gpu/drm/amd/display/dc/basics/logger.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,457 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/logger_interface.h"
 | 
				
			||||||
 | 
					#include "logger.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct dc_log_type_info log_type_info_tbl[] = {
 | 
				
			||||||
 | 
							{LOG_ERROR,                 "Error"},
 | 
				
			||||||
 | 
							{LOG_WARNING,               "Warning"},
 | 
				
			||||||
 | 
							{LOG_DC,                    "DC_Interface"},
 | 
				
			||||||
 | 
							{LOG_SURFACE,               "Surface"},
 | 
				
			||||||
 | 
							{LOG_HW_HOTPLUG,            "HW_Hotplug"},
 | 
				
			||||||
 | 
							{LOG_HW_LINK_TRAINING,      "HW_LKTN"},
 | 
				
			||||||
 | 
							{LOG_HW_SET_MODE,           "HW_Mode"},
 | 
				
			||||||
 | 
							{LOG_HW_RESUME_S3,          "HW_Resume"},
 | 
				
			||||||
 | 
							{LOG_HW_AUDIO,              "HW_Audio"},
 | 
				
			||||||
 | 
							{LOG_HW_HPD_IRQ,            "HW_HPDIRQ"},
 | 
				
			||||||
 | 
							{LOG_MST,                   "MST"},
 | 
				
			||||||
 | 
							{LOG_SCALER,                "Scaler"},
 | 
				
			||||||
 | 
							{LOG_BIOS,                  "BIOS"},
 | 
				
			||||||
 | 
							{LOG_BANDWIDTH_CALCS,       "BWCalcs"},
 | 
				
			||||||
 | 
							{LOG_BANDWIDTH_VALIDATION,  "BWValidation"},
 | 
				
			||||||
 | 
							{LOG_I2C_AUX,               "I2C_AUX"},
 | 
				
			||||||
 | 
							{LOG_SYNC,                  "Sync"},
 | 
				
			||||||
 | 
							{LOG_BACKLIGHT,             "Backlight"},
 | 
				
			||||||
 | 
							{LOG_FEATURE_OVERRIDE,      "Override"},
 | 
				
			||||||
 | 
							{LOG_DETECTION_EDID_PARSER, "Edid"},
 | 
				
			||||||
 | 
							{LOG_DETECTION_DP_CAPS,     "DP_Caps"},
 | 
				
			||||||
 | 
							{LOG_RESOURCE,              "Resource"},
 | 
				
			||||||
 | 
							{LOG_DML,                   "DML"},
 | 
				
			||||||
 | 
							{LOG_EVENT_MODE_SET,        "Mode"},
 | 
				
			||||||
 | 
							{LOG_EVENT_DETECTION,       "Detect"},
 | 
				
			||||||
 | 
							{LOG_EVENT_LINK_TRAINING,   "LKTN"},
 | 
				
			||||||
 | 
							{LOG_EVENT_LINK_LOSS,       "LinkLoss"},
 | 
				
			||||||
 | 
							{LOG_EVENT_UNDERFLOW,       "Underflow"},
 | 
				
			||||||
 | 
							{LOG_IF_TRACE,				"InterfaceTrace"}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DC_DEFAULT_LOG_MASK ((1 << LOG_ERROR) | \
 | 
				
			||||||
 | 
							(1 << LOG_WARNING) | \
 | 
				
			||||||
 | 
							(1 << LOG_EVENT_MODE_SET) | \
 | 
				
			||||||
 | 
							(1 << LOG_EVENT_DETECTION) | \
 | 
				
			||||||
 | 
							(1 << LOG_EVENT_LINK_TRAINING) | \
 | 
				
			||||||
 | 
							(1 << LOG_EVENT_LINK_LOSS) | \
 | 
				
			||||||
 | 
							(1 << LOG_EVENT_UNDERFLOW) | \
 | 
				
			||||||
 | 
							(1 << LOG_RESOURCE) | \
 | 
				
			||||||
 | 
							(1 << LOG_FEATURE_OVERRIDE) | \
 | 
				
			||||||
 | 
							(1 << LOG_DETECTION_EDID_PARSER) | \
 | 
				
			||||||
 | 
							(1 << LOG_DC) | \
 | 
				
			||||||
 | 
							(1 << LOG_HW_HOTPLUG) | \
 | 
				
			||||||
 | 
							(1 << LOG_HW_SET_MODE) | \
 | 
				
			||||||
 | 
							(1 << LOG_HW_RESUME_S3) | \
 | 
				
			||||||
 | 
							(1 << LOG_HW_HPD_IRQ) | \
 | 
				
			||||||
 | 
							(1 << LOG_SYNC) | \
 | 
				
			||||||
 | 
							(1 << LOG_BANDWIDTH_VALIDATION) | \
 | 
				
			||||||
 | 
							(1 << LOG_MST) | \
 | 
				
			||||||
 | 
							(1 << LOG_BIOS) | \
 | 
				
			||||||
 | 
							(1 << LOG_DETECTION_EDID_PARSER) | \
 | 
				
			||||||
 | 
							(1 << LOG_DETECTION_DP_CAPS) | \
 | 
				
			||||||
 | 
							(1 << LOG_BACKLIGHT)) | \
 | 
				
			||||||
 | 
							(1 << LOG_I2C_AUX) | \
 | 
				
			||||||
 | 
							(1 << LOG_IF_TRACE) /* | \
 | 
				
			||||||
 | 
							(1 << LOG_SURFACE) | \
 | 
				
			||||||
 | 
							(1 << LOG_SCALER) | \
 | 
				
			||||||
 | 
							(1 << LOG_DML) | \
 | 
				
			||||||
 | 
							(1 << LOG_HW_LINK_TRAINING) | \
 | 
				
			||||||
 | 
							(1 << LOG_HW_AUDIO)| \
 | 
				
			||||||
 | 
							(1 << LOG_BANDWIDTH_CALCS)*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ----------- Object init and destruction ----------- */
 | 
				
			||||||
 | 
					static bool construct(struct dc_context *ctx, struct dal_logger *logger)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* malloc buffer and init offsets */
 | 
				
			||||||
 | 
						logger->log_buffer_size = DAL_LOGGER_BUFFER_MAX_SIZE;
 | 
				
			||||||
 | 
						logger->log_buffer = (char *)dm_alloc(logger->log_buffer_size *
 | 
				
			||||||
 | 
							sizeof(char));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!logger->log_buffer)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize both offsets to start of buffer (empty) */
 | 
				
			||||||
 | 
						logger->buffer_read_offset = 0;
 | 
				
			||||||
 | 
						logger->buffer_write_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger->write_wrap_count = 0;
 | 
				
			||||||
 | 
						logger->read_wrap_count = 0;
 | 
				
			||||||
 | 
						logger->open_count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger->flags.bits.ENABLE_CONSOLE = 1;
 | 
				
			||||||
 | 
						logger->flags.bits.ENABLE_BUFFER = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger->ctx = ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger->mask = DC_DEFAULT_LOG_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destruct(struct dal_logger *logger)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (logger->log_buffer) {
 | 
				
			||||||
 | 
							dm_free(logger->log_buffer);
 | 
				
			||||||
 | 
							logger->log_buffer = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dal_logger *dal_logger_create(struct dc_context *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* malloc struct */
 | 
				
			||||||
 | 
						struct dal_logger *logger = dm_alloc(sizeof(struct dal_logger));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!logger)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						if (!construct(ctx, logger)) {
 | 
				
			||||||
 | 
							dm_free(logger);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return logger;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_logger_destroy(struct dal_logger **logger)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (logger == NULL || *logger == NULL)
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						destruct(*logger);
 | 
				
			||||||
 | 
						dm_free(*logger);
 | 
				
			||||||
 | 
						*logger = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ------------------------------------------------------------------------ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool dal_logger_should_log(
 | 
				
			||||||
 | 
						struct dal_logger *logger,
 | 
				
			||||||
 | 
						enum dc_log_type log_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (logger->mask & (1 << log_type))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void log_to_debug_console(struct log_entry *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dal_logger *logger = entry->logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (logger->flags.bits.ENABLE_CONSOLE == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (entry->buf_offset) {
 | 
				
			||||||
 | 
							switch (entry->type) {
 | 
				
			||||||
 | 
							case LOG_ERROR:
 | 
				
			||||||
 | 
								dm_error("%s", entry->buf);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								dm_output_to_console("%s", entry->buf);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Print everything unread existing in log_buffer to debug console*/
 | 
				
			||||||
 | 
					static void flush_to_debug_console(struct dal_logger *logger)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i = logger->buffer_read_offset;
 | 
				
			||||||
 | 
						char *string_start = &logger->log_buffer[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_output_to_console(
 | 
				
			||||||
 | 
							"---------------- FLUSHING LOG BUFFER ----------------\n");
 | 
				
			||||||
 | 
						while (i < logger->buffer_write_offset)	{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (logger->log_buffer[i] == '\0') {
 | 
				
			||||||
 | 
								dm_output_to_console("%s", string_start);
 | 
				
			||||||
 | 
								string_start = (char *)logger->log_buffer + i + 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dm_output_to_console(
 | 
				
			||||||
 | 
							"-------------- END FLUSHING LOG BUFFER --------------\n\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void log_to_internal_buffer(struct log_entry *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t size = entry->buf_offset;
 | 
				
			||||||
 | 
						struct dal_logger *logger = entry->logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (logger->flags.bits.ENABLE_BUFFER == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (logger->log_buffer == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (size > 0 && size < logger->log_buffer_size) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int total_free_space = 0;
 | 
				
			||||||
 | 
							int space_before_wrap = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (logger->buffer_write_offset > logger->buffer_read_offset) {
 | 
				
			||||||
 | 
								total_free_space = logger->log_buffer_size -
 | 
				
			||||||
 | 
										logger->buffer_write_offset +
 | 
				
			||||||
 | 
										logger->buffer_read_offset;
 | 
				
			||||||
 | 
								space_before_wrap = logger->log_buffer_size -
 | 
				
			||||||
 | 
										logger->buffer_write_offset;
 | 
				
			||||||
 | 
							} else if (logger->buffer_write_offset <
 | 
				
			||||||
 | 
									logger->buffer_read_offset) {
 | 
				
			||||||
 | 
								total_free_space = logger->log_buffer_size -
 | 
				
			||||||
 | 
										logger->buffer_read_offset +
 | 
				
			||||||
 | 
										logger->buffer_write_offset;
 | 
				
			||||||
 | 
								space_before_wrap = total_free_space;
 | 
				
			||||||
 | 
							} else if (logger->write_wrap_count !=
 | 
				
			||||||
 | 
									logger->read_wrap_count) {
 | 
				
			||||||
 | 
								/* Buffer is completely full already */
 | 
				
			||||||
 | 
								total_free_space = 0;
 | 
				
			||||||
 | 
								space_before_wrap = 0;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* Buffer is empty, start writing at beginning */
 | 
				
			||||||
 | 
								total_free_space = logger->log_buffer_size;
 | 
				
			||||||
 | 
								space_before_wrap = logger->log_buffer_size;
 | 
				
			||||||
 | 
								logger->buffer_write_offset = 0;
 | 
				
			||||||
 | 
								logger->buffer_read_offset = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (space_before_wrap > size) {
 | 
				
			||||||
 | 
								/* No wrap around, copy 'size' bytes
 | 
				
			||||||
 | 
								 * from 'entry->buf' to 'log_buffer'
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								memmove(logger->log_buffer +
 | 
				
			||||||
 | 
										logger->buffer_write_offset,
 | 
				
			||||||
 | 
										entry->buf, size);
 | 
				
			||||||
 | 
								logger->buffer_write_offset += size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							} else if (total_free_space > size) {
 | 
				
			||||||
 | 
								/* We have enough room without flushing,
 | 
				
			||||||
 | 
								 * but need to wrap around */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int space_after_wrap = total_free_space -
 | 
				
			||||||
 | 
										space_before_wrap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								memmove(logger->log_buffer +
 | 
				
			||||||
 | 
										logger->buffer_write_offset,
 | 
				
			||||||
 | 
										entry->buf, space_before_wrap);
 | 
				
			||||||
 | 
								memmove(logger->log_buffer, entry->buf +
 | 
				
			||||||
 | 
										space_before_wrap, space_after_wrap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logger->buffer_write_offset = space_after_wrap;
 | 
				
			||||||
 | 
								logger->write_wrap_count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* Not enough room remaining, we should flush
 | 
				
			||||||
 | 
								 * existing logs */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Flush existing unread logs to console */
 | 
				
			||||||
 | 
								flush_to_debug_console(logger);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Start writing to beginning of buffer */
 | 
				
			||||||
 | 
								memmove(logger->log_buffer, entry->buf, size);
 | 
				
			||||||
 | 
								logger->buffer_write_offset = size;
 | 
				
			||||||
 | 
								logger->buffer_read_offset = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void log_heading(struct log_entry *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (j = 0; j < NUM_ELEMENTS(log_type_info_tbl); j++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const struct dc_log_type_info *info = &log_type_info_tbl[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (info->type == entry->type)
 | 
				
			||||||
 | 
								dm_logger_append(entry, "[%s]\t", info->name);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void append_entry(
 | 
				
			||||||
 | 
							struct log_entry *entry,
 | 
				
			||||||
 | 
							char *buffer,
 | 
				
			||||||
 | 
							uint32_t buf_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!entry->buf ||
 | 
				
			||||||
 | 
							entry->buf_offset + buf_size > entry->max_buf_bytes
 | 
				
			||||||
 | 
						) {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Todo: check if off by 1 byte due to \0 anywhere */
 | 
				
			||||||
 | 
						memmove(entry->buf + entry->buf_offset, buffer, buf_size);
 | 
				
			||||||
 | 
						entry->buf_offset += buf_size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ------------------------------------------------------------------------ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Warning: Be careful that 'msg' is null terminated and the total size is
 | 
				
			||||||
 | 
					 * less than DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE (256) including '\0'
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void dm_logger_write(
 | 
				
			||||||
 | 
						struct dal_logger *logger,
 | 
				
			||||||
 | 
						enum dc_log_type log_type,
 | 
				
			||||||
 | 
						const char *msg,
 | 
				
			||||||
 | 
						...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (logger && dal_logger_should_log(logger, log_type)) {
 | 
				
			||||||
 | 
							uint32_t size;
 | 
				
			||||||
 | 
							va_list args;
 | 
				
			||||||
 | 
							char buffer[LOG_MAX_LINE_SIZE];
 | 
				
			||||||
 | 
							struct log_entry entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							va_start(args, msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							entry.logger = logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							entry.buf = buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							entry.buf_offset = 0;
 | 
				
			||||||
 | 
							entry.max_buf_bytes = DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							entry.type = log_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log_heading(&entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							size = dm_log_to_buffer(
 | 
				
			||||||
 | 
								buffer, LOG_MAX_LINE_SIZE, msg, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							entry.buf_offset += size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* --Flush log_entry buffer-- */
 | 
				
			||||||
 | 
							/* print to kernel console */
 | 
				
			||||||
 | 
							log_to_debug_console(&entry);
 | 
				
			||||||
 | 
							/* log internally for dsat */
 | 
				
			||||||
 | 
							log_to_internal_buffer(&entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							va_end(args);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Same as dm_logger_write, except without open() and close(), which must
 | 
				
			||||||
 | 
					 * be done separately.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void dm_logger_append(
 | 
				
			||||||
 | 
						struct log_entry *entry,
 | 
				
			||||||
 | 
						const char *msg,
 | 
				
			||||||
 | 
						...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dal_logger *logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!entry) {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger = entry->logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (logger && logger->open_count > 0 &&
 | 
				
			||||||
 | 
							dal_logger_should_log(logger, entry->type)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t size;
 | 
				
			||||||
 | 
							va_list args;
 | 
				
			||||||
 | 
							char buffer[LOG_MAX_LINE_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							va_start(args, msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							size = dm_log_to_buffer(
 | 
				
			||||||
 | 
								buffer, LOG_MAX_LINE_SIZE, msg, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (size < LOG_MAX_LINE_SIZE - 1) {
 | 
				
			||||||
 | 
								append_entry(entry, buffer, size);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								append_entry(entry, "LOG_ERROR, line too long\n", 27);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							va_end(args);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dm_logger_open(
 | 
				
			||||||
 | 
							struct dal_logger *logger,
 | 
				
			||||||
 | 
							struct log_entry *entry, /* out */
 | 
				
			||||||
 | 
							enum dc_log_type log_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!entry) {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						entry->type = log_type;
 | 
				
			||||||
 | 
						entry->logger = logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						entry->buf = dm_alloc(DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						entry->buf_offset = 0;
 | 
				
			||||||
 | 
						entry->max_buf_bytes = DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger->open_count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log_heading(entry);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dm_logger_close(struct log_entry *entry)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dal_logger *logger = entry->logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (logger && logger->open_count > 0) {
 | 
				
			||||||
 | 
							logger->open_count--;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							goto cleanup;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* --Flush log_entry buffer-- */
 | 
				
			||||||
 | 
						/* print to kernel console */
 | 
				
			||||||
 | 
						log_to_debug_console(entry);
 | 
				
			||||||
 | 
						/* log internally for dsat */
 | 
				
			||||||
 | 
						log_to_internal_buffer(entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO: Write end heading */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup:
 | 
				
			||||||
 | 
						if (entry->buf) {
 | 
				
			||||||
 | 
							dm_free(entry->buf);
 | 
				
			||||||
 | 
							entry->buf = NULL;
 | 
				
			||||||
 | 
							entry->buf_offset = 0;
 | 
				
			||||||
 | 
							entry->max_buf_bytes = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										67
									
								
								drivers/gpu/drm/amd/display/dc/basics/logger.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								drivers/gpu/drm/amd/display/dc/basics/logger.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,67 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_LOGGER_H__
 | 
				
			||||||
 | 
					#define __DAL_LOGGER_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Structure for keeping track of offsets, buffer, etc */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
 | 
				
			||||||
 | 
					 * change log line size to 896 to meet the request.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define LOG_MAX_LINE_SIZE 896
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/logger_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dal_logger {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* How far into the circular buffer has been read by dsat
 | 
				
			||||||
 | 
						 * Read offset should never cross write offset. Write \0's to
 | 
				
			||||||
 | 
						 * read data just to be sure?
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						uint32_t buffer_read_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* How far into the circular buffer we have written
 | 
				
			||||||
 | 
						 * Write offset should never cross read offset
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						uint32_t buffer_write_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t write_wrap_count;
 | 
				
			||||||
 | 
						uint32_t read_wrap_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t open_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *log_buffer;	/* Pointer to malloc'ed buffer */
 | 
				
			||||||
 | 
						uint32_t log_buffer_size; /* Size of circular buffer */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t mask; /*array of masks for major elements*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union logger_flags flags;
 | 
				
			||||||
 | 
						struct dc_context *ctx;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DAL_LOGGER_H__ */
 | 
				
			||||||
							
								
								
									
										197
									
								
								drivers/gpu/drm/amd/display/dc/basics/register_logger.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								drivers/gpu/drm/amd/display/dc/basics/register_logger.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,197 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/dal_types.h"
 | 
				
			||||||
 | 
					#include "include/logger_interface.h"
 | 
				
			||||||
 | 
					#include "logger.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Register Logger.
 | 
				
			||||||
 | 
					 * A facility to create register R/W logs.
 | 
				
			||||||
 | 
					 * Currently used for DAL Test.
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Private structures
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					struct dal_reg_dump_stack_location {
 | 
				
			||||||
 | 
						const char *current_caller_func;
 | 
				
			||||||
 | 
						long current_pid;
 | 
				
			||||||
 | 
						long current_tgid;
 | 
				
			||||||
 | 
						uint32_t rw_count;/* register access counter for current function. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This the maximum number of nested calls to the 'reg_dump' facility. */
 | 
				
			||||||
 | 
					#define DAL_REG_DUMP_STACK_MAX_SIZE 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dal_reg_dump_stack {
 | 
				
			||||||
 | 
						int32_t stack_pointer;
 | 
				
			||||||
 | 
						struct dal_reg_dump_stack_location
 | 
				
			||||||
 | 
							stack_locations[DAL_REG_DUMP_STACK_MAX_SIZE];
 | 
				
			||||||
 | 
						uint32_t total_rw_count; /* Total count for *all* functions. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct dal_reg_dump_stack reg_dump_stack = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Private functions
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Check if current process is the one which requested register dump.
 | 
				
			||||||
 | 
					 * The reason for the check:
 | 
				
			||||||
 | 
					 * mmCRTC_STATUS_FRAME_COUNT is accessed by dal_controller_get_vblank_counter().
 | 
				
			||||||
 | 
					 * Which runs all the time when at least one display is connected.
 | 
				
			||||||
 | 
					 * (Triggered by drm_mode_page_flip_ioctl()). */
 | 
				
			||||||
 | 
					static bool is_reg_dump_process(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* walk the list of our processes */
 | 
				
			||||||
 | 
						for (i = 0; i < reg_dump_stack.stack_pointer; i++) {
 | 
				
			||||||
 | 
							struct dal_reg_dump_stack_location *stack_location
 | 
				
			||||||
 | 
										= ®_dump_stack.stack_locations[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (stack_location->current_pid == dm_get_pid()
 | 
				
			||||||
 | 
								&& stack_location->current_tgid == dm_get_tgid())
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool dal_reg_dump_stack_is_empty(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (reg_dump_stack.stack_pointer <= 0)
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct dal_reg_dump_stack_location *dal_reg_dump_stack_push(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dal_reg_dump_stack_location *current_location = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (reg_dump_stack.stack_pointer >= DAL_REG_DUMP_STACK_MAX_SIZE) {
 | 
				
			||||||
 | 
							/* stack is full */
 | 
				
			||||||
 | 
							dm_output_to_console("[REG_DUMP]: %s: stack is full!\n",
 | 
				
			||||||
 | 
									__func__);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							current_location =
 | 
				
			||||||
 | 
							®_dump_stack.stack_locations[reg_dump_stack.stack_pointer];
 | 
				
			||||||
 | 
							++reg_dump_stack.stack_pointer;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return current_location;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct dal_reg_dump_stack_location *dal_reg_dump_stack_pop(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dal_reg_dump_stack_location *current_location = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dal_reg_dump_stack_is_empty()) {
 | 
				
			||||||
 | 
							/* stack is empty */
 | 
				
			||||||
 | 
							dm_output_to_console("[REG_DUMP]: %s: stack is empty!\n",
 | 
				
			||||||
 | 
									__func__);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							--reg_dump_stack.stack_pointer;
 | 
				
			||||||
 | 
							current_location =
 | 
				
			||||||
 | 
							®_dump_stack.stack_locations[reg_dump_stack.stack_pointer];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return current_location;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Public functions
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_reg_logger_push(const char *caller_func)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dal_reg_dump_stack_location *free_stack_location;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free_stack_location = dal_reg_dump_stack_push();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == free_stack_location)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(free_stack_location, 0, sizeof(*free_stack_location));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free_stack_location->current_caller_func = caller_func;
 | 
				
			||||||
 | 
						free_stack_location->current_pid = dm_get_pid();
 | 
				
			||||||
 | 
						free_stack_location->current_tgid = dm_get_tgid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_output_to_console("[REG_DUMP]:%s - start (pid:%ld, tgid:%ld)\n",
 | 
				
			||||||
 | 
							caller_func,
 | 
				
			||||||
 | 
							free_stack_location->current_pid,
 | 
				
			||||||
 | 
							free_stack_location->current_tgid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_reg_logger_pop(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dal_reg_dump_stack_location *top_stack_location;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						top_stack_location = dal_reg_dump_stack_pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == top_stack_location) {
 | 
				
			||||||
 | 
							dm_output_to_console("[REG_DUMP]:%s - Stack is Empty!\n",
 | 
				
			||||||
 | 
									__func__);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_output_to_console(
 | 
				
			||||||
 | 
						"[REG_DUMP]:%s - end."\
 | 
				
			||||||
 | 
						" Reg R/W Count: Total=%d Function=%d. (pid:%ld, tgid:%ld)\n",
 | 
				
			||||||
 | 
								top_stack_location->current_caller_func,
 | 
				
			||||||
 | 
								reg_dump_stack.total_rw_count,
 | 
				
			||||||
 | 
								top_stack_location->rw_count,
 | 
				
			||||||
 | 
								dm_get_pid(),
 | 
				
			||||||
 | 
								dm_get_tgid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(top_stack_location, 0, sizeof(*top_stack_location));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_reg_logger_rw_count_increment(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						++reg_dump_stack.total_rw_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						++reg_dump_stack.stack_locations
 | 
				
			||||||
 | 
							[reg_dump_stack.stack_pointer - 1].rw_count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_reg_logger_should_dump_register(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (true == dal_reg_dump_stack_is_empty())
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == is_reg_dump_process())
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * End of File.
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
							
								
								
									
										116
									
								
								drivers/gpu/drm/amd/display/dc/basics/signal_types.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								drivers/gpu/drm/amd/display/dc/basics/signal_types.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,116 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/signal_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_hdmi_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_HDMI_TYPE_A);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_dp_sst_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
 | 
				
			||||||
 | 
							signal == SIGNAL_TYPE_EDP);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_dp_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
 | 
				
			||||||
 | 
							signal == SIGNAL_TYPE_EDP ||
 | 
				
			||||||
 | 
							signal == SIGNAL_TYPE_DISPLAY_PORT_MST);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_dp_external_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
 | 
				
			||||||
 | 
							signal == SIGNAL_TYPE_DISPLAY_PORT_MST);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_analog_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_RGB:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_embedded_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_EDP || signal == SIGNAL_TYPE_LVDS);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_dvi_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_SINGLE_LINK:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_DUAL_LINK:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_dvi_single_link_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_DVI_SINGLE_LINK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_dual_link_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_DVI_DUAL_LINK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_is_audio_capable_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
 | 
				
			||||||
 | 
							signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
 | 
				
			||||||
 | 
							dc_is_hdmi_signal(signal) ||
 | 
				
			||||||
 | 
							signal == SIGNAL_TYPE_WIRELESS);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * @brief
 | 
				
			||||||
 | 
					 * Returns whether the signal is compatible
 | 
				
			||||||
 | 
					 * with other digital encoder signal types.
 | 
				
			||||||
 | 
					 * This is true for DVI, LVDS, and HDMI signal types.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dc_is_digital_encoder_compatible_signal(enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_SINGLE_LINK:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_DUAL_LINK:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_HDMI_TYPE_A:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_LVDS:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										307
									
								
								drivers/gpu/drm/amd/display/dc/basics/vector.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								drivers/gpu/drm/amd/display/dc/basics/vector.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,307 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/vector.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_vector_construct(
 | 
				
			||||||
 | 
						struct vector *vector,
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						uint32_t capacity,
 | 
				
			||||||
 | 
						uint32_t struct_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						vector->container = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!struct_size || !capacity) {
 | 
				
			||||||
 | 
							/* Container must be non-zero size*/
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vector->container = dm_alloc(struct_size * capacity);
 | 
				
			||||||
 | 
						if (vector->container == NULL)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						vector->capacity = capacity;
 | 
				
			||||||
 | 
						vector->struct_size = struct_size;
 | 
				
			||||||
 | 
						vector->count = 0;
 | 
				
			||||||
 | 
						vector->ctx = ctx;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_vector_presized_costruct(
 | 
				
			||||||
 | 
						struct vector *vector,
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						uint32_t count,
 | 
				
			||||||
 | 
						void *initial_value,
 | 
				
			||||||
 | 
						uint32_t struct_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vector->container = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!struct_size || !count) {
 | 
				
			||||||
 | 
							/* Container must be non-zero size*/
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vector->container = dm_alloc(struct_size * count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (vector->container == NULL)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If caller didn't supply initial value then the default
 | 
				
			||||||
 | 
						 * of all zeros is expected, which is exactly what dal_alloc()
 | 
				
			||||||
 | 
						 * initialises the memory to. */
 | 
				
			||||||
 | 
						if (NULL != initial_value) {
 | 
				
			||||||
 | 
							for (i = 0; i < count; ++i)
 | 
				
			||||||
 | 
								memmove(
 | 
				
			||||||
 | 
									vector->container + i * struct_size,
 | 
				
			||||||
 | 
									initial_value,
 | 
				
			||||||
 | 
									struct_size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vector->capacity = count;
 | 
				
			||||||
 | 
						vector->struct_size = struct_size;
 | 
				
			||||||
 | 
						vector->count = count;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct vector *dal_vector_presized_create(
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						uint32_t size,
 | 
				
			||||||
 | 
						void *initial_value,
 | 
				
			||||||
 | 
						uint32_t struct_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct vector *vector = dm_alloc(sizeof(struct vector));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (vector == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dal_vector_presized_costruct(
 | 
				
			||||||
 | 
							vector, ctx, size, initial_value, struct_size))
 | 
				
			||||||
 | 
							return vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
						dm_free(vector);
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct vector *dal_vector_create(
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						uint32_t capacity,
 | 
				
			||||||
 | 
						uint32_t struct_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct vector *vector = dm_alloc(sizeof(struct vector));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (vector == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dal_vector_construct(vector, ctx, capacity, struct_size))
 | 
				
			||||||
 | 
							return vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
						dm_free(vector);
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_vector_destruct(
 | 
				
			||||||
 | 
						struct vector *vector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (vector->container != NULL)
 | 
				
			||||||
 | 
							dm_free(vector->container);
 | 
				
			||||||
 | 
						vector->count = 0;
 | 
				
			||||||
 | 
						vector->capacity = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_vector_destroy(
 | 
				
			||||||
 | 
						struct vector **vector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (vector == NULL || *vector == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						dal_vector_destruct(*vector);
 | 
				
			||||||
 | 
						dm_free(*vector);
 | 
				
			||||||
 | 
						*vector = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_vector_get_count(
 | 
				
			||||||
 | 
						const struct vector *vector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return vector->count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *dal_vector_at_index(
 | 
				
			||||||
 | 
						const struct vector *vector,
 | 
				
			||||||
 | 
						uint32_t index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (vector->container == NULL || index >= vector->count)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						return vector->container + (index * vector->struct_size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_vector_remove_at_index(
 | 
				
			||||||
 | 
						struct vector *vector,
 | 
				
			||||||
 | 
						uint32_t index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (index >= vector->count)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (index != vector->count - 1)
 | 
				
			||||||
 | 
							memmove(
 | 
				
			||||||
 | 
								vector->container + (index * vector->struct_size),
 | 
				
			||||||
 | 
								vector->container + ((index + 1) * vector->struct_size),
 | 
				
			||||||
 | 
								(vector->count - index - 1) * vector->struct_size);
 | 
				
			||||||
 | 
						vector->count -= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_vector_set_at_index(
 | 
				
			||||||
 | 
						const struct vector *vector,
 | 
				
			||||||
 | 
						const void *what,
 | 
				
			||||||
 | 
						uint32_t index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void *where = dal_vector_at_index(vector, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!where) {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						memmove(
 | 
				
			||||||
 | 
							where,
 | 
				
			||||||
 | 
							what,
 | 
				
			||||||
 | 
							vector->struct_size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t calc_increased_capacity(
 | 
				
			||||||
 | 
						uint32_t old_capacity)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return old_capacity * 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_vector_insert_at(
 | 
				
			||||||
 | 
						struct vector *vector,
 | 
				
			||||||
 | 
						const void *what,
 | 
				
			||||||
 | 
						uint32_t position)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t *insert_address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (vector->count == vector->capacity) {
 | 
				
			||||||
 | 
							if (!dal_vector_reserve(
 | 
				
			||||||
 | 
								vector,
 | 
				
			||||||
 | 
								calc_increased_capacity(vector->capacity)))
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						insert_address = vector->container + (vector->struct_size * position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (vector->count && position < vector->count)
 | 
				
			||||||
 | 
							memmove(
 | 
				
			||||||
 | 
								insert_address + vector->struct_size,
 | 
				
			||||||
 | 
								insert_address,
 | 
				
			||||||
 | 
								vector->struct_size * (vector->count - position));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memmove(
 | 
				
			||||||
 | 
							insert_address,
 | 
				
			||||||
 | 
							what,
 | 
				
			||||||
 | 
							vector->struct_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vector->count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_vector_append(
 | 
				
			||||||
 | 
						struct vector *vector,
 | 
				
			||||||
 | 
						const void *item)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dal_vector_insert_at(vector, item, vector->count);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct vector *dal_vector_clone(
 | 
				
			||||||
 | 
						const struct vector *vector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct vector *vec_cloned;
 | 
				
			||||||
 | 
						uint32_t count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* create new vector */
 | 
				
			||||||
 | 
						count = dal_vector_get_count(vector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (count == 0)
 | 
				
			||||||
 | 
							/* when count is 0 we still want to create clone of the vector
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							vec_cloned = dal_vector_create(
 | 
				
			||||||
 | 
								vector->ctx,
 | 
				
			||||||
 | 
								vector->capacity,
 | 
				
			||||||
 | 
								vector->struct_size);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							/* Call "presized create" version, independently of how the
 | 
				
			||||||
 | 
							 * original vector was created.
 | 
				
			||||||
 | 
							 * The owner of original vector must know how to treat the new
 | 
				
			||||||
 | 
							 * vector - as "presized" or as "regular".
 | 
				
			||||||
 | 
							 * But from vector point of view it doesn't matter. */
 | 
				
			||||||
 | 
							vec_cloned = dal_vector_presized_create(vector->ctx, count,
 | 
				
			||||||
 | 
								NULL,/* no initial value */
 | 
				
			||||||
 | 
								vector->struct_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == vec_cloned) {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* copy vector's data */
 | 
				
			||||||
 | 
						memmove(vec_cloned->container, vector->container,
 | 
				
			||||||
 | 
								vec_cloned->struct_size * vec_cloned->capacity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return vec_cloned;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_vector_capacity(const struct vector *vector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return vector->capacity;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_vector_reserve(struct vector *vector, uint32_t capacity)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void *new_container;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (capacity <= vector->capacity)
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						new_container = dm_realloc(vector->container, capacity * vector->struct_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (new_container) {
 | 
				
			||||||
 | 
							vector->container = new_container;
 | 
				
			||||||
 | 
							vector->capacity = capacity;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_vector_clear(struct vector *vector)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						vector->count = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								drivers/gpu/drm/amd/display/dc/bios/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								drivers/gpu/drm/amd/display/dc/bios/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for the 'bios' sub-component of DAL.
 | 
				
			||||||
 | 
					# It provides the parsing and executing controls for atom bios image.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BIOS = bios_parser.o bios_parser_interface.o  bios_parser_helper.o command_table.o command_table_helper.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DAL_BIOS = $(addprefix $(AMDDALPATH)/dc/bios/,$(BIOS))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DAL_BIOS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# DCE 8x
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# All DCE8.x are derived from DCE8.0, so 8.0 MUST be defined if ANY of
 | 
				
			||||||
 | 
					# DCE8.x is compiled.
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMDDALPATH)/dc/bios/dce80/command_table_helper_dce80.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# DCE 11x
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMDDALPATH)/dc/bios/dce110/command_table_helper_dce110.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ccflags-y += -DLATEST_ATOM_BIOS_SUPPORT
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMDDALPATH)/dc/bios/dce112/command_table_helper_dce112.o
 | 
				
			||||||
							
								
								
									
										4220
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4220
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										33
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_BIOS_PARSER_H__
 | 
				
			||||||
 | 
					#define __DAL_BIOS_PARSER_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_bios *bios_parser_create(
 | 
				
			||||||
 | 
						struct bp_init_data *init,
 | 
				
			||||||
 | 
						enum dce_version dce_version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										82
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "atom.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/bios_parser_types.h"
 | 
				
			||||||
 | 
					#include "bios_parser_helper.h"
 | 
				
			||||||
 | 
					#include "command_table_helper.h"
 | 
				
			||||||
 | 
					#include "command_table.h"
 | 
				
			||||||
 | 
					#include "bios_parser_types_internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t *get_image(struct dc_bios *bp,
 | 
				
			||||||
 | 
						uint32_t offset,
 | 
				
			||||||
 | 
						uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (bp->bios && offset + size < bp->bios_size)
 | 
				
			||||||
 | 
							return bp->bios + offset;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "reg_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CTX \
 | 
				
			||||||
 | 
						bios->ctx
 | 
				
			||||||
 | 
					#define REG(reg)\
 | 
				
			||||||
 | 
						(bios->regs->reg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef FN
 | 
				
			||||||
 | 
					#define FN(reg_name, field_name) \
 | 
				
			||||||
 | 
							ATOM_ ## field_name ## _SHIFT, ATOM_ ## field_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bios_is_accelerated_mode(
 | 
				
			||||||
 | 
						struct dc_bios *bios)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t acc_mode;
 | 
				
			||||||
 | 
						REG_GET(BIOS_SCRATCH_6, S6_ACC_MODE, &acc_mode);
 | 
				
			||||||
 | 
						return (acc_mode == 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bios_set_scratch_acc_mode_change(
 | 
				
			||||||
 | 
						struct dc_bios *bios)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						REG_UPDATE(BIOS_SCRATCH_6, S6_ACC_MODE, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bios_set_scratch_critical_state(
 | 
				
			||||||
 | 
						struct dc_bios *bios,
 | 
				
			||||||
 | 
						bool state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t critial_state = state ? 1 : 0;
 | 
				
			||||||
 | 
						REG_UPDATE(BIOS_SCRATCH_6, S6_CRITICAL_STATE, critial_state);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-16 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_BIOS_PARSER_HELPER_H__
 | 
				
			||||||
 | 
					#define __DAL_BIOS_PARSER_HELPER_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bios_parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t *get_image(struct dc_bios *bp, uint32_t offset,
 | 
				
			||||||
 | 
						uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bios_is_accelerated_mode(struct dc_bios *bios);
 | 
				
			||||||
 | 
					void bios_set_scratch_acc_mode_change(struct dc_bios *bios);
 | 
				
			||||||
 | 
					void bios_set_scratch_critical_state(struct dc_bios *bios, bool state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GET_IMAGE(type, offset) ((type *) get_image(&bp->base, offset, sizeof(type)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										50
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser_interface.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								drivers/gpu/drm/amd/display/dc/bios/bios_parser_interface.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "include/logger_interface.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "bios_parser_interface.h"
 | 
				
			||||||
 | 
					#include "bios_parser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_bios *dal_bios_parser_create(
 | 
				
			||||||
 | 
						struct bp_init_data *init,
 | 
				
			||||||
 | 
						enum dce_version dce_version)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dc_bios *bios = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bios = bios_parser_create(init, dce_version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return bios;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_bios_parser_destroy(struct dc_bios **dcb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dc_bios *bios = *dcb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bios->funcs->bios_parser_destroy(dcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_BIOS_PARSER_TYPES_BIOS_H__
 | 
				
			||||||
 | 
					#define __DAL_BIOS_PARSER_TYPES_BIOS_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dc_bios_types.h"
 | 
				
			||||||
 | 
					#include "bios_parser_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct atom_data_revision {
 | 
				
			||||||
 | 
						uint32_t major;
 | 
				
			||||||
 | 
						uint32_t minor;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct object_info_table {
 | 
				
			||||||
 | 
						struct atom_data_revision revision;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							ATOM_OBJECT_HEADER *v1_1;
 | 
				
			||||||
 | 
							ATOM_OBJECT_HEADER_V3 *v1_3;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum spread_spectrum_id {
 | 
				
			||||||
 | 
						SS_ID_UNKNOWN = 0,
 | 
				
			||||||
 | 
						SS_ID_DP1 = 0xf1,
 | 
				
			||||||
 | 
						SS_ID_DP2 = 0xf2,
 | 
				
			||||||
 | 
						SS_ID_LVLINK_2700MHZ = 0xf3,
 | 
				
			||||||
 | 
						SS_ID_LVLINK_1620MHZ = 0xf4
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bios_parser {
 | 
				
			||||||
 | 
						struct dc_bios base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct object_info_table object_info_tbl;
 | 
				
			||||||
 | 
						uint32_t object_info_tbl_offset;
 | 
				
			||||||
 | 
						ATOM_MASTER_DATA_TABLE *master_data_tbl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const struct bios_parser_helper *bios_helper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const struct command_table_helper *cmd_helper;
 | 
				
			||||||
 | 
						struct cmd_tbl cmd_tbl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool remap_device_tags;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Bios Parser from DC Bios */
 | 
				
			||||||
 | 
					#define BP_FROM_DCB(dc_bios) \
 | 
				
			||||||
 | 
						container_of(dc_bios, struct bios_parser, base)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										2609
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2609
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										112
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,112 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_COMMAND_TABLE_H__
 | 
				
			||||||
 | 
					#define __DAL_COMMAND_TABLE_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bios_parser;
 | 
				
			||||||
 | 
					struct bp_encoder_control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_tbl {
 | 
				
			||||||
 | 
						enum bp_result (*dig_encoder_control)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_encoder_control *control);
 | 
				
			||||||
 | 
						enum bp_result (*encoder_control_dig1)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_encoder_control *control);
 | 
				
			||||||
 | 
						enum bp_result (*encoder_control_dig2)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_encoder_control *control);
 | 
				
			||||||
 | 
						enum bp_result (*transmitter_control)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_transmitter_control *control);
 | 
				
			||||||
 | 
						enum bp_result (*set_pixel_clock)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_pixel_clock_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*enable_spread_spectrum_on_ppll)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_spread_spectrum_parameters *bp_params,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
						enum bp_result (*adjust_display_pll)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_adjust_pixel_clock_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*dac1_encoder_control)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							bool enable,
 | 
				
			||||||
 | 
							uint32_t pixel_clock,
 | 
				
			||||||
 | 
							uint8_t dac_standard);
 | 
				
			||||||
 | 
						enum bp_result (*dac2_encoder_control)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							bool enable,
 | 
				
			||||||
 | 
							uint32_t pixel_clock,
 | 
				
			||||||
 | 
							uint8_t dac_standard);
 | 
				
			||||||
 | 
						enum bp_result (*dac1_output_control)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
						enum bp_result (*dac2_output_control)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
						enum bp_result (*blank_crtc)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_blank_crtc_parameters *bp_params,
 | 
				
			||||||
 | 
							bool blank);
 | 
				
			||||||
 | 
						enum bp_result (*set_crtc_timing)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_hw_crtc_timing_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*set_crtc_overscan)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_hw_crtc_overscan_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*select_crtc_source)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_crtc_source_select *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*enable_crtc)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							enum controller_id controller_id,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
						enum bp_result (*enable_crtc_mem_req)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							enum controller_id controller_id,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
						enum bp_result (*program_clock)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_pixel_clock_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*compute_memore_engine_pll)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_display_clock_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*external_encoder_control)(
 | 
				
			||||||
 | 
								struct bios_parser *bp,
 | 
				
			||||||
 | 
								struct bp_external_encoder_control *cntl);
 | 
				
			||||||
 | 
						enum bp_result (*enable_disp_power_gating)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							enum controller_id crtc_id,
 | 
				
			||||||
 | 
							enum bp_pipe_control_action action);
 | 
				
			||||||
 | 
						enum bp_result (*set_dce_clock)(
 | 
				
			||||||
 | 
							struct bios_parser *bp,
 | 
				
			||||||
 | 
							struct bp_set_dce_clock_parameters *bp_params);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										288
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,288 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "atom.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/bios_parser_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "command_table_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_bios_parser_init_cmd_tbl_helper(
 | 
				
			||||||
 | 
						const struct command_table_helper **h,
 | 
				
			||||||
 | 
						enum dce_version dce)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (dce) {
 | 
				
			||||||
 | 
						case DCE_VERSION_8_0:
 | 
				
			||||||
 | 
							*h = dal_cmd_tbl_helper_dce80_get_table();
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case DCE_VERSION_10_0:
 | 
				
			||||||
 | 
							*h = dal_cmd_tbl_helper_dce110_get_table();
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case DCE_VERSION_11_0:
 | 
				
			||||||
 | 
							*h = dal_cmd_tbl_helper_dce110_get_table();
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case DCE_VERSION_11_2:
 | 
				
			||||||
 | 
							*h = dal_cmd_tbl_helper_dce112_get_table();
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* Unsupported DCE */
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* real implementations */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_cmd_table_helper_controller_id_to_atom(
 | 
				
			||||||
 | 
						enum controller_id id,
 | 
				
			||||||
 | 
						uint8_t *atom_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (atom_id == NULL) {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case CONTROLLER_ID_D0:
 | 
				
			||||||
 | 
							*atom_id = ATOM_CRTC1;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CONTROLLER_ID_D1:
 | 
				
			||||||
 | 
							*atom_id = ATOM_CRTC2;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CONTROLLER_ID_D2:
 | 
				
			||||||
 | 
							*atom_id = ATOM_CRTC3;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CONTROLLER_ID_D3:
 | 
				
			||||||
 | 
							*atom_id = ATOM_CRTC4;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CONTROLLER_ID_D4:
 | 
				
			||||||
 | 
							*atom_id = ATOM_CRTC5;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CONTROLLER_ID_D5:
 | 
				
			||||||
 | 
							*atom_id = ATOM_CRTC6;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CONTROLLER_ID_UNDERLAY0:
 | 
				
			||||||
 | 
							*atom_id = ATOM_UNDERLAY_PIPE0;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CONTROLLER_ID_UNDEFINED:
 | 
				
			||||||
 | 
							*atom_id = ATOM_CRTC_INVALID;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* Wrong controller id */
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					* translate_transmitter_bp_to_atom
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* @brief
 | 
				
			||||||
 | 
					*  Translate the Transmitter to the corresponding ATOM BIOS value
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* @param
 | 
				
			||||||
 | 
					*   input transmitter
 | 
				
			||||||
 | 
					*   output digitalTransmitter
 | 
				
			||||||
 | 
					*    // =00: Digital Transmitter1 ( UNIPHY linkAB )
 | 
				
			||||||
 | 
					*    // =01: Digital Transmitter2 ( UNIPHY linkCD )
 | 
				
			||||||
 | 
					*    // =02: Digital Transmitter3 ( UNIPHY linkEF )
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					uint8_t dal_cmd_table_helper_transmitter_bp_to_atom(
 | 
				
			||||||
 | 
						enum transmitter t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (t) {
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_A:
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_B:
 | 
				
			||||||
 | 
						case TRANSMITTER_TRAVIS_LCD:
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_C:
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_D:
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_E:
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_F:
 | 
				
			||||||
 | 
							return 2;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* Invalid Transmitter Type! */
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom(
 | 
				
			||||||
 | 
						enum signal_type s,
 | 
				
			||||||
 | 
						bool enable_dp_audio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (s) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_SINGLE_LINK:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_DUAL_LINK:
 | 
				
			||||||
 | 
							return ATOM_ENCODER_MODE_DVI;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_HDMI_TYPE_A:
 | 
				
			||||||
 | 
							return ATOM_ENCODER_MODE_HDMI;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_LVDS:
 | 
				
			||||||
 | 
							return ATOM_ENCODER_MODE_LVDS;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_EDP:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT_MST:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_VIRTUAL:
 | 
				
			||||||
 | 
							if (enable_dp_audio)
 | 
				
			||||||
 | 
								return ATOM_ENCODER_MODE_DP_AUDIO;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return ATOM_ENCODER_MODE_DP;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_RGB:
 | 
				
			||||||
 | 
							return ATOM_ENCODER_MODE_CRT;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return ATOM_ENCODER_MODE_CRT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_cmd_table_helper_assign_control_parameter(
 | 
				
			||||||
 | 
						const struct command_table_helper *h,
 | 
				
			||||||
 | 
						struct bp_encoder_control *control,
 | 
				
			||||||
 | 
						DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* there are three transmitter blocks, each one has two links 4-lanes
 | 
				
			||||||
 | 
						 * each, A+B, C+D, E+F, Uniphy A, C and E are enumerated as link 0 in
 | 
				
			||||||
 | 
						 * each transmitter block B, D and F as link 1, third transmitter block
 | 
				
			||||||
 | 
						 * has non splitable links (UniphyE and UniphyF can not be configured
 | 
				
			||||||
 | 
						 * separately to drive two different streams)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if ((control->transmitter == TRANSMITTER_UNIPHY_B) ||
 | 
				
			||||||
 | 
							(control->transmitter == TRANSMITTER_UNIPHY_D) ||
 | 
				
			||||||
 | 
							(control->transmitter == TRANSMITTER_UNIPHY_F)) {
 | 
				
			||||||
 | 
							/* Bit2: Link Select
 | 
				
			||||||
 | 
							 * =0: PHY linkA/C/E
 | 
				
			||||||
 | 
							 * =1: PHY linkB/D/F
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ctrl_param->acConfig.ucLinkSel = 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Bit[4:3]: Transmitter Selection
 | 
				
			||||||
 | 
						 * =00: Digital Transmitter1 ( UNIPHY linkAB )
 | 
				
			||||||
 | 
						 * =01: Digital Transmitter2 ( UNIPHY linkCD )
 | 
				
			||||||
 | 
						 * =02: Digital Transmitter3 ( UNIPHY linkEF )
 | 
				
			||||||
 | 
						 * =03: Reserved
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ctrl_param->acConfig.ucTransmitterSel =
 | 
				
			||||||
 | 
							(uint8_t)(h->transmitter_bp_to_atom(control->transmitter));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We need to convert from KHz units into 10KHz units */
 | 
				
			||||||
 | 
						ctrl_param->ucAction = h->encoder_action_to_atom(control->action);
 | 
				
			||||||
 | 
						ctrl_param->usPixelClock = cpu_to_le16((uint16_t)(control->pixel_clock / 10));
 | 
				
			||||||
 | 
						ctrl_param->ucEncoderMode =
 | 
				
			||||||
 | 
							(uint8_t)(h->encoder_mode_bp_to_atom(
 | 
				
			||||||
 | 
								control->signal, control->enable_dp_audio));
 | 
				
			||||||
 | 
						ctrl_param->ucLaneNum = (uint8_t)(control->lanes_number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src(
 | 
				
			||||||
 | 
						enum clock_source_id id,
 | 
				
			||||||
 | 
						uint32_t *ref_clk_src_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ref_clk_src_id == NULL) {
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL1:
 | 
				
			||||||
 | 
							*ref_clk_src_id = ENCODER_REFCLK_SRC_P1PLL;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL2:
 | 
				
			||||||
 | 
							*ref_clk_src_id = ENCODER_REFCLK_SRC_P2PLL;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_DCPLL:
 | 
				
			||||||
 | 
							*ref_clk_src_id = ENCODER_REFCLK_SRC_DCPLL;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_EXTERNAL:
 | 
				
			||||||
 | 
							*ref_clk_src_id = ENCODER_REFCLK_SRC_EXTCLK;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_UNDEFINED:
 | 
				
			||||||
 | 
							*ref_clk_src_id = ENCODER_REFCLK_SRC_INVALID;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* Unsupported clock source id */
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t dal_cmd_table_helper_encoder_id_to_atom(
 | 
				
			||||||
 | 
						enum encoder_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_LVDS:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_LVDS;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_TMDS1:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_TMDS1;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_TMDS2:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_TMDS2;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_DAC1:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_DAC1;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_DAC2:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_DAC2;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_LVTM1:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_LVTM1;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_HDMI:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_HDMI_INTERNAL;
 | 
				
			||||||
 | 
						case ENCODER_ID_EXTERNAL_TRAVIS:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_TRAVIS;
 | 
				
			||||||
 | 
						case ENCODER_ID_EXTERNAL_NUTMEG:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_NUTMEG;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_KLDSCP_TMDS1:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
 | 
				
			||||||
 | 
						case ENCODER_ID_EXTERNAL_MVPU_FPGA:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_MVPU_FPGA;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_DDI:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_DDI;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_UNIPHY:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_KLDSCP_LVTMA:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_UNIPHY1:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_UNIPHY1;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_UNIPHY2:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_UNIPHY2;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_UNIPHY3:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_UNIPHY3;
 | 
				
			||||||
 | 
						case ENCODER_ID_INTERNAL_WIRELESS:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_INTERNAL_VCE;
 | 
				
			||||||
 | 
						case ENCODER_ID_UNKNOWN:
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_NONE;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* Invalid encoder id */
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							return ENCODER_OBJECT_ID_NONE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										90
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,90 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_COMMAND_TABLE_HELPER_H__
 | 
				
			||||||
 | 
					#define __DAL_COMMAND_TABLE_HELPER_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dce80/command_table_helper_dce80.h"
 | 
				
			||||||
 | 
					#include "dce110/command_table_helper_dce110.h"
 | 
				
			||||||
 | 
					#include "dce112/command_table_helper_dce112.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct command_table_helper {
 | 
				
			||||||
 | 
						bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id);
 | 
				
			||||||
 | 
						uint8_t (*encoder_action_to_atom)(
 | 
				
			||||||
 | 
								enum bp_encoder_control_action action);
 | 
				
			||||||
 | 
						uint32_t (*encoder_mode_bp_to_atom)(enum signal_type s,
 | 
				
			||||||
 | 
								bool enable_dp_audio);
 | 
				
			||||||
 | 
						bool (*engine_bp_to_atom)(enum engine_id engine_id,
 | 
				
			||||||
 | 
								uint32_t *atom_engine_id);
 | 
				
			||||||
 | 
						void (*assign_control_parameter)(
 | 
				
			||||||
 | 
								const struct command_table_helper *h,
 | 
				
			||||||
 | 
								struct bp_encoder_control *control,
 | 
				
			||||||
 | 
								DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param);
 | 
				
			||||||
 | 
						bool (*clock_source_id_to_atom)(enum clock_source_id id,
 | 
				
			||||||
 | 
								uint32_t *atom_pll_id);
 | 
				
			||||||
 | 
						bool (*clock_source_id_to_ref_clk_src)(
 | 
				
			||||||
 | 
								enum clock_source_id id,
 | 
				
			||||||
 | 
								uint32_t *ref_clk_src_id);
 | 
				
			||||||
 | 
						uint8_t (*transmitter_bp_to_atom)(enum transmitter t);
 | 
				
			||||||
 | 
						uint8_t (*encoder_id_to_atom)(enum encoder_id id);
 | 
				
			||||||
 | 
						uint8_t (*clock_source_id_to_atom_phy_clk_src_id)(
 | 
				
			||||||
 | 
								enum clock_source_id id);
 | 
				
			||||||
 | 
						uint8_t (*signal_type_to_atom_dig_mode)(enum signal_type s);
 | 
				
			||||||
 | 
						uint8_t (*hpd_sel_to_atom)(enum hpd_source_id id);
 | 
				
			||||||
 | 
						uint8_t (*dig_encoder_sel_to_atom)(enum engine_id engine_id);
 | 
				
			||||||
 | 
						uint8_t (*phy_id_to_atom)(enum transmitter t);
 | 
				
			||||||
 | 
						uint8_t (*disp_power_gating_action_to_atom)(
 | 
				
			||||||
 | 
								enum bp_pipe_control_action action);
 | 
				
			||||||
 | 
						bool (*dc_clock_type_to_atom)(enum bp_dce_clock_type id,
 | 
				
			||||||
 | 
								uint32_t *atom_clock_type);
 | 
				
			||||||
 | 
					    uint8_t (*transmitter_color_depth_to_atom)(enum transmitter_color_depth id);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_bios_parser_init_cmd_tbl_helper(const struct command_table_helper **h,
 | 
				
			||||||
 | 
						enum dce_version dce);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_cmd_table_helper_controller_id_to_atom(
 | 
				
			||||||
 | 
						enum controller_id id,
 | 
				
			||||||
 | 
						uint8_t *atom_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom(
 | 
				
			||||||
 | 
						enum signal_type s,
 | 
				
			||||||
 | 
						bool enable_dp_audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dal_cmd_table_helper_assign_control_parameter(
 | 
				
			||||||
 | 
						const struct command_table_helper *h,
 | 
				
			||||||
 | 
						struct bp_encoder_control *control,
 | 
				
			||||||
 | 
					DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src(
 | 
				
			||||||
 | 
						enum clock_source_id id,
 | 
				
			||||||
 | 
						uint32_t *ref_clk_src_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t dal_cmd_table_helper_transmitter_bp_to_atom(
 | 
				
			||||||
 | 
						enum transmitter t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t dal_cmd_table_helper_encoder_id_to_atom(
 | 
				
			||||||
 | 
						enum encoder_id id);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,364 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "atom.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/bios_parser_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../command_table_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t phy_id_to_atom(enum transmitter t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_phy_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (t) {
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_A:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYA;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_B:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYB;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_C:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYC;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_D:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYD;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_E:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_F:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYF;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_G:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYG;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYA;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return atom_phy_id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t signal_type_to_atom_dig_mode(enum signal_type s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (s) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_EDP:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_LVDS:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_LVDS;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_SINGLE_LINK:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_DUAL_LINK:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_HDMI_TYPE_A:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_HDMI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT_MST:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP_MST;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_dig_mode;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t clock_source_id_to_atom_phy_clk_src_id(
 | 
				
			||||||
 | 
							enum clock_source_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_phy_clk_src_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL0:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL1:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL2:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_EXTERNAL:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_phy_clk_src_id >> 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t hpd_sel_to_atom(enum hpd_source_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_hpd_sel = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case HPD_SOURCEID1:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID2:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID3:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID4:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID5:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID6:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID_UNKNOWN:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_hpd_sel = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return atom_hpd_sel >> 4;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t dig_encoder_sel_to_atom(enum engine_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_dig_encoder_sel = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGA:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGB:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGB_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGC:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGC_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGD:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGD_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGE:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGE_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGF:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGF_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGG:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGG_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_UNKNOWN:
 | 
				
			||||||
 | 
							 /* No DIG_FRONT is associated to DIG_BACKEND */
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_dig_encoder_sel;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool clock_source_id_to_atom(
 | 
				
			||||||
 | 
						enum clock_source_id id,
 | 
				
			||||||
 | 
						uint32_t *atom_pll_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool result = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (atom_pll_id != NULL)
 | 
				
			||||||
 | 
							switch (id) {
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_PLL0:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_PLL1:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_PLL2:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL2;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_EXTERNAL:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_DFS:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_EXT_PLL1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_VCE:
 | 
				
			||||||
 | 
								/* for VCE encoding,
 | 
				
			||||||
 | 
								 * we need to pass in ATOM_PPLL_INVALID
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_DP_DTO:
 | 
				
			||||||
 | 
								/* When programming DP DTO PLL ID should be invalid */
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_UNDEFINED:
 | 
				
			||||||
 | 
								/* Should not happen */
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								result = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								result = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool result = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (atom_engine_id != NULL)
 | 
				
			||||||
 | 
							switch (id) {
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGA:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG1_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGB:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG2_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGC:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG3_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGD:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG4_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGE:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG5_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGF:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG6_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGG:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG7_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DACA:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_action = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (action) {
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_ENABLE:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_DISABLE:
 | 
				
			||||||
 | 
							atom_action = ATOM_DISABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_SETUP:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENCODER_CMD_SETUP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_INIT:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENCODER_INIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_action;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t disp_power_gating_action_to_atom(
 | 
				
			||||||
 | 
						enum bp_pipe_control_action action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_pipe_action = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (action) {
 | 
				
			||||||
 | 
						case ASIC_PIPE_DISABLE:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_DISABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ASIC_PIPE_ENABLE:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_ENABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ASIC_PIPE_INIT:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_INIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ASSERT_CRITICAL(false); /* Unhandle action in driver! */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_pipe_action;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* function table */
 | 
				
			||||||
 | 
					static const struct command_table_helper command_table_helper_funcs = {
 | 
				
			||||||
 | 
						.controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom,
 | 
				
			||||||
 | 
						.encoder_action_to_atom = encoder_action_to_atom,
 | 
				
			||||||
 | 
						.engine_bp_to_atom = engine_bp_to_atom,
 | 
				
			||||||
 | 
						.clock_source_id_to_atom = clock_source_id_to_atom,
 | 
				
			||||||
 | 
						.clock_source_id_to_atom_phy_clk_src_id =
 | 
				
			||||||
 | 
								clock_source_id_to_atom_phy_clk_src_id,
 | 
				
			||||||
 | 
						.signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
 | 
				
			||||||
 | 
						.hpd_sel_to_atom = hpd_sel_to_atom,
 | 
				
			||||||
 | 
						.dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
 | 
				
			||||||
 | 
						.phy_id_to_atom = phy_id_to_atom,
 | 
				
			||||||
 | 
						.disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
 | 
				
			||||||
 | 
						.assign_control_parameter = NULL,
 | 
				
			||||||
 | 
						.clock_source_id_to_ref_clk_src = NULL,
 | 
				
			||||||
 | 
						.transmitter_bp_to_atom = NULL,
 | 
				
			||||||
 | 
						.encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom,
 | 
				
			||||||
 | 
						.encoder_mode_bp_to_atom = dal_cmd_table_helper_encoder_mode_bp_to_atom,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * dal_cmd_tbl_helper_dce110_get_table
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @brief
 | 
				
			||||||
 | 
					 * Initialize command table helper functions
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param
 | 
				
			||||||
 | 
					 * const struct command_table_helper **h - [out] struct of functions
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const struct command_table_helper *dal_cmd_tbl_helper_dce110_get_table()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return &command_table_helper_funcs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_COMMAND_TABLE_HELPER_DCE110_H__
 | 
				
			||||||
 | 
					#define __DAL_COMMAND_TABLE_HELPER_DCE110_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct command_table_helper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Initialize command table helper functions */
 | 
				
			||||||
 | 
					const struct command_table_helper *dal_cmd_tbl_helper_dce110_get_table(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,418 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "atom.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/bios_parser_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../command_table_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t phy_id_to_atom(enum transmitter t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_phy_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (t) {
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_A:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYA;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_B:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYB;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_C:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYC;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_D:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYD;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_E:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_F:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYF;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_G:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYG;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYA;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return atom_phy_id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t signal_type_to_atom_dig_mode(enum signal_type s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (s) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_EDP:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_SINGLE_LINK:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_DUAL_LINK:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_HDMI_TYPE_A:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_HDMI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT_MST:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP_MST;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_dig_mode;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t clock_source_id_to_atom_phy_clk_src_id(
 | 
				
			||||||
 | 
							enum clock_source_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_phy_clk_src_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL0:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL1:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL2:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_EXTERNAL:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_phy_clk_src_id >> 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t hpd_sel_to_atom(enum hpd_source_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_hpd_sel = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case HPD_SOURCEID1:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD1_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID2:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD2_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID3:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD3_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID4:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD4_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID5:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD5_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID6:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD6_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID_UNKNOWN:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_hpd_sel = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return atom_hpd_sel;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t dig_encoder_sel_to_atom(enum engine_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_dig_encoder_sel = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGA:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGA_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGB:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGB_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGC:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGC_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGD:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGD_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGE:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGE_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGF:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGF_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGG:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGG_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_UNKNOWN:
 | 
				
			||||||
 | 
							/* No DIG_FRONT is associated to DIG_BACKEND */
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGA_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_dig_encoder_sel;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool clock_source_id_to_atom(
 | 
				
			||||||
 | 
						enum clock_source_id id,
 | 
				
			||||||
 | 
						uint32_t *atom_pll_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool result = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (atom_pll_id != NULL)
 | 
				
			||||||
 | 
							switch (id) {
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_COMBO_PHY_PLL0:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_COMBOPHY_PLL0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_COMBO_PHY_PLL1:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_COMBOPHY_PLL1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_COMBO_PHY_PLL2:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_COMBOPHY_PLL2;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_COMBO_PHY_PLL3:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_COMBOPHY_PLL3;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_COMBO_PHY_PLL4:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_COMBOPHY_PLL4;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_COMBO_PHY_PLL5:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_COMBOPHY_PLL5;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_COMBO_DISPLAY_PLL0:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_DFS:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_GCK_DFS;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_VCE:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_DP_DTO;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_DP_DTO:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_DP_DTO;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_UNDEFINED:
 | 
				
			||||||
 | 
								/* Should not happen */
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								result = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								result = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool result = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (atom_engine_id != NULL)
 | 
				
			||||||
 | 
							switch (id) {
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGA:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG1_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGB:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG2_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGC:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG3_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGD:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG4_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGE:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG5_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGF:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG6_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGG:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG7_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DACA:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_action = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (action) {
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_ENABLE:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_DISABLE:
 | 
				
			||||||
 | 
							atom_action = ATOM_DISABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_SETUP:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENCODER_CMD_STREAM_SETUP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_INIT:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENCODER_INIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_action;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t disp_power_gating_action_to_atom(
 | 
				
			||||||
 | 
						enum bp_pipe_control_action action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_pipe_action = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (action) {
 | 
				
			||||||
 | 
						case ASIC_PIPE_DISABLE:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_DISABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ASIC_PIPE_ENABLE:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_ENABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ASIC_PIPE_INIT:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_INIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ASSERT_CRITICAL(false); /* Unhandle action in driver! */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_pipe_action;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool dc_clock_type_to_atom(
 | 
				
			||||||
 | 
							enum bp_dce_clock_type id,
 | 
				
			||||||
 | 
							uint32_t *atom_clock_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool retCode = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (atom_clock_type != NULL) {
 | 
				
			||||||
 | 
							switch (id) {
 | 
				
			||||||
 | 
							case DCECLOCK_TYPE_DISPLAY_CLOCK:
 | 
				
			||||||
 | 
								*atom_clock_type = DCE_CLOCK_TYPE_DISPCLK;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case DCECLOCK_TYPE_DPREFCLK:
 | 
				
			||||||
 | 
								*atom_clock_type = DCE_CLOCK_TYPE_DPREFCLK;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								ASSERT_CRITICAL(false); /* Unhandle action in driver! */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return retCode;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t transmitter_color_depth_to_atom(enum transmitter_color_depth id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atomColorDepth = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case TRANSMITTER_COLOR_DEPTH_24:
 | 
				
			||||||
 | 
							atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_COLOR_DEPTH_30:
 | 
				
			||||||
 | 
							atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_COLOR_DEPTH_36:
 | 
				
			||||||
 | 
							atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_COLOR_DEPTH_48:
 | 
				
			||||||
 | 
							atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ASSERT_CRITICAL(false); /* Unhandle action in driver! */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atomColorDepth;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* function table */
 | 
				
			||||||
 | 
					static const struct command_table_helper command_table_helper_funcs = {
 | 
				
			||||||
 | 
						.controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom,
 | 
				
			||||||
 | 
						.encoder_action_to_atom = encoder_action_to_atom,
 | 
				
			||||||
 | 
						.engine_bp_to_atom = engine_bp_to_atom,
 | 
				
			||||||
 | 
						.clock_source_id_to_atom = clock_source_id_to_atom,
 | 
				
			||||||
 | 
						.clock_source_id_to_atom_phy_clk_src_id =
 | 
				
			||||||
 | 
								clock_source_id_to_atom_phy_clk_src_id,
 | 
				
			||||||
 | 
						.signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
 | 
				
			||||||
 | 
						.hpd_sel_to_atom = hpd_sel_to_atom,
 | 
				
			||||||
 | 
						.dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
 | 
				
			||||||
 | 
						.phy_id_to_atom = phy_id_to_atom,
 | 
				
			||||||
 | 
						.disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
 | 
				
			||||||
 | 
						.assign_control_parameter = NULL,
 | 
				
			||||||
 | 
						.clock_source_id_to_ref_clk_src = NULL,
 | 
				
			||||||
 | 
						.transmitter_bp_to_atom = NULL,
 | 
				
			||||||
 | 
						.encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom,
 | 
				
			||||||
 | 
						.encoder_mode_bp_to_atom = dal_cmd_table_helper_encoder_mode_bp_to_atom,
 | 
				
			||||||
 | 
						.dc_clock_type_to_atom = dc_clock_type_to_atom,
 | 
				
			||||||
 | 
						.transmitter_color_depth_to_atom = transmitter_color_depth_to_atom,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * dal_cmd_tbl_helper_dce110_get_table
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @brief
 | 
				
			||||||
 | 
					 * Initialize command table helper functions
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param
 | 
				
			||||||
 | 
					 * const struct command_table_helper **h - [out] struct of functions
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return &command_table_helper_funcs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_COMMAND_TABLE_HELPER_DCE112_H__
 | 
				
			||||||
 | 
					#define __DAL_COMMAND_TABLE_HELPER_DCE112_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct command_table_helper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Initialize command table helper functions */
 | 
				
			||||||
 | 
					const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,354 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "atom.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/grph_object_id.h"
 | 
				
			||||||
 | 
					#include "include/grph_object_defs.h"
 | 
				
			||||||
 | 
					#include "include/bios_parser_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../command_table_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_action = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (action) {
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_ENABLE:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_DISABLE:
 | 
				
			||||||
 | 
							atom_action = ATOM_DISABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_SETUP:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENCODER_CMD_SETUP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENCODER_CONTROL_INIT:
 | 
				
			||||||
 | 
							atom_action = ATOM_ENCODER_INIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_action;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool result = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (atom_engine_id != NULL)
 | 
				
			||||||
 | 
							switch (id) {
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGA:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG1_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGB:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG2_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGC:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG3_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGD:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG4_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGE:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG5_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGF:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG6_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DIGG:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DIG7_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ENGINE_ID_DACA:
 | 
				
			||||||
 | 
								*atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
 | 
				
			||||||
 | 
								result = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool clock_source_id_to_atom(
 | 
				
			||||||
 | 
						enum clock_source_id id,
 | 
				
			||||||
 | 
						uint32_t *atom_pll_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool result = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (atom_pll_id != NULL)
 | 
				
			||||||
 | 
							switch (id) {
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_PLL0:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_PLL1:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_PLL2:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL2;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_EXTERNAL:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_DFS:
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_EXT_PLL1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_VCE:
 | 
				
			||||||
 | 
								/* for VCE encoding,
 | 
				
			||||||
 | 
								 * we need to pass in ATOM_PPLL_INVALID
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_DP_DTO:
 | 
				
			||||||
 | 
								/* When programming DP DTO PLL ID should be invalid */
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case CLOCK_SOURCE_ID_UNDEFINED:
 | 
				
			||||||
 | 
								BREAK_TO_DEBUGGER(); /* check when this will happen! */
 | 
				
			||||||
 | 
								*atom_pll_id = ATOM_PPLL_INVALID;
 | 
				
			||||||
 | 
								result = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								result = false;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t clock_source_id_to_atom_phy_clk_src_id(
 | 
				
			||||||
 | 
							enum clock_source_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_phy_clk_src_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL0:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL1:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_PLL2:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case CLOCK_SOURCE_ID_EXTERNAL:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_phy_clk_src_id >> 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t signal_type_to_atom_dig_mode(enum signal_type s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (s) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_EDP:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_LVDS:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_LVDS;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_SINGLE_LINK:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DVI_DUAL_LINK:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_HDMI_TYPE_A:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_HDMI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT_MST:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP_MST;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_dig_mode;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t hpd_sel_to_atom(enum hpd_source_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_hpd_sel = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case HPD_SOURCEID1:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID2:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID3:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID4:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID5:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID6:
 | 
				
			||||||
 | 
							atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HPD_SOURCEID_UNKNOWN:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_hpd_sel = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return atom_hpd_sel >> 4;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t dig_encoder_sel_to_atom(enum engine_id id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_dig_encoder_sel = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (id) {
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGA:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGB:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGB_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGC:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGC_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGD:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGD_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGE:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGE_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGF:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGF_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ENGINE_ID_DIGG:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGG_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_dig_encoder_sel;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t phy_id_to_atom(enum transmitter t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_phy_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (t) {
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_A:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYA;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_B:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYB;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_C:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYC;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_D:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYD;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_E:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_F:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYF;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TRANSMITTER_UNIPHY_G:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYG;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							atom_phy_id = ATOM_PHY_ID_UNIPHYA;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return atom_phy_id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t disp_power_gating_action_to_atom(
 | 
				
			||||||
 | 
						enum bp_pipe_control_action action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t atom_pipe_action = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (action) {
 | 
				
			||||||
 | 
						case ASIC_PIPE_DISABLE:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_DISABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ASIC_PIPE_ENABLE:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_ENABLE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ASIC_PIPE_INIT:
 | 
				
			||||||
 | 
							atom_pipe_action = ATOM_INIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER(); /* Unhandle action in driver! */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return atom_pipe_action;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct command_table_helper command_table_helper_funcs = {
 | 
				
			||||||
 | 
						.controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom,
 | 
				
			||||||
 | 
						.encoder_action_to_atom = encoder_action_to_atom,
 | 
				
			||||||
 | 
						.engine_bp_to_atom = engine_bp_to_atom,
 | 
				
			||||||
 | 
						.clock_source_id_to_atom = clock_source_id_to_atom,
 | 
				
			||||||
 | 
						.clock_source_id_to_atom_phy_clk_src_id =
 | 
				
			||||||
 | 
							clock_source_id_to_atom_phy_clk_src_id,
 | 
				
			||||||
 | 
						.signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
 | 
				
			||||||
 | 
						.hpd_sel_to_atom = hpd_sel_to_atom,
 | 
				
			||||||
 | 
						.dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
 | 
				
			||||||
 | 
						.phy_id_to_atom = phy_id_to_atom,
 | 
				
			||||||
 | 
						.disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
 | 
				
			||||||
 | 
						.assign_control_parameter =
 | 
				
			||||||
 | 
							dal_cmd_table_helper_assign_control_parameter,
 | 
				
			||||||
 | 
						.clock_source_id_to_ref_clk_src =
 | 
				
			||||||
 | 
							dal_cmd_table_helper_clock_source_id_to_ref_clk_src,
 | 
				
			||||||
 | 
						.transmitter_bp_to_atom = dal_cmd_table_helper_transmitter_bp_to_atom,
 | 
				
			||||||
 | 
						.encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom,
 | 
				
			||||||
 | 
						.encoder_mode_bp_to_atom =
 | 
				
			||||||
 | 
							dal_cmd_table_helper_encoder_mode_bp_to_atom,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct command_table_helper *dal_cmd_tbl_helper_dce80_get_table()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return &command_table_helper_funcs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DAL_COMMAND_TABLE_HELPER_DCE80_H__
 | 
				
			||||||
 | 
					#define __DAL_COMMAND_TABLE_HELPER_DCE80_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct command_table_helper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct command_table_helper *dal_cmd_tbl_helper_dce80_get_table(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										10
									
								
								drivers/gpu/drm/amd/display/dc/calcs/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								drivers/gpu/drm/amd/display/dc/calcs/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for the 'calcs' sub-component of DAL.
 | 
				
			||||||
 | 
					# It calculates Bandwidth and Watermarks values for HW programming
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BW_CALCS = bandwidth_calcs.o bw_fixed.o gamma_calcs.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DAL_BW_CALCS = $(addprefix $(AMDDALPATH)/dc/calcs/,$(BW_CALCS))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DAL_BW_CALCS)
 | 
				
			||||||
							
								
								
									
										3108
									
								
								drivers/gpu/drm/amd/display/dc/calcs/bandwidth_calcs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3108
									
								
								drivers/gpu/drm/amd/display/dc/calcs/bandwidth_calcs.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										299
									
								
								drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,299 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "bw_fixed.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BITS_PER_FRACTIONAL_PART 24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MIN_I32 \
 | 
				
			||||||
 | 
						(int64_t)(-(1LL << (63 - BITS_PER_FRACTIONAL_PART)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_I32 \
 | 
				
			||||||
 | 
						(int64_t)((1ULL << (63 - BITS_PER_FRACTIONAL_PART)) - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MIN_I64 \
 | 
				
			||||||
 | 
						(int64_t)(-(1LL << 63))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_I64 \
 | 
				
			||||||
 | 
						(int64_t)((1ULL << 63) - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FRACTIONAL_PART_MASK \
 | 
				
			||||||
 | 
						((1ULL << BITS_PER_FRACTIONAL_PART) - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GET_INTEGER_PART(x) \
 | 
				
			||||||
 | 
						((x) >> BITS_PER_FRACTIONAL_PART)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GET_FRACTIONAL_PART(x) \
 | 
				
			||||||
 | 
						(FRACTIONAL_PART_MASK & (x))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint64_t abs_i64(int64_t arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (arg >= 0)
 | 
				
			||||||
 | 
							return (uint64_t)(arg);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return (uint64_t)(-arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_min3(struct bw_fixed v1, struct bw_fixed v2, struct bw_fixed v3)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return bw_min2(bw_min2(v1, v2), v3);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_max3(struct bw_fixed v1, struct bw_fixed v2, struct bw_fixed v3)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return bw_max2(bw_max2(v1, v2), v3);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_int_to_fixed(int64_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed res;
 | 
				
			||||||
 | 
						ASSERT(value < MAX_I32 && value > MIN_I32);
 | 
				
			||||||
 | 
						res.value = value << BITS_PER_FRACTIONAL_PART;
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t bw_fixed_to_int(struct bw_fixed value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return GET_INTEGER_PART(value.value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_frc_to_fixed(int64_t numerator, int64_t denominator)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed res;
 | 
				
			||||||
 | 
						bool arg1_negative = numerator < 0;
 | 
				
			||||||
 | 
						bool arg2_negative = denominator < 0;
 | 
				
			||||||
 | 
						uint64_t arg1_value;
 | 
				
			||||||
 | 
						uint64_t arg2_value;
 | 
				
			||||||
 | 
						uint64_t remainder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* determine integer part */
 | 
				
			||||||
 | 
						uint64_t res_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(denominator != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg1_value = abs_i64(numerator);
 | 
				
			||||||
 | 
						arg2_value = abs_i64(denominator);
 | 
				
			||||||
 | 
						res_value = div64_u64_rem(arg1_value, arg2_value, &remainder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(res_value <= MAX_I32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* determine fractional part */
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint32_t i = BITS_PER_FRACTIONAL_PART;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							do
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								remainder <<= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								res_value <<= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (remainder >= arg2_value)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									res_value |= 1;
 | 
				
			||||||
 | 
									remainder -= arg2_value;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} while (--i != 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* round up LSB */
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint64_t summand = (remainder << 1) >= arg2_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ASSERT(res_value <= MAX_I64 - summand);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							res_value += summand;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = (int64_t)(res_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg1_negative ^ arg2_negative)
 | 
				
			||||||
 | 
							res.value = -res.value;
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_min2(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (arg1.value <= arg2.value) ? arg1 : arg2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_max2(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (arg2.value <= arg1.value) ? arg1 : arg2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_floor2(
 | 
				
			||||||
 | 
						const struct bw_fixed arg,
 | 
				
			||||||
 | 
						const struct bw_fixed significance)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed result;
 | 
				
			||||||
 | 
						int64_t multiplicand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						multiplicand = div64_s64(arg.value, abs_i64(significance.value));
 | 
				
			||||||
 | 
						result.value = abs_i64(significance.value) * multiplicand;
 | 
				
			||||||
 | 
						ASSERT(abs_i64(result.value) <= abs_i64(arg.value));
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_ceil2(
 | 
				
			||||||
 | 
						const struct bw_fixed arg,
 | 
				
			||||||
 | 
						const struct bw_fixed significance)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed result;
 | 
				
			||||||
 | 
						int64_t multiplicand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						multiplicand = div64_s64(arg.value, abs_i64(significance.value));
 | 
				
			||||||
 | 
						result.value = abs_i64(significance.value) * multiplicand;
 | 
				
			||||||
 | 
						if (abs_i64(result.value) < abs_i64(arg.value)) {
 | 
				
			||||||
 | 
							if (arg.value < 0)
 | 
				
			||||||
 | 
								result.value -= abs_i64(significance.value);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								result.value += abs_i64(significance.value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_add(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg1.value + arg2.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_sub(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg1.value - arg2.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_mul(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool arg1_negative = arg1.value < 0;
 | 
				
			||||||
 | 
						bool arg2_negative = arg2.value < 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg1_value = abs_i64(arg1.value);
 | 
				
			||||||
 | 
						uint64_t arg2_value = abs_i64(arg2.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg1_int = GET_INTEGER_PART(arg1_value);
 | 
				
			||||||
 | 
						uint64_t arg2_int = GET_INTEGER_PART(arg2_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t arg1_fra = GET_FRACTIONAL_PART(arg1_value);
 | 
				
			||||||
 | 
						uint64_t arg2_fra = GET_FRACTIONAL_PART(arg2_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value = arg1_int * arg2_int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(res.value <= MAX_I32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value <<= BITS_PER_FRACTIONAL_PART;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg1_int * arg2_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(MAX_I64 - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg2_int * arg1_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(MAX_I64 - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = arg1_fra * arg2_fra;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = (tmp >> BITS_PER_FRACTIONAL_PART) +
 | 
				
			||||||
 | 
							(tmp >= (uint64_t)(bw_frc_to_fixed(1, 2).value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(tmp <= (uint64_t)(MAX_I64 - res.value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.value += tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg1_negative ^ arg2_negative)
 | 
				
			||||||
 | 
							res.value = -res.value;
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_div(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed res = bw_frc_to_fixed(arg1.value, arg2.value);
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bw_fixed bw_mod(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed res;
 | 
				
			||||||
 | 
						div64_u64_rem(arg1.value, arg2.value, &res.value);
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					struct bw_fixed fixed31_32_to_bw_fixed(int64_t raw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bw_fixed result = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (raw < 0) {
 | 
				
			||||||
 | 
							raw = -raw;
 | 
				
			||||||
 | 
							result.value = -(raw >> (32 - BITS_PER_FRACTIONAL_PART));
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							result.value = raw >> (32 - BITS_PER_FRACTIONAL_PART);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bw_equ(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value == arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bw_neq(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value != arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bw_leq(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value <= arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bw_meq(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value >= arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bw_ltn(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value < arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool bw_mtn(const struct bw_fixed arg1, const struct bw_fixed arg2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return arg1.value > arg2.value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1382
									
								
								drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1382
									
								
								drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1846
									
								
								drivers/gpu/drm/amd/display/dc/core/dc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1846
									
								
								drivers/gpu/drm/amd/display/dc/core/dc.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										270
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_debug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_debug.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,270 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * dc_debug.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Nov 3, 2016
 | 
				
			||||||
 | 
					 *      Author: yonsun
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core_status.h"
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					#include "hw_sequencer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "resource.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SURFACE_TRACE(...) do {\
 | 
				
			||||||
 | 
							if (dc->debug.surface_trace) \
 | 
				
			||||||
 | 
								dm_logger_write(logger, \
 | 
				
			||||||
 | 
										LOG_IF_TRACE, \
 | 
				
			||||||
 | 
										##__VA_ARGS__); \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pre_surface_trace(
 | 
				
			||||||
 | 
							const struct dc *dc,
 | 
				
			||||||
 | 
							const struct dc_surface *const *surfaces,
 | 
				
			||||||
 | 
							int surface_count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						struct core_dc *core_dc = DC_TO_CORE(dc);
 | 
				
			||||||
 | 
						struct dal_logger *logger =  core_dc->ctx->logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < surface_count; i++) {
 | 
				
			||||||
 | 
							const struct dc_surface *surface = surfaces[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SURFACE_TRACE("Surface %d:\n", i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SURFACE_TRACE(
 | 
				
			||||||
 | 
									"surface->visible = %d;\n"
 | 
				
			||||||
 | 
									"surface->flip_immediate = %d;\n"
 | 
				
			||||||
 | 
									"surface->address.type = %d;\n"
 | 
				
			||||||
 | 
									"surface->address.grph.addr.quad_part = 0x%X;\n"
 | 
				
			||||||
 | 
									"surface->address.grph.meta_addr.quad_part = 0x%X;\n"
 | 
				
			||||||
 | 
									"surface->scaling_quality.h_taps = %d;\n"
 | 
				
			||||||
 | 
									"surface->scaling_quality.v_taps = %d;\n"
 | 
				
			||||||
 | 
									"surface->scaling_quality.h_taps_c = %d;\n"
 | 
				
			||||||
 | 
									"surface->scaling_quality.v_taps_c = %d;\n",
 | 
				
			||||||
 | 
									surface->visible,
 | 
				
			||||||
 | 
									surface->flip_immediate,
 | 
				
			||||||
 | 
									surface->address.type,
 | 
				
			||||||
 | 
									surface->address.grph.addr.quad_part,
 | 
				
			||||||
 | 
									surface->address.grph.meta_addr.quad_part,
 | 
				
			||||||
 | 
									surface->scaling_quality.h_taps,
 | 
				
			||||||
 | 
									surface->scaling_quality.v_taps,
 | 
				
			||||||
 | 
									surface->scaling_quality.h_taps_c,
 | 
				
			||||||
 | 
									surface->scaling_quality.v_taps_c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SURFACE_TRACE(
 | 
				
			||||||
 | 
									"surface->src_rect.x = %d;\n"
 | 
				
			||||||
 | 
									"surface->src_rect.y = %d;\n"
 | 
				
			||||||
 | 
									"surface->src_rect.width = %d;\n"
 | 
				
			||||||
 | 
									"surface->src_rect.height = %d;\n"
 | 
				
			||||||
 | 
									"surface->dst_rect.x = %d;\n"
 | 
				
			||||||
 | 
									"surface->dst_rect.y = %d;\n"
 | 
				
			||||||
 | 
									"surface->dst_rect.width = %d;\n"
 | 
				
			||||||
 | 
									"surface->dst_rect.height = %d;\n"
 | 
				
			||||||
 | 
									"surface->clip_rect.x = %d;\n"
 | 
				
			||||||
 | 
									"surface->clip_rect.y = %d;\n"
 | 
				
			||||||
 | 
									"surface->clip_rect.width = %d;\n"
 | 
				
			||||||
 | 
									"surface->clip_rect.height = %d;\n",
 | 
				
			||||||
 | 
									surface->src_rect.x,
 | 
				
			||||||
 | 
									surface->src_rect.y,
 | 
				
			||||||
 | 
									surface->src_rect.width,
 | 
				
			||||||
 | 
									surface->src_rect.height,
 | 
				
			||||||
 | 
									surface->dst_rect.x,
 | 
				
			||||||
 | 
									surface->dst_rect.y,
 | 
				
			||||||
 | 
									surface->dst_rect.width,
 | 
				
			||||||
 | 
									surface->dst_rect.height,
 | 
				
			||||||
 | 
									surface->clip_rect.x,
 | 
				
			||||||
 | 
									surface->clip_rect.y,
 | 
				
			||||||
 | 
									surface->clip_rect.width,
 | 
				
			||||||
 | 
									surface->clip_rect.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SURFACE_TRACE(
 | 
				
			||||||
 | 
									"surface->plane_size.grph.surface_size.x = %d;\n"
 | 
				
			||||||
 | 
									"surface->plane_size.grph.surface_size.y = %d;\n"
 | 
				
			||||||
 | 
									"surface->plane_size.grph.surface_size.width = %d;\n"
 | 
				
			||||||
 | 
									"surface->plane_size.grph.surface_size.height = %d;\n"
 | 
				
			||||||
 | 
									"surface->plane_size.grph.surface_pitch = %d;\n"
 | 
				
			||||||
 | 
									"surface->plane_size.grph.meta_pitch = %d;\n",
 | 
				
			||||||
 | 
									surface->plane_size.grph.surface_size.x,
 | 
				
			||||||
 | 
									surface->plane_size.grph.surface_size.y,
 | 
				
			||||||
 | 
									surface->plane_size.grph.surface_size.width,
 | 
				
			||||||
 | 
									surface->plane_size.grph.surface_size.height,
 | 
				
			||||||
 | 
									surface->plane_size.grph.surface_pitch,
 | 
				
			||||||
 | 
									surface->plane_size.grph.meta_pitch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SURFACE_TRACE(
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.num_banks = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.bank_width = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.bank_width_c = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.bank_height = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.bank_height_c = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.tile_aspect = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.tile_aspect_c = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.tile_split = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.tile_split_c = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.tile_mode = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.tile_mode_c = %d;\n",
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.num_banks,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.bank_width,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.bank_width_c,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.bank_height,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.bank_height_c,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.tile_aspect,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.tile_aspect_c,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.tile_split,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.tile_split_c,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.tile_mode,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.tile_mode_c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SURFACE_TRACE(
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.pipe_config = %d;\n"
 | 
				
			||||||
 | 
									"surface->tiling_info.gfx8.array_mode = %d;\n"
 | 
				
			||||||
 | 
									"surface->color_space = %d;\n"
 | 
				
			||||||
 | 
									"surface->dcc.enable = %d;\n"
 | 
				
			||||||
 | 
									"surface->format = %d;\n"
 | 
				
			||||||
 | 
									"surface->rotation = %d;\n"
 | 
				
			||||||
 | 
									"surface->stereo_format = %d;\n",
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.pipe_config,
 | 
				
			||||||
 | 
									surface->tiling_info.gfx8.array_mode,
 | 
				
			||||||
 | 
									surface->color_space,
 | 
				
			||||||
 | 
									surface->dcc.enable,
 | 
				
			||||||
 | 
									surface->format,
 | 
				
			||||||
 | 
									surface->rotation,
 | 
				
			||||||
 | 
									surface->stereo_format);
 | 
				
			||||||
 | 
							SURFACE_TRACE("\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						SURFACE_TRACE("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void update_surface_trace(
 | 
				
			||||||
 | 
							const struct dc *dc,
 | 
				
			||||||
 | 
							const struct dc_surface_update *updates,
 | 
				
			||||||
 | 
							int surface_count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						struct core_dc *core_dc = DC_TO_CORE(dc);
 | 
				
			||||||
 | 
						struct dal_logger *logger =  core_dc->ctx->logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < surface_count; i++) {
 | 
				
			||||||
 | 
							const struct dc_surface_update *update = &updates[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SURFACE_TRACE("Update %d\n", i);
 | 
				
			||||||
 | 
							if (update->flip_addr) {
 | 
				
			||||||
 | 
								SURFACE_TRACE("flip_addr->address.type = %d;\n"
 | 
				
			||||||
 | 
										"flip_addr->address.grph.addr.quad_part = 0x%X;\n"
 | 
				
			||||||
 | 
										"flip_addr->address.grph.meta_addr.quad_part = 0x%X;\n"
 | 
				
			||||||
 | 
										"flip_addr->flip_immediate = %d;\n",
 | 
				
			||||||
 | 
										update->flip_addr->address.type,
 | 
				
			||||||
 | 
										update->flip_addr->address.grph.addr.quad_part,
 | 
				
			||||||
 | 
										update->flip_addr->address.grph.meta_addr.quad_part,
 | 
				
			||||||
 | 
										update->flip_addr->flip_immediate);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (update->plane_info) {
 | 
				
			||||||
 | 
								SURFACE_TRACE(
 | 
				
			||||||
 | 
										"plane_info->color_space = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->format = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->plane_size.grph.meta_pitch = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->plane_size.grph.surface_pitch = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->plane_size.grph.surface_size.height = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->plane_size.grph.surface_size.width = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->plane_size.grph.surface_size.x = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->plane_size.grph.surface_size.y = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->rotation = %d;\n",
 | 
				
			||||||
 | 
										update->plane_info->color_space,
 | 
				
			||||||
 | 
										update->plane_info->format,
 | 
				
			||||||
 | 
										update->plane_info->plane_size.grph.meta_pitch,
 | 
				
			||||||
 | 
										update->plane_info->plane_size.grph.surface_pitch,
 | 
				
			||||||
 | 
										update->plane_info->plane_size.grph.surface_size.height,
 | 
				
			||||||
 | 
										update->plane_info->plane_size.grph.surface_size.width,
 | 
				
			||||||
 | 
										update->plane_info->plane_size.grph.surface_size.x,
 | 
				
			||||||
 | 
										update->plane_info->plane_size.grph.surface_size.y,
 | 
				
			||||||
 | 
										update->plane_info->rotation,
 | 
				
			||||||
 | 
										update->plane_info->stereo_format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								SURFACE_TRACE(
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.num_banks = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.bank_width = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.bank_width_c = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.bank_height = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.bank_height_c = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.tile_aspect = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.tile_aspect_c = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.tile_split = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.tile_split_c = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.tile_mode = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.tile_mode_c = %d;\n",
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.num_banks,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.bank_width,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.bank_width_c,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.bank_height,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.bank_height_c,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.tile_aspect,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.tile_aspect_c,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.tile_split,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.tile_split_c,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.tile_mode,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.tile_mode_c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								SURFACE_TRACE(
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.pipe_config = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->tiling_info.gfx8.array_mode = %d;\n"
 | 
				
			||||||
 | 
										"plane_info->visible = %d;\n",
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.pipe_config,
 | 
				
			||||||
 | 
										update->plane_info->tiling_info.gfx8.array_mode,
 | 
				
			||||||
 | 
										update->plane_info->visible);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (update->scaling_info) {
 | 
				
			||||||
 | 
								SURFACE_TRACE(
 | 
				
			||||||
 | 
										"scaling_info->src_rect.x = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->src_rect.y = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->src_rect.width = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->src_rect.height = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->dst_rect.x = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->dst_rect.y = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->dst_rect.width = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->dst_rect.height = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->clip_rect.x = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->clip_rect.y = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->clip_rect.width = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->clip_rect.height = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->scaling_quality.h_taps = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->scaling_quality.v_taps = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->scaling_quality.h_taps_c = %d;\n"
 | 
				
			||||||
 | 
										"scaling_info->scaling_quality.v_taps_c = %d;\n",
 | 
				
			||||||
 | 
										update->scaling_info->src_rect.x,
 | 
				
			||||||
 | 
										update->scaling_info->src_rect.y,
 | 
				
			||||||
 | 
										update->scaling_info->src_rect.width,
 | 
				
			||||||
 | 
										update->scaling_info->src_rect.height,
 | 
				
			||||||
 | 
										update->scaling_info->dst_rect.x,
 | 
				
			||||||
 | 
										update->scaling_info->dst_rect.y,
 | 
				
			||||||
 | 
										update->scaling_info->dst_rect.width,
 | 
				
			||||||
 | 
										update->scaling_info->dst_rect.height,
 | 
				
			||||||
 | 
										update->scaling_info->clip_rect.x,
 | 
				
			||||||
 | 
										update->scaling_info->clip_rect.y,
 | 
				
			||||||
 | 
										update->scaling_info->clip_rect.width,
 | 
				
			||||||
 | 
										update->scaling_info->clip_rect.height,
 | 
				
			||||||
 | 
										update->scaling_info->scaling_quality.h_taps,
 | 
				
			||||||
 | 
										update->scaling_info->scaling_quality.v_taps,
 | 
				
			||||||
 | 
										update->scaling_info->scaling_quality.h_taps_c,
 | 
				
			||||||
 | 
										update->scaling_info->scaling_quality.v_taps_c);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							SURFACE_TRACE("\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						SURFACE_TRACE("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void post_surface_trace(const struct dc *dc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct core_dc *core_dc = DC_TO_CORE(dc);
 | 
				
			||||||
 | 
						struct dal_logger *logger =  core_dc->ctx->logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SURFACE_TRACE("post surface process.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										93
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,93 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					#include "core_dc.h"
 | 
				
			||||||
 | 
					#include "timing_generator.h"
 | 
				
			||||||
 | 
					#include "hw_sequencer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* used as index in array of black_color_format */
 | 
				
			||||||
 | 
					enum black_color_format {
 | 
				
			||||||
 | 
						BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0,
 | 
				
			||||||
 | 
						BLACK_COLOR_FORMAT_RGB_LIMITED,
 | 
				
			||||||
 | 
						BLACK_COLOR_FORMAT_YUV_TV,
 | 
				
			||||||
 | 
						BLACK_COLOR_FORMAT_YUV_CV,
 | 
				
			||||||
 | 
						BLACK_COLOR_FORMAT_YUV_SUPER_AA,
 | 
				
			||||||
 | 
						BLACK_COLOR_FORMAT_DEBUG,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct tg_color black_color_format[] = {
 | 
				
			||||||
 | 
						/* BlackColorFormat_RGB_FullRange */
 | 
				
			||||||
 | 
						{0, 0, 0},
 | 
				
			||||||
 | 
						/* BlackColorFormat_RGB_Limited */
 | 
				
			||||||
 | 
						{0x40, 0x40, 0x40},
 | 
				
			||||||
 | 
						/* BlackColorFormat_YUV_TV */
 | 
				
			||||||
 | 
						{0x200, 0x40, 0x200},
 | 
				
			||||||
 | 
						/* BlackColorFormat_YUV_CV */
 | 
				
			||||||
 | 
						{0x1f4, 0x40, 0x1f4},
 | 
				
			||||||
 | 
						/* BlackColorFormat_YUV_SuperAA */
 | 
				
			||||||
 | 
						{0x1a2, 0x20, 0x1a2},
 | 
				
			||||||
 | 
						/* visual confirm debug */
 | 
				
			||||||
 | 
						{0xff, 0xff, 0},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void color_space_to_black_color(
 | 
				
			||||||
 | 
						const struct core_dc *dc,
 | 
				
			||||||
 | 
						enum dc_color_space colorspace,
 | 
				
			||||||
 | 
						struct tg_color *black_color)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dc->public.debug.surface_visual_confirm) {
 | 
				
			||||||
 | 
							*black_color =
 | 
				
			||||||
 | 
								black_color_format[BLACK_COLOR_FORMAT_DEBUG];
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (colorspace) {
 | 
				
			||||||
 | 
						case COLOR_SPACE_YPBPR601:
 | 
				
			||||||
 | 
							*black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_TV];
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case COLOR_SPACE_YPBPR709:
 | 
				
			||||||
 | 
						case COLOR_SPACE_YCBCR601:
 | 
				
			||||||
 | 
						case COLOR_SPACE_YCBCR709:
 | 
				
			||||||
 | 
						case COLOR_SPACE_YCBCR601_LIMITED:
 | 
				
			||||||
 | 
						case COLOR_SPACE_YCBCR709_LIMITED:
 | 
				
			||||||
 | 
							*black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV];
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case COLOR_SPACE_SRGB_LIMITED:
 | 
				
			||||||
 | 
							*black_color =
 | 
				
			||||||
 | 
								black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED];
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* fefault is sRGB black (full range). */
 | 
				
			||||||
 | 
							*black_color =
 | 
				
			||||||
 | 
								black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE];
 | 
				
			||||||
 | 
							/* default is sRGB black 0. */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1899
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1899
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1098
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1098
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										2462
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2462
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										222
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,222 @@
 | 
				
			||||||
 | 
					/* Copyright 2015 Advanced Micro Devices, Inc. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					#include "inc/core_dc.h"
 | 
				
			||||||
 | 
					#include "include/ddc_service_types.h"
 | 
				
			||||||
 | 
					#include "include/i2caux_interface.h"
 | 
				
			||||||
 | 
					#include "link_hwss.h"
 | 
				
			||||||
 | 
					#include "hw_sequencer.h"
 | 
				
			||||||
 | 
					#include "dc_link_dp.h"
 | 
				
			||||||
 | 
					#include "dc_link_ddc.h"
 | 
				
			||||||
 | 
					#include "dm_helpers.h"
 | 
				
			||||||
 | 
					#include "dce/dce_link_encoder.h"
 | 
				
			||||||
 | 
					#include "dce/dce_stream_encoder.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_status core_link_read_dpcd(
 | 
				
			||||||
 | 
						struct core_link* link,
 | 
				
			||||||
 | 
						uint32_t address,
 | 
				
			||||||
 | 
						uint8_t *data,
 | 
				
			||||||
 | 
						uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!dm_helpers_dp_read_dpcd(link->ctx,
 | 
				
			||||||
 | 
								&link->public,
 | 
				
			||||||
 | 
								address, data, size))
 | 
				
			||||||
 | 
								return DC_ERROR_UNEXPECTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return DC_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_status core_link_write_dpcd(
 | 
				
			||||||
 | 
						struct core_link* link,
 | 
				
			||||||
 | 
						uint32_t address,
 | 
				
			||||||
 | 
						const uint8_t *data,
 | 
				
			||||||
 | 
						uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!dm_helpers_dp_write_dpcd(link->ctx,
 | 
				
			||||||
 | 
								&link->public,
 | 
				
			||||||
 | 
								address, data, size))
 | 
				
			||||||
 | 
									return DC_ERROR_UNEXPECTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return DC_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dp_receiver_power_ctrl(struct core_link *link, bool on)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						core_link_write_dpcd(link, DPCD_ADDRESS_POWER_STATE, &state,
 | 
				
			||||||
 | 
								sizeof(state));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dp_enable_link_phy(
 | 
				
			||||||
 | 
						struct core_link *link,
 | 
				
			||||||
 | 
						enum signal_type signal,
 | 
				
			||||||
 | 
						enum clock_source_id clock_source,
 | 
				
			||||||
 | 
						const struct dc_link_settings *link_settings)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct link_encoder *link_enc = link->link_enc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dc_is_dp_sst_signal(signal)) {
 | 
				
			||||||
 | 
							if (signal == SIGNAL_TYPE_EDP) {
 | 
				
			||||||
 | 
								link_enc->funcs->power_control(link_enc, true);
 | 
				
			||||||
 | 
								link_enc->funcs->backlight_control(link_enc, true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							link_enc->funcs->enable_dp_output(
 | 
				
			||||||
 | 
											link_enc,
 | 
				
			||||||
 | 
											link_settings,
 | 
				
			||||||
 | 
											clock_source);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							link_enc->funcs->enable_dp_mst_output(
 | 
				
			||||||
 | 
											link_enc,
 | 
				
			||||||
 | 
											link_settings,
 | 
				
			||||||
 | 
											clock_source);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dp_receiver_power_ctrl(link, true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dp_disable_link_phy(struct core_link *link, enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!link->wa_flags.dp_keep_receiver_powered)
 | 
				
			||||||
 | 
							dp_receiver_power_ctrl(link, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (signal == SIGNAL_TYPE_EDP)
 | 
				
			||||||
 | 
							link->link_enc->funcs->backlight_control(link->link_enc, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						link->link_enc->funcs->disable_output(link->link_enc, signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Clear current link setting.*/
 | 
				
			||||||
 | 
						memset(&link->public.cur_link_settings, 0,
 | 
				
			||||||
 | 
								sizeof(link->public.cur_link_settings));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dp_disable_link_phy_mst(struct core_link *link, enum signal_type signal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* MST disable link only when no stream use the link */
 | 
				
			||||||
 | 
						if (link->mst_stream_alloc_table.stream_count > 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dp_disable_link_phy(link, signal);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dp_set_hw_training_pattern(
 | 
				
			||||||
 | 
						struct core_link *link,
 | 
				
			||||||
 | 
						enum hw_dp_training_pattern pattern)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (pattern) {
 | 
				
			||||||
 | 
						case HW_DP_TRAINING_PATTERN_1:
 | 
				
			||||||
 | 
							test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HW_DP_TRAINING_PATTERN_2:
 | 
				
			||||||
 | 
							test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HW_DP_TRAINING_PATTERN_3:
 | 
				
			||||||
 | 
							test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case HW_DP_TRAINING_PATTERN_4:
 | 
				
			||||||
 | 
							test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dp_set_hw_test_pattern(link, test_pattern, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dp_set_hw_lane_settings(
 | 
				
			||||||
 | 
						struct core_link *link,
 | 
				
			||||||
 | 
						const struct link_training_settings *link_settings)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct link_encoder *encoder = link->link_enc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* call Encoder to set lane settings */
 | 
				
			||||||
 | 
						encoder->funcs->dp_set_lane_settings(encoder, link_settings);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dp_panel_mode dp_get_panel_mode(struct core_link *link)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* We need to explicitly check that connector
 | 
				
			||||||
 | 
						 * is not DP. Some Travis_VGA get reported
 | 
				
			||||||
 | 
						 * by video bios as DP.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (link->public.connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (link->dpcd_caps.branch_dev_id) {
 | 
				
			||||||
 | 
							case DP_BRANCH_DEVICE_ID_2:
 | 
				
			||||||
 | 
								if (strncmp(
 | 
				
			||||||
 | 
									link->dpcd_caps.branch_dev_name,
 | 
				
			||||||
 | 
									DP_VGA_LVDS_CONVERTER_ID_2,
 | 
				
			||||||
 | 
									sizeof(
 | 
				
			||||||
 | 
									link->dpcd_caps.
 | 
				
			||||||
 | 
									branch_dev_name)) == 0) {
 | 
				
			||||||
 | 
									return DP_PANEL_MODE_SPECIAL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case DP_BRANCH_DEVICE_ID_3:
 | 
				
			||||||
 | 
								if (strncmp(link->dpcd_caps.branch_dev_name,
 | 
				
			||||||
 | 
									DP_VGA_LVDS_CONVERTER_ID_3,
 | 
				
			||||||
 | 
									sizeof(
 | 
				
			||||||
 | 
									link->dpcd_caps.
 | 
				
			||||||
 | 
									branch_dev_name)) == 0) {
 | 
				
			||||||
 | 
									return DP_PANEL_MODE_SPECIAL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (link->dpcd_caps.panel_mode_edp) {
 | 
				
			||||||
 | 
								return DP_PANEL_MODE_EDP;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return DP_PANEL_MODE_DEFAULT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dp_set_hw_test_pattern(
 | 
				
			||||||
 | 
						struct core_link *link,
 | 
				
			||||||
 | 
						enum dp_test_pattern test_pattern,
 | 
				
			||||||
 | 
						uint8_t *custom_pattern,
 | 
				
			||||||
 | 
						uint32_t custom_pattern_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct encoder_set_dp_phy_pattern_param pattern_param = {0};
 | 
				
			||||||
 | 
						struct link_encoder *encoder = link->link_enc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pattern_param.dp_phy_pattern = test_pattern;
 | 
				
			||||||
 | 
						pattern_param.custom_pattern = custom_pattern;
 | 
				
			||||||
 | 
						pattern_param.custom_pattern_size = custom_pattern_size;
 | 
				
			||||||
 | 
						pattern_param.dp_panel_mode = dp_get_panel_mode(link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dp_retrain_link(struct core_link *link)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pipe_ctx *pipes = link->dc->current_context->res_ctx.pipe_ctx;
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < MAX_PIPES; i++) {
 | 
				
			||||||
 | 
							if (pipes[i].stream_enc != NULL) {
 | 
				
			||||||
 | 
								dm_delay_in_microseconds(link->ctx, 100);
 | 
				
			||||||
 | 
								pipes->stream_enc->funcs->dp_blank(pipes[i].stream_enc);
 | 
				
			||||||
 | 
								link->dc->hwss.disable_stream(&pipes[i]);
 | 
				
			||||||
 | 
								dc_link_dp_perform_link_training(
 | 
				
			||||||
 | 
										&link->public,
 | 
				
			||||||
 | 
										&link->public.verified_link_cap,
 | 
				
			||||||
 | 
										true);
 | 
				
			||||||
 | 
								link->dc->hwss.enable_stream(&pipes[i]);
 | 
				
			||||||
 | 
								link->dc->hwss.unblank_stream(&pipes[i],
 | 
				
			||||||
 | 
										&link->public.verified_link_cap);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1934
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_resource.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1934
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_resource.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										113
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_sink.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_sink.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,113 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "dm_helpers.h"
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private definitions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sink {
 | 
				
			||||||
 | 
						struct core_sink protected;
 | 
				
			||||||
 | 
						int ref_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DC_SINK_TO_SINK(dc_sink) \
 | 
				
			||||||
 | 
								container_of(dc_sink, struct sink, protected.public)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destruct(struct sink *sink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool construct(struct sink *sink, const struct dc_sink_init_data *init_params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct core_link *core_link = DC_LINK_TO_LINK(init_params->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sink->protected.public.sink_signal = init_params->sink_signal;
 | 
				
			||||||
 | 
						sink->protected.link = core_link;
 | 
				
			||||||
 | 
						sink->protected.ctx = core_link->ctx;
 | 
				
			||||||
 | 
						sink->protected.dongle_max_pix_clk = init_params->dongle_max_pix_clk;
 | 
				
			||||||
 | 
						sink->protected.converter_disable_audio =
 | 
				
			||||||
 | 
								init_params->converter_disable_audio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Public functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_sink_retain(const struct dc_sink *dc_sink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sink *sink = DC_SINK_TO_SINK(dc_sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						++sink->ref_count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_sink_release(const struct dc_sink *dc_sink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sink *sink = DC_SINK_TO_SINK(dc_sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						--sink->ref_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sink->ref_count == 0) {
 | 
				
			||||||
 | 
							destruct(sink);
 | 
				
			||||||
 | 
							dm_free(sink);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sink *sink = dm_alloc(sizeof(*sink));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == sink)
 | 
				
			||||||
 | 
							goto alloc_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == construct(sink, init_params))
 | 
				
			||||||
 | 
							goto construct_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO should we move this outside to where the assignment actually happens? */
 | 
				
			||||||
 | 
						dc_sink_retain(&sink->protected.public);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &sink->protected.public;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					construct_fail:
 | 
				
			||||||
 | 
						dm_free(sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					alloc_fail:
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Protected functions - visible only inside of DC (not visible in DM)
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
							
								
								
									
										141
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_stream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_stream.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,141 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					#include "resource.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private definitions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct stream {
 | 
				
			||||||
 | 
						struct core_stream protected;
 | 
				
			||||||
 | 
						int ref_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DC_STREAM_TO_STREAM(dc_stream) container_of(dc_stream, struct stream, protected.public)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool construct(struct core_stream *stream,
 | 
				
			||||||
 | 
						const struct dc_sink *dc_sink_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stream->sink = DC_SINK_TO_CORE(dc_sink_data);
 | 
				
			||||||
 | 
						stream->ctx = stream->sink->ctx;
 | 
				
			||||||
 | 
						stream->public.sink = dc_sink_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_sink_retain(dc_sink_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Copy audio modes */
 | 
				
			||||||
 | 
						/* TODO - Remove this translation */
 | 
				
			||||||
 | 
						for (i = 0; i < (dc_sink_data->edid_caps.audio_mode_count); i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							stream->public.audio_info.modes[i].channel_count = dc_sink_data->edid_caps.audio_modes[i].channel_count;
 | 
				
			||||||
 | 
							stream->public.audio_info.modes[i].format_code = dc_sink_data->edid_caps.audio_modes[i].format_code;
 | 
				
			||||||
 | 
							stream->public.audio_info.modes[i].sample_rates.all = dc_sink_data->edid_caps.audio_modes[i].sample_rate;
 | 
				
			||||||
 | 
							stream->public.audio_info.modes[i].sample_size = dc_sink_data->edid_caps.audio_modes[i].sample_size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stream->public.audio_info.mode_count = dc_sink_data->edid_caps.audio_mode_count;
 | 
				
			||||||
 | 
						stream->public.audio_info.audio_latency = dc_sink_data->edid_caps.audio_latency;
 | 
				
			||||||
 | 
						stream->public.audio_info.video_latency = dc_sink_data->edid_caps.video_latency;
 | 
				
			||||||
 | 
						memmove(
 | 
				
			||||||
 | 
							stream->public.audio_info.display_name,
 | 
				
			||||||
 | 
							dc_sink_data->edid_caps.display_name,
 | 
				
			||||||
 | 
							AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS);
 | 
				
			||||||
 | 
						stream->public.audio_info.manufacture_id = dc_sink_data->edid_caps.manufacturer_id;
 | 
				
			||||||
 | 
						stream->public.audio_info.product_id = dc_sink_data->edid_caps.product_id;
 | 
				
			||||||
 | 
						stream->public.audio_info.flags.all = dc_sink_data->edid_caps.speaker_flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO - Unhardcode port_id */
 | 
				
			||||||
 | 
						stream->public.audio_info.port_id[0] = 0x5558859e;
 | 
				
			||||||
 | 
						stream->public.audio_info.port_id[1] = 0xd989449;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* EDID CAP translation for HDMI 2.0 */
 | 
				
			||||||
 | 
						stream->public.timing.flags.LTE_340MCSC_SCRAMBLE = dc_sink_data->edid_caps.lte_340mcsc_scramble;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stream->status.link = &stream->sink->link->public;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destruct(struct core_stream *stream)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dc_sink_release(&stream->sink->public);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_stream_retain(const struct dc_stream *dc_stream)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct stream *stream = DC_STREAM_TO_STREAM(dc_stream);
 | 
				
			||||||
 | 
						stream->ref_count++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_stream_release(const struct dc_stream *public)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct stream *stream = DC_STREAM_TO_STREAM(public);
 | 
				
			||||||
 | 
						struct core_stream *protected = DC_STREAM_TO_CORE(public);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (public != NULL) {
 | 
				
			||||||
 | 
							stream->ref_count--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (stream->ref_count == 0) {
 | 
				
			||||||
 | 
								destruct(protected);
 | 
				
			||||||
 | 
								dm_free(stream);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_stream *dc_create_stream_for_sink(
 | 
				
			||||||
 | 
							const struct dc_sink *dc_sink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct core_sink *sink = DC_SINK_TO_CORE(dc_sink);
 | 
				
			||||||
 | 
						struct stream *stream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sink == NULL)
 | 
				
			||||||
 | 
							goto alloc_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stream = dm_alloc(sizeof(struct stream));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == stream)
 | 
				
			||||||
 | 
							goto alloc_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == construct(&stream->protected, dc_sink))
 | 
				
			||||||
 | 
								goto construct_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_stream_retain(&stream->protected.public);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &stream->protected.public;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					construct_fail:
 | 
				
			||||||
 | 
						dm_free(stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					alloc_fail:
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										213
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_surface.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_surface.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,213 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DC interface (public) */
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DC core (private) */
 | 
				
			||||||
 | 
					#include "core_dc.h"
 | 
				
			||||||
 | 
					#include "transform.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private structures
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					struct surface {
 | 
				
			||||||
 | 
						struct core_surface protected;
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source;
 | 
				
			||||||
 | 
						int ref_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gamma {
 | 
				
			||||||
 | 
						struct core_gamma protected;
 | 
				
			||||||
 | 
						int ref_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DC_SURFACE_TO_SURFACE(dc_surface) container_of(dc_surface, struct surface, protected.public)
 | 
				
			||||||
 | 
					#define CORE_SURFACE_TO_SURFACE(core_surface) container_of(core_surface, struct surface, protected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DC_GAMMA_TO_GAMMA(dc_gamma) \
 | 
				
			||||||
 | 
						container_of(dc_gamma, struct gamma, protected.public)
 | 
				
			||||||
 | 
					#define CORE_GAMMA_TO_GAMMA(core_gamma) \
 | 
				
			||||||
 | 
						container_of(core_gamma, struct gamma, protected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					static bool construct(struct dc_context *ctx, struct surface *surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						surface->protected.ctx = ctx;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destruct(struct surface *surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Public functions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					void enable_surface_flip_reporting(struct dc_surface *dc_surface,
 | 
				
			||||||
 | 
							uint32_t controller_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
 | 
				
			||||||
 | 
						surface->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
 | 
				
			||||||
 | 
						/*register_flip_interrupt(surface);*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_surface *dc_create_surface(const struct dc *dc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct core_dc *core_dc = DC_TO_CORE(dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct surface *surface = dm_alloc(sizeof(*surface));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == surface)
 | 
				
			||||||
 | 
							goto alloc_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == construct(core_dc->ctx, surface))
 | 
				
			||||||
 | 
							goto construct_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_surface_retain(&surface->protected.public);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &surface->protected.public;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					construct_fail:
 | 
				
			||||||
 | 
						dm_free(surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					alloc_fail:
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct dc_surface_status *dc_surface_get_status(
 | 
				
			||||||
 | 
							const struct dc_surface *dc_surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dc_surface_status *surface_status;
 | 
				
			||||||
 | 
						struct core_surface *core_surface;
 | 
				
			||||||
 | 
						struct core_dc *core_dc;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dc_surface == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						core_surface = DC_SURFACE_TO_CORE(dc_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (core_surface == NULL || core_surface->ctx == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						surface_status = &core_surface->status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (core_surface->ctx == NULL || core_surface->ctx->dc == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						core_dc = DC_TO_CORE(core_surface->ctx->dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (core_dc->current_context == NULL)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < core_dc->current_context->res_ctx.pool->pipe_count;
 | 
				
			||||||
 | 
								i++) {
 | 
				
			||||||
 | 
							struct pipe_ctx *pipe_ctx =
 | 
				
			||||||
 | 
									&core_dc->current_context->res_ctx.pipe_ctx[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (pipe_ctx->surface !=
 | 
				
			||||||
 | 
									DC_SURFACE_TO_CORE(dc_surface))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							core_dc->hwss.update_pending_status(pipe_ctx);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return surface_status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_surface_retain(const struct dc_surface *dc_surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						++surface->ref_count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_surface_release(const struct dc_surface *dc_surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						--surface->ref_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (surface->ref_count == 0) {
 | 
				
			||||||
 | 
							destruct(surface);
 | 
				
			||||||
 | 
							dm_free(surface);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool construct_gamma(struct gamma *gamma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destruct_gamma(struct gamma *gamma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_gamma_retain(const struct dc_gamma *dc_gamma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						++gamma->ref_count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_gamma_release(const struct dc_gamma *dc_gamma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma);
 | 
				
			||||||
 | 
						--gamma->ref_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gamma->ref_count == 0) {
 | 
				
			||||||
 | 
							destruct_gamma(gamma);
 | 
				
			||||||
 | 
							dm_free(gamma);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_gamma *dc_create_gamma()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gamma *gamma = dm_alloc(sizeof(*gamma));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gamma == NULL)
 | 
				
			||||||
 | 
							goto alloc_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (false == construct_gamma(gamma))
 | 
				
			||||||
 | 
							goto construct_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_gamma_retain(&gamma->protected.public);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &gamma->protected.public;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					construct_fail:
 | 
				
			||||||
 | 
						dm_free(gamma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					alloc_fail:
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										334
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_target.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								drivers/gpu/drm/amd/display/dc/core/dc_target.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,334 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					#include "hw_sequencer.h"
 | 
				
			||||||
 | 
					#include "resource.h"
 | 
				
			||||||
 | 
					#include "ipp.h"
 | 
				
			||||||
 | 
					#include "timing_generator.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct target {
 | 
				
			||||||
 | 
						struct core_target protected;
 | 
				
			||||||
 | 
						int ref_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DC_TARGET_TO_TARGET(dc_target) \
 | 
				
			||||||
 | 
						container_of(dc_target, struct target, protected.public)
 | 
				
			||||||
 | 
					#define CORE_TARGET_TO_TARGET(core_target) \
 | 
				
			||||||
 | 
						container_of(core_target, struct target, protected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void construct(
 | 
				
			||||||
 | 
						struct core_target *target,
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dc_stream *dc_streams[],
 | 
				
			||||||
 | 
						uint8_t stream_count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t i;
 | 
				
			||||||
 | 
						for (i = 0; i < stream_count; i++) {
 | 
				
			||||||
 | 
							target->public.streams[i] = dc_streams[i];
 | 
				
			||||||
 | 
							dc_stream_retain(dc_streams[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						target->ctx = ctx;
 | 
				
			||||||
 | 
						target->public.stream_count = stream_count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destruct(struct core_target *core_target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < core_target->public.stream_count; i++) {
 | 
				
			||||||
 | 
							dc_stream_release(
 | 
				
			||||||
 | 
								(struct dc_stream *)core_target->public.streams[i]);
 | 
				
			||||||
 | 
							core_target->public.streams[i] = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_target_retain(const struct dc_target *dc_target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct target *target = DC_TARGET_TO_TARGET(dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						target->ref_count++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_target_release(const struct dc_target *dc_target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct target *target = DC_TARGET_TO_TARGET(dc_target);
 | 
				
			||||||
 | 
						struct core_target *protected = DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ASSERT(target->ref_count > 0);
 | 
				
			||||||
 | 
						target->ref_count--;
 | 
				
			||||||
 | 
						if (target->ref_count == 0) {
 | 
				
			||||||
 | 
							destruct(protected);
 | 
				
			||||||
 | 
							dm_free(target);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct dc_target_status *dc_target_get_status(
 | 
				
			||||||
 | 
										const struct dc_target* dc_target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t i;
 | 
				
			||||||
 | 
						struct core_target* target = DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
						struct core_dc *dc = DC_TO_CORE(target->ctx->dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < dc->current_context->target_count; i++)
 | 
				
			||||||
 | 
							if (target == dc->current_context->targets[i])
 | 
				
			||||||
 | 
								return &dc->current_context->target_status[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_target *dc_create_target_for_streams(
 | 
				
			||||||
 | 
							struct dc_stream *dc_streams[],
 | 
				
			||||||
 | 
							uint8_t stream_count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct core_stream *stream;
 | 
				
			||||||
 | 
						struct target *target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (0 == stream_count)
 | 
				
			||||||
 | 
							goto target_alloc_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stream = DC_STREAM_TO_CORE(dc_streams[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						target = dm_alloc(sizeof(struct target));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == target)
 | 
				
			||||||
 | 
							goto target_alloc_fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						construct(&target->protected, stream->ctx, dc_streams, stream_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc_target_retain(&target->protected.public);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &target->protected.public;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_alloc_fail:
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_target_is_connected_to_sink(
 | 
				
			||||||
 | 
							const struct dc_target * dc_target,
 | 
				
			||||||
 | 
							const struct dc_sink *dc_sink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct core_target *target = DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
						uint8_t i;
 | 
				
			||||||
 | 
						for (i = 0; i < target->public.stream_count; i++) {
 | 
				
			||||||
 | 
							if (target->public.streams[i]->sink == dc_sink)
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Update the cursor attributes and set cursor surface address
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dc_target_set_cursor_attributes(
 | 
				
			||||||
 | 
						struct dc_target *dc_target,
 | 
				
			||||||
 | 
						const struct dc_cursor_attributes *attributes)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t i, j;
 | 
				
			||||||
 | 
						struct core_target *target;
 | 
				
			||||||
 | 
						struct core_dc *core_dc;
 | 
				
			||||||
 | 
						struct resource_context *res_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == dc_target) {
 | 
				
			||||||
 | 
							dm_error("DC: dc_target is NULL!\n");
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (NULL == attributes) {
 | 
				
			||||||
 | 
							dm_error("DC: attributes is NULL!\n");
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						target = DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
						core_dc = DC_TO_CORE(target->ctx->dc);
 | 
				
			||||||
 | 
						res_ctx = &core_dc->current_context->res_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < target->public.stream_count; i++) {
 | 
				
			||||||
 | 
							for (j = 0; j < MAX_PIPES; j++) {
 | 
				
			||||||
 | 
								struct input_pixel_processor *ipp =
 | 
				
			||||||
 | 
											res_ctx->pipe_ctx[j].ipp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (res_ctx->pipe_ctx[j].stream !=
 | 
				
			||||||
 | 
									DC_STREAM_TO_CORE(target->public.streams[i]))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* As of writing of this code cursor is on the top
 | 
				
			||||||
 | 
								 * plane so we only need to set it on first pipe we
 | 
				
			||||||
 | 
								 * find. May need to make this code dce specific later.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (ipp->funcs->ipp_cursor_set_attributes(
 | 
				
			||||||
 | 
												ipp, attributes))
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_target_set_cursor_position(
 | 
				
			||||||
 | 
						struct dc_target *dc_target,
 | 
				
			||||||
 | 
						const struct dc_cursor_position *position)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t i, j;
 | 
				
			||||||
 | 
						struct core_target *target;
 | 
				
			||||||
 | 
						struct core_dc *core_dc;
 | 
				
			||||||
 | 
						struct resource_context *res_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == dc_target) {
 | 
				
			||||||
 | 
							dm_error("DC: dc_target is NULL!\n");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NULL == position) {
 | 
				
			||||||
 | 
							dm_error("DC: cursor position is NULL!\n");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						target = DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
						core_dc = DC_TO_CORE(target->ctx->dc);
 | 
				
			||||||
 | 
						res_ctx = &core_dc->current_context->res_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < target->public.stream_count; i++) {
 | 
				
			||||||
 | 
							for (j = 0; j < MAX_PIPES; j++) {
 | 
				
			||||||
 | 
								struct input_pixel_processor *ipp =
 | 
				
			||||||
 | 
											res_ctx->pipe_ctx[j].ipp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (res_ctx->pipe_ctx[j].stream !=
 | 
				
			||||||
 | 
									DC_STREAM_TO_CORE(target->public.streams[i]))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* As of writing of this code cursor is on the top
 | 
				
			||||||
 | 
								 * plane so we only need to set it on first pipe we
 | 
				
			||||||
 | 
								 * find. May need to make this code dce specific later.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								ipp->funcs->ipp_cursor_set_position(ipp, position);
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t i, j;
 | 
				
			||||||
 | 
						struct core_target *target = DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
						struct core_dc *core_dc = DC_TO_CORE(target->ctx->dc);
 | 
				
			||||||
 | 
						struct resource_context *res_ctx =
 | 
				
			||||||
 | 
							&core_dc->current_context->res_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < target->public.stream_count; i++) {
 | 
				
			||||||
 | 
							for (j = 0; j < MAX_PIPES; j++) {
 | 
				
			||||||
 | 
								struct timing_generator *tg = res_ctx->pipe_ctx[j].tg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (res_ctx->pipe_ctx[j].stream !=
 | 
				
			||||||
 | 
									DC_STREAM_TO_CORE(target->public.streams[i]))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return tg->funcs->get_frame_count(tg);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dc_target_get_scanoutpos(
 | 
				
			||||||
 | 
							const struct dc_target *dc_target,
 | 
				
			||||||
 | 
							uint32_t *vbl,
 | 
				
			||||||
 | 
							uint32_t *position)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t i, j;
 | 
				
			||||||
 | 
						struct core_target *target = DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
						struct core_dc *core_dc = DC_TO_CORE(target->ctx->dc);
 | 
				
			||||||
 | 
						struct resource_context *res_ctx =
 | 
				
			||||||
 | 
							&core_dc->current_context->res_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < target->public.stream_count; i++) {
 | 
				
			||||||
 | 
							for (j = 0; j < MAX_PIPES; j++) {
 | 
				
			||||||
 | 
								struct timing_generator *tg = res_ctx->pipe_ctx[j].tg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (res_ctx->pipe_ctx[j].stream !=
 | 
				
			||||||
 | 
									DC_STREAM_TO_CORE(target->public.streams[i]))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return tg->funcs->get_scanoutpos(tg, vbl, position);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_target_log(
 | 
				
			||||||
 | 
						const struct dc_target *dc_target,
 | 
				
			||||||
 | 
						struct dal_logger *dm_logger,
 | 
				
			||||||
 | 
						enum dc_log_type log_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const struct core_target *core_target =
 | 
				
			||||||
 | 
								CONST_DC_TARGET_TO_CORE(dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_logger_write(dm_logger,
 | 
				
			||||||
 | 
								log_type,
 | 
				
			||||||
 | 
								"core_target 0x%x: stream_count=%d\n",
 | 
				
			||||||
 | 
								core_target,
 | 
				
			||||||
 | 
								core_target->public.stream_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < core_target->public.stream_count; i++) {
 | 
				
			||||||
 | 
							const struct core_stream *core_stream =
 | 
				
			||||||
 | 
								DC_STREAM_TO_CORE(core_target->public.streams[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dm_logger_write(dm_logger,
 | 
				
			||||||
 | 
								log_type,
 | 
				
			||||||
 | 
								"core_stream 0x%x: src: %d, %d, %d, %d; dst: %d, %d, %d, %d;\n",
 | 
				
			||||||
 | 
								core_stream,
 | 
				
			||||||
 | 
								core_stream->public.src.x,
 | 
				
			||||||
 | 
								core_stream->public.src.y,
 | 
				
			||||||
 | 
								core_stream->public.src.width,
 | 
				
			||||||
 | 
								core_stream->public.src.height,
 | 
				
			||||||
 | 
								core_stream->public.dst.x,
 | 
				
			||||||
 | 
								core_stream->public.dst.y,
 | 
				
			||||||
 | 
								core_stream->public.dst.width,
 | 
				
			||||||
 | 
								core_stream->public.dst.height);
 | 
				
			||||||
 | 
							dm_logger_write(dm_logger,
 | 
				
			||||||
 | 
								log_type,
 | 
				
			||||||
 | 
								"\tpix_clk_khz: %d, h_total: %d, v_total: %d\n",
 | 
				
			||||||
 | 
								core_stream->public.timing.pix_clk_khz,
 | 
				
			||||||
 | 
								core_stream->public.timing.h_total,
 | 
				
			||||||
 | 
								core_stream->public.timing.v_total);
 | 
				
			||||||
 | 
							dm_logger_write(dm_logger,
 | 
				
			||||||
 | 
								log_type,
 | 
				
			||||||
 | 
								"\tsink name: %s, serial: %d\n",
 | 
				
			||||||
 | 
								core_stream->sink->public.edid_caps.display_name,
 | 
				
			||||||
 | 
								core_stream->sink->public.edid_caps.serial_number);
 | 
				
			||||||
 | 
							dm_logger_write(dm_logger,
 | 
				
			||||||
 | 
								log_type,
 | 
				
			||||||
 | 
								"\tlink: %d\n",
 | 
				
			||||||
 | 
								core_stream->sink->link->public.link_index);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										780
									
								
								drivers/gpu/drm/amd/display/dc/dc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										780
									
								
								drivers/gpu/drm/amd/display/dc/dc.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,780 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-14 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef DC_INTERFACE_H_
 | 
				
			||||||
 | 
					#define DC_INTERFACE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dc_types.h"
 | 
				
			||||||
 | 
					#include "dpcd_defs.h"
 | 
				
			||||||
 | 
					#include "grph_object_defs.h"
 | 
				
			||||||
 | 
					#include "logger_types.h"
 | 
				
			||||||
 | 
					#include "gpio_types.h"
 | 
				
			||||||
 | 
					#include "link_service_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_TARGETS 6
 | 
				
			||||||
 | 
					#define MAX_SURFACES 6
 | 
				
			||||||
 | 
					#define MAX_SINKS_PER_LINK 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Display Core Interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_caps {
 | 
				
			||||||
 | 
						uint32_t max_targets;
 | 
				
			||||||
 | 
						uint32_t max_links;
 | 
				
			||||||
 | 
						uint32_t max_audios;
 | 
				
			||||||
 | 
						uint32_t max_slave_planes;
 | 
				
			||||||
 | 
						uint32_t max_downscale_ratio;
 | 
				
			||||||
 | 
						uint32_t i2c_speed_in_khz;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_dcc_surface_param {
 | 
				
			||||||
 | 
						enum surface_pixel_format format;
 | 
				
			||||||
 | 
						struct dc_size surface_size;
 | 
				
			||||||
 | 
						enum dc_scan_direction scan;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_dcc_setting {
 | 
				
			||||||
 | 
						unsigned int max_compressed_blk_size;
 | 
				
			||||||
 | 
						unsigned int max_uncompressed_blk_size;
 | 
				
			||||||
 | 
						bool independent_64b_blks;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_surface_dcc_cap {
 | 
				
			||||||
 | 
						bool capable;
 | 
				
			||||||
 | 
						bool const_color_support;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								struct dc_dcc_setting rgb;
 | 
				
			||||||
 | 
							} grph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								struct dc_dcc_setting luma;
 | 
				
			||||||
 | 
								struct dc_dcc_setting chroma;
 | 
				
			||||||
 | 
							} video;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Forward declaration*/
 | 
				
			||||||
 | 
					struct dc;
 | 
				
			||||||
 | 
					struct dc_surface;
 | 
				
			||||||
 | 
					struct validate_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_cap_funcs {
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_stream_funcs {
 | 
				
			||||||
 | 
						bool (*adjust_vmin_vmax)(struct dc *dc,
 | 
				
			||||||
 | 
								const struct dc_stream **stream,
 | 
				
			||||||
 | 
								int num_streams,
 | 
				
			||||||
 | 
								int vmin,
 | 
				
			||||||
 | 
								int vmax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void (*stream_update_scaling)(const struct dc *dc,
 | 
				
			||||||
 | 
								const struct dc_stream *dc_stream,
 | 
				
			||||||
 | 
								const struct rect *src,
 | 
				
			||||||
 | 
								const struct rect *dst);
 | 
				
			||||||
 | 
						bool (*set_gamut_remap)(struct dc *dc,
 | 
				
			||||||
 | 
								const struct dc_stream **stream, int num_streams);
 | 
				
			||||||
 | 
						bool (*set_backlight)(struct dc *dc, unsigned int backlight_level,
 | 
				
			||||||
 | 
							unsigned int frame_ramp, const struct dc_stream *stream);
 | 
				
			||||||
 | 
						bool (*init_dmcu_backlight_settings)(struct dc *dc);
 | 
				
			||||||
 | 
						bool (*set_abm_level)(struct dc *dc, unsigned int abm_level);
 | 
				
			||||||
 | 
						bool (*set_psr_enable)(struct dc *dc, bool enable);
 | 
				
			||||||
 | 
						bool (*setup_psr)(struct dc *dc, const struct dc_stream *stream);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct link_training_settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_link_funcs {
 | 
				
			||||||
 | 
						void (*set_drive_settings)(struct dc *dc,
 | 
				
			||||||
 | 
								struct link_training_settings *lt_settings);
 | 
				
			||||||
 | 
						void (*perform_link_training)(struct dc *dc,
 | 
				
			||||||
 | 
								struct dc_link_settings *link_setting,
 | 
				
			||||||
 | 
								bool skip_video_pattern);
 | 
				
			||||||
 | 
						void (*set_preferred_link_settings)(struct dc *dc,
 | 
				
			||||||
 | 
								struct dc_link_settings *link_setting);
 | 
				
			||||||
 | 
						void (*enable_hpd)(const struct dc_link *link);
 | 
				
			||||||
 | 
						void (*disable_hpd)(const struct dc_link *link);
 | 
				
			||||||
 | 
						void (*set_test_pattern)(
 | 
				
			||||||
 | 
								const struct dc_link *link,
 | 
				
			||||||
 | 
								enum dp_test_pattern test_pattern,
 | 
				
			||||||
 | 
								const struct link_training_settings *p_link_settings,
 | 
				
			||||||
 | 
								const unsigned char *p_custom_pattern,
 | 
				
			||||||
 | 
								unsigned int cust_pattern_size);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Structure to hold configuration flags set by dm at dc creation. */
 | 
				
			||||||
 | 
					struct dc_config {
 | 
				
			||||||
 | 
						bool gpu_vm_support;
 | 
				
			||||||
 | 
						bool disable_disp_pll_sharing;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_debug {
 | 
				
			||||||
 | 
						bool surface_visual_confirm;
 | 
				
			||||||
 | 
						bool max_disp_clk;
 | 
				
			||||||
 | 
						bool target_trace;
 | 
				
			||||||
 | 
						bool surface_trace;
 | 
				
			||||||
 | 
						bool validation_trace;
 | 
				
			||||||
 | 
						bool disable_stutter;
 | 
				
			||||||
 | 
						bool disable_dcc;
 | 
				
			||||||
 | 
						bool disable_dfs_bypass;
 | 
				
			||||||
 | 
						bool disable_power_gate;
 | 
				
			||||||
 | 
						bool disable_clock_gate;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc {
 | 
				
			||||||
 | 
						struct dc_caps caps;
 | 
				
			||||||
 | 
						struct dc_cap_funcs cap_funcs;
 | 
				
			||||||
 | 
						struct dc_stream_funcs stream_funcs;
 | 
				
			||||||
 | 
						struct dc_link_funcs link_funcs;
 | 
				
			||||||
 | 
						struct dc_config config;
 | 
				
			||||||
 | 
						struct dc_debug debug;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum frame_buffer_mode {
 | 
				
			||||||
 | 
						FRAME_BUFFER_MODE_LOCAL_ONLY = 0,
 | 
				
			||||||
 | 
						FRAME_BUFFER_MODE_ZFB_ONLY,
 | 
				
			||||||
 | 
						FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL,
 | 
				
			||||||
 | 
					} ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dchub_init_data {
 | 
				
			||||||
 | 
						bool dchub_initialzied;
 | 
				
			||||||
 | 
						bool dchub_info_valid;
 | 
				
			||||||
 | 
						int64_t zfb_phys_addr_base;
 | 
				
			||||||
 | 
						int64_t zfb_mc_base_addr;
 | 
				
			||||||
 | 
						uint64_t zfb_size_in_byte;
 | 
				
			||||||
 | 
						enum frame_buffer_mode fb_mode;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_init_data {
 | 
				
			||||||
 | 
						struct hw_asic_id asic_id;
 | 
				
			||||||
 | 
						void *driver; /* ctx */
 | 
				
			||||||
 | 
						struct cgs_device *cgs_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int num_virtual_links;
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If 'vbios_override' not NULL, it will be called instead
 | 
				
			||||||
 | 
						 * of the real VBIOS. Intended use is Diagnostics on FPGA.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct dc_bios *vbios_override;
 | 
				
			||||||
 | 
						enum dce_environment dce_environment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct dc_config flags;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc *dc_create(const struct dc_init_data *init_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_destroy(struct dc **dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_init_dchub(struct dc *dc, struct dchub_init_data *dh_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Surface Interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						RGB_256X3X16 = 256,
 | 
				
			||||||
 | 
						FLOAT_GAMMA_RAMP_MAX = 1025
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_gamma_ramp_type {
 | 
				
			||||||
 | 
						GAMMA_RAMP_RBG256X3X16,
 | 
				
			||||||
 | 
						GAMMA_RAMP_FLOAT,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct float_rgb {
 | 
				
			||||||
 | 
						struct fixed32_32 red;
 | 
				
			||||||
 | 
						struct fixed32_32 green;
 | 
				
			||||||
 | 
						struct fixed32_32 blue;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_gamma_ramp_float {
 | 
				
			||||||
 | 
						struct float_rgb scale;
 | 
				
			||||||
 | 
						struct float_rgb offset;
 | 
				
			||||||
 | 
						struct float_rgb gamma_curve[FLOAT_GAMMA_RAMP_MAX];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_gamma_ramp_rgb256x3x16 {
 | 
				
			||||||
 | 
						uint16_t red[RGB_256X3X16];
 | 
				
			||||||
 | 
						uint16_t green[RGB_256X3X16];
 | 
				
			||||||
 | 
						uint16_t blue[RGB_256X3X16];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_gamma {
 | 
				
			||||||
 | 
						enum dc_gamma_ramp_type type;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct dc_gamma_ramp_rgb256x3x16 gamma_ramp_rgb256x3x16;
 | 
				
			||||||
 | 
							struct dc_gamma_ramp_float gamma_ramp_float;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						uint32_t size;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_surface {
 | 
				
			||||||
 | 
						bool visible;
 | 
				
			||||||
 | 
						bool flip_immediate;
 | 
				
			||||||
 | 
						struct dc_plane_address address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct scaling_taps scaling_quality;
 | 
				
			||||||
 | 
						struct rect src_rect;
 | 
				
			||||||
 | 
						struct rect dst_rect;
 | 
				
			||||||
 | 
						struct rect clip_rect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union plane_size plane_size;
 | 
				
			||||||
 | 
						union dc_tiling_info tiling_info;
 | 
				
			||||||
 | 
						struct dc_plane_dcc_param dcc;
 | 
				
			||||||
 | 
						enum dc_color_space color_space;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum surface_pixel_format format;
 | 
				
			||||||
 | 
						enum dc_rotation_angle rotation;
 | 
				
			||||||
 | 
						bool horizontal_mirror;
 | 
				
			||||||
 | 
						enum plane_stereo_format stereo_format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const struct dc_gamma *gamma_correction;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_plane_info {
 | 
				
			||||||
 | 
						union plane_size plane_size;
 | 
				
			||||||
 | 
						union dc_tiling_info tiling_info;
 | 
				
			||||||
 | 
						enum surface_pixel_format format;
 | 
				
			||||||
 | 
						enum dc_rotation_angle rotation;
 | 
				
			||||||
 | 
						bool horizontal_mirror;
 | 
				
			||||||
 | 
						enum plane_stereo_format stereo_format;
 | 
				
			||||||
 | 
						enum dc_color_space color_space; /*todo: wrong place, fits in scaling info*/
 | 
				
			||||||
 | 
						bool visible;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_scaling_info {
 | 
				
			||||||
 | 
							struct rect src_rect;
 | 
				
			||||||
 | 
							struct rect dst_rect;
 | 
				
			||||||
 | 
							struct rect clip_rect;
 | 
				
			||||||
 | 
							struct scaling_taps scaling_quality;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_surface_update {
 | 
				
			||||||
 | 
						const struct dc_surface *surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* isr safe update parameters.  null means no updates */
 | 
				
			||||||
 | 
						struct dc_flip_addrs *flip_addr;
 | 
				
			||||||
 | 
						struct dc_plane_info *plane_info;
 | 
				
			||||||
 | 
						struct dc_scaling_info *scaling_info;
 | 
				
			||||||
 | 
						/* following updates require alloc/sleep/spin that is not isr safe,
 | 
				
			||||||
 | 
						 * null means no updates
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct dc_gamma *gamma;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This structure is filled in by dc_surface_get_status and contains
 | 
				
			||||||
 | 
					 * the last requested address and the currently active address so the called
 | 
				
			||||||
 | 
					 * can determine if there are any outstanding flips
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_surface_status {
 | 
				
			||||||
 | 
						struct dc_plane_address requested_address;
 | 
				
			||||||
 | 
						struct dc_plane_address current_address;
 | 
				
			||||||
 | 
						bool is_flip_pending;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Create a new surface with default parameters;
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_surface *dc_create_surface(const struct dc *dc);
 | 
				
			||||||
 | 
					const struct dc_surface_status *dc_surface_get_status(
 | 
				
			||||||
 | 
							const struct dc_surface *dc_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_surface_retain(const struct dc_surface *dc_surface);
 | 
				
			||||||
 | 
					void dc_surface_release(const struct dc_surface *dc_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_gamma_release(const struct dc_gamma *dc_gamma);
 | 
				
			||||||
 | 
					struct dc_gamma *dc_create_gamma(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This structure holds a surface address.  There could be multiple addresses
 | 
				
			||||||
 | 
					 * in cases such as Stereo 3D, Planar YUV, etc.  Other per-flip attributes such
 | 
				
			||||||
 | 
					 * as frame durations and DCC format can also be set.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_flip_addrs {
 | 
				
			||||||
 | 
						struct dc_plane_address address;
 | 
				
			||||||
 | 
						bool flip_immediate;
 | 
				
			||||||
 | 
						/* TODO: DCC format info */
 | 
				
			||||||
 | 
						/* TODO: add flip duration for FreeSync */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Optimized flip address update function.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * After this call:
 | 
				
			||||||
 | 
					 *   Surface addresses and flip attributes are programmed.
 | 
				
			||||||
 | 
					 *   Surface flip occur at next configured time (h_sync or v_sync flip)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void dc_flip_surface_addrs(struct dc *dc,
 | 
				
			||||||
 | 
							const struct dc_surface *const surfaces[],
 | 
				
			||||||
 | 
							struct dc_flip_addrs flip_addrs[],
 | 
				
			||||||
 | 
							uint32_t count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Set up surface attributes and associate to a target
 | 
				
			||||||
 | 
					 * The surfaces parameter is an absolute set of all surface active for the target.
 | 
				
			||||||
 | 
					 * If no surfaces are provided, the target will be blanked; no memory read.
 | 
				
			||||||
 | 
					 * Any flip related attribute changes must be done through this interface.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * After this call:
 | 
				
			||||||
 | 
					 *   Surfaces attributes are programmed and configured to be composed into target.
 | 
				
			||||||
 | 
					 *   This does not trigger a flip.  No surface address is programmed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_commit_surfaces_to_target(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							const struct dc_surface **dc_surfaces,
 | 
				
			||||||
 | 
							uint8_t surface_count,
 | 
				
			||||||
 | 
							struct dc_target *dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_pre_update_surfaces_to_target(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							const struct dc_surface *const *new_surfaces,
 | 
				
			||||||
 | 
							uint8_t new_surface_count,
 | 
				
			||||||
 | 
							struct dc_target *dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_post_update_surfaces_to_target(
 | 
				
			||||||
 | 
							struct dc *dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *updates,
 | 
				
			||||||
 | 
							int surface_count, struct dc_target *dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Target Interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					#define MAX_STREAM_NUM 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_target {
 | 
				
			||||||
 | 
						uint8_t stream_count;
 | 
				
			||||||
 | 
						const struct dc_stream *streams[MAX_STREAM_NUM];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Target status is returned from dc_target_get_status in order to get the
 | 
				
			||||||
 | 
					 * the IRQ source, current frame counter and currently attached surfaces.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_target_status {
 | 
				
			||||||
 | 
						int primary_otg_inst;
 | 
				
			||||||
 | 
						int cur_frame_count;
 | 
				
			||||||
 | 
						int surface_count;
 | 
				
			||||||
 | 
						const struct dc_surface *surfaces[MAX_SURFACE_NUM];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_target *dc_create_target_for_streams(
 | 
				
			||||||
 | 
							struct dc_stream *dc_streams[],
 | 
				
			||||||
 | 
							uint8_t stream_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Get the current target status.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const struct dc_target_status *dc_target_get_status(
 | 
				
			||||||
 | 
										const struct dc_target* dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_target_retain(const struct dc_target *dc_target);
 | 
				
			||||||
 | 
					void dc_target_release(const struct dc_target *dc_target);
 | 
				
			||||||
 | 
					void dc_target_log(
 | 
				
			||||||
 | 
						const struct dc_target *dc_target,
 | 
				
			||||||
 | 
						struct dal_logger *dc_logger,
 | 
				
			||||||
 | 
						enum dc_log_type log_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t dc_get_current_target_count(const struct dc *dc);
 | 
				
			||||||
 | 
					struct dc_target *dc_get_target_at_index(const struct dc *dc, uint8_t i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_target_is_connected_to_sink(
 | 
				
			||||||
 | 
							const struct dc_target *dc_target,
 | 
				
			||||||
 | 
							const struct dc_sink *dc_sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TODO: Return parsed values rather than direct register read
 | 
				
			||||||
 | 
					 * This has a dependency on the caller (amdgpu_get_crtc_scanoutpos)
 | 
				
			||||||
 | 
					 * being refactored properly to be dce-specific
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t dc_target_get_scanoutpos(
 | 
				
			||||||
 | 
							const struct dc_target *dc_target,
 | 
				
			||||||
 | 
							uint32_t *vbl,
 | 
				
			||||||
 | 
							uint32_t *position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Structure to store surface/target associations for validation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_validation_set {
 | 
				
			||||||
 | 
						const struct dc_target *target;
 | 
				
			||||||
 | 
						const struct dc_surface *surfaces[MAX_SURFACES];
 | 
				
			||||||
 | 
						uint8_t surface_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This function takes a set of resources and checks that they are cofunctional.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * After this call:
 | 
				
			||||||
 | 
					 *   No hardware is programmed for call.  Only validation is done.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dc_validate_resources(
 | 
				
			||||||
 | 
							const struct dc *dc,
 | 
				
			||||||
 | 
							const struct dc_validation_set set[],
 | 
				
			||||||
 | 
							uint8_t set_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This function takes a target and checks if it is guaranteed to be supported.
 | 
				
			||||||
 | 
					 * Guaranteed means that MAX_COFUNC*target is supported.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * After this call:
 | 
				
			||||||
 | 
					 *   No hardware is programmed for call.  Only validation is done.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_validate_guaranteed(
 | 
				
			||||||
 | 
							const struct dc *dc,
 | 
				
			||||||
 | 
							const struct dc_target *dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Set up streams and links associated to targets to drive sinks
 | 
				
			||||||
 | 
					 * The targets parameter is an absolute set of all active targets.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * After this call:
 | 
				
			||||||
 | 
					 *   Phy, Encoder, Timing Generator are programmed and enabled.
 | 
				
			||||||
 | 
					 *   New targets are enabled with blank stream; no memory read.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dc_commit_targets(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							struct dc_target *targets[],
 | 
				
			||||||
 | 
							uint8_t target_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Stream Interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					struct dc_stream {
 | 
				
			||||||
 | 
						const struct dc_sink *sink;
 | 
				
			||||||
 | 
						struct dc_crtc_timing timing;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum dc_color_space output_color_space;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct rect src; /* viewport in target space*/
 | 
				
			||||||
 | 
						struct rect dst; /* stream addressable area */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct audio_info audio_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool ignore_msa_timing_param;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct freesync_context freesync_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO: dithering */
 | 
				
			||||||
 | 
						/* TODO: transfer function (CSC/regamma/gamut remap) */
 | 
				
			||||||
 | 
						struct colorspace_transform gamut_remap_matrix;
 | 
				
			||||||
 | 
						struct csc_transform csc_color_matrix;
 | 
				
			||||||
 | 
						/* TODO: custom INFO packets */
 | 
				
			||||||
 | 
						/* TODO: ABM info (DMCU) */
 | 
				
			||||||
 | 
						/* TODO: PSR info */
 | 
				
			||||||
 | 
						/* TODO: CEA VIC */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Create a new default stream for the requested sink
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_stream *dc_create_stream_for_sink(const struct dc_sink *dc_sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_stream_retain(const struct dc_stream *dc_stream);
 | 
				
			||||||
 | 
					void dc_stream_release(const struct dc_stream *dc_stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_stream_status {
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * link this stream passes through
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						const struct dc_link *link;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct dc_stream_status *dc_stream_get_status(
 | 
				
			||||||
 | 
						const struct dc_stream *dc_stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Link Interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * A link contains one or more sinks and their connected status.
 | 
				
			||||||
 | 
					 * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_link {
 | 
				
			||||||
 | 
						const struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK];
 | 
				
			||||||
 | 
						unsigned int sink_count;
 | 
				
			||||||
 | 
						const struct dc_sink *local_sink;
 | 
				
			||||||
 | 
						unsigned int link_index;
 | 
				
			||||||
 | 
						enum dc_connection_type type;
 | 
				
			||||||
 | 
						enum signal_type connector_signal;
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source_hpd;
 | 
				
			||||||
 | 
						enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse  */
 | 
				
			||||||
 | 
						/* caps is the same as reported_link_cap. link_traing use
 | 
				
			||||||
 | 
						 * reported_link_cap. Will clean up.  TODO
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct dc_link_settings reported_link_cap;
 | 
				
			||||||
 | 
						struct dc_link_settings verified_link_cap;
 | 
				
			||||||
 | 
						struct dc_link_settings max_link_setting;
 | 
				
			||||||
 | 
						struct dc_link_settings cur_link_settings;
 | 
				
			||||||
 | 
						struct dc_lane_settings cur_lane_setting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t ddc_hw_inst;
 | 
				
			||||||
 | 
						uint8_t link_enc_hw_inst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct psr_caps psr_caps;
 | 
				
			||||||
 | 
						bool test_pattern_enabled;
 | 
				
			||||||
 | 
						union compliance_test_state compliance_test_state;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dpcd_caps {
 | 
				
			||||||
 | 
						union dpcd_rev dpcd_rev;
 | 
				
			||||||
 | 
						union max_lane_count max_ln_count;
 | 
				
			||||||
 | 
						union max_down_spread max_down_spread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* dongle type (DP converter, CV smart dongle) */
 | 
				
			||||||
 | 
						enum display_dongle_type dongle_type;
 | 
				
			||||||
 | 
						/* Dongle's downstream count. */
 | 
				
			||||||
 | 
						union sink_count sink_count;
 | 
				
			||||||
 | 
						/* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
 | 
				
			||||||
 | 
						indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
 | 
				
			||||||
 | 
						bool is_dp_hdmi_s3d_converter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool allow_invalid_MSA_timing_param;
 | 
				
			||||||
 | 
						bool panel_mode_edp;
 | 
				
			||||||
 | 
						uint32_t sink_dev_id;
 | 
				
			||||||
 | 
						uint32_t branch_dev_id;
 | 
				
			||||||
 | 
						int8_t branch_dev_name[6];
 | 
				
			||||||
 | 
						int8_t branch_hw_revision;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_link_status {
 | 
				
			||||||
 | 
						struct dpcd_caps *dpcd_caps;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Return an enumerated dc_link.  dc_link order is constant and determined at
 | 
				
			||||||
 | 
					 * boot time.  They cannot be created or destroyed.
 | 
				
			||||||
 | 
					 * Use dc_get_caps() to get number of links.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const struct dc_link *dc_get_link_at_index(const struct dc *dc, uint32_t link_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Return id of physical connector represented by a dc_link at link_index.*/
 | 
				
			||||||
 | 
					const struct graphics_object_id dc_get_link_id_at_index(
 | 
				
			||||||
 | 
							struct dc *dc, uint32_t link_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set backlight level of an embedded panel (eDP, LVDS). */
 | 
				
			||||||
 | 
					bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
 | 
				
			||||||
 | 
							uint32_t frame_ramp, const struct dc_stream *stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_link_init_dmcu_backlight_settings(const struct dc_link *dc_link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_link_set_abm_level(const struct dc_link *dc_link, uint32_t level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_link_setup_psr(const struct dc_link *dc_link,
 | 
				
			||||||
 | 
							const struct dc_stream *stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Request DC to detect if there is a Panel connected.
 | 
				
			||||||
 | 
					 * boot - If this call is during initial boot.
 | 
				
			||||||
 | 
					 * Return false for any type of detection failure or MST detection
 | 
				
			||||||
 | 
					 * true otherwise. True meaning further action is required (status update
 | 
				
			||||||
 | 
					 * and OS notification).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dc_link_detect(const struct dc_link *dc_link, bool boot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
 | 
				
			||||||
 | 
					 * Return:
 | 
				
			||||||
 | 
					 * true - Downstream port status changed. DM should call DC to do the
 | 
				
			||||||
 | 
					 * detection.
 | 
				
			||||||
 | 
					 * false - no change in Downstream port status. No further action required
 | 
				
			||||||
 | 
					 * from DM. */
 | 
				
			||||||
 | 
					bool dc_link_handle_hpd_rx_irq(const struct dc_link *dc_link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_sink_init_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_sink *dc_link_add_remote_sink(
 | 
				
			||||||
 | 
							const struct dc_link *dc_link,
 | 
				
			||||||
 | 
							const uint8_t *edid,
 | 
				
			||||||
 | 
							int len,
 | 
				
			||||||
 | 
							struct dc_sink_init_data *init_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_link_remove_remote_sink(
 | 
				
			||||||
 | 
						const struct dc_link *link,
 | 
				
			||||||
 | 
						const struct dc_sink *sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Used by diagnostics for virtual link at the moment */
 | 
				
			||||||
 | 
					void dc_link_set_sink(const struct dc_link *link, struct dc_sink *sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_link_dp_set_drive_settings(
 | 
				
			||||||
 | 
						struct dc_link *link,
 | 
				
			||||||
 | 
						struct link_training_settings *lt_settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_link_dp_perform_link_training(
 | 
				
			||||||
 | 
						struct dc_link *link,
 | 
				
			||||||
 | 
						const struct dc_link_settings *link_setting,
 | 
				
			||||||
 | 
						bool skip_video_pattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_link_dp_enable_hpd(const struct dc_link *link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_link_dp_disable_hpd(const struct dc_link *link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_link_dp_set_test_pattern(
 | 
				
			||||||
 | 
						const struct dc_link *link,
 | 
				
			||||||
 | 
						enum dp_test_pattern test_pattern,
 | 
				
			||||||
 | 
						const struct link_training_settings *p_link_settings,
 | 
				
			||||||
 | 
						const unsigned char *p_custom_pattern,
 | 
				
			||||||
 | 
						unsigned int cust_pattern_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Sink Interfaces - A sink corresponds to a display output device
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The sink structure contains EDID and other display device properties
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_sink {
 | 
				
			||||||
 | 
						enum signal_type sink_signal;
 | 
				
			||||||
 | 
						struct dc_edid dc_edid; /* raw edid */
 | 
				
			||||||
 | 
						struct dc_edid_caps edid_caps; /* parse display caps */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_sink_retain(const struct dc_sink *sink);
 | 
				
			||||||
 | 
					void dc_sink_release(const struct dc_sink *sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct audio **dc_get_audios(struct dc *dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_sink_init_data {
 | 
				
			||||||
 | 
						enum signal_type sink_signal;
 | 
				
			||||||
 | 
						const struct dc_link *link;
 | 
				
			||||||
 | 
						uint32_t dongle_max_pix_clk;
 | 
				
			||||||
 | 
						bool converter_disable_audio;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Cursor interfaces - To manages the cursor within a target
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					/* TODO: Deprecated once we switch to dc_set_cursor_position */
 | 
				
			||||||
 | 
					bool dc_target_set_cursor_attributes(
 | 
				
			||||||
 | 
						struct dc_target *dc_target,
 | 
				
			||||||
 | 
						const struct dc_cursor_attributes *attributes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_target_set_cursor_position(
 | 
				
			||||||
 | 
						struct dc_target *dc_target,
 | 
				
			||||||
 | 
						const struct dc_cursor_position *position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Newer interfaces  */
 | 
				
			||||||
 | 
					struct dc_cursor {
 | 
				
			||||||
 | 
						struct dc_plane_address address;
 | 
				
			||||||
 | 
						struct dc_cursor_attributes attributes;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Create a new cursor with default values for a given target.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct dc_cursor *dc_create_cursor_for_target(
 | 
				
			||||||
 | 
							const struct dc *dc,
 | 
				
			||||||
 | 
							struct dc_target *dc_target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Commit cursor attribute changes such as pixel format and dimensions and
 | 
				
			||||||
 | 
					 * surface address.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * After this call:
 | 
				
			||||||
 | 
					 *   Cursor address and format is programmed to the new values.
 | 
				
			||||||
 | 
					 *   Cursor position is unmodified.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dc_commit_cursor(
 | 
				
			||||||
 | 
							const struct dc *dc,
 | 
				
			||||||
 | 
							struct dc_cursor *cursor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Optimized cursor position update
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * After this call:
 | 
				
			||||||
 | 
					 *   Cursor position will be programmed as well as enable/disable bit.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool dc_set_cursor_position(
 | 
				
			||||||
 | 
							const struct dc *dc,
 | 
				
			||||||
 | 
							struct dc_cursor *cursor,
 | 
				
			||||||
 | 
							struct dc_cursor_position *pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Interrupt interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					enum dc_irq_source dc_interrupt_to_irq_source(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							uint32_t src_id,
 | 
				
			||||||
 | 
							uint32_t ext_id);
 | 
				
			||||||
 | 
					void dc_interrupt_set(const struct dc *dc, enum dc_irq_source src, bool enable);
 | 
				
			||||||
 | 
					void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src);
 | 
				
			||||||
 | 
					enum dc_irq_source dc_get_hpd_irq_source_at_index(
 | 
				
			||||||
 | 
							struct dc *dc, uint32_t link_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Power Interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dc_set_power_state(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							enum dc_acpi_cm_power_state power_state,
 | 
				
			||||||
 | 
							enum dc_video_power_state video_power_state);
 | 
				
			||||||
 | 
					void dc_resume(const struct dc *dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * DDC Interfaces
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct ddc_service *dc_get_ddc_at_index(
 | 
				
			||||||
 | 
							struct dc *dc, uint32_t link_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * DPCD access interfaces
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_read_dpcd(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							uint32_t link_index,
 | 
				
			||||||
 | 
							uint32_t address,
 | 
				
			||||||
 | 
							uint8_t *data,
 | 
				
			||||||
 | 
							uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_write_dpcd(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							uint32_t link_index,
 | 
				
			||||||
 | 
							uint32_t address,
 | 
				
			||||||
 | 
							const uint8_t *data,
 | 
				
			||||||
 | 
						uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dc_submit_i2c(
 | 
				
			||||||
 | 
							struct dc *dc,
 | 
				
			||||||
 | 
							uint32_t link_index,
 | 
				
			||||||
 | 
							struct i2c_command *cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DC_INTERFACE_H_ */
 | 
				
			||||||
							
								
								
									
										224
									
								
								drivers/gpu/drm/amd/display/dc/dc_bios_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								drivers/gpu/drm/amd/display/dc/dc_bios_types.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,224 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef DC_BIOS_TYPES_H
 | 
				
			||||||
 | 
					#define DC_BIOS_TYPES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Interface file for VBIOS implementations.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The default implementation is inside DC.
 | 
				
			||||||
 | 
					 * Display Manager (which instantiates DC) has the option to supply it's own
 | 
				
			||||||
 | 
					 * (external to DC) implementation of VBIOS, which will be called by DC, using
 | 
				
			||||||
 | 
					 * this interface.
 | 
				
			||||||
 | 
					 * (The intended use is Diagnostics, but other uses may appear.)
 | 
				
			||||||
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/bios_parser_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_vbios_funcs {
 | 
				
			||||||
 | 
						uint8_t (*get_connectors_number)(struct dc_bios *bios);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct graphics_object_id (*get_encoder_id)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							uint32_t i);
 | 
				
			||||||
 | 
						struct graphics_object_id (*get_connector_id)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							uint8_t connector_index);
 | 
				
			||||||
 | 
						uint32_t (*get_dst_number)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct graphics_object_id id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t (*get_gpio_record)(
 | 
				
			||||||
 | 
							struct dc_bios *dcb,
 | 
				
			||||||
 | 
							struct graphics_object_id id,
 | 
				
			||||||
 | 
							struct bp_gpio_cntl_info *gpio_record,
 | 
				
			||||||
 | 
							uint32_t record_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum bp_result (*get_src_obj)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct graphics_object_id object_id, uint32_t index,
 | 
				
			||||||
 | 
							struct graphics_object_id *src_object_id);
 | 
				
			||||||
 | 
						enum bp_result (*get_dst_obj)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct graphics_object_id object_id, uint32_t index,
 | 
				
			||||||
 | 
							struct graphics_object_id *dest_object_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum bp_result (*get_i2c_info)(
 | 
				
			||||||
 | 
							struct dc_bios *dcb,
 | 
				
			||||||
 | 
							struct graphics_object_id id,
 | 
				
			||||||
 | 
							struct graphics_object_i2c_info *info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum bp_result (*get_voltage_ddc_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							uint32_t index,
 | 
				
			||||||
 | 
							struct graphics_object_i2c_info *info);
 | 
				
			||||||
 | 
						enum bp_result (*get_thermal_ddc_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							uint32_t i2c_channel_id,
 | 
				
			||||||
 | 
							struct graphics_object_i2c_info *info);
 | 
				
			||||||
 | 
						enum bp_result (*get_hpd_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct graphics_object_id id,
 | 
				
			||||||
 | 
							struct graphics_object_hpd_info *info);
 | 
				
			||||||
 | 
						enum bp_result (*get_device_tag)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct graphics_object_id connector_object_id,
 | 
				
			||||||
 | 
							uint32_t device_tag_index,
 | 
				
			||||||
 | 
							struct connector_device_tag_info *info);
 | 
				
			||||||
 | 
						enum bp_result (*get_firmware_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct firmware_info *info);
 | 
				
			||||||
 | 
						enum bp_result (*get_spread_spectrum_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							enum as_signal_type signal,
 | 
				
			||||||
 | 
							uint32_t index,
 | 
				
			||||||
 | 
							struct spread_spectrum_info *ss_info);
 | 
				
			||||||
 | 
						uint32_t (*get_ss_entry_number)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							enum as_signal_type signal);
 | 
				
			||||||
 | 
						enum bp_result (*get_embedded_panel_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct embedded_panel_info *info);
 | 
				
			||||||
 | 
						enum bp_result (*get_gpio_pin_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							uint32_t gpio_id,
 | 
				
			||||||
 | 
							struct gpio_pin_info *info);
 | 
				
			||||||
 | 
						enum bp_result (*get_encoder_cap_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct graphics_object_id object_id,
 | 
				
			||||||
 | 
							struct bp_encoder_cap_info *info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool (*is_lid_status_changed)(
 | 
				
			||||||
 | 
							struct dc_bios *bios);
 | 
				
			||||||
 | 
						bool (*is_display_config_changed)(
 | 
				
			||||||
 | 
							struct dc_bios *bios);
 | 
				
			||||||
 | 
						bool (*is_accelerated_mode)(
 | 
				
			||||||
 | 
							struct dc_bios *bios);
 | 
				
			||||||
 | 
						void (*get_bios_event_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bios_event_info *info);
 | 
				
			||||||
 | 
						void (*update_requested_backlight_level)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							uint32_t backlight_8bit);
 | 
				
			||||||
 | 
						uint32_t (*get_requested_backlight_level)(
 | 
				
			||||||
 | 
							struct dc_bios *bios);
 | 
				
			||||||
 | 
						void (*take_backlight_control)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							bool cntl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool (*is_active_display)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							enum signal_type signal,
 | 
				
			||||||
 | 
							const struct connector_device_tag_info *device_tag);
 | 
				
			||||||
 | 
						enum controller_id (*get_embedded_display_controller_id)(
 | 
				
			||||||
 | 
							struct dc_bios *bios);
 | 
				
			||||||
 | 
						uint32_t (*get_embedded_display_refresh_rate)(
 | 
				
			||||||
 | 
							struct dc_bios *bios);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void (*set_scratch_critical_state)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							bool state);
 | 
				
			||||||
 | 
						bool (*is_device_id_supported)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct device_id id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* COMMANDS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum bp_result (*encoder_control)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_encoder_control *cntl);
 | 
				
			||||||
 | 
						enum bp_result (*transmitter_control)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_transmitter_control *cntl);
 | 
				
			||||||
 | 
						enum bp_result (*crt_control)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							enum engine_id engine_id,
 | 
				
			||||||
 | 
							bool enable,
 | 
				
			||||||
 | 
							uint32_t pixel_clock);
 | 
				
			||||||
 | 
						enum bp_result (*enable_crtc)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							enum controller_id id,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
						enum bp_result (*adjust_pixel_clock)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_adjust_pixel_clock_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*set_pixel_clock)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_pixel_clock_parameters *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*set_dce_clock)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_set_dce_clock_parameters *bp_params);
 | 
				
			||||||
 | 
						unsigned int (*get_smu_clock_info)(
 | 
				
			||||||
 | 
							struct dc_bios *bios);
 | 
				
			||||||
 | 
						enum bp_result (*enable_spread_spectrum_on_ppll)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_spread_spectrum_parameters *bp_params,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
						enum bp_result (*program_crtc_timing)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_hw_crtc_timing_parameters *bp_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum bp_result (*crtc_source_select)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_crtc_source_select *bp_params);
 | 
				
			||||||
 | 
						enum bp_result (*program_display_engine_pll)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct bp_pixel_clock_parameters *bp_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum signal_type (*dac_load_detect)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							struct graphics_object_id encoder,
 | 
				
			||||||
 | 
							struct graphics_object_id connector,
 | 
				
			||||||
 | 
							enum signal_type display_signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum bp_result (*enable_disp_power_gating)(
 | 
				
			||||||
 | 
							struct dc_bios *bios,
 | 
				
			||||||
 | 
							enum controller_id controller_id,
 | 
				
			||||||
 | 
							enum bp_pipe_control_action action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void (*post_init)(struct dc_bios *bios);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void (*bios_parser_destroy)(struct dc_bios **dcb);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bios_registers {
 | 
				
			||||||
 | 
						uint32_t BIOS_SCRATCH_6;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_bios {
 | 
				
			||||||
 | 
						const struct dc_vbios_funcs *funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t *bios;
 | 
				
			||||||
 | 
						uint32_t bios_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t *bios_local_image;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct dc_context *ctx;
 | 
				
			||||||
 | 
						const struct bios_registers *regs;
 | 
				
			||||||
 | 
						struct integrated_info *integrated_info;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DC_BIOS_TYPES_H */
 | 
				
			||||||
							
								
								
									
										115
									
								
								drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,115 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef DC_DDC_TYPES_H_
 | 
				
			||||||
 | 
					#define DC_DDC_TYPES_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct i2c_payload {
 | 
				
			||||||
 | 
						bool write;
 | 
				
			||||||
 | 
						uint8_t address;
 | 
				
			||||||
 | 
						uint32_t length;
 | 
				
			||||||
 | 
						uint8_t *data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum i2c_command_engine {
 | 
				
			||||||
 | 
						I2C_COMMAND_ENGINE_DEFAULT,
 | 
				
			||||||
 | 
						I2C_COMMAND_ENGINE_SW,
 | 
				
			||||||
 | 
						I2C_COMMAND_ENGINE_HW
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct i2c_command {
 | 
				
			||||||
 | 
						struct i2c_payload *payloads;
 | 
				
			||||||
 | 
						uint8_t number_of_payloads;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum i2c_command_engine engine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* expressed in KHz
 | 
				
			||||||
 | 
						 * zero means "use default value" */
 | 
				
			||||||
 | 
						uint32_t speed;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gpio_ddc_hw_info {
 | 
				
			||||||
 | 
						bool hw_supported;
 | 
				
			||||||
 | 
						uint32_t ddc_channel;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ddc {
 | 
				
			||||||
 | 
						struct gpio *pin_data;
 | 
				
			||||||
 | 
						struct gpio *pin_clock;
 | 
				
			||||||
 | 
						struct gpio_ddc_hw_info hw_info;
 | 
				
			||||||
 | 
						struct dc_context *ctx;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union ddc_wa {
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							uint32_t DP_SKIP_POWER_OFF:1;
 | 
				
			||||||
 | 
							uint32_t DP_AUX_POWER_UP_WA_DELAY:1;
 | 
				
			||||||
 | 
						} bits;
 | 
				
			||||||
 | 
						uint32_t raw;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ddc_flags {
 | 
				
			||||||
 | 
						uint8_t EDID_QUERY_DONE_ONCE:1;
 | 
				
			||||||
 | 
						uint8_t IS_INTERNAL_DISPLAY:1;
 | 
				
			||||||
 | 
						uint8_t FORCE_READ_REPEATED_START:1;
 | 
				
			||||||
 | 
						uint8_t EDID_STRESS_READ:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ddc_transaction_type {
 | 
				
			||||||
 | 
						DDC_TRANSACTION_TYPE_NONE = 0,
 | 
				
			||||||
 | 
						DDC_TRANSACTION_TYPE_I2C,
 | 
				
			||||||
 | 
						DDC_TRANSACTION_TYPE_I2C_OVER_AUX,
 | 
				
			||||||
 | 
						DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER,
 | 
				
			||||||
 | 
						DDC_TRANSACTION_TYPE_I2C_OVER_AUX_RETRY_DEFER
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum display_dongle_type {
 | 
				
			||||||
 | 
						DISPLAY_DONGLE_NONE = 0,
 | 
				
			||||||
 | 
						/* Active converter types*/
 | 
				
			||||||
 | 
						DISPLAY_DONGLE_DP_VGA_CONVERTER,
 | 
				
			||||||
 | 
						DISPLAY_DONGLE_DP_DVI_CONVERTER,
 | 
				
			||||||
 | 
						DISPLAY_DONGLE_DP_HDMI_CONVERTER,
 | 
				
			||||||
 | 
						/* DP-HDMI/DVI passive dongles (Type 1 and Type 2)*/
 | 
				
			||||||
 | 
						DISPLAY_DONGLE_DP_DVI_DONGLE,
 | 
				
			||||||
 | 
						DISPLAY_DONGLE_DP_HDMI_DONGLE,
 | 
				
			||||||
 | 
						/* Other types of dongle*/
 | 
				
			||||||
 | 
						DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ddc_service {
 | 
				
			||||||
 | 
						struct ddc *ddc_pin;
 | 
				
			||||||
 | 
						struct ddc_flags flags;
 | 
				
			||||||
 | 
						union ddc_wa wa;
 | 
				
			||||||
 | 
						enum ddc_transaction_type transaction_type;
 | 
				
			||||||
 | 
						enum display_dongle_type dongle_type;
 | 
				
			||||||
 | 
						struct dc_context *ctx;
 | 
				
			||||||
 | 
						struct core_link *link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t address;
 | 
				
			||||||
 | 
						uint32_t edid_buf_len;
 | 
				
			||||||
 | 
						uint8_t edid_buf[MAX_EDID_BUFFER_SIZE];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DC_DDC_TYPES_H_ */
 | 
				
			||||||
							
								
								
									
										105
									
								
								drivers/gpu/drm/amd/display/dc/dc_dp_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								drivers/gpu/drm/amd/display/dc/dc_dp_types.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,105 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef DC_DP_TYPES_H
 | 
				
			||||||
 | 
					#define DC_DP_TYPES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_lane_count {
 | 
				
			||||||
 | 
						LANE_COUNT_UNKNOWN = 0,
 | 
				
			||||||
 | 
						LANE_COUNT_ONE = 1,
 | 
				
			||||||
 | 
						LANE_COUNT_TWO = 2,
 | 
				
			||||||
 | 
						LANE_COUNT_FOUR = 4,
 | 
				
			||||||
 | 
						LANE_COUNT_EIGHT = 8,
 | 
				
			||||||
 | 
						LANE_COUNT_DP_MAX = LANE_COUNT_FOUR
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This is actually a reference clock (27MHz) multiplier
 | 
				
			||||||
 | 
					 * 162MBps bandwidth for 1.62GHz like rate,
 | 
				
			||||||
 | 
					 * 270MBps for 2.70GHz,
 | 
				
			||||||
 | 
					 * 324MBps for 3.24Ghz,
 | 
				
			||||||
 | 
					 * 540MBps for 5.40GHz
 | 
				
			||||||
 | 
					 * 810MBps for 8.10GHz
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum dc_link_rate {
 | 
				
			||||||
 | 
						LINK_RATE_UNKNOWN = 0,
 | 
				
			||||||
 | 
						LINK_RATE_LOW = 0x06,
 | 
				
			||||||
 | 
						LINK_RATE_HIGH = 0x0A,
 | 
				
			||||||
 | 
						LINK_RATE_RBR2 = 0x0C,
 | 
				
			||||||
 | 
						LINK_RATE_HIGH2 = 0x14,
 | 
				
			||||||
 | 
						LINK_RATE_HIGH3 = 0x1E
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_link_spread {
 | 
				
			||||||
 | 
						LINK_SPREAD_DISABLED = 0x00,
 | 
				
			||||||
 | 
						/* 0.5 % downspread 30 kHz */
 | 
				
			||||||
 | 
						LINK_SPREAD_05_DOWNSPREAD_30KHZ = 0x10,
 | 
				
			||||||
 | 
						/* 0.5 % downspread 33 kHz */
 | 
				
			||||||
 | 
						LINK_SPREAD_05_DOWNSPREAD_33KHZ = 0x11
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_voltage_swing {
 | 
				
			||||||
 | 
						VOLTAGE_SWING_LEVEL0 = 0,	/* direct HW translation! */
 | 
				
			||||||
 | 
						VOLTAGE_SWING_LEVEL1,
 | 
				
			||||||
 | 
						VOLTAGE_SWING_LEVEL2,
 | 
				
			||||||
 | 
						VOLTAGE_SWING_LEVEL3,
 | 
				
			||||||
 | 
						VOLTAGE_SWING_MAX_LEVEL = VOLTAGE_SWING_LEVEL3
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_pre_emphasis {
 | 
				
			||||||
 | 
						PRE_EMPHASIS_DISABLED = 0,	/* direct HW translation! */
 | 
				
			||||||
 | 
						PRE_EMPHASIS_LEVEL1,
 | 
				
			||||||
 | 
						PRE_EMPHASIS_LEVEL2,
 | 
				
			||||||
 | 
						PRE_EMPHASIS_LEVEL3,
 | 
				
			||||||
 | 
						PRE_EMPHASIS_MAX_LEVEL = PRE_EMPHASIS_LEVEL3
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					/* Post Cursor 2 is optional for transmitter
 | 
				
			||||||
 | 
					 * and it applies only to the main link operating at HBR2
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum dc_post_cursor2 {
 | 
				
			||||||
 | 
						POST_CURSOR2_DISABLED = 0,	/* direct HW translation! */
 | 
				
			||||||
 | 
						POST_CURSOR2_LEVEL1,
 | 
				
			||||||
 | 
						POST_CURSOR2_LEVEL2,
 | 
				
			||||||
 | 
						POST_CURSOR2_LEVEL3,
 | 
				
			||||||
 | 
						POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_link_settings {
 | 
				
			||||||
 | 
						enum dc_lane_count lane_count;
 | 
				
			||||||
 | 
						enum dc_link_rate link_rate;
 | 
				
			||||||
 | 
						enum dc_link_spread link_spread;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_lane_settings {
 | 
				
			||||||
 | 
						enum dc_voltage_swing VOLTAGE_SWING;
 | 
				
			||||||
 | 
						enum dc_pre_emphasis PRE_EMPHASIS;
 | 
				
			||||||
 | 
						enum dc_post_cursor2 POST_CURSOR2;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_link_training_settings {
 | 
				
			||||||
 | 
						struct dc_link_settings link;
 | 
				
			||||||
 | 
						struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DC_DP_TYPES_H */
 | 
				
			||||||
							
								
								
									
										144
									
								
								drivers/gpu/drm/amd/display/dc/dc_helper.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								drivers/gpu/drm/amd/display/dc/dc_helper.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,144 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * dc_helper.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Aug 30, 2016
 | 
				
			||||||
 | 
					 *      Author: agrodzov
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t generic_reg_update_ex(const struct dc_context *ctx,
 | 
				
			||||||
 | 
							uint32_t addr, uint32_t reg_val, int n,
 | 
				
			||||||
 | 
							uint8_t shift1, uint32_t mask1, uint32_t field_value1,
 | 
				
			||||||
 | 
							...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t shift, mask, field_value;
 | 
				
			||||||
 | 
						int i = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_list ap;
 | 
				
			||||||
 | 
						va_start(ap, field_value1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (i < n) {
 | 
				
			||||||
 | 
							shift = va_arg(ap, uint32_t);
 | 
				
			||||||
 | 
							mask = va_arg(ap, uint32_t);
 | 
				
			||||||
 | 
							field_value = va_arg(ap, uint32_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift);
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_write_reg(ctx, addr, reg_val);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return reg_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr,
 | 
				
			||||||
 | 
							uint8_t shift, uint32_t mask, uint32_t *field_value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t reg_val = dm_read_reg(ctx, addr);
 | 
				
			||||||
 | 
						*field_value = get_reg_field_value_ex(reg_val, mask, shift);
 | 
				
			||||||
 | 
						return reg_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
 | 
				
			||||||
 | 
							uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
 | 
				
			||||||
 | 
							uint8_t shift2, uint32_t mask2, uint32_t *field_value2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t reg_val = dm_read_reg(ctx, addr);
 | 
				
			||||||
 | 
						*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
 | 
				
			||||||
 | 
						*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
 | 
				
			||||||
 | 
						return reg_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
 | 
				
			||||||
 | 
							uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
 | 
				
			||||||
 | 
							uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
 | 
				
			||||||
 | 
							uint8_t shift3, uint32_t mask3, uint32_t *field_value3)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t reg_val = dm_read_reg(ctx, addr);
 | 
				
			||||||
 | 
						*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
 | 
				
			||||||
 | 
						*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
 | 
				
			||||||
 | 
						*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
 | 
				
			||||||
 | 
						return reg_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t generic_reg_get5(const struct dc_context *ctx, uint32_t addr,
 | 
				
			||||||
 | 
							uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
 | 
				
			||||||
 | 
							uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
 | 
				
			||||||
 | 
							uint8_t shift3, uint32_t mask3, uint32_t *field_value3,
 | 
				
			||||||
 | 
							uint8_t shift4, uint32_t mask4, uint32_t *field_value4,
 | 
				
			||||||
 | 
							uint8_t shift5, uint32_t mask5, uint32_t *field_value5)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t reg_val = dm_read_reg(ctx, addr);
 | 
				
			||||||
 | 
						*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
 | 
				
			||||||
 | 
						*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
 | 
				
			||||||
 | 
						*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
 | 
				
			||||||
 | 
						*field_value4 = get_reg_field_value_ex(reg_val, mask4, shift4);
 | 
				
			||||||
 | 
						*field_value5 = get_reg_field_value_ex(reg_val, mask5, shift5);
 | 
				
			||||||
 | 
						return reg_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* note:  va version of this is pretty bad idea, since there is a output parameter pass by pointer
 | 
				
			||||||
 | 
					 * compiler won't be able to check for size match and is prone to stack corruption type of bugs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t generic_reg_get(const struct dc_context *ctx,
 | 
				
			||||||
 | 
							uint32_t addr, int n, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t shift, mask;
 | 
				
			||||||
 | 
						uint32_t *field_value;
 | 
				
			||||||
 | 
						uint32_t reg_val;
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reg_val = dm_read_reg(ctx, addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_list ap;
 | 
				
			||||||
 | 
						va_start(ap, n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (i < n) {
 | 
				
			||||||
 | 
							shift = va_arg(ap, uint32_t);
 | 
				
			||||||
 | 
							mask = va_arg(ap, uint32_t);
 | 
				
			||||||
 | 
							field_value = va_arg(ap, uint32_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							*field_value = get_reg_field_value_ex(reg_val, mask, shift);
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return reg_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t generic_reg_wait(const struct dc_context *ctx,
 | 
				
			||||||
 | 
						uint32_t addr, uint32_t shift, uint32_t mask, uint32_t condition_value,
 | 
				
			||||||
 | 
						unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
 | 
				
			||||||
 | 
						const char *func_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t field_value;
 | 
				
			||||||
 | 
						uint32_t reg_val;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i <= time_out_num_tries; i++) {
 | 
				
			||||||
 | 
							if (i) {
 | 
				
			||||||
 | 
								if (0 < delay_between_poll_us && delay_between_poll_us < 1000)
 | 
				
			||||||
 | 
									udelay(delay_between_poll_us);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (delay_between_poll_us > 1000)
 | 
				
			||||||
 | 
									msleep(delay_between_poll_us/1000);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							reg_val = dm_read_reg(ctx, addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							field_value = get_reg_field_value_ex(reg_val, mask, shift);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (field_value == condition_value)
 | 
				
			||||||
 | 
								return reg_val;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DC_ERR("REG_WAIT timeout %dus * %d tries - %s",
 | 
				
			||||||
 | 
								delay_between_poll_us, time_out_num_tries, func_name);
 | 
				
			||||||
 | 
						return reg_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										588
									
								
								drivers/gpu/drm/amd/display/dc/dc_hw_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										588
									
								
								drivers/gpu/drm/amd/display/dc/dc_hw_types.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,588 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef DC_HW_TYPES_H
 | 
				
			||||||
 | 
					#define DC_HW_TYPES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "os_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/******************************************************************************
 | 
				
			||||||
 | 
					 * Data types for Virtual HW Layer of DAL3.
 | 
				
			||||||
 | 
					 * (see DAL3 design documents for HW Layer definition)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The intended uses are:
 | 
				
			||||||
 | 
					 * 1. Generation pseudocode sequences for HW programming.
 | 
				
			||||||
 | 
					 * 2. Implementation of real HW programming by HW Sequencer of DAL3.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note: do *not* add any types which are *not* used for HW programming - this
 | 
				
			||||||
 | 
					 * will ensure separation of Logic layer from HW layer.
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union large_integer {
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							uint32_t low_part;
 | 
				
			||||||
 | 
							int32_t high_part;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							uint32_t low_part;
 | 
				
			||||||
 | 
							int32_t high_part;
 | 
				
			||||||
 | 
						} u;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int64_t quad_part;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PHYSICAL_ADDRESS_LOC union large_integer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_plane_addr_type {
 | 
				
			||||||
 | 
						PLN_ADDR_TYPE_GRAPHICS = 0,
 | 
				
			||||||
 | 
						PLN_ADDR_TYPE_GRPH_STEREO,
 | 
				
			||||||
 | 
						PLN_ADDR_TYPE_VIDEO_PROGRESSIVE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_plane_address {
 | 
				
			||||||
 | 
						enum dc_plane_addr_type type;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct{
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC addr;
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC meta_addr;
 | 
				
			||||||
 | 
								union large_integer dcc_const_color;
 | 
				
			||||||
 | 
							} grph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*stereo*/
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC left_addr;
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC left_meta_addr;
 | 
				
			||||||
 | 
								union large_integer left_dcc_const_color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC right_addr;
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC right_meta_addr;
 | 
				
			||||||
 | 
								union large_integer right_dcc_const_color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							} grph_stereo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*video  progressive*/
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC luma_addr;
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC luma_meta_addr;
 | 
				
			||||||
 | 
								union large_integer luma_dcc_const_color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC chroma_addr;
 | 
				
			||||||
 | 
								PHYSICAL_ADDRESS_LOC chroma_meta_addr;
 | 
				
			||||||
 | 
								union large_integer chroma_dcc_const_color;
 | 
				
			||||||
 | 
							} video_progressive;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_size {
 | 
				
			||||||
 | 
						uint32_t width;
 | 
				
			||||||
 | 
						uint32_t height;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rect {
 | 
				
			||||||
 | 
						int x;
 | 
				
			||||||
 | 
						int y;
 | 
				
			||||||
 | 
						uint32_t width;
 | 
				
			||||||
 | 
						uint32_t height;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union plane_size {
 | 
				
			||||||
 | 
						/* Grph or Video will be selected
 | 
				
			||||||
 | 
						 * based on format above:
 | 
				
			||||||
 | 
						 * Use Video structure if
 | 
				
			||||||
 | 
						 * format >= DalPixelFormat_VideoBegin
 | 
				
			||||||
 | 
						 * else use Grph structure
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct rect surface_size;
 | 
				
			||||||
 | 
							/* Graphic surface pitch in pixels.
 | 
				
			||||||
 | 
							 * In LINEAR_GENERAL mode, pitch
 | 
				
			||||||
 | 
							 * is 32 pixel aligned.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							uint32_t surface_pitch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t meta_pitch;
 | 
				
			||||||
 | 
						} grph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct rect luma_size;
 | 
				
			||||||
 | 
							/* Graphic surface pitch in pixels.
 | 
				
			||||||
 | 
							 * In LINEAR_GENERAL mode, pitch is
 | 
				
			||||||
 | 
							 * 32 pixel aligned.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							uint32_t luma_pitch;
 | 
				
			||||||
 | 
							uint32_t meta_luma_pitch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct rect chroma_size;
 | 
				
			||||||
 | 
							/* Graphic surface pitch in pixels.
 | 
				
			||||||
 | 
							 * In LINEAR_GENERAL mode, pitch is
 | 
				
			||||||
 | 
							 * 32 pixel aligned.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							uint32_t chroma_pitch;
 | 
				
			||||||
 | 
							uint32_t meta_chroma_pitch;
 | 
				
			||||||
 | 
						} video;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_plane_dcc_param {
 | 
				
			||||||
 | 
						bool enable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								uint32_t meta_pitch;
 | 
				
			||||||
 | 
								bool independent_64b_blks;
 | 
				
			||||||
 | 
							} grph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								uint32_t meta_pitch_l;
 | 
				
			||||||
 | 
								bool independent_64b_blks_l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								uint32_t meta_pitch_c;
 | 
				
			||||||
 | 
								bool independent_64b_blks_c;
 | 
				
			||||||
 | 
							} video;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*Displayable pixel format in fb*/
 | 
				
			||||||
 | 
					enum surface_pixel_format {
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_BEGIN = 0,
 | 
				
			||||||
 | 
						/*TOBE REMOVED paletta 256 colors*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS =
 | 
				
			||||||
 | 
							SURFACE_PIXEL_FORMAT_GRPH_BEGIN,
 | 
				
			||||||
 | 
						/*16 bpp*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ARGB1555,
 | 
				
			||||||
 | 
						/*16 bpp*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_RGB565,
 | 
				
			||||||
 | 
						/*32 bpp*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ARGB8888,
 | 
				
			||||||
 | 
						/*32 bpp swaped*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_BGRA8888,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010,
 | 
				
			||||||
 | 
						/*swaped*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010,
 | 
				
			||||||
 | 
						/*TOBE REMOVED swaped, XR_BIAS has no differance
 | 
				
			||||||
 | 
						 * for pixel layout than previous and we can
 | 
				
			||||||
 | 
						 * delete this after discusion*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS,
 | 
				
			||||||
 | 
						/*64 bpp */
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616,
 | 
				
			||||||
 | 
						/*float*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F,
 | 
				
			||||||
 | 
						/*swaped & float*/
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F,
 | 
				
			||||||
 | 
						/*grow graphics here if necessary */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_VIDEO_BEGIN,
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr =
 | 
				
			||||||
 | 
							SURFACE_PIXEL_FORMAT_VIDEO_BEGIN,
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb,
 | 
				
			||||||
 | 
						SURFACE_PIXEL_FORMAT_INVALID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*grow 444 video here if necessary */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Pixel format */
 | 
				
			||||||
 | 
					enum pixel_format {
 | 
				
			||||||
 | 
						/*graph*/
 | 
				
			||||||
 | 
						PIXEL_FORMAT_UNINITIALIZED,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_INDEX8,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_RGB565,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_ARGB8888,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_ARGB2101010,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_ARGB2101010_XRBIAS,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_FP16,
 | 
				
			||||||
 | 
						/*video*/
 | 
				
			||||||
 | 
						PIXEL_FORMAT_420BPP12,
 | 
				
			||||||
 | 
						/*end of pixel format definition*/
 | 
				
			||||||
 | 
						PIXEL_FORMAT_INVALID,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PIXEL_FORMAT_GRPH_BEGIN = PIXEL_FORMAT_INDEX8,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_GRPH_END = PIXEL_FORMAT_FP16,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_VIDEO_BEGIN = PIXEL_FORMAT_420BPP12,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_VIDEO_END = PIXEL_FORMAT_420BPP12,
 | 
				
			||||||
 | 
						PIXEL_FORMAT_UNKNOWN
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum tile_split_values {
 | 
				
			||||||
 | 
						DC_DISPLAY_MICRO_TILING = 0x0,
 | 
				
			||||||
 | 
						DC_THIN_MICRO_TILING = 0x1,
 | 
				
			||||||
 | 
						DC_DEPTH_MICRO_TILING = 0x2,
 | 
				
			||||||
 | 
						DC_ROTATED_MICRO_TILING = 0x3,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TODO: These values come from hardware spec. We need to readdress this
 | 
				
			||||||
 | 
					 * if they ever change.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum array_mode_values {
 | 
				
			||||||
 | 
						DC_ARRAY_LINEAR_GENERAL = 0,
 | 
				
			||||||
 | 
						DC_ARRAY_LINEAR_ALLIGNED,
 | 
				
			||||||
 | 
						DC_ARRAY_1D_TILED_THIN1,
 | 
				
			||||||
 | 
						DC_ARRAY_1D_TILED_THICK,
 | 
				
			||||||
 | 
						DC_ARRAY_2D_TILED_THIN1,
 | 
				
			||||||
 | 
						DC_ARRAY_PRT_TILED_THIN1,
 | 
				
			||||||
 | 
						DC_ARRAY_PRT_2D_TILED_THIN1,
 | 
				
			||||||
 | 
						DC_ARRAY_2D_TILED_THICK,
 | 
				
			||||||
 | 
						DC_ARRAY_2D_TILED_X_THICK,
 | 
				
			||||||
 | 
						DC_ARRAY_PRT_TILED_THICK,
 | 
				
			||||||
 | 
						DC_ARRAY_PRT_2D_TILED_THICK,
 | 
				
			||||||
 | 
						DC_ARRAY_PRT_3D_TILED_THIN1,
 | 
				
			||||||
 | 
						DC_ARRAY_3D_TILED_THIN1,
 | 
				
			||||||
 | 
						DC_ARRAY_3D_TILED_THICK,
 | 
				
			||||||
 | 
						DC_ARRAY_3D_TILED_X_THICK,
 | 
				
			||||||
 | 
						DC_ARRAY_PRT_3D_TILED_THICK,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum tile_mode_values {
 | 
				
			||||||
 | 
						DC_ADDR_SURF_MICRO_TILING_DISPLAY = 0x0,
 | 
				
			||||||
 | 
						DC_ADDR_SURF_MICRO_TILING_NON_DISPLAY = 0x1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union dc_tiling_info {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							/* Specifies the number of memory banks for tiling
 | 
				
			||||||
 | 
							 *	purposes.
 | 
				
			||||||
 | 
							 * Only applies to 2D and 3D tiling modes.
 | 
				
			||||||
 | 
							 *	POSSIBLE VALUES: 2,4,8,16
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							unsigned int num_banks;
 | 
				
			||||||
 | 
							/* Specifies the number of tiles in the x direction
 | 
				
			||||||
 | 
							 *	to be incorporated into the same bank.
 | 
				
			||||||
 | 
							 * Only applies to 2D and 3D tiling modes.
 | 
				
			||||||
 | 
							 *	POSSIBLE VALUES: 1,2,4,8
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							unsigned int bank_width;
 | 
				
			||||||
 | 
							unsigned int bank_width_c;
 | 
				
			||||||
 | 
							/* Specifies the number of tiles in the y direction to
 | 
				
			||||||
 | 
							 *	be incorporated into the same bank.
 | 
				
			||||||
 | 
							 * Only applies to 2D and 3D tiling modes.
 | 
				
			||||||
 | 
							 *	POSSIBLE VALUES: 1,2,4,8
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							unsigned int bank_height;
 | 
				
			||||||
 | 
							unsigned int bank_height_c;
 | 
				
			||||||
 | 
							/* Specifies the macro tile aspect ratio. Only applies
 | 
				
			||||||
 | 
							 * to 2D and 3D tiling modes.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							unsigned int tile_aspect;
 | 
				
			||||||
 | 
							unsigned int tile_aspect_c;
 | 
				
			||||||
 | 
							/* Specifies the number of bytes that will be stored
 | 
				
			||||||
 | 
							 *	contiguously for each tile.
 | 
				
			||||||
 | 
							 * If the tile data requires more storage than this
 | 
				
			||||||
 | 
							 *	amount, it is split into multiple slices.
 | 
				
			||||||
 | 
							 * This field must not be larger than
 | 
				
			||||||
 | 
							 *	GB_ADDR_CONFIG.DRAM_ROW_SIZE.
 | 
				
			||||||
 | 
							 * Only applies to 2D and 3D tiling modes.
 | 
				
			||||||
 | 
							 * For color render targets, TILE_SPLIT >= 256B.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							enum tile_split_values tile_split;
 | 
				
			||||||
 | 
							enum tile_split_values tile_split_c;
 | 
				
			||||||
 | 
							/* Specifies the addressing within a tile.
 | 
				
			||||||
 | 
							 *	0x0 - DISPLAY_MICRO_TILING
 | 
				
			||||||
 | 
							 *	0x1 - THIN_MICRO_TILING
 | 
				
			||||||
 | 
							 *	0x2 - DEPTH_MICRO_TILING
 | 
				
			||||||
 | 
							 *	0x3 - ROTATED_MICRO_TILING
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							enum tile_mode_values tile_mode;
 | 
				
			||||||
 | 
							enum tile_mode_values tile_mode_c;
 | 
				
			||||||
 | 
							/* Specifies the number of pipes and how they are
 | 
				
			||||||
 | 
							 *	interleaved in the surface.
 | 
				
			||||||
 | 
							 * Refer to memory addressing document for complete
 | 
				
			||||||
 | 
							 *	details and constraints.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							unsigned int pipe_config;
 | 
				
			||||||
 | 
							/* Specifies the tiling mode of the surface.
 | 
				
			||||||
 | 
							 * THIN tiles use an 8x8x1 tile size.
 | 
				
			||||||
 | 
							 * THICK tiles use an 8x8x4 tile size.
 | 
				
			||||||
 | 
							 * 2D tiling modes rotate banks for successive Z slices
 | 
				
			||||||
 | 
							 * 3D tiling modes rotate pipes and banks for Z slices
 | 
				
			||||||
 | 
							 * Refer to memory addressing document for complete
 | 
				
			||||||
 | 
							 *	details and constraints.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							enum array_mode_values array_mode;
 | 
				
			||||||
 | 
						} gfx8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Rotation angle */
 | 
				
			||||||
 | 
					enum dc_rotation_angle {
 | 
				
			||||||
 | 
						ROTATION_ANGLE_0 = 0,
 | 
				
			||||||
 | 
						ROTATION_ANGLE_90,
 | 
				
			||||||
 | 
						ROTATION_ANGLE_180,
 | 
				
			||||||
 | 
						ROTATION_ANGLE_270,
 | 
				
			||||||
 | 
						ROTATION_ANGLE_COUNT
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_scan_direction {
 | 
				
			||||||
 | 
						SCAN_DIRECTION_UNKNOWN = 0,
 | 
				
			||||||
 | 
						SCAN_DIRECTION_HORIZONTAL = 1,  /* 0, 180 rotation */
 | 
				
			||||||
 | 
						SCAN_DIRECTION_VERTICAL = 2,    /* 90, 270 rotation */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_cursor_position {
 | 
				
			||||||
 | 
						uint32_t x;
 | 
				
			||||||
 | 
						uint32_t y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t x_hotspot;
 | 
				
			||||||
 | 
						uint32_t y_hotspot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * This parameter indicates whether HW cursor should be enabled
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						bool enable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * This parameter indicates whether cursor hot spot should be
 | 
				
			||||||
 | 
						 * programmed
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						bool hot_spot_enable;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* IPP related types */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Used by both ipp amd opp functions*/
 | 
				
			||||||
 | 
					/* TODO: to be consolidated with enum color_space */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This enum is for programming CURSOR_MODE register field. What this register
 | 
				
			||||||
 | 
					 * should be programmed to depends on OS requested cursor shape flags and what
 | 
				
			||||||
 | 
					 * we stored in the cursor surface.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum dc_cursor_color_format {
 | 
				
			||||||
 | 
						CURSOR_MODE_MONO,
 | 
				
			||||||
 | 
						CURSOR_MODE_COLOR_1BIT_AND,
 | 
				
			||||||
 | 
						CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA,
 | 
				
			||||||
 | 
						CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This is all the parameters required by DAL in order to update the cursor
 | 
				
			||||||
 | 
					 * attributes, including the new cursor image surface address, size, hotspot
 | 
				
			||||||
 | 
					 * location, color format, etc.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union dc_cursor_attribute_flags {
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							uint32_t ENABLE_MAGNIFICATION:1;
 | 
				
			||||||
 | 
							uint32_t INVERSE_TRANSPARENT_CLAMPING:1;
 | 
				
			||||||
 | 
							uint32_t HORIZONTAL_MIRROR:1;
 | 
				
			||||||
 | 
							uint32_t VERTICAL_MIRROR:1;
 | 
				
			||||||
 | 
							uint32_t INVERT_PIXEL_DATA:1;
 | 
				
			||||||
 | 
							uint32_t ZERO_EXPANSION:1;
 | 
				
			||||||
 | 
							uint32_t MIN_MAX_INVERT:1;
 | 
				
			||||||
 | 
							uint32_t RESERVED:25;
 | 
				
			||||||
 | 
						} bits;
 | 
				
			||||||
 | 
						uint32_t value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_cursor_attributes {
 | 
				
			||||||
 | 
						PHYSICAL_ADDRESS_LOC address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Width and height should correspond to cursor surface width x heigh */
 | 
				
			||||||
 | 
						uint32_t width;
 | 
				
			||||||
 | 
						uint32_t height;
 | 
				
			||||||
 | 
						uint32_t x_hot;
 | 
				
			||||||
 | 
						uint32_t y_hot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum dc_cursor_color_format color_format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* In case we support HW Cursor rotation in the future */
 | 
				
			||||||
 | 
						enum dc_rotation_angle rotation_angle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union dc_cursor_attribute_flags attribute_flags;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* OPP */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_color_space {
 | 
				
			||||||
 | 
						COLOR_SPACE_UNKNOWN,
 | 
				
			||||||
 | 
						COLOR_SPACE_SRGB,
 | 
				
			||||||
 | 
						COLOR_SPACE_SRGB_LIMITED,
 | 
				
			||||||
 | 
						COLOR_SPACE_YPBPR601,
 | 
				
			||||||
 | 
						COLOR_SPACE_YPBPR709,
 | 
				
			||||||
 | 
						COLOR_SPACE_YCBCR601,
 | 
				
			||||||
 | 
						COLOR_SPACE_YCBCR709,
 | 
				
			||||||
 | 
						COLOR_SPACE_YCBCR601_LIMITED,
 | 
				
			||||||
 | 
						COLOR_SPACE_YCBCR709_LIMITED
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_quantization_range {
 | 
				
			||||||
 | 
						QUANTIZATION_RANGE_UNKNOWN,
 | 
				
			||||||
 | 
						QUANTIZATION_RANGE_FULL,
 | 
				
			||||||
 | 
						QUANTIZATION_RANGE_LIMITED
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* XFM */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* used in  struct dc_surface */
 | 
				
			||||||
 | 
					struct scaling_taps {
 | 
				
			||||||
 | 
						uint32_t v_taps;
 | 
				
			||||||
 | 
						uint32_t h_taps;
 | 
				
			||||||
 | 
						uint32_t v_taps_c;
 | 
				
			||||||
 | 
						uint32_t h_taps_c;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_timing_standard {
 | 
				
			||||||
 | 
						TIMING_STANDARD_UNDEFINED,
 | 
				
			||||||
 | 
						TIMING_STANDARD_DMT,
 | 
				
			||||||
 | 
						TIMING_STANDARD_GTF,
 | 
				
			||||||
 | 
						TIMING_STANDARD_CVT,
 | 
				
			||||||
 | 
						TIMING_STANDARD_CVT_RB,
 | 
				
			||||||
 | 
						TIMING_STANDARD_CEA770,
 | 
				
			||||||
 | 
						TIMING_STANDARD_CEA861,
 | 
				
			||||||
 | 
						TIMING_STANDARD_HDMI,
 | 
				
			||||||
 | 
						TIMING_STANDARD_TV_NTSC,
 | 
				
			||||||
 | 
						TIMING_STANDARD_TV_NTSC_J,
 | 
				
			||||||
 | 
						TIMING_STANDARD_TV_PAL,
 | 
				
			||||||
 | 
						TIMING_STANDARD_TV_PAL_M,
 | 
				
			||||||
 | 
						TIMING_STANDARD_TV_PAL_CN,
 | 
				
			||||||
 | 
						TIMING_STANDARD_TV_SECAM,
 | 
				
			||||||
 | 
						TIMING_STANDARD_EXPLICIT,
 | 
				
			||||||
 | 
						/*!< For explicit timings from EDID, VBIOS, etc.*/
 | 
				
			||||||
 | 
						TIMING_STANDARD_USER_OVERRIDE,
 | 
				
			||||||
 | 
						/*!< For mode timing override by user*/
 | 
				
			||||||
 | 
						TIMING_STANDARD_MAX
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_timing_3d_format {
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_NONE,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_FRAME_ALTERNATE, /* No stereosync at all*/
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_INBAND_FA, /* Inband Frame Alternate (DVI/DP)*/
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_DP_HDMI_INBAND_FA, /* Inband FA to HDMI Frame Pack*/
 | 
				
			||||||
 | 
						/* for active DP-HDMI dongle*/
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_SIDEBAND_FA, /* Sideband Frame Alternate (eDP)*/
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_HW_FRAME_PACKING,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_SW_FRAME_PACKING,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_ROW_INTERLEAVE,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_COLUMN_INTERLEAVE,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_PIXEL_INTERLEAVE,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_SIDE_BY_SIDE,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_TOP_AND_BOTTOM,
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_SBS_SW_PACKED,
 | 
				
			||||||
 | 
						/* Side-by-side, packed by application/driver into 2D frame*/
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_TB_SW_PACKED,
 | 
				
			||||||
 | 
						/* Top-and-bottom, packed by application/driver into 2D frame*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TIMING_3D_FORMAT_MAX,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_color_depth {
 | 
				
			||||||
 | 
						COLOR_DEPTH_UNDEFINED,
 | 
				
			||||||
 | 
						COLOR_DEPTH_666,
 | 
				
			||||||
 | 
						COLOR_DEPTH_888,
 | 
				
			||||||
 | 
						COLOR_DEPTH_101010,
 | 
				
			||||||
 | 
						COLOR_DEPTH_121212,
 | 
				
			||||||
 | 
						COLOR_DEPTH_141414,
 | 
				
			||||||
 | 
						COLOR_DEPTH_161616,
 | 
				
			||||||
 | 
						COLOR_DEPTH_COUNT
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_pixel_encoding {
 | 
				
			||||||
 | 
						PIXEL_ENCODING_UNDEFINED,
 | 
				
			||||||
 | 
						PIXEL_ENCODING_RGB,
 | 
				
			||||||
 | 
						PIXEL_ENCODING_YCBCR422,
 | 
				
			||||||
 | 
						PIXEL_ENCODING_YCBCR444,
 | 
				
			||||||
 | 
						PIXEL_ENCODING_YCBCR420,
 | 
				
			||||||
 | 
						PIXEL_ENCODING_COUNT
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_aspect_ratio {
 | 
				
			||||||
 | 
						ASPECT_RATIO_NO_DATA,
 | 
				
			||||||
 | 
						ASPECT_RATIO_4_3,
 | 
				
			||||||
 | 
						ASPECT_RATIO_16_9,
 | 
				
			||||||
 | 
						ASPECT_RATIO_64_27,
 | 
				
			||||||
 | 
						ASPECT_RATIO_256_135,
 | 
				
			||||||
 | 
						ASPECT_RATIO_FUTURE
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum scanning_type {
 | 
				
			||||||
 | 
						SCANNING_TYPE_NODATA = 0,
 | 
				
			||||||
 | 
						SCANNING_TYPE_OVERSCAN,
 | 
				
			||||||
 | 
						SCANNING_TYPE_UNDERSCAN,
 | 
				
			||||||
 | 
						SCANNING_TYPE_FUTURE,
 | 
				
			||||||
 | 
						SCANNING_TYPE_UNDEFINED
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_crtc_timing_flags {
 | 
				
			||||||
 | 
						uint32_t INTERLACE :1;
 | 
				
			||||||
 | 
						uint32_t HSYNC_POSITIVE_POLARITY :1; /* when set to 1,
 | 
				
			||||||
 | 
						 it is positive polarity --reversed with dal1 or video bios define*/
 | 
				
			||||||
 | 
						uint32_t VSYNC_POSITIVE_POLARITY :1; /* when set to 1,
 | 
				
			||||||
 | 
						 it is positive polarity --reversed with dal1 or video bios define*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t HORZ_COUNT_BY_TWO:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t EXCLUSIVE_3D :1; /* if this bit set,
 | 
				
			||||||
 | 
						 timing can be driven in 3D format only
 | 
				
			||||||
 | 
						 and there is no corresponding 2D timing*/
 | 
				
			||||||
 | 
						uint32_t RIGHT_EYE_3D_POLARITY :1; /* 1 - means right eye polarity
 | 
				
			||||||
 | 
						 (right eye = '1', left eye = '0') */
 | 
				
			||||||
 | 
						uint32_t SUB_SAMPLE_3D :1; /* 1 - means left/right  images subsampled
 | 
				
			||||||
 | 
						 when mixed into 3D image. 0 - means summation (3D timing is doubled)*/
 | 
				
			||||||
 | 
						uint32_t USE_IN_3D_VIEW_ONLY :1; /* Do not use this timing in 2D View,
 | 
				
			||||||
 | 
						 because corresponding 2D timing also present in the list*/
 | 
				
			||||||
 | 
						uint32_t STEREO_3D_PREFERENCE :1; /* Means this is 2D timing
 | 
				
			||||||
 | 
						 and we want to match priority of corresponding 3D timing*/
 | 
				
			||||||
 | 
						uint32_t Y_ONLY :1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t YCBCR420 :1; /* TODO: shouldn't need this flag, should be a separate pixel format */
 | 
				
			||||||
 | 
						uint32_t DTD_COUNTER :5; /* values 1 to 16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* HDMI 2.0 - Support scrambling for TMDS character
 | 
				
			||||||
 | 
						 * rates less than or equal to 340Mcsc */
 | 
				
			||||||
 | 
						uint32_t LTE_340MCSC_SCRAMBLE:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_crtc_timing {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t h_total;
 | 
				
			||||||
 | 
						uint32_t h_border_left;
 | 
				
			||||||
 | 
						uint32_t h_addressable;
 | 
				
			||||||
 | 
						uint32_t h_border_right;
 | 
				
			||||||
 | 
						uint32_t h_front_porch;
 | 
				
			||||||
 | 
						uint32_t h_sync_width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t v_total;
 | 
				
			||||||
 | 
						uint32_t v_border_top;
 | 
				
			||||||
 | 
						uint32_t v_addressable;
 | 
				
			||||||
 | 
						uint32_t v_border_bottom;
 | 
				
			||||||
 | 
						uint32_t v_front_porch;
 | 
				
			||||||
 | 
						uint32_t v_sync_width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t pix_clk_khz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t vic;
 | 
				
			||||||
 | 
						uint32_t hdmi_vic;
 | 
				
			||||||
 | 
						enum dc_timing_3d_format timing_3d_format;
 | 
				
			||||||
 | 
						enum dc_color_depth display_color_depth;
 | 
				
			||||||
 | 
						enum dc_pixel_encoding pixel_encoding;
 | 
				
			||||||
 | 
						enum dc_aspect_ratio aspect_ratio;
 | 
				
			||||||
 | 
						enum scanning_type scan_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct dc_crtc_timing_flags flags;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DC_HW_TYPES_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										493
									
								
								drivers/gpu/drm/amd/display/dc/dc_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										493
									
								
								drivers/gpu/drm/amd/display/dc/dc_types.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,493 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef DC_TYPES_H_
 | 
				
			||||||
 | 
					#define DC_TYPES_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "fixed32_32.h"
 | 
				
			||||||
 | 
					#include "fixed31_32.h"
 | 
				
			||||||
 | 
					#include "irq_types.h"
 | 
				
			||||||
 | 
					#include "dc_dp_types.h"
 | 
				
			||||||
 | 
					#include "dc_hw_types.h"
 | 
				
			||||||
 | 
					#include "dal_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* forward declarations */
 | 
				
			||||||
 | 
					struct dc_surface;
 | 
				
			||||||
 | 
					struct dc_target;
 | 
				
			||||||
 | 
					struct dc_stream;
 | 
				
			||||||
 | 
					struct dc_link;
 | 
				
			||||||
 | 
					struct dc_sink;
 | 
				
			||||||
 | 
					struct dal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/********************************
 | 
				
			||||||
 | 
					 * Environment definitions
 | 
				
			||||||
 | 
					 ********************************/
 | 
				
			||||||
 | 
					enum dce_environment {
 | 
				
			||||||
 | 
						DCE_ENV_PRODUCTION_DRV = 0,
 | 
				
			||||||
 | 
						/* Emulation on FPGA, in "Maximus" System.
 | 
				
			||||||
 | 
						 * This environment enforces that *only* DC registers accessed.
 | 
				
			||||||
 | 
						 * (access to non-DC registers will hang FPGA) */
 | 
				
			||||||
 | 
						DCE_ENV_FPGA_MAXIMUS,
 | 
				
			||||||
 | 
						/* Emulation on real HW or on FPGA. Used by Diagnostics, enforces
 | 
				
			||||||
 | 
						 * requirements of Diagnostics team. */
 | 
				
			||||||
 | 
						DCE_ENV_DIAG
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Note: use these macro definitions instead of direct comparison! */
 | 
				
			||||||
 | 
					#define IS_FPGA_MAXIMUS_DC(dce_environment) \
 | 
				
			||||||
 | 
						(dce_environment == DCE_ENV_FPGA_MAXIMUS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IS_DIAG_DC(dce_environment) \
 | 
				
			||||||
 | 
						(IS_FPGA_MAXIMUS_DC(dce_environment) || (dce_environment == DCE_ENV_DIAG))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct hw_asic_id {
 | 
				
			||||||
 | 
						uint32_t chip_id;
 | 
				
			||||||
 | 
						uint32_t chip_family;
 | 
				
			||||||
 | 
						uint32_t pci_revision_id;
 | 
				
			||||||
 | 
						uint32_t hw_internal_rev;
 | 
				
			||||||
 | 
						uint32_t vram_type;
 | 
				
			||||||
 | 
						uint32_t vram_width;
 | 
				
			||||||
 | 
						uint32_t feature_flags;
 | 
				
			||||||
 | 
						uint32_t fake_paths_num;
 | 
				
			||||||
 | 
						void *atombios_base_address;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_context {
 | 
				
			||||||
 | 
						struct dc *dc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *driver_context; /* e.g. amdgpu_device */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct dal_logger *logger;
 | 
				
			||||||
 | 
						void *cgs_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum dce_environment dce_environment;
 | 
				
			||||||
 | 
						struct hw_asic_id asic_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* todo: below should probably move to dc.  to facilitate removal
 | 
				
			||||||
 | 
						 * of AS we will store these here
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						enum dce_version dce_version;
 | 
				
			||||||
 | 
						struct dc_bios *dc_bios;
 | 
				
			||||||
 | 
						bool created_bios;
 | 
				
			||||||
 | 
						struct gpio_service *gpio_service;
 | 
				
			||||||
 | 
						struct i2caux *i2caux;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_EDID_BUFFER_SIZE 512
 | 
				
			||||||
 | 
					#define EDID_BLOCK_SIZE 128
 | 
				
			||||||
 | 
					#define MAX_SURFACE_NUM 2
 | 
				
			||||||
 | 
					#define NUM_PIXEL_FORMATS 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dc_ddc_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum tiling_mode {
 | 
				
			||||||
 | 
						TILING_MODE_INVALID,
 | 
				
			||||||
 | 
						TILING_MODE_LINEAR,
 | 
				
			||||||
 | 
						TILING_MODE_TILED,
 | 
				
			||||||
 | 
						TILING_MODE_COUNT
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum view_3d_format {
 | 
				
			||||||
 | 
						VIEW_3D_FORMAT_NONE = 0,
 | 
				
			||||||
 | 
						VIEW_3D_FORMAT_FRAME_SEQUENTIAL,
 | 
				
			||||||
 | 
						VIEW_3D_FORMAT_SIDE_BY_SIDE,
 | 
				
			||||||
 | 
						VIEW_3D_FORMAT_TOP_AND_BOTTOM,
 | 
				
			||||||
 | 
						VIEW_3D_FORMAT_COUNT,
 | 
				
			||||||
 | 
						VIEW_3D_FORMAT_FIRST = VIEW_3D_FORMAT_FRAME_SEQUENTIAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum plane_stereo_format {
 | 
				
			||||||
 | 
						PLANE_STEREO_FORMAT_NONE = 0,
 | 
				
			||||||
 | 
						PLANE_STEREO_FORMAT_SIDE_BY_SIDE = 1,
 | 
				
			||||||
 | 
						PLANE_STEREO_FORMAT_TOP_AND_BOTTOM = 2,
 | 
				
			||||||
 | 
						PLANE_STEREO_FORMAT_FRAME_ALTERNATE = 3,
 | 
				
			||||||
 | 
						PLANE_STEREO_FORMAT_ROW_INTERLEAVED = 5,
 | 
				
			||||||
 | 
						PLANE_STEREO_FORMAT_COLUMN_INTERLEAVED = 6,
 | 
				
			||||||
 | 
						PLANE_STEREO_FORMAT_CHECKER_BOARD = 7
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TODO: Find way to calculate number of bits
 | 
				
			||||||
 | 
					 *  Please increase if pixel_format enum increases
 | 
				
			||||||
 | 
					 * num  from  PIXEL_FORMAT_INDEX8 to PIXEL_FORMAT_444BPP32
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_edid_connector_type {
 | 
				
			||||||
 | 
						EDID_CONNECTOR_UNKNOWN = 0,
 | 
				
			||||||
 | 
						EDID_CONNECTOR_ANALOG = 1,
 | 
				
			||||||
 | 
						EDID_CONNECTOR_DIGITAL = 10,
 | 
				
			||||||
 | 
						EDID_CONNECTOR_DVI = 11,
 | 
				
			||||||
 | 
						EDID_CONNECTOR_HDMIA = 12,
 | 
				
			||||||
 | 
						EDID_CONNECTOR_MDDI = 14,
 | 
				
			||||||
 | 
						EDID_CONNECTOR_DISPLAYPORT = 15
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_edid_status {
 | 
				
			||||||
 | 
						EDID_OK,
 | 
				
			||||||
 | 
						EDID_BAD_INPUT,
 | 
				
			||||||
 | 
						EDID_NO_RESPONSE,
 | 
				
			||||||
 | 
						EDID_BAD_CHECKSUM,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* audio capability from EDID*/
 | 
				
			||||||
 | 
					struct dc_cea_audio_mode {
 | 
				
			||||||
 | 
						uint8_t format_code; /* ucData[0] [6:3]*/
 | 
				
			||||||
 | 
						uint8_t channel_count; /* ucData[0] [2:0]*/
 | 
				
			||||||
 | 
						uint8_t sample_rate; /* ucData[1]*/
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							uint8_t sample_size; /* for LPCM*/
 | 
				
			||||||
 | 
							/*  for Audio Formats 2-8 (Max bit rate divided by 8 kHz)*/
 | 
				
			||||||
 | 
							uint8_t max_bit_rate;
 | 
				
			||||||
 | 
							uint8_t audio_codec_vendor_specific; /* for Audio Formats 9-15*/
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_edid {
 | 
				
			||||||
 | 
						uint32_t length;
 | 
				
			||||||
 | 
						uint8_t raw_edid[MAX_EDID_BUFFER_SIZE];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* When speaker location data block is not available, DEFAULT_SPEAKER_LOCATION
 | 
				
			||||||
 | 
					 * is used. In this case we assume speaker location are: front left, front
 | 
				
			||||||
 | 
					 * right and front center. */
 | 
				
			||||||
 | 
					#define DEFAULT_SPEAKER_LOCATION 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DC_MAX_AUDIO_DESC_COUNT 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_edid_caps {
 | 
				
			||||||
 | 
						/* sink identification */
 | 
				
			||||||
 | 
						uint16_t manufacturer_id;
 | 
				
			||||||
 | 
						uint16_t product_id;
 | 
				
			||||||
 | 
						uint32_t serial_number;
 | 
				
			||||||
 | 
						uint8_t manufacture_week;
 | 
				
			||||||
 | 
						uint8_t manufacture_year;
 | 
				
			||||||
 | 
						uint8_t display_name[AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* audio caps */
 | 
				
			||||||
 | 
						uint8_t speaker_flags;
 | 
				
			||||||
 | 
						uint32_t audio_mode_count;
 | 
				
			||||||
 | 
						struct dc_cea_audio_mode audio_modes[DC_MAX_AUDIO_DESC_COUNT];
 | 
				
			||||||
 | 
						uint32_t audio_latency;
 | 
				
			||||||
 | 
						uint32_t video_latency;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*HDMI 2.0 caps*/
 | 
				
			||||||
 | 
						bool lte_340mcsc_scramble;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool edid_hdmi;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct view {
 | 
				
			||||||
 | 
						uint32_t width;
 | 
				
			||||||
 | 
						uint32_t height;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_mode_flags {
 | 
				
			||||||
 | 
						/* note: part of refresh rate flag*/
 | 
				
			||||||
 | 
						uint32_t INTERLACE :1;
 | 
				
			||||||
 | 
						/* native display timing*/
 | 
				
			||||||
 | 
						uint32_t NATIVE :1;
 | 
				
			||||||
 | 
						/* preferred is the recommended mode, one per display */
 | 
				
			||||||
 | 
						uint32_t PREFERRED :1;
 | 
				
			||||||
 | 
						/* true if this mode should use reduced blanking timings
 | 
				
			||||||
 | 
						 *_not_ related to the Reduced Blanking adjustment*/
 | 
				
			||||||
 | 
						uint32_t REDUCED_BLANKING :1;
 | 
				
			||||||
 | 
						/* note: part of refreshrate flag*/
 | 
				
			||||||
 | 
						uint32_t VIDEO_OPTIMIZED_RATE :1;
 | 
				
			||||||
 | 
						/* should be reported to upper layers as mode_flags*/
 | 
				
			||||||
 | 
						uint32_t PACKED_PIXEL_FORMAT :1;
 | 
				
			||||||
 | 
						/*< preferred view*/
 | 
				
			||||||
 | 
						uint32_t PREFERRED_VIEW :1;
 | 
				
			||||||
 | 
						/* this timing should be used only in tiled mode*/
 | 
				
			||||||
 | 
						uint32_t TILED_MODE :1;
 | 
				
			||||||
 | 
						uint32_t DSE_MODE :1;
 | 
				
			||||||
 | 
						/* Refresh rate divider when Miracast sink is using a
 | 
				
			||||||
 | 
						 different rate than the output display device
 | 
				
			||||||
 | 
						 Must be zero for wired displays and non-zero for
 | 
				
			||||||
 | 
						 Miracast displays*/
 | 
				
			||||||
 | 
						uint32_t MIRACAST_REFRESH_DIVIDER;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_timing_source {
 | 
				
			||||||
 | 
						TIMING_SOURCE_UNDEFINED,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* explicitly specifed by user, most important*/
 | 
				
			||||||
 | 
						TIMING_SOURCE_USER_FORCED,
 | 
				
			||||||
 | 
						TIMING_SOURCE_USER_OVERRIDE,
 | 
				
			||||||
 | 
						TIMING_SOURCE_CUSTOM,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EXPLICIT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* explicitly specified by the display device, more important*/
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_CEA_SVD_3D,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_CEA_SVD_PREFERRED,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_CEA_SVD_420,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_DETAILED,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_ESTABLISHED,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_STANDARD,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_CEA_SVD,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_CVT_3BYTE,
 | 
				
			||||||
 | 
						TIMING_SOURCE_EDID_4BYTE,
 | 
				
			||||||
 | 
						TIMING_SOURCE_VBIOS,
 | 
				
			||||||
 | 
						TIMING_SOURCE_CV,
 | 
				
			||||||
 | 
						TIMING_SOURCE_TV,
 | 
				
			||||||
 | 
						TIMING_SOURCE_HDMI_VIC,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* implicitly specified by display device, still safe but less important*/
 | 
				
			||||||
 | 
						TIMING_SOURCE_DEFAULT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* only used for custom base modes */
 | 
				
			||||||
 | 
						TIMING_SOURCE_CUSTOM_BASE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* these timing might not work, least important*/
 | 
				
			||||||
 | 
						TIMING_SOURCE_RANGELIMIT,
 | 
				
			||||||
 | 
						TIMING_SOURCE_OS_FORCED,
 | 
				
			||||||
 | 
						TIMING_SOURCE_IMPLICIT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* only used by default mode list*/
 | 
				
			||||||
 | 
						TIMING_SOURCE_BASICMODE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TIMING_SOURCE_COUNT
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_timing_support_method {
 | 
				
			||||||
 | 
						TIMING_SUPPORT_METHOD_UNDEFINED,
 | 
				
			||||||
 | 
						TIMING_SUPPORT_METHOD_EXPLICIT,
 | 
				
			||||||
 | 
						TIMING_SUPPORT_METHOD_IMPLICIT,
 | 
				
			||||||
 | 
						TIMING_SUPPORT_METHOD_NATIVE
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_mode_info {
 | 
				
			||||||
 | 
						uint32_t pixel_width;
 | 
				
			||||||
 | 
						uint32_t pixel_height;
 | 
				
			||||||
 | 
						uint32_t field_rate;
 | 
				
			||||||
 | 
						/* Vertical refresh rate for progressive modes.
 | 
				
			||||||
 | 
						* Field rate for interlaced modes.*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum dc_timing_standard timing_standard;
 | 
				
			||||||
 | 
						enum dc_timing_source timing_source;
 | 
				
			||||||
 | 
						struct dc_mode_flags flags;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_power_state {
 | 
				
			||||||
 | 
						DC_POWER_STATE_ON = 1,
 | 
				
			||||||
 | 
						DC_POWER_STATE_STANDBY,
 | 
				
			||||||
 | 
						DC_POWER_STATE_SUSPEND,
 | 
				
			||||||
 | 
						DC_POWER_STATE_OFF
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DC PowerStates */
 | 
				
			||||||
 | 
					enum dc_video_power_state {
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_UNSPECIFIED = 0,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_ON = 1,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_STANDBY,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_SUSPEND,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_OFF,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_HIBERNATE,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_SHUTDOWN,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_ULPS,	/* BACO or Ultra-Light-Power-State */
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_AFTER_RESET,
 | 
				
			||||||
 | 
						DC_VIDEO_POWER_MAXIMUM
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_acpi_cm_power_state {
 | 
				
			||||||
 | 
						DC_ACPI_CM_POWER_STATE_D0 = 1,
 | 
				
			||||||
 | 
						DC_ACPI_CM_POWER_STATE_D1 = 2,
 | 
				
			||||||
 | 
						DC_ACPI_CM_POWER_STATE_D2 = 4,
 | 
				
			||||||
 | 
						DC_ACPI_CM_POWER_STATE_D3 = 8
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum dc_connection_type {
 | 
				
			||||||
 | 
						dc_connection_none,
 | 
				
			||||||
 | 
						dc_connection_single,
 | 
				
			||||||
 | 
						dc_connection_mst_branch,
 | 
				
			||||||
 | 
						dc_connection_active_dongle
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dc_csc_adjustments {
 | 
				
			||||||
 | 
						struct fixed31_32 contrast;
 | 
				
			||||||
 | 
						struct fixed31_32 saturation;
 | 
				
			||||||
 | 
						struct fixed31_32 brightness;
 | 
				
			||||||
 | 
						struct fixed31_32 hue;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						MAX_LANES = 2,
 | 
				
			||||||
 | 
						MAX_COFUNC_PATH = 6,
 | 
				
			||||||
 | 
						LAYER_INDEX_PRIMARY = -1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Scaling format */
 | 
				
			||||||
 | 
					enum scaling_transformation {
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_UNINITIALIZED,
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_IDENTITY = 0x0001,
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_CENTER_TIMING = 0x0002,
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_FULL_SCREEN_SCALE = 0x0004,
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_PRESERVE_ASPECT_RATIO_SCALE = 0x0008,
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_DAL_DECIDE = 0x0010,
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_INVALID = 0x80000000,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Flag the first and last */
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_BEGING = SCALING_TRANSFORMATION_IDENTITY,
 | 
				
			||||||
 | 
						SCALING_TRANSFORMATION_END =
 | 
				
			||||||
 | 
							SCALING_TRANSFORMATION_PRESERVE_ASPECT_RATIO_SCALE
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* audio*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union audio_sample_rates {
 | 
				
			||||||
 | 
						struct sample_rates {
 | 
				
			||||||
 | 
							uint8_t RATE_32:1;
 | 
				
			||||||
 | 
							uint8_t RATE_44_1:1;
 | 
				
			||||||
 | 
							uint8_t RATE_48:1;
 | 
				
			||||||
 | 
							uint8_t RATE_88_2:1;
 | 
				
			||||||
 | 
							uint8_t RATE_96:1;
 | 
				
			||||||
 | 
							uint8_t RATE_176_4:1;
 | 
				
			||||||
 | 
							uint8_t RATE_192:1;
 | 
				
			||||||
 | 
						} rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t all;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct audio_speaker_flags {
 | 
				
			||||||
 | 
					    uint32_t FL_FR:1;
 | 
				
			||||||
 | 
					    uint32_t LFE:1;
 | 
				
			||||||
 | 
					    uint32_t FC:1;
 | 
				
			||||||
 | 
					    uint32_t RL_RR:1;
 | 
				
			||||||
 | 
					    uint32_t RC:1;
 | 
				
			||||||
 | 
					    uint32_t FLC_FRC:1;
 | 
				
			||||||
 | 
					    uint32_t RLC_RRC:1;
 | 
				
			||||||
 | 
					    uint32_t SUPPORT_AI:1;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct audio_speaker_info {
 | 
				
			||||||
 | 
						uint32_t ALLSPEAKERS:7;
 | 
				
			||||||
 | 
						uint32_t SUPPORT_AI:1;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct audio_info_flags {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct audio_speaker_flags speaker_flags;
 | 
				
			||||||
 | 
							struct audio_speaker_info   info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint8_t all;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum audio_format_code {
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_FIRST = 1,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_LINEARPCM = AUDIO_FORMAT_CODE_FIRST,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_AC3,
 | 
				
			||||||
 | 
						/*Layers 1 & 2 */
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_MPEG1,
 | 
				
			||||||
 | 
						/*MPEG1 Layer 3 */
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_MP3,
 | 
				
			||||||
 | 
						/*multichannel */
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_MPEG2,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_AAC,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_DTS,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_ATRAC,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_1BITAUDIO,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_DTS_HD,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_MAT_MLP,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_DST,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_WMAPRO,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_LAST,
 | 
				
			||||||
 | 
						AUDIO_FORMAT_CODE_COUNT =
 | 
				
			||||||
 | 
							AUDIO_FORMAT_CODE_LAST - AUDIO_FORMAT_CODE_FIRST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct audio_mode {
 | 
				
			||||||
 | 
						 /* ucData[0] [6:3] */
 | 
				
			||||||
 | 
						enum audio_format_code format_code;
 | 
				
			||||||
 | 
						/* ucData[0] [2:0] */
 | 
				
			||||||
 | 
						uint8_t channel_count;
 | 
				
			||||||
 | 
						/* ucData[1] */
 | 
				
			||||||
 | 
						union audio_sample_rates sample_rates;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							/* for LPCM */
 | 
				
			||||||
 | 
							uint8_t sample_size;
 | 
				
			||||||
 | 
							/* for Audio Formats 2-8 (Max bit rate divided by 8 kHz) */
 | 
				
			||||||
 | 
							uint8_t max_bit_rate;
 | 
				
			||||||
 | 
							/* for Audio Formats 9-15 */
 | 
				
			||||||
 | 
							uint8_t vendor_specific;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct audio_info {
 | 
				
			||||||
 | 
						struct audio_info_flags flags;
 | 
				
			||||||
 | 
						uint32_t video_latency;
 | 
				
			||||||
 | 
						uint32_t audio_latency;
 | 
				
			||||||
 | 
						uint32_t display_index;
 | 
				
			||||||
 | 
						uint8_t display_name[AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS];
 | 
				
			||||||
 | 
						uint32_t manufacture_id;
 | 
				
			||||||
 | 
						uint32_t product_id;
 | 
				
			||||||
 | 
						/* PortID used for ContainerID when defined */
 | 
				
			||||||
 | 
						uint32_t port_id[2];
 | 
				
			||||||
 | 
						uint32_t mode_count;
 | 
				
			||||||
 | 
						/* this field must be last in this struct */
 | 
				
			||||||
 | 
						struct audio_mode modes[DC_MAX_AUDIO_DESC_COUNT];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct freesync_context {
 | 
				
			||||||
 | 
						bool supported;
 | 
				
			||||||
 | 
						bool enabled;
 | 
				
			||||||
 | 
						bool active;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int min_refresh_in_micro_hz;
 | 
				
			||||||
 | 
						unsigned int nominal_refresh_in_micro_hz;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct colorspace_transform {
 | 
				
			||||||
 | 
						struct fixed31_32 matrix[12];
 | 
				
			||||||
 | 
						bool enable_remap;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct csc_transform {
 | 
				
			||||||
 | 
						uint16_t matrix[12];
 | 
				
			||||||
 | 
						bool enable_adjustment;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct psr_caps {
 | 
				
			||||||
 | 
						/* These parameters are from PSR capabilities reported by Sink DPCD */
 | 
				
			||||||
 | 
						unsigned char psr_version;
 | 
				
			||||||
 | 
						unsigned int psr_rfb_setup_time;
 | 
				
			||||||
 | 
						bool psr_exit_link_training_required;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* These parameters are calculated in Driver,
 | 
				
			||||||
 | 
						 * based on display timing and Sink capabilities.
 | 
				
			||||||
 | 
						 * If VBLANK region is too small and Sink takes a long time
 | 
				
			||||||
 | 
						 * to set up RFB, it may take an extra frame to enter PSR state.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						bool psr_frame_capture_indication_req;
 | 
				
			||||||
 | 
						unsigned int psr_sdp_transmit_line_num_deadline;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DC_TYPES_H_ */
 | 
				
			||||||
							
								
								
									
										14
									
								
								drivers/gpu/drm/amd/display/dc/dce/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								drivers/gpu/drm/amd/display/dc/dce/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for common 'dce' logic
 | 
				
			||||||
 | 
					# HW object file under this folder follow similar pattern for HW programming
 | 
				
			||||||
 | 
					#   - register offset and/or shift + mask stored in the dec_hw struct
 | 
				
			||||||
 | 
					#   - register programming through common macros that look up register 
 | 
				
			||||||
 | 
					#     offset/shift/mask stored in dce_hw struct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
 | 
				
			||||||
 | 
					dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DAL_DCE)
 | 
				
			||||||
							
								
								
									
										920
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										920
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,920 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "reg_helper.h"
 | 
				
			||||||
 | 
					#include "dce_audio.h"
 | 
				
			||||||
 | 
					#include "dce/dce_11_0_d.h"
 | 
				
			||||||
 | 
					#include "dce/dce_11_0_sh_mask.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DCE_AUD(audio)\
 | 
				
			||||||
 | 
						container_of(audio, struct dce_audio, base)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CTX \
 | 
				
			||||||
 | 
						aud->base.ctx
 | 
				
			||||||
 | 
					#define REG(reg)\
 | 
				
			||||||
 | 
						(aud->regs->reg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef FN
 | 
				
			||||||
 | 
					#define FN(reg_name, field_name) \
 | 
				
			||||||
 | 
						aud->shifts->field_name, aud->masks->field_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IX_REG(reg)\
 | 
				
			||||||
 | 
						ix ## reg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AZ_REG_READ(reg_name) \
 | 
				
			||||||
 | 
							read_indirect_azalia_reg(audio, IX_REG(reg_name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AZ_REG_WRITE(reg_name, value) \
 | 
				
			||||||
 | 
							write_indirect_azalia_reg(audio, IX_REG(reg_name), value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void write_indirect_azalia_reg(struct audio *audio,
 | 
				
			||||||
 | 
						uint32_t reg_index,
 | 
				
			||||||
 | 
						uint32_t reg_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dce_audio *aud = DCE_AUD(audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* AZALIA_F0_CODEC_ENDPOINT_INDEX  endpoint index  */
 | 
				
			||||||
 | 
						REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
 | 
				
			||||||
 | 
								AZALIA_ENDPOINT_REG_INDEX, reg_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
 | 
				
			||||||
 | 
						REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0,
 | 
				
			||||||
 | 
								AZALIA_ENDPOINT_REG_DATA, reg_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_logger_write(CTX->logger, LOG_HW_AUDIO,
 | 
				
			||||||
 | 
							"AUDIO:write_indirect_azalia_reg: index: %u  data: %u\n",
 | 
				
			||||||
 | 
							reg_index, reg_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dce_audio *aud = DCE_AUD(audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* AZALIA_F0_CODEC_ENDPOINT_INDEX  endpoint index  */
 | 
				
			||||||
 | 
						REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
 | 
				
			||||||
 | 
								AZALIA_ENDPOINT_REG_INDEX, reg_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
 | 
				
			||||||
 | 
						value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dm_logger_write(CTX->logger, LOG_HW_AUDIO,
 | 
				
			||||||
 | 
							"AUDIO:read_indirect_azalia_reg: index: %u  data: %u\n",
 | 
				
			||||||
 | 
							reg_index, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool is_audio_format_supported(
 | 
				
			||||||
 | 
						const struct audio_info *audio_info,
 | 
				
			||||||
 | 
						enum audio_format_code audio_format_code,
 | 
				
			||||||
 | 
						uint32_t *format_index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t index;
 | 
				
			||||||
 | 
						uint32_t max_channe_index = 0;
 | 
				
			||||||
 | 
						bool found = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (audio_info == NULL)
 | 
				
			||||||
 | 
							return found;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* pass through whole array */
 | 
				
			||||||
 | 
						for (index = 0; index < audio_info->mode_count; index++) {
 | 
				
			||||||
 | 
							if (audio_info->modes[index].format_code == audio_format_code) {
 | 
				
			||||||
 | 
								if (found) {
 | 
				
			||||||
 | 
									/* format has multiply entries, choose one with
 | 
				
			||||||
 | 
									 *  highst number of channels */
 | 
				
			||||||
 | 
									if (audio_info->modes[index].channel_count >
 | 
				
			||||||
 | 
							audio_info->modes[max_channe_index].channel_count) {
 | 
				
			||||||
 | 
										max_channe_index = index;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									/* format found, save it's index */
 | 
				
			||||||
 | 
									found = true;
 | 
				
			||||||
 | 
									max_channe_index = index;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* return index */
 | 
				
			||||||
 | 
						if (found && format_index != NULL)
 | 
				
			||||||
 | 
							*format_index = max_channe_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return found;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*For HDMI, calculate if specified sample rates can fit into a given timing */
 | 
				
			||||||
 | 
					static void check_audio_bandwidth_hdmi(
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						uint32_t channel_count,
 | 
				
			||||||
 | 
						union audio_sample_rates *sample_rates)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t samples;
 | 
				
			||||||
 | 
						uint32_t  h_blank;
 | 
				
			||||||
 | 
						bool limit_freq_to_48_khz = false;
 | 
				
			||||||
 | 
						bool limit_freq_to_88_2_khz = false;
 | 
				
			||||||
 | 
						bool limit_freq_to_96_khz = false;
 | 
				
			||||||
 | 
						bool limit_freq_to_174_4_khz = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* For two channels supported return whatever sink support,unmodified*/
 | 
				
			||||||
 | 
						if (channel_count > 2) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Based on HDMI spec 1.3 Table 7.5 */
 | 
				
			||||||
 | 
							if ((crtc_info->requested_pixel_clock <= 27000) &&
 | 
				
			||||||
 | 
							(crtc_info->v_active <= 576) &&
 | 
				
			||||||
 | 
							!(crtc_info->interlaced) &&
 | 
				
			||||||
 | 
							!(crtc_info->pixel_repetition == 2 ||
 | 
				
			||||||
 | 
							crtc_info->pixel_repetition == 4)) {
 | 
				
			||||||
 | 
								limit_freq_to_48_khz = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							} else if ((crtc_info->requested_pixel_clock <= 27000) &&
 | 
				
			||||||
 | 
									(crtc_info->v_active <= 576) &&
 | 
				
			||||||
 | 
									(crtc_info->interlaced) &&
 | 
				
			||||||
 | 
									(crtc_info->pixel_repetition == 2)) {
 | 
				
			||||||
 | 
								limit_freq_to_88_2_khz = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							} else if ((crtc_info->requested_pixel_clock <= 54000) &&
 | 
				
			||||||
 | 
									(crtc_info->v_active <= 576) &&
 | 
				
			||||||
 | 
									!(crtc_info->interlaced)) {
 | 
				
			||||||
 | 
								limit_freq_to_174_4_khz = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Also do some calculation for the available Audio Bandwidth for the
 | 
				
			||||||
 | 
						 * 8 ch (i.e. for the Layout 1 => ch > 2)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						h_blank = crtc_info->h_total - crtc_info->h_active;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (crtc_info->pixel_repetition)
 | 
				
			||||||
 | 
							h_blank *= crtc_info->pixel_repetition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*based on HDMI spec 1.3 Table 7.5 */
 | 
				
			||||||
 | 
						h_blank -= 58;
 | 
				
			||||||
 | 
						/*for Control Period */
 | 
				
			||||||
 | 
						h_blank -= 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						samples = h_blank * 10;
 | 
				
			||||||
 | 
						/* Number of Audio Packets (multiplied by 10) per Line (for 8 ch number
 | 
				
			||||||
 | 
						 * of Audio samples per line multiplied by 10 - Layout 1)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						 samples /= 32;
 | 
				
			||||||
 | 
						 samples *= crtc_info->v_active;
 | 
				
			||||||
 | 
						 /*Number of samples multiplied by 10, per second */
 | 
				
			||||||
 | 
						 samples *= crtc_info->refresh_rate;
 | 
				
			||||||
 | 
						 /*Number of Audio samples per second */
 | 
				
			||||||
 | 
						 samples /= 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						 /* @todo do it after deep color is implemented
 | 
				
			||||||
 | 
						  * 8xx - deep color bandwidth scaling
 | 
				
			||||||
 | 
						  * Extra bandwidth is avaliable in deep color b/c link runs faster than
 | 
				
			||||||
 | 
						  * pixel rate. This has the effect of allowing more tmds characters to
 | 
				
			||||||
 | 
						  * be transmitted during blank
 | 
				
			||||||
 | 
						  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (crtc_info->color_depth) {
 | 
				
			||||||
 | 
						case COLOR_DEPTH_888:
 | 
				
			||||||
 | 
							samples *= 4;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case COLOR_DEPTH_101010:
 | 
				
			||||||
 | 
							samples *= 5;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case COLOR_DEPTH_121212:
 | 
				
			||||||
 | 
							samples *= 6;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							samples *= 4;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						samples /= 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*check limitation*/
 | 
				
			||||||
 | 
						if (samples < 88200)
 | 
				
			||||||
 | 
							limit_freq_to_48_khz = true;
 | 
				
			||||||
 | 
						else if (samples < 96000)
 | 
				
			||||||
 | 
							limit_freq_to_88_2_khz = true;
 | 
				
			||||||
 | 
						else if (samples < 176400)
 | 
				
			||||||
 | 
							limit_freq_to_96_khz = true;
 | 
				
			||||||
 | 
						else if (samples < 192000)
 | 
				
			||||||
 | 
							limit_freq_to_174_4_khz = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sample_rates != NULL) {
 | 
				
			||||||
 | 
							/* limit frequencies */
 | 
				
			||||||
 | 
							if (limit_freq_to_174_4_khz)
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_192 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (limit_freq_to_96_khz) {
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_192 = 0;
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_176_4 = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (limit_freq_to_88_2_khz) {
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_192 = 0;
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_176_4 = 0;
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_96 = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (limit_freq_to_48_khz) {
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_192 = 0;
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_176_4 = 0;
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_96 = 0;
 | 
				
			||||||
 | 
								sample_rates->rate.RATE_88_2 = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*For DP SST, calculate if specified sample rates can fit into a given timing */
 | 
				
			||||||
 | 
					static void check_audio_bandwidth_dpsst(
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						uint32_t channel_count,
 | 
				
			||||||
 | 
						union audio_sample_rates *sample_rates)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* do nothing */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*For DP MST, calculate if specified sample rates can fit into a given timing */
 | 
				
			||||||
 | 
					static void check_audio_bandwidth_dpmst(
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						uint32_t channel_count,
 | 
				
			||||||
 | 
						union audio_sample_rates *sample_rates)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* do nothing  */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void check_audio_bandwidth(
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						uint32_t channel_count,
 | 
				
			||||||
 | 
						enum signal_type signal,
 | 
				
			||||||
 | 
						union audio_sample_rates *sample_rates)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_HDMI_TYPE_A:
 | 
				
			||||||
 | 
							check_audio_bandwidth_hdmi(
 | 
				
			||||||
 | 
								crtc_info, channel_count, sample_rates);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_EDP:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT:
 | 
				
			||||||
 | 
							check_audio_bandwidth_dpsst(
 | 
				
			||||||
 | 
								crtc_info, channel_count, sample_rates);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT_MST:
 | 
				
			||||||
 | 
							check_audio_bandwidth_dpmst(
 | 
				
			||||||
 | 
								crtc_info, channel_count, sample_rates);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* expose/not expose HBR capability to Audio driver */
 | 
				
			||||||
 | 
					static void set_high_bit_rate_capable(
 | 
				
			||||||
 | 
						struct audio *audio,
 | 
				
			||||||
 | 
						bool capable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* set high bit rate audio capable*/
 | 
				
			||||||
 | 
						value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, capable,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,
 | 
				
			||||||
 | 
							HBR_CAPABLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* set video latency in in ms/2+1 */
 | 
				
			||||||
 | 
					static void set_video_latency(
 | 
				
			||||||
 | 
						struct audio *audio,
 | 
				
			||||||
 | 
						int latency_in_ms)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((latency_in_ms < 0) || (latency_in_ms > 255))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, latency_in_ms,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
 | 
				
			||||||
 | 
							VIDEO_LIPSYNC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
 | 
				
			||||||
 | 
							value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* set audio latency in in ms/2+1 */
 | 
				
			||||||
 | 
					static void set_audio_latency(
 | 
				
			||||||
 | 
						struct audio *audio,
 | 
				
			||||||
 | 
						int latency_in_ms)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (latency_in_ms < 0)
 | 
				
			||||||
 | 
							latency_in_ms = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (latency_in_ms > 255)
 | 
				
			||||||
 | 
							latency_in_ms = 255;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, latency_in_ms,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
 | 
				
			||||||
 | 
							AUDIO_LIPSYNC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
 | 
				
			||||||
 | 
							value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_az_enable(struct audio *audio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (get_reg_field_value(value,
 | 
				
			||||||
 | 
								AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 | 
				
			||||||
 | 
								AUDIO_ENABLED) != 1)
 | 
				
			||||||
 | 
							set_reg_field_value(value, 1,
 | 
				
			||||||
 | 
								AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 | 
				
			||||||
 | 
								AUDIO_ENABLED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_az_disable(struct audio *audio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, 0,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 | 
				
			||||||
 | 
							AUDIO_ENABLED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_az_configure(
 | 
				
			||||||
 | 
						struct audio *audio,
 | 
				
			||||||
 | 
						enum signal_type signal,
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						const struct audio_info *audio_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dce_audio *aud = DCE_AUD(audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t speakers = audio_info->flags.info.ALLSPEAKERS;
 | 
				
			||||||
 | 
						uint32_t value;
 | 
				
			||||||
 | 
						uint32_t field = 0;
 | 
				
			||||||
 | 
						enum audio_format_code audio_format_code;
 | 
				
			||||||
 | 
						uint32_t format_index;
 | 
				
			||||||
 | 
						uint32_t index;
 | 
				
			||||||
 | 
						bool is_ac3_supported = false;
 | 
				
			||||||
 | 
						union audio_sample_rates sample_rate;
 | 
				
			||||||
 | 
						uint32_t strlen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Speaker Allocation */
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						uint32_t value;
 | 
				
			||||||
 | 
						uint32_t field = 0;*/
 | 
				
			||||||
 | 
						value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value,
 | 
				
			||||||
 | 
							speakers,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
							SPEAKER_ALLOCATION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* LFE_PLAYBACK_LEVEL = LFEPBL
 | 
				
			||||||
 | 
						 * LFEPBL = 0 : Unknown or refer to other information
 | 
				
			||||||
 | 
						 * LFEPBL = 1 : 0dB playback
 | 
				
			||||||
 | 
						 * LFEPBL = 2 : +10dB playback
 | 
				
			||||||
 | 
						 * LFE_BL = 3 : Reserved
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						set_reg_field_value(value,
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
							LFE_PLAYBACK_LEVEL);
 | 
				
			||||||
 | 
						/* todo: according to reg spec LFE_PLAYBACK_LEVEL is read only.
 | 
				
			||||||
 | 
						 *  why are we writing to it?  DCE8 does not write this */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value,
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
							HDMI_CONNECTION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value,
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
							DP_CONNECTION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						field = get_reg_field_value(value,
 | 
				
			||||||
 | 
								AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
								EXTRA_CONNECTION_INFO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						field &= ~0x1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value,
 | 
				
			||||||
 | 
							field,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
							EXTRA_CONNECTION_INFO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* set audio for output signal */
 | 
				
			||||||
 | 
						switch (signal) {
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_HDMI_TYPE_A:
 | 
				
			||||||
 | 
							set_reg_field_value(value,
 | 
				
			||||||
 | 
								1,
 | 
				
			||||||
 | 
								AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
								HDMI_CONNECTION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_EDP:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT:
 | 
				
			||||||
 | 
						case SIGNAL_TYPE_DISPLAY_PORT_MST:
 | 
				
			||||||
 | 
							set_reg_field_value(value,
 | 
				
			||||||
 | 
								1,
 | 
				
			||||||
 | 
								AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
 | 
				
			||||||
 | 
								DP_CONNECTION);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							BREAK_TO_DEBUGGER();
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*  Audio Descriptors   */
 | 
				
			||||||
 | 
						/* pass through all formats */
 | 
				
			||||||
 | 
						for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
 | 
				
			||||||
 | 
								format_index++) {
 | 
				
			||||||
 | 
							audio_format_code =
 | 
				
			||||||
 | 
								(AUDIO_FORMAT_CODE_FIRST + format_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* those are unsupported, skip programming */
 | 
				
			||||||
 | 
							if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
 | 
				
			||||||
 | 
								audio_format_code == AUDIO_FORMAT_CODE_DST)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* check if supported */
 | 
				
			||||||
 | 
							if (is_audio_format_supported(
 | 
				
			||||||
 | 
									audio_info, audio_format_code, &index)) {
 | 
				
			||||||
 | 
								const struct audio_mode *audio_mode =
 | 
				
			||||||
 | 
										&audio_info->modes[index];
 | 
				
			||||||
 | 
								union audio_sample_rates sample_rates =
 | 
				
			||||||
 | 
										audio_mode->sample_rates;
 | 
				
			||||||
 | 
								uint8_t byte2 = audio_mode->max_bit_rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* adjust specific properties */
 | 
				
			||||||
 | 
								switch (audio_format_code) {
 | 
				
			||||||
 | 
								case AUDIO_FORMAT_CODE_LINEARPCM: {
 | 
				
			||||||
 | 
									check_audio_bandwidth(
 | 
				
			||||||
 | 
										crtc_info,
 | 
				
			||||||
 | 
										audio_mode->channel_count,
 | 
				
			||||||
 | 
										signal,
 | 
				
			||||||
 | 
										&sample_rates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									byte2 = audio_mode->sample_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									set_reg_field_value(value,
 | 
				
			||||||
 | 
											sample_rates.all,
 | 
				
			||||||
 | 
											AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
 | 
				
			||||||
 | 
											SUPPORTED_FREQUENCIES_STEREO);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case AUDIO_FORMAT_CODE_AC3:
 | 
				
			||||||
 | 
									is_ac3_supported = true;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
 | 
				
			||||||
 | 
								case AUDIO_FORMAT_CODE_DTS_HD:
 | 
				
			||||||
 | 
								case AUDIO_FORMAT_CODE_MAT_MLP:
 | 
				
			||||||
 | 
								case AUDIO_FORMAT_CODE_DST:
 | 
				
			||||||
 | 
								case AUDIO_FORMAT_CODE_WMAPRO:
 | 
				
			||||||
 | 
									byte2 = audio_mode->vendor_specific;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* fill audio format data */
 | 
				
			||||||
 | 
								set_reg_field_value(value,
 | 
				
			||||||
 | 
										audio_mode->channel_count - 1,
 | 
				
			||||||
 | 
										AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
 | 
				
			||||||
 | 
										MAX_CHANNELS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								set_reg_field_value(value,
 | 
				
			||||||
 | 
										sample_rates.all,
 | 
				
			||||||
 | 
										AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
 | 
				
			||||||
 | 
										SUPPORTED_FREQUENCIES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								set_reg_field_value(value,
 | 
				
			||||||
 | 
										byte2,
 | 
				
			||||||
 | 
										AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
 | 
				
			||||||
 | 
										DESCRIPTOR_BYTE_2);
 | 
				
			||||||
 | 
							} /* if */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							AZ_REG_WRITE(
 | 
				
			||||||
 | 
									AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 + format_index,
 | 
				
			||||||
 | 
									value);
 | 
				
			||||||
 | 
						} /* for */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (is_ac3_supported)
 | 
				
			||||||
 | 
							/* todo: this reg global.  why program global register? */
 | 
				
			||||||
 | 
							REG_WRITE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS,
 | 
				
			||||||
 | 
									0x05);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* check for 192khz/8-Ch support for HBR requirements */
 | 
				
			||||||
 | 
						sample_rate.all = 0;
 | 
				
			||||||
 | 
						sample_rate.rate.RATE_192 = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check_audio_bandwidth(
 | 
				
			||||||
 | 
							crtc_info,
 | 
				
			||||||
 | 
							8,
 | 
				
			||||||
 | 
							signal,
 | 
				
			||||||
 | 
							&sample_rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_high_bit_rate_capable(audio, sample_rate.rate.RATE_192);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Audio and Video Lipsync */
 | 
				
			||||||
 | 
						set_video_latency(audio, audio_info->video_latency);
 | 
				
			||||||
 | 
						set_audio_latency(audio, audio_info->audio_latency);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->manufacture_id,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
 | 
				
			||||||
 | 
							MANUFACTURER_ID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->product_id,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
 | 
				
			||||||
 | 
							PRODUCT_ID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
 | 
				
			||||||
 | 
							value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*get display name string length */
 | 
				
			||||||
 | 
						while (audio_info->display_name[strlen++] != '\0') {
 | 
				
			||||||
 | 
							if (strlen >=
 | 
				
			||||||
 | 
							MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						set_reg_field_value(value, strlen,
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
 | 
				
			||||||
 | 
							SINK_DESCRIPTION_LEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
 | 
				
			||||||
 | 
							value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						*write the port ID:
 | 
				
			||||||
 | 
						*PORT_ID0 = display index
 | 
				
			||||||
 | 
						*PORT_ID1 = 16bit BDF
 | 
				
			||||||
 | 
						*(format MSB->LSB: 8bit Bus, 5bit Device, 3bit Function)
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->port_id[0],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,
 | 
				
			||||||
 | 
							PORT_ID0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->port_id[1],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,
 | 
				
			||||||
 | 
							PORT_ID1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*write the 18 char monitor string */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[0],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
 | 
				
			||||||
 | 
							DESCRIPTION0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[1],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
 | 
				
			||||||
 | 
							DESCRIPTION1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[2],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
 | 
				
			||||||
 | 
							DESCRIPTION2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[3],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
 | 
				
			||||||
 | 
							DESCRIPTION3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[4],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
 | 
				
			||||||
 | 
							DESCRIPTION4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[5],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
 | 
				
			||||||
 | 
							DESCRIPTION5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[6],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
 | 
				
			||||||
 | 
							DESCRIPTION6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[7],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
 | 
				
			||||||
 | 
							DESCRIPTION7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[8],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
 | 
				
			||||||
 | 
							DESCRIPTION8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[9],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
 | 
				
			||||||
 | 
							DESCRIPTION9);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[10],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
 | 
				
			||||||
 | 
							DESCRIPTION10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[11],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
 | 
				
			||||||
 | 
							DESCRIPTION11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[12],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
 | 
				
			||||||
 | 
							DESCRIPTION12);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[13],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
 | 
				
			||||||
 | 
							DESCRIPTION13);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[14],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
 | 
				
			||||||
 | 
							DESCRIPTION14);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[15],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
 | 
				
			||||||
 | 
							DESCRIPTION15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = 0;
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[16],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
 | 
				
			||||||
 | 
							DESCRIPTION16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set_reg_field_value(value, audio_info->display_name[17],
 | 
				
			||||||
 | 
							AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
 | 
				
			||||||
 | 
							DESCRIPTION17);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* todo: wall clk related functionality probably belong to clock_src.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* search pixel clock value for Azalia HDMI Audio */
 | 
				
			||||||
 | 
					static bool get_azalia_clock_info_hdmi(
 | 
				
			||||||
 | 
						uint32_t crtc_pixel_clock_in_khz,
 | 
				
			||||||
 | 
						uint32_t actual_pixel_clock_in_khz,
 | 
				
			||||||
 | 
						struct azalia_clock_info *azalia_clock_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (azalia_clock_info == NULL)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* audio_dto_phase= 24 * 10,000;
 | 
				
			||||||
 | 
						 *   24MHz in [100Hz] units */
 | 
				
			||||||
 | 
						azalia_clock_info->audio_dto_phase =
 | 
				
			||||||
 | 
								24 * 10000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* audio_dto_module = PCLKFrequency * 10,000;
 | 
				
			||||||
 | 
						 *  [khz] -> [100Hz] */
 | 
				
			||||||
 | 
						azalia_clock_info->audio_dto_module =
 | 
				
			||||||
 | 
								actual_pixel_clock_in_khz * 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool get_azalia_clock_info_dp(
 | 
				
			||||||
 | 
						uint32_t requested_pixel_clock_in_khz,
 | 
				
			||||||
 | 
						const struct audio_pll_info *pll_info,
 | 
				
			||||||
 | 
						struct azalia_clock_info *azalia_clock_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (pll_info == NULL || azalia_clock_info == NULL)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Reported dpDtoSourceClockInkhz value for
 | 
				
			||||||
 | 
						 * DCE8 already adjusted for SS, do not need any
 | 
				
			||||||
 | 
						 * adjustment here anymore
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*audio_dto_phase = 24 * 10,000;
 | 
				
			||||||
 | 
						 * 24MHz in [100Hz] units */
 | 
				
			||||||
 | 
						azalia_clock_info->audio_dto_phase = 24 * 10000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
 | 
				
			||||||
 | 
						 *  [khz] ->[100Hz] */
 | 
				
			||||||
 | 
						azalia_clock_info->audio_dto_module =
 | 
				
			||||||
 | 
							pll_info->dp_dto_source_clock_in_khz * 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_wall_dto_setup(
 | 
				
			||||||
 | 
						struct audio *audio,
 | 
				
			||||||
 | 
						enum signal_type signal,
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						const struct audio_pll_info *pll_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dce_audio *aud = DCE_AUD(audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct azalia_clock_info clock_info = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dc_is_hdmi_signal(signal)) {
 | 
				
			||||||
 | 
							uint32_t src_sel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*DTO0 Programming goal:
 | 
				
			||||||
 | 
							-generate 24MHz, 128*Fs from 24MHz
 | 
				
			||||||
 | 
							-use DTO0 when an active HDMI port is connected
 | 
				
			||||||
 | 
							(optionally a DP is connected) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* calculate DTO settings */
 | 
				
			||||||
 | 
							get_azalia_clock_info_hdmi(
 | 
				
			||||||
 | 
								crtc_info->requested_pixel_clock,
 | 
				
			||||||
 | 
								crtc_info->calculated_pixel_clock,
 | 
				
			||||||
 | 
								&clock_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* On TN/SI, Program DTO source select and DTO select before
 | 
				
			||||||
 | 
							programming DTO modulo and DTO phase. These bits must be
 | 
				
			||||||
 | 
							programmed first, otherwise there will be no HDMI audio at boot
 | 
				
			||||||
 | 
							up. This is a HW sequence change (different from old ASICs).
 | 
				
			||||||
 | 
							Caution when changing this programming sequence.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							HDMI enabled, using DTO0
 | 
				
			||||||
 | 
							program master CRTC for DTO0 */
 | 
				
			||||||
 | 
							src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
 | 
				
			||||||
 | 
							REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
 | 
				
			||||||
 | 
								DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
 | 
				
			||||||
 | 
								DCCG_AUDIO_DTO_SEL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* module */
 | 
				
			||||||
 | 
							REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
 | 
				
			||||||
 | 
								DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* phase */
 | 
				
			||||||
 | 
							REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
 | 
				
			||||||
 | 
								DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							/*DTO1 Programming goal:
 | 
				
			||||||
 | 
							-generate 24MHz, 512*Fs, 128*Fs from 24MHz
 | 
				
			||||||
 | 
							-default is to used DTO1, and switch to DTO0 when an audio
 | 
				
			||||||
 | 
							master HDMI port is connected
 | 
				
			||||||
 | 
							-use as default for DP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							calculate DTO settings */
 | 
				
			||||||
 | 
							get_azalia_clock_info_dp(
 | 
				
			||||||
 | 
								crtc_info->requested_pixel_clock,
 | 
				
			||||||
 | 
								pll_info,
 | 
				
			||||||
 | 
								&clock_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Program DTO select before programming DTO modulo and DTO
 | 
				
			||||||
 | 
							phase. default to use DTO1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
 | 
				
			||||||
 | 
									DCCG_AUDIO_DTO_SEL, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
 | 
				
			||||||
 | 
								DCCG_AUDIO_DTO_SEL, 1);
 | 
				
			||||||
 | 
								/* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
 | 
				
			||||||
 | 
								 * Select 512fs for DP TODO: web register definition
 | 
				
			||||||
 | 
								 * does not match register header file
 | 
				
			||||||
 | 
								 * DCE11 version it's commented out while DCE8 it's set to 1
 | 
				
			||||||
 | 
								*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* module */
 | 
				
			||||||
 | 
							REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
 | 
				
			||||||
 | 
									DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* phase */
 | 
				
			||||||
 | 
							REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
 | 
				
			||||||
 | 
									DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* DAL2 code separate DCCG_AUDIO_DTO_SEL and
 | 
				
			||||||
 | 
							DCCG_AUDIO_DTO2_USE_512FBR_DTO programming into two different
 | 
				
			||||||
 | 
							location. merge together should not hurt */
 | 
				
			||||||
 | 
							/*value.bits.DCCG_AUDIO_DTO2_USE_512FBR_DTO = 1;
 | 
				
			||||||
 | 
							dal_write_reg(mmDCCG_AUDIO_DTO_SOURCE, value);*/
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce_aud_endpoint_valid(
 | 
				
			||||||
 | 
							struct audio *audio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t value;
 | 
				
			||||||
 | 
						uint32_t port_connectivity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = AZ_REG_READ(
 | 
				
			||||||
 | 
								AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port_connectivity = get_reg_field_value(value,
 | 
				
			||||||
 | 
								AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT,
 | 
				
			||||||
 | 
								PORT_CONNECTIVITY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return !(port_connectivity == 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* initialize HW state */
 | 
				
			||||||
 | 
					void dce_aud_hw_init(
 | 
				
			||||||
 | 
							struct audio *audio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dce_audio *aud = DCE_AUD(audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* we only need to program the following registers once, so we only do
 | 
				
			||||||
 | 
						it for the inst 0*/
 | 
				
			||||||
 | 
						if (audio->inst != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Suport R5 - 32khz
 | 
				
			||||||
 | 
						 * Suport R6 - 44.1khz
 | 
				
			||||||
 | 
						 * Suport R7 - 48khz
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
 | 
				
			||||||
 | 
								AUDIO_RATE_CAPABILITIES, 0x70);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*Keep alive bit to verify HW block in BU. */
 | 
				
			||||||
 | 
						REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
 | 
				
			||||||
 | 
								CLKSTOP, 1,
 | 
				
			||||||
 | 
								EPSS, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct audio_funcs funcs = {
 | 
				
			||||||
 | 
						.endpoint_valid = dce_aud_endpoint_valid,
 | 
				
			||||||
 | 
						.hw_init = dce_aud_hw_init,
 | 
				
			||||||
 | 
						.wall_dto_setup = dce_aud_wall_dto_setup,
 | 
				
			||||||
 | 
						.az_enable = dce_aud_az_enable,
 | 
				
			||||||
 | 
						.az_disable = dce_aud_az_disable,
 | 
				
			||||||
 | 
						.az_configure = dce_aud_az_configure,
 | 
				
			||||||
 | 
						.destroy = dce_aud_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_destroy(struct audio **audio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dm_free(*audio);
 | 
				
			||||||
 | 
						*audio = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct audio *dce_audio_create(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							unsigned int inst,
 | 
				
			||||||
 | 
							const struct dce_audio_registers *reg,
 | 
				
			||||||
 | 
							const struct dce_audio_shift *shifts,
 | 
				
			||||||
 | 
							const struct dce_aduio_mask *masks
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct dce_audio *audio = dm_alloc(sizeof(*audio));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (audio == NULL) {
 | 
				
			||||||
 | 
							ASSERT_CRITICAL(audio);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						audio->base.ctx = ctx;
 | 
				
			||||||
 | 
						audio->base.inst = inst;
 | 
				
			||||||
 | 
						audio->base.funcs = &funcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						audio->regs = reg;
 | 
				
			||||||
 | 
						audio->shifts = shifts;
 | 
				
			||||||
 | 
						audio->masks = masks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &audio->base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										145
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,145 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef __DAL_AUDIO_DCE_110_H__
 | 
				
			||||||
 | 
					#define __DAL_AUDIO_DCE_110_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "audio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AUD_COMMON_REG_LIST(id)\
 | 
				
			||||||
 | 
						SRI(AZALIA_F0_CODEC_ENDPOINT_INDEX, AZF0ENDPOINT, id),\
 | 
				
			||||||
 | 
						SRI(AZALIA_F0_CODEC_ENDPOINT_DATA, AZF0ENDPOINT, id),\
 | 
				
			||||||
 | 
						SR(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS),\
 | 
				
			||||||
 | 
						SR(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES),\
 | 
				
			||||||
 | 
						SR(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES),\
 | 
				
			||||||
 | 
						SR(DCCG_AUDIO_DTO_SOURCE),\
 | 
				
			||||||
 | 
						SR(DCCG_AUDIO_DTO0_MODULE),\
 | 
				
			||||||
 | 
						SR(DCCG_AUDIO_DTO0_PHASE),\
 | 
				
			||||||
 | 
						SR(DCCG_AUDIO_DTO1_MODULE),\
 | 
				
			||||||
 | 
						SR(DCCG_AUDIO_DTO1_PHASE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 /* set field name */
 | 
				
			||||||
 | 
					#define SF(reg_name, field_name, post_fix)\
 | 
				
			||||||
 | 
						.field_name = reg_name ## __ ## field_name ## post_fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AUD_COMMON_MASK_SH_LIST_BASE(mask_sh)\
 | 
				
			||||||
 | 
							SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
 | 
				
			||||||
 | 
							SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
 | 
				
			||||||
 | 
							SF(DCCG_AUDIO_DTO0_MODULE, DCCG_AUDIO_DTO0_MODULE, mask_sh),\
 | 
				
			||||||
 | 
							SF(DCCG_AUDIO_DTO0_PHASE, DCCG_AUDIO_DTO0_PHASE, mask_sh),\
 | 
				
			||||||
 | 
							SF(DCCG_AUDIO_DTO0_MODULE, DCCG_AUDIO_DTO0_MODULE, mask_sh),\
 | 
				
			||||||
 | 
							SF(DCCG_AUDIO_DTO0_PHASE, DCCG_AUDIO_DTO0_PHASE, mask_sh),\
 | 
				
			||||||
 | 
							SF(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES, AUDIO_RATE_CAPABILITIES, mask_sh),\
 | 
				
			||||||
 | 
							SF(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, CLKSTOP, mask_sh),\
 | 
				
			||||||
 | 
							SF(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, EPSS, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AUD_COMMON_MASK_SH_LIST(mask_sh)\
 | 
				
			||||||
 | 
							AUD_COMMON_MASK_SH_LIST_BASE(mask_sh),\
 | 
				
			||||||
 | 
							SF(AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
 | 
				
			||||||
 | 
							SF(AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_audio_registers {
 | 
				
			||||||
 | 
						uint32_t AZALIA_F0_CODEC_ENDPOINT_INDEX;
 | 
				
			||||||
 | 
						uint32_t AZALIA_F0_CODEC_ENDPOINT_DATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS;
 | 
				
			||||||
 | 
						uint32_t AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES;
 | 
				
			||||||
 | 
						uint32_t AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO_SOURCE;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO0_MODULE;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO0_PHASE;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO1_MODULE;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO1_PHASE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t AUDIO_RATE_CAPABILITIES;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_audio_shift {
 | 
				
			||||||
 | 
						uint8_t AZALIA_ENDPOINT_REG_INDEX;
 | 
				
			||||||
 | 
						uint8_t AZALIA_ENDPOINT_REG_DATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t AUDIO_RATE_CAPABILITIES;
 | 
				
			||||||
 | 
						uint8_t CLKSTOP;
 | 
				
			||||||
 | 
						uint8_t EPSS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t DCCG_AUDIO_DTO0_SOURCE_SEL;
 | 
				
			||||||
 | 
						uint8_t DCCG_AUDIO_DTO_SEL;
 | 
				
			||||||
 | 
						uint8_t DCCG_AUDIO_DTO0_MODULE;
 | 
				
			||||||
 | 
						uint8_t DCCG_AUDIO_DTO0_PHASE;
 | 
				
			||||||
 | 
						uint8_t DCCG_AUDIO_DTO1_MODULE;
 | 
				
			||||||
 | 
						uint8_t DCCG_AUDIO_DTO1_PHASE;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_aduio_mask {
 | 
				
			||||||
 | 
						uint32_t AZALIA_ENDPOINT_REG_INDEX;
 | 
				
			||||||
 | 
						uint32_t AZALIA_ENDPOINT_REG_DATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t AUDIO_RATE_CAPABILITIES;
 | 
				
			||||||
 | 
						uint32_t CLKSTOP;
 | 
				
			||||||
 | 
						uint32_t EPSS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO0_SOURCE_SEL;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO_SEL;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO0_MODULE;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO0_PHASE;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO1_MODULE;
 | 
				
			||||||
 | 
						uint32_t DCCG_AUDIO_DTO1_PHASE;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_audio {
 | 
				
			||||||
 | 
						struct audio base;
 | 
				
			||||||
 | 
						const struct dce_audio_registers *regs;
 | 
				
			||||||
 | 
						const struct dce_audio_shift *shifts;
 | 
				
			||||||
 | 
						const struct dce_aduio_mask *masks;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct audio *dce_audio_create(
 | 
				
			||||||
 | 
							struct dc_context *ctx,
 | 
				
			||||||
 | 
							unsigned int inst,
 | 
				
			||||||
 | 
							const struct dce_audio_registers *reg,
 | 
				
			||||||
 | 
							const struct dce_audio_shift *shifts,
 | 
				
			||||||
 | 
							const struct dce_aduio_mask *masks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_destroy(struct audio **audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_hw_init(struct audio *audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_az_enable(struct audio *audio);
 | 
				
			||||||
 | 
					void dce_aud_az_disable(struct audio *audio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_az_configure(struct audio *audio,
 | 
				
			||||||
 | 
						enum signal_type signal,
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						const struct audio_info *audio_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_aud_wall_dto_setup(struct audio *audio,
 | 
				
			||||||
 | 
						enum signal_type signal,
 | 
				
			||||||
 | 
						const struct audio_crtc_info *crtc_info,
 | 
				
			||||||
 | 
						const struct audio_pll_info *pll_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif   /*__DAL_AUDIO_DCE_110_H__*/
 | 
				
			||||||
							
								
								
									
										1264
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1264
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										109
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,109 @@
 | 
				
			||||||
 | 
					/* Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DC_CLOCK_SOURCE_DCE_H__
 | 
				
			||||||
 | 
					#define __DC_CLOCK_SOURCE_DCE_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../inc/clock_source.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TO_DCE110_CLK_SRC(clk_src)\
 | 
				
			||||||
 | 
						container_of(clk_src, struct dce110_clk_src, base)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS_COMMON_REG_LIST_DCE_100_110(id) \
 | 
				
			||||||
 | 
							SRI(RESYNC_CNTL, PIXCLK, id), \
 | 
				
			||||||
 | 
							SRI(PLL_CNTL, BPHYC_PLL, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS_COMMON_REG_LIST_DCE_80(id) \
 | 
				
			||||||
 | 
							SRI(RESYNC_CNTL, PIXCLK, id), \
 | 
				
			||||||
 | 
							SRI(PLL_CNTL, DCCG_PLL, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS_COMMON_REG_LIST_DCE_112(id) \
 | 
				
			||||||
 | 
							SRI(PIXCLK_RESYNC_CNTL, PHYPLL, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS_SF(reg_name, field_name, post_fix)\
 | 
				
			||||||
 | 
						.field_name = reg_name ## __ ## field_name ## post_fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)\
 | 
				
			||||||
 | 
						CS_SF(PLL_CNTL, PLL_REF_DIV_SRC, mask_sh),\
 | 
				
			||||||
 | 
						CS_SF(PIXCLK1_RESYNC_CNTL, DCCG_DEEP_COLOR_CNTL1, mask_sh),\
 | 
				
			||||||
 | 
						CS_SF(PLL_POST_DIV, PLL_POST_DIV_PIXCLK, mask_sh),\
 | 
				
			||||||
 | 
						CS_SF(PLL_REF_DIV, PLL_REF_DIV, mask_sh),\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS_COMMON_MASK_SH_LIST_DCE_112(mask_sh)\
 | 
				
			||||||
 | 
						CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\
 | 
				
			||||||
 | 
						CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS_REG_FIELD_LIST(type) \
 | 
				
			||||||
 | 
						type PLL_REF_DIV_SRC; \
 | 
				
			||||||
 | 
						type DCCG_DEEP_COLOR_CNTL1; \
 | 
				
			||||||
 | 
						type PHYPLLA_DCCG_DEEP_COLOR_CNTL; \
 | 
				
			||||||
 | 
						type PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE; \
 | 
				
			||||||
 | 
						type PLL_POST_DIV_PIXCLK; \
 | 
				
			||||||
 | 
						type PLL_REF_DIV; \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_clk_src_shift {
 | 
				
			||||||
 | 
						CS_REG_FIELD_LIST(uint8_t)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_clk_src_mask{
 | 
				
			||||||
 | 
						CS_REG_FIELD_LIST(uint32_t)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_clk_src_regs {
 | 
				
			||||||
 | 
						uint32_t RESYNC_CNTL;
 | 
				
			||||||
 | 
						uint32_t PIXCLK_RESYNC_CNTL;
 | 
				
			||||||
 | 
						uint32_t PLL_CNTL;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_clk_src {
 | 
				
			||||||
 | 
						struct clock_source base;
 | 
				
			||||||
 | 
						const struct dce110_clk_src_regs *regs;
 | 
				
			||||||
 | 
						const struct dce110_clk_src_mask *cs_mask;
 | 
				
			||||||
 | 
						const struct dce110_clk_src_shift *cs_shift;
 | 
				
			||||||
 | 
						struct dc_bios *bios;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct spread_spectrum_data *dp_ss_params;
 | 
				
			||||||
 | 
						uint32_t dp_ss_params_cnt;
 | 
				
			||||||
 | 
						struct spread_spectrum_data *hdmi_ss_params;
 | 
				
			||||||
 | 
						uint32_t hdmi_ss_params_cnt;
 | 
				
			||||||
 | 
						struct spread_spectrum_data *dvi_ss_params;
 | 
				
			||||||
 | 
						uint32_t dvi_ss_params_cnt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t ext_clk_khz;
 | 
				
			||||||
 | 
						uint32_t ref_freq_khz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct calc_pll_clock_source calc_pll;
 | 
				
			||||||
 | 
						struct calc_pll_clock_source calc_pll_hdmi;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_clk_src_construct(
 | 
				
			||||||
 | 
						struct dce110_clk_src *clk_src,
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dc_bios *bios,
 | 
				
			||||||
 | 
						enum clock_source_id,
 | 
				
			||||||
 | 
						const struct dce110_clk_src_regs *regs,
 | 
				
			||||||
 | 
						const struct dce110_clk_src_shift *cs_shift,
 | 
				
			||||||
 | 
						const struct dce110_clk_src_mask *cs_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										195
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,195 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dce_hwseq.h"
 | 
				
			||||||
 | 
					#include "reg_helper.h"
 | 
				
			||||||
 | 
					#include "hw_sequencer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CTX \
 | 
				
			||||||
 | 
						hws->ctx
 | 
				
			||||||
 | 
					#define REG(reg)\
 | 
				
			||||||
 | 
						hws->regs->reg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef FN
 | 
				
			||||||
 | 
					#define FN(reg_name, field_name) \
 | 
				
			||||||
 | 
						hws->shifts->field_name, hws->masks->field_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_enable_fe_clock(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
							unsigned int fe_inst, bool enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						REG_UPDATE(DCFE_CLOCK_CONTROL[fe_inst],
 | 
				
			||||||
 | 
								DCFE_CLOCK_ENABLE, enable);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_pipe_control_lock(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
							unsigned int blnd_inst,
 | 
				
			||||||
 | 
							enum pipe_lock_control control_mask,
 | 
				
			||||||
 | 
							bool lock)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t lock_val = lock ? 1 : 0;
 | 
				
			||||||
 | 
						uint32_t dcp_grph, scl, dcp_grph_surf, blnd, update_lock_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t val = REG_GET_5(BLND_V_UPDATE_LOCK[blnd_inst],
 | 
				
			||||||
 | 
								BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
 | 
				
			||||||
 | 
								BLND_SCL_V_UPDATE_LOCK, &scl,
 | 
				
			||||||
 | 
								BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, &dcp_grph_surf,
 | 
				
			||||||
 | 
								BLND_BLND_V_UPDATE_LOCK, &blnd,
 | 
				
			||||||
 | 
								BLND_V_UPDATE_LOCK_MODE, &update_lock_mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (control_mask & PIPE_LOCK_CONTROL_GRAPHICS)
 | 
				
			||||||
 | 
							dcp_grph = lock_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (control_mask & PIPE_LOCK_CONTROL_SCL)
 | 
				
			||||||
 | 
							scl = lock_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (control_mask & PIPE_LOCK_CONTROL_SURFACE)
 | 
				
			||||||
 | 
							dcp_grph_surf = lock_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (control_mask & PIPE_LOCK_CONTROL_BLENDER)
 | 
				
			||||||
 | 
							blnd = lock_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (control_mask & PIPE_LOCK_CONTROL_MODE)
 | 
				
			||||||
 | 
							update_lock_mode = lock_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET_5(BLND_V_UPDATE_LOCK[blnd_inst], val,
 | 
				
			||||||
 | 
								BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
 | 
				
			||||||
 | 
								BLND_SCL_V_UPDATE_LOCK, scl,
 | 
				
			||||||
 | 
								BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, dcp_grph_surf,
 | 
				
			||||||
 | 
								BLND_BLND_V_UPDATE_LOCK, blnd,
 | 
				
			||||||
 | 
								BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hws->wa.blnd_crtc_trigger)
 | 
				
			||||||
 | 
							if (!lock && (control_mask & PIPE_LOCK_CONTROL_BLENDER)) {
 | 
				
			||||||
 | 
								uint32_t value = REG_READ(CRTC_H_BLANK_START_END[blnd_inst]);
 | 
				
			||||||
 | 
								REG_WRITE(CRTC_H_BLANK_START_END[blnd_inst], value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_set_blender_mode(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
						unsigned int blnd_inst,
 | 
				
			||||||
 | 
						enum blnd_mode mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t feedthrough = 1;
 | 
				
			||||||
 | 
						uint32_t blnd_mode = 0;
 | 
				
			||||||
 | 
						uint32_t multiplied_mode = 0;
 | 
				
			||||||
 | 
						uint32_t alpha_mode = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (mode) {
 | 
				
			||||||
 | 
						case BLND_MODE_OTHER_PIPE:
 | 
				
			||||||
 | 
							feedthrough = 0;
 | 
				
			||||||
 | 
							blnd_mode = 1;
 | 
				
			||||||
 | 
							alpha_mode = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BLND_MODE_BLENDING:
 | 
				
			||||||
 | 
							feedthrough = 0;
 | 
				
			||||||
 | 
							blnd_mode = 2;
 | 
				
			||||||
 | 
							alpha_mode = 0;
 | 
				
			||||||
 | 
							multiplied_mode = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BLND_MODE_CURRENT_PIPE:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							if (REG(BLND_CONTROL[blnd_inst]) == REG(BLNDV_CONTROL) ||
 | 
				
			||||||
 | 
									blnd_inst == 0)
 | 
				
			||||||
 | 
								feedthrough = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_UPDATE_4(BLND_CONTROL[blnd_inst],
 | 
				
			||||||
 | 
							BLND_FEEDTHROUGH_EN, feedthrough,
 | 
				
			||||||
 | 
							BLND_ALPHA_MODE, alpha_mode,
 | 
				
			||||||
 | 
							BLND_MODE, blnd_mode,
 | 
				
			||||||
 | 
							BLND_MULTIPLIED_MODE, multiplied_mode);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dce_disable_sram_shut_down(struct dce_hwseq *hws)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL))
 | 
				
			||||||
 | 
							REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL,
 | 
				
			||||||
 | 
									DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dce_underlay_clock_enable(struct dce_hwseq *hws)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* todo: why do we need this at boot? is dce_enable_fe_clock enough? */
 | 
				
			||||||
 | 
						if (REG(DCFEV_CLOCK_CONTROL))
 | 
				
			||||||
 | 
							REG_UPDATE(DCFEV_CLOCK_CONTROL,
 | 
				
			||||||
 | 
									DCFEV_CLOCK_ENABLE, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void enable_hw_base_light_sleep(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: implement */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void disable_sw_manual_control_light_sleep(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: implement */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_clock_gating_power_up(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
							bool enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (enable) {
 | 
				
			||||||
 | 
							enable_hw_base_light_sleep();
 | 
				
			||||||
 | 
							disable_sw_manual_control_light_sleep();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							dce_disable_sram_shut_down(hws);
 | 
				
			||||||
 | 
							dce_underlay_clock_enable(hws);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
							struct clock_source *clk_src,
 | 
				
			||||||
 | 
							unsigned int tg_inst)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO) {
 | 
				
			||||||
 | 
							REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
 | 
				
			||||||
 | 
									DP_DTO0_ENABLE, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						} else if (clk_src->id >= CLOCK_SOURCE_COMBO_PHY_PLL0) {
 | 
				
			||||||
 | 
							uint32_t rate_source = clk_src->id - CLOCK_SOURCE_COMBO_PHY_PLL0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
 | 
				
			||||||
 | 
									PHYPLL_PIXEL_RATE_SOURCE, rate_source,
 | 
				
			||||||
 | 
									PIXEL_RATE_PLL_SOURCE, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
 | 
				
			||||||
 | 
									DP_DTO0_ENABLE, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						} else if (clk_src->id <= CLOCK_SOURCE_ID_PLL2) {
 | 
				
			||||||
 | 
							uint32_t rate_source = clk_src->id - CLOCK_SOURCE_ID_PLL0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE_2(PIXEL_RATE_CNTL[tg_inst],
 | 
				
			||||||
 | 
									PIXEL_RATE_SOURCE, rate_source,
 | 
				
			||||||
 | 
									DP_DTO0_ENABLE, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (REG(PHYPLL_PIXEL_RATE_CNTL[tg_inst]))
 | 
				
			||||||
 | 
								REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
 | 
				
			||||||
 | 
										PIXEL_RATE_PLL_SOURCE, 1);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							DC_ERR("unknown clock source");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										250
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,250 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef __DCE_HWSEQ_H__
 | 
				
			||||||
 | 
					#define __DCE_HWSEQ_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "hw_sequencer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCEF_REG_LIST_DCE8() \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[2] = mmCRTC2_CRTC_DCFE_CLOCK_CONTROL, \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[3] = mmCRTC3_CRTC_DCFE_CLOCK_CONTROL, \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[4] = mmCRTC4_CRTC_DCFE_CLOCK_CONTROL, \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[5] = mmCRTC5_CRTC_DCFE_CLOCK_CONTROL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCEF_REG_LIST() \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 0), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 1), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 2), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 3), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 4), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 5), \
 | 
				
			||||||
 | 
						SR(DC_MEM_GLOBAL_PWR_REQ_CNTL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_BLND_REG_LIST() \
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 0), \
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 1), \
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 2), \
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 3), \
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 4), \
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 5), \
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 0), \
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 1), \
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 2), \
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 3), \
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 4), \
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_PIXEL_RATE_REG_LIST(blk) \
 | 
				
			||||||
 | 
						SRII(PIXEL_RATE_CNTL, blk, 0), \
 | 
				
			||||||
 | 
						SRII(PIXEL_RATE_CNTL, blk, 1), \
 | 
				
			||||||
 | 
						SRII(PIXEL_RATE_CNTL, blk, 2), \
 | 
				
			||||||
 | 
						SRII(PIXEL_RATE_CNTL, blk, 3), \
 | 
				
			||||||
 | 
						SRII(PIXEL_RATE_CNTL, blk, 4), \
 | 
				
			||||||
 | 
						SRII(PIXEL_RATE_CNTL, blk, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_PHYPLL_REG_LIST(blk) \
 | 
				
			||||||
 | 
						SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \
 | 
				
			||||||
 | 
						SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1), \
 | 
				
			||||||
 | 
						SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2), \
 | 
				
			||||||
 | 
						SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \
 | 
				
			||||||
 | 
						SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \
 | 
				
			||||||
 | 
						SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE11_REG_LIST_BASE() \
 | 
				
			||||||
 | 
						SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \
 | 
				
			||||||
 | 
						SR(DCFEV_CLOCK_CONTROL), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 0), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 1), \
 | 
				
			||||||
 | 
						SRII(CRTC_H_BLANK_START_END, CRTC, 0),\
 | 
				
			||||||
 | 
						SRII(CRTC_H_BLANK_START_END, CRTC, 1),\
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 0),\
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 1),\
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 0),\
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 1),\
 | 
				
			||||||
 | 
						SR(BLNDV_CONTROL),\
 | 
				
			||||||
 | 
						HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE8_REG_LIST() \
 | 
				
			||||||
 | 
						HWSEQ_DCEF_REG_LIST_DCE8(), \
 | 
				
			||||||
 | 
						HWSEQ_BLND_REG_LIST(), \
 | 
				
			||||||
 | 
						HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE10_REG_LIST() \
 | 
				
			||||||
 | 
						HWSEQ_DCEF_REG_LIST(), \
 | 
				
			||||||
 | 
						HWSEQ_BLND_REG_LIST(), \
 | 
				
			||||||
 | 
						HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_ST_REG_LIST() \
 | 
				
			||||||
 | 
						HWSEQ_DCE11_REG_LIST_BASE(), \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \
 | 
				
			||||||
 | 
						.CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \
 | 
				
			||||||
 | 
						.BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \
 | 
				
			||||||
 | 
						.BLND_CONTROL[2] = mmBLNDV_CONTROL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_CZ_REG_LIST() \
 | 
				
			||||||
 | 
						HWSEQ_DCE11_REG_LIST_BASE(), \
 | 
				
			||||||
 | 
						SRII(DCFE_CLOCK_CONTROL, DCFE, 2), \
 | 
				
			||||||
 | 
						SRII(CRTC_H_BLANK_START_END, CRTC, 2), \
 | 
				
			||||||
 | 
						SRII(BLND_V_UPDATE_LOCK, BLND, 2), \
 | 
				
			||||||
 | 
						SRII(BLND_CONTROL, BLND, 2), \
 | 
				
			||||||
 | 
						.DCFE_CLOCK_CONTROL[3] = mmDCFEV_CLOCK_CONTROL, \
 | 
				
			||||||
 | 
						.CRTC_H_BLANK_START_END[3] = mmCRTCV_H_BLANK_START_END, \
 | 
				
			||||||
 | 
						.BLND_V_UPDATE_LOCK[3] = mmBLNDV_V_UPDATE_LOCK, \
 | 
				
			||||||
 | 
						.BLND_CONTROL[3] = mmBLNDV_CONTROL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE112_REG_LIST() \
 | 
				
			||||||
 | 
						HWSEQ_DCE10_REG_LIST(), \
 | 
				
			||||||
 | 
						HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
 | 
				
			||||||
 | 
						HWSEQ_PHYPLL_REG_LIST(CRTC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_hwseq_registers {
 | 
				
			||||||
 | 
						uint32_t DCFE_CLOCK_CONTROL[6];
 | 
				
			||||||
 | 
						uint32_t DCFEV_CLOCK_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL;
 | 
				
			||||||
 | 
						uint32_t BLND_V_UPDATE_LOCK[6];
 | 
				
			||||||
 | 
						uint32_t BLND_CONTROL[6];
 | 
				
			||||||
 | 
						uint32_t BLNDV_CONTROL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t CRTC_H_BLANK_START_END[6];
 | 
				
			||||||
 | 
						uint32_t PIXEL_RATE_CNTL[6];
 | 
				
			||||||
 | 
						uint32_t PHYPLL_PIXEL_RATE_CNTL[6];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					 /* set field name */
 | 
				
			||||||
 | 
					#define HWS_SF(blk_name, reg_name, field_name, post_fix)\
 | 
				
			||||||
 | 
						.field_name = blk_name ## reg_name ## __ ## field_name ## post_fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWS_SF1(blk_name, reg_name, field_name, post_fix)\
 | 
				
			||||||
 | 
						.field_name = blk_name ## reg_name ## __ ## blk_name ## field_name ## post_fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCEF_MASK_SH_LIST(mask_sh, blk)\
 | 
				
			||||||
 | 
						HWS_SF(blk, CLOCK_CONTROL, DCFE_CLOCK_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_BLND_MASK_SH_LIST(mask_sh, blk)\
 | 
				
			||||||
 | 
						HWS_SF(blk, V_UPDATE_LOCK, BLND_DCP_GRPH_V_UPDATE_LOCK, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, V_UPDATE_LOCK, BLND_BLND_V_UPDATE_LOCK, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, V_UPDATE_LOCK, BLND_V_UPDATE_LOCK_MODE, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, CONTROL, BLND_FEEDTHROUGH_EN, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, CONTROL, BLND_ALPHA_MODE, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, CONTROL, BLND_MODE, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, CONTROL, BLND_MULTIPLIED_MODE, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, blk)\
 | 
				
			||||||
 | 
						HWS_SF1(blk, PIXEL_RATE_CNTL, PIXEL_RATE_SOURCE, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(blk, PIXEL_RATE_CNTL, DP_DTO0_ENABLE, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, blk)\
 | 
				
			||||||
 | 
						HWS_SF1(blk, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF1(blk, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE8_MASK_SH_LIST(mask_sh)\
 | 
				
			||||||
 | 
						.DCFE_CLOCK_ENABLE = CRTC_DCFE_CLOCK_CONTROL__CRTC_DCFE_CLOCK_ENABLE ## mask_sh, \
 | 
				
			||||||
 | 
						HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_V_UPDATE_LOCK, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
 | 
				
			||||||
 | 
						HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\
 | 
				
			||||||
 | 
						HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\
 | 
				
			||||||
 | 
						HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\
 | 
				
			||||||
 | 
						HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\
 | 
				
			||||||
 | 
						HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\
 | 
				
			||||||
 | 
						HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
 | 
				
			||||||
 | 
						SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\
 | 
				
			||||||
 | 
						HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
 | 
				
			||||||
 | 
						HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HWSEQ_REG_FIED_LIST(type) \
 | 
				
			||||||
 | 
						type DCFE_CLOCK_ENABLE; \
 | 
				
			||||||
 | 
						type DCFEV_CLOCK_ENABLE; \
 | 
				
			||||||
 | 
						type DC_MEM_GLOBAL_PWR_REQ_DIS; \
 | 
				
			||||||
 | 
						type BLND_DCP_GRPH_V_UPDATE_LOCK; \
 | 
				
			||||||
 | 
						type BLND_SCL_V_UPDATE_LOCK; \
 | 
				
			||||||
 | 
						type BLND_DCP_GRPH_SURF_V_UPDATE_LOCK; \
 | 
				
			||||||
 | 
						type BLND_BLND_V_UPDATE_LOCK; \
 | 
				
			||||||
 | 
						type BLND_V_UPDATE_LOCK_MODE; \
 | 
				
			||||||
 | 
						type BLND_FEEDTHROUGH_EN; \
 | 
				
			||||||
 | 
						type BLND_ALPHA_MODE; \
 | 
				
			||||||
 | 
						type BLND_MODE; \
 | 
				
			||||||
 | 
						type BLND_MULTIPLIED_MODE; \
 | 
				
			||||||
 | 
						type DP_DTO0_ENABLE; \
 | 
				
			||||||
 | 
						type PIXEL_RATE_SOURCE; \
 | 
				
			||||||
 | 
						type PHYPLL_PIXEL_RATE_SOURCE; \
 | 
				
			||||||
 | 
						type PIXEL_RATE_PLL_SOURCE; \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_hwseq_shift {
 | 
				
			||||||
 | 
						HWSEQ_REG_FIED_LIST(uint8_t)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_hwseq_mask {
 | 
				
			||||||
 | 
						HWSEQ_REG_FIED_LIST(uint32_t)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_hwseq_wa {
 | 
				
			||||||
 | 
						bool blnd_crtc_trigger;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_hwseq {
 | 
				
			||||||
 | 
						struct dc_context *ctx;
 | 
				
			||||||
 | 
						const struct dce_hwseq_registers *regs;
 | 
				
			||||||
 | 
						const struct dce_hwseq_shift *shifts;
 | 
				
			||||||
 | 
						const struct dce_hwseq_mask *masks;
 | 
				
			||||||
 | 
						struct dce_hwseq_wa wa;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum blnd_mode {
 | 
				
			||||||
 | 
						BLND_MODE_CURRENT_PIPE = 0,/* Data from current pipe only */
 | 
				
			||||||
 | 
						BLND_MODE_OTHER_PIPE, /* Data from other pipe only */
 | 
				
			||||||
 | 
						BLND_MODE_BLENDING,/* Alpha blending - blend 'current' and 'other' */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_enable_fe_clock(struct dce_hwseq *hwss,
 | 
				
			||||||
 | 
							unsigned int inst, bool enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_pipe_control_lock(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
							unsigned int blnd_inst,
 | 
				
			||||||
 | 
							enum pipe_lock_control control_mask,
 | 
				
			||||||
 | 
							bool lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_set_blender_mode(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
						unsigned int blnd_inst, enum blnd_mode mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_clock_gating_power_up(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
							bool enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
 | 
				
			||||||
 | 
							struct clock_source *clk_src,
 | 
				
			||||||
 | 
							unsigned int tg_inst);
 | 
				
			||||||
 | 
					#endif   /*__DCE_HWSEQ_H__*/
 | 
				
			||||||
							
								
								
									
										2176
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2176
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										363
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										363
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,363 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DC_LINK_ENCODER__DCE110_H__
 | 
				
			||||||
 | 
					#define __DC_LINK_ENCODER__DCE110_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "link_encoder.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TO_DCE110_LINK_ENC(link_encoder)\
 | 
				
			||||||
 | 
						container_of(link_encoder, struct dce110_link_encoder, base)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AUX_REG_LIST(id)\
 | 
				
			||||||
 | 
						SRI(AUX_CONTROL, DP_AUX, id), \
 | 
				
			||||||
 | 
						SRI(AUX_DPHY_RX_CONTROL0, DP_AUX, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HPD_REG_LIST(id)\
 | 
				
			||||||
 | 
						SRI(DC_HPD_CONTROL, HPD, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LE_COMMON_REG_LIST_BASE(id) \
 | 
				
			||||||
 | 
						SR(BL_PWM_CNTL), \
 | 
				
			||||||
 | 
						SR(BL_PWM_GRP1_REG_LOCK), \
 | 
				
			||||||
 | 
						SR(BL_PWM_PERIOD_CNTL), \
 | 
				
			||||||
 | 
						SR(LVTMA_PWRSEQ_CNTL), \
 | 
				
			||||||
 | 
						SR(LVTMA_PWRSEQ_STATE), \
 | 
				
			||||||
 | 
						SR(BL_PWM_CNTL2), \
 | 
				
			||||||
 | 
						SR(LVTMA_PWRSEQ_REF_DIV), \
 | 
				
			||||||
 | 
						SR(MASTER_COMM_DATA_REG1), \
 | 
				
			||||||
 | 
						SR(MASTER_COMM_DATA_REG2), \
 | 
				
			||||||
 | 
						SR(MASTER_COMM_DATA_REG3), \
 | 
				
			||||||
 | 
						SR(MASTER_COMM_CMD_REG), \
 | 
				
			||||||
 | 
						SR(MASTER_COMM_CNTL_REG), \
 | 
				
			||||||
 | 
						SR(DMCU_RAM_ACCESS_CTRL), \
 | 
				
			||||||
 | 
						SR(DMCU_IRAM_RD_CTRL), \
 | 
				
			||||||
 | 
						SR(DMCU_IRAM_RD_DATA), \
 | 
				
			||||||
 | 
						SR(DMCU_INTERRUPT_TO_UC_EN_MASK), \
 | 
				
			||||||
 | 
						SR(SMU_INTERRUPT_CONTROL), \
 | 
				
			||||||
 | 
						SRI(DIG_BE_CNTL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(DIG_BE_EN_CNTL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(DP_CONFIG, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_DPHY_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_DPHY_PRBS_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_DPHY_SCRAM_CNTL, DP, id),\
 | 
				
			||||||
 | 
						SRI(DP_DPHY_SYM0, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_DPHY_SYM1, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_DPHY_SYM2, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_DPHY_TRAINING_PATTERN_SEL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_LINK_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_LINK_FRAMING_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_MSE_SAT0, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_MSE_SAT1, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_MSE_SAT2, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_MSE_SAT_UPDATE, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_SEC_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_VID_STREAM_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_DPHY_FAST_TRAINING, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_SEC_CNTL1, DP, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#define LE_COMMON_REG_LIST(id)\
 | 
				
			||||||
 | 
							LE_COMMON_REG_LIST_BASE(id), \
 | 
				
			||||||
 | 
							SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
 | 
				
			||||||
 | 
							SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
 | 
				
			||||||
 | 
							SR(BIOS_SCRATCH_2), \
 | 
				
			||||||
 | 
							SR(BL1_PWM_USER_LEVEL), \
 | 
				
			||||||
 | 
							SR(DCI_MEM_PWR_STATUS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#define LE_DCE110_REG_LIST(id)\
 | 
				
			||||||
 | 
							LE_COMMON_REG_LIST_BASE(id), \
 | 
				
			||||||
 | 
							SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
 | 
				
			||||||
 | 
							SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
 | 
				
			||||||
 | 
							SR(BIOS_SCRATCH_2), \
 | 
				
			||||||
 | 
							SR(BL1_PWM_USER_LEVEL), \
 | 
				
			||||||
 | 
							SR(DCI_MEM_PWR_STATUS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#define LE_DCE80_REG_LIST(id)\
 | 
				
			||||||
 | 
							SR(BIOS_SCRATCH_2), \
 | 
				
			||||||
 | 
							SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
 | 
				
			||||||
 | 
							SR(BL1_PWM_USER_LEVEL), \
 | 
				
			||||||
 | 
							LE_COMMON_REG_LIST_BASE(id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_link_enc_aux_registers {
 | 
				
			||||||
 | 
						uint32_t AUX_CONTROL;
 | 
				
			||||||
 | 
						uint32_t AUX_DPHY_RX_CONTROL0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_link_enc_hpd_registers {
 | 
				
			||||||
 | 
						uint32_t DC_HPD_CONTROL;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_link_enc_registers {
 | 
				
			||||||
 | 
						/* BL registers */
 | 
				
			||||||
 | 
						uint32_t BL_PWM_CNTL;
 | 
				
			||||||
 | 
						uint32_t BL_PWM_GRP1_REG_LOCK;
 | 
				
			||||||
 | 
						uint32_t BL_PWM_PERIOD_CNTL;
 | 
				
			||||||
 | 
						uint32_t LVTMA_PWRSEQ_CNTL;
 | 
				
			||||||
 | 
						uint32_t LVTMA_PWRSEQ_STATE;
 | 
				
			||||||
 | 
						uint32_t BL_PWM_CNTL2;
 | 
				
			||||||
 | 
						uint32_t LVTMA_PWRSEQ_REF_DIV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* DMCU registers */
 | 
				
			||||||
 | 
						uint32_t BL1_PWM_USER_LEVEL;
 | 
				
			||||||
 | 
						uint32_t ABM0_BL1_PWM_USER_LEVEL;
 | 
				
			||||||
 | 
						uint32_t MASTER_COMM_DATA_REG1;
 | 
				
			||||||
 | 
						uint32_t MASTER_COMM_DATA_REG2;
 | 
				
			||||||
 | 
						uint32_t MASTER_COMM_DATA_REG3;
 | 
				
			||||||
 | 
						uint32_t MASTER_COMM_CMD_REG;
 | 
				
			||||||
 | 
						uint32_t MASTER_COMM_CNTL_REG;
 | 
				
			||||||
 | 
						uint32_t BIOS_SCRATCH_2;
 | 
				
			||||||
 | 
						uint32_t DMCU_RAM_ACCESS_CTRL;
 | 
				
			||||||
 | 
						uint32_t DCI_MEM_PWR_STATUS;
 | 
				
			||||||
 | 
						uint32_t DMU_MEM_PWR_CNTL;
 | 
				
			||||||
 | 
						uint32_t DMCU_IRAM_RD_CTRL;
 | 
				
			||||||
 | 
						uint32_t DMCU_IRAM_RD_DATA;
 | 
				
			||||||
 | 
						uint32_t DMCU_INTERRUPT_TO_UC_EN_MASK;
 | 
				
			||||||
 | 
						uint32_t SMU_INTERRUPT_CONTROL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Common DP registers */
 | 
				
			||||||
 | 
						uint32_t DIG_BE_CNTL;
 | 
				
			||||||
 | 
						uint32_t DIG_BE_EN_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_CONFIG;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_INTERNAL_CTRL;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_PRBS_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_SCRAM_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_SYM0;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_SYM1;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_SYM2;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_TRAINING_PATTERN_SEL;
 | 
				
			||||||
 | 
						uint32_t DP_LINK_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_LINK_FRAMING_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_SAT0;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_SAT1;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_SAT2;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_SAT_UPDATE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_VID_STREAM_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_FAST_TRAINING;
 | 
				
			||||||
 | 
						uint32_t DP_DPHY_BS_SR_SWAP_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_CNTL1;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_link_encoder {
 | 
				
			||||||
 | 
						struct link_encoder base;
 | 
				
			||||||
 | 
						const struct dce110_link_enc_registers *link_regs;
 | 
				
			||||||
 | 
						const struct dce110_link_enc_aux_registers *aux_regs;
 | 
				
			||||||
 | 
						const struct dce110_link_enc_hpd_registers *hpd_regs;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************
 | 
				
			||||||
 | 
					*   MASTER_COMM_DATA_REG1   Bit position    Data
 | 
				
			||||||
 | 
					*                           7:0	            hyst_frames[7:0]
 | 
				
			||||||
 | 
					*                           14:8	        hyst_lines[6:0]
 | 
				
			||||||
 | 
					*                           15	            RFB_UPDATE_AUTO_EN
 | 
				
			||||||
 | 
					*                           18:16	        phy_num[2:0]
 | 
				
			||||||
 | 
					*                           21:19	        dcp_sel[2:0]
 | 
				
			||||||
 | 
					*                           22	            phy_type
 | 
				
			||||||
 | 
					*                           23	            frame_cap_ind
 | 
				
			||||||
 | 
					*                           26:24	        aux_chan[2:0]
 | 
				
			||||||
 | 
					*                           30:27	        aux_repeat[3:0]
 | 
				
			||||||
 | 
					*                           31:31	        reserved[31:31]
 | 
				
			||||||
 | 
					*******************************************************************/
 | 
				
			||||||
 | 
					union dce110_dmcu_psr_config_data_reg1 {
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							unsigned int timehyst_frames:8;    /*[7:0]*/
 | 
				
			||||||
 | 
							unsigned int hyst_lines:7;         /*[14:8]*/
 | 
				
			||||||
 | 
							unsigned int rfb_update_auto_en:1; /*[15:15]*/
 | 
				
			||||||
 | 
							unsigned int dp_port_num:3;        /*[18:16]*/
 | 
				
			||||||
 | 
							unsigned int dcp_sel:3;            /*[21:19]*/
 | 
				
			||||||
 | 
							unsigned int phy_type:1;           /*[22:22]*/
 | 
				
			||||||
 | 
							unsigned int frame_cap_ind:1;      /*[23:23]*/
 | 
				
			||||||
 | 
							unsigned int aux_chan:3;           /*[26:24]*/
 | 
				
			||||||
 | 
							unsigned int aux_repeat:4;         /*[30:27]*/
 | 
				
			||||||
 | 
							unsigned int reserved:1;           /*[31:31]*/
 | 
				
			||||||
 | 
						} bits;
 | 
				
			||||||
 | 
						unsigned int u32All;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************
 | 
				
			||||||
 | 
					*   MASTER_COMM_DATA_REG2
 | 
				
			||||||
 | 
					*******************************************************************/
 | 
				
			||||||
 | 
					union dce110_dmcu_psr_config_data_reg2 {
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							unsigned int dig_fe:3;                  /*[2:0]*/
 | 
				
			||||||
 | 
							unsigned int dig_be:3;                  /*[5:3]*/
 | 
				
			||||||
 | 
							unsigned int skip_wait_for_pll_lock:1;  /*[6:6]*/
 | 
				
			||||||
 | 
							unsigned int reserved:9;                /*[15:7]*/
 | 
				
			||||||
 | 
							unsigned int frame_delay:8;             /*[23:16]*/
 | 
				
			||||||
 | 
							unsigned int smu_phy_id:4;              /*[27:24]*/
 | 
				
			||||||
 | 
							unsigned int num_of_controllers:4;      /*[31:28]*/
 | 
				
			||||||
 | 
						} bits;
 | 
				
			||||||
 | 
						unsigned int u32All;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************
 | 
				
			||||||
 | 
					*   MASTER_COMM_DATA_REG3
 | 
				
			||||||
 | 
					*******************************************************************/
 | 
				
			||||||
 | 
					union dce110_dmcu_psr_config_data_reg3 {
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							unsigned int psr_level:16;      /*[15:0]*/
 | 
				
			||||||
 | 
							unsigned int link_rate:4;       /*[19:16]*/
 | 
				
			||||||
 | 
							unsigned int reserved:12;       /*[31:20]*/
 | 
				
			||||||
 | 
						} bits;
 | 
				
			||||||
 | 
						unsigned int u32All;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_abm_backlight_registers {
 | 
				
			||||||
 | 
						unsigned int vBL_PWM_CNTL;
 | 
				
			||||||
 | 
						unsigned int vBL_PWM_CNTL2;
 | 
				
			||||||
 | 
						unsigned int vBL_PWM_PERIOD_CNTL;
 | 
				
			||||||
 | 
						unsigned int vLVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_link_encoder_construct(
 | 
				
			||||||
 | 
						struct dce110_link_encoder *enc110,
 | 
				
			||||||
 | 
						const struct encoder_init_data *init_data,
 | 
				
			||||||
 | 
						const struct dce110_link_enc_registers *link_regs,
 | 
				
			||||||
 | 
						const struct dce110_link_enc_aux_registers *aux_regs,
 | 
				
			||||||
 | 
						const struct dce110_link_enc_hpd_registers *hpd_regs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_link_encoder_validate_dvi_output(
 | 
				
			||||||
 | 
						const struct dce110_link_encoder *enc110,
 | 
				
			||||||
 | 
						enum signal_type connector_signal,
 | 
				
			||||||
 | 
						enum signal_type signal,
 | 
				
			||||||
 | 
						const struct dc_crtc_timing *crtc_timing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_link_encoder_validate_rgb_output(
 | 
				
			||||||
 | 
						const struct dce110_link_encoder *enc110,
 | 
				
			||||||
 | 
						const struct dc_crtc_timing *crtc_timing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_link_encoder_validate_dp_output(
 | 
				
			||||||
 | 
						const struct dce110_link_encoder *enc110,
 | 
				
			||||||
 | 
						const struct dc_crtc_timing *crtc_timing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_link_encoder_validate_wireless_output(
 | 
				
			||||||
 | 
						const struct dce110_link_encoder *enc110,
 | 
				
			||||||
 | 
						const struct dc_crtc_timing *crtc_timing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_link_encoder_validate_output_with_stream(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						struct pipe_ctx *pipe_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************** HW programming ************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* initialize HW */  /* why do we initialze aux in here? */
 | 
				
			||||||
 | 
					void dce110_link_encoder_hw_init(struct link_encoder *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_destroy(struct link_encoder **enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* program DIG_MODE in DIG_BE */
 | 
				
			||||||
 | 
					/* TODO can this be combined with enable_output? */
 | 
				
			||||||
 | 
					void dce110_link_encoder_setup(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						enum signal_type signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* enables TMDS PHY output */
 | 
				
			||||||
 | 
					/* TODO: still need depth or just pass in adjusted pixel clock? */
 | 
				
			||||||
 | 
					void dce110_link_encoder_enable_tmds_output(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						enum clock_source_id clock_source,
 | 
				
			||||||
 | 
						enum dc_color_depth color_depth,
 | 
				
			||||||
 | 
						bool hdmi,
 | 
				
			||||||
 | 
						bool dual_link,
 | 
				
			||||||
 | 
						uint32_t pixel_clock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* enables DP PHY output */
 | 
				
			||||||
 | 
					void dce110_link_encoder_enable_dp_output(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						const struct dc_link_settings *link_settings,
 | 
				
			||||||
 | 
						enum clock_source_id clock_source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* enables DP PHY output in MST mode */
 | 
				
			||||||
 | 
					void dce110_link_encoder_enable_dp_mst_output(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						const struct dc_link_settings *link_settings,
 | 
				
			||||||
 | 
						enum clock_source_id clock_source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* disable PHY output */
 | 
				
			||||||
 | 
					void dce110_link_encoder_disable_output(
 | 
				
			||||||
 | 
						struct link_encoder *link_enc,
 | 
				
			||||||
 | 
						enum signal_type signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* set DP lane settings */
 | 
				
			||||||
 | 
					void dce110_link_encoder_dp_set_lane_settings(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						const struct link_training_settings *link_settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_dp_set_phy_pattern(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						const struct encoder_set_dp_phy_pattern_param *param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* programs DP MST VC payload allocation */
 | 
				
			||||||
 | 
					void dce110_link_encoder_update_mst_stream_allocation_table(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						const struct link_mst_stream_allocation_table *table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_set_lcd_backlight_level(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						uint32_t level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_set_dmcu_backlight_level(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						uint32_t level,
 | 
				
			||||||
 | 
						uint32_t frame_ramp,
 | 
				
			||||||
 | 
						uint32_t controller_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_init_dmcu_backlight_settings(
 | 
				
			||||||
 | 
						struct link_encoder *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_set_dmcu_abm_level(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						uint32_t level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_set_dmcu_psr_enable(
 | 
				
			||||||
 | 
							struct link_encoder *enc, bool enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_setup_dmcu_psr(struct link_encoder *enc,
 | 
				
			||||||
 | 
								struct psr_dmcu_context *psr_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_edp_backlight_control(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						bool enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_edp_power_control(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						bool power_up);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_connect_dig_be_to_fe(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						enum engine_id engine,
 | 
				
			||||||
 | 
						bool connect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_set_dp_phy_pattern_training_pattern(
 | 
				
			||||||
 | 
						struct link_encoder *enc,
 | 
				
			||||||
 | 
						uint32_t index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_enable_hpd(struct link_encoder *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_link_encoder_disable_hpd(struct link_encoder *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DC_LINK_ENCODER__DCE110_H__ */
 | 
				
			||||||
							
								
								
									
										384
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										384
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,384 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "mem_input.h"
 | 
				
			||||||
 | 
					#include "reg_helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CTX \
 | 
				
			||||||
 | 
						mi->ctx
 | 
				
			||||||
 | 
					#define REG(reg)\
 | 
				
			||||||
 | 
						mi->regs->reg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef FN
 | 
				
			||||||
 | 
					#define FN(reg_name, field_name) \
 | 
				
			||||||
 | 
						mi->shifts->field_name, mi->masks->field_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void program_urgency_watermark(struct mem_input *mi,
 | 
				
			||||||
 | 
						uint32_t wm_select,
 | 
				
			||||||
 | 
						uint32_t urgency_low_wm,
 | 
				
			||||||
 | 
						uint32_t urgency_high_wm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
 | 
				
			||||||
 | 
							URGENCY_WATERMARK_MASK, wm_select);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
 | 
				
			||||||
 | 
							URGENCY_LOW_WATERMARK, urgency_low_wm,
 | 
				
			||||||
 | 
							URGENCY_HIGH_WATERMARK, urgency_high_wm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void program_nbp_watermark(struct mem_input *mi,
 | 
				
			||||||
 | 
						uint32_t wm_select,
 | 
				
			||||||
 | 
						uint32_t nbp_wm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) {
 | 
				
			||||||
 | 
							REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
 | 
				
			||||||
 | 
									NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
 | 
				
			||||||
 | 
									NB_PSTATE_CHANGE_ENABLE, 1,
 | 
				
			||||||
 | 
									NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
 | 
				
			||||||
 | 
									NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
 | 
				
			||||||
 | 
									NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void program_stutter_watermark(struct mem_input *mi,
 | 
				
			||||||
 | 
						uint32_t wm_select,
 | 
				
			||||||
 | 
						uint32_t stutter_mark)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
 | 
				
			||||||
 | 
							STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
 | 
				
			||||||
 | 
									STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_mem_input_program_display_marks(struct mem_input *mi,
 | 
				
			||||||
 | 
						struct bw_watermarks nbp,
 | 
				
			||||||
 | 
						struct bw_watermarks stutter,
 | 
				
			||||||
 | 
						struct bw_watermarks urgent,
 | 
				
			||||||
 | 
						uint32_t total_dest_line_time_ns)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						program_urgency_watermark(mi, 0, /* set a */
 | 
				
			||||||
 | 
								urgent.a_mark, total_dest_line_time_ns);
 | 
				
			||||||
 | 
						program_urgency_watermark(mi, 1, /* set b */
 | 
				
			||||||
 | 
								urgent.b_mark, total_dest_line_time_ns);
 | 
				
			||||||
 | 
						program_urgency_watermark(mi, 2, /* set c */
 | 
				
			||||||
 | 
								urgent.c_mark, total_dest_line_time_ns);
 | 
				
			||||||
 | 
						program_urgency_watermark(mi, 3, /* set d */
 | 
				
			||||||
 | 
								urgent.d_mark, total_dest_line_time_ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
 | 
				
			||||||
 | 
							STUTTER_ENABLE, stutter_en,
 | 
				
			||||||
 | 
							STUTTER_IGNORE_FBC, 1);
 | 
				
			||||||
 | 
						program_nbp_watermark(mi, 0, nbp.a_mark); /* set a */
 | 
				
			||||||
 | 
						program_nbp_watermark(mi, 1, nbp.b_mark); /* set b */
 | 
				
			||||||
 | 
						program_nbp_watermark(mi, 2, nbp.c_mark); /* set c */
 | 
				
			||||||
 | 
						program_nbp_watermark(mi, 3, nbp.d_mark); /* set d */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						program_stutter_watermark(mi, 0, stutter.a_mark); /* set a */
 | 
				
			||||||
 | 
						program_stutter_watermark(mi, 1, stutter.b_mark); /* set b */
 | 
				
			||||||
 | 
						program_stutter_watermark(mi, 2, stutter.c_mark); /* set c */
 | 
				
			||||||
 | 
						program_stutter_watermark(mi, 3, stutter.d_mark); /* set d */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void program_tiling(struct mem_input *mi,
 | 
				
			||||||
 | 
						const union dc_tiling_info *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (mi->masks->GRPH_ARRAY_MODE) { /* GFX8 */
 | 
				
			||||||
 | 
							REG_UPDATE_9(GRPH_CONTROL,
 | 
				
			||||||
 | 
									GRPH_NUM_BANKS, info->gfx8.num_banks,
 | 
				
			||||||
 | 
									GRPH_BANK_WIDTH, info->gfx8.bank_width,
 | 
				
			||||||
 | 
									GRPH_BANK_HEIGHT, info->gfx8.bank_height,
 | 
				
			||||||
 | 
									GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect,
 | 
				
			||||||
 | 
									GRPH_TILE_SPLIT, info->gfx8.tile_split,
 | 
				
			||||||
 | 
									GRPH_MICRO_TILE_MODE, info->gfx8.tile_mode,
 | 
				
			||||||
 | 
									GRPH_PIPE_CONFIG, info->gfx8.pipe_config,
 | 
				
			||||||
 | 
									GRPH_ARRAY_MODE, info->gfx8.array_mode,
 | 
				
			||||||
 | 
									GRPH_COLOR_EXPANSION_MODE, 1);
 | 
				
			||||||
 | 
							/* 01 - DCP_GRPH_COLOR_EXPANSION_MODE_ZEXP: zero expansion for YCbCr */
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
									GRPH_Z, 0);
 | 
				
			||||||
 | 
									*/
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void program_size_and_rotation(
 | 
				
			||||||
 | 
						struct mem_input *mi,
 | 
				
			||||||
 | 
						enum dc_rotation_angle rotation,
 | 
				
			||||||
 | 
						const union plane_size *plane_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct rect *in_rect = &plane_size->grph.surface_size;
 | 
				
			||||||
 | 
						struct rect hw_rect = plane_size->grph.surface_size;
 | 
				
			||||||
 | 
						const uint32_t rotation_angles[ROTATION_ANGLE_COUNT] = {
 | 
				
			||||||
 | 
								[ROTATION_ANGLE_0] = 0,
 | 
				
			||||||
 | 
								[ROTATION_ANGLE_90] = 1,
 | 
				
			||||||
 | 
								[ROTATION_ANGLE_180] = 2,
 | 
				
			||||||
 | 
								[ROTATION_ANGLE_270] = 3,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) {
 | 
				
			||||||
 | 
							hw_rect.x = in_rect->y;
 | 
				
			||||||
 | 
							hw_rect.y = in_rect->x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hw_rect.height = in_rect->width;
 | 
				
			||||||
 | 
							hw_rect.width = in_rect->height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(GRPH_X_START, 0,
 | 
				
			||||||
 | 
								GRPH_X_START, hw_rect.x);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(GRPH_Y_START, 0,
 | 
				
			||||||
 | 
								GRPH_Y_START, hw_rect.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(GRPH_X_END, 0,
 | 
				
			||||||
 | 
								GRPH_X_END, hw_rect.width);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(GRPH_Y_END, 0,
 | 
				
			||||||
 | 
								GRPH_Y_END, hw_rect.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(GRPH_PITCH, 0,
 | 
				
			||||||
 | 
								GRPH_PITCH, plane_size->grph.surface_pitch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(HW_ROTATION, 0,
 | 
				
			||||||
 | 
								GRPH_ROTATION_ANGLE, rotation_angles[rotation]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void program_grph_pixel_format(
 | 
				
			||||||
 | 
						struct mem_input *mi,
 | 
				
			||||||
 | 
						enum surface_pixel_format format)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
 | 
				
			||||||
 | 
						uint32_t grph_depth, grph_format;
 | 
				
			||||||
 | 
						uint32_t sign = 0, floating = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (format == SURFACE_PIXEL_FORMAT_GRPH_BGRA8888 ||
 | 
				
			||||||
 | 
								/*todo: doesn't look like we handle BGRA here,
 | 
				
			||||||
 | 
								 *  should problem swap endian*/
 | 
				
			||||||
 | 
							format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
 | 
				
			||||||
 | 
							format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
 | 
				
			||||||
 | 
							format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
 | 
				
			||||||
 | 
							/* ABGR formats */
 | 
				
			||||||
 | 
							red_xbar = 2;
 | 
				
			||||||
 | 
							blue_xbar = 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET_2(GRPH_SWAP_CNTL, 0,
 | 
				
			||||||
 | 
								GRPH_RED_CROSSBAR, red_xbar,
 | 
				
			||||||
 | 
								GRPH_BLUE_CROSSBAR, blue_xbar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (format) {
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
 | 
				
			||||||
 | 
							grph_depth = 0;
 | 
				
			||||||
 | 
							grph_format = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
 | 
				
			||||||
 | 
							grph_depth = 1;
 | 
				
			||||||
 | 
							grph_format = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
 | 
				
			||||||
 | 
							grph_depth = 1;
 | 
				
			||||||
 | 
							grph_format = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
 | 
				
			||||||
 | 
							grph_depth = 2;
 | 
				
			||||||
 | 
							grph_format = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
 | 
				
			||||||
 | 
							grph_depth = 2;
 | 
				
			||||||
 | 
							grph_format = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
 | 
				
			||||||
 | 
							sign = 1;
 | 
				
			||||||
 | 
							floating = 1;
 | 
				
			||||||
 | 
							/* no break */
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */
 | 
				
			||||||
 | 
						case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
 | 
				
			||||||
 | 
							grph_depth = 3;
 | 
				
			||||||
 | 
							grph_format = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							DC_ERR("unsupported grph pixel format");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_UPDATE_2(GRPH_CONTROL,
 | 
				
			||||||
 | 
								GRPH_DEPTH, grph_depth,
 | 
				
			||||||
 | 
								GRPH_FORMAT, grph_format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_UPDATE_4(PRESCALE_GRPH_CONTROL,
 | 
				
			||||||
 | 
								GRPH_PRESCALE_SELECT, floating,
 | 
				
			||||||
 | 
								GRPH_PRESCALE_R_SIGN, sign,
 | 
				
			||||||
 | 
								GRPH_PRESCALE_G_SIGN, sign,
 | 
				
			||||||
 | 
								GRPH_PRESCALE_B_SIGN, sign);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce_mem_input_program_surface_config(struct mem_input *mi,
 | 
				
			||||||
 | 
						enum surface_pixel_format format,
 | 
				
			||||||
 | 
						union dc_tiling_info *tiling_info,
 | 
				
			||||||
 | 
						union plane_size *plane_size,
 | 
				
			||||||
 | 
						enum dc_rotation_angle rotation,
 | 
				
			||||||
 | 
						struct dc_plane_dcc_param *dcc,
 | 
				
			||||||
 | 
						bool horizontal_mirror)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						program_tiling(mi, tiling_info);
 | 
				
			||||||
 | 
						program_size_and_rotation(mi, rotation, plane_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
 | 
				
			||||||
 | 
							format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
 | 
				
			||||||
 | 
							program_grph_pixel_format(mi, format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t get_dmif_switch_time_us(
 | 
				
			||||||
 | 
						uint32_t h_total,
 | 
				
			||||||
 | 
						uint32_t v_total,
 | 
				
			||||||
 | 
						uint32_t pix_clk_khz)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t frame_time;
 | 
				
			||||||
 | 
						uint32_t pixels_per_second;
 | 
				
			||||||
 | 
						uint32_t pixels_per_frame;
 | 
				
			||||||
 | 
						uint32_t refresh_rate;
 | 
				
			||||||
 | 
						const uint32_t us_in_sec = 1000000;
 | 
				
			||||||
 | 
						const uint32_t min_single_frame_time_us = 30000;
 | 
				
			||||||
 | 
						/*return double of frame time*/
 | 
				
			||||||
 | 
						const uint32_t single_frame_time_multiplier = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!h_total || v_total || !pix_clk_khz)
 | 
				
			||||||
 | 
							return single_frame_time_multiplier * min_single_frame_time_us;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*TODO: should we use pixel format normalized pixel clock here?*/
 | 
				
			||||||
 | 
						pixels_per_second = pix_clk_khz * 1000;
 | 
				
			||||||
 | 
						pixels_per_frame = h_total * v_total;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!pixels_per_second || !pixels_per_frame) {
 | 
				
			||||||
 | 
							/* avoid division by zero */
 | 
				
			||||||
 | 
							ASSERT(pixels_per_frame);
 | 
				
			||||||
 | 
							ASSERT(pixels_per_second);
 | 
				
			||||||
 | 
							return single_frame_time_multiplier * min_single_frame_time_us;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						refresh_rate = pixels_per_second / pixels_per_frame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!refresh_rate) {
 | 
				
			||||||
 | 
							/* avoid division by zero*/
 | 
				
			||||||
 | 
							ASSERT(refresh_rate);
 | 
				
			||||||
 | 
							return single_frame_time_multiplier * min_single_frame_time_us;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						frame_time = us_in_sec / refresh_rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (frame_time < min_single_frame_time_us)
 | 
				
			||||||
 | 
							frame_time = min_single_frame_time_us;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						frame_time *= single_frame_time_multiplier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return frame_time;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_mem_input_allocate_dmif(struct mem_input *mi,
 | 
				
			||||||
 | 
						uint32_t h_total,
 | 
				
			||||||
 | 
						uint32_t v_total,
 | 
				
			||||||
 | 
						uint32_t pix_clk_khz,
 | 
				
			||||||
 | 
						uint32_t total_stream_num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const uint32_t retry_delay = 10;
 | 
				
			||||||
 | 
						uint32_t retry_count = get_dmif_switch_time_us(
 | 
				
			||||||
 | 
								h_total,
 | 
				
			||||||
 | 
								v_total,
 | 
				
			||||||
 | 
								pix_clk_khz) / retry_delay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t pix_dur;
 | 
				
			||||||
 | 
						uint32_t buffers_allocated;
 | 
				
			||||||
 | 
						uint32_t dmif_buffer_control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
 | 
				
			||||||
 | 
								DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buffers_allocated == 2)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
 | 
				
			||||||
 | 
								DMIF_BUFFERS_ALLOCATED, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_WAIT(DMIF_BUFFER_CONTROL,
 | 
				
			||||||
 | 
								DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
 | 
				
			||||||
 | 
								retry_delay, retry_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pix_clk_khz != 0) {
 | 
				
			||||||
 | 
							pix_dur = 1000000000ULL / pix_clk_khz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
 | 
				
			||||||
 | 
								PIXEL_DURATION, pix_dur);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mi->wa.single_head_rdreq_dmif_limit) {
 | 
				
			||||||
 | 
							uint32_t eanble =  (total_stream_num > 1) ? 0 :
 | 
				
			||||||
 | 
									mi->wa.single_head_rdreq_dmif_limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
 | 
				
			||||||
 | 
									ENABLE, eanble);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_mem_input_free_dmif(struct mem_input *mi,
 | 
				
			||||||
 | 
							uint32_t total_stream_num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t buffers_allocated;
 | 
				
			||||||
 | 
						uint32_t dmif_buffer_control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
 | 
				
			||||||
 | 
								DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buffers_allocated == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
 | 
				
			||||||
 | 
								DMIF_BUFFERS_ALLOCATED, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						REG_WAIT(DMIF_BUFFER_CONTROL,
 | 
				
			||||||
 | 
								DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
 | 
				
			||||||
 | 
								10, 0xBB8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mi->wa.single_head_rdreq_dmif_limit) {
 | 
				
			||||||
 | 
							uint32_t eanble =  (total_stream_num > 1) ? 0 :
 | 
				
			||||||
 | 
									mi->wa.single_head_rdreq_dmif_limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
 | 
				
			||||||
 | 
									ENABLE, eanble);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										217
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,217 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef __DCE_MEM_INPUT_H__
 | 
				
			||||||
 | 
					#define __DCE_MEM_INPUT_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_DCE_BASE_REG_LIST(id)\
 | 
				
			||||||
 | 
						SRI(GRPH_ENABLE, DCP, id),\
 | 
				
			||||||
 | 
						SRI(GRPH_CONTROL, DCP, id),\
 | 
				
			||||||
 | 
						SRI(GRPH_X_START, DCP, id),\
 | 
				
			||||||
 | 
						SRI(GRPH_Y_START, DCP, id),\
 | 
				
			||||||
 | 
						SRI(GRPH_X_END, DCP, id),\
 | 
				
			||||||
 | 
						SRI(GRPH_Y_END, DCP, id),\
 | 
				
			||||||
 | 
						SRI(GRPH_PITCH, DCP, id),\
 | 
				
			||||||
 | 
						SRI(HW_ROTATION, DCP, id),\
 | 
				
			||||||
 | 
						SRI(GRPH_SWAP_CNTL, DCP, id),\
 | 
				
			||||||
 | 
						SRI(PRESCALE_GRPH_CONTROL, DCP, id),\
 | 
				
			||||||
 | 
						SRI(DPG_PIPE_ARBITRATION_CONTROL1, DMIF_PG, id),\
 | 
				
			||||||
 | 
						SRI(DPG_WATERMARK_MASK_CONTROL, DMIF_PG, id),\
 | 
				
			||||||
 | 
						SRI(DPG_PIPE_URGENCY_CONTROL, DMIF_PG, id),\
 | 
				
			||||||
 | 
						SRI(DPG_PIPE_STUTTER_CONTROL, DMIF_PG, id),\
 | 
				
			||||||
 | 
						SRI(DMIF_BUFFER_CONTROL, PIPE, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_REG_LIST(id)\
 | 
				
			||||||
 | 
						MI_DCE_BASE_REG_LIST(id),\
 | 
				
			||||||
 | 
						SRI(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, DMIF_PG, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_mem_input_registers {
 | 
				
			||||||
 | 
						/* DCP */
 | 
				
			||||||
 | 
						uint32_t GRPH_ENABLE;
 | 
				
			||||||
 | 
						uint32_t GRPH_CONTROL;
 | 
				
			||||||
 | 
						uint32_t GRPH_X_START;
 | 
				
			||||||
 | 
						uint32_t GRPH_Y_START;
 | 
				
			||||||
 | 
						uint32_t GRPH_X_END;
 | 
				
			||||||
 | 
						uint32_t GRPH_Y_END;
 | 
				
			||||||
 | 
						uint32_t GRPH_PITCH;
 | 
				
			||||||
 | 
						uint32_t HW_ROTATION;
 | 
				
			||||||
 | 
						uint32_t GRPH_SWAP_CNTL;
 | 
				
			||||||
 | 
						uint32_t PRESCALE_GRPH_CONTROL;
 | 
				
			||||||
 | 
						/* DMIF_PG */
 | 
				
			||||||
 | 
						uint32_t DPG_PIPE_ARBITRATION_CONTROL1;
 | 
				
			||||||
 | 
						uint32_t DPG_WATERMARK_MASK_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DPG_PIPE_URGENCY_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DPG_PIPE_LOW_POWER_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DPG_PIPE_STUTTER_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DPG_PIPE_STUTTER_CONTROL2;
 | 
				
			||||||
 | 
						/* DCI */
 | 
				
			||||||
 | 
						uint32_t DMIF_BUFFER_CONTROL;
 | 
				
			||||||
 | 
						/* MC_HUB */
 | 
				
			||||||
 | 
						uint32_t MC_HUB_RDREQ_DMIF_LIMIT;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set_Filed_for_Block */
 | 
				
			||||||
 | 
					#define SFB(blk_name, reg_name, field_name, post_fix)\
 | 
				
			||||||
 | 
						.field_name = blk_name ## reg_name ## __ ## field_name ## post_fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_GFX8_TILE_MASK_SH_LIST(mask_sh, blk)\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_BANK_HEIGHT, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_TILE_SPLIT, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_MICRO_TILE_MODE, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_PIPE_CONFIG, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_ARRAY_MODE, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_DCP_MASK_SH_LIST(mask_sh, blk)\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_ENABLE, GRPH_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_DEPTH, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_FORMAT, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_CONTROL, GRPH_NUM_BANKS, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_X_START, GRPH_X_START, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_Y_START, GRPH_Y_START, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_X_END, GRPH_X_END, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_Y_END, GRPH_Y_END, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_PITCH, GRPH_PITCH, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, HW_ROTATION, GRPH_ROTATION_ANGLE, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_SWAP_CNTL, GRPH_RED_CROSSBAR, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, GRPH_SWAP_CNTL, GRPH_BLUE_CROSSBAR, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_SELECT, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_R_SIGN, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_G_SIGN, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_B_SIGN, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_DMIF_PG_MASK_SH_LIST(mask_sh, blk)\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_ARBITRATION_CONTROL1, PIXEL_DURATION, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_WATERMARK_MASK_CONTROL, URGENCY_WATERMARK_MASK, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_WATERMARK_MASK_CONTROL, STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_LOW_WATERMARK, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_URGENCY_CONTROL, URGENCY_HIGH_WATERMARK, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_IGNORE_FBC, mask_sh),\
 | 
				
			||||||
 | 
						SF(PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED, mask_sh),\
 | 
				
			||||||
 | 
						SF(PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATION_COMPLETED, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_DMIF_PG_MASK_SH_DCE(mask_sh, blk)\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_STUTTER_CONTROL, STUTTER_EXIT_SELF_REFRESH_WATERMARK, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_WATERMARK_MASK_CONTROL, NB_PSTATE_CHANGE_WATERMARK_MASK, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, mask_sh),\
 | 
				
			||||||
 | 
						SFB(blk, DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, NB_PSTATE_CHANGE_WATERMARK, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_DCE_MASK_SH_LIST(mask_sh)\
 | 
				
			||||||
 | 
						MI_DCP_MASK_SH_LIST(mask_sh,),\
 | 
				
			||||||
 | 
						MI_DMIF_PG_MASK_SH_LIST(mask_sh,),\
 | 
				
			||||||
 | 
						MI_DMIF_PG_MASK_SH_DCE(mask_sh,),\
 | 
				
			||||||
 | 
						MI_GFX8_TILE_MASK_SH_LIST(mask_sh,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI_REG_FIELD_LIST(type) \
 | 
				
			||||||
 | 
						type GRPH_ENABLE; \
 | 
				
			||||||
 | 
						type GRPH_X_START; \
 | 
				
			||||||
 | 
						type GRPH_Y_START; \
 | 
				
			||||||
 | 
						type GRPH_X_END; \
 | 
				
			||||||
 | 
						type GRPH_Y_END; \
 | 
				
			||||||
 | 
						type GRPH_PITCH; \
 | 
				
			||||||
 | 
						type GRPH_ROTATION_ANGLE; \
 | 
				
			||||||
 | 
						type GRPH_RED_CROSSBAR; \
 | 
				
			||||||
 | 
						type GRPH_BLUE_CROSSBAR; \
 | 
				
			||||||
 | 
						type GRPH_PRESCALE_SELECT; \
 | 
				
			||||||
 | 
						type GRPH_PRESCALE_R_SIGN; \
 | 
				
			||||||
 | 
						type GRPH_PRESCALE_G_SIGN; \
 | 
				
			||||||
 | 
						type GRPH_PRESCALE_B_SIGN; \
 | 
				
			||||||
 | 
						type GRPH_DEPTH; \
 | 
				
			||||||
 | 
						type GRPH_FORMAT; \
 | 
				
			||||||
 | 
						type GRPH_NUM_BANKS; \
 | 
				
			||||||
 | 
						type GRPH_BANK_WIDTH;\
 | 
				
			||||||
 | 
						type GRPH_BANK_HEIGHT;\
 | 
				
			||||||
 | 
						type GRPH_MACRO_TILE_ASPECT;\
 | 
				
			||||||
 | 
						type GRPH_TILE_SPLIT;\
 | 
				
			||||||
 | 
						type GRPH_MICRO_TILE_MODE;\
 | 
				
			||||||
 | 
						type GRPH_PIPE_CONFIG;\
 | 
				
			||||||
 | 
						type GRPH_ARRAY_MODE;\
 | 
				
			||||||
 | 
						type GRPH_COLOR_EXPANSION_MODE;\
 | 
				
			||||||
 | 
						type GRPH_SW_MODE; \
 | 
				
			||||||
 | 
						type GRPH_NUM_SHADER_ENGINES; \
 | 
				
			||||||
 | 
						type GRPH_NUM_PIPES; \
 | 
				
			||||||
 | 
						type PIXEL_DURATION; \
 | 
				
			||||||
 | 
						type URGENCY_WATERMARK_MASK; \
 | 
				
			||||||
 | 
						type PSTATE_CHANGE_WATERMARK_MASK; \
 | 
				
			||||||
 | 
						type NB_PSTATE_CHANGE_WATERMARK_MASK; \
 | 
				
			||||||
 | 
						type STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK; \
 | 
				
			||||||
 | 
						type URGENCY_LOW_WATERMARK; \
 | 
				
			||||||
 | 
						type URGENCY_HIGH_WATERMARK; \
 | 
				
			||||||
 | 
						type NB_PSTATE_CHANGE_ENABLE; \
 | 
				
			||||||
 | 
						type NB_PSTATE_CHANGE_URGENT_DURING_REQUEST; \
 | 
				
			||||||
 | 
						type NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \
 | 
				
			||||||
 | 
						type NB_PSTATE_CHANGE_WATERMARK; \
 | 
				
			||||||
 | 
						type PSTATE_CHANGE_ENABLE; \
 | 
				
			||||||
 | 
						type PSTATE_CHANGE_URGENT_DURING_REQUEST; \
 | 
				
			||||||
 | 
						type PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST; \
 | 
				
			||||||
 | 
						type PSTATE_CHANGE_WATERMARK; \
 | 
				
			||||||
 | 
						type STUTTER_ENABLE; \
 | 
				
			||||||
 | 
						type STUTTER_IGNORE_FBC; \
 | 
				
			||||||
 | 
						type STUTTER_EXIT_SELF_REFRESH_WATERMARK; \
 | 
				
			||||||
 | 
						type DMIF_BUFFERS_ALLOCATED; \
 | 
				
			||||||
 | 
						type DMIF_BUFFERS_ALLOCATION_COMPLETED; \
 | 
				
			||||||
 | 
						type ENABLE; /* MC_HUB_RDREQ_DMIF_LIMIT */\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_mem_input_shift {
 | 
				
			||||||
 | 
						MI_REG_FIELD_LIST(uint8_t)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_mem_input_mask {
 | 
				
			||||||
 | 
						MI_REG_FIELD_LIST(uint32_t)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_mem_input_wa {
 | 
				
			||||||
 | 
						uint8_t single_head_rdreq_dmif_limit;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mem_input;
 | 
				
			||||||
 | 
					bool dce_mem_input_program_surface_config(struct mem_input *mi,
 | 
				
			||||||
 | 
						enum surface_pixel_format format,
 | 
				
			||||||
 | 
						union dc_tiling_info *tiling_info,
 | 
				
			||||||
 | 
						union plane_size *plane_size,
 | 
				
			||||||
 | 
						enum dc_rotation_angle rotation,
 | 
				
			||||||
 | 
						struct dc_plane_dcc_param *dcc,
 | 
				
			||||||
 | 
						bool horizontal_mirror);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_mem_input_allocate_dmif(struct mem_input *mi,
 | 
				
			||||||
 | 
						uint32_t h_total,
 | 
				
			||||||
 | 
						uint32_t v_total,
 | 
				
			||||||
 | 
						uint32_t pix_clk_khz,
 | 
				
			||||||
 | 
						uint32_t total_stream_num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_mem_input_free_dmif(struct mem_input *mi,
 | 
				
			||||||
 | 
						uint32_t total_stream_num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce_mem_input_program_display_marks(struct mem_input *mi,
 | 
				
			||||||
 | 
						struct bw_watermarks nbp,
 | 
				
			||||||
 | 
						struct bw_watermarks stutter,
 | 
				
			||||||
 | 
						struct bw_watermarks urgent,
 | 
				
			||||||
 | 
						uint32_t total_dest_line_time_ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /*__DCE_MEM_INPUT_H__*/
 | 
				
			||||||
							
								
								
									
										501
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										501
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_scl_filters.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,501 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-16 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "transform.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_2tap_16p[18] = {
 | 
				
			||||||
 | 
						4096, 0,
 | 
				
			||||||
 | 
						3840, 256,
 | 
				
			||||||
 | 
						3584, 512,
 | 
				
			||||||
 | 
						3328, 768,
 | 
				
			||||||
 | 
						3072, 1024,
 | 
				
			||||||
 | 
						2816, 1280,
 | 
				
			||||||
 | 
						2560, 1536,
 | 
				
			||||||
 | 
						2304, 1792,
 | 
				
			||||||
 | 
						2048, 2048
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_16p_upscale[27] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						1708, 2424, 16348,
 | 
				
			||||||
 | 
						1372, 2796, 16308,
 | 
				
			||||||
 | 
						1056, 3148, 16272,
 | 
				
			||||||
 | 
						768, 3464, 16244,
 | 
				
			||||||
 | 
						512, 3728, 16236,
 | 
				
			||||||
 | 
						296, 3928, 16252,
 | 
				
			||||||
 | 
						124, 4052, 16296,
 | 
				
			||||||
 | 
						0, 4096, 0
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_16p_117[27] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						1824, 2276, 16376,
 | 
				
			||||||
 | 
						1600, 2496, 16380,
 | 
				
			||||||
 | 
						1376, 2700, 16,
 | 
				
			||||||
 | 
						1156, 2880, 52,
 | 
				
			||||||
 | 
						948, 3032, 108,
 | 
				
			||||||
 | 
						756, 3144, 192,
 | 
				
			||||||
 | 
						580, 3212, 296,
 | 
				
			||||||
 | 
						428, 3236, 428
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_16p_150[27] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						1872, 2184, 36,
 | 
				
			||||||
 | 
						1692, 2308, 88,
 | 
				
			||||||
 | 
						1516, 2420, 156,
 | 
				
			||||||
 | 
						1340, 2516, 236,
 | 
				
			||||||
 | 
						1168, 2592, 328,
 | 
				
			||||||
 | 
						1004, 2648, 440,
 | 
				
			||||||
 | 
						844, 2684, 560,
 | 
				
			||||||
 | 
						696, 2696, 696
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_16p_183[27] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						1892, 2104, 92,
 | 
				
			||||||
 | 
						1744, 2152, 196,
 | 
				
			||||||
 | 
						1592, 2196, 300,
 | 
				
			||||||
 | 
						1448, 2232, 412,
 | 
				
			||||||
 | 
						1304, 2256, 528,
 | 
				
			||||||
 | 
						1168, 2276, 648,
 | 
				
			||||||
 | 
						1032, 2288, 772,
 | 
				
			||||||
 | 
						900, 2292, 900
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_16p_upscale[36] = {
 | 
				
			||||||
 | 
						0, 4096, 0, 0,
 | 
				
			||||||
 | 
						16240, 4056, 180, 16380,
 | 
				
			||||||
 | 
						16136, 3952, 404, 16364,
 | 
				
			||||||
 | 
						16072, 3780, 664, 16344,
 | 
				
			||||||
 | 
						16040, 3556, 952, 16312,
 | 
				
			||||||
 | 
						16036, 3284, 1268, 16272,
 | 
				
			||||||
 | 
						16052, 2980, 1604, 16224,
 | 
				
			||||||
 | 
						16084, 2648, 1952, 16176,
 | 
				
			||||||
 | 
						16128, 2304, 2304, 16128
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_16p_117[36] = {
 | 
				
			||||||
 | 
						428, 3236, 428, 0,
 | 
				
			||||||
 | 
						276, 3232, 604, 16364,
 | 
				
			||||||
 | 
						148, 3184, 800, 16340,
 | 
				
			||||||
 | 
						44, 3104, 1016, 16312,
 | 
				
			||||||
 | 
						16344, 2984, 1244, 16284,
 | 
				
			||||||
 | 
						16284, 2832, 1488, 16256,
 | 
				
			||||||
 | 
						16244, 2648, 1732, 16236,
 | 
				
			||||||
 | 
						16220, 2440, 1976, 16220,
 | 
				
			||||||
 | 
						16212, 2216, 2216, 16212
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_16p_150[36] = {
 | 
				
			||||||
 | 
						696, 2700, 696, 0,
 | 
				
			||||||
 | 
						560, 2700, 848, 16364,
 | 
				
			||||||
 | 
						436, 2676, 1008, 16348,
 | 
				
			||||||
 | 
						328, 2628, 1180, 16336,
 | 
				
			||||||
 | 
						232, 2556, 1356, 16328,
 | 
				
			||||||
 | 
						152, 2460, 1536, 16328,
 | 
				
			||||||
 | 
						84, 2344, 1716, 16332,
 | 
				
			||||||
 | 
						28, 2208, 1888, 16348,
 | 
				
			||||||
 | 
						16376, 2052, 2052, 16376
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_16p_183[36] = {
 | 
				
			||||||
 | 
						940, 2208, 940, 0,
 | 
				
			||||||
 | 
						832, 2200, 1052, 4,
 | 
				
			||||||
 | 
						728, 2180, 1164, 16,
 | 
				
			||||||
 | 
						628, 2148, 1280, 36,
 | 
				
			||||||
 | 
						536, 2100, 1392, 60,
 | 
				
			||||||
 | 
						448, 2044, 1504, 92,
 | 
				
			||||||
 | 
						368, 1976, 1612, 132,
 | 
				
			||||||
 | 
						296, 1900, 1716, 176,
 | 
				
			||||||
 | 
						232, 1812, 1812, 232
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_2tap_64p[66] = {
 | 
				
			||||||
 | 
						4096, 0,
 | 
				
			||||||
 | 
						4032, 64,
 | 
				
			||||||
 | 
						3968, 128,
 | 
				
			||||||
 | 
						3904, 192,
 | 
				
			||||||
 | 
						3840, 256,
 | 
				
			||||||
 | 
						3776, 320,
 | 
				
			||||||
 | 
						3712, 384,
 | 
				
			||||||
 | 
						3648, 448,
 | 
				
			||||||
 | 
						3584, 512,
 | 
				
			||||||
 | 
						3520, 576,
 | 
				
			||||||
 | 
						3456, 640,
 | 
				
			||||||
 | 
						3392, 704,
 | 
				
			||||||
 | 
						3328, 768,
 | 
				
			||||||
 | 
						3264, 832,
 | 
				
			||||||
 | 
						3200, 896,
 | 
				
			||||||
 | 
						3136, 960,
 | 
				
			||||||
 | 
						3072, 1024,
 | 
				
			||||||
 | 
						3008, 1088,
 | 
				
			||||||
 | 
						2944, 1152,
 | 
				
			||||||
 | 
						2880, 1216,
 | 
				
			||||||
 | 
						2816, 1280,
 | 
				
			||||||
 | 
						2752, 1344,
 | 
				
			||||||
 | 
						2688, 1408,
 | 
				
			||||||
 | 
						2624, 1472,
 | 
				
			||||||
 | 
						2560, 1536,
 | 
				
			||||||
 | 
						2496, 1600,
 | 
				
			||||||
 | 
						2432, 1664,
 | 
				
			||||||
 | 
						2368, 1728,
 | 
				
			||||||
 | 
						2304, 1792,
 | 
				
			||||||
 | 
						2240, 1856,
 | 
				
			||||||
 | 
						2176, 1920,
 | 
				
			||||||
 | 
						2112, 1984,
 | 
				
			||||||
 | 
						2048, 2048 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_64p_upscale[99] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						1960, 2140, 16376,
 | 
				
			||||||
 | 
						1876, 2236, 16364,
 | 
				
			||||||
 | 
						1792, 2328, 16356,
 | 
				
			||||||
 | 
						1708, 2424, 16348,
 | 
				
			||||||
 | 
						1620, 2516, 16336,
 | 
				
			||||||
 | 
						1540, 2612, 16328,
 | 
				
			||||||
 | 
						1456, 2704, 16316,
 | 
				
			||||||
 | 
						1372, 2796, 16308,
 | 
				
			||||||
 | 
						1292, 2884, 16296,
 | 
				
			||||||
 | 
						1212, 2976, 16288,
 | 
				
			||||||
 | 
						1136, 3060, 16280,
 | 
				
			||||||
 | 
						1056, 3148, 16272,
 | 
				
			||||||
 | 
						984, 3228, 16264,
 | 
				
			||||||
 | 
						908, 3312, 16256,
 | 
				
			||||||
 | 
						836, 3388, 16248,
 | 
				
			||||||
 | 
						768, 3464, 16244,
 | 
				
			||||||
 | 
						700, 3536, 16240,
 | 
				
			||||||
 | 
						636, 3604, 16236,
 | 
				
			||||||
 | 
						572, 3668, 16236,
 | 
				
			||||||
 | 
						512, 3728, 16236,
 | 
				
			||||||
 | 
						456, 3784, 16236,
 | 
				
			||||||
 | 
						400, 3836, 16240,
 | 
				
			||||||
 | 
						348, 3884, 16244,
 | 
				
			||||||
 | 
						296, 3928, 16252,
 | 
				
			||||||
 | 
						252, 3964, 16260,
 | 
				
			||||||
 | 
						204, 4000, 16268,
 | 
				
			||||||
 | 
						164, 4028, 16284,
 | 
				
			||||||
 | 
						124, 4052, 16296,
 | 
				
			||||||
 | 
						88, 4072, 16316,
 | 
				
			||||||
 | 
						56, 4084, 16336,
 | 
				
			||||||
 | 
						24, 4092, 16356,
 | 
				
			||||||
 | 
						0, 4096, 0
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_64p_117[99] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						1992, 2104, 16380,
 | 
				
			||||||
 | 
						1936, 2160, 16380,
 | 
				
			||||||
 | 
						1880, 2220, 16376,
 | 
				
			||||||
 | 
						1824, 2276, 16376,
 | 
				
			||||||
 | 
						1768, 2332, 16376,
 | 
				
			||||||
 | 
						1712, 2388, 16376,
 | 
				
			||||||
 | 
						1656, 2444, 16376,
 | 
				
			||||||
 | 
						1600, 2496, 16380,
 | 
				
			||||||
 | 
						1544, 2548, 0,
 | 
				
			||||||
 | 
						1488, 2600, 4,
 | 
				
			||||||
 | 
						1432, 2652, 8,
 | 
				
			||||||
 | 
						1376, 2700, 16,
 | 
				
			||||||
 | 
						1320, 2748, 20,
 | 
				
			||||||
 | 
						1264, 2796, 32,
 | 
				
			||||||
 | 
						1212, 2840, 40,
 | 
				
			||||||
 | 
						1156, 2880, 52,
 | 
				
			||||||
 | 
						1104, 2920, 64,
 | 
				
			||||||
 | 
						1052, 2960, 80,
 | 
				
			||||||
 | 
						1000, 2996, 92,
 | 
				
			||||||
 | 
						948, 3032, 108,
 | 
				
			||||||
 | 
						900, 3060, 128,
 | 
				
			||||||
 | 
						852, 3092, 148,
 | 
				
			||||||
 | 
						804, 3120, 168,
 | 
				
			||||||
 | 
						756, 3144, 192,
 | 
				
			||||||
 | 
						712, 3164, 216,
 | 
				
			||||||
 | 
						668, 3184, 240,
 | 
				
			||||||
 | 
						624, 3200, 268,
 | 
				
			||||||
 | 
						580, 3212, 296,
 | 
				
			||||||
 | 
						540, 3220, 328,
 | 
				
			||||||
 | 
						500, 3228, 360,
 | 
				
			||||||
 | 
						464, 3232, 392,
 | 
				
			||||||
 | 
						428, 3236, 428
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_64p_150[99] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						2004, 2080, 8,
 | 
				
			||||||
 | 
						1960, 2116, 16,
 | 
				
			||||||
 | 
						1916, 2148, 28,
 | 
				
			||||||
 | 
						1872, 2184, 36,
 | 
				
			||||||
 | 
						1824, 2216, 48,
 | 
				
			||||||
 | 
						1780, 2248, 60,
 | 
				
			||||||
 | 
						1736, 2280, 76,
 | 
				
			||||||
 | 
						1692, 2308, 88,
 | 
				
			||||||
 | 
						1648, 2336, 104,
 | 
				
			||||||
 | 
						1604, 2368, 120,
 | 
				
			||||||
 | 
						1560, 2392, 136,
 | 
				
			||||||
 | 
						1516, 2420, 156,
 | 
				
			||||||
 | 
						1472, 2444, 172,
 | 
				
			||||||
 | 
						1428, 2472, 192,
 | 
				
			||||||
 | 
						1384, 2492, 212,
 | 
				
			||||||
 | 
						1340, 2516, 236,
 | 
				
			||||||
 | 
						1296, 2536, 256,
 | 
				
			||||||
 | 
						1252, 2556, 280,
 | 
				
			||||||
 | 
						1212, 2576, 304,
 | 
				
			||||||
 | 
						1168, 2592, 328,
 | 
				
			||||||
 | 
						1124, 2608, 356,
 | 
				
			||||||
 | 
						1084, 2624, 384,
 | 
				
			||||||
 | 
						1044, 2636, 412,
 | 
				
			||||||
 | 
						1004, 2648, 440,
 | 
				
			||||||
 | 
						964, 2660, 468,
 | 
				
			||||||
 | 
						924, 2668, 500,
 | 
				
			||||||
 | 
						884, 2676, 528,
 | 
				
			||||||
 | 
						844, 2684, 560,
 | 
				
			||||||
 | 
						808, 2688, 596,
 | 
				
			||||||
 | 
						768, 2692, 628,
 | 
				
			||||||
 | 
						732, 2696, 664,
 | 
				
			||||||
 | 
						696, 2696, 696
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_3tap_64p_183[99] = {
 | 
				
			||||||
 | 
						2048, 2048, 0,
 | 
				
			||||||
 | 
						2008, 2060, 20,
 | 
				
			||||||
 | 
						1968, 2076, 44,
 | 
				
			||||||
 | 
						1932, 2088, 68,
 | 
				
			||||||
 | 
						1892, 2104, 92,
 | 
				
			||||||
 | 
						1856, 2116, 120,
 | 
				
			||||||
 | 
						1816, 2128, 144,
 | 
				
			||||||
 | 
						1780, 2140, 168,
 | 
				
			||||||
 | 
						1744, 2152, 196,
 | 
				
			||||||
 | 
						1704, 2164, 220,
 | 
				
			||||||
 | 
						1668, 2176, 248,
 | 
				
			||||||
 | 
						1632, 2188, 272,
 | 
				
			||||||
 | 
						1592, 2196, 300,
 | 
				
			||||||
 | 
						1556, 2204, 328,
 | 
				
			||||||
 | 
						1520, 2216, 356,
 | 
				
			||||||
 | 
						1484, 2224, 384,
 | 
				
			||||||
 | 
						1448, 2232, 412,
 | 
				
			||||||
 | 
						1412, 2240, 440,
 | 
				
			||||||
 | 
						1376, 2244, 468,
 | 
				
			||||||
 | 
						1340, 2252, 496,
 | 
				
			||||||
 | 
						1304, 2256, 528,
 | 
				
			||||||
 | 
						1272, 2264, 556,
 | 
				
			||||||
 | 
						1236, 2268, 584,
 | 
				
			||||||
 | 
						1200, 2272, 616,
 | 
				
			||||||
 | 
						1168, 2276, 648,
 | 
				
			||||||
 | 
						1132, 2280, 676,
 | 
				
			||||||
 | 
						1100, 2284, 708,
 | 
				
			||||||
 | 
						1064, 2288, 740,
 | 
				
			||||||
 | 
						1032, 2288, 772,
 | 
				
			||||||
 | 
						996, 2292, 800,
 | 
				
			||||||
 | 
						964, 2292, 832,
 | 
				
			||||||
 | 
						932, 2292, 868,
 | 
				
			||||||
 | 
						900, 2292, 900
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_64p_upscale[132] = {
 | 
				
			||||||
 | 
						0, 4096, 0, 0,
 | 
				
			||||||
 | 
						16344, 4092, 40, 0,
 | 
				
			||||||
 | 
						16308, 4084, 84, 16380,
 | 
				
			||||||
 | 
						16272, 4072, 132, 16380,
 | 
				
			||||||
 | 
						16240, 4056, 180, 16380,
 | 
				
			||||||
 | 
						16212, 4036, 232, 16376,
 | 
				
			||||||
 | 
						16184, 4012, 288, 16372,
 | 
				
			||||||
 | 
						16160, 3984, 344, 16368,
 | 
				
			||||||
 | 
						16136, 3952, 404, 16364,
 | 
				
			||||||
 | 
						16116, 3916, 464, 16360,
 | 
				
			||||||
 | 
						16100, 3872, 528, 16356,
 | 
				
			||||||
 | 
						16084, 3828, 596, 16348,
 | 
				
			||||||
 | 
						16072, 3780, 664, 16344,
 | 
				
			||||||
 | 
						16060, 3728, 732, 16336,
 | 
				
			||||||
 | 
						16052, 3676, 804, 16328,
 | 
				
			||||||
 | 
						16044, 3616, 876, 16320,
 | 
				
			||||||
 | 
						16040, 3556, 952, 16312,
 | 
				
			||||||
 | 
						16036, 3492, 1028, 16300,
 | 
				
			||||||
 | 
						16032, 3424, 1108, 16292,
 | 
				
			||||||
 | 
						16032, 3356, 1188, 16280,
 | 
				
			||||||
 | 
						16036, 3284, 1268, 16272,
 | 
				
			||||||
 | 
						16036, 3212, 1352, 16260,
 | 
				
			||||||
 | 
						16040, 3136, 1436, 16248,
 | 
				
			||||||
 | 
						16044, 3056, 1520, 16236,
 | 
				
			||||||
 | 
						16052, 2980, 1604, 16224,
 | 
				
			||||||
 | 
						16060, 2896, 1688, 16212,
 | 
				
			||||||
 | 
						16064, 2816, 1776, 16200,
 | 
				
			||||||
 | 
						16076, 2732, 1864, 16188,
 | 
				
			||||||
 | 
						16084, 2648, 1952, 16176,
 | 
				
			||||||
 | 
						16092, 2564, 2040, 16164,
 | 
				
			||||||
 | 
						16104, 2476, 2128, 16152,
 | 
				
			||||||
 | 
						16116, 2388, 2216, 16140,
 | 
				
			||||||
 | 
						16128, 2304, 2304, 16128 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_64p_117[132] = {
 | 
				
			||||||
 | 
						420, 3248, 420, 0,
 | 
				
			||||||
 | 
						380, 3248, 464, 16380,
 | 
				
			||||||
 | 
						344, 3248, 508, 16372,
 | 
				
			||||||
 | 
						308, 3248, 552, 16368,
 | 
				
			||||||
 | 
						272, 3240, 596, 16364,
 | 
				
			||||||
 | 
						236, 3236, 644, 16356,
 | 
				
			||||||
 | 
						204, 3224, 692, 16352,
 | 
				
			||||||
 | 
						172, 3212, 744, 16344,
 | 
				
			||||||
 | 
						144, 3196, 796, 16340,
 | 
				
			||||||
 | 
						116, 3180, 848, 16332,
 | 
				
			||||||
 | 
						88, 3160, 900, 16324,
 | 
				
			||||||
 | 
						60, 3136, 956, 16320,
 | 
				
			||||||
 | 
						36, 3112, 1012, 16312,
 | 
				
			||||||
 | 
						16, 3084, 1068, 16304,
 | 
				
			||||||
 | 
						16380, 3056, 1124, 16296,
 | 
				
			||||||
 | 
						16360, 3024, 1184, 16292,
 | 
				
			||||||
 | 
						16340, 2992, 1244, 16284,
 | 
				
			||||||
 | 
						16324, 2956, 1304, 16276,
 | 
				
			||||||
 | 
						16308, 2920, 1364, 16268,
 | 
				
			||||||
 | 
						16292, 2880, 1424, 16264,
 | 
				
			||||||
 | 
						16280, 2836, 1484, 16256,
 | 
				
			||||||
 | 
						16268, 2792, 1548, 16252,
 | 
				
			||||||
 | 
						16256, 2748, 1608, 16244,
 | 
				
			||||||
 | 
						16248, 2700, 1668, 16240,
 | 
				
			||||||
 | 
						16240, 2652, 1732, 16232,
 | 
				
			||||||
 | 
						16232, 2604, 1792, 16228,
 | 
				
			||||||
 | 
						16228, 2552, 1856, 16224,
 | 
				
			||||||
 | 
						16220, 2500, 1916, 16220,
 | 
				
			||||||
 | 
						16216, 2444, 1980, 16216,
 | 
				
			||||||
 | 
						16216, 2388, 2040, 16216,
 | 
				
			||||||
 | 
						16212, 2332, 2100, 16212,
 | 
				
			||||||
 | 
						16212, 2276, 2160, 16212,
 | 
				
			||||||
 | 
						16212, 2220, 2220, 16212 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_64p_150[132] = {
 | 
				
			||||||
 | 
						696, 2700, 696, 0,
 | 
				
			||||||
 | 
						660, 2704, 732, 16380,
 | 
				
			||||||
 | 
						628, 2704, 768, 16376,
 | 
				
			||||||
 | 
						596, 2704, 804, 16372,
 | 
				
			||||||
 | 
						564, 2700, 844, 16364,
 | 
				
			||||||
 | 
						532, 2696, 884, 16360,
 | 
				
			||||||
 | 
						500, 2692, 924, 16356,
 | 
				
			||||||
 | 
						472, 2684, 964, 16352,
 | 
				
			||||||
 | 
						440, 2676, 1004, 16352,
 | 
				
			||||||
 | 
						412, 2668, 1044, 16348,
 | 
				
			||||||
 | 
						384, 2656, 1088, 16344,
 | 
				
			||||||
 | 
						360, 2644, 1128, 16340,
 | 
				
			||||||
 | 
						332, 2632, 1172, 16336,
 | 
				
			||||||
 | 
						308, 2616, 1216, 16336,
 | 
				
			||||||
 | 
						284, 2600, 1260, 16332,
 | 
				
			||||||
 | 
						260, 2580, 1304, 16332,
 | 
				
			||||||
 | 
						236, 2560, 1348, 16328,
 | 
				
			||||||
 | 
						216, 2540, 1392, 16328,
 | 
				
			||||||
 | 
						196, 2516, 1436, 16328,
 | 
				
			||||||
 | 
						176, 2492, 1480, 16324,
 | 
				
			||||||
 | 
						156, 2468, 1524, 16324,
 | 
				
			||||||
 | 
						136, 2440, 1568, 16328,
 | 
				
			||||||
 | 
						120, 2412, 1612, 16328,
 | 
				
			||||||
 | 
						104, 2384, 1656, 16328,
 | 
				
			||||||
 | 
						88, 2352, 1700, 16332,
 | 
				
			||||||
 | 
						72, 2324, 1744, 16332,
 | 
				
			||||||
 | 
						60, 2288, 1788, 16336,
 | 
				
			||||||
 | 
						48, 2256, 1828, 16340,
 | 
				
			||||||
 | 
						36, 2220, 1872, 16344,
 | 
				
			||||||
 | 
						24, 2184, 1912, 16352,
 | 
				
			||||||
 | 
						12, 2148, 1952, 16356,
 | 
				
			||||||
 | 
						4, 2112, 1996, 16364,
 | 
				
			||||||
 | 
						16380, 2072, 2036, 16372 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t filter_4tap_64p_183[132] = {
 | 
				
			||||||
 | 
						944, 2204, 944, 0,
 | 
				
			||||||
 | 
						916, 2204, 972, 0,
 | 
				
			||||||
 | 
						888, 2200, 996, 0,
 | 
				
			||||||
 | 
						860, 2200, 1024, 4,
 | 
				
			||||||
 | 
						832, 2196, 1052, 4,
 | 
				
			||||||
 | 
						808, 2192, 1080, 8,
 | 
				
			||||||
 | 
						780, 2188, 1108, 12,
 | 
				
			||||||
 | 
						756, 2180, 1140, 12,
 | 
				
			||||||
 | 
						728, 2176, 1168, 16,
 | 
				
			||||||
 | 
						704, 2168, 1196, 20,
 | 
				
			||||||
 | 
						680, 2160, 1224, 24,
 | 
				
			||||||
 | 
						656, 2152, 1252, 28,
 | 
				
			||||||
 | 
						632, 2144, 1280, 36,
 | 
				
			||||||
 | 
						608, 2132, 1308, 40,
 | 
				
			||||||
 | 
						584, 2120, 1336, 48,
 | 
				
			||||||
 | 
						560, 2112, 1364, 52,
 | 
				
			||||||
 | 
						536, 2096, 1392, 60,
 | 
				
			||||||
 | 
						516, 2084, 1420, 68,
 | 
				
			||||||
 | 
						492, 2072, 1448, 76,
 | 
				
			||||||
 | 
						472, 2056, 1476, 84,
 | 
				
			||||||
 | 
						452, 2040, 1504, 92,
 | 
				
			||||||
 | 
						428, 2024, 1532, 100,
 | 
				
			||||||
 | 
						408, 2008, 1560, 112,
 | 
				
			||||||
 | 
						392, 1992, 1584, 120,
 | 
				
			||||||
 | 
						372, 1972, 1612, 132,
 | 
				
			||||||
 | 
						352, 1956, 1636, 144,
 | 
				
			||||||
 | 
						336, 1936, 1664, 156,
 | 
				
			||||||
 | 
						316, 1916, 1688, 168,
 | 
				
			||||||
 | 
						300, 1896, 1712, 180,
 | 
				
			||||||
 | 
						284, 1876, 1736, 192,
 | 
				
			||||||
 | 
						268, 1852, 1760, 208,
 | 
				
			||||||
 | 
						252, 1832, 1784, 220,
 | 
				
			||||||
 | 
						236, 1808, 1808, 236 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t *get_filter_3tap_16p(struct fixed31_32 ratio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ratio.value < dal_fixed31_32_one.value)
 | 
				
			||||||
 | 
							return filter_3tap_16p_upscale;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value)
 | 
				
			||||||
 | 
							return filter_3tap_16p_117;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value)
 | 
				
			||||||
 | 
							return filter_3tap_16p_150;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return filter_3tap_16p_183;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t *get_filter_3tap_64p(struct fixed31_32 ratio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ratio.value < dal_fixed31_32_one.value)
 | 
				
			||||||
 | 
							return filter_3tap_64p_upscale;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value)
 | 
				
			||||||
 | 
							return filter_3tap_64p_117;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value)
 | 
				
			||||||
 | 
							return filter_3tap_64p_150;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return filter_3tap_64p_183;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t *get_filter_4tap_16p(struct fixed31_32 ratio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ratio.value < dal_fixed31_32_one.value)
 | 
				
			||||||
 | 
							return filter_4tap_16p_upscale;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value)
 | 
				
			||||||
 | 
							return filter_4tap_16p_117;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value)
 | 
				
			||||||
 | 
							return filter_4tap_16p_150;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return filter_4tap_16p_183;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uint16_t *get_filter_4tap_64p(struct fixed31_32 ratio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ratio.value < dal_fixed31_32_one.value)
 | 
				
			||||||
 | 
							return filter_4tap_64p_upscale;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(4, 3).value)
 | 
				
			||||||
 | 
							return filter_4tap_64p_117;
 | 
				
			||||||
 | 
						else if (ratio.value < dal_fixed31_32_from_fraction(5, 3).value)
 | 
				
			||||||
 | 
							return filter_4tap_64p_150;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return filter_4tap_64p_183;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1302
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1302
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										564
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										564
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,564 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DC_STREAM_ENCODER_DCE110_H__
 | 
				
			||||||
 | 
					#define __DC_STREAM_ENCODER_DCE110_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "stream_encoder.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DCE110STRENC_FROM_STRENC(stream_encoder)\
 | 
				
			||||||
 | 
						container_of(stream_encoder, struct dce110_stream_encoder, base)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TMDS_CNTL__TMDS_PIXEL_ENCODING_MASK
 | 
				
			||||||
 | 
						#define TMDS_CNTL__TMDS_PIXEL_ENCODING_MASK       0x00000010L
 | 
				
			||||||
 | 
						#define TMDS_CNTL__TMDS_COLOR_FORMAT_MASK         0x00000300L
 | 
				
			||||||
 | 
						#define	TMDS_CNTL__TMDS_PIXEL_ENCODING__SHIFT     0x00000004
 | 
				
			||||||
 | 
						#define	TMDS_CNTL__TMDS_COLOR_FORMAT__SHIFT       0x00000008
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_REG_LIST_DCE_BASE(id) \
 | 
				
			||||||
 | 
						SE_COMMON_REG_LIST_BASE(id),\
 | 
				
			||||||
 | 
						SRI(AFMT_AVI_INFO0, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_AVI_INFO1, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_AVI_INFO2, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_AVI_INFO3, DIG, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_REG_LIST_BASE(id) \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_0, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_1, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_2, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_3, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_4, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_5, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_6, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_7, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_GENERIC_HDR, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_INFOFRAME_CONTROL0, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_VBI_PACKET_CONTROL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_AUDIO_PACKET_CONTROL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_AUDIO_PACKET_CONTROL2, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_AUDIO_SRC_CONTROL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_60958_0, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_60958_1, DIG, id), \
 | 
				
			||||||
 | 
						SRI(AFMT_60958_2, DIG, id), \
 | 
				
			||||||
 | 
						SRI(DIG_FE_CNTL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_CONTROL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_GC, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_GENERIC_PACKET_CONTROL1, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_INFOFRAME_CONTROL0, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_INFOFRAME_CONTROL1, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_VBI_PACKET_CONTROL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(HDMI_AUDIO_PACKET_CONTROL, DIG, id),\
 | 
				
			||||||
 | 
						SRI(HDMI_ACR_PACKET_CONTROL, DIG, id),\
 | 
				
			||||||
 | 
						SRI(HDMI_ACR_32_0, DIG, id),\
 | 
				
			||||||
 | 
						SRI(HDMI_ACR_32_1, DIG, id),\
 | 
				
			||||||
 | 
						SRI(HDMI_ACR_44_0, DIG, id),\
 | 
				
			||||||
 | 
						SRI(HDMI_ACR_44_1, DIG, id),\
 | 
				
			||||||
 | 
						SRI(HDMI_ACR_48_0, DIG, id),\
 | 
				
			||||||
 | 
						SRI(HDMI_ACR_48_1, DIG, id),\
 | 
				
			||||||
 | 
						SRI(TMDS_CNTL, DIG, id), \
 | 
				
			||||||
 | 
						SRI(DP_MSE_RATE_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_MSE_RATE_UPDATE, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_PIXEL_FORMAT, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_SEC_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_STEER_FIFO, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_VID_M, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_VID_N, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_VID_STREAM_CNTL, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_VID_TIMING, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_SEC_AUD_N, DP, id), \
 | 
				
			||||||
 | 
						SRI(DP_SEC_TIMESTAMP, DP, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_REG_LIST(id)\
 | 
				
			||||||
 | 
						SE_COMMON_REG_LIST_DCE_BASE(id), \
 | 
				
			||||||
 | 
						SRI(AFMT_CNTL, DIG, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_SF(reg_name, field_name, post_fix)\
 | 
				
			||||||
 | 
						.field_name = reg_name ## __ ## field_name ## post_fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)\
 | 
				
			||||||
 | 
						SE_SF(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_INDEX, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC0_UPDATE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC2_UPDATE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_GENERIC_HDR, AFMT_GENERIC_HB0, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_GENERIC_HDR, AFMT_GENERIC_HB1, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_GENERIC_HDR, AFMT_GENERIC_HB2, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_GENERIC_HDR, AFMT_GENERIC_HB3, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_CONT, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_SEND, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_LINE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_CONT, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_SEND, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_LINE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_PIXEL_FORMAT, DP_DYN_RANGE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_PIXEL_FORMAT, DP_YCBCR_RANGE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_PACKET_GEN_VERSION, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_KEEPOUT_MODE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_DEEP_COLOR_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_GC, HDMI_GC_AVMUTE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_MSE_RATE_CNTL, DP_MSE_RATE_X, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_MSE_RATE_CNTL, DP_MSE_RATE_Y, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_MSE_RATE_UPDATE, DP_MSE_RATE_UPDATE_PENDING, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_AVI_INFO3, AFMT_AVI_INFO_VERSION, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_INFOFRAME_CONTROL0, HDMI_AVI_INFO_SEND, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_INFOFRAME_CONTROL0, HDMI_AVI_INFO_CONT, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_INFOFRAME_CONTROL1, HDMI_AVI_INFO_LINE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_GSP1_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_AVI_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_MPG_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_STEER_FIFO, DP_STEER_FIFO_RESET, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_VID_TIMING, DP_VID_M_N_GEN_EN, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_VID_N, DP_VID_N, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_VID_M, DP_VID_M, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DIG_FE_CNTL, DIG_START, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_AUDIO_SRC_CONTROL, AFMT_AUDIO_SRC_SELECT, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_AUDIO_PACKET_CONTROL, HDMI_AUDIO_PACKETS_PER_LINE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_AUDIO_PACKET_CONTROL, HDMI_AUDIO_DELAY_EN, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_LAYOUT_OVRD, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_AUDIO_PACKET_CONTROL2, AFMT_60958_OSF_OVRD, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUTO_SEND, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_PACKET_CONTROL, HDMI_ACR_SOURCE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUDIO_PRIORITY, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_32_0, HDMI_ACR_CTS_32, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_32_1, HDMI_ACR_N_32, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_44_0, HDMI_ACR_CTS_44, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_44_1, HDMI_ACR_N_44, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_48_0, HDMI_ACR_CTS_48, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_ACR_48_1, HDMI_ACR_N_48, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_0, AFMT_60958_CS_CHANNEL_NUMBER_L, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_2, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_3, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_4, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_5, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_6, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_7, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_AUD_N, DP_SEC_AUD_N, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_TIMESTAMP, DP_SEC_TIMESTAMP_MODE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_ASP_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_ATP_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_AIP_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_SEC_CNTL, DP_SEC_ACM_ENABLE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh)\
 | 
				
			||||||
 | 
						SE_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_MASK_SH_LIST_DCE80_100(mask_sh)\
 | 
				
			||||||
 | 
						SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(TMDS_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_MASK_SH_LIST_DCE110(mask_sh)\
 | 
				
			||||||
 | 
						SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_CLOCK_CHANNEL_RATE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DIG_FE_CNTL, TMDS_COLOR_FORMAT, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SE_COMMON_MASK_SH_LIST_DCE112(mask_sh)\
 | 
				
			||||||
 | 
						SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_CLOCK_CHANNEL_RATE, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DIG_FE_CNTL, TMDS_COLOR_FORMAT, mask_sh),\
 | 
				
			||||||
 | 
						SE_SF(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_stream_encoder_shift {
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_INDEX;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC0_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC2_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_HB0;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_HB1;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_HB2;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_HB3;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_LOCK_STATUS;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_CONFLICT;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC_CONFLICT_CLR;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC0_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC1_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC2_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC3_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC4_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC5_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC6_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC7_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC0_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC1_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC2_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC3_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC4_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC5_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC6_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_GENERIC7_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint8_t HDMI_GENERIC0_CONT;
 | 
				
			||||||
 | 
						uint8_t HDMI_GENERIC0_SEND;
 | 
				
			||||||
 | 
						uint8_t HDMI_GENERIC0_LINE;
 | 
				
			||||||
 | 
						uint8_t HDMI_GENERIC1_CONT;
 | 
				
			||||||
 | 
						uint8_t HDMI_GENERIC1_SEND;
 | 
				
			||||||
 | 
						uint8_t HDMI_GENERIC1_LINE;
 | 
				
			||||||
 | 
						uint8_t DP_PIXEL_ENCODING;
 | 
				
			||||||
 | 
						uint8_t DP_COMPONENT_DEPTH;
 | 
				
			||||||
 | 
						uint8_t DP_DYN_RANGE;
 | 
				
			||||||
 | 
						uint8_t DP_YCBCR_RANGE;
 | 
				
			||||||
 | 
						uint8_t HDMI_PACKET_GEN_VERSION;
 | 
				
			||||||
 | 
						uint8_t HDMI_KEEPOUT_MODE;
 | 
				
			||||||
 | 
						uint8_t HDMI_DEEP_COLOR_ENABLE;
 | 
				
			||||||
 | 
						uint8_t HDMI_CLOCK_CHANNEL_RATE;
 | 
				
			||||||
 | 
						uint8_t HDMI_DEEP_COLOR_DEPTH;
 | 
				
			||||||
 | 
						uint8_t HDMI_GC_CONT;
 | 
				
			||||||
 | 
						uint8_t HDMI_GC_SEND;
 | 
				
			||||||
 | 
						uint8_t HDMI_NULL_SEND;
 | 
				
			||||||
 | 
						uint8_t HDMI_DATA_SCRAMBLE_EN;
 | 
				
			||||||
 | 
						uint8_t HDMI_AUDIO_INFO_SEND;
 | 
				
			||||||
 | 
						uint8_t AFMT_AUDIO_INFO_UPDATE;
 | 
				
			||||||
 | 
						uint8_t HDMI_AUDIO_INFO_LINE;
 | 
				
			||||||
 | 
						uint8_t HDMI_GC_AVMUTE;
 | 
				
			||||||
 | 
						uint8_t DP_MSE_RATE_X;
 | 
				
			||||||
 | 
						uint8_t DP_MSE_RATE_Y;
 | 
				
			||||||
 | 
						uint8_t DP_MSE_RATE_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint8_t AFMT_AVI_INFO_VERSION;
 | 
				
			||||||
 | 
						uint8_t HDMI_AVI_INFO_SEND;
 | 
				
			||||||
 | 
						uint8_t HDMI_AVI_INFO_CONT;
 | 
				
			||||||
 | 
						uint8_t HDMI_AVI_INFO_LINE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP0_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_STREAM_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP1_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP2_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP3_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP4_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP5_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP6_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_GSP7_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_AVI_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_MPG_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_VID_STREAM_DIS_DEFER;
 | 
				
			||||||
 | 
						uint8_t DP_VID_STREAM_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_VID_STREAM_STATUS;
 | 
				
			||||||
 | 
						uint8_t DP_STEER_FIFO_RESET;
 | 
				
			||||||
 | 
						uint8_t DP_VID_M_N_GEN_EN;
 | 
				
			||||||
 | 
						uint8_t DP_VID_N;
 | 
				
			||||||
 | 
						uint8_t DP_VID_M;
 | 
				
			||||||
 | 
						uint8_t DIG_START;
 | 
				
			||||||
 | 
						uint8_t AFMT_AUDIO_SRC_SELECT;
 | 
				
			||||||
 | 
						uint8_t AFMT_AUDIO_CHANNEL_ENABLE;
 | 
				
			||||||
 | 
						uint8_t HDMI_AUDIO_PACKETS_PER_LINE;
 | 
				
			||||||
 | 
						uint8_t HDMI_AUDIO_DELAY_EN;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_UPDATE;
 | 
				
			||||||
 | 
						uint8_t AFMT_AUDIO_LAYOUT_OVRD;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_OSF_OVRD;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_AUTO_SEND;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_SOURCE;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_AUDIO_PRIORITY;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_CTS_32;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_N_32;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_CTS_44;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_N_44;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_CTS_48;
 | 
				
			||||||
 | 
						uint8_t HDMI_ACR_N_48;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_L;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CLOCK_ACCURACY;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_R;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_2;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_3;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_4;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_5;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_6;
 | 
				
			||||||
 | 
						uint8_t AFMT_60958_CS_CHANNEL_NUMBER_7;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_AUD_N;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_TIMESTAMP_MODE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_ASP_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_ATP_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_AIP_ENABLE;
 | 
				
			||||||
 | 
						uint8_t DP_SEC_ACM_ENABLE;
 | 
				
			||||||
 | 
						uint8_t AFMT_AUDIO_SAMPLE_SEND;
 | 
				
			||||||
 | 
						uint8_t AFMT_AUDIO_CLOCK_EN;
 | 
				
			||||||
 | 
						uint8_t TMDS_PIXEL_ENCODING;
 | 
				
			||||||
 | 
						uint8_t TMDS_COLOR_FORMAT;
 | 
				
			||||||
 | 
						uint8_t DP_DB_DISABLE;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_MISC0;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_HTOTAL;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_VTOTAL;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_HSTART;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_VSTART;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_HSYNCWIDTH;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_HSYNCPOLARITY;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_VSYNCWIDTH;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_VSYNCPOLARITY;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_HWIDTH;
 | 
				
			||||||
 | 
						uint8_t DP_MSA_VHEIGHT;
 | 
				
			||||||
 | 
						uint8_t HDMI_DB_DISABLE;
 | 
				
			||||||
 | 
						uint8_t DP_VID_N_MUL;
 | 
				
			||||||
 | 
						uint8_t DP_VID_M_DOUBLE_VALUE_EN;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_stream_encoder_mask {
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_INDEX;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC0_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC2_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_HB0;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_HB1;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_HB2;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_HB3;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_LOCK_STATUS;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_CONFLICT;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_CONFLICT_CLR;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC0_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC1_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC2_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC3_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC4_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC5_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC6_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC7_FRAME_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC0_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC1_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC2_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC3_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC4_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC5_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC6_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC7_FRAME_UPDATE;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC0_CONT;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC0_SEND;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC0_LINE;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC1_CONT;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC1_SEND;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC1_LINE;
 | 
				
			||||||
 | 
						uint32_t DP_PIXEL_ENCODING;
 | 
				
			||||||
 | 
						uint32_t DP_COMPONENT_DEPTH;
 | 
				
			||||||
 | 
						uint32_t DP_DYN_RANGE;
 | 
				
			||||||
 | 
						uint32_t DP_YCBCR_RANGE;
 | 
				
			||||||
 | 
						uint32_t HDMI_PACKET_GEN_VERSION;
 | 
				
			||||||
 | 
						uint32_t HDMI_KEEPOUT_MODE;
 | 
				
			||||||
 | 
						uint32_t HDMI_DEEP_COLOR_ENABLE;
 | 
				
			||||||
 | 
						uint32_t HDMI_CLOCK_CHANNEL_RATE;
 | 
				
			||||||
 | 
						uint32_t HDMI_DEEP_COLOR_DEPTH;
 | 
				
			||||||
 | 
						uint32_t HDMI_GC_CONT;
 | 
				
			||||||
 | 
						uint32_t HDMI_GC_SEND;
 | 
				
			||||||
 | 
						uint32_t HDMI_NULL_SEND;
 | 
				
			||||||
 | 
						uint32_t HDMI_DATA_SCRAMBLE_EN;
 | 
				
			||||||
 | 
						uint32_t HDMI_AUDIO_INFO_SEND;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_INFO_UPDATE;
 | 
				
			||||||
 | 
						uint32_t HDMI_AUDIO_INFO_LINE;
 | 
				
			||||||
 | 
						uint32_t HDMI_GC_AVMUTE;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_RATE_X;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_RATE_Y;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_RATE_UPDATE_PENDING;
 | 
				
			||||||
 | 
						uint32_t AFMT_AVI_INFO_VERSION;
 | 
				
			||||||
 | 
						uint32_t HDMI_AVI_INFO_SEND;
 | 
				
			||||||
 | 
						uint32_t HDMI_AVI_INFO_CONT;
 | 
				
			||||||
 | 
						uint32_t HDMI_AVI_INFO_LINE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP0_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_STREAM_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP1_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP2_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP3_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP4_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP5_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP6_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_GSP7_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_AVI_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_MPG_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_VID_STREAM_DIS_DEFER;
 | 
				
			||||||
 | 
						uint32_t DP_VID_STREAM_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_VID_STREAM_STATUS;
 | 
				
			||||||
 | 
						uint32_t DP_STEER_FIFO_RESET;
 | 
				
			||||||
 | 
						uint32_t DP_VID_M_N_GEN_EN;
 | 
				
			||||||
 | 
						uint32_t DP_VID_N;
 | 
				
			||||||
 | 
						uint32_t DP_VID_M;
 | 
				
			||||||
 | 
						uint32_t DIG_START;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_SRC_SELECT;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_CHANNEL_ENABLE;
 | 
				
			||||||
 | 
						uint32_t HDMI_AUDIO_PACKETS_PER_LINE;
 | 
				
			||||||
 | 
						uint32_t HDMI_AUDIO_DELAY_EN;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_UPDATE;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_LAYOUT_OVRD;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_OSF_OVRD;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_AUTO_SEND;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_SOURCE;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_AUDIO_PRIORITY;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_CTS_32;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_N_32;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_CTS_44;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_N_44;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_CTS_48;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_N_48;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_L;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CLOCK_ACCURACY;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_R;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_2;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_3;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_4;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_5;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_6;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_CS_CHANNEL_NUMBER_7;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_AUD_N;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_TIMESTAMP_MODE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_ASP_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_ATP_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_AIP_ENABLE;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_ACM_ENABLE;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_SAMPLE_SEND;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_CLOCK_EN;
 | 
				
			||||||
 | 
						uint32_t TMDS_PIXEL_ENCODING;
 | 
				
			||||||
 | 
						uint32_t TMDS_COLOR_FORMAT;
 | 
				
			||||||
 | 
						uint32_t DP_DB_DISABLE;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_MISC0;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_HTOTAL;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_VTOTAL;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_HSTART;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_VSTART;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_HSYNCWIDTH;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_HSYNCPOLARITY;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_VSYNCWIDTH;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_VSYNCPOLARITY;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_HWIDTH;
 | 
				
			||||||
 | 
						uint32_t DP_MSA_VHEIGHT;
 | 
				
			||||||
 | 
						uint32_t HDMI_DB_DISABLE;
 | 
				
			||||||
 | 
						uint32_t DP_VID_N_MUL;
 | 
				
			||||||
 | 
						uint32_t DP_VID_M_DOUBLE_VALUE_EN;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_stream_enc_registers {
 | 
				
			||||||
 | 
						uint32_t AFMT_CNTL;
 | 
				
			||||||
 | 
						uint32_t AFMT_AVI_INFO0;
 | 
				
			||||||
 | 
						uint32_t AFMT_AVI_INFO1;
 | 
				
			||||||
 | 
						uint32_t AFMT_AVI_INFO2;
 | 
				
			||||||
 | 
						uint32_t AFMT_AVI_INFO3;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_0;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_1;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_2;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_3;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_4;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_5;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_6;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_7;
 | 
				
			||||||
 | 
						uint32_t AFMT_GENERIC_HDR;
 | 
				
			||||||
 | 
						uint32_t AFMT_INFOFRAME_CONTROL0;
 | 
				
			||||||
 | 
						uint32_t AFMT_VBI_PACKET_CONTROL;
 | 
				
			||||||
 | 
						uint32_t AFMT_VBI_PACKET_CONTROL1;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_PACKET_CONTROL;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_PACKET_CONTROL2;
 | 
				
			||||||
 | 
						uint32_t AFMT_AUDIO_SRC_CONTROL;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_0;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_1;
 | 
				
			||||||
 | 
						uint32_t AFMT_60958_2;
 | 
				
			||||||
 | 
						uint32_t DIG_FE_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_RATE_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_MSE_RATE_UPDATE;
 | 
				
			||||||
 | 
						uint32_t DP_PIXEL_FORMAT;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_STEER_FIFO;
 | 
				
			||||||
 | 
						uint32_t DP_VID_M;
 | 
				
			||||||
 | 
						uint32_t DP_VID_N;
 | 
				
			||||||
 | 
						uint32_t DP_VID_STREAM_CNTL;
 | 
				
			||||||
 | 
						uint32_t DP_VID_TIMING;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_AUD_N;
 | 
				
			||||||
 | 
						uint32_t DP_SEC_TIMESTAMP;
 | 
				
			||||||
 | 
						uint32_t HDMI_CONTROL;
 | 
				
			||||||
 | 
						uint32_t HDMI_GC;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC_PACKET_CONTROL0;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC_PACKET_CONTROL1;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC_PACKET_CONTROL2;
 | 
				
			||||||
 | 
						uint32_t HDMI_GENERIC_PACKET_CONTROL3;
 | 
				
			||||||
 | 
						uint32_t HDMI_INFOFRAME_CONTROL0;
 | 
				
			||||||
 | 
						uint32_t HDMI_INFOFRAME_CONTROL1;
 | 
				
			||||||
 | 
						uint32_t HDMI_VBI_PACKET_CONTROL;
 | 
				
			||||||
 | 
						uint32_t HDMI_AUDIO_PACKET_CONTROL;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_PACKET_CONTROL;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_32_0;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_32_1;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_44_0;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_44_1;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_48_0;
 | 
				
			||||||
 | 
						uint32_t HDMI_ACR_48_1;
 | 
				
			||||||
 | 
						uint32_t TMDS_CNTL;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce110_stream_encoder {
 | 
				
			||||||
 | 
						struct stream_encoder base;
 | 
				
			||||||
 | 
						const struct dce110_stream_enc_registers *regs;
 | 
				
			||||||
 | 
						const struct dce_stream_encoder_shift *se_shift;
 | 
				
			||||||
 | 
						const struct dce_stream_encoder_mask *se_mask;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce110_stream_encoder_construct(
 | 
				
			||||||
 | 
						struct dce110_stream_encoder *enc110,
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						struct dc_bios *bp,
 | 
				
			||||||
 | 
						enum engine_id eng_id,
 | 
				
			||||||
 | 
						const struct dce110_stream_enc_registers *regs,
 | 
				
			||||||
 | 
						const struct dce_stream_encoder_shift *se_shift,
 | 
				
			||||||
 | 
						const struct dce_stream_encoder_mask *se_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_se_audio_mute_control(
 | 
				
			||||||
 | 
						struct stream_encoder *enc, bool mute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_se_dp_audio_setup(
 | 
				
			||||||
 | 
						struct stream_encoder *enc,
 | 
				
			||||||
 | 
						unsigned int az_inst,
 | 
				
			||||||
 | 
						struct audio_info *info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_se_dp_audio_enable(
 | 
				
			||||||
 | 
							struct stream_encoder *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_se_dp_audio_disable(
 | 
				
			||||||
 | 
							struct stream_encoder *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_se_hdmi_audio_setup(
 | 
				
			||||||
 | 
						struct stream_encoder *enc,
 | 
				
			||||||
 | 
						unsigned int az_inst,
 | 
				
			||||||
 | 
						struct audio_info *info,
 | 
				
			||||||
 | 
						struct audio_crtc_info *audio_crtc_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void dce110_se_hdmi_audio_disable(
 | 
				
			||||||
 | 
						struct stream_encoder *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DC_STREAM_ENCODER_DCE110_H__ */
 | 
				
			||||||
							
								
								
									
										1002
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1002
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										313
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_transform.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								drivers/gpu/drm/amd/display/dc/dce/dce_transform.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,313 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-16 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _DCE_DCE_TRANSFORM_H_
 | 
				
			||||||
 | 
					#define _DCE_DCE_TRANSFORM_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "transform.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TO_DCE_TRANSFORM(transform)\
 | 
				
			||||||
 | 
						container_of(transform, struct dce_transform, base)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LB_TOTAL_NUMBER_OF_ENTRIES 1712
 | 
				
			||||||
 | 
					#define LB_BITS_PER_ENTRY 144
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XFM_COMMON_REG_LIST_DCE_BASE(id) \
 | 
				
			||||||
 | 
						SRI(LB_DATA_FORMAT, LB, id), \
 | 
				
			||||||
 | 
						SRI(GAMUT_REMAP_CONTROL, DCP, id), \
 | 
				
			||||||
 | 
						SRI(GAMUT_REMAP_C11_C12, DCP, id), \
 | 
				
			||||||
 | 
						SRI(GAMUT_REMAP_C13_C14, DCP, id), \
 | 
				
			||||||
 | 
						SRI(GAMUT_REMAP_C21_C22, DCP, id), \
 | 
				
			||||||
 | 
						SRI(GAMUT_REMAP_C23_C24, DCP, id), \
 | 
				
			||||||
 | 
						SRI(GAMUT_REMAP_C31_C32, DCP, id), \
 | 
				
			||||||
 | 
						SRI(GAMUT_REMAP_C33_C34, DCP, id), \
 | 
				
			||||||
 | 
						SRI(DENORM_CONTROL, DCP, id), \
 | 
				
			||||||
 | 
						SRI(DCP_SPATIAL_DITHER_CNTL, DCP, id), \
 | 
				
			||||||
 | 
						SRI(OUT_ROUND_CONTROL, DCP, id), \
 | 
				
			||||||
 | 
						SRI(OUT_CLAMP_CONTROL_R_CR, DCP, id), \
 | 
				
			||||||
 | 
						SRI(OUT_CLAMP_CONTROL_G_Y, DCP, id), \
 | 
				
			||||||
 | 
						SRI(OUT_CLAMP_CONTROL_B_CB, DCP, id), \
 | 
				
			||||||
 | 
						SRI(SCL_MODE, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_TAP_CONTROL, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_CONTROL, SCL, id), \
 | 
				
			||||||
 | 
						SRI(EXT_OVERSCAN_LEFT_RIGHT, SCL, id), \
 | 
				
			||||||
 | 
						SRI(EXT_OVERSCAN_TOP_BOTTOM, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_VERT_FILTER_CONTROL, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_HORZ_FILTER_CONTROL, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_COEF_RAM_SELECT, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_COEF_RAM_TAP_DATA, SCL, id), \
 | 
				
			||||||
 | 
						SRI(VIEWPORT_START, SCL, id), \
 | 
				
			||||||
 | 
						SRI(VIEWPORT_SIZE, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_HORZ_FILTER_SCALE_RATIO, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_VERT_FILTER_SCALE_RATIO, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_HORZ_FILTER_INIT, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_VERT_FILTER_INIT, SCL, id), \
 | 
				
			||||||
 | 
						SRI(SCL_AUTOMATIC_MODE_CONTROL, SCL, id), \
 | 
				
			||||||
 | 
						SRI(LB_MEMORY_CTRL, LB, id), \
 | 
				
			||||||
 | 
						SRI(SCL_UPDATE, SCL, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XFM_COMMON_REG_LIST_DCE100(id) \
 | 
				
			||||||
 | 
						XFM_COMMON_REG_LIST_DCE_BASE(id), \
 | 
				
			||||||
 | 
						SRI(DCFE_MEM_PWR_CTRL, CRTC, id), \
 | 
				
			||||||
 | 
						SRI(DCFE_MEM_PWR_STATUS, CRTC, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XFM_COMMON_REG_LIST_DCE110(id) \
 | 
				
			||||||
 | 
						XFM_COMMON_REG_LIST_DCE_BASE(id), \
 | 
				
			||||||
 | 
						SRI(DCFE_MEM_PWR_CTRL, DCFE, id), \
 | 
				
			||||||
 | 
						SRI(DCFE_MEM_PWR_STATUS, DCFE, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XFM_SF(reg_name, field_name, post_fix)\
 | 
				
			||||||
 | 
						.field_name = reg_name ## __ ## field_name ## post_fix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XFM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \
 | 
				
			||||||
 | 
						XFM_SF(OUT_CLAMP_CONTROL_B_CB, OUT_CLAMP_MIN_B_CB, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(OUT_CLAMP_CONTROL_B_CB, OUT_CLAMP_MAX_B_CB, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(OUT_CLAMP_CONTROL_G_Y, OUT_CLAMP_MIN_G_Y, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(OUT_CLAMP_CONTROL_G_Y, OUT_CLAMP_MAX_G_Y, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(OUT_CLAMP_CONTROL_R_CR, OUT_CLAMP_MIN_R_CR, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(OUT_CLAMP_CONTROL_R_CR, OUT_CLAMP_MAX_R_CR, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(OUT_ROUND_CONTROL, OUT_ROUND_TRUNC_MODE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCP_SPATIAL_DITHER_CNTL, DCP_SPATIAL_DITHER_EN, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCP_SPATIAL_DITHER_CNTL, DCP_SPATIAL_DITHER_MODE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCP_SPATIAL_DITHER_CNTL, DCP_SPATIAL_DITHER_DEPTH, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCP_SPATIAL_DITHER_CNTL, DCP_FRAME_RANDOM_ENABLE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCP_SPATIAL_DITHER_CNTL, DCP_RGB_RANDOM_ENABLE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCP_SPATIAL_DITHER_CNTL, DCP_HIGHPASS_RANDOM_ENABLE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DENORM_CONTROL, DENORM_MODE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(LB_DATA_FORMAT, PIXEL_DEPTH, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(LB_DATA_FORMAT, PIXEL_EXPAN_MODE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C11_C12, GAMUT_REMAP_C11, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C11_C12, GAMUT_REMAP_C12, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C13_C14, GAMUT_REMAP_C13, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C13_C14, GAMUT_REMAP_C14, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C21_C22, GAMUT_REMAP_C21, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C21_C22, GAMUT_REMAP_C22, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C23_C24, GAMUT_REMAP_C23, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C23_C24, GAMUT_REMAP_C24, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C31_C32, GAMUT_REMAP_C31, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C31_C32, GAMUT_REMAP_C32, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C33_C34, GAMUT_REMAP_C33, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_C33_C34, GAMUT_REMAP_C34, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(GAMUT_REMAP_CONTROL, GRPH_GAMUT_REMAP_MODE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_MODE, SCL_MODE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_TAP_CONTROL, SCL_H_NUM_OF_TAPS, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_TAP_CONTROL, SCL_V_NUM_OF_TAPS, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_CONTROL, SCL_BOUNDARY_MODE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_COEF_RAM_SELECT, SCL_C_RAM_FILTER_TYPE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_COEF_RAM_SELECT, SCL_C_RAM_PHASE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_COEF_RAM_SELECT, SCL_C_RAM_TAP_PAIR_IDX, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_COEF_RAM_TAP_DATA, SCL_C_RAM_EVEN_TAP_COEF_EN, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_COEF_RAM_TAP_DATA, SCL_C_RAM_EVEN_TAP_COEF, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_COEF_RAM_TAP_DATA, SCL_C_RAM_ODD_TAP_COEF_EN, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_COEF_RAM_TAP_DATA, SCL_C_RAM_ODD_TAP_COEF, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(VIEWPORT_START, VIEWPORT_X_START, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(VIEWPORT_START, VIEWPORT_Y_START, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(VIEWPORT_SIZE, VIEWPORT_HEIGHT, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(VIEWPORT_SIZE, VIEWPORT_WIDTH, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_HORZ_FILTER_SCALE_RATIO, SCL_H_SCALE_RATIO, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_VERT_FILTER_SCALE_RATIO, SCL_V_SCALE_RATIO, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_HORZ_FILTER_INIT, SCL_H_INIT_INT, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_HORZ_FILTER_INIT, SCL_H_INIT_FRAC, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_VERT_FILTER_INIT, SCL_V_INIT_INT, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_VERT_FILTER_INIT, SCL_V_INIT_FRAC, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(LB_MEMORY_CTRL, LB_MEMORY_CONFIG, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(LB_MEMORY_CTRL, LB_MEMORY_SIZE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_VERT_FILTER_CONTROL, SCL_V_2TAP_HARDCODE_COEF_EN, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_HORZ_FILTER_CONTROL, SCL_H_2TAP_HARDCODE_COEF_EN, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_UPDATE, SCL_COEF_UPDATE_COMPLETE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(LB_DATA_FORMAT, ALPHA_EN, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XFM_COMMON_MASK_SH_LIST_DCE110(mask_sh) \
 | 
				
			||||||
 | 
						XFM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCFE_MEM_PWR_CTRL, SCL_COEFF_MEM_PWR_DIS, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(DCFE_MEM_PWR_STATUS, SCL_COEFF_MEM_PWR_STATE, mask_sh), \
 | 
				
			||||||
 | 
						XFM_SF(SCL_MODE, SCL_PSCL_EN, mask_sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XFM_REG_FIELD_LIST(type) \
 | 
				
			||||||
 | 
						type OUT_CLAMP_MIN_B_CB; \
 | 
				
			||||||
 | 
						type OUT_CLAMP_MAX_B_CB; \
 | 
				
			||||||
 | 
						type OUT_CLAMP_MIN_G_Y; \
 | 
				
			||||||
 | 
						type OUT_CLAMP_MAX_G_Y; \
 | 
				
			||||||
 | 
						type OUT_CLAMP_MIN_R_CR; \
 | 
				
			||||||
 | 
						type OUT_CLAMP_MAX_R_CR; \
 | 
				
			||||||
 | 
						type OUT_ROUND_TRUNC_MODE; \
 | 
				
			||||||
 | 
						type DCP_SPATIAL_DITHER_EN; \
 | 
				
			||||||
 | 
						type DCP_SPATIAL_DITHER_MODE; \
 | 
				
			||||||
 | 
						type DCP_SPATIAL_DITHER_DEPTH; \
 | 
				
			||||||
 | 
						type DCP_FRAME_RANDOM_ENABLE; \
 | 
				
			||||||
 | 
						type DCP_RGB_RANDOM_ENABLE; \
 | 
				
			||||||
 | 
						type DCP_HIGHPASS_RANDOM_ENABLE; \
 | 
				
			||||||
 | 
						type DENORM_MODE; \
 | 
				
			||||||
 | 
						type PIXEL_DEPTH; \
 | 
				
			||||||
 | 
						type PIXEL_EXPAN_MODE; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C11; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C12; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C13; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C14; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C21; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C22; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C23; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C24; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C31; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C32; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C33; \
 | 
				
			||||||
 | 
						type GAMUT_REMAP_C34; \
 | 
				
			||||||
 | 
						type GRPH_GAMUT_REMAP_MODE; \
 | 
				
			||||||
 | 
						type SCL_MODE; \
 | 
				
			||||||
 | 
						type SCL_PSCL_EN; \
 | 
				
			||||||
 | 
						type SCL_H_NUM_OF_TAPS; \
 | 
				
			||||||
 | 
						type SCL_V_NUM_OF_TAPS; \
 | 
				
			||||||
 | 
						type SCL_BOUNDARY_MODE; \
 | 
				
			||||||
 | 
						type EXT_OVERSCAN_LEFT; \
 | 
				
			||||||
 | 
						type EXT_OVERSCAN_RIGHT; \
 | 
				
			||||||
 | 
						type EXT_OVERSCAN_TOP; \
 | 
				
			||||||
 | 
						type EXT_OVERSCAN_BOTTOM; \
 | 
				
			||||||
 | 
						type SCL_COEFF_MEM_PWR_DIS; \
 | 
				
			||||||
 | 
						type SCL_COEFF_MEM_PWR_STATE; \
 | 
				
			||||||
 | 
						type SCL_C_RAM_FILTER_TYPE; \
 | 
				
			||||||
 | 
						type SCL_C_RAM_PHASE; \
 | 
				
			||||||
 | 
						type SCL_C_RAM_TAP_PAIR_IDX; \
 | 
				
			||||||
 | 
						type SCL_C_RAM_EVEN_TAP_COEF_EN; \
 | 
				
			||||||
 | 
						type SCL_C_RAM_EVEN_TAP_COEF; \
 | 
				
			||||||
 | 
						type SCL_C_RAM_ODD_TAP_COEF_EN; \
 | 
				
			||||||
 | 
						type SCL_C_RAM_ODD_TAP_COEF; \
 | 
				
			||||||
 | 
						type VIEWPORT_X_START; \
 | 
				
			||||||
 | 
						type VIEWPORT_Y_START; \
 | 
				
			||||||
 | 
						type VIEWPORT_HEIGHT; \
 | 
				
			||||||
 | 
						type VIEWPORT_WIDTH; \
 | 
				
			||||||
 | 
						type SCL_H_SCALE_RATIO; \
 | 
				
			||||||
 | 
						type SCL_V_SCALE_RATIO; \
 | 
				
			||||||
 | 
						type SCL_H_INIT_INT; \
 | 
				
			||||||
 | 
						type SCL_H_INIT_FRAC; \
 | 
				
			||||||
 | 
						type SCL_V_INIT_INT; \
 | 
				
			||||||
 | 
						type SCL_V_INIT_FRAC; \
 | 
				
			||||||
 | 
						type LB_MEMORY_CONFIG; \
 | 
				
			||||||
 | 
						type LB_MEMORY_SIZE; \
 | 
				
			||||||
 | 
						type SCL_V_2TAP_HARDCODE_COEF_EN; \
 | 
				
			||||||
 | 
						type SCL_H_2TAP_HARDCODE_COEF_EN; \
 | 
				
			||||||
 | 
						type SCL_COEF_UPDATE_COMPLETE; \
 | 
				
			||||||
 | 
						type ALPHA_EN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_transform_shift {
 | 
				
			||||||
 | 
						XFM_REG_FIELD_LIST(uint8_t);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_transform_mask {
 | 
				
			||||||
 | 
						XFM_REG_FIELD_LIST(uint32_t);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_transform_registers {
 | 
				
			||||||
 | 
						uint32_t LB_DATA_FORMAT;
 | 
				
			||||||
 | 
						uint32_t GAMUT_REMAP_CONTROL;
 | 
				
			||||||
 | 
						uint32_t GAMUT_REMAP_C11_C12;
 | 
				
			||||||
 | 
						uint32_t GAMUT_REMAP_C13_C14;
 | 
				
			||||||
 | 
						uint32_t GAMUT_REMAP_C21_C22;
 | 
				
			||||||
 | 
						uint32_t GAMUT_REMAP_C23_C24;
 | 
				
			||||||
 | 
						uint32_t GAMUT_REMAP_C31_C32;
 | 
				
			||||||
 | 
						uint32_t GAMUT_REMAP_C33_C34;
 | 
				
			||||||
 | 
						uint32_t DENORM_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DCP_SPATIAL_DITHER_CNTL;
 | 
				
			||||||
 | 
						uint32_t OUT_ROUND_CONTROL;
 | 
				
			||||||
 | 
						uint32_t OUT_CLAMP_CONTROL_R_CR;
 | 
				
			||||||
 | 
						uint32_t OUT_CLAMP_CONTROL_G_Y;
 | 
				
			||||||
 | 
						uint32_t OUT_CLAMP_CONTROL_B_CB;
 | 
				
			||||||
 | 
						uint32_t SCL_MODE;
 | 
				
			||||||
 | 
						uint32_t SCL_TAP_CONTROL;
 | 
				
			||||||
 | 
						uint32_t SCL_CONTROL;
 | 
				
			||||||
 | 
						uint32_t EXT_OVERSCAN_LEFT_RIGHT;
 | 
				
			||||||
 | 
						uint32_t EXT_OVERSCAN_TOP_BOTTOM;
 | 
				
			||||||
 | 
						uint32_t SCL_VERT_FILTER_CONTROL;
 | 
				
			||||||
 | 
						uint32_t SCL_HORZ_FILTER_CONTROL;
 | 
				
			||||||
 | 
						uint32_t DCFE_MEM_PWR_CTRL;
 | 
				
			||||||
 | 
						uint32_t DCFE_MEM_PWR_STATUS;
 | 
				
			||||||
 | 
						uint32_t SCL_COEF_RAM_SELECT;
 | 
				
			||||||
 | 
						uint32_t SCL_COEF_RAM_TAP_DATA;
 | 
				
			||||||
 | 
						uint32_t VIEWPORT_START;
 | 
				
			||||||
 | 
						uint32_t VIEWPORT_SIZE;
 | 
				
			||||||
 | 
						uint32_t SCL_HORZ_FILTER_SCALE_RATIO;
 | 
				
			||||||
 | 
						uint32_t SCL_VERT_FILTER_SCALE_RATIO;
 | 
				
			||||||
 | 
						uint32_t SCL_HORZ_FILTER_INIT;
 | 
				
			||||||
 | 
						uint32_t SCL_VERT_FILTER_INIT;
 | 
				
			||||||
 | 
						uint32_t SCL_AUTOMATIC_MODE_CONTROL;
 | 
				
			||||||
 | 
						uint32_t LB_MEMORY_CTRL;
 | 
				
			||||||
 | 
						uint32_t SCL_UPDATE;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct init_int_and_frac {
 | 
				
			||||||
 | 
						uint32_t integer;
 | 
				
			||||||
 | 
						uint32_t fraction;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct scl_ratios_inits {
 | 
				
			||||||
 | 
						uint32_t h_int_scale_ratio;
 | 
				
			||||||
 | 
						uint32_t v_int_scale_ratio;
 | 
				
			||||||
 | 
						struct init_int_and_frac h_init;
 | 
				
			||||||
 | 
						struct init_int_and_frac v_init;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ram_filter_type {
 | 
				
			||||||
 | 
						FILTER_TYPE_RGB_Y_VERTICAL	= 0, /* 0 - RGB/Y Vertical filter */
 | 
				
			||||||
 | 
						FILTER_TYPE_CBCR_VERTICAL	= 1, /* 1 - CbCr  Vertical filter */
 | 
				
			||||||
 | 
						FILTER_TYPE_RGB_Y_HORIZONTAL	= 2, /* 1 - RGB/Y Horizontal filter */
 | 
				
			||||||
 | 
						FILTER_TYPE_CBCR_HORIZONTAL	= 3, /* 3 - CbCr  Horizontal filter */
 | 
				
			||||||
 | 
						FILTER_TYPE_ALPHA_VERTICAL	= 4, /* 4 - Alpha Vertical filter. */
 | 
				
			||||||
 | 
						FILTER_TYPE_ALPHA_HORIZONTAL	= 5, /* 5 - Alpha Horizontal filter. */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce_transform {
 | 
				
			||||||
 | 
						struct transform base;
 | 
				
			||||||
 | 
						const struct dce_transform_registers *regs;
 | 
				
			||||||
 | 
						const struct dce_transform_shift *xfm_shift;
 | 
				
			||||||
 | 
						const struct dce_transform_mask *xfm_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const uint16_t *filter_v;
 | 
				
			||||||
 | 
						const uint16_t *filter_h;
 | 
				
			||||||
 | 
						const uint16_t *filter_v_c;
 | 
				
			||||||
 | 
						const uint16_t *filter_h_c;
 | 
				
			||||||
 | 
						int lb_pixel_depth_supported;
 | 
				
			||||||
 | 
						int lb_memory_size;
 | 
				
			||||||
 | 
						int lb_bits_per_entry;
 | 
				
			||||||
 | 
						bool prescaler_on;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce_transform_construct(struct dce_transform *xfm110,
 | 
				
			||||||
 | 
						struct dc_context *ctx,
 | 
				
			||||||
 | 
						uint32_t inst,
 | 
				
			||||||
 | 
						const struct dce_transform_registers *regs,
 | 
				
			||||||
 | 
						const struct dce_transform_shift *xfm_shift,
 | 
				
			||||||
 | 
						const struct dce_transform_mask *xfm_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce_transform_get_optimal_number_of_taps(
 | 
				
			||||||
 | 
						struct transform *xfm,
 | 
				
			||||||
 | 
						struct scaler_data *scl_data,
 | 
				
			||||||
 | 
						const struct scaling_taps *in_taps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _DCE_DCE_TRANSFORM_H_ */
 | 
				
			||||||
							
								
								
									
										23
									
								
								drivers/gpu/drm/amd/display/dc/dce100/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								drivers/gpu/drm/amd/display/dc/dce100/Makefile
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Makefile for the 'controller' sub-component of DAL.
 | 
				
			||||||
 | 
					# It provides the control and status of HW CRTC block.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DCE100 = dce100_resource.o dce100_hw_sequencer.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DAL_DCE100 = $(addprefix $(AMDDALPATH)/dc/dce100/,$(DCE100))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DAL_DCE100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					# DCE 10x
 | 
				
			||||||
 | 
					###############################################################################
 | 
				
			||||||
 | 
					ifdef 0#CONFIG_DRM_AMD_DC_DCE11_0
 | 
				
			||||||
 | 
					TG_DCE100 = dce100_resource.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DAL_TG_DCE100 = $(addprefix \
 | 
				
			||||||
 | 
						$(AMDDALPATH)/dc/dce100/,$(TG_DCE100))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AMD_DISPLAY_FILES += $(AMD_DAL_TG_DCE100)
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										140
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,140 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2015 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "dm_services.h"
 | 
				
			||||||
 | 
					#include "dc.h"
 | 
				
			||||||
 | 
					#include "core_dc.h"
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					#include "hw_sequencer.h"
 | 
				
			||||||
 | 
					#include "dce100_hw_sequencer.h"
 | 
				
			||||||
 | 
					#include "dce110/dce110_hw_sequencer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* include DCE10 register header files */
 | 
				
			||||||
 | 
					#include "dce/dce_10_0_d.h"
 | 
				
			||||||
 | 
					#include "dce/dce_10_0_sh_mask.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct dce100_hw_seq_reg_offsets {
 | 
				
			||||||
 | 
						uint32_t blnd;
 | 
				
			||||||
 | 
						uint32_t crtc;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct dce100_hw_seq_reg_offsets reg_offsets[] = {
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						.crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						.crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						.crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HW_REG_CRTC(reg, id)\
 | 
				
			||||||
 | 
						(reg + reg_offsets[id].crtc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					 * Private definitions
 | 
				
			||||||
 | 
					 ******************************************************************************/
 | 
				
			||||||
 | 
					/***************************PIPE_CONTROL***********************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool dce100_enable_display_power_gating(
 | 
				
			||||||
 | 
						struct core_dc *dc,
 | 
				
			||||||
 | 
						uint8_t controller_id,
 | 
				
			||||||
 | 
						struct dc_bios *dcb,
 | 
				
			||||||
 | 
						enum pipe_gating_control power_gating)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum bp_result bp_result = BP_RESULT_OK;
 | 
				
			||||||
 | 
						enum bp_pipe_control_action cntl;
 | 
				
			||||||
 | 
						struct dc_context *ctx = dc->ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (power_gating == PIPE_GATING_CONTROL_INIT)
 | 
				
			||||||
 | 
							cntl = ASIC_PIPE_INIT;
 | 
				
			||||||
 | 
						else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
 | 
				
			||||||
 | 
							cntl = ASIC_PIPE_ENABLE;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							cntl = ASIC_PIPE_DISABLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(power_gating == PIPE_GATING_CONTROL_INIT && controller_id != 0)){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bp_result = dcb->funcs->enable_disp_power_gating(
 | 
				
			||||||
 | 
											dcb, controller_id + 1, cntl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
 | 
				
			||||||
 | 
							 * by default when command table is called
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							dm_write_reg(ctx,
 | 
				
			||||||
 | 
								HW_REG_CRTC(mmMASTER_UPDATE_MODE, controller_id),
 | 
				
			||||||
 | 
								0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bp_result == BP_RESULT_OK)
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void set_display_mark_for_pipe_if_needed(struct core_dc *dc,
 | 
				
			||||||
 | 
							struct pipe_ctx *pipe_ctx,
 | 
				
			||||||
 | 
							struct validate_context *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Do nothing until we have proper bandwitdth calcs */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void set_displaymarks(
 | 
				
			||||||
 | 
							const struct core_dc *dc, struct validate_context *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Do nothing until we have proper bandwitdth calcs */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void set_bandwidth(struct core_dc *dc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Do nothing until we have proper bandwitdth calcs */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce100_hw_sequencer_construct(struct core_dc *dc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dce110_hw_sequencer_construct(dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO: dce80 is empty implementation at the moment*/
 | 
				
			||||||
 | 
						dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating;
 | 
				
			||||||
 | 
						dc->hwss.set_displaymarks = set_displaymarks;
 | 
				
			||||||
 | 
						dc->hwss.increase_watermarks_for_pipe = set_display_mark_for_pipe_if_needed;
 | 
				
			||||||
 | 
						dc->hwss.set_bandwidth = set_bandwidth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										36
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Copyright 2012-15 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Authors: AMD
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DC_HWSS_DCE100_H__
 | 
				
			||||||
 | 
					#define __DC_HWSS_DCE100_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct core_dc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool dce100_hw_sequencer_construct(struct core_dc *dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DC_HWSS_DCE100_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										1085
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1085
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										19
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * dce100_resource.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: 2016-01-20
 | 
				
			||||||
 | 
					 *      Author: qyang
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef DCE100_RESOURCE_H_
 | 
				
			||||||
 | 
					#define DCE100_RESOURCE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct core_dc;
 | 
				
			||||||
 | 
					struct resource_pool;
 | 
				
			||||||
 | 
					struct dc_validation_set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct resource_pool *dce100_create_resource_pool(
 | 
				
			||||||
 | 
						uint8_t num_virtual_links,
 | 
				
			||||||
 | 
						struct core_dc *dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DCE100_RESOURCE_H_ */
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue