Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-fixes-2019-06-07-1' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
"A small bit more lively this week but not majorly so. I'm away in
Japan next week for family holiday, so I'll be pretty disconnected,
I've asked Daniel to do fixes for the week while I'm out.

The nouveau firmware changes are a bit large, but they address a big
problem where a whole set of boards don't load with the driver, and
the new firmware fixes that, so I think it's worth trying to land it
now.

core:
- Allow fb changes in async commits (drivers as well)

udmabuf:
- Unmap scatterlist when unmapping udmabuf

nouveau:
- firmware loading fixes for secboot firmware on new GPU revision.

komeda:
- oops, dma mapping and warning fixes

arm-hdlcd:
- clock fixes
- mode validation fix

i915:
- Add a missing Icelake workaround
- GVT - DMA map fault fix and enforcement fixes

amdgpu:
- DCE resume fix
- New raven variation updates"

* tag 'drm-fixes-2019-06-07-1' of git://anongit.freedesktop.org/drm/drm: (33 commits)
drm/nouveau/secboot/gp10[2467]: support newer FW to fix SEC2 failures on some boards
drm/nouveau/secboot: enable loading of versioned LS PMU/SEC2 ACR msgqueue FW
drm/nouveau/secboot: split out FW version-specific LS function pointers
drm/nouveau/secboot: pass max supported FW version to LS load funcs
drm/nouveau/core: support versioned firmware loading
drm/nouveau/core: pass subdev into nvkm_firmware_get, rather than device
drm/komeda: Potential error pointer dereference
drm/komeda: remove set but not used variable 'kcrtc'
drm/amd/amdgpu: add RLC firmware to support raven1 refresh
drm/amd/powerplay: add set_power_profile_mode for raven1_refresh
drm/amdgpu: fix ring test failure issue during s3 in vce 3.0 (V2)
udmabuf: actually unmap the scatterlist
drm/arm/hdlcd: Allow a bit of clock tolerance
drm/arm/hdlcd: Actually validate CRTC modes
drm/arm/mali-dp: Add a loop around the second set CVAL and try 5 times
drm/komeda: fixing of DMA mapping sg segment warning
drm: don't block fb changes for async plane updates
drm/vc4: fix fb references in async update
drm/msm: fix fb references in async update
drm/amd: fix fb references in async update
...

+511 -198
+1
drivers/dma-buf/udmabuf.c
··· 77 77 struct sg_table *sg, 78 78 enum dma_data_direction direction) 79 79 { 80 + dma_unmap_sg(at->dev, sg->sgl, sg->nents, direction); 80 81 sg_free_table(sg); 81 82 kfree(sg); 82 83 }
+3 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 1589 1589 { 1590 1590 int r = 0; 1591 1591 int i; 1592 + uint32_t smu_version; 1592 1593 1593 1594 if (adev->asic_type >= CHIP_VEGA10) { 1594 1595 for (i = 0; i < adev->num_ip_blocks; i++) { ··· 1615 1614 } 1616 1615 } 1617 1616 } 1617 + r = amdgpu_pm_load_smu_firmware(adev, &smu_version); 1618 1618 1619 - if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) { 1620 - r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle); 1621 - if (r) { 1622 - pr_err("firmware loading failed\n"); 1623 - return r; 1624 - } 1625 - } 1626 - 1627 - return 0; 1619 + return r; 1628 1620 } 1629 1621 1630 1622 /**
+15
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
··· 2490 2490 2491 2491 } 2492 2492 2493 + int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version) 2494 + { 2495 + int r = -EINVAL; 2496 + 2497 + if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) { 2498 + r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle); 2499 + if (r) { 2500 + pr_err("smu firmware loading failed\n"); 2501 + return r; 2502 + } 2503 + *smu_version = adev->pm.fw_version; 2504 + } 2505 + return r; 2506 + } 2507 + 2493 2508 int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) 2494 2509 { 2495 2510 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
··· 34 34 int amdgpu_pm_sysfs_init(struct amdgpu_device *adev); 35 35 void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev); 36 36 void amdgpu_pm_print_power_states(struct amdgpu_device *adev); 37 + int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version); 37 38 void amdgpu_pm_compute_clocks(struct amdgpu_device *adev); 38 39 void amdgpu_dpm_thermal_work_handler(struct work_struct *work); 39 40 void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable);
+3 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
··· 1072 1072 int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) 1073 1073 { 1074 1074 struct amdgpu_device *adev = ring->adev; 1075 - uint32_t rptr = amdgpu_ring_get_rptr(ring); 1075 + uint32_t rptr; 1076 1076 unsigned i; 1077 1077 int r, timeout = adev->usec_timeout; 1078 1078 ··· 1083 1083 r = amdgpu_ring_alloc(ring, 16); 1084 1084 if (r) 1085 1085 return r; 1086 + 1087 + rptr = amdgpu_ring_get_rptr(ring); 1086 1088 1087 1089 amdgpu_ring_write(ring, VCE_CMD_END); 1088 1090 amdgpu_ring_commit(ring);
+11 -1
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
··· 28 28 #include "soc15.h" 29 29 #include "soc15d.h" 30 30 #include "amdgpu_atomfirmware.h" 31 + #include "amdgpu_pm.h" 31 32 32 33 #include "gc/gc_9_0_offset.h" 33 34 #include "gc/gc_9_0_sh_mask.h" ··· 97 96 MODULE_FIRMWARE("amdgpu/raven2_mec.bin"); 98 97 MODULE_FIRMWARE("amdgpu/raven2_mec2.bin"); 99 98 MODULE_FIRMWARE("amdgpu/raven2_rlc.bin"); 99 + MODULE_FIRMWARE("amdgpu/raven_kicker_rlc.bin"); 100 100 101 101 static const struct soc15_reg_golden golden_settings_gc_9_0[] = 102 102 { ··· 590 588 case CHIP_RAVEN: 591 589 if (adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) 592 590 break; 593 - if ((adev->gfx.rlc_fw_version < 531) || 591 + if ((adev->gfx.rlc_fw_version != 106 && 592 + adev->gfx.rlc_fw_version < 531) || 594 593 (adev->gfx.rlc_fw_version == 53815) || 595 594 (adev->gfx.rlc_feature_version < 1) || 596 595 !adev->gfx.rlc.is_rlc_v2_1) ··· 615 612 unsigned int i = 0; 616 613 uint16_t version_major; 617 614 uint16_t version_minor; 615 + uint32_t smu_version; 618 616 619 617 DRM_DEBUG("\n"); 620 618 ··· 686 682 (((adev->pdev->revision >= 0xC8) && (adev->pdev->revision <= 0xCF)) || 687 683 ((adev->pdev->revision >= 0xD8) && (adev->pdev->revision <= 0xDF)))) 688 684 snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc_am4.bin", chip_name); 685 + else if (!strcmp(chip_name, "raven") && (amdgpu_pm_load_smu_firmware(adev, &smu_version) == 0) && 686 + (smu_version >= 0x41e2b)) 687 + /** 688 + *SMC is loaded by SBIOS on APU and it's able to get the SMU version directly. 689 + */ 690 + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_kicker_rlc.bin", chip_name); 689 691 else 690 692 snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); 691 693 err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
+1 -2
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 4232 4232 struct drm_plane_state *old_state = 4233 4233 drm_atomic_get_old_plane_state(new_state->state, plane); 4234 4234 4235 - if (plane->state->fb != new_state->fb) 4236 - drm_atomic_set_fb_for_plane(plane->state, new_state->fb); 4235 + swap(plane->state->fb, new_state->fb); 4237 4236 4238 4237 plane->state->src_x = new_state->src_x; 4239 4238 plane->state->src_y = new_state->src_y;
+1
drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
··· 92 92 hwmgr_set_user_specify_caps(hwmgr); 93 93 hwmgr->fan_ctrl_is_in_default_mode = true; 94 94 hwmgr_init_workload_prority(hwmgr); 95 + hwmgr->gfxoff_state_changed_by_workload = false; 95 96 96 97 switch (hwmgr->chip_family) { 97 98 case AMDGPU_FAMILY_CI:
+28 -3
drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
··· 1258 1258 return size; 1259 1259 } 1260 1260 1261 + static bool smu10_is_raven1_refresh(struct pp_hwmgr *hwmgr) 1262 + { 1263 + struct amdgpu_device *adev = hwmgr->adev; 1264 + if ((adev->asic_type == CHIP_RAVEN) && 1265 + (adev->rev_id != 0x15d8) && 1266 + (hwmgr->smu_version >= 0x41e2b)) 1267 + return true; 1268 + else 1269 + return false; 1270 + } 1271 + 1261 1272 static int smu10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size) 1262 1273 { 1263 1274 int workload_type = 0; 1275 + int result = 0; 1264 1276 1265 1277 if (input[size] > PP_SMC_POWER_PROFILE_COMPUTE) { 1266 1278 pr_err("Invalid power profile mode %ld\n", input[size]); 1267 1279 return -EINVAL; 1268 1280 } 1269 - hwmgr->power_profile_mode = input[size]; 1281 + if (hwmgr->power_profile_mode == input[size]) 1282 + return 0; 1270 1283 1271 1284 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ 1272 1285 workload_type = 1273 - conv_power_profile_to_pplib_workload(hwmgr->power_profile_mode); 1274 - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ActiveProcessNotify, 1286 + conv_power_profile_to_pplib_workload(input[size]); 1287 + if (workload_type && 1288 + smu10_is_raven1_refresh(hwmgr) && 1289 + !hwmgr->gfxoff_state_changed_by_workload) { 1290 + smu10_gfx_off_control(hwmgr, false); 1291 + hwmgr->gfxoff_state_changed_by_workload = true; 1292 + } 1293 + result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ActiveProcessNotify, 1275 1294 1 << workload_type); 1295 + if (!result) 1296 + hwmgr->power_profile_mode = input[size]; 1297 + if (workload_type && hwmgr->gfxoff_state_changed_by_workload) { 1298 + smu10_gfx_off_control(hwmgr, true); 1299 + hwmgr->gfxoff_state_changed_by_workload = false; 1300 + } 1276 1301 1277 1302 return 0; 1278 1303 }
+1
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
··· 782 782 uint32_t workload_mask; 783 783 uint32_t workload_prority[Workload_Policy_Max]; 784 784 uint32_t workload_setting[Workload_Policy_Max]; 785 + bool gfxoff_state_changed_by_workload; 785 786 }; 786 787 787 788 int hwmgr_early_init(struct pp_hwmgr *hwmgr);
+4 -4
drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
··· 245 245 seq_printf(sf, "%sAD_V_CROP:\t\t0x%X\n", prefix, v[2]); 246 246 } 247 247 248 - static struct komeda_component_funcs d71_layer_funcs = { 248 + static const struct komeda_component_funcs d71_layer_funcs = { 249 249 .update = d71_layer_update, 250 250 .disable = d71_layer_disable, 251 251 .dump_register = d71_layer_dump, ··· 391 391 seq_printf(sf, "CU_USER_HIGH:\t\t0x%X\n", v[1]); 392 392 } 393 393 394 - static struct komeda_component_funcs d71_compiz_funcs = { 394 + static const struct komeda_component_funcs d71_compiz_funcs = { 395 395 .update = d71_compiz_update, 396 396 .disable = d71_component_disable, 397 397 .dump_register = d71_compiz_dump, ··· 467 467 seq_printf(sf, "IPS_RGB_YUV_COEFF%u:\t0x%X\n", i, v[i]); 468 468 } 469 469 470 - static struct komeda_component_funcs d71_improc_funcs = { 470 + static const struct komeda_component_funcs d71_improc_funcs = { 471 471 .update = d71_improc_update, 472 472 .disable = d71_component_disable, 473 473 .dump_register = d71_improc_dump, ··· 580 580 seq_printf(sf, "BS_USER:\t\t0x%X\n", v[4]); 581 581 } 582 582 583 - static struct komeda_component_funcs d71_timing_ctrlr_funcs = { 583 + static const struct komeda_component_funcs d71_timing_ctrlr_funcs = { 584 584 .update = d71_timing_ctrlr_update, 585 585 .disable = d71_timing_ctrlr_disable, 586 586 .dump_register = d71_timing_ctrlr_dump,
+2 -2
drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
··· 502 502 table->n_formats = ARRAY_SIZE(d71_format_caps_table); 503 503 } 504 504 505 - static struct komeda_dev_funcs d71_chip_funcs = { 505 + static const struct komeda_dev_funcs d71_chip_funcs = { 506 506 .init_format_table = d71_init_fmt_tbl, 507 507 .enum_resources = d71_enum_resources, 508 508 .cleanup = d71_cleanup, ··· 514 514 .flush = d71_flush, 515 515 }; 516 516 517 - struct komeda_dev_funcs * 517 + const struct komeda_dev_funcs * 518 518 d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip) 519 519 { 520 520 chip->arch_id = malidp_read32(reg_base, GLB_ARCH_ID);
+1 -1
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
··· 350 350 return true; 351 351 } 352 352 353 - static struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { 353 + static const struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { 354 354 .atomic_check = komeda_crtc_atomic_check, 355 355 .atomic_flush = komeda_crtc_atomic_flush, 356 356 .atomic_enable = komeda_crtc_atomic_enable,
+5 -1
drivers/gpu/drm/arm/display/komeda/komeda_dev.c
··· 8 8 #include <linux/of_device.h> 9 9 #include <linux/of_graph.h> 10 10 #include <linux/platform_device.h> 11 + #include <linux/dma-mapping.h> 11 12 #ifdef CONFIG_DEBUG_FS 12 13 #include <linux/debugfs.h> 13 14 #include <linux/seq_file.h> ··· 250 249 goto err_cleanup; 251 250 } 252 251 252 + dev->dma_parms = &mdev->dma_parms; 253 + dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); 254 + 253 255 err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group); 254 256 if (err) { 255 257 DRM_ERROR("create sysfs group failed.\n"); ··· 273 269 void komeda_dev_destroy(struct komeda_dev *mdev) 274 270 { 275 271 struct device *dev = mdev->dev; 276 - struct komeda_dev_funcs *funcs = mdev->funcs; 272 + const struct komeda_dev_funcs *funcs = mdev->funcs; 277 273 int i; 278 274 279 275 sysfs_remove_group(&dev->kobj, &komeda_sysfs_attr_group);
+5 -3
drivers/gpu/drm/arm/display/komeda/komeda_dev.h
··· 60 60 61 61 struct komeda_product_data { 62 62 u32 product_id; 63 - struct komeda_dev_funcs *(*identify)(u32 __iomem *reg, 63 + const struct komeda_dev_funcs *(*identify)(u32 __iomem *reg, 64 64 struct komeda_chip_info *info); 65 65 }; 66 66 ··· 149 149 struct device *dev; 150 150 /** @reg_base: the base address of komeda io space */ 151 151 u32 __iomem *reg_base; 152 + /** @dma_parms: the dma parameters of komeda */ 153 + struct device_dma_parameters dma_parms; 152 154 153 155 /** @chip: the basic chip information */ 154 156 struct komeda_chip_info chip; ··· 175 173 struct komeda_pipeline *pipelines[KOMEDA_MAX_PIPELINES]; 176 174 177 175 /** @funcs: chip funcs to access to HW */ 178 - struct komeda_dev_funcs *funcs; 176 + const struct komeda_dev_funcs *funcs; 179 177 /** 180 178 * @chip_data: 181 179 * ··· 194 192 return MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id) == target; 195 193 } 196 194 197 - struct komeda_dev_funcs * 195 + const struct komeda_dev_funcs * 198 196 d71_identify(u32 __iomem *reg, struct komeda_chip_info *chip); 199 197 200 198 struct komeda_dev *komeda_dev_create(struct device *dev);
+2 -2
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
··· 12 12 /** komeda_pipeline_add - Add a pipeline to &komeda_dev */ 13 13 struct komeda_pipeline * 14 14 komeda_pipeline_add(struct komeda_dev *mdev, size_t size, 15 - struct komeda_pipeline_funcs *funcs) 15 + const struct komeda_pipeline_funcs *funcs) 16 16 { 17 17 struct komeda_pipeline *pipe; 18 18 ··· 130 130 struct komeda_component * 131 131 komeda_component_add(struct komeda_pipeline *pipe, 132 132 size_t comp_sz, u32 id, u32 hw_id, 133 - struct komeda_component_funcs *funcs, 133 + const struct komeda_component_funcs *funcs, 134 134 u8 max_active_inputs, u32 supported_inputs, 135 135 u8 max_active_outputs, u32 __iomem *reg, 136 136 const char *name_fmt, ...)
+5 -5
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
··· 124 124 /** 125 125 * @funcs: chip functions to access HW 126 126 */ 127 - struct komeda_component_funcs *funcs; 127 + const struct komeda_component_funcs *funcs; 128 128 }; 129 129 130 130 /** ··· 346 346 struct komeda_improc *improc; 347 347 /** @ctrlr: timing controller */ 348 348 struct komeda_timing_ctrlr *ctrlr; 349 - /** @funcs: chip pipeline functions */ 350 - struct komeda_pipeline_funcs *funcs; /* private pipeline functions */ 349 + /** @funcs: chip private pipeline functions */ 350 + const struct komeda_pipeline_funcs *funcs; 351 351 352 352 /** @of_node: pipeline dt node */ 353 353 struct device_node *of_node; ··· 397 397 /* pipeline APIs */ 398 398 struct komeda_pipeline * 399 399 komeda_pipeline_add(struct komeda_dev *mdev, size_t size, 400 - struct komeda_pipeline_funcs *funcs); 400 + const struct komeda_pipeline_funcs *funcs); 401 401 void komeda_pipeline_destroy(struct komeda_dev *mdev, 402 402 struct komeda_pipeline *pipe); 403 403 int komeda_assemble_pipelines(struct komeda_dev *mdev); ··· 411 411 struct komeda_component * 412 412 komeda_component_add(struct komeda_pipeline *pipe, 413 413 size_t comp_sz, u32 id, u32 hw_id, 414 - struct komeda_component_funcs *funcs, 414 + const struct komeda_component_funcs *funcs, 415 415 u8 max_active_inputs, u32 supported_inputs, 416 416 u8 max_active_outputs, u32 __iomem *reg, 417 417 const char *name_fmt, ...);
+1 -3
drivers/gpu/drm/arm/display/komeda/komeda_plane.c
··· 55 55 struct komeda_plane_state *kplane_st = to_kplane_st(state); 56 56 struct komeda_layer *layer = kplane->layer; 57 57 struct drm_crtc_state *crtc_st; 58 - struct komeda_crtc *kcrtc; 59 58 struct komeda_crtc_state *kcrtc_st; 60 59 struct komeda_data_flow_cfg dflow; 61 60 int err; ··· 63 64 return 0; 64 65 65 66 crtc_st = drm_atomic_get_crtc_state(state->state, state->crtc); 66 - if (!crtc_st->enable) { 67 + if (IS_ERR(crtc_st) || !crtc_st->enable) { 67 68 DRM_DEBUG_ATOMIC("Cannot update plane on a disabled CRTC.\n"); 68 69 return -EINVAL; 69 70 } ··· 72 73 if (!crtc_st->active) 73 74 return 0; 74 75 75 - kcrtc = to_kcrtc(state->crtc); 76 76 kcrtc_st = to_kcrtc_st(crtc_st); 77 77 78 78 err = komeda_plane_init_data_flow(state, &dflow);
+7 -7
drivers/gpu/drm/arm/hdlcd_crtc.c
··· 186 186 clk_disable_unprepare(hdlcd->clk); 187 187 } 188 188 189 - static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, 190 - struct drm_crtc_state *state) 189 + static enum drm_mode_status hdlcd_crtc_mode_valid(struct drm_crtc *crtc, 190 + const struct drm_display_mode *mode) 191 191 { 192 192 struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); 193 - struct drm_display_mode *mode = &state->adjusted_mode; 194 193 long rate, clk_rate = mode->clock * 1000; 195 194 196 195 rate = clk_round_rate(hdlcd->clk, clk_rate); 197 - if (rate != clk_rate) { 196 + /* 0.1% seems a close enough tolerance for the TDA19988 on Juno */ 197 + if (abs(rate - clk_rate) * 1000 > clk_rate) { 198 198 /* clock required by mode not supported by hardware */ 199 - return -EINVAL; 199 + return MODE_NOCLOCK; 200 200 } 201 201 202 - return 0; 202 + return MODE_OK; 203 203 } 204 204 205 205 static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, ··· 220 220 } 221 221 222 222 static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { 223 - .atomic_check = hdlcd_crtc_atomic_check, 223 + .mode_valid = hdlcd_crtc_mode_valid, 224 224 .atomic_begin = hdlcd_crtc_atomic_begin, 225 225 .atomic_enable = hdlcd_crtc_atomic_enable, 226 226 .atomic_disable = hdlcd_crtc_atomic_disable,
+12 -1
drivers/gpu/drm/arm/malidp_drv.c
··· 192 192 { 193 193 struct drm_device *drm = state->dev; 194 194 struct malidp_drm *malidp = drm->dev_private; 195 + int loop = 5; 195 196 196 197 malidp->event = malidp->crtc.state->event; 197 198 malidp->crtc.state->event = NULL; ··· 207 206 drm_crtc_vblank_get(&malidp->crtc); 208 207 209 208 /* only set config_valid if the CRTC is enabled */ 210 - if (malidp_set_and_wait_config_valid(drm) < 0) 209 + if (malidp_set_and_wait_config_valid(drm) < 0) { 210 + /* 211 + * make a loop around the second CVAL setting and 212 + * try 5 times before giving up. 213 + */ 214 + while (loop--) { 215 + if (!malidp_set_and_wait_config_valid(drm)) 216 + break; 217 + } 211 218 DRM_DEBUG_DRIVER("timed out waiting for updated configuration\n"); 219 + } 220 + 212 221 } else if (malidp->event) { 213 222 /* CRTC inactive means vblank IRQ is disabled, send event directly */ 214 223 spin_lock_irq(&drm->event_lock);
+12 -10
drivers/gpu/drm/drm_atomic_helper.c
··· 1607 1607 old_plane_state->crtc != new_plane_state->crtc) 1608 1608 return -EINVAL; 1609 1609 1610 - /* 1611 - * FIXME: Since prepare_fb and cleanup_fb are always called on 1612 - * the new_plane_state for async updates we need to block framebuffer 1613 - * changes. This prevents use of a fb that's been cleaned up and 1614 - * double cleanups from occuring. 1615 - */ 1616 - if (old_plane_state->fb != new_plane_state->fb) 1617 - return -EINVAL; 1618 - 1619 1610 funcs = plane->helper_private; 1620 1611 if (!funcs->atomic_async_update) 1621 1612 return -EINVAL; ··· 1637 1646 * drm_atomic_async_check() succeeds. Async commits are not supposed to swap 1638 1647 * the states like normal sync commits, but just do in-place changes on the 1639 1648 * current state. 1649 + * 1650 + * TODO: Implement full swap instead of doing in-place changes. 1640 1651 */ 1641 1652 void drm_atomic_helper_async_commit(struct drm_device *dev, 1642 1653 struct drm_atomic_state *state) ··· 1649 1656 int i; 1650 1657 1651 1658 for_each_new_plane_in_state(state, plane, plane_state, i) { 1659 + struct drm_framebuffer *new_fb = plane_state->fb; 1660 + struct drm_framebuffer *old_fb = plane->state->fb; 1661 + 1652 1662 funcs = plane->helper_private; 1653 1663 funcs->atomic_async_update(plane, plane_state); 1654 1664 ··· 1660 1664 * plane->state in-place, make sure at least common 1661 1665 * properties have been properly updated. 1662 1666 */ 1663 - WARN_ON_ONCE(plane->state->fb != plane_state->fb); 1667 + WARN_ON_ONCE(plane->state->fb != new_fb); 1664 1668 WARN_ON_ONCE(plane->state->crtc_x != plane_state->crtc_x); 1665 1669 WARN_ON_ONCE(plane->state->crtc_y != plane_state->crtc_y); 1666 1670 WARN_ON_ONCE(plane->state->src_x != plane_state->src_x); 1667 1671 WARN_ON_ONCE(plane->state->src_y != plane_state->src_y); 1672 + 1673 + /* 1674 + * Make sure the FBs have been swapped so that cleanups in the 1675 + * new_state performs a cleanup in the old FB. 1676 + */ 1677 + WARN_ON_ONCE(plane_state->fb != old_fb); 1668 1678 } 1669 1679 } 1670 1680 EXPORT_SYMBOL(drm_atomic_helper_async_commit);
+1 -1
drivers/gpu/drm/i915/gvt/cmd_parser.c
··· 2530 2530 0, 12, NULL}, 2531 2531 2532 2532 {"VEB_DI_IECP", OP_VEB_DNDI_IECP_STATE, F_LEN_VAR, R_VECS, D_BDW_PLUS, 2533 - 0, 20, NULL}, 2533 + 0, 12, NULL}, 2534 2534 }; 2535 2535 2536 2536 static void add_cmd_entry(struct intel_gvt *gvt, struct cmd_entry *e)
+28 -10
drivers/gpu/drm/i915/gvt/gtt.c
··· 53 53 */ 54 54 bool intel_gvt_ggtt_validate_range(struct intel_vgpu *vgpu, u64 addr, u32 size) 55 55 { 56 - if ((!vgpu_gmadr_is_valid(vgpu, addr)) || (size 57 - && !vgpu_gmadr_is_valid(vgpu, addr + size - 1))) { 58 - gvt_vgpu_err("invalid range gmadr 0x%llx size 0x%x\n", 59 - addr, size); 60 - return false; 61 - } 62 - return true; 56 + if (size == 0) 57 + return vgpu_gmadr_is_valid(vgpu, addr); 58 + 59 + if (vgpu_gmadr_is_aperture(vgpu, addr) && 60 + vgpu_gmadr_is_aperture(vgpu, addr + size - 1)) 61 + return true; 62 + else if (vgpu_gmadr_is_hidden(vgpu, addr) && 63 + vgpu_gmadr_is_hidden(vgpu, addr + size - 1)) 64 + return true; 65 + 66 + gvt_dbg_mm("Invalid ggtt range at 0x%llx, size: 0x%x\n", 67 + addr, size); 68 + return false; 63 69 } 64 70 65 71 /* translate a guest gmadr to host gmadr */ ··· 948 942 949 943 if (e->type != GTT_TYPE_PPGTT_ROOT_L3_ENTRY 950 944 && e->type != GTT_TYPE_PPGTT_ROOT_L4_ENTRY) { 951 - cur_pt_type = get_next_pt_type(e->type) + 1; 945 + cur_pt_type = get_next_pt_type(e->type); 946 + 947 + if (!gtt_type_is_pt(cur_pt_type) || 948 + !gtt_type_is_pt(cur_pt_type + 1)) { 949 + WARN(1, "Invalid page table type, cur_pt_type is: %d\n", cur_pt_type); 950 + return -EINVAL; 951 + } 952 + 953 + cur_pt_type += 1; 954 + 952 955 if (ops->get_pfn(e) == 953 956 vgpu->gtt.scratch_pt[cur_pt_type].page_mfn) 954 957 return 0; ··· 1117 1102 1118 1103 err_free_spt: 1119 1104 ppgtt_free_spt(spt); 1105 + spt = NULL; 1120 1106 err: 1121 1107 gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n", 1122 1108 spt, we->val64, we->type); ··· 2199 2183 struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops; 2200 2184 unsigned long g_gtt_index = off >> info->gtt_entry_size_shift; 2201 2185 unsigned long gma, gfn; 2202 - struct intel_gvt_gtt_entry e, m; 2186 + struct intel_gvt_gtt_entry e = {.val64 = 0, .type = GTT_TYPE_GGTT_PTE}; 2187 + struct intel_gvt_gtt_entry m = {.val64 = 0, .type = GTT_TYPE_GGTT_PTE}; 2203 2188 dma_addr_t dma_addr; 2204 2189 int ret; 2205 2190 struct intel_gvt_partial_pte *partial_pte, *pos, *n; ··· 2267 2250 2268 2251 if (!partial_update && (ops->test_present(&e))) { 2269 2252 gfn = ops->get_pfn(&e); 2270 - m = e; 2253 + m.val64 = e.val64; 2254 + m.type = e.type; 2271 2255 2272 2256 /* one PTE update may be issued in multiple writes and the 2273 2257 * first write may not construct a valid gfn
+42 -7
drivers/gpu/drm/i915/gvt/handlers.c
··· 464 464 _MMIO(0x2690), 465 465 _MMIO(0x2694), 466 466 _MMIO(0x2698), 467 + _MMIO(0x2754), 468 + _MMIO(0x28a0), 467 469 _MMIO(0x4de0), 468 470 _MMIO(0x4de4), 469 471 _MMIO(0x4dfc), ··· 1692 1690 bool enable_execlist; 1693 1691 int ret; 1694 1692 1693 + (*(u32 *)p_data) &= ~_MASKED_BIT_ENABLE(1); 1694 + if (IS_COFFEELAKE(vgpu->gvt->dev_priv)) 1695 + (*(u32 *)p_data) &= ~_MASKED_BIT_ENABLE(2); 1695 1696 write_vreg(vgpu, offset, p_data, bytes); 1697 + 1698 + if (data & _MASKED_BIT_ENABLE(1)) { 1699 + enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); 1700 + return 0; 1701 + } 1702 + 1703 + if (IS_COFFEELAKE(vgpu->gvt->dev_priv) && 1704 + data & _MASKED_BIT_ENABLE(2)) { 1705 + enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); 1706 + return 0; 1707 + } 1696 1708 1697 1709 /* when PPGTT mode enabled, we will check if guest has called 1698 1710 * pvinfo, if not, we will treat this guest as non-gvtg-aware ··· 1786 1770 data &= ~RESET_CTL_READY_TO_RESET; 1787 1771 1788 1772 vgpu_vreg(vgpu, offset) = data; 1773 + return 0; 1774 + } 1775 + 1776 + static int csfe_chicken1_mmio_write(struct intel_vgpu *vgpu, 1777 + unsigned int offset, void *p_data, 1778 + unsigned int bytes) 1779 + { 1780 + u32 data = *(u32 *)p_data; 1781 + 1782 + (*(u32 *)p_data) &= ~_MASKED_BIT_ENABLE(0x18); 1783 + write_vreg(vgpu, offset, p_data, bytes); 1784 + 1785 + if (data & _MASKED_BIT_ENABLE(0x10) || data & _MASKED_BIT_ENABLE(0x8)) 1786 + enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); 1787 + 1789 1788 return 0; 1790 1789 } 1791 1790 ··· 1924 1893 MMIO_DFH(_MMIO(0x20dc), D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); 1925 1894 MMIO_DFH(_3D_CHICKEN3, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); 1926 1895 MMIO_DFH(_MMIO(0x2088), D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); 1927 - MMIO_DFH(_MMIO(0x20e4), D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); 1896 + MMIO_DFH(FF_SLICE_CS_CHICKEN2, D_ALL, 1897 + F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); 1928 1898 MMIO_DFH(_MMIO(0x2470), D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); 1929 1899 MMIO_DFH(GAM_ECOCHK, D_ALL, F_CMD_ACCESS, NULL, NULL); 1930 1900 MMIO_DFH(GEN7_COMMON_SLICE_CHICKEN1, D_ALL, F_MODE_MASK | F_CMD_ACCESS, ··· 3029 2997 MMIO_D(CSR_HTP_SKL, D_SKL_PLUS); 3030 2998 MMIO_D(CSR_LAST_WRITE, D_SKL_PLUS); 3031 2999 3032 - MMIO_D(BDW_SCRATCH1, D_SKL_PLUS); 3000 + MMIO_DFH(BDW_SCRATCH1, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); 3033 3001 3034 3002 MMIO_D(SKL_DFSM, D_SKL_PLUS); 3035 3003 MMIO_D(DISPIO_CR_TX_BMU_CR0, D_SKL_PLUS); ··· 3042 3010 MMIO_D(RPM_CONFIG0, D_SKL_PLUS); 3043 3011 MMIO_D(_MMIO(0xd08), D_SKL_PLUS); 3044 3012 MMIO_D(RC6_LOCATION, D_SKL_PLUS); 3045 - MMIO_DFH(GEN7_FF_SLICE_CS_CHICKEN1, D_SKL_PLUS, F_MODE_MASK, 3046 - NULL, NULL); 3013 + MMIO_DFH(GEN7_FF_SLICE_CS_CHICKEN1, D_SKL_PLUS, 3014 + F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); 3047 3015 MMIO_DFH(GEN9_CS_DEBUG_MODE1, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, 3048 3016 NULL, NULL); 3049 3017 ··· 3062 3030 MMIO_D(_MMIO(0x46520), D_SKL_PLUS); 3063 3031 3064 3032 MMIO_D(_MMIO(0xc403c), D_SKL_PLUS); 3065 - MMIO_D(_MMIO(0xb004), D_SKL_PLUS); 3033 + MMIO_DFH(GEN8_GARBCNTL, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); 3066 3034 MMIO_DH(DMA_CTRL, D_SKL_PLUS, NULL, dma_ctrl_write); 3067 3035 3068 3036 MMIO_D(_MMIO(0x65900), D_SKL_PLUS); ··· 3091 3059 MMIO_D(_MMIO(_PLANE_KEYMSK_1(PIPE_C)), D_SKL_PLUS); 3092 3060 3093 3061 MMIO_D(_MMIO(0x44500), D_SKL_PLUS); 3094 - MMIO_DFH(GEN9_CSFE_CHICKEN1_RCS, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); 3062 + #define CSFE_CHICKEN1_REG(base) _MMIO((base) + 0xD4) 3063 + MMIO_RING_DFH(CSFE_CHICKEN1_REG, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, 3064 + NULL, csfe_chicken1_mmio_write); 3065 + #undef CSFE_CHICKEN1_REG 3095 3066 MMIO_DFH(GEN8_HDC_CHICKEN1, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, 3096 3067 NULL, NULL); 3097 3068 MMIO_DFH(GEN9_WM_CHICKEN3, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, ··· 3274 3239 MMIO_D(GEN8_PUSHBUS_ENABLE, D_BXT); 3275 3240 MMIO_D(GEN8_PUSHBUS_SHIFT, D_BXT); 3276 3241 MMIO_D(GEN6_GFXPAUSE, D_BXT); 3277 - MMIO_D(GEN8_L3SQCREG1, D_BXT); 3242 + MMIO_DFH(GEN8_L3SQCREG1, D_BXT, F_CMD_ACCESS, NULL, NULL); 3278 3243 3279 3244 MMIO_DFH(GEN9_CTX_PREEMPT_REG, D_BXT, F_CMD_ACCESS, NULL, NULL); 3280 3245
+2
drivers/gpu/drm/i915/gvt/reg.h
··· 102 102 #define FORCEWAKE_ACK_MEDIA_GEN9_REG 0x0D88 103 103 #define FORCEWAKE_ACK_HSW_REG 0x130044 104 104 105 + #define RB_HEAD_WRAP_CNT_MAX ((1 << 11) - 1) 106 + #define RB_HEAD_WRAP_CNT_OFF 21 105 107 #define RB_HEAD_OFF_MASK ((1U << 21) - (1U << 2)) 106 108 #define RB_TAIL_OFF_MASK ((1U << 21) - (1U << 3)) 107 109 #define RB_TAIL_SIZE_MASK ((1U << 21) - (1U << 12))
+25
drivers/gpu/drm/i915/gvt/scheduler.c
··· 812 812 void *src; 813 813 unsigned long context_gpa, context_page_num; 814 814 int i; 815 + struct drm_i915_private *dev_priv = gvt->dev_priv; 816 + u32 ring_base; 817 + u32 head, tail; 818 + u16 wrap_count; 815 819 816 820 gvt_dbg_sched("ring id %d workload lrca %x\n", rq->engine->id, 817 821 workload->ctx_desc.lrca); 822 + 823 + head = workload->rb_head; 824 + tail = workload->rb_tail; 825 + wrap_count = workload->guest_rb_head >> RB_HEAD_WRAP_CNT_OFF; 826 + 827 + if (tail < head) { 828 + if (wrap_count == RB_HEAD_WRAP_CNT_MAX) 829 + wrap_count = 0; 830 + else 831 + wrap_count += 1; 832 + } 833 + 834 + head = (wrap_count << RB_HEAD_WRAP_CNT_OFF) | tail; 835 + 836 + ring_base = dev_priv->engine[workload->ring_id]->mmio_base; 837 + vgpu_vreg_t(vgpu, RING_TAIL(ring_base)) = tail; 838 + vgpu_vreg_t(vgpu, RING_HEAD(ring_base)) = head; 818 839 819 840 context_page_num = rq->engine->context_size; 820 841 context_page_num = context_page_num >> PAGE_SHIFT; ··· 1436 1415 struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 1437 1416 u64 ring_context_gpa; 1438 1417 u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx; 1418 + u32 guest_head; 1439 1419 int ret; 1440 1420 1441 1421 ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, ··· 1451 1429 1452 1430 intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + 1453 1431 RING_CTX_OFF(ring_tail.val), &tail, 4); 1432 + 1433 + guest_head = head; 1454 1434 1455 1435 head &= RB_HEAD_OFF_MASK; 1456 1436 tail &= RB_TAIL_OFF_MASK; ··· 1486 1462 workload->ctx_desc = *desc; 1487 1463 workload->ring_context_gpa = ring_context_gpa; 1488 1464 workload->rb_head = head; 1465 + workload->guest_rb_head = guest_head; 1489 1466 workload->rb_tail = tail; 1490 1467 workload->rb_start = start; 1491 1468 workload->rb_ctl = ctl;
+1
drivers/gpu/drm/i915/gvt/scheduler.h
··· 100 100 struct execlist_ctx_descriptor_format ctx_desc; 101 101 struct execlist_ring_context *ring_context; 102 102 unsigned long rb_head, rb_tail, rb_ctl, rb_start, rb_len; 103 + unsigned long guest_rb_head; 103 104 bool restore_inhibit; 104 105 struct intel_vgpu_elsp_dwords elsp_dwords; 105 106 bool emulate_schedule_in;
+3
drivers/gpu/drm/i915/i915_reg.h
··· 7620 7620 #define GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION (1 << 8) 7621 7621 #define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1 << 0) 7622 7622 7623 + #define GEN8_L3CNTLREG _MMIO(0x7034) 7624 + #define GEN8_ERRDETBCTRL (1 << 9) 7625 + 7623 7626 #define GEN11_COMMON_SLICE_CHICKEN3 _MMIO(0x7304) 7624 7627 #define GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC (1 << 11) 7625 7628
+6
drivers/gpu/drm/i915/intel_workarounds.c
··· 518 518 struct drm_i915_private *i915 = engine->i915; 519 519 struct i915_wa_list *wal = &engine->ctx_wa_list; 520 520 521 + /* WaDisableBankHangMode:icl */ 522 + wa_write(wal, 523 + GEN8_L3CNTLREG, 524 + intel_uncore_read(engine->uncore, GEN8_L3CNTLREG) | 525 + GEN8_ERRDETBCTRL); 526 + 521 527 /* Wa_1604370585:icl (pre-prod) 522 528 * Formerly known as WaPushConstantDereferenceHoldDisable 523 529 */
+4
drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
··· 502 502 static void mdp5_plane_atomic_async_update(struct drm_plane *plane, 503 503 struct drm_plane_state *new_state) 504 504 { 505 + struct drm_framebuffer *old_fb = plane->state->fb; 506 + 505 507 plane->state->src_x = new_state->src_x; 506 508 plane->state->src_y = new_state->src_y; 507 509 plane->state->crtc_x = new_state->crtc_x; ··· 526 524 527 525 *to_mdp5_plane_state(plane->state) = 528 526 *to_mdp5_plane_state(new_state); 527 + 528 + new_state->fb = old_fb; 529 529 } 530 530 531 531 static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = {
+7 -7
drivers/gpu/drm/nouveau/include/nvkm/core/firmware.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #ifndef __NVKM_FIRMWARE_H__ 3 3 #define __NVKM_FIRMWARE_H__ 4 + #include <core/subdev.h> 4 5 5 - #include <core/device.h> 6 - 7 - int nvkm_firmware_get(struct nvkm_device *device, const char *fwname, 8 - const struct firmware **fw); 9 - 10 - void nvkm_firmware_put(const struct firmware *fw); 11 - 6 + int nvkm_firmware_get_version(const struct nvkm_subdev *, const char *fwname, 7 + int min_version, int max_version, 8 + const struct firmware **); 9 + int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, 10 + const struct firmware **); 11 + void nvkm_firmware_put(const struct firmware *); 12 12 #endif
+28 -5
drivers/gpu/drm/nouveau/nvkm/core/firmware.c
··· 24 24 25 25 /** 26 26 * nvkm_firmware_get - load firmware from the official nvidia/chip/ directory 27 - * @device device that will use that firmware 27 + * @subdev subdevice that will use that firmware 28 28 * @fwname name of firmware file to load 29 29 * @fw firmware structure to load to 30 30 * ··· 32 32 * Firmware files released by NVIDIA will always follow this format. 33 33 */ 34 34 int 35 - nvkm_firmware_get(struct nvkm_device *device, const char *fwname, 36 - const struct firmware **fw) 35 + nvkm_firmware_get_version(const struct nvkm_subdev *subdev, const char *fwname, 36 + int min_version, int max_version, 37 + const struct firmware **fw) 37 38 { 39 + struct nvkm_device *device = subdev->device; 38 40 char f[64]; 39 41 char cname[16]; 40 42 int i; ··· 50 48 cname[i] = tolower(cname[i]); 51 49 } 52 50 53 - snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname); 54 - return request_firmware(fw, f, device->dev); 51 + for (i = max_version; i >= min_version; i--) { 52 + if (i != 0) 53 + snprintf(f, sizeof(f), "nvidia/%s/%s-%d.bin", cname, fwname, i); 54 + else 55 + snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname); 56 + 57 + if (!firmware_request_nowarn(fw, f, device->dev)) { 58 + nvkm_debug(subdev, "firmware \"%s\" loaded\n", f); 59 + return i; 60 + } 61 + 62 + nvkm_debug(subdev, "firmware \"%s\" unavailable\n", f); 63 + } 64 + 65 + nvkm_error(subdev, "failed to load firmware \"%s\"", fwname); 66 + return -ENOENT; 67 + } 68 + 69 + int 70 + nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname, 71 + const struct firmware **fw) 72 + { 73 + return nvkm_firmware_get_version(subdev, fwname, 0, 0, fw); 55 74 } 56 75 57 76 /**
+1 -3
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
··· 2115 2115 gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname, 2116 2116 struct gf100_gr_fuc *fuc) 2117 2117 { 2118 - struct nvkm_subdev *subdev = &gr->base.engine.subdev; 2119 - struct nvkm_device *device = subdev->device; 2120 2118 const struct firmware *fw; 2121 2119 int ret; 2122 2120 2123 - ret = nvkm_firmware_get(device, fwname, &fw); 2121 + ret = nvkm_firmware_get(&gr->base.engine.subdev, fwname, &fw); 2124 2122 if (ret) { 2125 2123 ret = gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret); 2126 2124 if (ret)
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.c
··· 36 36 void *blob; 37 37 int ret; 38 38 39 - ret = nvkm_firmware_get(subdev->device, name, &fw); 39 + ret = nvkm_firmware_get(subdev, name, &fw); 40 40 if (ret) 41 41 return ERR_PTR(ret); 42 42 if (fw->size < min_size) {
+42 -16
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
··· 229 229 struct ls_ucode_img_r352 { 230 230 struct ls_ucode_img base; 231 231 232 + const struct acr_r352_lsf_func *func; 233 + 232 234 struct acr_r352_lsf_wpr_header wpr_header; 233 235 struct acr_r352_lsf_lsb_header lsb_header; 234 236 }; ··· 245 243 enum nvkm_secboot_falcon falcon_id) 246 244 { 247 245 const struct nvkm_subdev *subdev = acr->base.subdev; 246 + const struct acr_r352_ls_func *func = acr->func->ls_func[falcon_id]; 248 247 struct ls_ucode_img_r352 *img; 249 248 int ret; 250 249 ··· 255 252 256 253 img->base.falcon_id = falcon_id; 257 254 258 - ret = acr->func->ls_func[falcon_id]->load(sb, &img->base); 259 - 260 - if (ret) { 255 + ret = func->load(sb, func->version_max, &img->base); 256 + if (ret < 0) { 261 257 kfree(img->base.ucode_data); 262 258 kfree(img->base.sig); 263 259 kfree(img); 264 260 return ERR_PTR(ret); 265 261 } 262 + 263 + img->func = func->version[ret]; 266 264 267 265 /* Check that the signature size matches our expectations... */ 268 266 if (img->base.sig_size != sizeof(img->lsb_header.signature)) { ··· 306 302 struct acr_r352_lsf_wpr_header *whdr = &img->wpr_header; 307 303 struct acr_r352_lsf_lsb_header *lhdr = &img->lsb_header; 308 304 struct ls_ucode_img_desc *desc = &_img->ucode_desc; 309 - const struct acr_r352_ls_func *func = 310 - acr->func->ls_func[_img->falcon_id]; 305 + const struct acr_r352_lsf_func *func = img->func; 311 306 312 307 /* Fill WPR header */ 313 308 whdr->falcon_id = _img->falcon_id; ··· 422 419 423 420 /* Figure out how large we need gdesc to be. */ 424 421 list_for_each_entry(_img, imgs, node) { 425 - const struct acr_r352_ls_func *ls_func = 426 - acr->func->ls_func[_img->falcon_id]; 422 + struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); 423 + const struct acr_r352_lsf_func *ls_func = img->func; 427 424 428 425 max_desc_size = max(max_desc_size, ls_func->bl_desc_size); 429 426 } ··· 436 433 437 434 list_for_each_entry(_img, imgs, node) { 438 435 struct ls_ucode_img_r352 *img = ls_ucode_img_r352(_img); 439 - const struct acr_r352_ls_func *ls_func = 440 - acr->func->ls_func[_img->falcon_id]; 436 + const struct acr_r352_lsf_func *ls_func = img->func; 441 437 442 438 nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, 443 439 sizeof(img->wpr_header)); ··· 1065 1063 kfree(acr); 1066 1064 } 1067 1065 1068 - const struct acr_r352_ls_func 1069 - acr_r352_ls_fecs_func = { 1070 - .load = acr_ls_ucode_load_fecs, 1066 + static const struct acr_r352_lsf_func 1067 + acr_r352_ls_fecs_func_0 = { 1071 1068 .generate_bl_desc = acr_r352_generate_flcn_bl_desc, 1072 1069 .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc), 1073 1070 }; 1074 1071 1075 1072 const struct acr_r352_ls_func 1076 - acr_r352_ls_gpccs_func = { 1077 - .load = acr_ls_ucode_load_gpccs, 1073 + acr_r352_ls_fecs_func = { 1074 + .load = acr_ls_ucode_load_fecs, 1075 + .version_max = 0, 1076 + .version = { 1077 + &acr_r352_ls_fecs_func_0, 1078 + } 1079 + }; 1080 + 1081 + static const struct acr_r352_lsf_func 1082 + acr_r352_ls_gpccs_func_0 = { 1078 1083 .generate_bl_desc = acr_r352_generate_flcn_bl_desc, 1079 1084 .bl_desc_size = sizeof(struct acr_r352_flcn_bl_desc), 1080 1085 /* GPCCS will be loaded using PRI */ 1081 1086 .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, 1087 + }; 1088 + 1089 + const struct acr_r352_ls_func 1090 + acr_r352_ls_gpccs_func = { 1091 + .load = acr_ls_ucode_load_gpccs, 1092 + .version_max = 0, 1093 + .version = { 1094 + &acr_r352_ls_gpccs_func_0, 1095 + } 1082 1096 }; 1083 1097 1084 1098 ··· 1168 1150 desc->argv = addr_args; 1169 1151 } 1170 1152 1153 + static const struct acr_r352_lsf_func 1154 + acr_r352_ls_pmu_func_0 = { 1155 + .generate_bl_desc = acr_r352_generate_pmu_bl_desc, 1156 + .bl_desc_size = sizeof(struct acr_r352_pmu_bl_desc), 1157 + }; 1158 + 1171 1159 static const struct acr_r352_ls_func 1172 1160 acr_r352_ls_pmu_func = { 1173 1161 .load = acr_ls_ucode_load_pmu, 1174 - .generate_bl_desc = acr_r352_generate_pmu_bl_desc, 1175 - .bl_desc_size = sizeof(struct acr_r352_pmu_bl_desc), 1176 1162 .post_run = acr_ls_pmu_post_run, 1163 + .version_max = 0, 1164 + .version = { 1165 + &acr_r352_ls_pmu_func_0, 1166 + } 1177 1167 }; 1178 1168 1179 1169 const struct acr_r352_func
+16 -6
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.h
··· 47 47 } 48 48 49 49 /** 50 - * struct acr_r352_ls_func - manages a single LS firmware 50 + * struct acr_r352_lsf_func - manages a specific LS firmware version 51 51 * 52 - * @load: load the external firmware into a ls_ucode_img 53 52 * @generate_bl_desc: function called on a block of bl_desc_size to generate the 54 53 * proper bootloader descriptor for this LS firmware 55 54 * @bl_desc_size: size of the bootloader descriptor 56 - * @post_run: hook called right after the ACR is executed 57 55 * @lhdr_flags: LS flags 58 56 */ 59 - struct acr_r352_ls_func { 60 - int (*load)(const struct nvkm_secboot *, struct ls_ucode_img *); 57 + struct acr_r352_lsf_func { 61 58 void (*generate_bl_desc)(const struct nvkm_acr *, 62 59 const struct ls_ucode_img *, u64, void *); 63 60 u32 bl_desc_size; 64 - int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *); 65 61 u32 lhdr_flags; 62 + }; 63 + 64 + /** 65 + * struct acr_r352_ls_func - manages a single LS falcon 66 + * 67 + * @load: load the external firmware into a ls_ucode_img 68 + * @post_run: hook called right after the ACR is executed 69 + */ 70 + struct acr_r352_ls_func { 71 + int (*load)(const struct nvkm_secboot *, int maxver, 72 + struct ls_ucode_img *); 73 + int (*post_run)(const struct nvkm_acr *, const struct nvkm_secboot *); 74 + int version_max; 75 + const struct acr_r352_lsf_func *version[]; 66 76 }; 67 77 68 78 struct acr_r352;
+42 -10
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.c
··· 66 66 bl_desc->data_size = hdr->data_size; 67 67 } 68 68 69 - const struct acr_r352_ls_func 70 - acr_r361_ls_fecs_func = { 71 - .load = acr_ls_ucode_load_fecs, 69 + static const struct acr_r352_lsf_func 70 + acr_r361_ls_fecs_func_0 = { 72 71 .generate_bl_desc = acr_r361_generate_flcn_bl_desc, 73 72 .bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc), 74 73 }; 75 74 76 75 const struct acr_r352_ls_func 77 - acr_r361_ls_gpccs_func = { 78 - .load = acr_ls_ucode_load_gpccs, 76 + acr_r361_ls_fecs_func = { 77 + .load = acr_ls_ucode_load_fecs, 78 + .version_max = 0, 79 + .version = { 80 + &acr_r361_ls_fecs_func_0, 81 + } 82 + }; 83 + 84 + static const struct acr_r352_lsf_func 85 + acr_r361_ls_gpccs_func_0 = { 79 86 .generate_bl_desc = acr_r361_generate_flcn_bl_desc, 80 87 .bl_desc_size = sizeof(struct acr_r361_flcn_bl_desc), 81 88 /* GPCCS will be loaded using PRI */ 82 89 .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, 90 + }; 91 + 92 + const struct acr_r352_ls_func 93 + acr_r361_ls_gpccs_func = { 94 + .load = acr_ls_ucode_load_gpccs, 95 + .version_max = 0, 96 + .version = { 97 + &acr_r361_ls_gpccs_func_0, 98 + } 83 99 }; 84 100 85 101 struct acr_r361_pmu_bl_desc { ··· 141 125 desc->argv = addr_args; 142 126 } 143 127 128 + static const struct acr_r352_lsf_func 129 + acr_r361_ls_pmu_func_0 = { 130 + .generate_bl_desc = acr_r361_generate_pmu_bl_desc, 131 + .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc), 132 + }; 133 + 144 134 const struct acr_r352_ls_func 145 135 acr_r361_ls_pmu_func = { 146 136 .load = acr_ls_ucode_load_pmu, 147 - .generate_bl_desc = acr_r361_generate_pmu_bl_desc, 148 - .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc), 149 137 .post_run = acr_ls_pmu_post_run, 138 + .version_max = 0, 139 + .version = { 140 + &acr_r361_ls_pmu_func_0, 141 + } 150 142 }; 151 143 152 144 static void ··· 188 164 desc->argv = 0x01000000; 189 165 } 190 166 191 - const struct acr_r352_ls_func 192 - acr_r361_ls_sec2_func = { 193 - .load = acr_ls_ucode_load_sec2, 167 + const struct acr_r352_lsf_func 168 + acr_r361_ls_sec2_func_0 = { 194 169 .generate_bl_desc = acr_r361_generate_sec2_bl_desc, 195 170 .bl_desc_size = sizeof(struct acr_r361_pmu_bl_desc), 171 + }; 172 + 173 + static const struct acr_r352_ls_func 174 + acr_r361_ls_sec2_func = { 175 + .load = acr_ls_ucode_load_sec2, 196 176 .post_run = acr_ls_sec2_post_run, 177 + .version_max = 0, 178 + .version = { 179 + &acr_r361_ls_sec2_func_0, 180 + } 197 181 }; 198 182 199 183
+1 -2
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r361.h
··· 67 67 extern const struct acr_r352_ls_func acr_r361_ls_fecs_func; 68 68 extern const struct acr_r352_ls_func acr_r361_ls_gpccs_func; 69 69 extern const struct acr_r352_ls_func acr_r361_ls_pmu_func; 70 - extern const struct acr_r352_ls_func acr_r361_ls_sec2_func; 71 - 70 + extern const struct acr_r352_lsf_func acr_r361_ls_sec2_func_0; 72 71 #endif
+24 -9
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c
··· 22 22 23 23 #include "acr_r367.h" 24 24 #include "acr_r361.h" 25 + #include "acr_r370.h" 25 26 26 27 #include <core/gpuobj.h> 27 28 ··· 101 100 struct ls_ucode_img_r367 { 102 101 struct ls_ucode_img base; 103 102 103 + const struct acr_r352_lsf_func *func; 104 + 104 105 struct acr_r367_lsf_wpr_header wpr_header; 105 106 struct acr_r367_lsf_lsb_header lsb_header; 106 107 }; ··· 114 111 enum nvkm_secboot_falcon falcon_id) 115 112 { 116 113 const struct nvkm_subdev *subdev = acr->base.subdev; 114 + const struct acr_r352_ls_func *func = acr->func->ls_func[falcon_id]; 117 115 struct ls_ucode_img_r367 *img; 118 116 int ret; 119 117 ··· 124 120 125 121 img->base.falcon_id = falcon_id; 126 122 127 - ret = acr->func->ls_func[falcon_id]->load(sb, &img->base); 128 - if (ret) { 123 + ret = func->load(sb, func->version_max, &img->base); 124 + if (ret < 0) { 129 125 kfree(img->base.ucode_data); 130 126 kfree(img->base.sig); 131 127 kfree(img); 132 128 return ERR_PTR(ret); 133 129 } 130 + 131 + img->func = func->version[ret]; 134 132 135 133 /* Check that the signature size matches our expectations... */ 136 134 if (img->base.sig_size != sizeof(img->lsb_header.signature)) { ··· 164 158 struct acr_r367_lsf_wpr_header *whdr = &img->wpr_header; 165 159 struct acr_r367_lsf_lsb_header *lhdr = &img->lsb_header; 166 160 struct ls_ucode_img_desc *desc = &_img->ucode_desc; 167 - const struct acr_r352_ls_func *func = 168 - acr->func->ls_func[_img->falcon_id]; 161 + const struct acr_r352_lsf_func *func = img->func; 169 162 170 163 /* Fill WPR header */ 171 164 whdr->falcon_id = _img->falcon_id; ··· 274 269 u8 *gdesc; 275 270 276 271 list_for_each_entry(_img, imgs, node) { 277 - const struct acr_r352_ls_func *ls_func = 278 - acr->func->ls_func[_img->falcon_id]; 272 + struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img); 273 + const struct acr_r352_lsf_func *ls_func = img->func; 279 274 280 275 max_desc_size = max(max_desc_size, ls_func->bl_desc_size); 281 276 } ··· 288 283 289 284 list_for_each_entry(_img, imgs, node) { 290 285 struct ls_ucode_img_r367 *img = ls_ucode_img_r367(_img); 291 - const struct acr_r352_ls_func *ls_func = 292 - acr->func->ls_func[_img->falcon_id]; 286 + const struct acr_r352_lsf_func *ls_func = img->func; 293 287 294 288 nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, 295 289 sizeof(img->wpr_header)); ··· 382 378 } 383 379 } 384 380 381 + static const struct acr_r352_ls_func 382 + acr_r367_ls_sec2_func = { 383 + .load = acr_ls_ucode_load_sec2, 384 + .post_run = acr_ls_sec2_post_run, 385 + .version_max = 1, 386 + .version = { 387 + &acr_r361_ls_sec2_func_0, 388 + &acr_r370_ls_sec2_func_0, 389 + } 390 + }; 391 + 385 392 const struct acr_r352_func 386 393 acr_r367_func = { 387 394 .fixup_hs_desc = acr_r367_fixup_hs_desc, ··· 406 391 [NVKM_SECBOOT_FALCON_FECS] = &acr_r361_ls_fecs_func, 407 392 [NVKM_SECBOOT_FALCON_GPCCS] = &acr_r361_ls_gpccs_func, 408 393 [NVKM_SECBOOT_FALCON_PMU] = &acr_r361_ls_pmu_func, 409 - [NVKM_SECBOOT_FALCON_SEC2] = &acr_r361_ls_sec2_func, 394 + [NVKM_SECBOOT_FALCON_SEC2] = &acr_r367_ls_sec2_func, 410 395 }, 411 396 }; 412 397
+31 -7
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.c
··· 49 49 desc->data_size = pdesc->app_resident_data_size; 50 50 } 51 51 52 - const struct acr_r352_ls_func 53 - acr_r370_ls_fecs_func = { 54 - .load = acr_ls_ucode_load_fecs, 52 + static const struct acr_r352_lsf_func 53 + acr_r370_ls_fecs_func_0 = { 55 54 .generate_bl_desc = acr_r370_generate_flcn_bl_desc, 56 55 .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 57 56 }; 58 57 59 58 const struct acr_r352_ls_func 60 - acr_r370_ls_gpccs_func = { 61 - .load = acr_ls_ucode_load_gpccs, 59 + acr_r370_ls_fecs_func = { 60 + .load = acr_ls_ucode_load_fecs, 61 + .version_max = 0, 62 + .version = { 63 + &acr_r370_ls_fecs_func_0, 64 + } 65 + }; 66 + 67 + static const struct acr_r352_lsf_func 68 + acr_r370_ls_gpccs_func_0 = { 62 69 .generate_bl_desc = acr_r370_generate_flcn_bl_desc, 63 70 .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 64 71 /* GPCCS will be loaded using PRI */ 65 72 .lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD, 73 + }; 74 + 75 + const struct acr_r352_ls_func 76 + acr_r370_ls_gpccs_func = { 77 + .load = acr_ls_ucode_load_gpccs, 78 + .version_max = 0, 79 + .version = { 80 + &acr_r370_ls_gpccs_func_0, 81 + } 66 82 }; 67 83 68 84 static void ··· 111 95 desc->argv = 0x01000000; 112 96 } 113 97 98 + const struct acr_r352_lsf_func 99 + acr_r370_ls_sec2_func_0 = { 100 + .generate_bl_desc = acr_r370_generate_sec2_bl_desc, 101 + .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 102 + }; 103 + 114 104 const struct acr_r352_ls_func 115 105 acr_r370_ls_sec2_func = { 116 106 .load = acr_ls_ucode_load_sec2, 117 - .generate_bl_desc = acr_r370_generate_sec2_bl_desc, 118 - .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 119 107 .post_run = acr_ls_sec2_post_run, 108 + .version_max = 0, 109 + .version = { 110 + &acr_r370_ls_sec2_func_0, 111 + } 120 112 }; 121 113 122 114 void
+1
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.h
··· 46 46 void acr_r370_generate_hs_bl_desc(const struct hsf_load_header *, void *, u64); 47 47 extern const struct acr_r352_ls_func acr_r370_ls_fecs_func; 48 48 extern const struct acr_r352_ls_func acr_r370_ls_gpccs_func; 49 + extern const struct acr_r352_lsf_func acr_r370_ls_sec2_func_0; 49 50 #endif
+10 -2
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c
··· 54 54 desc->argv = addr_args; 55 55 } 56 56 57 + static const struct acr_r352_lsf_func 58 + acr_r375_ls_pmu_func_0 = { 59 + .generate_bl_desc = acr_r375_generate_pmu_bl_desc, 60 + .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 61 + }; 62 + 57 63 const struct acr_r352_ls_func 58 64 acr_r375_ls_pmu_func = { 59 65 .load = acr_ls_ucode_load_pmu, 60 - .generate_bl_desc = acr_r375_generate_pmu_bl_desc, 61 - .bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc), 62 66 .post_run = acr_ls_pmu_post_run, 67 + .version_max = 0, 68 + .version = { 69 + &acr_r375_ls_pmu_func_0, 70 + } 63 71 }; 64 72 65 73 const struct acr_r352_func
+8 -4
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode.h
··· 147 147 u32 data_size; 148 148 }; 149 149 150 - int acr_ls_ucode_load_fecs(const struct nvkm_secboot *, struct ls_ucode_img *); 151 - int acr_ls_ucode_load_gpccs(const struct nvkm_secboot *, struct ls_ucode_img *); 152 - int acr_ls_ucode_load_pmu(const struct nvkm_secboot *, struct ls_ucode_img *); 150 + int acr_ls_ucode_load_fecs(const struct nvkm_secboot *, int, 151 + struct ls_ucode_img *); 152 + int acr_ls_ucode_load_gpccs(const struct nvkm_secboot *, int, 153 + struct ls_ucode_img *); 154 + int acr_ls_ucode_load_pmu(const struct nvkm_secboot *, int, 155 + struct ls_ucode_img *); 153 156 int acr_ls_pmu_post_run(const struct nvkm_acr *, const struct nvkm_secboot *); 154 - int acr_ls_ucode_load_sec2(const struct nvkm_secboot *, struct ls_ucode_img *); 157 + int acr_ls_ucode_load_sec2(const struct nvkm_secboot *, int, 158 + struct ls_ucode_img *); 155 159 int acr_ls_sec2_post_run(const struct nvkm_acr *, const struct nvkm_secboot *); 156 160 157 161 #endif
+12 -10
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c
··· 90 90 * blob. Also generate the corresponding ucode descriptor. 91 91 */ 92 92 static int 93 - ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img, 94 - const char *falcon_name) 93 + ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, int maxver, 94 + struct ls_ucode_img *img, const char *falcon_name) 95 95 { 96 96 const struct firmware *bl, *code, *data, *sig; 97 97 char f[64]; 98 98 int ret; 99 99 100 100 snprintf(f, sizeof(f), "gr/%s_bl", falcon_name); 101 - ret = nvkm_firmware_get(subdev->device, f, &bl); 101 + ret = nvkm_firmware_get(subdev, f, &bl); 102 102 if (ret) 103 103 goto error; 104 104 105 105 snprintf(f, sizeof(f), "gr/%s_inst", falcon_name); 106 - ret = nvkm_firmware_get(subdev->device, f, &code); 106 + ret = nvkm_firmware_get(subdev, f, &code); 107 107 if (ret) 108 108 goto free_bl; 109 109 110 110 snprintf(f, sizeof(f), "gr/%s_data", falcon_name); 111 - ret = nvkm_firmware_get(subdev->device, f, &data); 111 + ret = nvkm_firmware_get(subdev, f, &data); 112 112 if (ret) 113 113 goto free_inst; 114 114 115 115 snprintf(f, sizeof(f), "gr/%s_sig", falcon_name); 116 - ret = nvkm_firmware_get(subdev->device, f, &sig); 116 + ret = nvkm_firmware_get(subdev, f, &sig); 117 117 if (ret) 118 118 goto free_data; 119 119 ··· 146 146 } 147 147 148 148 int 149 - acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 149 + acr_ls_ucode_load_fecs(const struct nvkm_secboot *sb, int maxver, 150 + struct ls_ucode_img *img) 150 151 { 151 - return ls_ucode_img_load_gr(&sb->subdev, img, "fecs"); 152 + return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "fecs"); 152 153 } 153 154 154 155 int 155 - acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 156 + acr_ls_ucode_load_gpccs(const struct nvkm_secboot *sb, int maxver, 157 + struct ls_ucode_img *img) 156 158 { 157 - return ls_ucode_img_load_gr(&sb->subdev, img, "gpccs"); 159 + return ls_ucode_img_load_gr(&sb->subdev, maxver, img, "gpccs"); 158 160 }
+20 -18
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
··· 39 39 */ 40 40 static int 41 41 acr_ls_ucode_load_msgqueue(const struct nvkm_subdev *subdev, const char *name, 42 - struct ls_ucode_img *img) 42 + int maxver, struct ls_ucode_img *img) 43 43 { 44 44 const struct firmware *image, *desc, *sig; 45 45 char f[64]; 46 - int ret; 46 + int ver, ret; 47 47 48 48 snprintf(f, sizeof(f), "%s/image", name); 49 - ret = nvkm_firmware_get(subdev->device, f, &image); 50 - if (ret) 51 - return ret; 49 + ver = nvkm_firmware_get_version(subdev, f, 0, maxver, &image); 50 + if (ver < 0) 51 + return ver; 52 52 img->ucode_data = kmemdup(image->data, image->size, GFP_KERNEL); 53 53 nvkm_firmware_put(image); 54 54 if (!img->ucode_data) 55 55 return -ENOMEM; 56 56 57 57 snprintf(f, sizeof(f), "%s/desc", name); 58 - ret = nvkm_firmware_get(subdev->device, f, &desc); 59 - if (ret) 58 + ret = nvkm_firmware_get_version(subdev, f, ver, ver, &desc); 59 + if (ret < 0) 60 60 return ret; 61 61 memcpy(&img->ucode_desc, desc->data, sizeof(img->ucode_desc)); 62 62 img->ucode_size = ALIGN(img->ucode_desc.app_start_offset + img->ucode_desc.app_size, 256); 63 63 nvkm_firmware_put(desc); 64 64 65 65 snprintf(f, sizeof(f), "%s/sig", name); 66 - ret = nvkm_firmware_get(subdev->device, f, &sig); 67 - if (ret) 66 + ret = nvkm_firmware_get_version(subdev, f, ver, ver, &sig); 67 + if (ret < 0) 68 68 return ret; 69 69 img->sig_size = sig->size; 70 70 img->sig = kmemdup(sig->data, sig->size, GFP_KERNEL); ··· 72 72 if (!img->sig) 73 73 return -ENOMEM; 74 74 75 - return 0; 75 + return ver; 76 76 } 77 77 78 78 static int ··· 99 99 } 100 100 101 101 int 102 - acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 102 + acr_ls_ucode_load_pmu(const struct nvkm_secboot *sb, int maxver, 103 + struct ls_ucode_img *img) 103 104 { 104 105 struct nvkm_pmu *pmu = sb->subdev.device->pmu; 105 106 int ret; 106 107 107 - ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", img); 108 + ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "pmu", maxver, img); 108 109 if (ret) 109 110 return ret; 110 111 ··· 137 136 } 138 137 139 138 int 140 - acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img) 139 + acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, int maxver, 140 + struct ls_ucode_img *img) 141 141 { 142 142 struct nvkm_sec2 *sec = sb->subdev.device->sec2; 143 - int ret; 143 + int ver, ret; 144 144 145 - ret = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", img); 146 - if (ret) 147 - return ret; 145 + ver = acr_ls_ucode_load_msgqueue(&sb->subdev, "sec2", maxver, img); 146 + if (ver < 0) 147 + return ver; 148 148 149 149 /* Allocate the PMU queue corresponding to the FW version */ 150 150 ret = nvkm_msgqueue_new(img->ucode_desc.app_version, sec->falcon, ··· 153 151 if (ret) 154 152 return ret; 155 153 156 - return 0; 154 + return ver; 157 155 } 158 156 159 157 int
+25 -24
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
··· 924 924 struct drm_plane_state *new_state) 925 925 { 926 926 struct vop *vop = to_vop(plane->state->crtc); 927 - struct drm_plane_state *plane_state; 927 + struct drm_framebuffer *old_fb = plane->state->fb; 928 928 929 - plane_state = plane->funcs->atomic_duplicate_state(plane); 930 - plane_state->crtc_x = new_state->crtc_x; 931 - plane_state->crtc_y = new_state->crtc_y; 932 - plane_state->crtc_h = new_state->crtc_h; 933 - plane_state->crtc_w = new_state->crtc_w; 934 - plane_state->src_x = new_state->src_x; 935 - plane_state->src_y = new_state->src_y; 936 - plane_state->src_h = new_state->src_h; 937 - plane_state->src_w = new_state->src_w; 938 - 939 - if (plane_state->fb != new_state->fb) 940 - drm_atomic_set_fb_for_plane(plane_state, new_state->fb); 941 - 942 - swap(plane_state, plane->state); 943 - 944 - if (plane->state->fb && plane->state->fb != new_state->fb) { 945 - drm_framebuffer_get(plane->state->fb); 946 - WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0); 947 - drm_flip_work_queue(&vop->fb_unref_work, plane->state->fb); 948 - set_bit(VOP_PENDING_FB_UNREF, &vop->pending); 949 - } 929 + plane->state->crtc_x = new_state->crtc_x; 930 + plane->state->crtc_y = new_state->crtc_y; 931 + plane->state->crtc_h = new_state->crtc_h; 932 + plane->state->crtc_w = new_state->crtc_w; 933 + plane->state->src_x = new_state->src_x; 934 + plane->state->src_y = new_state->src_y; 935 + plane->state->src_h = new_state->src_h; 936 + plane->state->src_w = new_state->src_w; 937 + swap(plane->state->fb, new_state->fb); 950 938 951 939 if (vop->is_enabled) { 952 940 rockchip_drm_psr_inhibit_get_state(new_state->state); ··· 943 955 vop_cfg_done(vop); 944 956 spin_unlock(&vop->reg_lock); 945 957 rockchip_drm_psr_inhibit_put_state(new_state->state); 946 - } 947 958 948 - plane->funcs->atomic_destroy_state(plane, plane_state); 959 + /* 960 + * A scanout can still be occurring, so we can't drop the 961 + * reference to the old framebuffer. To solve this we get a 962 + * reference to old_fb and set a worker to release it later. 963 + * FIXME: if we perform 500 async_update calls before the 964 + * vblank, then we can have 500 different framebuffers waiting 965 + * to be released. 966 + */ 967 + if (old_fb && plane->state->fb != old_fb) { 968 + drm_framebuffer_get(old_fb); 969 + WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0); 970 + drm_flip_work_queue(&vop->fb_unref_work, old_fb); 971 + set_bit(VOP_PENDING_FB_UNREF, &vop->pending); 972 + } 973 + } 949 974 } 950 975 951 976 static const struct drm_plane_helper_funcs plane_helper_funcs = {
+1 -1
drivers/gpu/drm/vc4/vc4_plane.c
··· 1025 1025 { 1026 1026 struct vc4_plane_state *vc4_state, *new_vc4_state; 1027 1027 1028 - drm_atomic_set_fb_for_plane(plane->state, state->fb); 1028 + swap(plane->state->fb, state->fb); 1029 1029 plane->state->crtc_x = state->crtc_x; 1030 1030 plane->state->crtc_y = state->crtc_y; 1031 1031 plane->state->crtc_w = state->crtc_w;
+8
include/drm/drm_modeset_helper_vtables.h
··· 1185 1185 * current one with the new plane configurations in the new 1186 1186 * plane_state. 1187 1187 * 1188 + * Drivers should also swap the framebuffers between current plane 1189 + * state (&drm_plane.state) and new_state. 1190 + * This is required since cleanup for async commits is performed on 1191 + * the new state, rather than old state like for traditional commits. 1192 + * Since we want to give up the reference on the current (old) fb 1193 + * instead of our brand new one, swap them in the driver during the 1194 + * async commit. 1195 + * 1188 1196 * FIXME: 1189 1197 * - It only works for single plane updates 1190 1198 * - Async Pageflips are not supported yet