diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2018-08-06 14:56:34 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2018-08-06 14:56:34 -0400 |
| commit | 315706049c343794ad0d3e5b6f6b60b900457b11 (patch) | |
| tree | 0a1596a4b5843a6262d17b4c656715854784977d /drivers/gpu | |
| parent | 706d51681d636a0c4a5ef53395ec3b803e45ed4d (diff) | |
| parent | c40a56a7818cfe735fc93a69e1875f8bba834483 (diff) | |
Merge branch 'x86/pti-urgent' into x86/pti
Integrate the PTI Global bit fixes which conflict with the 32bit PTI
support.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/gpu')
51 files changed, 445 insertions, 149 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index f4c474a95875..71efcf38f11b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | |||
| @@ -57,6 +57,10 @@ | |||
| 57 | #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 | 57 | #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 |
| 58 | #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c | 58 | #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c |
| 59 | #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 | 59 | #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 |
| 60 | #define ACP_BT_PLAY_REGS_START 0x14970 | ||
| 61 | #define ACP_BT_PLAY_REGS_END 0x14a24 | ||
| 62 | #define ACP_BT_COMP1_REG_OFFSET 0xac | ||
| 63 | #define ACP_BT_COMP2_REG_OFFSET 0xa8 | ||
| 60 | 64 | ||
| 61 | #define mmACP_PGFSM_RETAIN_REG 0x51c9 | 65 | #define mmACP_PGFSM_RETAIN_REG 0x51c9 |
| 62 | #define mmACP_PGFSM_CONFIG_REG 0x51ca | 66 | #define mmACP_PGFSM_CONFIG_REG 0x51ca |
| @@ -77,7 +81,7 @@ | |||
| 77 | #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF | 81 | #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF |
| 78 | 82 | ||
| 79 | #define ACP_TIMEOUT_LOOP 0x000000FF | 83 | #define ACP_TIMEOUT_LOOP 0x000000FF |
| 80 | #define ACP_DEVS 3 | 84 | #define ACP_DEVS 4 |
| 81 | #define ACP_SRC_ID 162 | 85 | #define ACP_SRC_ID 162 |
| 82 | 86 | ||
| 83 | enum { | 87 | enum { |
| @@ -316,14 +320,13 @@ static int acp_hw_init(void *handle) | |||
| 316 | if (adev->acp.acp_cell == NULL) | 320 | if (adev->acp.acp_cell == NULL) |
| 317 | return -ENOMEM; | 321 | return -ENOMEM; |
| 318 | 322 | ||
| 319 | adev->acp.acp_res = kcalloc(4, sizeof(struct resource), GFP_KERNEL); | 323 | adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL); |
| 320 | |||
| 321 | if (adev->acp.acp_res == NULL) { | 324 | if (adev->acp.acp_res == NULL) { |
| 322 | kfree(adev->acp.acp_cell); | 325 | kfree(adev->acp.acp_cell); |
| 323 | return -ENOMEM; | 326 | return -ENOMEM; |
| 324 | } | 327 | } |
| 325 | 328 | ||
| 326 | i2s_pdata = kcalloc(2, sizeof(struct i2s_platform_data), GFP_KERNEL); | 329 | i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL); |
| 327 | if (i2s_pdata == NULL) { | 330 | if (i2s_pdata == NULL) { |
| 328 | kfree(adev->acp.acp_res); | 331 | kfree(adev->acp.acp_res); |
| 329 | kfree(adev->acp.acp_cell); | 332 | kfree(adev->acp.acp_cell); |
| @@ -358,6 +361,20 @@ static int acp_hw_init(void *handle) | |||
| 358 | i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; | 361 | i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; |
| 359 | i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; | 362 | i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; |
| 360 | 363 | ||
| 364 | i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; | ||
| 365 | switch (adev->asic_type) { | ||
| 366 | case CHIP_STONEY: | ||
| 367 | i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; | ||
| 368 | break; | ||
| 369 | default: | ||
| 370 | break; | ||
| 371 | } | ||
| 372 | |||
| 373 | i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD; | ||
| 374 | i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000; | ||
| 375 | i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET; | ||
| 376 | i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET; | ||
| 377 | |||
| 361 | adev->acp.acp_res[0].name = "acp2x_dma"; | 378 | adev->acp.acp_res[0].name = "acp2x_dma"; |
| 362 | adev->acp.acp_res[0].flags = IORESOURCE_MEM; | 379 | adev->acp.acp_res[0].flags = IORESOURCE_MEM; |
| 363 | adev->acp.acp_res[0].start = acp_base; | 380 | adev->acp.acp_res[0].start = acp_base; |
| @@ -373,13 +390,18 @@ static int acp_hw_init(void *handle) | |||
| 373 | adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START; | 390 | adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START; |
| 374 | adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END; | 391 | adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END; |
| 375 | 392 | ||
| 376 | adev->acp.acp_res[3].name = "acp2x_dma_irq"; | 393 | adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap"; |
| 377 | adev->acp.acp_res[3].flags = IORESOURCE_IRQ; | 394 | adev->acp.acp_res[3].flags = IORESOURCE_MEM; |
| 378 | adev->acp.acp_res[3].start = amdgpu_irq_create_mapping(adev, 162); | 395 | adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START; |
| 379 | adev->acp.acp_res[3].end = adev->acp.acp_res[3].start; | 396 | adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END; |
| 397 | |||
| 398 | adev->acp.acp_res[4].name = "acp2x_dma_irq"; | ||
| 399 | adev->acp.acp_res[4].flags = IORESOURCE_IRQ; | ||
| 400 | adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162); | ||
| 401 | adev->acp.acp_res[4].end = adev->acp.acp_res[4].start; | ||
| 380 | 402 | ||
| 381 | adev->acp.acp_cell[0].name = "acp_audio_dma"; | 403 | adev->acp.acp_cell[0].name = "acp_audio_dma"; |
| 382 | adev->acp.acp_cell[0].num_resources = 4; | 404 | adev->acp.acp_cell[0].num_resources = 5; |
| 383 | adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; | 405 | adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; |
| 384 | adev->acp.acp_cell[0].platform_data = &adev->asic_type; | 406 | adev->acp.acp_cell[0].platform_data = &adev->asic_type; |
| 385 | adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); | 407 | adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); |
| @@ -396,6 +418,12 @@ static int acp_hw_init(void *handle) | |||
| 396 | adev->acp.acp_cell[2].platform_data = &i2s_pdata[1]; | 418 | adev->acp.acp_cell[2].platform_data = &i2s_pdata[1]; |
| 397 | adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data); | 419 | adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data); |
| 398 | 420 | ||
| 421 | adev->acp.acp_cell[3].name = "designware-i2s"; | ||
| 422 | adev->acp.acp_cell[3].num_resources = 1; | ||
| 423 | adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3]; | ||
| 424 | adev->acp.acp_cell[3].platform_data = &i2s_pdata[2]; | ||
| 425 | adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data); | ||
| 426 | |||
| 399 | r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, | 427 | r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, |
| 400 | ACP_DEVS); | 428 | ACP_DEVS); |
| 401 | if (r) | 429 | if (r) |
| @@ -451,7 +479,6 @@ static int acp_hw_init(void *handle) | |||
| 451 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | 479 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); |
| 452 | val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; | 480 | val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; |
| 453 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); | 481 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); |
| 454 | |||
| 455 | return 0; | 482 | return 0; |
| 456 | } | 483 | } |
| 457 | 484 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 9ab89371d9e8..ca8bf1c9a98e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | |||
| @@ -575,6 +575,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = { | |||
| 575 | { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, | 575 | { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, |
| 576 | { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, | 576 | { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, |
| 577 | { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, | 577 | { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, |
| 578 | { 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX }, | ||
| 578 | { 0, 0, 0, 0, 0 }, | 579 | { 0, 0, 0, 0, 0 }, |
| 579 | }; | 580 | }; |
| 580 | 581 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 82312a7bc6ad..9c85a90be293 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
| @@ -927,6 +927,10 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
| 927 | r = amdgpu_bo_vm_update_pte(p); | 927 | r = amdgpu_bo_vm_update_pte(p); |
| 928 | if (r) | 928 | if (r) |
| 929 | return r; | 929 | return r; |
| 930 | |||
| 931 | r = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv); | ||
| 932 | if (r) | ||
| 933 | return r; | ||
| 930 | } | 934 | } |
| 931 | 935 | ||
| 932 | return amdgpu_cs_sync_rings(p); | 936 | return amdgpu_cs_sync_rings(p); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 6e5284e6c028..2c5f093e79e3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -2747,6 +2747,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
| 2747 | if (r) | 2747 | if (r) |
| 2748 | return r; | 2748 | return r; |
| 2749 | 2749 | ||
| 2750 | /* Make sure IB tests flushed */ | ||
| 2751 | flush_delayed_work(&adev->late_init_work); | ||
| 2752 | |||
| 2750 | /* blat the mode back in */ | 2753 | /* blat the mode back in */ |
| 2751 | if (fbcon) { | 2754 | if (fbcon) { |
| 2752 | if (!amdgpu_device_has_dc_support(adev)) { | 2755 | if (!amdgpu_device_has_dc_support(adev)) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index edf16b2b957a..fdcb498f6d19 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
| @@ -107,6 +107,9 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base, | |||
| 107 | return; | 107 | return; |
| 108 | list_add_tail(&base->bo_list, &bo->va); | 108 | list_add_tail(&base->bo_list, &bo->va); |
| 109 | 109 | ||
| 110 | if (bo->tbo.type == ttm_bo_type_kernel) | ||
| 111 | list_move(&base->vm_status, &vm->relocated); | ||
| 112 | |||
| 110 | if (bo->tbo.resv != vm->root.base.bo->tbo.resv) | 113 | if (bo->tbo.resv != vm->root.base.bo->tbo.resv) |
| 111 | return; | 114 | return; |
| 112 | 115 | ||
| @@ -468,7 +471,6 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, | |||
| 468 | pt->parent = amdgpu_bo_ref(parent->base.bo); | 471 | pt->parent = amdgpu_bo_ref(parent->base.bo); |
| 469 | 472 | ||
| 470 | amdgpu_vm_bo_base_init(&entry->base, vm, pt); | 473 | amdgpu_vm_bo_base_init(&entry->base, vm, pt); |
| 471 | list_move(&entry->base.vm_status, &vm->relocated); | ||
| 472 | } | 474 | } |
| 473 | 475 | ||
| 474 | if (level < AMDGPU_VM_PTB) { | 476 | if (level < AMDGPU_VM_PTB) { |
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 4304d9e408b8..ace9ad578ca0 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 | |||
| @@ -83,22 +83,21 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, | |||
| 83 | enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? | 83 | enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? |
| 84 | I2C_MOT_TRUE : I2C_MOT_FALSE; | 84 | I2C_MOT_TRUE : I2C_MOT_FALSE; |
| 85 | enum ddc_result res; | 85 | enum ddc_result res; |
| 86 | uint32_t read_bytes = msg->size; | 86 | ssize_t read_bytes; |
| 87 | 87 | ||
| 88 | if (WARN_ON(msg->size > 16)) | 88 | if (WARN_ON(msg->size > 16)) |
| 89 | return -E2BIG; | 89 | return -E2BIG; |
| 90 | 90 | ||
| 91 | switch (msg->request & ~DP_AUX_I2C_MOT) { | 91 | switch (msg->request & ~DP_AUX_I2C_MOT) { |
| 92 | case DP_AUX_NATIVE_READ: | 92 | case DP_AUX_NATIVE_READ: |
| 93 | res = dal_ddc_service_read_dpcd_data( | 93 | read_bytes = dal_ddc_service_read_dpcd_data( |
| 94 | TO_DM_AUX(aux)->ddc_service, | 94 | TO_DM_AUX(aux)->ddc_service, |
| 95 | false, | 95 | false, |
| 96 | I2C_MOT_UNDEF, | 96 | I2C_MOT_UNDEF, |
| 97 | msg->address, | 97 | msg->address, |
| 98 | msg->buffer, | 98 | msg->buffer, |
| 99 | msg->size, | 99 | msg->size); |
| 100 | &read_bytes); | 100 | return read_bytes; |
| 101 | break; | ||
| 102 | case DP_AUX_NATIVE_WRITE: | 101 | case DP_AUX_NATIVE_WRITE: |
| 103 | res = dal_ddc_service_write_dpcd_data( | 102 | res = dal_ddc_service_write_dpcd_data( |
| 104 | TO_DM_AUX(aux)->ddc_service, | 103 | TO_DM_AUX(aux)->ddc_service, |
| @@ -109,15 +108,14 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, | |||
| 109 | msg->size); | 108 | msg->size); |
| 110 | break; | 109 | break; |
| 111 | case DP_AUX_I2C_READ: | 110 | case DP_AUX_I2C_READ: |
| 112 | res = dal_ddc_service_read_dpcd_data( | 111 | read_bytes = dal_ddc_service_read_dpcd_data( |
| 113 | TO_DM_AUX(aux)->ddc_service, | 112 | TO_DM_AUX(aux)->ddc_service, |
| 114 | true, | 113 | true, |
| 115 | mot, | 114 | mot, |
| 116 | msg->address, | 115 | msg->address, |
| 117 | msg->buffer, | 116 | msg->buffer, |
| 118 | msg->size, | 117 | msg->size); |
| 119 | &read_bytes); | 118 | return read_bytes; |
| 120 | break; | ||
| 121 | case DP_AUX_I2C_WRITE: | 119 | case DP_AUX_I2C_WRITE: |
| 122 | res = dal_ddc_service_write_dpcd_data( | 120 | res = dal_ddc_service_write_dpcd_data( |
| 123 | TO_DM_AUX(aux)->ddc_service, | 121 | TO_DM_AUX(aux)->ddc_service, |
| @@ -139,9 +137,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, | |||
| 139 | r == DDC_RESULT_SUCESSFULL); | 137 | r == DDC_RESULT_SUCESSFULL); |
| 140 | #endif | 138 | #endif |
| 141 | 139 | ||
| 142 | if (res != DDC_RESULT_SUCESSFULL) | 140 | return msg->size; |
| 143 | return -EIO; | ||
| 144 | return read_bytes; | ||
| 145 | } | 141 | } |
| 146 | 142 | ||
| 147 | static enum drm_connector_status | 143 | static enum drm_connector_status |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index 5a3346124a01..5a2e952c5bea 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c | |||
| @@ -255,8 +255,9 @@ static void pp_to_dc_clock_levels_with_latency( | |||
| 255 | DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); | 255 | DC_DECODE_PP_CLOCK_TYPE(dc_clk_type)); |
| 256 | 256 | ||
| 257 | for (i = 0; i < clk_level_info->num_levels; i++) { | 257 | for (i = 0; i < clk_level_info->num_levels; i++) { |
| 258 | DRM_DEBUG("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); | 258 | DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); |
| 259 | clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; | 259 | /* translate 10kHz to kHz */ |
| 260 | clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10; | ||
| 260 | clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; | 261 | clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us; |
| 261 | } | 262 | } |
| 262 | } | 263 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index ae48d603ebd6..49c2face1e7a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | |||
| @@ -629,14 +629,13 @@ bool dal_ddc_service_query_ddc_data( | |||
| 629 | return ret; | 629 | return ret; |
| 630 | } | 630 | } |
| 631 | 631 | ||
| 632 | enum ddc_result dal_ddc_service_read_dpcd_data( | 632 | ssize_t dal_ddc_service_read_dpcd_data( |
| 633 | struct ddc_service *ddc, | 633 | struct ddc_service *ddc, |
| 634 | bool i2c, | 634 | bool i2c, |
| 635 | enum i2c_mot_mode mot, | 635 | enum i2c_mot_mode mot, |
| 636 | uint32_t address, | 636 | uint32_t address, |
| 637 | uint8_t *data, | 637 | uint8_t *data, |
| 638 | uint32_t len, | 638 | uint32_t len) |
| 639 | uint32_t *read) | ||
| 640 | { | 639 | { |
| 641 | struct aux_payload read_payload = { | 640 | struct aux_payload read_payload = { |
| 642 | .i2c_over_aux = i2c, | 641 | .i2c_over_aux = i2c, |
| @@ -653,8 +652,6 @@ enum ddc_result dal_ddc_service_read_dpcd_data( | |||
| 653 | .mot = mot | 652 | .mot = mot |
| 654 | }; | 653 | }; |
| 655 | 654 | ||
| 656 | *read = 0; | ||
| 657 | |||
| 658 | if (len > DEFAULT_AUX_MAX_DATA_SIZE) { | 655 | if (len > DEFAULT_AUX_MAX_DATA_SIZE) { |
| 659 | BREAK_TO_DEBUGGER(); | 656 | BREAK_TO_DEBUGGER(); |
| 660 | return DDC_RESULT_FAILED_INVALID_OPERATION; | 657 | return DDC_RESULT_FAILED_INVALID_OPERATION; |
| @@ -664,8 +661,7 @@ enum ddc_result dal_ddc_service_read_dpcd_data( | |||
| 664 | ddc->ctx->i2caux, | 661 | ddc->ctx->i2caux, |
| 665 | ddc->ddc_pin, | 662 | ddc->ddc_pin, |
| 666 | &command)) { | 663 | &command)) { |
| 667 | *read = command.payloads->length; | 664 | return (ssize_t)command.payloads->length; |
| 668 | return DDC_RESULT_SUCESSFULL; | ||
| 669 | } | 665 | } |
| 670 | 666 | ||
| 671 | return DDC_RESULT_FAILED_OPERATION; | 667 | return DDC_RESULT_FAILED_OPERATION; |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 7857cb42b3e6..bdd121485cbc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | |||
| @@ -1767,12 +1767,10 @@ static void dp_test_send_link_training(struct dc_link *link) | |||
| 1767 | dp_retrain_link_dp_test(link, &link_settings, false); | 1767 | dp_retrain_link_dp_test(link, &link_settings, false); |
| 1768 | } | 1768 | } |
| 1769 | 1769 | ||
| 1770 | /* TODO hbr2 compliance eye output is unstable | 1770 | /* TODO Raven hbr2 compliance eye output is unstable |
| 1771 | * (toggling on and off) with debugger break | 1771 | * (toggling on and off) with debugger break |
| 1772 | * This caueses intermittent PHY automation failure | 1772 | * This caueses intermittent PHY automation failure |
| 1773 | * Need to look into the root cause */ | 1773 | * Need to look into the root cause */ |
| 1774 | static uint8_t force_tps4_for_cp2520 = 1; | ||
| 1775 | |||
| 1776 | static void dp_test_send_phy_test_pattern(struct dc_link *link) | 1774 | static void dp_test_send_phy_test_pattern(struct dc_link *link) |
| 1777 | { | 1775 | { |
| 1778 | union phy_test_pattern dpcd_test_pattern; | 1776 | union phy_test_pattern dpcd_test_pattern; |
| @@ -1832,13 +1830,13 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) | |||
| 1832 | break; | 1830 | break; |
| 1833 | case PHY_TEST_PATTERN_CP2520_1: | 1831 | case PHY_TEST_PATTERN_CP2520_1: |
| 1834 | /* CP2520 pattern is unstable, temporarily use TPS4 instead */ | 1832 | /* CP2520 pattern is unstable, temporarily use TPS4 instead */ |
| 1835 | test_pattern = (force_tps4_for_cp2520 == 1) ? | 1833 | test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ? |
| 1836 | DP_TEST_PATTERN_TRAINING_PATTERN4 : | 1834 | DP_TEST_PATTERN_TRAINING_PATTERN4 : |
| 1837 | DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; | 1835 | DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; |
| 1838 | break; | 1836 | break; |
| 1839 | case PHY_TEST_PATTERN_CP2520_2: | 1837 | case PHY_TEST_PATTERN_CP2520_2: |
| 1840 | /* CP2520 pattern is unstable, temporarily use TPS4 instead */ | 1838 | /* CP2520 pattern is unstable, temporarily use TPS4 instead */ |
| 1841 | test_pattern = (force_tps4_for_cp2520 == 1) ? | 1839 | test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ? |
| 1842 | DP_TEST_PATTERN_TRAINING_PATTERN4 : | 1840 | DP_TEST_PATTERN_TRAINING_PATTERN4 : |
| 1843 | DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; | 1841 | DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; |
| 1844 | break; | 1842 | break; |
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 9cfde0ccf4e9..53c71296f3dd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h | |||
| @@ -76,6 +76,7 @@ struct dc_caps { | |||
| 76 | bool is_apu; | 76 | bool is_apu; |
| 77 | bool dual_link_dvi; | 77 | bool dual_link_dvi; |
| 78 | bool post_blend_color_processing; | 78 | bool post_blend_color_processing; |
| 79 | bool force_dp_tps4_for_cp2520; | ||
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 81 | struct dc_dcc_surface_param { | 82 | struct dc_dcc_surface_param { |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index b235a75355b8..bae752332a9f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c | |||
| @@ -741,6 +741,29 @@ static struct mem_input_funcs dce_mi_funcs = { | |||
| 741 | .mem_input_is_flip_pending = dce_mi_is_flip_pending | 741 | .mem_input_is_flip_pending = dce_mi_is_flip_pending |
| 742 | }; | 742 | }; |
| 743 | 743 | ||
| 744 | static struct mem_input_funcs dce112_mi_funcs = { | ||
| 745 | .mem_input_program_display_marks = dce112_mi_program_display_marks, | ||
| 746 | .allocate_mem_input = dce_mi_allocate_dmif, | ||
| 747 | .free_mem_input = dce_mi_free_dmif, | ||
| 748 | .mem_input_program_surface_flip_and_addr = | ||
| 749 | dce_mi_program_surface_flip_and_addr, | ||
| 750 | .mem_input_program_pte_vm = dce_mi_program_pte_vm, | ||
| 751 | .mem_input_program_surface_config = | ||
| 752 | dce_mi_program_surface_config, | ||
| 753 | .mem_input_is_flip_pending = dce_mi_is_flip_pending | ||
| 754 | }; | ||
| 755 | |||
| 756 | static struct mem_input_funcs dce120_mi_funcs = { | ||
| 757 | .mem_input_program_display_marks = dce120_mi_program_display_marks, | ||
| 758 | .allocate_mem_input = dce_mi_allocate_dmif, | ||
| 759 | .free_mem_input = dce_mi_free_dmif, | ||
| 760 | .mem_input_program_surface_flip_and_addr = | ||
| 761 | dce_mi_program_surface_flip_and_addr, | ||
| 762 | .mem_input_program_pte_vm = dce_mi_program_pte_vm, | ||
| 763 | .mem_input_program_surface_config = | ||
| 764 | dce_mi_program_surface_config, | ||
| 765 | .mem_input_is_flip_pending = dce_mi_is_flip_pending | ||
| 766 | }; | ||
| 744 | 767 | ||
| 745 | void dce_mem_input_construct( | 768 | void dce_mem_input_construct( |
| 746 | struct dce_mem_input *dce_mi, | 769 | struct dce_mem_input *dce_mi, |
| @@ -769,7 +792,7 @@ void dce112_mem_input_construct( | |||
| 769 | const struct dce_mem_input_mask *mi_mask) | 792 | const struct dce_mem_input_mask *mi_mask) |
| 770 | { | 793 | { |
| 771 | dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); | 794 | dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); |
| 772 | dce_mi->base.funcs->mem_input_program_display_marks = dce112_mi_program_display_marks; | 795 | dce_mi->base.funcs = &dce112_mi_funcs; |
| 773 | } | 796 | } |
| 774 | 797 | ||
| 775 | void dce120_mem_input_construct( | 798 | void dce120_mem_input_construct( |
| @@ -781,5 +804,5 @@ void dce120_mem_input_construct( | |||
| 781 | const struct dce_mem_input_mask *mi_mask) | 804 | const struct dce_mem_input_mask *mi_mask) |
| 782 | { | 805 | { |
| 783 | dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); | 806 | dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); |
| 784 | dce_mi->base.funcs->mem_input_program_display_marks = dce120_mi_program_display_marks; | 807 | dce_mi->base.funcs = &dce120_mi_funcs; |
| 785 | } | 808 | } |
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 38ec0d609297..344dd2e69e7c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | |||
| @@ -678,9 +678,22 @@ bool dce100_validate_bandwidth( | |||
| 678 | struct dc *dc, | 678 | struct dc *dc, |
| 679 | struct dc_state *context) | 679 | struct dc_state *context) |
| 680 | { | 680 | { |
| 681 | /* TODO implement when needed but for now hardcode max value*/ | 681 | int i; |
| 682 | context->bw.dce.dispclk_khz = 681000; | 682 | bool at_least_one_pipe = false; |
| 683 | context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER; | 683 | |
| 684 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
| 685 | if (context->res_ctx.pipe_ctx[i].stream) | ||
| 686 | at_least_one_pipe = true; | ||
| 687 | } | ||
| 688 | |||
| 689 | if (at_least_one_pipe) { | ||
| 690 | /* TODO implement when needed but for now hardcode max value*/ | ||
| 691 | context->bw.dce.dispclk_khz = 681000; | ||
| 692 | context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER; | ||
| 693 | } else { | ||
| 694 | context->bw.dce.dispclk_khz = 0; | ||
| 695 | context->bw.dce.yclk_khz = 0; | ||
| 696 | } | ||
| 684 | 697 | ||
| 685 | return true; | 698 | return true; |
| 686 | } | 699 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index df5cb2d1d164..34dac84066a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | |||
| @@ -1027,6 +1027,8 @@ static bool construct( | |||
| 1027 | dc->caps.max_slave_planes = 1; | 1027 | dc->caps.max_slave_planes = 1; |
| 1028 | dc->caps.is_apu = true; | 1028 | dc->caps.is_apu = true; |
| 1029 | dc->caps.post_blend_color_processing = false; | 1029 | dc->caps.post_blend_color_processing = false; |
| 1030 | /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ | ||
| 1031 | dc->caps.force_dp_tps4_for_cp2520 = true; | ||
| 1030 | 1032 | ||
| 1031 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) | 1033 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) |
| 1032 | dc->debug = debug_defaults_drv; | 1034 | dc->debug = debug_defaults_drv; |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h index 30b3a08b91be..090b7a8dd67b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h | |||
| @@ -102,14 +102,13 @@ bool dal_ddc_service_query_ddc_data( | |||
| 102 | uint8_t *read_buf, | 102 | uint8_t *read_buf, |
| 103 | uint32_t read_size); | 103 | uint32_t read_size); |
| 104 | 104 | ||
| 105 | enum ddc_result dal_ddc_service_read_dpcd_data( | 105 | ssize_t dal_ddc_service_read_dpcd_data( |
| 106 | struct ddc_service *ddc, | 106 | struct ddc_service *ddc, |
| 107 | bool i2c, | 107 | bool i2c, |
| 108 | enum i2c_mot_mode mot, | 108 | enum i2c_mot_mode mot, |
| 109 | uint32_t address, | 109 | uint32_t address, |
| 110 | uint8_t *data, | 110 | uint8_t *data, |
| 111 | uint32_t len, | 111 | uint32_t len); |
| 112 | uint32_t *read); | ||
| 113 | 112 | ||
| 114 | enum ddc_result dal_ddc_service_write_dpcd_data( | 113 | enum ddc_result dal_ddc_service_write_dpcd_data( |
| 115 | struct ddc_service *ddc, | 114 | struct ddc_service *ddc, |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c index d644a9bb9078..9f407c48d4f0 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | |||
| @@ -381,6 +381,7 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) | |||
| 381 | uint32_t fw_to_load; | 381 | uint32_t fw_to_load; |
| 382 | int result = 0; | 382 | int result = 0; |
| 383 | struct SMU_DRAMData_TOC *toc; | 383 | struct SMU_DRAMData_TOC *toc; |
| 384 | uint32_t num_entries = 0; | ||
| 384 | 385 | ||
| 385 | if (!hwmgr->reload_fw) { | 386 | if (!hwmgr->reload_fw) { |
| 386 | pr_info("skip reloading...\n"); | 387 | pr_info("skip reloading...\n"); |
| @@ -422,41 +423,41 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) | |||
| 422 | } | 423 | } |
| 423 | 424 | ||
| 424 | toc = (struct SMU_DRAMData_TOC *)smu_data->header; | 425 | toc = (struct SMU_DRAMData_TOC *)smu_data->header; |
| 425 | toc->num_entries = 0; | ||
| 426 | toc->structure_version = 1; | 426 | toc->structure_version = 1; |
| 427 | 427 | ||
| 428 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 428 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 429 | UCODE_ID_RLC_G, &toc->entry[toc->num_entries++]), | 429 | UCODE_ID_RLC_G, &toc->entry[num_entries++]), |
| 430 | "Failed to Get Firmware Entry.", return -EINVAL); | 430 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 431 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 431 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 432 | UCODE_ID_CP_CE, &toc->entry[toc->num_entries++]), | 432 | UCODE_ID_CP_CE, &toc->entry[num_entries++]), |
| 433 | "Failed to Get Firmware Entry.", return -EINVAL); | 433 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 434 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 434 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 435 | UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]), | 435 | UCODE_ID_CP_PFP, &toc->entry[num_entries++]), |
| 436 | "Failed to Get Firmware Entry.", return -EINVAL); | 436 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 437 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 437 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 438 | UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]), | 438 | UCODE_ID_CP_ME, &toc->entry[num_entries++]), |
| 439 | "Failed to Get Firmware Entry.", return -EINVAL); | 439 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 440 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 440 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 441 | UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]), | 441 | UCODE_ID_CP_MEC, &toc->entry[num_entries++]), |
| 442 | "Failed to Get Firmware Entry.", return -EINVAL); | 442 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 443 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 443 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 444 | UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]), | 444 | UCODE_ID_CP_MEC_JT1, &toc->entry[num_entries++]), |
| 445 | "Failed to Get Firmware Entry.", return -EINVAL); | 445 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 446 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 446 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 447 | UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]), | 447 | UCODE_ID_CP_MEC_JT2, &toc->entry[num_entries++]), |
| 448 | "Failed to Get Firmware Entry.", return -EINVAL); | 448 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 449 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 449 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 450 | UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]), | 450 | UCODE_ID_SDMA0, &toc->entry[num_entries++]), |
| 451 | "Failed to Get Firmware Entry.", return -EINVAL); | 451 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 452 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 452 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 453 | UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), | 453 | UCODE_ID_SDMA1, &toc->entry[num_entries++]), |
| 454 | "Failed to Get Firmware Entry.", return -EINVAL); | 454 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 455 | if (!hwmgr->not_vf) | 455 | if (!hwmgr->not_vf) |
| 456 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, | 456 | PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, |
| 457 | UCODE_ID_MEC_STORAGE, &toc->entry[toc->num_entries++]), | 457 | UCODE_ID_MEC_STORAGE, &toc->entry[num_entries++]), |
| 458 | "Failed to Get Firmware Entry.", return -EINVAL); | 458 | "Failed to Get Firmware Entry.", return -EINVAL); |
| 459 | 459 | ||
| 460 | toc->num_entries = num_entries; | ||
| 460 | smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_HI, upper_32_bits(smu_data->header_buffer.mc_addr)); | 461 | smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_HI, upper_32_bits(smu_data->header_buffer.mc_addr)); |
| 461 | smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_LO, lower_32_bits(smu_data->header_buffer.mc_addr)); | 462 | smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_LO, lower_32_bits(smu_data->header_buffer.mc_addr)); |
| 462 | 463 | ||
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 03eeee11dd5b..42a40daff132 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
| @@ -519,8 +519,9 @@ static irqreturn_t armada_drm_irq(int irq, void *arg) | |||
| 519 | u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); | 519 | u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); |
| 520 | 520 | ||
| 521 | /* | 521 | /* |
| 522 | * This is rediculous - rather than writing bits to clear, we | 522 | * Reading the ISR appears to clear bits provided CLEAN_SPU_IRQ_ISR |
| 523 | * have to set the actual status register value. This is racy. | 523 | * is set. Writing has some other effect to acknowledge the IRQ - |
| 524 | * without this, we only get a single IRQ. | ||
| 524 | */ | 525 | */ |
| 525 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); | 526 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); |
| 526 | 527 | ||
| @@ -1116,16 +1117,22 @@ armada_drm_crtc_set_property(struct drm_crtc *crtc, | |||
| 1116 | static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc) | 1117 | static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc) |
| 1117 | { | 1118 | { |
| 1118 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 1119 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); |
| 1120 | unsigned long flags; | ||
| 1119 | 1121 | ||
| 1122 | spin_lock_irqsave(&dcrtc->irq_lock, flags); | ||
| 1120 | armada_drm_crtc_enable_irq(dcrtc, VSYNC_IRQ_ENA); | 1123 | armada_drm_crtc_enable_irq(dcrtc, VSYNC_IRQ_ENA); |
| 1124 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); | ||
| 1121 | return 0; | 1125 | return 0; |
| 1122 | } | 1126 | } |
| 1123 | 1127 | ||
| 1124 | static void armada_drm_crtc_disable_vblank(struct drm_crtc *crtc) | 1128 | static void armada_drm_crtc_disable_vblank(struct drm_crtc *crtc) |
| 1125 | { | 1129 | { |
| 1126 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 1130 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); |
| 1131 | unsigned long flags; | ||
| 1127 | 1132 | ||
| 1133 | spin_lock_irqsave(&dcrtc->irq_lock, flags); | ||
| 1128 | armada_drm_crtc_disable_irq(dcrtc, VSYNC_IRQ_ENA); | 1134 | armada_drm_crtc_disable_irq(dcrtc, VSYNC_IRQ_ENA); |
| 1135 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); | ||
| 1129 | } | 1136 | } |
| 1130 | 1137 | ||
| 1131 | static const struct drm_crtc_funcs armada_crtc_funcs = { | 1138 | static const struct drm_crtc_funcs armada_crtc_funcs = { |
| @@ -1415,6 +1422,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, | |||
| 1415 | CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); | 1422 | CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); |
| 1416 | writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); | 1423 | writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); |
| 1417 | writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); | 1424 | writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); |
| 1425 | readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR); | ||
| 1418 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); | 1426 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); |
| 1419 | 1427 | ||
| 1420 | ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", | 1428 | ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", |
diff --git a/drivers/gpu/drm/armada/armada_hw.h b/drivers/gpu/drm/armada/armada_hw.h index 27319a8335e2..345dc4d0851e 100644 --- a/drivers/gpu/drm/armada/armada_hw.h +++ b/drivers/gpu/drm/armada/armada_hw.h | |||
| @@ -160,6 +160,7 @@ enum { | |||
| 160 | CFG_ALPHAM_GRA = 0x1 << 16, | 160 | CFG_ALPHAM_GRA = 0x1 << 16, |
| 161 | CFG_ALPHAM_CFG = 0x2 << 16, | 161 | CFG_ALPHAM_CFG = 0x2 << 16, |
| 162 | CFG_ALPHA_MASK = 0xff << 8, | 162 | CFG_ALPHA_MASK = 0xff << 8, |
| 163 | #define CFG_ALPHA(x) ((x) << 8) | ||
| 163 | CFG_PIXCMD_MASK = 0xff, | 164 | CFG_PIXCMD_MASK = 0xff, |
| 164 | }; | 165 | }; |
| 165 | 166 | ||
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index c391955009d6..afa7ded3ae31 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c | |||
| @@ -28,6 +28,7 @@ struct armada_ovl_plane_properties { | |||
| 28 | uint16_t contrast; | 28 | uint16_t contrast; |
| 29 | uint16_t saturation; | 29 | uint16_t saturation; |
| 30 | uint32_t colorkey_mode; | 30 | uint32_t colorkey_mode; |
| 31 | uint32_t colorkey_enable; | ||
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| 33 | struct armada_ovl_plane { | 34 | struct armada_ovl_plane { |
| @@ -54,11 +55,13 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties *prop, | |||
| 54 | writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE); | 55 | writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE); |
| 55 | 56 | ||
| 56 | spin_lock_irq(&dcrtc->irq_lock); | 57 | spin_lock_irq(&dcrtc->irq_lock); |
| 57 | armada_updatel(prop->colorkey_mode | CFG_ALPHAM_GRA, | 58 | armada_updatel(prop->colorkey_mode, |
| 58 | CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK, | 59 | CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK, |
| 59 | dcrtc->base + LCD_SPU_DMA_CTRL1); | 60 | dcrtc->base + LCD_SPU_DMA_CTRL1); |
| 60 | 61 | if (dcrtc->variant->has_spu_adv_reg) | |
| 61 | armada_updatel(ADV_GRACOLORKEY, 0, dcrtc->base + LCD_SPU_ADV_REG); | 62 | armada_updatel(prop->colorkey_enable, |
| 63 | ADV_GRACOLORKEY | ADV_VIDCOLORKEY, | ||
| 64 | dcrtc->base + LCD_SPU_ADV_REG); | ||
| 62 | spin_unlock_irq(&dcrtc->irq_lock); | 65 | spin_unlock_irq(&dcrtc->irq_lock); |
| 63 | } | 66 | } |
| 64 | 67 | ||
| @@ -321,8 +324,17 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane, | |||
| 321 | dplane->prop.colorkey_vb |= K2B(val); | 324 | dplane->prop.colorkey_vb |= K2B(val); |
| 322 | update_attr = true; | 325 | update_attr = true; |
| 323 | } else if (property == priv->colorkey_mode_prop) { | 326 | } else if (property == priv->colorkey_mode_prop) { |
| 324 | dplane->prop.colorkey_mode &= ~CFG_CKMODE_MASK; | 327 | if (val == CKMODE_DISABLE) { |
| 325 | dplane->prop.colorkey_mode |= CFG_CKMODE(val); | 328 | dplane->prop.colorkey_mode = |
| 329 | CFG_CKMODE(CKMODE_DISABLE) | | ||
| 330 | CFG_ALPHAM_CFG | CFG_ALPHA(255); | ||
| 331 | dplane->prop.colorkey_enable = 0; | ||
| 332 | } else { | ||
| 333 | dplane->prop.colorkey_mode = | ||
| 334 | CFG_CKMODE(val) | | ||
| 335 | CFG_ALPHAM_GRA | CFG_ALPHA(0); | ||
| 336 | dplane->prop.colorkey_enable = ADV_GRACOLORKEY; | ||
| 337 | } | ||
| 326 | update_attr = true; | 338 | update_attr = true; |
| 327 | } else if (property == priv->brightness_prop) { | 339 | } else if (property == priv->brightness_prop) { |
| 328 | dplane->prop.brightness = val - 256; | 340 | dplane->prop.brightness = val - 256; |
| @@ -453,7 +465,9 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) | |||
| 453 | dplane->prop.colorkey_yr = 0xfefefe00; | 465 | dplane->prop.colorkey_yr = 0xfefefe00; |
| 454 | dplane->prop.colorkey_ug = 0x01010100; | 466 | dplane->prop.colorkey_ug = 0x01010100; |
| 455 | dplane->prop.colorkey_vb = 0x01010100; | 467 | dplane->prop.colorkey_vb = 0x01010100; |
| 456 | dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB); | 468 | dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB) | |
| 469 | CFG_ALPHAM_GRA | CFG_ALPHA(0); | ||
| 470 | dplane->prop.colorkey_enable = ADV_GRACOLORKEY; | ||
| 457 | dplane->prop.brightness = 0; | 471 | dplane->prop.brightness = 0; |
| 458 | dplane->prop.contrast = 0x4000; | 472 | dplane->prop.contrast = 0x4000; |
| 459 | dplane->prop.saturation = 0x4000; | 473 | dplane->prop.saturation = 0x4000; |
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 73021b388e12..dd3ff2f2cdce 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | |||
| @@ -429,6 +429,18 @@ static void adv7511_hpd_work(struct work_struct *work) | |||
| 429 | else | 429 | else |
| 430 | status = connector_status_disconnected; | 430 | status = connector_status_disconnected; |
| 431 | 431 | ||
| 432 | /* | ||
| 433 | * The bridge resets its registers on unplug. So when we get a plug | ||
| 434 | * event and we're already supposed to be powered, cycle the bridge to | ||
| 435 | * restore its state. | ||
| 436 | */ | ||
| 437 | if (status == connector_status_connected && | ||
| 438 | adv7511->connector.status == connector_status_disconnected && | ||
| 439 | adv7511->powered) { | ||
| 440 | regcache_mark_dirty(adv7511->regmap); | ||
| 441 | adv7511_power_on(adv7511); | ||
| 442 | } | ||
| 443 | |||
| 432 | if (adv7511->connector.status != status) { | 444 | if (adv7511->connector.status != status) { |
| 433 | adv7511->connector.status = status; | 445 | adv7511->connector.status = status; |
| 434 | if (status == connector_status_disconnected) | 446 | if (status == connector_status_disconnected) |
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 130da5195f3b..81e32199d3ef 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
| @@ -1510,8 +1510,9 @@ int drm_atomic_helper_async_check(struct drm_device *dev, | |||
| 1510 | { | 1510 | { |
| 1511 | struct drm_crtc *crtc; | 1511 | struct drm_crtc *crtc; |
| 1512 | struct drm_crtc_state *crtc_state; | 1512 | struct drm_crtc_state *crtc_state; |
| 1513 | struct drm_plane *plane; | 1513 | struct drm_plane *plane = NULL; |
| 1514 | struct drm_plane_state *old_plane_state, *new_plane_state; | 1514 | struct drm_plane_state *old_plane_state = NULL; |
| 1515 | struct drm_plane_state *new_plane_state = NULL; | ||
| 1515 | const struct drm_plane_helper_funcs *funcs; | 1516 | const struct drm_plane_helper_funcs *funcs; |
| 1516 | int i, n_planes = 0; | 1517 | int i, n_planes = 0; |
| 1517 | 1518 | ||
| @@ -1527,7 +1528,8 @@ int drm_atomic_helper_async_check(struct drm_device *dev, | |||
| 1527 | if (n_planes != 1) | 1528 | if (n_planes != 1) |
| 1528 | return -EINVAL; | 1529 | return -EINVAL; |
| 1529 | 1530 | ||
| 1530 | if (!new_plane_state->crtc) | 1531 | if (!new_plane_state->crtc || |
| 1532 | old_plane_state->crtc != new_plane_state->crtc) | ||
| 1531 | return -EINVAL; | 1533 | return -EINVAL; |
| 1532 | 1534 | ||
| 1533 | funcs = plane->helper_private; | 1535 | funcs = plane->helper_private; |
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index 3c4000facb36..f973d287696a 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c | |||
| @@ -372,7 +372,7 @@ int drm_legacy_addctx(struct drm_device *dev, void *data, | |||
| 372 | ctx->handle = drm_legacy_ctxbitmap_next(dev); | 372 | ctx->handle = drm_legacy_ctxbitmap_next(dev); |
| 373 | } | 373 | } |
| 374 | DRM_DEBUG("%d\n", ctx->handle); | 374 | DRM_DEBUG("%d\n", ctx->handle); |
| 375 | if (ctx->handle == -1) { | 375 | if (ctx->handle < 0) { |
| 376 | DRM_DEBUG("Not enough free contexts.\n"); | 376 | DRM_DEBUG("Not enough free contexts.\n"); |
| 377 | /* Should this return -EBUSY instead? */ | 377 | /* Should this return -EBUSY instead? */ |
| 378 | return -ENOMEM; | 378 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 50c73c0a20b9..d638c0fb3418 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c | |||
| @@ -553,24 +553,13 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, | |||
| 553 | 553 | ||
| 554 | /* Clone the lessor file to create a new file for us */ | 554 | /* Clone the lessor file to create a new file for us */ |
| 555 | DRM_DEBUG_LEASE("Allocating lease file\n"); | 555 | DRM_DEBUG_LEASE("Allocating lease file\n"); |
| 556 | path_get(&lessor_file->f_path); | 556 | lessee_file = filp_clone_open(lessor_file); |
| 557 | lessee_file = alloc_file(&lessor_file->f_path, | ||
| 558 | lessor_file->f_mode, | ||
| 559 | fops_get(lessor_file->f_inode->i_fop)); | ||
| 560 | |||
| 561 | if (IS_ERR(lessee_file)) { | 557 | if (IS_ERR(lessee_file)) { |
| 562 | ret = PTR_ERR(lessee_file); | 558 | ret = PTR_ERR(lessee_file); |
| 563 | goto out_lessee; | 559 | goto out_lessee; |
| 564 | } | 560 | } |
| 565 | 561 | ||
| 566 | /* Initialize the new file for DRM */ | ||
| 567 | DRM_DEBUG_LEASE("Initializing the file with %p\n", lessee_file->f_op->open); | ||
| 568 | ret = lessee_file->f_op->open(lessee_file->f_inode, lessee_file); | ||
| 569 | if (ret) | ||
| 570 | goto out_lessee_file; | ||
| 571 | |||
| 572 | lessee_priv = lessee_file->private_data; | 562 | lessee_priv = lessee_file->private_data; |
| 573 | |||
| 574 | /* Change the file to a master one */ | 563 | /* Change the file to a master one */ |
| 575 | drm_master_put(&lessee_priv->master); | 564 | drm_master_put(&lessee_priv->master); |
| 576 | lessee_priv->master = lessee; | 565 | lessee_priv->master = lessee; |
| @@ -588,9 +577,6 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, | |||
| 588 | DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n"); | 577 | DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n"); |
| 589 | return 0; | 578 | return 0; |
| 590 | 579 | ||
| 591 | out_lessee_file: | ||
| 592 | fput(lessee_file); | ||
| 593 | |||
| 594 | out_lessee: | 580 | out_lessee: |
| 595 | drm_master_put(&lessee); | 581 | drm_master_put(&lessee); |
| 596 | 582 | ||
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index b51c05d03f14..7f562410f9cf 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c | |||
| @@ -862,6 +862,7 @@ static int cmd_reg_handler(struct parser_exec_state *s, | |||
| 862 | { | 862 | { |
| 863 | struct intel_vgpu *vgpu = s->vgpu; | 863 | struct intel_vgpu *vgpu = s->vgpu; |
| 864 | struct intel_gvt *gvt = vgpu->gvt; | 864 | struct intel_gvt *gvt = vgpu->gvt; |
| 865 | u32 ctx_sr_ctl; | ||
| 865 | 866 | ||
| 866 | if (offset + 4 > gvt->device_info.mmio_size) { | 867 | if (offset + 4 > gvt->device_info.mmio_size) { |
| 867 | gvt_vgpu_err("%s access to (%x) outside of MMIO range\n", | 868 | gvt_vgpu_err("%s access to (%x) outside of MMIO range\n", |
| @@ -894,6 +895,28 @@ static int cmd_reg_handler(struct parser_exec_state *s, | |||
| 894 | patch_value(s, cmd_ptr(s, index), VGT_PVINFO_PAGE); | 895 | patch_value(s, cmd_ptr(s, index), VGT_PVINFO_PAGE); |
| 895 | } | 896 | } |
| 896 | 897 | ||
| 898 | /* TODO | ||
| 899 | * Right now only scan LRI command on KBL and in inhibit context. | ||
| 900 | * It's good enough to support initializing mmio by lri command in | ||
| 901 | * vgpu inhibit context on KBL. | ||
| 902 | */ | ||
| 903 | if (IS_KABYLAKE(s->vgpu->gvt->dev_priv) && | ||
| 904 | intel_gvt_mmio_is_in_ctx(gvt, offset) && | ||
| 905 | !strncmp(cmd, "lri", 3)) { | ||
| 906 | intel_gvt_hypervisor_read_gpa(s->vgpu, | ||
| 907 | s->workload->ring_context_gpa + 12, &ctx_sr_ctl, 4); | ||
| 908 | /* check inhibit context */ | ||
| 909 | if (ctx_sr_ctl & 1) { | ||
| 910 | u32 data = cmd_val(s, index + 1); | ||
| 911 | |||
| 912 | if (intel_gvt_mmio_has_mode_mask(s->vgpu->gvt, offset)) | ||
| 913 | intel_vgpu_mask_mmio_write(vgpu, | ||
| 914 | offset, &data, 4); | ||
| 915 | else | ||
| 916 | vgpu_vreg(vgpu, offset) = data; | ||
| 917 | } | ||
| 918 | } | ||
| 919 | |||
| 897 | /* TODO: Update the global mask if this MMIO is a masked-MMIO */ | 920 | /* TODO: Update the global mask if this MMIO is a masked-MMIO */ |
| 898 | intel_gvt_mmio_set_cmd_accessed(gvt, offset); | 921 | intel_gvt_mmio_set_cmd_accessed(gvt, offset); |
| 899 | return 0; | 922 | return 0; |
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 05d15a095310..858967daf04b 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h | |||
| @@ -268,6 +268,8 @@ struct intel_gvt_mmio { | |||
| 268 | #define F_CMD_ACCESSED (1 << 5) | 268 | #define F_CMD_ACCESSED (1 << 5) |
| 269 | /* This reg could be accessed by unaligned address */ | 269 | /* This reg could be accessed by unaligned address */ |
| 270 | #define F_UNALIGN (1 << 6) | 270 | #define F_UNALIGN (1 << 6) |
| 271 | /* This reg is saved/restored in context */ | ||
| 272 | #define F_IN_CTX (1 << 7) | ||
| 271 | 273 | ||
| 272 | struct gvt_mmio_block *mmio_block; | 274 | struct gvt_mmio_block *mmio_block; |
| 273 | unsigned int num_mmio_block; | 275 | unsigned int num_mmio_block; |
| @@ -639,6 +641,33 @@ static inline bool intel_gvt_mmio_has_mode_mask( | |||
| 639 | return gvt->mmio.mmio_attribute[offset >> 2] & F_MODE_MASK; | 641 | return gvt->mmio.mmio_attribute[offset >> 2] & F_MODE_MASK; |
| 640 | } | 642 | } |
| 641 | 643 | ||
| 644 | /** | ||
| 645 | * intel_gvt_mmio_is_in_ctx - check if a MMIO has in-ctx mask | ||
| 646 | * @gvt: a GVT device | ||
| 647 | * @offset: register offset | ||
| 648 | * | ||
| 649 | * Returns: | ||
| 650 | * True if a MMIO has a in-context mask, false if it isn't. | ||
| 651 | * | ||
| 652 | */ | ||
| 653 | static inline bool intel_gvt_mmio_is_in_ctx( | ||
| 654 | struct intel_gvt *gvt, unsigned int offset) | ||
| 655 | { | ||
| 656 | return gvt->mmio.mmio_attribute[offset >> 2] & F_IN_CTX; | ||
| 657 | } | ||
| 658 | |||
| 659 | /** | ||
| 660 | * intel_gvt_mmio_set_in_ctx - mask a MMIO in logical context | ||
| 661 | * @gvt: a GVT device | ||
| 662 | * @offset: register offset | ||
| 663 | * | ||
| 664 | */ | ||
| 665 | static inline void intel_gvt_mmio_set_in_ctx( | ||
| 666 | struct intel_gvt *gvt, unsigned int offset) | ||
| 667 | { | ||
| 668 | gvt->mmio.mmio_attribute[offset >> 2] |= F_IN_CTX; | ||
| 669 | } | ||
| 670 | |||
| 642 | int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu); | 671 | int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu); |
| 643 | void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu); | 672 | void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu); |
| 644 | int intel_gvt_debugfs_init(struct intel_gvt *gvt); | 673 | int intel_gvt_debugfs_init(struct intel_gvt *gvt); |
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index bcbc47a88a70..8f1caacdc78a 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
| @@ -3046,6 +3046,30 @@ int intel_vgpu_default_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 3046 | } | 3046 | } |
| 3047 | 3047 | ||
| 3048 | /** | 3048 | /** |
| 3049 | * intel_vgpu_mask_mmio_write - write mask register | ||
| 3050 | * @vgpu: a vGPU | ||
| 3051 | * @offset: access offset | ||
| 3052 | * @p_data: write data buffer | ||
| 3053 | * @bytes: access data length | ||
| 3054 | * | ||
| 3055 | * Returns: | ||
| 3056 | * Zero on success, negative error code if failed. | ||
| 3057 | */ | ||
| 3058 | int intel_vgpu_mask_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | ||
| 3059 | void *p_data, unsigned int bytes) | ||
| 3060 | { | ||
| 3061 | u32 mask, old_vreg; | ||
| 3062 | |||
| 3063 | old_vreg = vgpu_vreg(vgpu, offset); | ||
| 3064 | write_vreg(vgpu, offset, p_data, bytes); | ||
| 3065 | mask = vgpu_vreg(vgpu, offset) >> 16; | ||
| 3066 | vgpu_vreg(vgpu, offset) = (old_vreg & ~mask) | | ||
| 3067 | (vgpu_vreg(vgpu, offset) & mask); | ||
| 3068 | |||
| 3069 | return 0; | ||
| 3070 | } | ||
| 3071 | |||
| 3072 | /** | ||
| 3049 | * intel_gvt_in_force_nonpriv_whitelist - if a mmio is in whitelist to be | 3073 | * intel_gvt_in_force_nonpriv_whitelist - if a mmio is in whitelist to be |
| 3050 | * force-nopriv register | 3074 | * force-nopriv register |
| 3051 | * | 3075 | * |
diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h index 71b620875943..dac8c6401e26 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.h +++ b/drivers/gpu/drm/i915/gvt/mmio.h | |||
| @@ -98,4 +98,6 @@ bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt, | |||
| 98 | int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset, | 98 | int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset, |
| 99 | void *pdata, unsigned int bytes, bool is_read); | 99 | void *pdata, unsigned int bytes, bool is_read); |
| 100 | 100 | ||
| 101 | int intel_vgpu_mask_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | ||
| 102 | void *p_data, unsigned int bytes); | ||
| 101 | #endif | 103 | #endif |
diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index 0f949554d118..5ca9caf7552a 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c | |||
| @@ -581,7 +581,9 @@ void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt) | |||
| 581 | 581 | ||
| 582 | for (mmio = gvt->engine_mmio_list.mmio; | 582 | for (mmio = gvt->engine_mmio_list.mmio; |
| 583 | i915_mmio_reg_valid(mmio->reg); mmio++) { | 583 | i915_mmio_reg_valid(mmio->reg); mmio++) { |
| 584 | if (mmio->in_context) | 584 | if (mmio->in_context) { |
| 585 | gvt->engine_mmio_list.ctx_mmio_count[mmio->ring_id]++; | 585 | gvt->engine_mmio_list.ctx_mmio_count[mmio->ring_id]++; |
| 586 | intel_gvt_mmio_set_in_ctx(gvt, mmio->reg.reg); | ||
| 587 | } | ||
| 586 | } | 588 | } |
| 587 | } | 589 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 52f3b91d14fd..71e1aa54f774 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -652,6 +652,7 @@ enum intel_sbi_destination { | |||
| 652 | #define QUIRK_BACKLIGHT_PRESENT (1<<3) | 652 | #define QUIRK_BACKLIGHT_PRESENT (1<<3) |
| 653 | #define QUIRK_PIN_SWIZZLED_PAGES (1<<5) | 653 | #define QUIRK_PIN_SWIZZLED_PAGES (1<<5) |
| 654 | #define QUIRK_INCREASE_T12_DELAY (1<<6) | 654 | #define QUIRK_INCREASE_T12_DELAY (1<<6) |
| 655 | #define QUIRK_INCREASE_DDI_DISABLED_TIME (1<<7) | ||
| 655 | 656 | ||
| 656 | struct intel_fbdev; | 657 | struct intel_fbdev; |
| 657 | struct intel_fbc_work; | 658 | struct intel_fbc_work; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4a02747ac658..c16cb025755e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -1998,10 +1998,38 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, | |||
| 1998 | 1998 | ||
| 1999 | static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv) | 1999 | static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv) |
| 2000 | { | 2000 | { |
| 2001 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); | 2001 | u32 hotplug_status = 0, hotplug_status_mask; |
| 2002 | int i; | ||
| 2003 | |||
| 2004 | if (IS_G4X(dev_priv) || | ||
| 2005 | IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) | ||
| 2006 | hotplug_status_mask = HOTPLUG_INT_STATUS_G4X | | ||
| 2007 | DP_AUX_CHANNEL_MASK_INT_STATUS_G4X; | ||
| 2008 | else | ||
| 2009 | hotplug_status_mask = HOTPLUG_INT_STATUS_I915; | ||
| 2002 | 2010 | ||
| 2003 | if (hotplug_status) | 2011 | /* |
| 2012 | * We absolutely have to clear all the pending interrupt | ||
| 2013 | * bits in PORT_HOTPLUG_STAT. Otherwise the ISR port | ||
| 2014 | * interrupt bit won't have an edge, and the i965/g4x | ||
| 2015 | * edge triggered IIR will not notice that an interrupt | ||
| 2016 | * is still pending. We can't use PORT_HOTPLUG_EN to | ||
| 2017 | * guarantee the edge as the act of toggling the enable | ||
| 2018 | * bits can itself generate a new hotplug interrupt :( | ||
| 2019 | */ | ||
| 2020 | for (i = 0; i < 10; i++) { | ||
| 2021 | u32 tmp = I915_READ(PORT_HOTPLUG_STAT) & hotplug_status_mask; | ||
| 2022 | |||
| 2023 | if (tmp == 0) | ||
| 2024 | return hotplug_status; | ||
| 2025 | |||
| 2026 | hotplug_status |= tmp; | ||
| 2004 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); | 2027 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
| 2028 | } | ||
| 2029 | |||
| 2030 | WARN_ONCE(1, | ||
| 2031 | "PORT_HOTPLUG_STAT did not clear (0x%08x)\n", | ||
| 2032 | I915_READ(PORT_HOTPLUG_STAT)); | ||
| 2005 | 2033 | ||
| 2006 | return hotplug_status; | 2034 | return hotplug_status; |
| 2007 | } | 2035 | } |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f4a8598a2d39..fed26d6e4e27 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -1782,15 +1782,24 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state) | |||
| 1782 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); | 1782 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
| 1783 | } | 1783 | } |
| 1784 | 1784 | ||
| 1785 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, | 1785 | void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state) |
| 1786 | enum transcoder cpu_transcoder) | ||
| 1787 | { | 1786 | { |
| 1787 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | ||
| 1788 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | ||
| 1789 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; | ||
| 1788 | i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); | 1790 | i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
| 1789 | uint32_t val = I915_READ(reg); | 1791 | uint32_t val = I915_READ(reg); |
| 1790 | 1792 | ||
| 1791 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC); | 1793 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC); |
| 1792 | val |= TRANS_DDI_PORT_NONE; | 1794 | val |= TRANS_DDI_PORT_NONE; |
| 1793 | I915_WRITE(reg, val); | 1795 | I915_WRITE(reg, val); |
| 1796 | |||
| 1797 | if (dev_priv->quirks & QUIRK_INCREASE_DDI_DISABLED_TIME && | ||
| 1798 | intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { | ||
| 1799 | DRM_DEBUG_KMS("Quirk Increase DDI disabled time\n"); | ||
| 1800 | /* Quirk time at 100ms for reliable operation */ | ||
| 1801 | msleep(100); | ||
| 1802 | } | ||
| 1794 | } | 1803 | } |
| 1795 | 1804 | ||
| 1796 | int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, | 1805 | int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2cc6faa1daa8..dec0d60921bf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -5809,7 +5809,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state, | |||
| 5809 | intel_ddi_set_vc_payload_alloc(intel_crtc->config, false); | 5809 | intel_ddi_set_vc_payload_alloc(intel_crtc->config, false); |
| 5810 | 5810 | ||
| 5811 | if (!transcoder_is_dsi(cpu_transcoder)) | 5811 | if (!transcoder_is_dsi(cpu_transcoder)) |
| 5812 | intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); | 5812 | intel_ddi_disable_transcoder_func(old_crtc_state); |
| 5813 | 5813 | ||
| 5814 | if (INTEL_GEN(dev_priv) >= 9) | 5814 | if (INTEL_GEN(dev_priv) >= 9) |
| 5815 | skylake_scaler_disable(intel_crtc); | 5815 | skylake_scaler_disable(intel_crtc); |
| @@ -14646,6 +14646,18 @@ static void quirk_increase_t12_delay(struct drm_device *dev) | |||
| 14646 | DRM_INFO("Applying T12 delay quirk\n"); | 14646 | DRM_INFO("Applying T12 delay quirk\n"); |
| 14647 | } | 14647 | } |
| 14648 | 14648 | ||
| 14649 | /* | ||
| 14650 | * GeminiLake NUC HDMI outputs require additional off time | ||
| 14651 | * this allows the onboard retimer to correctly sync to signal | ||
| 14652 | */ | ||
| 14653 | static void quirk_increase_ddi_disabled_time(struct drm_device *dev) | ||
| 14654 | { | ||
| 14655 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 14656 | |||
| 14657 | dev_priv->quirks |= QUIRK_INCREASE_DDI_DISABLED_TIME; | ||
| 14658 | DRM_INFO("Applying Increase DDI Disabled quirk\n"); | ||
| 14659 | } | ||
| 14660 | |||
| 14649 | struct intel_quirk { | 14661 | struct intel_quirk { |
| 14650 | int device; | 14662 | int device; |
| 14651 | int subsystem_vendor; | 14663 | int subsystem_vendor; |
| @@ -14732,6 +14744,13 @@ static struct intel_quirk intel_quirks[] = { | |||
| 14732 | 14744 | ||
| 14733 | /* Toshiba Satellite P50-C-18C */ | 14745 | /* Toshiba Satellite P50-C-18C */ |
| 14734 | { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay }, | 14746 | { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay }, |
| 14747 | |||
| 14748 | /* GeminiLake NUC */ | ||
| 14749 | { 0x3185, 0x8086, 0x2072, quirk_increase_ddi_disabled_time }, | ||
| 14750 | { 0x3184, 0x8086, 0x2072, quirk_increase_ddi_disabled_time }, | ||
| 14751 | /* ASRock ITX*/ | ||
| 14752 | { 0x3185, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, | ||
| 14753 | { 0x3184, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, | ||
| 14735 | }; | 14754 | }; |
| 14736 | 14755 | ||
| 14737 | static void intel_init_quirks(struct drm_device *dev) | 14756 | static void intel_init_quirks(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0361130500a6..b8eefbffc77d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -1388,8 +1388,7 @@ void hsw_fdi_link_train(struct intel_crtc *crtc, | |||
| 1388 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); | 1388 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); |
| 1389 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); | 1389 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); |
| 1390 | void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); | 1390 | void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); |
| 1391 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, | 1391 | void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state); |
| 1392 | enum transcoder cpu_transcoder); | ||
| 1393 | void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state); | 1392 | void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state); |
| 1394 | void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state); | 1393 | void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state); |
| 1395 | struct intel_encoder * | 1394 | struct intel_encoder * |
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 56dd7a9a8e25..dd5312b02a8d 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c | |||
| @@ -612,6 +612,9 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 612 | return PTR_ERR(imx_ldb->regmap); | 612 | return PTR_ERR(imx_ldb->regmap); |
| 613 | } | 613 | } |
| 614 | 614 | ||
| 615 | /* disable LDB by resetting the control register to POR default */ | ||
| 616 | regmap_write(imx_ldb->regmap, IOMUXC_GPR2, 0); | ||
| 617 | |||
| 615 | imx_ldb->dev = dev; | 618 | imx_ldb->dev = dev; |
| 616 | 619 | ||
| 617 | if (of_id) | 620 | if (of_id) |
| @@ -652,14 +655,14 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 652 | if (ret || i < 0 || i > 1) | 655 | if (ret || i < 0 || i > 1) |
| 653 | return -EINVAL; | 656 | return -EINVAL; |
| 654 | 657 | ||
| 658 | if (!of_device_is_available(child)) | ||
| 659 | continue; | ||
| 660 | |||
| 655 | if (dual && i > 0) { | 661 | if (dual && i > 0) { |
| 656 | dev_warn(dev, "dual-channel mode, ignoring second output\n"); | 662 | dev_warn(dev, "dual-channel mode, ignoring second output\n"); |
| 657 | continue; | 663 | continue; |
| 658 | } | 664 | } |
| 659 | 665 | ||
| 660 | if (!of_device_is_available(child)) | ||
| 661 | continue; | ||
| 662 | |||
| 663 | channel = &imx_ldb->channel[i]; | 666 | channel = &imx_ldb->channel[i]; |
| 664 | channel->ldb = imx_ldb; | 667 | channel->ldb = imx_ldb; |
| 665 | channel->chno = i; | 668 | channel->chno = i; |
diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index 501d2d290e9c..70dce544984e 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c | |||
| @@ -55,6 +55,9 @@ nv04_display_create(struct drm_device *dev) | |||
| 55 | nouveau_display(dev)->init = nv04_display_init; | 55 | nouveau_display(dev)->init = nv04_display_init; |
| 56 | nouveau_display(dev)->fini = nv04_display_fini; | 56 | nouveau_display(dev)->fini = nv04_display_fini; |
| 57 | 57 | ||
| 58 | /* Pre-nv50 doesn't support atomic, so don't expose the ioctls */ | ||
| 59 | dev->driver->driver_features &= ~DRIVER_ATOMIC; | ||
| 60 | |||
| 58 | nouveau_hw_save_vga_fonts(dev, 1); | 61 | nouveau_hw_save_vga_fonts(dev, 1); |
| 59 | 62 | ||
| 60 | nv04_crtc_create(dev, 0); | 63 | nv04_crtc_create(dev, 0); |
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index b83465ae7c1b..9bae4db84cfb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c | |||
| @@ -1585,8 +1585,9 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) | |||
| 1585 | *****************************************************************************/ | 1585 | *****************************************************************************/ |
| 1586 | 1586 | ||
| 1587 | static void | 1587 | static void |
| 1588 | nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock) | 1588 | nv50_disp_atomic_commit_core(struct drm_atomic_state *state, u32 *interlock) |
| 1589 | { | 1589 | { |
| 1590 | struct nouveau_drm *drm = nouveau_drm(state->dev); | ||
| 1590 | struct nv50_disp *disp = nv50_disp(drm->dev); | 1591 | struct nv50_disp *disp = nv50_disp(drm->dev); |
| 1591 | struct nv50_core *core = disp->core; | 1592 | struct nv50_core *core = disp->core; |
| 1592 | struct nv50_mstm *mstm; | 1593 | struct nv50_mstm *mstm; |
| @@ -1618,6 +1619,22 @@ nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock) | |||
| 1618 | } | 1619 | } |
| 1619 | 1620 | ||
| 1620 | static void | 1621 | static void |
| 1622 | nv50_disp_atomic_commit_wndw(struct drm_atomic_state *state, u32 *interlock) | ||
| 1623 | { | ||
| 1624 | struct drm_plane_state *new_plane_state; | ||
| 1625 | struct drm_plane *plane; | ||
| 1626 | int i; | ||
| 1627 | |||
| 1628 | for_each_new_plane_in_state(state, plane, new_plane_state, i) { | ||
| 1629 | struct nv50_wndw *wndw = nv50_wndw(plane); | ||
| 1630 | if (interlock[wndw->interlock.type] & wndw->interlock.data) { | ||
| 1631 | if (wndw->func->update) | ||
| 1632 | wndw->func->update(wndw, interlock); | ||
| 1633 | } | ||
| 1634 | } | ||
| 1635 | } | ||
| 1636 | |||
| 1637 | static void | ||
| 1621 | nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) | 1638 | nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) |
| 1622 | { | 1639 | { |
| 1623 | struct drm_device *dev = state->dev; | 1640 | struct drm_device *dev = state->dev; |
| @@ -1684,7 +1701,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 1684 | help->disable(encoder); | 1701 | help->disable(encoder); |
| 1685 | interlock[NV50_DISP_INTERLOCK_CORE] |= 1; | 1702 | interlock[NV50_DISP_INTERLOCK_CORE] |= 1; |
| 1686 | if (outp->flush_disable) { | 1703 | if (outp->flush_disable) { |
| 1687 | nv50_disp_atomic_commit_core(drm, interlock); | 1704 | nv50_disp_atomic_commit_wndw(state, interlock); |
| 1705 | nv50_disp_atomic_commit_core(state, interlock); | ||
| 1688 | memset(interlock, 0x00, sizeof(interlock)); | 1706 | memset(interlock, 0x00, sizeof(interlock)); |
| 1689 | } | 1707 | } |
| 1690 | } | 1708 | } |
| @@ -1693,15 +1711,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 1693 | /* Flush disable. */ | 1711 | /* Flush disable. */ |
| 1694 | if (interlock[NV50_DISP_INTERLOCK_CORE]) { | 1712 | if (interlock[NV50_DISP_INTERLOCK_CORE]) { |
| 1695 | if (atom->flush_disable) { | 1713 | if (atom->flush_disable) { |
| 1696 | for_each_new_plane_in_state(state, plane, new_plane_state, i) { | 1714 | nv50_disp_atomic_commit_wndw(state, interlock); |
| 1697 | struct nv50_wndw *wndw = nv50_wndw(plane); | 1715 | nv50_disp_atomic_commit_core(state, interlock); |
| 1698 | if (interlock[wndw->interlock.type] & wndw->interlock.data) { | ||
| 1699 | if (wndw->func->update) | ||
| 1700 | wndw->func->update(wndw, interlock); | ||
| 1701 | } | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | nv50_disp_atomic_commit_core(drm, interlock); | ||
| 1705 | memset(interlock, 0x00, sizeof(interlock)); | 1716 | memset(interlock, 0x00, sizeof(interlock)); |
| 1706 | } | 1717 | } |
| 1707 | } | 1718 | } |
| @@ -1762,18 +1773,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 1762 | } | 1773 | } |
| 1763 | 1774 | ||
| 1764 | /* Flush update. */ | 1775 | /* Flush update. */ |
| 1765 | for_each_new_plane_in_state(state, plane, new_plane_state, i) { | 1776 | nv50_disp_atomic_commit_wndw(state, interlock); |
| 1766 | struct nv50_wndw *wndw = nv50_wndw(plane); | ||
| 1767 | if (interlock[wndw->interlock.type] & wndw->interlock.data) { | ||
| 1768 | if (wndw->func->update) | ||
| 1769 | wndw->func->update(wndw, interlock); | ||
| 1770 | } | ||
| 1771 | } | ||
| 1772 | 1777 | ||
| 1773 | if (interlock[NV50_DISP_INTERLOCK_CORE]) { | 1778 | if (interlock[NV50_DISP_INTERLOCK_CORE]) { |
| 1774 | if (interlock[NV50_DISP_INTERLOCK_BASE] || | 1779 | if (interlock[NV50_DISP_INTERLOCK_BASE] || |
| 1780 | interlock[NV50_DISP_INTERLOCK_OVLY] || | ||
| 1781 | interlock[NV50_DISP_INTERLOCK_WNDW] || | ||
| 1775 | !atom->state.legacy_cursor_update) | 1782 | !atom->state.legacy_cursor_update) |
| 1776 | nv50_disp_atomic_commit_core(drm, interlock); | 1783 | nv50_disp_atomic_commit_core(state, interlock); |
| 1777 | else | 1784 | else |
| 1778 | disp->core->func->update(disp->core, interlock, false); | 1785 | disp->core->func->update(disp->core, interlock, false); |
| 1779 | } | 1786 | } |
| @@ -1871,7 +1878,7 @@ nv50_disp_atomic_commit(struct drm_device *dev, | |||
| 1871 | nv50_disp_atomic_commit_tail(state); | 1878 | nv50_disp_atomic_commit_tail(state); |
| 1872 | 1879 | ||
| 1873 | drm_for_each_crtc(crtc, dev) { | 1880 | drm_for_each_crtc(crtc, dev) { |
| 1874 | if (crtc->state->enable) { | 1881 | if (crtc->state->active) { |
| 1875 | if (!drm->have_disp_power_ref) { | 1882 | if (!drm->have_disp_power_ref) { |
| 1876 | drm->have_disp_power_ref = true; | 1883 | drm->have_disp_power_ref = true; |
| 1877 | return 0; | 1884 | return 0; |
| @@ -2119,10 +2126,6 @@ nv50_display_destroy(struct drm_device *dev) | |||
| 2119 | kfree(disp); | 2126 | kfree(disp); |
| 2120 | } | 2127 | } |
| 2121 | 2128 | ||
| 2122 | MODULE_PARM_DESC(atomic, "Expose atomic ioctl (default: disabled)"); | ||
| 2123 | static int nouveau_atomic = 0; | ||
| 2124 | module_param_named(atomic, nouveau_atomic, int, 0400); | ||
| 2125 | |||
| 2126 | int | 2129 | int |
| 2127 | nv50_display_create(struct drm_device *dev) | 2130 | nv50_display_create(struct drm_device *dev) |
| 2128 | { | 2131 | { |
| @@ -2147,8 +2150,6 @@ nv50_display_create(struct drm_device *dev) | |||
| 2147 | disp->disp = &nouveau_display(dev)->disp; | 2150 | disp->disp = &nouveau_display(dev)->disp; |
| 2148 | dev->mode_config.funcs = &nv50_disp_func; | 2151 | dev->mode_config.funcs = &nv50_disp_func; |
| 2149 | dev->driver->driver_features |= DRIVER_PREFER_XBGR_30BPP; | 2152 | dev->driver->driver_features |= DRIVER_PREFER_XBGR_30BPP; |
| 2150 | if (nouveau_atomic) | ||
| 2151 | dev->driver->driver_features |= DRIVER_ATOMIC; | ||
| 2152 | 2153 | ||
| 2153 | /* small shared memory area we use for notifiers and semaphores */ | 2154 | /* small shared memory area we use for notifiers and semaphores */ |
| 2154 | ret = nouveau_bo_new(&drm->client, 4096, 0x1000, TTM_PL_FLAG_VRAM, | 2155 | ret = nouveau_bo_new(&drm->client, 4096, 0x1000, TTM_PL_FLAG_VRAM, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index debbbf0fd4bd..408b955e5c39 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c | |||
| @@ -267,6 +267,7 @@ nouveau_backlight_init(struct drm_device *dev) | |||
| 267 | struct nouveau_drm *drm = nouveau_drm(dev); | 267 | struct nouveau_drm *drm = nouveau_drm(dev); |
| 268 | struct nvif_device *device = &drm->client.device; | 268 | struct nvif_device *device = &drm->client.device; |
| 269 | struct drm_connector *connector; | 269 | struct drm_connector *connector; |
| 270 | struct drm_connector_list_iter conn_iter; | ||
| 270 | 271 | ||
| 271 | INIT_LIST_HEAD(&drm->bl_connectors); | 272 | INIT_LIST_HEAD(&drm->bl_connectors); |
| 272 | 273 | ||
| @@ -275,7 +276,8 @@ nouveau_backlight_init(struct drm_device *dev) | |||
| 275 | return 0; | 276 | return 0; |
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 279 | drm_connector_list_iter_begin(dev, &conn_iter); |
| 280 | drm_for_each_connector_iter(connector, &conn_iter) { | ||
| 279 | if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && | 281 | if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && |
| 280 | connector->connector_type != DRM_MODE_CONNECTOR_eDP) | 282 | connector->connector_type != DRM_MODE_CONNECTOR_eDP) |
| 281 | continue; | 283 | continue; |
| @@ -292,7 +294,7 @@ nouveau_backlight_init(struct drm_device *dev) | |||
| 292 | break; | 294 | break; |
| 293 | } | 295 | } |
| 294 | } | 296 | } |
| 295 | 297 | drm_connector_list_iter_end(&conn_iter); | |
| 296 | 298 | ||
| 297 | return 0; | 299 | return 0; |
| 298 | } | 300 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7b557c354307..af68eae4c626 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
| @@ -1208,14 +1208,19 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
| 1208 | struct nouveau_display *disp = nouveau_display(dev); | 1208 | struct nouveau_display *disp = nouveau_display(dev); |
| 1209 | struct nouveau_connector *nv_connector = NULL; | 1209 | struct nouveau_connector *nv_connector = NULL; |
| 1210 | struct drm_connector *connector; | 1210 | struct drm_connector *connector; |
| 1211 | struct drm_connector_list_iter conn_iter; | ||
| 1211 | int type, ret = 0; | 1212 | int type, ret = 0; |
| 1212 | bool dummy; | 1213 | bool dummy; |
| 1213 | 1214 | ||
| 1214 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1215 | drm_connector_list_iter_begin(dev, &conn_iter); |
| 1216 | nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { | ||
| 1215 | nv_connector = nouveau_connector(connector); | 1217 | nv_connector = nouveau_connector(connector); |
| 1216 | if (nv_connector->index == index) | 1218 | if (nv_connector->index == index) { |
| 1219 | drm_connector_list_iter_end(&conn_iter); | ||
| 1217 | return connector; | 1220 | return connector; |
| 1221 | } | ||
| 1218 | } | 1222 | } |
| 1223 | drm_connector_list_iter_end(&conn_iter); | ||
| 1219 | 1224 | ||
| 1220 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); | 1225 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); |
| 1221 | if (!nv_connector) | 1226 | if (!nv_connector) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index a4d1a059bd3d..dc7454e7f19a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <drm/drm_encoder.h> | 33 | #include <drm/drm_encoder.h> |
| 34 | #include <drm/drm_dp_helper.h> | 34 | #include <drm/drm_dp_helper.h> |
| 35 | #include "nouveau_crtc.h" | 35 | #include "nouveau_crtc.h" |
| 36 | #include "nouveau_encoder.h" | ||
| 36 | 37 | ||
| 37 | struct nvkm_i2c_port; | 38 | struct nvkm_i2c_port; |
| 38 | 39 | ||
| @@ -60,19 +61,46 @@ static inline struct nouveau_connector *nouveau_connector( | |||
| 60 | return container_of(con, struct nouveau_connector, base); | 61 | return container_of(con, struct nouveau_connector, base); |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 64 | static inline bool | ||
| 65 | nouveau_connector_is_mst(struct drm_connector *connector) | ||
| 66 | { | ||
| 67 | const struct nouveau_encoder *nv_encoder; | ||
| 68 | const struct drm_encoder *encoder; | ||
| 69 | |||
| 70 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
| 71 | return false; | ||
| 72 | |||
| 73 | nv_encoder = find_encoder(connector, DCB_OUTPUT_ANY); | ||
| 74 | if (!nv_encoder) | ||
| 75 | return false; | ||
| 76 | |||
| 77 | encoder = &nv_encoder->base.base; | ||
| 78 | return encoder->encoder_type == DRM_MODE_ENCODER_DPMST; | ||
| 79 | } | ||
| 80 | |||
| 81 | #define nouveau_for_each_non_mst_connector_iter(connector, iter) \ | ||
| 82 | drm_for_each_connector_iter(connector, iter) \ | ||
| 83 | for_each_if(!nouveau_connector_is_mst(connector)) | ||
| 84 | |||
| 63 | static inline struct nouveau_connector * | 85 | static inline struct nouveau_connector * |
| 64 | nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) | 86 | nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) |
| 65 | { | 87 | { |
| 66 | struct drm_device *dev = nv_crtc->base.dev; | 88 | struct drm_device *dev = nv_crtc->base.dev; |
| 67 | struct drm_connector *connector; | 89 | struct drm_connector *connector; |
| 90 | struct drm_connector_list_iter conn_iter; | ||
| 91 | struct nouveau_connector *nv_connector = NULL; | ||
| 68 | struct drm_crtc *crtc = to_drm_crtc(nv_crtc); | 92 | struct drm_crtc *crtc = to_drm_crtc(nv_crtc); |
| 69 | 93 | ||
| 70 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 94 | drm_connector_list_iter_begin(dev, &conn_iter); |
| 71 | if (connector->encoder && connector->encoder->crtc == crtc) | 95 | nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { |
| 72 | return nouveau_connector(connector); | 96 | if (connector->encoder && connector->encoder->crtc == crtc) { |
| 97 | nv_connector = nouveau_connector(connector); | ||
| 98 | break; | ||
| 99 | } | ||
| 73 | } | 100 | } |
| 101 | drm_connector_list_iter_end(&conn_iter); | ||
| 74 | 102 | ||
| 75 | return NULL; | 103 | return nv_connector; |
| 76 | } | 104 | } |
| 77 | 105 | ||
| 78 | struct drm_connector * | 106 | struct drm_connector * |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 774b429142bc..ec7861457b84 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
| @@ -404,6 +404,7 @@ nouveau_display_init(struct drm_device *dev) | |||
| 404 | struct nouveau_display *disp = nouveau_display(dev); | 404 | struct nouveau_display *disp = nouveau_display(dev); |
| 405 | struct nouveau_drm *drm = nouveau_drm(dev); | 405 | struct nouveau_drm *drm = nouveau_drm(dev); |
| 406 | struct drm_connector *connector; | 406 | struct drm_connector *connector; |
| 407 | struct drm_connector_list_iter conn_iter; | ||
| 407 | int ret; | 408 | int ret; |
| 408 | 409 | ||
| 409 | ret = disp->init(dev); | 410 | ret = disp->init(dev); |
| @@ -411,10 +412,12 @@ nouveau_display_init(struct drm_device *dev) | |||
| 411 | return ret; | 412 | return ret; |
| 412 | 413 | ||
| 413 | /* enable hotplug interrupts */ | 414 | /* enable hotplug interrupts */ |
| 414 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 415 | drm_connector_list_iter_begin(dev, &conn_iter); |
| 416 | nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { | ||
| 415 | struct nouveau_connector *conn = nouveau_connector(connector); | 417 | struct nouveau_connector *conn = nouveau_connector(connector); |
| 416 | nvif_notify_get(&conn->hpd); | 418 | nvif_notify_get(&conn->hpd); |
| 417 | } | 419 | } |
| 420 | drm_connector_list_iter_end(&conn_iter); | ||
| 418 | 421 | ||
| 419 | /* enable flip completion events */ | 422 | /* enable flip completion events */ |
| 420 | nvif_notify_get(&drm->flip); | 423 | nvif_notify_get(&drm->flip); |
| @@ -427,6 +430,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend) | |||
| 427 | struct nouveau_display *disp = nouveau_display(dev); | 430 | struct nouveau_display *disp = nouveau_display(dev); |
| 428 | struct nouveau_drm *drm = nouveau_drm(dev); | 431 | struct nouveau_drm *drm = nouveau_drm(dev); |
| 429 | struct drm_connector *connector; | 432 | struct drm_connector *connector; |
| 433 | struct drm_connector_list_iter conn_iter; | ||
| 430 | 434 | ||
| 431 | if (!suspend) { | 435 | if (!suspend) { |
| 432 | if (drm_drv_uses_atomic_modeset(dev)) | 436 | if (drm_drv_uses_atomic_modeset(dev)) |
| @@ -439,10 +443,12 @@ nouveau_display_fini(struct drm_device *dev, bool suspend) | |||
| 439 | nvif_notify_put(&drm->flip); | 443 | nvif_notify_put(&drm->flip); |
| 440 | 444 | ||
| 441 | /* disable hotplug interrupts */ | 445 | /* disable hotplug interrupts */ |
| 442 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 446 | drm_connector_list_iter_begin(dev, &conn_iter); |
| 447 | nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { | ||
| 443 | struct nouveau_connector *conn = nouveau_connector(connector); | 448 | struct nouveau_connector *conn = nouveau_connector(connector); |
| 444 | nvif_notify_put(&conn->hpd); | 449 | nvif_notify_put(&conn->hpd); |
| 445 | } | 450 | } |
| 451 | drm_connector_list_iter_end(&conn_iter); | ||
| 446 | 452 | ||
| 447 | drm_kms_helper_poll_disable(dev); | 453 | drm_kms_helper_poll_disable(dev); |
| 448 | disp->fini(dev); | 454 | disp->fini(dev); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 775443c9af94..f5d3158f0378 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -81,6 +81,10 @@ MODULE_PARM_DESC(modeset, "enable driver (default: auto, " | |||
| 81 | int nouveau_modeset = -1; | 81 | int nouveau_modeset = -1; |
| 82 | module_param_named(modeset, nouveau_modeset, int, 0400); | 82 | module_param_named(modeset, nouveau_modeset, int, 0400); |
| 83 | 83 | ||
| 84 | MODULE_PARM_DESC(atomic, "Expose atomic ioctl (default: disabled)"); | ||
| 85 | static int nouveau_atomic = 0; | ||
| 86 | module_param_named(atomic, nouveau_atomic, int, 0400); | ||
| 87 | |||
| 84 | MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1)"); | 88 | MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1)"); |
| 85 | static int nouveau_runtime_pm = -1; | 89 | static int nouveau_runtime_pm = -1; |
| 86 | module_param_named(runpm, nouveau_runtime_pm, int, 0400); | 90 | module_param_named(runpm, nouveau_runtime_pm, int, 0400); |
| @@ -509,6 +513,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev, | |||
| 509 | 513 | ||
| 510 | pci_set_master(pdev); | 514 | pci_set_master(pdev); |
| 511 | 515 | ||
| 516 | if (nouveau_atomic) | ||
| 517 | driver_pci.driver_features |= DRIVER_ATOMIC; | ||
| 518 | |||
| 512 | ret = drm_get_pci_dev(pdev, pent, &driver_pci); | 519 | ret = drm_get_pci_dev(pdev, pent, &driver_pci); |
| 513 | if (ret) { | 520 | if (ret) { |
| 514 | nvkm_device_del(&device); | 521 | nvkm_device_del(&device); |
| @@ -874,22 +881,11 @@ nouveau_pmops_runtime_resume(struct device *dev) | |||
| 874 | static int | 881 | static int |
| 875 | nouveau_pmops_runtime_idle(struct device *dev) | 882 | nouveau_pmops_runtime_idle(struct device *dev) |
| 876 | { | 883 | { |
| 877 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 878 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
| 879 | struct nouveau_drm *drm = nouveau_drm(drm_dev); | ||
| 880 | struct drm_crtc *crtc; | ||
| 881 | |||
| 882 | if (!nouveau_pmops_runtime()) { | 884 | if (!nouveau_pmops_runtime()) { |
| 883 | pm_runtime_forbid(dev); | 885 | pm_runtime_forbid(dev); |
| 884 | return -EBUSY; | 886 | return -EBUSY; |
| 885 | } | 887 | } |
| 886 | 888 | ||
| 887 | list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { | ||
| 888 | if (crtc->enabled) { | ||
| 889 | DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); | ||
| 890 | return -EBUSY; | ||
| 891 | } | ||
| 892 | } | ||
| 893 | pm_runtime_mark_last_busy(dev); | 889 | pm_runtime_mark_last_busy(dev); |
| 894 | pm_runtime_autosuspend(dev); | 890 | pm_runtime_autosuspend(dev); |
| 895 | /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ | 891 | /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 300daee74209..e6ccafcb9c41 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
| @@ -616,7 +616,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, | |||
| 616 | struct nouveau_bo *nvbo; | 616 | struct nouveau_bo *nvbo; |
| 617 | uint32_t data; | 617 | uint32_t data; |
| 618 | 618 | ||
| 619 | if (unlikely(r->bo_index > req->nr_buffers)) { | 619 | if (unlikely(r->bo_index >= req->nr_buffers)) { |
| 620 | NV_PRINTK(err, cli, "reloc bo index invalid\n"); | 620 | NV_PRINTK(err, cli, "reloc bo index invalid\n"); |
| 621 | ret = -EINVAL; | 621 | ret = -EINVAL; |
| 622 | break; | 622 | break; |
| @@ -626,7 +626,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, | |||
| 626 | if (b->presumed.valid) | 626 | if (b->presumed.valid) |
| 627 | continue; | 627 | continue; |
| 628 | 628 | ||
| 629 | if (unlikely(r->reloc_bo_index > req->nr_buffers)) { | 629 | if (unlikely(r->reloc_bo_index >= req->nr_buffers)) { |
| 630 | NV_PRINTK(err, cli, "reloc container bo index invalid\n"); | 630 | NV_PRINTK(err, cli, "reloc container bo index invalid\n"); |
| 631 | ret = -EINVAL; | 631 | ret = -EINVAL; |
| 632 | break; | 632 | break; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index 73b5d46104bd..434d2fc5bb1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | |||
| @@ -140,6 +140,9 @@ nvkm_fb_init(struct nvkm_subdev *subdev) | |||
| 140 | if (fb->func->init) | 140 | if (fb->func->init) |
| 141 | fb->func->init(fb); | 141 | fb->func->init(fb); |
| 142 | 142 | ||
| 143 | if (fb->func->init_remapper) | ||
| 144 | fb->func->init_remapper(fb); | ||
| 145 | |||
| 143 | if (fb->func->init_page) { | 146 | if (fb->func->init_page) { |
| 144 | ret = fb->func->init_page(fb); | 147 | ret = fb->func->init_page(fb); |
| 145 | if (WARN_ON(ret)) | 148 | if (WARN_ON(ret)) |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c index dffe1f5e1071..8205ce436b3e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c | |||
| @@ -37,6 +37,14 @@ gp100_fb_init_unkn(struct nvkm_fb *base) | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void | 39 | void |
| 40 | gp100_fb_init_remapper(struct nvkm_fb *fb) | ||
| 41 | { | ||
| 42 | struct nvkm_device *device = fb->subdev.device; | ||
| 43 | /* Disable address remapper. */ | ||
| 44 | nvkm_mask(device, 0x100c14, 0x00040000, 0x00000000); | ||
| 45 | } | ||
| 46 | |||
| 47 | void | ||
| 40 | gp100_fb_init(struct nvkm_fb *base) | 48 | gp100_fb_init(struct nvkm_fb *base) |
| 41 | { | 49 | { |
| 42 | struct gf100_fb *fb = gf100_fb(base); | 50 | struct gf100_fb *fb = gf100_fb(base); |
| @@ -56,6 +64,7 @@ gp100_fb = { | |||
| 56 | .dtor = gf100_fb_dtor, | 64 | .dtor = gf100_fb_dtor, |
| 57 | .oneinit = gf100_fb_oneinit, | 65 | .oneinit = gf100_fb_oneinit, |
| 58 | .init = gp100_fb_init, | 66 | .init = gp100_fb_init, |
| 67 | .init_remapper = gp100_fb_init_remapper, | ||
| 59 | .init_page = gm200_fb_init_page, | 68 | .init_page = gm200_fb_init_page, |
| 60 | .init_unkn = gp100_fb_init_unkn, | 69 | .init_unkn = gp100_fb_init_unkn, |
| 61 | .ram_new = gp100_ram_new, | 70 | .ram_new = gp100_ram_new, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c index b84b9861ef26..b4d74e815674 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c | |||
| @@ -31,6 +31,7 @@ gp102_fb = { | |||
| 31 | .dtor = gf100_fb_dtor, | 31 | .dtor = gf100_fb_dtor, |
| 32 | .oneinit = gf100_fb_oneinit, | 32 | .oneinit = gf100_fb_oneinit, |
| 33 | .init = gp100_fb_init, | 33 | .init = gp100_fb_init, |
| 34 | .init_remapper = gp100_fb_init_remapper, | ||
| 34 | .init_page = gm200_fb_init_page, | 35 | .init_page = gm200_fb_init_page, |
| 35 | .ram_new = gp100_ram_new, | 36 | .ram_new = gp100_ram_new, |
| 36 | }; | 37 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index 2857f31466bf..1e4ad61c19e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | |||
| @@ -11,6 +11,7 @@ struct nvkm_fb_func { | |||
| 11 | u32 (*tags)(struct nvkm_fb *); | 11 | u32 (*tags)(struct nvkm_fb *); |
| 12 | int (*oneinit)(struct nvkm_fb *); | 12 | int (*oneinit)(struct nvkm_fb *); |
| 13 | void (*init)(struct nvkm_fb *); | 13 | void (*init)(struct nvkm_fb *); |
| 14 | void (*init_remapper)(struct nvkm_fb *); | ||
| 14 | int (*init_page)(struct nvkm_fb *); | 15 | int (*init_page)(struct nvkm_fb *); |
| 15 | void (*init_unkn)(struct nvkm_fb *); | 16 | void (*init_unkn)(struct nvkm_fb *); |
| 16 | void (*intr)(struct nvkm_fb *); | 17 | void (*intr)(struct nvkm_fb *); |
| @@ -69,5 +70,6 @@ int gf100_fb_init_page(struct nvkm_fb *); | |||
| 69 | 70 | ||
| 70 | int gm200_fb_init_page(struct nvkm_fb *); | 71 | int gm200_fb_init_page(struct nvkm_fb *); |
| 71 | 72 | ||
| 73 | void gp100_fb_init_remapper(struct nvkm_fb *); | ||
| 72 | void gp100_fb_init_unkn(struct nvkm_fb *); | 74 | void gp100_fb_init_unkn(struct nvkm_fb *); |
| 73 | #endif | 75 | #endif |
diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile index 2589f4acd5ae..9c81301d0eed 100644 --- a/drivers/gpu/drm/sun4i/Makefile +++ b/drivers/gpu/drm/sun4i/Makefile | |||
| @@ -32,7 +32,10 @@ obj-$(CONFIG_DRM_SUN4I) += sun4i-tcon.o | |||
| 32 | obj-$(CONFIG_DRM_SUN4I) += sun4i_tv.o | 32 | obj-$(CONFIG_DRM_SUN4I) += sun4i_tv.o |
| 33 | obj-$(CONFIG_DRM_SUN4I) += sun6i_drc.o | 33 | obj-$(CONFIG_DRM_SUN4I) += sun6i_drc.o |
| 34 | 34 | ||
| 35 | obj-$(CONFIG_DRM_SUN4I_BACKEND) += sun4i-backend.o sun4i-frontend.o | 35 | obj-$(CONFIG_DRM_SUN4I_BACKEND) += sun4i-backend.o |
| 36 | ifdef CONFIG_DRM_SUN4I_BACKEND | ||
| 37 | obj-$(CONFIG_DRM_SUN4I) += sun4i-frontend.o | ||
| 38 | endif | ||
| 36 | obj-$(CONFIG_DRM_SUN4I_HDMI) += sun4i-drm-hdmi.o | 39 | obj-$(CONFIG_DRM_SUN4I_HDMI) += sun4i-drm-hdmi.o |
| 37 | obj-$(CONFIG_DRM_SUN6I_DSI) += sun6i-dsi.o | 40 | obj-$(CONFIG_DRM_SUN6I_DSI) += sun6i-dsi.o |
| 38 | obj-$(CONFIG_DRM_SUN8I_DW_HDMI) += sun8i-drm-hdmi.o | 41 | obj-$(CONFIG_DRM_SUN8I_DW_HDMI) += sun8i-drm-hdmi.o |
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 776c1513e582..a2bd5876c633 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
| @@ -398,7 +398,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, | |||
| 398 | * unaligned offset is malformed and cause commands stream | 398 | * unaligned offset is malformed and cause commands stream |
| 399 | * corruption on the buffer address relocation. | 399 | * corruption on the buffer address relocation. |
| 400 | */ | 400 | */ |
| 401 | if (offset & 3 || offset >= obj->gem.size) { | 401 | if (offset & 3 || offset > obj->gem.size) { |
| 402 | err = -EINVAL; | 402 | err = -EINVAL; |
| 403 | goto fail; | 403 | goto fail; |
| 404 | } | 404 | } |
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 1d34619eb3fe..a951ec75d01f 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c | |||
| @@ -320,6 +320,9 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) | |||
| 320 | vc4_state->x_scaling[0] = VC4_SCALING_TPZ; | 320 | vc4_state->x_scaling[0] = VC4_SCALING_TPZ; |
| 321 | if (vc4_state->y_scaling[0] == VC4_SCALING_NONE) | 321 | if (vc4_state->y_scaling[0] == VC4_SCALING_NONE) |
| 322 | vc4_state->y_scaling[0] = VC4_SCALING_TPZ; | 322 | vc4_state->y_scaling[0] = VC4_SCALING_TPZ; |
| 323 | } else { | ||
| 324 | vc4_state->x_scaling[1] = VC4_SCALING_NONE; | ||
| 325 | vc4_state->y_scaling[1] = VC4_SCALING_NONE; | ||
| 323 | } | 326 | } |
| 324 | 327 | ||
| 325 | vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE && | 328 | vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE && |
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index f1d5f76e9c33..d88073e7d22d 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c | |||
| @@ -218,6 +218,9 @@ static int host1x_probe(struct platform_device *pdev) | |||
| 218 | return err; | 218 | return err; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) | ||
| 222 | goto skip_iommu; | ||
| 223 | |||
| 221 | host->group = iommu_group_get(&pdev->dev); | 224 | host->group = iommu_group_get(&pdev->dev); |
| 222 | if (host->group) { | 225 | if (host->group) { |
| 223 | struct iommu_domain_geometry *geometry; | 226 | struct iommu_domain_geometry *geometry; |
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index e2f4a4d93d20..527a1cddb14f 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c | |||
| @@ -569,7 +569,8 @@ void host1x_job_unpin(struct host1x_job *job) | |||
| 569 | for (i = 0; i < job->num_unpins; i++) { | 569 | for (i = 0; i < job->num_unpins; i++) { |
| 570 | struct host1x_job_unpin_data *unpin = &job->unpins[i]; | 570 | struct host1x_job_unpin_data *unpin = &job->unpins[i]; |
| 571 | 571 | ||
| 572 | if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) { | 572 | if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && |
| 573 | unpin->size && host->domain) { | ||
| 573 | iommu_unmap(host->domain, job->addr_phys[i], | 574 | iommu_unmap(host->domain, job->addr_phys[i], |
| 574 | unpin->size); | 575 | unpin->size); |
| 575 | free_iova(&host->iova, | 576 | free_iova(&host->iova, |
diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c index caa05b0702e1..5450a2db1219 100644 --- a/drivers/gpu/ipu-v3/ipu-csi.c +++ b/drivers/gpu/ipu-v3/ipu-csi.c | |||
| @@ -339,7 +339,8 @@ static void fill_csi_bus_cfg(struct ipu_csi_bus_config *csicfg, | |||
| 339 | break; | 339 | break; |
| 340 | case V4L2_MBUS_BT656: | 340 | case V4L2_MBUS_BT656: |
| 341 | csicfg->ext_vsync = 0; | 341 | csicfg->ext_vsync = 0; |
| 342 | if (V4L2_FIELD_HAS_BOTH(mbus_fmt->field)) | 342 | if (V4L2_FIELD_HAS_BOTH(mbus_fmt->field) || |
| 343 | mbus_fmt->field == V4L2_FIELD_ALTERNATE) | ||
| 343 | csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED; | 344 | csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED; |
| 344 | else | 345 | else |
| 345 | csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE; | 346 | csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE; |
