Re: [PATCH v2] crypto: ccp - Allocate TEE ring and cmd buffer using DMA APIs
On 12/30/2022 1:54 PM, Herbert Xu wrote: > On Fri, Dec 23, 2022 at 05:45:24PM +0530, Rijo Thomas wrote: >> >>> dma_alloc_coherent memory is just as contiguous as __get_free_pages, and >>> calling dma_alloc_coherent from a guest does not guarantee that the memory >>> is >>> contiguous in host memory either. The memory would look contiguous from the >>> device point of view thanks to the IOMMU though (in both cases). So this is >>> not >>> about being contiguous but other properties that you might rely on (dma mask >>> most likely, or coherent if you're not running this on x86?). >>> >>> Can you confirm why this fixes things and update the comment to reflect >>> that. >> >> I see what you are saying. >> >> We verified this in Xen Dom0 PV guest, where dma_alloc_coherent() returned a >> memory >> that is contiguous in machine address space, and the machine address was >> returned >> in the dma handle (buf->dma). > > So is this even relevant to the mainstream kernel or is this patch > only needed for Xen Dom0? > > Thanks, Herbert, This patch is no longer relevant to the mainstream kernel. Thanks, Rijo
Re: [PATCH v4 07/27] drm/amd: Convert SDMA to use `amdgpu_ucode_ip_version_decode`
On 1/4/2023 3:48 AM, Mario Limonciello wrote: Simplifies the code so that all SDMA versions will get the firmware name from `amdgpu_ucode_ip_version_decode`. Signed-off-by: Mario Limonciello --- v3->v4: * Move out of IP discovery and instead simplify early_init v2->v3: * Fix dGPU naming scheme --- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h | 4 +- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 47 +--- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 30 + drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 55 +--- drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 25 +-- 6 files changed, 13 insertions(+), 155 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index 9e85a078d918..83e8f0dae647 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -200,15 +200,18 @@ void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev, } int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, - char *fw_name, u32 instance, - bool duplicate) + u32 instance, bool duplicate) { struct amdgpu_firmware_info *info = NULL; const struct common_firmware_header *header = NULL; int err = 0, i; const struct sdma_firmware_header_v2_0 *sdma_hdr; uint16_t version_major; + char ucode_prefix[30]; + char fw_name[40]; + amdgpu_ucode_ip_version_decode(adev, SDMA0_HWIP, ucode_prefix, sizeof(ucode_prefix)); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s%s.bin", ucode_prefix, !instance ? "" : "1"); It is safer to keep the original logic with instance number as suffix rather than hardcoding to 1. Thanks, Lijo err = amdgpu_ucode_load(adev, >sdma.instance[instance].fw, fw_name); if (err) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h index 7d99205c2e01..2d16e6d36728 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h @@ -124,8 +124,8 @@ int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev, int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry); -int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, -char *fw_name, u32 instance, bool duplicate); +int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, u32 instance, + bool duplicate); void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev, bool duplicate); void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 4d780e4430e7..017ae298558e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -575,60 +575,17 @@ static void sdma_v4_0_setup_ulv(struct amdgpu_device *adev) // vega10 real chip need to use PSP to load firmware static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) { - const char *chip_name; - char fw_name[30]; int ret, i; - DRM_DEBUG("\n"); - - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 0, 0): - chip_name = "vega10"; - break; - case IP_VERSION(4, 0, 1): - chip_name = "vega12"; - break; - case IP_VERSION(4, 2, 0): - chip_name = "vega20"; - break; - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): - if (adev->apu_flags & AMD_APU_IS_RAVEN2) - chip_name = "raven2"; - else if (adev->apu_flags & AMD_APU_IS_PICASSO) - chip_name = "picasso"; - else - chip_name = "raven"; - break; - case IP_VERSION(4, 2, 2): - chip_name = "arcturus"; - break; - case IP_VERSION(4, 1, 2): - if (adev->apu_flags & AMD_APU_IS_RENOIR) - chip_name = "renoir"; - else - chip_name = "green_sardine"; - break; - case IP_VERSION(4, 4, 0): - chip_name = "aldebaran"; - break; - default: - BUG(); - } - for (i = 0; i < adev->sdma.num_instances; i++) { - if (i == 0) - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name); - else - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i); if (adev->ip_versions[SDMA0_HWIP][0]
Re: [PATCH v4 05/27] drm/amd: Add a new helper for loading/validating microcode
On 1/4/2023 3:48 AM, Mario Limonciello wrote: All microcode runs a basic validation after it's been loaded. Each IP block as part of init will run both. Introduce a wrapper for request_firmware and amdgpu_ucode_validate. This wrapper will also remap any error codes from request_firmware to -ENODEV. This is so that early_init will fail if firmware couldn't be loaded instead of the IP block being disabled. Signed-off-by: Mario Limonciello --- v3-v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 24 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 1 + 2 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index eafcddce58d3..8c4a7b09e344 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -1312,3 +1312,27 @@ void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, snprintf(ucode_prefix, len, "%s_%d_%d_%d", ip_name, maj, min, rev); } + +/* + * amdgpu_ucode_load - Load and validate amdgpu microcode + * + * @adev: amdgpu device + * @fw: pointer to load firmware to + * @fw_name: firmware to load + * + * This is a helper that will use request_firmware and amdgpu_ucode_validate + * to load and run basic validation on firmware. If the load fails, remap + * the error code to -ENODEV, so that early_init functions will fail to load. + */ +int amdgpu_ucode_load(struct amdgpu_device *adev, const struct firmware **fw, char *fw_name) 'load' also takes a different meaning of loading firmware to ASIC. Maybe keep it as 'get' and keep another corresponding common 'put' for release_firmware? Thanks, Lijo +{ + int err = request_firmware(fw, fw_name, adev->dev); + + if (err) + return -ENODEV; + err = amdgpu_ucode_validate(*fw); + if (err) + dev_dbg(adev->dev, "\"%s\" failed to validate\n", fw_name); + + return err; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index 552e06929229..b9139fb44506 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -544,6 +544,7 @@ void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header *hdr); int amdgpu_ucode_validate(const struct firmware *fw); +int amdgpu_ucode_load(struct amdgpu_device *adev, const struct firmware **fw, char *fw_name); bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr, uint16_t hdr_major, uint16_t hdr_minor);
Re: [PATCH] drm/gem: Check for valid formats
On Tue, Jan 3, 2023 at 5:11 PM Maíra Canal wrote: > > On 1/3/23 19:46, Rob Clark wrote: > > drive-by thought/concern, what are the odds that there is some wayland > > compositor out there that creates an fb for every window surface, even > > if it later decides to composite on the GPU because the display does > > not support the format? It seems like there is a non-zero chance of > > breaking userspace.. > > > > As Simon pointed out, drivers like i915 and AMDGPU already reject IOCTLs > with invalid parameters, as you can see on [1] and [2], so this patch > would make the behavior more consistent between the drivers. That said, > I don't believe that this patch would break userspace, as userspace > already needs to handle with the existing drivers. ok, maybe this won't be a problem then BR, -R > [1] > https://cgit.freedesktop.org/drm/drm-misc/tree/drivers/gpu/drm/i915/display/intel_fb.c#n1917 > [2] > https://cgit.freedesktop.org/drm/drm-misc/tree/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c#n1124 > > Best Regards, > - Maíra Canal > > > BR, > > -R > > >
Re: renesas/master bisection: igt-kms-rockchip.kms_vblank.pipe-A-wait-forked on rk3399-gru-kevin
Hi Michel, Thanks for your thoughts. I'll give my attempt at weighing my and your options, with the caveat that I'm still not much of a DRM expert. On Tue, Jan 03, 2023 at 07:04:00PM +0100, Michel Dänzer wrote: > On 12/21/22 23:02, Brian Norris wrote: > > So how to fix this? > > > > 1. ignore it; it's "just" a test failure, IIUC [1] Probably discarded, per Michel's notes. > > 2. change the test, to skip this test if the device has PSR Doesn't seem great, and not just because PSR is not directly detectable in user space. > > 3. leave vblank enabled even in the presence of PSR I'm leaning toward this. > > 4. otherwise modify the vblank ioctl interface, such that one can "wait" > >for a vblank that won't come (because the display is in self-refresh > >/ there are no new frames or vblanks) That doesn't sound so great of an API, to essentially induce hangs, pending other activity. (Assuming I understand the DRM APIs here correctly.) > FWIW, a couple more alternatives: > > 5. Go/stay out of PSR while vblank interrupts are enabled (probably want to > make sure vblankoffdelay is set up such that vblank interrupts are disabled > ASAP) That seems not extremely nice, to waste power. Based on the earlier downstream implementation (which left vblank interrupts enabled), I'd wager there's a much larger power win from PSR (on the display-transport and memory-bandwidth costs), relative to the power cost of vblank interrupts. Also, messing with vblankoffdelay sounds likely to trigger the races mentioned in the drm_vblank.c kerneldoc. > 6. Use fallback timers for vblank events while in PSR (there might be some > infrastructure for this, since some drivers don't have real vblank interrupts) There's drm_atomic_helper_fake_vblank(), but I don't think that's really hooked up to a timer. That's potentially promising though. > > [1] Or is it? I don't really know the DRM_IOCTL_WAIT_VBLANK ABI > > contract in the presence of PSR, but I believe the upstream PSR > > support has always worked this way. I could imagine > > DRM_IOCTL_WAIT_VBLANK users might not love seeing EINVAL here > > though. > > Yeah, that's pretty likely to cause issues with existing real-world user > space. OK. Any hints as to what kind of user space uses this? A cursory look doesn't show that any of the ChromeOS user space uses it, which may be why it was overlooked in the initial PSR development and upstreaming. I'm in part simply curious, but I'm also wondering what the error-handling and reliability (e.g., what if vblanks don't come?) expectations might be in practice. All in all, it's seeming like maybe option 3 or 6 are best. I'd lean toward 3, assuming I can hack my way through "driver forgot to call drm_crtc_vblank_off()" and similar problems, in part because it's ground that has partially been tread before. I hope that doesn't complicate the DRM state machine even more though, now that I'll have to better coordinate the "enabled"/"self_refresh_active" states with "vblank enabled"... Thoughts still welcome of course. Brian
Re: [RFC PATCH v2 2/3] drm: Adjust atomic checks for solid fill color
On 12/22/2022 7:08 PM, Dmitry Baryshkov wrote: On 23/12/2022 00:14, Jessica Zhang wrote: Loosen the requirements for atomic and legacy commit so that, in cases where solid fill planes is enabled (and FB_ID is NULL), the commit can still go through. In addition, add framebuffer NULL checks in other areas to account for FB being NULL when solid fill is enabled. Changes in V2: - Changed to checks for if solid_fill_blob is set (Dmitry) - Abstracted (plane_state && !solid_fill_blob) checks to helper method (Dmitry) - Fixed indentation issue (Dmitry) Signed-off-by: Jessica Zhang --- drivers/gpu/drm/drm_atomic.c | 69 - drivers/gpu/drm/drm_atomic_helper.c | 34 -- drivers/gpu/drm/drm_plane.c | 8 ++-- include/drm/drm_atomic_helper.h | 6 ++- include/drm/drm_plane.h | 12 + 5 files changed, 78 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index f197f59f6d99..b92d75bda7fd 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -601,8 +601,10 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, uint32_t num_clips; int ret; - /* either *both* CRTC and FB must be set, or neither */ - if (crtc && !fb) { + /* When solid_fill is disabled, + * either *both* CRTC and FB must be set, or neither + */ The cause and effect logic seems to be broken here. I'd expect something like: "When CRTC is set, at least one of fb and solid_fill should be set." Also it might be worth defining bool drm_plane_has_visible_data(struct drm_plane_state *state) { return state->fb || drm_plane_solid_fill_enabled(state); } Then you can use this function here and below, where you check both fb and solid_fill property. Hi Dmitry, Sounds good, that makes more sense. + if (crtc && !fb && !new_plane_state->solid_fill_blob) { drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n", plane->base.id, plane->name); return -EINVAL; @@ -626,14 +628,17 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, } /* Check whether this plane supports the fb pixel format. */ - ret = drm_plane_check_pixel_format(plane, fb->format->format, - fb->modifier); - if (ret) { - drm_dbg_atomic(plane->dev, - "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n", - plane->base.id, plane->name, - >format->format, fb->modifier); - return ret; + if (fb) { + ret = drm_plane_check_pixel_format(plane, fb->format->format, + fb->modifier); + + if (ret) { + drm_dbg_atomic(plane->dev, + "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n", + plane->base.id, plane->name, + >format->format, fb->modifier); + return ret; + } I'd suggest merging twof if(fb) blocks and extracting them to a separate functions. Noted. } /* Give drivers some help against integer overflows */ @@ -649,28 +654,30 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, return -ERANGE; } - fb_width = fb->width << 16; - fb_height = fb->height << 16; + if (fb) { + fb_width = fb->width << 16; + fb_height = fb->height << 16; - /* Make sure source coordinates are inside the fb. */ - if (new_plane_state->src_w > fb_width || - new_plane_state->src_x > fb_width - new_plane_state->src_w || - new_plane_state->src_h > fb_height || - new_plane_state->src_y > fb_height - new_plane_state->src_h) { - drm_dbg_atomic(plane->dev, - "[PLANE:%d:%s] invalid source coordinates " - "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n", - plane->base.id, plane->name, - new_plane_state->src_w >> 16, - ((new_plane_state->src_w & 0x) * 15625) >> 10, - new_plane_state->src_h >> 16, - ((new_plane_state->src_h & 0x) * 15625) >> 10, - new_plane_state->src_x >> 16, - ((new_plane_state->src_x & 0x) * 15625) >> 10, - new_plane_state->src_y >> 16, - ((new_plane_state->src_y & 0x) * 15625) >> 10, - fb->width, fb->height); - return -ENOSPC; + /* Make sure source coordinates are inside the fb. */ + if (new_plane_state->src_w > fb_width || + new_plane_state->src_x > fb_width - new_plane_state->src_w || + new_plane_state->src_h > fb_height || + new_plane_state->src_y > fb_height - new_plane_state->src_h) { + drm_dbg_atomic(plane->dev, +
Re: [PATCH] drm/gem: Check for valid formats
On 1/3/23 19:46, Rob Clark wrote: drive-by thought/concern, what are the odds that there is some wayland compositor out there that creates an fb for every window surface, even if it later decides to composite on the GPU because the display does not support the format? It seems like there is a non-zero chance of breaking userspace.. As Simon pointed out, drivers like i915 and AMDGPU already reject IOCTLs with invalid parameters, as you can see on [1] and [2], so this patch would make the behavior more consistent between the drivers. That said, I don't believe that this patch would break userspace, as userspace already needs to handle with the existing drivers. [1] https://cgit.freedesktop.org/drm/drm-misc/tree/drivers/gpu/drm/i915/display/intel_fb.c#n1917 [2] https://cgit.freedesktop.org/drm/drm-misc/tree/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c#n1124 Best Regards, - Maíra Canal BR, -R
Re: [RFC PATCH v2 3/3] drm/msm/dpu: Use color_fill property for DPU planes
On 12/22/2022 7:12 PM, Dmitry Baryshkov wrote: On 23/12/2022 00:14, Jessica Zhang wrote: Initialize and use the color_fill properties for planes in DPU driver. In addition, relax framebuffer requirements within atomic commit path and add checks for NULL framebuffers. Finally, drop DPU_PLANE_COLOR_FILL_FLAG as it's unused. Changes since V2: - Fixed dropped 'const' warning - Dropped use of solid_fill_format - Switched to using drm_plane_solid_fill_enabled helper method - Added helper to convert color fill to BGR888 (Rob) - Added support for solid fill on planes of varying sizes - Removed DPU_PLANE_COLOR_FILL_FLAG Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 9 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 65 ++- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 13ce321283ff..0695b70ea1b7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -409,6 +409,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, struct drm_plane_state *state; struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); struct dpu_plane_state *pstate = NULL; + const struct msm_format *fmt; struct dpu_format *format; struct dpu_hw_ctl *ctl = mixer->lm_ctl; @@ -441,7 +442,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, sspp_idx - SSPP_VIG0, state->fb ? state->fb->base.id : -1); - format = to_dpu_format(msm_framebuffer_format(pstate->base.fb)); + if (pstate->base.fb) + fmt = msm_framebuffer_format(pstate->base.fb); + else + fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base, + DRM_FORMAT_ABGR, 0); + + format = to_dpu_format(fmt); if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable) bg_alpha_enable = true; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 86719020afe2..51a7507373f7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -44,7 +44,6 @@ #define DPU_NAME_SIZE 12 -#define DPU_PLANE_COLOR_FILL_FLAG BIT(31) #define DPU_ZPOS_MAX 255 /* multirect rect index */ @@ -105,7 +104,6 @@ struct dpu_plane { enum dpu_sspp pipe; struct dpu_hw_pipe *pipe_hw; - uint32_t color_fill; bool is_error; bool is_rt_pipe; const struct dpu_mdss_cfg *catalog; @@ -678,6 +676,17 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu, _cfg); } +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill) +{ + uint32_t ret = 0; + + ret |= ((uint8_t) solid_fill.b) << 16; + ret |= ((uint8_t) solid_fill.g) << 8; + ret |= ((uint8_t) solid_fill.r); + + return ret; +} + /** * _dpu_plane_color_fill - enables color fill on plane * @pdpu: Pointer to DPU plane object @@ -1001,12 +1010,17 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, dst = drm_plane_state_dest(new_plane_state); - fb_rect.x2 = new_plane_state->fb->width; - fb_rect.y2 = new_plane_state->fb->height; + if (new_plane_state->fb) { + fb_rect.x2 = new_plane_state->fb->width; + fb_rect.y2 = new_plane_state->fb->height; + } max_linewidth = pdpu->catalog->caps->max_linewidth; - fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb)); + if (new_plane_state->fb) + fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb)); + else + fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR); min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1; @@ -1018,7 +1032,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; /* check src bounds */ - } else if (!dpu_plane_validate_src(, _rect, min_src_size)) { + } else if (new_plane_state->fb && !dpu_plane_validate_src(, _rect, min_src_size)) { DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n", DRM_RECT_ARG()); return -E2BIG; @@ -1086,9 +1100,10 @@ void dpu_plane_flush(struct drm_plane *plane) if (pdpu->is_error) /* force white frame with 100% alpha pipe output on error */ _dpu_plane_color_fill(pdpu, 0xFF, 0xFF); - else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) + else if (!(plane->state->fb) && drm_plane_solid_fill_enabled(plane->state)) And what if the plane has both fb and solid_fill proprety? Hi Dmitry, If both the FB and solid_fill are set, then the driver should prioritize the FB over the solid_fill. Thanks, Jessica Zhang /* force 100% alpha */ - _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF); + _dpu_plane_color_fill(pdpu,
Re: [RESEND][PATCH] drm/nouveau/fb/ga102: Replace zero-length array of trailing structs with flex-array
On Tue, Jan 03, 2023 at 03:48:36PM -0800, Kees Cook wrote: > Zero-length arrays are deprecated[1] and are being replaced with > flexible array members in support of the ongoing efforts to tighten the > FORTIFY_SOURCE routines on memcpy(), correctly instrument array indexing > with UBSAN_BOUNDS, and to globally enable -fstrict-flex-arrays=3. > > Replace zero-length array with flexible-array member. > > This results in no differences in binary output. > > [1] https://github.com/KSPP/linux/issues/78 > > Cc: Ben Skeggs > Cc: Karol Herbst > Cc: Lyude Paul > Cc: David Airlie > Cc: Daniel Vetter > Cc: Gourav Samaiya > Cc: "Gustavo A. R. Silva" > Cc: dri-devel@lists.freedesktop.org > Cc: nouv...@lists.freedesktop.org > Signed-off-by: Kees Cook Here is my RB again: Reviewed-by: Gustavo A. R. Silva Thanks! -- Gustavo > --- > Sent before as: > https://lore.kernel.org/all/20221118211207.never.039-k...@kernel.org/ > --- > drivers/gpu/drm/nouveau/include/nvfw/hs.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/nouveau/include/nvfw/hs.h > b/drivers/gpu/drm/nouveau/include/nvfw/hs.h > index 8c4cd08a7b5f..8b58b668fc0c 100644 > --- a/drivers/gpu/drm/nouveau/include/nvfw/hs.h > +++ b/drivers/gpu/drm/nouveau/include/nvfw/hs.h > @@ -52,7 +52,7 @@ struct nvfw_hs_load_header_v2 { > struct { > u32 offset; > u32 size; > - } app[0]; > + } app[]; > }; > > const struct nvfw_hs_load_header_v2 *nvfw_hs_load_header_v2(struct > nvkm_subdev *, const void *); > -- > 2.34.1 >
Re: [PATCH v6 07/18] dt-bindings: display/msm: Add list of mdss-dsi-ctrl compats
On Fri, Dec 23, 2022 at 02:10:14AM +, Bryan O'Donoghue wrote: > Add the list of current compats absent the deprecated qcm2290 to the list > of dsi compats listed here. > > Several MDSS yaml files exist which document the dsi sub-node. > For each existing SoC MDSS yaml, provide the right dsi compat string. > > Signed-off-by: Bryan O'Donoghue > --- > .../bindings/display/msm/qcom,mdss.yaml | 16 +++- > .../bindings/display/msm/qcom,msm8998-mdss.yaml | 8 +--- > .../bindings/display/msm/qcom,sc7180-mdss.yaml | 6 -- > .../bindings/display/msm/qcom,sc7280-mdss.yaml | 6 -- > .../bindings/display/msm/qcom,sdm845-mdss.yaml | 8 +--- > .../bindings/display/msm/qcom,sm8250-mdss.yaml | 8 +--- > 6 files changed, 38 insertions(+), 14 deletions(-) > > diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml > b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml > index ba0460268731b..86bb43489bf4a 100644 > --- a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml > +++ b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml > @@ -94,7 +94,21 @@ patternProperties: > type: object > properties: >compatible: > -const: qcom,mdss-dsi-ctrl > +items: > + - enum: > + - qcom,apq8064-dsi-ctrl > + - qcom,msm8916-dsi-ctrl > + - qcom,msm8953-dsi-ctrl > + - qcom,msm8974-dsi-ctrl > + - qcom,msm8996-dsi-ctrl > + - qcom,msm8998-dsi-ctrl > + - qcom,qcm2290-dsi-ctrl > + - qcom,sc7180-dsi-ctrl > + - qcom,sc7280-dsi-ctrl > + - qcom,sdm660-dsi-ctrl > + - qcom,sdm845-dsi-ctrl > + - qcom,sm8250-dsi-ctrl > + - const: qcom,mdss-dsi-ctrl No need to have an exact match here. Just this is enough: compatible: contains: const: qcom,mdss-dsi-ctrl Then the DSI schema will check the rest. Same for the rest. Rob
[PATCH] drm/i915: Fix potential context UAFs
From: Rob Clark gem_context_register() makes the context visible to userspace, and which point a separate thread can trigger the I915_GEM_CONTEXT_DESTROY ioctl. So we need to ensure that nothing uses the ctx ptr after this. And we need to ensure that adding the ctx to the xarray is the *last* thing that gem_context_register() does with the ctx pointer. Signed-off-by: Rob Clark --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 24 +++-- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 7f2831efc798..6250de9b9196 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -1688,6 +1688,10 @@ void i915_gem_init__contexts(struct drm_i915_private *i915) init_contexts(>gem.contexts); } +/* + * Note that this implicitly consumes the ctx reference, by placing + * the ctx in the context_xa. + */ static void gem_context_register(struct i915_gem_context *ctx, struct drm_i915_file_private *fpriv, u32 id) @@ -1703,10 +1707,6 @@ static void gem_context_register(struct i915_gem_context *ctx, snprintf(ctx->name, sizeof(ctx->name), "%s[%d]", current->comm, pid_nr(ctx->pid)); - /* And finally expose ourselves to userspace via the idr */ - old = xa_store(>context_xa, id, ctx, GFP_KERNEL); - WARN_ON(old); - spin_lock(>client->ctx_lock); list_add_tail_rcu(>client_link, >client->ctx_list); spin_unlock(>client->ctx_lock); @@ -1714,6 +1714,10 @@ static void gem_context_register(struct i915_gem_context *ctx, spin_lock(>gem.contexts.lock); list_add_tail(>link, >gem.contexts.list); spin_unlock(>gem.contexts.lock); + + /* And finally expose ourselves to userspace via the idr */ + old = xa_store(>context_xa, id, ctx, GFP_KERNEL); + WARN_ON(old); } int i915_gem_context_open(struct drm_i915_private *i915, @@ -2199,14 +2203,22 @@ finalize_create_context_locked(struct drm_i915_file_private *file_priv, if (IS_ERR(ctx)) return ctx; + /* +* One for the xarray and one for the caller. We need to grab +* the reference *prior* to making the ctx visble to userspace +* in gem_context_register(), as at any point after that +* userspace can try to race us with another thread destroying +* the context under our feet. +*/ + i915_gem_context_get(ctx); + gem_context_register(ctx, file_priv, id); old = xa_erase(_priv->proto_context_xa, id); GEM_BUG_ON(old != pc); proto_context_close(file_priv->dev_priv, pc); - /* One for the xarray and one for the caller */ - return i915_gem_context_get(ctx); + return ctx; } struct i915_gem_context * -- 2.38.1
[RESEND][PATCH] drm/nouveau/fb/ga102: Replace zero-length array of trailing structs with flex-array
Zero-length arrays are deprecated[1] and are being replaced with flexible array members in support of the ongoing efforts to tighten the FORTIFY_SOURCE routines on memcpy(), correctly instrument array indexing with UBSAN_BOUNDS, and to globally enable -fstrict-flex-arrays=3. Replace zero-length array with flexible-array member. This results in no differences in binary output. [1] https://github.com/KSPP/linux/issues/78 Cc: Ben Skeggs Cc: Karol Herbst Cc: Lyude Paul Cc: David Airlie Cc: Daniel Vetter Cc: Gourav Samaiya Cc: "Gustavo A. R. Silva" Cc: dri-devel@lists.freedesktop.org Cc: nouv...@lists.freedesktop.org Signed-off-by: Kees Cook --- Sent before as: https://lore.kernel.org/all/20221118211207.never.039-k...@kernel.org/ --- drivers/gpu/drm/nouveau/include/nvfw/hs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/include/nvfw/hs.h b/drivers/gpu/drm/nouveau/include/nvfw/hs.h index 8c4cd08a7b5f..8b58b668fc0c 100644 --- a/drivers/gpu/drm/nouveau/include/nvfw/hs.h +++ b/drivers/gpu/drm/nouveau/include/nvfw/hs.h @@ -52,7 +52,7 @@ struct nvfw_hs_load_header_v2 { struct { u32 offset; u32 size; - } app[0]; + } app[]; }; const struct nvfw_hs_load_header_v2 *nvfw_hs_load_header_v2(struct nvkm_subdev *, const void *); -- 2.34.1
Re: [PATCH] drm/gem: Check for valid formats
On Tuesday, January 3rd, 2023 at 23:46, Rob Clark wrote: > drive-by thought/concern, what are the odds that there is some wayland > compositor out there that creates an fb for every window surface, even > if it later decides to composite on the GPU because the display does > not support the format? It seems like there is a non-zero chance of > breaking userspace.. User-space is prepared for ADDFB2 to fail. Other drivers already reject IOCTLs with FB parameters not supported for scanout.
Re: [PATCH 1/4] drm/i915/gt: Remove platform comments from workarounds
On Fri, Dec 23, 2022 at 10:28:07AM -0800, Lucas De Marchi wrote: > On Fri, Dec 23, 2022 at 09:02:35AM +, Tvrtko Ursulin wrote: > > > > On 22/12/2022 15:55, Lucas De Marchi wrote: > > > On Thu, Dec 22, 2022 at 10:27:00AM +, Tvrtko Ursulin wrote: > > > > > > > > On 22/12/2022 08:25, Lucas De Marchi wrote: > > > > > The comments are redundant to the checks being done to apply the > > > > > workarounds and very often get outdated as workarounds need to be > > > > > extended to new platforms or steppings. Remove them altogether with > > > > > the following matches (platforms extracted from intel_workarounds.c): > > > > > > > > > > find drivers/gpu/drm/i915/gt/ -name '*.c' | xargs sed -i -E \ > > > > > 's/(Wa.*):(bdw|chv|bxt|glk|skl|kbl|cfl|cfl|whl|cml|aml|chv|cl|bw|ctg|elk|ilk|snb|dg|pvc|g4x|ilk|gen|glk|kbl|cml|glk|kbl|cml|hsw|icl|ehl|ivb|hsw|ivb|vlv|kbl|pvc|rkl|dg|adl|skl|skl|bxt|blk|cfl|cnl|glk|snb|tgl|vlv|xehpsdv).*/\1/' > > > > > find drivers/gpu/drm/i915/gt/ -name '*.c' | xargs sed -i -E \ > > > > > 's/(Wa.*):(bdw|chv|bxt|glk|skl|kbl|cfl|cfl|whl|cml|aml|chv|cl|bw|ctg|elk|ilk|snb|dg|pvc|g4x|ilk|gen|glk|kbl|cml|glk|kbl|cml|hsw|icl|ehl|ivb|hsw|ivb|vlv|kbl|pvc|rkl|dg|adl|skl|skl|bxt|blk|cfl|cnl|glk|snb|tgl|vlv|xehpsdv).*\*\//\1 > > > > > > > > > > Same things was executed in the gem directory, omitted here for > > > > > brevity. > > > > > > > > > There were a few false positives that included the workaround > > > > > description. Those were manually patched. > > > > > > > > sed -E 's/(Wa[a-zA-Z0-9_]+)[:,]([a-zA-Z0-9,-_\+\[]{2,})/\1/' > > > > > > then there are false negatives. We have Was in the form > > > "Wa_xxx:tgl,dg2, mtl". False positives we can fixup, false negatives > > > we simply don't see. After running that in gt/: > > > > > > $ git grep ": mtl" -- drivers/gpu/drm/i915/ > > > drivers/gpu/drm/i915/gt/intel_gt_pm.c: /* Wa_14017073508: mtl */ > > > drivers/gpu/drm/i915/gt/intel_gt_pm.c: /* Wa_14017073508: mtl */ > > > drivers/gpu/drm/i915/gt/intel_gt_pm.c: /* Wa_14017073508: mtl */ > > > drivers/gpu/drm/i915/gt/intel_gt_pm.c: /* Wa_14017073508: mtl */ > > > drivers/gpu/drm/i915/gt/uc/intel_guc_rc.c: * Wa_14017073508: mtl > > > drivers/gpu/drm/i915/i915_reg.h:/* Wa_14017210380: mtl */ > > > > > > I was going with the platform names to avoid the false > > > negatives and because I was entertaining the idea of only doing this for > > > latest platforms where we do have the "Wa_[[:number:]]" form > > > > > > > > > > > Maybe.. > > > > > > > > Matt recently said he has this worked planned, but more > > > > importantly - I gather then that the WA lookup tool definitely > > > > does not output these strings? > > > > > > Whatever it does it's true only at the time it's called. It simply > > > tells what > > > are the platforms and steppings the Wa applies to. We can change the > > > output to whatever we want, but that is not the point. > > > Those comments get stale and bring no real value as they match 1:1 > > > what the code is supposed to be doing. Several times a patch has to > > > update just that comment to "extend a workaround" to a next platform. > > > This is not always done, so we get a comment that doesn't match what is > > > supposed to be there. > > > > Tl;dr; version - lets park this until January and discuss once everyone > > is back. > > I'll leave my comment here since I will be out until mid January. > > > > > Longer version. I've been trying to get us talking about this a couple > > times before and I'd really like to close with an explicit consensus, > > discussion points addressed instead of skipped and just moving ahead > > with patches. > > > > References: > > 3fcf71b9-337f-6186-7b00-27cbfd116...@linux.intel.com > > Y5j0b/bykbitc...@mdroper-desk1.amr.corp.intel.com > > > > So point I wanted to discuss is whether these comments are truly useless > > or maybe they can help during review. If the tool can actually output > > them then I am leaning towards that they can be. > > I consider "can the tool output xyz?" asking the wrong question. > "The tool", which is our own small python script querying a database can > output anything like that if we want to. The database has information of > what are the platforms/steppings for each the WA is known to be applied > *today*. And that can change and do change often, particularly for early > steppings and recent platforms. > > > Thought is, when a patch comes for review adding a new platform, > > stepping, whatever, to an existing if condition, if it contains the > > comments reviewer can more easily spot a hyphotetical logic inversion > > error or similar. It is also trivial to check that both condition and > > comment have been updated. (So lets not be rash and remove something > > maybe useful just because it can go stale *only if* reviewers are not > > giving sufficient attention that changes are made in tandem.) > > I can argue to the other side too. We don't have comments in the kernel >
Re: [PATCH] drm/gem: Check for valid formats
drive-by thought/concern, what are the odds that there is some wayland compositor out there that creates an fb for every window surface, even if it later decides to composite on the GPU because the display does not support the format? It seems like there is a non-zero chance of breaking userspace.. BR, -R On Tue, Jan 3, 2023 at 4:55 AM Maíra Canal wrote: > > Currently, drm_gem_fb_create() doesn't check if the pixel format is > supported, which can lead to the acceptance of invalid pixel formats > e.g. the acceptance of invalid modifiers. Therefore, add a check for > valid formats on drm_gem_fb_create(). > > Moreover, note that this check is only valid for atomic drivers, > because, for non-atomic drivers, checking drm_any_plane_has_format() is > not possible since the format list for the primary plane is fake, and > we'd therefor reject valid formats. > > Suggested-by: Thomas Zimmermann > Signed-off-by: Maíra Canal > --- > Documentation/gpu/todo.rst | 7 ++- > drivers/gpu/drm/drm_gem_framebuffer_helper.c | 9 + > 2 files changed, 11 insertions(+), 5 deletions(-) > > diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst > index 1f8a5ebe188e..68bdafa0284f 100644 > --- a/Documentation/gpu/todo.rst > +++ b/Documentation/gpu/todo.rst > @@ -276,11 +276,8 @@ Various hold-ups: > - Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom > fb >setup code can't be deleted. > > -- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For > - atomic drivers we could check for valid formats by calling > - drm_plane_check_pixel_format() against all planes, and pass if any plane > - supports the format. For non-atomic that's not possible since like the > format > - list for the primary plane is fake and we'd therefor reject valid formats. > +- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks > for > + valid formats for atomic drivers. > > - Many drivers subclass drm_framebuffer, we'd need a embedding compatible >version of the varios drm_gem_fb_create functions. Maybe called > diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c > b/drivers/gpu/drm/drm_gem_framebuffer_helper.c > index e93533b86037..b8a615a138cd 100644 > --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c > +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c > @@ -9,6 +9,7 @@ > #include > > #include > +#include > #include > #include > #include > @@ -164,6 +165,14 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev, > return -EINVAL; > } > > + if (drm_drv_uses_atomic_modeset(dev) && > + !drm_any_plane_has_format(dev, mode_cmd->pixel_format, > + mode_cmd->modifier[0])) { > + drm_dbg(dev, "Unsupported pixel format %p4cc / modifier > 0x%llx\n", > + _cmd->pixel_format, mode_cmd->modifier[0]); > + return -EINVAL; > + } > + > for (i = 0; i < info->num_planes; i++) { > unsigned int width = mode_cmd->width / (i ? info->hsub : 1); > unsigned int height = mode_cmd->height / (i ? info->vsub : 1); > -- > 2.38.1 >
[PATCH v4 27/27] drm/amd: Optimize SRIOV switch/case for PSP microcode load
Now that IP version decoding is used, a number of case statements can be combined. Signed-off-by: Mario Limonciello --- v3->v4: * New patch drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index f45362dd8228..83e253b5d928 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -132,14 +132,8 @@ static int psp_init_sriov_microcode(struct psp_context *psp) switch (adev->ip_versions[MP0_HWIP][0]) { case IP_VERSION(9, 0, 0): - adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; - ret = psp_init_cap_microcode(psp, ucode_prefix); - break; - case IP_VERSION(11, 0, 9): - adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; - ret = psp_init_cap_microcode(psp, ucode_prefix); - break; case IP_VERSION(11, 0, 7): + case IP_VERSION(11, 0, 9): adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; ret = psp_init_cap_microcode(psp, ucode_prefix); break; -- 2.34.1
[PATCH v4 25/27] drm/amd: Use `amdgpu_ucode_load` helper for SMU
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 5 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 5 + 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index d4756bd30830..1d693cda5818 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -109,10 +109,7 @@ int smu_v11_0_init_microcode(struct smu_context *smu) snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); - err = request_firmware(>pm.fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->pm.fw); + err = amdgpu_ucode_load(adev, >pm.fw, fw_name); if (err) goto out; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 506a49a4b425..845a7fc83ba8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -103,10 +103,7 @@ int smu_v13_0_init_microcode(struct smu_context *smu) snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); - err = request_firmware(>pm.fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->pm.fw); + err = amdgpu_ucode_load(adev, >pm.fw, fw_name); if (err) goto out; -- 2.34.1
[PATCH v4 26/27] drm/amd: Load SMU microcode during early_init
This will ensure that the microcode is available before the firmware framebuffer has been destroyed. Signed-off-by: Mario Limonciello --- v3->v4: * new patch --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 2fa79f892a92..ec52830dde24 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -623,6 +623,7 @@ static int smu_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu; + int r; smu = kzalloc(sizeof(struct smu_context), GFP_KERNEL); if (!smu) @@ -640,7 +641,10 @@ static int smu_early_init(void *handle) adev->powerplay.pp_handle = smu; adev->powerplay.pp_funcs = _pm_funcs; - return smu_set_funcs(adev); + r = smu_set_funcs(adev); + if (r) + return r; + return smu_init_microcode(smu); } static int smu_set_default_dpm_table(struct smu_context *smu) @@ -1067,12 +1071,6 @@ static int smu_sw_init(void *handle) smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; smu->smu_dpm.requested_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; - ret = smu_init_microcode(smu); - if (ret) { - dev_err(adev->dev, "Failed to load smu firmware!\n"); - return ret; - } - ret = smu_smc_table_sw_init(smu); if (ret) { dev_err(adev->dev, "Failed to sw init smc table!\n"); -- 2.34.1
[PATCH v4 23/27] drm/amd: Use `amdgpu_ucode_load` helper for PSP
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 42 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 3 +- 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 3b0644600a1f..f45362dd8228 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2912,11 +2912,7 @@ int psp_init_asd_microcode(struct psp_context *psp, char *ucode_prefix) int err = 0; snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", ucode_prefix); - err = request_firmware(>psp.asd_fw, fw_name, adev->dev); - if (err) - goto out; - - err = amdgpu_ucode_validate(adev->psp.asd_fw); + err = amdgpu_ucode_load(adev, >psp.asd_fw, fw_name); if (err) goto out; @@ -2928,7 +2924,6 @@ int psp_init_asd_microcode(struct psp_context *psp, char *ucode_prefix) le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes); return 0; out: - dev_err(adev->dev, "fail to initialize asd microcode\n"); release_firmware(adev->psp.asd_fw); adev->psp.asd_fw = NULL; return err; @@ -2942,11 +2937,7 @@ int psp_init_toc_microcode(struct psp_context *psp, char *ucode_prefix) int err = 0; snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", ucode_prefix); - err = request_firmware(>psp.toc_fw, fw_name, adev->dev); - if (err) - goto out; - - err = amdgpu_ucode_validate(adev->psp.toc_fw); + err = amdgpu_ucode_load(adev, >psp.toc_fw, fw_name); if (err) goto out; @@ -2958,7 +2949,6 @@ int psp_init_toc_microcode(struct psp_context *psp, char *ucode_prefix) le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes); return 0; out: - dev_err(adev->dev, "fail to request/validate toc microcode\n"); release_firmware(adev->psp.toc_fw); adev->psp.toc_fw = NULL; return err; @@ -3105,11 +3095,7 @@ int psp_init_sos_microcode(struct psp_context *psp, char *ucode_prefix) int fw_index = 0; snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sos.bin", ucode_prefix); - err = request_firmware(>psp.sos_fw, fw_name, adev->dev); - if (err) - goto out; - - err = amdgpu_ucode_validate(adev->psp.sos_fw); + err = amdgpu_ucode_load(adev, >psp.sos_fw, fw_name); if (err) goto out; @@ -3181,8 +3167,6 @@ int psp_init_sos_microcode(struct psp_context *psp, char *ucode_prefix) return 0; out: - dev_err(adev->dev, - "failed to init sos firmware\n"); release_firmware(adev->psp.sos_fw); adev->psp.sos_fw = NULL; @@ -3340,10 +3324,7 @@ int psp_init_ta_microcode(struct psp_context *psp, char *ucode_prefix) int err; snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", ucode_prefix); - err = request_firmware(>psp.ta_fw, fw_name, adev->dev); - if (err) - return err; - err = amdgpu_ucode_validate(adev->psp.ta_fw); + err = amdgpu_ucode_load(adev, >psp.ta_fw, fw_name); if (err) return err; @@ -3383,17 +3364,14 @@ int psp_init_cap_microcode(struct psp_context *psp, char *ucode_prefix) } snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_cap.bin", ucode_prefix); - err = request_firmware(>psp.cap_fw, fw_name, adev->dev); - if (err) { - dev_warn(adev->dev, "cap microcode does not exist, skip\n"); - err = 0; - goto out; - } - - err = amdgpu_ucode_validate(adev->psp.cap_fw); + err = amdgpu_ucode_load(adev, >psp.cap_fw, fw_name); if (err) { + if (err == -ENODEV) { + dev_warn(adev->dev, "cap microcode does not exist, skip\n"); + err = 0; + goto out; + } dev_err(adev->dev, "fail to initialize cap microcode\n"); - goto out; } info = >firmware.ucode[AMDGPU_UCODE_ID_CAP]; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 47b88233bf94..415d32306b9a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -506,8 +506,7 @@ int psp_init_asd_microcode(struct psp_context *psp, char *ucode_prefix); int psp_init_toc_microcode(struct psp_context *psp, char *ucode_prefix); int psp_init_sos_microcode(struct psp_context *psp, char *ucode_prefix); int psp_init_ta_microcode(struct psp_context *psp, char *ucode_prefix); -int psp_init_cap_microcode(struct psp_context
[PATCH v4 22/27] drm/amd: Load PSP microcode during early_init
Simplifies the code so that all PSP versions will get the firmware name from `amdgpu_ucode_ip_version_decode` and then use this filename to load microcode as part of the early_init process. Any failures will cause the driver to fail to probe before the firmware framebuffer has been removed. Signed-off-by: Mario Limonciello --- v3->v4: * new patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 128 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 3 + drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 16 +-- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 55 ++ drivers/gpu/drm/amd/amdgpu/psp_v12_0.c | 13 +-- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 27 ++--- drivers/gpu/drm/amd/amdgpu/psp_v13_0_4.c | 14 +-- drivers/gpu/drm/amd/amdgpu/psp_v3_1.c| 16 +-- 8 files changed, 79 insertions(+), 193 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index d51fe3431e2b..3b0644600a1f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -122,6 +122,44 @@ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp } } +static int psp_init_sriov_microcode(struct psp_context *psp) +{ + struct amdgpu_device *adev = psp->adev; + char ucode_prefix[30]; + int ret = 0; + + amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix)); + + switch (adev->ip_versions[MP0_HWIP][0]) { + case IP_VERSION(9, 0, 0): + adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; + ret = psp_init_cap_microcode(psp, ucode_prefix); + break; + case IP_VERSION(11, 0, 9): + adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; + ret = psp_init_cap_microcode(psp, ucode_prefix); + break; + case IP_VERSION(11, 0, 7): + adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; + ret = psp_init_cap_microcode(psp, ucode_prefix); + break; + case IP_VERSION(13, 0, 2): + adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; + ret = psp_init_cap_microcode(psp, ucode_prefix); + ret &= psp_init_ta_microcode(psp, ucode_prefix); + break; + case IP_VERSION(13, 0, 0): + adev->virt.autoload_ucode_id = 0; + break; + case IP_VERSION(13, 0, 10): + adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA; + break; + default: + return -EINVAL; + } + return ret; +} + static int psp_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -192,7 +230,10 @@ static int psp_early_init(void *handle) psp_check_pmfw_centralized_cstate_management(psp); - return 0; + if (amdgpu_sriov_vf(adev)) + return psp_init_sriov_microcode(psp); + else + return psp_init_microcode(psp); } void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx) @@ -350,42 +391,6 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev, return ret; } -static int psp_init_sriov_microcode(struct psp_context *psp) -{ - struct amdgpu_device *adev = psp->adev; - int ret = 0; - - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(9, 0, 0): - adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; - ret = psp_init_cap_microcode(psp, "vega10"); - break; - case IP_VERSION(11, 0, 9): - adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; - ret = psp_init_cap_microcode(psp, "navi12"); - break; - case IP_VERSION(11, 0, 7): - adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; - ret = psp_init_cap_microcode(psp, "sienna_cichlid"); - break; - case IP_VERSION(13, 0, 2): - adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2; - ret = psp_init_cap_microcode(psp, "aldebaran"); - ret &= psp_init_ta_microcode(psp, "aldebaran"); - break; - case IP_VERSION(13, 0, 0): - adev->virt.autoload_ucode_id = 0; - break; - case IP_VERSION(13, 0, 10): - adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - static int psp_sw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -401,15 +406,6 @@ static int psp_sw_init(void *handle) ret = -ENOMEM; } - if (amdgpu_sriov_vf(adev)) - ret = psp_init_sriov_microcode(psp); - else - ret =
[PATCH v4 24/27] drm/amd/display: Load DMUB microcode during early_init
If DMUB is required for an ASIC, ensure that the microcode is available and validates during early_init. Any failures will cause the driver to fail to probe before the firmware framebuffer has been removed. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 89 --- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 4829b5431e4c..eeccc8af0320 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1945,7 +1945,6 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) struct dmub_srv_fb_info *fb_info; struct dmub_srv *dmub_srv; const struct dmcub_firmware_header_v1_0 *hdr; - const char *fw_name_dmub; enum dmub_asic dmub_asic; enum dmub_status status; int r; @@ -1953,73 +1952,46 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) switch (adev->ip_versions[DCE_HWIP][0]) { case IP_VERSION(2, 1, 0): dmub_asic = DMUB_ASIC_DCN21; - fw_name_dmub = FIRMWARE_RENOIR_DMUB; - if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id)) - fw_name_dmub = FIRMWARE_GREEN_SARDINE_DMUB; break; case IP_VERSION(3, 0, 0): - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) { + if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) dmub_asic = DMUB_ASIC_DCN30; - fw_name_dmub = FIRMWARE_SIENNA_CICHLID_DMUB; - } else { + else dmub_asic = DMUB_ASIC_DCN30; - fw_name_dmub = FIRMWARE_NAVY_FLOUNDER_DMUB; - } break; case IP_VERSION(3, 0, 1): dmub_asic = DMUB_ASIC_DCN301; - fw_name_dmub = FIRMWARE_VANGOGH_DMUB; break; case IP_VERSION(3, 0, 2): dmub_asic = DMUB_ASIC_DCN302; - fw_name_dmub = FIRMWARE_DIMGREY_CAVEFISH_DMUB; break; case IP_VERSION(3, 0, 3): dmub_asic = DMUB_ASIC_DCN303; - fw_name_dmub = FIRMWARE_BEIGE_GOBY_DMUB; break; case IP_VERSION(3, 1, 2): case IP_VERSION(3, 1, 3): dmub_asic = (adev->external_rev_id == YELLOW_CARP_B0) ? DMUB_ASIC_DCN31B : DMUB_ASIC_DCN31; - fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB; break; case IP_VERSION(3, 1, 4): dmub_asic = DMUB_ASIC_DCN314; - fw_name_dmub = FIRMWARE_DCN_314_DMUB; break; case IP_VERSION(3, 1, 5): dmub_asic = DMUB_ASIC_DCN315; - fw_name_dmub = FIRMWARE_DCN_315_DMUB; break; case IP_VERSION(3, 1, 6): dmub_asic = DMUB_ASIC_DCN316; - fw_name_dmub = FIRMWARE_DCN316_DMUB; break; case IP_VERSION(3, 2, 0): dmub_asic = DMUB_ASIC_DCN32; - fw_name_dmub = FIRMWARE_DCN_V3_2_0_DMCUB; break; case IP_VERSION(3, 2, 1): dmub_asic = DMUB_ASIC_DCN321; - fw_name_dmub = FIRMWARE_DCN_V3_2_1_DMCUB; break; default: /* ASIC doesn't support DMUB. */ return 0; } - r = request_firmware_direct(>dm.dmub_fw, fw_name_dmub, adev->dev); - if (r) { - DRM_ERROR("DMUB firmware loading failed: %d\n", r); - return 0; - } - - r = amdgpu_ucode_validate(adev->dm.dmub_fw); - if (r) { - DRM_ERROR("Couldn't validate DMUB firmware: %d\n", r); - return 0; - } - hdr = (const struct dmcub_firmware_header_v1_0 *)adev->dm.dmub_fw->data; adev->dm.dmcub_fw_version = le32_to_cpu(hdr->header.ucode_version); @@ -4513,6 +4485,61 @@ DEVICE_ATTR_WO(s3_debug); #endif +static int dm_init_microcode(struct amdgpu_device *adev) +{ + char *fw_name_dmub; + int r; + + switch (adev->ip_versions[DCE_HWIP][0]) { + case IP_VERSION(2, 1, 0): + fw_name_dmub = FIRMWARE_RENOIR_DMUB; + if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id)) + fw_name_dmub = FIRMWARE_GREEN_SARDINE_DMUB; + break; + case IP_VERSION(3, 0, 0): + if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) + fw_name_dmub = FIRMWARE_SIENNA_CICHLID_DMUB; + else + fw_name_dmub = FIRMWARE_NAVY_FLOUNDER_DMUB; + break; + case IP_VERSION(3, 0, 1): + fw_name_dmub = FIRMWARE_VANGOGH_DMUB; + break; + case IP_VERSION(3, 0, 2): +
[PATCH v4 21/27] drm/amd: Avoid BUG() for case of SRIOV missing IP version
No need to crash the kernel. AMDGPU will now fail to probe. Signed-off-by: Mario Limonciello --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index ac4d675abcb5..d51fe3431e2b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -380,7 +380,7 @@ static int psp_init_sriov_microcode(struct psp_context *psp) adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA; break; default: - BUG(); + ret = -EINVAL; break; } return ret; -- 2.34.1
[PATCH v4 20/27] drm/amd: Parse both v1 and v2 TA microcode headers using same function
Several IP versions duplicate code and can't use the common helpers. Move this code into a single function so that the helpers can be used. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 120 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 9 +- drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 60 +--- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 74 ++- drivers/gpu/drm/amd/amdgpu/psp_v12_0.c | 62 +--- 5 files changed, 107 insertions(+), 218 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 7a2fc920739b..ac4d675abcb5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -3272,41 +3272,75 @@ static int parse_ta_bin_descriptor(struct psp_context *psp, return 0; } -int psp_init_ta_microcode(struct psp_context *psp, - const char *chip_name) +static int parse_ta_v1_microcode(struct psp_context *psp) { + const struct ta_firmware_header_v1_0 *ta_hdr; struct amdgpu_device *adev = psp->adev; - char fw_name[PSP_FW_NAME_LEN]; - const struct ta_firmware_header_v2_0 *ta_hdr; - int err = 0; - int ta_index = 0; - if (!chip_name) { - dev_err(adev->dev, "invalid chip name for ta microcode\n"); + ta_hdr = (const struct ta_firmware_header_v1_0 *) +adev->psp.ta_fw->data; + + if (le16_to_cpu(ta_hdr->header.header_version_major) != 1) return -EINVAL; + + adev->psp.xgmi_context.context.bin_desc.fw_version = + le32_to_cpu(ta_hdr->xgmi.fw_version); + adev->psp.xgmi_context.context.bin_desc.size_bytes = + le32_to_cpu(ta_hdr->xgmi.size_bytes); + adev->psp.xgmi_context.context.bin_desc.start_addr = + (uint8_t *)ta_hdr + + le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); + adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); + adev->psp.ras_context.context.bin_desc.fw_version = + le32_to_cpu(ta_hdr->ras.fw_version); + adev->psp.ras_context.context.bin_desc.size_bytes = + le32_to_cpu(ta_hdr->ras.size_bytes); + adev->psp.ras_context.context.bin_desc.start_addr = + (uint8_t *)adev->psp.xgmi_context.context.bin_desc.start_addr + + le32_to_cpu(ta_hdr->ras.offset_bytes); + adev->psp.hdcp_context.context.bin_desc.fw_version = + le32_to_cpu(ta_hdr->hdcp.fw_version); + adev->psp.hdcp_context.context.bin_desc.size_bytes = + le32_to_cpu(ta_hdr->hdcp.size_bytes); + adev->psp.hdcp_context.context.bin_desc.start_addr = + (uint8_t *)ta_hdr + + le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); + adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); + adev->psp.dtm_context.context.bin_desc.fw_version = + le32_to_cpu(ta_hdr->dtm.fw_version); + adev->psp.dtm_context.context.bin_desc.size_bytes = + le32_to_cpu(ta_hdr->dtm.size_bytes); + adev->psp.dtm_context.context.bin_desc.start_addr = + (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr + + le32_to_cpu(ta_hdr->dtm.offset_bytes); + if (adev->apu_flags & AMD_APU_IS_RENOIR) { + adev->psp.securedisplay_context.context.bin_desc.fw_version = + le32_to_cpu(ta_hdr->securedisplay.fw_version); + adev->psp.securedisplay_context.context.bin_desc.size_bytes = + le32_to_cpu(ta_hdr->securedisplay.size_bytes); + adev->psp.securedisplay_context.context.bin_desc.start_addr = + (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr + + le32_to_cpu(ta_hdr->securedisplay.offset_bytes); } - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); - err = request_firmware(>psp.ta_fw, fw_name, adev->dev); - if (err) - goto out; + return 0; +} - err = amdgpu_ucode_validate(adev->psp.ta_fw); - if (err) - goto out; +static int parse_ta_v2_microcode(struct psp_context *psp) +{ + const struct ta_firmware_header_v2_0 *ta_hdr; + struct amdgpu_device *adev = psp->adev; + int err = 0; + int ta_index = 0; ta_hdr = (const struct ta_firmware_header_v2_0 *)adev->psp.ta_fw->data; - if (le16_to_cpu(ta_hdr->header.header_version_major) != 2) { - dev_err(adev->dev, "unsupported TA header version\n"); - err = -EINVAL; - goto out; - } + if (le16_to_cpu(ta_hdr->header.header_version_major) != 2) + return -EINVAL; if (le32_to_cpu(ta_hdr->ta_fw_bin_count) >= UCODE_MAX_PSP_PACKAGING) {
[PATCH v4 17/27] drm/amd: Load GFX10 microcode during early_init
Simplifies the code so that GFX10 will get the firmware name from `amdgpu_ucode_ip_version_decode` and then use this filename to load microcode as part of the early_init process. Any failures will cause the driver to fail to probe before the firmware framebuffer has been removed. Signed-off-by: Mario Limonciello --- v3->v4: * Move out of discovery into early_init --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 82 ++ 1 file changed, 17 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 5f6b59e23313..75781722c7e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -3974,9 +3974,9 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev) static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) { - const char *chip_name; char fw_name[40]; - char *wks = ""; + char ucode_prefix[30]; + const char *wks = ""; int err; const struct rlc_firmware_header_v2_0 *rlc_hdr; uint16_t version_major; @@ -3984,71 +3984,31 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) DRM_DEBUG("\n"); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - chip_name = "navi10"; - break; - case IP_VERSION(10, 1, 1): - chip_name = "navi14"; - if (!(adev->pdev->device == 0x7340 && - adev->pdev->revision != 0x00)) - wks = "_wks"; - break; - case IP_VERSION(10, 1, 2): - chip_name = "navi12"; - break; - case IP_VERSION(10, 3, 0): - chip_name = "sienna_cichlid"; - break; - case IP_VERSION(10, 3, 2): - chip_name = "navy_flounder"; - break; - case IP_VERSION(10, 3, 1): - chip_name = "vangogh"; - break; - case IP_VERSION(10, 3, 4): - chip_name = "dimgrey_cavefish"; - break; - case IP_VERSION(10, 3, 5): - chip_name = "beige_goby"; - break; - case IP_VERSION(10, 3, 3): - chip_name = "yellow_carp"; - break; - case IP_VERSION(10, 3, 6): - chip_name = "gc_10_3_6"; - break; - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 1, 4): - chip_name = "cyan_skillfish2"; - break; - case IP_VERSION(10, 3, 7): - chip_name = "gc_10_3_7"; - break; - default: - BUG(); - } + if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 1) && + (!(adev->pdev->device == 0x7340 && adev->pdev->revision != 0x00))) + wks = "_wks"; + amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp%s.bin", chip_name, wks); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp%s.bin", ucode_prefix, wks); err = amdgpu_ucode_load(adev, >gfx.pfp_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP); - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me%s.bin", chip_name, wks); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me%s.bin", ucode_prefix, wks); err = amdgpu_ucode_load(adev, >gfx.me_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME); - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce%s.bin", chip_name, wks); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce%s.bin", ucode_prefix, wks); err = amdgpu_ucode_load(adev, >gfx.ce_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE); if (!amdgpu_sriov_vf(adev)) { - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix); err = amdgpu_ucode_load(adev, >gfx.rlc_fw, fw_name); /* don't check this. There are apparently firmwares in the wild with * incorrect size in the header @@ -4067,14 +4027,14 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) goto out; } - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", chip_name, wks); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", ucode_prefix, wks); err = amdgpu_ucode_load(adev, >gfx.mec_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1); amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT); -
[PATCH v4 16/27] drm/amd: Use `amdgpu_ucode_load` helper for GFX10
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 35 ++ 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 49d34c7bbf20..5f6b59e23313 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -4030,41 +4030,31 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) } snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp%s.bin", chip_name, wks); - err = request_firmware(>gfx.pfp_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.pfp_fw); + err = amdgpu_ucode_load(adev, >gfx.pfp_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me%s.bin", chip_name, wks); - err = request_firmware(>gfx.me_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.me_fw); + err = amdgpu_ucode_load(adev, >gfx.me_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce%s.bin", chip_name, wks); - err = request_firmware(>gfx.ce_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.ce_fw); + err = amdgpu_ucode_load(adev, >gfx.ce_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE); if (!amdgpu_sriov_vf(adev)) { 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; + err = amdgpu_ucode_load(adev, >gfx.rlc_fw, fw_name); /* don't check this. There are apparently firmwares in the wild with * incorrect size in the header */ - err = amdgpu_ucode_validate(adev->gfx.rlc_fw); + if (err == -ENODEV) + goto out; if (err) dev_dbg(adev->dev, "gfx10: amdgpu_ucode_validate() failed \"%s\"\n", @@ -4078,21 +4068,15 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) } snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec%s.bin", chip_name, wks); - err = request_firmware(>gfx.mec_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.mec_fw); + err = amdgpu_ucode_load(adev, >gfx.mec_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1); amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2%s.bin", chip_name, wks); - err = request_firmware(>gfx.mec2_fw, fw_name, adev->dev); + err = amdgpu_ucode_load(adev, >gfx.mec2_fw, fw_name); if (!err) { - err = amdgpu_ucode_validate(adev->gfx.mec2_fw); - if (err) - goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2); amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT); } else { @@ -4103,9 +4087,6 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) gfx_v10_0_check_fw_write_wait(adev); out: if (err) { - dev_err(adev->dev, - "gfx10: Failed to init firmware \"%s\"\n", - fw_name); release_firmware(adev->gfx.pfp_fw); adev->gfx.pfp_fw = NULL; release_firmware(adev->gfx.me_fw); -- 2.34.1
[PATCH v4 19/27] drm/amd: Load GFX11 microcode during early_init
If GFX11 microcode is required but not available during early init, the firmware framebuffer will have already been released and the screen will freeze. Move the request for GFX11 microcode into the early_init phase so that if it's not available, driver init will fail. Signed-off-by: Mario Limonciello --- v3->v4: * Move to early_init phase --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 78 ++ 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 0c77d165caf7..5c7bc286618a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -443,6 +443,30 @@ static void gfx_v11_0_free_microcode(struct amdgpu_device *adev) kfree(adev->gfx.rlc.register_list_format); } +static int gfx_v11_0_init_toc_microcode(struct amdgpu_device *adev, char *ucode_prefix) +{ + const struct psp_firmware_header_v1_0 *toc_hdr; + int err = 0; + char fw_name[40]; + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", ucode_prefix); + err = amdgpu_ucode_load(adev, >psp.toc_fw, fw_name); + if (err) + goto out; + + toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data; + adev->psp.toc.fw_version = le32_to_cpu(toc_hdr->header.ucode_version); + adev->psp.toc.feature_version = le32_to_cpu(toc_hdr->sos.fw_version); + adev->psp.toc.size_bytes = le32_to_cpu(toc_hdr->header.ucode_size_bytes); + adev->psp.toc.start_addr = (uint8_t *)toc_hdr + + le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes); + return 0; +out: + release_firmware(adev->psp.toc_fw); + adev->psp.toc_fw = NULL; + return err; +} + static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) { char fw_name[40]; @@ -513,6 +537,9 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT); } + if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) + err = gfx_v11_0_init_toc_microcode(adev, ucode_prefix); + /* only one MEC for gfx 11.0.0. */ adev->gfx.mec2_fw = NULL; @@ -531,38 +558,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) return err; } -static int gfx_v11_0_init_toc_microcode(struct amdgpu_device *adev) -{ - const struct psp_firmware_header_v1_0 *toc_hdr; - int err = 0; - char fw_name[40]; - char ucode_prefix[30]; - - amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); - - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", ucode_prefix); - err = request_firmware(>psp.toc_fw, fw_name, adev->dev); - if (err) - goto out; - - err = amdgpu_ucode_validate(adev->psp.toc_fw); - if (err) - goto out; - - toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data; - adev->psp.toc.fw_version = le32_to_cpu(toc_hdr->header.ucode_version); - adev->psp.toc.feature_version = le32_to_cpu(toc_hdr->sos.fw_version); - adev->psp.toc.size_bytes = le32_to_cpu(toc_hdr->header.ucode_size_bytes); - adev->psp.toc.start_addr = (uint8_t *)toc_hdr + - le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes); - return 0; -out: - dev_err(adev->dev, "Failed to load TOC microcode\n"); - release_firmware(adev->psp.toc_fw); - adev->psp.toc_fw = NULL; - return err; -} - static u32 gfx_v11_0_get_csb_size(struct amdgpu_device *adev) { u32 count = 0; @@ -699,19 +694,11 @@ static void gfx_v11_0_mec_fini(struct amdgpu_device *adev) amdgpu_bo_free_kernel(>gfx.mec.mec_fw_data_obj, NULL, NULL); } -static int gfx_v11_0_me_init(struct amdgpu_device *adev) +static void gfx_v11_0_me_init(struct amdgpu_device *adev) { - int r; - bitmap_zero(adev->gfx.me.queue_bitmap, AMDGPU_MAX_GFX_QUEUES); amdgpu_gfx_graphics_queue_acquire(adev); - - r = gfx_v11_0_init_microcode(adev); - if (r) - DRM_ERROR("Failed to load gfx firmware!\n"); - - return r; } static int gfx_v11_0_mec_init(struct amdgpu_device *adev) @@ -1324,9 +1311,7 @@ static int gfx_v11_0_sw_init(void *handle) } } - r = gfx_v11_0_me_init(adev); - if (r) - return r; + gfx_v11_0_me_init(adev); r = gfx_v11_0_rlc_init(adev); if (r) { @@ -1394,9 +1379,6 @@ static int gfx_v11_0_sw_init(void *handle) /* allocate visible FB for rlc auto-loading fw */ if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) { - r = gfx_v11_0_init_toc_microcode(adev); - if (r) - dev_err(adev->dev, "Failed to load toc
[PATCH v4 18/27] drm/amd: Use `amdgpu_ucode_load` helper for GFX11
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 23 --- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index a56c6e106d00..0c77d165caf7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -457,10 +457,7 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", ucode_prefix); - err = request_firmware(>gfx.pfp_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.pfp_fw); + err = amdgpu_ucode_load(adev, >gfx.pfp_fw, fw_name); if (err) goto out; /* check pfp fw hdr version to decide if enable rs64 for gfx11.*/ @@ -477,10 +474,7 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) } snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", ucode_prefix); - err = request_firmware(>gfx.me_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.me_fw); + err = amdgpu_ucode_load(adev, >gfx.me_fw, fw_name); if (err) goto out; if (adev->gfx.rs64_enable) { @@ -493,10 +487,7 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) if (!amdgpu_sriov_vf(adev)) { snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix); - err = request_firmware(>gfx.rlc_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.rlc_fw); + err = amdgpu_ucode_load(adev, >gfx.rlc_fw, fw_name); if (err) goto out; rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data; @@ -508,10 +499,7 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) } snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", ucode_prefix); - err = request_firmware(>gfx.mec_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.mec_fw); + err = amdgpu_ucode_load(adev, >gfx.mec_fw, fw_name); if (err) goto out; if (adev->gfx.rs64_enable) { @@ -530,9 +518,6 @@ static int gfx_v11_0_init_microcode(struct amdgpu_device *adev) out: if (err) { - dev_err(adev->dev, - "gfx11: Failed to init firmware \"%s\"\n", - fw_name); release_firmware(adev->gfx.pfp_fw); adev->gfx.pfp_fw = NULL; release_firmware(adev->gfx.me_fw); -- 2.34.1
[PATCH v4 11/27] drm/amd: Load MES microcode during early_init
Add an early_init phase to MES for fetching and validating microcode from the filesystem. If MES microcode is required but not available during early init, the firmware framebuffer will have already been released and the screen will freeze. Move the request for MES microcode into the early_init phase so that if it's not available, early_init will fail. Signed-off-by: Mario Limonciello --- v3->v4: * Introduce new early_init phase for MES v2->v3: * Add a missing newline --- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 65 + drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 1 + drivers/gpu/drm/amd/amdgpu/mes_v10_1.c | 97 + drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 88 +- 4 files changed, 100 insertions(+), 151 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 0c546245793b..dd8f35234507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -21,6 +21,8 @@ * */ +#include + #include "amdgpu_mes.h" #include "amdgpu.h" #include "soc15_common.h" @@ -1423,3 +1425,66 @@ int amdgpu_mes_self_test(struct amdgpu_device *adev) kfree(vm); return 0; } + +int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe) +{ + const struct mes_firmware_header_v1_0 *mes_hdr; + struct amdgpu_firmware_info *info; + char ucode_prefix[30]; + char fw_name[40]; + int r; + + amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin", + ucode_prefix, + pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1"); + r = request_firmware(>mes.fw[pipe], fw_name, adev->dev); + if (r) + goto out; + + r = amdgpu_ucode_validate(adev->mes.fw[pipe]); + if (r) + goto out; + + mes_hdr = (const struct mes_firmware_header_v1_0 *) + adev->mes.fw[pipe]->data; + adev->mes.uc_start_addr[pipe] = + le32_to_cpu(mes_hdr->mes_uc_start_addr_lo) | + ((uint64_t)(le32_to_cpu(mes_hdr->mes_uc_start_addr_hi)) << 32); + adev->mes.data_start_addr[pipe] = + le32_to_cpu(mes_hdr->mes_data_start_addr_lo) | + ((uint64_t)(le32_to_cpu(mes_hdr->mes_data_start_addr_hi)) << 32); + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + int ucode, ucode_data; + + if (pipe == AMDGPU_MES_SCHED_PIPE) { + ucode = AMDGPU_UCODE_ID_CP_MES; + ucode_data = AMDGPU_UCODE_ID_CP_MES_DATA; + } else { + ucode = AMDGPU_UCODE_ID_CP_MES1; + ucode_data = AMDGPU_UCODE_ID_CP_MES1_DATA; + } + + info = >firmware.ucode[ucode]; + info->ucode_id = ucode; + info->fw = adev->mes.fw[pipe]; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(mes_hdr->mes_ucode_size_bytes), + PAGE_SIZE); + + info = >firmware.ucode[ucode_data]; + info->ucode_id = ucode_data; + info->fw = adev->mes.fw[pipe]; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes), + PAGE_SIZE); + } + + return 0; + +out: + release_firmware(adev->mes.fw[pipe]); + adev->mes.fw[pipe] = NULL; + return r; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h index 97c05d08a551..547ec35691fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -306,6 +306,7 @@ struct amdgpu_mes_funcs { int amdgpu_mes_ctx_get_offs(struct amdgpu_ring *ring, unsigned int id_offs); +int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe); int amdgpu_mes_init(struct amdgpu_device *adev); void amdgpu_mes_fini(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c index 614394118a53..9c5ff8b7c202 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c @@ -379,82 +379,6 @@ static const struct amdgpu_mes_funcs mes_v10_1_funcs = { .resume_gang = mes_v10_1_resume_gang, }; -static int mes_v10_1_init_microcode(struct amdgpu_device *adev, - enum admgpu_mes_pipe pipe) -{ - const char *chip_name; - char fw_name[30]; - int err; - const struct mes_firmware_header_v1_0 *mes_hdr; - struct amdgpu_firmware_info *info; - - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - chip_name = "navi10"; - break; - case IP_VERSION(10, 3, 0): -
[PATCH v4 15/27] drm/amd: Load GFX9 microcode during early_init
If GFX9 microcode is required but not available during early init, the firmware framebuffer will have already been released and the screen will freeze. Signed-off-by: Mario Limonciello --- v3->v4: * Move microcode load phase to early init v2->v3: * Fix issues found on real hardware where num_gfx_rings not set during discovery --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 58 +-- 1 file changed, 9 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 27040821d764..4e9c230e42ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1251,7 +1251,7 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) } static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev, - const char *chip_name) + char *chip_name) { char fw_name[30]; int err; @@ -1287,7 +1287,7 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev, } static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev, - const char *chip_name) + char *chip_name) { char fw_name[30]; int err; @@ -1344,7 +1344,7 @@ static bool gfx_v9_0_load_mec2_fw_bin_support(struct amdgpu_device *adev) } static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev, - const char *chip_name) + char *chip_name) { char fw_name[30]; int err; @@ -1392,58 +1392,24 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev, static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) { - const char *chip_name; + char ucode_prefix[30]; int r; DRM_DEBUG("\n"); - - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - chip_name = "vega10"; - break; - case IP_VERSION(9, 2, 1): - chip_name = "vega12"; - break; - case IP_VERSION(9, 4, 0): - chip_name = "vega20"; - break; - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): - if (adev->apu_flags & AMD_APU_IS_RAVEN2) - chip_name = "raven2"; - else if (adev->apu_flags & AMD_APU_IS_PICASSO) - chip_name = "picasso"; - else - chip_name = "raven"; - break; - case IP_VERSION(9, 4, 1): - chip_name = "arcturus"; - break; - case IP_VERSION(9, 3, 0): - if (adev->apu_flags & AMD_APU_IS_RENOIR) - chip_name = "renoir"; - else - chip_name = "green_sardine"; - break; - case IP_VERSION(9, 4, 2): - chip_name = "aldebaran"; - break; - default: - BUG(); - } + amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); /* No CPG in Arcturus */ if (adev->gfx.num_gfx_rings) { - r = gfx_v9_0_init_cp_gfx_microcode(adev, chip_name); + r = gfx_v9_0_init_cp_gfx_microcode(adev, ucode_prefix); if (r) return r; } - r = gfx_v9_0_init_rlc_microcode(adev, chip_name); + r = gfx_v9_0_init_rlc_microcode(adev, ucode_prefix); if (r) return r; - r = gfx_v9_0_init_cp_compute_microcode(adev, chip_name); + r = gfx_v9_0_init_cp_compute_microcode(adev, ucode_prefix); if (r) return r; @@ -2131,12 +2097,6 @@ static int gfx_v9_0_sw_init(void *handle) adev->gfx.gfx_current_status = AMDGPU_GFX_NORMAL_MODE; - r = gfx_v9_0_init_microcode(adev); - if (r) { - DRM_ERROR("Failed to load gfx firmware!\n"); - return r; - } - if (adev->gfx.rlc.funcs) { if (adev->gfx.rlc.funcs->init) { r = adev->gfx.rlc.funcs->init(adev); @@ -4578,7 +4538,7 @@ static int gfx_v9_0_early_init(void *handle) /* init rlcg reg access ctrl */ gfx_v9_0_init_rlcg_reg_access_ctrl(adev); - return 0; + return gfx_v9_0_init_microcode(adev); } static int gfx_v9_0_ecc_late_init(void *handle) -- 2.34.1
[PATCH v4 14/27] drm/amd: Use `amdgpu_ucode_load` helper for GFX9
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * new patch --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 43 +-- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index f202b45c413c..27040821d764 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1257,37 +1257,25 @@ static int gfx_v9_0_init_cp_gfx_microcode(struct amdgpu_device *adev, int err; snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name); - err = request_firmware(>gfx.pfp_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.pfp_fw); + err = amdgpu_ucode_load(adev, >gfx.pfp_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); - err = request_firmware(>gfx.me_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.me_fw); + err = amdgpu_ucode_load(adev, >gfx.me_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); - err = request_firmware(>gfx.ce_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.ce_fw); + err = amdgpu_ucode_load(adev, >gfx.ce_fw, fw_name); if (err) goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_CE); out: if (err) { - dev_err(adev->dev, - "gfx9: Failed to init firmware \"%s\"\n", - fw_name); release_firmware(adev->gfx.pfp_fw); adev->gfx.pfp_fw = NULL; release_firmware(adev->gfx.me_fw); @@ -1328,10 +1316,7 @@ static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev, snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_kicker_rlc.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; - err = amdgpu_ucode_validate(adev->gfx.rlc_fw); + err = amdgpu_ucode_load(adev, >gfx.rlc_fw, fw_name); if (err) goto out; rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data; @@ -1341,12 +1326,10 @@ static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev, err = amdgpu_gfx_rlc_init_microcode(adev, version_major, version_minor); out: if (err) { - dev_err(adev->dev, - "gfx9: Failed to init firmware \"%s\"\n", - fw_name); release_firmware(adev->gfx.rlc_fw); adev->gfx.rlc_fw = NULL; } + return err; } @@ -1371,12 +1354,9 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev, else snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); - err = request_firmware(>gfx.mec_fw, fw_name, adev->dev); - if (err) - goto out; - err = amdgpu_ucode_validate(adev->gfx.mec_fw); + err = amdgpu_ucode_load(adev, >gfx.mec_fw, fw_name); if (err) - goto out; + return err; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1); amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT); @@ -1386,11 +1366,8 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev, else snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); - err = request_firmware(>gfx.mec2_fw, fw_name, adev->dev); + err = amdgpu_ucode_load(adev, >gfx.mec2_fw, fw_name); if (!err) { - err = amdgpu_ucode_validate(adev->gfx.mec2_fw); - if (err) - goto out; amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2); amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC2_JT); } else { @@ -1402,13 +1379,9 @@ static int gfx_v9_0_init_cp_compute_microcode(struct amdgpu_device *adev, adev->gfx.mec2_feature_version = adev->gfx.mec_feature_version; } -out: gfx_v9_0_check_if_need_gfxoff(adev); gfx_v9_0_check_fw_write_wait(adev); if (err) { - dev_err(adev->dev, -
[PATCH v4 12/27] drm/amd: Use `amdgpu_ucode_load` helper for MES
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index dd8f35234507..df9efbca0f70 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -1438,11 +1438,7 @@ int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe) snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin", ucode_prefix, pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1"); - r = request_firmware(>mes.fw[pipe], fw_name, adev->dev); - if (r) - goto out; - - r = amdgpu_ucode_validate(adev->mes.fw[pipe]); + r = amdgpu_ucode_load(adev, >mes.fw[pipe], fw_name); if (r) goto out; @@ -1482,7 +1478,6 @@ int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe) } return 0; - out: release_firmware(adev->mes.fw[pipe]); adev->mes.fw[pipe] = NULL; -- 2.34.1
[PATCH v4 13/27] drm/amd: Remove superfluous assignment for `adev->mes.adev`
`amdgpu_mes_init` already sets `adev->mes.adev`, so there is no need to also set it in the IP specific versions. Signed-off-by: Mario Limonciello --- v4: * New patch --- drivers/gpu/drm/amd/amdgpu/mes_v10_1.c | 1 - drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c index 9c5ff8b7c202..f58debf2783c 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c @@ -931,7 +931,6 @@ static int mes_v10_1_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int pipe, r; - adev->mes.adev = adev; adev->mes.funcs = _v10_1_funcs; adev->mes.kiq_hw_init = _v10_1_kiq_hw_init; diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c index 3af77a32baac..c8bdee9a66c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -1020,7 +1020,6 @@ static int mes_v11_0_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int pipe, r; - adev->mes.adev = adev; adev->mes.funcs = _v11_0_funcs; adev->mes.kiq_hw_init = _v11_0_kiq_hw_init; adev->mes.kiq_hw_fini = _v11_0_kiq_hw_fini; -- 2.34.1
[PATCH v4 09/27] drm/amd: Use `amdgpu_ucode_load` helper for VCN
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 15 +++ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index a23e26b272b4..6d9cb7fb67cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -206,19 +206,10 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) return -EINVAL; } - r = request_firmware(>vcn.fw, fw_name, adev->dev); + r = amdgpu_ucode_load(adev, >vcn.fw, fw_name); if (r) { - dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n", - fw_name); - return r; - } - - r = amdgpu_ucode_validate(adev->vcn.fw); - if (r) { - dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n", - fw_name); - release_firmware(adev->vcn.fw); - adev->vcn.fw = NULL; + if (adev->vcn.fw) + release_firmware(adev->vcn.fw); return r; } -- 2.34.1
[PATCH v4 08/27] drm/amd: Make SDMA firmware load failures less noisy.
When firmware is missing we get failures at every step. ``` [3.855086] amdgpu :04:00.0: Direct firmware load for amdgpu/green_sardine_sdma.bin failed with error -2 [3.855087] [drm:amdgpu_sdma_init_microcode [amdgpu]] *ERROR* SDMA: Failed to init firmware "amdgpu/green_sardine_sdma.bin" [3.855398] [drm:sdma_v4_0_early_init [amdgpu]] *ERROR* Failed to load sdma firmware! ``` Realistically we don't need all of these, a user can tell from the first one that request_firmware emitted what happened. Drop the others. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index 83e8f0dae647..f052173ef1e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -277,10 +277,8 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, } out: - if (err) { - DRM_ERROR("SDMA: Failed to init firmware \"%s\"\n", fw_name); + if (err) amdgpu_sdma_destroy_inst_ctx(adev, duplicate); - } return err; } -- 2.34.1
[PATCH v4 10/27] drm/amd: Load VCN microcode during early_init
Simplifies the code so that all VCN versions will get the firmware name from `amdgpu_ucode_ip_version_decode` and then use this filename to load microcode as part of the early_init process. Signed-off-by: Mario Limonciello --- v3->v4: * Move out of IP discovery and introduce early_init phase for VCN --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 94 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 5 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 5 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 5 +- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 5 +- drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 5 +- 7 files changed, 52 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 6d9cb7fb67cf..48fc9059c386 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -36,25 +36,25 @@ #include "soc15d.h" /* Firmware Names */ -#define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin" -#define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin" -#define FIRMWARE_RAVEN2"amdgpu/raven2_vcn.bin" -#define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" -#define FIRMWARE_RENOIR"amdgpu/renoir_vcn.bin" -#define FIRMWARE_GREEN_SARDINE "amdgpu/green_sardine_vcn.bin" -#define FIRMWARE_NAVI10"amdgpu/navi10_vcn.bin" -#define FIRMWARE_NAVI14"amdgpu/navi14_vcn.bin" -#define FIRMWARE_NAVI12"amdgpu/navi12_vcn.bin" -#define FIRMWARE_SIENNA_CICHLID"amdgpu/sienna_cichlid_vcn.bin" -#define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_vcn.bin" -#define FIRMWARE_VANGOGH "amdgpu/vangogh_vcn.bin" -#define FIRMWARE_DIMGREY_CAVEFISH "amdgpu/dimgrey_cavefish_vcn.bin" -#define FIRMWARE_ALDEBARAN "amdgpu/aldebaran_vcn.bin" -#define FIRMWARE_BEIGE_GOBY"amdgpu/beige_goby_vcn.bin" -#define FIRMWARE_YELLOW_CARP "amdgpu/yellow_carp_vcn.bin" -#define FIRMWARE_VCN_3_1_2 "amdgpu/vcn_3_1_2.bin" -#define FIRMWARE_VCN4_0_0 "amdgpu/vcn_4_0_0.bin" -#define FIRMWARE_VCN4_0_2 "amdgpu/vcn_4_0_2.bin" +#define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin" +#define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin" +#define FIRMWARE_RAVEN2"amdgpu/raven2_vcn.bin" +#define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" +#define FIRMWARE_RENOIR"amdgpu/renoir_vcn.bin" +#define FIRMWARE_GREEN_SARDINE "amdgpu/green_sardine_vcn.bin" +#define FIRMWARE_NAVI10"amdgpu/navi10_vcn.bin" +#define FIRMWARE_NAVI14"amdgpu/navi14_vcn.bin" +#define FIRMWARE_NAVI12"amdgpu/navi12_vcn.bin" +#define FIRMWARE_SIENNA_CICHLID"amdgpu/sienna_cichlid_vcn.bin" +#define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_vcn.bin" +#define FIRMWARE_VANGOGH "amdgpu/vangogh_vcn.bin" +#define FIRMWARE_DIMGREY_CAVEFISH "amdgpu/dimgrey_cavefish_vcn.bin" +#define FIRMWARE_ALDEBARAN "amdgpu/aldebaran_vcn.bin" +#define FIRMWARE_BEIGE_GOBY"amdgpu/beige_goby_vcn.bin" +#define FIRMWARE_YELLOW_CARP "amdgpu/yellow_carp_vcn.bin" +#define FIRMWARE_VCN_3_1_2 "amdgpu/vcn_3_1_2.bin" +#define FIRMWARE_VCN4_0_0 "amdgpu/vcn_4_0_0.bin" +#define FIRMWARE_VCN4_0_2 "amdgpu/vcn_4_0_2.bin" #define FIRMWARE_VCN4_0_4 "amdgpu/vcn_4_0_4.bin" MODULE_FIRMWARE(FIRMWARE_RAVEN); @@ -80,10 +80,26 @@ MODULE_FIRMWARE(FIRMWARE_VCN4_0_4); static void amdgpu_vcn_idle_work_handler(struct work_struct *work); +int amdgpu_vcn_early_init(struct amdgpu_device *adev) +{ + char ucode_prefix[30]; + char fw_name[40]; + int r; + + amdgpu_ucode_ip_version_decode(adev, UVD_HWIP, ucode_prefix, sizeof(ucode_prefix)); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + r = amdgpu_ucode_load(adev, >vcn.fw, fw_name); + if (r) { + release_firmware(adev->vcn.fw); + adev->vcn.fw = NULL; + } + + return r; +} + int amdgpu_vcn_sw_init(struct amdgpu_device *adev) { unsigned long bo_size; - const char *fw_name; const struct common_firmware_header *hdr; unsigned char fw_check; unsigned int fw_shared_size, log_offset; @@ -99,46 +115,27 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) switch (adev->ip_versions[UVD_HWIP][0]) { case IP_VERSION(1, 0, 0): case IP_VERSION(1, 0, 1): - if (adev->apu_flags & AMD_APU_IS_RAVEN2) - fw_name = FIRMWARE_RAVEN2; - else if (adev->apu_flags & AMD_APU_IS_PICASSO) - fw_name = FIRMWARE_PICASSO; - else - fw_name = FIRMWARE_RAVEN; - break; case IP_VERSION(2, 5, 0): - fw_name = FIRMWARE_ARCTURUS; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags
[PATCH v4 07/27] drm/amd: Convert SDMA to use `amdgpu_ucode_ip_version_decode`
Simplifies the code so that all SDMA versions will get the firmware name from `amdgpu_ucode_ip_version_decode`. Signed-off-by: Mario Limonciello --- v3->v4: * Move out of IP discovery and instead simplify early_init v2->v3: * Fix dGPU naming scheme --- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h | 4 +- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 47 +--- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 30 + drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 55 +--- drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 25 +-- 6 files changed, 13 insertions(+), 155 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index 9e85a078d918..83e8f0dae647 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -200,15 +200,18 @@ void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev, } int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, - char *fw_name, u32 instance, - bool duplicate) + u32 instance, bool duplicate) { struct amdgpu_firmware_info *info = NULL; const struct common_firmware_header *header = NULL; int err = 0, i; const struct sdma_firmware_header_v2_0 *sdma_hdr; uint16_t version_major; + char ucode_prefix[30]; + char fw_name[40]; + amdgpu_ucode_ip_version_decode(adev, SDMA0_HWIP, ucode_prefix, sizeof(ucode_prefix)); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s%s.bin", ucode_prefix, !instance ? "" : "1"); err = amdgpu_ucode_load(adev, >sdma.instance[instance].fw, fw_name); if (err) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h index 7d99205c2e01..2d16e6d36728 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h @@ -124,8 +124,8 @@ int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev, int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry); -int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, -char *fw_name, u32 instance, bool duplicate); +int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, u32 instance, + bool duplicate); void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev, bool duplicate); void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 4d780e4430e7..017ae298558e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -575,60 +575,17 @@ static void sdma_v4_0_setup_ulv(struct amdgpu_device *adev) // vega10 real chip need to use PSP to load firmware static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) { - const char *chip_name; - char fw_name[30]; int ret, i; - DRM_DEBUG("\n"); - - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 0, 0): - chip_name = "vega10"; - break; - case IP_VERSION(4, 0, 1): - chip_name = "vega12"; - break; - case IP_VERSION(4, 2, 0): - chip_name = "vega20"; - break; - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): - if (adev->apu_flags & AMD_APU_IS_RAVEN2) - chip_name = "raven2"; - else if (adev->apu_flags & AMD_APU_IS_PICASSO) - chip_name = "picasso"; - else - chip_name = "raven"; - break; - case IP_VERSION(4, 2, 2): - chip_name = "arcturus"; - break; - case IP_VERSION(4, 1, 2): - if (adev->apu_flags & AMD_APU_IS_RENOIR) - chip_name = "renoir"; - else - chip_name = "green_sardine"; - break; - case IP_VERSION(4, 4, 0): - chip_name = "aldebaran"; - break; - default: - BUG(); - } - for (i = 0; i < adev->sdma.num_instances; i++) { - if (i == 0) - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma.bin", chip_name); - else - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i); if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) || adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0)) { /* Acturus & Aldebaran will leverage the same FW
[PATCH v4 06/27] drm/amd: Use `amdgpu_ucode_load` helper for SDMA
The `amdgpu_ucode_load` helper will ensure that the return code for missing firmware is -ENODEV so that early_init can fail. Signed-off-by: Mario Limonciello --- v3->v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index ea5278f094c0..9e85a078d918 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -154,16 +154,11 @@ int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev, static int amdgpu_sdma_init_inst_ctx(struct amdgpu_sdma_instance *sdma_inst) { - int err = 0; uint16_t version_major; const struct common_firmware_header *header = NULL; const struct sdma_firmware_header_v1_0 *hdr; const struct sdma_firmware_header_v2_0 *hdr_v2; - err = amdgpu_ucode_validate(sdma_inst->fw); - if (err) - return err; - header = (const struct common_firmware_header *) sdma_inst->fw->data; version_major = le16_to_cpu(header->header_version_major); @@ -214,7 +209,7 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, const struct sdma_firmware_header_v2_0 *sdma_hdr; uint16_t version_major; - err = request_firmware(>sdma.instance[instance].fw, fw_name, adev->dev); + err = amdgpu_ucode_load(adev, >sdma.instance[instance].fw, fw_name); if (err) goto out; -- 2.34.1
[PATCH v4 05/27] drm/amd: Add a new helper for loading/validating microcode
All microcode runs a basic validation after it's been loaded. Each IP block as part of init will run both. Introduce a wrapper for request_firmware and amdgpu_ucode_validate. This wrapper will also remap any error codes from request_firmware to -ENODEV. This is so that early_init will fail if firmware couldn't be loaded instead of the IP block being disabled. Signed-off-by: Mario Limonciello --- v3-v4: * New patch --- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 24 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 1 + 2 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index eafcddce58d3..8c4a7b09e344 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -1312,3 +1312,27 @@ void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, snprintf(ucode_prefix, len, "%s_%d_%d_%d", ip_name, maj, min, rev); } + +/* + * amdgpu_ucode_load - Load and validate amdgpu microcode + * + * @adev: amdgpu device + * @fw: pointer to load firmware to + * @fw_name: firmware to load + * + * This is a helper that will use request_firmware and amdgpu_ucode_validate + * to load and run basic validation on firmware. If the load fails, remap + * the error code to -ENODEV, so that early_init functions will fail to load. + */ +int amdgpu_ucode_load(struct amdgpu_device *adev, const struct firmware **fw, char *fw_name) +{ + int err = request_firmware(fw, fw_name, adev->dev); + + if (err) + return -ENODEV; + err = amdgpu_ucode_validate(*fw); + if (err) + dev_dbg(adev->dev, "\"%s\" failed to validate\n", fw_name); + + return err; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index 552e06929229..b9139fb44506 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -544,6 +544,7 @@ void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header *hdr); int amdgpu_ucode_validate(const struct firmware *fw); +int amdgpu_ucode_load(struct amdgpu_device *adev, const struct firmware **fw, char *fw_name); bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr, uint16_t hdr_major, uint16_t hdr_minor); -- 2.34.1
[PATCH v4 02/27] drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode"
This will allow other parts of the driver that currently special case firmware file names to before IP version style naming to just have a single call to `amdgpu_ucode_ip_version_decode`. Signed-off-by: Mario Limonciello Acked-by: Christian König --- v3->v4: * No changes v2->v3: * Fixes for GFX9 SDMA --- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 221 ++ 1 file changed, 221 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 5cb62e6249c2..eafcddce58d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -1059,12 +1059,233 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) return 0; } +static const char *amdgpu_ucode_legacy_naming(struct amdgpu_device *adev, int block_type) +{ + if (block_type == MP0_HWIP) { + switch (adev->ip_versions[MP0_HWIP][0]) { + case IP_VERSION(9, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: + return "vega10"; + case CHIP_VEGA12: + return "vega12"; + default: + return NULL; + } + break; + case IP_VERSION(10, 0, 0): + case IP_VERSION(10, 0, 1): + if (adev->asic_type == CHIP_RAVEN) { + if (adev->apu_flags & AMD_APU_IS_RAVEN2) + return "raven2"; + else if (adev->apu_flags & AMD_APU_IS_PICASSO) + return "picasso"; + return "raven"; + } + break; + case IP_VERSION(11, 0, 0): + return "navi10"; + case IP_VERSION(11, 0, 2): + return "vega20"; + case IP_VERSION(11, 0, 4): + return "arcturus"; + case IP_VERSION(11, 0, 5): + return "navi14"; + case IP_VERSION(11, 0, 7): + return "sienna_cichlid"; + case IP_VERSION(11, 0, 9): + return "navi12"; + case IP_VERSION(11, 0, 11): + return "navy_flounder"; + case IP_VERSION(11, 0, 12): + return "dimgrey_cavefish"; + case IP_VERSION(11, 0, 13): + return "beige_goby"; + case IP_VERSION(11, 5, 0): + return "vangogh"; + case IP_VERSION(12, 0, 1): + if (adev->asic_type == CHIP_RENOIR) { + if (adev->apu_flags & AMD_APU_IS_RENOIR) + return "renoir"; + return "green_sardine"; + } + break; + case IP_VERSION(13, 0, 2): + return "aldebaran"; + case IP_VERSION(13, 0, 1): + case IP_VERSION(13, 0, 3): + return "yellow_carp"; + } + } else if (block_type == MP1_HWIP) { + switch (adev->ip_versions[MP1_HWIP][0]) { + case IP_VERSION(9, 0, 0): + case IP_VERSION(10, 0, 0): + case IP_VERSION(10, 0, 1): + case IP_VERSION(11, 0, 2): + if (adev->asic_type == CHIP_ARCTURUS) + return "arcturus_smc"; + return NULL; + case IP_VERSION(11, 0, 0): + return "navi10_smc"; + case IP_VERSION(11, 0, 5): + return "navi14_smc"; + case IP_VERSION(11, 0, 9): + return "navi12_smc"; + case IP_VERSION(11, 0, 7): + return "sienna_cichlid_smc"; + case IP_VERSION(11, 0, 11): + return "navy_flounder_smc"; + case IP_VERSION(11, 0, 12): + return "dimgrey_cavefish_smc"; + case IP_VERSION(11, 0, 13): + return "beige_goby_smc"; + case IP_VERSION(13, 0, 2): + return "aldebaran_smc"; + } + } else if (block_type == SDMA0_HWIP) { + switch (adev->ip_versions[SDMA0_HWIP][0]) { + case IP_VERSION(4, 0, 0): + return "vega10_sdma"; + case IP_VERSION(4, 0, 1): + return "vega12_sdma"; + case IP_VERSION(4, 1, 0): + case IP_VERSION(4, 1, 1): + if (adev->apu_flags & AMD_APU_IS_RAVEN2) + return
[PATCH v4 04/27] drm/amd: Convert SMUv13 microcode to use `amdgpu_ucode_ip_version_decode`
The special case for the one dGPU has been moved into `amdgpu_ucode_ip_version_decode`, so simplify this code. Reviewed-by: Alex Deucher Signed-off-by: Mario Limonciello Acked-by: Christian König --- v3->v4: * No changes --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 0ac9cac805f9..506a49a4b425 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -88,7 +88,6 @@ static const int link_speed[] = {25, 50, 80, 160}; int smu_v13_0_init_microcode(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - const char *chip_name; char fw_name[30]; char ucode_prefix[30]; int err = 0; @@ -100,16 +99,9 @@ int smu_v13_0_init_microcode(struct smu_context *smu) if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(13, 0, 2): - chip_name = "aldebaran_smc"; - break; - default: - amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix)); - chip_name = ucode_prefix; - } + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix)); - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); err = request_firmware(>pm.fw, fw_name, adev->dev); if (err) -- 2.34.1
[PATCH v4 03/27] drm/amd: Convert SMUv11 microcode to use `amdgpu_ucode_ip_version_decode`
Remove the special casing from SMU v11 code. No intended functional changes. Signed-off-by: Mario Limonciello Acked-by: Christian König --- v3->v4: * No changes --- .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c| 35 ++- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index ad66d57aa102..d4756bd30830 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -93,7 +93,7 @@ static void smu_v11_0_poll_baco_exit(struct smu_context *smu) int smu_v11_0_init_microcode(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - const char *chip_name; + char ucode_prefix[30]; char fw_name[SMU_FW_NAME_LEN]; int err = 0; const struct smc_firmware_header_v1_0 *hdr; @@ -105,38 +105,9 @@ int smu_v11_0_init_microcode(struct smu_context *smu) (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7 return 0; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 0): - chip_name = "navi10"; - break; - case IP_VERSION(11, 0, 5): - chip_name = "navi14"; - break; - case IP_VERSION(11, 0, 9): - chip_name = "navi12"; - break; - case IP_VERSION(11, 0, 7): - chip_name = "sienna_cichlid"; - break; - case IP_VERSION(11, 0, 11): - chip_name = "navy_flounder"; - break; - case IP_VERSION(11, 0, 12): - chip_name = "dimgrey_cavefish"; - break; - case IP_VERSION(11, 0, 13): - chip_name = "beige_goby"; - break; - case IP_VERSION(11, 0, 2): - chip_name = "arcturus"; - break; - default: - dev_err(adev->dev, "Unsupported IP version 0x%x\n", - adev->ip_versions[MP1_HWIP][0]); - return -EINVAL; - } + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix)); - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_smc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); err = request_firmware(>pm.fw, fw_name, adev->dev); if (err) -- 2.34.1
[PATCH v4 01/27] drm/amd: Delay removal of the firmware framebuffer
Removing the firmware framebuffer from the driver means that even if the driver doesn't support the IP blocks in a GPU it will no longer be functional after the driver fails to initialize. This change will ensure that unsupported IP blocks at least cause the driver to work with the EFI framebuffer. Cc: sta...@vger.kernel.org Suggested-by: Alex Deucher Signed-off-by: Mario Limonciello --- v3->v4: * Drop all R-b/A-b tags. * Move to after early IP init instead --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 6 -- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9a1a5c2864a0..cdb681398a99 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -89,6 +90,8 @@ MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin"); #define AMDGPU_MAX_RETRY_LIMIT 2 #define AMDGPU_RETRY_SRIOV_RESET(r) ((r) == -EBUSY || (r) == -ETIMEDOUT || (r) == -EINVAL) +static const struct drm_driver amdgpu_kms_driver; + const char *amdgpu_asic_name[] = { "TAHITI", "PITCAIRN", @@ -3685,6 +3688,11 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (r) return r; + /* Get rid of things like offb */ + r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, _kms_driver); + if (r) + return r; + /* Enable TMZ based on IP_VERSION */ amdgpu_gmc_tmz_set(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index db7e34eacc35..b9f14ec9edb2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -23,7 +23,6 @@ */ #include -#include #include #include #include @@ -2096,11 +2095,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, } #endif - /* Get rid of things like offb */ - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, _kms_driver); - if (ret) - return ret; - adev = devm_drm_dev_alloc(>dev, _kms_driver, typeof(*adev), ddev); if (IS_ERR(adev)) return PTR_ERR(adev); -- 2.34.1
[PATCH v4 00/27] Recover from failure to probe GPU
One of the first thing that KMS drivers do during initialization is destroy the system firmware framebuffer by means of `drm_aperture_remove_conflicting_pci_framebuffers` This means that if for any reason the GPU failed to probe the user will be stuck with at best a screen frozen at the last thing that was shown before the KMS driver continued it's probe. The problem is most pronounced when new GPU support is introduced because users will need to have a recent linux-firmware snapshot on their system when they boot a kernel with matching support. However the problem is further exaggerated in the case of amdgpu because it has migrated to "IP discovery" where amdgpu will attempt to load on "ALL" AMD GPUs even if the driver is missing support for IP blocks contained in that GPU. IP discovery requires some probing and isn't run until after the framebuffer has been destroyed. This means a situation can occur where a user purchases a new GPU not yet supported by a distribution and when booting the installer it will "freeze" even if the distribution doesn't have the matching kernel support for those IP blocks. The perfect example of this is Ubuntu 22.10 and the new dGPUs just launched by AMD. The installation media ships with kernel 5.19 (which has IP discovery) but the amdgpu support for those IP blocks landed in kernel 6.0. The matching linux-firmware was released after 22.10's launch. The screen will freeze without nomodeset. Even if a user manages to install and then upgrades to kernel 6.0 after install they'll still have the problem of missing firmware, and the same experience. This is quite jarring for users, particularly if they don't know that they have to use "nomodeset" to install. To help the situation make changes to GPU discovery: 1) Delay releasing the firmware framebuffer until after early_init completed. This will help the situation of an older kernel that doesn't yet support the IP blocks probing a new GPU. IP discovery will have failed. 2) Request loading all PSP, VCN, SDMA, SMU, DMCUB, MES and GC microcode into memory during early_init. This will help the situation of new enough kernel for the IP discovery phase to otherwise pass but missing microcode from linux-firmware.git. v3->v4: * Rework to delay framebuffer release until early_init is done * Make individual IPs load microcode during early init phase * Add SMU and DMCUB cases for early_init loading * Add some new helper code for wrapping request_firmware calls (needed for early_init to return something besides -ENOENT) v2->v3: * Pick up tags for patches 1-10 * Rework patch 11 to not validate during discovery * Fix bugs with GFX9 due to gfx.num_gfx_rings not being set during discovery * Fix naming scheme for SDMA on dGPUs v1->v2: * Take the suggestion from v1 thread to delay the framebuffer release until ip discovery is done. This patch is CC to stable to that older stable kernels with IP discovery won't try to probe unknown IP. * Drop changes to drm aperature. * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery. Mario Limonciello (27): drm/amd: Delay removal of the firmware framebuffer drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode" drm/amd: Convert SMUv11 microcode to use `amdgpu_ucode_ip_version_decode` drm/amd: Convert SMUv13 microcode to use `amdgpu_ucode_ip_version_decode` drm/amd: Add a new helper for loading/validating microcode drm/amd: Use `amdgpu_ucode_load` helper for SDMA drm/amd: Convert SDMA to use `amdgpu_ucode_ip_version_decode` drm/amd: Make SDMA firmware load failures less noisy. drm/amd: Use `amdgpu_ucode_load` helper for VCN drm/amd: Load VCN microcode during early_init drm/amd: Load MES microcode during early_init drm/amd: Use `amdgpu_ucode_load` helper for MES drm/amd: Remove superfluous assignment for `adev->mes.adev` drm/amd: Use `amdgpu_ucode_load` helper for GFX9 drm/amd: Load GFX9 microcode during early_init drm/amd: Use `amdgpu_ucode_load` helper for GFX10 drm/amd: Load GFX10 microcode during early_init drm/amd: Use `amdgpu_ucode_load` helper for GFX11 drm/amd: Load GFX11 microcode during early_init drm/amd: Parse both v1 and v2 TA microcode headers using same function drm/amd: Avoid BUG() for case of SRIOV missing IP version drm/amd: Load PSP microcode during early_init drm/amd: Use `amdgpu_ucode_load` helper for PSP drm/amd/display: Load DMUB microcode during early_init drm/amd: Use `amdgpu_ucode_load` helper for SMU drm/amd: Load SMU microcode during early_init drm/amd: Optimize SRIOV switch/case for PSP microcode load drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 8 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 6 - drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 60 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 276 +- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 15 +-
Re: [PATCH v3 11/13] drm/fb-helper: Fix single-probe color-format selection
Hi Thomas, On 1/2/23 08:29, Thomas Zimmermann wrote: Fix the color-format selection of the single-probe helper. Go through all user-specified values and test each for compatibility with the driver. If none is supported, use the driver-provided default. This guarantees that the console is always available in any color format at least. Until now, the format selection of the single-probe helper tried to either use a user-specified format or a 32-bit default format. If the user-specified format was not supported by the driver, the selection failed and the display remained blank. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- I started to get the following warning on the Raspberry Pi 4 Model B (arm64/defconfig) using drm-misc-next: [4.376317] [drm] Initialized vc4 0.0.0 20140616 for gpu on minor 0 [4.433587] vc4-drm gpu: [drm] bpp/depth value of 16/24 not supported [4.433617] vc4-drm gpu: [drm] bpp/depth value of 16/24 not supported [4.433629] vc4-drm gpu: [drm] bpp/depth value of 16/24 not supported [4.433640] vc4-drm gpu: [drm] bpp/depth value of 16/24 not supported [4.433650] vc4-drm gpu: [drm] bpp/depth value of 16/24 not supported [4.433658] vc4-drm gpu: [drm] No compatible format found [4.433854] [ cut here ] [4.433861] WARNING: CPU: 2 PID: 66 at drivers/gpu/drm/drm_atomic.c:1604 __drm_atomic_helper_set_config+0x2e8/0x314 [drm] [4.434172] Modules linked in: btbcm(+) crct10dif_ce reset_raspberrypi clk_raspberrypi raspberrypi_hwmon bluetooth ecdh_generic ecc pwm_bcm2835 broadcom rfkill iproc_rng200 bcm_phy_lib i2c_bcm2835 vc4 rng_core snd_soc_hdmi_codec bcm2711_thermal cec drm_display_helper v3d pcie_brcmstb drm_dma_helper gpu_sched genet drm_shmem_helper nvmem_rmem mdio_bcm_unimac drm_kms_helper drm fuse ip_tables x_tables ipv6 [4.434322] CPU: 2 PID: 66 Comm: kworker/u8:2 Not tainted 6.1.0-rc6-00011-g37c90d589dc0 #29 [4.434337] Hardware name: Raspberry Pi 4 Model B Rev 1.4 (DT) [4.434345] Workqueue: events_unbound deferred_probe_work_func [4.434376] pstate: 8005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [4.434390] pc : __drm_atomic_helper_set_config+0x2e8/0x314 [drm] [4.434668] lr : __drm_atomic_helper_set_config+0x64/0x314 [drm] [4.434943] sp : 882c3840 [4.434949] x29: 882c3850 x28: 2d6d448e12c0 x27: 0001 [4.434972] x26: 0038 x25: 2d6d448e12c0 x24: 2d6d401a0690 [4.434991] x23: 2d6d41f74080 x22: 2d6d40d8a400 x21: 2d6d433fcc00 [4.435009] x20: 2d6d401a0690 x19: 2d6d44b8e180 x18: 0020 [4.435027] x17: 0010 x16: a6757bee52d0 x15: [4.435044] x14: x13: x12: [4.435063] x11: x10: 2d6d43240800 x9 : 2d6d44b8e200 [4.435081] x8 : x7 : 2d6d44b8e180 x6 : 2d6d40d8a400 [4.435099] x5 : 2d6d45e7ca80 x4 : 0050 x3 : a675498c3bad [4.435116] x2 : 0004 x1 : 2d6d4323f080 x0 : 2d6d433fcc00 [4.435136] Call trace: [4.435143] __drm_atomic_helper_set_config+0x2e8/0x314 [drm] [4.435440] drm_client_modeset_commit_atomic+0x140/0x244 [drm] [4.435723] drm_client_modeset_commit_locked+0x50/0x168 [drm] [4.436001] drm_client_modeset_commit+0x2c/0x54 [drm] [4.436273] __drm_fb_helper_initial_config_and_unlock+0x548/0x5a0 [drm_kms_helper] [4.436407] drm_fb_helper_initial_config+0x38/0x50 [drm_kms_helper] [4.436528] drm_fbdev_client_hotplug+0xa8/0x120 [drm_kms_helper] [4.436648] drm_fbdev_generic_setup+0x80/0x150 [drm_kms_helper] [4.436768] vc4_drm_bind+0x1f0/0x22c [vc4] [4.436928] try_to_bring_up_aggregate_device+0x168/0x1b4 [4.436958] __component_add+0xbc/0x15c [4.436974] component_add+0x14/0x20 [4.436990] vc4_hdmi_dev_probe+0x1c/0x28 [vc4] [4.437146] platform_probe+0xa8/0xd0 [4.437158] really_probe+0x130/0x2f4 [4.437174] __driver_probe_device+0xb4/0xe0 [4.437189] driver_probe_device+0x3c/0x1f8 [4.437202] __device_attach_driver+0x118/0x140 [4.437217] bus_for_each_drv+0x84/0xd0 [4.437229] __device_attach+0xd0/0x19c [4.437243] device_initial_probe+0x14/0x20 [4.437256] bus_probe_device+0x34/0x98 [4.437268] deferred_probe_work_func+0x88/0xc4 [4.437282] process_one_work+0x1cc/0x2c8 [4.437295] worker_thread+0x248/0x458 [4.437304] kthread+0xec/0x198 [4.437319] ret_from_fork+0x10/0x20 [4.437333] ---[ end trace ]--- After bisecting the problem, I was able to detect that the warning started to appear on the commit 37c90d589dc0 ("drm/fb-helper: Fix single-probe color-format selection"). Do you have any idea on what might be causing this warning? Best Regards, - Maíra Canal
Re: [PATCH v2] drm/amdgpu: Retry DDC probing on DVI on failure if we got an HPD interrupt
On Fri, Dec 23, 2022 at 9:23 AM xurui wrote: > > HPD signals on DVI ports can be fired off before the pins required for > DDC probing actually make contact, due to the pins for HPD making > contact first. This results in a HPD signal being asserted but DDC > probing failing, resulting in hotplugging occasionally failing. > > Rescheduling the hotplug work for a second when we run into an HPD > signal with a failing DDC probe usually gives enough time for the rest > of the connector's pins to make contact, and fixes this issue. > > Signed-off-by: xurui > Reported-by: kernel test robot Applied. Thanks! Alex > --- > V1 -> V2: Fixed a compilation error > > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- > .../gpu/drm/amd/amdgpu/amdgpu_connectors.c| 22 ++- > drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 1 + > drivers/gpu/drm/amd/amdgpu/dce_v10_0.c| 6 ++--- > drivers/gpu/drm/amd/amdgpu/dce_v11_0.c| 6 ++--- > drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 6 ++--- > drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 6 ++--- > 8 files changed, 36 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 6b74df446694..b1d901fe578e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -870,7 +870,7 @@ struct amdgpu_device { > struct amdgpu_vkms_output *amdgpu_vkms_output; > struct amdgpu_mode_info mode_info; > /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ > - struct work_struct hotplug_work; > + struct delayed_work hotplug_work; > struct amdgpu_irq_src crtc_irq; > struct amdgpu_irq_src vline0_irq; > struct amdgpu_irq_src vupdate_irq; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > index 2ebbc6382a06..d2abd334b1b5 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > @@ -996,13 +996,33 @@ amdgpu_connector_dvi_detect(struct drm_connector > *connector, bool force) > } > } > > + if (amdgpu_connector->detected_hpd_without_ddc) { > + force = true; > + amdgpu_connector->detected_hpd_without_ddc = false; > + } > + > if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) > { > ret = connector->status; > goto exit; > } > > - if (amdgpu_connector->ddc_bus) > + if (amdgpu_connector->ddc_bus) { > dret = amdgpu_display_ddc_probe(amdgpu_connector, false); > + > + /* Sometimes the pins required for the DDC probe on DVI > +* connectors don't make contact at the same time that the > ones > +* for HPD do. If the DDC probe fails even though we had an > HPD > +* signal, try again later > +*/ > + if (!dret && !force && > + amdgpu_display_hpd_sense(adev, > amdgpu_connector->hpd.hpd)) { > + DRM_DEBUG_KMS("hpd detected without ddc, retrying in > 1 second\n"); > + amdgpu_connector->detected_hpd_without_ddc = true; > + schedule_delayed_work(>hotplug_work, > + msecs_to_jiffies(1000)); > + goto exit; > + } > + } > if (dret) { > amdgpu_connector->detected_by_load = false; > amdgpu_connector_free_edid(connector); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c > index b22471b3bd63..a876648e3d7a 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c > @@ -63,7 +63,7 @@ > void amdgpu_display_hotplug_work_func(struct work_struct *work) > { > struct amdgpu_device *adev = container_of(work, struct amdgpu_device, > - hotplug_work); > + hotplug_work.work); > struct drm_device *dev = adev_to_drm(adev); > struct drm_mode_config *mode_config = >mode_config; > struct drm_connector *connector; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > index 8a39300b1a84..93c73faa5714 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > @@ -534,6 +534,7 @@ struct amdgpu_connector { > void *con_priv; > bool dac_load_detect; > bool detected_by_load; /* if the connection status was determined by > load */ > + bool
Re: [PATCH V7 3/4] drm/panel: Add Magnachip D53E6EA8966 Panel Driver
Hi Chris. On Tue, Jan 03, 2023 at 01:07:06PM -0600, Chris Morgan wrote: > From: Chris Morgan > > Support Magnachip D53E6EA8966 based panels such as the Samsung > AMS495QA01 panel as found on the Anbernic RG503. Note this driver > supports only the AMS495QA01 today which receives video signals via DSI, > however it receives commands via 3-wire SPI using DBI. > > Signed-off-by: Chris Morgan > Signed-off-by: Maya Matuszczyk > Reviewed-by: Linus Walleij Sorry for being late with my feedback - I have not had any linux bandwidth lately. See a few comments in the following. Mostly, I am concerned that backlight does not work in an optimal way. Sam > --- > drivers/gpu/drm/panel/Kconfig | 11 + > drivers/gpu/drm/panel/Makefile| 1 + > .../drm/panel/panel-magnachip-d53e6ea8966.c | 514 ++ > 3 files changed, 526 insertions(+) > create mode 100644 drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index 737edcdf9eef..204b84a83604 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -298,6 +298,17 @@ config DRM_PANEL_LG_LG4573 > Say Y here if you want to enable support for LG4573 RGB panel. > To compile this driver as a module, choose M here. > > +config DRM_PANEL_MAGNACHIP_D53E6EA8966 > + tristate "Magnachip D53E6EA8966 DSI panel" > + depends on OF && SPI > + depends on DRM_MIPI_DSI > + depends on BACKLIGHT_CLASS_DEVICE > + select DRM_MIPI_DBI > + help > + DRM panel driver for the Samsung AMS495QA01 panel controlled > + with the Magnachip D53E6EA8966 panel IC. This panel receives > + video data via DSI but commands via 9-bit SPI using DBI. > + > config DRM_PANEL_NEC_NL8048HL11 > tristate "NEC NL8048HL11 RGB panel" > depends on GPIOLIB && OF && SPI > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index f8f9d9f6a307..20de312aa5e9 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += > panel-leadtek-ltk050h3146w.o > obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o > obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o > obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o > +obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += > panel-magnachip-d53e6ea8966.o > obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o > obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o > obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o > diff --git a/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c > b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c > new file mode 100644 > index ..ec90da8e2ae7 > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c > @@ -0,0 +1,514 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Magnachip d53e6ea8966 MIPI-DSI panel driver > + * Copyright (C) 2022 Chris Morgan 2023 > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +/* Forward declaration for use in backlight function */ > +struct d53e6ea8966; > + > +/* Panel info, unique to each panel */ > +struct d53e6ea8966_panel_info { > + /** @display_modes: the supported display modes */ > + const struct drm_display_mode *display_modes; > + /** @num_modes: the number of supported display modes */ > + unsigned int num_modes; > + /** @width_mm: panel width in mm */ > + u16 width_mm; > + /** @height_mm: panel height in mm */ > + u16 height_mm; > + /** @bus_flags: drm bus flags for panel */ > + u32 bus_flags; > + /** @panel_funcs: panel functions for panel */ > + const struct drm_panel_funcs *panel_funcs; I can see that the prepare function is panel specific, the rest looks like they are controller specific. I suggest to refactor out the panel specifics in the prepare function, and have this as the only function pointer. The other operations in drm_panel_funcs are all controller specific and there should be no need to set them depending on the panel. > + /** @backlight: panel backlight registration or NULL */ > + int (*backlight_register)(struct d53e6ea8966 *db); > +}; > + > +struct d53e6ea8966 { > + /** @dev: the container device */ > + struct device *dev; > + /** @dbi: the DBI bus abstraction handle */ > + struct mipi_dbi dbi; > + /** @panel: the DRM panel instance for this device */ > + struct drm_panel panel; > + /** @reset: reset GPIO line */ > + struct gpio_desc *reset; > + /** @enable: enable GPIO line */ > + struct gpio_desc *enable; > + /**
Re: [PULL] drm-misc-next-fixes
On Tue, Jan 03, 2023 at 03:49:26PM +0100, Maxime Ripard wrote: > Hi Daniel, Dave, > > Here's the drm-misc-next-fixes leftovers. > > Maxime > > drm-misc-next-fixes-2023-01-03: > The drm-misc-next-fixes leftovers. It addresses a bug in drm/scheduler > ending up causing a lockup, and reduces the stack usage of some drm/mm > kunit tests. > The following changes since commit b02897e56b4e1fa6445be695ce5d605bb098435c: > > Revert "drm/fb-helper: Perform damage handling in deferred-I/O helper" > (2022-11-23 09:11:32 +0100) > > are available in the Git repository at: > > git://anongit.freedesktop.org/drm/drm-misc > tags/drm-misc-next-fixes-2023-01-03 Thanks, pulled. -Daniel > > for you to fetch changes up to 03dec92c4f788c54a7c01b40a018f601eb8a6c52: > > drm/scheduler: Fix lockup in drm_sched_entity_kill() (2023-01-02 17:45:18 > +0300) > > > The drm-misc-next-fixes leftovers. It addresses a bug in drm/scheduler > ending up causing a lockup, and reduces the stack usage of some drm/mm > kunit tests. > > > Arnd Bergmann (1): > drm/tests: reduce drm_mm_test stack usage > > Dmitry Osipenko (1): > drm/scheduler: Fix lockup in drm_sched_entity_kill() > > drivers/gpu/drm/scheduler/sched_entity.c | 2 +- > drivers/gpu/drm/scheduler/sched_main.c | 4 ++-- > drivers/gpu/drm/tests/Makefile | 2 ++ > drivers/gpu/drm/tests/drm_mm_test.c | 6 +++--- > 4 files changed, 8 insertions(+), 6 deletions(-) -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [Intel-gfx] [PATCH 2/2] drm/i915: Consolidate TLB invalidation flow
On Mon, Dec 19, 2022 at 05:10:02PM +0100, Andrzej Hajda wrote: > On 19.12.2022 11:13, Tvrtko Ursulin wrote: > > From: Tvrtko Ursulin > > > > As the logic for selecting the register and corresponsing values grew, the > > corresponding > > > code become a bit unsightly. Consolidate by storing the required values at > > engine init time in the engine itself, and by doing so minimise the amount > > of invariant platform and engine checks during each and every TLB > > invalidation. > > > > v2: > > * Fail engine probe if TLB invlidations registers are unknown. > > > > Signed-off-by: Tvrtko Ursulin > > Cc: Andrzej Hajda > > Cc: Matt Roper > > Reviewed-by: Andrzej Hajda # v1 > > --- > > drivers/gpu/drm/i915/gt/intel_engine_cs.c| 93 + > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 15 +++ > > drivers/gpu/drm/i915/gt/intel_gt.c | 135 +++ > > 3 files changed, 128 insertions(+), 115 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > index 99c4b866addd..d47dadfc25c8 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > @@ -1143,12 +1143,105 @@ static int init_status_page(struct intel_engine_cs > > *engine) > > return ret; > > } > > +static int intel_engine_init_tlb_invalidation(struct intel_engine_cs > > *engine) > > +{ > > + static const union intel_engine_tlb_inv_reg gen8_regs[] = { > > + [RENDER_CLASS].reg = GEN8_RTCR, > > + [VIDEO_DECODE_CLASS].reg= GEN8_M1TCR, /* , GEN8_M2TCR */ > > + [VIDEO_ENHANCEMENT_CLASS].reg = GEN8_VTCR, > > + [COPY_ENGINE_CLASS].reg = GEN8_BTCR, > > + }; > > + static const union intel_engine_tlb_inv_reg gen12_regs[] = { > > + [RENDER_CLASS].reg = GEN12_GFX_TLB_INV_CR, > > + [VIDEO_DECODE_CLASS].reg= GEN12_VD_TLB_INV_CR, > > + [VIDEO_ENHANCEMENT_CLASS].reg = GEN12_VE_TLB_INV_CR, > > + [COPY_ENGINE_CLASS].reg = GEN12_BLT_TLB_INV_CR, > > + [COMPUTE_CLASS].reg = GEN12_COMPCTX_TLB_INV_CR, > > + }; > > + static const union intel_engine_tlb_inv_reg xehp_regs[] = { > > + [RENDER_CLASS].mcr_reg= XEHP_GFX_TLB_INV_CR, > > + [VIDEO_DECODE_CLASS].mcr_reg = XEHP_VD_TLB_INV_CR, > > + [VIDEO_ENHANCEMENT_CLASS].mcr_reg = XEHP_VE_TLB_INV_CR, > > + [COPY_ENGINE_CLASS].mcr_reg = XEHP_BLT_TLB_INV_CR, > > + [COMPUTE_CLASS].mcr_reg = XEHP_COMPCTX_TLB_INV_CR, > > + }; > > + struct drm_i915_private *i915 = engine->i915; > > + const union intel_engine_tlb_inv_reg *regs; > > + union intel_engine_tlb_inv_reg reg; > > + unsigned int class = engine->class; > > + unsigned int num = 0; > > + u32 val; > > + > > + /* > > +* New platforms should not be added with catch-all-newer (>=) > > +* condition so that any later platform added triggers the below warning > > +* and in turn mandates a human cross-check of whether the invalidation > > +* flows have compatible semantics. > > +* > > +* For instance with the 11.00 -> 12.00 transition three out of five > > +* respective engine registers were moved to masked type. Then after the > > +* 12.00 -> 12.50 transition multi cast handling is required too. > > +*/ > > + > > + if (GRAPHICS_VER_FULL(i915) == IP_VER(12, 50)) { This is bad...it only captures XEHPSDV and breaks the handling of DG2 (12.55), PVC (12.60), and MTL (12.70, 12.71, and 12.72). You're not hitting the warning as expected since those are all now being captured by the next case of the if/else ladder. With the way GMD_ID works, we may also get new version numbers that silently show up in hardware too at some point (e.g., 12.73, 12.74, etc.) > > + regs = xehp_regs; > > + num = ARRAY_SIZE(xehp_regs); > > + } else if (GRAPHICS_VER(i915) == 12) { You'd want to change this to GRAPHICS_VER_FULL(i915) == IP_VER(12, 0) to get the behavior you expected. Matt > > + regs = gen12_regs; > > + num = ARRAY_SIZE(gen12_regs); > > + } else if (GRAPHICS_VER(i915) >= 8 && GRAPHICS_VER(i915) <= 11) { > > + regs = gen8_regs; > > + num = ARRAY_SIZE(gen8_regs); > > + } else if (GRAPHICS_VER(i915) < 8) { > > + return 0; > > + } > + > > + if (drm_WARN_ONCE(>drm, !num, > > + "Platform does not implement TLB invalidation!")) > > + return -ENODEV; > > + > > + if (drm_WARN_ON_ONCE(>drm, > > +class >= num || > > +(!regs[class].reg.reg && > > + !regs[class].mcr_reg.reg))) > > + return -ERANGE; > > I hope the propagation of -ERANGE to device probe is OK. > > Reviewed-by: Andrzej Hajda > > Regards > Andrzej > > > + > > +
Re: [PATCH V7 1/4] drm: of: Add drm_of_get_dsi_bus helper function
Hi Chris. On Tue, Jan 03, 2023 at 01:07:04PM -0600, Chris Morgan wrote: > From: Chris Morgan > > Add helper function to find DSI host for devices where DSI panel is not > a minor of a DSI bus (such as the Samsung AMS495QA01 panel or the > official Raspberry Pi touchscreen display). > > Signed-off-by: Chris Morgan > Signed-off-by: Maya Matuszczyk > Reviewed-by: Linus Walleij > --- > drivers/gpu/drm/drm_of.c | 62 > include/drm/drm_of.h | 11 +++ > 2 files changed, 73 insertions(+) > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > index 7bbcb999bb75..7d89ac164069 100644 > --- a/drivers/gpu/drm/drm_of.c > +++ b/drivers/gpu/drm/drm_of.c > @@ -10,6 +10,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -493,3 +494,64 @@ int drm_of_get_data_lanes_count_ep(const struct > device_node *port, > return ret; > } > EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep); > + > +/** > + * drm_of_get_dsi_bus - find the DSI bus for a given device > + * @dev: parent device of display (SPI, I2C) > + * @dsi_host: DSI host to be populated > + * @info: DSI device info to be updated with correct DSI node > + * > + * Given a panel device parented to a non-DSI device, follow the > + * devicetree to find the correct DSI host node and populate the > + * dsi_host with the correct host and info with the correct node. I think you need and empty line before Returns ... This is what others does in the same file, so for consistency please add it. With this detail fixed: Reviewed-by: Sam Ravnborg > + * Returns zero if successful, -EPROBE_DEFER if the DSI host is > + * found but not available, or -ENODEV otherwise. > + */ > +int drm_of_get_dsi_bus(struct device *dev, > + struct mipi_dsi_host **dsi_host, > + struct mipi_dsi_device_info *info) > +{ > + struct device_node *endpoint, *dsi_host_node; > + > + /* > + * Get first endpoint child from device. > + */ > + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); > + if (!endpoint) > + return -ENODEV; > + > + /* > + * Follow the first endpoint to get the DSI host node. > + */ > + dsi_host_node = of_graph_get_remote_port_parent(endpoint); > + if (!dsi_host_node) > + goto error; > + > + /* > + * Get the DSI host from the DSI host node. If we get an error > + * or the return is null assume we're not ready to probe just > + * yet. Release the DSI host node since we're done with it. > + */ > + *dsi_host = of_find_mipi_dsi_host_by_node(dsi_host_node); > + of_node_put(dsi_host_node); > + if (IS_ERR_OR_NULL(*dsi_host)) { > + of_node_put(endpoint); > + return -EPROBE_DEFER; > + } > + > + /* > + * Set the node of the mipi_dsi_device_info to the correct node > + * and then release the endpoint node since we're done with it. > + */ > + info->node = of_graph_get_remote_port(endpoint); > + if (IS_ERR_OR_NULL(info->node)) > + goto error; > + > + of_node_put(endpoint); > + return 0; > + > +error: > + of_node_put(endpoint); > + return -ENODEV; > +} > +EXPORT_SYMBOL_GPL(drm_of_get_dsi_bus); > diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h > index 10ab58c40746..e27061b02315 100644 > --- a/include/drm/drm_of.h > +++ b/include/drm/drm_of.h > @@ -15,6 +15,8 @@ struct drm_encoder; > struct drm_panel; > struct drm_bridge; > struct device_node; > +struct mipi_dsi_device_info; > +struct mipi_dsi_host; > > /** > * enum drm_lvds_dual_link_pixels - Pixel order of an LVDS dual-link > connection > @@ -56,6 +58,9 @@ int drm_of_get_data_lanes_count_ep(const struct device_node > *port, > int port_reg, int reg, > const unsigned int min, > const unsigned int max); > +int drm_of_get_dsi_bus(struct device *dev, > +struct mipi_dsi_host **dsi_host, > +struct mipi_dsi_device_info *info); > #else > static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev, > struct device_node *port) > @@ -127,6 +132,12 @@ drm_of_get_data_lanes_count_ep(const struct device_node > *port, > { > return -EINVAL; > } > +static int drm_of_get_dsi_bus(struct device *dev, > + struct mipi_dsi_host **dsi_host, > + struct mipi_dsi_device_info *info) > +{ > + return -EINVAL; > +} > #endif > > /* > -- > 2.34.1
Re: [PATCH] drm/v3d: replace open-coded implementation of drm_gem_object_lookup
On 12/28, Melissa Wen wrote: > On 12/27, Maíra Canal wrote: > > As v3d_submit_tfu_ioctl() performs the same steps as > > drm_gem_object_lookup(), > > replace the open-code implementation in v3d with its DRM core equivalent. > > > > Signed-off-by: Maíra Canal > > --- > > drivers/gpu/drm/v3d/v3d_gem.c | 7 +-- > > 1 file changed, 1 insertion(+), 6 deletions(-) > > > > diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c > > index 6e152ef26358..5da1806f3969 100644 > > --- a/drivers/gpu/drm/v3d/v3d_gem.c > > +++ b/drivers/gpu/drm/v3d/v3d_gem.c > > @@ -861,7 +861,6 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, > > > > job->args = *args; > > > > - spin_lock(_priv->table_lock); > > for (job->base.bo_count = 0; > > job->base.bo_count < ARRAY_SIZE(args->bo_handles); > > job->base.bo_count++) { > > @@ -870,20 +869,16 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void > > *data, > > if (!args->bo_handles[job->base.bo_count]) > > break; > > > > - bo = idr_find(_priv->object_idr, > > - args->bo_handles[job->base.bo_count]); > > + bo = drm_gem_object_lookup(file_priv, > > args->bo_handles[job->base.bo_count]); > > if (!bo) { > > DRM_DEBUG("Failed to look up GEM BO %d: %d\n", > > job->base.bo_count, > > args->bo_handles[job->base.bo_count]); > > ret = -ENOENT; > > - spin_unlock(_priv->table_lock); > > goto fail; > > } > > - drm_gem_object_get(bo); > > job->base.bo[job->base.bo_count] = bo; > > } > > - spin_unlock(_priv->table_lock); > > Hi Maíra, > > Thanks for you patch. > > LGTM > > Reviewed-by: Melissa Wen Applied to drm-misc-next. Thanks, Melissa > > > > > ret = v3d_lock_bo_reservations(>base, _ctx); > > if (ret) > > -- > > 2.38.1 > > signature.asc Description: PGP signature
[PATCH V7 3/4] drm/panel: Add Magnachip D53E6EA8966 Panel Driver
From: Chris Morgan Support Magnachip D53E6EA8966 based panels such as the Samsung AMS495QA01 panel as found on the Anbernic RG503. Note this driver supports only the AMS495QA01 today which receives video signals via DSI, however it receives commands via 3-wire SPI using DBI. Signed-off-by: Chris Morgan Signed-off-by: Maya Matuszczyk Reviewed-by: Linus Walleij --- drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-magnachip-d53e6ea8966.c | 514 ++ 3 files changed, 526 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 737edcdf9eef..204b84a83604 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -298,6 +298,17 @@ config DRM_PANEL_LG_LG4573 Say Y here if you want to enable support for LG4573 RGB panel. To compile this driver as a module, choose M here. +config DRM_PANEL_MAGNACHIP_D53E6EA8966 + tristate "Magnachip D53E6EA8966 DSI panel" + depends on OF && SPI + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select DRM_MIPI_DBI + help + DRM panel driver for the Samsung AMS495QA01 panel controlled + with the Magnachip D53E6EA8966 panel IC. This panel receives + video data via DSI but commands via 9-bit SPI using DBI. + config DRM_PANEL_NEC_NL8048HL11 tristate "NEC NL8048HL11 RGB panel" depends on GPIOLIB && OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index f8f9d9f6a307..20de312aa5e9 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o +obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += panel-magnachip-d53e6ea8966.o obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o diff --git a/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c new file mode 100644 index ..ec90da8e2ae7 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c @@ -0,0 +1,514 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Magnachip d53e6ea8966 MIPI-DSI panel driver + * Copyright (C) 2022 Chris Morgan + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Forward declaration for use in backlight function */ +struct d53e6ea8966; + +/* Panel info, unique to each panel */ +struct d53e6ea8966_panel_info { + /** @display_modes: the supported display modes */ + const struct drm_display_mode *display_modes; + /** @num_modes: the number of supported display modes */ + unsigned int num_modes; + /** @width_mm: panel width in mm */ + u16 width_mm; + /** @height_mm: panel height in mm */ + u16 height_mm; + /** @bus_flags: drm bus flags for panel */ + u32 bus_flags; + /** @panel_funcs: panel functions for panel */ + const struct drm_panel_funcs *panel_funcs; + /** @backlight: panel backlight registration or NULL */ + int (*backlight_register)(struct d53e6ea8966 *db); +}; + +struct d53e6ea8966 { + /** @dev: the container device */ + struct device *dev; + /** @dbi: the DBI bus abstraction handle */ + struct mipi_dbi dbi; + /** @panel: the DRM panel instance for this device */ + struct drm_panel panel; + /** @reset: reset GPIO line */ + struct gpio_desc *reset; + /** @enable: enable GPIO line */ + struct gpio_desc *enable; + /** @reg_vdd: VDD supply regulator for panel logic */ + struct regulator *reg_vdd; + /** @reg_elvdd: ELVDD supply regulator for panel display */ + struct regulator *reg_elvdd; + /** @dsi_dev: DSI child device (panel) */ + struct mipi_dsi_device *dsi_dev; + /** @bl_dev: pseudo-backlight device for oled panel */ + struct backlight_device *bl_dev; + /** @panel_info: struct containing panel timing and info */ + const struct d53e6ea8966_panel_info *panel_info; +}; + +#define NUM_GAMMA_LEVELS 16 +#define GAMMA_TABLE_COUNT 23 +#define MAX_BRIGHTNESS (NUM_GAMMA_LEVELS - 1) + +#define MCS_ELVSS_ON 0xb1 +#define MCS_TEMP_SWIRE 0xb2 +#define MCS_PASSWORD_0 0xf0 +#define MCS_PASSWORD_1
[PATCH V7 4/4] arm64: dts: rockchip: add display to RG503
From: Chris Morgan Add Samsung AMS495QA01 panel to RG503. Signed-off-by: Chris Morgan Signed-off-by: Maya Matuszczyk --- .../dts/rockchip/rk3566-anbernic-rg503.dts| 55 +++ 1 file changed, 55 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts index 5dafcc86296b..b4b2df821cba 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts +++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts @@ -47,6 +47,21 @@ gpio_spi: spi { mosi-gpios = < RK_PB0 GPIO_ACTIVE_HIGH>; cs-gpios = < RK_PA7 GPIO_ACTIVE_HIGH>; num-chipselects = <0>; + + panel@0 { + compatible = "samsung,ams495qa01"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <_reset>; + reset-gpios = < RK_PA0 GPIO_ACTIVE_LOW>; + vdd-supply = <_3v3>; + + port { + mipi_in_panel: endpoint { + remote-endpoint = <_out_panel>; + }; + }; + }; }; /* Channels reversed for both headphones and speakers. */ @@ -94,6 +109,32 @@ { assigned-clock-rates = <12>, <2>, <5>; }; +_dphy0 { + status = "okay"; +}; + + { + status = "okay"; + + ports { + dsi0_in: port@0 { + reg = <0>; + + dsi0_in_vp1: endpoint { + remote-endpoint = <_out_dsi0>; + }; + }; + + dsi0_out: port@1 { + reg = <1>; + + mipi_out_panel: endpoint { + remote-endpoint = <_in_panel>; + }; + }; + }; +}; + _keys_control { button-a { gpios = < RK_PC1 GPIO_ACTIVE_LOW>; @@ -146,6 +187,13 @@ spk_amp_enable_h: spk-amp-enable-h { }; }; + gpio-lcd { + lcd_reset: lcd-reset { + rockchip,pins = + <4 RK_PA0 RK_FUNC_GPIO _pull_none>; + }; + }; + gpio-spi { spi_pins: spi-pins { rockchip,pins = @@ -164,3 +212,10 @@ rk817_charger: charger { rockchip,sleep-filter-current-microamp = <10>; }; }; + + { + vp1_out_dsi0: endpoint@ROCKCHIP_VOP2_EP_MIPI0 { + reg = ; + remote-endpoint = <_in_vp1>; + }; +}; -- 2.34.1
[PATCH V7 1/4] drm: of: Add drm_of_get_dsi_bus helper function
From: Chris Morgan Add helper function to find DSI host for devices where DSI panel is not a minor of a DSI bus (such as the Samsung AMS495QA01 panel or the official Raspberry Pi touchscreen display). Signed-off-by: Chris Morgan Signed-off-by: Maya Matuszczyk Reviewed-by: Linus Walleij --- drivers/gpu/drm/drm_of.c | 62 include/drm/drm_of.h | 11 +++ 2 files changed, 73 insertions(+) diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 7bbcb999bb75..7d89ac164069 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -493,3 +494,64 @@ int drm_of_get_data_lanes_count_ep(const struct device_node *port, return ret; } EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep); + +/** + * drm_of_get_dsi_bus - find the DSI bus for a given device + * @dev: parent device of display (SPI, I2C) + * @dsi_host: DSI host to be populated + * @info: DSI device info to be updated with correct DSI node + * + * Given a panel device parented to a non-DSI device, follow the + * devicetree to find the correct DSI host node and populate the + * dsi_host with the correct host and info with the correct node. + * Returns zero if successful, -EPROBE_DEFER if the DSI host is + * found but not available, or -ENODEV otherwise. + */ +int drm_of_get_dsi_bus(struct device *dev, + struct mipi_dsi_host **dsi_host, + struct mipi_dsi_device_info *info) +{ + struct device_node *endpoint, *dsi_host_node; + + /* +* Get first endpoint child from device. +*/ + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); + if (!endpoint) + return -ENODEV; + + /* +* Follow the first endpoint to get the DSI host node. +*/ + dsi_host_node = of_graph_get_remote_port_parent(endpoint); + if (!dsi_host_node) + goto error; + + /* +* Get the DSI host from the DSI host node. If we get an error +* or the return is null assume we're not ready to probe just +* yet. Release the DSI host node since we're done with it. +*/ + *dsi_host = of_find_mipi_dsi_host_by_node(dsi_host_node); + of_node_put(dsi_host_node); + if (IS_ERR_OR_NULL(*dsi_host)) { + of_node_put(endpoint); + return -EPROBE_DEFER; + } + + /* +* Set the node of the mipi_dsi_device_info to the correct node +* and then release the endpoint node since we're done with it. +*/ + info->node = of_graph_get_remote_port(endpoint); + if (IS_ERR_OR_NULL(info->node)) + goto error; + + of_node_put(endpoint); + return 0; + +error: + of_node_put(endpoint); + return -ENODEV; +} +EXPORT_SYMBOL_GPL(drm_of_get_dsi_bus); diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 10ab58c40746..e27061b02315 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -15,6 +15,8 @@ struct drm_encoder; struct drm_panel; struct drm_bridge; struct device_node; +struct mipi_dsi_device_info; +struct mipi_dsi_host; /** * enum drm_lvds_dual_link_pixels - Pixel order of an LVDS dual-link connection @@ -56,6 +58,9 @@ int drm_of_get_data_lanes_count_ep(const struct device_node *port, int port_reg, int reg, const unsigned int min, const unsigned int max); +int drm_of_get_dsi_bus(struct device *dev, + struct mipi_dsi_host **dsi_host, + struct mipi_dsi_device_info *info); #else static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev, struct device_node *port) @@ -127,6 +132,12 @@ drm_of_get_data_lanes_count_ep(const struct device_node *port, { return -EINVAL; } +static int drm_of_get_dsi_bus(struct device *dev, + struct mipi_dsi_host **dsi_host, + struct mipi_dsi_device_info *info) +{ + return -EINVAL; +} #endif /* -- 2.34.1
[PATCH V7 2/4] dt-bindings: display: panel: Add Samsung AMS495QA01
From: Chris Morgan Add documentation for Samsung AMS495QA01 panel (with Magnachip D53E6EA8966 controller IC). Signed-off-by: Chris Morgan Signed-off-by: Maya Matuszczyk --- .../display/panel/samsung,ams495qa01.yaml | 57 +++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml diff --git a/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml b/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml new file mode 100644 index ..58fa073ce258 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,ams495qa01.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung AMS495QA01 panel with Magnachip D53E6EA8966 controller + +maintainers: + - Chris Morgan + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: samsung,ams495qa01 + + reg: true + reset-gpios: +description: reset gpio, must be GPIO_ACTIVE_LOW + elvdd-supply: +description: regulator that supplies voltage to the panel display + enable-gpios: true + port: true + vdd-supply: +description: regulator that supplies voltage to panel logic + +required: + - compatible + - reg + - reset-gpios + - vdd-supply + +additionalProperties: false + +examples: + - | +#include +spi { +#address-cells = <1>; +#size-cells = <0>; +panel@0 { +compatible = "samsung,ams495qa01"; +reg = <0>; +reset-gpios = < 0 GPIO_ACTIVE_LOW>; +vdd-supply = <_3v3>; + +port { +mipi_in_panel: endpoint { + remote-endpoint = <_out_panel>; +}; +}; +}; +}; + +... -- 2.34.1
[PATCH v7 0/4] drm/panel: Add Magnachip D53E6EA8966 Panel Controller
From: Chris Morgan Add the Magnachip D53E6EA8966 panel IC controller for display panels such as the Samsung AMS495QA01 panel as found on the Anbernic RG503. This panel uses DSI to receive video signals, but 3-wire SPI to receive command signals using DBI. Changes since V6: - Fixed a trivial error with definition of drm_of_get_dsi_bus(). Reported-by: kernel test robot Changes since V5: - Reverted dt binding documentation name back to samsung,ams495qa01.yaml. - Removed no longer needed of_graph.h header file. - Added backlight as a dependency. Changes since V4: - Renamed driver from the panel model to the panel IC controller per DRM team. - Added a drm_of helper function of drm_of_get_dsi_bus() to handle finding and populating the DSI node when the DSI node is not the parent of the DSI controlled display. - Converted the documented commands to constants to make it more readable. - Reset GPIO is now required and documented as GPIO_ACTIVE_LOW. - Removed "prepared" logic from panel. Changes since V3: - Updated documentation to add spi-peripheral-props.yaml per updates made for similar devices. Note that I removed a "Reviewed-by" tag from Rob Herring since this change probably needs to be confirmed. - Added binding for RG503, since this device is now accepted with this request: https://lore.kernel.org/linux-rockchip/166274831283.21181.6861718157177507544.b4...@sntech.de/ Changes since V2: - Added 50hz mode at request of userspace devs. - Renamed "dupa" to panel name. Good catch Maya. - Added Maya's Signed-off-by. - Removed check for max backlight, since it is already done by backlight_device_set_brightness. - Fixed minor formatting issues on devicetree binding documentation and added port to provided example. Changes since V1: - Removed errant reference to backlight in documentation. This is an OLED panel. - Made elvss regulator optional. In my case its hard wired and not controllable. - Added "prepared" enum to track panel status to prevent unbalanced regulator enable/disable. Chris Morgan (4): drm: of: Add drm_of_get_dsi_bus helper function dt-bindings: display: panel: Add Samsung AMS495QA01 drm/panel: Add Magnachip D53E6EA8966 Panel Driver arm64: dts: rockchip: add display to RG503 .../display/panel/samsung,ams495qa01.yaml | 57 ++ .../dts/rockchip/rk3566-anbernic-rg503.dts| 55 ++ drivers/gpu/drm/drm_of.c | 62 +++ drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-magnachip-d53e6ea8966.c | 514 ++ include/drm/drm_of.h | 11 + 7 files changed, 711 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml create mode 100644 drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c -- 2.34.1
[PATCH AUTOSEL 6.1 04/10] drm/amd/display: Report to ACPI video if no panels were found
From: Mario Limonciello [ Upstream commit c573e240609ff781a0246c0c8c8351abd0475287 ] On desktop APUs amdgpu doesn't create a native backlight device as no eDP panels are found. However if the BIOS has reported backlight control methods in the ACPI tables then an acpi_video0 backlight device will be made 8 seconds after boot. This has manifested in a power slider on a number of desktop APUs ranging from Ryzen 5000 through Ryzen 7000 on various motherboard manufacturers. To avoid this, report to the acpi video detection that the system does not have any panel connected in the native driver. Link: https://bugzilla.redhat.com/show_bug.cgi?id=1783786 Reported-by: Hans de Goede Signed-off-by: Mario Limonciello Reviewed-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 512c32327eb1..b73f61ac5dd5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4371,6 +4371,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) amdgpu_set_panel_orientation(>base); } + /* If we didn't find a panel, notify the acpi video detection */ + if (dm->adev->flags & AMD_IS_APU && dm->num_of_edps == 0) + acpi_video_report_nolcd(); + /* Software is initialized. Now we can register interrupt handlers. */ switch (adev->asic_type) { #if defined(CONFIG_DRM_AMD_DC_SI) -- 2.35.1
Re: [PATCH] drm/docs: Explicitly document default CRTC background behavior
Nice! Reviewed-by: Simon Ser
Re: [PATCH 2/2] drm/panel: add visionox vtdr6130 DSI panel driver
Hi Neil, On Tue, Jan 03, 2023 at 03:22:28PM +0100, Neil Armstrong wrote: > Add support for the 1080x2400 Visionox VTDR6130 AMOLED DSI panel > found on the Qualcomm SM8550 MTP board. > > By default the the panel is configured to work with DSI compressed > streams, but can work in uncompressed video mode since 1080x2400 in > RGB888 fits in the 4 DSI lanes bandwidth. > > While display compression is preferred for performance and power > reasons, let's start with the uncompressed video mode support and > add the DSC support later on. > > Signed-off-by: Neil Armstrong a few comments in the following. Sam > --- > drivers/gpu/drm/panel/Kconfig | 8 + > drivers/gpu/drm/panel/Makefile | 1 + > drivers/gpu/drm/panel/panel-visionox-vtdr6130.c | 366 > > 3 files changed, 375 insertions(+) > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index 737edcdf9eef..fd1d7e6f536b 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -717,6 +717,14 @@ config DRM_PANEL_VISIONOX_RM69299 > Say Y here if you want to enable support for Visionox > RM69299 DSI Video Mode panel. > > +config DRM_PANEL_VISIONOX_VTDR6130 > + tristate "Visionox VTDR6130" > + depends on OF > + depends on DRM_MIPI_DSI > + help > + Say Y here if you want to enable support for Visionox > + VTDR6130 1080x2400 AMOLED DSI panel. > + > config DRM_PANEL_WIDECHIPS_WS2401 > tristate "Widechips WS2401 DPI panel driver" > depends on SPI && GPIOLIB > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index f8f9d9f6a307..1966404fcf7a 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -73,5 +73,6 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += > panel-tpo-td043mtea1.o > obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o > obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o > obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o > +obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o > obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o > obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o > diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c > b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c > new file mode 100644 > index ..94ad2a32efc9 > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c > @@ -0,0 +1,366 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +// Copyright (c) 2023, Linaro Limited > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include Keep linux includes in one block. > + > +struct visionox_vtdr6130 { > + struct drm_panel panel; > + struct mipi_dsi_device *dsi; > + struct gpio_desc *reset_gpio; > + struct regulator_bulk_data supplies[3]; > + bool prepared; > +}; > + > +static inline struct visionox_vtdr6130 *to_visionox_vtdr6130(struct > drm_panel *panel) > +{ > + return container_of(panel, struct visionox_vtdr6130, panel); > +} > + > +static inline int visionox_vtdr6130_dsi_write(struct mipi_dsi_device *dsi, > const void *seq, > + size_t len) > +{ > + return mipi_dsi_dcs_write_buffer(dsi, seq, len); > +} > + > +#define dsi_dcs_write_seq(dsi, seq...) > \ > + { \ > + const u8 d[] = { seq }; \ > + visionox_vtdr6130_dsi_write(dsi, d, ARRAY_SIZE(d)); \ > + } Please use mipi_dsi_dcs_write_seq() No need to add your own macros here. This will also add a little bit of error reporting that is missing here. > + > +static void visionox_vtdr6130_reset(struct visionox_vtdr6130 *ctx) > +{ > + gpiod_set_value_cansleep(ctx->reset_gpio, 0); > + usleep_range(1, 11000); > + gpiod_set_value_cansleep(ctx->reset_gpio, 1); > + usleep_range(1, 11000); > + gpiod_set_value_cansleep(ctx->reset_gpio, 0); > + usleep_range(1, 11000); > +} I have seen this pattern before - and I am still confused if the HW really requires the 0 => 1 => 0 sequence. I would expect writing 1 - wait and then writing 0 would do it. > + > +static int visionox_vtdr6130_on(struct visionox_vtdr6130 *ctx) > +{ > + struct mipi_dsi_device *dsi = ctx->dsi; > + struct device *dev = >dev; > + int ret; > + > + dsi->mode_flags |= MIPI_DSI_MODE_LPM; > + > + dsi_dcs_write_seq(dsi, 0x03, 0x01); MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM? > + dsi_dcs_write_seq(dsi, 0x35, 0x00); MIPI_DCS_SET_TEAR_ON? > + dsi_dcs_write_seq(dsi, 0x53, 0x20); MIPI_DCS_WRITE_CONTROL_DISPLAY? etc - use the MIPI_DCS commands, not just hex-values > +
Re: renesas/master bisection: igt-kms-rockchip.kms_vblank.pipe-A-wait-forked on rk3399-gru-kevin
On 12/21/22 23:02, Brian Norris wrote: > Hi Mark, Sean, (and dri-devel) > > On Wed, Dec 14, 2022 at 07:04:37PM -0800, Brian Norris wrote: >> On Tue, Dec 13, 2022 at 04:51:11PM +, Mark Brown wrote: >>> On Tue, Dec 13, 2022 at 05:56:30AM -0800, KernelCI bot wrote: >>> >>> The KernelCI bisection bot found regressions in at least two KMS tests >>> in the Renesas tree on rk3399-gru-kevin just after the Renesas tree >>> merged up mainline: >>> >>>igt-kms-rockchip.kms_vblank.pipe-A-wait-forked >>>igt-kms-rockchip.kms_vblank.pipe-A-query-busy >>> >>> which it bisected to ca871659ec16 ("drm/bridge: analogix_dp: Support >>> PSR-exit to disable transition"). I'm not *100%* sure I trust the >>> bisection but it sure is suspicous that two separate bisects for related >>> issues landed on the same commit. > > ... > >>> | IGT-Version: 1.26-gf8a4a0b (aarch64) (Linux: 6.1.0 aarch64) >>> | <14>[ 35.48] [IGT] drm_read: starting subtest short-buffer-wakeup >>> | Starting subtest: short-buffer-wakeup >>> | >>> | (| drm_read:350) CRITICAL: Test assertion failure function >>> generate_event, file ../tests/drm_read.c:65: >>> | (drm_read:350) CRITICAL: <14>[ 36.155642] [IGT] drm_read: exiting, >>> ret=98 >>> | Failed assertion: kmstest_get_vblank(fd, pipe, DRM_VBLANK_EVENT) >>> | >>> | (drm_read:350) CRITICAL: Last errno: 22, Invalid argument >>> | Stack trace: >>> | >>> | #0 ../lib/igt_core.c:1933 __igt_fail_assert() >>> | #1 [+0xd5362770] >>> | #2 [+0xd536193c] >>> | #3 [__libc_start_main+0xe8] >>> | #4 [+0xd5361974] >>> | #5 [[ 36.162851] Console: switching to colour frame buffer >>> device 300x100>+0xd5361974] >>> | Subtest short-buffer-wakeup failed. > > ... > >> I'll look some more, but this might be a difference of test setup, such >> that my setup has the issue before and after that commit, but your setup >> sees a regression. > > I believe this is the case; things are broken both before and after, but > depending on test sequencing, etc., they might have seemed less broken > before. > > When we're failing, we're getting EINVAL from drm_vblank_get(). That > essentially means that vblank has been disabled (drm_crtc_vblank_off()). > As it happens, this is exactly what we do when we enter PSR (Panel Self > Refresh). > > Now, these test cases (especially 'kms_vblank.pipe-A-wait-forked') seem > to display a static image, and then wait for a bunch of vblank events. > This is exactly the sort of case where we should enter PSR, and so we're > likely to disable vblank events. Thus, if everything is working right, > we will often hit EINVAL in ioctl(DRM_IOCTL_WAIT_VBLANK) ... -> > drm_vblank_get(), and fail the test. > > As to why this appears to be a regression: like mentioned in my previous > mail, these tests tend to hose the Analogix PSR state before my patch > set. When PSR is hosed, we tend to stay with PSR disabled, and so > drm_vblank_get() doesn't return EINVAL, and the test is happy. (Never > mind that the display is likely non-functional.) [0] > > So how to fix this? > > 1. ignore it; it's "just" a test failure, IIUC [1] > 2. change the test, to skip this test if the device has PSR > 3. leave vblank enabled even in the presence of PSR > 4. otherwise modify the vblank ioctl interface, such that one can "wait" >for a vblank that won't come (because the display is in self-refresh >/ there are no new frames or vblanks) FWIW, a couple more alternatives: 5. Go/stay out of PSR while vblank interrupts are enabled (probably want to make sure vblankoffdelay is set up such that vblank interrupts are disabled ASAP) 6. Use fallback timers for vblank events while in PSR (there might be some infrastructure for this, since some drivers don't have real vblank interrupts) > [1] Or is it? I don't really know the DRM_IOCTL_WAIT_VBLANK ABI > contract in the presence of PSR, but I believe the upstream PSR > support has always worked this way. I could imagine > DRM_IOCTL_WAIT_VBLANK users might not love seeing EINVAL here > though. Yeah, that's pretty likely to cause issues with existing real-world user space. -- Earthling Michel Dänzer| https://redhat.com Libre software enthusiast | Mesa and Xwayland developer
Re: [PATCH 1/2] dt-bindings: display: panel: document the Visionox VTDR6130 AMOLED DSI Panel bindings
Hi Neil, On Tue, Jan 03, 2023 at 03:22:27PM +0100, Neil Armstrong wrote: > Document the 1080x2400 Visionox VTDR6130 AMOLED DSI Panel bindings. > > Signed-off-by: Neil Armstrong > --- > .../bindings/display/panel/visionox,vtdr6130.yaml | 53 > ++ > 1 file changed, 53 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml > b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml > new file mode 100644 > index ..49e2fd4b4e99 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml > @@ -0,0 +1,53 @@ > +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/panel/visionox,vtdr6130.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Visionox VTDR6130 AMOLED DSI Panel > + > +maintainers: > + - Neil Armstrong > + > +allOf: > + - $ref: panel-common.yaml# > + > +properties: > + compatible: > +const: visionox,vtdr6130 > + > + vddio-supply: true > + vci-supply: true > + vdd-supply: true These 3 looks wrong to me, as the above are not documented in panel-common. But maybe I miss something and this is OK? Sam > + port: true > + reset-gpios: true > + > +additionalProperties: false > + > +required: > + - compatible > + - vddio-supply > + - vci-supply > + - vdd-supply > + - reset-gpios > + - port > + > +examples: > + - | > +#include > +panel { > +compatible = "visionox,vtdr6130"; > + > +vddio-supply = <_l12b_1p8>; > +vci-supply = <_l13b_3p0>; > +vdd-supply = <_l11b_1p2>; > + > +reset-gpios = < 133 GPIO_ACTIVE_LOW>; > + > +port { > +panel0_in: endpoint { > +remote-endpoint = <_out>; > +}; > +}; > +}; > +... > > -- > 2.34.1
Re: [PATCH] drm: Replace DRM_DEBUG with drm_dbg_core in file and ioctl handling
Pushed, thanks!
Re: [PATCH v16 1/5] arm64: dts: qcom: add data-lanes and link-freuencies into dp_out endpoint
Hi Krzysztof/Dmitry, Would you please review this patch. Thanks, On 12/27/2022 9:44 AM, Kuogee Hsieh wrote: Move data-lanes property from mdss_dp node to dp_out endpoint. Also add link-frequencies property into dp_out endpoint as well. The last frequency specified at link-frequencies will be the max link rate supported by DP. Changes in v5: -- revert changes at sc7180.dtsi and sc7280.dtsi -- add _out to sc7180-trogdor.dtsi and sc7280-herobrine.dtsi Changes in v6: -- add data-lanes and link-frequencies to yaml Changes in v7: -- change 16000 to 162000 -- separate yaml to different patch Changes in v8: -- correct Bjorn mail address to kernel.org Changes in v9: -- use symbol rate (hz) for link-frequencies at dp_out at sc7180_trogdor.dtsi Changes in v13: -- delete an extra space at data-lanes Changes in v15: -- replace space with tab at sc7180-trogdor.dtsi Changes in v16: -- rename dp_out with mdss_dp_Out and keep the order Signed-off-by: Kuogee Hsieh --- arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 4 arch/arm64/boot/dts/qcom/sc7180.dtsi | 2 +- arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 4 arch/arm64/boot/dts/qcom/sc7280.dtsi | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi index eae22e6..21fbaff 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -814,7 +814,11 @@ hp_i2c: { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <_hot_plug_det>; +}; + +_dp_out { data-lanes = <0 1>; + link-frequencies = /bits/ 64 <162000 27 54>; }; _adc { diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 58976a1b..0a90cce 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -3119,7 +3119,7 @@ port@1 { reg = <1>; - dp_out: endpoint { }; + mdss_dp_out: endpoint { }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi index c11e371..3f6f1c9 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi @@ -442,7 +442,11 @@ ap_i2c_tpm: { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <_hot_plug_det>; +}; + +_dp_out { data-lanes = <0 1>; + link-frequencies = /bits/ 64 <162000 27 54 81>; }; _mdp { diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index 2125803..43ef6dc 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -4135,7 +4135,7 @@ port@1 { reg = <1>; - dp_out: endpoint { }; + mdss_dp_out: endpoint { }; }; };
Re: [PATCH v2 2/3] iommu/sound: Use component_match_add_of helper
On 03/01/2023 4:15 pm, Maxime Ripard wrote: Hi Robin, On Tue, Jan 03, 2023 at 01:01:07PM +, Robin Murphy wrote: Hi Sean, On 22/12/2022 11:37 pm, Sean Anderson wrote: Convert users of component_match_add_release with component_release_of and component_compare_of to component_match_add_of. Signed-off-by: Sean Anderson Acked-by: Mark Brown --- Changes in v2: - Split off from helper addition drivers/iommu/mtk_iommu.c| 3 +-- drivers/iommu/mtk_iommu_v1.c | 3 +-- sound/soc/codecs/wcd938x.c | 6 ++ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 2ab2ecfe01f8..483b7a9e4410 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -1079,8 +1079,7 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m } data->larb_imu[id].dev = >dev; - component_match_add_release(dev, match, component_release_of, - component_compare_of, larbnode); + component_match_add_of(dev, match, larbnode); I've long since given up trying to make sense of how the DRM tree works, but the conflicting change is definitely already in mainline: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=b5765a1b44bea9dfcae69c53ffeb4c689d0922a7 As far as I can see, that patch doesn't affect DRM at all, and the commit you pointed to doesn't either, nor has it been merged through the DRM tree. Right it doesn't affect DRM, and was merged via the IOMMU tree, but it does affect *this* patch, which Sean has based on a drm-next branch that seemingly still wasn't up to date with 6.2-rc1 at the time. Since v2 had already been posted, it seemed like a bright idea to comment here to clarify that it was still relevant, rather than bumping the old thread to reply directly. Apologies for any confusion. In practical terms I think it's merely a case of dropping this hunk; the other one in mtk_iommu_v1.c looks fine to me. Cheers, Robin. Can you expand a bit on how we're involved in this, what we should clarify or help with? Maxime
Re: [PATCH] drm: Replace DRM_DEBUG with drm_dbg_core in file and ioctl handling
On 03/01/2023 15:39, Simon Ser wrote: On Tuesday, January 3rd, 2023 at 16:37, Tvrtko Ursulin wrote: On 23/12/2022 11:26, Simon Ser wrote: Reviewed-by: Simon Ser cont...@emersion.fr Thanks - adding some drm-misc maintainers to consider pulling the patch in. I can push the patches if you don't have commit rights. Don't think I do - drm-intel only. Great if you can then, thanks! Regards, Tvrtko
Re: [PATCH v2 2/3] iommu/sound: Use component_match_add_of helper
On 1/3/23 11:15, Maxime Ripard wrote: > Hi Robin, > > On Tue, Jan 03, 2023 at 01:01:07PM +, Robin Murphy wrote: >> Hi Sean, >> >> On 22/12/2022 11:37 pm, Sean Anderson wrote: >> > Convert users of component_match_add_release with component_release_of >> > and component_compare_of to component_match_add_of. >> > >> > Signed-off-by: Sean Anderson >> > Acked-by: Mark Brown >> > --- >> > >> > Changes in v2: >> > - Split off from helper addition >> > >> > drivers/iommu/mtk_iommu.c| 3 +-- >> > drivers/iommu/mtk_iommu_v1.c | 3 +-- >> > sound/soc/codecs/wcd938x.c | 6 ++ >> > 3 files changed, 4 insertions(+), 8 deletions(-) >> > >> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c >> > index 2ab2ecfe01f8..483b7a9e4410 100644 >> > --- a/drivers/iommu/mtk_iommu.c >> > +++ b/drivers/iommu/mtk_iommu.c >> > @@ -1079,8 +1079,7 @@ static int mtk_iommu_mm_dts_parse(struct device >> > *dev, struct component_match **m >> >} >> >data->larb_imu[id].dev = >dev; >> > - component_match_add_release(dev, match, component_release_of, >> > - component_compare_of, larbnode); >> > + component_match_add_of(dev, match, larbnode); >> >> I've long since given up trying to make sense of how the DRM tree works, but >> the conflicting change is definitely already in mainline: >> >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=b5765a1b44bea9dfcae69c53ffeb4c689d0922a7 > > As far as I can see, that patch doesn't affect DRM at all, and the > commit you pointed to doesn't either, nor has it been merged through the > DRM tree. > > Can you expand a bit on how we're involved in this, what we should > clarify or help with? Patches 2 and 3 of this series depend on patch 1. Since patch 3 contains the bulk of the changes, I based this series on the drm-next tree. However, patch 2 has a conflict elswhere in the tree, which did not appear until 6.2-rc1. At the time I sent out this series, drm-next did not contain this commit, and I couldn't find it based on Robin's description [1], so now we end up with a conflict. As this commit has now been merged into drm-next, I can rebase and resend if there are no other comments. --Sean [1] https://lore.kernel.org/linux-arm-kernel/56310773-a062-0e48-28f7-6d2c5d035...@seco.com/
Re: [syzbot] WARNING: locking bug in inet_autobind
Am 2023-01-03 um 11:05 schrieb Waiman Long: On 1/3/23 10:39, Felix Kuehling wrote: The regression point doesn't make sense. The kernel config doesn't enable CONFIG_DRM_AMDGPU, so there is no way that a change in AMDGPU could have caused this regression. I agree. It is likely a pre-existing problem or caused by another commit that got triggered because of the change in cacheline alignment caused by commit c0d9271ecbd ("drm/amdgpu: Delete user queue doorbell variable"). I don't think the change can affect cache line alignment. The entire amdgpu driver doesn't even get compiled in the kernel config that was used, and the change doesn't touch any files outside drivers/gpu/drm/amd/amdgpu: # CONFIG_DRM_AMDGPU is not set My guess would be that it's an intermittent bug that is confusing bisect. Regards, Felix Cheers, Longman Regards, Felix Am 2022-12-29 um 01:26 schrieb syzbot: syzbot has found a reproducer for the following issue on: HEAD commit: 1b929c02afd3 Linux 6.2-rc1 git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=145c6a6848 kernel config: https://syzkaller.appspot.com/x/.config?x=2651619a26b4d687 dashboard link: https://syzkaller.appspot.com/bug?extid=94cc2a66fc228b23f360 compiler: gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13e13e3248 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=13790f0848 Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/d1849f1ca322/disk-1b929c02.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/924cb8aa4ada/vmlinux-1b929c02.xz kernel image: https://storage.googleapis.com/syzbot-assets/8c7330dae0a0/bzImage-1b929c02.xz The issue was bisected to: commit c0d9271ecbd891cdeb0fad1edcdd99ee717a655f Author: Yong Zhao Date: Fri Feb 1 23:36:21 2019 + drm/amdgpu: Delete user queue doorbell variables bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1433ece4a0 final oops: https://syzkaller.appspot.com/x/report.txt?x=1633ece4a0 console output: https://syzkaller.appspot.com/x/log.txt?x=1233ece4a0 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+94cc2a66fc228b23f...@syzkaller.appspotmail.com Fixes: c0d9271ecbd8 ("drm/amdgpu: Delete user queue doorbell variables") [ cut here ] Looking for class "l2tp_sock" with key l2tp_socket_class, but found a different class "slock-AF_INET6" with the same key WARNING: CPU: 0 PID: 7280 at kernel/locking/lockdep.c:937 look_up_lock_class+0x97/0x110 kernel/locking/lockdep.c:937 Modules linked in: CPU: 0 PID: 7280 Comm: syz-executor835 Not tainted 6.2.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:look_up_lock_class+0x97/0x110 kernel/locking/lockdep.c:937 Code: 17 48 81 fa e0 e5 f6 8f 74 59 80 3d 5d bc 57 04 00 75 50 48 c7 c7 00 4d 4c 8a 48 89 04 24 c6 05 49 bc 57 04 01 e8 a9 42 b9 ff <0f> 0b 48 8b 04 24 eb 31 9c 5a 80 e6 02 74 95 e8 45 38 02 fa 85 c0 RSP: 0018:c9000b5378b8 EFLAGS: 00010082 RAX: RBX: 91c06a00 RCX: RDX: 8880292d RSI: 8166721c RDI: f520016a6f09 RBP: R08: 0005 R09: R10: 8201 R11: 20676e696b6f6f4c R12: R13: 88802a5820b0 R14: R15: FS: 7f1fd7a97700() GS:8880b980() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 2100 CR3: 78ab4000 CR4: 003506f0 DR0: DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0400 Call Trace: register_lock_class+0xbe/0x1120 kernel/locking/lockdep.c:1289 __lock_acquire+0x109/0x56d0 kernel/locking/lockdep.c:4934 lock_acquire kernel/locking/lockdep.c:5668 [inline] lock_acquire+0x1e3/0x630 kernel/locking/lockdep.c:5633 __raw_spin_lock_bh include/linux/spinlock_api_smp.h:126 [inline] _raw_spin_lock_bh+0x33/0x40 kernel/locking/spinlock.c:178 spin_lock_bh include/linux/spinlock.h:355 [inline] lock_sock_nested+0x5f/0xf0 net/core/sock.c:3473 lock_sock include/net/sock.h:1725 [inline] inet_autobind+0x1a/0x190 net/ipv4/af_inet.c:177 inet_send_prepare net/ipv4/af_inet.c:813 [inline] inet_send_prepare+0x325/0x4e0 net/ipv4/af_inet.c:807 inet6_sendmsg+0x43/0xe0 net/ipv6/af_inet6.c:655 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xd3/0x120 net/socket.c:734 __sys_sendto+0x23a/0x340 net/socket.c:2117 __do_sys_sendto net/socket.c:2129 [inline] __se_sys_sendto net/socket.c:2125 [inline] __x64_sys_sendto+0xe1/0x1b0 net/socket.c:2125 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
Re: [Intel-gfx] [PATCH v2] drm/i915: dell wyse 3040 shutdown fix
On Tue, Jan 03, 2023 at 07:09:20PM +0300, Alexey Lukyachuk wrote: > On Tue, 3 Jan 2023 07:46:40 -0500 > Rodrigo Vivi wrote: > > > On Mon, Jan 02, 2023 at 04:56:49PM +0300, Alexey Lukyachuk wrote: > > > On Tue, 27 Dec 2022 20:40:03 +0300 > > > Alexey Lukyachuk wrote: > > > > > > > On Tue, 27 Dec 2022 11:39:25 -0500 > > > > Rodrigo Vivi wrote: > > > > > > > > > On Sun, Dec 25, 2022 at 09:55:08PM +0300, Alexey Lukyanchuk wrote: > > > > > > dell wyse 3040 doesn't peform poweroff properly, but instead > > > > > > remains in > > > > > > turned power on state. > > > > > > > > > > okay, the motivation is explained in the commit msg.. > > > > > > > > > > > Additional mutex_lock and > > > > > > intel_crtc_wait_for_next_vblank > > > > > > feature 6.2 kernel resolve this trouble. > > > > > > > > > > but this why is not very clear... seems that by magic it was found, > > > > > without explaining what race we are really protecting here. > > > > > > > > > > but even worse is: > > > > > what about those many random vblank waits in the code? what's the > > > > > reasoning? > > > > > > > > > > > > > > > > > cc: sta...@vger.kernel.org > > > > > > original commit Link: > > > > > > https://patchwork.freedesktop.org/patch/508926/ > > > > > > fixes: fe0f1e3bfdfeb53e18f1206aea4f40b9bd1f291c > > > > > > Signed-off-by: Alexey Lukyanchuk > > > > > > --- > > > > > > I got some troubles with this device (dell wyse 3040) since kernel > > > > > > 5.11 > > > > > > started to use i915_driver_shutdown function. I found solution here: > > > > > > > > > > > > https://lore.kernel.org/dri-devel/y1wd6zj8ldjpc...@intel.com/#r > > > > > > > > > > > > --- > > > > > > drivers/gpu/drm/i915/display/intel_audio.c | 37 > > > > > > +++--- > > > > > > 1 file changed, 25 insertions(+), 12 deletions(-) > > > > > > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_audio.c > > > > > > b/drivers/gpu/drm/i915/display/intel_audio.c > > > > > > index aacbc6da8..44344ecdf 100644 > > > > > > --- a/drivers/gpu/drm/i915/display/intel_audio.c > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_audio.c > > > > > > @@ -336,6 +336,7 @@ static void g4x_audio_codec_disable(struct > > > > > > intel_encoder *encoder, > > > > > > const struct drm_connector_state > > > > > > *old_conn_state) > > > > > > { > > > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > > > + struct intel_crtc *crtc = > > > > > > to_intel_crtc(old_crtc_state->uapi.crtc); > > > > > > u32 eldv, tmp; > > > > > > > > > > > > tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); > > > > > > @@ -348,6 +349,9 @@ static void g4x_audio_codec_disable(struct > > > > > > intel_encoder *encoder, > > > > > > tmp = intel_de_read(dev_priv, G4X_AUD_CNTL_ST); > > > > > > tmp &= ~eldv; > > > > > > intel_de_write(dev_priv, G4X_AUD_CNTL_ST, tmp); > > > > > > + > > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > > } > > > > > > > > > > > > static void g4x_audio_codec_enable(struct intel_encoder *encoder, > > > > > > @@ -355,12 +359,15 @@ static void g4x_audio_codec_enable(struct > > > > > > intel_encoder *encoder, > > > > > >const struct drm_connector_state > > > > > > *conn_state) > > > > > > { > > > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > > > + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > > > > > > struct drm_connector *connector = conn_state->connector; > > > > > > const u8 *eld = connector->eld; > > > > > > u32 eldv; > > > > > > u32 tmp; > > > > > > int len, i; > > > > > > > > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > > + > > > > > > tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); > > > > > > if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL) > > > > > > eldv = G4X_ELDV_DEVCL_DEVBLC; > > > > > > @@ -493,6 +500,7 @@ static void hsw_audio_codec_disable(struct > > > > > > intel_encoder *encoder, > > > > > > const struct drm_connector_state > > > > > > *old_conn_state) > > > > > > { > > > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > > > + struct intel_crtc *crtc = > > > > > > to_intel_crtc(old_crtc_state->uapi.crtc); > > > > > > enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; > > > > > > u32 tmp; > > > > > > > > > > > > @@ -508,6 +516,10 @@ static void hsw_audio_codec_disable(struct > > > > > > intel_encoder *encoder, > > > > > > tmp |= AUD_CONFIG_N_VALUE_INDEX; > > > > > > intel_de_write(dev_priv, HSW_AUD_CFG(cpu_transcoder), tmp); > > > > > > > > > > > > + > > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > > + > > > > > > /* Invalidate ELD */ > > > > > >
Re: [PATCH v2 2/3] iommu/sound: Use component_match_add_of helper
Hi Robin, On Tue, Jan 03, 2023 at 01:01:07PM +, Robin Murphy wrote: > Hi Sean, > > On 22/12/2022 11:37 pm, Sean Anderson wrote: > > Convert users of component_match_add_release with component_release_of > > and component_compare_of to component_match_add_of. > > > > Signed-off-by: Sean Anderson > > Acked-by: Mark Brown > > --- > > > > Changes in v2: > > - Split off from helper addition > > > > drivers/iommu/mtk_iommu.c| 3 +-- > > drivers/iommu/mtk_iommu_v1.c | 3 +-- > > sound/soc/codecs/wcd938x.c | 6 ++ > > 3 files changed, 4 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > > index 2ab2ecfe01f8..483b7a9e4410 100644 > > --- a/drivers/iommu/mtk_iommu.c > > +++ b/drivers/iommu/mtk_iommu.c > > @@ -1079,8 +1079,7 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, > > struct component_match **m > > } > > data->larb_imu[id].dev = >dev; > > - component_match_add_release(dev, match, component_release_of, > > - component_compare_of, larbnode); > > + component_match_add_of(dev, match, larbnode); > > I've long since given up trying to make sense of how the DRM tree works, but > the conflicting change is definitely already in mainline: > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=b5765a1b44bea9dfcae69c53ffeb4c689d0922a7 As far as I can see, that patch doesn't affect DRM at all, and the commit you pointed to doesn't either, nor has it been merged through the DRM tree. Can you expand a bit on how we're involved in this, what we should clarify or help with? Maxime signature.asc Description: PGP signature
Re: [Intel-gfx] [PATCH v2] drm/i915: dell wyse 3040 shutdown fix
On Tue, 3 Jan 2023 07:46:40 -0500 Rodrigo Vivi wrote: > On Mon, Jan 02, 2023 at 04:56:49PM +0300, Alexey Lukyachuk wrote: > > On Tue, 27 Dec 2022 20:40:03 +0300 > > Alexey Lukyachuk wrote: > > > > > On Tue, 27 Dec 2022 11:39:25 -0500 > > > Rodrigo Vivi wrote: > > > > > > > On Sun, Dec 25, 2022 at 09:55:08PM +0300, Alexey Lukyanchuk wrote: > > > > > dell wyse 3040 doesn't peform poweroff properly, but instead remains > > > > > in > > > > > turned power on state. > > > > > > > > okay, the motivation is explained in the commit msg.. > > > > > > > > > Additional mutex_lock and > > > > > intel_crtc_wait_for_next_vblank > > > > > feature 6.2 kernel resolve this trouble. > > > > > > > > but this why is not very clear... seems that by magic it was found, > > > > without explaining what race we are really protecting here. > > > > > > > > but even worse is: > > > > what about those many random vblank waits in the code? what's the > > > > reasoning? > > > > > > > > > > > > > > cc: sta...@vger.kernel.org > > > > > original commit Link: https://patchwork.freedesktop.org/patch/508926/ > > > > > fixes: fe0f1e3bfdfeb53e18f1206aea4f40b9bd1f291c > > > > > Signed-off-by: Alexey Lukyanchuk > > > > > --- > > > > > I got some troubles with this device (dell wyse 3040) since kernel > > > > > 5.11 > > > > > started to use i915_driver_shutdown function. I found solution here: > > > > > > > > > > https://lore.kernel.org/dri-devel/y1wd6zj8ldjpc...@intel.com/#r > > > > > > > > > > --- > > > > > drivers/gpu/drm/i915/display/intel_audio.c | 37 > > > > > +++--- > > > > > 1 file changed, 25 insertions(+), 12 deletions(-) > > > > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_audio.c > > > > > b/drivers/gpu/drm/i915/display/intel_audio.c > > > > > index aacbc6da8..44344ecdf 100644 > > > > > --- a/drivers/gpu/drm/i915/display/intel_audio.c > > > > > +++ b/drivers/gpu/drm/i915/display/intel_audio.c > > > > > @@ -336,6 +336,7 @@ static void g4x_audio_codec_disable(struct > > > > > intel_encoder *encoder, > > > > > const struct drm_connector_state > > > > > *old_conn_state) > > > > > { > > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > > + struct intel_crtc *crtc = > > > > > to_intel_crtc(old_crtc_state->uapi.crtc); > > > > > u32 eldv, tmp; > > > > > > > > > > tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); > > > > > @@ -348,6 +349,9 @@ static void g4x_audio_codec_disable(struct > > > > > intel_encoder *encoder, > > > > > tmp = intel_de_read(dev_priv, G4X_AUD_CNTL_ST); > > > > > tmp &= ~eldv; > > > > > intel_de_write(dev_priv, G4X_AUD_CNTL_ST, tmp); > > > > > + > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > } > > > > > > > > > > static void g4x_audio_codec_enable(struct intel_encoder *encoder, > > > > > @@ -355,12 +359,15 @@ static void g4x_audio_codec_enable(struct > > > > > intel_encoder *encoder, > > > > > const struct drm_connector_state > > > > > *conn_state) > > > > > { > > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > > + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > > > > > struct drm_connector *connector = conn_state->connector; > > > > > const u8 *eld = connector->eld; > > > > > u32 eldv; > > > > > u32 tmp; > > > > > int len, i; > > > > > > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > + > > > > > tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); > > > > > if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL) > > > > > eldv = G4X_ELDV_DEVCL_DEVBLC; > > > > > @@ -493,6 +500,7 @@ static void hsw_audio_codec_disable(struct > > > > > intel_encoder *encoder, > > > > > const struct drm_connector_state > > > > > *old_conn_state) > > > > > { > > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > > + struct intel_crtc *crtc = > > > > > to_intel_crtc(old_crtc_state->uapi.crtc); > > > > > enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; > > > > > u32 tmp; > > > > > > > > > > @@ -508,6 +516,10 @@ static void hsw_audio_codec_disable(struct > > > > > intel_encoder *encoder, > > > > > tmp |= AUD_CONFIG_N_VALUE_INDEX; > > > > > intel_de_write(dev_priv, HSW_AUD_CFG(cpu_transcoder), tmp); > > > > > > > > > > + > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > > + > > > > > /* Invalidate ELD */ > > > > > tmp = intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD); > > > > > tmp &= ~AUDIO_ELD_VALID(cpu_transcoder); > > > > > @@ -633,6 +645,7 @@ static void hsw_audio_codec_enable(struct > > > > > intel_encoder *encoder, > > > > >
Re: [syzbot] WARNING: locking bug in inet_autobind
On 1/3/23 10:39, Felix Kuehling wrote: The regression point doesn't make sense. The kernel config doesn't enable CONFIG_DRM_AMDGPU, so there is no way that a change in AMDGPU could have caused this regression. I agree. It is likely a pre-existing problem or caused by another commit that got triggered because of the change in cacheline alignment caused by commit c0d9271ecbd ("drm/amdgpu: Delete user queue doorbell variable"). Cheers, Longman Regards, Felix Am 2022-12-29 um 01:26 schrieb syzbot: syzbot has found a reproducer for the following issue on: HEAD commit: 1b929c02afd3 Linux 6.2-rc1 git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=145c6a6848 kernel config: https://syzkaller.appspot.com/x/.config?x=2651619a26b4d687 dashboard link: https://syzkaller.appspot.com/bug?extid=94cc2a66fc228b23f360 compiler: gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13e13e3248 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=13790f0848 Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/d1849f1ca322/disk-1b929c02.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/924cb8aa4ada/vmlinux-1b929c02.xz kernel image: https://storage.googleapis.com/syzbot-assets/8c7330dae0a0/bzImage-1b929c02.xz The issue was bisected to: commit c0d9271ecbd891cdeb0fad1edcdd99ee717a655f Author: Yong Zhao Date: Fri Feb 1 23:36:21 2019 + drm/amdgpu: Delete user queue doorbell variables bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1433ece4a0 final oops: https://syzkaller.appspot.com/x/report.txt?x=1633ece4a0 console output: https://syzkaller.appspot.com/x/log.txt?x=1233ece4a0 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+94cc2a66fc228b23f...@syzkaller.appspotmail.com Fixes: c0d9271ecbd8 ("drm/amdgpu: Delete user queue doorbell variables") [ cut here ] Looking for class "l2tp_sock" with key l2tp_socket_class, but found a different class "slock-AF_INET6" with the same key WARNING: CPU: 0 PID: 7280 at kernel/locking/lockdep.c:937 look_up_lock_class+0x97/0x110 kernel/locking/lockdep.c:937 Modules linked in: CPU: 0 PID: 7280 Comm: syz-executor835 Not tainted 6.2.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:look_up_lock_class+0x97/0x110 kernel/locking/lockdep.c:937 Code: 17 48 81 fa e0 e5 f6 8f 74 59 80 3d 5d bc 57 04 00 75 50 48 c7 c7 00 4d 4c 8a 48 89 04 24 c6 05 49 bc 57 04 01 e8 a9 42 b9 ff <0f> 0b 48 8b 04 24 eb 31 9c 5a 80 e6 02 74 95 e8 45 38 02 fa 85 c0 RSP: 0018:c9000b5378b8 EFLAGS: 00010082 RAX: RBX: 91c06a00 RCX: RDX: 8880292d RSI: 8166721c RDI: f520016a6f09 RBP: R08: 0005 R09: R10: 8201 R11: 20676e696b6f6f4c R12: R13: 88802a5820b0 R14: R15: FS: 7f1fd7a97700() GS:8880b980() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 2100 CR3: 78ab4000 CR4: 003506f0 DR0: DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0400 Call Trace: register_lock_class+0xbe/0x1120 kernel/locking/lockdep.c:1289 __lock_acquire+0x109/0x56d0 kernel/locking/lockdep.c:4934 lock_acquire kernel/locking/lockdep.c:5668 [inline] lock_acquire+0x1e3/0x630 kernel/locking/lockdep.c:5633 __raw_spin_lock_bh include/linux/spinlock_api_smp.h:126 [inline] _raw_spin_lock_bh+0x33/0x40 kernel/locking/spinlock.c:178 spin_lock_bh include/linux/spinlock.h:355 [inline] lock_sock_nested+0x5f/0xf0 net/core/sock.c:3473 lock_sock include/net/sock.h:1725 [inline] inet_autobind+0x1a/0x190 net/ipv4/af_inet.c:177 inet_send_prepare net/ipv4/af_inet.c:813 [inline] inet_send_prepare+0x325/0x4e0 net/ipv4/af_inet.c:807 inet6_sendmsg+0x43/0xe0 net/ipv6/af_inet6.c:655 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xd3/0x120 net/socket.c:734 __sys_sendto+0x23a/0x340 net/socket.c:2117 __do_sys_sendto net/socket.c:2129 [inline] __se_sys_sendto net/socket.c:2125 [inline] __x64_sys_sendto+0xe1/0x1b0 net/socket.c:2125 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f1fd78538b9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 15 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:7f1fd7a971f8 EFLAGS: 0212 ORIG_RAX: 002c RAX: ffda RBX: 7f1fd78f0038 RCX: 7f1fd78538b9 RDX:
[PATCH v2] drm/msm: another fix for the headless Adreno GPU
Fix another oops reproducible when rebooting the board with the Adreno GPU wokring in the headless mode (e.g. iMX platforms). Unable to handle kernel NULL pointer dereference at virtual address when read [] *pgd=74936831, *pte=, *ppte= Internal error: Oops: 17 [#1] ARM CPU: 0 PID: 51 Comm: reboot Not tainted 6.2.0-rc1-dirty #11 Hardware name: Freescale i.MX53 (Device Tree Support) PC is at msm_atomic_commit_tail+0x50/0x970 LR is at commit_tail+0x9c/0x188 pc : []lr : []psr: 600e0013 sp : e0851d30 ip : ee4eb7eb fp : 00090acc r10: 0058 r9 : c2193014 r8 : c431 r7 : c4759380 r6 : 07bef61d r5 : r4 : r3 : c44cc440 r2 : r1 : r0 : Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c5387d Table: 74910019 DAC: 0051 Register r0 information: NULL pointer Register r1 information: NULL pointer Register r2 information: NULL pointer Register r3 information: slab kmalloc-1k start c44cc400 pointer offset 64 size 1024 Register r4 information: NULL pointer Register r5 information: NULL pointer Register r6 information: non-paged memory Register r7 information: slab kmalloc-128 start c4759380 pointer offset 0 size 128 Register r8 information: slab kmalloc-2k start c431 pointer offset 0 size 2048 Register r9 information: non-slab/vmalloc memory Register r10 information: non-paged memory Register r11 information: non-paged memory Register r12 information: non-paged memory Process reboot (pid: 51, stack limit = 0xc80046d9) Stack: (0xe0851d30 to 0xe0852000) 1d20: c4759380 fbd77200 05ff 002b9c70 1d40: c4759380 c4759380 07bef61d 0600 c0d6fe7c c2193014 0058 1d60: 00090acc c067a214 c4759380 c431 c44cc854 c067a89c 1d80: c4310468 c4759380 c431 c4310468 1da0: c4310470 c0643258 c4759380 c0c4ee24 c44cc810 1dc0: c0c4ee24 c44cc810 0347d2a8 e0851e00 e0851e00 1de0: c4759380 c067ad20 c431 c44cc810 c27f8718 c44cc854 c067adb8 1e00: c4933000 0002 0001 c2130850 c2130854 1e20: c25fc488 c0ff162c 0001 0002 1e40: c43102c0 c43102c0 0347d2a8 c44cc810 c44cc814 c2133da8 c06d1a60 1e60: 00079028 c2012f24 fee1dead c4933000 0058 c01431e4 1e80: 01234567 c0143a20 1ea0: 1ec0: 1ee0: 1f00: 1f20: 1f40: 1f60: 1f80: 0347d2a8 0002 0004 0078 0058 1fa0: c010028c c0100060 0002 0004 fee1dead 28121969 01234567 00079028 1fc0: 0002 0004 0078 0058 0002fdc5 00090acc 1fe0: 0058 becc9c64 b6e97e05 b6e0e5f6 600e0030 fee1dead msm_atomic_commit_tail from commit_tail+0x9c/0x188 commit_tail from drm_atomic_helper_commit+0x160/0x188 drm_atomic_helper_commit from drm_atomic_commit+0xac/0xe0 drm_atomic_commit from drm_atomic_helper_disable_all+0x1b0/0x1c0 drm_atomic_helper_disable_all from drm_atomic_helper_shutdown+0x88/0x140 drm_atomic_helper_shutdown from device_shutdown+0x16c/0x240 device_shutdown from kernel_restart+0x38/0x90 kernel_restart from __do_sys_reboot+0x174/0x224 __do_sys_reboot from ret_fast_syscall+0x0/0x1c Exception stack(0xe0851fa8 to 0xe0851ff0) 1fa0: 0002 0004 fee1dead 28121969 01234567 00079028 1fc0: 0002 0004 0078 0058 0002fdc5 00090acc 1fe0: 0058 becc9c64 b6e97e05 b6e0e5f6 Code: 15922088 1184421c e153 1af8 (e5953000) ---[ end trace ]--- Fixes: 0a58d2ae572a ("drm/msm: Make .remove and .shutdown HW shutdown consistent") Reported-by: kernel test robot Signed-off-by: Dmitry Baryshkov --- Changes since v1: - Moved setting of `async' before the call to trace to fix the uninitialized variable warning --- drivers/gpu/drm/msm/msm_atomic.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 1686fbb611fd..d8cded52cabf 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -186,7 +186,12 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) struct msm_kms *kms = priv->kms; struct drm_crtc *async_crtc = NULL; unsigned crtc_mask =
Re: [syzbot] WARNING: locking bug in inet_autobind
The regression point doesn't make sense. The kernel config doesn't enable CONFIG_DRM_AMDGPU, so there is no way that a change in AMDGPU could have caused this regression. Regards, Felix Am 2022-12-29 um 01:26 schrieb syzbot: syzbot has found a reproducer for the following issue on: HEAD commit:1b929c02afd3 Linux 6.2-rc1 git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=145c6a6848 kernel config: https://syzkaller.appspot.com/x/.config?x=2651619a26b4d687 dashboard link: https://syzkaller.appspot.com/bug?extid=94cc2a66fc228b23f360 compiler: gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13e13e3248 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=13790f0848 Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/d1849f1ca322/disk-1b929c02.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/924cb8aa4ada/vmlinux-1b929c02.xz kernel image: https://storage.googleapis.com/syzbot-assets/8c7330dae0a0/bzImage-1b929c02.xz The issue was bisected to: commit c0d9271ecbd891cdeb0fad1edcdd99ee717a655f Author: Yong Zhao Date: Fri Feb 1 23:36:21 2019 + drm/amdgpu: Delete user queue doorbell variables bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1433ece4a0 final oops: https://syzkaller.appspot.com/x/report.txt?x=1633ece4a0 console output: https://syzkaller.appspot.com/x/log.txt?x=1233ece4a0 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+94cc2a66fc228b23f...@syzkaller.appspotmail.com Fixes: c0d9271ecbd8 ("drm/amdgpu: Delete user queue doorbell variables") [ cut here ] Looking for class "l2tp_sock" with key l2tp_socket_class, but found a different class "slock-AF_INET6" with the same key WARNING: CPU: 0 PID: 7280 at kernel/locking/lockdep.c:937 look_up_lock_class+0x97/0x110 kernel/locking/lockdep.c:937 Modules linked in: CPU: 0 PID: 7280 Comm: syz-executor835 Not tainted 6.2.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:look_up_lock_class+0x97/0x110 kernel/locking/lockdep.c:937 Code: 17 48 81 fa e0 e5 f6 8f 74 59 80 3d 5d bc 57 04 00 75 50 48 c7 c7 00 4d 4c 8a 48 89 04 24 c6 05 49 bc 57 04 01 e8 a9 42 b9 ff <0f> 0b 48 8b 04 24 eb 31 9c 5a 80 e6 02 74 95 e8 45 38 02 fa 85 c0 RSP: 0018:c9000b5378b8 EFLAGS: 00010082 RAX: RBX: 91c06a00 RCX: RDX: 8880292d RSI: 8166721c RDI: f520016a6f09 RBP: R08: 0005 R09: R10: 8201 R11: 20676e696b6f6f4c R12: R13: 88802a5820b0 R14: R15: FS: 7f1fd7a97700() GS:8880b980() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 2100 CR3: 78ab4000 CR4: 003506f0 DR0: DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0400 Call Trace: register_lock_class+0xbe/0x1120 kernel/locking/lockdep.c:1289 __lock_acquire+0x109/0x56d0 kernel/locking/lockdep.c:4934 lock_acquire kernel/locking/lockdep.c:5668 [inline] lock_acquire+0x1e3/0x630 kernel/locking/lockdep.c:5633 __raw_spin_lock_bh include/linux/spinlock_api_smp.h:126 [inline] _raw_spin_lock_bh+0x33/0x40 kernel/locking/spinlock.c:178 spin_lock_bh include/linux/spinlock.h:355 [inline] lock_sock_nested+0x5f/0xf0 net/core/sock.c:3473 lock_sock include/net/sock.h:1725 [inline] inet_autobind+0x1a/0x190 net/ipv4/af_inet.c:177 inet_send_prepare net/ipv4/af_inet.c:813 [inline] inet_send_prepare+0x325/0x4e0 net/ipv4/af_inet.c:807 inet6_sendmsg+0x43/0xe0 net/ipv6/af_inet6.c:655 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xd3/0x120 net/socket.c:734 __sys_sendto+0x23a/0x340 net/socket.c:2117 __do_sys_sendto net/socket.c:2129 [inline] __se_sys_sendto net/socket.c:2125 [inline] __x64_sys_sendto+0xe1/0x1b0 net/socket.c:2125 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f1fd78538b9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 15 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:7f1fd7a971f8 EFLAGS: 0212 ORIG_RAX: 002c RAX: ffda RBX: 7f1fd78f0038 RCX: 7f1fd78538b9 RDX: RSI: RDI: 0004 RBP: 7f1fd78f0030 R08: 2100 R09: 001c R10: 04008000 R11: 0212 R12: 7f1fd78f003c R13: 7f1fd79ffc8f R14: 7f1fd7a97300 R15: 00022000
Re: [PATCH] drm: Replace DRM_DEBUG with drm_dbg_core in file and ioctl handling
On Tuesday, January 3rd, 2023 at 16:37, Tvrtko Ursulin wrote: > On 23/12/2022 11:26, Simon Ser wrote: > > > Reviewed-by: Simon Ser cont...@emersion.fr > > Thanks - adding some drm-misc maintainers to consider pulling the patch in. I can push the patches if you don't have commit rights.
Re: [PATCH] drm: Replace DRM_DEBUG with drm_dbg_core in file and ioctl handling
On 23/12/2022 11:26, Simon Ser wrote: Reviewed-by: Simon Ser Thanks - adding some drm-misc maintainers to consider pulling the patch in. Regards, Tvrtko
[PATCH] drm/docs: Explicitly document default CRTC background behavior
From: Sean Paul Add a paragraph explaining that the default behavior for areas which are not covered by planes or where planes are blending with the CRTC background, is black. This is alluded to in the "pixel blend mode" property docs, but not called out explicitly. Signed-off-by: Sean Paul --- drivers/gpu/drm/drm_plane.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 33357629a7f5..24e7998d1731 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -46,6 +46,11 @@ * properties that specify how the pixels are positioned and blended, like * rotation or Z-position. All these properties are stored in _plane_state. * + * Unless explicitly specified (via CRTC property or otherwise), the active area + * of a CRTC will be black by default. This means portions of the active area + * which are not covered by a plane will be black, and alpha blending of any + * planes with the CRTC background will blend with black at the lowest zpos. + * * To create a plane, a KMS drivers allocates and zeroes an instances of * drm_plane (possibly as part of a larger structure) and registers it * with a call to drm_universal_plane_init(). -- Sean Paul, Software Engineer, Google / Chromium OS
[PULL] drm-misc-next-fixes
Hi Daniel, Dave, Here's the drm-misc-next-fixes leftovers. Maxime drm-misc-next-fixes-2023-01-03: The drm-misc-next-fixes leftovers. It addresses a bug in drm/scheduler ending up causing a lockup, and reduces the stack usage of some drm/mm kunit tests. The following changes since commit b02897e56b4e1fa6445be695ce5d605bb098435c: Revert "drm/fb-helper: Perform damage handling in deferred-I/O helper" (2022-11-23 09:11:32 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-misc tags/drm-misc-next-fixes-2023-01-03 for you to fetch changes up to 03dec92c4f788c54a7c01b40a018f601eb8a6c52: drm/scheduler: Fix lockup in drm_sched_entity_kill() (2023-01-02 17:45:18 +0300) The drm-misc-next-fixes leftovers. It addresses a bug in drm/scheduler ending up causing a lockup, and reduces the stack usage of some drm/mm kunit tests. Arnd Bergmann (1): drm/tests: reduce drm_mm_test stack usage Dmitry Osipenko (1): drm/scheduler: Fix lockup in drm_sched_entity_kill() drivers/gpu/drm/scheduler/sched_entity.c | 2 +- drivers/gpu/drm/scheduler/sched_main.c | 4 ++-- drivers/gpu/drm/tests/Makefile | 2 ++ drivers/gpu/drm/tests/drm_mm_test.c | 6 +++--- 4 files changed, 8 insertions(+), 6 deletions(-) signature.asc Description: PGP signature
Re: [RFC PATCH 00/20] Initial Xe driver submission
> > For one thing, setting that up would be a lot of up front infrastructure > > work. I'm not sure how to even pull that off when Xe is still > > out-of-tree and i915 development plunges on upstream as ever. > > > > For another, realistically, the overlap between supported platforms is > > going to end at some point, and eventually new platforms are only going > > to be supported with Xe. That's going to open up new possibilities for > > refactoring also the display code. I think it would be premature to lock > > in to a common directory structure or a common helper module at this > > point. > > > > I'm not saying no to the idea, and we've contemplated it before, but I > > think there are still too many moving parts to decide to go that way. > > FWIW, I actually have the same dilemma with the driver for new Mali GPUs > I'm working on. I initially started making it a sub-driver of the > existing panfrost driver (some HW blocks are similar, like the > IOMMU and a few other things, and some SW abstracts can be shared here > and there, like the GEM allocator logic). But I'm now considering > forking the driver (after Alyssa planted the seed :-)), not only > because I want to start from a clean sheet on the the uAPI front > (wouldn't be an issue in your case, because you're talking about > sharing helpers, not the driver frontend), but also because any refactor > to panfrost is a potential source of regression for existing users. So, > I tend to agree with Jani here, trying to share code before things have > settled down is likely to cause pain to both Xe and i915 > users+developers. ++ I pretend to have never written a kernel driver, so will not comment there. But Boris and I were previously bit trying to share code between our GL and VK drivers, before VK settled down, causing pain for both. I don't want a kernelside repeat of that (for either Mali or Intel). I tend to think that, if you're tempted to share a driver frontend without the backend, that's a sign that there's too much boilerplate for the frontend and maybe there needs to be more helpers somewhere. For Xe, that doesn't apply since the hw overlaps between the drivers, but for Mali, there really is more different than similar and there's an obvious, acute break between "old Mali" and "new Mali". The shared "instantiate a DRM driver boilerplate" is pretty trivial, and the MMU code is as simple as it gets...
[PATCH 2/2] drm/panel: add visionox vtdr6130 DSI panel driver
Add support for the 1080x2400 Visionox VTDR6130 AMOLED DSI panel found on the Qualcomm SM8550 MTP board. By default the the panel is configured to work with DSI compressed streams, but can work in uncompressed video mode since 1080x2400 in RGB888 fits in the 4 DSI lanes bandwidth. While display compression is preferred for performance and power reasons, let's start with the uncompressed video mode support and add the DSC support later on. Signed-off-by: Neil Armstrong --- drivers/gpu/drm/panel/Kconfig | 8 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-visionox-vtdr6130.c | 366 3 files changed, 375 insertions(+) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 737edcdf9eef..fd1d7e6f536b 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -717,6 +717,14 @@ config DRM_PANEL_VISIONOX_RM69299 Say Y here if you want to enable support for Visionox RM69299 DSI Video Mode panel. +config DRM_PANEL_VISIONOX_VTDR6130 + tristate "Visionox VTDR6130" + depends on OF + depends on DRM_MIPI_DSI + help + Say Y here if you want to enable support for Visionox + VTDR6130 1080x2400 AMOLED DSI panel. + config DRM_PANEL_WIDECHIPS_WS2401 tristate "Widechips WS2401 DPI panel driver" depends on SPI && GPIOLIB diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index f8f9d9f6a307..1966404fcf7a 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -73,5 +73,6 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o +obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c new file mode 100644 index ..94ad2a32efc9 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c @@ -0,0 +1,366 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2023, Linaro Limited + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct visionox_vtdr6130 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[3]; + bool prepared; +}; + +static inline struct visionox_vtdr6130 *to_visionox_vtdr6130(struct drm_panel *panel) +{ + return container_of(panel, struct visionox_vtdr6130, panel); +} + +static inline int visionox_vtdr6130_dsi_write(struct mipi_dsi_device *dsi, const void *seq, + size_t len) +{ + return mipi_dsi_dcs_write_buffer(dsi, seq, len); +} + +#define dsi_dcs_write_seq(dsi, seq...) \ + { \ + const u8 d[] = { seq }; \ + visionox_vtdr6130_dsi_write(dsi, d, ARRAY_SIZE(d)); \ + } + +static void visionox_vtdr6130_reset(struct visionox_vtdr6130 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(1, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(1, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(1, 11000); +} + +static int visionox_vtdr6130_on(struct visionox_vtdr6130 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = >dev; + int ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + dsi_dcs_write_seq(dsi, 0x03, 0x01); + dsi_dcs_write_seq(dsi, 0x35, 0x00); + dsi_dcs_write_seq(dsi, 0x53, 0x20); + dsi_dcs_write_seq(dsi, 0x51, 0x00, 0x00); + dsi_dcs_write_seq(dsi, 0x59, 0x09); + dsi_dcs_write_seq(dsi, 0x6c, 0x01); + dsi_dcs_write_seq(dsi, 0x6d, 0x00); + dsi_dcs_write_seq(dsi, 0x6f, 0x01); + dsi_dcs_write_seq(dsi, 0x70, + 0x12, 0x00, 0x00, 0xab, 0x30, 0x80, 0x09, 0x60, 0x04, + 0x38, 0x00, 0x28, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x00, + 0x02, 0x0e, 0x00, 0x20, 0x03, 0xdd, 0x00, 0x07, 0x00, + 0x0c, 0x02, 0x77, 0x02, 0x8b, 0x18, 0x00, 0x10, 0xf0, + 0x07, 0x10, 0x20, 0x00, 0x06, 0x0f, 0x0f, 0x33, 0x0e, + 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, + 0x79, 0x7b, 0x7d, 0x7e, 0x02, 0x02, 0x22, 0x00, 0x2a, +
[PATCH 1/2] dt-bindings: display: panel: document the Visionox VTDR6130 AMOLED DSI Panel bindings
Document the 1080x2400 Visionox VTDR6130 AMOLED DSI Panel bindings. Signed-off-by: Neil Armstrong --- .../bindings/display/panel/visionox,vtdr6130.yaml | 53 ++ 1 file changed, 53 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml new file mode 100644 index ..49e2fd4b4e99 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/visionox,vtdr6130.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Visionox VTDR6130 AMOLED DSI Panel + +maintainers: + - Neil Armstrong + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: visionox,vtdr6130 + + vddio-supply: true + vci-supply: true + vdd-supply: true + port: true + reset-gpios: true + +additionalProperties: false + +required: + - compatible + - vddio-supply + - vci-supply + - vdd-supply + - reset-gpios + - port + +examples: + - | +#include +panel { +compatible = "visionox,vtdr6130"; + +vddio-supply = <_l12b_1p8>; +vci-supply = <_l13b_3p0>; +vdd-supply = <_l11b_1p2>; + +reset-gpios = < 133 GPIO_ACTIVE_LOW>; + +port { +panel0_in: endpoint { +remote-endpoint = <_out>; +}; +}; +}; +... -- 2.34.1
[PATCH 0/2] drm/panel: add support for the Visionox VTDR6130 AMOLED DSI panel
Add support for the 1080x2400 Visionox VTDR6130 AMOLED DSI panel found on the Qualcomm SM8550 MTP board. By default the the panel is configured to work with DSI compressed streams, but can work in uncompressed video mode since 1080x2400 in RGB888 fits in the 4 DSI lanes bandwidth. While display compression is preferred for performance and power reasons, let's start with the uncompressed video mode support and add the DSC support later on. To: Thierry Reding To: Sam Ravnborg To: David Airlie To: Daniel Vetter To: Rob Herring To: Krzysztof Kozlowski Cc: dri-devel@lists.freedesktop.org Cc: devicet...@vger.kernel.org Cc: linux-arm-...@vger.kernel.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Neil Armstrong --- Neil Armstrong (2): dt-bindings: display: panel: document the Visionox VTDR6130 AMOLED DSI Panel bindings drm/panel: add visionox vtdr6130 DSI panel driver .../bindings/display/panel/visionox,vtdr6130.yaml | 53 +++ drivers/gpu/drm/panel/Kconfig | 8 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-visionox-vtdr6130.c| 366 + 4 files changed, 428 insertions(+) --- base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2 change-id: 20230103-topic-sm8550-upstream-vtdr6130-panel-f81dad976abd Best regards, -- Neil Armstrong
Re: [Intel-gfx] [RFC PATCH 04/20] drm/sched: Convert drm scheduler to use a work queue rather than kthread
Hi, On Tue, 3 Jan 2023 13:02:15 + Tvrtko Ursulin wrote: > On 02/01/2023 07:30, Boris Brezillon wrote: > > On Fri, 30 Dec 2022 12:55:08 +0100 > > Boris Brezillon wrote: > > > >> On Fri, 30 Dec 2022 11:20:42 +0100 > >> Boris Brezillon wrote: > >> > >>> Hello Matthew, > >>> > >>> On Thu, 22 Dec 2022 14:21:11 -0800 > >>> Matthew Brost wrote: > >>> > In XE, the new Intel GPU driver, a choice has made to have a 1 to 1 > mapping between a drm_gpu_scheduler and drm_sched_entity. At first this > seems a bit odd but let us explain the reasoning below. > > 1. In XE the submission order from multiple drm_sched_entity is not > guaranteed to be the same completion even if targeting the same hardware > engine. This is because in XE we have a firmware scheduler, the GuC, > which allowed to reorder, timeslice, and preempt submissions. If a using > shared drm_gpu_scheduler across multiple drm_sched_entity, the TDR falls > apart as the TDR expects submission order == completion order. Using a > dedicated drm_gpu_scheduler per drm_sched_entity solve this problem. > >>> > >>> Oh, that's interesting. I've been trying to solve the same sort of > >>> issues to support Arm's new Mali GPU which is relying on a FW-assisted > >>> scheduling scheme (you give the FW N streams to execute, and it does > >>> the scheduling between those N command streams, the kernel driver > >>> does timeslice scheduling to update the command streams passed to the > >>> FW). I must admit I gave up on using drm_sched at some point, mostly > >>> because the integration with drm_sched was painful, but also because I > >>> felt trying to bend drm_sched to make it interact with a > >>> timeslice-oriented scheduling model wasn't really future proof. Giving > >>> drm_sched_entity exlusive access to a drm_gpu_scheduler probably might > >>> help for a few things (didn't think it through yet), but I feel it's > >>> coming short on other aspects we have to deal with on Arm GPUs. > >> > >> Ok, so I just had a quick look at the Xe driver and how it > >> instantiates the drm_sched_entity and drm_gpu_scheduler, and I think I > >> have a better understanding of how you get away with using drm_sched > >> while still controlling how scheduling is really done. Here > >> drm_gpu_scheduler is just a dummy abstract that let's you use the > >> drm_sched job queuing/dep/tracking mechanism. The whole run-queue > >> selection is dumb because there's only one entity ever bound to the > >> scheduler (the one that's part of the xe_guc_engine object which also > >> contains the drm_gpu_scheduler instance). I guess the main issue we'd > >> have on Arm is the fact that the stream doesn't necessarily get > >> scheduled when ->run_job() is called, it can be placed in the runnable > >> queue and be picked later by the kernel-side scheduler when a FW slot > >> gets released. That can probably be sorted out by manually disabling the > >> job timer and re-enabling it when the stream gets picked by the > >> scheduler. But my main concern remains, we're basically abusing > >> drm_sched here. > >> > >> For the Arm driver, that means turning the following sequence > >> > >> 1. wait for job deps > >> 2. queue job to ringbuf and push the stream to the runnable > >> queue (if it wasn't queued already). Wakeup the timeslice scheduler > >> to re-evaluate (if the stream is not on a FW slot already) > >> 3. stream gets picked by the timeslice scheduler and sent to the FW for > >> execution > >> > >> into > >> > >> 1. queue job to entity which takes care of waiting for job deps for > >> us > >> 2. schedule a drm_sched_main iteration > >> 3. the only available entity is picked, and the first job from this > >> entity is dequeued. ->run_job() is called: the job is queued to the > >> ringbuf and the stream is pushed to the runnable queue (if it wasn't > >> queued already). Wakeup the timeslice scheduler to re-evaluate (if > >> the stream is not on a FW slot already) > >> 4. stream gets picked by the timeslice scheduler and sent to the FW for > >> execution > >> > >> That's one extra step we don't really need. To sum-up, yes, all the > >> job/entity tracking might be interesting to share/re-use, but I wonder > >> if we couldn't have that without pulling out the scheduling part of > >> drm_sched, or maybe I'm missing something, and there's something in > >> drm_gpu_scheduler you really need. > > > > On second thought, that's probably an acceptable overhead (not even > > sure the extra step I was mentioning exists in practice, because dep > > fence signaled state is checked as part of the drm_sched_main > > iteration, so that's basically replacing the worker I schedule to > > check job deps), and I like the idea of being able to re-use drm_sched > > dep-tracking without resorting to invasive changes to the existing > > logic, so I'll probably give it a try. > > I agree with the concerns
Re: [PATCH v2 00/11] Recover from failure to probe GPU
On Tue, Jan 3, 2023 at 5:10 AM Lazar, Lijo wrote: > > > > On 12/28/2022 10:00 PM, Mario Limonciello wrote: > > One of the first thing that KMS drivers do during initialization is > > destroy the system firmware framebuffer by means of > > `drm_aperture_remove_conflicting_pci_framebuffers` > > > > This means that if for any reason the GPU failed to probe the user > > will be stuck with at best a screen frozen at the last thing that > > was shown before the KMS driver continued it's probe. > > > > The problem is most pronounced when new GPU support is introduced > > because users will need to have a recent linux-firmware snapshot > > on their system when they boot a kernel with matching support. > > > > However the problem is further exaggerated in the case of amdgpu because > > it has migrated to "IP discovery" where amdgpu will attempt to load > > on "ALL" AMD GPUs even if the driver is missing support for IP blocks > > contained in that GPU. > > > > IP discovery requires some probing and isn't run until after the > > framebuffer has been destroyed. > > > > This means a situation can occur where a user purchases a new GPU not > > yet supported by a distribution and when booting the installer it will > > "freeze" even if the distribution doesn't have the matching kernel support > > for those IP blocks. > > > > The perfect example of this is Ubuntu 22.10 and the new dGPUs just > > launched by AMD. The installation media ships with kernel 5.19 (which > > has IP discovery) but the amdgpu support for those IP blocks landed in > > kernel 6.0. The matching linux-firmware was released after 22.10's launch. > > The screen will freeze without nomodeset. Even if a user manages to install > > and then upgrades to kernel 6.0 after install they'll still have the > > problem of missing firmware, and the same experience. > > > > This is quite jarring for users, particularly if they don't know > > that they have to use "nomodeset" to install. > > > > To help the situation make changes to GPU discovery: > > 1) Delay releasing the firmware framebuffer until after IP discovery has > > completed. This will help the situation of an older kernel that doesn't > > yet support the IP blocks probing a new GPU. > > 2) Request loading all PSP, VCN, SDMA, MES and GC microcode into memory > > during IP discovery. This will help the situation of new enough kernel for > > the IP discovery phase to otherwise pass but missing microcode from > > linux-firmware.git. > > > > Not all requested firmware will be loaded during IP discovery as some of it > > will require larger driver architecture changes. For example SMU firmware > > isn't loaded on certain products, but that's not known until later on when > > the early_init phase of the SMU load occurs. > > > > v1->v2: > > * Take the suggestion from v1 thread to delay the framebuffer release > > until > > ip discovery is done. This patch is CC to stable to that older stable > > kernels with IP discovery won't try to probe unknown IP. > > * Drop changes to drm aperature. > > * Fetch SDMA, VCN, MES, GC and PSP microcode during IP discovery. > > > > What is the gain here in just checking if firmware files are available? > It can fail anywhere during sw_init and it's the same situation. Other failures are presumably a bug or hardware issue. The missing firmware would be a common issue when chips are first launched. Thinking about it a bit more, another option might be to move the calls to request_firmware() into the IP specific early_init() functions and then move the drm_aperture release after early_init(). That would keep the firmware handling in the IPs and should still happen early enough that we haven't messed with the hardware yet. Alex > > Restricting IP FWs to IP specific files looks better to me than > centralizing and creating interdependencies. > > Thanks, > Lijo > > > Mario Limonciello (11): > >drm/amd: Delay removal of the firmware framebuffer > >drm/amd: Add a legacy mapping to "amdgpu_ucode_ip_version_decode" > >drm/amd: Convert SMUv11 microcode init to use > > `amdgpu_ucode_ip_version_decode` > >drm/amd: Convert SMU v13 to use `amdgpu_ucode_ip_version_decode` > >drm/amd: Request SDMA microcode during IP discovery > >drm/amd: Request VCN microcode during IP discovery > >drm/amd: Request MES microcode during IP discovery > >drm/amd: Request GFX9 microcode during IP discovery > >drm/amd: Request GFX10 microcode during IP discovery > >drm/amd: Request GFX11 microcode during IP discovery > >drm/amd: Request PSP microcode during IP discovery > > > > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 8 + > > drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 590 +- > > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 6 - > > drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 2 - > > drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 9 +- > > drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h | 2 +- >
Re: [PATCH v2] drm/gem: Check for valid formats
Am 03.01.23 um 14:59 schrieb Maíra Canal: Currently, drm_gem_fb_create() doesn't check if the pixel format is supported, which can lead to the acceptance of invalid pixel formats e.g. the acceptance of invalid modifiers. Therefore, add a check for valid formats on drm_gem_fb_create(). Moreover, note that this check is only valid for atomic drivers, because, for non-atomic drivers, checking drm_any_plane_has_format() is not possible since the format list for the primary plane is fake, and we'd therefor reject valid formats. Suggested-by: Thomas Zimmermann Signed-off-by: Maíra Canal Reviewed-by: Thomas Zimmermann --- v1 -> v2: https://lore.kernel.org/dri-devel/20230103125322.855089-1-mca...@igalia.com/T/ - Check the modifier for each pixel plane in multi-plane formats (Thomas Zimmermann). - Use drm_dbg_kms() instead of drm_dbg() (Thomas Zimmermann). --- Documentation/gpu/todo.rst | 7 ++- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 13 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1f8a5ebe188e..68bdafa0284f 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -276,11 +276,8 @@ Various hold-ups: - Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb setup code can't be deleted. -- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For - atomic drivers we could check for valid formats by calling - drm_plane_check_pixel_format() against all planes, and pass if any plane - supports the format. For non-atomic that's not possible since like the format - list for the primary plane is fake and we'd therefor reject valid formats. +- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks for + valid formats for atomic drivers. - Many drivers subclass drm_framebuffer, we'd need a embedding compatible version of the varios drm_gem_fb_create functions. Maybe called diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index e93533b86037..92d748f8553f 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -164,6 +165,18 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev, return -EINVAL; } + if (drm_drv_uses_atomic_modeset(dev)) { + for (i = 0; i < info->num_planes; i++) { + if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format, + mode_cmd->modifier[i])) { + drm_dbg_kms(dev, + "Unsupported pixel format %p4cc / modifier 0x%llx\n", + _cmd->pixel_format, mode_cmd->modifier[i]); + return -EINVAL; + } + } + } + for (i = 0; i < info->num_planes; i++) { unsigned int width = mode_cmd->width / (i ? info->hsub : 1); unsigned int height = mode_cmd->height / (i ? info->vsub : 1); -- 2.38.1 -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/nouveau/mmu: fix Use after Free bug in nvkm_vmm_node_split
On Fri, 30 Dec 2022 08:27:58 +0100, Zheng Wang wrote: > > Here is a function call chain. > nvkm_vmm_pfn_map->nvkm_vmm_pfn_split_merge->nvkm_vmm_node_split > If nvkm_vma_tail return NULL in nvkm_vmm_node_split, it will > finally invoke nvkm_vmm_node_merge->nvkm_vmm_node_delete, which > will free the vma. However, nvkm_vmm_pfn_map didn't notice that. > It goes into next label and UAF happens. > > Fix it by returning the return-value of nvkm_vmm_node_merge > instead of NULL. > > Signed-off-by: Zheng Wang FWIW, CVE-2023-0030 has been assigned to this bug. It's a question whether it really deserves as a security issue, but a bug is a bug... Ben, could you review this please? thanks, Takashi > --- > drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > index ae793f400ba1..84d6fc87b2e8 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c > @@ -937,8 +937,8 @@ nvkm_vmm_node_split(struct nvkm_vmm *vmm, > if (vma->size != size) { > struct nvkm_vma *tmp; > if (!(tmp = nvkm_vma_tail(vma, vma->size - size))) { > - nvkm_vmm_node_merge(vmm, prev, vma, NULL, vma->size); > - return NULL; > + tmp = nvkm_vmm_node_merge(vmm, prev, vma, NULL, > vma->size); > + return tmp; > } > tmp->part = true; > nvkm_vmm_node_insert(vmm, tmp); > -- > 2.25.1 >
[PATCH v2] drm/gem: Check for valid formats
Currently, drm_gem_fb_create() doesn't check if the pixel format is supported, which can lead to the acceptance of invalid pixel formats e.g. the acceptance of invalid modifiers. Therefore, add a check for valid formats on drm_gem_fb_create(). Moreover, note that this check is only valid for atomic drivers, because, for non-atomic drivers, checking drm_any_plane_has_format() is not possible since the format list for the primary plane is fake, and we'd therefor reject valid formats. Suggested-by: Thomas Zimmermann Signed-off-by: Maíra Canal --- v1 -> v2: https://lore.kernel.org/dri-devel/20230103125322.855089-1-mca...@igalia.com/T/ - Check the modifier for each pixel plane in multi-plane formats (Thomas Zimmermann). - Use drm_dbg_kms() instead of drm_dbg() (Thomas Zimmermann). --- Documentation/gpu/todo.rst | 7 ++- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 13 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1f8a5ebe188e..68bdafa0284f 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -276,11 +276,8 @@ Various hold-ups: - Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb setup code can't be deleted. -- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For - atomic drivers we could check for valid formats by calling - drm_plane_check_pixel_format() against all planes, and pass if any plane - supports the format. For non-atomic that's not possible since like the format - list for the primary plane is fake and we'd therefor reject valid formats. +- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks for + valid formats for atomic drivers. - Many drivers subclass drm_framebuffer, we'd need a embedding compatible version of the varios drm_gem_fb_create functions. Maybe called diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index e93533b86037..92d748f8553f 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -164,6 +165,18 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev, return -EINVAL; } + if (drm_drv_uses_atomic_modeset(dev)) { + for (i = 0; i < info->num_planes; i++) { + if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format, + mode_cmd->modifier[i])) { + drm_dbg_kms(dev, + "Unsupported pixel format %p4cc / modifier 0x%llx\n", + _cmd->pixel_format, mode_cmd->modifier[i]); + return -EINVAL; + } + } + } + for (i = 0; i < info->num_planes; i++) { unsigned int width = mode_cmd->width / (i ? info->hsub : 1); unsigned int height = mode_cmd->height / (i ? info->vsub : 1); -- 2.38.1
Re: [RFC PATCH 00/20] Initial Xe driver submission
Hi, On Mon, 02 Jan 2023 13:42:46 +0200 Jani Nikula wrote: > On Mon, 02 Jan 2023, Thomas Zimmermann wrote: > > Hi > > > > Am 22.12.22 um 23:21 schrieb Matthew Brost: > >> Hello, > >> > >> This is a submission for Xe, a new driver for Intel GPUs that supports both > >> integrated and discrete platforms starting with Tiger Lake (first platform > >> with > >> Intel Xe Architecture). The intention of this new driver is to have a > >> fresh base > >> to work from that is unencumbered by older platforms, whilst also taking > >> the > >> opportunity to rearchitect our driver to increase sharing across the drm > >> subsystem, both leveraging and allowing us to contribute more towards other > >> shared components like TTM and drm/scheduler. The memory model is based on > >> VM > >> bind which is similar to the i915 implementation. Likewise the execbuf > >> implementation for Xe is very similar to execbuf3 in the i915 [1]. > > > > After Xe has stabilized, will i915 loose the ability to drive this > > hardware (and possibly other)? I'm specfically thinking of the i915 > > code that requires TTM. Keeping that dependecy within Xe only might > > benefit DRM as a whole. > > There's going to be a number of platforms supported by both drivers, and > from purely a i915 standpoint dropping any currently supported platforms > or that dependency from i915 would be a regression. > > >> > >> The code is at a stage where it is already functional and has experimental > >> support for multiple platforms starting from Tiger Lake, with initial > >> support > >> implemented in Mesa (for Iris and Anv, our OpenGL and Vulkan drivers), as > >> well > >> as in NEO (for OpenCL and Level0). A Mesa MR has been posted [2] and NEO > >> implementation will be released publicly early next year. We also have a > >> suite > >> of IGTs for XE that will appear on the IGT list shortly. > >> > >> It has been built with the assumption of supporting multiple architectures > >> from > >> the get-go, right now with tests running both on X86 and ARM hosts. And we > >> intend to continue working on it and improving on it as part of the kernel > >> community upstream. > >> > >> The new Xe driver leverages a lot from i915 and work on i915 continues as > >> we > >> ready Xe for production throughout 2023. > >> > >> As for display, the intent is to share the display code with the i915 > >> driver so > >> that there is maximum reuse there. Currently this is being done by > >> compiling the > >> display code twice, but alternatives to that are under consideration and > >> we want > >> to have more discussion on what the best final solution will look like > >> over the > >> next few months. Right now, work is ongoing in refactoring the display > >> codebase > >> to remove as much as possible any unnecessary dependencies on i915 > >> specific data > >> structures there.. > > > > Could both drivers reside in a common parent directory and share > > something like a DRM Intel helper module with the common code? This > > would fit well with the common design of DRM helpers. > > I think it's too early to tell. > > For one thing, setting that up would be a lot of up front infrastructure > work. I'm not sure how to even pull that off when Xe is still > out-of-tree and i915 development plunges on upstream as ever. > > For another, realistically, the overlap between supported platforms is > going to end at some point, and eventually new platforms are only going > to be supported with Xe. That's going to open up new possibilities for > refactoring also the display code. I think it would be premature to lock > in to a common directory structure or a common helper module at this > point. > > I'm not saying no to the idea, and we've contemplated it before, but I > think there are still too many moving parts to decide to go that way. FWIW, I actually have the same dilemma with the driver for new Mali GPUs I'm working on. I initially started making it a sub-driver of the existing panfrost driver (some HW blocks are similar, like the IOMMU and a few other things, and some SW abstracts can be shared here and there, like the GEM allocator logic). But I'm now considering forking the driver (after Alyssa planted the seed :-)), not only because I want to start from a clean sheet on the the uAPI front (wouldn't be an issue in your case, because you're talking about sharing helpers, not the driver frontend), but also because any refactor to panfrost is a potential source of regression for existing users. So, I tend to agree with Jani here, trying to share code before things have settled down is likely to cause pain to both Xe and i915 users+developers. Best Regards, Boris
Re: [PATCH 09/18] vfio-mdev/mdpy-fb: Do not set struct fb_info.apertures
Am 20.12.22 um 10:32 schrieb Javier Martinez Canillas: [adding Kirti Wankhede and k...@vger.kernel.org to Cc list] On 12/19/22 17:05, Thomas Zimmermann wrote: Generic fbdev drivers use the apertures field in struct fb_info to control ownership of the framebuffer memory and graphics device. Do not set the values in mdpy-fb. Signed-off-by: Thomas Zimmermann --- samples/vfio-mdev/mdpy-fb.c | 8 1 file changed, 8 deletions(-) diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c index 9ec93d90e8a5..1de5801cd2e8 100644 --- a/samples/vfio-mdev/mdpy-fb.c +++ b/samples/vfio-mdev/mdpy-fb.c @@ -161,14 +161,6 @@ static int mdpy_fb_probe(struct pci_dev *pdev, goto err_release_fb; } - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto err_unmap; - } - info->apertures->ranges[0].base = info->fix.smem_start; - info->apertures->ranges[0].size = info->fix.smem_len; - info->fbops = _fb_ops; info->flags = FBINFO_DEFAULT; info->pseudo_palette = par->palette; Reviewed-by: Javier Martinez Canillas But I think an ack from Kirti Wankhede or other virt folk is needed if you want to merge this through drm-misc-next. ping. Could I have a review from the vfio devs, please. Best regards Thomas -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 3/9] drm/arm/hdlcd: use new debugfs device-centered functions
On Mon, Dec 26, 2022 at 12:50:23PM -0300, Maíra Canal wrote: > Replace the use of drm_debugfs_create_files() with the new > drm_debugfs_add_files() function, which center the debugfs files > management on the drm_device instead of drm_minor. Moreover, remove the > debugfs_init hook and add the debugfs files directly on hdlcd_drm_bind(), > before drm_dev_register(). > > Signed-off-by: Maíra Canal Acked-by: Liviu Dudau Best regards, Liviu > --- > drivers/gpu/drm/arm/hdlcd_drv.c | 24 +--- > 1 file changed, 9 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c > index 7043d1c9ed8f..e3507dd6f82a 100644 > --- a/drivers/gpu/drm/arm/hdlcd_drv.c > +++ b/drivers/gpu/drm/arm/hdlcd_drv.c > @@ -195,8 +195,8 @@ static int hdlcd_setup_mode_config(struct drm_device *drm) > #ifdef CONFIG_DEBUG_FS > static int hdlcd_show_underrun_count(struct seq_file *m, void *arg) > { > - struct drm_info_node *node = (struct drm_info_node *)m->private; > - struct drm_device *drm = node->minor->dev; > + struct drm_debugfs_entry *entry = m->private; > + struct drm_device *drm = entry->dev; > struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm); > > seq_printf(m, "underrun : %d\n", > atomic_read(>buffer_underrun_count)); > @@ -208,8 +208,8 @@ static int hdlcd_show_underrun_count(struct seq_file *m, > void *arg) > > static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) > { > - struct drm_info_node *node = (struct drm_info_node *)m->private; > - struct drm_device *drm = node->minor->dev; > + struct drm_debugfs_entry *entry = m->private; > + struct drm_device *drm = entry->dev; > struct hdlcd_drm_private *hdlcd = drm_to_hdlcd_priv(drm); > unsigned long clkrate = clk_get_rate(hdlcd->clk); > unsigned long mode_clock = hdlcd->crtc.mode.crtc_clock * 1000; > @@ -219,17 +219,10 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void > *arg) > return 0; > } > > -static struct drm_info_list hdlcd_debugfs_list[] = { > +static struct drm_debugfs_info hdlcd_debugfs_list[] = { > { "interrupt_count", hdlcd_show_underrun_count, 0 }, > { "clocks", hdlcd_show_pxlclock, 0 }, > }; > - > -static void hdlcd_debugfs_init(struct drm_minor *minor) > -{ > - drm_debugfs_create_files(hdlcd_debugfs_list, > - ARRAY_SIZE(hdlcd_debugfs_list), > - minor->debugfs_root, minor); > -} > #endif > > DEFINE_DRM_GEM_DMA_FOPS(fops); > @@ -237,9 +230,6 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); > static const struct drm_driver hdlcd_driver = { > .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, > DRM_GEM_DMA_DRIVER_OPS, > -#ifdef CONFIG_DEBUG_FS > - .debugfs_init = hdlcd_debugfs_init, > -#endif > .fops = , > .name = "hdlcd", > .desc = "ARM HDLCD Controller DRM", > @@ -303,6 +293,10 @@ static int hdlcd_drm_bind(struct device *dev) > drm_mode_config_reset(drm); > drm_kms_helper_poll_init(drm); > > +#ifdef CONFIG_DEBUG_FS > + drm_debugfs_add_files(drm, hdlcd_debugfs_list, > ARRAY_SIZE(hdlcd_debugfs_list)); > +#endif > + > ret = drm_dev_register(drm, 0); > if (ret) > goto err_register; > -- > 2.38.1 > -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --- ¯\_(ツ)_/¯
Re: [Intel-gfx] [PATCH v2] drm/i915: dell wyse 3040 shutdown fix
On Tue, 03 Jan 2023, Rodrigo Vivi wrote: > On Mon, Jan 02, 2023 at 04:56:49PM +0300, Alexey Lukyachuk wrote: >> On Tue, 27 Dec 2022 20:40:03 +0300 >> Alexey Lukyachuk wrote: >> >> > On Tue, 27 Dec 2022 11:39:25 -0500 >> > Rodrigo Vivi wrote: >> > >> > > On Sun, Dec 25, 2022 at 09:55:08PM +0300, Alexey Lukyanchuk wrote: >> > > > dell wyse 3040 doesn't peform poweroff properly, but instead remains >> > > > in >> > > > turned power on state. >> > > >> > > okay, the motivation is explained in the commit msg.. >> > > >> > > > Additional mutex_lock and >> > > > intel_crtc_wait_for_next_vblank >> > > > feature 6.2 kernel resolve this trouble. >> > > >> > > but this why is not very clear... seems that by magic it was found, >> > > without explaining what race we are really protecting here. >> > > >> > > but even worse is: >> > > what about those many random vblank waits in the code? what's the >> > > reasoning? >> > > >> > > > >> > > > cc: sta...@vger.kernel.org >> > > > original commit Link: https://patchwork.freedesktop.org/patch/508926/ >> > > > fixes: fe0f1e3bfdfeb53e18f1206aea4f40b9bd1f291c >> > > > Signed-off-by: Alexey Lukyanchuk >> > > > --- >> > > > I got some troubles with this device (dell wyse 3040) since kernel 5.11 >> > > > started to use i915_driver_shutdown function. I found solution here: >> > > > >> > > > https://lore.kernel.org/dri-devel/y1wd6zj8ldjpc...@intel.com/#r >> > > > >> > > > --- >> > > > drivers/gpu/drm/i915/display/intel_audio.c | 37 +++--- >> > > > 1 file changed, 25 insertions(+), 12 deletions(-) >> > > > >> > > > diff --git a/drivers/gpu/drm/i915/display/intel_audio.c >> > > > b/drivers/gpu/drm/i915/display/intel_audio.c >> > > > index aacbc6da8..44344ecdf 100644 >> > > > --- a/drivers/gpu/drm/i915/display/intel_audio.c >> > > > +++ b/drivers/gpu/drm/i915/display/intel_audio.c >> > > > @@ -336,6 +336,7 @@ static void g4x_audio_codec_disable(struct >> > > > intel_encoder *encoder, >> > > >const struct drm_connector_state >> > > > *old_conn_state) >> > > > { >> > > >struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); >> > > > + struct intel_crtc *crtc = >> > > > to_intel_crtc(old_crtc_state->uapi.crtc); >> > > >u32 eldv, tmp; >> > > > >> > > >tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); >> > > > @@ -348,6 +349,9 @@ static void g4x_audio_codec_disable(struct >> > > > intel_encoder *encoder, >> > > >tmp = intel_de_read(dev_priv, G4X_AUD_CNTL_ST); >> > > >tmp &= ~eldv; >> > > >intel_de_write(dev_priv, G4X_AUD_CNTL_ST, tmp); >> > > > + >> > > > + intel_crtc_wait_for_next_vblank(crtc); >> > > > + intel_crtc_wait_for_next_vblank(crtc); >> > > > } >> > > > >> > > > static void g4x_audio_codec_enable(struct intel_encoder *encoder, >> > > > @@ -355,12 +359,15 @@ static void g4x_audio_codec_enable(struct >> > > > intel_encoder *encoder, >> > > > const struct drm_connector_state >> > > > *conn_state) >> > > > { >> > > >struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); >> > > > + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); >> > > >struct drm_connector *connector = conn_state->connector; >> > > >const u8 *eld = connector->eld; >> > > >u32 eldv; >> > > >u32 tmp; >> > > >int len, i; >> > > > >> > > > + intel_crtc_wait_for_next_vblank(crtc); >> > > > + >> > > >tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); >> > > >if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL) >> > > >eldv = G4X_ELDV_DEVCL_DEVBLC; >> > > > @@ -493,6 +500,7 @@ static void hsw_audio_codec_disable(struct >> > > > intel_encoder *encoder, >> > > >const struct drm_connector_state >> > > > *old_conn_state) >> > > > { >> > > >struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); >> > > > + struct intel_crtc *crtc = >> > > > to_intel_crtc(old_crtc_state->uapi.crtc); >> > > >enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; >> > > >u32 tmp; >> > > > >> > > > @@ -508,6 +516,10 @@ static void hsw_audio_codec_disable(struct >> > > > intel_encoder *encoder, >> > > >tmp |= AUD_CONFIG_N_VALUE_INDEX; >> > > >intel_de_write(dev_priv, HSW_AUD_CFG(cpu_transcoder), tmp); >> > > > >> > > > + >> > > > + intel_crtc_wait_for_next_vblank(crtc); >> > > > + intel_crtc_wait_for_next_vblank(crtc); >> > > > + >> > > >/* Invalidate ELD */ >> > > >tmp = intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD); >> > > >tmp &= ~AUDIO_ELD_VALID(cpu_transcoder); >> > > > @@ -633,6 +645,7 @@ static void hsw_audio_codec_enable(struct >> > > > intel_encoder *encoder, >> > > > const struct drm_connector_state >> > > > *conn_state) >> > > > { >> > > >
Re: [PATCH] drm/gem: Check for valid formats
Hi, thanks for the follow-up patch. Am 03.01.23 um 13:53 schrieb Maíra Canal: Currently, drm_gem_fb_create() doesn't check if the pixel format is supported, which can lead to the acceptance of invalid pixel formats e.g. the acceptance of invalid modifiers. Therefore, add a check for valid formats on drm_gem_fb_create(). Moreover, note that this check is only valid for atomic drivers, because, for non-atomic drivers, checking drm_any_plane_has_format() is not possible since the format list for the primary plane is fake, and we'd therefor reject valid formats. Suggested-by: Thomas Zimmermann Signed-off-by: Maíra Canal --- Documentation/gpu/todo.rst | 7 ++- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 9 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1f8a5ebe188e..68bdafa0284f 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -276,11 +276,8 @@ Various hold-ups: - Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb setup code can't be deleted. -- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For - atomic drivers we could check for valid formats by calling - drm_plane_check_pixel_format() against all planes, and pass if any plane - supports the format. For non-atomic that's not possible since like the format - list for the primary plane is fake and we'd therefor reject valid formats. +- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks for + valid formats for atomic drivers. - Many drivers subclass drm_framebuffer, we'd need a embedding compatible version of the varios drm_gem_fb_create functions. Maybe called diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index e93533b86037..b8a615a138cd 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -164,6 +165,14 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev, return -EINVAL; } + if (drm_drv_uses_atomic_modeset(dev) && + !drm_any_plane_has_format(dev, mode_cmd->pixel_format, + mode_cmd->modifier[0])) { Because this is a generic helper, it has to handle the odd cases as well. Here we cannot assume modifier[0], because there's a modifier for each pixel plane in multi-plane formats. (That's a different type of plane than the struct plane we're passing in.) If one combination isn't supported, the helper should fail. We get the number of pixel planes from the format info. So the correct implementation is something like that if (drm_drv_uses_atomic_modeset())) { for (i = 0; i < info->num_planes; ++i) { if (!drm_any_plane_has_format(dev, pixel_format, \ modifier[i]) { drm_dbg_kms(dev, "error msg"); return -EINVAL; } } } + drm_dbg(dev, "Unsupported pixel format %p4cc / modifier 0x%llx\n", drm_dbg() is for drivers. Use drm_dbg_kms() please. Best regards Thomas + _cmd->pixel_format, mode_cmd->modifier[0]); + return -EINVAL; + } + for (i = 0; i < info->num_planes; i++) { unsigned int width = mode_cmd->width / (i ? info->hsub : 1); unsigned int height = mode_cmd->height / (i ? info->vsub : 1); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [Intel-gfx] [RFC PATCH 04/20] drm/sched: Convert drm scheduler to use a work queue rather than kthread
On 02/01/2023 07:30, Boris Brezillon wrote: On Fri, 30 Dec 2022 12:55:08 +0100 Boris Brezillon wrote: On Fri, 30 Dec 2022 11:20:42 +0100 Boris Brezillon wrote: Hello Matthew, On Thu, 22 Dec 2022 14:21:11 -0800 Matthew Brost wrote: In XE, the new Intel GPU driver, a choice has made to have a 1 to 1 mapping between a drm_gpu_scheduler and drm_sched_entity. At first this seems a bit odd but let us explain the reasoning below. 1. In XE the submission order from multiple drm_sched_entity is not guaranteed to be the same completion even if targeting the same hardware engine. This is because in XE we have a firmware scheduler, the GuC, which allowed to reorder, timeslice, and preempt submissions. If a using shared drm_gpu_scheduler across multiple drm_sched_entity, the TDR falls apart as the TDR expects submission order == completion order. Using a dedicated drm_gpu_scheduler per drm_sched_entity solve this problem. Oh, that's interesting. I've been trying to solve the same sort of issues to support Arm's new Mali GPU which is relying on a FW-assisted scheduling scheme (you give the FW N streams to execute, and it does the scheduling between those N command streams, the kernel driver does timeslice scheduling to update the command streams passed to the FW). I must admit I gave up on using drm_sched at some point, mostly because the integration with drm_sched was painful, but also because I felt trying to bend drm_sched to make it interact with a timeslice-oriented scheduling model wasn't really future proof. Giving drm_sched_entity exlusive access to a drm_gpu_scheduler probably might help for a few things (didn't think it through yet), but I feel it's coming short on other aspects we have to deal with on Arm GPUs. Ok, so I just had a quick look at the Xe driver and how it instantiates the drm_sched_entity and drm_gpu_scheduler, and I think I have a better understanding of how you get away with using drm_sched while still controlling how scheduling is really done. Here drm_gpu_scheduler is just a dummy abstract that let's you use the drm_sched job queuing/dep/tracking mechanism. The whole run-queue selection is dumb because there's only one entity ever bound to the scheduler (the one that's part of the xe_guc_engine object which also contains the drm_gpu_scheduler instance). I guess the main issue we'd have on Arm is the fact that the stream doesn't necessarily get scheduled when ->run_job() is called, it can be placed in the runnable queue and be picked later by the kernel-side scheduler when a FW slot gets released. That can probably be sorted out by manually disabling the job timer and re-enabling it when the stream gets picked by the scheduler. But my main concern remains, we're basically abusing drm_sched here. For the Arm driver, that means turning the following sequence 1. wait for job deps 2. queue job to ringbuf and push the stream to the runnable queue (if it wasn't queued already). Wakeup the timeslice scheduler to re-evaluate (if the stream is not on a FW slot already) 3. stream gets picked by the timeslice scheduler and sent to the FW for execution into 1. queue job to entity which takes care of waiting for job deps for us 2. schedule a drm_sched_main iteration 3. the only available entity is picked, and the first job from this entity is dequeued. ->run_job() is called: the job is queued to the ringbuf and the stream is pushed to the runnable queue (if it wasn't queued already). Wakeup the timeslice scheduler to re-evaluate (if the stream is not on a FW slot already) 4. stream gets picked by the timeslice scheduler and sent to the FW for execution That's one extra step we don't really need. To sum-up, yes, all the job/entity tracking might be interesting to share/re-use, but I wonder if we couldn't have that without pulling out the scheduling part of drm_sched, or maybe I'm missing something, and there's something in drm_gpu_scheduler you really need. On second thought, that's probably an acceptable overhead (not even sure the extra step I was mentioning exists in practice, because dep fence signaled state is checked as part of the drm_sched_main iteration, so that's basically replacing the worker I schedule to check job deps), and I like the idea of being able to re-use drm_sched dep-tracking without resorting to invasive changes to the existing logic, so I'll probably give it a try. I agree with the concerns and think that how Xe proposes to integrate with drm_sched is a problem, or at least significantly inelegant. AFAICT it proposes to have 1:1 between *userspace* created contexts (per context _and_ engine) and drm_sched. I am not sure avoiding invasive changes to the shared code is in the spirit of the overall idea and instead opportunity should be used to look at way to refactor/improve drm_sched. Even on the low level, the idea to replace drm_sched threads with workers has a few problems. To start with, the pattern
Re: [PATCH v2 2/3] iommu/sound: Use component_match_add_of helper
Hi Sean, On 22/12/2022 11:37 pm, Sean Anderson wrote: Convert users of component_match_add_release with component_release_of and component_compare_of to component_match_add_of. Signed-off-by: Sean Anderson Acked-by: Mark Brown --- Changes in v2: - Split off from helper addition drivers/iommu/mtk_iommu.c| 3 +-- drivers/iommu/mtk_iommu_v1.c | 3 +-- sound/soc/codecs/wcd938x.c | 6 ++ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 2ab2ecfe01f8..483b7a9e4410 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -1079,8 +1079,7 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m } data->larb_imu[id].dev = >dev; - component_match_add_release(dev, match, component_release_of, - component_compare_of, larbnode); + component_match_add_of(dev, match, larbnode); I've long since given up trying to make sense of how the DRM tree works, but the conflicting change is definitely already in mainline: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=b5765a1b44bea9dfcae69c53ffeb4c689d0922a7 Thanks, Robin. } /* Get smi-(sub)-common dev from the last larb. */ diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 6e0e65831eb7..fb09ed6bf550 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -672,8 +672,7 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) } data->larb_imu[i].dev = >dev; - component_match_add_release(dev, , component_release_of, - component_compare_of, larbnode); + component_match_add_of(dev, , larbnode); } platform_set_drvdata(pdev, data); diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index aca06a4026f3..2f8444e54083 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -4474,8 +4474,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x, } of_node_get(wcd938x->rxnode); - component_match_add_release(dev, matchptr, component_release_of, - component_compare_of, wcd938x->rxnode); + component_match_add_of(dev, matchptr, wcd938x->rxnode); wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0); if (!wcd938x->txnode) { @@ -4483,8 +4482,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x, return -ENODEV; } of_node_get(wcd938x->txnode); - component_match_add_release(dev, matchptr, component_release_of, - component_compare_of, wcd938x->txnode); + component_match_add_of(dev, matchptr, wcd938x->txnode); return 0; }
[PATCH] drm/gem: Check for valid formats
Currently, drm_gem_fb_create() doesn't check if the pixel format is supported, which can lead to the acceptance of invalid pixel formats e.g. the acceptance of invalid modifiers. Therefore, add a check for valid formats on drm_gem_fb_create(). Moreover, note that this check is only valid for atomic drivers, because, for non-atomic drivers, checking drm_any_plane_has_format() is not possible since the format list for the primary plane is fake, and we'd therefor reject valid formats. Suggested-by: Thomas Zimmermann Signed-off-by: Maíra Canal --- Documentation/gpu/todo.rst | 7 ++- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 9 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1f8a5ebe188e..68bdafa0284f 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -276,11 +276,8 @@ Various hold-ups: - Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb setup code can't be deleted. -- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For - atomic drivers we could check for valid formats by calling - drm_plane_check_pixel_format() against all planes, and pass if any plane - supports the format. For non-atomic that's not possible since like the format - list for the primary plane is fake and we'd therefor reject valid formats. +- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks for + valid formats for atomic drivers. - Many drivers subclass drm_framebuffer, we'd need a embedding compatible version of the varios drm_gem_fb_create functions. Maybe called diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index e93533b86037..b8a615a138cd 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -164,6 +165,14 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev, return -EINVAL; } + if (drm_drv_uses_atomic_modeset(dev) && + !drm_any_plane_has_format(dev, mode_cmd->pixel_format, + mode_cmd->modifier[0])) { + drm_dbg(dev, "Unsupported pixel format %p4cc / modifier 0x%llx\n", + _cmd->pixel_format, mode_cmd->modifier[0]); + return -EINVAL; + } + for (i = 0; i < info->num_planes; i++) { unsigned int width = mode_cmd->width / (i ? info->hsub : 1); unsigned int height = mode_cmd->height / (i ? info->vsub : 1); -- 2.38.1
Re: [Intel-gfx] [PATCH v2] drm/i915: dell wyse 3040 shutdown fix
On Mon, Jan 02, 2023 at 04:56:49PM +0300, Alexey Lukyachuk wrote: > On Tue, 27 Dec 2022 20:40:03 +0300 > Alexey Lukyachuk wrote: > > > On Tue, 27 Dec 2022 11:39:25 -0500 > > Rodrigo Vivi wrote: > > > > > On Sun, Dec 25, 2022 at 09:55:08PM +0300, Alexey Lukyanchuk wrote: > > > > dell wyse 3040 doesn't peform poweroff properly, but instead remains in > > > > turned power on state. > > > > > > okay, the motivation is explained in the commit msg.. > > > > > > > Additional mutex_lock and > > > > intel_crtc_wait_for_next_vblank > > > > feature 6.2 kernel resolve this trouble. > > > > > > but this why is not very clear... seems that by magic it was found, > > > without explaining what race we are really protecting here. > > > > > > but even worse is: > > > what about those many random vblank waits in the code? what's the > > > reasoning? > > > > > > > > > > > cc: sta...@vger.kernel.org > > > > original commit Link: https://patchwork.freedesktop.org/patch/508926/ > > > > fixes: fe0f1e3bfdfeb53e18f1206aea4f40b9bd1f291c > > > > Signed-off-by: Alexey Lukyanchuk > > > > --- > > > > I got some troubles with this device (dell wyse 3040) since kernel 5.11 > > > > started to use i915_driver_shutdown function. I found solution here: > > > > > > > > https://lore.kernel.org/dri-devel/y1wd6zj8ldjpc...@intel.com/#r > > > > > > > > --- > > > > drivers/gpu/drm/i915/display/intel_audio.c | 37 +++--- > > > > 1 file changed, 25 insertions(+), 12 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_audio.c > > > > b/drivers/gpu/drm/i915/display/intel_audio.c > > > > index aacbc6da8..44344ecdf 100644 > > > > --- a/drivers/gpu/drm/i915/display/intel_audio.c > > > > +++ b/drivers/gpu/drm/i915/display/intel_audio.c > > > > @@ -336,6 +336,7 @@ static void g4x_audio_codec_disable(struct > > > > intel_encoder *encoder, > > > > const struct drm_connector_state > > > > *old_conn_state) > > > > { > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > + struct intel_crtc *crtc = > > > > to_intel_crtc(old_crtc_state->uapi.crtc); > > > > u32 eldv, tmp; > > > > > > > > tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); > > > > @@ -348,6 +349,9 @@ static void g4x_audio_codec_disable(struct > > > > intel_encoder *encoder, > > > > tmp = intel_de_read(dev_priv, G4X_AUD_CNTL_ST); > > > > tmp &= ~eldv; > > > > intel_de_write(dev_priv, G4X_AUD_CNTL_ST, tmp); > > > > + > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > } > > > > > > > > static void g4x_audio_codec_enable(struct intel_encoder *encoder, > > > > @@ -355,12 +359,15 @@ static void g4x_audio_codec_enable(struct > > > > intel_encoder *encoder, > > > >const struct drm_connector_state > > > > *conn_state) > > > > { > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > > > > struct drm_connector *connector = conn_state->connector; > > > > const u8 *eld = connector->eld; > > > > u32 eldv; > > > > u32 tmp; > > > > int len, i; > > > > > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > + > > > > tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID); > > > > if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL) > > > > eldv = G4X_ELDV_DEVCL_DEVBLC; > > > > @@ -493,6 +500,7 @@ static void hsw_audio_codec_disable(struct > > > > intel_encoder *encoder, > > > > const struct drm_connector_state > > > > *old_conn_state) > > > > { > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > + struct intel_crtc *crtc = > > > > to_intel_crtc(old_crtc_state->uapi.crtc); > > > > enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; > > > > u32 tmp; > > > > > > > > @@ -508,6 +516,10 @@ static void hsw_audio_codec_disable(struct > > > > intel_encoder *encoder, > > > > tmp |= AUD_CONFIG_N_VALUE_INDEX; > > > > intel_de_write(dev_priv, HSW_AUD_CFG(cpu_transcoder), tmp); > > > > > > > > + > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > + intel_crtc_wait_for_next_vblank(crtc); > > > > + > > > > /* Invalidate ELD */ > > > > tmp = intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD); > > > > tmp &= ~AUDIO_ELD_VALID(cpu_transcoder); > > > > @@ -633,6 +645,7 @@ static void hsw_audio_codec_enable(struct > > > > intel_encoder *encoder, > > > >const struct drm_connector_state > > > > *conn_state) > > > > { > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > > > > + struct intel_crtc *crtc =
Re: [PATCH AUTOSEL 5.15 24/27] Revert "drm/amdgpu: Revert "drm/amdgpu: getting fan speed pwm for vega10 properly""
Hello! Why is this revert for revert coming for 6.1 but reverted again for 6.1.2? My GPU is not working correctly again! https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.1.2 It seems like somebody made a mistake and pick up the wrong patch for the stable channel. Regards! On Sat, Nov 19, 2022 at 11:14 AM Sasha Levin wrote: > From: Asher Song > > [ Upstream commit 30b8e7b8ee3be003e0df85c857c5cd0e0bd58b82 ] > > This reverts commit 4545ae2ed3f2f7c3f615a53399c9c8460ee5bca7. > > The origin patch "drm/amdgpu: getting fan speed pwm for vega10 properly" > works fine. > Test failure is caused by test case self. > > Signed-off-by: Asher Song > Reviewed-by: Guchun Chen > Signed-off-by: Alex Deucher > Signed-off-by: Sasha Levin > --- > .../amd/pm/powerplay/hwmgr/vega10_thermal.c | 25 +-- > 1 file changed, 12 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c > b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c > index dad3e3741a4e..190af79f3236 100644 > --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c > +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c > @@ -67,22 +67,21 @@ int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr > *hwmgr, > int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, > uint32_t *speed) > { > - uint32_t current_rpm; > - uint32_t percent = 0; > - > - if (hwmgr->thermal_controller.fanInfo.bNoFan) > - return 0; > + struct amdgpu_device *adev = hwmgr->adev; > + uint32_t duty100, duty; > + uint64_t tmp64; > > - if (vega10_get_current_rpm(hwmgr, _rpm)) > - return -1; > + duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), > + CG_FDO_CTRL1, FMAX_DUTY100); > + duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS), > + CG_THERMAL_STATUS, FDO_PWM_DUTY); > > - if (hwmgr->thermal_controller. > - advanceFanControlParameters.usMaxFanRPM != 0) > - percent = current_rpm * 255 / > - hwmgr->thermal_controller. > - advanceFanControlParameters.usMaxFanRPM; > + if (!duty100) > + return -EINVAL; > > - *speed = MIN(percent, 255); > + tmp64 = (uint64_t)duty * 255; > + do_div(tmp64, duty100); > + *speed = MIN((uint32_t)tmp64, 255); > > return 0; > } > -- > 2.35.1 > >
Re: [Intel-gfx] [RFC PATCH 00/20] Initial Xe driver submission
On 22/12/2022 22:21, Matthew Brost wrote: Hello, This is a submission for Xe, a new driver for Intel GPUs that supports both integrated and discrete platforms starting with Tiger Lake (first platform with Intel Xe Architecture). The intention of this new driver is to have a fresh base to work from that is unencumbered by older platforms, whilst also taking the opportunity to rearchitect our driver to increase sharing across the drm subsystem, both leveraging and allowing us to contribute more towards other shared components like TTM and drm/scheduler. The memory model is based on VM bind which is similar to the i915 implementation. Likewise the execbuf implementation for Xe is very similar to execbuf3 in the i915 [1]. The code is at a stage where it is already functional and has experimental support for multiple platforms starting from Tiger Lake, with initial support implemented in Mesa (for Iris and Anv, our OpenGL and Vulkan drivers), as well as in NEO (for OpenCL and Level0). A Mesa MR has been posted [2] and NEO implementation will be released publicly early next year. We also have a suite of IGTs for XE that will appear on the IGT list shortly. It has been built with the assumption of supporting multiple architectures from the get-go, right now with tests running both on X86 and ARM hosts. And we intend to continue working on it and improving on it as part of the kernel community upstream. The new Xe driver leverages a lot from i915 and work on i915 continues as we ready Xe for production throughout 2023. As for display, the intent is to share the display code with the i915 driver so that there is maximum reuse there. Currently this is being done by compiling the display code twice, but alternatives to that are under consideration and we want to have more discussion on what the best final solution will look like over the next few months. Right now, work is ongoing in refactoring the display codebase to remove as much as possible any unnecessary dependencies on i915 specific data structures there.. We currently have 2 submission backends, execlists and GuC. The execlist is meant mostly for testing and is not fully functional while GuC backend is fully functional. As with the i915 and GuC submission, in Xe the GuC firmware is required and should be placed in /lib/firmware/xe. What is the plan going forward for the execlists backend? I think it would be preferable to not upstream something semi-functional and so to carry technical debt in the brand new code base, from the very start. If it is for Tigerlake, which is the starting platform for Xe, could it be made GuC only Tigerlake for instance? Regards, Tvrtko
[Bug 172421] radeon: allow to set the TMDS frequency by a special kernel parameter
https://bugzilla.kernel.org/show_bug.cgi?id=172421 Eduard Bloch (bl...@debian.org) changed: What|Removed |Added CC||bl...@debian.org --- Comment #24 from Eduard Bloch (bl...@debian.org) --- Hey guys, I am trying to port this mod to AMDGPU. The intention is, however, not to unlock the advertised features but to force an APU to accept HDMI clocks over a DVI port (with DVI-HDMI cable, the monitor expects HDMI signal). The port itself is easy but it does not work. amdgpu.hdmimhz=... parameter has apparently no effect, Xorg keeps reporting: [16.107] (--) AMDGPU(0): HDMI max TMDS frequency 28KHz Does anyone have an idea how to tackle this? Here is the patch: https://github.com/Code7R/linux/commits/amdgpu-custom-maxtdmsclock -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [RFC PATCH 3/4] dt-bindings: panel: Introduce dual-link LVDS panel
Il 03/01/23 07:46, Aradhya Bhatia ha scritto: Dual-link LVDS interfaces have 2 links, with even pixels traveling on one link, and odd pixels on the other. These panels are also generic in nature, with no documented constraints, much like their single-link counterparts, "panel-lvds". Add a new compatible, "panel-dual-lvds", and a dt-binding document for these panels. Signed-off-by: Aradhya Bhatia --- .../display/panel/panel-dual-lvds.yaml| 157 ++ MAINTAINERS | 1 + 2 files changed, 158 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml diff --git a/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml new file mode 100644 index ..88a7aa2410be --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml @@ -0,0 +1,157 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/panel-dual-lvds.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Generic Dual-Link LVDS Display Panel + +maintainers: + - Aradhya Bhatia + - Thierry Reding + +description: | + A dual-LVDS interface is a dual-link connection with the even pixels + traveling on one link, and the odd pixels traveling on the other. + +allOf: + - $ref: panel-common.yaml# + - $ref: /schemas/display/lvds.yaml/# + +properties: + compatible: +oneOf: + - items: + - enum: + - lincolntech,lcd185-101ct + - microtips,13-101hieb0hf0-s + - const: panel-dual-lvds + - const: panel-dual-lvds + + ports: +$ref: /schemas/graph.yaml#/properties/ports + +properties: + port@0: +$ref: /schemas/graph.yaml#/$defs/port-base +unevaluatedProperties: false +description: The sink for first set of LVDS pixels. + +properties: + dual-lvds-odd-pixels: +type: boolean + + dual-lvds-even-pixels: +type: boolean + +oneOf: + - required: [dual-lvds-odd-pixels] One question: why do we need a "panel-dual-lvds" compatible? A Dual-LVDS panel is a LVDS panel using two ports, hence still a panel-lvds. If you're doing this to clearly distinguish, for human readability purposes, single-link vs dual-link panels, I think that this would still be clear even if we use panel-lvds alone because dual-link panels, as you wrote in this binding, does *require* two ports, with "dual-lvds-{odd,even}-pixels" properties. So... the devicetree node would look like this: panel { compatible = "vendor,panel", "panel-lvds"; ports { port@0 { . -> dual-lvds-odd-pixels <- } port@1 { . -> dual-lvds-even-pixels <- }; }; }; + - required: [dual-lvds-even-pixels] ...Though, if you expect dual-lvds panels to get other quirks in the future, that's a whole different story and you may actually need the panel-dual-lvds compatible. Regards, Angelo
Re: [RFC PATCH 3/4] dt-bindings: panel: Introduce dual-link LVDS panel
On 03/01/2023 12:02, Aradhya Bhatia wrote: > But this is throwing an error. I am confused what else could be done. > Can you please suggest what might be a more accurate check here? > >> >>> + required: >>> +- dual-lvds-odd-pixels >>> +then: >>> + properties: >>> +port@1: >>> + properties: >>> +dual-lvds-even-pixels: true >>> +dual-lvds-odd-pixels: false >> >> Why do you need this? Your oneOf before already solves it. > > I agree with your comment here. It makes sense to only have > > dual-lvds-even-pixels: true > > and have the oneOf condition take care of the other. But, I just tested > this and it was unable to pick-up this intentionally-added error. > > I added 'dual-lvds-odd-pixels' property to both the nodes, and > dt_binding_check passes successfully (which it should have not.) > > Instead, if I only keep this, > > dual-lvds-odd-pixels: false > > then the dt_binding_check detects the error as it should. > > Regardless, I am curious why the first method doesn't work. Will try to > explore more on that. The check for presence of properties is only against required:, but you added there properties. Like this: https://elixir.bootlin.com/linux/v5.17-rc2/source/Documentation/devicetree/bindings/mfd/samsung,s5m8767.yaml#L155 Other way is to drop your both oneOf and entire allOf from ports and use: oneOf: - properties: ports: $ref: /schemas/graph.yaml#/properties/ports properties: port@0: required: - dual-lvds-odd-pixels port@1: required: - dual-lvds-even-pixels - properties: ports: $ref: /schemas/graph.yaml#/properties/ports properties: port@1: required: - dual-lvds-odd-pixels port@0: required: - dual-lvds-even-pixels Best regards, Krzysztof
Re: [RFC PATCH 3/4] dt-bindings: panel: Introduce dual-link LVDS panel
Hi Krzysztof, Thank you for reviewing the patches! On 03-Jan-23 14:02, Krzysztof Kozlowski wrote: On 03/01/2023 07:46, Aradhya Bhatia wrote: Dual-link LVDS interfaces have 2 links, with even pixels traveling on one link, and odd pixels on the other. These panels are also generic in nature, with no documented constraints, much like their single-link counterparts, "panel-lvds". Add a new compatible, "panel-dual-lvds", and a dt-binding document for these panels. Signed-off-by: Aradhya Bhatia --- .../display/panel/panel-dual-lvds.yaml| 157 ++ MAINTAINERS | 1 + 2 files changed, 158 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml diff --git a/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml new file mode 100644 index ..88a7aa2410be --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml @@ -0,0 +1,157 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/panel-dual-lvds.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Generic Dual-Link LVDS Display Panel + +maintainers: + - Aradhya Bhatia + - Thierry Reding + +description: | + A dual-LVDS interface is a dual-link connection with the even pixels + traveling on one link, and the odd pixels traveling on the other. + +allOf: + - $ref: panel-common.yaml# + - $ref: /schemas/display/lvds.yaml/# Drop trailing / Okay, will do! + +properties: + compatible: +oneOf: + - items: + - enum: + - lincolntech,lcd185-101ct + - microtips,13-101hieb0hf0-s + - const: panel-dual-lvds + - const: panel-dual-lvds You cannot have this compatible alone Okay, will make the change! + + ports: +$ref: /schemas/graph.yaml#/properties/ports + +properties: + port@0: +$ref: /schemas/graph.yaml#/$defs/port-base +unevaluatedProperties: false +description: The sink for first set of LVDS pixels. + +properties: + dual-lvds-odd-pixels: +type: boolean + + dual-lvds-even-pixels: +type: boolean + +oneOf: + - required: [dual-lvds-odd-pixels] + - required: [dual-lvds-even-pixels] + + port@1: +$ref: /schemas/graph.yaml#/$defs/port-base +unevaluatedProperties: false +description: The sink for second set of LVDS pixels. + +properties: + dual-lvds-even-pixels: +type: boolean + + dual-lvds-odd-pixels: +type: boolean + +oneOf: + - required: [dual-lvds-even-pixels] + - required: [dual-lvds-odd-pixels] + +allOf: + - if: + properties: +port@0: + properties: +dual-lvds-odd-pixels: true That's not correct clause. It has no effect. The idea behind this is to check the presence of the boolean property. if (dual-lvds-odd-pixels is present) then [..] I tried implementing this: [..] dual-lvds-odd-pixels: - const: true [..] But this is throwing an error. I am confused what else could be done. Can you please suggest what might be a more accurate check here? + required: +- dual-lvds-odd-pixels +then: + properties: +port@1: + properties: +dual-lvds-even-pixels: true +dual-lvds-odd-pixels: false Why do you need this? Your oneOf before already solves it. I agree with your comment here. It makes sense to only have dual-lvds-even-pixels: true and have the oneOf condition take care of the other. But, I just tested this and it was unable to pick-up this intentionally-added error. I added 'dual-lvds-odd-pixels' property to both the nodes, and dt_binding_check passes successfully (which it should have not.) Instead, if I only keep this, dual-lvds-odd-pixels: false then the dt_binding_check detects the error as it should. Regardless, I am curious why the first method doesn't work. Will try to explore more on that. + + - if: + properties: +port@0: + properties: +dual-lvds-even-pixels: true + required: +- dual-lvds-even-pixels +then: + properties: +port@1: + properties: +dual-lvds-odd-pixels: true +dual-lvds-even-pixels: false + +required: + - port@0 + - port@1 + + port: false + +unevaluatedProperties: false + +required: + - compatible + - width-mm + - height-mm + - data-mapping + - panel-timing + - ports + +examples: + - |+ Drop + Okay! +panel-dual-lvds {