Skip to content

Commit

Permalink
Merge branch 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5…
Browse files Browse the repository at this point in the history
…f/linux into drm-next

Initial pull request for DC support.  We've completed a substantial amount of
the cleanup and restructuring in our TODO.  There are a few additional
cleanups that we are continuing to work on, but I don't think there are any
showstoppers remaining. We've tried to maintain most of the history for bisect
purposes.  Harry made sure all the commits build.  We've enabled DC for vega10
and Raven.  Pre-vega10 parts can be enabled via module parameter (amdgpu.dc=1),
but are not enabled by default at this point until we get further testing
upstream.

This code provides atomic modesetting support for DCE8 (CIK), DCE10 (Tonga,
Fiji), DCE11 (CZ, ST, Polaris), DCE12 (vega10), and DCN1 (RV) including
HDMI and DP audio, DP MST, and many other advanced display features.

+

Latest cleanups for DC from you and Harry.  Note that there is some
flickering on some older asics with this branch due to a regression in powerplay
that has already been fixed and will be included in my next non-DC pull request
next week.

* 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux: (897 commits)
  amdgpu/dc: use kref for dc_state.
  amdgpu/dc: convert dc_sink to kref.
  amdgpu/dc: convert dc_stream_state to kref.
  amdgpu/dc: use kref for dc_plane_state.
  amdgpu/dc: convert dc_gamma to kref reference counting.
  amdgpu/dc: convert dc_transfer to use a kref.
  amdgpu/dc: kill a bunch of dead code.
  amdgpu/dc: set a bunch of functions to static.
  amdgpu/dc: kill some deadcode in dc core.
  amdgpu/dc: fix indentation on a couple of returns.
  amdgpu/dm: don't use after free.
  amdgpu/dc: kfree already checks for NULL.
  amdgpu/dc: fix a bunch of misc whitespace.
  amdgpu/dc: drop hw_sequencer_types.h
  amdgpu/dc: drop dce110_types.h
  amdgpu/dc: use kernel ilog2 for log_2.
  amdgpu/dc: don't memset after kzalloc.
  amdgpu/dc: inline dal grph object id functions.
  amdgpu/dc: inline dml_round_to_multiple
  amdgpu/dc: rename bios get_image symbol to something more searchable.
  ...
  • Loading branch information
airlied committed Oct 9, 2017
2 parents bb7a9c8 + 8ee5702 commit b9e56e4
Show file tree
Hide file tree
Showing 363 changed files with 124,754 additions and 75 deletions.
10 changes: 10 additions & 0 deletions Documentation/gpu/todo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -397,5 +397,15 @@ those drivers as simple as possible, so lots of room for refactoring:

Contact: Noralf Trønnes, Daniel Vetter

AMD DC Display Driver
---------------------

AMD DC is the display driver for AMD devices starting with Vega. There has been
a bunch of progress cleaning it up but there's still plenty of work to be done.

See drivers/gpu/drm/amd/display/TODO for tasks.

Contact: Harry Wentland, Alex Deucher

Outside DRM
===========
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdgpu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
17 changes: 16 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
16 changes: 16 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -101,6 +102,8 @@ 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_dc_log;
extern int amdgpu_sched_jobs;
extern int amdgpu_sched_hw_submission;
extern int amdgpu_no_evict;
Expand Down Expand Up @@ -1510,6 +1513,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;
Expand Down Expand Up @@ -1565,6 +1569,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;
Expand Down Expand Up @@ -1626,6 +1633,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.
*/
Expand Down Expand Up @@ -1886,5 +1896,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
59 changes: 34 additions & 25 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -911,10 +911,6 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
struct cgs_display_info *info)
{
CGS_FUNC_ADEV;
struct amdgpu_crtc *amdgpu_crtc;
struct drm_device *ddev = adev->ddev;
struct drm_crtc *crtc;
uint32_t line_time_us, vblank_lines;
struct cgs_mode_info *mode_info;

if (info == NULL)
Expand All @@ -928,30 +924,43 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
mode_info->ref_clock = adev->clock.spll.reference_freq;
}

if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
list_for_each_entry(crtc,
&ddev->mode_config.crtc_list, head) {
amdgpu_crtc = to_amdgpu_crtc(crtc);
if (crtc->enabled) {
info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
info->display_count++;
}
if (mode_info != NULL &&
crtc->enabled && amdgpu_crtc->enabled &&
amdgpu_crtc->hw_mode.clock) {
line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
amdgpu_crtc->hw_mode.clock;
vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
amdgpu_crtc->hw_mode.crtc_vdisplay +
(amdgpu_crtc->v_border * 2);
mode_info->vblank_time_us = vblank_lines * line_time_us;
mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
mode_info->ref_clock = adev->clock.spll.reference_freq;
mode_info = NULL;
if (!amdgpu_device_has_dc_support(adev)) {
struct amdgpu_crtc *amdgpu_crtc;
struct drm_device *ddev = adev->ddev;
struct drm_crtc *crtc;
uint32_t line_time_us, vblank_lines;

if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
list_for_each_entry(crtc,
&ddev->mode_config.crtc_list, head) {
amdgpu_crtc = to_amdgpu_crtc(crtc);
if (crtc->enabled) {
info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
info->display_count++;
}
if (mode_info != NULL &&
crtc->enabled && amdgpu_crtc->enabled &&
amdgpu_crtc->hw_mode.clock) {
line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
amdgpu_crtc->hw_mode.clock;
vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
amdgpu_crtc->hw_mode.crtc_vdisplay +
(amdgpu_crtc->v_border * 2);
mode_info->vblank_time_us = vblank_lines * line_time_us;
mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
mode_info->ref_clock = adev->clock.spll.reference_freq;
mode_info = NULL;
}
}
}
} else {
info->display_count = adev->pm.pm_display_cfg.num_display;
if (mode_info != NULL) {
mode_info->vblank_time_us = adev->pm.pm_display_cfg.min_vblank_time;
mode_info->refresh_rate = adev->pm.pm_display_cfg.vrefresh;
mode_info->ref_clock = adev->clock.spll.reference_freq;
}
}

return 0;
}

Expand Down
105 changes: 89 additions & 16 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -1982,6 +1983,52 @@ 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_KAVERI:
case CHIP_CARRIZO:
case CHIP_STONEY:
case CHIP_POLARIS11:
case CHIP_POLARIS10:
case CHIP_POLARIS12:
case CHIP_TONGA:
case CHIP_FIJI:
#if defined(CONFIG_DRM_AMD_DC_PRE_VEGA)
return amdgpu_dc != 0;
#endif
case CHIP_KABINI:
case CHIP_MULLINS:
return amdgpu_dc > 0;
case CHIP_VEGA10:
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
case CHIP_RAVEN:
#endif
return amdgpu_dc != 0;
#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)
{
if (amdgpu_sriov_vf(adev))
return false;

return amdgpu_device_asic_has_dc_support(adev->asic_type);
}

/**
* amdgpu_device_init - initialize the driver
*
Expand Down Expand Up @@ -2035,7 +2082,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg;
adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg;


DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n",
amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision);
Expand Down Expand Up @@ -2178,7 +2224,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
goto failed;
}
/* init i2c buses */
amdgpu_atombios_i2c_init(adev);
if (!amdgpu_device_has_dc_support(adev))
amdgpu_atombios_i2c_init(adev);
}

/* Fence driver */
Expand Down Expand Up @@ -2310,7 +2357,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
adev->accel_working = false;
cancel_delayed_work_sync(&adev->late_init_work);
/* free i2c buses */
amdgpu_i2c_fini(adev);
if (!amdgpu_device_has_dc_support(adev))
amdgpu_i2c_fini(adev);
amdgpu_atombios_fini(adev);
kfree(adev->bios);
adev->bios = NULL;
Expand Down Expand Up @@ -2361,12 +2409,14 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)

drm_kms_helper_poll_disable(dev);

/* 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);
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);
}
drm_modeset_unlock_all(dev);

amdgpu_amdkfd_suspend(adev);

Expand Down Expand Up @@ -2509,13 +2559,25 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)

/* blat the mode back in */
if (fbcon) {
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);
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_modeset_unlock_all(dev);
}

drm_kms_helper_poll_enable(dev);
Expand All @@ -2532,7 +2594,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
#ifdef CONFIG_PM
dev->dev->power.disable_depth++;
#endif
drm_helper_hpd_irq_event(dev);
if (!amdgpu_device_has_dc_support(adev))
drm_helper_hpd_irq_event(dev);
else
drm_kms_helper_hotplug_event(dev);
#ifdef CONFIG_PM
dev->dev->power.disable_depth--;
#endif
Expand Down Expand Up @@ -2829,6 +2894,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;
Expand All @@ -2842,6 +2908,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) {
Expand Down Expand Up @@ -2959,7 +3028,11 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
}
}

drm_helper_resume_force_mode(adev->ddev);
if (amdgpu_device_has_dc_support(adev)) {
r = drm_atomic_helper_resume(adev->ddev, state);
amdgpu_dm_display_resume(adev);
} else
drm_helper_resume_force_mode(adev->ddev);

ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
if (r) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ amdgpu_framebuffer_init(struct drm_device *dev,
return 0;
}

static struct drm_framebuffer *
struct drm_framebuffer *
amdgpu_user_framebuffer_create(struct drm_device *dev,
struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd)
Expand Down Expand Up @@ -556,7 +556,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
return &amdgpu_fb->base;
}

static void amdgpu_output_poll_changed(struct drm_device *dev)
void amdgpu_output_poll_changed(struct drm_device *dev)
{
struct amdgpu_device *adev = dev->dev_private;
amdgpu_fb_output_poll_changed(adev);
Expand Down
Loading

0 comments on commit b9e56e4

Please sign in to comment.