diff options
33 files changed, 381 insertions, 294 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 57afad79f55d..8fa850a070e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | |||
| @@ -540,6 +540,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, | |||
| 540 | size_t size; | 540 | size_t size; |
| 541 | u32 retry = 3; | 541 | u32 retry = 3; |
| 542 | 542 | ||
| 543 | if (amdgpu_acpi_pcie_notify_device_ready(adev)) | ||
| 544 | return -EINVAL; | ||
| 545 | |||
| 543 | /* Get the device handle */ | 546 | /* Get the device handle */ |
| 544 | handle = ACPI_HANDLE(&adev->pdev->dev); | 547 | handle = ACPI_HANDLE(&adev->pdev->dev); |
| 545 | if (!handle) | 548 | if (!handle) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 13044e66dcaf..561d3312af32 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
| @@ -481,7 +481,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, | |||
| 481 | result = 0; | 481 | result = 0; |
| 482 | 482 | ||
| 483 | if (*pos < 12) { | 483 | if (*pos < 12) { |
| 484 | early[0] = amdgpu_ring_get_rptr(ring); | 484 | early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask; |
| 485 | early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask; | 485 | early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask; |
| 486 | early[2] = ring->wptr & ring->buf_mask; | 486 | early[2] = ring->wptr & ring->buf_mask; |
| 487 | for (i = *pos / 4; i < 3 && size; i++) { | 487 | for (i = *pos / 4; i < 3 && size; i++) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index b2eae86bf906..5c26a8e806b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
| @@ -299,12 +299,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) | |||
| 299 | 299 | ||
| 300 | cancel_delayed_work_sync(&adev->uvd.idle_work); | 300 | cancel_delayed_work_sync(&adev->uvd.idle_work); |
| 301 | 301 | ||
| 302 | for (i = 0; i < adev->uvd.max_handles; ++i) | 302 | /* only valid for physical mode */ |
| 303 | if (atomic_read(&adev->uvd.handles[i])) | 303 | if (adev->asic_type < CHIP_POLARIS10) { |
| 304 | break; | 304 | for (i = 0; i < adev->uvd.max_handles; ++i) |
| 305 | if (atomic_read(&adev->uvd.handles[i])) | ||
| 306 | break; | ||
| 305 | 307 | ||
| 306 | if (i == AMDGPU_MAX_UVD_HANDLES) | 308 | if (i == adev->uvd.max_handles) |
| 307 | return 0; | 309 | return 0; |
| 310 | } | ||
| 308 | 311 | ||
| 309 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); | 312 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); |
| 310 | ptr = adev->uvd.cpu_addr; | 313 | ptr = adev->uvd.cpu_addr; |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index bd2c4f727df6..a712f4b285f6 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | |||
| @@ -3093,7 +3093,7 @@ static int dce_v6_0_hpd_irq(struct amdgpu_device *adev, | |||
| 3093 | tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK; | 3093 | tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK; |
| 3094 | WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp); | 3094 | WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp); |
| 3095 | schedule_work(&adev->hotplug_work); | 3095 | schedule_work(&adev->hotplug_work); |
| 3096 | DRM_INFO("IH: HPD%d\n", hpd + 1); | 3096 | DRM_DEBUG("IH: HPD%d\n", hpd + 1); |
| 3097 | } | 3097 | } |
| 3098 | 3098 | ||
| 3099 | return 0; | 3099 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index a066c5eda135..a4309698e76c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
| @@ -4384,34 +4384,8 @@ static void gfx_v7_0_gpu_early_init(struct amdgpu_device *adev) | |||
| 4384 | case CHIP_KAVERI: | 4384 | case CHIP_KAVERI: |
| 4385 | adev->gfx.config.max_shader_engines = 1; | 4385 | adev->gfx.config.max_shader_engines = 1; |
| 4386 | adev->gfx.config.max_tile_pipes = 4; | 4386 | adev->gfx.config.max_tile_pipes = 4; |
| 4387 | if ((adev->pdev->device == 0x1304) || | 4387 | adev->gfx.config.max_cu_per_sh = 8; |
| 4388 | (adev->pdev->device == 0x1305) || | 4388 | adev->gfx.config.max_backends_per_se = 2; |
| 4389 | (adev->pdev->device == 0x130C) || | ||
| 4390 | (adev->pdev->device == 0x130F) || | ||
| 4391 | (adev->pdev->device == 0x1310) || | ||
| 4392 | (adev->pdev->device == 0x1311) || | ||
| 4393 | (adev->pdev->device == 0x131C)) { | ||
| 4394 | adev->gfx.config.max_cu_per_sh = 8; | ||
| 4395 | adev->gfx.config.max_backends_per_se = 2; | ||
| 4396 | } else if ((adev->pdev->device == 0x1309) || | ||
| 4397 | (adev->pdev->device == 0x130A) || | ||
| 4398 | (adev->pdev->device == 0x130D) || | ||
| 4399 | (adev->pdev->device == 0x1313) || | ||
| 4400 | (adev->pdev->device == 0x131D)) { | ||
| 4401 | adev->gfx.config.max_cu_per_sh = 6; | ||
| 4402 | adev->gfx.config.max_backends_per_se = 2; | ||
| 4403 | } else if ((adev->pdev->device == 0x1306) || | ||
| 4404 | (adev->pdev->device == 0x1307) || | ||
| 4405 | (adev->pdev->device == 0x130B) || | ||
| 4406 | (adev->pdev->device == 0x130E) || | ||
| 4407 | (adev->pdev->device == 0x1315) || | ||
| 4408 | (adev->pdev->device == 0x131B)) { | ||
| 4409 | adev->gfx.config.max_cu_per_sh = 4; | ||
| 4410 | adev->gfx.config.max_backends_per_se = 1; | ||
| 4411 | } else { | ||
| 4412 | adev->gfx.config.max_cu_per_sh = 3; | ||
| 4413 | adev->gfx.config.max_backends_per_se = 1; | ||
| 4414 | } | ||
| 4415 | adev->gfx.config.max_sh_per_se = 1; | 4389 | adev->gfx.config.max_sh_per_se = 1; |
| 4416 | adev->gfx.config.max_texture_channel_caches = 4; | 4390 | adev->gfx.config.max_texture_channel_caches = 4; |
| 4417 | adev->gfx.config.max_gprs = 256; | 4391 | adev->gfx.config.max_gprs = 256; |
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index 543101d5a5ed..2095173aaabf 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include "amdgpu_uvd.h" | 31 | #include "amdgpu_uvd.h" |
| 32 | #include "amdgpu_vce.h" | 32 | #include "amdgpu_vce.h" |
| 33 | #include "atom.h" | 33 | #include "atom.h" |
| 34 | #include "amd_pcie.h" | ||
| 34 | #include "amdgpu_powerplay.h" | 35 | #include "amdgpu_powerplay.h" |
| 35 | #include "sid.h" | 36 | #include "sid.h" |
| 36 | #include "si_ih.h" | 37 | #include "si_ih.h" |
| @@ -1461,8 +1462,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | |||
| 1461 | { | 1462 | { |
| 1462 | struct pci_dev *root = adev->pdev->bus->self; | 1463 | struct pci_dev *root = adev->pdev->bus->self; |
| 1463 | int bridge_pos, gpu_pos; | 1464 | int bridge_pos, gpu_pos; |
| 1464 | u32 speed_cntl, mask, current_data_rate; | 1465 | u32 speed_cntl, current_data_rate; |
| 1465 | int ret, i; | 1466 | int i; |
| 1466 | u16 tmp16; | 1467 | u16 tmp16; |
| 1467 | 1468 | ||
| 1468 | if (pci_is_root_bus(adev->pdev->bus)) | 1469 | if (pci_is_root_bus(adev->pdev->bus)) |
| @@ -1474,23 +1475,20 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | |||
| 1474 | if (adev->flags & AMD_IS_APU) | 1475 | if (adev->flags & AMD_IS_APU) |
| 1475 | return; | 1476 | return; |
| 1476 | 1477 | ||
| 1477 | ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); | 1478 | if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | |
| 1478 | if (ret != 0) | 1479 | CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) |
| 1479 | return; | ||
| 1480 | |||
| 1481 | if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) | ||
| 1482 | return; | 1480 | return; |
| 1483 | 1481 | ||
| 1484 | speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); | 1482 | speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); |
| 1485 | current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> | 1483 | current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> |
| 1486 | LC_CURRENT_DATA_RATE_SHIFT; | 1484 | LC_CURRENT_DATA_RATE_SHIFT; |
| 1487 | if (mask & DRM_PCIE_SPEED_80) { | 1485 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { |
| 1488 | if (current_data_rate == 2) { | 1486 | if (current_data_rate == 2) { |
| 1489 | DRM_INFO("PCIE gen 3 link speeds already enabled\n"); | 1487 | DRM_INFO("PCIE gen 3 link speeds already enabled\n"); |
| 1490 | return; | 1488 | return; |
| 1491 | } | 1489 | } |
| 1492 | DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n"); | 1490 | DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n"); |
| 1493 | } else if (mask & DRM_PCIE_SPEED_50) { | 1491 | } else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) { |
| 1494 | if (current_data_rate == 1) { | 1492 | if (current_data_rate == 1) { |
| 1495 | DRM_INFO("PCIE gen 2 link speeds already enabled\n"); | 1493 | DRM_INFO("PCIE gen 2 link speeds already enabled\n"); |
| 1496 | return; | 1494 | return; |
| @@ -1506,7 +1504,7 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | |||
| 1506 | if (!gpu_pos) | 1504 | if (!gpu_pos) |
| 1507 | return; | 1505 | return; |
| 1508 | 1506 | ||
| 1509 | if (mask & DRM_PCIE_SPEED_80) { | 1507 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { |
| 1510 | if (current_data_rate != 2) { | 1508 | if (current_data_rate != 2) { |
| 1511 | u16 bridge_cfg, gpu_cfg; | 1509 | u16 bridge_cfg, gpu_cfg; |
| 1512 | u16 bridge_cfg2, gpu_cfg2; | 1510 | u16 bridge_cfg2, gpu_cfg2; |
| @@ -1589,9 +1587,9 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) | |||
| 1589 | 1587 | ||
| 1590 | pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); | 1588 | pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); |
| 1591 | tmp16 &= ~0xf; | 1589 | tmp16 &= ~0xf; |
| 1592 | if (mask & DRM_PCIE_SPEED_80) | 1590 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) |
| 1593 | tmp16 |= 3; | 1591 | tmp16 |= 3; |
| 1594 | else if (mask & DRM_PCIE_SPEED_50) | 1592 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) |
| 1595 | tmp16 |= 2; | 1593 | tmp16 |= 2; |
| 1596 | else | 1594 | else |
| 1597 | tmp16 |= 1; | 1595 | tmp16 |= 1; |
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index ce675a7f179a..22f0b7ff3ac9 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "amdgpu_pm.h" | 26 | #include "amdgpu_pm.h" |
| 27 | #include "amdgpu_dpm.h" | 27 | #include "amdgpu_dpm.h" |
| 28 | #include "amdgpu_atombios.h" | 28 | #include "amdgpu_atombios.h" |
| 29 | #include "amd_pcie.h" | ||
| 29 | #include "sid.h" | 30 | #include "sid.h" |
| 30 | #include "r600_dpm.h" | 31 | #include "r600_dpm.h" |
| 31 | #include "si_dpm.h" | 32 | #include "si_dpm.h" |
| @@ -3331,29 +3332,6 @@ static void btc_apply_voltage_delta_rules(struct amdgpu_device *adev, | |||
| 3331 | } | 3332 | } |
| 3332 | } | 3333 | } |
| 3333 | 3334 | ||
| 3334 | static enum amdgpu_pcie_gen r600_get_pcie_gen_support(struct amdgpu_device *adev, | ||
| 3335 | u32 sys_mask, | ||
| 3336 | enum amdgpu_pcie_gen asic_gen, | ||
| 3337 | enum amdgpu_pcie_gen default_gen) | ||
| 3338 | { | ||
| 3339 | switch (asic_gen) { | ||
| 3340 | case AMDGPU_PCIE_GEN1: | ||
| 3341 | return AMDGPU_PCIE_GEN1; | ||
| 3342 | case AMDGPU_PCIE_GEN2: | ||
| 3343 | return AMDGPU_PCIE_GEN2; | ||
| 3344 | case AMDGPU_PCIE_GEN3: | ||
| 3345 | return AMDGPU_PCIE_GEN3; | ||
| 3346 | default: | ||
| 3347 | if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == AMDGPU_PCIE_GEN3)) | ||
| 3348 | return AMDGPU_PCIE_GEN3; | ||
| 3349 | else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == AMDGPU_PCIE_GEN2)) | ||
| 3350 | return AMDGPU_PCIE_GEN2; | ||
| 3351 | else | ||
| 3352 | return AMDGPU_PCIE_GEN1; | ||
| 3353 | } | ||
| 3354 | return AMDGPU_PCIE_GEN1; | ||
| 3355 | } | ||
| 3356 | |||
| 3357 | static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b, | 3335 | static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b, |
| 3358 | u32 *p, u32 *u) | 3336 | u32 *p, u32 *u) |
| 3359 | { | 3337 | { |
| @@ -5028,10 +5006,11 @@ static int si_populate_smc_acpi_state(struct amdgpu_device *adev, | |||
| 5028 | table->ACPIState.levels[0].vddc.index, | 5006 | table->ACPIState.levels[0].vddc.index, |
| 5029 | &table->ACPIState.levels[0].std_vddc); | 5007 | &table->ACPIState.levels[0].std_vddc); |
| 5030 | } | 5008 | } |
| 5031 | table->ACPIState.levels[0].gen2PCIE = (u8)r600_get_pcie_gen_support(adev, | 5009 | table->ACPIState.levels[0].gen2PCIE = |
| 5032 | si_pi->sys_pcie_mask, | 5010 | (u8)amdgpu_get_pcie_gen_support(adev, |
| 5033 | si_pi->boot_pcie_gen, | 5011 | si_pi->sys_pcie_mask, |
| 5034 | AMDGPU_PCIE_GEN1); | 5012 | si_pi->boot_pcie_gen, |
| 5013 | AMDGPU_PCIE_GEN1); | ||
| 5035 | 5014 | ||
| 5036 | if (si_pi->vddc_phase_shed_control) | 5015 | if (si_pi->vddc_phase_shed_control) |
| 5037 | si_populate_phase_shedding_value(adev, | 5016 | si_populate_phase_shedding_value(adev, |
| @@ -7168,10 +7147,10 @@ static void si_parse_pplib_clock_info(struct amdgpu_device *adev, | |||
| 7168 | pl->vddc = le16_to_cpu(clock_info->si.usVDDC); | 7147 | pl->vddc = le16_to_cpu(clock_info->si.usVDDC); |
| 7169 | pl->vddci = le16_to_cpu(clock_info->si.usVDDCI); | 7148 | pl->vddci = le16_to_cpu(clock_info->si.usVDDCI); |
| 7170 | pl->flags = le32_to_cpu(clock_info->si.ulFlags); | 7149 | pl->flags = le32_to_cpu(clock_info->si.ulFlags); |
| 7171 | pl->pcie_gen = r600_get_pcie_gen_support(adev, | 7150 | pl->pcie_gen = amdgpu_get_pcie_gen_support(adev, |
| 7172 | si_pi->sys_pcie_mask, | 7151 | si_pi->sys_pcie_mask, |
| 7173 | si_pi->boot_pcie_gen, | 7152 | si_pi->boot_pcie_gen, |
| 7174 | clock_info->si.ucPCIEGen); | 7153 | clock_info->si.ucPCIEGen); |
| 7175 | 7154 | ||
| 7176 | /* patch up vddc if necessary */ | 7155 | /* patch up vddc if necessary */ |
| 7177 | ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc, | 7156 | ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc, |
| @@ -7326,7 +7305,6 @@ static int si_dpm_init(struct amdgpu_device *adev) | |||
| 7326 | struct si_power_info *si_pi; | 7305 | struct si_power_info *si_pi; |
| 7327 | struct atom_clock_dividers dividers; | 7306 | struct atom_clock_dividers dividers; |
| 7328 | int ret; | 7307 | int ret; |
| 7329 | u32 mask; | ||
| 7330 | 7308 | ||
| 7331 | si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL); | 7309 | si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL); |
| 7332 | if (si_pi == NULL) | 7310 | if (si_pi == NULL) |
| @@ -7336,11 +7314,9 @@ static int si_dpm_init(struct amdgpu_device *adev) | |||
| 7336 | eg_pi = &ni_pi->eg; | 7314 | eg_pi = &ni_pi->eg; |
| 7337 | pi = &eg_pi->rv7xx; | 7315 | pi = &eg_pi->rv7xx; |
| 7338 | 7316 | ||
| 7339 | ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); | 7317 | si_pi->sys_pcie_mask = |
| 7340 | if (ret) | 7318 | (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK) >> |
| 7341 | si_pi->sys_pcie_mask = 0; | 7319 | CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT; |
| 7342 | else | ||
| 7343 | si_pi->sys_pcie_mask = mask; | ||
| 7344 | si_pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID; | 7320 | si_pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID; |
| 7345 | si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev); | 7321 | si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev); |
| 7346 | 7322 | ||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 862835dc054e..c345e645f1d7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
| @@ -1037,6 +1037,10 @@ static void handle_hpd_rx_irq(void *param) | |||
| 1037 | !is_mst_root_connector) { | 1037 | !is_mst_root_connector) { |
| 1038 | /* Downstream Port status changed. */ | 1038 | /* Downstream Port status changed. */ |
| 1039 | if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) { | 1039 | if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) { |
| 1040 | |||
| 1041 | if (aconnector->fake_enable) | ||
| 1042 | aconnector->fake_enable = false; | ||
| 1043 | |||
| 1040 | amdgpu_dm_update_connector_after_detect(aconnector); | 1044 | amdgpu_dm_update_connector_after_detect(aconnector); |
| 1041 | 1045 | ||
| 1042 | 1046 | ||
| @@ -2012,30 +2016,32 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode, | |||
| 2012 | dst.width = stream->timing.h_addressable; | 2016 | dst.width = stream->timing.h_addressable; |
| 2013 | dst.height = stream->timing.v_addressable; | 2017 | dst.height = stream->timing.v_addressable; |
| 2014 | 2018 | ||
| 2015 | rmx_type = dm_state->scaling; | 2019 | if (dm_state) { |
| 2016 | if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) { | 2020 | rmx_type = dm_state->scaling; |
| 2017 | if (src.width * dst.height < | 2021 | if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) { |
| 2018 | src.height * dst.width) { | 2022 | if (src.width * dst.height < |
| 2019 | /* height needs less upscaling/more downscaling */ | 2023 | src.height * dst.width) { |
| 2020 | dst.width = src.width * | 2024 | /* height needs less upscaling/more downscaling */ |
| 2021 | dst.height / src.height; | 2025 | dst.width = src.width * |
| 2022 | } else { | 2026 | dst.height / src.height; |
| 2023 | /* width needs less upscaling/more downscaling */ | 2027 | } else { |
| 2024 | dst.height = src.height * | 2028 | /* width needs less upscaling/more downscaling */ |
| 2025 | dst.width / src.width; | 2029 | dst.height = src.height * |
| 2030 | dst.width / src.width; | ||
| 2031 | } | ||
| 2032 | } else if (rmx_type == RMX_CENTER) { | ||
| 2033 | dst = src; | ||
| 2026 | } | 2034 | } |
| 2027 | } else if (rmx_type == RMX_CENTER) { | ||
| 2028 | dst = src; | ||
| 2029 | } | ||
| 2030 | 2035 | ||
| 2031 | dst.x = (stream->timing.h_addressable - dst.width) / 2; | 2036 | dst.x = (stream->timing.h_addressable - dst.width) / 2; |
| 2032 | dst.y = (stream->timing.v_addressable - dst.height) / 2; | 2037 | dst.y = (stream->timing.v_addressable - dst.height) / 2; |
| 2033 | 2038 | ||
| 2034 | if (dm_state->underscan_enable) { | 2039 | if (dm_state->underscan_enable) { |
| 2035 | dst.x += dm_state->underscan_hborder / 2; | 2040 | dst.x += dm_state->underscan_hborder / 2; |
| 2036 | dst.y += dm_state->underscan_vborder / 2; | 2041 | dst.y += dm_state->underscan_vborder / 2; |
| 2037 | dst.width -= dm_state->underscan_hborder; | 2042 | dst.width -= dm_state->underscan_hborder; |
| 2038 | dst.height -= dm_state->underscan_vborder; | 2043 | dst.height -= dm_state->underscan_vborder; |
| 2044 | } | ||
| 2039 | } | 2045 | } |
| 2040 | 2046 | ||
| 2041 | stream->src = src; | 2047 | stream->src = src; |
| @@ -2360,12 +2366,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2360 | 2366 | ||
| 2361 | if (aconnector == NULL) { | 2367 | if (aconnector == NULL) { |
| 2362 | DRM_ERROR("aconnector is NULL!\n"); | 2368 | DRM_ERROR("aconnector is NULL!\n"); |
| 2363 | goto drm_connector_null; | 2369 | return stream; |
| 2364 | } | ||
| 2365 | |||
| 2366 | if (dm_state == NULL) { | ||
| 2367 | DRM_ERROR("dm_state is NULL!\n"); | ||
| 2368 | goto dm_state_null; | ||
| 2369 | } | 2370 | } |
| 2370 | 2371 | ||
| 2371 | drm_connector = &aconnector->base; | 2372 | drm_connector = &aconnector->base; |
| @@ -2377,18 +2378,18 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2377 | */ | 2378 | */ |
| 2378 | if (aconnector->mst_port) { | 2379 | if (aconnector->mst_port) { |
| 2379 | dm_dp_mst_dc_sink_create(drm_connector); | 2380 | dm_dp_mst_dc_sink_create(drm_connector); |
| 2380 | goto mst_dc_sink_create_done; | 2381 | return stream; |
| 2381 | } | 2382 | } |
| 2382 | 2383 | ||
| 2383 | if (create_fake_sink(aconnector)) | 2384 | if (create_fake_sink(aconnector)) |
| 2384 | goto stream_create_fail; | 2385 | return stream; |
| 2385 | } | 2386 | } |
| 2386 | 2387 | ||
| 2387 | stream = dc_create_stream_for_sink(aconnector->dc_sink); | 2388 | stream = dc_create_stream_for_sink(aconnector->dc_sink); |
| 2388 | 2389 | ||
| 2389 | if (stream == NULL) { | 2390 | if (stream == NULL) { |
| 2390 | DRM_ERROR("Failed to create stream for sink!\n"); | 2391 | DRM_ERROR("Failed to create stream for sink!\n"); |
| 2391 | goto stream_create_fail; | 2392 | return stream; |
| 2392 | } | 2393 | } |
| 2393 | 2394 | ||
| 2394 | list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { | 2395 | list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { |
| @@ -2414,9 +2415,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2414 | } else { | 2415 | } else { |
| 2415 | decide_crtc_timing_for_drm_display_mode( | 2416 | decide_crtc_timing_for_drm_display_mode( |
| 2416 | &mode, preferred_mode, | 2417 | &mode, preferred_mode, |
| 2417 | dm_state->scaling != RMX_OFF); | 2418 | dm_state ? (dm_state->scaling != RMX_OFF) : false); |
| 2418 | } | 2419 | } |
| 2419 | 2420 | ||
| 2421 | if (!dm_state) | ||
| 2422 | drm_mode_set_crtcinfo(&mode, 0); | ||
| 2423 | |||
| 2420 | fill_stream_properties_from_drm_display_mode(stream, | 2424 | fill_stream_properties_from_drm_display_mode(stream, |
| 2421 | &mode, &aconnector->base); | 2425 | &mode, &aconnector->base); |
| 2422 | update_stream_scaling_settings(&mode, dm_state, stream); | 2426 | update_stream_scaling_settings(&mode, dm_state, stream); |
| @@ -2426,10 +2430,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
| 2426 | drm_connector, | 2430 | drm_connector, |
| 2427 | aconnector->dc_sink); | 2431 | aconnector->dc_sink); |
| 2428 | 2432 | ||
| 2429 | stream_create_fail: | 2433 | update_stream_signal(stream); |
| 2430 | dm_state_null: | 2434 | |
| 2431 | drm_connector_null: | ||
| 2432 | mst_dc_sink_create_done: | ||
| 2433 | return stream; | 2435 | return stream; |
| 2434 | } | 2436 | } |
| 2435 | 2437 | ||
| @@ -2497,6 +2499,27 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) | |||
| 2497 | return &state->base; | 2499 | return &state->base; |
| 2498 | } | 2500 | } |
| 2499 | 2501 | ||
| 2502 | |||
| 2503 | static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) | ||
| 2504 | { | ||
| 2505 | enum dc_irq_source irq_source; | ||
| 2506 | struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); | ||
| 2507 | struct amdgpu_device *adev = crtc->dev->dev_private; | ||
| 2508 | |||
| 2509 | irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; | ||
| 2510 | return dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; | ||
| 2511 | } | ||
| 2512 | |||
| 2513 | static int dm_enable_vblank(struct drm_crtc *crtc) | ||
| 2514 | { | ||
| 2515 | return dm_set_vblank(crtc, true); | ||
| 2516 | } | ||
| 2517 | |||
| 2518 | static void dm_disable_vblank(struct drm_crtc *crtc) | ||
| 2519 | { | ||
| 2520 | dm_set_vblank(crtc, false); | ||
| 2521 | } | ||
| 2522 | |||
| 2500 | /* Implemented only the options currently availible for the driver */ | 2523 | /* Implemented only the options currently availible for the driver */ |
| 2501 | static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { | 2524 | static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { |
| 2502 | .reset = dm_crtc_reset_state, | 2525 | .reset = dm_crtc_reset_state, |
| @@ -2506,6 +2529,8 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { | |||
| 2506 | .page_flip = drm_atomic_helper_page_flip, | 2529 | .page_flip = drm_atomic_helper_page_flip, |
| 2507 | .atomic_duplicate_state = dm_crtc_duplicate_state, | 2530 | .atomic_duplicate_state = dm_crtc_duplicate_state, |
| 2508 | .atomic_destroy_state = dm_crtc_destroy_state, | 2531 | .atomic_destroy_state = dm_crtc_destroy_state, |
| 2532 | .enable_vblank = dm_enable_vblank, | ||
| 2533 | .disable_vblank = dm_disable_vblank, | ||
| 2509 | }; | 2534 | }; |
| 2510 | 2535 | ||
| 2511 | static enum drm_connector_status | 2536 | static enum drm_connector_status |
| @@ -2800,7 +2825,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector, | |||
| 2800 | goto fail; | 2825 | goto fail; |
| 2801 | } | 2826 | } |
| 2802 | 2827 | ||
| 2803 | stream = dc_create_stream_for_sink(dc_sink); | 2828 | stream = create_stream_for_sink(aconnector, mode, NULL); |
| 2804 | if (stream == NULL) { | 2829 | if (stream == NULL) { |
| 2805 | DRM_ERROR("Failed to create stream for sink!\n"); | 2830 | DRM_ERROR("Failed to create stream for sink!\n"); |
| 2806 | goto fail; | 2831 | goto fail; |
| @@ -3060,6 +3085,9 @@ static int dm_plane_atomic_check(struct drm_plane *plane, | |||
| 3060 | if (!dm_plane_state->dc_state) | 3085 | if (!dm_plane_state->dc_state) |
| 3061 | return 0; | 3086 | return 0; |
| 3062 | 3087 | ||
| 3088 | if (!fill_rects_from_plane_state(state, dm_plane_state->dc_state)) | ||
| 3089 | return -EINVAL; | ||
| 3090 | |||
| 3063 | if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) | 3091 | if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) |
| 3064 | return 0; | 3092 | return 0; |
| 3065 | 3093 | ||
| @@ -4632,8 +4660,6 @@ static int dm_update_planes_state(struct dc *dc, | |||
| 4632 | bool pflip_needed = !state->allow_modeset; | 4660 | bool pflip_needed = !state->allow_modeset; |
| 4633 | int ret = 0; | 4661 | int ret = 0; |
| 4634 | 4662 | ||
| 4635 | if (pflip_needed) | ||
| 4636 | return ret; | ||
| 4637 | 4663 | ||
| 4638 | /* Add new planes */ | 4664 | /* Add new planes */ |
| 4639 | for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { | 4665 | for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { |
| @@ -4648,6 +4674,8 @@ static int dm_update_planes_state(struct dc *dc, | |||
| 4648 | 4674 | ||
| 4649 | /* Remove any changed/removed planes */ | 4675 | /* Remove any changed/removed planes */ |
| 4650 | if (!enable) { | 4676 | if (!enable) { |
| 4677 | if (pflip_needed) | ||
| 4678 | continue; | ||
| 4651 | 4679 | ||
| 4652 | if (!old_plane_crtc) | 4680 | if (!old_plane_crtc) |
| 4653 | continue; | 4681 | continue; |
| @@ -4679,6 +4707,7 @@ static int dm_update_planes_state(struct dc *dc, | |||
| 4679 | *lock_and_validation_needed = true; | 4707 | *lock_and_validation_needed = true; |
| 4680 | 4708 | ||
| 4681 | } else { /* Add new planes */ | 4709 | } else { /* Add new planes */ |
| 4710 | struct dc_plane_state *dc_new_plane_state; | ||
| 4682 | 4711 | ||
| 4683 | if (drm_atomic_plane_disabling(plane->state, new_plane_state)) | 4712 | if (drm_atomic_plane_disabling(plane->state, new_plane_state)) |
| 4684 | continue; | 4713 | continue; |
| @@ -4692,38 +4721,50 @@ static int dm_update_planes_state(struct dc *dc, | |||
| 4692 | if (!dm_new_crtc_state->stream) | 4721 | if (!dm_new_crtc_state->stream) |
| 4693 | continue; | 4722 | continue; |
| 4694 | 4723 | ||
| 4724 | if (pflip_needed) | ||
| 4725 | continue; | ||
| 4695 | 4726 | ||
| 4696 | WARN_ON(dm_new_plane_state->dc_state); | 4727 | WARN_ON(dm_new_plane_state->dc_state); |
| 4697 | 4728 | ||
| 4698 | dm_new_plane_state->dc_state = dc_create_plane_state(dc); | 4729 | dc_new_plane_state = dc_create_plane_state(dc); |
| 4699 | 4730 | if (!dc_new_plane_state) { | |
| 4700 | DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n", | ||
| 4701 | plane->base.id, new_plane_crtc->base.id); | ||
| 4702 | |||
| 4703 | if (!dm_new_plane_state->dc_state) { | ||
| 4704 | ret = -EINVAL; | 4731 | ret = -EINVAL; |
| 4705 | return ret; | 4732 | return ret; |
| 4706 | } | 4733 | } |
| 4707 | 4734 | ||
| 4735 | DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n", | ||
| 4736 | plane->base.id, new_plane_crtc->base.id); | ||
| 4737 | |||
| 4708 | ret = fill_plane_attributes( | 4738 | ret = fill_plane_attributes( |
| 4709 | new_plane_crtc->dev->dev_private, | 4739 | new_plane_crtc->dev->dev_private, |
| 4710 | dm_new_plane_state->dc_state, | 4740 | dc_new_plane_state, |
| 4711 | new_plane_state, | 4741 | new_plane_state, |
| 4712 | new_crtc_state); | 4742 | new_crtc_state); |
| 4713 | if (ret) | 4743 | if (ret) { |
| 4744 | dc_plane_state_release(dc_new_plane_state); | ||
| 4714 | return ret; | 4745 | return ret; |
| 4746 | } | ||
| 4715 | 4747 | ||
| 4716 | 4748 | /* | |
| 4749 | * Any atomic check errors that occur after this will | ||
| 4750 | * not need a release. The plane state will be attached | ||
| 4751 | * to the stream, and therefore part of the atomic | ||
| 4752 | * state. It'll be released when the atomic state is | ||
| 4753 | * cleaned. | ||
| 4754 | */ | ||
| 4717 | if (!dc_add_plane_to_context( | 4755 | if (!dc_add_plane_to_context( |
| 4718 | dc, | 4756 | dc, |
| 4719 | dm_new_crtc_state->stream, | 4757 | dm_new_crtc_state->stream, |
| 4720 | dm_new_plane_state->dc_state, | 4758 | dc_new_plane_state, |
| 4721 | dm_state->context)) { | 4759 | dm_state->context)) { |
| 4722 | 4760 | ||
| 4761 | dc_plane_state_release(dc_new_plane_state); | ||
| 4723 | ret = -EINVAL; | 4762 | ret = -EINVAL; |
| 4724 | return ret; | 4763 | return ret; |
| 4725 | } | 4764 | } |
| 4726 | 4765 | ||
| 4766 | dm_new_plane_state->dc_state = dc_new_plane_state; | ||
| 4767 | |||
| 4727 | /* Tell DC to do a full surface update every time there | 4768 | /* Tell DC to do a full surface update every time there |
| 4728 | * is a plane change. Inefficient, but works for now. | 4769 | * is a plane change. Inefficient, but works for now. |
| 4729 | */ | 4770 | */ |
| @@ -4737,6 +4778,30 @@ static int dm_update_planes_state(struct dc *dc, | |||
| 4737 | return ret; | 4778 | return ret; |
| 4738 | } | 4779 | } |
| 4739 | 4780 | ||
| 4781 | static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state, | ||
| 4782 | struct drm_crtc *crtc) | ||
| 4783 | { | ||
| 4784 | struct drm_plane *plane; | ||
| 4785 | struct drm_crtc_state *crtc_state; | ||
| 4786 | |||
| 4787 | WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc)); | ||
| 4788 | |||
| 4789 | drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) { | ||
| 4790 | struct drm_plane_state *plane_state = | ||
| 4791 | drm_atomic_get_plane_state(state, plane); | ||
| 4792 | |||
| 4793 | if (IS_ERR(plane_state)) | ||
| 4794 | return -EDEADLK; | ||
| 4795 | |||
| 4796 | crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc); | ||
| 4797 | if (crtc->primary == plane && crtc_state->active) { | ||
| 4798 | if (!plane_state->fb) | ||
| 4799 | return -EINVAL; | ||
| 4800 | } | ||
| 4801 | } | ||
| 4802 | return 0; | ||
| 4803 | } | ||
| 4804 | |||
| 4740 | static int amdgpu_dm_atomic_check(struct drm_device *dev, | 4805 | static int amdgpu_dm_atomic_check(struct drm_device *dev, |
| 4741 | struct drm_atomic_state *state) | 4806 | struct drm_atomic_state *state) |
| 4742 | { | 4807 | { |
| @@ -4760,6 +4825,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, | |||
| 4760 | goto fail; | 4825 | goto fail; |
| 4761 | 4826 | ||
| 4762 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { | 4827 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
| 4828 | ret = dm_atomic_check_plane_state_fb(state, crtc); | ||
| 4829 | if (ret) | ||
| 4830 | goto fail; | ||
| 4831 | |||
| 4763 | if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && | 4832 | if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && |
| 4764 | !new_crtc_state->color_mgmt_changed) | 4833 | !new_crtc_state->color_mgmt_changed) |
| 4765 | continue; | 4834 | continue; |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 1874b6cee6af..422055080df4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | |||
| @@ -683,10 +683,8 @@ static const struct amdgpu_irq_src_funcs dm_hpd_irq_funcs = { | |||
| 683 | 683 | ||
| 684 | void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev) | 684 | void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev) |
| 685 | { | 685 | { |
| 686 | if (adev->mode_info.num_crtc > 0) | 686 | |
| 687 | adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc; | 687 | adev->crtc_irq.num_types = adev->mode_info.num_crtc; |
| 688 | else | ||
| 689 | adev->crtc_irq.num_types = 0; | ||
| 690 | adev->crtc_irq.funcs = &dm_crtc_irq_funcs; | 688 | adev->crtc_irq.funcs = &dm_crtc_irq_funcs; |
| 691 | 689 | ||
| 692 | adev->pageflip_irq.num_types = adev->mode_info.num_crtc; | 690 | adev->pageflip_irq.num_types = adev->mode_info.num_crtc; |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index f3d87f418d2e..93421dad21bd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | |||
| @@ -189,6 +189,12 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector) | |||
| 189 | .link = aconnector->dc_link, | 189 | .link = aconnector->dc_link, |
| 190 | .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | 190 | .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; |
| 191 | 191 | ||
| 192 | /* | ||
| 193 | * TODO: Need to further figure out why ddc.algo is NULL while MST port exists | ||
| 194 | */ | ||
| 195 | if (!aconnector->port || !aconnector->port->aux.ddc.algo) | ||
| 196 | return; | ||
| 197 | |||
| 192 | edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); | 198 | edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); |
| 193 | 199 | ||
| 194 | if (!edid) { | 200 | if (!edid) { |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 35e84ed031de..12868c769606 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c | |||
| @@ -1358,13 +1358,13 @@ enum dc_irq_source dc_interrupt_to_irq_source( | |||
| 1358 | return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); | 1358 | return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); |
| 1359 | } | 1359 | } |
| 1360 | 1360 | ||
| 1361 | void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) | 1361 | bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) |
| 1362 | { | 1362 | { |
| 1363 | 1363 | ||
| 1364 | if (dc == NULL) | 1364 | if (dc == NULL) |
| 1365 | return; | 1365 | return false; |
| 1366 | 1366 | ||
| 1367 | dal_irq_service_set(dc->res_pool->irqs, src, enable); | 1367 | return dal_irq_service_set(dc->res_pool->irqs, src, enable); |
| 1368 | } | 1368 | } |
| 1369 | 1369 | ||
| 1370 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) | 1370 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index a37428271573..be5546181fa8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
| @@ -1749,8 +1749,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) | |||
| 1749 | link->link_enc, | 1749 | link->link_enc, |
| 1750 | pipe_ctx->clock_source->id, | 1750 | pipe_ctx->clock_source->id, |
| 1751 | display_color_depth, | 1751 | display_color_depth, |
| 1752 | pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A, | 1752 | pipe_ctx->stream->signal, |
| 1753 | pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK, | ||
| 1754 | stream->phy_pix_clk); | 1753 | stream->phy_pix_clk); |
| 1755 | 1754 | ||
| 1756 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) | 1755 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 95b8dd0e53c6..4d07ffebfd31 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c | |||
| @@ -1360,9 +1360,6 @@ bool dc_is_stream_scaling_unchanged( | |||
| 1360 | return true; | 1360 | return true; |
| 1361 | } | 1361 | } |
| 1362 | 1362 | ||
| 1363 | /* Maximum TMDS single link pixel clock 165MHz */ | ||
| 1364 | #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 | ||
| 1365 | |||
| 1366 | static void update_stream_engine_usage( | 1363 | static void update_stream_engine_usage( |
| 1367 | struct resource_context *res_ctx, | 1364 | struct resource_context *res_ctx, |
| 1368 | const struct resource_pool *pool, | 1365 | const struct resource_pool *pool, |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 539c3e0a6292..cd5819789d76 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c | |||
| @@ -33,8 +33,7 @@ | |||
| 33 | /******************************************************************************* | 33 | /******************************************************************************* |
| 34 | * Private functions | 34 | * Private functions |
| 35 | ******************************************************************************/ | 35 | ******************************************************************************/ |
| 36 | #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000 | 36 | void update_stream_signal(struct dc_stream_state *stream) |
| 37 | static void update_stream_signal(struct dc_stream_state *stream) | ||
| 38 | { | 37 | { |
| 39 | 38 | ||
| 40 | struct dc_sink *dc_sink = stream->sink; | 39 | struct dc_sink *dc_sink = stream->sink; |
| @@ -45,8 +44,9 @@ static void update_stream_signal(struct dc_stream_state *stream) | |||
| 45 | stream->signal = dc_sink->sink_signal; | 44 | stream->signal = dc_sink->sink_signal; |
| 46 | 45 | ||
| 47 | if (dc_is_dvi_signal(stream->signal)) { | 46 | if (dc_is_dvi_signal(stream->signal)) { |
| 48 | if (stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST && | 47 | if (stream->ctx->dc->caps.dual_link_dvi && |
| 49 | stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK) | 48 | stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK && |
| 49 | stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK) | ||
| 50 | stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK; | 50 | stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK; |
| 51 | else | 51 | else |
| 52 | stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK; | 52 | stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK; |
| @@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes( | |||
| 193 | 193 | ||
| 194 | core_dc = stream->ctx->dc; | 194 | core_dc = stream->ctx->dc; |
| 195 | res_ctx = &core_dc->current_state->res_ctx; | 195 | res_ctx = &core_dc->current_state->res_ctx; |
| 196 | stream->cursor_attributes = *attributes; | ||
| 196 | 197 | ||
| 197 | for (i = 0; i < MAX_PIPES; i++) { | 198 | for (i = 0; i < MAX_PIPES; i++) { |
| 198 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; | 199 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; |
| @@ -204,34 +205,8 @@ bool dc_stream_set_cursor_attributes( | |||
| 204 | continue; | 205 | continue; |
| 205 | 206 | ||
| 206 | 207 | ||
| 207 | if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL) | 208 | core_dc->hwss.set_cursor_attribute(pipe_ctx); |
| 208 | pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( | ||
| 209 | pipe_ctx->plane_res.ipp, attributes); | ||
| 210 | |||
| 211 | if (pipe_ctx->plane_res.hubp != NULL && | ||
| 212 | pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL) | ||
| 213 | pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( | ||
| 214 | pipe_ctx->plane_res.hubp, attributes); | ||
| 215 | |||
| 216 | if (pipe_ctx->plane_res.mi != NULL && | ||
| 217 | pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL) | ||
| 218 | pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( | ||
| 219 | pipe_ctx->plane_res.mi, attributes); | ||
| 220 | |||
| 221 | |||
| 222 | if (pipe_ctx->plane_res.xfm != NULL && | ||
| 223 | pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL) | ||
| 224 | pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( | ||
| 225 | pipe_ctx->plane_res.xfm, attributes); | ||
| 226 | |||
| 227 | if (pipe_ctx->plane_res.dpp != NULL && | ||
| 228 | pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL) | ||
| 229 | pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( | ||
| 230 | pipe_ctx->plane_res.dpp, attributes->color_format); | ||
| 231 | } | 209 | } |
| 232 | |||
| 233 | stream->cursor_attributes = *attributes; | ||
| 234 | |||
| 235 | return true; | 210 | return true; |
| 236 | } | 211 | } |
| 237 | 212 | ||
| @@ -255,21 +230,10 @@ bool dc_stream_set_cursor_position( | |||
| 255 | 230 | ||
| 256 | core_dc = stream->ctx->dc; | 231 | core_dc = stream->ctx->dc; |
| 257 | res_ctx = &core_dc->current_state->res_ctx; | 232 | res_ctx = &core_dc->current_state->res_ctx; |
| 233 | stream->cursor_position = *position; | ||
| 258 | 234 | ||
| 259 | for (i = 0; i < MAX_PIPES; i++) { | 235 | for (i = 0; i < MAX_PIPES; i++) { |
| 260 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; | 236 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; |
| 261 | struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; | ||
| 262 | struct mem_input *mi = pipe_ctx->plane_res.mi; | ||
| 263 | struct hubp *hubp = pipe_ctx->plane_res.hubp; | ||
| 264 | struct dpp *dpp = pipe_ctx->plane_res.dpp; | ||
| 265 | struct dc_cursor_position pos_cpy = *position; | ||
| 266 | struct dc_cursor_mi_param param = { | ||
| 267 | .pixel_clk_khz = stream->timing.pix_clk_khz, | ||
| 268 | .ref_clk_khz = core_dc->res_pool->ref_clock_inKhz, | ||
| 269 | .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, | ||
| 270 | .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, | ||
| 271 | .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz | ||
| 272 | }; | ||
| 273 | 237 | ||
| 274 | if (pipe_ctx->stream != stream || | 238 | if (pipe_ctx->stream != stream || |
| 275 | (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || | 239 | (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || |
| @@ -278,33 +242,9 @@ bool dc_stream_set_cursor_position( | |||
| 278 | !pipe_ctx->plane_res.ipp) | 242 | !pipe_ctx->plane_res.ipp) |
| 279 | continue; | 243 | continue; |
| 280 | 244 | ||
| 281 | if (pipe_ctx->plane_state->address.type | 245 | core_dc->hwss.set_cursor_position(pipe_ctx); |
| 282 | == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) | ||
| 283 | pos_cpy.enable = false; | ||
| 284 | |||
| 285 | if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) | ||
| 286 | pos_cpy.enable = false; | ||
| 287 | |||
| 288 | |||
| 289 | if (ipp != NULL && ipp->funcs->ipp_cursor_set_position != NULL) | ||
| 290 | ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); | ||
| 291 | |||
| 292 | if (mi != NULL && mi->funcs->set_cursor_position != NULL) | ||
| 293 | mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); | ||
| 294 | |||
| 295 | if (!hubp) | ||
| 296 | continue; | ||
| 297 | |||
| 298 | if (hubp->funcs->set_cursor_position != NULL) | ||
| 299 | hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); | ||
| 300 | |||
| 301 | if (dpp != NULL && dpp->funcs->set_cursor_position != NULL) | ||
| 302 | dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width); | ||
| 303 | |||
| 304 | } | 246 | } |
| 305 | 247 | ||
| 306 | stream->cursor_position = *position; | ||
| 307 | |||
| 308 | return true; | 248 | return true; |
| 309 | } | 249 | } |
| 310 | 250 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e2e3c9df79ea..d6d56611604e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h | |||
| @@ -62,6 +62,7 @@ struct dc_caps { | |||
| 62 | bool dcc_const_color; | 62 | bool dcc_const_color; |
| 63 | bool dynamic_audio; | 63 | bool dynamic_audio; |
| 64 | bool is_apu; | 64 | bool is_apu; |
| 65 | bool dual_link_dvi; | ||
| 65 | }; | 66 | }; |
| 66 | 67 | ||
| 67 | struct dc_dcc_surface_param { | 68 | struct dc_dcc_surface_param { |
| @@ -672,7 +673,7 @@ enum dc_irq_source dc_interrupt_to_irq_source( | |||
| 672 | struct dc *dc, | 673 | struct dc *dc, |
| 673 | uint32_t src_id, | 674 | uint32_t src_id, |
| 674 | uint32_t ext_id); | 675 | uint32_t ext_id); |
| 675 | void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable); | 676 | bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable); |
| 676 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src); | 677 | void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src); |
| 677 | enum dc_irq_source dc_get_hpd_irq_source_at_index( | 678 | enum dc_irq_source dc_get_hpd_irq_source_at_index( |
| 678 | struct dc *dc, uint32_t link_index); | 679 | struct dc *dc, uint32_t link_index); |
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 01c60f11b2bd..456e4d29eadd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h | |||
| @@ -237,6 +237,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream( | |||
| 237 | */ | 237 | */ |
| 238 | struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink); | 238 | struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink); |
| 239 | 239 | ||
| 240 | void update_stream_signal(struct dc_stream_state *stream); | ||
| 241 | |||
| 240 | void dc_stream_retain(struct dc_stream_state *dc_stream); | 242 | void dc_stream_retain(struct dc_stream_state *dc_stream); |
| 241 | void dc_stream_release(struct dc_stream_state *dc_stream); | 243 | void dc_stream_release(struct dc_stream_state *dc_stream); |
| 242 | 244 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index b73db9e78437..a993279a8f2d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | |||
| @@ -236,6 +236,7 @@ | |||
| 236 | SR(D2VGA_CONTROL), \ | 236 | SR(D2VGA_CONTROL), \ |
| 237 | SR(D3VGA_CONTROL), \ | 237 | SR(D3VGA_CONTROL), \ |
| 238 | SR(D4VGA_CONTROL), \ | 238 | SR(D4VGA_CONTROL), \ |
| 239 | SR(VGA_TEST_CONTROL), \ | ||
| 239 | SR(DC_IP_REQUEST_CNTL), \ | 240 | SR(DC_IP_REQUEST_CNTL), \ |
| 240 | BL_REG_LIST() | 241 | BL_REG_LIST() |
| 241 | 242 | ||
| @@ -337,6 +338,7 @@ struct dce_hwseq_registers { | |||
| 337 | uint32_t D2VGA_CONTROL; | 338 | uint32_t D2VGA_CONTROL; |
| 338 | uint32_t D3VGA_CONTROL; | 339 | uint32_t D3VGA_CONTROL; |
| 339 | uint32_t D4VGA_CONTROL; | 340 | uint32_t D4VGA_CONTROL; |
| 341 | uint32_t VGA_TEST_CONTROL; | ||
| 340 | /* MMHUB registers. read only. temporary hack */ | 342 | /* MMHUB registers. read only. temporary hack */ |
| 341 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32; | 343 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32; |
| 342 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; | 344 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; |
| @@ -493,6 +495,9 @@ struct dce_hwseq_registers { | |||
| 493 | HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ | 495 | HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ |
| 494 | HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ | 496 | HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ |
| 495 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ | 497 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ |
| 498 | HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\ | ||
| 499 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ | ||
| 500 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh),\ | ||
| 496 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ | 501 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ |
| 497 | HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) | 502 | HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) |
| 498 | 503 | ||
| @@ -583,7 +588,10 @@ struct dce_hwseq_registers { | |||
| 583 | type DCFCLK_GATE_DIS; \ | 588 | type DCFCLK_GATE_DIS; \ |
| 584 | type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ | 589 | type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ |
| 585 | type DENTIST_DPPCLK_WDIVIDER; \ | 590 | type DENTIST_DPPCLK_WDIVIDER; \ |
| 586 | type DENTIST_DISPCLK_WDIVIDER; | 591 | type DENTIST_DISPCLK_WDIVIDER; \ |
| 592 | type VGA_TEST_ENABLE; \ | ||
| 593 | type VGA_TEST_RENDER_START; \ | ||
| 594 | type D1VGA_MODE_ENABLE; | ||
| 587 | 595 | ||
| 588 | struct dce_hwseq_shift { | 596 | struct dce_hwseq_shift { |
| 589 | HWSEQ_REG_FIELD_LIST(uint8_t) | 597 | HWSEQ_REG_FIELD_LIST(uint8_t) |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index a266e3f5e75f..e4741f1a2b01 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | |||
| @@ -82,13 +82,6 @@ | |||
| 82 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 | 82 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 |
| 83 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 | 83 | #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 |
| 84 | 84 | ||
| 85 | /* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */ | ||
| 86 | #define TMDS_MIN_PIXEL_CLOCK 25000 | ||
| 87 | /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */ | ||
| 88 | #define TMDS_MAX_PIXEL_CLOCK 165000 | ||
| 89 | /* For current ASICs pixel clock - 600MHz */ | ||
| 90 | #define MAX_ENCODER_CLOCK 600000 | ||
| 91 | |||
| 92 | enum { | 85 | enum { |
| 93 | DP_MST_UPDATE_MAX_RETRY = 50 | 86 | DP_MST_UPDATE_MAX_RETRY = 50 |
| 94 | }; | 87 | }; |
| @@ -683,6 +676,7 @@ void dce110_link_encoder_construct( | |||
| 683 | { | 676 | { |
| 684 | struct bp_encoder_cap_info bp_cap_info = {0}; | 677 | struct bp_encoder_cap_info bp_cap_info = {0}; |
| 685 | const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; | 678 | const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; |
| 679 | enum bp_result result = BP_RESULT_OK; | ||
| 686 | 680 | ||
| 687 | enc110->base.funcs = &dce110_lnk_enc_funcs; | 681 | enc110->base.funcs = &dce110_lnk_enc_funcs; |
| 688 | enc110->base.ctx = init_data->ctx; | 682 | enc110->base.ctx = init_data->ctx; |
| @@ -757,15 +751,24 @@ void dce110_link_encoder_construct( | |||
| 757 | enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; | 751 | enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; |
| 758 | } | 752 | } |
| 759 | 753 | ||
| 754 | /* default to one to mirror Windows behavior */ | ||
| 755 | enc110->base.features.flags.bits.HDMI_6GB_EN = 1; | ||
| 756 | |||
| 757 | result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios, | ||
| 758 | enc110->base.id, &bp_cap_info); | ||
| 759 | |||
| 760 | /* Override features with DCE-specific values */ | 760 | /* Override features with DCE-specific values */ |
| 761 | if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info( | 761 | if (BP_RESULT_OK == result) { |
| 762 | enc110->base.ctx->dc_bios, enc110->base.id, | ||
| 763 | &bp_cap_info)) { | ||
| 764 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = | 762 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = |
| 765 | bp_cap_info.DP_HBR2_EN; | 763 | bp_cap_info.DP_HBR2_EN; |
| 766 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = | 764 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = |
| 767 | bp_cap_info.DP_HBR3_EN; | 765 | bp_cap_info.DP_HBR3_EN; |
| 768 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; | 766 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; |
| 767 | } else { | ||
| 768 | dm_logger_write(enc110->base.ctx->logger, LOG_WARNING, | ||
| 769 | "%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", | ||
| 770 | __func__, | ||
| 771 | result); | ||
| 769 | } | 772 | } |
| 770 | } | 773 | } |
| 771 | 774 | ||
| @@ -904,8 +907,7 @@ void dce110_link_encoder_enable_tmds_output( | |||
| 904 | struct link_encoder *enc, | 907 | struct link_encoder *enc, |
| 905 | enum clock_source_id clock_source, | 908 | enum clock_source_id clock_source, |
| 906 | enum dc_color_depth color_depth, | 909 | enum dc_color_depth color_depth, |
| 907 | bool hdmi, | 910 | enum signal_type signal, |
| 908 | bool dual_link, | ||
| 909 | uint32_t pixel_clock) | 911 | uint32_t pixel_clock) |
| 910 | { | 912 | { |
| 911 | struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); | 913 | struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); |
| @@ -919,16 +921,12 @@ void dce110_link_encoder_enable_tmds_output( | |||
| 919 | cntl.engine_id = enc->preferred_engine; | 921 | cntl.engine_id = enc->preferred_engine; |
| 920 | cntl.transmitter = enc110->base.transmitter; | 922 | cntl.transmitter = enc110->base.transmitter; |
| 921 | cntl.pll_id = clock_source; | 923 | cntl.pll_id = clock_source; |
| 922 | if (hdmi) { | 924 | cntl.signal = signal; |
| 923 | cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A; | 925 | if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK) |
| 924 | cntl.lanes_number = 4; | ||
| 925 | } else if (dual_link) { | ||
| 926 | cntl.signal = SIGNAL_TYPE_DVI_DUAL_LINK; | ||
| 927 | cntl.lanes_number = 8; | 926 | cntl.lanes_number = 8; |
| 928 | } else { | 927 | else |
| 929 | cntl.signal = SIGNAL_TYPE_DVI_SINGLE_LINK; | ||
| 930 | cntl.lanes_number = 4; | 928 | cntl.lanes_number = 4; |
| 931 | } | 929 | |
| 932 | cntl.hpd_sel = enc110->base.hpd_source; | 930 | cntl.hpd_sel = enc110->base.hpd_source; |
| 933 | 931 | ||
| 934 | cntl.pixel_clock = pixel_clock; | 932 | cntl.pixel_clock = pixel_clock; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index 8ca9afe47a2b..0ec3433d34b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h | |||
| @@ -210,8 +210,7 @@ void dce110_link_encoder_enable_tmds_output( | |||
| 210 | struct link_encoder *enc, | 210 | struct link_encoder *enc, |
| 211 | enum clock_source_id clock_source, | 211 | enum clock_source_id clock_source, |
| 212 | enum dc_color_depth color_depth, | 212 | enum dc_color_depth color_depth, |
| 213 | bool hdmi, | 213 | enum signal_type signal, |
| 214 | bool dual_link, | ||
| 215 | uint32_t pixel_clock); | 214 | uint32_t pixel_clock); |
| 216 | 215 | ||
| 217 | /* enables DP PHY output */ | 216 | /* enables DP PHY output */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 3ea43e2a9450..442dd2d93618 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | |||
| @@ -852,6 +852,7 @@ static bool construct( | |||
| 852 | dc->caps.max_downscale_ratio = 200; | 852 | dc->caps.max_downscale_ratio = 200; |
| 853 | dc->caps.i2c_speed_in_khz = 40; | 853 | dc->caps.i2c_speed_in_khz = 40; |
| 854 | dc->caps.max_cursor_size = 128; | 854 | dc->caps.max_cursor_size = 128; |
| 855 | dc->caps.dual_link_dvi = true; | ||
| 855 | 856 | ||
| 856 | for (i = 0; i < pool->base.pipe_count; i++) { | 857 | for (i = 0; i < pool->base.pipe_count; i++) { |
| 857 | pool->base.timing_generators[i] = | 858 | pool->base.timing_generators[i] = |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 86cdd7b4811f..6f382a3ac90f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
| @@ -688,15 +688,22 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) | |||
| 688 | struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; | 688 | struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; |
| 689 | struct dc_link *link = pipe_ctx->stream->sink->link; | 689 | struct dc_link *link = pipe_ctx->stream->sink->link; |
| 690 | 690 | ||
| 691 | /* 1. update AVI info frame (HDMI, DP) | 691 | |
| 692 | * we always need to update info frame | ||
| 693 | */ | ||
| 694 | uint32_t active_total_with_borders; | 692 | uint32_t active_total_with_borders; |
| 695 | uint32_t early_control = 0; | 693 | uint32_t early_control = 0; |
| 696 | struct timing_generator *tg = pipe_ctx->stream_res.tg; | 694 | struct timing_generator *tg = pipe_ctx->stream_res.tg; |
| 697 | 695 | ||
| 698 | /* TODOFPGA may change to hwss.update_info_frame */ | 696 | /* For MST, there are multiply stream go to only one link. |
| 697 | * connect DIG back_end to front_end while enable_stream and | ||
| 698 | * disconnect them during disable_stream | ||
| 699 | * BY this, it is logic clean to separate stream and link */ | ||
| 700 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, | ||
| 701 | pipe_ctx->stream_res.stream_enc->id, true); | ||
| 702 | |||
| 703 | /* update AVI info frame (HDMI, DP)*/ | ||
| 704 | /* TODO: FPGA may change to hwss.update_info_frame */ | ||
| 699 | dce110_update_info_frame(pipe_ctx); | 705 | dce110_update_info_frame(pipe_ctx); |
| 706 | |||
| 700 | /* enable early control to avoid corruption on DP monitor*/ | 707 | /* enable early control to avoid corruption on DP monitor*/ |
| 701 | active_total_with_borders = | 708 | active_total_with_borders = |
| 702 | timing->h_addressable | 709 | timing->h_addressable |
| @@ -717,12 +724,8 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) | |||
| 717 | pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); | 724 | pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); |
| 718 | } | 725 | } |
| 719 | 726 | ||
| 720 | /* For MST, there are multiply stream go to only one link. | 727 | |
| 721 | * connect DIG back_end to front_end while enable_stream and | 728 | |
| 722 | * disconnect them during disable_stream | ||
| 723 | * BY this, it is logic clean to separate stream and link */ | ||
| 724 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, | ||
| 725 | pipe_ctx->stream_res.stream_enc->id, true); | ||
| 726 | 729 | ||
| 727 | } | 730 | } |
| 728 | 731 | ||
| @@ -1690,9 +1693,13 @@ static void apply_min_clocks( | |||
| 1690 | * Check if FBC can be enabled | 1693 | * Check if FBC can be enabled |
| 1691 | */ | 1694 | */ |
| 1692 | static bool should_enable_fbc(struct dc *dc, | 1695 | static bool should_enable_fbc(struct dc *dc, |
| 1693 | struct dc_state *context) | 1696 | struct dc_state *context, |
| 1697 | uint32_t *pipe_idx) | ||
| 1694 | { | 1698 | { |
| 1695 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0]; | 1699 | uint32_t i; |
| 1700 | struct pipe_ctx *pipe_ctx = NULL; | ||
| 1701 | struct resource_context *res_ctx = &context->res_ctx; | ||
| 1702 | |||
| 1696 | 1703 | ||
| 1697 | ASSERT(dc->fbc_compressor); | 1704 | ASSERT(dc->fbc_compressor); |
| 1698 | 1705 | ||
| @@ -1704,6 +1711,14 @@ static bool should_enable_fbc(struct dc *dc, | |||
| 1704 | if (context->stream_count != 1) | 1711 | if (context->stream_count != 1) |
| 1705 | return false; | 1712 | return false; |
| 1706 | 1713 | ||
| 1714 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
| 1715 | if (res_ctx->pipe_ctx[i].stream) { | ||
| 1716 | pipe_ctx = &res_ctx->pipe_ctx[i]; | ||
| 1717 | *pipe_idx = i; | ||
| 1718 | break; | ||
| 1719 | } | ||
| 1720 | } | ||
| 1721 | |||
| 1707 | /* Only supports eDP */ | 1722 | /* Only supports eDP */ |
| 1708 | if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) | 1723 | if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) |
| 1709 | return false; | 1724 | return false; |
| @@ -1729,11 +1744,14 @@ static bool should_enable_fbc(struct dc *dc, | |||
| 1729 | static void enable_fbc(struct dc *dc, | 1744 | static void enable_fbc(struct dc *dc, |
| 1730 | struct dc_state *context) | 1745 | struct dc_state *context) |
| 1731 | { | 1746 | { |
| 1732 | if (should_enable_fbc(dc, context)) { | 1747 | uint32_t pipe_idx = 0; |
| 1748 | |||
| 1749 | if (should_enable_fbc(dc, context, &pipe_idx)) { | ||
| 1733 | /* Program GRPH COMPRESSED ADDRESS and PITCH */ | 1750 | /* Program GRPH COMPRESSED ADDRESS and PITCH */ |
| 1734 | struct compr_addr_and_pitch_params params = {0, 0, 0}; | 1751 | struct compr_addr_and_pitch_params params = {0, 0, 0}; |
| 1735 | struct compressor *compr = dc->fbc_compressor; | 1752 | struct compressor *compr = dc->fbc_compressor; |
| 1736 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0]; | 1753 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; |
| 1754 | |||
| 1737 | 1755 | ||
| 1738 | params.source_view_width = pipe_ctx->stream->timing.h_addressable; | 1756 | params.source_view_width = pipe_ctx->stream->timing.h_addressable; |
| 1739 | params.source_view_height = pipe_ctx->stream->timing.v_addressable; | 1757 | params.source_view_height = pipe_ctx->stream->timing.v_addressable; |
| @@ -2915,6 +2933,49 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, | |||
| 2915 | } | 2933 | } |
| 2916 | } | 2934 | } |
| 2917 | 2935 | ||
| 2936 | void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) | ||
| 2937 | { | ||
| 2938 | struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; | ||
| 2939 | struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; | ||
| 2940 | struct mem_input *mi = pipe_ctx->plane_res.mi; | ||
| 2941 | struct dc_cursor_mi_param param = { | ||
| 2942 | .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, | ||
| 2943 | .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, | ||
| 2944 | .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, | ||
| 2945 | .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, | ||
| 2946 | .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz | ||
| 2947 | }; | ||
| 2948 | |||
| 2949 | if (pipe_ctx->plane_state->address.type | ||
| 2950 | == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) | ||
| 2951 | pos_cpy.enable = false; | ||
| 2952 | |||
| 2953 | if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) | ||
| 2954 | pos_cpy.enable = false; | ||
| 2955 | |||
| 2956 | if (ipp->funcs->ipp_cursor_set_position) | ||
| 2957 | ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); | ||
| 2958 | if (mi->funcs->set_cursor_position) | ||
| 2959 | mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); | ||
| 2960 | } | ||
| 2961 | |||
| 2962 | void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) | ||
| 2963 | { | ||
| 2964 | struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; | ||
| 2965 | |||
| 2966 | if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) | ||
| 2967 | pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( | ||
| 2968 | pipe_ctx->plane_res.ipp, attributes); | ||
| 2969 | |||
| 2970 | if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) | ||
| 2971 | pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( | ||
| 2972 | pipe_ctx->plane_res.mi, attributes); | ||
| 2973 | |||
| 2974 | if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) | ||
| 2975 | pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( | ||
| 2976 | pipe_ctx->plane_res.xfm, attributes); | ||
| 2977 | } | ||
| 2978 | |||
| 2918 | static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} | 2979 | static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} |
| 2919 | 2980 | ||
| 2920 | static void optimize_shared_resources(struct dc *dc) {} | 2981 | static void optimize_shared_resources(struct dc *dc) {} |
| @@ -2957,6 +3018,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { | |||
| 2957 | .edp_backlight_control = hwss_edp_backlight_control, | 3018 | .edp_backlight_control = hwss_edp_backlight_control, |
| 2958 | .edp_power_control = hwss_edp_power_control, | 3019 | .edp_power_control = hwss_edp_power_control, |
| 2959 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, | 3020 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, |
| 3021 | .set_cursor_position = dce110_set_cursor_position, | ||
| 3022 | .set_cursor_attribute = dce110_set_cursor_attribute | ||
| 2960 | }; | 3023 | }; |
| 2961 | 3024 | ||
| 2962 | void dce110_hw_sequencer_construct(struct dc *dc) | 3025 | void dce110_hw_sequencer_construct(struct dc *dc) |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 7c4779578fb7..00f18c485e1e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | |||
| @@ -846,6 +846,16 @@ static bool dce110_validate_bandwidth( | |||
| 846 | return result; | 846 | return result; |
| 847 | } | 847 | } |
| 848 | 848 | ||
| 849 | enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state, | ||
| 850 | struct dc_caps *caps) | ||
| 851 | { | ||
| 852 | if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) || | ||
| 853 | ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height)) | ||
| 854 | return DC_FAIL_SURFACE_VALIDATE; | ||
| 855 | |||
| 856 | return DC_OK; | ||
| 857 | } | ||
| 858 | |||
| 849 | static bool dce110_validate_surface_sets( | 859 | static bool dce110_validate_surface_sets( |
| 850 | struct dc_state *context) | 860 | struct dc_state *context) |
| 851 | { | 861 | { |
| @@ -869,6 +879,13 @@ static bool dce110_validate_surface_sets( | |||
| 869 | plane->src_rect.height > 1080)) | 879 | plane->src_rect.height > 1080)) |
| 870 | return false; | 880 | return false; |
| 871 | 881 | ||
| 882 | /* we don't have the logic to support underlay | ||
| 883 | * only yet so block the use case where we get | ||
| 884 | * NV12 plane as top layer | ||
| 885 | */ | ||
| 886 | if (j == 0) | ||
| 887 | return false; | ||
| 888 | |||
| 872 | /* irrespective of plane format, | 889 | /* irrespective of plane format, |
| 873 | * stream should be RGB encoded | 890 | * stream should be RGB encoded |
| 874 | */ | 891 | */ |
| @@ -1021,6 +1038,7 @@ static const struct resource_funcs dce110_res_pool_funcs = { | |||
| 1021 | .link_enc_create = dce110_link_encoder_create, | 1038 | .link_enc_create = dce110_link_encoder_create, |
| 1022 | .validate_guaranteed = dce110_validate_guaranteed, | 1039 | .validate_guaranteed = dce110_validate_guaranteed, |
| 1023 | .validate_bandwidth = dce110_validate_bandwidth, | 1040 | .validate_bandwidth = dce110_validate_bandwidth, |
| 1041 | .validate_plane = dce110_validate_plane, | ||
| 1024 | .acquire_idle_pipe_for_layer = dce110_acquire_underlay, | 1042 | .acquire_idle_pipe_for_layer = dce110_acquire_underlay, |
| 1025 | .add_stream_to_ctx = dce110_add_stream_to_ctx, | 1043 | .add_stream_to_ctx = dce110_add_stream_to_ctx, |
| 1026 | .validate_global = dce110_validate_global | 1044 | .validate_global = dce110_validate_global |
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 663e0a047a4b..98d9cd0109e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | |||
| @@ -1103,6 +1103,8 @@ static bool construct( | |||
| 1103 | dc->caps.max_downscale_ratio = 200; | 1103 | dc->caps.max_downscale_ratio = 200; |
| 1104 | dc->caps.i2c_speed_in_khz = 100; | 1104 | dc->caps.i2c_speed_in_khz = 100; |
| 1105 | dc->caps.max_cursor_size = 128; | 1105 | dc->caps.max_cursor_size = 128; |
| 1106 | dc->caps.dual_link_dvi = true; | ||
| 1107 | |||
| 1106 | 1108 | ||
| 1107 | /************************************************* | 1109 | /************************************************* |
| 1108 | * Create resources * | 1110 | * Create resources * |
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 57cd67359567..5aab01db28ee 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c | |||
| @@ -835,6 +835,8 @@ static bool construct( | |||
| 835 | dc->caps.max_downscale_ratio = 200; | 835 | dc->caps.max_downscale_ratio = 200; |
| 836 | dc->caps.i2c_speed_in_khz = 100; | 836 | dc->caps.i2c_speed_in_khz = 100; |
| 837 | dc->caps.max_cursor_size = 128; | 837 | dc->caps.max_cursor_size = 128; |
| 838 | dc->caps.dual_link_dvi = true; | ||
| 839 | |||
| 838 | dc->debug = debug_defaults; | 840 | dc->debug = debug_defaults; |
| 839 | 841 | ||
| 840 | /************************************************* | 842 | /************************************************* |
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 8f2bd56f3461..25d7eb1567ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | |||
| @@ -793,6 +793,7 @@ static bool dce80_construct( | |||
| 793 | dc->caps.max_downscale_ratio = 200; | 793 | dc->caps.max_downscale_ratio = 200; |
| 794 | dc->caps.i2c_speed_in_khz = 40; | 794 | dc->caps.i2c_speed_in_khz = 40; |
| 795 | dc->caps.max_cursor_size = 128; | 795 | dc->caps.max_cursor_size = 128; |
| 796 | dc->caps.dual_link_dvi = true; | ||
| 796 | 797 | ||
| 797 | /************************************************* | 798 | /************************************************* |
| 798 | * Create resources * | 799 | * Create resources * |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 82572863acab..072e4485e85e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | |||
| @@ -238,10 +238,24 @@ static void enable_power_gating_plane( | |||
| 238 | static void disable_vga( | 238 | static void disable_vga( |
| 239 | struct dce_hwseq *hws) | 239 | struct dce_hwseq *hws) |
| 240 | { | 240 | { |
| 241 | unsigned int in_vga_mode = 0; | ||
| 242 | |||
| 243 | REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga_mode); | ||
| 244 | |||
| 245 | if (in_vga_mode == 0) | ||
| 246 | return; | ||
| 247 | |||
| 241 | REG_WRITE(D1VGA_CONTROL, 0); | 248 | REG_WRITE(D1VGA_CONTROL, 0); |
| 242 | REG_WRITE(D2VGA_CONTROL, 0); | 249 | |
| 243 | REG_WRITE(D3VGA_CONTROL, 0); | 250 | /* HW Engineer's Notes: |
| 244 | REG_WRITE(D4VGA_CONTROL, 0); | 251 | * During switch from vga->extended, if we set the VGA_TEST_ENABLE and |
| 252 | * then hit the VGA_TEST_RENDER_START, then the DCHUBP timing gets updated correctly. | ||
| 253 | * | ||
| 254 | * Then vBIOS will have it poll for the VGA_TEST_RENDER_DONE and unset | ||
| 255 | * VGA_TEST_ENABLE, to leave it in the same state as before. | ||
| 256 | */ | ||
| 257 | REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_ENABLE, 1); | ||
| 258 | REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1); | ||
| 245 | } | 259 | } |
| 246 | 260 | ||
| 247 | static void dpp_pg_control( | 261 | static void dpp_pg_control( |
| @@ -1761,6 +1775,11 @@ static void update_dchubp_dpp( | |||
| 1761 | &pipe_ctx->plane_res.scl_data.viewport_c); | 1775 | &pipe_ctx->plane_res.scl_data.viewport_c); |
| 1762 | } | 1776 | } |
| 1763 | 1777 | ||
| 1778 | if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) { | ||
| 1779 | dc->hwss.set_cursor_position(pipe_ctx); | ||
| 1780 | dc->hwss.set_cursor_attribute(pipe_ctx); | ||
| 1781 | } | ||
| 1782 | |||
| 1764 | if (plane_state->update_flags.bits.full_update) { | 1783 | if (plane_state->update_flags.bits.full_update) { |
| 1765 | /*gamut remap*/ | 1784 | /*gamut remap*/ |
| 1766 | program_gamut_remap(pipe_ctx); | 1785 | program_gamut_remap(pipe_ctx); |
| @@ -2296,7 +2315,7 @@ static bool dcn10_dummy_display_power_gating( | |||
| 2296 | return true; | 2315 | return true; |
| 2297 | } | 2316 | } |
| 2298 | 2317 | ||
| 2299 | void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) | 2318 | static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) |
| 2300 | { | 2319 | { |
| 2301 | struct dc_plane_state *plane_state = pipe_ctx->plane_state; | 2320 | struct dc_plane_state *plane_state = pipe_ctx->plane_state; |
| 2302 | struct timing_generator *tg = pipe_ctx->stream_res.tg; | 2321 | struct timing_generator *tg = pipe_ctx->stream_res.tg; |
| @@ -2316,12 +2335,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) | |||
| 2316 | } | 2335 | } |
| 2317 | } | 2336 | } |
| 2318 | 2337 | ||
| 2319 | void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) | 2338 | static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) |
| 2320 | { | 2339 | { |
| 2321 | if (hws->ctx->dc->res_pool->hubbub != NULL) | 2340 | if (hws->ctx->dc->res_pool->hubbub != NULL) |
| 2322 | hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); | 2341 | hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data); |
| 2323 | } | 2342 | } |
| 2324 | 2343 | ||
| 2344 | static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) | ||
| 2345 | { | ||
| 2346 | struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; | ||
| 2347 | struct hubp *hubp = pipe_ctx->plane_res.hubp; | ||
| 2348 | struct dpp *dpp = pipe_ctx->plane_res.dpp; | ||
| 2349 | struct dc_cursor_mi_param param = { | ||
| 2350 | .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, | ||
| 2351 | .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, | ||
| 2352 | .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, | ||
| 2353 | .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, | ||
| 2354 | .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz | ||
| 2355 | }; | ||
| 2356 | |||
| 2357 | if (pipe_ctx->plane_state->address.type | ||
| 2358 | == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) | ||
| 2359 | pos_cpy.enable = false; | ||
| 2360 | |||
| 2361 | if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) | ||
| 2362 | pos_cpy.enable = false; | ||
| 2363 | |||
| 2364 | hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); | ||
| 2365 | dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, hubp->curs_attr.width); | ||
| 2366 | } | ||
| 2367 | |||
| 2368 | static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx) | ||
| 2369 | { | ||
| 2370 | struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; | ||
| 2371 | |||
| 2372 | pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes( | ||
| 2373 | pipe_ctx->plane_res.hubp, attributes); | ||
| 2374 | pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes( | ||
| 2375 | pipe_ctx->plane_res.dpp, attributes->color_format); | ||
| 2376 | } | ||
| 2377 | |||
| 2325 | static const struct hw_sequencer_funcs dcn10_funcs = { | 2378 | static const struct hw_sequencer_funcs dcn10_funcs = { |
| 2326 | .program_gamut_remap = program_gamut_remap, | 2379 | .program_gamut_remap = program_gamut_remap, |
| 2327 | .program_csc_matrix = program_csc_matrix, | 2380 | .program_csc_matrix = program_csc_matrix, |
| @@ -2362,6 +2415,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { | |||
| 2362 | .edp_backlight_control = hwss_edp_backlight_control, | 2415 | .edp_backlight_control = hwss_edp_backlight_control, |
| 2363 | .edp_power_control = hwss_edp_power_control, | 2416 | .edp_power_control = hwss_edp_power_control, |
| 2364 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, | 2417 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, |
| 2418 | .set_cursor_position = dcn10_set_cursor_position, | ||
| 2419 | .set_cursor_attribute = dcn10_set_cursor_attribute | ||
| 2365 | }; | 2420 | }; |
| 2366 | 2421 | ||
| 2367 | 2422 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index 0fd329deacd8..54d8a1386142 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h | |||
| @@ -123,8 +123,7 @@ struct link_encoder_funcs { | |||
| 123 | void (*enable_tmds_output)(struct link_encoder *enc, | 123 | void (*enable_tmds_output)(struct link_encoder *enc, |
| 124 | enum clock_source_id clock_source, | 124 | enum clock_source_id clock_source, |
| 125 | enum dc_color_depth color_depth, | 125 | enum dc_color_depth color_depth, |
| 126 | bool hdmi, | 126 | enum signal_type signal, |
| 127 | bool dual_link, | ||
| 128 | uint32_t pixel_clock); | 127 | uint32_t pixel_clock); |
| 129 | void (*enable_dp_output)(struct link_encoder *enc, | 128 | void (*enable_dp_output)(struct link_encoder *enc, |
| 130 | const struct dc_link_settings *link_settings, | 129 | const struct dc_link_settings *link_settings, |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 4c0aa56f7bae..379c6ecd271a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | |||
| @@ -198,6 +198,9 @@ struct hw_sequencer_funcs { | |||
| 198 | bool enable); | 198 | bool enable); |
| 199 | void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); | 199 | void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up); |
| 200 | 200 | ||
| 201 | void (*set_cursor_position)(struct pipe_ctx *pipe); | ||
| 202 | void (*set_cursor_attribute)(struct pipe_ctx *pipe); | ||
| 203 | |||
| 201 | }; | 204 | }; |
| 202 | 205 | ||
| 203 | void color_space_to_black_color( | 206 | void color_space_to_black_color( |
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c index f7e40b292dfb..d3e1923b01a8 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c | |||
| @@ -217,7 +217,7 @@ bool dce110_vblank_set( | |||
| 217 | core_dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg; | 217 | core_dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg; |
| 218 | 218 | ||
| 219 | if (enable) { | 219 | if (enable) { |
| 220 | if (!tg->funcs->arm_vert_intr(tg, 2)) { | 220 | if (!tg || !tg->funcs->arm_vert_intr(tg, 2)) { |
| 221 | DC_ERROR("Failed to get VBLANK!\n"); | 221 | DC_ERROR("Failed to get VBLANK!\n"); |
| 222 | return false; | 222 | return false; |
| 223 | } | 223 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c index 57a54a7b89e5..1c079ba37c30 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c | |||
| @@ -42,8 +42,7 @@ static void virtual_link_encoder_enable_tmds_output( | |||
| 42 | struct link_encoder *enc, | 42 | struct link_encoder *enc, |
| 43 | enum clock_source_id clock_source, | 43 | enum clock_source_id clock_source, |
| 44 | enum dc_color_depth color_depth, | 44 | enum dc_color_depth color_depth, |
| 45 | bool hdmi, | 45 | enum signal_type signal, |
| 46 | bool dual_link, | ||
| 47 | uint32_t pixel_clock) {} | 46 | uint32_t pixel_clock) {} |
| 48 | 47 | ||
| 49 | static void virtual_link_encoder_enable_dp_output( | 48 | static void virtual_link_encoder_enable_dp_output( |
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h index 7a9b43f84a31..36bbad594267 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h | |||
| @@ -419,11 +419,6 @@ struct bios_event_info { | |||
| 419 | bool backlight_changed; | 419 | bool backlight_changed; |
| 420 | }; | 420 | }; |
| 421 | 421 | ||
| 422 | enum { | ||
| 423 | HDMI_PIXEL_CLOCK_IN_KHZ_297 = 297000, | ||
| 424 | TMDS_PIXEL_CLOCK_IN_KHZ_165 = 165000 | ||
| 425 | }; | ||
| 426 | |||
| 427 | /* | 422 | /* |
| 428 | * DFS-bypass flag | 423 | * DFS-bypass flag |
| 429 | */ | 424 | */ |
diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h b/drivers/gpu/drm/amd/display/include/signal_types.h index b5ebde642207..199c5db67cbc 100644 --- a/drivers/gpu/drm/amd/display/include/signal_types.h +++ b/drivers/gpu/drm/amd/display/include/signal_types.h | |||
| @@ -26,6 +26,11 @@ | |||
| 26 | #ifndef __DC_SIGNAL_TYPES_H__ | 26 | #ifndef __DC_SIGNAL_TYPES_H__ |
| 27 | #define __DC_SIGNAL_TYPES_H__ | 27 | #define __DC_SIGNAL_TYPES_H__ |
| 28 | 28 | ||
| 29 | /* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */ | ||
| 30 | #define TMDS_MIN_PIXEL_CLOCK 25000 | ||
| 31 | /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */ | ||
| 32 | #define TMDS_MAX_PIXEL_CLOCK 165000 | ||
| 33 | |||
| 29 | enum signal_type { | 34 | enum signal_type { |
| 30 | SIGNAL_TYPE_NONE = 0L, /* no signal */ | 35 | SIGNAL_TYPE_NONE = 0L, /* no signal */ |
| 31 | SIGNAL_TYPE_DVI_SINGLE_LINK = (1 << 0), | 36 | SIGNAL_TYPE_DVI_SINGLE_LINK = (1 << 0), |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index d3045a371a55..7c73bc7e2f85 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -3221,35 +3221,8 @@ static void cik_gpu_init(struct radeon_device *rdev) | |||
| 3221 | case CHIP_KAVERI: | 3221 | case CHIP_KAVERI: |
| 3222 | rdev->config.cik.max_shader_engines = 1; | 3222 | rdev->config.cik.max_shader_engines = 1; |
| 3223 | rdev->config.cik.max_tile_pipes = 4; | 3223 | rdev->config.cik.max_tile_pipes = 4; |
| 3224 | if ((rdev->pdev->device == 0x1304) || | 3224 | rdev->config.cik.max_cu_per_sh = 8; |
| 3225 | (rdev->pdev->device == 0x1305) || | 3225 | rdev->config.cik.max_backends_per_se = 2; |
| 3226 | (rdev->pdev->device == 0x130C) || | ||
| 3227 | (rdev->pdev->device == 0x130F) || | ||
| 3228 | (rdev->pdev->device == 0x1310) || | ||
| 3229 | (rdev->pdev->device == 0x1311) || | ||
| 3230 | (rdev->pdev->device == 0x131C)) { | ||
| 3231 | rdev->config.cik.max_cu_per_sh = 8; | ||
| 3232 | rdev->config.cik.max_backends_per_se = 2; | ||
| 3233 | } else if ((rdev->pdev->device == 0x1309) || | ||
| 3234 | (rdev->pdev->device == 0x130A) || | ||
| 3235 | (rdev->pdev->device == 0x130D) || | ||
| 3236 | (rdev->pdev->device == 0x1313) || | ||
| 3237 | (rdev->pdev->device == 0x131D)) { | ||
| 3238 | rdev->config.cik.max_cu_per_sh = 6; | ||
| 3239 | rdev->config.cik.max_backends_per_se = 2; | ||
| 3240 | } else if ((rdev->pdev->device == 0x1306) || | ||
| 3241 | (rdev->pdev->device == 0x1307) || | ||
| 3242 | (rdev->pdev->device == 0x130B) || | ||
| 3243 | (rdev->pdev->device == 0x130E) || | ||
| 3244 | (rdev->pdev->device == 0x1315) || | ||
| 3245 | (rdev->pdev->device == 0x1318) || | ||
| 3246 | (rdev->pdev->device == 0x131B)) { | ||
| 3247 | rdev->config.cik.max_cu_per_sh = 4; | ||
| 3248 | rdev->config.cik.max_backends_per_se = 1; | ||
| 3249 | } else { | ||
| 3250 | rdev->config.cik.max_cu_per_sh = 3; | ||
| 3251 | rdev->config.cik.max_backends_per_se = 1; | ||
| 3252 | } | ||
| 3253 | rdev->config.cik.max_sh_per_se = 1; | 3226 | rdev->config.cik.max_sh_per_se = 1; |
| 3254 | rdev->config.cik.max_texture_channel_caches = 4; | 3227 | rdev->config.cik.max_texture_channel_caches = 4; |
| 3255 | rdev->config.cik.max_gprs = 256; | 3228 | rdev->config.cik.max_gprs = 256; |
