drm i915, amdgpu, qxl and etnaviv fixes

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJcivCBAAoJEAx081l5xIa+5OcQAKh/k6N1o83OIlw4OjWXZN/z
 YIyj/E/RjDwtXweXWC9cbv41hqWxYrUWQ6JrFgH19vF4grbOlpBpvlr2tQXyGS2c
 Gl87+w/VUBYXHe+SqFNsMq8SQQCAKfxb1hIXOScmpBHrCYK21NT8ulw6CY32d3Da
 QF+VhA3P4MOdecrrINA+GbxM0Pf/E3qjLA8U2jbZsW7vIYC5AyLuwTXFTC9vVR5S
 JfMfjU6T2m8eX0x79S8scinMqfkMsrdwBgG53FkRTi0DJb65ab97/cCtHVABrS/4
 xoF52Gb1uSin1S4KliWyB7Z+UcieYPhsLdo/983Vp56oZta2Rgi5R3L+cPLNgKGj
 +kFJBGT25zgtl+va5XqZ9CYkb/zW08nif7USWt+B6XGJ2ppyyyLX+jLoQHZK8ywn
 1CC/IYMKs+vRA+2N7MfZHgx2LAIGtpxCL6xYuyfJuWOCb/TNR+ijpnmbBRClDdfF
 mvL4sPCLT84ntpgFXOnbtWx+uRNTLWdtJaL3M3ovtlESLT3xdXSJnXHs0pc3+ygi
 rVTLPl3yjGCqGPf9Rv33g3c4dSIWkwSbRgWjTYhRQukd9rqZNxywC8AbgyAAHadS
 JefVt3G7dJgKOrb+5nyBWQYaq8I+Q/DjRJv3o36qCBsmGExeDR5IawTAQtjGmoZl
 LXA2uyuLoGGFHKUcdYU5
 =vzKe
 -----END PGP SIGNATURE-----

Merge tag 'drm-next-2019-03-15' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes and updates from Dave Airlie:
 "A few various fixes pulls and one late etnaviv pull but it was nearly
  all fixes anyways.

  etnaviv:
   - late next pull
   - mmu mapping fix
   - build non-ARM arches
   - misc fixes

  i915:
   - HDCP state handling fix
   - shrinker interaction fix
   - atomic state leak fix

  qxl:
   - kick out framebuffers early fix

  amdgpu:
   - Powerplay fixes
   - DC fixes
   - BACO turned off for now on vega20
   - Locking fix
   - KFD MQD fix
   - gfx9 golden register updates"

* tag 'drm-next-2019-03-15' of git://anongit.freedesktop.org/drm/drm: (43 commits)
  drm/amdgpu: Update gc golden setting for vega family
  drm/amd/powerplay: correct power reading on fiji
  drm/amd/powerplay: set max fan target temperature as 105C
  drm/i915: Relax mmap VMA check
  drm/i915: Fix atomic state leak when resetting HDMI link
  drm/i915: Acquire breadcrumb ref before cancelling
  drm/i915/selftests: Always free spinner on __sseu_prepare error
  drm/i915: Reacquire priolist cache after dropping the engine lock
  drm/i915: Protect i915_active iterators from the shrinker
  drm/i915: HDCP state handling in ddi_update_pipe
  drm/qxl: remove conflicting framebuffers earlier
  drm/fb-helper: call vga_remove_vgacon automatically.
  drm: move i915_kick_out_vgacon to vgaarb
  drm/amd/display: don't call dm_pp_ function from an fpu block
  drm: add __user attribute to ptr_to_compat()
  drm/amdgpu: clear PDs/PTs only after initializing them
  drm/amd/display: Pass app_tf by value rather than by reference
  Revert "drm/amdgpu: use BACO reset on vega20 if platform support"
  drm/amd/powerplay: show the right override pcie parameters
  drm/amd/powerplay: honor the OD settings
  ...
This commit is contained in:
Linus Torvalds 2019-03-15 13:58:35 -07:00
commit 8264fd046a
46 changed files with 451 additions and 375 deletions

View File

@ -5278,7 +5278,7 @@ DRM DRIVERS FOR VIVANTE GPU IP
M: Lucas Stach <l.stach@pengutronix.de> M: Lucas Stach <l.stach@pengutronix.de>
R: Russell King <linux+etnaviv@armlinux.org.uk> R: Russell King <linux+etnaviv@armlinux.org.uk>
R: Christian Gmeiner <christian.gmeiner@gmail.com> R: Christian Gmeiner <christian.gmeiner@gmail.com>
L: etnaviv@lists.freedesktop.org L: etnaviv@lists.freedesktop.org (moderated for non-subscribers)
L: dri-devel@lists.freedesktop.org L: dri-devel@lists.freedesktop.org
S: Maintained S: Maintained
F: drivers/gpu/drm/etnaviv/ F: drivers/gpu/drm/etnaviv/

View File

@ -947,10 +947,6 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
if (r) if (r)
return r; return r;
r = amdgpu_vm_clear_bo(adev, vm, pt, cursor.level, ats);
if (r)
goto error_free_pt;
if (vm->use_cpu_for_update) { if (vm->use_cpu_for_update) {
r = amdgpu_bo_kmap(pt, NULL); r = amdgpu_bo_kmap(pt, NULL);
if (r) if (r)
@ -963,6 +959,10 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
pt->parent = amdgpu_bo_ref(cursor.parent->base.bo); pt->parent = amdgpu_bo_ref(cursor.parent->base.bo);
amdgpu_vm_bo_base_init(&entry->base, vm, pt); amdgpu_vm_bo_base_init(&entry->base, vm, pt);
r = amdgpu_vm_clear_bo(adev, vm, pt, cursor.level, ats);
if (r)
goto error_free_pt;
} }
return 0; return 0;
@ -3033,13 +3033,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r) if (r)
goto error_unreserve; goto error_unreserve;
amdgpu_vm_bo_base_init(&vm->root.base, vm, root);
r = amdgpu_vm_clear_bo(adev, vm, root, r = amdgpu_vm_clear_bo(adev, vm, root,
adev->vm_manager.root_level, adev->vm_manager.root_level,
vm->pte_support_ats); vm->pte_support_ats);
if (r) if (r)
goto error_unreserve; goto error_unreserve;
amdgpu_vm_bo_base_init(&vm->root.base, vm, root);
amdgpu_bo_unreserve(vm->root.base.bo); amdgpu_bo_unreserve(vm->root.base.bo);
if (pasid) { if (pasid) {

View File

@ -220,6 +220,7 @@ static const struct soc15_reg_golden golden_settings_gc_9_1_rv2[] =
static const struct soc15_reg_golden golden_settings_gc_9_x_common[] = static const struct soc15_reg_golden golden_settings_gc_9_x_common[] =
{ {
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_SD_CNTL, 0xffffffff, 0x000001ff),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_INDEX, 0xffffffff, 0x00000000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_INDEX, 0xffffffff, 0x00000000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2544c382) SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2544c382)
}; };

View File

@ -500,9 +500,7 @@ static bool psp_v3_1_smu_reload_quirk(struct psp_context *psp)
struct amdgpu_device *adev = psp->adev; struct amdgpu_device *adev = psp->adev;
uint32_t reg; uint32_t reg;
reg = smnMP1_FIRMWARE_FLAGS | 0x03b00000; reg = RREG32_PCIE(smnMP1_FIRMWARE_FLAGS | 0x03b00000);
WREG32_SOC15(NBIO, 0, mmPCIE_INDEX2, reg);
reg = RREG32_SOC15(NBIO, 0, mmPCIE_DATA2);
return (reg & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) ? true : false; return (reg & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) ? true : false;
} }

View File

@ -461,7 +461,6 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
switch (adev->asic_type) { switch (adev->asic_type) {
case CHIP_VEGA10: case CHIP_VEGA10:
case CHIP_VEGA20:
soc15_asic_get_baco_capability(adev, &baco_reset); soc15_asic_get_baco_capability(adev, &baco_reset);
break; break;
default: default:

View File

@ -323,57 +323,7 @@ static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr, struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *q) struct queue_properties *q)
{ {
uint64_t addr; return init_mqd(mm, mqd, mqd_mem_obj, gart_addr, q);
struct cik_mqd *m;
int retval;
retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
mqd_mem_obj);
if (retval != 0)
return -ENOMEM;
m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
addr = (*mqd_mem_obj)->gpu_addr;
memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
m->header = 0xC0310800;
m->compute_pipelinestat_enable = 1;
m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE |
PRELOAD_REQ;
m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
QUANTUM_DURATION(10);
m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
m->cp_mqd_base_addr_lo = lower_32_bits(addr);
m->cp_mqd_base_addr_hi = upper_32_bits(addr);
m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE;
/*
* Pipe Priority
* Identifies the pipe relative priority when this queue is connected
* to the pipeline. The pipe priority is against the GFX pipe and HP3D.
* In KFD we are using a fixed pipe priority set to CS_MEDIUM.
* 0 = CS_LOW (typically below GFX)
* 1 = CS_MEDIUM (typically between HP3D and GFX
* 2 = CS_HIGH (typically above HP3D)
*/
m->cp_hqd_pipe_priority = 1;
m->cp_hqd_queue_priority = 15;
*mqd = m;
if (gart_addr)
*gart_addr = addr;
retval = mm->update_mqd(mm, m, q);
return retval;
} }
static int update_mqd_hiq(struct mqd_manager *mm, void *mqd, static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,

View File

@ -886,6 +886,7 @@ static void emulated_link_detect(struct dc_link *link)
return; return;
} }
/* dc_sink_create returns a new reference */
link->local_sink = sink; link->local_sink = sink;
edid_status = dm_helpers_read_local_edid( edid_status = dm_helpers_read_local_edid(
@ -952,6 +953,8 @@ static int dm_resume(void *handle)
if (aconnector->fake_enable && aconnector->dc_link->local_sink) if (aconnector->fake_enable && aconnector->dc_link->local_sink)
aconnector->fake_enable = false; aconnector->fake_enable = false;
if (aconnector->dc_sink)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL; aconnector->dc_sink = NULL;
amdgpu_dm_update_connector_after_detect(aconnector); amdgpu_dm_update_connector_after_detect(aconnector);
mutex_unlock(&aconnector->hpd_lock); mutex_unlock(&aconnector->hpd_lock);
@ -1061,6 +1064,8 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
sink = aconnector->dc_link->local_sink; sink = aconnector->dc_link->local_sink;
if (sink)
dc_sink_retain(sink);
/* /*
* Edid mgmt connector gets first update only in mode_valid hook and then * Edid mgmt connector gets first update only in mode_valid hook and then
@ -1085,21 +1090,24 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
* to it anymore after disconnect, so on next crtc to connector * to it anymore after disconnect, so on next crtc to connector
* reshuffle by UMD we will get into unwanted dc_sink release * reshuffle by UMD we will get into unwanted dc_sink release
*/ */
if (aconnector->dc_sink != aconnector->dc_em_sink) dc_sink_release(aconnector->dc_sink);
dc_sink_release(aconnector->dc_sink);
} }
aconnector->dc_sink = sink; aconnector->dc_sink = sink;
dc_sink_retain(aconnector->dc_sink);
amdgpu_dm_update_freesync_caps(connector, amdgpu_dm_update_freesync_caps(connector,
aconnector->edid); aconnector->edid);
} else { } else {
amdgpu_dm_update_freesync_caps(connector, NULL); amdgpu_dm_update_freesync_caps(connector, NULL);
if (!aconnector->dc_sink) if (!aconnector->dc_sink) {
aconnector->dc_sink = aconnector->dc_em_sink; aconnector->dc_sink = aconnector->dc_em_sink;
else if (aconnector->dc_sink != aconnector->dc_em_sink)
dc_sink_retain(aconnector->dc_sink); dc_sink_retain(aconnector->dc_sink);
}
} }
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
if (sink)
dc_sink_release(sink);
return; return;
} }
@ -1107,8 +1115,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
* TODO: temporary guard to look for proper fix * TODO: temporary guard to look for proper fix
* if this sink is MST sink, we should not do anything * if this sink is MST sink, we should not do anything
*/ */
if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
dc_sink_release(sink);
return; return;
}
if (aconnector->dc_sink == sink) { if (aconnector->dc_sink == sink) {
/* /*
@ -1117,6 +1127,8 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
*/ */
DRM_DEBUG_DRIVER("DCHPD: connector_id=%d: dc_sink didn't change.\n", DRM_DEBUG_DRIVER("DCHPD: connector_id=%d: dc_sink didn't change.\n",
aconnector->connector_id); aconnector->connector_id);
if (sink)
dc_sink_release(sink);
return; return;
} }
@ -1138,6 +1150,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
amdgpu_dm_update_freesync_caps(connector, NULL); amdgpu_dm_update_freesync_caps(connector, NULL);
aconnector->dc_sink = sink; aconnector->dc_sink = sink;
dc_sink_retain(aconnector->dc_sink);
if (sink->dc_edid.length == 0) { if (sink->dc_edid.length == 0) {
aconnector->edid = NULL; aconnector->edid = NULL;
drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux); drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
@ -1158,11 +1171,15 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
amdgpu_dm_update_freesync_caps(connector, NULL); amdgpu_dm_update_freesync_caps(connector, NULL);
drm_connector_update_edid_property(connector, NULL); drm_connector_update_edid_property(connector, NULL);
aconnector->num_modes = 0; aconnector->num_modes = 0;
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL; aconnector->dc_sink = NULL;
aconnector->edid = NULL; aconnector->edid = NULL;
} }
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
if (sink)
dc_sink_release(sink);
} }
static void handle_hpd_irq(void *param) static void handle_hpd_irq(void *param)
@ -2977,6 +2994,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
return stream; return stream;
} else { } else {
sink = aconnector->dc_sink; sink = aconnector->dc_sink;
dc_sink_retain(sink);
} }
stream = dc_create_stream_for_sink(sink); stream = dc_create_stream_for_sink(sink);
@ -3042,8 +3060,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
update_stream_signal(stream, sink); update_stream_signal(stream, sink);
finish: finish:
if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON) dc_sink_release(sink);
dc_sink_release(sink);
return stream; return stream;
} }
@ -3301,6 +3318,14 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
dm->backlight_dev = NULL; dm->backlight_dev = NULL;
} }
#endif #endif
if (aconnector->dc_em_sink)
dc_sink_release(aconnector->dc_em_sink);
aconnector->dc_em_sink = NULL;
if (aconnector->dc_sink)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
drm_dp_cec_unregister_connector(&aconnector->dm_dp_aux.aux); drm_dp_cec_unregister_connector(&aconnector->dm_dp_aux.aux);
drm_connector_unregister(connector); drm_connector_unregister(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
@ -3398,10 +3423,12 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
(edid->extensions + 1) * EDID_LENGTH, (edid->extensions + 1) * EDID_LENGTH,
&init_params); &init_params);
if (aconnector->base.force == DRM_FORCE_ON) if (aconnector->base.force == DRM_FORCE_ON) {
aconnector->dc_sink = aconnector->dc_link->local_sink ? aconnector->dc_sink = aconnector->dc_link->local_sink ?
aconnector->dc_link->local_sink : aconnector->dc_link->local_sink :
aconnector->dc_em_sink; aconnector->dc_em_sink;
dc_sink_retain(aconnector->dc_sink);
}
} }
static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector) static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)

View File

@ -191,6 +191,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
&init_params); &init_params);
dc_sink->priv = aconnector; dc_sink->priv = aconnector;
/* dc_link_add_remote_sink returns a new reference */
aconnector->dc_sink = dc_sink; aconnector->dc_sink = dc_sink;
if (aconnector->dc_sink) if (aconnector->dc_sink)

View File

@ -1348,12 +1348,12 @@ void dcn_bw_update_from_pplib(struct dc *dc)
struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0}; struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};
bool res; bool res;
kernel_fpu_begin();
/* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */ /* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
res = dm_pp_get_clock_levels_by_type_with_voltage( res = dm_pp_get_clock_levels_by_type_with_voltage(
ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks); ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks);
kernel_fpu_begin();
if (res) if (res)
res = verify_clock_values(&fclks); res = verify_clock_values(&fclks);
@ -1372,9 +1372,13 @@ void dcn_bw_update_from_pplib(struct dc *dc)
} else } else
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
kernel_fpu_end();
res = dm_pp_get_clock_levels_by_type_with_voltage( res = dm_pp_get_clock_levels_by_type_with_voltage(
ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks); ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks);
kernel_fpu_begin();
if (res) if (res)
res = verify_clock_values(&dcfclks); res = verify_clock_values(&dcfclks);

View File

@ -794,6 +794,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock; sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
sink->converter_disable_audio = converter_disable_audio; sink->converter_disable_audio = converter_disable_audio;
/* dc_sink_create returns a new reference */
link->local_sink = sink; link->local_sink = sink;
edid_status = dm_helpers_read_local_edid( edid_status = dm_helpers_read_local_edid(
@ -2037,6 +2038,9 @@ static enum dc_status enable_link(
break; break;
} }
if (status == DC_OK)
pipe_ctx->stream->link->link_status.link_active = true;
return status; return status;
} }
@ -2060,6 +2064,14 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
dp_disable_link_phy_mst(link, signal); dp_disable_link_phy_mst(link, signal);
} else } else
link->link_enc->funcs->disable_output(link->link_enc, signal); link->link_enc->funcs->disable_output(link->link_enc, signal);
if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
/* MST disable link only when no stream use the link */
if (link->mst_stream_alloc_table.stream_count <= 0)
link->link_status.link_active = false;
} else {
link->link_status.link_active = false;
}
} }
static bool dp_active_dongle_validate_timing( static bool dp_active_dongle_validate_timing(
@ -2623,8 +2635,6 @@ void core_link_enable_stream(
} }
} }
stream->link->link_status.link_active = true;
core_dc->hwss.enable_audio_stream(pipe_ctx); core_dc->hwss.enable_audio_stream(pipe_ctx);
/* turn off otg test pattern if enable */ /* turn off otg test pattern if enable */
@ -2659,8 +2669,6 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
core_dc->hwss.disable_stream(pipe_ctx, option); core_dc->hwss.disable_stream(pipe_ctx, option);
disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
pipe_ctx->stream->link->link_status.link_active = false;
} }
void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)

View File

@ -724,7 +724,7 @@ static void build_vrr_infopacket_v1(enum signal_type signal,
static void build_vrr_infopacket_v2(enum signal_type signal, static void build_vrr_infopacket_v2(enum signal_type signal,
const struct mod_vrr_params *vrr, const struct mod_vrr_params *vrr,
const enum color_transfer_func *app_tf, enum color_transfer_func app_tf,
struct dc_info_packet *infopacket) struct dc_info_packet *infopacket)
{ {
unsigned int payload_size = 0; unsigned int payload_size = 0;
@ -732,8 +732,7 @@ static void build_vrr_infopacket_v2(enum signal_type signal,
build_vrr_infopacket_header_v2(signal, infopacket, &payload_size); build_vrr_infopacket_header_v2(signal, infopacket, &payload_size);
build_vrr_infopacket_data(vrr, infopacket); build_vrr_infopacket_data(vrr, infopacket);
if (app_tf != NULL) build_vrr_infopacket_fs2_data(app_tf, infopacket);
build_vrr_infopacket_fs2_data(*app_tf, infopacket);
build_vrr_infopacket_checksum(&payload_size, infopacket); build_vrr_infopacket_checksum(&payload_size, infopacket);
@ -757,7 +756,7 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
const struct dc_stream_state *stream, const struct dc_stream_state *stream,
const struct mod_vrr_params *vrr, const struct mod_vrr_params *vrr,
enum vrr_packet_type packet_type, enum vrr_packet_type packet_type,
const enum color_transfer_func *app_tf, enum color_transfer_func app_tf,
struct dc_info_packet *infopacket) struct dc_info_packet *infopacket)
{ {
/* SPD info packet for FreeSync /* SPD info packet for FreeSync

View File

@ -145,7 +145,7 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
const struct dc_stream_state *stream, const struct dc_stream_state *stream,
const struct mod_vrr_params *vrr, const struct mod_vrr_params *vrr,
enum vrr_packet_type packet_type, enum vrr_packet_type packet_type,
const enum color_transfer_func *app_tf, enum color_transfer_func app_tf,
struct dc_info_packet *infopacket); struct dc_info_packet *infopacket);
void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,

View File

@ -277,8 +277,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
if (!skip_display_settings) if (!skip_display_settings)
phm_notify_smc_display_config_after_ps_adjustment(hwmgr); phm_notify_smc_display_config_after_ps_adjustment(hwmgr);
if ((hwmgr->request_dpm_level != hwmgr->dpm_level) && if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level))
!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level))
hwmgr->dpm_level = hwmgr->request_dpm_level; hwmgr->dpm_level = hwmgr->request_dpm_level;
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {

View File

@ -489,15 +489,16 @@ int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,
} }
int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr,
uint8_t id, uint32_t *frequency) uint8_t clk_id, uint8_t syspll_id,
uint32_t *frequency)
{ {
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
struct atom_get_smu_clock_info_parameters_v3_1 parameters; struct atom_get_smu_clock_info_parameters_v3_1 parameters;
struct atom_get_smu_clock_info_output_parameters_v3_1 *output; struct atom_get_smu_clock_info_output_parameters_v3_1 *output;
uint32_t ix; uint32_t ix;
parameters.clk_id = id; parameters.clk_id = clk_id;
parameters.syspll_id = 0; parameters.syspll_id = syspll_id;
parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ; parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ;
parameters.dfsdid = 0; parameters.dfsdid = 0;
@ -530,20 +531,23 @@ static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr,
boot_values->ulSocClk = 0; boot_values->ulSocClk = 0;
boot_values->ulDCEFClk = 0; boot_values->ulDCEFClk = 0;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, SMU11_SYSPLL0_ID, &frequency))
boot_values->ulSocClk = frequency; boot_values->ulSocClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, SMU11_SYSPLL0_ID, &frequency))
boot_values->ulDCEFClk = frequency; boot_values->ulDCEFClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, SMU11_SYSPLL0_ID, &frequency))
boot_values->ulEClk = frequency; boot_values->ulEClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, SMU11_SYSPLL0_ID, &frequency))
boot_values->ulVClk = frequency; boot_values->ulVClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, SMU11_SYSPLL0_ID, &frequency))
boot_values->ulDClk = frequency; boot_values->ulDClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL1_0_FCLK_ID, SMU11_SYSPLL1_2_ID, &frequency))
boot_values->ulFClk = frequency;
} }
static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr, static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr,
@ -563,19 +567,19 @@ static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr,
boot_values->ulSocClk = 0; boot_values->ulSocClk = 0;
boot_values->ulDCEFClk = 0; boot_values->ulDCEFClk = 0;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, 0, &frequency))
boot_values->ulSocClk = frequency; boot_values->ulSocClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, 0, &frequency))
boot_values->ulDCEFClk = frequency; boot_values->ulDCEFClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, 0, &frequency))
boot_values->ulEClk = frequency; boot_values->ulEClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, 0, &frequency))
boot_values->ulVClk = frequency; boot_values->ulVClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, &frequency)) if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, 0, &frequency))
boot_values->ulDClk = frequency; boot_values->ulDClk = frequency;
} }

View File

@ -139,6 +139,7 @@ struct pp_atomfwctrl_bios_boot_up_values {
uint32_t ulEClk; uint32_t ulEClk;
uint32_t ulVClk; uint32_t ulVClk;
uint32_t ulDClk; uint32_t ulDClk;
uint32_t ulFClk;
uint16_t usVddc; uint16_t usVddc;
uint16_t usVddci; uint16_t usVddci;
uint16_t usMvddc; uint16_t usMvddc;
@ -236,7 +237,8 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr, int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_smc_dpm_parameters *param); struct pp_atomfwctrl_smc_dpm_parameters *param);
int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr,
uint8_t id, uint32_t *frequency); uint8_t clk_id, uint8_t syspll_id,
uint32_t *frequency);
#endif #endif

View File

@ -3491,14 +3491,14 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogStart); smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogStart);
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
ixSMU_PM_STATUS_94, 0); ixSMU_PM_STATUS_95, 0);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
mdelay(1); mdelay(500);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogSample); smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogSample);
tmp = cgs_read_ind_register(hwmgr->device, tmp = cgs_read_ind_register(hwmgr->device,
CGS_IND_REG__SMC, CGS_IND_REG__SMC,
ixSMU_PM_STATUS_94); ixSMU_PM_STATUS_95);
if (tmp != 0) if (tmp != 0)
break; break;
} }

View File

@ -2575,10 +2575,10 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk; data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk;
data->vbios_boot_state.mem_clock = boot_up_values.ulUClk; data->vbios_boot_state.mem_clock = boot_up_values.ulUClk;
pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, pp_atomfwctrl_get_clk_information_by_clkid(hwmgr,
SMU9_SYSPLL0_SOCCLK_ID, &boot_up_values.ulSocClk); SMU9_SYSPLL0_SOCCLK_ID, 0, &boot_up_values.ulSocClk);
pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, pp_atomfwctrl_get_clk_information_by_clkid(hwmgr,
SMU9_SYSPLL0_DCEFCLK_ID, &boot_up_values.ulDCEFClk); SMU9_SYSPLL0_DCEFCLK_ID, 0, &boot_up_values.ulDCEFClk);
data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk; data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;
data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk; data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk;
@ -4407,9 +4407,9 @@ static int vega10_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe
return ret; return ret;
features_to_disable = features_to_disable =
(features_enabled ^ new_ppfeature_masks) & features_enabled; features_enabled & ~new_ppfeature_masks;
features_to_enable = features_to_enable =
(features_enabled ^ new_ppfeature_masks) ^ features_to_disable; ~features_enabled & new_ppfeature_masks;
pr_debug("features_to_disable 0x%llx\n", features_to_disable); pr_debug("features_to_disable 0x%llx\n", features_to_disable);
pr_debug("features_to_enable 0x%llx\n", features_to_enable); pr_debug("features_to_enable 0x%llx\n", features_to_enable);

View File

@ -2009,9 +2009,9 @@ static int vega12_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe
return ret; return ret;
features_to_disable = features_to_disable =
(features_enabled ^ new_ppfeature_masks) & features_enabled; features_enabled & ~new_ppfeature_masks;
features_to_enable = features_to_enable =
(features_enabled ^ new_ppfeature_masks) ^ features_to_disable; ~features_enabled & new_ppfeature_masks;
pr_debug("features_to_disable 0x%llx\n", features_to_disable); pr_debug("features_to_disable 0x%llx\n", features_to_disable);
pr_debug("features_to_enable 0x%llx\n", features_to_enable); pr_debug("features_to_enable 0x%llx\n", features_to_enable);

View File

@ -463,9 +463,9 @@ static int vega20_setup_asic_task(struct pp_hwmgr *hwmgr)
static void vega20_init_dpm_state(struct vega20_dpm_state *dpm_state) static void vega20_init_dpm_state(struct vega20_dpm_state *dpm_state)
{ {
dpm_state->soft_min_level = 0x0; dpm_state->soft_min_level = 0x0;
dpm_state->soft_max_level = 0xffff; dpm_state->soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_state->hard_min_level = 0x0; dpm_state->hard_min_level = 0x0;
dpm_state->hard_max_level = 0xffff; dpm_state->hard_max_level = VG20_CLOCK_MAX_DEFAULT;
} }
static int vega20_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, static int vega20_get_number_of_dpm_level(struct pp_hwmgr *hwmgr,
@ -711,8 +711,10 @@ static int vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
"[SetupDefaultDpmTable] failed to get fclk dpm levels!", "[SetupDefaultDpmTable] failed to get fclk dpm levels!",
return ret); return ret);
} else } else {
dpm_table->count = 0; dpm_table->count = 1;
dpm_table->dpm_levels[0].value = data->vbios_boot_state.fclock / 100;
}
vega20_init_dpm_state(&(dpm_table->dpm_state)); vega20_init_dpm_state(&(dpm_table->dpm_state));
/* save a copy of the default DPM table */ /* save a copy of the default DPM table */
@ -754,6 +756,7 @@ static int vega20_init_smc_table(struct pp_hwmgr *hwmgr)
data->vbios_boot_state.eclock = boot_up_values.ulEClk; data->vbios_boot_state.eclock = boot_up_values.ulEClk;
data->vbios_boot_state.vclock = boot_up_values.ulVClk; data->vbios_boot_state.vclock = boot_up_values.ulVClk;
data->vbios_boot_state.dclock = boot_up_values.ulDClk; data->vbios_boot_state.dclock = boot_up_values.ulDClk;
data->vbios_boot_state.fclock = boot_up_values.ulFClk;
data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID; data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID;
smum_send_msg_to_smc_with_parameter(hwmgr, smum_send_msg_to_smc_with_parameter(hwmgr,
@ -780,6 +783,8 @@ static int vega20_init_smc_table(struct pp_hwmgr *hwmgr)
static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr) static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;
int ret; int ret;
@ -816,6 +821,10 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
"[OverridePcieParameters] Attempt to override pcie params failed!", "[OverridePcieParameters] Attempt to override pcie params failed!",
return ret); return ret);
data->pcie_parameters_override = 1;
data->pcie_gen_level1 = pcie_gen;
data->pcie_width_level1 = pcie_width;
return 0; return 0;
} }
@ -979,6 +988,8 @@ static int vega20_od8_set_feature_capabilities(
} }
if (data->smu_features[GNLD_DPM_UCLK].enabled) { if (data->smu_features[GNLD_DPM_UCLK].enabled) {
pptable_information->od_settings_min[OD8_SETTING_UCLK_FMAX] =
data->dpm_table.mem_table.dpm_levels[data->dpm_table.mem_table.count - 2].value;
if (pptable_information->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_UCLK_MAX] && if (pptable_information->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_UCLK_MAX] &&
pptable_information->od_settings_min[OD8_SETTING_UCLK_FMAX] > 0 && pptable_information->od_settings_min[OD8_SETTING_UCLK_FMAX] > 0 &&
pptable_information->od_settings_max[OD8_SETTING_UCLK_FMAX] > 0 && pptable_information->od_settings_max[OD8_SETTING_UCLK_FMAX] > 0 &&
@ -2314,32 +2325,8 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr)
static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr) static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
{ {
struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend);
uint32_t soft_min_level, soft_max_level;
int ret = 0; int ret = 0;
soft_min_level = vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
soft_max_level = vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table));
data->dpm_table.gfx_table.dpm_state.soft_min_level =
data->dpm_table.gfx_table.dpm_levels[soft_min_level].value;
data->dpm_table.gfx_table.dpm_state.soft_max_level =
data->dpm_table.gfx_table.dpm_levels[soft_max_level].value;
soft_min_level = vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table));
soft_max_level = vega20_find_highest_dpm_level(&(data->dpm_table.mem_table));
data->dpm_table.mem_table.dpm_state.soft_min_level =
data->dpm_table.mem_table.dpm_levels[soft_min_level].value;
data->dpm_table.mem_table.dpm_state.soft_max_level =
data->dpm_table.mem_table.dpm_levels[soft_max_level].value;
soft_min_level = vega20_find_lowest_dpm_level(&(data->dpm_table.soc_table));
soft_max_level = vega20_find_highest_dpm_level(&(data->dpm_table.soc_table));
data->dpm_table.soc_table.dpm_state.soft_min_level =
data->dpm_table.soc_table.dpm_levels[soft_min_level].value;
data->dpm_table.soc_table.dpm_state.soft_max_level =
data->dpm_table.soc_table.dpm_levels[soft_max_level].value;
ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF); ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);
PP_ASSERT_WITH_CODE(!ret, PP_ASSERT_WITH_CODE(!ret,
"Failed to upload DPM Bootup Levels!", "Failed to upload DPM Bootup Levels!",
@ -2641,9 +2628,8 @@ static int vega20_get_sclks(struct pp_hwmgr *hwmgr,
struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table); struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table);
int i, count; int i, count;
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_GFXCLK].enabled, if (!data->smu_features[GNLD_DPM_GFXCLK].enabled)
"[GetSclks]: gfxclk dpm not enabled!\n", return -1;
return -EPERM);
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count; count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
clocks->num_levels = count; clocks->num_levels = count;
@ -2670,9 +2656,8 @@ static int vega20_get_memclocks(struct pp_hwmgr *hwmgr,
struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.mem_table); struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.mem_table);
int i, count; int i, count;
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_UCLK].enabled, if (!data->smu_features[GNLD_DPM_UCLK].enabled)
"[GetMclks]: uclk dpm not enabled!\n", return -1;
return -EPERM);
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count; count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
clocks->num_levels = data->mclk_latency_table.count = count; clocks->num_levels = data->mclk_latency_table.count = count;
@ -2696,9 +2681,8 @@ static int vega20_get_dcefclocks(struct pp_hwmgr *hwmgr,
struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.dcef_table); struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.dcef_table);
int i, count; int i, count;
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_DCEFCLK].enabled, if (!data->smu_features[GNLD_DPM_DCEFCLK].enabled)
"[GetDcfclocks]: dcefclk dpm not enabled!\n", return -1;
return -EPERM);
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count; count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
clocks->num_levels = count; clocks->num_levels = count;
@ -2719,9 +2703,8 @@ static int vega20_get_socclocks(struct pp_hwmgr *hwmgr,
struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.soc_table); struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.soc_table);
int i, count; int i, count;
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_SOCCLK].enabled, if (!data->smu_features[GNLD_DPM_SOCCLK].enabled)
"[GetSocclks]: socclk dpm not enabled!\n", return -1;
return -EPERM);
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count; count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
clocks->num_levels = count; clocks->num_levels = count;
@ -2799,7 +2782,6 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
data->od8_settings.od8_settings_array; data->od8_settings.od8_settings_array;
OverDriveTable_t *od_table = OverDriveTable_t *od_table =
&(data->smc_state_table.overdrive_table); &(data->smc_state_table.overdrive_table);
struct pp_clock_levels_with_latency clocks;
int32_t input_index, input_clk, input_vol, i; int32_t input_index, input_clk, input_vol, i;
int od8_id; int od8_id;
int ret; int ret;
@ -2858,11 +2840,6 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
ret = vega20_get_memclocks(hwmgr, &clocks);
PP_ASSERT_WITH_CODE(!ret,
"Attempt to get memory clk levels failed!",
return ret);
for (i = 0; i < size; i += 2) { for (i = 0; i < size; i += 2) {
if (i + 2 > size) { if (i + 2 > size) {
pr_info("invalid number of input parameters %d\n", pr_info("invalid number of input parameters %d\n",
@ -2879,11 +2856,11 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
return -EINVAL; return -EINVAL;
} }
if (input_clk < clocks.data[0].clocks_in_khz / 1000 || if (input_clk < od8_settings[OD8_SETTING_UCLK_FMAX].min_value ||
input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) { input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) {
pr_info("clock freq %d is not within allowed range [%d - %d]\n", pr_info("clock freq %d is not within allowed range [%d - %d]\n",
input_clk, input_clk,
clocks.data[0].clocks_in_khz / 1000, od8_settings[OD8_SETTING_UCLK_FMAX].min_value,
od8_settings[OD8_SETTING_UCLK_FMAX].max_value); od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
return -EINVAL; return -EINVAL;
} }
@ -3088,9 +3065,9 @@ static int vega20_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe
return ret; return ret;
features_to_disable = features_to_disable =
(features_enabled ^ new_ppfeature_masks) & features_enabled; features_enabled & ~new_ppfeature_masks;
features_to_enable = features_to_enable =
(features_enabled ^ new_ppfeature_masks) ^ features_to_disable; ~features_enabled & new_ppfeature_masks;
pr_debug("features_to_disable 0x%llx\n", features_to_disable); pr_debug("features_to_disable 0x%llx\n", features_to_disable);
pr_debug("features_to_enable 0x%llx\n", features_to_enable); pr_debug("features_to_enable 0x%llx\n", features_to_enable);
@ -3128,7 +3105,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
&(data->dpm_table.fclk_table); &(data->dpm_table.fclk_table);
int i, now, size = 0; int i, now, size = 0;
int ret = 0; int ret = 0;
uint32_t gen_speed, lane_width; uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
switch (type) { switch (type) {
case PP_SCLK: case PP_SCLK:
@ -3137,10 +3114,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
"Attempt to get current gfx clk Failed!", "Attempt to get current gfx clk Failed!",
return ret); return ret);
ret = vega20_get_sclks(hwmgr, &clocks); if (vega20_get_sclks(hwmgr, &clocks)) {
PP_ASSERT_WITH_CODE(!ret, size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
"Attempt to get gfx clk levels Failed!", now / 100);
return ret); break;
}
for (i = 0; i < clocks.num_levels; i++) for (i = 0; i < clocks.num_levels; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -3154,10 +3132,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
"Attempt to get current mclk freq Failed!", "Attempt to get current mclk freq Failed!",
return ret); return ret);
ret = vega20_get_memclocks(hwmgr, &clocks); if (vega20_get_memclocks(hwmgr, &clocks)) {
PP_ASSERT_WITH_CODE(!ret, size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
"Attempt to get memory clk levels Failed!", now / 100);
return ret); break;
}
for (i = 0; i < clocks.num_levels; i++) for (i = 0; i < clocks.num_levels; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -3171,10 +3150,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
"Attempt to get current socclk freq Failed!", "Attempt to get current socclk freq Failed!",
return ret); return ret);
ret = vega20_get_socclocks(hwmgr, &clocks); if (vega20_get_socclocks(hwmgr, &clocks)) {
PP_ASSERT_WITH_CODE(!ret, size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
"Attempt to get soc clk levels Failed!", now / 100);
return ret); break;
}
for (i = 0; i < clocks.num_levels; i++) for (i = 0; i < clocks.num_levels; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -3200,10 +3180,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
"Attempt to get current dcefclk freq Failed!", "Attempt to get current dcefclk freq Failed!",
return ret); return ret);
ret = vega20_get_dcefclocks(hwmgr, &clocks); if (vega20_get_dcefclocks(hwmgr, &clocks)) {
PP_ASSERT_WITH_CODE(!ret, size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
"Attempt to get dcefclk levels Failed!", now / 100);
return ret); break;
}
for (i = 0; i < clocks.num_levels; i++) for (i = 0; i < clocks.num_levels; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -3212,28 +3193,36 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
break; break;
case PP_PCIE: case PP_PCIE:
gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & current_gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &
PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)
>> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & current_lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) &
PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK)
>> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT;
for (i = 0; i < NUM_LINK_LEVELS; i++) for (i = 0; i < NUM_LINK_LEVELS; i++) {
if (i == 1 && data->pcie_parameters_override) {
gen_speed = data->pcie_gen_level1;
lane_width = data->pcie_width_level1;
} else {
gen_speed = pptable->PcieGenSpeed[i];
lane_width = pptable->PcieLaneCount[i];
}
size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
(pptable->PcieGenSpeed[i] == 0) ? "2.5GT/s," : (gen_speed == 0) ? "2.5GT/s," :
(pptable->PcieGenSpeed[i] == 1) ? "5.0GT/s," : (gen_speed == 1) ? "5.0GT/s," :
(pptable->PcieGenSpeed[i] == 2) ? "8.0GT/s," : (gen_speed == 2) ? "8.0GT/s," :
(pptable->PcieGenSpeed[i] == 3) ? "16.0GT/s," : "", (gen_speed == 3) ? "16.0GT/s," : "",
(pptable->PcieLaneCount[i] == 1) ? "x1" : (lane_width == 1) ? "x1" :
(pptable->PcieLaneCount[i] == 2) ? "x2" : (lane_width == 2) ? "x2" :
(pptable->PcieLaneCount[i] == 3) ? "x4" : (lane_width == 3) ? "x4" :
(pptable->PcieLaneCount[i] == 4) ? "x8" : (lane_width == 4) ? "x8" :
(pptable->PcieLaneCount[i] == 5) ? "x12" : (lane_width == 5) ? "x12" :
(pptable->PcieLaneCount[i] == 6) ? "x16" : "", (lane_width == 6) ? "x16" : "",
pptable->LclkFreq[i], pptable->LclkFreq[i],
(gen_speed == pptable->PcieGenSpeed[i]) && (current_gen_speed == gen_speed) &&
(lane_width == pptable->PcieLaneCount[i]) ? (current_lane_width == lane_width) ?
"*" : ""); "*" : "");
}
break; break;
case OD_SCLK: case OD_SCLK:
@ -3288,13 +3277,8 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
} }
if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) { if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) {
ret = vega20_get_memclocks(hwmgr, &clocks);
PP_ASSERT_WITH_CODE(!ret,
"Fail to get memory clk levels!",
return ret);
size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n", size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
clocks.data[0].clocks_in_khz / 1000, od8_settings[OD8_SETTING_UCLK_FMAX].min_value,
od8_settings[OD8_SETTING_UCLK_FMAX].max_value); od8_settings[OD8_SETTING_UCLK_FMAX].max_value);
} }
@ -3356,6 +3340,31 @@ static int vega20_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr,
return ret; return ret;
} }
static int vega20_set_fclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr)
{
struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.fclk_table);
int ret = 0;
if (data->smu_features[GNLD_DPM_FCLK].enabled) {
PP_ASSERT_WITH_CODE(dpm_table->count > 0,
"[SetFclkToHightestDpmLevel] Dpm table has no entry!",
return -EINVAL);
PP_ASSERT_WITH_CODE(dpm_table->count <= NUM_FCLK_DPM_LEVELS,
"[SetFclkToHightestDpmLevel] Dpm table has too many entries!",
return -EINVAL);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetSoftMinByFreq,
(PPCLK_FCLK << 16 ) | dpm_table->dpm_state.soft_min_level)),
"[SetFclkToHightestDpmLevel] Set soft min fclk failed!",
return ret);
}
return ret;
}
static int vega20_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr) static int vega20_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
{ {
struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
@ -3366,8 +3375,10 @@ static int vega20_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
ret = vega20_set_uclk_to_highest_dpm_level(hwmgr, ret = vega20_set_uclk_to_highest_dpm_level(hwmgr,
&data->dpm_table.mem_table); &data->dpm_table.mem_table);
if (ret)
return ret;
return ret; return vega20_set_fclk_to_highest_dpm_level(hwmgr);
} }
static int vega20_display_configuration_changed_task(struct pp_hwmgr *hwmgr) static int vega20_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
@ -3461,9 +3472,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
/* gfxclk */ /* gfxclk */
dpm_table = &(data->dpm_table.gfx_table); dpm_table = &(data->dpm_table.gfx_table);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;
if (PP_CAP(PHM_PlatformCaps_UMDPState)) { if (PP_CAP(PHM_PlatformCaps_UMDPState)) {
if (VEGA20_UMD_PSTATE_GFXCLK_LEVEL < dpm_table->count) { if (VEGA20_UMD_PSTATE_GFXCLK_LEVEL < dpm_table->count) {
@ -3485,9 +3496,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
/* memclk */ /* memclk */
dpm_table = &(data->dpm_table.mem_table); dpm_table = &(data->dpm_table.mem_table);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;
if (PP_CAP(PHM_PlatformCaps_UMDPState)) { if (PP_CAP(PHM_PlatformCaps_UMDPState)) {
if (VEGA20_UMD_PSTATE_MCLK_LEVEL < dpm_table->count) { if (VEGA20_UMD_PSTATE_MCLK_LEVEL < dpm_table->count) {
@ -3526,12 +3537,21 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
if (hwmgr->display_config->nb_pstate_switch_disable) if (hwmgr->display_config->nb_pstate_switch_disable)
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
/* fclk */
dpm_table = &(data->dpm_table.fclk_table);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;
if (hwmgr->display_config->nb_pstate_switch_disable)
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value;
/* vclk */ /* vclk */
dpm_table = &(data->dpm_table.vclk_table); dpm_table = &(data->dpm_table.vclk_table);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;
if (PP_CAP(PHM_PlatformCaps_UMDPState)) { if (PP_CAP(PHM_PlatformCaps_UMDPState)) {
if (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) { if (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) {
@ -3548,9 +3568,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
/* dclk */ /* dclk */
dpm_table = &(data->dpm_table.dclk_table); dpm_table = &(data->dpm_table.dclk_table);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;
if (PP_CAP(PHM_PlatformCaps_UMDPState)) { if (PP_CAP(PHM_PlatformCaps_UMDPState)) {
if (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) { if (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) {
@ -3567,9 +3587,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
/* socclk */ /* socclk */
dpm_table = &(data->dpm_table.soc_table); dpm_table = &(data->dpm_table.soc_table);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;
if (PP_CAP(PHM_PlatformCaps_UMDPState)) { if (PP_CAP(PHM_PlatformCaps_UMDPState)) {
if (VEGA20_UMD_PSTATE_SOCCLK_LEVEL < dpm_table->count) { if (VEGA20_UMD_PSTATE_SOCCLK_LEVEL < dpm_table->count) {
@ -3586,9 +3606,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
/* eclk */ /* eclk */
dpm_table = &(data->dpm_table.eclk_table); dpm_table = &(data->dpm_table.eclk_table);
dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;
dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value;
dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;
if (PP_CAP(PHM_PlatformCaps_UMDPState)) { if (PP_CAP(PHM_PlatformCaps_UMDPState)) {
if (VEGA20_UMD_PSTATE_VCEMCLK_LEVEL < dpm_table->count) { if (VEGA20_UMD_PSTATE_VCEMCLK_LEVEL < dpm_table->count) {

View File

@ -42,6 +42,8 @@
#define AVFS_CURVE 0 #define AVFS_CURVE 0
#define OD8_HOTCURVE_TEMPERATURE 85 #define OD8_HOTCURVE_TEMPERATURE 85
#define VG20_CLOCK_MAX_DEFAULT 0xFFFF
typedef uint32_t PP_Clock; typedef uint32_t PP_Clock;
enum { enum {
@ -219,6 +221,7 @@ struct vega20_vbios_boot_state {
uint32_t eclock; uint32_t eclock;
uint32_t dclock; uint32_t dclock;
uint32_t vclock; uint32_t vclock;
uint32_t fclock;
}; };
#define DPMTABLE_OD_UPDATE_SCLK 0x00000001 #define DPMTABLE_OD_UPDATE_SCLK 0x00000001
@ -523,6 +526,10 @@ struct vega20_hwmgr {
unsigned long metrics_time; unsigned long metrics_time;
SmuMetrics_t metrics_table; SmuMetrics_t metrics_table;
bool pcie_parameters_override;
uint32_t pcie_gen_level1;
uint32_t pcie_width_level1;
}; };
#define VEGA20_DPM2_NEAR_TDP_DEC 10 #define VEGA20_DPM2_NEAR_TDP_DEC 10

View File

@ -32,6 +32,8 @@
#include "cgs_common.h" #include "cgs_common.h"
#include "vega20_pptable.h" #include "vega20_pptable.h"
#define VEGA20_FAN_TARGET_TEMPERATURE_OVERRIDE 105
static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable, static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
enum phm_platform_caps cap) enum phm_platform_caps cap)
{ {
@ -798,6 +800,17 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
return 0; return 0;
} }
static int override_powerplay_table_fantargettemperature(struct pp_hwmgr *hwmgr)
{
struct phm_ppt_v3_information *pptable_information =
(struct phm_ppt_v3_information *)hwmgr->pptable;
PPTable_t *ppsmc_pptable = (PPTable_t *)(pptable_information->smc_pptable);
ppsmc_pptable->FanTargetTemperature = VEGA20_FAN_TARGET_TEMPERATURE_OVERRIDE;
return 0;
}
#define VEGA20_ENGINECLOCK_HARDMAX 198000 #define VEGA20_ENGINECLOCK_HARDMAX 198000
static int init_powerplay_table_information( static int init_powerplay_table_information(
struct pp_hwmgr *hwmgr, struct pp_hwmgr *hwmgr,
@ -887,6 +900,10 @@ static int init_powerplay_table_information(
result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable)); result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable));
if (result)
return result;
result = override_powerplay_table_fantargettemperature(hwmgr);
return result; return result;
} }

View File

@ -2330,6 +2330,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member)
case DRAM_LOG_BUFF_SIZE: case DRAM_LOG_BUFF_SIZE:
return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE); return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE);
} }
break;
case SMU_Discrete_DpmTable: case SMU_Discrete_DpmTable:
switch (member) { switch (member) {
case UvdBootLevel: case UvdBootLevel:
@ -2339,6 +2340,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member)
case LowSclkInterruptThreshold: case LowSclkInterruptThreshold:
return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold); return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold);
} }
break;
} }
pr_warn("can't get the offset of type %x member %x\n", type, member); pr_warn("can't get the offset of type %x member %x\n", type, member);
return 0; return 0;

View File

@ -40,10 +40,8 @@ bool smu9_is_smc_ram_running(struct pp_hwmgr *hwmgr)
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
uint32_t mp1_fw_flags; uint32_t mp1_fw_flags;
WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2, mp1_fw_flags = RREG32_PCIE(MP1_Public |
(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2);
if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK)
return true; return true;

View File

@ -49,10 +49,8 @@ static bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
uint32_t mp1_fw_flags; uint32_t mp1_fw_flags;
WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2, mp1_fw_flags = RREG32_PCIE(MP1_Public |
(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2);
if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)

View File

@ -3039,9 +3039,31 @@ commit:
return 0; return 0;
} }
static int __drm_atomic_helper_disable_all(struct drm_device *dev, /**
struct drm_modeset_acquire_ctx *ctx, * drm_atomic_helper_disable_all - disable all currently active outputs
bool clean_old_fbs) * @dev: DRM device
* @ctx: lock acquisition context
*
* Loops through all connectors, finding those that aren't turned off and then
* turns them off by setting their DPMS mode to OFF and deactivating the CRTC
* that they are connected to.
*
* This is used for example in suspend/resume to disable all currently active
* functions when suspending. If you just want to shut down everything at e.g.
* driver unload, look at drm_atomic_helper_shutdown().
*
* Note that if callers haven't already acquired all modeset locks this might
* return -EDEADLK, which must be handled by calling drm_modeset_backoff().
*
* Returns:
* 0 on success or a negative error code on failure.
*
* See also:
* drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
* drm_atomic_helper_shutdown().
*/
int drm_atomic_helper_disable_all(struct drm_device *dev,
struct drm_modeset_acquire_ctx *ctx)
{ {
struct drm_atomic_state *state; struct drm_atomic_state *state;
struct drm_connector_state *conn_state; struct drm_connector_state *conn_state;
@ -3099,35 +3121,6 @@ free:
drm_atomic_state_put(state); drm_atomic_state_put(state);
return ret; return ret;
} }
/**
* drm_atomic_helper_disable_all - disable all currently active outputs
* @dev: DRM device
* @ctx: lock acquisition context
*
* Loops through all connectors, finding those that aren't turned off and then
* turns them off by setting their DPMS mode to OFF and deactivating the CRTC
* that they are connected to.
*
* This is used for example in suspend/resume to disable all currently active
* functions when suspending. If you just want to shut down everything at e.g.
* driver unload, look at drm_atomic_helper_shutdown().
*
* Note that if callers haven't already acquired all modeset locks this might
* return -EDEADLK, which must be handled by calling drm_modeset_backoff().
*
* Returns:
* 0 on success or a negative error code on failure.
*
* See also:
* drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
* drm_atomic_helper_shutdown().
*/
int drm_atomic_helper_disable_all(struct drm_device *dev,
struct drm_modeset_acquire_ctx *ctx)
{
return __drm_atomic_helper_disable_all(dev, ctx, false);
}
EXPORT_SYMBOL(drm_atomic_helper_disable_all); EXPORT_SYMBOL(drm_atomic_helper_disable_all);
/** /**
@ -3148,7 +3141,7 @@ void drm_atomic_helper_shutdown(struct drm_device *dev)
DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
ret = __drm_atomic_helper_disable_all(dev, &ctx, true); ret = drm_atomic_helper_disable_all(dev, &ctx);
if (ret) if (ret)
DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret); DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);

View File

@ -185,7 +185,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
m32.size = map.size; m32.size = map.size;
m32.type = map.type; m32.type = map.type;
m32.flags = map.flags; m32.flags = map.flags;
m32.handle = ptr_to_compat(map.handle); m32.handle = ptr_to_compat((void __user *)map.handle);
m32.mtrr = map.mtrr; m32.mtrr = map.mtrr;
if (copy_to_user(argp, &m32, sizeof(m32))) if (copy_to_user(argp, &m32, sizeof(m32)))
return -EFAULT; return -EFAULT;
@ -216,7 +216,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
m32.offset = map.offset; m32.offset = map.offset;
m32.mtrr = map.mtrr; m32.mtrr = map.mtrr;
m32.handle = ptr_to_compat(map.handle); m32.handle = ptr_to_compat((void __user *)map.handle);
if (map.handle != compat_ptr(m32.handle)) if (map.handle != compat_ptr(m32.handle))
pr_err_ratelimited("compat_drm_addmap truncated handle %p for type %d offset %x\n", pr_err_ratelimited("compat_drm_addmap truncated handle %p for type %d offset %x\n",
map.handle, m32.type, m32.offset); map.handle, m32.type, m32.offset);
@ -526,7 +526,7 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
if (err) if (err)
return err; return err;
req32.handle = ptr_to_compat(req.handle); req32.handle = ptr_to_compat((void __user *)req.handle);
if (copy_to_user(argp, &req32, sizeof(req32))) if (copy_to_user(argp, &req32, sizeof(req32)))
return -EFAULT; return -EFAULT;

View File

@ -2,7 +2,6 @@
config DRM_ETNAVIV config DRM_ETNAVIV
tristate "ETNAVIV (DRM support for Vivante GPU IP cores)" tristate "ETNAVIV (DRM support for Vivante GPU IP cores)"
depends on DRM depends on DRM
depends on ARCH_MXC || ARCH_DOVE || (ARM && COMPILE_TEST)
depends on MMU depends on MMU
select SHMEM select SHMEM
select SYNC_FILE select SYNC_FILE

View File

@ -15,8 +15,6 @@ struct etnaviv_perfmon_request;
struct etnaviv_cmdbuf { struct etnaviv_cmdbuf {
/* suballocator this cmdbuf is allocated from */ /* suballocator this cmdbuf is allocated from */
struct etnaviv_cmdbuf_suballoc *suballoc; struct etnaviv_cmdbuf_suballoc *suballoc;
/* user context key, must be unique between all active users */
struct etnaviv_file_private *ctx;
/* cmdbuf properties */ /* cmdbuf properties */
int suballoc_offset; int suballoc_offset;
void *vaddr; void *vaddr;

View File

@ -215,7 +215,7 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
mutex_lock(&obj->lock); mutex_lock(&obj->lock);
pages = etnaviv_gem_get_pages(obj); pages = etnaviv_gem_get_pages(obj);
mutex_unlock(&obj->lock); mutex_unlock(&obj->lock);
if (pages) { if (!IS_ERR(pages)) {
int j; int j;
iter.hdr->data[0] = bomap - bomap_start; iter.hdr->data[0] = bomap - bomap_start;

View File

@ -95,6 +95,7 @@ struct etnaviv_gem_submit_bo {
struct etnaviv_gem_submit { struct etnaviv_gem_submit {
struct drm_sched_job sched_job; struct drm_sched_job sched_job;
struct kref refcount; struct kref refcount;
struct etnaviv_file_private *ctx;
struct etnaviv_gpu *gpu; struct etnaviv_gpu *gpu;
struct dma_fence *out_fence, *in_fence; struct dma_fence *out_fence, *in_fence;
int out_fence_id; int out_fence_id;

View File

@ -15,7 +15,7 @@ struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj)
int npages = obj->size >> PAGE_SHIFT; int npages = obj->size >> PAGE_SHIFT;
if (WARN_ON(!etnaviv_obj->pages)) /* should have already pinned! */ if (WARN_ON(!etnaviv_obj->pages)) /* should have already pinned! */
return NULL; return ERR_PTR(-EINVAL);
return drm_prime_pages_to_sg(etnaviv_obj->pages, npages); return drm_prime_pages_to_sg(etnaviv_obj->pages, npages);
} }

View File

@ -506,7 +506,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
if (ret) if (ret)
goto err_submit_objects; goto err_submit_objects;
submit->cmdbuf.ctx = file->driver_priv; submit->ctx = file->driver_priv;
submit->exec_state = args->exec_state; submit->exec_state = args->exec_state;
submit->flags = args->flags; submit->flags = args->flags;

View File

@ -320,8 +320,8 @@ etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu)
domain = &etnaviv_domain->base; domain = &etnaviv_domain->base;
domain->dev = gpu->dev; domain->dev = gpu->dev;
domain->base = 0; domain->base = SZ_4K;
domain->size = (u64)SZ_1G * 4; domain->size = (u64)SZ_1G * 4 - SZ_4K;
domain->ops = &etnaviv_iommuv2_ops; domain->ops = &etnaviv_iommuv2_ops;
ret = etnaviv_iommuv2_init(etnaviv_domain); ret = etnaviv_iommuv2_init(etnaviv_domain);

View File

@ -113,7 +113,7 @@ static const struct etnaviv_pm_domain doms_3d[] = {
.name = "PE", .name = "PE",
.profile_read = VIVS_MC_PROFILE_PE_READ, .profile_read = VIVS_MC_PROFILE_PE_READ,
.profile_config = VIVS_MC_PROFILE_CONFIG0, .profile_config = VIVS_MC_PROFILE_CONFIG0,
.nr_signals = 5, .nr_signals = 4,
.signal = (const struct etnaviv_pm_signal[]) { .signal = (const struct etnaviv_pm_signal[]) {
{ {
"PIXEL_COUNT_KILLED_BY_COLOR_PIPE", "PIXEL_COUNT_KILLED_BY_COLOR_PIPE",
@ -435,7 +435,7 @@ int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
dom = meta->domains + signal->domain; dom = meta->domains + signal->domain;
if (signal->iter > dom->nr_signals) if (signal->iter >= dom->nr_signals)
return -EINVAL; return -EINVAL;
sig = &dom->signal[signal->iter]; sig = &dom->signal[signal->iter];
@ -461,7 +461,7 @@ int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r,
dom = meta->domains + r->domain; dom = meta->domains + r->domain;
if (r->signal > dom->nr_signals) if (r->signal >= dom->nr_signals)
return -EINVAL; return -EINVAL;
return 0; return 0;

View File

@ -153,7 +153,7 @@ int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity,
mutex_lock(&submit->gpu->fence_lock); mutex_lock(&submit->gpu->fence_lock);
ret = drm_sched_job_init(&submit->sched_job, sched_entity, ret = drm_sched_job_init(&submit->sched_job, sched_entity,
submit->cmdbuf.ctx); submit->ctx);
if (ret) if (ret)
goto out_unlock; goto out_unlock;

View File

@ -163,17 +163,25 @@ int i915_active_ref(struct i915_active *ref,
struct i915_request *rq) struct i915_request *rq)
{ {
struct i915_active_request *active; struct i915_active_request *active;
int err = 0;
/* Prevent reaping in case we malloc/wait while building the tree */
i915_active_acquire(ref);
active = active_instance(ref, timeline); active = active_instance(ref, timeline);
if (IS_ERR(active)) if (IS_ERR(active)) {
return PTR_ERR(active); err = PTR_ERR(active);
goto out;
}
if (!i915_active_request_isset(active)) if (!i915_active_request_isset(active))
ref->count++; ref->count++;
__i915_active_request_set(active, rq); __i915_active_request_set(active, rq);
GEM_BUG_ON(!ref->count); GEM_BUG_ON(!ref->count);
return 0; out:
i915_active_release(ref);
return err;
} }
bool i915_active_acquire(struct i915_active *ref) bool i915_active_acquire(struct i915_active *ref)
@ -223,19 +231,25 @@ int i915_request_await_active_request(struct i915_request *rq,
int i915_request_await_active(struct i915_request *rq, struct i915_active *ref) int i915_request_await_active(struct i915_request *rq, struct i915_active *ref)
{ {
struct active_node *it, *n; struct active_node *it, *n;
int ret; int err = 0;
ret = i915_request_await_active_request(rq, &ref->last); /* await allocates and so we need to avoid hitting the shrinker */
if (ret) if (i915_active_acquire(ref))
return ret; goto out; /* was idle */
err = i915_request_await_active_request(rq, &ref->last);
if (err)
goto out;
rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) { rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
ret = i915_request_await_active_request(rq, &it->base); err = i915_request_await_active_request(rq, &it->base);
if (ret) if (err)
return ret; goto out;
} }
return 0; out:
i915_active_release(ref);
return err;
} }
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)

View File

@ -757,39 +757,6 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
return ret; return ret;
} }
#if !defined(CONFIG_VGA_CONSOLE)
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
{
return 0;
}
#elif !defined(CONFIG_DUMMY_CONSOLE)
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
{
return -ENODEV;
}
#else
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
{
int ret = 0;
DRM_INFO("Replacing VGA console driver\n");
console_lock();
if (con_is_bound(&vga_con))
ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
if (ret == 0) {
ret = do_unregister_con_driver(&vga_con);
/* Ignore "already unregistered". */
if (ret == -ENODEV)
ret = 0;
}
console_unlock();
return ret;
}
#endif
static void intel_init_dpio(struct drm_i915_private *dev_priv) static void intel_init_dpio(struct drm_i915_private *dev_priv)
{ {
/* /*
@ -1420,7 +1387,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
goto err_ggtt; goto err_ggtt;
} }
ret = i915_kick_out_vgacon(dev_priv); ret = vga_remove_vgacon(pdev);
if (ret) { if (ret) {
DRM_ERROR("failed to remove conflicting VGA console\n"); DRM_ERROR("failed to remove conflicting VGA console\n");
goto err_ggtt; goto err_ggtt;

View File

@ -1688,7 +1688,8 @@ __vma_matches(struct vm_area_struct *vma, struct file *filp,
if (vma->vm_file != filp) if (vma->vm_file != filp)
return false; return false;
return vma->vm_start == addr && (vma->vm_end - vma->vm_start) == size; return vma->vm_start == addr &&
(vma->vm_end - vma->vm_start) == PAGE_ALIGN(size);
} }
/** /**

View File

@ -223,8 +223,14 @@ out:
return &p->requests[idx]; return &p->requests[idx];
} }
struct sched_cache {
struct list_head *priolist;
};
static struct intel_engine_cs * static struct intel_engine_cs *
sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked) sched_lock_engine(const struct i915_sched_node *node,
struct intel_engine_cs *locked,
struct sched_cache *cache)
{ {
struct intel_engine_cs *engine = node_to_request(node)->engine; struct intel_engine_cs *engine = node_to_request(node)->engine;
@ -232,6 +238,7 @@ sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
if (engine != locked) { if (engine != locked) {
spin_unlock(&locked->timeline.lock); spin_unlock(&locked->timeline.lock);
memset(cache, 0, sizeof(*cache));
spin_lock(&engine->timeline.lock); spin_lock(&engine->timeline.lock);
} }
@ -253,11 +260,11 @@ static bool inflight(const struct i915_request *rq,
static void __i915_schedule(struct i915_request *rq, static void __i915_schedule(struct i915_request *rq,
const struct i915_sched_attr *attr) const struct i915_sched_attr *attr)
{ {
struct list_head *uninitialized_var(pl); struct intel_engine_cs *engine;
struct intel_engine_cs *engine, *last;
struct i915_dependency *dep, *p; struct i915_dependency *dep, *p;
struct i915_dependency stack; struct i915_dependency stack;
const int prio = attr->priority; const int prio = attr->priority;
struct sched_cache cache;
LIST_HEAD(dfs); LIST_HEAD(dfs);
/* Needed in order to use the temporary link inside i915_dependency */ /* Needed in order to use the temporary link inside i915_dependency */
@ -328,7 +335,7 @@ static void __i915_schedule(struct i915_request *rq,
__list_del_entry(&stack.dfs_link); __list_del_entry(&stack.dfs_link);
} }
last = NULL; memset(&cache, 0, sizeof(cache));
engine = rq->engine; engine = rq->engine;
spin_lock_irq(&engine->timeline.lock); spin_lock_irq(&engine->timeline.lock);
@ -338,7 +345,7 @@ static void __i915_schedule(struct i915_request *rq,
INIT_LIST_HEAD(&dep->dfs_link); INIT_LIST_HEAD(&dep->dfs_link);
engine = sched_lock_engine(node, engine); engine = sched_lock_engine(node, engine, &cache);
lockdep_assert_held(&engine->timeline.lock); lockdep_assert_held(&engine->timeline.lock);
/* Recheck after acquiring the engine->timeline.lock */ /* Recheck after acquiring the engine->timeline.lock */
@ -347,11 +354,11 @@ static void __i915_schedule(struct i915_request *rq,
node->attr.priority = prio; node->attr.priority = prio;
if (!list_empty(&node->link)) { if (!list_empty(&node->link)) {
if (last != engine) { if (!cache.priolist)
pl = i915_sched_lookup_priolist(engine, prio); cache.priolist =
last = engine; i915_sched_lookup_priolist(engine,
} prio);
list_move_tail(&node->link, pl); list_move_tail(&node->link, cache.priolist);
} else { } else {
/* /*
* If the request is not in the priolist queue because * If the request is not in the priolist queue because

View File

@ -106,16 +106,6 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL, GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
&rq->fence.flags)); &rq->fence.flags));
clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
/*
* We may race with direct invocation of
* dma_fence_signal(), e.g. i915_request_retire(),
* in which case we can skip processing it ourselves.
*/
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
&rq->fence.flags))
continue;
/* /*
* Queue for execution after dropping the signaling * Queue for execution after dropping the signaling
@ -123,6 +113,14 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
* more signalers to the same context or engine. * more signalers to the same context or engine.
*/ */
i915_request_get(rq); i915_request_get(rq);
/*
* We may race with direct invocation of
* dma_fence_signal(), e.g. i915_request_retire(),
* so we need to acquire our reference to the request
* before we cancel the breadcrumb.
*/
clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
list_add_tail(&rq->signal_link, &signal); list_add_tail(&rq->signal_link, &signal);
} }

View File

@ -3568,6 +3568,13 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
{ {
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state); intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
if (conn_state->content_protection ==
DRM_MODE_CONTENT_PROTECTION_DESIRED)
intel_hdcp_enable(to_intel_connector(conn_state->connector));
else if (conn_state->content_protection ==
DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
intel_hdcp_disable(to_intel_connector(conn_state->connector));
} }
static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder, static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
@ -3962,12 +3969,7 @@ static int modeset_pipe(struct drm_crtc *crtc,
goto out; goto out;
ret = drm_atomic_commit(state); ret = drm_atomic_commit(state);
if (ret) out:
goto out;
return 0;
out:
drm_atomic_state_put(state); drm_atomic_state_put(state);
return ret; return ret;

View File

@ -710,47 +710,45 @@ __sseu_prepare(struct drm_i915_private *i915,
unsigned int flags, unsigned int flags,
struct i915_gem_context *ctx, struct i915_gem_context *ctx,
struct intel_engine_cs *engine, struct intel_engine_cs *engine,
struct igt_spinner **spin_out) struct igt_spinner **spin)
{ {
int ret = 0; struct i915_request *rq;
int ret;
if (flags & (TEST_BUSY | TEST_RESET)) { *spin = NULL;
struct igt_spinner *spin; if (!(flags & (TEST_BUSY | TEST_RESET)))
struct i915_request *rq; return 0;
spin = kzalloc(sizeof(*spin), GFP_KERNEL); *spin = kzalloc(sizeof(**spin), GFP_KERNEL);
if (!spin) { if (!*spin)
ret = -ENOMEM; return -ENOMEM;
goto out;
}
ret = igt_spinner_init(spin, i915); ret = igt_spinner_init(*spin, i915);
if (ret) if (ret)
return ret; goto err_free;
rq = igt_spinner_create_request(spin, ctx, engine, MI_NOOP); rq = igt_spinner_create_request(*spin, ctx, engine, MI_NOOP);
if (IS_ERR(rq)) { if (IS_ERR(rq)) {
ret = PTR_ERR(rq); ret = PTR_ERR(rq);
igt_spinner_fini(spin); goto err_fini;
kfree(spin);
goto out;
}
i915_request_add(rq);
if (!igt_wait_for_spinner(spin, rq)) {
pr_err("%s: Spinner failed to start!\n", name);
igt_spinner_end(spin);
igt_spinner_fini(spin);
kfree(spin);
ret = -ETIMEDOUT;
goto out;
}
*spin_out = spin;
} }
out: i915_request_add(rq);
if (!igt_wait_for_spinner(*spin, rq)) {
pr_err("%s: Spinner failed to start!\n", name);
ret = -ETIMEDOUT;
goto err_end;
}
return 0;
err_end:
igt_spinner_end(*spin);
err_fini:
igt_spinner_fini(*spin);
err_free:
kfree(fetch_and_zero(spin));
return ret; return ret;
} }
@ -897,22 +895,23 @@ __sseu_test(struct drm_i915_private *i915,
ret = __sseu_prepare(i915, name, flags, ctx, engine, &spin); ret = __sseu_prepare(i915, name, flags, ctx, engine, &spin);
if (ret) if (ret)
goto out; goto out_context;
ret = __i915_gem_context_reconfigure_sseu(ctx, engine, sseu); ret = __i915_gem_context_reconfigure_sseu(ctx, engine, sseu);
if (ret) if (ret)
goto out; goto out_spin;
ret = __sseu_finish(i915, name, flags, ctx, kctx, engine, obj, ret = __sseu_finish(i915, name, flags, ctx, kctx, engine, obj,
hweight32(sseu.slice_mask), spin); hweight32(sseu.slice_mask), spin);
out: out_spin:
if (spin) { if (spin) {
igt_spinner_end(spin); igt_spinner_end(spin);
igt_spinner_fini(spin); igt_spinner_fini(spin);
kfree(spin); kfree(spin);
} }
out_context:
kernel_context_close(kctx); kernel_context_close(kctx);
return ret; return ret;

View File

@ -79,6 +79,10 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret) if (ret)
goto free_dev; goto free_dev;
ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "qxl");
if (ret)
goto disable_pci;
ret = qxl_device_init(qdev, &qxl_driver, pdev); ret = qxl_device_init(qdev, &qxl_driver, pdev);
if (ret) if (ret)
goto disable_pci; goto disable_pci;
@ -94,7 +98,6 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret) if (ret)
goto modeset_cleanup; goto modeset_cleanup;
drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "qxl");
drm_fbdev_generic_setup(&qdev->ddev, 32); drm_fbdev_generic_setup(&qdev->ddev, 32);
return 0; return 0;

View File

@ -48,6 +48,8 @@
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/screen_info.h> #include <linux/screen_info.h>
#include <linux/vt.h>
#include <linux/console.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
@ -168,6 +170,53 @@ void vga_set_default_device(struct pci_dev *pdev)
vga_default = pci_dev_get(pdev); vga_default = pci_dev_get(pdev);
} }
/**
* vga_remove_vgacon - deactivete vga console
*
* Unbind and unregister vgacon in case pdev is the default vga
* device. Can be called by gpu drivers on initialization to make
* sure vga register access done by vgacon will not disturb the
* device.
*
* @pdev: pci device.
*/
#if !defined(CONFIG_VGA_CONSOLE)
int vga_remove_vgacon(struct pci_dev *pdev)
{
return 0;
}
#elif !defined(CONFIG_DUMMY_CONSOLE)
int vga_remove_vgacon(struct pci_dev *pdev)
{
return -ENODEV;
}
#else
int vga_remove_vgacon(struct pci_dev *pdev)
{
int ret = 0;
if (pdev != vga_default)
return 0;
vgaarb_info(&pdev->dev, "deactivate vga console\n");
console_lock();
if (con_is_bound(&vga_con))
ret = do_take_over_console(&dummy_con, 0,
MAX_NR_CONSOLES - 1, 1);
if (ret == 0) {
ret = do_unregister_con_driver(&vga_con);
/* Ignore "already unregistered". */
if (ret == -ENODEV)
ret = 0;
}
console_unlock();
return ret;
}
#endif
EXPORT_SYMBOL(vga_remove_vgacon);
static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) static inline void vga_irq_set_state(struct vga_device *vgadev, bool state)
{ {
if (vgadev->irq_set_state) if (vgadev->irq_set_state)

View File

@ -36,6 +36,7 @@ struct drm_fb_helper;
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <linux/kgdb.h> #include <linux/kgdb.h>
#include <linux/vgaarb.h>
enum mode_set_atomic { enum mode_set_atomic {
LEAVE_ATOMIC_MODE_SET, LEAVE_ATOMIC_MODE_SET,
@ -642,11 +643,18 @@ drm_fb_helper_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
int resource_id, int resource_id,
const char *name) const char *name)
{ {
int ret = 0;
/*
* WARNING: Apparently we must kick fbdev drivers before vgacon,
* otherwise the vga fbdev driver falls over.
*/
#if IS_REACHABLE(CONFIG_FB) #if IS_REACHABLE(CONFIG_FB)
return remove_conflicting_pci_framebuffers(pdev, resource_id, name); ret = remove_conflicting_pci_framebuffers(pdev, resource_id, name);
#else
return 0;
#endif #endif
if (ret == 0)
ret = vga_remove_vgacon(pdev);
return ret;
} }
#endif #endif

View File

@ -125,9 +125,11 @@ extern void vga_put(struct pci_dev *pdev, unsigned int rsrc);
#ifdef CONFIG_VGA_ARB #ifdef CONFIG_VGA_ARB
extern struct pci_dev *vga_default_device(void); extern struct pci_dev *vga_default_device(void);
extern void vga_set_default_device(struct pci_dev *pdev); extern void vga_set_default_device(struct pci_dev *pdev);
extern int vga_remove_vgacon(struct pci_dev *pdev);
#else #else
static inline struct pci_dev *vga_default_device(void) { return NULL; }; static inline struct pci_dev *vga_default_device(void) { return NULL; };
static inline void vga_set_default_device(struct pci_dev *pdev) { }; static inline void vga_set_default_device(struct pci_dev *pdev) { };
static inline int vga_remove_vgacon(struct pci_dev *pdev) { return 0; };
#endif #endif
/* /*