From 351b71a53a01276932fe2269c2bcbd5bf35da0f2 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Thu, 31 Mar 2016 17:45:07 -0400 Subject: [PATCH 0512/1110] drm/amdgpu: Use dal driver for CZ Signed-off-by: Harry Wentland Acked-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/Kconfig | 1 + drivers/gpu/drm/amd/amdgpu/Makefile | 18 +++++- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 12 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 34 ++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 5 -- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 11 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 51 +++++++++++++++- drivers/gpu/drm/amd/amdgpu/vi.c | 96 +++++++++++++++++++++++++++++- 9 files changed, 216 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 7335c04..6b9dac8 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -25,3 +25,4 @@ config DRM_AMDGPU_GART_DEBUGFS Selecting this option creates a debugfs file to inspect the mapped pages. Uses more memory for housekeeping, enable only for debugging. +source "drivers/gpu/drm/amd/dal/Kconfig" diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index dceebbb..3efc971 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -3,13 +3,18 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. FULL_AMD_PATH=$(src)/.. +DAL_FOLDER_NAME=dal +FULL_AMD_DAL_PATH = $(FULL_AMD_PATH)/$(DAL_FOLDER_NAME) ccflags-y := -Iinclude/drm -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_DAL_PATH) \ + -I$(FULL_AMD_DAL_PATH)/include \ + -I$(FULL_AMD_DAL_PATH)/amdgpu_dm amdgpu-y := amdgpu_drv.o @@ -110,9 +115,18 @@ amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o +ifneq ($(CONFIG_DRM_AMD_DAL),) + +RELATIVE_AMD_DAL_PATH = ../$(DAL_FOLDER_NAME) +include $(FULL_AMD_DAL_PATH)/Makefile + +amdgpu-y += $(AMD_DAL_FILES) + +endif + ifneq ($(CONFIG_DRM_AMD_POWERPLAY),) -include $(FULL_AMD_PATH)/powerplay/Makefile +include drivers/gpu/drm/amd/powerplay/Makefile amdgpu-y += $(AMD_POWERPLAY_FILES) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 06cf1eb..1e5dd09 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -52,8 +52,9 @@ #include "amdgpu_irq.h" #include "amdgpu_ucode.h" #include "amdgpu_gds.h" -#include "amd_powerplay.h" #include "amdgpu_acp.h" +#include "amdgpu_dm.h" +#include "amd_powerplay.h" #include "gpu_scheduler.h" @@ -82,6 +83,7 @@ extern int amdgpu_vm_size; extern int amdgpu_vm_block_size; extern int amdgpu_vm_fault_stop; extern int amdgpu_vm_debug; +extern int amdgpu_dal; extern int amdgpu_sched_jobs; extern int amdgpu_sched_hw_submission; extern int amdgpu_powerplay; @@ -2010,6 +2012,7 @@ struct amdgpu_device { /* 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; @@ -2056,6 +2059,9 @@ struct amdgpu_device { /* GDS */ struct amdgpu_gds gds; + /* display related functionality */ + struct amdgpu_display_manager dm; + const struct amdgpu_ip_block_version *ip_blocks; int num_ip_blocks; struct amdgpu_ip_block_status *ip_block_status; @@ -2090,7 +2096,7 @@ void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v); u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index); void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v); - +bool amdgpu_device_has_dal_support(struct amdgpu_device *adev); /* * Registers read & write functions. */ @@ -2325,6 +2331,8 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) #define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a)) +#define amdgpu_has_dal_support(adev) (amdgpu_dal && amdgpu_device_has_dal_support(adev)) + /* Common functions */ int amdgpu_gpu_reset(struct amdgpu_device *adev); void amdgpu_pci_config_reset(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 8ff3286..fcfdf2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1378,6 +1378,28 @@ static int amdgpu_resume(struct amdgpu_device *adev) return 0; } + +/** + * amdgpu_device_has_dal_support - check if dal is supported + * + * @adev: amdgpu_device_pointer + * + * Returns true for supported, false for not supported + */ +bool amdgpu_device_has_dal_support(struct amdgpu_device *adev) +{ + + switch(adev->asic_type) { + case CHIP_CARRIZO: +#if defined(CONFIG_DRM_AMD_DAL) && defined(CONFIG_DRM_AMD_DAL_DCE11_0) + return true; +#endif + default: + return false; + } +} + + /** * amdgpu_device_init - initialize the driver * @@ -1529,8 +1551,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n"); return r; } + /* init i2c buses */ - amdgpu_atombios_i2c_init(adev); + if (!amdgpu_has_dal_support(adev)) + amdgpu_atombios_i2c_init(adev); /* Fence driver */ r = amdgpu_fence_driver_init(adev); @@ -1630,7 +1654,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) adev->ip_block_status = NULL; adev->accel_working = false; /* free i2c buses */ - amdgpu_i2c_fini(adev); + if (!amdgpu_has_dal_support(adev)) + amdgpu_i2c_fini(adev); amdgpu_atombios_fini(adev); kfree(adev->bios); adev->bios = NULL; @@ -1811,6 +1836,11 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon) /* blat the mode back in */ if (fbcon) { drm_helper_resume_force_mode(dev); + if (!amdgpu_has_dal_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) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 943cdfb..97e5b69 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -77,6 +77,7 @@ int amdgpu_vm_block_size = -1; int amdgpu_vm_fault_stop = 0; int amdgpu_vm_debug = 0; int amdgpu_exp_hw_support = 0; +int amdgpu_dal = 1; int amdgpu_sched_jobs = 32; int amdgpu_sched_hw_submission = 2; int amdgpu_powerplay = -1; @@ -149,6 +150,9 @@ module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); 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(dal, "DAL display driver (1 = enable (default), 0 = disable)"); +module_param_named(dal, amdgpu_dal, 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); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 9191467..e694c99 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -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 struct fb_ops amdgpufb_ops = { .owner = THIS_MODULE, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 9266c7b..4fe38d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -36,6 +36,10 @@ #include +#ifdef CONFIG_DRM_AMD_DAL +#include "amdgpu_dm_irq.h" +#endif + #define AMDGPU_WAIT_IDLE_TIMEOUT 200 /* @@ -232,7 +236,12 @@ int amdgpu_irq_init(struct amdgpu_device *adev) } } - INIT_WORK(&adev->hotplug_work, amdgpu_hotplug_work_func); + if (!amdgpu_has_dal_support(adev)) { + /* 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; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 81bd964..d7b9c93 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -37,9 +37,12 @@ #include #include #include +#include #include #include +#include + struct amdgpu_bo; struct amdgpu_device; struct amdgpu_encoder; @@ -305,6 +308,18 @@ struct amdgpu_display_funcs { struct amdgpu_mode_mc_save *save); }; +struct amdgpu_framebuffer { + struct drm_framebuffer base; + struct drm_gem_object *obj; +}; + +struct amdgpu_fbdev { + struct drm_fb_helper helper; + struct amdgpu_framebuffer rfb; + struct list_head fbdev_list; + struct amdgpu_device *adev; +}; + struct amdgpu_mode_info { struct atom_context *atom_context; struct card_info *atom_card_info; @@ -409,6 +424,9 @@ struct amdgpu_crtc { u32 wm_high; u32 lb_vblank_lead_lines; struct drm_display_mode hw_mode; + + /* After Set Mode target will be non-NULL */ + struct dc_target *target; }; struct amdgpu_encoder_atom_dig { @@ -498,6 +516,13 @@ enum amdgpu_connector_dither { AMDGPU_FMT_DITHER_ENABLE = 1, }; +struct amdgpu_dm_dp_aux { + struct drm_dp_aux aux; + 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; @@ -509,6 +534,12 @@ 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; void *con_priv; bool dac_load_detect; bool detected_by_load; /* if the connection status was determined by load */ @@ -519,11 +550,25 @@ 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; + bool is_mst_connector; + struct amdgpu_encoder *mst_encoder; }; -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) || \ diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index ddbb63a..c3b5ed6 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -73,10 +73,11 @@ #include "uvd_v5_0.h" #include "uvd_v6_0.h" #include "vce_v3_0.h" -#include "amdgpu_powerplay.h" #if defined(CONFIG_DRM_AMD_ACP) #include "amdgpu_acp.h" #endif +#include "amdgpu_dm.h" +#include "amdgpu_powerplay.h" /* * Indirect registers accessor @@ -984,6 +985,89 @@ static const struct amdgpu_ip_block_version cz_ip_blocks[] = #endif }; +/* + * This is temporary. After we've gone through full testing with + * DAL we want to remove dce_v11 + */ +#if defined(CONFIG_DRM_AMD_DAL) +static const struct amdgpu_ip_block_version cz_ip_blocks_dal[] = +{ + /* ORDER MATTERS! */ + { + .type = AMD_IP_BLOCK_TYPE_COMMON, + .major = 2, + .minor = 0, + .rev = 0, + .funcs = &vi_common_ip_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_GMC, + .major = 8, + .minor = 0, + .rev = 0, + .funcs = &gmc_v8_0_ip_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_IH, + .major = 3, + .minor = 0, + .rev = 0, + .funcs = &cz_ih_ip_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_SMC, + .major = 8, + .minor = 0, + .rev = 0, + .funcs = &amdgpu_pp_ip_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_DCE, + .major = 11, + .minor = 0, + .rev = 0, + .funcs = &amdgpu_dm_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_GFX, + .major = 8, + .minor = 0, + .rev = 0, + .funcs = &gfx_v8_0_ip_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_SDMA, + .major = 3, + .minor = 0, + .rev = 0, + .funcs = &sdma_v3_0_ip_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_UVD, + .major = 6, + .minor = 0, + .rev = 0, + .funcs = &uvd_v6_0_ip_funcs, + }, + { + .type = AMD_IP_BLOCK_TYPE_VCE, + .major = 3, + .minor = 0, + .rev = 0, + .funcs = &vce_v3_0_ip_funcs, + }, +#if defined(CONFIG_DRM_AMD_ACP) + { + .type = AMD_IP_BLOCK_TYPE_ACP, + .major = 2, + .minor = 2, + .rev = 0, + .funcs = &acp_ip_funcs, + }, +#endif +}; +#endif + int vi_set_ip_blocks(struct amdgpu_device *adev) { switch (adev->asic_type) { @@ -1001,8 +1085,18 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) break; case CHIP_CARRIZO: case CHIP_STONEY: +#if defined(CONFIG_DRM_AMD_DAL) + if (amdgpu_dal && amdgpu_device_has_dal_support(adev)) { + adev->ip_blocks = cz_ip_blocks_dal; + adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks_dal); + } else { + adev->ip_blocks = cz_ip_blocks; + adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks); + } +#else adev->ip_blocks = cz_ip_blocks; adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks); +#endif break; default: /* FIXME: not supported yet */ -- 2.7.4