diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-24 12:12:46 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-24 12:12:46 -0400 |
| commit | a3b25d157d5a52ef3f9296a739ee28f5d36e8968 (patch) | |
| tree | 5359f2589f5ee25bb4532b6692364f1940f65817 | |
| parent | 4dde821e4296e156d133b98ddc4c45861935a4fb (diff) | |
| parent | c074989171801171af6c5f53dd16b27f36b31deb (diff) | |
Merge tag 'drm-fixes-2019-05-24-1' of git://anongit.freedesktop.org/drm/drm
Pull drm fixes from Dave Airlie:
"Nothing too unusual here for rc2. Except the amdgpu DMCU firmware
loading fix caused build breakage with a different set of Kconfig
options. I've just reverted it for now until the AMD folks can rewrite
it to avoid that problem.
i915:
- boosting fix
- bump ready task fixes
- GVT - reset fix, error return, TRTT handling fix
amdgpu:
- DMCU firmware loading fix
- Polaris 10 pci id for kfd
- picasso screen corruption fix
- SR-IOV fixes
- vega driver reload fixes
- SMU locking fix
- compute profile fix for kfd
vmwgfx:
- integer overflow fixes
- dma sg fix
sun4i:
- HDMI phy fixes
gma500:
- LVDS detection fix
panfrost:
- devfreq selection fix"
* tag 'drm-fixes-2019-05-24-1' of git://anongit.freedesktop.org/drm/drm: (32 commits)
Revert "drm/amd/display: Don't load DMCU for Raven 1"
drm/panfrost: Select devfreq
drm/gma500/cdv: Check vbt config bits when detecting lvds panels
drm/vmwgfx: integer underflow in vmw_cmd_dx_set_shader() leading to an invalid read
drm/vmwgfx: NULL pointer dereference from vmw_cmd_dx_view_define()
drm/vmwgfx: Use the dma scatter-gather iterator to get dma addresses
drm/vmwgfx: Fix compat mode shader operation
drm/vmwgfx: Fix user space handle equal to zero
drm/vmwgfx: Don't send drm sysfs hotplug events on initial master set
drm/i915/gvt: Fix an error code in ppgtt_populate_spt_by_guest_entry()
drm/i915/gvt: do not let TRTTE and 0x4dfc write passthrough to hardware
drm/i915/gvt: add 0x4dfc to gen9 save-restore list
drm/i915/gvt: Tiled Resources mmios are in-context mmios for gen9+
drm/i915/gvt: use cmd to restore in-context mmios to hw for gen9 platform
drm/i915/gvt: emit init breadcrumb for gvt request
drm/amdkfd: Fix compute profile switching
drm/amdgpu: skip fw pri bo alloc for SRIOV
drm/amd/powerplay: fix locking in smu_feature_set_supported()
drm/amdgpu/gmc9: set vram_width properly for SR-IOV
drm/amdgpu/soc15: skip reset on init
...
31 files changed, 326 insertions, 263 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 05897b05766b..86cc24b2e0aa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
| @@ -877,13 +877,16 @@ static int psp_load_fw(struct amdgpu_device *adev) | |||
| 877 | if (!psp->cmd) | 877 | if (!psp->cmd) |
| 878 | return -ENOMEM; | 878 | return -ENOMEM; |
| 879 | 879 | ||
| 880 | ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, | 880 | /* this fw pri bo is not used under SRIOV */ |
| 881 | AMDGPU_GEM_DOMAIN_GTT, | 881 | if (!amdgpu_sriov_vf(psp->adev)) { |
| 882 | &psp->fw_pri_bo, | 882 | ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, |
| 883 | &psp->fw_pri_mc_addr, | 883 | AMDGPU_GEM_DOMAIN_GTT, |
| 884 | &psp->fw_pri_buf); | 884 | &psp->fw_pri_bo, |
| 885 | if (ret) | 885 | &psp->fw_pri_mc_addr, |
| 886 | goto failed; | 886 | &psp->fw_pri_buf); |
| 887 | if (ret) | ||
| 888 | goto failed; | ||
| 889 | } | ||
| 887 | 890 | ||
| 888 | ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, | 891 | ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, |
| 889 | AMDGPU_GEM_DOMAIN_VRAM, | 892 | AMDGPU_GEM_DOMAIN_VRAM, |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 3fd79e07944d..3b7370d914a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | |||
| @@ -626,6 +626,7 @@ static bool gmc_v9_0_keep_stolen_memory(struct amdgpu_device *adev) | |||
| 626 | case CHIP_VEGA10: | 626 | case CHIP_VEGA10: |
| 627 | return true; | 627 | return true; |
| 628 | case CHIP_RAVEN: | 628 | case CHIP_RAVEN: |
| 629 | return (adev->pdev->device == 0x15d8); | ||
| 629 | case CHIP_VEGA12: | 630 | case CHIP_VEGA12: |
| 630 | case CHIP_VEGA20: | 631 | case CHIP_VEGA20: |
| 631 | default: | 632 | default: |
| @@ -812,8 +813,16 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev) | |||
| 812 | int chansize, numchan; | 813 | int chansize, numchan; |
| 813 | int r; | 814 | int r; |
| 814 | 815 | ||
| 815 | if (amdgpu_emu_mode != 1) | 816 | if (amdgpu_sriov_vf(adev)) { |
| 817 | /* For Vega10 SR-IOV, vram_width can't be read from ATOM as RAVEN, | ||
| 818 | * and DF related registers is not readable, seems hardcord is the | ||
| 819 | * only way to set the correct vram_width | ||
| 820 | */ | ||
| 821 | adev->gmc.vram_width = 2048; | ||
| 822 | } else if (amdgpu_emu_mode != 1) { | ||
| 816 | adev->gmc.vram_width = amdgpu_atomfirmware_get_vram_width(adev); | 823 | adev->gmc.vram_width = amdgpu_atomfirmware_get_vram_width(adev); |
| 824 | } | ||
| 825 | |||
| 817 | if (!adev->gmc.vram_width) { | 826 | if (!adev->gmc.vram_width) { |
| 818 | /* hbm memory channel size */ | 827 | /* hbm memory channel size */ |
| 819 | if (adev->flags & AMD_IS_APU) | 828 | if (adev->flags & AMD_IS_APU) |
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 4900e4958dec..b7e594c2bfb4 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c | |||
| @@ -730,6 +730,11 @@ static bool soc15_need_reset_on_init(struct amdgpu_device *adev) | |||
| 730 | { | 730 | { |
| 731 | u32 sol_reg; | 731 | u32 sol_reg; |
| 732 | 732 | ||
| 733 | /* Just return false for soc15 GPUs. Reset does not seem to | ||
| 734 | * be necessary. | ||
| 735 | */ | ||
| 736 | return false; | ||
| 737 | |||
| 733 | if (adev->flags & AMD_IS_APU) | 738 | if (adev->flags & AMD_IS_APU) |
| 734 | return false; | 739 | return false; |
| 735 | 740 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index c1e4d44d6137..765b58a17dc7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c | |||
| @@ -355,6 +355,7 @@ static const struct kfd_deviceid supported_devices[] = { | |||
| 355 | { 0x67CF, &polaris10_device_info }, /* Polaris10 */ | 355 | { 0x67CF, &polaris10_device_info }, /* Polaris10 */ |
| 356 | { 0x67D0, &polaris10_vf_device_info }, /* Polaris10 vf*/ | 356 | { 0x67D0, &polaris10_vf_device_info }, /* Polaris10 vf*/ |
| 357 | { 0x67DF, &polaris10_device_info }, /* Polaris10 */ | 357 | { 0x67DF, &polaris10_device_info }, /* Polaris10 */ |
| 358 | { 0x6FDF, &polaris10_device_info }, /* Polaris10 */ | ||
| 358 | { 0x67E0, &polaris11_device_info }, /* Polaris11 */ | 359 | { 0x67E0, &polaris11_device_info }, /* Polaris11 */ |
| 359 | { 0x67E1, &polaris11_device_info }, /* Polaris11 */ | 360 | { 0x67E1, &polaris11_device_info }, /* Polaris11 */ |
| 360 | { 0x67E3, &polaris11_device_info }, /* Polaris11 */ | 361 | { 0x67E3, &polaris11_device_info }, /* Polaris11 */ |
| @@ -462,6 +463,7 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, | |||
| 462 | kfd->pdev = pdev; | 463 | kfd->pdev = pdev; |
| 463 | kfd->init_complete = false; | 464 | kfd->init_complete = false; |
| 464 | kfd->kfd2kgd = f2g; | 465 | kfd->kfd2kgd = f2g; |
| 466 | atomic_set(&kfd->compute_profile, 0); | ||
| 465 | 467 | ||
| 466 | mutex_init(&kfd->doorbell_mutex); | 468 | mutex_init(&kfd->doorbell_mutex); |
| 467 | memset(&kfd->doorbell_available_index, 0, | 469 | memset(&kfd->doorbell_available_index, 0, |
| @@ -1036,6 +1038,21 @@ void kgd2kfd_set_sram_ecc_flag(struct kfd_dev *kfd) | |||
| 1036 | atomic_inc(&kfd->sram_ecc_flag); | 1038 | atomic_inc(&kfd->sram_ecc_flag); |
| 1037 | } | 1039 | } |
| 1038 | 1040 | ||
| 1041 | void kfd_inc_compute_active(struct kfd_dev *kfd) | ||
| 1042 | { | ||
| 1043 | if (atomic_inc_return(&kfd->compute_profile) == 1) | ||
| 1044 | amdgpu_amdkfd_set_compute_idle(kfd->kgd, false); | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | void kfd_dec_compute_active(struct kfd_dev *kfd) | ||
| 1048 | { | ||
| 1049 | int count = atomic_dec_return(&kfd->compute_profile); | ||
| 1050 | |||
| 1051 | if (count == 0) | ||
| 1052 | amdgpu_amdkfd_set_compute_idle(kfd->kgd, true); | ||
| 1053 | WARN_ONCE(count < 0, "Compute profile ref. count error"); | ||
| 1054 | } | ||
| 1055 | |||
| 1039 | #if defined(CONFIG_DEBUG_FS) | 1056 | #if defined(CONFIG_DEBUG_FS) |
| 1040 | 1057 | ||
| 1041 | /* This function will send a package to HIQ to hang the HWS | 1058 | /* This function will send a package to HIQ to hang the HWS |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index c6c9530e704e..ae381450601c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
| @@ -811,8 +811,8 @@ static int register_process(struct device_queue_manager *dqm, | |||
| 811 | 811 | ||
| 812 | retval = dqm->asic_ops.update_qpd(dqm, qpd); | 812 | retval = dqm->asic_ops.update_qpd(dqm, qpd); |
| 813 | 813 | ||
| 814 | if (dqm->processes_count++ == 0) | 814 | dqm->processes_count++; |
| 815 | amdgpu_amdkfd_set_compute_idle(dqm->dev->kgd, false); | 815 | kfd_inc_compute_active(dqm->dev); |
| 816 | 816 | ||
| 817 | dqm_unlock(dqm); | 817 | dqm_unlock(dqm); |
| 818 | 818 | ||
| @@ -835,9 +835,8 @@ static int unregister_process(struct device_queue_manager *dqm, | |||
| 835 | if (qpd == cur->qpd) { | 835 | if (qpd == cur->qpd) { |
| 836 | list_del(&cur->list); | 836 | list_del(&cur->list); |
| 837 | kfree(cur); | 837 | kfree(cur); |
| 838 | if (--dqm->processes_count == 0) | 838 | dqm->processes_count--; |
| 839 | amdgpu_amdkfd_set_compute_idle( | 839 | kfd_dec_compute_active(dqm->dev); |
| 840 | dqm->dev->kgd, true); | ||
| 841 | goto out; | 840 | goto out; |
| 842 | } | 841 | } |
| 843 | } | 842 | } |
| @@ -1539,6 +1538,7 @@ static int process_termination_nocpsch(struct device_queue_manager *dqm, | |||
| 1539 | list_del(&cur->list); | 1538 | list_del(&cur->list); |
| 1540 | kfree(cur); | 1539 | kfree(cur); |
| 1541 | dqm->processes_count--; | 1540 | dqm->processes_count--; |
| 1541 | kfd_dec_compute_active(dqm->dev); | ||
| 1542 | break; | 1542 | break; |
| 1543 | } | 1543 | } |
| 1544 | } | 1544 | } |
| @@ -1626,6 +1626,7 @@ static int process_termination_cpsch(struct device_queue_manager *dqm, | |||
| 1626 | list_del(&cur->list); | 1626 | list_del(&cur->list); |
| 1627 | kfree(cur); | 1627 | kfree(cur); |
| 1628 | dqm->processes_count--; | 1628 | dqm->processes_count--; |
| 1629 | kfd_dec_compute_active(dqm->dev); | ||
| 1629 | break; | 1630 | break; |
| 1630 | } | 1631 | } |
| 1631 | } | 1632 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 9e0230965675..487d5da337c1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
| @@ -279,6 +279,9 @@ struct kfd_dev { | |||
| 279 | 279 | ||
| 280 | /* SRAM ECC flag */ | 280 | /* SRAM ECC flag */ |
| 281 | atomic_t sram_ecc_flag; | 281 | atomic_t sram_ecc_flag; |
| 282 | |||
| 283 | /* Compute Profile ref. count */ | ||
| 284 | atomic_t compute_profile; | ||
| 282 | }; | 285 | }; |
| 283 | 286 | ||
| 284 | enum kfd_mempool { | 287 | enum kfd_mempool { |
| @@ -978,6 +981,10 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p); | |||
| 978 | 981 | ||
| 979 | bool kfd_is_locked(void); | 982 | bool kfd_is_locked(void); |
| 980 | 983 | ||
| 984 | /* Compute profile */ | ||
| 985 | void kfd_inc_compute_active(struct kfd_dev *dev); | ||
| 986 | void kfd_dec_compute_active(struct kfd_dev *dev); | ||
| 987 | |||
| 981 | /* Debugfs */ | 988 | /* Debugfs */ |
| 982 | #if defined(CONFIG_DEBUG_FS) | 989 | #if defined(CONFIG_DEBUG_FS) |
| 983 | 990 | ||
diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index 34d6fdcb32e2..4c8ce7938f01 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h | |||
| @@ -138,13 +138,14 @@ | |||
| 138 | #endif | 138 | #endif |
| 139 | #define RAVEN_UNKNOWN 0xFF | 139 | #define RAVEN_UNKNOWN 0xFF |
| 140 | 140 | ||
| 141 | #if defined(CONFIG_DRM_AMD_DC_DCN1_01) | ||
| 142 | #define ASICREV_IS_RAVEN2(eChipRev) ((eChipRev >= RAVEN2_A0) && (eChipRev < 0xF0)) | ||
| 143 | #endif /* DCN1_01 */ | ||
| 144 | #define ASIC_REV_IS_RAVEN(eChipRev) ((eChipRev >= RAVEN_A0) && eChipRev < RAVEN_UNKNOWN) | 141 | #define ASIC_REV_IS_RAVEN(eChipRev) ((eChipRev >= RAVEN_A0) && eChipRev < RAVEN_UNKNOWN) |
| 145 | #define RAVEN1_F0 0xF0 | 142 | #define RAVEN1_F0 0xF0 |
| 146 | #define ASICREV_IS_RV1_F0(eChipRev) ((eChipRev >= RAVEN1_F0) && (eChipRev < RAVEN_UNKNOWN)) | 143 | #define ASICREV_IS_RV1_F0(eChipRev) ((eChipRev >= RAVEN1_F0) && (eChipRev < RAVEN_UNKNOWN)) |
| 147 | 144 | ||
| 145 | #if defined(CONFIG_DRM_AMD_DC_DCN1_01) | ||
| 146 | #define ASICREV_IS_PICASSO(eChipRev) ((eChipRev >= PICASSO_A0) && (eChipRev < RAVEN2_A0)) | ||
| 147 | #define ASICREV_IS_RAVEN2(eChipRev) ((eChipRev >= RAVEN2_A0) && (eChipRev < 0xF0)) | ||
| 148 | #endif /* DCN1_01 */ | ||
| 148 | 149 | ||
| 149 | #define FAMILY_RV 142 /* DCN 1*/ | 150 | #define FAMILY_RV 142 /* DCN 1*/ |
| 150 | 151 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index c058c784180e..eec329ab6037 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | |||
| @@ -280,7 +280,7 @@ int smu_feature_set_supported(struct smu_context *smu, int feature_id, | |||
| 280 | 280 | ||
| 281 | WARN_ON(feature_id > feature->feature_num); | 281 | WARN_ON(feature_id > feature->feature_num); |
| 282 | 282 | ||
| 283 | mutex_unlock(&feature->mutex); | 283 | mutex_lock(&feature->mutex); |
| 284 | if (enable) | 284 | if (enable) |
| 285 | test_and_set_bit(feature_id, feature->supported); | 285 | test_and_set_bit(feature_id, feature->supported); |
| 286 | else | 286 | else |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index de9531caaca0..9c8446184b17 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c | |||
| @@ -594,6 +594,9 @@ void cdv_intel_lvds_init(struct drm_device *dev, | |||
| 594 | int pipe; | 594 | int pipe; |
| 595 | u8 pin; | 595 | u8 pin; |
| 596 | 596 | ||
| 597 | if (!dev_priv->lvds_enabled_in_vbt) | ||
| 598 | return; | ||
| 599 | |||
| 597 | pin = GMBUS_PORT_PANEL; | 600 | pin = GMBUS_PORT_PANEL; |
| 598 | if (!lvds_is_present_in_vbt(dev, &pin)) { | 601 | if (!lvds_is_present_in_vbt(dev, &pin)) { |
| 599 | DRM_DEBUG_KMS("LVDS is not present in VBT\n"); | 602 | DRM_DEBUG_KMS("LVDS is not present in VBT\n"); |
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index 63bde4e86c6a..e019ea271ffc 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c | |||
| @@ -436,6 +436,9 @@ parse_driver_features(struct drm_psb_private *dev_priv, | |||
| 436 | if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | 436 | if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) |
| 437 | dev_priv->edp.support = 1; | 437 | dev_priv->edp.support = 1; |
| 438 | 438 | ||
| 439 | dev_priv->lvds_enabled_in_vbt = driver->lvds_config != 0; | ||
| 440 | DRM_DEBUG_KMS("LVDS VBT config bits: 0x%x\n", driver->lvds_config); | ||
| 441 | |||
| 439 | /* This bit means to use 96Mhz for DPLL_A or not */ | 442 | /* This bit means to use 96Mhz for DPLL_A or not */ |
| 440 | if (driver->primary_lfp_id) | 443 | if (driver->primary_lfp_id) |
| 441 | dev_priv->dplla_96mhz = true; | 444 | dev_priv->dplla_96mhz = true; |
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 941b238bdcc9..bc608ddc3bd1 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h | |||
| @@ -537,6 +537,7 @@ struct drm_psb_private { | |||
| 537 | int lvds_ssc_freq; | 537 | int lvds_ssc_freq; |
| 538 | bool is_lvds_on; | 538 | bool is_lvds_on; |
| 539 | bool is_mipi_on; | 539 | bool is_mipi_on; |
| 540 | bool lvds_enabled_in_vbt; | ||
| 540 | u32 mipi_ctrl_display; | 541 | u32 mipi_ctrl_display; |
| 541 | 542 | ||
| 542 | unsigned int core_freq; | 543 | unsigned int core_freq; |
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index ab002cfd3cab..5cb59c0b4bbe 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c | |||
| @@ -896,12 +896,16 @@ static int cmd_reg_handler(struct parser_exec_state *s, | |||
| 896 | } | 896 | } |
| 897 | 897 | ||
| 898 | /* TODO | 898 | /* TODO |
| 899 | * Right now only scan LRI command on KBL and in inhibit context. | 899 | * In order to let workload with inhibit context to generate |
| 900 | * It's good enough to support initializing mmio by lri command in | 900 | * correct image data into memory, vregs values will be loaded to |
| 901 | * vgpu inhibit context on KBL. | 901 | * hw via LRIs in the workload with inhibit context. But as |
| 902 | * indirect context is loaded prior to LRIs in workload, we don't | ||
| 903 | * want reg values specified in indirect context overwritten by | ||
| 904 | * LRIs in workloads. So, when scanning an indirect context, we | ||
| 905 | * update reg values in it into vregs, so LRIs in workload with | ||
| 906 | * inhibit context will restore with correct values | ||
| 902 | */ | 907 | */ |
| 903 | if ((IS_KABYLAKE(s->vgpu->gvt->dev_priv) | 908 | if (IS_GEN(gvt->dev_priv, 9) && |
| 904 | || IS_COFFEELAKE(s->vgpu->gvt->dev_priv)) && | ||
| 905 | intel_gvt_mmio_is_in_ctx(gvt, offset) && | 909 | intel_gvt_mmio_is_in_ctx(gvt, offset) && |
| 906 | !strncmp(cmd, "lri", 3)) { | 910 | !strncmp(cmd, "lri", 3)) { |
| 907 | intel_gvt_hypervisor_read_gpa(s->vgpu, | 911 | intel_gvt_hypervisor_read_gpa(s->vgpu, |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 08c74e65836b..244ad1729764 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
| @@ -1076,8 +1076,10 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_spt_by_guest_entry( | |||
| 1076 | } else { | 1076 | } else { |
| 1077 | int type = get_next_pt_type(we->type); | 1077 | int type = get_next_pt_type(we->type); |
| 1078 | 1078 | ||
| 1079 | if (!gtt_type_is_pt(type)) | 1079 | if (!gtt_type_is_pt(type)) { |
| 1080 | ret = -EINVAL; | ||
| 1080 | goto err; | 1081 | goto err; |
| 1082 | } | ||
| 1081 | 1083 | ||
| 1082 | spt = ppgtt_alloc_spt_gfn(vgpu, type, ops->get_pfn(we), ips); | 1084 | spt = ppgtt_alloc_spt_gfn(vgpu, type, ops->get_pfn(we), ips); |
| 1083 | if (IS_ERR(spt)) { | 1085 | if (IS_ERR(spt)) { |
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 90673fca792f..e09bd6e0cc4d 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
| @@ -1364,7 +1364,6 @@ static int dma_ctrl_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 1364 | static int gen9_trtte_write(struct intel_vgpu *vgpu, unsigned int offset, | 1364 | static int gen9_trtte_write(struct intel_vgpu *vgpu, unsigned int offset, |
| 1365 | void *p_data, unsigned int bytes) | 1365 | void *p_data, unsigned int bytes) |
| 1366 | { | 1366 | { |
| 1367 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
| 1368 | u32 trtte = *(u32 *)p_data; | 1367 | u32 trtte = *(u32 *)p_data; |
| 1369 | 1368 | ||
| 1370 | if ((trtte & 1) && (trtte & (1 << 1)) == 0) { | 1369 | if ((trtte & 1) && (trtte & (1 << 1)) == 0) { |
| @@ -1373,11 +1372,6 @@ static int gen9_trtte_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 1373 | return -EINVAL; | 1372 | return -EINVAL; |
| 1374 | } | 1373 | } |
| 1375 | write_vreg(vgpu, offset, p_data, bytes); | 1374 | write_vreg(vgpu, offset, p_data, bytes); |
| 1376 | /* TRTTE is not per-context */ | ||
| 1377 | |||
| 1378 | mmio_hw_access_pre(dev_priv); | ||
| 1379 | I915_WRITE(_MMIO(offset), vgpu_vreg(vgpu, offset)); | ||
| 1380 | mmio_hw_access_post(dev_priv); | ||
| 1381 | 1375 | ||
| 1382 | return 0; | 1376 | return 0; |
| 1383 | } | 1377 | } |
| @@ -1385,15 +1379,6 @@ static int gen9_trtte_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 1385 | static int gen9_trtt_chicken_write(struct intel_vgpu *vgpu, unsigned int offset, | 1379 | static int gen9_trtt_chicken_write(struct intel_vgpu *vgpu, unsigned int offset, |
| 1386 | void *p_data, unsigned int bytes) | 1380 | void *p_data, unsigned int bytes) |
| 1387 | { | 1381 | { |
| 1388 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
| 1389 | u32 val = *(u32 *)p_data; | ||
| 1390 | |||
| 1391 | if (val & 1) { | ||
| 1392 | /* unblock hw logic */ | ||
| 1393 | mmio_hw_access_pre(dev_priv); | ||
| 1394 | I915_WRITE(_MMIO(offset), val); | ||
| 1395 | mmio_hw_access_post(dev_priv); | ||
| 1396 | } | ||
| 1397 | write_vreg(vgpu, offset, p_data, bytes); | 1382 | write_vreg(vgpu, offset, p_data, bytes); |
| 1398 | return 0; | 1383 | return 0; |
| 1399 | } | 1384 | } |
diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index edf6d646eb25..90bb3df0db50 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c | |||
| @@ -108,12 +108,13 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = { | |||
| 108 | {RCS0, GEN9_HALF_SLICE_CHICKEN5, 0xffff, true}, /* 0xe188 */ | 108 | {RCS0, GEN9_HALF_SLICE_CHICKEN5, 0xffff, true}, /* 0xe188 */ |
| 109 | {RCS0, GEN9_HALF_SLICE_CHICKEN7, 0xffff, true}, /* 0xe194 */ | 109 | {RCS0, GEN9_HALF_SLICE_CHICKEN7, 0xffff, true}, /* 0xe194 */ |
| 110 | {RCS0, GEN8_ROW_CHICKEN, 0xffff, true}, /* 0xe4f0 */ | 110 | {RCS0, GEN8_ROW_CHICKEN, 0xffff, true}, /* 0xe4f0 */ |
| 111 | {RCS0, TRVATTL3PTRDW(0), 0, false}, /* 0x4de0 */ | 111 | {RCS0, TRVATTL3PTRDW(0), 0, true}, /* 0x4de0 */ |
| 112 | {RCS0, TRVATTL3PTRDW(1), 0, false}, /* 0x4de4 */ | 112 | {RCS0, TRVATTL3PTRDW(1), 0, true}, /* 0x4de4 */ |
| 113 | {RCS0, TRNULLDETCT, 0, false}, /* 0x4de8 */ | 113 | {RCS0, TRNULLDETCT, 0, true}, /* 0x4de8 */ |
| 114 | {RCS0, TRINVTILEDETCT, 0, false}, /* 0x4dec */ | 114 | {RCS0, TRINVTILEDETCT, 0, true}, /* 0x4dec */ |
| 115 | {RCS0, TRVADR, 0, false}, /* 0x4df0 */ | 115 | {RCS0, TRVADR, 0, true}, /* 0x4df0 */ |
| 116 | {RCS0, TRTTE, 0, false}, /* 0x4df4 */ | 116 | {RCS0, TRTTE, 0, true}, /* 0x4df4 */ |
| 117 | {RCS0, _MMIO(0x4dfc), 0, true}, | ||
| 117 | 118 | ||
| 118 | {BCS0, RING_GFX_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2229c */ | 119 | {BCS0, RING_GFX_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2229c */ |
| 119 | {BCS0, RING_MI_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2209c */ | 120 | {BCS0, RING_MI_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2209c */ |
| @@ -392,10 +393,7 @@ static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next, | |||
| 392 | if (WARN_ON(ring_id >= ARRAY_SIZE(regs))) | 393 | if (WARN_ON(ring_id >= ARRAY_SIZE(regs))) |
| 393 | return; | 394 | return; |
| 394 | 395 | ||
| 395 | if (ring_id == RCS0 && | 396 | if (ring_id == RCS0 && IS_GEN(dev_priv, 9)) |
| 396 | (IS_KABYLAKE(dev_priv) || | ||
| 397 | IS_BROXTON(dev_priv) || | ||
| 398 | IS_COFFEELAKE(dev_priv))) | ||
| 399 | return; | 397 | return; |
| 400 | 398 | ||
| 401 | if (!pre && !gen9_render_mocs.initialized) | 399 | if (!pre && !gen9_render_mocs.initialized) |
| @@ -470,11 +468,10 @@ static void switch_mmio(struct intel_vgpu *pre, | |||
| 470 | continue; | 468 | continue; |
| 471 | /* | 469 | /* |
| 472 | * No need to do save or restore of the mmio which is in context | 470 | * No need to do save or restore of the mmio which is in context |
| 473 | * state image on kabylake, it's initialized by lri command and | 471 | * state image on gen9, it's initialized by lri command and |
| 474 | * save or restore with context together. | 472 | * save or restore with context together. |
| 475 | */ | 473 | */ |
| 476 | if ((IS_KABYLAKE(dev_priv) || IS_BROXTON(dev_priv) | 474 | if (IS_GEN(dev_priv, 9) && mmio->in_context) |
| 477 | || IS_COFFEELAKE(dev_priv)) && mmio->in_context) | ||
| 478 | continue; | 475 | continue; |
| 479 | 476 | ||
| 480 | // save | 477 | // save |
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 7c99bbc3e2b8..13632dba8b2a 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c | |||
| @@ -298,12 +298,29 @@ static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload) | |||
| 298 | struct i915_request *req = workload->req; | 298 | struct i915_request *req = workload->req; |
| 299 | void *shadow_ring_buffer_va; | 299 | void *shadow_ring_buffer_va; |
| 300 | u32 *cs; | 300 | u32 *cs; |
| 301 | int err; | ||
| 301 | 302 | ||
| 302 | if ((IS_KABYLAKE(req->i915) || IS_BROXTON(req->i915) | 303 | if (IS_GEN(req->i915, 9) && is_inhibit_context(req->hw_context)) |
| 303 | || IS_COFFEELAKE(req->i915)) | ||
| 304 | && is_inhibit_context(req->hw_context)) | ||
| 305 | intel_vgpu_restore_inhibit_context(vgpu, req); | 304 | intel_vgpu_restore_inhibit_context(vgpu, req); |
| 306 | 305 | ||
| 306 | /* | ||
| 307 | * To track whether a request has started on HW, we can emit a | ||
| 308 | * breadcrumb at the beginning of the request and check its | ||
| 309 | * timeline's HWSP to see if the breadcrumb has advanced past the | ||
| 310 | * start of this request. Actually, the request must have the | ||
| 311 | * init_breadcrumb if its timeline set has_init_bread_crumb, or the | ||
| 312 | * scheduler might get a wrong state of it during reset. Since the | ||
| 313 | * requests from gvt always set the has_init_breadcrumb flag, here | ||
| 314 | * need to do the emit_init_breadcrumb for all the requests. | ||
| 315 | */ | ||
| 316 | if (req->engine->emit_init_breadcrumb) { | ||
| 317 | err = req->engine->emit_init_breadcrumb(req); | ||
| 318 | if (err) { | ||
| 319 | gvt_vgpu_err("fail to emit init breadcrumb\n"); | ||
| 320 | return err; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | |||
| 307 | /* allocate shadow ring buffer */ | 324 | /* allocate shadow ring buffer */ |
| 308 | cs = intel_ring_begin(workload->req, workload->rb_len / sizeof(u32)); | 325 | cs = intel_ring_begin(workload->req, workload->rb_len / sizeof(u32)); |
| 309 | if (IS_ERR(cs)) { | 326 | if (IS_ERR(cs)) { |
diff --git a/drivers/gpu/drm/i915/i915_priolist_types.h b/drivers/gpu/drm/i915/i915_priolist_types.h index cc44ebd3b553..49709de69875 100644 --- a/drivers/gpu/drm/i915/i915_priolist_types.h +++ b/drivers/gpu/drm/i915/i915_priolist_types.h | |||
| @@ -20,15 +20,14 @@ enum { | |||
| 20 | I915_PRIORITY_INVALID = INT_MIN | 20 | I915_PRIORITY_INVALID = INT_MIN |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | #define I915_USER_PRIORITY_SHIFT 3 | 23 | #define I915_USER_PRIORITY_SHIFT 2 |
| 24 | #define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT) | 24 | #define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT) |
| 25 | 25 | ||
| 26 | #define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT) | 26 | #define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT) |
| 27 | #define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1) | 27 | #define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1) |
| 28 | 28 | ||
| 29 | #define I915_PRIORITY_WAIT ((u8)BIT(0)) | 29 | #define I915_PRIORITY_WAIT ((u8)BIT(0)) |
| 30 | #define I915_PRIORITY_NEWCLIENT ((u8)BIT(1)) | 30 | #define I915_PRIORITY_NOSEMAPHORE ((u8)BIT(1)) |
| 31 | #define I915_PRIORITY_NOSEMAPHORE ((u8)BIT(2)) | ||
| 32 | 31 | ||
| 33 | #define __NO_PREEMPTION (I915_PRIORITY_WAIT) | 32 | #define __NO_PREEMPTION (I915_PRIORITY_WAIT) |
| 34 | 33 | ||
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index f6c78c0fa74b..c88e538b2ef4 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c | |||
| @@ -502,15 +502,6 @@ void __i915_request_unsubmit(struct i915_request *request) | |||
| 502 | /* We may be recursing from the signal callback of another i915 fence */ | 502 | /* We may be recursing from the signal callback of another i915 fence */ |
| 503 | spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); | 503 | spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); |
| 504 | 504 | ||
| 505 | /* | ||
| 506 | * As we do not allow WAIT to preempt inflight requests, | ||
| 507 | * once we have executed a request, along with triggering | ||
| 508 | * any execution callbacks, we must preserve its ordering | ||
| 509 | * within the non-preemptible FIFO. | ||
| 510 | */ | ||
| 511 | BUILD_BUG_ON(__NO_PREEMPTION & ~I915_PRIORITY_MASK); /* only internal */ | ||
| 512 | request->sched.attr.priority |= __NO_PREEMPTION; | ||
| 513 | |||
| 514 | if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags)) | 505 | if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags)) |
| 515 | i915_request_cancel_breadcrumb(request); | 506 | i915_request_cancel_breadcrumb(request); |
| 516 | 507 | ||
| @@ -582,18 +573,7 @@ semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) | |||
| 582 | 573 | ||
| 583 | switch (state) { | 574 | switch (state) { |
| 584 | case FENCE_COMPLETE: | 575 | case FENCE_COMPLETE: |
| 585 | /* | 576 | i915_schedule_bump_priority(request, I915_PRIORITY_NOSEMAPHORE); |
| 586 | * We only check a small portion of our dependencies | ||
| 587 | * and so cannot guarantee that there remains no | ||
| 588 | * semaphore chain across all. Instead of opting | ||
| 589 | * for the full NOSEMAPHORE boost, we go for the | ||
| 590 | * smaller (but still preempting) boost of | ||
| 591 | * NEWCLIENT. This will be enough to boost over | ||
| 592 | * a busywaiting request (as that cannot be | ||
| 593 | * NEWCLIENT) without accidentally boosting | ||
| 594 | * a busywait over real work elsewhere. | ||
| 595 | */ | ||
| 596 | i915_schedule_bump_priority(request, I915_PRIORITY_NEWCLIENT); | ||
| 597 | break; | 577 | break; |
| 598 | 578 | ||
| 599 | case FENCE_FREE: | 579 | case FENCE_FREE: |
| @@ -874,12 +854,6 @@ emit_semaphore_wait(struct i915_request *to, | |||
| 874 | if (err < 0) | 854 | if (err < 0) |
| 875 | return err; | 855 | return err; |
| 876 | 856 | ||
| 877 | err = i915_sw_fence_await_dma_fence(&to->semaphore, | ||
| 878 | &from->fence, 0, | ||
| 879 | I915_FENCE_GFP); | ||
| 880 | if (err < 0) | ||
| 881 | return err; | ||
| 882 | |||
| 883 | /* We need to pin the signaler's HWSP until we are finished reading. */ | 857 | /* We need to pin the signaler's HWSP until we are finished reading. */ |
| 884 | err = i915_timeline_read_hwsp(from, to, &hwsp_offset); | 858 | err = i915_timeline_read_hwsp(from, to, &hwsp_offset); |
| 885 | if (err) | 859 | if (err) |
| @@ -945,8 +919,18 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from) | |||
| 945 | &from->fence, 0, | 919 | &from->fence, 0, |
| 946 | I915_FENCE_GFP); | 920 | I915_FENCE_GFP); |
| 947 | } | 921 | } |
| 922 | if (ret < 0) | ||
| 923 | return ret; | ||
| 948 | 924 | ||
| 949 | return ret < 0 ? ret : 0; | 925 | if (to->sched.flags & I915_SCHED_HAS_SEMAPHORE_CHAIN) { |
| 926 | ret = i915_sw_fence_await_dma_fence(&to->semaphore, | ||
| 927 | &from->fence, 0, | ||
| 928 | I915_FENCE_GFP); | ||
| 929 | if (ret < 0) | ||
| 930 | return ret; | ||
| 931 | } | ||
| 932 | |||
| 933 | return 0; | ||
| 950 | } | 934 | } |
| 951 | 935 | ||
| 952 | int | 936 | int |
| @@ -1237,7 +1221,7 @@ void i915_request_add(struct i915_request *request) | |||
| 1237 | * the bulk clients. (FQ_CODEL) | 1221 | * the bulk clients. (FQ_CODEL) |
| 1238 | */ | 1222 | */ |
| 1239 | if (list_empty(&request->sched.signalers_list)) | 1223 | if (list_empty(&request->sched.signalers_list)) |
| 1240 | attr.priority |= I915_PRIORITY_NEWCLIENT; | 1224 | attr.priority |= I915_PRIORITY_WAIT; |
| 1241 | 1225 | ||
| 1242 | engine->schedule(request, &attr); | 1226 | engine->schedule(request, &attr); |
| 1243 | } | 1227 | } |
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index 39bc4f54e272..108f52e1bf35 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c | |||
| @@ -35,109 +35,6 @@ static inline bool node_signaled(const struct i915_sched_node *node) | |||
| 35 | return i915_request_completed(node_to_request(node)); | 35 | return i915_request_completed(node_to_request(node)); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | void i915_sched_node_init(struct i915_sched_node *node) | ||
| 39 | { | ||
| 40 | INIT_LIST_HEAD(&node->signalers_list); | ||
| 41 | INIT_LIST_HEAD(&node->waiters_list); | ||
| 42 | INIT_LIST_HEAD(&node->link); | ||
| 43 | node->attr.priority = I915_PRIORITY_INVALID; | ||
| 44 | node->semaphores = 0; | ||
| 45 | node->flags = 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | static struct i915_dependency * | ||
| 49 | i915_dependency_alloc(void) | ||
| 50 | { | ||
| 51 | return kmem_cache_alloc(global.slab_dependencies, GFP_KERNEL); | ||
| 52 | } | ||
| 53 | |||
| 54 | static void | ||
| 55 | i915_dependency_free(struct i915_dependency *dep) | ||
| 56 | { | ||
| 57 | kmem_cache_free(global.slab_dependencies, dep); | ||
| 58 | } | ||
| 59 | |||
| 60 | bool __i915_sched_node_add_dependency(struct i915_sched_node *node, | ||
| 61 | struct i915_sched_node *signal, | ||
| 62 | struct i915_dependency *dep, | ||
| 63 | unsigned long flags) | ||
| 64 | { | ||
| 65 | bool ret = false; | ||
| 66 | |||
| 67 | spin_lock_irq(&schedule_lock); | ||
| 68 | |||
| 69 | if (!node_signaled(signal)) { | ||
| 70 | INIT_LIST_HEAD(&dep->dfs_link); | ||
| 71 | list_add(&dep->wait_link, &signal->waiters_list); | ||
| 72 | list_add(&dep->signal_link, &node->signalers_list); | ||
| 73 | dep->signaler = signal; | ||
| 74 | dep->flags = flags; | ||
| 75 | |||
| 76 | /* Keep track of whether anyone on this chain has a semaphore */ | ||
| 77 | if (signal->flags & I915_SCHED_HAS_SEMAPHORE_CHAIN && | ||
| 78 | !node_started(signal)) | ||
| 79 | node->flags |= I915_SCHED_HAS_SEMAPHORE_CHAIN; | ||
| 80 | |||
| 81 | ret = true; | ||
| 82 | } | ||
| 83 | |||
| 84 | spin_unlock_irq(&schedule_lock); | ||
| 85 | |||
| 86 | return ret; | ||
| 87 | } | ||
| 88 | |||
| 89 | int i915_sched_node_add_dependency(struct i915_sched_node *node, | ||
| 90 | struct i915_sched_node *signal) | ||
| 91 | { | ||
| 92 | struct i915_dependency *dep; | ||
| 93 | |||
| 94 | dep = i915_dependency_alloc(); | ||
| 95 | if (!dep) | ||
| 96 | return -ENOMEM; | ||
| 97 | |||
| 98 | if (!__i915_sched_node_add_dependency(node, signal, dep, | ||
| 99 | I915_DEPENDENCY_ALLOC)) | ||
| 100 | i915_dependency_free(dep); | ||
| 101 | |||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | void i915_sched_node_fini(struct i915_sched_node *node) | ||
| 106 | { | ||
| 107 | struct i915_dependency *dep, *tmp; | ||
| 108 | |||
| 109 | GEM_BUG_ON(!list_empty(&node->link)); | ||
| 110 | |||
| 111 | spin_lock_irq(&schedule_lock); | ||
| 112 | |||
| 113 | /* | ||
| 114 | * Everyone we depended upon (the fences we wait to be signaled) | ||
| 115 | * should retire before us and remove themselves from our list. | ||
| 116 | * However, retirement is run independently on each timeline and | ||
| 117 | * so we may be called out-of-order. | ||
| 118 | */ | ||
| 119 | list_for_each_entry_safe(dep, tmp, &node->signalers_list, signal_link) { | ||
| 120 | GEM_BUG_ON(!node_signaled(dep->signaler)); | ||
| 121 | GEM_BUG_ON(!list_empty(&dep->dfs_link)); | ||
| 122 | |||
| 123 | list_del(&dep->wait_link); | ||
| 124 | if (dep->flags & I915_DEPENDENCY_ALLOC) | ||
| 125 | i915_dependency_free(dep); | ||
| 126 | } | ||
| 127 | |||
| 128 | /* Remove ourselves from everyone who depends upon us */ | ||
| 129 | list_for_each_entry_safe(dep, tmp, &node->waiters_list, wait_link) { | ||
| 130 | GEM_BUG_ON(dep->signaler != node); | ||
| 131 | GEM_BUG_ON(!list_empty(&dep->dfs_link)); | ||
| 132 | |||
| 133 | list_del(&dep->signal_link); | ||
| 134 | if (dep->flags & I915_DEPENDENCY_ALLOC) | ||
| 135 | i915_dependency_free(dep); | ||
| 136 | } | ||
| 137 | |||
| 138 | spin_unlock_irq(&schedule_lock); | ||
| 139 | } | ||
| 140 | |||
| 141 | static inline struct i915_priolist *to_priolist(struct rb_node *rb) | 38 | static inline struct i915_priolist *to_priolist(struct rb_node *rb) |
| 142 | { | 39 | { |
| 143 | return rb_entry(rb, struct i915_priolist, node); | 40 | return rb_entry(rb, struct i915_priolist, node); |
| @@ -239,6 +136,11 @@ out: | |||
| 239 | return &p->requests[idx]; | 136 | return &p->requests[idx]; |
| 240 | } | 137 | } |
| 241 | 138 | ||
| 139 | void __i915_priolist_free(struct i915_priolist *p) | ||
| 140 | { | ||
| 141 | kmem_cache_free(global.slab_priorities, p); | ||
| 142 | } | ||
| 143 | |||
| 242 | struct sched_cache { | 144 | struct sched_cache { |
| 243 | struct list_head *priolist; | 145 | struct list_head *priolist; |
| 244 | }; | 146 | }; |
| @@ -273,7 +175,7 @@ static bool inflight(const struct i915_request *rq, | |||
| 273 | return active->hw_context == rq->hw_context; | 175 | return active->hw_context == rq->hw_context; |
| 274 | } | 176 | } |
| 275 | 177 | ||
| 276 | static void __i915_schedule(struct i915_request *rq, | 178 | static void __i915_schedule(struct i915_sched_node *node, |
| 277 | const struct i915_sched_attr *attr) | 179 | const struct i915_sched_attr *attr) |
| 278 | { | 180 | { |
| 279 | struct intel_engine_cs *engine; | 181 | struct intel_engine_cs *engine; |
| @@ -287,13 +189,13 @@ static void __i915_schedule(struct i915_request *rq, | |||
| 287 | lockdep_assert_held(&schedule_lock); | 189 | lockdep_assert_held(&schedule_lock); |
| 288 | GEM_BUG_ON(prio == I915_PRIORITY_INVALID); | 190 | GEM_BUG_ON(prio == I915_PRIORITY_INVALID); |
| 289 | 191 | ||
| 290 | if (i915_request_completed(rq)) | 192 | if (node_signaled(node)) |
| 291 | return; | 193 | return; |
| 292 | 194 | ||
| 293 | if (prio <= READ_ONCE(rq->sched.attr.priority)) | 195 | if (prio <= READ_ONCE(node->attr.priority)) |
| 294 | return; | 196 | return; |
| 295 | 197 | ||
| 296 | stack.signaler = &rq->sched; | 198 | stack.signaler = node; |
| 297 | list_add(&stack.dfs_link, &dfs); | 199 | list_add(&stack.dfs_link, &dfs); |
| 298 | 200 | ||
| 299 | /* | 201 | /* |
| @@ -344,9 +246,9 @@ static void __i915_schedule(struct i915_request *rq, | |||
| 344 | * execlists_submit_request()), we can set our own priority and skip | 246 | * execlists_submit_request()), we can set our own priority and skip |
| 345 | * acquiring the engine locks. | 247 | * acquiring the engine locks. |
| 346 | */ | 248 | */ |
| 347 | if (rq->sched.attr.priority == I915_PRIORITY_INVALID) { | 249 | if (node->attr.priority == I915_PRIORITY_INVALID) { |
| 348 | GEM_BUG_ON(!list_empty(&rq->sched.link)); | 250 | GEM_BUG_ON(!list_empty(&node->link)); |
| 349 | rq->sched.attr = *attr; | 251 | node->attr = *attr; |
| 350 | 252 | ||
| 351 | if (stack.dfs_link.next == stack.dfs_link.prev) | 253 | if (stack.dfs_link.next == stack.dfs_link.prev) |
| 352 | return; | 254 | return; |
| @@ -355,15 +257,14 @@ static void __i915_schedule(struct i915_request *rq, | |||
| 355 | } | 257 | } |
| 356 | 258 | ||
| 357 | memset(&cache, 0, sizeof(cache)); | 259 | memset(&cache, 0, sizeof(cache)); |
| 358 | engine = rq->engine; | 260 | engine = node_to_request(node)->engine; |
| 359 | spin_lock(&engine->timeline.lock); | 261 | spin_lock(&engine->timeline.lock); |
| 360 | 262 | ||
| 361 | /* Fifo and depth-first replacement ensure our deps execute before us */ | 263 | /* Fifo and depth-first replacement ensure our deps execute before us */ |
| 362 | list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) { | 264 | list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) { |
| 363 | struct i915_sched_node *node = dep->signaler; | ||
| 364 | |||
| 365 | INIT_LIST_HEAD(&dep->dfs_link); | 265 | INIT_LIST_HEAD(&dep->dfs_link); |
| 366 | 266 | ||
| 267 | node = dep->signaler; | ||
| 367 | engine = sched_lock_engine(node, engine, &cache); | 268 | engine = sched_lock_engine(node, engine, &cache); |
| 368 | lockdep_assert_held(&engine->timeline.lock); | 269 | lockdep_assert_held(&engine->timeline.lock); |
| 369 | 270 | ||
| @@ -413,13 +314,20 @@ static void __i915_schedule(struct i915_request *rq, | |||
| 413 | void i915_schedule(struct i915_request *rq, const struct i915_sched_attr *attr) | 314 | void i915_schedule(struct i915_request *rq, const struct i915_sched_attr *attr) |
| 414 | { | 315 | { |
| 415 | spin_lock_irq(&schedule_lock); | 316 | spin_lock_irq(&schedule_lock); |
| 416 | __i915_schedule(rq, attr); | 317 | __i915_schedule(&rq->sched, attr); |
| 417 | spin_unlock_irq(&schedule_lock); | 318 | spin_unlock_irq(&schedule_lock); |
| 418 | } | 319 | } |
| 419 | 320 | ||
| 321 | static void __bump_priority(struct i915_sched_node *node, unsigned int bump) | ||
| 322 | { | ||
| 323 | struct i915_sched_attr attr = node->attr; | ||
| 324 | |||
| 325 | attr.priority |= bump; | ||
| 326 | __i915_schedule(node, &attr); | ||
| 327 | } | ||
| 328 | |||
| 420 | void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump) | 329 | void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump) |
| 421 | { | 330 | { |
| 422 | struct i915_sched_attr attr; | ||
| 423 | unsigned long flags; | 331 | unsigned long flags; |
| 424 | 332 | ||
| 425 | GEM_BUG_ON(bump & ~I915_PRIORITY_MASK); | 333 | GEM_BUG_ON(bump & ~I915_PRIORITY_MASK); |
| @@ -428,17 +336,122 @@ void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump) | |||
| 428 | return; | 336 | return; |
| 429 | 337 | ||
| 430 | spin_lock_irqsave(&schedule_lock, flags); | 338 | spin_lock_irqsave(&schedule_lock, flags); |
| 339 | __bump_priority(&rq->sched, bump); | ||
| 340 | spin_unlock_irqrestore(&schedule_lock, flags); | ||
| 341 | } | ||
| 431 | 342 | ||
| 432 | attr = rq->sched.attr; | 343 | void i915_sched_node_init(struct i915_sched_node *node) |
| 433 | attr.priority |= bump; | 344 | { |
| 434 | __i915_schedule(rq, &attr); | 345 | INIT_LIST_HEAD(&node->signalers_list); |
| 346 | INIT_LIST_HEAD(&node->waiters_list); | ||
| 347 | INIT_LIST_HEAD(&node->link); | ||
| 348 | node->attr.priority = I915_PRIORITY_INVALID; | ||
| 349 | node->semaphores = 0; | ||
| 350 | node->flags = 0; | ||
| 351 | } | ||
| 435 | 352 | ||
| 436 | spin_unlock_irqrestore(&schedule_lock, flags); | 353 | static struct i915_dependency * |
| 354 | i915_dependency_alloc(void) | ||
| 355 | { | ||
| 356 | return kmem_cache_alloc(global.slab_dependencies, GFP_KERNEL); | ||
| 437 | } | 357 | } |
| 438 | 358 | ||
| 439 | void __i915_priolist_free(struct i915_priolist *p) | 359 | static void |
| 360 | i915_dependency_free(struct i915_dependency *dep) | ||
| 440 | { | 361 | { |
| 441 | kmem_cache_free(global.slab_priorities, p); | 362 | kmem_cache_free(global.slab_dependencies, dep); |
| 363 | } | ||
| 364 | |||
| 365 | bool __i915_sched_node_add_dependency(struct i915_sched_node *node, | ||
| 366 | struct i915_sched_node *signal, | ||
| 367 | struct i915_dependency *dep, | ||
| 368 | unsigned long flags) | ||
| 369 | { | ||
| 370 | bool ret = false; | ||
| 371 | |||
| 372 | spin_lock_irq(&schedule_lock); | ||
| 373 | |||
| 374 | if (!node_signaled(signal)) { | ||
| 375 | INIT_LIST_HEAD(&dep->dfs_link); | ||
| 376 | list_add(&dep->wait_link, &signal->waiters_list); | ||
| 377 | list_add(&dep->signal_link, &node->signalers_list); | ||
| 378 | dep->signaler = signal; | ||
| 379 | dep->flags = flags; | ||
| 380 | |||
| 381 | /* Keep track of whether anyone on this chain has a semaphore */ | ||
| 382 | if (signal->flags & I915_SCHED_HAS_SEMAPHORE_CHAIN && | ||
| 383 | !node_started(signal)) | ||
| 384 | node->flags |= I915_SCHED_HAS_SEMAPHORE_CHAIN; | ||
| 385 | |||
| 386 | /* | ||
| 387 | * As we do not allow WAIT to preempt inflight requests, | ||
| 388 | * once we have executed a request, along with triggering | ||
| 389 | * any execution callbacks, we must preserve its ordering | ||
| 390 | * within the non-preemptible FIFO. | ||
| 391 | */ | ||
| 392 | BUILD_BUG_ON(__NO_PREEMPTION & ~I915_PRIORITY_MASK); | ||
| 393 | if (flags & I915_DEPENDENCY_EXTERNAL) | ||
| 394 | __bump_priority(signal, __NO_PREEMPTION); | ||
| 395 | |||
| 396 | ret = true; | ||
| 397 | } | ||
| 398 | |||
| 399 | spin_unlock_irq(&schedule_lock); | ||
| 400 | |||
| 401 | return ret; | ||
| 402 | } | ||
| 403 | |||
| 404 | int i915_sched_node_add_dependency(struct i915_sched_node *node, | ||
| 405 | struct i915_sched_node *signal) | ||
| 406 | { | ||
| 407 | struct i915_dependency *dep; | ||
| 408 | |||
| 409 | dep = i915_dependency_alloc(); | ||
| 410 | if (!dep) | ||
| 411 | return -ENOMEM; | ||
| 412 | |||
| 413 | if (!__i915_sched_node_add_dependency(node, signal, dep, | ||
| 414 | I915_DEPENDENCY_EXTERNAL | | ||
| 415 | I915_DEPENDENCY_ALLOC)) | ||
| 416 | i915_dependency_free(dep); | ||
| 417 | |||
| 418 | return 0; | ||
| 419 | } | ||
| 420 | |||
| 421 | void i915_sched_node_fini(struct i915_sched_node *node) | ||
| 422 | { | ||
| 423 | struct i915_dependency *dep, *tmp; | ||
| 424 | |||
| 425 | GEM_BUG_ON(!list_empty(&node->link)); | ||
| 426 | |||
| 427 | spin_lock_irq(&schedule_lock); | ||
| 428 | |||
| 429 | /* | ||
| 430 | * Everyone we depended upon (the fences we wait to be signaled) | ||
| 431 | * should retire before us and remove themselves from our list. | ||
| 432 | * However, retirement is run independently on each timeline and | ||
| 433 | * so we may be called out-of-order. | ||
| 434 | */ | ||
| 435 | list_for_each_entry_safe(dep, tmp, &node->signalers_list, signal_link) { | ||
| 436 | GEM_BUG_ON(!node_signaled(dep->signaler)); | ||
| 437 | GEM_BUG_ON(!list_empty(&dep->dfs_link)); | ||
| 438 | |||
| 439 | list_del(&dep->wait_link); | ||
| 440 | if (dep->flags & I915_DEPENDENCY_ALLOC) | ||
| 441 | i915_dependency_free(dep); | ||
| 442 | } | ||
| 443 | |||
| 444 | /* Remove ourselves from everyone who depends upon us */ | ||
| 445 | list_for_each_entry_safe(dep, tmp, &node->waiters_list, wait_link) { | ||
| 446 | GEM_BUG_ON(dep->signaler != node); | ||
| 447 | GEM_BUG_ON(!list_empty(&dep->dfs_link)); | ||
| 448 | |||
| 449 | list_del(&dep->signal_link); | ||
| 450 | if (dep->flags & I915_DEPENDENCY_ALLOC) | ||
| 451 | i915_dependency_free(dep); | ||
| 452 | } | ||
| 453 | |||
| 454 | spin_unlock_irq(&schedule_lock); | ||
| 442 | } | 455 | } |
| 443 | 456 | ||
| 444 | static void i915_global_scheduler_shrink(void) | 457 | static void i915_global_scheduler_shrink(void) |
diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h index f1af3916a808..4f2b2eb7c3e5 100644 --- a/drivers/gpu/drm/i915/i915_scheduler_types.h +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h | |||
| @@ -66,7 +66,8 @@ struct i915_dependency { | |||
| 66 | struct list_head wait_link; | 66 | struct list_head wait_link; |
| 67 | struct list_head dfs_link; | 67 | struct list_head dfs_link; |
| 68 | unsigned long flags; | 68 | unsigned long flags; |
| 69 | #define I915_DEPENDENCY_ALLOC BIT(0) | 69 | #define I915_DEPENDENCY_ALLOC BIT(0) |
| 70 | #define I915_DEPENDENCY_EXTERNAL BIT(1) | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | #endif /* _I915_SCHEDULER_TYPES_H_ */ | 73 | #endif /* _I915_SCHEDULER_TYPES_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 4e0a351bfbca..11e5a86610bf 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
| @@ -164,7 +164,7 @@ | |||
| 164 | #define WA_TAIL_DWORDS 2 | 164 | #define WA_TAIL_DWORDS 2 |
| 165 | #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS) | 165 | #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS) |
| 166 | 166 | ||
| 167 | #define ACTIVE_PRIORITY (I915_PRIORITY_NEWCLIENT | I915_PRIORITY_NOSEMAPHORE) | 167 | #define ACTIVE_PRIORITY (I915_PRIORITY_NOSEMAPHORE) |
| 168 | 168 | ||
| 169 | static int execlists_context_deferred_alloc(struct intel_context *ce, | 169 | static int execlists_context_deferred_alloc(struct intel_context *ce, |
| 170 | struct intel_engine_cs *engine); | 170 | struct intel_engine_cs *engine); |
diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index fbee030db940..e8b0b5dbcb2c 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c | |||
| @@ -99,12 +99,14 @@ static int live_busywait_preempt(void *arg) | |||
| 99 | ctx_hi = kernel_context(i915); | 99 | ctx_hi = kernel_context(i915); |
| 100 | if (!ctx_hi) | 100 | if (!ctx_hi) |
| 101 | goto err_unlock; | 101 | goto err_unlock; |
| 102 | ctx_hi->sched.priority = INT_MAX; | 102 | ctx_hi->sched.priority = |
| 103 | I915_USER_PRIORITY(I915_CONTEXT_MAX_USER_PRIORITY); | ||
| 103 | 104 | ||
| 104 | ctx_lo = kernel_context(i915); | 105 | ctx_lo = kernel_context(i915); |
| 105 | if (!ctx_lo) | 106 | if (!ctx_lo) |
| 106 | goto err_ctx_hi; | 107 | goto err_ctx_hi; |
| 107 | ctx_lo->sched.priority = INT_MIN; | 108 | ctx_lo->sched.priority = |
| 109 | I915_USER_PRIORITY(I915_CONTEXT_MIN_USER_PRIORITY); | ||
| 108 | 110 | ||
| 109 | obj = i915_gem_object_create_internal(i915, PAGE_SIZE); | 111 | obj = i915_gem_object_create_internal(i915, PAGE_SIZE); |
| 110 | if (IS_ERR(obj)) { | 112 | if (IS_ERR(obj)) { |
| @@ -954,12 +956,14 @@ static int live_preempt_hang(void *arg) | |||
| 954 | ctx_hi = kernel_context(i915); | 956 | ctx_hi = kernel_context(i915); |
| 955 | if (!ctx_hi) | 957 | if (!ctx_hi) |
| 956 | goto err_spin_lo; | 958 | goto err_spin_lo; |
| 957 | ctx_hi->sched.priority = I915_CONTEXT_MAX_USER_PRIORITY; | 959 | ctx_hi->sched.priority = |
| 960 | I915_USER_PRIORITY(I915_CONTEXT_MAX_USER_PRIORITY); | ||
| 958 | 961 | ||
| 959 | ctx_lo = kernel_context(i915); | 962 | ctx_lo = kernel_context(i915); |
| 960 | if (!ctx_lo) | 963 | if (!ctx_lo) |
| 961 | goto err_ctx_hi; | 964 | goto err_ctx_hi; |
| 962 | ctx_lo->sched.priority = I915_CONTEXT_MIN_USER_PRIORITY; | 965 | ctx_lo->sched.priority = |
| 966 | I915_USER_PRIORITY(I915_CONTEXT_MIN_USER_PRIORITY); | ||
| 963 | 967 | ||
| 964 | for_each_engine(engine, i915, id) { | 968 | for_each_engine(engine, i915, id) { |
| 965 | struct i915_request *rq; | 969 | struct i915_request *rq; |
diff --git a/drivers/gpu/drm/panfrost/Kconfig b/drivers/gpu/drm/panfrost/Kconfig index 591611dc4e34..81963e964b0f 100644 --- a/drivers/gpu/drm/panfrost/Kconfig +++ b/drivers/gpu/drm/panfrost/Kconfig | |||
| @@ -9,6 +9,7 @@ config DRM_PANFROST | |||
| 9 | select IOMMU_SUPPORT | 9 | select IOMMU_SUPPORT |
| 10 | select IOMMU_IO_PGTABLE_LPAE | 10 | select IOMMU_IO_PGTABLE_LPAE |
| 11 | select DRM_GEM_SHMEM_HELPER | 11 | select DRM_GEM_SHMEM_HELPER |
| 12 | select PM_DEVFREQ | ||
| 12 | help | 13 | help |
| 13 | DRM driver for ARM Mali Midgard (T6xx, T7xx, T8xx) and | 14 | DRM driver for ARM Mali Midgard (T6xx, T7xx, T8xx) and |
| 14 | Bifrost (G3x, G5x, G7x) GPUs. | 15 | Bifrost (G3x, G5x, G7x) GPUs. |
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c index 238bd1d89d43..29fcffdf2d57 100644 --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c | |||
| @@ -140,8 +140,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) | |||
| 140 | return 0; | 140 | return 0; |
| 141 | 141 | ||
| 142 | ret = dev_pm_opp_of_add_table(&pfdev->pdev->dev); | 142 | ret = dev_pm_opp_of_add_table(&pfdev->pdev->dev); |
| 143 | if (ret == -ENODEV) /* Optional, continue without devfreq */ | 143 | if (ret) |
| 144 | return 0; | 144 | return ret; |
| 145 | 145 | ||
| 146 | panfrost_devfreq_reset(pfdev); | 146 | panfrost_devfreq_reset(pfdev); |
| 147 | 147 | ||
| @@ -170,9 +170,6 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev) | |||
| 170 | { | 170 | { |
| 171 | int i; | 171 | int i; |
| 172 | 172 | ||
| 173 | if (!pfdev->devfreq.devfreq) | ||
| 174 | return; | ||
| 175 | |||
| 176 | panfrost_devfreq_reset(pfdev); | 173 | panfrost_devfreq_reset(pfdev); |
| 177 | for (i = 0; i < NUM_JOB_SLOTS; i++) | 174 | for (i = 0; i < NUM_JOB_SLOTS; i++) |
| 178 | pfdev->devfreq.slot[i].busy = false; | 175 | pfdev->devfreq.slot[i].busy = false; |
| @@ -182,9 +179,6 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev) | |||
| 182 | 179 | ||
| 183 | void panfrost_devfreq_suspend(struct panfrost_device *pfdev) | 180 | void panfrost_devfreq_suspend(struct panfrost_device *pfdev) |
| 184 | { | 181 | { |
| 185 | if (!pfdev->devfreq.devfreq) | ||
| 186 | return; | ||
| 187 | |||
| 188 | devfreq_suspend_device(pfdev->devfreq.devfreq); | 182 | devfreq_suspend_device(pfdev->devfreq.devfreq); |
| 189 | } | 183 | } |
| 190 | 184 | ||
| @@ -194,9 +188,6 @@ static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev, i | |||
| 194 | ktime_t now; | 188 | ktime_t now; |
| 195 | ktime_t last; | 189 | ktime_t last; |
| 196 | 190 | ||
| 197 | if (!pfdev->devfreq.devfreq) | ||
| 198 | return; | ||
| 199 | |||
| 200 | now = ktime_get(); | 191 | now = ktime_get(); |
| 201 | last = pfdev->devfreq.slot[slot].time_last_update; | 192 | last = pfdev->devfreq.slot[slot].time_last_update; |
| 202 | 193 | ||
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index 6ff585055a07..bfa7e2b146df 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | |||
| @@ -457,8 +457,9 @@ static void sun6i_dsi_setup_inst_loop(struct sun6i_dsi *dsi, | |||
| 457 | u16 delay = 50 - 1; | 457 | u16 delay = 50 - 1; |
| 458 | 458 | ||
| 459 | if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { | 459 | if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { |
| 460 | delay = (mode->htotal - mode->hdisplay) * 150; | 460 | u32 hsync_porch = (mode->htotal - mode->hdisplay) * 150; |
| 461 | delay /= (mode->clock / 1000) * 8; | 461 | |
| 462 | delay = (hsync_porch / ((mode->clock / 1000) * 8)); | ||
| 462 | delay -= 50; | 463 | delay -= 50; |
| 463 | } | 464 | } |
| 464 | 465 | ||
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 66ea3a902e36..43643ad31730 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | |||
| @@ -293,7 +293,8 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi, | |||
| 293 | SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW | | 293 | SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW | |
| 294 | SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4); | 294 | SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4); |
| 295 | ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(9) | | 295 | ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(9) | |
| 296 | SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(13); | 296 | SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(13) | |
| 297 | SUN8I_HDMI_PHY_ANA_CFG3_REG_EMP(3); | ||
| 297 | } | 298 | } |
| 298 | 299 | ||
| 299 | regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, | 300 | regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, |
| @@ -672,22 +673,13 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) | |||
| 672 | goto err_put_clk_pll0; | 673 | goto err_put_clk_pll0; |
| 673 | } | 674 | } |
| 674 | } | 675 | } |
| 675 | |||
| 676 | ret = sun8i_phy_clk_create(phy, dev, | ||
| 677 | phy->variant->has_second_pll); | ||
| 678 | if (ret) { | ||
| 679 | dev_err(dev, "Couldn't create the PHY clock\n"); | ||
| 680 | goto err_put_clk_pll1; | ||
| 681 | } | ||
| 682 | |||
| 683 | clk_prepare_enable(phy->clk_phy); | ||
| 684 | } | 676 | } |
| 685 | 677 | ||
| 686 | phy->rst_phy = of_reset_control_get_shared(node, "phy"); | 678 | phy->rst_phy = of_reset_control_get_shared(node, "phy"); |
| 687 | if (IS_ERR(phy->rst_phy)) { | 679 | if (IS_ERR(phy->rst_phy)) { |
| 688 | dev_err(dev, "Could not get phy reset control\n"); | 680 | dev_err(dev, "Could not get phy reset control\n"); |
| 689 | ret = PTR_ERR(phy->rst_phy); | 681 | ret = PTR_ERR(phy->rst_phy); |
| 690 | goto err_disable_clk_phy; | 682 | goto err_put_clk_pll1; |
| 691 | } | 683 | } |
| 692 | 684 | ||
| 693 | ret = reset_control_deassert(phy->rst_phy); | 685 | ret = reset_control_deassert(phy->rst_phy); |
| @@ -708,18 +700,29 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) | |||
| 708 | goto err_disable_clk_bus; | 700 | goto err_disable_clk_bus; |
| 709 | } | 701 | } |
| 710 | 702 | ||
| 703 | if (phy->variant->has_phy_clk) { | ||
| 704 | ret = sun8i_phy_clk_create(phy, dev, | ||
| 705 | phy->variant->has_second_pll); | ||
| 706 | if (ret) { | ||
| 707 | dev_err(dev, "Couldn't create the PHY clock\n"); | ||
| 708 | goto err_disable_clk_mod; | ||
| 709 | } | ||
| 710 | |||
| 711 | clk_prepare_enable(phy->clk_phy); | ||
| 712 | } | ||
| 713 | |||
| 711 | hdmi->phy = phy; | 714 | hdmi->phy = phy; |
| 712 | 715 | ||
| 713 | return 0; | 716 | return 0; |
| 714 | 717 | ||
| 718 | err_disable_clk_mod: | ||
| 719 | clk_disable_unprepare(phy->clk_mod); | ||
| 715 | err_disable_clk_bus: | 720 | err_disable_clk_bus: |
| 716 | clk_disable_unprepare(phy->clk_bus); | 721 | clk_disable_unprepare(phy->clk_bus); |
| 717 | err_deassert_rst_phy: | 722 | err_deassert_rst_phy: |
| 718 | reset_control_assert(phy->rst_phy); | 723 | reset_control_assert(phy->rst_phy); |
| 719 | err_put_rst_phy: | 724 | err_put_rst_phy: |
| 720 | reset_control_put(phy->rst_phy); | 725 | reset_control_put(phy->rst_phy); |
| 721 | err_disable_clk_phy: | ||
| 722 | clk_disable_unprepare(phy->clk_phy); | ||
| 723 | err_put_clk_pll1: | 726 | err_put_clk_pll1: |
| 724 | clk_put(phy->clk_pll1); | 727 | clk_put(phy->clk_pll1); |
| 725 | err_put_clk_pll0: | 728 | err_put_clk_pll0: |
diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c index 36990b80e790..16077785ad47 100644 --- a/drivers/gpu/drm/vmwgfx/ttm_object.c +++ b/drivers/gpu/drm/vmwgfx/ttm_object.c | |||
| @@ -174,7 +174,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile, | |||
| 174 | kref_init(&base->refcount); | 174 | kref_init(&base->refcount); |
| 175 | idr_preload(GFP_KERNEL); | 175 | idr_preload(GFP_KERNEL); |
| 176 | spin_lock(&tdev->object_lock); | 176 | spin_lock(&tdev->object_lock); |
| 177 | ret = idr_alloc(&tdev->idr, base, 0, 0, GFP_NOWAIT); | 177 | ret = idr_alloc(&tdev->idr, base, 1, 0, GFP_NOWAIT); |
| 178 | spin_unlock(&tdev->object_lock); | 178 | spin_unlock(&tdev->object_lock); |
| 179 | idr_preload_end(); | 179 | idr_preload_end(); |
| 180 | if (ret < 0) | 180 | if (ret < 0) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index bf6c3500d363..4ff11a0077e1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -1239,7 +1239,13 @@ static int vmw_master_set(struct drm_device *dev, | |||
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| 1241 | dev_priv->active_master = vmaster; | 1241 | dev_priv->active_master = vmaster; |
| 1242 | drm_sysfs_hotplug_event(dev); | 1242 | |
| 1243 | /* | ||
| 1244 | * Inform a new master that the layout may have changed while | ||
| 1245 | * it was gone. | ||
| 1246 | */ | ||
| 1247 | if (!from_open) | ||
| 1248 | drm_sysfs_hotplug_event(dev); | ||
| 1243 | 1249 | ||
| 1244 | return 0; | 1250 | return 0; |
| 1245 | } | 1251 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 96983c47fb40..366dcfc1f9bb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -296,7 +296,7 @@ struct vmw_sg_table { | |||
| 296 | struct vmw_piter { | 296 | struct vmw_piter { |
| 297 | struct page **pages; | 297 | struct page **pages; |
| 298 | const dma_addr_t *addrs; | 298 | const dma_addr_t *addrs; |
| 299 | struct sg_page_iter iter; | 299 | struct sg_dma_page_iter iter; |
| 300 | unsigned long i; | 300 | unsigned long i; |
| 301 | unsigned long num_pages; | 301 | unsigned long num_pages; |
| 302 | bool (*next)(struct vmw_piter *); | 302 | bool (*next)(struct vmw_piter *); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 2ff7ba04d8c8..33533d126277 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
| @@ -2010,6 +2010,11 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
| 2010 | return 0; | 2010 | return 0; |
| 2011 | 2011 | ||
| 2012 | if (cmd->body.shid != SVGA3D_INVALID_ID) { | 2012 | if (cmd->body.shid != SVGA3D_INVALID_ID) { |
| 2013 | /* | ||
| 2014 | * This is the compat shader path - Per device guest-backed | ||
| 2015 | * shaders, but user-space thinks it's per context host- | ||
| 2016 | * backed shaders. | ||
| 2017 | */ | ||
| 2013 | res = vmw_shader_lookup(vmw_context_res_man(ctx), | 2018 | res = vmw_shader_lookup(vmw_context_res_man(ctx), |
| 2014 | cmd->body.shid, cmd->body.type); | 2019 | cmd->body.shid, cmd->body.type); |
| 2015 | if (!IS_ERR(res)) { | 2020 | if (!IS_ERR(res)) { |
| @@ -2017,6 +2022,14 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
| 2017 | VMW_RES_DIRTY_NONE); | 2022 | VMW_RES_DIRTY_NONE); |
| 2018 | if (unlikely(ret != 0)) | 2023 | if (unlikely(ret != 0)) |
| 2019 | return ret; | 2024 | return ret; |
| 2025 | |||
| 2026 | ret = vmw_resource_relocation_add | ||
| 2027 | (sw_context, res, | ||
| 2028 | vmw_ptr_diff(sw_context->buf_start, | ||
| 2029 | &cmd->body.shid), | ||
| 2030 | vmw_res_rel_normal); | ||
| 2031 | if (unlikely(ret != 0)) | ||
| 2032 | return ret; | ||
| 2020 | } | 2033 | } |
| 2021 | } | 2034 | } |
| 2022 | 2035 | ||
| @@ -2193,7 +2206,8 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, | |||
| 2193 | 2206 | ||
| 2194 | cmd = container_of(header, typeof(*cmd), header); | 2207 | cmd = container_of(header, typeof(*cmd), header); |
| 2195 | 2208 | ||
| 2196 | if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { | 2209 | if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX || |
| 2210 | cmd->body.type < SVGA3D_SHADERTYPE_MIN) { | ||
| 2197 | VMW_DEBUG_USER("Illegal shader type %u.\n", | 2211 | VMW_DEBUG_USER("Illegal shader type %u.\n", |
| 2198 | (unsigned int) cmd->body.type); | 2212 | (unsigned int) cmd->body.type); |
| 2199 | return -EINVAL; | 2213 | return -EINVAL; |
| @@ -2414,6 +2428,10 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, | |||
| 2414 | return -EINVAL; | 2428 | return -EINVAL; |
| 2415 | 2429 | ||
| 2416 | cmd = container_of(header, typeof(*cmd), header); | 2430 | cmd = container_of(header, typeof(*cmd), header); |
| 2431 | if (unlikely(cmd->sid == SVGA3D_INVALID_ID)) { | ||
| 2432 | VMW_DEBUG_USER("Invalid surface id.\n"); | ||
| 2433 | return -EINVAL; | ||
| 2434 | } | ||
| 2417 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, | 2435 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, |
| 2418 | VMW_RES_DIRTY_NONE, user_surface_converter, | 2436 | VMW_RES_DIRTY_NONE, user_surface_converter, |
| 2419 | &cmd->sid, &srf); | 2437 | &cmd->sid, &srf); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index a3357ff7540d..a6ea75b58a83 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | |||
| @@ -266,7 +266,9 @@ static bool __vmw_piter_non_sg_next(struct vmw_piter *viter) | |||
| 266 | 266 | ||
| 267 | static bool __vmw_piter_sg_next(struct vmw_piter *viter) | 267 | static bool __vmw_piter_sg_next(struct vmw_piter *viter) |
| 268 | { | 268 | { |
| 269 | return __sg_page_iter_next(&viter->iter); | 269 | bool ret = __vmw_piter_non_sg_next(viter); |
| 270 | |||
| 271 | return __sg_page_iter_dma_next(&viter->iter) && ret; | ||
| 270 | } | 272 | } |
| 271 | 273 | ||
| 272 | 274 | ||
| @@ -284,12 +286,6 @@ static struct page *__vmw_piter_non_sg_page(struct vmw_piter *viter) | |||
| 284 | return viter->pages[viter->i]; | 286 | return viter->pages[viter->i]; |
| 285 | } | 287 | } |
| 286 | 288 | ||
| 287 | static struct page *__vmw_piter_sg_page(struct vmw_piter *viter) | ||
| 288 | { | ||
| 289 | return sg_page_iter_page(&viter->iter); | ||
| 290 | } | ||
| 291 | |||
| 292 | |||
| 293 | /** | 289 | /** |
| 294 | * Helper functions to return the DMA address of the current page. | 290 | * Helper functions to return the DMA address of the current page. |
| 295 | * | 291 | * |
| @@ -311,13 +307,7 @@ static dma_addr_t __vmw_piter_dma_addr(struct vmw_piter *viter) | |||
| 311 | 307 | ||
| 312 | static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter) | 308 | static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter) |
| 313 | { | 309 | { |
| 314 | /* | 310 | return sg_page_iter_dma_address(&viter->iter); |
| 315 | * FIXME: This driver wrongly mixes DMA and CPU SG list iteration and | ||
| 316 | * needs revision. See | ||
| 317 | * https://lore.kernel.org/lkml/20190104223531.GA1705@ziepe.ca/ | ||
| 318 | */ | ||
| 319 | return sg_page_iter_dma_address( | ||
| 320 | container_of(&viter->iter, struct sg_dma_page_iter, base)); | ||
| 321 | } | 311 | } |
| 322 | 312 | ||
| 323 | 313 | ||
| @@ -336,26 +326,23 @@ void vmw_piter_start(struct vmw_piter *viter, const struct vmw_sg_table *vsgt, | |||
| 336 | { | 326 | { |
| 337 | viter->i = p_offset - 1; | 327 | viter->i = p_offset - 1; |
| 338 | viter->num_pages = vsgt->num_pages; | 328 | viter->num_pages = vsgt->num_pages; |
| 329 | viter->page = &__vmw_piter_non_sg_page; | ||
| 330 | viter->pages = vsgt->pages; | ||
| 339 | switch (vsgt->mode) { | 331 | switch (vsgt->mode) { |
| 340 | case vmw_dma_phys: | 332 | case vmw_dma_phys: |
| 341 | viter->next = &__vmw_piter_non_sg_next; | 333 | viter->next = &__vmw_piter_non_sg_next; |
| 342 | viter->dma_address = &__vmw_piter_phys_addr; | 334 | viter->dma_address = &__vmw_piter_phys_addr; |
| 343 | viter->page = &__vmw_piter_non_sg_page; | ||
| 344 | viter->pages = vsgt->pages; | ||
| 345 | break; | 335 | break; |
| 346 | case vmw_dma_alloc_coherent: | 336 | case vmw_dma_alloc_coherent: |
| 347 | viter->next = &__vmw_piter_non_sg_next; | 337 | viter->next = &__vmw_piter_non_sg_next; |
| 348 | viter->dma_address = &__vmw_piter_dma_addr; | 338 | viter->dma_address = &__vmw_piter_dma_addr; |
| 349 | viter->page = &__vmw_piter_non_sg_page; | ||
| 350 | viter->addrs = vsgt->addrs; | 339 | viter->addrs = vsgt->addrs; |
| 351 | viter->pages = vsgt->pages; | ||
| 352 | break; | 340 | break; |
| 353 | case vmw_dma_map_populate: | 341 | case vmw_dma_map_populate: |
| 354 | case vmw_dma_map_bind: | 342 | case vmw_dma_map_bind: |
| 355 | viter->next = &__vmw_piter_sg_next; | 343 | viter->next = &__vmw_piter_sg_next; |
| 356 | viter->dma_address = &__vmw_piter_sg_addr; | 344 | viter->dma_address = &__vmw_piter_sg_addr; |
| 357 | viter->page = &__vmw_piter_sg_page; | 345 | __sg_page_iter_start(&viter->iter.base, vsgt->sgt->sgl, |
| 358 | __sg_page_iter_start(&viter->iter, vsgt->sgt->sgl, | ||
| 359 | vsgt->sgt->orig_nents, p_offset); | 346 | vsgt->sgt->orig_nents, p_offset); |
| 360 | break; | 347 | break; |
| 361 | default: | 348 | default: |
