mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-03 18:20:25 +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.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
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 \
 | 
			
		||||
	-I$(FULL_AMD_PATH)/include \
 | 
			
		||||
	-I$(FULL_AMD_PATH)/amdgpu \
 | 
			
		||||
	-I$(FULL_AMD_PATH)/scheduler \
 | 
			
		||||
	-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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -132,4 +138,13 @@ include $(FULL_AMD_PATH)/powerplay/Makefile
 | 
			
		|||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,7 @@
 | 
			
		|||
#include "amdgpu_vce.h"
 | 
			
		||||
#include "amdgpu_vcn.h"
 | 
			
		||||
#include "amdgpu_mn.h"
 | 
			
		||||
#include "amdgpu_dm.h"
 | 
			
		||||
 | 
			
		||||
#include "gpu_scheduler.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_debug;
 | 
			
		||||
extern int amdgpu_vm_update_mode;
 | 
			
		||||
extern int amdgpu_dc;
 | 
			
		||||
extern int amdgpu_sched_jobs;
 | 
			
		||||
extern int amdgpu_sched_hw_submission;
 | 
			
		||||
extern int amdgpu_no_evict;
 | 
			
		||||
| 
						 | 
				
			
			@ -1507,6 +1509,7 @@ struct amdgpu_device {
 | 
			
		|||
	/* display */
 | 
			
		||||
	bool				enable_virtual_display;
 | 
			
		||||
	struct amdgpu_mode_info		mode_info;
 | 
			
		||||
	/* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
 | 
			
		||||
	struct work_struct		hotplug_work;
 | 
			
		||||
	struct amdgpu_irq_src		crtc_irq;
 | 
			
		||||
	struct amdgpu_irq_src		pageflip_irq;
 | 
			
		||||
| 
						 | 
				
			
			@ -1563,6 +1566,9 @@ struct amdgpu_device {
 | 
			
		|||
	/* GDS */
 | 
			
		||||
	struct amdgpu_gds		gds;
 | 
			
		||||
 | 
			
		||||
	/* display related functionality */
 | 
			
		||||
	struct amdgpu_display_manager dm;
 | 
			
		||||
 | 
			
		||||
	struct amdgpu_ip_block          ip_blocks[AMDGPU_MAX_IP_NUM];
 | 
			
		||||
	int				num_ip_blocks;
 | 
			
		||||
	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);
 | 
			
		||||
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.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1884,5 +1893,11 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
 | 
			
		|||
			   uint64_t addr, struct amdgpu_bo **bo,
 | 
			
		||||
			   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"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,7 @@
 | 
			
		|||
#include <linux/debugfs.h>
 | 
			
		||||
#include <drm/drmP.h>
 | 
			
		||||
#include <drm/drm_crtc_helper.h>
 | 
			
		||||
#include <drm/drm_atomic_helper.h>
 | 
			
		||||
#include <drm/amdgpu_drm.h>
 | 
			
		||||
#include <linux/vgaarb.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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -2168,6 +2204,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 | 
			
		|||
			goto failed;
 | 
			
		||||
		}
 | 
			
		||||
		/* init i2c buses */
 | 
			
		||||
		if (!amdgpu_device_has_dc_support(adev))
 | 
			
		||||
			amdgpu_atombios_i2c_init(adev);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2296,6 +2333,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
 | 
			
		|||
	adev->accel_working = false;
 | 
			
		||||
	cancel_delayed_work_sync(&adev->late_init_work);
 | 
			
		||||
	/* free i2c buses */
 | 
			
		||||
	if (!amdgpu_device_has_dc_support(adev))
 | 
			
		||||
		amdgpu_i2c_fini(adev);
 | 
			
		||||
	amdgpu_atombios_fini(adev);
 | 
			
		||||
	kfree(adev->bios);
 | 
			
		||||
| 
						 | 
				
			
			@ -2346,12 +2384,14 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
 | 
			
		|||
 | 
			
		||||
	drm_kms_helper_poll_disable(dev);
 | 
			
		||||
 | 
			
		||||
	if (!amdgpu_device_has_dc_support(adev)) {
 | 
			
		||||
		/* turn off 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_OFF);
 | 
			
		||||
		}
 | 
			
		||||
		drm_modeset_unlock_all(dev);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 */
 | 
			
		||||
	if (fbcon) {
 | 
			
		||||
		if (!amdgpu_device_has_dc_support(adev)) {
 | 
			
		||||
			/* pre DCE11 */
 | 
			
		||||
			drm_helper_resume_force_mode(dev);
 | 
			
		||||
 | 
			
		||||
			/* 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_kms_helper_poll_enable(dev);
 | 
			
		||||
| 
						 | 
				
			
			@ -2517,7 +2569,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
 | 
			
		|||
#ifdef CONFIG_PM
 | 
			
		||||
	dev->dev->power.disable_depth++;
 | 
			
		||||
#endif
 | 
			
		||||
	if (!amdgpu_device_has_dc_support(adev))
 | 
			
		||||
		drm_helper_hpd_irq_event(dev);
 | 
			
		||||
	else
 | 
			
		||||
		drm_kms_helper_hotplug_event(dev);
 | 
			
		||||
#ifdef CONFIG_PM
 | 
			
		||||
	dev->dev->power.disable_depth--;
 | 
			
		||||
#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)
 | 
			
		||||
{
 | 
			
		||||
	struct drm_atomic_state *state = NULL;
 | 
			
		||||
	int i, r;
 | 
			
		||||
	int resched;
 | 
			
		||||
	bool need_full_reset, vram_lost = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -2827,6 +2883,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
 | 
			
		|||
 | 
			
		||||
	/* block TTM */
 | 
			
		||||
	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 */
 | 
			
		||||
	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2944,6 +3003,10 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -429,7 +429,7 @@ struct amdgpu_pm {
 | 
			
		|||
	uint32_t                fw_version;
 | 
			
		||||
	uint32_t                pcie_gen_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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,6 +103,7 @@ int amdgpu_vm_debug = 0;
 | 
			
		|||
int amdgpu_vram_page_split = 512;
 | 
			
		||||
int amdgpu_vm_update_mode = -1;
 | 
			
		||||
int amdgpu_exp_hw_support = 0;
 | 
			
		||||
int amdgpu_dc = -1;
 | 
			
		||||
int amdgpu_sched_jobs = 32;
 | 
			
		||||
int amdgpu_sched_hw_submission = 2;
 | 
			
		||||
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_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_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,11 +42,6 @@
 | 
			
		|||
   this contains a helper + a amdgpu fb
 | 
			
		||||
   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
 | 
			
		||||
amdgpufb_open(struct fb_info *info, int user)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,10 @@
 | 
			
		|||
 | 
			
		||||
#include <linux/pm_runtime.h>
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_DRM_AMD_DC
 | 
			
		||||
#include "amdgpu_dm_irq.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define AMDGPU_WAIT_IDLE_TIMEOUT 200
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -221,15 +225,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 | 
			
		|||
 | 
			
		||||
	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 */
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	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_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_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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,11 +38,15 @@
 | 
			
		|||
#include <drm/drm_crtc_helper.h>
 | 
			
		||||
#include <drm/drm_fb_helper.h>
 | 
			
		||||
#include <drm/drm_plane_helper.h>
 | 
			
		||||
#include <drm/drm_fb_helper.h>
 | 
			
		||||
#include <linux/i2c.h>
 | 
			
		||||
#include <linux/i2c-algo-bit.h>
 | 
			
		||||
#include <linux/hrtimer.h>
 | 
			
		||||
#include "amdgpu_irq.h"
 | 
			
		||||
 | 
			
		||||
#include <drm/drm_dp_mst_helper.h>
 | 
			
		||||
#include "modules/inc/mod_freesync.h"
 | 
			
		||||
 | 
			
		||||
struct amdgpu_bo;
 | 
			
		||||
struct amdgpu_device;
 | 
			
		||||
struct amdgpu_encoder;
 | 
			
		||||
| 
						 | 
				
			
			@ -292,6 +296,27 @@ struct amdgpu_display_funcs {
 | 
			
		|||
			      uint16_t connector_object_id,
 | 
			
		||||
			      struct amdgpu_hpd *hpd,
 | 
			
		||||
			      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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -400,6 +425,11 @@ struct amdgpu_crtc {
 | 
			
		|||
	/* for virtual dce */
 | 
			
		||||
	struct hrtimer vblank_timer;
 | 
			
		||||
	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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -489,6 +519,19 @@ enum amdgpu_connector_dither {
 | 
			
		|||
	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 drm_connector base;
 | 
			
		||||
	uint32_t connector_id;
 | 
			
		||||
| 
						 | 
				
			
			@ -500,6 +543,14 @@ struct amdgpu_connector {
 | 
			
		|||
	/* we need to mind the EDID between detect
 | 
			
		||||
	   and get modes due to analog/digital/tvencoder */
 | 
			
		||||
	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;
 | 
			
		||||
	bool dac_load_detect;
 | 
			
		||||
	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_dither dither;
 | 
			
		||||
	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 {
 | 
			
		||||
	struct drm_framebuffer base;
 | 
			
		||||
	struct drm_gem_object *obj;
 | 
			
		||||
/* TODO: start to use this struct and remove same field from base one */
 | 
			
		||||
struct amdgpu_mst_connector {
 | 
			
		||||
	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) || \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1467,7 +1467,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
 | 
			
		|||
			list_for_each_entry(crtc,
 | 
			
		||||
					    &ddev->mode_config.crtc_list, head) {
 | 
			
		||||
				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_crtc_count++;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,6 +65,7 @@
 | 
			
		|||
#include "oss/oss_2_0_d.h"
 | 
			
		||||
#include "oss/oss_2_0_sh_mask.h"
 | 
			
		||||
 | 
			
		||||
#include "amdgpu_dm.h"
 | 
			
		||||
#include "amdgpu_amdkfd.h"
 | 
			
		||||
#include "amdgpu_powerplay.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);
 | 
			
		||||
		if (adev->enable_virtual_display)
 | 
			
		||||
			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
 | 
			
		||||
			amdgpu_ip_block_add(adev, &dce_v8_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);
 | 
			
		||||
		if (adev->enable_virtual_display)
 | 
			
		||||
			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
 | 
			
		||||
			amdgpu_ip_block_add(adev, &dce_v8_5_ip_block);
 | 
			
		||||
		amdgpu_ip_block_add(adev, &gfx_v7_3_ip_block);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
#include "dce_virtual.h"
 | 
			
		||||
#include "mxgpu_vi.h"
 | 
			
		||||
#include "amdgpu_dm.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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);
 | 
			
		||||
		if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
 | 
			
		||||
			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
 | 
			
		||||
			amdgpu_ip_block_add(adev, &dce_v10_1_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);
 | 
			
		||||
		if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
 | 
			
		||||
			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
 | 
			
		||||
			amdgpu_ip_block_add(adev, &dce_v10_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);
 | 
			
		||||
		if (adev->enable_virtual_display)
 | 
			
		||||
			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
 | 
			
		||||
			amdgpu_ip_block_add(adev, &dce_v11_2_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);
 | 
			
		||||
		if (adev->enable_virtual_display)
 | 
			
		||||
			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
 | 
			
		||||
			amdgpu_ip_block_add(adev, &dce_v11_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);
 | 
			
		||||
		if (adev->enable_virtual_display)
 | 
			
		||||
			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
 | 
			
		||||
			amdgpu_ip_block_add(adev, &dce_v11_0_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