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:
commit
8264fd046a
|
@ -5278,7 +5278,7 @@ DRM DRIVERS FOR VIVANTE GPU IP
|
|||
M: Lucas Stach <l.stach@pengutronix.de>
|
||||
R: Russell King <linux+etnaviv@armlinux.org.uk>
|
||||
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
|
||||
S: Maintained
|
||||
F: drivers/gpu/drm/etnaviv/
|
||||
|
|
|
@ -947,10 +947,6 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
|
|||
if (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) {
|
||||
r = amdgpu_bo_kmap(pt, NULL);
|
||||
if (r)
|
||||
|
@ -963,6 +959,10 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
|
|||
pt->parent = amdgpu_bo_ref(cursor.parent->base.bo);
|
||||
|
||||
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;
|
||||
|
@ -3033,13 +3033,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
if (r)
|
||||
goto error_unreserve;
|
||||
|
||||
amdgpu_vm_bo_base_init(&vm->root.base, vm, root);
|
||||
|
||||
r = amdgpu_vm_clear_bo(adev, vm, root,
|
||||
adev->vm_manager.root_level,
|
||||
vm->pte_support_ats);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
|
||||
amdgpu_vm_bo_base_init(&vm->root.base, vm, root);
|
||||
amdgpu_bo_unreserve(vm->root.base.bo);
|
||||
|
||||
if (pasid) {
|
||||
|
|
|
@ -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[] =
|
||||
{
|
||||
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_DATA, 0xffffffff, 0x2544c382)
|
||||
};
|
||||
|
|
|
@ -500,9 +500,7 @@ static bool psp_v3_1_smu_reload_quirk(struct psp_context *psp)
|
|||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t reg;
|
||||
|
||||
reg = smnMP1_FIRMWARE_FLAGS | 0x03b00000;
|
||||
WREG32_SOC15(NBIO, 0, mmPCIE_INDEX2, reg);
|
||||
reg = RREG32_SOC15(NBIO, 0, mmPCIE_DATA2);
|
||||
reg = RREG32_PCIE(smnMP1_FIRMWARE_FLAGS | 0x03b00000);
|
||||
return (reg & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) ? true : false;
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,6 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
|
|||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA20:
|
||||
soc15_asic_get_baco_capability(adev, &baco_reset);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -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 queue_properties *q)
|
||||
{
|
||||
uint64_t addr;
|
||||
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;
|
||||
return init_mqd(mm, mqd, mqd_mem_obj, gart_addr, q);
|
||||
}
|
||||
|
||||
static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
|
||||
|
|
|
@ -886,6 +886,7 @@ static void emulated_link_detect(struct dc_link *link)
|
|||
return;
|
||||
}
|
||||
|
||||
/* dc_sink_create returns a new reference */
|
||||
link->local_sink = sink;
|
||||
|
||||
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)
|
||||
aconnector->fake_enable = false;
|
||||
|
||||
if (aconnector->dc_sink)
|
||||
dc_sink_release(aconnector->dc_sink);
|
||||
aconnector->dc_sink = NULL;
|
||||
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||
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;
|
||||
if (sink)
|
||||
dc_sink_retain(sink);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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;
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
amdgpu_dm_update_freesync_caps(connector,
|
||||
aconnector->edid);
|
||||
} else {
|
||||
amdgpu_dm_update_freesync_caps(connector, NULL);
|
||||
if (!aconnector->dc_sink)
|
||||
if (!aconnector->dc_sink) {
|
||||
aconnector->dc_sink = aconnector->dc_em_sink;
|
||||
else if (aconnector->dc_sink != aconnector->dc_em_sink)
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
if (sink)
|
||||
dc_sink_release(sink);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1107,8 +1115,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
|
|||
* TODO: temporary guard to look for proper fix
|
||||
* 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;
|
||||
}
|
||||
|
||||
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",
|
||||
aconnector->connector_id);
|
||||
if (sink)
|
||||
dc_sink_release(sink);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1138,6 +1150,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
|
|||
amdgpu_dm_update_freesync_caps(connector, NULL);
|
||||
|
||||
aconnector->dc_sink = sink;
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
if (sink->dc_edid.length == 0) {
|
||||
aconnector->edid = NULL;
|
||||
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);
|
||||
drm_connector_update_edid_property(connector, NULL);
|
||||
aconnector->num_modes = 0;
|
||||
dc_sink_release(aconnector->dc_sink);
|
||||
aconnector->dc_sink = NULL;
|
||||
aconnector->edid = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
if (sink)
|
||||
dc_sink_release(sink);
|
||||
}
|
||||
|
||||
static void handle_hpd_irq(void *param)
|
||||
|
@ -2977,6 +2994,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
return stream;
|
||||
} else {
|
||||
sink = aconnector->dc_sink;
|
||||
dc_sink_retain(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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -3301,6 +3318,14 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
|
|||
dm->backlight_dev = NULL;
|
||||
}
|
||||
#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_connector_unregister(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
|
@ -3398,10 +3423,12 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
|
|||
(edid->extensions + 1) * EDID_LENGTH,
|
||||
&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_link->local_sink :
|
||||
aconnector->dc_em_sink;
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
|
||||
|
|
|
@ -191,6 +191,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|||
&init_params);
|
||||
|
||||
dc_sink->priv = aconnector;
|
||||
/* dc_link_add_remote_sink returns a new reference */
|
||||
aconnector->dc_sink = dc_sink;
|
||||
|
||||
if (aconnector->dc_sink)
|
||||
|
|
|
@ -1348,12 +1348,12 @@ void dcn_bw_update_from_pplib(struct dc *dc)
|
|||
struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};
|
||||
bool res;
|
||||
|
||||
kernel_fpu_begin();
|
||||
|
||||
/* 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(
|
||||
ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks);
|
||||
|
||||
kernel_fpu_begin();
|
||||
|
||||
if (res)
|
||||
res = verify_clock_values(&fclks);
|
||||
|
||||
|
@ -1372,9 +1372,13 @@ void dcn_bw_update_from_pplib(struct dc *dc)
|
|||
} else
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
||||
kernel_fpu_end();
|
||||
|
||||
res = dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks);
|
||||
|
||||
kernel_fpu_begin();
|
||||
|
||||
if (res)
|
||||
res = verify_clock_values(&dcfclks);
|
||||
|
||||
|
|
|
@ -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->converter_disable_audio = converter_disable_audio;
|
||||
|
||||
/* dc_sink_create returns a new reference */
|
||||
link->local_sink = sink;
|
||||
|
||||
edid_status = dm_helpers_read_local_edid(
|
||||
|
@ -2037,6 +2038,9 @@ static enum dc_status enable_link(
|
|||
break;
|
||||
}
|
||||
|
||||
if (status == DC_OK)
|
||||
pipe_ctx->stream->link->link_status.link_active = true;
|
||||
|
||||
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);
|
||||
} else
|
||||
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(
|
||||
|
@ -2623,8 +2635,6 @@ void core_link_enable_stream(
|
|||
}
|
||||
}
|
||||
|
||||
stream->link->link_status.link_active = true;
|
||||
|
||||
core_dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
|
||||
/* 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);
|
||||
|
||||
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)
|
||||
|
|
|
@ -724,7 +724,7 @@ static void build_vrr_infopacket_v1(enum signal_type signal,
|
|||
|
||||
static void build_vrr_infopacket_v2(enum signal_type signal,
|
||||
const struct mod_vrr_params *vrr,
|
||||
const enum color_transfer_func *app_tf,
|
||||
enum color_transfer_func app_tf,
|
||||
struct dc_info_packet *infopacket)
|
||||
{
|
||||
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_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);
|
||||
|
||||
|
@ -757,7 +756,7 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
|
|||
const struct dc_stream_state *stream,
|
||||
const struct mod_vrr_params *vrr,
|
||||
enum vrr_packet_type packet_type,
|
||||
const enum color_transfer_func *app_tf,
|
||||
enum color_transfer_func app_tf,
|
||||
struct dc_info_packet *infopacket)
|
||||
{
|
||||
/* SPD info packet for FreeSync
|
||||
|
|
|
@ -145,7 +145,7 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
|
|||
const struct dc_stream_state *stream,
|
||||
const struct mod_vrr_params *vrr,
|
||||
enum vrr_packet_type packet_type,
|
||||
const enum color_transfer_func *app_tf,
|
||||
enum color_transfer_func app_tf,
|
||||
struct dc_info_packet *infopacket);
|
||||
|
||||
void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
|
||||
|
|
|
@ -277,8 +277,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
|
|||
if (!skip_display_settings)
|
||||
phm_notify_smc_display_config_after_ps_adjustment(hwmgr);
|
||||
|
||||
if ((hwmgr->request_dpm_level != hwmgr->dpm_level) &&
|
||||
!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level))
|
||||
if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level))
|
||||
hwmgr->dpm_level = hwmgr->request_dpm_level;
|
||||
|
||||
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
|
|
|
@ -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,
|
||||
uint8_t id, uint32_t *frequency)
|
||||
uint8_t clk_id, uint8_t syspll_id,
|
||||
uint32_t *frequency)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
struct atom_get_smu_clock_info_parameters_v3_1 parameters;
|
||||
struct atom_get_smu_clock_info_output_parameters_v3_1 *output;
|
||||
uint32_t ix;
|
||||
|
||||
parameters.clk_id = id;
|
||||
parameters.syspll_id = 0;
|
||||
parameters.clk_id = clk_id;
|
||||
parameters.syspll_id = syspll_id;
|
||||
parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ;
|
||||
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->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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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,
|
||||
|
@ -563,19 +567,19 @@ static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr,
|
|||
boot_values->ulSocClk = 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ struct pp_atomfwctrl_bios_boot_up_values {
|
|||
uint32_t ulEClk;
|
||||
uint32_t ulVClk;
|
||||
uint32_t ulDClk;
|
||||
uint32_t ulFClk;
|
||||
uint16_t usVddc;
|
||||
uint16_t usVddci;
|
||||
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,
|
||||
struct pp_atomfwctrl_smc_dpm_parameters *param);
|
||||
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
|
||||
|
||||
|
|
|
@ -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);
|
||||
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++) {
|
||||
mdelay(1);
|
||||
mdelay(500);
|
||||
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogSample);
|
||||
tmp = cgs_read_ind_register(hwmgr->device,
|
||||
CGS_IND_REG__SMC,
|
||||
ixSMU_PM_STATUS_94);
|
||||
ixSMU_PM_STATUS_95);
|
||||
if (tmp != 0)
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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.mem_clock = boot_up_values.ulUClk;
|
||||
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,
|
||||
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.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;
|
||||
|
||||
features_to_disable =
|
||||
(features_enabled ^ new_ppfeature_masks) & features_enabled;
|
||||
features_enabled & ~new_ppfeature_masks;
|
||||
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_enable 0x%llx\n", features_to_enable);
|
||||
|
|
|
@ -2009,9 +2009,9 @@ static int vega12_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe
|
|||
return ret;
|
||||
|
||||
features_to_disable =
|
||||
(features_enabled ^ new_ppfeature_masks) & features_enabled;
|
||||
features_enabled & ~new_ppfeature_masks;
|
||||
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_enable 0x%llx\n", features_to_enable);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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_max_level = 0xffff;
|
||||
dpm_state->hard_max_level = VG20_CLOCK_MAX_DEFAULT;
|
||||
}
|
||||
|
||||
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,
|
||||
"[SetupDefaultDpmTable] failed to get fclk dpm levels!",
|
||||
return ret);
|
||||
} else
|
||||
dpm_table->count = 0;
|
||||
} else {
|
||||
dpm_table->count = 1;
|
||||
dpm_table->dpm_levels[0].value = data->vbios_boot_state.fclock / 100;
|
||||
}
|
||||
vega20_init_dpm_state(&(dpm_table->dpm_state));
|
||||
|
||||
/* 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.vclock = boot_up_values.ulVClk;
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
int ret;
|
||||
|
||||
|
@ -816,6 +821,10 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
|||
"[OverridePcieParameters] Attempt to override pcie params failed!",
|
||||
return ret);
|
||||
|
||||
data->pcie_parameters_override = 1;
|
||||
data->pcie_gen_level1 = pcie_gen;
|
||||
data->pcie_width_level1 = pcie_width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -979,6 +988,8 @@ static int vega20_od8_set_feature_capabilities(
|
|||
}
|
||||
|
||||
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] &&
|
||||
pptable_information->od_settings_min[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)
|
||||
{
|
||||
struct vega20_hwmgr *data =
|
||||
(struct vega20_hwmgr *)(hwmgr->backend);
|
||||
uint32_t soft_min_level, soft_max_level;
|
||||
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);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"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);
|
||||
int i, count;
|
||||
|
||||
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_GFXCLK].enabled,
|
||||
"[GetSclks]: gfxclk dpm not enabled!\n",
|
||||
return -EPERM);
|
||||
if (!data->smu_features[GNLD_DPM_GFXCLK].enabled)
|
||||
return -1;
|
||||
|
||||
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->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);
|
||||
int i, count;
|
||||
|
||||
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_UCLK].enabled,
|
||||
"[GetMclks]: uclk dpm not enabled!\n",
|
||||
return -EPERM);
|
||||
if (!data->smu_features[GNLD_DPM_UCLK].enabled)
|
||||
return -1;
|
||||
|
||||
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->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);
|
||||
int i, count;
|
||||
|
||||
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_DCEFCLK].enabled,
|
||||
"[GetDcfclocks]: dcefclk dpm not enabled!\n",
|
||||
return -EPERM);
|
||||
if (!data->smu_features[GNLD_DPM_DCEFCLK].enabled)
|
||||
return -1;
|
||||
|
||||
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->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);
|
||||
int i, count;
|
||||
|
||||
PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_SOCCLK].enabled,
|
||||
"[GetSocclks]: socclk dpm not enabled!\n",
|
||||
return -EPERM);
|
||||
if (!data->smu_features[GNLD_DPM_SOCCLK].enabled)
|
||||
return -1;
|
||||
|
||||
count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->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;
|
||||
OverDriveTable_t *od_table =
|
||||
&(data->smc_state_table.overdrive_table);
|
||||
struct pp_clock_levels_with_latency clocks;
|
||||
int32_t input_index, input_clk, input_vol, i;
|
||||
int od8_id;
|
||||
int ret;
|
||||
|
@ -2858,11 +2840,6 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
|
|||
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) {
|
||||
if (i + 2 > size) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
pr_info("clock freq %d is not within allowed range [%d - %d]\n",
|
||||
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);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -3088,9 +3065,9 @@ static int vega20_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe
|
|||
return ret;
|
||||
|
||||
features_to_disable =
|
||||
(features_enabled ^ new_ppfeature_masks) & features_enabled;
|
||||
features_enabled & ~new_ppfeature_masks;
|
||||
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_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);
|
||||
int i, now, size = 0;
|
||||
int ret = 0;
|
||||
uint32_t gen_speed, lane_width;
|
||||
uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
|
||||
|
||||
switch (type) {
|
||||
case PP_SCLK:
|
||||
|
@ -3137,10 +3114,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|||
"Attempt to get current gfx clk Failed!",
|
||||
return ret);
|
||||
|
||||
ret = vega20_get_sclks(hwmgr, &clocks);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Attempt to get gfx clk levels Failed!",
|
||||
return ret);
|
||||
if (vega20_get_sclks(hwmgr, &clocks)) {
|
||||
size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
|
||||
now / 100);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < clocks.num_levels; i++)
|
||||
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!",
|
||||
return ret);
|
||||
|
||||
ret = vega20_get_memclocks(hwmgr, &clocks);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Attempt to get memory clk levels Failed!",
|
||||
return ret);
|
||||
if (vega20_get_memclocks(hwmgr, &clocks)) {
|
||||
size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
|
||||
now / 100);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < clocks.num_levels; i++)
|
||||
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!",
|
||||
return ret);
|
||||
|
||||
ret = vega20_get_socclocks(hwmgr, &clocks);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Attempt to get soc clk levels Failed!",
|
||||
return ret);
|
||||
if (vega20_get_socclocks(hwmgr, &clocks)) {
|
||||
size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
|
||||
now / 100);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < clocks.num_levels; i++)
|
||||
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!",
|
||||
return ret);
|
||||
|
||||
ret = vega20_get_dcefclocks(hwmgr, &clocks);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Attempt to get dcefclk levels Failed!",
|
||||
return ret);
|
||||
if (vega20_get_dcefclocks(hwmgr, &clocks)) {
|
||||
size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n",
|
||||
now / 100);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < clocks.num_levels; i++)
|
||||
size += sprintf(buf + size, "%d: %uMhz %s\n",
|
||||
|
@ -3212,28 +3193,36 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|||
break;
|
||||
|
||||
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__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__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,
|
||||
(pptable->PcieGenSpeed[i] == 0) ? "2.5GT/s," :
|
||||
(pptable->PcieGenSpeed[i] == 1) ? "5.0GT/s," :
|
||||
(pptable->PcieGenSpeed[i] == 2) ? "8.0GT/s," :
|
||||
(pptable->PcieGenSpeed[i] == 3) ? "16.0GT/s," : "",
|
||||
(pptable->PcieLaneCount[i] == 1) ? "x1" :
|
||||
(pptable->PcieLaneCount[i] == 2) ? "x2" :
|
||||
(pptable->PcieLaneCount[i] == 3) ? "x4" :
|
||||
(pptable->PcieLaneCount[i] == 4) ? "x8" :
|
||||
(pptable->PcieLaneCount[i] == 5) ? "x12" :
|
||||
(pptable->PcieLaneCount[i] == 6) ? "x16" : "",
|
||||
(gen_speed == 0) ? "2.5GT/s," :
|
||||
(gen_speed == 1) ? "5.0GT/s," :
|
||||
(gen_speed == 2) ? "8.0GT/s," :
|
||||
(gen_speed == 3) ? "16.0GT/s," : "",
|
||||
(lane_width == 1) ? "x1" :
|
||||
(lane_width == 2) ? "x2" :
|
||||
(lane_width == 3) ? "x4" :
|
||||
(lane_width == 4) ? "x8" :
|
||||
(lane_width == 5) ? "x12" :
|
||||
(lane_width == 6) ? "x16" : "",
|
||||
pptable->LclkFreq[i],
|
||||
(gen_speed == pptable->PcieGenSpeed[i]) &&
|
||||
(lane_width == pptable->PcieLaneCount[i]) ?
|
||||
(current_gen_speed == gen_speed) &&
|
||||
(current_lane_width == lane_width) ?
|
||||
"*" : "");
|
||||
}
|
||||
break;
|
||||
|
||||
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) {
|
||||
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",
|
||||
clocks.data[0].clocks_in_khz / 1000,
|
||||
od8_settings[OD8_SETTING_UCLK_FMAX].min_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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
&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)
|
||||
|
@ -3461,9 +3472,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
|
|||
/* gfxclk */
|
||||
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_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_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 (VEGA20_UMD_PSTATE_GFXCLK_LEVEL < dpm_table->count) {
|
||||
|
@ -3485,9 +3496,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
|
|||
/* memclk */
|
||||
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_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_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 (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)
|
||||
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 */
|
||||
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_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_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 (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) {
|
||||
|
@ -3548,9 +3568,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
|
|||
/* dclk */
|
||||
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_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_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 (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) {
|
||||
|
@ -3567,9 +3587,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
|
|||
/* socclk */
|
||||
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_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_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 (VEGA20_UMD_PSTATE_SOCCLK_LEVEL < dpm_table->count) {
|
||||
|
@ -3586,9 +3606,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)
|
|||
/* eclk */
|
||||
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_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_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 (VEGA20_UMD_PSTATE_VCEMCLK_LEVEL < dpm_table->count) {
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#define AVFS_CURVE 0
|
||||
#define OD8_HOTCURVE_TEMPERATURE 85
|
||||
|
||||
#define VG20_CLOCK_MAX_DEFAULT 0xFFFF
|
||||
|
||||
typedef uint32_t PP_Clock;
|
||||
|
||||
enum {
|
||||
|
@ -219,6 +221,7 @@ struct vega20_vbios_boot_state {
|
|||
uint32_t eclock;
|
||||
uint32_t dclock;
|
||||
uint32_t vclock;
|
||||
uint32_t fclock;
|
||||
};
|
||||
|
||||
#define DPMTABLE_OD_UPDATE_SCLK 0x00000001
|
||||
|
@ -523,6 +526,10 @@ struct vega20_hwmgr {
|
|||
|
||||
unsigned long metrics_time;
|
||||
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
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "cgs_common.h"
|
||||
#include "vega20_pptable.h"
|
||||
|
||||
#define VEGA20_FAN_TARGET_TEMPERATURE_OVERRIDE 105
|
||||
|
||||
static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
|
||||
enum phm_platform_caps cap)
|
||||
{
|
||||
|
@ -798,6 +800,17 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
|
|||
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
|
||||
static int init_powerplay_table_information(
|
||||
struct pp_hwmgr *hwmgr,
|
||||
|
@ -887,6 +900,10 @@ static int init_powerplay_table_information(
|
|||
|
||||
|
||||
result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = override_powerplay_table_fantargettemperature(hwmgr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -2330,6 +2330,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member)
|
|||
case DRAM_LOG_BUFF_SIZE:
|
||||
return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE);
|
||||
}
|
||||
break;
|
||||
case SMU_Discrete_DpmTable:
|
||||
switch (member) {
|
||||
case UvdBootLevel:
|
||||
|
@ -2339,6 +2340,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member)
|
|||
case LowSclkInterruptThreshold:
|
||||
return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold);
|
||||
}
|
||||
break;
|
||||
}
|
||||
pr_warn("can't get the offset of type %x member %x\n", type, member);
|
||||
return 0;
|
||||
|
|
|
@ -40,10 +40,8 @@ bool smu9_is_smc_ram_running(struct pp_hwmgr *hwmgr)
|
|||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
uint32_t mp1_fw_flags;
|
||||
|
||||
WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2,
|
||||
(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff)));
|
||||
|
||||
mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2);
|
||||
mp1_fw_flags = RREG32_PCIE(MP1_Public |
|
||||
(smnMP1_FIRMWARE_FLAGS & 0xffffffff));
|
||||
|
||||
if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK)
|
||||
return true;
|
||||
|
|
|
@ -49,10 +49,8 @@ static bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
|
|||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
uint32_t mp1_fw_flags;
|
||||
|
||||
WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2,
|
||||
(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff)));
|
||||
|
||||
mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2);
|
||||
mp1_fw_flags = RREG32_PCIE(MP1_Public |
|
||||
(smnMP1_FIRMWARE_FLAGS & 0xffffffff));
|
||||
|
||||
if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
|
||||
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
|
||||
|
|
|
@ -3039,9 +3039,31 @@ commit:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __drm_atomic_helper_disable_all(struct drm_device *dev,
|
||||
struct drm_modeset_acquire_ctx *ctx,
|
||||
bool clean_old_fbs)
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_connector_state *conn_state;
|
||||
|
@ -3099,35 +3121,6 @@ free:
|
|||
drm_atomic_state_put(state);
|
||||
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);
|
||||
|
||||
/**
|
||||
|
@ -3148,7 +3141,7 @@ void drm_atomic_helper_shutdown(struct drm_device *dev)
|
|||
|
||||
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)
|
||||
DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
|
|||
m32.size = map.size;
|
||||
m32.type = map.type;
|
||||
m32.flags = map.flags;
|
||||
m32.handle = ptr_to_compat(map.handle);
|
||||
m32.handle = ptr_to_compat((void __user *)map.handle);
|
||||
m32.mtrr = map.mtrr;
|
||||
if (copy_to_user(argp, &m32, sizeof(m32)))
|
||||
return -EFAULT;
|
||||
|
@ -216,7 +216,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
|
|||
|
||||
m32.offset = map.offset;
|
||||
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))
|
||||
pr_err_ratelimited("compat_drm_addmap truncated handle %p for type %d offset %x\n",
|
||||
map.handle, m32.type, m32.offset);
|
||||
|
@ -526,7 +526,7 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
|
|||
if (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)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
config DRM_ETNAVIV
|
||||
tristate "ETNAVIV (DRM support for Vivante GPU IP cores)"
|
||||
depends on DRM
|
||||
depends on ARCH_MXC || ARCH_DOVE || (ARM && COMPILE_TEST)
|
||||
depends on MMU
|
||||
select SHMEM
|
||||
select SYNC_FILE
|
||||
|
|
|
@ -15,8 +15,6 @@ struct etnaviv_perfmon_request;
|
|||
struct etnaviv_cmdbuf {
|
||||
/* suballocator this cmdbuf is allocated from */
|
||||
struct etnaviv_cmdbuf_suballoc *suballoc;
|
||||
/* user context key, must be unique between all active users */
|
||||
struct etnaviv_file_private *ctx;
|
||||
/* cmdbuf properties */
|
||||
int suballoc_offset;
|
||||
void *vaddr;
|
||||
|
|
|
@ -215,7 +215,7 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
|
|||
mutex_lock(&obj->lock);
|
||||
pages = etnaviv_gem_get_pages(obj);
|
||||
mutex_unlock(&obj->lock);
|
||||
if (pages) {
|
||||
if (!IS_ERR(pages)) {
|
||||
int j;
|
||||
|
||||
iter.hdr->data[0] = bomap - bomap_start;
|
||||
|
|
|
@ -95,6 +95,7 @@ struct etnaviv_gem_submit_bo {
|
|||
struct etnaviv_gem_submit {
|
||||
struct drm_sched_job sched_job;
|
||||
struct kref refcount;
|
||||
struct etnaviv_file_private *ctx;
|
||||
struct etnaviv_gpu *gpu;
|
||||
struct dma_fence *out_fence, *in_fence;
|
||||
int out_fence_id;
|
||||
|
|
|
@ -15,7 +15,7 @@ struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj)
|
|||
int npages = obj->size >> PAGE_SHIFT;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -506,7 +506,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
|
|||
if (ret)
|
||||
goto err_submit_objects;
|
||||
|
||||
submit->cmdbuf.ctx = file->driver_priv;
|
||||
submit->ctx = file->driver_priv;
|
||||
submit->exec_state = args->exec_state;
|
||||
submit->flags = args->flags;
|
||||
|
||||
|
|
|
@ -320,8 +320,8 @@ etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu)
|
|||
domain = &etnaviv_domain->base;
|
||||
|
||||
domain->dev = gpu->dev;
|
||||
domain->base = 0;
|
||||
domain->size = (u64)SZ_1G * 4;
|
||||
domain->base = SZ_4K;
|
||||
domain->size = (u64)SZ_1G * 4 - SZ_4K;
|
||||
domain->ops = &etnaviv_iommuv2_ops;
|
||||
|
||||
ret = etnaviv_iommuv2_init(etnaviv_domain);
|
||||
|
|
|
@ -113,7 +113,7 @@ static const struct etnaviv_pm_domain doms_3d[] = {
|
|||
.name = "PE",
|
||||
.profile_read = VIVS_MC_PROFILE_PE_READ,
|
||||
.profile_config = VIVS_MC_PROFILE_CONFIG0,
|
||||
.nr_signals = 5,
|
||||
.nr_signals = 4,
|
||||
.signal = (const struct etnaviv_pm_signal[]) {
|
||||
{
|
||||
"PIXEL_COUNT_KILLED_BY_COLOR_PIPE",
|
||||
|
@ -435,7 +435,7 @@ int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
|
|||
|
||||
dom = meta->domains + signal->domain;
|
||||
|
||||
if (signal->iter > dom->nr_signals)
|
||||
if (signal->iter >= dom->nr_signals)
|
||||
return -EINVAL;
|
||||
|
||||
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;
|
||||
|
||||
if (r->signal > dom->nr_signals)
|
||||
if (r->signal >= dom->nr_signals)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -153,7 +153,7 @@ int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity,
|
|||
mutex_lock(&submit->gpu->fence_lock);
|
||||
|
||||
ret = drm_sched_job_init(&submit->sched_job, sched_entity,
|
||||
submit->cmdbuf.ctx);
|
||||
submit->ctx);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
|
|
|
@ -163,17 +163,25 @@ int i915_active_ref(struct i915_active *ref,
|
|||
struct i915_request *rq)
|
||||
{
|
||||
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);
|
||||
if (IS_ERR(active))
|
||||
return PTR_ERR(active);
|
||||
if (IS_ERR(active)) {
|
||||
err = PTR_ERR(active);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!i915_active_request_isset(active))
|
||||
ref->count++;
|
||||
__i915_active_request_set(active, rq);
|
||||
|
||||
GEM_BUG_ON(!ref->count);
|
||||
return 0;
|
||||
out:
|
||||
i915_active_release(ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct active_node *it, *n;
|
||||
int ret;
|
||||
int err = 0;
|
||||
|
||||
ret = i915_request_await_active_request(rq, &ref->last);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* await allocates and so we need to avoid hitting the shrinker */
|
||||
if (i915_active_acquire(ref))
|
||||
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) {
|
||||
ret = i915_request_await_active_request(rq, &it->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
err = i915_request_await_active_request(rq, &it->base);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
i915_active_release(ref);
|
||||
return err;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
|
||||
|
|
|
@ -757,39 +757,6 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
|
|||
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)
|
||||
{
|
||||
/*
|
||||
|
@ -1420,7 +1387,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
|||
goto err_ggtt;
|
||||
}
|
||||
|
||||
ret = i915_kick_out_vgacon(dev_priv);
|
||||
ret = vga_remove_vgacon(pdev);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to remove conflicting VGA console\n");
|
||||
goto err_ggtt;
|
||||
|
|
|
@ -1688,7 +1688,8 @@ __vma_matches(struct vm_area_struct *vma, struct file *filp,
|
|||
if (vma->vm_file != filp)
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -223,8 +223,14 @@ out:
|
|||
return &p->requests[idx];
|
||||
}
|
||||
|
||||
struct sched_cache {
|
||||
struct list_head *priolist;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
|
@ -232,6 +238,7 @@ sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
|
|||
|
||||
if (engine != locked) {
|
||||
spin_unlock(&locked->timeline.lock);
|
||||
memset(cache, 0, sizeof(*cache));
|
||||
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,
|
||||
const struct i915_sched_attr *attr)
|
||||
{
|
||||
struct list_head *uninitialized_var(pl);
|
||||
struct intel_engine_cs *engine, *last;
|
||||
struct intel_engine_cs *engine;
|
||||
struct i915_dependency *dep, *p;
|
||||
struct i915_dependency stack;
|
||||
const int prio = attr->priority;
|
||||
struct sched_cache cache;
|
||||
LIST_HEAD(dfs);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
last = NULL;
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
engine = rq->engine;
|
||||
spin_lock_irq(&engine->timeline.lock);
|
||||
|
||||
|
@ -338,7 +345,7 @@ static void __i915_schedule(struct i915_request *rq,
|
|||
|
||||
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);
|
||||
|
||||
/* Recheck after acquiring the engine->timeline.lock */
|
||||
|
@ -347,11 +354,11 @@ static void __i915_schedule(struct i915_request *rq,
|
|||
|
||||
node->attr.priority = prio;
|
||||
if (!list_empty(&node->link)) {
|
||||
if (last != engine) {
|
||||
pl = i915_sched_lookup_priolist(engine, prio);
|
||||
last = engine;
|
||||
}
|
||||
list_move_tail(&node->link, pl);
|
||||
if (!cache.priolist)
|
||||
cache.priolist =
|
||||
i915_sched_lookup_priolist(engine,
|
||||
prio);
|
||||
list_move_tail(&node->link, cache.priolist);
|
||||
} else {
|
||||
/*
|
||||
* If the request is not in the priolist queue because
|
||||
|
|
|
@ -106,16 +106,6 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
|
|||
|
||||
GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
|
||||
&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
|
||||
|
@ -123,6 +113,14 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
|
|||
* more signalers to the same context or engine.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -3568,6 +3568,13 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
|
|||
{
|
||||
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
|
||||
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,
|
||||
|
@ -3962,12 +3969,7 @@ static int modeset_pipe(struct drm_crtc *crtc,
|
|||
goto out;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
out:
|
||||
drm_atomic_state_put(state);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -710,47 +710,45 @@ __sseu_prepare(struct drm_i915_private *i915,
|
|||
unsigned int flags,
|
||||
struct i915_gem_context *ctx,
|
||||
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)) {
|
||||
struct igt_spinner *spin;
|
||||
struct i915_request *rq;
|
||||
*spin = NULL;
|
||||
if (!(flags & (TEST_BUSY | TEST_RESET)))
|
||||
return 0;
|
||||
|
||||
spin = kzalloc(sizeof(*spin), GFP_KERNEL);
|
||||
if (!spin) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
*spin = kzalloc(sizeof(**spin), GFP_KERNEL);
|
||||
if (!*spin)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = igt_spinner_init(spin, i915);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = igt_spinner_init(*spin, i915);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
rq = igt_spinner_create_request(spin, ctx, engine, MI_NOOP);
|
||||
if (IS_ERR(rq)) {
|
||||
ret = PTR_ERR(rq);
|
||||
igt_spinner_fini(spin);
|
||||
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;
|
||||
rq = igt_spinner_create_request(*spin, ctx, engine, MI_NOOP);
|
||||
if (IS_ERR(rq)) {
|
||||
ret = PTR_ERR(rq);
|
||||
goto err_fini;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -897,22 +895,23 @@ __sseu_test(struct drm_i915_private *i915,
|
|||
|
||||
ret = __sseu_prepare(i915, name, flags, ctx, engine, &spin);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto out_context;
|
||||
|
||||
ret = __i915_gem_context_reconfigure_sseu(ctx, engine, sseu);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto out_spin;
|
||||
|
||||
ret = __sseu_finish(i915, name, flags, ctx, kctx, engine, obj,
|
||||
hweight32(sseu.slice_mask), spin);
|
||||
|
||||
out:
|
||||
out_spin:
|
||||
if (spin) {
|
||||
igt_spinner_end(spin);
|
||||
igt_spinner_fini(spin);
|
||||
kfree(spin);
|
||||
}
|
||||
|
||||
out_context:
|
||||
kernel_context_close(kctx);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -79,6 +79,10 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (ret)
|
||||
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);
|
||||
if (ret)
|
||||
goto disable_pci;
|
||||
|
@ -94,7 +98,6 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (ret)
|
||||
goto modeset_cleanup;
|
||||
|
||||
drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "qxl");
|
||||
drm_fbdev_generic_setup(&qdev->ddev, 32);
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include <linux/miscdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/vt.h>
|
||||
#include <linux/console.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_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)
|
||||
{
|
||||
if (vgadev->irq_set_state)
|
||||
|
|
|
@ -36,6 +36,7 @@ struct drm_fb_helper;
|
|||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/vgaarb.h>
|
||||
|
||||
enum mode_set_atomic {
|
||||
LEAVE_ATOMIC_MODE_SET,
|
||||
|
@ -642,11 +643,18 @@ drm_fb_helper_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
|
|||
int resource_id,
|
||||
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)
|
||||
return remove_conflicting_pci_framebuffers(pdev, resource_id, name);
|
||||
#else
|
||||
return 0;
|
||||
ret = remove_conflicting_pci_framebuffers(pdev, resource_id, name);
|
||||
#endif
|
||||
if (ret == 0)
|
||||
ret = vga_remove_vgacon(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -125,9 +125,11 @@ extern void vga_put(struct pci_dev *pdev, unsigned int rsrc);
|
|||
#ifdef CONFIG_VGA_ARB
|
||||
extern struct pci_dev *vga_default_device(void);
|
||||
extern void vga_set_default_device(struct pci_dev *pdev);
|
||||
extern int vga_remove_vgacon(struct pci_dev *pdev);
|
||||
#else
|
||||
static inline struct pci_dev *vga_default_device(void) { return NULL; };
|
||||
static inline void vga_set_default_device(struct pci_dev *pdev) { };
|
||||
static inline int vga_remove_vgacon(struct pci_dev *pdev) { return 0; };
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue