mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge 4.16-rc7 into char-misc-next
We want the hyperv fix in here for merging and testing. Signed-off-by: Greg Kroah-Hartman <[email protected]>
This commit is contained in:
commit
b24d0d5b12
769 changed files with 8044 additions and 5298 deletions
|
|
@ -540,6 +540,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
|
|||
size_t size;
|
||||
u32 retry = 3;
|
||||
|
||||
if (amdgpu_acpi_pcie_notify_device_ready(adev))
|
||||
return -EINVAL;
|
||||
|
||||
/* Get the device handle */
|
||||
handle = ACPI_HANDLE(&adev->pdev->dev);
|
||||
if (!handle)
|
||||
|
|
|
|||
|
|
@ -69,25 +69,18 @@ void amdgpu_connector_hotplug(struct drm_connector *connector)
|
|||
/* don't do anything if sink is not display port, i.e.,
|
||||
* passive dp->(dvi|hdmi) adaptor
|
||||
*/
|
||||
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
|
||||
int saved_dpms = connector->dpms;
|
||||
/* Only turn off the display if it's physically disconnected */
|
||||
if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
} else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
|
||||
/* Don't try to start link training before we
|
||||
* have the dpcd */
|
||||
if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
|
||||
return;
|
||||
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&
|
||||
amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd) &&
|
||||
amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
|
||||
/* Don't start link training before we have the DPCD */
|
||||
if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
|
||||
return;
|
||||
|
||||
/* set it to OFF so that drm_helper_connector_dpms()
|
||||
* won't return immediately since the current state
|
||||
* is ON at this point.
|
||||
*/
|
||||
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
connector->dpms = saved_dpms;
|
||||
/* Turn the connector off and back on immediately, which
|
||||
* will trigger link training
|
||||
*/
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2063,9 +2063,12 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
|
|||
|
||||
DRM_INFO("amdgpu: finishing device.\n");
|
||||
adev->shutdown = true;
|
||||
if (adev->mode_info.mode_config_initialized)
|
||||
drm_crtc_force_disable_all(adev->ddev);
|
||||
|
||||
if (adev->mode_info.mode_config_initialized){
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
drm_crtc_force_disable_all(adev->ddev);
|
||||
else
|
||||
drm_atomic_helper_shutdown(adev->ddev);
|
||||
}
|
||||
amdgpu_ib_pool_fini(adev);
|
||||
amdgpu_fence_driver_fini(adev);
|
||||
amdgpu_fbdev_fini(adev);
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj)
|
|||
struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
|
||||
|
||||
if (robj) {
|
||||
if (robj->gem_base.import_attach)
|
||||
drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
|
||||
amdgpu_mn_unregister(robj);
|
||||
amdgpu_bo_unref(&robj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -352,6 +352,7 @@ struct amdgpu_mode_info {
|
|||
u16 firmware_flags;
|
||||
/* pointer to backlight encoder */
|
||||
struct amdgpu_encoder *bl_encoder;
|
||||
u8 bl_level; /* saved backlight level */
|
||||
struct amdgpu_audio audio; /* audio stuff */
|
||||
int num_crtc; /* number of crtcs */
|
||||
int num_hpd; /* number of hpd pins */
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
|
|||
|
||||
amdgpu_bo_kunmap(bo);
|
||||
|
||||
if (bo->gem_base.import_attach)
|
||||
drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg);
|
||||
drm_gem_object_release(&bo->gem_base);
|
||||
amdgpu_bo_unref(&bo->parent);
|
||||
if (!list_empty(&bo->shadow_list)) {
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
|
|||
result = 0;
|
||||
|
||||
if (*pos < 12) {
|
||||
early[0] = amdgpu_ring_get_rptr(ring);
|
||||
early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask;
|
||||
early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask;
|
||||
early[2] = ring->wptr & ring->buf_mask;
|
||||
for (i = *pos / 4; i < 3 && size; i++) {
|
||||
|
|
|
|||
|
|
@ -299,12 +299,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
|
|||
|
||||
cancel_delayed_work_sync(&adev->uvd.idle_work);
|
||||
|
||||
for (i = 0; i < adev->uvd.max_handles; ++i)
|
||||
if (atomic_read(&adev->uvd.handles[i]))
|
||||
break;
|
||||
/* only valid for physical mode */
|
||||
if (adev->asic_type < CHIP_POLARIS10) {
|
||||
for (i = 0; i < adev->uvd.max_handles; ++i)
|
||||
if (atomic_read(&adev->uvd.handles[i]))
|
||||
break;
|
||||
|
||||
if (i == AMDGPU_MAX_UVD_HANDLES)
|
||||
return 0;
|
||||
if (i == adev->uvd.max_handles)
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = amdgpu_bo_size(adev->uvd.vcpu_bo);
|
||||
ptr = adev->uvd.cpu_addr;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include <linux/backlight.h>
|
||||
#include "bif/bif_4_1_d.h"
|
||||
|
||||
static u8
|
||||
u8
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(struct amdgpu_device *adev)
|
||||
{
|
||||
u8 backlight_level;
|
||||
|
|
@ -48,7 +48,7 @@ amdgpu_atombios_encoder_get_backlight_level_from_reg(struct amdgpu_device *adev)
|
|||
return backlight_level;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
amdgpu_atombios_encoder_set_backlight_level_to_reg(struct amdgpu_device *adev,
|
||||
u8 backlight_level)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@
|
|||
#ifndef __ATOMBIOS_ENCODER_H__
|
||||
#define __ATOMBIOS_ENCODER_H__
|
||||
|
||||
u8
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(struct amdgpu_device *adev);
|
||||
void
|
||||
amdgpu_atombios_encoder_set_backlight_level_to_reg(struct amdgpu_device *adev,
|
||||
u8 backlight_level);
|
||||
u8
|
||||
amdgpu_atombios_encoder_get_backlight_level(struct amdgpu_encoder *amdgpu_encoder);
|
||||
void
|
||||
|
|
|
|||
|
|
@ -2921,6 +2921,11 @@ static int dce_v10_0_hw_fini(void *handle)
|
|||
|
||||
static int dce_v10_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
||||
return dce_v10_0_hw_fini(handle);
|
||||
}
|
||||
|
||||
|
|
@ -2929,6 +2934,9 @@ static int dce_v10_0_resume(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret;
|
||||
|
||||
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
|
||||
adev->mode_info.bl_level);
|
||||
|
||||
ret = dce_v10_0_hw_init(handle);
|
||||
|
||||
/* turn on the BL */
|
||||
|
|
|
|||
|
|
@ -3047,6 +3047,11 @@ static int dce_v11_0_hw_fini(void *handle)
|
|||
|
||||
static int dce_v11_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
||||
return dce_v11_0_hw_fini(handle);
|
||||
}
|
||||
|
||||
|
|
@ -3055,6 +3060,9 @@ static int dce_v11_0_resume(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret;
|
||||
|
||||
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
|
||||
adev->mode_info.bl_level);
|
||||
|
||||
ret = dce_v11_0_hw_init(handle);
|
||||
|
||||
/* turn on the BL */
|
||||
|
|
|
|||
|
|
@ -2787,6 +2787,11 @@ static int dce_v6_0_hw_fini(void *handle)
|
|||
|
||||
static int dce_v6_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
||||
return dce_v6_0_hw_fini(handle);
|
||||
}
|
||||
|
||||
|
|
@ -2795,6 +2800,9 @@ static int dce_v6_0_resume(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret;
|
||||
|
||||
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
|
||||
adev->mode_info.bl_level);
|
||||
|
||||
ret = dce_v6_0_hw_init(handle);
|
||||
|
||||
/* turn on the BL */
|
||||
|
|
@ -3093,7 +3101,7 @@ static int dce_v6_0_hpd_irq(struct amdgpu_device *adev,
|
|||
tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
|
||||
WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);
|
||||
schedule_work(&adev->hotplug_work);
|
||||
DRM_INFO("IH: HPD%d\n", hpd + 1);
|
||||
DRM_DEBUG("IH: HPD%d\n", hpd + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2819,6 +2819,11 @@ static int dce_v8_0_hw_fini(void *handle)
|
|||
|
||||
static int dce_v8_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
||||
return dce_v8_0_hw_fini(handle);
|
||||
}
|
||||
|
||||
|
|
@ -2827,6 +2832,9 @@ static int dce_v8_0_resume(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret;
|
||||
|
||||
amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
|
||||
adev->mode_info.bl_level);
|
||||
|
||||
ret = dce_v8_0_hw_init(handle);
|
||||
|
||||
/* turn on the BL */
|
||||
|
|
|
|||
|
|
@ -4384,34 +4384,8 @@ static void gfx_v7_0_gpu_early_init(struct amdgpu_device *adev)
|
|||
case CHIP_KAVERI:
|
||||
adev->gfx.config.max_shader_engines = 1;
|
||||
adev->gfx.config.max_tile_pipes = 4;
|
||||
if ((adev->pdev->device == 0x1304) ||
|
||||
(adev->pdev->device == 0x1305) ||
|
||||
(adev->pdev->device == 0x130C) ||
|
||||
(adev->pdev->device == 0x130F) ||
|
||||
(adev->pdev->device == 0x1310) ||
|
||||
(adev->pdev->device == 0x1311) ||
|
||||
(adev->pdev->device == 0x131C)) {
|
||||
adev->gfx.config.max_cu_per_sh = 8;
|
||||
adev->gfx.config.max_backends_per_se = 2;
|
||||
} else if ((adev->pdev->device == 0x1309) ||
|
||||
(adev->pdev->device == 0x130A) ||
|
||||
(adev->pdev->device == 0x130D) ||
|
||||
(adev->pdev->device == 0x1313) ||
|
||||
(adev->pdev->device == 0x131D)) {
|
||||
adev->gfx.config.max_cu_per_sh = 6;
|
||||
adev->gfx.config.max_backends_per_se = 2;
|
||||
} else if ((adev->pdev->device == 0x1306) ||
|
||||
(adev->pdev->device == 0x1307) ||
|
||||
(adev->pdev->device == 0x130B) ||
|
||||
(adev->pdev->device == 0x130E) ||
|
||||
(adev->pdev->device == 0x1315) ||
|
||||
(adev->pdev->device == 0x131B)) {
|
||||
adev->gfx.config.max_cu_per_sh = 4;
|
||||
adev->gfx.config.max_backends_per_se = 1;
|
||||
} else {
|
||||
adev->gfx.config.max_cu_per_sh = 3;
|
||||
adev->gfx.config.max_backends_per_se = 1;
|
||||
}
|
||||
adev->gfx.config.max_cu_per_sh = 8;
|
||||
adev->gfx.config.max_backends_per_se = 2;
|
||||
adev->gfx.config.max_sh_per_se = 1;
|
||||
adev->gfx.config.max_texture_channel_caches = 4;
|
||||
adev->gfx.config.max_gprs = 256;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "amdgpu_uvd.h"
|
||||
#include "amdgpu_vce.h"
|
||||
#include "atom.h"
|
||||
#include "amd_pcie.h"
|
||||
#include "amdgpu_powerplay.h"
|
||||
#include "sid.h"
|
||||
#include "si_ih.h"
|
||||
|
|
@ -1461,8 +1462,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
|
|||
{
|
||||
struct pci_dev *root = adev->pdev->bus->self;
|
||||
int bridge_pos, gpu_pos;
|
||||
u32 speed_cntl, mask, current_data_rate;
|
||||
int ret, i;
|
||||
u32 speed_cntl, current_data_rate;
|
||||
int i;
|
||||
u16 tmp16;
|
||||
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
|
|
@ -1474,23 +1475,20 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
|
|||
if (adev->flags & AMD_IS_APU)
|
||||
return;
|
||||
|
||||
ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
|
||||
if (ret != 0)
|
||||
return;
|
||||
|
||||
if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
|
||||
if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
|
||||
CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
|
||||
return;
|
||||
|
||||
speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
|
||||
current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
|
||||
LC_CURRENT_DATA_RATE_SHIFT;
|
||||
if (mask & DRM_PCIE_SPEED_80) {
|
||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
|
||||
if (current_data_rate == 2) {
|
||||
DRM_INFO("PCIE gen 3 link speeds already enabled\n");
|
||||
return;
|
||||
}
|
||||
DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n");
|
||||
} else if (mask & DRM_PCIE_SPEED_50) {
|
||||
} else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) {
|
||||
if (current_data_rate == 1) {
|
||||
DRM_INFO("PCIE gen 2 link speeds already enabled\n");
|
||||
return;
|
||||
|
|
@ -1506,7 +1504,7 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
|
|||
if (!gpu_pos)
|
||||
return;
|
||||
|
||||
if (mask & DRM_PCIE_SPEED_80) {
|
||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
|
||||
if (current_data_rate != 2) {
|
||||
u16 bridge_cfg, gpu_cfg;
|
||||
u16 bridge_cfg2, gpu_cfg2;
|
||||
|
|
@ -1589,9 +1587,9 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
|
|||
|
||||
pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
|
||||
tmp16 &= ~0xf;
|
||||
if (mask & DRM_PCIE_SPEED_80)
|
||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||
tmp16 |= 3;
|
||||
else if (mask & DRM_PCIE_SPEED_50)
|
||||
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
|
||||
tmp16 |= 2;
|
||||
else
|
||||
tmp16 |= 1;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "amdgpu_pm.h"
|
||||
#include "amdgpu_dpm.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "amd_pcie.h"
|
||||
#include "sid.h"
|
||||
#include "r600_dpm.h"
|
||||
#include "si_dpm.h"
|
||||
|
|
@ -3331,29 +3332,6 @@ static void btc_apply_voltage_delta_rules(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
static enum amdgpu_pcie_gen r600_get_pcie_gen_support(struct amdgpu_device *adev,
|
||||
u32 sys_mask,
|
||||
enum amdgpu_pcie_gen asic_gen,
|
||||
enum amdgpu_pcie_gen default_gen)
|
||||
{
|
||||
switch (asic_gen) {
|
||||
case AMDGPU_PCIE_GEN1:
|
||||
return AMDGPU_PCIE_GEN1;
|
||||
case AMDGPU_PCIE_GEN2:
|
||||
return AMDGPU_PCIE_GEN2;
|
||||
case AMDGPU_PCIE_GEN3:
|
||||
return AMDGPU_PCIE_GEN3;
|
||||
default:
|
||||
if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == AMDGPU_PCIE_GEN3))
|
||||
return AMDGPU_PCIE_GEN3;
|
||||
else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == AMDGPU_PCIE_GEN2))
|
||||
return AMDGPU_PCIE_GEN2;
|
||||
else
|
||||
return AMDGPU_PCIE_GEN1;
|
||||
}
|
||||
return AMDGPU_PCIE_GEN1;
|
||||
}
|
||||
|
||||
static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
|
||||
u32 *p, u32 *u)
|
||||
{
|
||||
|
|
@ -5028,10 +5006,11 @@ static int si_populate_smc_acpi_state(struct amdgpu_device *adev,
|
|||
table->ACPIState.levels[0].vddc.index,
|
||||
&table->ACPIState.levels[0].std_vddc);
|
||||
}
|
||||
table->ACPIState.levels[0].gen2PCIE = (u8)r600_get_pcie_gen_support(adev,
|
||||
si_pi->sys_pcie_mask,
|
||||
si_pi->boot_pcie_gen,
|
||||
AMDGPU_PCIE_GEN1);
|
||||
table->ACPIState.levels[0].gen2PCIE =
|
||||
(u8)amdgpu_get_pcie_gen_support(adev,
|
||||
si_pi->sys_pcie_mask,
|
||||
si_pi->boot_pcie_gen,
|
||||
AMDGPU_PCIE_GEN1);
|
||||
|
||||
if (si_pi->vddc_phase_shed_control)
|
||||
si_populate_phase_shedding_value(adev,
|
||||
|
|
@ -7168,10 +7147,10 @@ static void si_parse_pplib_clock_info(struct amdgpu_device *adev,
|
|||
pl->vddc = le16_to_cpu(clock_info->si.usVDDC);
|
||||
pl->vddci = le16_to_cpu(clock_info->si.usVDDCI);
|
||||
pl->flags = le32_to_cpu(clock_info->si.ulFlags);
|
||||
pl->pcie_gen = r600_get_pcie_gen_support(adev,
|
||||
si_pi->sys_pcie_mask,
|
||||
si_pi->boot_pcie_gen,
|
||||
clock_info->si.ucPCIEGen);
|
||||
pl->pcie_gen = amdgpu_get_pcie_gen_support(adev,
|
||||
si_pi->sys_pcie_mask,
|
||||
si_pi->boot_pcie_gen,
|
||||
clock_info->si.ucPCIEGen);
|
||||
|
||||
/* patch up vddc if necessary */
|
||||
ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc,
|
||||
|
|
@ -7326,7 +7305,6 @@ static int si_dpm_init(struct amdgpu_device *adev)
|
|||
struct si_power_info *si_pi;
|
||||
struct atom_clock_dividers dividers;
|
||||
int ret;
|
||||
u32 mask;
|
||||
|
||||
si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL);
|
||||
if (si_pi == NULL)
|
||||
|
|
@ -7336,11 +7314,9 @@ static int si_dpm_init(struct amdgpu_device *adev)
|
|||
eg_pi = &ni_pi->eg;
|
||||
pi = &eg_pi->rv7xx;
|
||||
|
||||
ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
|
||||
if (ret)
|
||||
si_pi->sys_pcie_mask = 0;
|
||||
else
|
||||
si_pi->sys_pcie_mask = mask;
|
||||
si_pi->sys_pcie_mask =
|
||||
(adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK) >>
|
||||
CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT;
|
||||
si_pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID;
|
||||
si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev);
|
||||
|
||||
|
|
|
|||
|
|
@ -1037,6 +1037,10 @@ static void handle_hpd_rx_irq(void *param)
|
|||
!is_mst_root_connector) {
|
||||
/* Downstream Port status changed. */
|
||||
if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
|
||||
|
||||
if (aconnector->fake_enable)
|
||||
aconnector->fake_enable = false;
|
||||
|
||||
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||
|
||||
|
||||
|
|
@ -2012,30 +2016,32 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode,
|
|||
dst.width = stream->timing.h_addressable;
|
||||
dst.height = stream->timing.v_addressable;
|
||||
|
||||
rmx_type = dm_state->scaling;
|
||||
if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) {
|
||||
if (src.width * dst.height <
|
||||
src.height * dst.width) {
|
||||
/* height needs less upscaling/more downscaling */
|
||||
dst.width = src.width *
|
||||
dst.height / src.height;
|
||||
} else {
|
||||
/* width needs less upscaling/more downscaling */
|
||||
dst.height = src.height *
|
||||
dst.width / src.width;
|
||||
if (dm_state) {
|
||||
rmx_type = dm_state->scaling;
|
||||
if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) {
|
||||
if (src.width * dst.height <
|
||||
src.height * dst.width) {
|
||||
/* height needs less upscaling/more downscaling */
|
||||
dst.width = src.width *
|
||||
dst.height / src.height;
|
||||
} else {
|
||||
/* width needs less upscaling/more downscaling */
|
||||
dst.height = src.height *
|
||||
dst.width / src.width;
|
||||
}
|
||||
} else if (rmx_type == RMX_CENTER) {
|
||||
dst = src;
|
||||
}
|
||||
} else if (rmx_type == RMX_CENTER) {
|
||||
dst = src;
|
||||
}
|
||||
|
||||
dst.x = (stream->timing.h_addressable - dst.width) / 2;
|
||||
dst.y = (stream->timing.v_addressable - dst.height) / 2;
|
||||
dst.x = (stream->timing.h_addressable - dst.width) / 2;
|
||||
dst.y = (stream->timing.v_addressable - dst.height) / 2;
|
||||
|
||||
if (dm_state->underscan_enable) {
|
||||
dst.x += dm_state->underscan_hborder / 2;
|
||||
dst.y += dm_state->underscan_vborder / 2;
|
||||
dst.width -= dm_state->underscan_hborder;
|
||||
dst.height -= dm_state->underscan_vborder;
|
||||
if (dm_state->underscan_enable) {
|
||||
dst.x += dm_state->underscan_hborder / 2;
|
||||
dst.y += dm_state->underscan_vborder / 2;
|
||||
dst.width -= dm_state->underscan_hborder;
|
||||
dst.height -= dm_state->underscan_vborder;
|
||||
}
|
||||
}
|
||||
|
||||
stream->src = src;
|
||||
|
|
@ -2360,12 +2366,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
|
||||
if (aconnector == NULL) {
|
||||
DRM_ERROR("aconnector is NULL!\n");
|
||||
goto drm_connector_null;
|
||||
}
|
||||
|
||||
if (dm_state == NULL) {
|
||||
DRM_ERROR("dm_state is NULL!\n");
|
||||
goto dm_state_null;
|
||||
return stream;
|
||||
}
|
||||
|
||||
drm_connector = &aconnector->base;
|
||||
|
|
@ -2377,18 +2378,18 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
*/
|
||||
if (aconnector->mst_port) {
|
||||
dm_dp_mst_dc_sink_create(drm_connector);
|
||||
goto mst_dc_sink_create_done;
|
||||
return stream;
|
||||
}
|
||||
|
||||
if (create_fake_sink(aconnector))
|
||||
goto stream_create_fail;
|
||||
return stream;
|
||||
}
|
||||
|
||||
stream = dc_create_stream_for_sink(aconnector->dc_sink);
|
||||
|
||||
if (stream == NULL) {
|
||||
DRM_ERROR("Failed to create stream for sink!\n");
|
||||
goto stream_create_fail;
|
||||
return stream;
|
||||
}
|
||||
|
||||
list_for_each_entry(preferred_mode, &aconnector->base.modes, head) {
|
||||
|
|
@ -2414,9 +2415,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
} else {
|
||||
decide_crtc_timing_for_drm_display_mode(
|
||||
&mode, preferred_mode,
|
||||
dm_state->scaling != RMX_OFF);
|
||||
dm_state ? (dm_state->scaling != RMX_OFF) : false);
|
||||
}
|
||||
|
||||
if (!dm_state)
|
||||
drm_mode_set_crtcinfo(&mode, 0);
|
||||
|
||||
fill_stream_properties_from_drm_display_mode(stream,
|
||||
&mode, &aconnector->base);
|
||||
update_stream_scaling_settings(&mode, dm_state, stream);
|
||||
|
|
@ -2426,10 +2430,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
drm_connector,
|
||||
aconnector->dc_sink);
|
||||
|
||||
stream_create_fail:
|
||||
dm_state_null:
|
||||
drm_connector_null:
|
||||
mst_dc_sink_create_done:
|
||||
update_stream_signal(stream);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
|
@ -2497,6 +2499,27 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
|
|||
return &state->base;
|
||||
}
|
||||
|
||||
|
||||
static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
|
||||
{
|
||||
enum dc_irq_source irq_source;
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
struct amdgpu_device *adev = crtc->dev->dev_private;
|
||||
|
||||
irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst;
|
||||
return dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY;
|
||||
}
|
||||
|
||||
static int dm_enable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
return dm_set_vblank(crtc, true);
|
||||
}
|
||||
|
||||
static void dm_disable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
dm_set_vblank(crtc, false);
|
||||
}
|
||||
|
||||
/* Implemented only the options currently availible for the driver */
|
||||
static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
|
||||
.reset = dm_crtc_reset_state,
|
||||
|
|
@ -2506,6 +2529,8 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
|
|||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.atomic_duplicate_state = dm_crtc_duplicate_state,
|
||||
.atomic_destroy_state = dm_crtc_destroy_state,
|
||||
.enable_vblank = dm_enable_vblank,
|
||||
.disable_vblank = dm_disable_vblank,
|
||||
};
|
||||
|
||||
static enum drm_connector_status
|
||||
|
|
@ -2800,7 +2825,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
stream = dc_create_stream_for_sink(dc_sink);
|
||||
stream = create_stream_for_sink(aconnector, mode, NULL);
|
||||
if (stream == NULL) {
|
||||
DRM_ERROR("Failed to create stream for sink!\n");
|
||||
goto fail;
|
||||
|
|
@ -3060,6 +3085,9 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
|
|||
if (!dm_plane_state->dc_state)
|
||||
return 0;
|
||||
|
||||
if (!fill_rects_from_plane_state(state, dm_plane_state->dc_state))
|
||||
return -EINVAL;
|
||||
|
||||
if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
|
||||
return 0;
|
||||
|
||||
|
|
@ -3106,8 +3134,6 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
|
|||
|
||||
switch (aplane->base.type) {
|
||||
case DRM_PLANE_TYPE_PRIMARY:
|
||||
aplane->base.format_default = true;
|
||||
|
||||
res = drm_universal_plane_init(
|
||||
dm->adev->ddev,
|
||||
&aplane->base,
|
||||
|
|
@ -4632,8 +4658,6 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
bool pflip_needed = !state->allow_modeset;
|
||||
int ret = 0;
|
||||
|
||||
if (pflip_needed)
|
||||
return ret;
|
||||
|
||||
/* Add new planes */
|
||||
for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
|
||||
|
|
@ -4648,6 +4672,8 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
|
||||
/* Remove any changed/removed planes */
|
||||
if (!enable) {
|
||||
if (pflip_needed)
|
||||
continue;
|
||||
|
||||
if (!old_plane_crtc)
|
||||
continue;
|
||||
|
|
@ -4679,6 +4705,7 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
*lock_and_validation_needed = true;
|
||||
|
||||
} else { /* Add new planes */
|
||||
struct dc_plane_state *dc_new_plane_state;
|
||||
|
||||
if (drm_atomic_plane_disabling(plane->state, new_plane_state))
|
||||
continue;
|
||||
|
|
@ -4692,38 +4719,50 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
if (!dm_new_crtc_state->stream)
|
||||
continue;
|
||||
|
||||
if (pflip_needed)
|
||||
continue;
|
||||
|
||||
WARN_ON(dm_new_plane_state->dc_state);
|
||||
|
||||
dm_new_plane_state->dc_state = dc_create_plane_state(dc);
|
||||
dc_new_plane_state = dc_create_plane_state(dc);
|
||||
if (!dc_new_plane_state) {
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n",
|
||||
plane->base.id, new_plane_crtc->base.id);
|
||||
|
||||
if (!dm_new_plane_state->dc_state) {
|
||||
ret = -EINVAL;
|
||||
ret = fill_plane_attributes(
|
||||
new_plane_crtc->dev->dev_private,
|
||||
dc_new_plane_state,
|
||||
new_plane_state,
|
||||
new_crtc_state);
|
||||
if (ret) {
|
||||
dc_plane_state_release(dc_new_plane_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fill_plane_attributes(
|
||||
new_plane_crtc->dev->dev_private,
|
||||
dm_new_plane_state->dc_state,
|
||||
new_plane_state,
|
||||
new_crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
/*
|
||||
* Any atomic check errors that occur after this will
|
||||
* not need a release. The plane state will be attached
|
||||
* to the stream, and therefore part of the atomic
|
||||
* state. It'll be released when the atomic state is
|
||||
* cleaned.
|
||||
*/
|
||||
if (!dc_add_plane_to_context(
|
||||
dc,
|
||||
dm_new_crtc_state->stream,
|
||||
dm_new_plane_state->dc_state,
|
||||
dc_new_plane_state,
|
||||
dm_state->context)) {
|
||||
|
||||
dc_plane_state_release(dc_new_plane_state);
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dm_new_plane_state->dc_state = dc_new_plane_state;
|
||||
|
||||
/* Tell DC to do a full surface update every time there
|
||||
* is a plane change. Inefficient, but works for now.
|
||||
*/
|
||||
|
|
@ -4737,6 +4776,33 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_plane *plane;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
|
||||
|
||||
drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
|
||||
struct drm_plane_state *plane_state =
|
||||
drm_atomic_get_plane_state(state, plane);
|
||||
|
||||
if (IS_ERR(plane_state))
|
||||
return -EDEADLK;
|
||||
|
||||
crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc);
|
||||
if (IS_ERR(crtc_state))
|
||||
return PTR_ERR(crtc_state);
|
||||
|
||||
if (crtc->primary == plane && crtc_state->active) {
|
||||
if (!plane_state->fb)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
|
|
@ -4760,6 +4826,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
goto fail;
|
||||
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
ret = dm_atomic_check_plane_state_fb(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
|
||||
!new_crtc_state->color_mgmt_changed)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
|
|||
struct cea_sad *sad = &sads[i];
|
||||
|
||||
edid_caps->audio_modes[i].format_code = sad->format;
|
||||
edid_caps->audio_modes[i].channel_count = sad->channels;
|
||||
edid_caps->audio_modes[i].channel_count = sad->channels + 1;
|
||||
edid_caps->audio_modes[i].sample_rate = sad->freq;
|
||||
edid_caps->audio_modes[i].sample_size = sad->byte2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -683,10 +683,8 @@ static const struct amdgpu_irq_src_funcs dm_hpd_irq_funcs = {
|
|||
|
||||
void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mode_info.num_crtc > 0)
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
|
||||
else
|
||||
adev->crtc_irq.num_types = 0;
|
||||
|
||||
adev->crtc_irq.num_types = adev->mode_info.num_crtc;
|
||||
adev->crtc_irq.funcs = &dm_crtc_irq_funcs;
|
||||
|
||||
adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
|
||||
|
|
|
|||
|
|
@ -189,6 +189,12 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
|
|||
.link = aconnector->dc_link,
|
||||
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
|
||||
|
||||
/*
|
||||
* TODO: Need to further figure out why ddc.algo is NULL while MST port exists
|
||||
*/
|
||||
if (!aconnector->port || !aconnector->port->aux.ddc.algo)
|
||||
return;
|
||||
|
||||
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
|
||||
|
||||
if (!edid) {
|
||||
|
|
|
|||
|
|
@ -1358,13 +1358,13 @@ enum dc_irq_source dc_interrupt_to_irq_source(
|
|||
return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id);
|
||||
}
|
||||
|
||||
void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
|
||||
bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
|
||||
{
|
||||
|
||||
if (dc == NULL)
|
||||
return;
|
||||
return false;
|
||||
|
||||
dal_irq_service_set(dc->res_pool->irqs, src, enable);
|
||||
return dal_irq_service_set(dc->res_pool->irqs, src, enable);
|
||||
}
|
||||
|
||||
void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
|
||||
|
|
|
|||
|
|
@ -1749,8 +1749,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
|
|||
link->link_enc,
|
||||
pipe_ctx->clock_source->id,
|
||||
display_color_depth,
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A,
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK,
|
||||
pipe_ctx->stream->signal,
|
||||
stream->phy_pix_clk);
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
|
||||
|
|
|
|||
|
|
@ -1360,9 +1360,6 @@ bool dc_is_stream_scaling_unchanged(
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Maximum TMDS single link pixel clock 165MHz */
|
||||
#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
|
||||
|
||||
static void update_stream_engine_usage(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@
|
|||
/*******************************************************************************
|
||||
* Private functions
|
||||
******************************************************************************/
|
||||
#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000
|
||||
static void update_stream_signal(struct dc_stream_state *stream)
|
||||
void update_stream_signal(struct dc_stream_state *stream)
|
||||
{
|
||||
|
||||
struct dc_sink *dc_sink = stream->sink;
|
||||
|
|
@ -45,8 +44,9 @@ static void update_stream_signal(struct dc_stream_state *stream)
|
|||
stream->signal = dc_sink->sink_signal;
|
||||
|
||||
if (dc_is_dvi_signal(stream->signal)) {
|
||||
if (stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST &&
|
||||
stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
|
||||
if (stream->ctx->dc->caps.dual_link_dvi &&
|
||||
stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK &&
|
||||
stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
|
||||
stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK;
|
||||
else
|
||||
stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
|
||||
|
|
@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes(
|
|||
|
||||
core_dc = stream->ctx->dc;
|
||||
res_ctx = &core_dc->current_state->res_ctx;
|
||||
stream->cursor_attributes = *attributes;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
|
||||
|
|
@ -204,34 +205,8 @@ bool dc_stream_set_cursor_attributes(
|
|||
continue;
|
||||
|
||||
|
||||
if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
|
||||
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
|
||||
pipe_ctx->plane_res.ipp, attributes);
|
||||
|
||||
if (pipe_ctx->plane_res.hubp != NULL &&
|
||||
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
|
||||
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.hubp, attributes);
|
||||
|
||||
if (pipe_ctx->plane_res.mi != NULL &&
|
||||
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
|
||||
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.mi, attributes);
|
||||
|
||||
|
||||
if (pipe_ctx->plane_res.xfm != NULL &&
|
||||
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
|
||||
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.xfm, attributes);
|
||||
|
||||
if (pipe_ctx->plane_res.dpp != NULL &&
|
||||
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
|
||||
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.dpp, attributes->color_format);
|
||||
core_dc->hwss.set_cursor_attribute(pipe_ctx);
|
||||
}
|
||||
|
||||
stream->cursor_attributes = *attributes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -255,21 +230,10 @@ bool dc_stream_set_cursor_position(
|
|||
|
||||
core_dc = stream->ctx->dc;
|
||||
res_ctx = &core_dc->current_state->res_ctx;
|
||||
stream->cursor_position = *position;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
|
||||
struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
|
||||
struct mem_input *mi = pipe_ctx->plane_res.mi;
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct dpp *dpp = pipe_ctx->plane_res.dpp;
|
||||
struct dc_cursor_position pos_cpy = *position;
|
||||
struct dc_cursor_mi_param param = {
|
||||
.pixel_clk_khz = stream->timing.pix_clk_khz,
|
||||
.ref_clk_khz = core_dc->res_pool->ref_clock_inKhz,
|
||||
.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
|
||||
.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
|
||||
.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
|
||||
};
|
||||
|
||||
if (pipe_ctx->stream != stream ||
|
||||
(!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) ||
|
||||
|
|
@ -278,33 +242,9 @@ bool dc_stream_set_cursor_position(
|
|||
!pipe_ctx->plane_res.ipp)
|
||||
continue;
|
||||
|
||||
if (pipe_ctx->plane_state->address.type
|
||||
== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
pos_cpy.enable = false;
|
||||
|
||||
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
|
||||
pos_cpy.enable = false;
|
||||
|
||||
|
||||
if (ipp != NULL && ipp->funcs->ipp_cursor_set_position != NULL)
|
||||
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m);
|
||||
|
||||
if (mi != NULL && mi->funcs->set_cursor_position != NULL)
|
||||
mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m);
|
||||
|
||||
if (!hubp)
|
||||
continue;
|
||||
|
||||
if (hubp->funcs->set_cursor_position != NULL)
|
||||
hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m);
|
||||
|
||||
if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
|
||||
dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width);
|
||||
|
||||
core_dc->hwss.set_cursor_position(pipe_ctx);
|
||||
}
|
||||
|
||||
stream->cursor_position = *position;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ struct dc_caps {
|
|||
bool dcc_const_color;
|
||||
bool dynamic_audio;
|
||||
bool is_apu;
|
||||
bool dual_link_dvi;
|
||||
};
|
||||
|
||||
struct dc_dcc_surface_param {
|
||||
|
|
@ -672,7 +673,7 @@ enum dc_irq_source dc_interrupt_to_irq_source(
|
|||
struct dc *dc,
|
||||
uint32_t src_id,
|
||||
uint32_t ext_id);
|
||||
void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable);
|
||||
bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable);
|
||||
void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src);
|
||||
enum dc_irq_source dc_get_hpd_irq_source_at_index(
|
||||
struct dc *dc, uint32_t link_index);
|
||||
|
|
|
|||
|
|
@ -237,6 +237,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
|
|||
*/
|
||||
struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink);
|
||||
|
||||
void update_stream_signal(struct dc_stream_state *stream);
|
||||
|
||||
void dc_stream_retain(struct dc_stream_state *dc_stream);
|
||||
void dc_stream_release(struct dc_stream_state *dc_stream);
|
||||
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@
|
|||
SR(D2VGA_CONTROL), \
|
||||
SR(D3VGA_CONTROL), \
|
||||
SR(D4VGA_CONTROL), \
|
||||
SR(VGA_TEST_CONTROL), \
|
||||
SR(DC_IP_REQUEST_CNTL), \
|
||||
BL_REG_LIST()
|
||||
|
||||
|
|
@ -337,6 +338,7 @@ struct dce_hwseq_registers {
|
|||
uint32_t D2VGA_CONTROL;
|
||||
uint32_t D3VGA_CONTROL;
|
||||
uint32_t D4VGA_CONTROL;
|
||||
uint32_t VGA_TEST_CONTROL;
|
||||
/* MMHUB registers. read only. temporary hack */
|
||||
uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32;
|
||||
uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
|
||||
|
|
@ -493,6 +495,12 @@ struct dce_hwseq_registers {
|
|||
HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
|
||||
HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, D2VGA_CONTROL, D2VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, D3VGA_CONTROL, D3VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, D4VGA_CONTROL, D4VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\
|
||||
HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh),\
|
||||
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
|
||||
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
|
||||
|
||||
|
|
@ -583,7 +591,13 @@ struct dce_hwseq_registers {
|
|||
type DCFCLK_GATE_DIS; \
|
||||
type DCHUBBUB_GLOBAL_TIMER_REFDIV; \
|
||||
type DENTIST_DPPCLK_WDIVIDER; \
|
||||
type DENTIST_DISPCLK_WDIVIDER;
|
||||
type DENTIST_DISPCLK_WDIVIDER; \
|
||||
type VGA_TEST_ENABLE; \
|
||||
type VGA_TEST_RENDER_START; \
|
||||
type D1VGA_MODE_ENABLE; \
|
||||
type D2VGA_MODE_ENABLE; \
|
||||
type D3VGA_MODE_ENABLE; \
|
||||
type D4VGA_MODE_ENABLE;
|
||||
|
||||
struct dce_hwseq_shift {
|
||||
HWSEQ_REG_FIELD_LIST(uint8_t)
|
||||
|
|
|
|||
|
|
@ -82,13 +82,6 @@
|
|||
#define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
|
||||
#define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
|
||||
|
||||
/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
|
||||
#define TMDS_MIN_PIXEL_CLOCK 25000
|
||||
/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
|
||||
#define TMDS_MAX_PIXEL_CLOCK 165000
|
||||
/* For current ASICs pixel clock - 600MHz */
|
||||
#define MAX_ENCODER_CLOCK 600000
|
||||
|
||||
enum {
|
||||
DP_MST_UPDATE_MAX_RETRY = 50
|
||||
};
|
||||
|
|
@ -683,6 +676,7 @@ void dce110_link_encoder_construct(
|
|||
{
|
||||
struct bp_encoder_cap_info bp_cap_info = {0};
|
||||
const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
|
||||
enum bp_result result = BP_RESULT_OK;
|
||||
|
||||
enc110->base.funcs = &dce110_lnk_enc_funcs;
|
||||
enc110->base.ctx = init_data->ctx;
|
||||
|
|
@ -757,15 +751,24 @@ void dce110_link_encoder_construct(
|
|||
enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
|
||||
}
|
||||
|
||||
/* default to one to mirror Windows behavior */
|
||||
enc110->base.features.flags.bits.HDMI_6GB_EN = 1;
|
||||
|
||||
result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios,
|
||||
enc110->base.id, &bp_cap_info);
|
||||
|
||||
/* Override features with DCE-specific values */
|
||||
if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info(
|
||||
enc110->base.ctx->dc_bios, enc110->base.id,
|
||||
&bp_cap_info)) {
|
||||
if (BP_RESULT_OK == result) {
|
||||
enc110->base.features.flags.bits.IS_HBR2_CAPABLE =
|
||||
bp_cap_info.DP_HBR2_EN;
|
||||
enc110->base.features.flags.bits.IS_HBR3_CAPABLE =
|
||||
bp_cap_info.DP_HBR3_EN;
|
||||
enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
|
||||
} else {
|
||||
dm_logger_write(enc110->base.ctx->logger, LOG_WARNING,
|
||||
"%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
|
||||
__func__,
|
||||
result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -904,8 +907,7 @@ void dce110_link_encoder_enable_tmds_output(
|
|||
struct link_encoder *enc,
|
||||
enum clock_source_id clock_source,
|
||||
enum dc_color_depth color_depth,
|
||||
bool hdmi,
|
||||
bool dual_link,
|
||||
enum signal_type signal,
|
||||
uint32_t pixel_clock)
|
||||
{
|
||||
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
|
||||
|
|
@ -919,16 +921,12 @@ void dce110_link_encoder_enable_tmds_output(
|
|||
cntl.engine_id = enc->preferred_engine;
|
||||
cntl.transmitter = enc110->base.transmitter;
|
||||
cntl.pll_id = clock_source;
|
||||
if (hdmi) {
|
||||
cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
cntl.lanes_number = 4;
|
||||
} else if (dual_link) {
|
||||
cntl.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
|
||||
cntl.signal = signal;
|
||||
if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
|
||||
cntl.lanes_number = 8;
|
||||
} else {
|
||||
cntl.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
|
||||
else
|
||||
cntl.lanes_number = 4;
|
||||
}
|
||||
|
||||
cntl.hpd_sel = enc110->base.hpd_source;
|
||||
|
||||
cntl.pixel_clock = pixel_clock;
|
||||
|
|
|
|||
|
|
@ -210,8 +210,7 @@ void dce110_link_encoder_enable_tmds_output(
|
|||
struct link_encoder *enc,
|
||||
enum clock_source_id clock_source,
|
||||
enum dc_color_depth color_depth,
|
||||
bool hdmi,
|
||||
bool dual_link,
|
||||
enum signal_type signal,
|
||||
uint32_t pixel_clock);
|
||||
|
||||
/* enables DP PHY output */
|
||||
|
|
|
|||
|
|
@ -128,23 +128,22 @@ static void set_truncation(
|
|||
return;
|
||||
}
|
||||
/* on other format-to do */
|
||||
if (params->flags.TRUNCATE_ENABLED == 0 ||
|
||||
params->flags.TRUNCATE_DEPTH == 2)
|
||||
if (params->flags.TRUNCATE_ENABLED == 0)
|
||||
return;
|
||||
/*Set truncation depth and Enable truncation*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TRUNCATE_EN, 1,
|
||||
FMT_TRUNCATE_DEPTH,
|
||||
params->flags.TRUNCATE_MODE,
|
||||
params->flags.TRUNCATE_DEPTH,
|
||||
FMT_TRUNCATE_MODE,
|
||||
params->flags.TRUNCATE_DEPTH);
|
||||
params->flags.TRUNCATE_MODE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set_spatial_dither
|
||||
* 1) set spatial dithering mode: pattern of seed
|
||||
* 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp
|
||||
* 2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp
|
||||
* 3) set random seed
|
||||
* 4) set random mode
|
||||
* lfsr is reset every frame or not reset
|
||||
|
|
|
|||
|
|
@ -852,6 +852,7 @@ static bool construct(
|
|||
dc->caps.max_downscale_ratio = 200;
|
||||
dc->caps.i2c_speed_in_khz = 40;
|
||||
dc->caps.max_cursor_size = 128;
|
||||
dc->caps.dual_link_dvi = true;
|
||||
|
||||
for (i = 0; i < pool->base.pipe_count; i++) {
|
||||
pool->base.timing_generators[i] =
|
||||
|
|
|
|||
|
|
@ -688,15 +688,22 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
|
||||
struct dc_link *link = pipe_ctx->stream->sink->link;
|
||||
|
||||
/* 1. update AVI info frame (HDMI, DP)
|
||||
* we always need to update info frame
|
||||
*/
|
||||
|
||||
uint32_t active_total_with_borders;
|
||||
uint32_t early_control = 0;
|
||||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
|
||||
/* TODOFPGA may change to hwss.update_info_frame */
|
||||
/* For MST, there are multiply stream go to only one link.
|
||||
* connect DIG back_end to front_end while enable_stream and
|
||||
* disconnect them during disable_stream
|
||||
* BY this, it is logic clean to separate stream and link */
|
||||
link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
|
||||
pipe_ctx->stream_res.stream_enc->id, true);
|
||||
|
||||
/* update AVI info frame (HDMI, DP)*/
|
||||
/* TODO: FPGA may change to hwss.update_info_frame */
|
||||
dce110_update_info_frame(pipe_ctx);
|
||||
|
||||
/* enable early control to avoid corruption on DP monitor*/
|
||||
active_total_with_borders =
|
||||
timing->h_addressable
|
||||
|
|
@ -717,12 +724,8 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
|
||||
}
|
||||
|
||||
/* For MST, there are multiply stream go to only one link.
|
||||
* connect DIG back_end to front_end while enable_stream and
|
||||
* disconnect them during disable_stream
|
||||
* BY this, it is logic clean to separate stream and link */
|
||||
link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
|
||||
pipe_ctx->stream_res.stream_enc->id, true);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1690,9 +1693,13 @@ static void apply_min_clocks(
|
|||
* Check if FBC can be enabled
|
||||
*/
|
||||
static bool should_enable_fbc(struct dc *dc,
|
||||
struct dc_state *context)
|
||||
struct dc_state *context,
|
||||
uint32_t *pipe_idx)
|
||||
{
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
|
||||
uint32_t i;
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
struct resource_context *res_ctx = &context->res_ctx;
|
||||
|
||||
|
||||
ASSERT(dc->fbc_compressor);
|
||||
|
||||
|
|
@ -1704,6 +1711,14 @@ static bool should_enable_fbc(struct dc *dc,
|
|||
if (context->stream_count != 1)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (res_ctx->pipe_ctx[i].stream) {
|
||||
pipe_ctx = &res_ctx->pipe_ctx[i];
|
||||
*pipe_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only supports eDP */
|
||||
if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
|
||||
return false;
|
||||
|
|
@ -1729,11 +1744,14 @@ static bool should_enable_fbc(struct dc *dc,
|
|||
static void enable_fbc(struct dc *dc,
|
||||
struct dc_state *context)
|
||||
{
|
||||
if (should_enable_fbc(dc, context)) {
|
||||
uint32_t pipe_idx = 0;
|
||||
|
||||
if (should_enable_fbc(dc, context, &pipe_idx)) {
|
||||
/* Program GRPH COMPRESSED ADDRESS and PITCH */
|
||||
struct compr_addr_and_pitch_params params = {0, 0, 0};
|
||||
struct compressor *compr = dc->fbc_compressor;
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
|
||||
|
||||
|
||||
params.source_view_width = pipe_ctx->stream->timing.h_addressable;
|
||||
params.source_view_height = pipe_ctx->stream->timing.v_addressable;
|
||||
|
|
@ -2915,6 +2933,49 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
|
||||
struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
|
||||
struct mem_input *mi = pipe_ctx->plane_res.mi;
|
||||
struct dc_cursor_mi_param param = {
|
||||
.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
|
||||
.ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
|
||||
.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
|
||||
.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
|
||||
.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
|
||||
};
|
||||
|
||||
if (pipe_ctx->plane_state->address.type
|
||||
== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
pos_cpy.enable = false;
|
||||
|
||||
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
|
||||
pos_cpy.enable = false;
|
||||
|
||||
if (ipp->funcs->ipp_cursor_set_position)
|
||||
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m);
|
||||
if (mi->funcs->set_cursor_position)
|
||||
mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m);
|
||||
}
|
||||
|
||||
void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
|
||||
|
||||
if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes)
|
||||
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
|
||||
pipe_ctx->plane_res.ipp, attributes);
|
||||
|
||||
if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes)
|
||||
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.mi, attributes);
|
||||
|
||||
if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes)
|
||||
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.xfm, attributes);
|
||||
}
|
||||
|
||||
static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
|
||||
|
||||
static void optimize_shared_resources(struct dc *dc) {}
|
||||
|
|
@ -2957,6 +3018,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
|||
.edp_backlight_control = hwss_edp_backlight_control,
|
||||
.edp_power_control = hwss_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
|
||||
.set_cursor_position = dce110_set_cursor_position,
|
||||
.set_cursor_attribute = dce110_set_cursor_attribute
|
||||
};
|
||||
|
||||
void dce110_hw_sequencer_construct(struct dc *dc)
|
||||
|
|
|
|||
|
|
@ -846,6 +846,16 @@ static bool dce110_validate_bandwidth(
|
|||
return result;
|
||||
}
|
||||
|
||||
enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state,
|
||||
struct dc_caps *caps)
|
||||
{
|
||||
if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) ||
|
||||
((plane_state->dst_rect.height * 2) < plane_state->src_rect.height))
|
||||
return DC_FAIL_SURFACE_VALIDATE;
|
||||
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
static bool dce110_validate_surface_sets(
|
||||
struct dc_state *context)
|
||||
{
|
||||
|
|
@ -869,6 +879,13 @@ static bool dce110_validate_surface_sets(
|
|||
plane->src_rect.height > 1080))
|
||||
return false;
|
||||
|
||||
/* we don't have the logic to support underlay
|
||||
* only yet so block the use case where we get
|
||||
* NV12 plane as top layer
|
||||
*/
|
||||
if (j == 0)
|
||||
return false;
|
||||
|
||||
/* irrespective of plane format,
|
||||
* stream should be RGB encoded
|
||||
*/
|
||||
|
|
@ -1021,6 +1038,7 @@ static const struct resource_funcs dce110_res_pool_funcs = {
|
|||
.link_enc_create = dce110_link_encoder_create,
|
||||
.validate_guaranteed = dce110_validate_guaranteed,
|
||||
.validate_bandwidth = dce110_validate_bandwidth,
|
||||
.validate_plane = dce110_validate_plane,
|
||||
.acquire_idle_pipe_for_layer = dce110_acquire_underlay,
|
||||
.add_stream_to_ctx = dce110_add_stream_to_ctx,
|
||||
.validate_global = dce110_validate_global
|
||||
|
|
|
|||
|
|
@ -1103,6 +1103,8 @@ static bool construct(
|
|||
dc->caps.max_downscale_ratio = 200;
|
||||
dc->caps.i2c_speed_in_khz = 100;
|
||||
dc->caps.max_cursor_size = 128;
|
||||
dc->caps.dual_link_dvi = true;
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Create resources *
|
||||
|
|
|
|||
|
|
@ -835,6 +835,8 @@ static bool construct(
|
|||
dc->caps.max_downscale_ratio = 200;
|
||||
dc->caps.i2c_speed_in_khz = 100;
|
||||
dc->caps.max_cursor_size = 128;
|
||||
dc->caps.dual_link_dvi = true;
|
||||
|
||||
dc->debug = debug_defaults;
|
||||
|
||||
/*************************************************
|
||||
|
|
|
|||
|
|
@ -793,6 +793,7 @@ static bool dce80_construct(
|
|||
dc->caps.max_downscale_ratio = 200;
|
||||
dc->caps.i2c_speed_in_khz = 40;
|
||||
dc->caps.max_cursor_size = 128;
|
||||
dc->caps.dual_link_dvi = true;
|
||||
|
||||
/*************************************************
|
||||
* Create resources *
|
||||
|
|
|
|||
|
|
@ -238,10 +238,34 @@ static void enable_power_gating_plane(
|
|||
static void disable_vga(
|
||||
struct dce_hwseq *hws)
|
||||
{
|
||||
unsigned int in_vga1_mode = 0;
|
||||
unsigned int in_vga2_mode = 0;
|
||||
unsigned int in_vga3_mode = 0;
|
||||
unsigned int in_vga4_mode = 0;
|
||||
|
||||
REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode);
|
||||
REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode);
|
||||
REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode);
|
||||
REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode);
|
||||
|
||||
if (in_vga1_mode == 0 && in_vga2_mode == 0 &&
|
||||
in_vga3_mode == 0 && in_vga4_mode == 0)
|
||||
return;
|
||||
|
||||
REG_WRITE(D1VGA_CONTROL, 0);
|
||||
REG_WRITE(D2VGA_CONTROL, 0);
|
||||
REG_WRITE(D3VGA_CONTROL, 0);
|
||||
REG_WRITE(D4VGA_CONTROL, 0);
|
||||
|
||||
/* HW Engineer's Notes:
|
||||
* During switch from vga->extended, if we set the VGA_TEST_ENABLE and
|
||||
* then hit the VGA_TEST_RENDER_START, then the DCHUBP timing gets updated correctly.
|
||||
*
|
||||
* Then vBIOS will have it poll for the VGA_TEST_RENDER_DONE and unset
|
||||
* VGA_TEST_ENABLE, to leave it in the same state as before.
|
||||
*/
|
||||
REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_ENABLE, 1);
|
||||
REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
|
||||
}
|
||||
|
||||
static void dpp_pg_control(
|
||||
|
|
@ -1761,6 +1785,11 @@ static void update_dchubp_dpp(
|
|||
&pipe_ctx->plane_res.scl_data.viewport_c);
|
||||
}
|
||||
|
||||
if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
|
||||
dc->hwss.set_cursor_position(pipe_ctx);
|
||||
dc->hwss.set_cursor_attribute(pipe_ctx);
|
||||
}
|
||||
|
||||
if (plane_state->update_flags.bits.full_update) {
|
||||
/*gamut remap*/
|
||||
program_gamut_remap(pipe_ctx);
|
||||
|
|
@ -2296,7 +2325,7 @@ static bool dcn10_dummy_display_power_gating(
|
|||
return true;
|
||||
}
|
||||
|
||||
void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
|
||||
static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
|
|
@ -2316,12 +2345,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
|
||||
static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
|
||||
{
|
||||
if (hws->ctx->dc->res_pool->hubbub != NULL)
|
||||
hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data);
|
||||
}
|
||||
|
||||
static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct dpp *dpp = pipe_ctx->plane_res.dpp;
|
||||
struct dc_cursor_mi_param param = {
|
||||
.pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
|
||||
.ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
|
||||
.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
|
||||
.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
|
||||
.h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
|
||||
};
|
||||
|
||||
if (pipe_ctx->plane_state->address.type
|
||||
== PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
pos_cpy.enable = false;
|
||||
|
||||
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
|
||||
pos_cpy.enable = false;
|
||||
|
||||
hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m);
|
||||
dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width);
|
||||
}
|
||||
|
||||
static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
|
||||
|
||||
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.hubp, attributes);
|
||||
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
|
||||
pipe_ctx->plane_res.dpp, attributes->color_format);
|
||||
}
|
||||
|
||||
static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.program_gamut_remap = program_gamut_remap,
|
||||
.program_csc_matrix = program_csc_matrix,
|
||||
|
|
@ -2362,6 +2425,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
|||
.edp_backlight_control = hwss_edp_backlight_control,
|
||||
.edp_power_control = hwss_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
|
||||
.set_cursor_position = dcn10_set_cursor_position,
|
||||
.set_cursor_attribute = dcn10_set_cursor_attribute
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -123,8 +123,7 @@ struct link_encoder_funcs {
|
|||
void (*enable_tmds_output)(struct link_encoder *enc,
|
||||
enum clock_source_id clock_source,
|
||||
enum dc_color_depth color_depth,
|
||||
bool hdmi,
|
||||
bool dual_link,
|
||||
enum signal_type signal,
|
||||
uint32_t pixel_clock);
|
||||
void (*enable_dp_output)(struct link_encoder *enc,
|
||||
const struct dc_link_settings *link_settings,
|
||||
|
|
|
|||
|
|
@ -198,6 +198,9 @@ struct hw_sequencer_funcs {
|
|||
bool enable);
|
||||
void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);
|
||||
|
||||
void (*set_cursor_position)(struct pipe_ctx *pipe);
|
||||
void (*set_cursor_attribute)(struct pipe_ctx *pipe);
|
||||
|
||||
};
|
||||
|
||||
void color_space_to_black_color(
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ bool dce110_vblank_set(
|
|||
core_dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg;
|
||||
|
||||
if (enable) {
|
||||
if (!tg->funcs->arm_vert_intr(tg, 2)) {
|
||||
if (!tg || !tg->funcs->arm_vert_intr(tg, 2)) {
|
||||
DC_ERROR("Failed to get VBLANK!\n");
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ static void virtual_link_encoder_enable_tmds_output(
|
|||
struct link_encoder *enc,
|
||||
enum clock_source_id clock_source,
|
||||
enum dc_color_depth color_depth,
|
||||
bool hdmi,
|
||||
bool dual_link,
|
||||
enum signal_type signal,
|
||||
uint32_t pixel_clock) {}
|
||||
|
||||
static void virtual_link_encoder_enable_dp_output(
|
||||
|
|
|
|||
|
|
@ -419,11 +419,6 @@ struct bios_event_info {
|
|||
bool backlight_changed;
|
||||
};
|
||||
|
||||
enum {
|
||||
HDMI_PIXEL_CLOCK_IN_KHZ_297 = 297000,
|
||||
TMDS_PIXEL_CLOCK_IN_KHZ_165 = 165000
|
||||
};
|
||||
|
||||
/*
|
||||
* DFS-bypass flag
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@
|
|||
#ifndef __DC_SIGNAL_TYPES_H__
|
||||
#define __DC_SIGNAL_TYPES_H__
|
||||
|
||||
/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
|
||||
#define TMDS_MIN_PIXEL_CLOCK 25000
|
||||
/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
|
||||
#define TMDS_MAX_PIXEL_CLOCK 165000
|
||||
|
||||
enum signal_type {
|
||||
SIGNAL_TYPE_NONE = 0L, /* no signal */
|
||||
SIGNAL_TYPE_DVI_SINGLE_LINK = (1 << 0),
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ static const struct ast_vbios_dclk_info dclk_table[] = {
|
|||
{0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */
|
||||
{0x6A, 0x22, 0x00}, /* 0F: VCLK162 */
|
||||
{0x4d, 0x4c, 0x80}, /* 10: VCLK154 */
|
||||
{0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x28, 0x49, 0x80}, /* 12: VCLK106.5 */
|
||||
{0x37, 0x49, 0x80}, /* 13: VCLK146.25 */
|
||||
{0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */
|
||||
|
|
@ -127,7 +127,7 @@ static const struct ast_vbios_dclk_info dclk_table_ast2500[] = {
|
|||
{0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */
|
||||
{0x6A, 0x22, 0x00}, /* 0F: VCLK162 */
|
||||
{0x4d, 0x4c, 0x80}, /* 10: VCLK154 */
|
||||
{0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x28, 0x49, 0x80}, /* 12: VCLK106.5 */
|
||||
{0x37, 0x49, 0x80}, /* 13: VCLK146.25 */
|
||||
{0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */
|
||||
|
|
|
|||
|
|
@ -461,6 +461,12 @@ int drm_mode_getfb(struct drm_device *dev,
|
|||
if (!fb)
|
||||
return -ENOENT;
|
||||
|
||||
/* Multi-planar framebuffers need getfb2. */
|
||||
if (fb->format->num_planes > 1) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r->height = fb->height;
|
||||
r->width = fb->width;
|
||||
r->depth = fb->format->depth;
|
||||
|
|
@ -484,6 +490,7 @@ int drm_mode_getfb(struct drm_device *dev,
|
|||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
out:
|
||||
drm_framebuffer_put(fb);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -471,6 +471,7 @@ struct parser_exec_state {
|
|||
* used when ret from 2nd level batch buffer
|
||||
*/
|
||||
int saved_buf_addr_type;
|
||||
bool is_ctx_wa;
|
||||
|
||||
struct cmd_info *info;
|
||||
|
||||
|
|
@ -1715,6 +1716,11 @@ static int perform_bb_shadow(struct parser_exec_state *s)
|
|||
bb->accessing = true;
|
||||
bb->bb_start_cmd_va = s->ip_va;
|
||||
|
||||
if ((s->buf_type == BATCH_BUFFER_INSTRUCTION) && (!s->is_ctx_wa))
|
||||
bb->bb_offset = s->ip_va - s->rb_va;
|
||||
else
|
||||
bb->bb_offset = 0;
|
||||
|
||||
/*
|
||||
* ip_va saves the virtual address of the shadow batch buffer, while
|
||||
* ip_gma saves the graphics address of the original batch buffer.
|
||||
|
|
@ -2571,6 +2577,7 @@ static int scan_workload(struct intel_vgpu_workload *workload)
|
|||
s.ring_tail = gma_tail;
|
||||
s.rb_va = workload->shadow_ring_buffer_va;
|
||||
s.workload = workload;
|
||||
s.is_ctx_wa = false;
|
||||
|
||||
if ((bypass_scan_mask & (1 << workload->ring_id)) ||
|
||||
gma_head == gma_tail)
|
||||
|
|
@ -2624,6 +2631,7 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
|
|||
s.ring_tail = gma_tail;
|
||||
s.rb_va = wa_ctx->indirect_ctx.shadow_va;
|
||||
s.workload = workload;
|
||||
s.is_ctx_wa = true;
|
||||
|
||||
if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
|
||||
ret = -EINVAL;
|
||||
|
|
|
|||
|
|
@ -394,9 +394,11 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre,
|
|||
* performace for batch mmio read/write, so we need
|
||||
* handle forcewake mannually.
|
||||
*/
|
||||
intel_runtime_pm_get(dev_priv);
|
||||
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
|
||||
switch_mmio(pre, next, ring_id);
|
||||
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -52,6 +52,54 @@ static void set_context_pdp_root_pointer(
|
|||
pdp_pair[i].val = pdp[7 - i];
|
||||
}
|
||||
|
||||
/*
|
||||
* when populating shadow ctx from guest, we should not overrride oa related
|
||||
* registers, so that they will not be overlapped by guest oa configs. Thus
|
||||
* made it possible to capture oa data from host for both host and guests.
|
||||
*/
|
||||
static void sr_oa_regs(struct intel_vgpu_workload *workload,
|
||||
u32 *reg_state, bool save)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
|
||||
u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset;
|
||||
u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset;
|
||||
int i = 0;
|
||||
u32 flex_mmio[] = {
|
||||
i915_mmio_reg_offset(EU_PERF_CNTL0),
|
||||
i915_mmio_reg_offset(EU_PERF_CNTL1),
|
||||
i915_mmio_reg_offset(EU_PERF_CNTL2),
|
||||
i915_mmio_reg_offset(EU_PERF_CNTL3),
|
||||
i915_mmio_reg_offset(EU_PERF_CNTL4),
|
||||
i915_mmio_reg_offset(EU_PERF_CNTL5),
|
||||
i915_mmio_reg_offset(EU_PERF_CNTL6),
|
||||
};
|
||||
|
||||
if (!workload || !reg_state || workload->ring_id != RCS)
|
||||
return;
|
||||
|
||||
if (save) {
|
||||
workload->oactxctrl = reg_state[ctx_oactxctrl + 1];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(workload->flex_mmio); i++) {
|
||||
u32 state_offset = ctx_flexeu0 + i * 2;
|
||||
|
||||
workload->flex_mmio[i] = reg_state[state_offset + 1];
|
||||
}
|
||||
} else {
|
||||
reg_state[ctx_oactxctrl] =
|
||||
i915_mmio_reg_offset(GEN8_OACTXCONTROL);
|
||||
reg_state[ctx_oactxctrl + 1] = workload->oactxctrl;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(workload->flex_mmio); i++) {
|
||||
u32 state_offset = ctx_flexeu0 + i * 2;
|
||||
u32 mmio = flex_mmio[i];
|
||||
|
||||
reg_state[state_offset] = mmio;
|
||||
reg_state[state_offset + 1] = workload->flex_mmio[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int populate_shadow_context(struct intel_vgpu_workload *workload)
|
||||
{
|
||||
struct intel_vgpu *vgpu = workload->vgpu;
|
||||
|
|
@ -98,6 +146,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
|
|||
page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
|
||||
shadow_ring_context = kmap(page);
|
||||
|
||||
sr_oa_regs(workload, (u32 *)shadow_ring_context, true);
|
||||
#define COPY_REG(name) \
|
||||
intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \
|
||||
+ RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4)
|
||||
|
|
@ -122,6 +171,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
|
|||
sizeof(*shadow_ring_context),
|
||||
I915_GTT_PAGE_SIZE - sizeof(*shadow_ring_context));
|
||||
|
||||
sr_oa_regs(workload, (u32 *)shadow_ring_context, false);
|
||||
kunmap(page);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -376,6 +426,17 @@ static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/* For privilge batch buffer and not wa_ctx, the bb_start_cmd_va
|
||||
* is only updated into ring_scan_buffer, not real ring address
|
||||
* allocated in later copy_workload_to_ring_buffer. pls be noted
|
||||
* shadow_ring_buffer_va is now pointed to real ring buffer va
|
||||
* in copy_workload_to_ring_buffer.
|
||||
*/
|
||||
|
||||
if (bb->bb_offset)
|
||||
bb->bb_start_cmd_va = workload->shadow_ring_buffer_va
|
||||
+ bb->bb_offset;
|
||||
|
||||
/* relocate shadow batch buffer */
|
||||
bb->bb_start_cmd_va[1] = i915_ggtt_offset(bb->vma);
|
||||
if (gmadr_bytes == 8)
|
||||
|
|
@ -1044,10 +1105,12 @@ int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
|
|||
|
||||
bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES);
|
||||
|
||||
s->workloads = kmem_cache_create("gvt-g_vgpu_workload",
|
||||
sizeof(struct intel_vgpu_workload), 0,
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
NULL);
|
||||
s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload",
|
||||
sizeof(struct intel_vgpu_workload), 0,
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
offsetof(struct intel_vgpu_workload, rb_tail),
|
||||
sizeof_field(struct intel_vgpu_workload, rb_tail),
|
||||
NULL);
|
||||
|
||||
if (!s->workloads) {
|
||||
ret = -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -110,6 +110,10 @@ struct intel_vgpu_workload {
|
|||
/* shadow batch buffer */
|
||||
struct list_head shadow_bb;
|
||||
struct intel_shadow_wa_ctx wa_ctx;
|
||||
|
||||
/* oa registers */
|
||||
u32 oactxctrl;
|
||||
u32 flex_mmio[7];
|
||||
};
|
||||
|
||||
struct intel_vgpu_shadow_bb {
|
||||
|
|
@ -120,6 +124,7 @@ struct intel_vgpu_shadow_bb {
|
|||
u32 *bb_start_cmd_va;
|
||||
unsigned int clflush;
|
||||
bool accessing;
|
||||
unsigned long bb_offset;
|
||||
};
|
||||
|
||||
#define workload_q_head(vgpu, ring_id) \
|
||||
|
|
|
|||
|
|
@ -434,20 +434,28 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
|
|||
dma_fence_put(shared[i]);
|
||||
kfree(shared);
|
||||
|
||||
/*
|
||||
* If both shared fences and an exclusive fence exist,
|
||||
* then by construction the shared fences must be later
|
||||
* than the exclusive fence. If we successfully wait for
|
||||
* all the shared fences, we know that the exclusive fence
|
||||
* must all be signaled. If all the shared fences are
|
||||
* signaled, we can prune the array and recover the
|
||||
* floating references on the fences/requests.
|
||||
*/
|
||||
prune_fences = count && timeout >= 0;
|
||||
} else {
|
||||
excl = reservation_object_get_excl_rcu(resv);
|
||||
}
|
||||
|
||||
if (excl && timeout >= 0) {
|
||||
if (excl && timeout >= 0)
|
||||
timeout = i915_gem_object_wait_fence(excl, flags, timeout,
|
||||
rps_client);
|
||||
prune_fences = timeout >= 0;
|
||||
}
|
||||
|
||||
dma_fence_put(excl);
|
||||
|
||||
/* Oportunistically prune the fences iff we know they have *all* been
|
||||
/*
|
||||
* Opportunistically prune the fences iff we know they have *all* been
|
||||
* signaled and that the reservation object has not been changed (i.e.
|
||||
* no new fences have been added).
|
||||
*/
|
||||
|
|
@ -3205,8 +3213,10 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
|
|||
* rolling the global seqno forward (since this would complete requests
|
||||
* for which we haven't set the fence error to EIO yet).
|
||||
*/
|
||||
for_each_engine(engine, i915, id)
|
||||
for_each_engine(engine, i915, id) {
|
||||
i915_gem_reset_prepare_engine(engine);
|
||||
engine->submit_request = nop_submit_request;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure no one is running the old callback before we proceed with
|
||||
|
|
@ -3244,6 +3254,8 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
|
|||
intel_engine_init_global_seqno(engine,
|
||||
intel_engine_last_submit(engine));
|
||||
spin_unlock_irqrestore(&engine->timeline->lock, flags);
|
||||
|
||||
i915_gem_reset_finish_engine(engine);
|
||||
}
|
||||
|
||||
set_bit(I915_WEDGED, &i915->gpu_error.flags);
|
||||
|
|
|
|||
|
|
@ -1303,9 +1303,8 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
|
|||
*/
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
dev_priv->perf.oa.exclusive_stream = NULL;
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
free_oa_buffer(dev_priv);
|
||||
|
||||
|
|
@ -1756,22 +1755,13 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
|
|||
* Note: it's only the RCS/Render context that has any OA state.
|
||||
*/
|
||||
static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
|
||||
const struct i915_oa_config *oa_config,
|
||||
bool interruptible)
|
||||
const struct i915_oa_config *oa_config)
|
||||
{
|
||||
struct i915_gem_context *ctx;
|
||||
int ret;
|
||||
unsigned int wait_flags = I915_WAIT_LOCKED;
|
||||
|
||||
if (interruptible) {
|
||||
ret = i915_mutex_lock_interruptible(&dev_priv->drm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wait_flags |= I915_WAIT_INTERRUPTIBLE;
|
||||
} else {
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
}
|
||||
lockdep_assert_held(&dev_priv->drm.struct_mutex);
|
||||
|
||||
/* Switch away from any user context. */
|
||||
ret = gen8_switch_to_updated_kernel_context(dev_priv, oa_config);
|
||||
|
|
@ -1819,8 +1809,6 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
|
|||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1863,7 +1851,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
|
|||
* to make sure all slices/subslices are ON before writing to NOA
|
||||
* registers.
|
||||
*/
|
||||
ret = gen8_configure_all_contexts(dev_priv, oa_config, true);
|
||||
ret = gen8_configure_all_contexts(dev_priv, oa_config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1878,7 +1866,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
|
|||
static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
/* Reset all contexts' slices/subslices configurations. */
|
||||
gen8_configure_all_contexts(dev_priv, NULL, false);
|
||||
gen8_configure_all_contexts(dev_priv, NULL);
|
||||
|
||||
I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
|
||||
~GT_NOA_ENABLE));
|
||||
|
|
@ -1888,7 +1876,7 @@ static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
|
|||
static void gen10_disable_metric_set(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
/* Reset all contexts' slices/subslices configurations. */
|
||||
gen8_configure_all_contexts(dev_priv, NULL, false);
|
||||
gen8_configure_all_contexts(dev_priv, NULL);
|
||||
|
||||
/* Make sure we disable noa to save power. */
|
||||
I915_WRITE(RPM_CONFIG1,
|
||||
|
|
@ -2138,6 +2126,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
|
|||
if (ret)
|
||||
goto err_oa_buf_alloc;
|
||||
|
||||
ret = i915_mutex_lock_interruptible(&dev_priv->drm);
|
||||
if (ret)
|
||||
goto err_lock;
|
||||
|
||||
ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv,
|
||||
stream->oa_config);
|
||||
if (ret)
|
||||
|
|
@ -2145,23 +2137,17 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
|
|||
|
||||
stream->ops = &i915_oa_stream_ops;
|
||||
|
||||
/* Lock device for exclusive_stream access late because
|
||||
* enable_metric_set() might lock as well on gen8+.
|
||||
*/
|
||||
ret = i915_mutex_lock_interruptible(&dev_priv->drm);
|
||||
if (ret)
|
||||
goto err_lock;
|
||||
|
||||
dev_priv->perf.oa.exclusive_stream = stream;
|
||||
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
err_lock:
|
||||
dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
|
||||
|
||||
err_enable:
|
||||
dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
err_lock:
|
||||
free_oa_buffer(dev_priv);
|
||||
|
||||
err_oa_buf_alloc:
|
||||
|
|
|
|||
|
|
@ -304,8 +304,9 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
|
|||
{
|
||||
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
|
||||
struct intel_rps *rps = &dev_priv->gt_pm.rps;
|
||||
u32 val;
|
||||
bool boost = false;
|
||||
ssize_t ret;
|
||||
u32 val;
|
||||
|
||||
ret = kstrtou32(buf, 0, &val);
|
||||
if (ret)
|
||||
|
|
@ -317,8 +318,13 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&dev_priv->pcu_lock);
|
||||
rps->boost_freq = val;
|
||||
if (val != rps->boost_freq) {
|
||||
rps->boost_freq = val;
|
||||
boost = atomic_read(&rps->num_waiters);
|
||||
}
|
||||
mutex_unlock(&dev_priv->pcu_lock);
|
||||
if (boost)
|
||||
schedule_work(&rps->work);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2175,8 +2175,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
|
|||
intel_prepare_dp_ddi_buffers(encoder, crtc_state);
|
||||
|
||||
intel_ddi_init_dp_buf_reg(encoder);
|
||||
if (!is_mst)
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
|
||||
intel_dp_start_link_train(intel_dp);
|
||||
if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
|
||||
intel_dp_stop_link_train(intel_dp);
|
||||
|
|
@ -2274,14 +2273,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
|
|||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
|
||||
struct intel_dp *intel_dp = &dig_port->dp;
|
||||
bool is_mst = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST);
|
||||
|
||||
/*
|
||||
* Power down sink before disabling the port, otherwise we end
|
||||
* up getting interrupts from the sink on detecting link loss.
|
||||
*/
|
||||
if (!is_mst)
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
|
||||
|
||||
intel_disable_ddi_buf(encoder);
|
||||
|
||||
|
|
|
|||
|
|
@ -620,19 +620,15 @@ static int
|
|||
bxt_power_sequencer_idx(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
|
||||
int backlight_controller = dev_priv->vbt.backlight.controller;
|
||||
|
||||
lockdep_assert_held(&dev_priv->pps_mutex);
|
||||
|
||||
/* We should never land here with regular DP ports */
|
||||
WARN_ON(!intel_dp_is_edp(intel_dp));
|
||||
|
||||
/*
|
||||
* TODO: BXT has 2 PPS instances. The correct port->PPS instance
|
||||
* mapping needs to be retrieved from VBT, for now just hard-code to
|
||||
* use instance #0 always.
|
||||
*/
|
||||
if (!intel_dp->pps_reset)
|
||||
return 0;
|
||||
return backlight_controller;
|
||||
|
||||
intel_dp->pps_reset = false;
|
||||
|
||||
|
|
@ -642,7 +638,7 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp)
|
|||
*/
|
||||
intel_dp_init_panel_power_sequencer_registers(intel_dp, false);
|
||||
|
||||
return 0;
|
||||
return backlight_controller;
|
||||
}
|
||||
|
||||
typedef bool (*vlv_pipe_check)(struct drm_i915_private *dev_priv,
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
|
|||
*/
|
||||
tmp = I915_READ_CTL(engine);
|
||||
if (tmp & RING_WAIT) {
|
||||
i915_handle_error(dev_priv, 0,
|
||||
i915_handle_error(dev_priv, BIT(engine->id),
|
||||
"Kicking stuck wait on %s",
|
||||
engine->name);
|
||||
I915_WRITE_CTL(engine, tmp);
|
||||
|
|
@ -258,7 +258,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
|
|||
default:
|
||||
return ENGINE_DEAD;
|
||||
case 1:
|
||||
i915_handle_error(dev_priv, 0,
|
||||
i915_handle_error(dev_priv, ALL_ENGINES,
|
||||
"Kicking stuck semaphore on %s",
|
||||
engine->name);
|
||||
I915_WRITE_CTL(engine, tmp);
|
||||
|
|
|
|||
|
|
@ -719,6 +719,8 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
|
|||
struct rb_node *rb;
|
||||
unsigned long flags;
|
||||
|
||||
GEM_TRACE("%s\n", engine->name);
|
||||
|
||||
spin_lock_irqsave(&engine->timeline->lock, flags);
|
||||
|
||||
/* Cancel the requests on the HW and clear the ELSP tracker. */
|
||||
|
|
@ -765,6 +767,9 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
|
|||
*/
|
||||
clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
|
||||
|
||||
/* Mark all CS interrupts as complete */
|
||||
execlists->active = 0;
|
||||
|
||||
spin_unlock_irqrestore(&engine->timeline->lock, flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,7 +225,11 @@ static void ipu_crtc_atomic_begin(struct drm_crtc *crtc,
|
|||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
static void ipu_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
spin_lock_irq(&crtc->dev->event_lock);
|
||||
if (crtc->state->event) {
|
||||
WARN_ON(drm_crtc_vblank_get(crtc));
|
||||
|
|
@ -293,6 +297,7 @@ static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
|
|||
.mode_set_nofb = ipu_crtc_mode_set_nofb,
|
||||
.atomic_check = ipu_crtc_atomic_check,
|
||||
.atomic_begin = ipu_crtc_atomic_begin,
|
||||
.atomic_flush = ipu_crtc_atomic_flush,
|
||||
.atomic_disable = ipu_crtc_atomic_disable,
|
||||
.atomic_enable = ipu_crtc_atomic_enable,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <drm/drm_plane_helper.h>
|
||||
|
||||
#include "video/imx-ipu-v3.h"
|
||||
#include "imx-drm.h"
|
||||
#include "ipuv3-plane.h"
|
||||
|
||||
struct ipu_plane_state {
|
||||
|
|
@ -272,7 +273,7 @@ static void ipu_plane_destroy(struct drm_plane *plane)
|
|||
kfree(ipu_plane);
|
||||
}
|
||||
|
||||
void ipu_plane_state_reset(struct drm_plane *plane)
|
||||
static void ipu_plane_state_reset(struct drm_plane *plane)
|
||||
{
|
||||
struct ipu_plane_state *ipu_state;
|
||||
|
||||
|
|
@ -292,7 +293,8 @@ void ipu_plane_state_reset(struct drm_plane *plane)
|
|||
plane->state = &ipu_state->base;
|
||||
}
|
||||
|
||||
struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane)
|
||||
static struct drm_plane_state *
|
||||
ipu_plane_duplicate_state(struct drm_plane *plane)
|
||||
{
|
||||
struct ipu_plane_state *state;
|
||||
|
||||
|
|
@ -306,8 +308,8 @@ struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane)
|
|||
return &state->base;
|
||||
}
|
||||
|
||||
void ipu_plane_destroy_state(struct drm_plane *plane,
|
||||
struct drm_plane_state *state)
|
||||
static void ipu_plane_destroy_state(struct drm_plane *plane,
|
||||
struct drm_plane_state *state)
|
||||
{
|
||||
struct ipu_plane_state *ipu_state = to_ipu_plane_state(state);
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ nv50_get_intensity(struct backlight_device *bd)
|
|||
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
|
||||
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
|
||||
struct nvif_object *device = &drm->client.device.object;
|
||||
int or = nv_encoder->or;
|
||||
int or = ffs(nv_encoder->dcb->or) - 1;
|
||||
u32 div = 1025;
|
||||
u32 val;
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ nv50_set_intensity(struct backlight_device *bd)
|
|||
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
|
||||
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
|
||||
struct nvif_object *device = &drm->client.device.object;
|
||||
int or = nv_encoder->or;
|
||||
int or = ffs(nv_encoder->dcb->or) - 1;
|
||||
u32 div = 1025;
|
||||
u32 val = (bd->props.brightness * div) / 100;
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ nva3_get_intensity(struct backlight_device *bd)
|
|||
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
|
||||
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
|
||||
struct nvif_object *device = &drm->client.device.object;
|
||||
int or = nv_encoder->or;
|
||||
int or = ffs(nv_encoder->dcb->or) - 1;
|
||||
u32 div, val;
|
||||
|
||||
div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
|
||||
|
|
@ -188,7 +188,7 @@ nva3_set_intensity(struct backlight_device *bd)
|
|||
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
|
||||
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
|
||||
struct nvif_object *device = &drm->client.device.object;
|
||||
int or = nv_encoder->or;
|
||||
int or = ffs(nv_encoder->dcb->or) - 1;
|
||||
u32 div, val;
|
||||
|
||||
div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
|
||||
|
|
@ -228,7 +228,7 @@ nv50_backlight_init(struct drm_connector *connector)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or)))
|
||||
if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1)))
|
||||
return 0;
|
||||
|
||||
if (drm->client.device.info.chipset <= 0xa0 ||
|
||||
|
|
@ -268,13 +268,13 @@ nouveau_backlight_init(struct drm_device *dev)
|
|||
struct nvif_device *device = &drm->client.device;
|
||||
struct drm_connector *connector;
|
||||
|
||||
INIT_LIST_HEAD(&drm->bl_connectors);
|
||||
|
||||
if (apple_gmux_present()) {
|
||||
NV_INFO(drm, "Apple GMUX detected: not registering Nouveau backlight interface\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&drm->bl_connectors);
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
|
||||
connector->connector_type != DRM_MODE_CONNECTOR_eDP)
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,7 @@ nvkm_vmm_get_locked(struct nvkm_vmm *vmm, bool getref, bool mapref, bool sparse,
|
|||
|
||||
tail = this->addr + this->size;
|
||||
if (vmm->func->page_block && next && next->page != p)
|
||||
tail = ALIGN_DOWN(addr, vmm->func->page_block);
|
||||
tail = ALIGN_DOWN(tail, vmm->func->page_block);
|
||||
|
||||
if (addr <= tail && tail - addr >= size) {
|
||||
rb_erase(&this->tree, &vmm->free);
|
||||
|
|
|
|||
|
|
@ -3221,35 +3221,8 @@ static void cik_gpu_init(struct radeon_device *rdev)
|
|||
case CHIP_KAVERI:
|
||||
rdev->config.cik.max_shader_engines = 1;
|
||||
rdev->config.cik.max_tile_pipes = 4;
|
||||
if ((rdev->pdev->device == 0x1304) ||
|
||||
(rdev->pdev->device == 0x1305) ||
|
||||
(rdev->pdev->device == 0x130C) ||
|
||||
(rdev->pdev->device == 0x130F) ||
|
||||
(rdev->pdev->device == 0x1310) ||
|
||||
(rdev->pdev->device == 0x1311) ||
|
||||
(rdev->pdev->device == 0x131C)) {
|
||||
rdev->config.cik.max_cu_per_sh = 8;
|
||||
rdev->config.cik.max_backends_per_se = 2;
|
||||
} else if ((rdev->pdev->device == 0x1309) ||
|
||||
(rdev->pdev->device == 0x130A) ||
|
||||
(rdev->pdev->device == 0x130D) ||
|
||||
(rdev->pdev->device == 0x1313) ||
|
||||
(rdev->pdev->device == 0x131D)) {
|
||||
rdev->config.cik.max_cu_per_sh = 6;
|
||||
rdev->config.cik.max_backends_per_se = 2;
|
||||
} else if ((rdev->pdev->device == 0x1306) ||
|
||||
(rdev->pdev->device == 0x1307) ||
|
||||
(rdev->pdev->device == 0x130B) ||
|
||||
(rdev->pdev->device == 0x130E) ||
|
||||
(rdev->pdev->device == 0x1315) ||
|
||||
(rdev->pdev->device == 0x1318) ||
|
||||
(rdev->pdev->device == 0x131B)) {
|
||||
rdev->config.cik.max_cu_per_sh = 4;
|
||||
rdev->config.cik.max_backends_per_se = 1;
|
||||
} else {
|
||||
rdev->config.cik.max_cu_per_sh = 3;
|
||||
rdev->config.cik.max_backends_per_se = 1;
|
||||
}
|
||||
rdev->config.cik.max_cu_per_sh = 8;
|
||||
rdev->config.cik.max_backends_per_se = 2;
|
||||
rdev->config.cik.max_sh_per_se = 1;
|
||||
rdev->config.cik.max_texture_channel_caches = 4;
|
||||
rdev->config.cik.max_gprs = 256;
|
||||
|
|
|
|||
|
|
@ -90,25 +90,18 @@ void radeon_connector_hotplug(struct drm_connector *connector)
|
|||
/* don't do anything if sink is not display port, i.e.,
|
||||
* passive dp->(dvi|hdmi) adaptor
|
||||
*/
|
||||
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
|
||||
int saved_dpms = connector->dpms;
|
||||
/* Only turn off the display if it's physically disconnected */
|
||||
if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
} else if (radeon_dp_needs_link_train(radeon_connector)) {
|
||||
/* Don't try to start link training before we
|
||||
* have the dpcd */
|
||||
if (!radeon_dp_getdpcd(radeon_connector))
|
||||
return;
|
||||
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&
|
||||
radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
|
||||
radeon_dp_needs_link_train(radeon_connector)) {
|
||||
/* Don't start link training before we have the DPCD */
|
||||
if (!radeon_dp_getdpcd(radeon_connector))
|
||||
return;
|
||||
|
||||
/* set it to OFF so that drm_helper_connector_dpms()
|
||||
* won't return immediately since the current state
|
||||
* is ON at this point.
|
||||
*/
|
||||
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
connector->dpms = saved_dpms;
|
||||
/* Turn the connector off and back on immediately, which
|
||||
* will trigger link training
|
||||
*/
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ void radeon_gem_object_free(struct drm_gem_object *gobj)
|
|||
struct radeon_bo *robj = gem_to_radeon_bo(gobj);
|
||||
|
||||
if (robj) {
|
||||
if (robj->gem_base.import_attach)
|
||||
drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
|
||||
radeon_mn_unregister(robj);
|
||||
radeon_bo_unref(&robj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
|
|||
mutex_unlock(&bo->rdev->gem.mutex);
|
||||
radeon_bo_clear_surface_reg(bo);
|
||||
WARN_ON_ONCE(!list_empty(&bo->va));
|
||||
if (bo->gem_base.import_attach)
|
||||
drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg);
|
||||
drm_gem_object_release(&bo->gem_base);
|
||||
kfree(bo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||
|
||||
DRM_DEBUG_DRIVER("Disabling the CRTC\n");
|
||||
|
||||
drm_crtc_vblank_off(crtc);
|
||||
|
||||
sun4i_tcon_set_status(scrtc->tcon, encoder, false);
|
||||
|
||||
if (crtc->state->event && !crtc->state->active) {
|
||||
|
|
@ -113,6 +115,8 @@ static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||
DRM_DEBUG_DRIVER("Enabling the CRTC\n");
|
||||
|
||||
sun4i_tcon_set_status(scrtc->tcon, encoder, true);
|
||||
|
||||
drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
||||
|
|
|
|||
|
|
@ -132,10 +132,13 @@ static int sun4i_dclk_get_phase(struct clk_hw *hw)
|
|||
static int sun4i_dclk_set_phase(struct clk_hw *hw, int degrees)
|
||||
{
|
||||
struct sun4i_dclk *dclk = hw_to_dclk(hw);
|
||||
u32 val = degrees / 120;
|
||||
|
||||
val <<= 28;
|
||||
|
||||
regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG,
|
||||
GENMASK(29, 28),
|
||||
degrees / 120);
|
||||
val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ static int sun4i_drv_bind(struct device *dev)
|
|||
/* drm_vblank_init calls kcalloc, which can fail */
|
||||
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
|
||||
if (ret)
|
||||
goto free_mem_region;
|
||||
goto cleanup_mode_config;
|
||||
|
||||
drm->irq_enabled = true;
|
||||
|
||||
|
|
@ -139,7 +139,6 @@ finish_poll:
|
|||
sun4i_framebuffer_free(drm);
|
||||
cleanup_mode_config:
|
||||
drm_mode_config_cleanup(drm);
|
||||
free_mem_region:
|
||||
of_reserved_mem_device_release(dev);
|
||||
free_drm:
|
||||
drm_dev_unref(drm);
|
||||
|
|
|
|||
|
|
@ -538,7 +538,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
|
|||
&sun4i_hdmi_regmap_config);
|
||||
if (IS_ERR(hdmi->regmap)) {
|
||||
dev_err(dev, "Couldn't create HDMI encoder regmap\n");
|
||||
return PTR_ERR(hdmi->regmap);
|
||||
ret = PTR_ERR(hdmi->regmap);
|
||||
goto err_disable_mod_clk;
|
||||
}
|
||||
|
||||
ret = sun4i_tmds_create(hdmi);
|
||||
|
|
@ -551,7 +552,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
|
|||
hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc");
|
||||
if (IS_ERR(hdmi->ddc_parent_clk)) {
|
||||
dev_err(dev, "Couldn't get the HDMI DDC clock\n");
|
||||
return PTR_ERR(hdmi->ddc_parent_clk);
|
||||
ret = PTR_ERR(hdmi->ddc_parent_clk);
|
||||
goto err_disable_mod_clk;
|
||||
}
|
||||
} else {
|
||||
hdmi->ddc_parent_clk = hdmi->tmds_clk;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,
|
|||
|
||||
DRM_DEBUG_DRIVER("Vertical parameters OK\n");
|
||||
|
||||
tcon->dclk_min_div = 6;
|
||||
tcon->dclk_max_div = 127;
|
||||
rounded_rate = clk_round_rate(tcon->dclk, rate);
|
||||
if (rounded_rate < rate)
|
||||
return MODE_CLOCK_LOW;
|
||||
|
|
|
|||
|
|
@ -101,10 +101,13 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
|
|||
return;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
if (enabled) {
|
||||
clk_prepare_enable(clk);
|
||||
else
|
||||
clk_rate_exclusive_get(clk);
|
||||
} else {
|
||||
clk_rate_exclusive_put(clk);
|
||||
clk_disable_unprepare(clk);
|
||||
}
|
||||
}
|
||||
|
||||
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
|
||||
|
|
@ -260,7 +263,7 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
|
|||
const struct drm_display_mode *mode)
|
||||
{
|
||||
/* Configure the dot clock */
|
||||
clk_set_rate_exclusive(tcon->dclk, mode->crtc_clock * 1000);
|
||||
clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
|
||||
|
||||
/* Set the resolution */
|
||||
regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
|
||||
|
|
@ -421,7 +424,7 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
|
|||
WARN_ON(!tcon->quirks->has_channel_1);
|
||||
|
||||
/* Configure the dot clock */
|
||||
clk_set_rate_exclusive(tcon->sclk1, mode->crtc_clock * 1000);
|
||||
clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
|
||||
|
||||
/* Adjust clock delay */
|
||||
clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
|
||||
|
|
@ -873,52 +876,56 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This can only be made optional since we've had DT nodes
|
||||
* without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and print a
|
||||
* warning.
|
||||
*/
|
||||
tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
|
||||
if (IS_ERR(tcon->lvds_rst)) {
|
||||
dev_err(dev, "Couldn't get our reset line\n");
|
||||
return PTR_ERR(tcon->lvds_rst);
|
||||
} else if (tcon->lvds_rst) {
|
||||
has_lvds_rst = true;
|
||||
reset_control_reset(tcon->lvds_rst);
|
||||
} else {
|
||||
has_lvds_rst = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This can only be made optional since we've had DT nodes
|
||||
* without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and print a
|
||||
* warning.
|
||||
*/
|
||||
if (tcon->quirks->has_lvds_alt) {
|
||||
tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
|
||||
if (IS_ERR(tcon->lvds_pll)) {
|
||||
if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
|
||||
has_lvds_alt = false;
|
||||
} else {
|
||||
dev_err(dev, "Couldn't get the LVDS PLL\n");
|
||||
return PTR_ERR(tcon->lvds_pll);
|
||||
}
|
||||
if (tcon->quirks->supports_lvds) {
|
||||
/*
|
||||
* This can only be made optional since we've had DT
|
||||
* nodes without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and
|
||||
* print a warning.
|
||||
*/
|
||||
tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
|
||||
if (IS_ERR(tcon->lvds_rst)) {
|
||||
dev_err(dev, "Couldn't get our reset line\n");
|
||||
return PTR_ERR(tcon->lvds_rst);
|
||||
} else if (tcon->lvds_rst) {
|
||||
has_lvds_rst = true;
|
||||
reset_control_reset(tcon->lvds_rst);
|
||||
} else {
|
||||
has_lvds_alt = true;
|
||||
has_lvds_rst = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_lvds_rst || (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
|
||||
dev_warn(dev,
|
||||
"Missing LVDS properties, Please upgrade your DT\n");
|
||||
dev_warn(dev, "LVDS output disabled\n");
|
||||
can_lvds = false;
|
||||
/*
|
||||
* This can only be made optional since we've had DT
|
||||
* nodes without the LVDS reset properties.
|
||||
*
|
||||
* If the property is missing, just disable LVDS, and
|
||||
* print a warning.
|
||||
*/
|
||||
if (tcon->quirks->has_lvds_alt) {
|
||||
tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
|
||||
if (IS_ERR(tcon->lvds_pll)) {
|
||||
if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
|
||||
has_lvds_alt = false;
|
||||
} else {
|
||||
dev_err(dev, "Couldn't get the LVDS PLL\n");
|
||||
return PTR_ERR(tcon->lvds_pll);
|
||||
}
|
||||
} else {
|
||||
has_lvds_alt = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_lvds_rst ||
|
||||
(tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
|
||||
dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
|
||||
dev_warn(dev, "LVDS output disabled\n");
|
||||
can_lvds = false;
|
||||
} else {
|
||||
can_lvds = true;
|
||||
}
|
||||
} else {
|
||||
can_lvds = true;
|
||||
can_lvds = false;
|
||||
}
|
||||
|
||||
ret = sun4i_tcon_init_clocks(dev, tcon);
|
||||
|
|
@ -1137,7 +1144,7 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
|
|||
};
|
||||
|
||||
static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
|
||||
/* nothing is supported */
|
||||
.supports_lvds = true,
|
||||
};
|
||||
|
||||
static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ struct sun4i_tcon_quirks {
|
|||
bool has_channel_1; /* a33 does not have channel 1 */
|
||||
bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */
|
||||
bool needs_de_be_mux; /* sun6i needs mux to select backend */
|
||||
bool supports_lvds; /* Does the TCON support an LVDS output? */
|
||||
|
||||
/* callback to handle tcon muxing options */
|
||||
int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
|
||||
|
|
|
|||
|
|
@ -1903,8 +1903,12 @@ cleanup:
|
|||
if (!IS_ERR(primary))
|
||||
drm_plane_cleanup(primary);
|
||||
|
||||
if (group && tegra->domain) {
|
||||
iommu_detach_group(tegra->domain, group);
|
||||
if (group && dc->domain) {
|
||||
if (group == tegra->group) {
|
||||
iommu_detach_group(dc->domain, group);
|
||||
tegra->group = NULL;
|
||||
}
|
||||
|
||||
dc->domain = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1913,8 +1917,10 @@ cleanup:
|
|||
|
||||
static int tegra_dc_exit(struct host1x_client *client)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(client->parent);
|
||||
struct iommu_group *group = iommu_group_get(client->dev);
|
||||
struct tegra_dc *dc = host1x_client_to_dc(client);
|
||||
struct tegra_drm *tegra = drm->dev_private;
|
||||
int err;
|
||||
|
||||
devm_free_irq(dc->dev, dc->irq, dc);
|
||||
|
|
@ -1926,7 +1932,11 @@ static int tegra_dc_exit(struct host1x_client *client)
|
|||
}
|
||||
|
||||
if (group && dc->domain) {
|
||||
iommu_detach_group(dc->domain, group);
|
||||
if (group == tegra->group) {
|
||||
iommu_detach_group(dc->domain, group);
|
||||
tegra->group = NULL;
|
||||
}
|
||||
|
||||
dc->domain = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ static void tegra_drm_unload(struct drm_device *drm)
|
|||
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
tegra_drm_fb_exit(drm);
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
drm_mode_config_cleanup(drm);
|
||||
|
||||
err = host1x_device_exit(device);
|
||||
|
|
|
|||
|
|
@ -1072,7 +1072,6 @@ static int tegra_dsi_exit(struct host1x_client *client)
|
|||
struct tegra_dsi *dsi = host1x_client_to_dsi(client);
|
||||
|
||||
tegra_output_exit(&dsi->output);
|
||||
regulator_disable(dsi->vdd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,6 +297,10 @@ int tegra_plane_format_get_alpha(unsigned int opaque, unsigned int *alpha)
|
|||
case WIN_COLOR_DEPTH_B8G8R8X8:
|
||||
*alpha = WIN_COLOR_DEPTH_B8G8R8A8;
|
||||
return 0;
|
||||
|
||||
case WIN_COLOR_DEPTH_B5G6R5:
|
||||
*alpha = opaque;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
|
@ -330,9 +334,6 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra,
|
|||
unsigned int zpos[2];
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
state->dependent[i] = false;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
zpos[i] = 0;
|
||||
|
||||
|
|
@ -346,6 +347,8 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra,
|
|||
|
||||
index = tegra_plane_get_overlap_index(tegra, p);
|
||||
|
||||
state->dependent[index] = false;
|
||||
|
||||
/*
|
||||
* If any of the other planes is on top of this plane and uses
|
||||
* a format with an alpha component, mark this plane as being
|
||||
|
|
|
|||
|
|
@ -159,10 +159,15 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
|||
{
|
||||
unsigned long start = vma->vm_start;
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long offset;
|
||||
unsigned long page, pos;
|
||||
|
||||
if (offset + size > info->fix.smem_len)
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
|
||||
offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
|
||||
if (offset > info->fix.smem_len || size > info->fix.smem_len - offset)
|
||||
return -EINVAL;
|
||||
|
||||
pos = (unsigned long)info->fix.smem_start + offset;
|
||||
|
|
|
|||
|
|
@ -1337,6 +1337,19 @@ static void __vmw_svga_disable(struct vmw_private *dev_priv)
|
|||
*/
|
||||
void vmw_svga_disable(struct vmw_private *dev_priv)
|
||||
{
|
||||
/*
|
||||
* Disabling SVGA will turn off device modesetting capabilities, so
|
||||
* notify KMS about that so that it doesn't cache atomic state that
|
||||
* isn't valid anymore, for example crtcs turned on.
|
||||
* Strictly we'd want to do this under the SVGA lock (or an SVGA mutex),
|
||||
* but vmw_kms_lost_device() takes the reservation sem and thus we'll
|
||||
* end up with lock order reversal. Thus, a master may actually perform
|
||||
* a new modeset just after we call vmw_kms_lost_device() and race with
|
||||
* vmw_svga_disable(), but that should at worst cause atomic KMS state
|
||||
* to be inconsistent with the device, causing modesetting problems.
|
||||
*
|
||||
*/
|
||||
vmw_kms_lost_device(dev_priv->dev);
|
||||
ttm_write_lock(&dev_priv->reservation_sem, false);
|
||||
spin_lock(&dev_priv->svga_lock);
|
||||
if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) {
|
||||
|
|
|
|||
|
|
@ -938,6 +938,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
|
|||
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv);
|
||||
void vmw_kms_lost_device(struct drm_device *dev);
|
||||
|
||||
int vmw_dumb_create(struct drm_file *file_priv,
|
||||
struct drm_device *dev,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_rect.h>
|
||||
|
||||
|
||||
/* Might need a hrtimer here? */
|
||||
#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
|
||||
|
||||
|
|
@ -2517,9 +2516,12 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
|
|||
* Helper to be used if an error forces the caller to undo the actions of
|
||||
* vmw_kms_helper_resource_prepare.
|
||||
*/
|
||||
void vmw_kms_helper_resource_revert(struct vmw_resource *res)
|
||||
void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx)
|
||||
{
|
||||
vmw_kms_helper_buffer_revert(res->backup);
|
||||
struct vmw_resource *res = ctx->res;
|
||||
|
||||
vmw_kms_helper_buffer_revert(ctx->buf);
|
||||
vmw_dmabuf_unreference(&ctx->buf);
|
||||
vmw_resource_unreserve(res, false, NULL, 0);
|
||||
mutex_unlock(&res->dev_priv->cmdbuf_mutex);
|
||||
}
|
||||
|
|
@ -2536,10 +2538,14 @@ void vmw_kms_helper_resource_revert(struct vmw_resource *res)
|
|||
* interrupted by a signal.
|
||||
*/
|
||||
int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
||||
bool interruptible)
|
||||
bool interruptible,
|
||||
struct vmw_validation_ctx *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ctx->buf = NULL;
|
||||
ctx->res = res;
|
||||
|
||||
if (interruptible)
|
||||
ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex);
|
||||
else
|
||||
|
|
@ -2558,6 +2564,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
|||
res->dev_priv->has_mob);
|
||||
if (ret)
|
||||
goto out_unreserve;
|
||||
|
||||
ctx->buf = vmw_dmabuf_reference(res->backup);
|
||||
}
|
||||
ret = vmw_resource_validate(res);
|
||||
if (ret)
|
||||
|
|
@ -2565,7 +2573,7 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
|||
return 0;
|
||||
|
||||
out_revert:
|
||||
vmw_kms_helper_buffer_revert(res->backup);
|
||||
vmw_kms_helper_buffer_revert(ctx->buf);
|
||||
out_unreserve:
|
||||
vmw_resource_unreserve(res, false, NULL, 0);
|
||||
out_unlock:
|
||||
|
|
@ -2581,11 +2589,13 @@ out_unlock:
|
|||
* @out_fence: Optional pointer to a fence pointer. If non-NULL, a
|
||||
* ref-counted fence pointer is returned here.
|
||||
*/
|
||||
void vmw_kms_helper_resource_finish(struct vmw_resource *res,
|
||||
struct vmw_fence_obj **out_fence)
|
||||
void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
|
||||
struct vmw_fence_obj **out_fence)
|
||||
{
|
||||
if (res->backup || out_fence)
|
||||
vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup,
|
||||
struct vmw_resource *res = ctx->res;
|
||||
|
||||
if (ctx->buf || out_fence)
|
||||
vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
|
||||
out_fence, NULL);
|
||||
|
||||
vmw_resource_unreserve(res, false, NULL, 0);
|
||||
|
|
@ -2851,3 +2861,14 @@ int vmw_kms_set_config(struct drm_mode_set *set,
|
|||
|
||||
return drm_atomic_helper_set_config(set, ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost
|
||||
*
|
||||
* @dev: Pointer to the drm device
|
||||
*/
|
||||
void vmw_kms_lost_device(struct drm_device *dev)
|
||||
{
|
||||
drm_atomic_helper_shutdown(dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,6 +240,11 @@ struct vmw_display_unit {
|
|||
int set_gui_y;
|
||||
};
|
||||
|
||||
struct vmw_validation_ctx {
|
||||
struct vmw_resource *res;
|
||||
struct vmw_dma_buffer *buf;
|
||||
};
|
||||
|
||||
#define vmw_crtc_to_du(x) \
|
||||
container_of(x, struct vmw_display_unit, crtc)
|
||||
#define vmw_connector_to_du(x) \
|
||||
|
|
@ -296,9 +301,10 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
|
|||
struct drm_vmw_fence_rep __user *
|
||||
user_fence_rep);
|
||||
int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
||||
bool interruptible);
|
||||
void vmw_kms_helper_resource_revert(struct vmw_resource *res);
|
||||
void vmw_kms_helper_resource_finish(struct vmw_resource *res,
|
||||
bool interruptible,
|
||||
struct vmw_validation_ctx *ctx);
|
||||
void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx);
|
||||
void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
|
||||
struct vmw_fence_obj **out_fence);
|
||||
int vmw_kms_readback(struct vmw_private *dev_priv,
|
||||
struct drm_file *file_priv,
|
||||
|
|
@ -439,5 +445,4 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
|
|||
|
||||
int vmw_kms_set_config(struct drm_mode_set *set,
|
||||
struct drm_modeset_acquire_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -909,12 +909,13 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
|||
struct vmw_framebuffer_surface *vfbs =
|
||||
container_of(framebuffer, typeof(*vfbs), base);
|
||||
struct vmw_kms_sou_surface_dirty sdirty;
|
||||
struct vmw_validation_ctx ctx;
|
||||
int ret;
|
||||
|
||||
if (!srf)
|
||||
srf = &vfbs->surface->res;
|
||||
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true);
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -933,7 +934,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
|||
ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
|
||||
dest_x, dest_y, num_clips, inc,
|
||||
&sdirty.base);
|
||||
vmw_kms_helper_resource_finish(srf, out_fence);
|
||||
vmw_kms_helper_resource_finish(&ctx, out_fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -980,12 +980,13 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
|||
struct vmw_framebuffer_surface *vfbs =
|
||||
container_of(framebuffer, typeof(*vfbs), base);
|
||||
struct vmw_stdu_dirty sdirty;
|
||||
struct vmw_validation_ctx ctx;
|
||||
int ret;
|
||||
|
||||
if (!srf)
|
||||
srf = &vfbs->surface->res;
|
||||
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true);
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1008,7 +1009,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
|||
dest_x, dest_y, num_clips, inc,
|
||||
&sdirty.base);
|
||||
out_finish:
|
||||
vmw_kms_helper_resource_finish(srf, out_fence);
|
||||
vmw_kms_helper_resource_finish(&ctx, out_fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,10 +250,14 @@ void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan)
|
|||
{
|
||||
int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
|
||||
struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
|
||||
struct ipu_prg_channel *chan = &prg->chan[prg_chan];
|
||||
struct ipu_prg_channel *chan;
|
||||
u32 val;
|
||||
|
||||
if (!chan->enabled || prg_chan < 0)
|
||||
if (prg_chan < 0)
|
||||
return;
|
||||
|
||||
chan = &prg->chan[prg_chan];
|
||||
if (!chan->enabled)
|
||||
return;
|
||||
|
||||
pm_runtime_get_sync(prg->dev);
|
||||
|
|
@ -280,13 +284,15 @@ int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan,
|
|||
{
|
||||
int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
|
||||
struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
|
||||
struct ipu_prg_channel *chan = &prg->chan[prg_chan];
|
||||
struct ipu_prg_channel *chan;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (prg_chan < 0)
|
||||
return prg_chan;
|
||||
|
||||
chan = &prg->chan[prg_chan];
|
||||
|
||||
if (chan->enabled) {
|
||||
ipu_pre_update(prg->pres[chan->used_pre], *eba);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue