Re: [PATCH 1/4] drm/edid: Pass connector to AVI inforframe functions
On 04.12.2018 20:02, Ville Syrjälä wrote: > On Tue, Dec 04, 2018 at 08:03:53AM +0100, Andrzej Hajda wrote: >> On 03.12.2018 22:48, Ville Syrjälä wrote: >>> On Thu, Nov 29, 2018 at 09:46:16AM +0100, Andrzej Hajda wrote: Quite late, hopefully not too late. On 21.11.2018 12:51, Ville Syrjälä wrote: > On Wed, Nov 21, 2018 at 01:40:43PM +0200, Jani Nikula wrote: >>> return; >>> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c >>> b/drivers/gpu/drm/bridge/sil-sii8620.c >>> index a6e8f4591e63..0cc293a6ac24 100644 >>> --- a/drivers/gpu/drm/bridge/sil-sii8620.c >>> +++ b/drivers/gpu/drm/bridge/sil-sii8620.c >>> @@ -1104,8 +1104,7 @@ static void sii8620_set_infoframes(struct sii8620 >>> *ctx, >>> int ret; >>> >>> ret = drm_hdmi_avi_infoframe_from_display_mode(, >>> - mode, >>> - true); >>> + NULL, mode); >>> if (ctx->use_packed_pixel) >>> frm.avi.colorspace = HDMI_COLORSPACE_YUV422; >>> >>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >>> index 64c3cf027518..88b720b63126 100644 >>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c >>> @@ -1344,7 +1344,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, >>> struct drm_display_mode *mode) >>> u8 val; >>> >>> /* Initialise info frame from DRM mode */ >>> - drm_hdmi_avi_infoframe_from_display_mode(, mode, false); >>> + drm_hdmi_avi_infoframe_from_display_mode(, >>> +>connector, >>> mode); >>> >>> if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) >>> frame.colorspace = HDMI_COLORSPACE_YUV444; >>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c >>> index b506e3622b08..501ac05ba7da 100644 >>> --- a/drivers/gpu/drm/drm_edid.c >>> +++ b/drivers/gpu/drm/drm_edid.c >>> @@ -4830,19 +4830,32 @@ void drm_set_preferred_mode(struct >>> drm_connector *connector, >>> } >>> EXPORT_SYMBOL(drm_set_preferred_mode); >>> >>> +static bool is_hdmi2_sink(struct drm_connector *connector) >> You're usually known for adding const all around, why not const pointer >> here and in all the other drm_* functions that call this? > My current approach is to constify states/fbs/etc. but not so much > crtcs/connectors/etc. Too much const can sometimes get in the way > of things requiring that you remove the const later. But I guess > in this case the const shouldn't really get in the way of anything > because these are pretty much supposed to be pure functions. > >>> +{ >>> + /* >>> +* FIXME: sil-sii8620 doesn't have a connector around when >>> +* we need one, so we have to be prepared for a NULL connector. >>> +*/ >>> + if (!connector) >>> + return false; >> This actually changes the is_hdmi2_sink value for sil-sii8620. > Hmm. No idea why they would have set that to true when everyone else is > passing false. Because false does not work :) More precisely MHLv3 (used in Sii8620) uses CTA-861-F standard for infoframes, which is specific to HDMI2.0. Unfortunately I have no access to MHL specs, but my experiments and vendor drivers strongly suggests it is done this way. This is important in case of 4K modes which are handled differently by HDMI 1.4 and HDMI2.0. >>> HDMI 2.0 handles 4k just like 1.4 handled it when you use one of >>> the 4k modes defined in 1.4. Only if you use features beyond 1.4 do we >>> switch over to the HDMI 2.0 specific signalling. >> >> The difference is in infoframes: >> >> HDMI 1.4 sets AVI infoframe VIC to 0, and sends HDMI_VIC in VSI. >> >> HDMI 2.0 sets AVI infoframe to non zero VICs introduced by >> HDMI2.0/CEA-861-F, VSI can be omitted if I remember correctly, unless 3d >> is in use. > Like I said, The HDMI 1.4 method is used even with HDMI 2.0 sinks unless > some feature gets used which can't be signalled via the HDMI 1.4 vendor > specific infoframe. Do you mean that 4K VICs 95, 94, 93, 98 defined in CEA-861-F are not used at all for non-3d video in HDMI 2.0? Chapter 10.1 of HDMI2.0 spec says clearly: > When transmitting any additional Video Format for which a VIC value > has been defined in > CEA-861-F tables 1, 2, and 3, an HDMI Source shall set the VIC field > to the Video Code for > that format. It contradicts your statement, or am I missing something? > >> >> So setting VICs to non-zero in case of HDMI1.4 sinks and 4k modes seems >>
RE: [PATCH] drm/amdgpu: both support PCO real/fake rlc fw
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Aaron Liu > Sent: Wednesday, December 05, 2018 11:12 AM > To: amd-gfx@lists.freedesktop.org > Cc: Liu, Aaron > Subject: [PATCH] drm/amdgpu: both support PCO real/fake rlc fw > > For Picasso && AM4 SOCKET board, we use picasso_rlc_fake.bin For Picasso > && FP5 SOCKET board, we use picasso_rlc.bin > > Judgment method: > PCO AM4: revision >= 0xC8 && revision <= 0xCF > or revision >= 0xD8 && revision <= 0xDF otherwise is PCO FP5 > > Change-Id: I359f0a3d1bc7d4d49c871cb3fb82797c7b91b259 > Signed-off-by: Aaron Liu Reviewed-by: Huang Rui > --- > drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 15 ++- > 1 file changed, 14 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > index 94740ea..639a50d 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > @@ -645,7 +645,20 @@ static int gfx_v9_0_init_microcode(struct > amdgpu_device *adev) > adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr- > >header.ucode_version); > adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr- > >ucode_feature_version); > > - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", > chip_name); > + /* > + * For Picasso && AM4 SOCKET board, we use picasso_rlc_fake.bin > + * instead of picasso_rlc.bin. > + * Judgment method: > + * PCO AM4: revision >= 0xC8 && revision <= 0xCF > + * or revision >= 0xD8 && revision <= 0xDF > + * otherwise is PCO FP5 > + */ > + if (!strcmp(chip_name, "picasso") && > + (((adev->pdev->revision >= 0xC8) && (adev->pdev->revision > <= 0xCF)) || > + ((adev->pdev->revision >= 0xD8) && (adev->pdev->revision > <= 0xDF > + snprintf(fw_name, sizeof(fw_name), > "amdgpu/%s_rlc_fake.bin", chip_name); > + else > + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", > chip_name); > err = request_firmware(>gfx.rlc_fw, fw_name, adev->dev); > if (err) > goto out; > -- > 2.7.4 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/3] drm/amdgpu/psp: Add support VMR ring for VF
PSP only support VMR ring for SRIOV vf since v45 and all commands will be send to VMR ring for executing. VMR ring use C2PMSG 101 ~ 103 instead of C2PMSG 64 ~ 71. Signed-off-by: Xiangliang Yu --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 18 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 1 + drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h | 5 +- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 92 +++-- 4 files changed, 85 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index e05dc66..3142f84 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -155,10 +155,22 @@ psp_cmd_submit_buf(struct psp_context *psp, return ret; } -static void psp_prep_tmr_cmd_buf(struct psp_gfx_cmd_resp *cmd, +bool psp_support_vmr_ring(struct psp_context *psp) +{ + if (amdgpu_sriov_vf(psp->adev) && psp->sos_fw_version > 0x80045) + return true; + else + return false; +} + +static void psp_prep_tmr_cmd_buf(struct psp_context *psp, +struct psp_gfx_cmd_resp *cmd, uint64_t tmr_mc, uint32_t size) { - cmd->cmd_id = GFX_CMD_ID_SETUP_TMR; + if (psp_support_vmr_ring(psp)) + cmd->cmd_id = GFX_CMD_ID_SETUP_VMR; + else + cmd->cmd_id = GFX_CMD_ID_SETUP_TMR; cmd->cmd.cmd_setup_tmr.buf_phy_addr_lo = lower_32_bits(tmr_mc); cmd->cmd.cmd_setup_tmr.buf_phy_addr_hi = upper_32_bits(tmr_mc); cmd->cmd.cmd_setup_tmr.buf_size = size; @@ -192,7 +204,7 @@ static int psp_tmr_load(struct psp_context *psp) if (!cmd) return -ENOMEM; - psp_prep_tmr_cmd_buf(cmd, psp->tmr_mc_addr, PSP_TMR_SIZE); + psp_prep_tmr_cmd_buf(psp, cmd, psp->tmr_mc_addr, PSP_TMR_SIZE); DRM_INFO("reserve 0x%x from 0x%llx for PSP TMR SIZE\n", PSP_TMR_SIZE, psp->tmr_mc_addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 9ec5d1a..10decf7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -217,6 +217,7 @@ extern const struct amdgpu_ip_block_version psp_v10_0_ip_block; int psp_gpu_reset(struct amdgpu_device *adev); int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id); +bool psp_support_vmr_ring(struct psp_context *psp); extern const struct amdgpu_ip_block_version psp_v11_0_ip_block; diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h index 882bd83..0de00fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h @@ -43,6 +43,8 @@ enum psp_gfx_crtl_cmd_id GFX_CTRL_CMD_ID_ENABLE_INT = 0x0005, /* enable PSP-to-Gfx interrupt */ GFX_CTRL_CMD_ID_DISABLE_INT = 0x0006, /* disable PSP-to-Gfx interrupt */ GFX_CTRL_CMD_ID_MODE1_RST = 0x0007, /* trigger the Mode 1 reset */ +GFX_CTRL_CMD_ID_CONSUME_CMD = 0x000A, /* send interrupt to psp for updating write pointer of vf */ +GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C, /* destroy GPCOM ring */ GFX_CTRL_CMD_ID_MAX = 0x000F, /* max command ID */ }; @@ -89,7 +91,8 @@ enum psp_gfx_cmd_id GFX_CMD_ID_LOAD_IP_FW = 0x0006, /* load HW IP FW */ GFX_CMD_ID_DESTROY_TMR = 0x0007, /* destroy TMR region */ GFX_CMD_ID_SAVE_RESTORE = 0x0008, /* save/restore HW IP FW */ - +GFX_CMD_ID_SETUP_VMR= 0x0009, /* setup VMR region */ +GFX_CMD_ID_DESTROY_VMR = 0x000A, /* destroy VMR region */ }; diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 792b770..aa31a32 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -183,6 +183,7 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); if (sol_reg) { psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); + printk("sos fw version = 0x%x.\n", psp->sos_fw_version); return 0; } @@ -308,26 +309,47 @@ static int psp_v11_0_ring_create(struct psp_context *psp, struct psp_ring *ring = >km_ring; struct amdgpu_device *adev = psp->adev; - /* Write low address of the ring to C2PMSG_69 */ - psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg); - /* Write high address of the ring to C2PMSG_70 */ - psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr); - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_70, psp_ring_reg); - /* Write size of ring to C2PMSG_71 */ - psp_ring_reg = ring->ring_size; - WREG32_SOC15(MP0, 0,
[PATCH 3/3] drm/amdgpu/psp: Destroy psp ring when doing gpu reset
PSP ring need to be destroy before starting reinit for vf. This patche move it from hypervisor driver into guest. Signed-off-by: Xiangliang Yu Signed-off-by: Frank Min --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 3142f84..6759d89 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -548,8 +548,10 @@ static int psp_load_fw(struct amdgpu_device *adev) int ret; struct psp_context *psp = >psp; - if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset != 0) + if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset) { + psp_ring_destroy(psp, PSP_RING_TYPE__KM); goto skip_memalloc; + } psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); if (!psp->cmd) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/3] drm/amdgpu/psp: Get psp fw version through reading register
If PSP FW is running already, driver will not load PSP FW again and skip it. So psp fw version is not correct if reading it from FW binary file, need to get right version from register. Signed-off-by: Xiangliang Yu --- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 9c1569b..792b770 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -181,8 +181,10 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) * are already been loaded. */ sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); - if (sol_reg) + if (sol_reg) { + psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); return 0; + } /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/4] drm/edid: Pass connector to AVI inforframe functions
Hi Ville, On Tuesday, 4 December 2018 21:13:20 EET Ville Syrjälä wrote: > On Tue, Dec 04, 2018 at 08:46:53AM +0100, Andrzej Hajda wrote: > > On 03.12.2018 22:38, Ville Syrjälä wrote: > >> On Thu, Nov 29, 2018 at 10:08:07AM +0100, Andrzej Hajda wrote: > >>> On 21.11.2018 19:19, Laurent Pinchart wrote: > On Tuesday, 20 November 2018 18:13:42 EET Ville Syrjala wrote: > > From: Ville Syrjälä > > > > Make life easier for drivers by simply passing the connector > > to drm_hdmi_avi_infoframe_from_display_mode() and > > drm_hdmi_avi_infoframe_quant_range(). That way drivers don't > > need to worry about is_hdmi2_sink mess. > > While this is good for display controller drivers, the change isn't > great for bridge drivers. Down the road we're looking at moving > connector support out of the bridge drivers. Adding an additional > dependency to connectors in the bridges will make that more > difficult. Ideally bridges should retrieve the information from their > sink, regardless of whether it is a connector or another bridge. > >>> > >>> I agree with it, and case of sii8620 shows that there are cases where > >>> bridge has no direct access to the connector. > >> > >> It's just a matter of plumbing it through. > > > > What do you mean exactly? > > void bridge_foo(... > + ,struct drm_connector *connector); > > >>> On the other side, since you are passing connector to > >>> drm_hdmi_avi_infoframe_from_display_mode(), you could drop mode > >>> parameter and rename the function to > >>> drm_hdmi_avi_infoframe_from_connector() then, unless mode passed and > >>> mode set on the connector differs? > >> > >> Connectors don't have a mode. > > > > As they are passing video stream they should have it, even if not > > directly, for example: > > > > connector->state->crtc->mode > > That's not really how atomic works. One shouldn't go digging > through the obj->state pointers when we're not holding the > relevant locks anymore. The atomic way would be to pass either > both crtc state and connector state, or drm_atomic_state + > crtc/connector. Or a bridge state ? With chained bridges the mode can vary along the pipeline, the CRTC adjusted mode will only cover the link between the CRTC and the first bridge. It's only a matter of time until we need to store other intermediate modes in states. I'd rather prepare for that instead of passing the CRTC state to bridges. > > In moment of creating infoframe it should be set properly. > > > Please see below for an additional comment. > > > Cc: Alex Deucher > > Cc: "Christian König" > > Cc: "David (ChunMing) Zhou" > > Cc: Archit Taneja > > Cc: Andrzej Hajda > > Cc: Laurent Pinchart > > Cc: Inki Dae > > Cc: Joonyoung Shim > Cc: Seung-Woo Kim > > Cc: Kyungmin Park > > Cc: Russell King > > Cc: CK Hu > > Cc: Philipp Zabel > > Cc: Rob Clark > > Cc: Ben Skeggs > > Cc: Tomi Valkeinen > > Cc: Sandy Huang > > Cc: "Heiko Stübner" > > Cc: Benjamin Gaignard > > Cc: Vincent Abriou > > Cc: Thierry Reding > > Cc: Eric Anholt > > Cc: Shawn Guo > > Cc: Ilia Mirkin > > Cc: amd-gfx@lists.freedesktop.org > > Cc: linux-arm-...@vger.kernel.org > > Cc: freedr...@lists.freedesktop.org > > Cc: nouv...@lists.freedesktop.org > > Cc: linux-te...@vger.kernel.org > > Signed-off-by: Ville Syrjälä > > --- > > > > drivers/gpu/drm/amd/amdgpu/dce_v10_0.c| 2 +- > > drivers/gpu/drm/amd/amdgpu/dce_v11_0.c| 2 +- > > drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 3 ++- > > drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 2 +- > > drivers/gpu/drm/bridge/analogix-anx78xx.c | 5 ++-- > > drivers/gpu/drm/bridge/sii902x.c | 3 ++- > > drivers/gpu/drm/bridge/sil-sii8620.c | 3 +-- > > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 ++- > > drivers/gpu/drm/drm_edid.c| 33 > > drivers/gpu/drm/exynos/exynos_hdmi.c | 3 ++- > > drivers/gpu/drm/i2c/tda998x_drv.c | 3 ++- > > drivers/gpu/drm/i915/intel_hdmi.c | 14 +- > > drivers/gpu/drm/i915/intel_lspcon.c | 15 ++- > > drivers/gpu/drm/i915/intel_sdvo.c | 10 --- > > drivers/gpu/drm/mediatek/mtk_hdmi.c | 3 ++- > > drivers/gpu/drm/msm/hdmi/hdmi_bridge.c| 3 ++- > > drivers/gpu/drm/nouveau/dispnv50/disp.c | 7 +++-- > > drivers/gpu/drm/omapdrm/omap_encoder.c| 5 ++-- > > drivers/gpu/drm/radeon/radeon_audio.c | 2 +- > > drivers/gpu/drm/rockchip/inno_hdmi.c | 4 ++- > > drivers/gpu/drm/sti/sti_hdmi.c| 3 ++- > > drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c| 3 ++- > > drivers/gpu/drm/tegra/hdmi.c | 3 ++- > > drivers/gpu/drm/tegra/sor.c | 3 ++- > >
[PATCH] drm/amdgpu: both support PCO real/fake rlc fw
For Picasso && AM4 SOCKET board, we use picasso_rlc_fake.bin For Picasso && FP5 SOCKET board, we use picasso_rlc.bin Judgment method: PCO AM4: revision >= 0xC8 && revision <= 0xCF or revision >= 0xD8 && revision <= 0xDF otherwise is PCO FP5 Change-Id: I359f0a3d1bc7d4d49c871cb3fb82797c7b91b259 Signed-off-by: Aaron Liu --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 94740ea..639a50d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -645,7 +645,20 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); + /* +* For Picasso && AM4 SOCKET board, we use picasso_rlc_fake.bin +* instead of picasso_rlc.bin. +* Judgment method: +* PCO AM4: revision >= 0xC8 && revision <= 0xCF +* or revision >= 0xD8 && revision <= 0xDF +* otherwise is PCO FP5 +*/ + if (!strcmp(chip_name, "picasso") && + (((adev->pdev->revision >= 0xC8) && (adev->pdev->revision <= 0xCF)) || + ((adev->pdev->revision >= 0xD8) && (adev->pdev->revision <= 0xDF + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc_fake.bin", chip_name); + else + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); err = request_firmware(>gfx.rlc_fw, fw_name, adev->dev); if (err) goto out; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/2] drm/amdgpu: use HMM mirror callback to replace mmu notifier v5
On 2018-12-04 4:06 a.m., Christian König wrote: > Am 03.12.18 um 21:19 schrieb Yang, Philip: >> Replace our MMU notifier with hmm_mirror_ops.sync_cpu_device_pagetables >> callback. Enable CONFIG_HMM and CONFIG_HMM_MIRROR as a dependency in >> DRM_AMDGPU_USERPTR Kconfig. >> >> It supports both KFD userptr and gfx userptr paths. >> >> The depdent HMM patchsets from Jérôme Glisse are all merged into 4.20.0 >> kernel now. >> >> Change-Id: Ie62c3c5e3c5b8521ab3b438d1eff2aa2a003835e >> Signed-off-by: Philip Yang >> --- >> drivers/gpu/drm/amd/amdgpu/Kconfig | 6 +- >> drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- >> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 124 +++-- >> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | 2 +- >> 4 files changed, 57 insertions(+), 77 deletions(-) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig >> b/drivers/gpu/drm/amd/amdgpu/Kconfig >> index 9221e5489069..960a63355705 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/Kconfig >> +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig >> @@ -26,10 +26,10 @@ config DRM_AMDGPU_CIK >> config DRM_AMDGPU_USERPTR >> bool "Always enable userptr write support" >> depends on DRM_AMDGPU >> - select MMU_NOTIFIER >> + select HMM_MIRROR >> help >> - This option selects CONFIG_MMU_NOTIFIER if it isn't already >> - selected to enabled full userptr support. >> + This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it >> + isn't already selected to enabled full userptr support. >> config DRM_AMDGPU_GART_DEBUGFS >> bool "Allow GART access through debugfs" >> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile >> b/drivers/gpu/drm/amd/amdgpu/Makefile >> index f76bcb9c45e4..05ca6dc381e0 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/Makefile >> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile >> @@ -172,7 +172,7 @@ endif >> amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o >> amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o >> amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o >> -amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o >> +amdgpu-$(CONFIG_HMM) += amdgpu_mn.o > > This probably need to be CONFIG_HMM_MIRROR. Yes, CONFIG_HMM_MIRROR selects CONFIG_HMM, but the reverse is not true. > >> include $(FULL_AMD_PATH)/powerplay/Makefile >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c >> index e55508b39496..56595b3d90d2 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c >> @@ -45,7 +45,7 @@ >> #include >> #include >> -#include >> +#include >> #include >> #include >> #include >> @@ -58,7 +58,6 @@ >> * >> * @adev: amdgpu device pointer >> * @mm: process address space >> - * @mn: MMU notifier structure >> * @type: type of MMU notifier >> * @work: destruction work item >> * @node: hash table node to find structure by adev and mn >> @@ -66,6 +65,7 @@ >> * @objects: interval tree containing amdgpu_mn_nodes >> * @read_lock: mutex for recursive locking of @lock >> * @recursion: depth of recursion >> + * @mirror: HMM mirror function support >> * >> * Data for each amdgpu device and process address space. >> */ >> @@ -73,7 +73,6 @@ struct amdgpu_mn { >> /* constant after initialisation */ >> struct amdgpu_device *adev; >> struct mm_struct *mm; >> - struct mmu_notifier mn; >> enum amdgpu_mn_type type; >> /* only used on destruction */ >> @@ -87,6 +86,9 @@ struct amdgpu_mn { >> struct rb_root_cached objects; >> struct mutex read_lock; >> atomic_t recursion; >> + >> + /* HMM mirror */ >> + struct hmm_mirror mirror; >> }; >> /** >> @@ -103,7 +105,7 @@ struct amdgpu_mn_node { >> }; >> /** >> - * amdgpu_mn_destroy - destroy the MMU notifier >> + * amdgpu_mn_destroy - destroy the HMM mirror >> * >> * @work: previously sheduled work item >> * >> @@ -129,28 +131,26 @@ static void amdgpu_mn_destroy(struct >> work_struct *work) >> } >> up_write(>lock); >> mutex_unlock(>mn_lock); >> - mmu_notifier_unregister_no_release(>mn, amn->mm); >> + >> + hmm_mirror_unregister(>mirror); >> kfree(amn); >> } >> /** >> - * amdgpu_mn_release - callback to notify about mm destruction >> + * amdgpu_hmm_mirror_release - callback to notify about mm destruction >> * >> - * @mn: our notifier >> - * @mm: the mm this callback is about >> + * @mirror: the HMM mirror (mm) this callback is about >> * >> - * Shedule a work item to lazy destroy our notifier. >> + * Shedule a work item to lazy destroy HMM mirror. >> */ >> -static void amdgpu_mn_release(struct mmu_notifier *mn, >> - struct mm_struct *mm) >> +static void amdgpu_hmm_mirror_release(struct hmm_mirror *mirror) >> { >> - struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); >> + struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, >>
RE: [PATCH] drm/amdgpu/si: fix SI after doorbell rework
Reviewed-by: Oak Zeng Regards, Oak -Original Message- From: Alex Deucher Sent: Tuesday, December 4, 2018 2:01 PM To: amd-gfx list ; Zeng, Oak Cc: Deucher, Alexander Subject: Re: [PATCH] drm/amdgpu/si: fix SI after doorbell rework Ping? On Sun, Dec 2, 2018 at 9:50 PM Alex Deucher wrote: > > SI does not use doorbells, move asic doorbell init later asic check. > > Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=108920 > Signed-off-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index c75badfa5c4c..5a72906fdc6b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -515,7 +515,6 @@ void amdgpu_device_pci_config_reset(struct amdgpu_device > *adev) > */ > static int amdgpu_device_doorbell_init(struct amdgpu_device *adev) { > - amdgpu_asic_init_doorbell_index(adev); > > /* No doorbell on SI hardware generation */ > if (adev->asic_type < CHIP_BONAIRE) { @@ -529,6 +528,8 @@ > static int amdgpu_device_doorbell_init(struct amdgpu_device *adev) > if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET) > return -EINVAL; > > + amdgpu_asic_init_doorbell_index(adev); > + > /* doorbell bar mapping */ > adev->doorbell.base = pci_resource_start(adev->pdev, 2); > adev->doorbell.size = pci_resource_len(adev->pdev, 2); > -- > 2.13.6 > ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/4] drm/edid: Pass connector to AVI inforframe functions
On Tue, Dec 04, 2018 at 08:46:53AM +0100, Andrzej Hajda wrote: > On 03.12.2018 22:38, Ville Syrjälä wrote: > > On Thu, Nov 29, 2018 at 10:08:07AM +0100, Andrzej Hajda wrote: > >> On 21.11.2018 19:19, Laurent Pinchart wrote: > >>> Hi Ville, > >>> > >>> Thank you for the patch. > >>> > >>> On Tuesday, 20 November 2018 18:13:42 EET Ville Syrjala wrote: > From: Ville Syrjälä > > Make life easier for drivers by simply passing the connector > to drm_hdmi_avi_infoframe_from_display_mode() and > drm_hdmi_avi_infoframe_quant_range(). That way drivers don't > need to worry about is_hdmi2_sink mess. > >>> While this is good for display controller drivers, the change isn't great > >>> for > >>> bridge drivers. Down the road we're looking at moving connector support > >>> out of > >>> the bridge drivers. Adding an additional dependency to connectors in the > >>> bridges will make that more difficult. Ideally bridges should retrieve > >>> the > >>> information from their sink, regardless of whether it is a connector or > >>> another bridge. > >> > >> I agree with it, and case of sii8620 shows that there are cases where > >> bridge has no direct access to the connector. > > It's just a matter of plumbing it through. > > > What do you mean exactly? void bridge_foo(... + ,struct drm_connector *connector); > > > > > >> On the other side, since you are passing connector to > >> drm_hdmi_avi_infoframe_from_display_mode(), you could drop mode > >> parameter and rename the function to > >> drm_hdmi_avi_infoframe_from_connector() then, unless mode passed and > >> mode set on the connector differs? > > Connectors don't have a mode. > > > As they are passing video stream they should have it, even if not > directly, for example: > > connector->state->crtc->mode That's not really how atomic works. One shouldn't go digging through the obj->state pointers when we're not holding the relevant locks anymore. The atomic way would be to pass either both crtc state and connector state, or drm_atomic_state + crtc/connector. > > In moment of creating infoframe it should be set properly. > > > Regards > > Andrzej > > > > > >> > >> Regards > >> > >> Andrzej > >> > >> > >>> Please see below for an additional comment. > >>> > Cc: Alex Deucher > Cc: "Christian König" > Cc: "David (ChunMing) Zhou" > Cc: Archit Taneja > Cc: Andrzej Hajda > Cc: Laurent Pinchart > Cc: Inki Dae > Cc: Joonyoung Shim > Cc: Seung-Woo Kim > Cc: Kyungmin Park > Cc: Russell King > Cc: CK Hu > Cc: Philipp Zabel > Cc: Rob Clark > Cc: Ben Skeggs > Cc: Tomi Valkeinen > Cc: Sandy Huang > Cc: "Heiko Stübner" > Cc: Benjamin Gaignard > Cc: Vincent Abriou > Cc: Thierry Reding > Cc: Eric Anholt > Cc: Shawn Guo > Cc: Ilia Mirkin > Cc: amd-gfx@lists.freedesktop.org > Cc: linux-arm-...@vger.kernel.org > Cc: freedr...@lists.freedesktop.org > Cc: nouv...@lists.freedesktop.org > Cc: linux-te...@vger.kernel.org > Signed-off-by: Ville Syrjälä > --- > drivers/gpu/drm/amd/amdgpu/dce_v10_0.c| 2 +- > drivers/gpu/drm/amd/amdgpu/dce_v11_0.c| 2 +- > drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 3 ++- > drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 2 +- > drivers/gpu/drm/bridge/analogix-anx78xx.c | 5 ++-- > drivers/gpu/drm/bridge/sii902x.c | 3 ++- > drivers/gpu/drm/bridge/sil-sii8620.c | 3 +-- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 ++- > drivers/gpu/drm/drm_edid.c| 33 ++- > drivers/gpu/drm/exynos/exynos_hdmi.c | 3 ++- > drivers/gpu/drm/i2c/tda998x_drv.c | 3 ++- > drivers/gpu/drm/i915/intel_hdmi.c | 14 +- > drivers/gpu/drm/i915/intel_lspcon.c | 15 ++- > drivers/gpu/drm/i915/intel_sdvo.c | 10 --- > drivers/gpu/drm/mediatek/mtk_hdmi.c | 3 ++- > drivers/gpu/drm/msm/hdmi/hdmi_bridge.c| 3 ++- > drivers/gpu/drm/nouveau/dispnv50/disp.c | 7 +++-- > drivers/gpu/drm/omapdrm/omap_encoder.c| 5 ++-- > drivers/gpu/drm/radeon/radeon_audio.c | 2 +- > drivers/gpu/drm/rockchip/inno_hdmi.c | 4 ++- > drivers/gpu/drm/sti/sti_hdmi.c| 3 ++- > drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c| 3 ++- > drivers/gpu/drm/tegra/hdmi.c | 3 ++- > drivers/gpu/drm/tegra/sor.c | 3 ++- > drivers/gpu/drm/vc4/vc4_hdmi.c| 11 +--- > drivers/gpu/drm/zte/zx_hdmi.c | 4 ++- > include/drm/drm_edid.h| 8 +++--- > 27 files changed, 94 insertions(+), 66 deletions(-) > >>> For dw-hdmi and omapdrm, > >>> > >>> Reviewed-by: Laurent Pinchart > >>> -- Ville Syrjälä Intel
Re: [PATCH] drm/amdgpu/si: fix SI after doorbell rework
On Tue, Dec 04, 2018 at 02:00:54PM -0500, Alex Deucher wrote: > Ping? Does fix the SI issue (done in bugzilla). -- Sylvain ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/4] drm/edid: Pass connector to AVI inforframe functions
On Tue, Dec 04, 2018 at 08:03:53AM +0100, Andrzej Hajda wrote: > On 03.12.2018 22:48, Ville Syrjälä wrote: > > On Thu, Nov 29, 2018 at 09:46:16AM +0100, Andrzej Hajda wrote: > >> Quite late, hopefully not too late. > >> > >> > >> On 21.11.2018 12:51, Ville Syrjälä wrote: > >>> On Wed, Nov 21, 2018 at 01:40:43PM +0200, Jani Nikula wrote: > > return; > > diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c > > b/drivers/gpu/drm/bridge/sil-sii8620.c > > index a6e8f4591e63..0cc293a6ac24 100644 > > --- a/drivers/gpu/drm/bridge/sil-sii8620.c > > +++ b/drivers/gpu/drm/bridge/sil-sii8620.c > > @@ -1104,8 +1104,7 @@ static void sii8620_set_infoframes(struct sii8620 > > *ctx, > > int ret; > > > > ret = drm_hdmi_avi_infoframe_from_display_mode(, > > - mode, > > - true); > > + NULL, mode); > > if (ctx->use_packed_pixel) > > frm.avi.colorspace = HDMI_COLORSPACE_YUV422; > > > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > > index 64c3cf027518..88b720b63126 100644 > > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > > @@ -1344,7 +1344,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, > > struct drm_display_mode *mode) > > u8 val; > > > > /* Initialise info frame from DRM mode */ > > - drm_hdmi_avi_infoframe_from_display_mode(, mode, false); > > + drm_hdmi_avi_infoframe_from_display_mode(, > > +>connector, > > mode); > > > > if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) > > frame.colorspace = HDMI_COLORSPACE_YUV444; > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > > index b506e3622b08..501ac05ba7da 100644 > > --- a/drivers/gpu/drm/drm_edid.c > > +++ b/drivers/gpu/drm/drm_edid.c > > @@ -4830,19 +4830,32 @@ void drm_set_preferred_mode(struct > > drm_connector *connector, > > } > > EXPORT_SYMBOL(drm_set_preferred_mode); > > > > +static bool is_hdmi2_sink(struct drm_connector *connector) > You're usually known for adding const all around, why not const pointer > here and in all the other drm_* functions that call this? > >>> My current approach is to constify states/fbs/etc. but not so much > >>> crtcs/connectors/etc. Too much const can sometimes get in the way > >>> of things requiring that you remove the const later. But I guess > >>> in this case the const shouldn't really get in the way of anything > >>> because these are pretty much supposed to be pure functions. > >>> > > +{ > > + /* > > +* FIXME: sil-sii8620 doesn't have a connector around when > > +* we need one, so we have to be prepared for a NULL connector. > > +*/ > > + if (!connector) > > + return false; > This actually changes the is_hdmi2_sink value for sil-sii8620. > >>> Hmm. No idea why they would have set that to true when everyone else is > >>> passing false. > >> > >> Because false does not work :) More precisely MHLv3 (used in Sii8620) > >> uses CTA-861-F standard for infoframes, which is specific to HDMI2.0. > >> > >> Unfortunately I have no access to MHL specs, but my experiments and > >> vendor drivers strongly suggests it is done this way. > >> > >> This is important in case of 4K modes which are handled differently by > >> HDMI 1.4 and HDMI2.0. > > HDMI 2.0 handles 4k just like 1.4 handled it when you use one of > > the 4k modes defined in 1.4. Only if you use features beyond 1.4 do we > > switch over to the HDMI 2.0 specific signalling. > > > The difference is in infoframes: > > HDMI 1.4 sets AVI infoframe VIC to 0, and sends HDMI_VIC in VSI. > > HDMI 2.0 sets AVI infoframe to non zero VICs introduced by > HDMI2.0/CEA-861-F, VSI can be omitted if I remember correctly, unless 3d > is in use. Like I said, The HDMI 1.4 method is used even with HDMI 2.0 sinks unless some feature gets used which can't be signalled via the HDMI 1.4 vendor specific infoframe. > > > So setting VICs to non-zero in case of HDMI1.4 sinks and 4k modes seems > risky. That is not what I was proposing. > > > Regards > > Andrzej > > > > > >> The pipeline looks like (in parenthesis HDMI version on the stream): > >> > >> exynos_hdmi --(1.4)--> SII8620 --(2.0)--> MHL_dongle --(1.4)--> TV > >> > >> > >>> I guess I can change this to true to not change it. IIRC > >>> that was the only driver that didn't have a connector around. > >>> > >>> That said, I was actually thinking of removing this hdmi2 vs. not > >>> stuff from
Re: [PATCH] drm/amdgpu/si: fix SI after doorbell rework
Ping? On Sun, Dec 2, 2018 at 9:50 PM Alex Deucher wrote: > > SI does not use doorbells, move asic doorbell init later > asic check. > > Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=108920 > Signed-off-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index c75badfa5c4c..5a72906fdc6b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -515,7 +515,6 @@ void amdgpu_device_pci_config_reset(struct amdgpu_device > *adev) > */ > static int amdgpu_device_doorbell_init(struct amdgpu_device *adev) > { > - amdgpu_asic_init_doorbell_index(adev); > > /* No doorbell on SI hardware generation */ > if (adev->asic_type < CHIP_BONAIRE) { > @@ -529,6 +528,8 @@ static int amdgpu_device_doorbell_init(struct > amdgpu_device *adev) > if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET) > return -EINVAL; > > + amdgpu_asic_init_doorbell_index(adev); > + > /* doorbell bar mapping */ > adev->doorbell.base = pci_resource_start(adev->pdev, 2); > adev->doorbell.size = pci_resource_len(adev->pdev, 2); > -- > 2.13.6 > ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 2/2] drm/amdgpu/powerplay: fix clock stretcher limits on polaris
On Mon, Dec 3, 2018 at 9:39 PM Zhang, Jerry(Junwei) wrote: > > On 12/4/18 12:21 AM, Alex Deucher wrote: > > Adjust limits for newer polaris variants. > > > > Signed-off-by: Alex Deucher > > --- > > drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | 17 > > +++-- > > 1 file changed, 15 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > > b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > > index 2b2c26616902..1f8736b8291d 100644 > > --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > > @@ -1528,8 +1528,21 @@ static int > > polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr) > > efuse = efuse >> 24; > > > > if (hwmgr->chip_id == CHIP_POLARIS10) { > > - min = 1000; > > - max = 2300; > > + if (hwmgr->is_kicker) { > > + min = 1200; > > + max = 2500; > > + } else { > > + min = 1000; > > + max = 2300; > > + } > > + } else if (hwmgr->chip_id == CHIP_POLARIS11) { > > + if (hwmgr->is_kicker) { > > + min = 900; > > + max = 2500; > > the max is 2100, I think. Fixed locally. Thanks! Alex > > Apart from that, it's > Reviewed-by: Junwei Zhang > > Regards, > Jerry > > > + } else { > > + min = 1100; > > + max = 2100; > > + } > > } else { > > min = 1100; > > max = 2100; > ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: regression in ttm
Thanks, going to take a look tomorrow. Christian. Am 04.12.2018 18:28 schrieb "StDenis, Tom" : This commit causes a regression on my Carrizo running piglit (dmesg attached) commit 5786b66c9e3b7b18f3c24566e70cae450969cb14 Refs: v4.20-rc3-498-g5786b66c9e3b Author: Christian König AuthorDate: Mon Sep 24 13:35:53 2018 +0200 Commit: Christian König CommitDate: Tue Dec 4 10:22:22 2018 +0100 drm/ttm: drop the extra reservation for pipelined BO moves The driver is now responsible to allocate enough shared slots. Signed-off-by: Christian König Reviewed-by: Michel Dänzer Reviewed-by: Junwei Zhang Reviewed-by: Huang Rui Tom. ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
regression in ttm
This commit causes a regression on my Carrizo running piglit (dmesg attached) commit 5786b66c9e3b7b18f3c24566e70cae450969cb14 Refs: v4.20-rc3-498-g5786b66c9e3b Author: Christian König AuthorDate: Mon Sep 24 13:35:53 2018 +0200 Commit: Christian König CommitDate: Tue Dec 4 10:22:22 2018 +0100 drm/ttm: drop the extra reservation for pipelined BO moves The driver is now responsible to allocate enough shared slots. Signed-off-by: Christian König Reviewed-by: Michel Dänzer Reviewed-by: Junwei Zhang Reviewed-by: Huang Rui Tom. dmesg.log.gz Description: dmesg.log.gz ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amdgpu/vcn:Fixed S3 hung issue
Please re-state the patch subject instead of "Fixed S3 hung issue" With that fixed, the patch is Reviewed-by: Leo Liu On 12/4/18 10:31 AM, Zhu, James wrote: > Replace vcn_v1_0_stop with vcn_v1_0_set_powergating_state during suspend, > to keep adev->vcn.cur_state update. It will fix VCN S3 hung issue. > > Signed-off-by: James Zhu > --- > drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c > b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c > index c1a0350..4f83520 100644 > --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c > @@ -48,6 +48,7 @@ static void vcn_v1_0_set_enc_ring_funcs(struct > amdgpu_device *adev); > static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev); > static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); > static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, > uint32_t ptr); > +static int vcn_v1_0_set_powergating_state(void *handle, enum > amd_powergating_state state); > > /** >* vcn_v1_0_early_init - set function pointers > @@ -214,7 +215,7 @@ static int vcn_v1_0_hw_fini(void *handle) > struct amdgpu_ring *ring = >vcn.ring_dec; > > if (RREG32_SOC15(VCN, 0, mmUVD_STATUS)) > - vcn_v1_0_stop(adev); > + vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE); > > ring->sched.ready = false; > ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu/vcn:Fixed S3 hung issue
Replace vcn_v1_0_stop with vcn_v1_0_set_powergating_state during suspend, to keep adev->vcn.cur_state update. It will fix VCN S3 hung issue. Signed-off-by: James Zhu --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index c1a0350..4f83520 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -48,6 +48,7 @@ static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev); static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr); +static int vcn_v1_0_set_powergating_state(void *handle, enum amd_powergating_state state); /** * vcn_v1_0_early_init - set function pointers @@ -214,7 +215,7 @@ static int vcn_v1_0_hw_fini(void *handle) struct amdgpu_ring *ring = >vcn.ring_dec; if (RREG32_SOC15(VCN, 0, mmUVD_STATUS)) - vcn_v1_0_stop(adev); + vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE); ring->sched.ready = false; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 0/4] KFD upstreaming Nov 2018, part 2
For the series: Acked-by: Alex Deucher On Mon, Dec 3, 2018 at 7:05 PM Kuehling, Felix wrote: > > Ping. Any comments, R-b, A-b? > > On 2018-11-20 10:07 p.m., Kuehling, Felix wrote: > > This round adds support for more ROCm memory manager features: > > * VRAM limit checking to avoid overcommitment > > * DMABuf import for graphics interoperability > > * Support for mapping doorbells into GPUVM address space > > > > Felix Kuehling (4): > > drm/amdgpu: Add KFD VRAM limit checking > > drm/amdkfd: Add NULL-pointer check > > drm/amdkfd: Add DMABuf import functionality > > drm/amdkfd: Add support for doorbell BOs > > > > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 7 +- > > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 109 --- > > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 19 ++- > > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 170 > > ++- > > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h | 2 + > > drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- > > drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c| 4 +- > > drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 124 - > > drivers/gpu/drm/amd/amdkfd/kfd_priv.h| 1 + > > drivers/gpu/drm/amd/amdkfd/kfd_topology.c| 20 ++- > > drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 4 +- > > include/uapi/linux/kfd_ioctl.h | 26 +++- > > 12 files changed, 423 insertions(+), 65 deletions(-) > > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
Quoting Chris Wilson (2018-12-04 12:52:15) > Quoting Christian König (2018-12-04 11:59:39) > > -static inline bool __dma_fence_is_later(u32 f1, u32 f2) > > +static inline bool __dma_fence_is_later(u64 f1, u64 f2) > > { > > - return (int)(f1 - f2) > 0; > > + /* This is for backward compatibility with drivers which can only > > handle > > +* 32bit sequence numbers. Use a 64bit compare when any of the > > higher > > +* bits are none zero, otherwise use a 32bit compare with wrap > > around > > +* handling. > > +*/ > > + if (upper_32_bits(f1) || upper_32_bits(f2)) > > + return f1 > f2; > > + > > + return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0; > > Or just "(int64_t)(f1 - f2) > 0", works if drivers are only using the low > 32b and if they use the full 64b. No, it doesn't. -Chris ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
Quoting Christian König (2018-12-04 11:59:39) > -static inline bool __dma_fence_is_later(u32 f1, u32 f2) > +static inline bool __dma_fence_is_later(u64 f1, u64 f2) > { > - return (int)(f1 - f2) > 0; > + /* This is for backward compatibility with drivers which can only > handle > +* 32bit sequence numbers. Use a 64bit compare when any of the higher > +* bits are none zero, otherwise use a 32bit compare with wrap around > +* handling. > +*/ > + if (upper_32_bits(f1) || upper_32_bits(f2)) > + return f1 > f2; > + > + return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0; Or just "(int64_t)(f1 - f2) > 0", works if drivers are only using the low 32b and if they use the full 64b. -Chris ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
在 2018/12/4 19:59, Christian König 写道: > Implement finding the right timeline point in drm_syncobj_find_fence. > > v2: return -EINVAL when the point is not submitted yet. > v3: fix reference counting bug, add flags handling as well > > Signed-off-by: Christian König > --- > drivers/gpu/drm/drm_syncobj.c | 43 > --- > 1 file changed, 40 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c > index ee44cf2a8a12..fdbec8cedc3d 100644 > --- a/drivers/gpu/drm/drm_syncobj.c > +++ b/drivers/gpu/drm/drm_syncobj.c > @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file > *file_private, > struct dma_fence **fence) > { > struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); > - int ret = 0; > + struct syncobj_wait_entry wait; > + int ret; > > if (!syncobj) > return -ENOENT; > > *fence = drm_syncobj_fence_get(syncobj); > - if (!*fence) { > + drm_syncobj_put(syncobj); > + > + if (*fence) { > + ret = dma_fence_chain_find_seqno(fence, point); > + if (!ret) > + return 0; > + dma_fence_put(*fence); > + } else { > ret = -EINVAL; > } > - drm_syncobj_put(syncobj); > + > + if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) > + return ret; > + > + memset(, 0, sizeof(wait)); > + wait.task = current; > + wait.point = point; > + drm_syncobj_fence_add_wait(syncobj, ); > + > + do { > + set_current_state(TASK_INTERRUPTIBLE); > + if (wait.fence) { > + ret = 0; > + break; > + } > + > + if (signal_pending(current)) { > + ret = -ERESTARTSYS; > + break; > + } > + > + schedule(); > + } while (1); > + > + __set_current_state(TASK_RUNNING); > + *fence = wait.fence; > + > + if (wait.node.next) This condition isn't need, which is already in drm_syncobj_remove_wait(), with that fix, Reviewed-by: Chunming Zhou > + drm_syncobj_remove_wait(syncobj, ); > + > return ret; > } > EXPORT_SYMBOL(drm_syncobj_find_fence); ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2
在 2018/12/4 19:59, Christian König 写道: > Use the dma_fence_chain object to create a timeline of fence objects > instead of just replacing the existing fence. > > v2: rebase and cleanup > > Signed-off-by: Christian König Reviewed-by: Chunming Zhou > --- > drivers/gpu/drm/drm_syncobj.c | 37 + > include/drm/drm_syncobj.h | 5 + > 2 files changed, 42 insertions(+) > > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c > index e19525af0cce..64fcfea1c39f 100644 > --- a/drivers/gpu/drm/drm_syncobj.c > +++ b/drivers/gpu/drm/drm_syncobj.c > @@ -122,6 +122,43 @@ static void drm_syncobj_remove_wait(struct drm_syncobj > *syncobj, > spin_unlock(>lock); > } > > +/** > + * drm_syncobj_add_point - add new timeline point to the syncobj > + * @syncobj: sync object to add timeline point do > + * @chain: chain node to use to add the point > + * @fence: fence to encapsulate in the chain node > + * @point: sequence number to use for the point > + * > + * Add the chain node as new timeline point to the syncobj. > + */ > +void drm_syncobj_add_point(struct drm_syncobj *syncobj, > +struct dma_fence_chain *chain, > +struct dma_fence *fence, > +uint64_t point) > +{ > + struct syncobj_wait_entry *cur, *tmp; > + struct dma_fence *prev; > + > + dma_fence_get(fence); > + > + spin_lock(>lock); > + > + prev = rcu_dereference_protected(syncobj->fence, > + lockdep_is_held(>lock)); > + dma_fence_chain_init(chain, prev, fence, point); > + rcu_assign_pointer(syncobj->fence, >base); > + > + list_for_each_entry_safe(cur, tmp, >cb_list, node) { > + list_del_init(>node); > + syncobj_wait_syncobj_func(syncobj, cur); > + } > + spin_unlock(>lock); > + > + /* Walk the chain once to trigger garbage collection */ > + dma_fence_chain_for_each(fence); > +} > +EXPORT_SYMBOL(drm_syncobj_add_point); > + > /** >* drm_syncobj_replace_fence - replace fence in a sync object. >* @syncobj: Sync object to replace fence in > diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h > index 7c6ed845c70d..8acb4ae4f311 100644 > --- a/include/drm/drm_syncobj.h > +++ b/include/drm/drm_syncobj.h > @@ -27,6 +27,7 @@ > #define __DRM_SYNCOBJ_H__ > > #include "linux/dma-fence.h" > +#include "linux/dma-fence-chain.h" > > /** >* struct drm_syncobj - sync object. > @@ -110,6 +111,10 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj) > > struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, >u32 handle); > +void drm_syncobj_add_point(struct drm_syncobj *syncobj, > +struct dma_fence_chain *chain, > +struct dma_fence *fence, > +uint64_t point); > void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, > struct dma_fence *fence); > int drm_syncobj_find_fence(struct drm_file *file_private, ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup
在 2018/12/4 19:59, Christian König 写道: > This completes "drm/syncobj: Drop add/remove_callback from driver > interface" and cleans up the implementation a bit. > > Signed-off-by: Christian König Reviewed-by: Chunming Zhou > --- > drivers/gpu/drm/drm_syncobj.c | 91 > ++- > include/drm/drm_syncobj.h | 21 -- > 2 files changed, 30 insertions(+), 82 deletions(-) > > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c > index db30a0e89db8..e19525af0cce 100644 > --- a/drivers/gpu/drm/drm_syncobj.c > +++ b/drivers/gpu/drm/drm_syncobj.c > @@ -56,6 +56,16 @@ > #include "drm_internal.h" > #include > > +struct syncobj_wait_entry { > + struct list_head node; > + struct task_struct *task; > + struct dma_fence *fence; > + struct dma_fence_cb fence_cb; > +}; > + > +static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, > + struct syncobj_wait_entry *wait); > + > /** >* drm_syncobj_find - lookup and reference a sync object. >* @file_private: drm file private pointer > @@ -82,58 +92,33 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file > *file_private, > } > EXPORT_SYMBOL(drm_syncobj_find); > > -static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj, > - struct drm_syncobj_cb *cb, > - drm_syncobj_func_t func) > +static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj, > +struct syncobj_wait_entry *wait) > { > - cb->func = func; > - list_add_tail(>node, >cb_list); > -} > - > -static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj, > - struct dma_fence **fence, > - struct drm_syncobj_cb *cb, > - drm_syncobj_func_t func) > -{ > - int ret; > - > - *fence = drm_syncobj_fence_get(syncobj); > - if (*fence) > - return 1; > + if (wait->fence) > + return; > > spin_lock(>lock); > /* We've already tried once to get a fence and failed. Now that we >* have the lock, try one more time just to be sure we don't add a >* callback when a fence has already been set. >*/ > - if (syncobj->fence) { > - *fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, > - > lockdep_is_held(>lock))); > - ret = 1; > - } else { > - *fence = NULL; > - drm_syncobj_add_callback_locked(syncobj, cb, func); > - ret = 0; > - } > + if (syncobj->fence) > + wait->fence = dma_fence_get( > + rcu_dereference_protected(syncobj->fence, 1)); > + else > + list_add_tail(>node, >cb_list); > spin_unlock(>lock); > - > - return ret; > } > > -void drm_syncobj_add_callback(struct drm_syncobj *syncobj, > - struct drm_syncobj_cb *cb, > - drm_syncobj_func_t func) > +static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj, > + struct syncobj_wait_entry *wait) > { > - spin_lock(>lock); > - drm_syncobj_add_callback_locked(syncobj, cb, func); > - spin_unlock(>lock); > -} > + if (!wait->node.next) > + return; > > -void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, > - struct drm_syncobj_cb *cb) > -{ > spin_lock(>lock); > - list_del_init(>node); > + list_del_init(>node); > spin_unlock(>lock); > } > > @@ -148,7 +133,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj > *syncobj, > struct dma_fence *fence) > { > struct dma_fence *old_fence; > - struct drm_syncobj_cb *cur, *tmp; > + struct syncobj_wait_entry *cur, *tmp; > > if (fence) > dma_fence_get(fence); > @@ -162,7 +147,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj > *syncobj, > if (fence != old_fence) { > list_for_each_entry_safe(cur, tmp, >cb_list, node) { > list_del_init(>node); > - cur->func(syncobj, cur); > + syncobj_wait_syncobj_func(syncobj, cur); > } > } > > @@ -608,13 +593,6 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, > void *data, > >handle); > } > > -struct syncobj_wait_entry { > - struct task_struct *task; > - struct dma_fence *fence; > - struct dma_fence_cb fence_cb; > - struct drm_syncobj_cb syncobj_cb; > -}; > - > static void syncobj_wait_fence_func(struct dma_fence *fence, >
Re: [PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2"
在 2018/12/4 19:59, Christian König 写道: > This reverts commit 9a09a42369a4a37a959c051d8e1a1f948c1529a4. > > The whole interface isn't thought through. Since this function can't > fail we actually can't allocate an object to store the sync point. > > Sorry, I should have taken the lead on this from the very beginning and > reviewed it more thoughtfully. Going to propose a new interface as a > follow up change. > > Signed-off-by: Christian König Reviewed-by: Chunming Zhou > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- > drivers/gpu/drm/drm_syncobj.c | 14 ++ > drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- > drivers/gpu/drm/v3d/v3d_gem.c | 3 +-- > drivers/gpu/drm/vc4/vc4_gem.c | 2 +- > include/drm/drm_syncobj.h | 2 +- > 6 files changed, 11 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > index c0740a924769..149b3065119b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > @@ -1200,7 +1200,7 @@ static void amdgpu_cs_post_dependencies(struct > amdgpu_cs_parser *p) > int i; > > for (i = 0; i < p->num_post_dep_syncobjs; ++i) > - drm_syncobj_replace_fence(p->post_dep_syncobjs[i], 0, p->fence); > + drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence); > } > > static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c > index 5c5ba1f14307..db30a0e89db8 100644 > --- a/drivers/gpu/drm/drm_syncobj.c > +++ b/drivers/gpu/drm/drm_syncobj.c > @@ -140,13 +140,11 @@ void drm_syncobj_remove_callback(struct drm_syncobj > *syncobj, > /** >* drm_syncobj_replace_fence - replace fence in a sync object. >* @syncobj: Sync object to replace fence in > - * @point: timeline point >* @fence: fence to install in sync file. >* > - * This replaces the fence on a sync object, or a timeline point fence. > + * This replaces the fence on a sync object. >*/ > void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, > -u64 point, > struct dma_fence *fence) > { > struct dma_fence *old_fence; > @@ -184,7 +182,7 @@ static void drm_syncobj_assign_null_handle(struct > drm_syncobj *syncobj) > { > struct dma_fence *fence = dma_fence_get_stub(); > > - drm_syncobj_replace_fence(syncobj, 0, fence); > + drm_syncobj_replace_fence(syncobj, fence); > dma_fence_put(fence); > } > > @@ -233,7 +231,7 @@ void drm_syncobj_free(struct kref *kref) > struct drm_syncobj *syncobj = container_of(kref, > struct drm_syncobj, > refcount); > - drm_syncobj_replace_fence(syncobj, 0, NULL); > + drm_syncobj_replace_fence(syncobj, NULL); > kfree(syncobj); > } > EXPORT_SYMBOL(drm_syncobj_free); > @@ -267,7 +265,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, > uint32_t flags, > drm_syncobj_assign_null_handle(syncobj); > > if (fence) > - drm_syncobj_replace_fence(syncobj, 0, fence); > + drm_syncobj_replace_fence(syncobj, fence); > > *out_syncobj = syncobj; > return 0; > @@ -452,7 +450,7 @@ static int drm_syncobj_import_sync_file_fence(struct > drm_file *file_private, > return -ENOENT; > } > > - drm_syncobj_replace_fence(syncobj, 0, fence); > + drm_syncobj_replace_fence(syncobj, fence); > dma_fence_put(fence); > drm_syncobj_put(syncobj); > return 0; > @@ -923,7 +921,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void > *data, > return ret; > > for (i = 0; i < args->count_handles; i++) > - drm_syncobj_replace_fence(syncobjs[i], 0, NULL); > + drm_syncobj_replace_fence(syncobjs[i], NULL); > > drm_syncobj_array_free(syncobjs, args->count_handles); > > diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c > b/drivers/gpu/drm/i915/i915_gem_execbuffer.c > index 1aaccbe7e1de..786d719e652d 100644 > --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c > +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c > @@ -2186,7 +2186,7 @@ signal_fence_array(struct i915_execbuffer *eb, > if (!(flags & I915_EXEC_FENCE_SIGNAL)) > continue; > > - drm_syncobj_replace_fence(syncobj, 0, fence); > + drm_syncobj_replace_fence(syncobj, fence); > } > } > > diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c > index b88c96911453..655be1a865fa 100644 > --- a/drivers/gpu/drm/v3d/v3d_gem.c > +++ b/drivers/gpu/drm/v3d/v3d_gem.c > @@ -588,8 +588,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, > /* Update the return
Re: [PATCH 02/10] dma-buf: add new dma_fence_chain container v3
在 2018/12/4 19:59, Christian König 写道: > Lockless container implementation similar to a dma_fence_array, but with > only two elements per node and automatic garbage collection. > > v2: properly document dma_fence_chain_for_each, add > dma_fence_chain_find_seqno, > drop prev reference during garbage collection if it's not a chain fence. > v3: use head and iterator for dma_fence_chain_for_each > > Signed-off-by: Christian König Reviewed-by: Chunming Zhou > --- > drivers/dma-buf/Makefile | 3 +- > drivers/dma-buf/dma-fence-chain.c | 234 > ++ > include/linux/dma-fence-chain.h | 81 + > 3 files changed, 317 insertions(+), 1 deletion(-) > create mode 100644 drivers/dma-buf/dma-fence-chain.c > create mode 100644 include/linux/dma-fence-chain.h > > diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile > index 0913a6ccab5a..1f006e083eb9 100644 > --- a/drivers/dma-buf/Makefile > +++ b/drivers/dma-buf/Makefile > @@ -1,4 +1,5 @@ > -obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o > +obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ > + reservation.o seqno-fence.o > obj-$(CONFIG_SYNC_FILE) += sync_file.o > obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o > obj-$(CONFIG_UDMABUF) += udmabuf.o > diff --git a/drivers/dma-buf/dma-fence-chain.c > b/drivers/dma-buf/dma-fence-chain.c > new file mode 100644 > index ..1ec234d66081 > --- /dev/null > +++ b/drivers/dma-buf/dma-fence-chain.c > @@ -0,0 +1,234 @@ > +/* > + * fence-chain: chain fences together in a timeline > + * > + * Copyright (C) 2018 Advanced Micro Devices, Inc. > + * Authors: > + * Christian König > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 as published > by > + * the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, but > WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + */ > + > +#include > + > +static bool dma_fence_chain_enable_signaling(struct dma_fence *fence); > + > +/** > + * dma_fence_chain_get_prev - use RCU to get a reference to the previous > fence > + * @chain: chain node to get the previous node from > + * > + * Use dma_fence_get_rcu_safe to get a reference to the previous fence of the > + * chain node. > + */ > +static struct dma_fence *dma_fence_chain_get_prev(struct dma_fence_chain > *chain) > +{ > + struct dma_fence *prev; > + > + rcu_read_lock(); > + prev = dma_fence_get_rcu_safe(>prev); > + rcu_read_unlock(); > + return prev; > +} > + > +/** > + * dma_fence_chain_walk - chain walking function > + * @fence: current chain node > + * > + * Walk the chain to the next node. Returns the next fence or NULL if we are > at > + * the end of the chain. Garbage collects chain nodes which are already > + * signaled. > + */ > +struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence) > +{ > + struct dma_fence_chain *chain, *prev_chain; > + struct dma_fence *prev, *replacement, *tmp; > + > + chain = to_dma_fence_chain(fence); > + if (!chain) { > + dma_fence_put(fence); > + return NULL; > + } > + > + while ((prev = dma_fence_chain_get_prev(chain))) { > + > + prev_chain = to_dma_fence_chain(prev); > + if (prev_chain) { > + if (!dma_fence_is_signaled(prev_chain->fence)) > + break; > + > + replacement = dma_fence_chain_get_prev(prev_chain); > + } else { > + if (!dma_fence_is_signaled(prev)) > + break; > + > + replacement = NULL; > + } > + > + tmp = cmpxchg(>prev, prev, replacement); > + if (tmp == prev) > + dma_fence_put(tmp); > + else > + dma_fence_put(replacement); > + dma_fence_put(prev); > + } > + > + dma_fence_put(fence); > + return prev; > +} > +EXPORT_SYMBOL(dma_fence_chain_walk); > + > +/** > + * dma_fence_chain_find_seqno - find fence chain node by seqno > + * @pfence: pointer to the chain node where to start > + * @seqno: the sequence number to search for > + * > + * Advance the fence pointer to the chain node which will signal this > sequence > + * number. If no sequence number is provided then this is a no-op. > + * > + * Returns EINVAL if the fence is not a chain node or the sequence number has > + * not yet advanced far enough. > + */ > +int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno) > +{ > + struct dma_fence_chain *chain; > + > + if (!seqno) > +
Re: [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
在 2018/12/4 19:59, Christian König 写道: > For a lot of use cases we need 64bit sequence numbers. Currently drivers > overload the dma_fence structure to store the additional bits. > > Stop doing that and make the sequence number in the dma_fence always > 64bit. > > For compatibility with hardware which can do only 32bit sequences the > comparisons in __dma_fence_is_later only takes the lower 32bits as significant > when the upper 32bits are all zero. > > v2: change the logic in __dma_fence_is_later > > Signed-off-by: Christian König Reviewed-by: Chunming Zhou > --- > drivers/dma-buf/dma-fence.c| 2 +- > drivers/dma-buf/sw_sync.c | 2 +- > drivers/dma-buf/sync_file.c| 4 ++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | 2 +- > drivers/gpu/drm/i915/i915_sw_fence.c | 2 +- > drivers/gpu/drm/i915/intel_engine_cs.c | 2 +- > drivers/gpu/drm/vgem/vgem_fence.c | 4 ++-- > include/linux/dma-fence.h | 22 +++--- > 8 files changed, 24 insertions(+), 16 deletions(-) > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > index 136ec04d683f..3aa8733f832a 100644 > --- a/drivers/dma-buf/dma-fence.c > +++ b/drivers/dma-buf/dma-fence.c > @@ -649,7 +649,7 @@ EXPORT_SYMBOL(dma_fence_wait_any_timeout); >*/ > void > dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops, > -spinlock_t *lock, u64 context, unsigned seqno) > +spinlock_t *lock, u64 context, u64 seqno) > { > BUG_ON(!lock); > BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name); > diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c > index 53c1d6d36a64..32dcf7b4c935 100644 > --- a/drivers/dma-buf/sw_sync.c > +++ b/drivers/dma-buf/sw_sync.c > @@ -172,7 +172,7 @@ static bool timeline_fence_enable_signaling(struct > dma_fence *fence) > static void timeline_fence_value_str(struct dma_fence *fence, > char *str, int size) > { > - snprintf(str, size, "%d", fence->seqno); > + snprintf(str, size, "%lld", fence->seqno); > } > > static void timeline_fence_timeline_value_str(struct dma_fence *fence, > diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c > index 35dd06479867..4f6305ca52c8 100644 > --- a/drivers/dma-buf/sync_file.c > +++ b/drivers/dma-buf/sync_file.c > @@ -144,7 +144,7 @@ char *sync_file_get_name(struct sync_file *sync_file, > char *buf, int len) > } else { > struct dma_fence *fence = sync_file->fence; > > - snprintf(buf, len, "%s-%s%llu-%d", > + snprintf(buf, len, "%s-%s%llu-%lld", >fence->ops->get_driver_name(fence), >fence->ops->get_timeline_name(fence), >fence->context, > @@ -258,7 +258,7 @@ static struct sync_file *sync_file_merge(const char > *name, struct sync_file *a, > > i_b++; > } else { > - if (pt_a->seqno - pt_b->seqno <= INT_MAX) > + if (__dma_fence_is_later(pt_a->seqno, pt_b->seqno)) > add_fence(fences, , pt_a); > else > add_fence(fences, , pt_b); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c > index 12f2bf97611f..bfaf5c6323be 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c > @@ -388,7 +388,7 @@ void amdgpu_sa_bo_dump_debug_info(struct > amdgpu_sa_manager *sa_manager, > soffset, eoffset, eoffset - soffset); > > if (i->fence) > - seq_printf(m, " protected by 0x%08x on context %llu", > + seq_printf(m, " protected by 0x%016llx on context %llu", > i->fence->seqno, i->fence->context); > > seq_printf(m, "\n"); > diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c > b/drivers/gpu/drm/i915/i915_sw_fence.c > index 6dbeed079ae5..11bcdabd5177 100644 > --- a/drivers/gpu/drm/i915/i915_sw_fence.c > +++ b/drivers/gpu/drm/i915/i915_sw_fence.c > @@ -393,7 +393,7 @@ static void timer_i915_sw_fence_wake(struct timer_list *t) > if (!fence) > return; > > - pr_notice("Asynchronous wait on fence %s:%s:%x timed out (hint:%pS)\n", > + pr_notice("Asynchronous wait on fence %s:%s:%llx timed out > (hint:%pS)\n", > cb->dma->ops->get_driver_name(cb->dma), > cb->dma->ops->get_timeline_name(cb->dma), > cb->dma->seqno, > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c > b/drivers/gpu/drm/i915/intel_engine_cs.c > index 217ed3ee1cab..f28a66c67d34 100644 > --- a/drivers/gpu/drm/i915/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/intel_engine_cs.c > @@ -1236,7 +1236,7 @@ static void print_request(struct drm_printer *m, >
[PATCH 06/10] drm/syncobj: add support for timeline point wait v7
From: Chunming Zhou points array is one-to-one match with syncobjs array. v2: add seperate ioctl for timeline point wait, otherwise break uapi. v3: userspace can specify two kinds waits:: a. Wait for time point to be completed. b. and wait for time point to become available v4: rebase v5: add comment for xxx_WAIT_AVAILABLE v6: rebase and rework on new container v7: drop _WAIT_COMPLETED, it is the default anyway Signed-off-by: Chunming Zhou Signed-off-by: Christian König Cc: Daniel Rakos Cc: Jason Ekstrand Cc: Bas Nieuwenhuizen Cc: Dave Airlie Cc: Chris Wilson --- drivers/gpu/drm/drm_internal.h | 2 + drivers/gpu/drm/drm_ioctl.c| 2 + drivers/gpu/drm/drm_syncobj.c | 151 + include/uapi/drm/drm.h | 15 4 files changed, 140 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 0c4eb4a9ab31..566d44e3c782 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -183,6 +183,8 @@ int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); +int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private); int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 94bd872d56c4..a9a17ed35cc4 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -675,6 +675,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl, + DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 64fcfea1c39f..86063475f46c 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -61,6 +61,7 @@ struct syncobj_wait_entry { struct task_struct *task; struct dma_fence *fence; struct dma_fence_cb fence_cb; + u64point; }; static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, @@ -95,6 +96,9 @@ EXPORT_SYMBOL(drm_syncobj_find); static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj, struct syncobj_wait_entry *wait) { + struct dma_fence *fence; + int ret; + if (wait->fence) return; @@ -103,11 +107,14 @@ static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj, * have the lock, try one more time just to be sure we don't add a * callback when a fence has already been set. */ - if (syncobj->fence) - wait->fence = dma_fence_get( - rcu_dereference_protected(syncobj->fence, 1)); - else + fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1)); + ret = dma_fence_chain_find_seqno(, wait->point); + if (ret) { + dma_fence_put(fence); list_add_tail(>node, >cb_list); + } else { + wait->fence = fence; + } spin_unlock(>lock); } @@ -148,10 +155,8 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj, dma_fence_chain_init(chain, prev, fence, point); rcu_assign_pointer(syncobj->fence, >base); - list_for_each_entry_safe(cur, tmp, >cb_list, node) { - list_del_init(>node); + list_for_each_entry_safe(cur, tmp, >cb_list, node) syncobj_wait_syncobj_func(syncobj, cur); - } spin_unlock(>lock); /* Walk the chain once to trigger garbage collection */ @@ -182,10 +187,8 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, rcu_assign_pointer(syncobj->fence, fence); if (fence != old_fence) { - list_for_each_entry_safe(cur, tmp, >cb_list, node) { - list_del_init(>node); + list_for_each_entry_safe(cur, tmp, >cb_list, node) syncobj_wait_syncobj_func(syncobj, cur); - } } spin_unlock(>lock); @@ -642,13 +645,25 @@ static void syncobj_wait_fence_func(struct dma_fence *fence, static void syncobj_wait_syncobj_func(struct drm_syncobj
[PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2
Use the dma_fence_chain object to create a timeline of fence objects instead of just replacing the existing fence. v2: rebase and cleanup Signed-off-by: Christian König --- drivers/gpu/drm/drm_syncobj.c | 37 + include/drm/drm_syncobj.h | 5 + 2 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index e19525af0cce..64fcfea1c39f 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -122,6 +122,43 @@ static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj, spin_unlock(>lock); } +/** + * drm_syncobj_add_point - add new timeline point to the syncobj + * @syncobj: sync object to add timeline point do + * @chain: chain node to use to add the point + * @fence: fence to encapsulate in the chain node + * @point: sequence number to use for the point + * + * Add the chain node as new timeline point to the syncobj. + */ +void drm_syncobj_add_point(struct drm_syncobj *syncobj, + struct dma_fence_chain *chain, + struct dma_fence *fence, + uint64_t point) +{ + struct syncobj_wait_entry *cur, *tmp; + struct dma_fence *prev; + + dma_fence_get(fence); + + spin_lock(>lock); + + prev = rcu_dereference_protected(syncobj->fence, +lockdep_is_held(>lock)); + dma_fence_chain_init(chain, prev, fence, point); + rcu_assign_pointer(syncobj->fence, >base); + + list_for_each_entry_safe(cur, tmp, >cb_list, node) { + list_del_init(>node); + syncobj_wait_syncobj_func(syncobj, cur); + } + spin_unlock(>lock); + + /* Walk the chain once to trigger garbage collection */ + dma_fence_chain_for_each(fence); +} +EXPORT_SYMBOL(drm_syncobj_add_point); + /** * drm_syncobj_replace_fence - replace fence in a sync object. * @syncobj: Sync object to replace fence in diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 7c6ed845c70d..8acb4ae4f311 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -27,6 +27,7 @@ #define __DRM_SYNCOBJ_H__ #include "linux/dma-fence.h" +#include "linux/dma-fence-chain.h" /** * struct drm_syncobj - sync object. @@ -110,6 +111,10 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj) struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, u32 handle); +void drm_syncobj_add_point(struct drm_syncobj *syncobj, + struct dma_fence_chain *chain, + struct dma_fence *fence, + uint64_t point); void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, struct dma_fence *fence); int drm_syncobj_find_fence(struct drm_file *file_private, -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu
From: Chunming Zhou Signed-off-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 90f474f98b6e..316bfc1a6a75 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -71,9 +71,10 @@ * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk). * - 3.26.0 - GFX9: Process AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE. * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation. + * - 3.28.0 - Add syncobj timeline support to AMDGPU_CS. */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 27 +#define KMS_DRIVER_MINOR 28 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
Implement finding the right timeline point in drm_syncobj_find_fence. v2: return -EINVAL when the point is not submitted yet. v3: fix reference counting bug, add flags handling as well Signed-off-by: Christian König --- drivers/gpu/drm/drm_syncobj.c | 43 --- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index ee44cf2a8a12..fdbec8cedc3d 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private, struct dma_fence **fence) { struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); - int ret = 0; + struct syncobj_wait_entry wait; + int ret; if (!syncobj) return -ENOENT; *fence = drm_syncobj_fence_get(syncobj); - if (!*fence) { + drm_syncobj_put(syncobj); + + if (*fence) { + ret = dma_fence_chain_find_seqno(fence, point); + if (!ret) + return 0; + dma_fence_put(*fence); + } else { ret = -EINVAL; } - drm_syncobj_put(syncobj); + + if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) + return ret; + + memset(, 0, sizeof(wait)); + wait.task = current; + wait.point = point; + drm_syncobj_fence_add_wait(syncobj, ); + + do { + set_current_state(TASK_INTERRUPTIBLE); + if (wait.fence) { + ret = 0; + break; + } + + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + schedule(); + } while (1); + + __set_current_state(TASK_RUNNING); + *fence = wait.fence; + + if (wait.node.next) + drm_syncobj_remove_wait(syncobj, ); + return ret; } EXPORT_SYMBOL(drm_syncobj_find_fence); -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 09/10] drm/amdgpu: add timeline support in amdgpu CS v2
From: Chunming Zhou syncobj wait/signal operation is appending in command submission. v2: separate to two kinds in/out_deps functions Signed-off-by: Chunming Zhou Cc: Daniel Rakos Cc: Jason Ekstrand Cc: Bas Nieuwenhuizen Cc: Dave Airlie Cc: Christian König Cc: Chris Wilson --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 10 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 147 +++-- include/uapi/drm/amdgpu_drm.h | 8 ++ 3 files changed, 140 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index aa26a144c7f5..c1cd1c8ee6ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -429,6 +429,12 @@ struct amdgpu_cs_chunk { void*kdata; }; +struct amdgpu_cs_post_dep { + struct drm_syncobj *syncobj; + struct dma_fence_chain *chain; + u64 point; +}; + struct amdgpu_cs_parser { struct amdgpu_device*adev; struct drm_file *filp; @@ -458,8 +464,8 @@ struct amdgpu_cs_parser { /* user fence */ struct amdgpu_bo_list_entry uf_entry; - unsigned num_post_dep_syncobjs; - struct drm_syncobj **post_dep_syncobjs; + unsignednum_post_deps; + struct amdgpu_cs_post_dep *post_deps; }; static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 149b3065119b..c61fb0e6881b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -214,6 +214,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs case AMDGPU_CHUNK_ID_DEPENDENCIES: case AMDGPU_CHUNK_ID_SYNCOBJ_IN: case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: + case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT: + case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL: break; default: @@ -803,9 +805,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, ttm_eu_backoff_reservation(>ticket, >validated); - for (i = 0; i < parser->num_post_dep_syncobjs; i++) - drm_syncobj_put(parser->post_dep_syncobjs[i]); - kfree(parser->post_dep_syncobjs); + for (i = 0; i < parser->num_post_deps; i++) { + drm_syncobj_put(parser->post_deps[i].syncobj); + kfree(parser->post_deps[i].chain); + } + kfree(parser->post_deps); dma_fence_put(parser->fence); @@ -1107,13 +,18 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, } static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, -uint32_t handle) +uint32_t handle, u64 point, +u64 flags) { - int r; struct dma_fence *fence; - r = drm_syncobj_find_fence(p->filp, handle, 0, 0, ); - if (r) + int r; + + r = drm_syncobj_find_fence(p->filp, handle, point, flags, ); + if (r) { + DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n", + handle, point, r); return r; + } r = amdgpu_sync_fence(p->adev, >job->sync, fence, true); dma_fence_put(fence); @@ -1124,46 +1133,115 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p, struct amdgpu_cs_chunk *chunk) { + struct drm_amdgpu_cs_chunk_sem *deps; unsigned num_deps; int i, r; - struct drm_amdgpu_cs_chunk_sem *deps; deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; num_deps = chunk->length_dw * 4 / sizeof(struct drm_amdgpu_cs_chunk_sem); + for (i = 0; i < num_deps; ++i) { + r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle, + 0, 0); + if (r) + return r; + } + + return 0; +} + +static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser *p, +struct amdgpu_cs_chunk *chunk) +{ + struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps; + unsigned num_deps; + int i, r; + + syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata; + num_deps = chunk->length_dw * 4 / + sizeof(struct drm_amdgpu_cs_chunk_syncobj); for (i = 0; i < num_deps; ++i) { - r = amdgpu_syncobj_lookup_and_add_to_sync(p,
[PATCH 07/10] drm/syncobj: add timeline payload query ioctl v4
From: Chunming Zhou user mode can query timeline payload. v2: check return value of copy_to_user v3: handle querying entry by entry v4: rebase on new chain container, simplify interface Signed-off-by: Chunming Zhou Cc: Daniel Rakos Cc: Jason Ekstrand Cc: Bas Nieuwenhuizen Cc: Dave Airlie Cc: Christian König Cc: Chris Wilson --- drivers/gpu/drm/drm_internal.h | 2 ++ drivers/gpu/drm/drm_ioctl.c| 2 ++ drivers/gpu/drm/drm_syncobj.c | 40 include/uapi/drm/drm.h | 11 +++ 4 files changed, 55 insertions(+) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 566d44e3c782..9c4826411a3c 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -189,6 +189,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); +int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private); /* drm_framebuffer.c */ void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index a9a17ed35cc4..7578ef6dc1d1 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -681,6 +681,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl, + DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 86063475f46c..ee44cf2a8a12 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1057,3 +1057,43 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, return ret; } + +int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private) +{ + struct drm_syncobj_timeline_query *args = data; + struct drm_syncobj **syncobjs; + uint64_t __user *points = u64_to_user_ptr(args->points); + uint32_t i; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + return -ENODEV; + + if (args->count_handles == 0) + return -EINVAL; + + ret = drm_syncobj_array_find(file_private, +u64_to_user_ptr(args->handles), +args->count_handles, +); + if (ret < 0) + return ret; + + for (i = 0; i < args->count_handles; i++) { + struct dma_fence_chain *chain; + struct dma_fence *fence; + uint64_t point; + + fence = drm_syncobj_fence_get(syncobjs[i]); + chain = to_dma_fence_chain(fence); + point = chain ? fence->seqno : 0; + ret = copy_to_user([i], , sizeof(uint64_t)); + ret = ret ? -EFAULT : 0; + if (ret) + break; + } + drm_syncobj_array_free(syncobjs, args->count_handles); + + return ret; +} diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 627032df23e6..14ca02a3d5f2 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -768,6 +768,15 @@ struct drm_syncobj_array { __u32 pad; }; +struct drm_syncobj_timeline_query { + __u64 handles; + /* points are timeline syncobjs payloads returned by query ioctl */ + __u64 points; + __u32 count_handles; + __u32 pad; +}; + + /* Query current scanout sequence number */ struct drm_crtc_get_sequence { __u32 crtc_id; /* requested crtc_id */ @@ -925,6 +934,8 @@ extern "C" { #define DRM_IOCTL_MODE_REVOKE_LEASEDRM_IOWR(0xC9, struct drm_mode_revoke_lease) #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAITDRM_IOWR(0xCA, struct drm_syncobj_timeline_wait) +#define DRM_IOCTL_SYNCOBJ_QUERYDRM_IOWR(0xCB, struct drm_syncobj_timeline_query) + /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup
This completes "drm/syncobj: Drop add/remove_callback from driver interface" and cleans up the implementation a bit. Signed-off-by: Christian König --- drivers/gpu/drm/drm_syncobj.c | 91 ++- include/drm/drm_syncobj.h | 21 -- 2 files changed, 30 insertions(+), 82 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index db30a0e89db8..e19525af0cce 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -56,6 +56,16 @@ #include "drm_internal.h" #include +struct syncobj_wait_entry { + struct list_head node; + struct task_struct *task; + struct dma_fence *fence; + struct dma_fence_cb fence_cb; +}; + +static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, + struct syncobj_wait_entry *wait); + /** * drm_syncobj_find - lookup and reference a sync object. * @file_private: drm file private pointer @@ -82,58 +92,33 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, } EXPORT_SYMBOL(drm_syncobj_find); -static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj, - struct drm_syncobj_cb *cb, - drm_syncobj_func_t func) +static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj, + struct syncobj_wait_entry *wait) { - cb->func = func; - list_add_tail(>node, >cb_list); -} - -static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj, -struct dma_fence **fence, -struct drm_syncobj_cb *cb, -drm_syncobj_func_t func) -{ - int ret; - - *fence = drm_syncobj_fence_get(syncobj); - if (*fence) - return 1; + if (wait->fence) + return; spin_lock(>lock); /* We've already tried once to get a fence and failed. Now that we * have the lock, try one more time just to be sure we don't add a * callback when a fence has already been set. */ - if (syncobj->fence) { - *fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, - lockdep_is_held(>lock))); - ret = 1; - } else { - *fence = NULL; - drm_syncobj_add_callback_locked(syncobj, cb, func); - ret = 0; - } + if (syncobj->fence) + wait->fence = dma_fence_get( + rcu_dereference_protected(syncobj->fence, 1)); + else + list_add_tail(>node, >cb_list); spin_unlock(>lock); - - return ret; } -void drm_syncobj_add_callback(struct drm_syncobj *syncobj, - struct drm_syncobj_cb *cb, - drm_syncobj_func_t func) +static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj, + struct syncobj_wait_entry *wait) { - spin_lock(>lock); - drm_syncobj_add_callback_locked(syncobj, cb, func); - spin_unlock(>lock); -} + if (!wait->node.next) + return; -void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, -struct drm_syncobj_cb *cb) -{ spin_lock(>lock); - list_del_init(>node); + list_del_init(>node); spin_unlock(>lock); } @@ -148,7 +133,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, struct dma_fence *fence) { struct dma_fence *old_fence; - struct drm_syncobj_cb *cur, *tmp; + struct syncobj_wait_entry *cur, *tmp; if (fence) dma_fence_get(fence); @@ -162,7 +147,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, if (fence != old_fence) { list_for_each_entry_safe(cur, tmp, >cb_list, node) { list_del_init(>node); - cur->func(syncobj, cur); + syncobj_wait_syncobj_func(syncobj, cur); } } @@ -608,13 +593,6 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, >handle); } -struct syncobj_wait_entry { - struct task_struct *task; - struct dma_fence *fence; - struct dma_fence_cb fence_cb; - struct drm_syncobj_cb syncobj_cb; -}; - static void syncobj_wait_fence_func(struct dma_fence *fence, struct dma_fence_cb *cb) { @@ -625,11 +603,8 @@ static void syncobj_wait_fence_func(struct dma_fence *fence, } static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, - struct
[PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2"
This reverts commit 9a09a42369a4a37a959c051d8e1a1f948c1529a4. The whole interface isn't thought through. Since this function can't fail we actually can't allocate an object to store the sync point. Sorry, I should have taken the lead on this from the very beginning and reviewed it more thoughtfully. Going to propose a new interface as a follow up change. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/drm_syncobj.c | 14 ++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/v3d/v3d_gem.c | 3 +-- drivers/gpu/drm/vc4/vc4_gem.c | 2 +- include/drm/drm_syncobj.h | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index c0740a924769..149b3065119b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1200,7 +1200,7 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) int i; for (i = 0; i < p->num_post_dep_syncobjs; ++i) - drm_syncobj_replace_fence(p->post_dep_syncobjs[i], 0, p->fence); + drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence); } static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 5c5ba1f14307..db30a0e89db8 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -140,13 +140,11 @@ void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, /** * drm_syncobj_replace_fence - replace fence in a sync object. * @syncobj: Sync object to replace fence in - * @point: timeline point * @fence: fence to install in sync file. * - * This replaces the fence on a sync object, or a timeline point fence. + * This replaces the fence on a sync object. */ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, - u64 point, struct dma_fence *fence) { struct dma_fence *old_fence; @@ -184,7 +182,7 @@ static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) { struct dma_fence *fence = dma_fence_get_stub(); - drm_syncobj_replace_fence(syncobj, 0, fence); + drm_syncobj_replace_fence(syncobj, fence); dma_fence_put(fence); } @@ -233,7 +231,7 @@ void drm_syncobj_free(struct kref *kref) struct drm_syncobj *syncobj = container_of(kref, struct drm_syncobj, refcount); - drm_syncobj_replace_fence(syncobj, 0, NULL); + drm_syncobj_replace_fence(syncobj, NULL); kfree(syncobj); } EXPORT_SYMBOL(drm_syncobj_free); @@ -267,7 +265,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, drm_syncobj_assign_null_handle(syncobj); if (fence) - drm_syncobj_replace_fence(syncobj, 0, fence); + drm_syncobj_replace_fence(syncobj, fence); *out_syncobj = syncobj; return 0; @@ -452,7 +450,7 @@ static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, return -ENOENT; } - drm_syncobj_replace_fence(syncobj, 0, fence); + drm_syncobj_replace_fence(syncobj, fence); dma_fence_put(fence); drm_syncobj_put(syncobj); return 0; @@ -923,7 +921,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, return ret; for (i = 0; i < args->count_handles; i++) - drm_syncobj_replace_fence(syncobjs[i], 0, NULL); + drm_syncobj_replace_fence(syncobjs[i], NULL); drm_syncobj_array_free(syncobjs, args->count_handles); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 1aaccbe7e1de..786d719e652d 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -2186,7 +2186,7 @@ signal_fence_array(struct i915_execbuffer *eb, if (!(flags & I915_EXEC_FENCE_SIGNAL)) continue; - drm_syncobj_replace_fence(syncobj, 0, fence); + drm_syncobj_replace_fence(syncobj, fence); } } diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index b88c96911453..655be1a865fa 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -588,8 +588,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, /* Update the return sync object for the */ sync_out = drm_syncobj_find(file_priv, args->out_sync); if (sync_out) { - drm_syncobj_replace_fence(sync_out, 0, - exec->render_done_fence); +
[PATCH 02/10] dma-buf: add new dma_fence_chain container v3
Lockless container implementation similar to a dma_fence_array, but with only two elements per node and automatic garbage collection. v2: properly document dma_fence_chain_for_each, add dma_fence_chain_find_seqno, drop prev reference during garbage collection if it's not a chain fence. v3: use head and iterator for dma_fence_chain_for_each Signed-off-by: Christian König --- drivers/dma-buf/Makefile | 3 +- drivers/dma-buf/dma-fence-chain.c | 234 ++ include/linux/dma-fence-chain.h | 81 + 3 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 drivers/dma-buf/dma-fence-chain.c create mode 100644 include/linux/dma-fence-chain.h diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 0913a6ccab5a..1f006e083eb9 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,4 +1,5 @@ -obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o +obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ +reservation.o seqno-fence.o obj-$(CONFIG_SYNC_FILE)+= sync_file.o obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o obj-$(CONFIG_UDMABUF) += udmabuf.o diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c new file mode 100644 index ..1ec234d66081 --- /dev/null +++ b/drivers/dma-buf/dma-fence-chain.c @@ -0,0 +1,234 @@ +/* + * fence-chain: chain fences together in a timeline + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * Authors: + * Christian König + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +static bool dma_fence_chain_enable_signaling(struct dma_fence *fence); + +/** + * dma_fence_chain_get_prev - use RCU to get a reference to the previous fence + * @chain: chain node to get the previous node from + * + * Use dma_fence_get_rcu_safe to get a reference to the previous fence of the + * chain node. + */ +static struct dma_fence *dma_fence_chain_get_prev(struct dma_fence_chain *chain) +{ + struct dma_fence *prev; + + rcu_read_lock(); + prev = dma_fence_get_rcu_safe(>prev); + rcu_read_unlock(); + return prev; +} + +/** + * dma_fence_chain_walk - chain walking function + * @fence: current chain node + * + * Walk the chain to the next node. Returns the next fence or NULL if we are at + * the end of the chain. Garbage collects chain nodes which are already + * signaled. + */ +struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence) +{ + struct dma_fence_chain *chain, *prev_chain; + struct dma_fence *prev, *replacement, *tmp; + + chain = to_dma_fence_chain(fence); + if (!chain) { + dma_fence_put(fence); + return NULL; + } + + while ((prev = dma_fence_chain_get_prev(chain))) { + + prev_chain = to_dma_fence_chain(prev); + if (prev_chain) { + if (!dma_fence_is_signaled(prev_chain->fence)) + break; + + replacement = dma_fence_chain_get_prev(prev_chain); + } else { + if (!dma_fence_is_signaled(prev)) + break; + + replacement = NULL; + } + + tmp = cmpxchg(>prev, prev, replacement); + if (tmp == prev) + dma_fence_put(tmp); + else + dma_fence_put(replacement); + dma_fence_put(prev); + } + + dma_fence_put(fence); + return prev; +} +EXPORT_SYMBOL(dma_fence_chain_walk); + +/** + * dma_fence_chain_find_seqno - find fence chain node by seqno + * @pfence: pointer to the chain node where to start + * @seqno: the sequence number to search for + * + * Advance the fence pointer to the chain node which will signal this sequence + * number. If no sequence number is provided then this is a no-op. + * + * Returns EINVAL if the fence is not a chain node or the sequence number has + * not yet advanced far enough. + */ +int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno) +{ + struct dma_fence_chain *chain; + + if (!seqno) + return 0; + + chain = to_dma_fence_chain(*pfence); + if (!chain || chain->base.seqno < seqno) + return -EINVAL; + + dma_fence_chain_for_each(*pfence, >base) { + if ((*pfence)->context != chain->base.context || +
[PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
For a lot of use cases we need 64bit sequence numbers. Currently drivers overload the dma_fence structure to store the additional bits. Stop doing that and make the sequence number in the dma_fence always 64bit. For compatibility with hardware which can do only 32bit sequences the comparisons in __dma_fence_is_later only takes the lower 32bits as significant when the upper 32bits are all zero. v2: change the logic in __dma_fence_is_later Signed-off-by: Christian König --- drivers/dma-buf/dma-fence.c| 2 +- drivers/dma-buf/sw_sync.c | 2 +- drivers/dma-buf/sync_file.c| 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | 2 +- drivers/gpu/drm/i915/i915_sw_fence.c | 2 +- drivers/gpu/drm/i915/intel_engine_cs.c | 2 +- drivers/gpu/drm/vgem/vgem_fence.c | 4 ++-- include/linux/dma-fence.h | 22 +++--- 8 files changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 136ec04d683f..3aa8733f832a 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -649,7 +649,7 @@ EXPORT_SYMBOL(dma_fence_wait_any_timeout); */ void dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops, - spinlock_t *lock, u64 context, unsigned seqno) + spinlock_t *lock, u64 context, u64 seqno) { BUG_ON(!lock); BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name); diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index 53c1d6d36a64..32dcf7b4c935 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -172,7 +172,7 @@ static bool timeline_fence_enable_signaling(struct dma_fence *fence) static void timeline_fence_value_str(struct dma_fence *fence, char *str, int size) { - snprintf(str, size, "%d", fence->seqno); + snprintf(str, size, "%lld", fence->seqno); } static void timeline_fence_timeline_value_str(struct dma_fence *fence, diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 35dd06479867..4f6305ca52c8 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -144,7 +144,7 @@ char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len) } else { struct dma_fence *fence = sync_file->fence; - snprintf(buf, len, "%s-%s%llu-%d", + snprintf(buf, len, "%s-%s%llu-%lld", fence->ops->get_driver_name(fence), fence->ops->get_timeline_name(fence), fence->context, @@ -258,7 +258,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, i_b++; } else { - if (pt_a->seqno - pt_b->seqno <= INT_MAX) + if (__dma_fence_is_later(pt_a->seqno, pt_b->seqno)) add_fence(fences, , pt_a); else add_fence(fences, , pt_b); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 12f2bf97611f..bfaf5c6323be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c @@ -388,7 +388,7 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager, soffset, eoffset, eoffset - soffset); if (i->fence) - seq_printf(m, " protected by 0x%08x on context %llu", + seq_printf(m, " protected by 0x%016llx on context %llu", i->fence->seqno, i->fence->context); seq_printf(m, "\n"); diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 6dbeed079ae5..11bcdabd5177 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -393,7 +393,7 @@ static void timer_i915_sw_fence_wake(struct timer_list *t) if (!fence) return; - pr_notice("Asynchronous wait on fence %s:%s:%x timed out (hint:%pS)\n", + pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%pS)\n", cb->dma->ops->get_driver_name(cb->dma), cb->dma->ops->get_timeline_name(cb->dma), cb->dma->seqno, diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 217ed3ee1cab..f28a66c67d34 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1236,7 +1236,7 @@ static void print_request(struct drm_printer *m, x = print_sched_attr(rq->i915, >sched.attr, buf, x, sizeof(buf)); - drm_printf(m, "%s%x%s [%llx:%x]%s @ %dms: %s\n", + drm_printf(m, "%s%x%s [%llx:%llx]%s @ %dms: %s\n", prefix,
Re: [PATCH v3 1/3] drm/connector: Add generic underscan properties
On Mon, Dec 03, 2018 at 07:50:53AM -0800, Eric Anholt wrote: > Boris Brezillon writes: > > > On Mon, 3 Dec 2018 16:40:11 +0200 > > Ville Syrjälä wrote: > > > >> On Thu, Nov 22, 2018 at 12:23:29PM +0100, Boris Brezillon wrote: > >> > @@ -924,6 +978,29 @@ struct drm_connector { > >> > */ > >> > struct drm_property_blob *path_blob_ptr; > >> > > >> > +/** > >> > + * @underscan_mode_property: Optional connector underscan mode. > >> > Used by > >> > + * the driver to scale the output image and compensate an > >> > overscan done > >> > + * on the display side. > >> > + */ > >> > +struct drm_property *underscan_mode_property; > >> > + > >> > +/** > >> > + * @underscan_hborder_property: Optional connector underscan > >> > horizontal > >> > + * border (expressed in pixels). Used by the driver to adjust > >> > the > >> > + * output image position and compensate an overscan done on the > >> > display > >> > + * side. > >> > + */ > >> > +struct drm_property *underscan_hborder_property; > >> > + > >> > +/** > >> > + * @underscan_hborder_property: Optional connector underscan > >> > vertical > >> > + * border (expressed in pixels). Used by the driver to adjust > >> > the > >> > + * output image position and compensate an overscan done on the > >> > display > >> > + * side. > >> > + */ > >> > +struct drm_property *underscan_vborder_property; > >> > >> I'm wondering why we're adding these new props when we already have the > >> (slightly more flexible) margin properties for TV out. We could just > >> reuse those AFAICS. > > > > I'm not against the idea, but I can't use > > drm_mode_create_tv_properties() directly, as most props created by this > > function are not applicable to an HDMI displays. Should I move the > > margins props out of the tv_connector_state and provide new helpers to > > create those props? > > TV margin props look good to me, FWIW. Yeah extracting the margin props from the tv props sounds like a good idea. If we go full ocd we'd also split out margin_connector_state or something like that (should be doable with some cocci), but not sure that's fully worth it. Tuning margins is largely an analog TV issue I think, so could just leave them there. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
答复: [PATCH] drm/amd/powerplay: improve OD code robustness
thanks Rex, done! I only push it to amd-staging-drm-next, is this enough? 发件人: Zhu, Rex 发送时间: 2018年12月4日 17:26:36 收件人: Yin, Tianci (Rico); Zhang, Jerry; Li, Pauline; Teng, Rui; Liang, Prike; Zhu, Changfeng; Wang, Kevin(Yang); amd-gfx@lists.freedesktop.org 主题: Re: [PATCH] drm/amd/powerplay: improve OD code robustness Please add Signed-off-by in the patch commit. Except that, Patch is Reviewed-by: Rex Zhu Best Regards Rex From: Yin, Tianci (Rico) Sent: Tuesday, December 4, 2018 5:01 PM To: Zhu, Rex; Zhang, Jerry; Li, Pauline; Teng, Rui; Liang, Prike; Zhu, Changfeng; Wang, Kevin(Yang); amd-gfx@lists.freedesktop.org Subject: 答复: [PATCH] drm/amd/powerplay: improve OD code robustness hi , a lower request system clock may cause gpu hang, add protection code to avoid this kind of issue, pls help to review. thanks! Rico From e043842962adb62cfa9b2abf9e291be6f36c99dd Mon Sep 17 00:00:00 2001 From: tianci yin Date: Tue, 4 Dec 2018 16:07:18 +0800 Subject: [PATCH] drm/amd/powerplay: improve OD code robustness add protection code to avoid lower frequency trigger over drive. Change-Id: If2f51d27e1cc19f67a24816e121b19fadc38cfa4 Reviewed-by: Rex Zhu Signed-off-by: Tianci Yin --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 12 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 12 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 5dcd21d..13d779e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -3589,8 +3589,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons } if (i >= sclk_table->count) { - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; - sclk_table->dpm_levels[i-1].value = sclk; + if (sclk > sclk_table->dpm_levels[i-1].value) { + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; + sclk_table->dpm_levels[i-1].value = sclk; + } } else { /* TODO: Check SCLK in DAL's minimum clocks * in case DeepSleep divider update is required. @@ -3607,8 +3609,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons } if (i >= mclk_table->count) { - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; - mclk_table->dpm_levels[i-1].value = mclk; + if (mclk > mclk_table->dpm_levels[i-1].value) { + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; + mclk_table->dpm_levels[i-1].value = mclk; + } } if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index e2bc6e0..79c8624 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -3266,8 +3266,10 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co } if (i >= sclk_table->count) { - data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; - sclk_table->dpm_levels[i-1].value = sclk; + if (sclk > sclk_table->dpm_levels[i-1].value) { + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; + sclk_table->dpm_levels[i-1].value = sclk; + } } for (i = 0; i < mclk_table->count; i++) { @@ -3276,8 +3278,10 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co } if (i >= mclk_table->count) { - data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; - mclk_table->dpm_levels[i-1].value = mclk; + if (mclk > mclk_table->dpm_levels[i-1].value) { + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; + mclk_table->dpm_levels[i-1].value = mclk; + } } if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amd/powerplay: improve OD code robustness
Please add Signed-off-by in the patch commit. Except that, Patch is Reviewed-by: Rex Zhu Best Regards Rex From: Yin, Tianci (Rico) Sent: Tuesday, December 4, 2018 5:01 PM To: Zhu, Rex; Zhang, Jerry; Li, Pauline; Teng, Rui; Liang, Prike; Zhu, Changfeng; Wang, Kevin(Yang); amd-gfx@lists.freedesktop.org Subject: 答复: [PATCH] drm/amd/powerplay: improve OD code robustness hi , a lower request system clock may cause gpu hang, add protection code to avoid this kind of issue, pls help to review. thanks! Rico ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/2] drm/amdgpu: use HMM mirror callback to replace mmu notifier v5
Am 03.12.18 um 21:19 schrieb Yang, Philip: Replace our MMU notifier with hmm_mirror_ops.sync_cpu_device_pagetables callback. Enable CONFIG_HMM and CONFIG_HMM_MIRROR as a dependency in DRM_AMDGPU_USERPTR Kconfig. It supports both KFD userptr and gfx userptr paths. The depdent HMM patchsets from Jérôme Glisse are all merged into 4.20.0 kernel now. Change-Id: Ie62c3c5e3c5b8521ab3b438d1eff2aa2a003835e Signed-off-by: Philip Yang --- drivers/gpu/drm/amd/amdgpu/Kconfig | 6 +- drivers/gpu/drm/amd/amdgpu/Makefile| 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 124 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | 2 +- 4 files changed, 57 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 9221e5489069..960a63355705 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -26,10 +26,10 @@ config DRM_AMDGPU_CIK config DRM_AMDGPU_USERPTR bool "Always enable userptr write support" depends on DRM_AMDGPU - select MMU_NOTIFIER + select HMM_MIRROR help - This option selects CONFIG_MMU_NOTIFIER if it isn't already - selected to enabled full userptr support. + This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it + isn't already selected to enabled full userptr support. config DRM_AMDGPU_GART_DEBUGFS bool "Allow GART access through debugfs" diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index f76bcb9c45e4..05ca6dc381e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -172,7 +172,7 @@ endif amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o -amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o +amdgpu-$(CONFIG_HMM) += amdgpu_mn.o This probably need to be CONFIG_HMM_MIRROR. include $(FULL_AMD_PATH)/powerplay/Makefile diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index e55508b39496..56595b3d90d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c @@ -45,7 +45,7 @@ #include #include -#include +#include #include #include #include @@ -58,7 +58,6 @@ * * @adev: amdgpu device pointer * @mm: process address space - * @mn: MMU notifier structure * @type: type of MMU notifier * @work: destruction work item * @node: hash table node to find structure by adev and mn @@ -66,6 +65,7 @@ * @objects: interval tree containing amdgpu_mn_nodes * @read_lock: mutex for recursive locking of @lock * @recursion: depth of recursion + * @mirror: HMM mirror function support * * Data for each amdgpu device and process address space. */ @@ -73,7 +73,6 @@ struct amdgpu_mn { /* constant after initialisation */ struct amdgpu_device*adev; struct mm_struct*mm; - struct mmu_notifier mn; enum amdgpu_mn_type type; /* only used on destruction */ @@ -87,6 +86,9 @@ struct amdgpu_mn { struct rb_root_cached objects; struct mutexread_lock; atomic_trecursion; + + /* HMM mirror */ + struct hmm_mirror mirror; }; /** @@ -103,7 +105,7 @@ struct amdgpu_mn_node { }; /** - * amdgpu_mn_destroy - destroy the MMU notifier + * amdgpu_mn_destroy - destroy the HMM mirror * * @work: previously sheduled work item * @@ -129,28 +131,26 @@ static void amdgpu_mn_destroy(struct work_struct *work) } up_write(>lock); mutex_unlock(>mn_lock); - mmu_notifier_unregister_no_release(>mn, amn->mm); + + hmm_mirror_unregister(>mirror); kfree(amn); } /** - * amdgpu_mn_release - callback to notify about mm destruction + * amdgpu_hmm_mirror_release - callback to notify about mm destruction * - * @mn: our notifier - * @mm: the mm this callback is about + * @mirror: the HMM mirror (mm) this callback is about * - * Shedule a work item to lazy destroy our notifier. + * Shedule a work item to lazy destroy HMM mirror. */ -static void amdgpu_mn_release(struct mmu_notifier *mn, - struct mm_struct *mm) +static void amdgpu_hmm_mirror_release(struct hmm_mirror *mirror) { - struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); + struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, mirror); INIT_WORK(>work, amdgpu_mn_destroy); schedule_work(>work); } - /** * amdgpu_mn_lock - take the write side lock for this notifier * @@ -237,21 +237,19 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node, /** * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change * - * @mn: our notifier - * @mm: the mm this callback
答复: [PATCH] drm/amd/powerplay: improve OD code robustness
hi , a lower request system clock may cause gpu hang, add protection code to avoid this kind of issue, pls help to review. thanks! Rico From e8f0a05ae172f6e2988148dc925b0bde9943be9a Mon Sep 17 00:00:00 2001 From: tianci yin Date: Tue, 4 Dec 2018 16:07:18 +0800 Subject: [PATCH] drm/amd/powerplay: improve OD code robustness add protection code to avoid lower frequency trigger over driver. Change-Id: If2f51d27e1cc19f67a24816e121b19fadc38cfa4 --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 12 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 12 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 5dcd21d..13d779e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -3589,8 +3589,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons } if (i >= sclk_table->count) { - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; - sclk_table->dpm_levels[i-1].value = sclk; + if (sclk > sclk_table->dpm_levels[i-1].value) { + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; + sclk_table->dpm_levels[i-1].value = sclk; + } } else { /* TODO: Check SCLK in DAL's minimum clocks * in case DeepSleep divider update is required. @@ -3607,8 +3609,10 @@ static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, cons } if (i >= mclk_table->count) { - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; - mclk_table->dpm_levels[i-1].value = mclk; + if (mclk > mclk_table->dpm_levels[i-1].value) { + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; + mclk_table->dpm_levels[i-1].value = mclk; + } } if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index e2bc6e0..79c8624 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -3266,8 +3266,10 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co } if (i >= sclk_table->count) { - data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; - sclk_table->dpm_levels[i-1].value = sclk; + if (sclk > sclk_table->dpm_levels[i-1].value) { + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; + sclk_table->dpm_levels[i-1].value = sclk; + } } for (i = 0; i < mclk_table->count; i++) { @@ -3276,8 +3278,10 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co } if (i >= mclk_table->count) { - data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; - mclk_table->dpm_levels[i-1].value = mclk; + if (mclk > mclk_table->dpm_levels[i-1].value) { + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; + mclk_table->dpm_levels[i-1].value = mclk; + } } if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH -next] drm/amdgpu: Fix return value check in amdgpu_allocate_static_csa()
Fix the return value check which testing the wrong variable in amdgpu_allocate_static_csa(). Fixes: 7946340fa389 ("drm/amdgpu: Move csa related code to separate file") Signed-off-by: Wei Yongjun --- drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c index 0c590dd..a5fbc6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c @@ -43,7 +43,7 @@ int amdgpu_allocate_static_csa(struct amdgpu_device *adev, struct amdgpu_bo **bo r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE, domain, bo, NULL, ); - if (!bo) + if (!r) return -ENOMEM; memset(ptr, 0, size); ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx