Re: [PATCH] drm/ttm: remove special handling for non GEM drivers
Christian König wrote: > This is a known issue and fixed by: > > commit a3a9ee4b5254f212c2adaa8cd8ca03bfa112f49d > Author: Christian König > Date: Wed Jun 9 19:25:56 2021 +0200 > > drm/nouveau: init the base GEM fields for internal BOs > > TTMs buffer objects are based on GEM objects for quite a while > and rely on initializing those fields before initializing the TTM BO. > > Nouveau now doesn't init the GEM object for internally allocated BOs, > so make sure that we at least initialize some necessary fields. Ah, good deal. Thanks -- Jamie Heilman http://audible.transient.net/~jamie/
[PATCH] drm/panfrost: devfreq: Don't display error for EPROBE_DEFER
From: Chris Morgan Set a condition for the message of "Couldn't set OPP regulators" to not display if the error code is EPROBE_DEFER. Note that I used an if statement to capture the condition instead of the dev_err_probe function because I didn't want to change the DRM_DEV_ERROR usage. Signed-off-by: Chris Morgan --- drivers/gpu/drm/panfrost/panfrost_devfreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c index 3644652f726f..194af7f607a6 100644 --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c @@ -106,7 +106,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) if (ret) { /* Continue if the optional regulator is missing */ if (ret != -ENODEV) { - DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n"); + if (ret != -EPROBE_DEFER) + DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n"); return ret; } } -- 2.25.1
Re: [PATCH v1 06/10] drm/mediatek: add ETHDR support for MT8195
Hi Chun-Kuang, On Mon, 2021-07-19 at 07:56 +0800, Chun-Kuang Hu wrote: > Hi, Nancy: > > Nancy.Lin 於 2021年7月17日 週六 下午5:04寫道: > > > > Add ETHDR module files: > > ETHDR is designed for HDR video and graphics conversion in the > > external > > display path. It handles multiple HDR input types and performs tone > > mapping, color space/color format conversion, and then combines > > different layers, output the required HDR or SDR signal to the > > subsequent display path. > > > > Signed-off-by: Nancy.Lin > > --- > > drivers/gpu/drm/mediatek/Makefile | 3 +- > > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 8 + > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 11 + > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 + > > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 4 + > > drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 + > > drivers/gpu/drm/mediatek/mtk_ethdr.c| 537 > > > > drivers/gpu/drm/mediatek/mtk_ethdr.h| 20 + > > 8 files changed, 584 insertions(+), 1 deletion(-) > > create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c > > create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h > > > > diff --git a/drivers/gpu/drm/mediatek/Makefile > > b/drivers/gpu/drm/mediatek/Makefile > > index 27c89847d43b..fcce08710cef 100644 > > --- a/drivers/gpu/drm/mediatek/Makefile > > +++ b/drivers/gpu/drm/mediatek/Makefile > > @@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \ > > mtk_drm_gem.o \ > > mtk_drm_plane.o \ > > mtk_dsi.o \ > > - mtk_dpi.o > > + mtk_dpi.o \ > > + mtk_ethdr.o > > > > obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > index 3e27ce7fef57..7227ffbc3eae 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h > > @@ -105,4 +105,12 @@ void mtk_rdma_enable_vblank(struct device > > *dev, > > void *vblank_cb_data); > > void mtk_rdma_disable_vblank(struct device *dev); > > > > +int mtk_ethdr_clk_enable(struct device *dev); > > +void mtk_ethdr_clk_disable(struct device *dev); > > +void mtk_ethdr_config(struct device *dev, unsigned int w, > > + unsigned int h, unsigned int vrefresh, > > + unsigned int bpc, struct cmdq_pkt *cmdq_pkt); > > +void mtk_ethdr_start(struct device *dev); > > +void mtk_ethdr_stop(struct device *dev); > > + > > #endif > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c > > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c > > index 9125d0f6352f..3fa86f12feb4 100644 > > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c > > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c > > @@ -355,6 +355,14 @@ static const struct mtk_ddp_comp_funcs > > ddp_ufoe = { > > .start = mtk_ufoe_start, > > }; > > > > +static const struct mtk_ddp_comp_funcs ddp_ethdr = { > > + .clk_enable = mtk_ethdr_clk_enable, > > + .clk_disable = mtk_ethdr_clk_disable, > > + .config = mtk_ethdr_config, > > + .start = mtk_ethdr_start, > > + .stop = mtk_ethdr_stop, > > +}; > > + > > static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] > > = { > > [MTK_DISP_OVL] = "ovl", > > [MTK_DISP_OVL_2L] = "ovl-2l", > > @@ -363,6 +371,7 @@ static const char * const > > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = { > > [MTK_DISP_COLOR] = "color", > > [MTK_DISP_CCORR] = "ccorr", > > [MTK_DISP_AAL] = "aal", > > + [MTK_DISP_ETHDR] = "ethdr", > > [MTK_DISP_GAMMA] = "gamma", > > [MTK_DISP_DITHER] = "dither", > > [MTK_DISP_UFOE] = "ufoe", > > @@ -399,6 +408,7 @@ static const struct mtk_ddp_comp_match > > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { > > [DDP_COMPONENT_DSI1]= { MTK_DSI,1, &ddp_dsi > > }, > > [DDP_COMPONENT_DSI2]= { MTK_DSI,2, &ddp_dsi > > }, > > [DDP_COMPONENT_DSI3]= { MTK_DSI,3, &ddp_dsi > > }, > > + [DDP_COMPONENT_ETHDR] = { MTK_DISP_ETHDR, 0, > > &ddp_ethdr}, > > [DDP_COMPONENT_GAMMA] = { MTK_DISP_GAMMA, 0, > > &ddp_gamma }, > > [DDP_COMPONENT_MERGE0] = { MTK_DISP_MERGE, 0, > > &ddp_merge }, > > [DDP_COMPONENT_MERGE1] = { MTK_DISP_MERGE, 1, > > &ddp_merge }, > > @@ -536,6 +546,7 @@ int mtk_ddp_comp_init(struct device_node *node, > > struct mtk_ddp_comp *comp, > > type == MTK_DISP_CCORR || > > type == MTK_DISP_COLOR || > > type == MTK_DISP_DSC || > > + type == MTK_DISP_ETHDR || > > type == MTK_DISP_GAMMA || > > type == MTK_DISP_MERGE || > > type == MTK_DISP_OVL || > > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h > > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h > > index 0afd78c0bc92..f5
Re: [PATCH] drm/ttm: remove special handling for non GEM drivers
Christian König wrote: > vmwgfx is the only driver actually using this. Move the handling into > the driver instead. Maybe it isn't the only driver? This commit broke video on my system with a G86 [Quadro NVS 290]. Bisected to d02117f8efaa5fbc37437df1ae955a147a2a424a, and reverting it restored functionality. dmesg of v5.14-rc2: nouveau :01:00.0: vgaarb: deactivate vga console Console: switching to colour dummy device 80x25 nouveau :01:00.0: NVIDIA G86 (086f00a2) nouveau :01:00.0: bios: version 60.86.6c.00.21 nouveau :01:00.0: bios: M0203T not found nouveau :01:00.0: bios: M0203E not matched! nouveau :01:00.0: fb: 256 MiB DDR2 nouveau :01:00.0: DRM: VRAM: 256 MiB nouveau :01:00.0: DRM: GART: 1048576 MiB nouveau :01:00.0: DRM: TMDS table version 2.0 nouveau :01:00.0: DRM: DCB version 4.0 nouveau :01:00.0: DRM: DCB outp 00: 02011300 0028 nouveau :01:00.0: DRM: DCB outp 01: 01011302 0010 nouveau :01:00.0: DRM: DCB outp 02: 01000310 0028 nouveau :01:00.0: DRM: DCB outp 03: 02000312 0010 nouveau :01:00.0: DRM: DCB conn 00: 2030 nouveau :01:00.0: DRM: DCB conn 01: 1130 nouveau :01:00.0: DRM: failed to initialise sync subsystem, -28 nouveau: probe of :01:00.0 failed with error -28 dmesg of v5.14-rc2 w/d02117f8efaa5fbc37437df1ae955a147a2a424a reverted: nouveau :01:00.0: vgaarb: deactivate vga console Console: switching to colour dummy device 80x25 nouveau :01:00.0: NVIDIA G86 (086f00a2) nouveau :01:00.0: bios: version 60.86.6c.00.21 nouveau :01:00.0: bios: M0203T not found nouveau :01:00.0: bios: M0203E not matched! nouveau :01:00.0: fb: 256 MiB DDR2 nouveau :01:00.0: DRM: VRAM: 256 MiB nouveau :01:00.0: DRM: GART: 1048576 MiB nouveau :01:00.0: DRM: TMDS table version 2.0 nouveau :01:00.0: DRM: DCB version 4.0 nouveau :01:00.0: DRM: DCB outp 00: 02011300 0028 nouveau :01:00.0: DRM: DCB outp 01: 01011302 0010 nouveau :01:00.0: DRM: DCB outp 02: 01000310 0028 nouveau :01:00.0: DRM: DCB outp 03: 02000312 0010 nouveau :01:00.0: DRM: DCB conn 00: 2030 nouveau :01:00.0: DRM: DCB conn 01: 1130 nouveau :01:00.0: DRM: MM: using CRYPT for buffer copies nouveau :01:00.0: DRM: allocated 1920x1200 fb: 0x5, bo d0819d42 fbcon: nouveau (fb0) is primary device Console: switching to colour frame buffer device 240x75 nouveau :01:00.0: [drm] fb0: nouveau frame buffer device [drm] Initialized nouveau 1.3.1 20120801 for :01:00.0 on minor 0 > Signed-off-by: Christian König > --- > drivers/gpu/drm/ttm/ttm_bo.c | 11 --- > drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 10 ++ > include/drm/ttm/ttm_bo_api.h | 19 --- > 3 files changed, 10 insertions(+), 30 deletions(-) > > diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c > index 80831df0ef61..38183e227116 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo.c > +++ b/drivers/gpu/drm/ttm/ttm_bo.c > @@ -460,8 +460,6 @@ static void ttm_bo_release(struct kref *kref) > > atomic_dec(&ttm_glob.bo_count); > dma_fence_put(bo->moving); > - if (!ttm_bo_uses_embedded_gem_object(bo)) > - dma_resv_fini(&bo->base._resv); > bo->destroy(bo); > } > > @@ -1056,15 +1054,6 @@ int ttm_bo_init_reserved(struct ttm_device *bdev, > } else { > bo->base.resv = &bo->base._resv; > } > - if (!ttm_bo_uses_embedded_gem_object(bo)) { > - /* > - * bo.base is not initialized, so we have to setup the > - * struct elements we want use regardless. > - */ > - bo->base.size = size; > - dma_resv_init(&bo->base._resv); > - drm_vma_node_reset(&bo->base.vma_node); > - } > atomic_inc(&ttm_glob.bo_count); > > /* > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > index 50e529a01677..587314d57991 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c > @@ -460,6 +460,7 @@ void vmw_bo_bo_free(struct ttm_buffer_object *bo) > WARN_ON(vmw_bo->dirty); > WARN_ON(!RB_EMPTY_ROOT(&vmw_bo->res_tree)); > vmw_bo_unmap(vmw_bo); > + dma_resv_fini(&bo->base._resv); > kfree(vmw_bo); > } > > @@ -512,6 +513,11 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, > unsigned long size, > if (unlikely(ret)) > goto error_free; > > + > + bo->base.size = size; > + dma_resv_init(&bo->base._resv); > + drm_vma_node_reset(&bo->base.vma_node); > + > ret = ttm_bo_init_reserved(&dev_priv->bdev, bo, size, > ttm_bo_type_device, placement, 0, > &ctx, NULL, NULL, NULL); > @@ -570,6 +576,10 @@ int vmw_bo_init(struct vmw_private *dev_priv, > if (unlikely(ret)) > return ret; >
[PATCH] video: fbdev: neofb: add a check against divide error
The userspace program could pass any values to the driver through ioctl() interface. If the driver doesn't check the value of 'pixclock', it may cause divide error because of the 'PICOS2KHZ' macro. Fix this by checking whether 'pixclock' is zero first. The following log reveals it: [ 53.093806] divide error: [#1] PREEMPT SMP KASAN PTI [ 53.093838] CPU: 3 PID: 11763 Comm: hang Not tainted 5.14.0-rc2-00478-g2734d6c1b1a0 #215 [ 53.093859] RIP: 0010:neofb_check_var+0x80/0xe50 [ 53.093951] Call Trace: [ 53.093956] ? neofb_setcolreg+0x2b0/0x2b0 [ 53.093968] fb_set_var+0x2e4/0xeb0 [ 53.093977] ? fb_blank+0x1a0/0x1a0 [ 53.093984] ? lock_acquire+0x1ef/0x530 [ 53.093996] ? lock_release+0x810/0x810 [ 53.094005] ? lock_is_held_type+0x100/0x140 [ 53.094016] ? ___might_sleep+0x1ee/0x2d0 [ 53.094028] ? __mutex_lock+0x620/0x1190 [ 53.094036] ? do_fb_ioctl+0x313/0x700 [ 53.094044] ? mutex_lock_io_nested+0xfa0/0xfa0 [ 53.094051] ? __this_cpu_preempt_check+0x1d/0x30 [ 53.094060] ? _raw_spin_unlock_irqrestore+0x46/0x60 [ 53.094069] ? lockdep_hardirqs_on+0x59/0x100 [ 53.094076] ? _raw_spin_unlock_irqrestore+0x46/0x60 [ 53.094085] ? trace_hardirqs_on+0x6a/0x1c0 [ 53.094096] do_fb_ioctl+0x31e/0x700 Signed-off-by: Zheyu Ma --- drivers/video/fbdev/neofb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c index c0f4f402da3f..966df2a07360 100644 --- a/drivers/video/fbdev/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -585,7 +585,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) DBG("neofb_check_var"); - if (PICOS2KHZ(var->pixclock) > par->maxClock) + if (var->pixclock && PICOS2KHZ(var->pixclock) > par->maxClock) return -EINVAL; /* Is the mode larger than the LCD panel? */ -- 2.17.6
Re: [PATCH v1 01/10] dt-bindings: mediatek: add pseudo-ovl definition for mt8195
Hi Chun-Kuang, On Mon, 2021-07-19 at 07:22 +0800, Chun-Kuang Hu wrote: > Hi, Nancy: > > Nancy.Lin 於 2021年7月17日 週六 下午5:04寫道: > > > > 1. Add pseudo-ovl definition file for mt8195 display. > > 2. Add mediatek,pseudo-ovl.yaml to decribe pseudo-ovl module in > > details. > > > > Signed-off-by: Nancy.Lin > > --- > > .../display/mediatek/mediatek,disp.yaml | 5 + > > .../display/mediatek/mediatek,pseudo-ovl.yaml | 105 > > ++ > > 2 files changed, 110 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/display/mediatek/mediatek,pseudo- > > ovl.yaml > > > > diff --git > > a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp. > > yaml > > b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp. > > yaml > > index aac1796e3f6b..bb6d28572b48 100644 > > --- > > a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp. > > yaml > > +++ > > b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp. > > yaml > > @@ -230,6 +230,11 @@ properties: > >- items: > >- const: mediatek,mt8173-disp-od > > > > + # PSEUDO-OVL: see > > Documentation/devicetree/bindings/display/mediatek/mediatek,pseudo- > > ovl.yaml > > + # for details. > > + - items: > > + - const: mediatek,mt8195-disp-pseudo-ovl > > + > >reg: > > description: Physical base address and length of the function > > block register space. > > > > diff --git > > a/Documentation/devicetree/bindings/display/mediatek/mediatek,pseud > > o-ovl.yaml > > b/Documentation/devicetree/bindings/display/mediatek/mediatek,pseud > > o-ovl.yaml > > new file mode 100644 > > index ..9059d96ce70e > > --- /dev/null > > +++ > > b/Documentation/devicetree/bindings/display/mediatek/mediatek,pseud > > o-ovl.yaml > > @@ -0,0 +1,105 @@ > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: > > https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,pseudo-ovl.yaml*__;Iw!!CTRNKA9wMg0ARbw!1_1k5jdZ0VK46IctSjt63iq1UMWSrAw8cV97W1BmonfuqPnYWBg8R_-BZuPFSKBk$ > > > > +$schema: > > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!1_1k5jdZ0VK46IctSjt63iq1UMWSrAw8cV97W1BmonfuqPnYWBg8R_-BZgMaVN_K$ > > > > + > > +title: mediatek pseudo ovl Device Tree Bindings > > + > > +maintainers: > > + - CK Hu > > + - Nancy.Lin > > + > > +description: | > > + The Mediatek pseudo ovl function block is composed of eight RDMA > > and > > + four MERGE devices. It's encapsulated as an overlay device, > > which supports > > + 4 layers. > > + > > +properties: > > + compatible: > > +oneOf: > > + # pseudo ovl controller > > + - items: > > + - const: mediatek,mt8195-disp-pseudo-ovl > > + # RDMA: read DMA > > + - items: > > + - const: mediatek,mt8195-vdo1-rdma > > + # MERGE: merge streams from two RDMA sources > > + - items: > > + - const: mediatek,mt8195-vdo1-merge > > + reg: > > +maxItems: 1 > > + interrupts: > > +maxItems: 1 > > + iommus: > > +description: The compatible property is DMA function blocks. > > + Should point to the respective IOMMU block with master port > > as argument, > > + see > > Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for > > + details. > > +maxItems: 1 > > + clocks: > > +maxItems: 2 > > + clock-names: > > +maxItems: 2 > > + power-domains: > > +maxItems: 1 > > + mediatek,gce-client-reg: > > +$ref: /schemas/types.yaml#/definitions/phandle-array > > +description: The register of display function block to be set > > by gce. > > + There are 4 arguments in this property, gce node, subsys id, > > offset and > > + register size. The subsys id is defined in the gce header of > > each chips > > + include/include/dt-bindings/gce/-gce.h, mapping to the > > register of > > + display function block. > > + > > +allOf: > > + - if: > > + properties: > > +compatible: > > + contains: > > +const: > > + - mediatek,mt8195-vdo1-merge > > + > > +then: > > + properties: > > +clocks: > > + items: > > +- description: merge clock > > +- description: merge async clock > > +clock-names: > > + items: > > +- const: merge > > +- const: merge_async > > + > > +required: > > + - compatible > > + - reg > > + - clocks > > + > > +additionalProperties: false > > + > > +examples: > > + - | > > + > > +vdo1_rdma@1c104000 { > > +compatible = "mediatek,mt8195-vdo1-rdma", > > + "mediatek,mt8195-disp-pseudo-ovl"; > > Do not create pseudo or virtual device, so just leave the > "mediatek,mt8195-vdo1-rdma". > > Regards, > Chun-Kuang. > OK, I will remove it. > > +reg = <0 0x1c104000 0 0x1000>; > > +interrup
[PATCH v1 3/7] drm/bridge: Add drm_bridge_new_crtc_state() helper
drm_bridge_new_crtc_state() will be used by bridge drivers to provide easy access to the mode from the drm_bridge_funcs operations. The helper will be useful in the atomic operations of struct drm_bridge_funcs. Signed-off-by: Sam Ravnborg Suggested-by: Laurent Pinchart Cc: Laurent Pinchart Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: Andrzej Hajda Cc: Neil Armstrong Cc: Robert Foss Cc: Daniel Vetter --- drivers/gpu/drm/drm_atomic.c | 34 ++ include/drm/drm_atomic.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a8bbb021684b..93d513078e9a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1133,6 +1133,40 @@ drm_atomic_get_new_bridge_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_new_bridge_state); +/** + * drm_bridge_new_crtc_state - get crtc_state for the bridge + * @bridge: bridge object + * @old_bridge_state: state of the bridge + * + * This function returns the &struct drm_crtc_state for the given bridge/state, + * or NULL if no crtc_state could be looked up. In case no crtc_state then this is + * logged using WARN as the crtc_state is always expected to be present. + * This function is often used in the &struct drm_bridge_funcs operations. + */ +const struct drm_crtc_state * +drm_bridge_new_crtc_state(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct drm_atomic_state *state = old_bridge_state->base.state; + const struct drm_connector_state *conn_state; + const struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + if (WARN_ON(!connector)) + return NULL; + + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (WARN_ON(!conn_state || !conn_state->crtc)) + return NULL; + + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + if (WARN_ON(!crtc_state)) + return NULL; + + return crtc_state; +} + /** * drm_atomic_add_encoder_bridges - add bridges attached to an encoder * @state: atomic state diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 1701c2128a5c..a3001eef98bf 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -1119,5 +1119,8 @@ drm_atomic_get_old_bridge_state(struct drm_atomic_state *state, struct drm_bridge_state * drm_atomic_get_new_bridge_state(struct drm_atomic_state *state, struct drm_bridge *bridge); +const struct drm_crtc_state * +drm_bridge_new_crtc_state(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state); #endif /* DRM_ATOMIC_H_ */ -- 2.30.2
[PATCH v1 7/7] drm/todo: Add bridge related todo items
- deprecated callbacks in drm_bridge_funcs - move connector creation to display drivers Signed-off-by: Sam Ravnborg Cc: Laurent Pinchart Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter --- Documentation/gpu/todo.rst | 47 ++ 1 file changed, 47 insertions(+) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 12e61869939e..0ed1f49df73e 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -477,6 +477,53 @@ Contact: Thomas Zimmermann , Christian König, Daniel Vette Level: Intermediate +Drop use of deprecated callbacks in bridge drivers +-- + +&struct drm_bridge_funcs contains a number of deprecated operations +which use can be replaced by the atomic variants. + +* pre_enable => atomic_pre_enable +* enable => atomic_enable +* disable => atomic_disable +* post_disable => atomic_post_disable + +The above are in most cases a simple adjustment of the arguments and names. + +* mode_set is no longer required and the implementation shall be merged + with atomic_enable. + +* mode_fixup => atomic_check + mode_fixup() was created a long time ago, when we were supposed to have + a single bridge at the output of the CRTC. The bridge could then instruct + the CRTC to output a different mode than what the display requires. + Now that we have support for multiple bridges, it's not as straightforward, + and we've so far just pretended to ignore the problem. The .mode_fixup() + operation is used and abused, and just telling people to use .atomic_check() + will likely make things worse as that operation has access to the full atomic + commit and can alter the mode of pretty much anything. We need to define clear + semantics for .atomic_check() in bridges. + + +Contact: Sam Ravnborg , Laurent Pinchart + +Level: Beginner or intermediate (depending on the driver) + +Move connector creation to display drivers +-- + +With the introduction of chained bridges the creation of connectors are moved to the +display drivers. The flag DRM_BRIDGE_ATTACH_NO_CONNECTOR is used to signal to the bridge +driver that no connector shall be created and that the display driver will take care. +Display drivers will in most cases be able to utilise drm_bridge_connector_init() for all +the logic. + +This task requires all bridge drivers to support optional or no connector creation and all +display drivers using bridges to support creating the connector. + +Contact: Sam Ravnborg , bridge maintainers, driver maintainer + +Level: Intermediate or advanced (depending on the driver) Core refactorings = -- 2.30.2
[PATCH v1 5/7] drm/mediatek: Drop chain_mode_fixup call in mode_valid()
The mode_valid implementation had a call to drm_bridge_chain_mode_fixup() which would be wrong as the mode_valid is not allowed to change anything - only to validate the mode. As the next bridge is often/always a connector the call had no effect anyway. So drop it. >From the git history I could see this call was included in the original version of the driver so there was no help there to find out why it was added in the first place. But a lot has changed since the initial driver were added and is seems safe to remove the call now. Signed-off-by: Sam Ravnborg Cc: Chun-Kuang Hu Cc: Philipp Zabel Cc: Matthias Brugger Cc: Dafna Hirschfeld Cc: linux-media...@lists.infradead.org Cc: linux-arm-ker...@lists.infradead.org --- drivers/gpu/drm/mediatek/mtk_hdmi.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index dea46d66e712..c45e4dbd9a2f 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1206,22 +1206,11 @@ static int mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); - struct drm_bridge *next_bridge; dev_dbg(hdmi->dev, "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), !!(mode->flags & DRM_MODE_FLAG_INTERLACE), mode->clock * 1000); - next_bridge = drm_bridge_get_next_bridge(&hdmi->bridge); - if (next_bridge) { - struct drm_display_mode adjusted_mode; - - drm_mode_copy(&adjusted_mode, mode); - if (!drm_bridge_chain_mode_fixup(next_bridge, mode, -&adjusted_mode)) - return MODE_BAD; - } - if (mode->clock < 27000) return MODE_CLOCK_LOW; if (mode->clock > 297000) -- 2.30.2
[PATCH v1 4/7] drm/bridge: lontium-lt9611: Use atomic variants of drm_bridge_funcs
The atomic variants of enable/disable in drm_bridge_funcs are the preferred operations - introduce these. Use of mode_set is deprecated - merge the functionality with atomic_enable() Signed-off-by: Sam Ravnborg Cc: Andrzej Hajda Cc: Neil Armstrong Cc: Robert Foss Cc: Laurent Pinchart Cc: Jonas Karlman Cc: Jernej Skrabec --- drivers/gpu/drm/bridge/lontium-lt9611.c | 69 ++--- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 29b1ce2140ab..dfa7baefe2ab 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -700,9 +700,17 @@ lt9611_connector_mode_valid(struct drm_connector *connector, } /* bridge funcs */ -static void lt9611_bridge_enable(struct drm_bridge *bridge) +static void lt9611_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + const struct drm_display_mode *mode; + const struct drm_crtc_state *crtc_state; + struct hdmi_avi_infoframe avi_frame; + int ret; + + crtc_state = drm_bridge_new_crtc_state(bridge, old_bridge_state); + mode = &crtc_state->mode; if (lt9611_power_on(lt9611)) { dev_err(lt9611->dev, "power on failed\n"); @@ -719,9 +727,21 @@ static void lt9611_bridge_enable(struct drm_bridge *bridge) /* Enable HDMI output */ regmap_write(lt9611->regmap, 0x8130, 0xea); + + lt9611_mipi_input_digital(lt9611, mode); + lt9611_pll_setup(lt9611, mode); + lt9611_mipi_video_setup(lt9611, mode); + lt9611_pcr_setup(lt9611, mode); + + ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, + <9611->connector, + mode); + if (!ret) + lt9611->vic = avi_frame.video_code; } -static void lt9611_bridge_disable(struct drm_bridge *bridge) +static void lt9611_bridge_atomic_disable(struct drm_bridge *bridge, +struct drm_bridge_state *old_bridge_state) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); int ret; @@ -877,48 +897,14 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void lt9611_bridge_pre_enable(struct drm_bridge *bridge) -{ - struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - - if (!lt9611->sleep) - return; - - lt9611_reset(lt9611); - regmap_write(lt9611->regmap, 0x80ee, 0x01); - - lt9611->sleep = false; -} - -static void lt9611_bridge_post_disable(struct drm_bridge *bridge) +static void lt9611_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); lt9611_sleep_setup(lt9611); } -static void lt9611_bridge_mode_set(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - const struct drm_display_mode *adj_mode) -{ - struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - struct hdmi_avi_infoframe avi_frame; - int ret; - - lt9611_bridge_pre_enable(bridge); - - lt9611_mipi_input_digital(lt9611, mode); - lt9611_pll_setup(lt9611, mode); - lt9611_mipi_video_setup(lt9611, mode); - lt9611_pcr_setup(lt9611, mode); - - ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, - <9611->connector, - mode); - if (!ret) - lt9611->vic = avi_frame.video_code; -} - static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge *bridge) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); @@ -954,10 +940,9 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = { .attach = lt9611_bridge_attach, .detach = lt9611_bridge_detach, .mode_valid = lt9611_bridge_mode_valid, - .enable = lt9611_bridge_enable, - .disable = lt9611_bridge_disable, - .post_disable = lt9611_bridge_post_disable, - .mode_set = lt9611_bridge_mode_set, + .atomic_enable = lt9611_bridge_atomic_enable, + .atomic_disable = lt9611_bridge_atomic_disable, + .atomic_post_disable = lt9611_bridge_atomic_post_disable, .detect = lt9611_bridge_detect, .get_edid = lt9611_bridge_get_edid, .hpd_enable = lt9611_bridge_hpd_enable, -- 2.30.2
[PATCH v1 6/7] drm/bridge: Drop drm_bridge_chain_mode_fixup
There are no users left and we do not want to have this function available. drm_atomic_bridge_check() is used to call the mode_fixup() operation for the chained bridges and there is no need for drm_atomic_bridge_check(). Drop it. Signed-off-by: Sam Ravnborg Cc: Laurent Pinchart Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter --- drivers/gpu/drm/drm_bridge.c | 37 include/drm/drm_bridge.h | 3 --- 2 files changed, 40 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index f34a3382a738..fff5abb2a733 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -336,43 +336,6 @@ void drm_bridge_detach(struct drm_bridge *bridge) * needed, in order to gradually transition to the new model. */ -/** - * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the - * encoder chain - * @bridge: bridge control structure - * @mode: desired mode to be set for the bridge - * @adjusted_mode: updated mode that works for this bridge - * - * Calls &drm_bridge_funcs.mode_fixup for all the bridges in the - * encoder chain, starting from the first bridge to the last. - * - * Note: the bridge passed should be the one closest to the encoder - * - * RETURNS: - * true on success, false on failure - */ -bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, -const struct drm_display_mode *mode, -struct drm_display_mode *adjusted_mode) -{ - struct drm_encoder *encoder; - - if (!bridge) - return true; - - encoder = bridge->encoder; - list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { - if (!bridge->funcs->mode_fixup) - continue; - - if (!bridge->funcs->mode_fixup(bridge, mode, adjusted_mode)) - return false; - } - - return true; -} -EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); - /** * drm_bridge_chain_mode_valid - validate the mode against all bridges in the * encoder chain. diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 7bf3d44ecf46..a39531406bfe 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -829,9 +829,6 @@ drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder) #define drm_for_each_bridge_in_chain(encoder, bridge) \ list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node) -bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, -const struct drm_display_mode *mode, -struct drm_display_mode *adjusted_mode); enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, -- 2.30.2
[PATCH v1 2/7] drm/bridge: Drop unused drm_bridge_chain functions
The drm_bridge_chain_{pre_enable,enable,disable,post_disable} has no users left and we have atomic variants that should be used. Drop them so they do not gain new users. Adjust a few comments to avoid references to the dropped functions. Signed-off-by: Sam Ravnborg Cc: Laurent Pinchart Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: Andrzej Hajda Cc: Neil Armstrong Cc: Robert Foss Cc: Daniel Vetter --- drivers/gpu/drm/drm_bridge.c | 110 --- include/drm/drm_bridge.h | 28 - 2 files changed, 138 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 044acd07c153..f34a3382a738 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -415,61 +415,6 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge, } EXPORT_SYMBOL(drm_bridge_chain_mode_valid); -/** - * drm_bridge_chain_disable - disables all bridges in the encoder chain - * @bridge: bridge control structure - * - * Calls &drm_bridge_funcs.disable op for all the bridges in the encoder - * chain, starting from the last bridge to the first. These are called before - * calling the encoder's prepare op. - * - * Note: the bridge passed should be the one closest to the encoder - */ -void drm_bridge_chain_disable(struct drm_bridge *bridge) -{ - struct drm_encoder *encoder; - struct drm_bridge *iter; - - if (!bridge) - return; - - encoder = bridge->encoder; - list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { - if (iter->funcs->disable) - iter->funcs->disable(iter); - - if (iter == bridge) - break; - } -} -EXPORT_SYMBOL(drm_bridge_chain_disable); - -/** - * drm_bridge_chain_post_disable - cleans up after disabling all bridges in the - *encoder chain - * @bridge: bridge control structure - * - * Calls &drm_bridge_funcs.post_disable op for all the bridges in the - * encoder chain, starting from the first bridge to the last. These are called - * after completing the encoder's prepare op. - * - * Note: the bridge passed should be the one closest to the encoder - */ -void drm_bridge_chain_post_disable(struct drm_bridge *bridge) -{ - struct drm_encoder *encoder; - - if (!bridge) - return; - - encoder = bridge->encoder; - list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { - if (bridge->funcs->post_disable) - bridge->funcs->post_disable(bridge); - } -} -EXPORT_SYMBOL(drm_bridge_chain_post_disable); - /** * drm_bridge_chain_mode_set - set proposed mode for all bridges in the *encoder chain @@ -499,61 +444,6 @@ void drm_bridge_chain_mode_set(struct drm_bridge *bridge, } EXPORT_SYMBOL(drm_bridge_chain_mode_set); -/** - * drm_bridge_chain_pre_enable - prepares for enabling all bridges in the - * encoder chain - * @bridge: bridge control structure - * - * Calls &drm_bridge_funcs.pre_enable op for all the bridges in the encoder - * chain, starting from the last bridge to the first. These are called - * before calling the encoder's commit op. - * - * Note: the bridge passed should be the one closest to the encoder - */ -void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) -{ - struct drm_encoder *encoder; - struct drm_bridge *iter; - - if (!bridge) - return; - - encoder = bridge->encoder; - list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { - if (iter->funcs->pre_enable) - iter->funcs->pre_enable(iter); - - if (iter == bridge) - break; - } -} -EXPORT_SYMBOL(drm_bridge_chain_pre_enable); - -/** - * drm_bridge_chain_enable - enables all bridges in the encoder chain - * @bridge: bridge control structure - * - * Calls &drm_bridge_funcs.enable op for all the bridges in the encoder - * chain, starting from the first bridge to the last. These are called - * after completing the encoder's commit op. - * - * Note that the bridge passed should be the one closest to the encoder - */ -void drm_bridge_chain_enable(struct drm_bridge *bridge) -{ - struct drm_encoder *encoder; - - if (!bridge) - return; - - encoder = bridge->encoder; - list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { - if (bridge->funcs->enable) - bridge->funcs->enable(bridge); - } -} -EXPORT_SYMBOL(drm_bridge_chain_enable); - /** * drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain * @bridge: bridge control structure diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 46bdfa48c413..7bf3d44ecf46 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bri
[PATCH v1 1/7] drm/bridge: ps8640: Use atomic variants of drm_bridge_funcs
The atomic variants of enable/disable in drm_bridge_funcs are the preferred operations - introduce these. The ps8640 driver used the non-atomic variants of the drm_bridge chain functions - convert these to the atomic variants. Signed-off-by: Sam Ravnborg Cc: Andrzej Hajda Cc: Neil Armstrong Cc: Robert Foss Cc: Laurent Pinchart Cc: Jonas Karlman Cc: Jernej Skrabec --- drivers/gpu/drm/bridge/parade-ps8640.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c index 7bd0affa057a..58f8122ffb03 100644 --- a/drivers/gpu/drm/bridge/parade-ps8640.c +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -189,7 +189,8 @@ static void ps8640_bridge_poweroff(struct ps8640 *ps_bridge) ps_bridge->powered = false; } -static void ps8640_pre_enable(struct drm_bridge *bridge) +static void ps8640_atomic_pre_enable(struct drm_bridge *bridge, +struct drm_bridge_state *old_bridge_state) { struct ps8640 *ps_bridge = bridge_to_ps8640(bridge); int ret; @@ -201,7 +202,8 @@ static void ps8640_pre_enable(struct drm_bridge *bridge) ps8640_bridge_poweroff(ps_bridge); } -static void ps8640_post_disable(struct drm_bridge *bridge) +static void ps8640_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct ps8640 *ps_bridge = bridge_to_ps8640(bridge); @@ -287,7 +289,7 @@ static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge, * EDID, for this chip, we need to do a full poweron, otherwise it will * fail. */ - drm_bridge_chain_pre_enable(bridge); + drm_atomic_bridge_chain_pre_enable(bridge, connector->state->state); edid = drm_get_edid(connector, ps_bridge->page[PAGE0_DP_CNTL]->adapter); @@ -297,7 +299,7 @@ static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge, * before, return the chip to its original power state. */ if (poweroff) - drm_bridge_chain_post_disable(bridge); + drm_atomic_bridge_chain_post_disable(bridge, connector->state->state); return edid; } @@ -305,8 +307,8 @@ static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge, static const struct drm_bridge_funcs ps8640_bridge_funcs = { .attach = ps8640_bridge_attach, .get_edid = ps8640_bridge_get_edid, - .post_disable = ps8640_post_disable, - .pre_enable = ps8640_pre_enable, + .atomic_post_disable = ps8640_atomic_post_disable, + .atomic_pre_enable = ps8640_atomic_pre_enable, }; static int ps8640_probe(struct i2c_client *client) -- 2.30.2
[PATCH v1 0/7] drm/bridge: Drop deprecated functions
Over time we have accumulated some deprecated functions etc. in drm_bridge. This patch-set starts to move over to the atomic variants and deletes what is not used anymore. There was only one user of the non-atomic drm_bridge_chain functions in parade-ps8640 - migrate it to the atomic variants and delete the non-atomic drm_bridge_chain functions. There was only one user of drm_bridge_chain_mode_fixup in mediatk. The use in the mediatek driver was wrong and with the single user gone we could also delete this function. Added a few todo items. Next step is to migrate the easy bridge drivers to use the atomic variants of drm_bridge_funcs operations. The easy ones are the drivers wihtout mode_set or mode_fixup. I have something typed up already, but wanted feedback on this patchset before sending out additional patches. Sam Sam Ravnborg (7): drm/bridge: ps8640: Use atomic variants of drm_bridge_funcs drm/bridge: Drop unused drm_bridge_chain functions drm/bridge: Add drm_bridge_new_crtc_state() helper drm/bridge: lontium-lt9611: Use atomic variants of drm_bridge_funcs drm/mediatek: Drop chain_mode_fixup call in mode_valid() drm/bridge: Drop drm_bridge_chain_mode_fixup drm/todo: Add bridge related todo items Documentation/gpu/todo.rst | 47 ++ drivers/gpu/drm/bridge/lontium-lt9611.c | 69 ++- drivers/gpu/drm/bridge/parade-ps8640.c | 14 +-- drivers/gpu/drm/drm_atomic.c| 34 drivers/gpu/drm/drm_bridge.c| 147 drivers/gpu/drm/mediatek/mtk_hdmi.c | 11 --- include/drm/drm_atomic.h| 3 + include/drm/drm_bridge.h| 31 --- 8 files changed, 119 insertions(+), 237 deletions(-)
Re: [PATCH v1 06/10] drm/mediatek: add ETHDR support for MT8195
Hi, Nancy: On Thu, 2021-07-22 at 09:32 +0800, Nancy.Lin wrote: > Hi Chun-Kuang, > > On Mon, 2021-07-19 at 07:56 +0800, Chun-Kuang Hu wrote: > > Hi, Nancy: > > > > Nancy.Lin 於 2021年7月17日 週六 下午5:04寫道: > > > > > > Add ETHDR module files: > > > ETHDR is designed for HDR video and graphics conversion in the > > > external > > > display path. It handles multiple HDR input types and performs tone > > > mapping, color space/color format conversion, and then combines > > > different layers, output the required HDR or SDR signal to the > > > subsequent display path. > > > > > > Signed-off-by: Nancy.Lin > > > --- > > > drivers/gpu/drm/mediatek/Makefile | 3 +- > > > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 8 + > > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 11 + > > > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 + > > > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 4 + > > > drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 + > > > drivers/gpu/drm/mediatek/mtk_ethdr.c| 537 > > > > > > drivers/gpu/drm/mediatek/mtk_ethdr.h| 20 + > > > 8 files changed, 584 insertions(+), 1 deletion(-) > > > create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c > > > create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h > > > > > > + > > > +void mtk_ethdr_layer_on(struct device *dev, unsigned int idx, > > > + struct cmdq_pkt *cmdq_pkt) > > > +{ > > > + struct mtk_ethdr *priv = dev_get_drvdata(dev); > > > + struct mtk_ethdr_comp *mixer = &priv- > > > >ethdr_comp[ETHDR_MIXER]; > > > + > > > + dev_dbg(dev, "%s+ idx:%d", __func__, idx); > > > + > > > + if (idx < 4) > > > + mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer- > > > >cmdq_base, > > > + mixer->regs, MIX_SRC_CON, > > > BIT(idx)); > > > +} > > > + > > > +void mtk_ethdr_layer_off(struct device *dev, unsigned int idx, > > > +struct cmdq_pkt *cmdq_pkt) > > > +{ > > > + struct mtk_ethdr *priv = dev_get_drvdata(dev); > > > + struct mtk_ethdr_comp *mixer = &priv- > > > >ethdr_comp[ETHDR_MIXER]; > > > + > > > + dev_dbg(dev, "%s+ idx:%d", __func__, idx); > > > + > > > + switch (idx) { > > > + case 0: > > > + mtk_ddp_write_mask(cmdq_pkt, 0, &mixer->cmdq_base, > > > + mixer->regs, MIX_L0_SRC_SIZE, > > > ~0); > > > + break; > > > + case 1: > > > + mtk_ddp_write_mask(cmdq_pkt, 0, &mixer->cmdq_base, > > > + mixer->regs, MIX_L1_SRC_SIZE, > > > ~0); > > > + break; > > > + case 2: > > > + mtk_ddp_write_mask(cmdq_pkt, 0, &mixer->cmdq_base, > > > + mixer->regs, MIX_L2_SRC_SIZE, > > > ~0); > > > + break; > > > + case 3: > > > + mtk_ddp_write_mask(cmdq_pkt, 0, &mixer->cmdq_base, > > > + mixer->regs, MIX_L3_SRC_SIZE, > > > ~0); > > > + break; > > > + default: > > > + dev_dbg(dev, "%s Wrong layer ID\n", __func__); > > > + break; > > > + } > > > > Why not just > > > >mtk_ddp_write_mask(cmdq_pkt, 0, &mixer->cmdq_base, > > mixer->regs, MIX_SRC_CON, > > BIT(idx)); > > > > There are two modes in Mixer. > 1. Background relay mode: all layers off > 2. Normal mix mode: at least one layer on > The timing of the two modes is different, so keep using the normal mix > mode. > Just set the layer region to 0 when the layer off. layer_on() and layer_off() does different things. Comparing before turn on a layer with after turn on->off a layer, the register setting are different. I would like just restore the register. Regards, CK > > > > +} > > > +
Re: [Intel-gfx] [PATCH 3/4] drm/i915/gt: rename legacy engine->hw_id to engine->gen6_hw_id
On Wed, Jul 21, 2021 at 3:51 PM Matt Roper wrote: > > On Tue, Jul 20, 2021 at 04:20:13PM -0700, Lucas De Marchi wrote: > > We kept adding new engines and for that increasing hw_id unnecessarily: > > it's not used since GRAPHICS_VER == 8. Prepend "gen6" to the field and > > try to pack it in the structs to give a hint this field is actually not > > used in recent platforms. > > > > Signed-off-by: Lucas De Marchi > > Reviewed-by: Matt Roper > > although if we apply patch #4 we could probably drop this intermediate I was not so confident people would agree with that patch. Adding the macros to the header as suggested helps it being more palatable though. thanks Lucas De Marchi > step. > > > Matt > > > --- > > drivers/gpu/drm/i915/gt/intel_engine_cs.c| 12 ++-- > > drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- > > drivers/gpu/drm/i915/i915_reg.h | 2 +- > > 3 files changed, 8 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > index a11f69f2e46e..508221de411c 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > @@ -42,7 +42,7 @@ > > > > #define MAX_MMIO_BASES 3 > > struct engine_info { > > - unsigned int hw_id; > > + u8 gen6_hw_id; > > u8 class; > > u8 instance; > > /* mmio bases table *must* be sorted in reverse graphics_ver order */ > > @@ -54,7 +54,7 @@ struct engine_info { > > > > static const struct engine_info intel_engines[] = { > > [RCS0] = { > > - .hw_id = RCS0_HW, > > + .gen6_hw_id = RCS0_HW, > > .class = RENDER_CLASS, > > .instance = 0, > > .mmio_bases = { > > @@ -62,7 +62,7 @@ static const struct engine_info intel_engines[] = { > > }, > > }, > > [BCS0] = { > > - .hw_id = BCS0_HW, > > + .gen6_hw_id = BCS0_HW, > > .class = COPY_ENGINE_CLASS, > > .instance = 0, > > .mmio_bases = { > > @@ -70,7 +70,7 @@ static const struct engine_info intel_engines[] = { > > }, > > }, > > [VCS0] = { > > - .hw_id = VCS0_HW, > > + .gen6_hw_id = VCS0_HW, > > .class = VIDEO_DECODE_CLASS, > > .instance = 0, > > .mmio_bases = { > > @@ -102,7 +102,7 @@ static const struct engine_info intel_engines[] = { > > }, > > }, > > [VECS0] = { > > - .hw_id = VECS0_HW, > > + .gen6_hw_id = VECS0_HW, > > .class = VIDEO_ENHANCEMENT_CLASS, > > .instance = 0, > > .mmio_bases = { > > @@ -290,7 +290,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum > > intel_engine_id id) > > engine->i915 = i915; > > engine->gt = gt; > > engine->uncore = gt->uncore; > > - engine->hw_id = info->hw_id; > > + engine->gen6_hw_id = info->gen6_hw_id; > > guc_class = engine_class_to_guc_class(info->class); > > engine->guc_id = MAKE_GUC_ID(guc_class, info->instance); > > engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases); > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > index a107eb58ffa2..266422d8d1b1 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > @@ -264,11 +264,11 @@ struct intel_engine_cs { > > enum intel_engine_id id; > > enum intel_engine_id legacy_idx; > > > > - unsigned int hw_id; > > unsigned int guc_id; > > > > intel_engine_mask_t mask; > > > > + u8 gen6_hw_id; > > u8 class; > > u8 instance; > > > > diff --git a/drivers/gpu/drm/i915/i915_reg.h > > b/drivers/gpu/drm/i915/i915_reg.h > > index 943fe485c662..8750ffce9d61 100644 > > --- a/drivers/gpu/drm/i915/i915_reg.h > > +++ b/drivers/gpu/drm/i915/i915_reg.h > > @@ -2572,7 +2572,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) > > #define ARB_MODE_BWGTLB_DISABLE (1 << 9) > > #define ARB_MODE_SWIZZLE_BDW (1 << 1) > > #define RENDER_HWS_PGA_GEN7 _MMIO(0x04080) > > -#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * > > (engine)->hw_id) > > +#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * > > (engine)->gen6_hw_id) > > #define GEN8_RING_FAULT_REG _MMIO(0x4094) > > #define GEN12_RING_FAULT_REG _MMIO(0xcec4) > > #define GEN8_RING_FAULT_ENGINE_ID(x) (((x) >> 12) & 0x7) > > -- > > 2.31.1 > > > > -- > Matt Roper > Graphics Software Engineer > VTT-OSGC Platform Enablement > Intel Corporation > (916) 356-2795 > ___ > Intel-gfx mailing list > intel-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 33/51] drm/i915/guc: Provide mmio list to be saved/restored on engine reset
On Fri, Jul 16, 2021 at 01:17:06PM -0700, Matthew Brost wrote: > From: John Harrison > > The driver must provide GuC with a list of mmio registers > that should be saved/restored during a GuC-based engine reset. > Unfortunately, the list must be dynamically allocated as its size is > variable. That means the driver must generate the list twice - once to > work out the size and a second time to actually save it. > > v2: > (Alan / CI) > - GEN7_GT_MODE -> GEN6_GT_MODE to fix WA selftest failure > > Signed-off-by: John Harrison > Signed-off-by: Fernando Pacheco > Signed-off-by: Matthew Brost Everything looks structurally correct. Feel confident on my below RB but W/A are not my area of expertise. If any one else wanted to give it a look, I wouldn't mind. With that: Reviewed-by: Matthew Brost > Cc: Daniele Ceraolo Spurio > Cc: Tvrtko Ursulin > --- > drivers/gpu/drm/i915/gt/intel_workarounds.c | 46 ++-- > .../gpu/drm/i915/gt/intel_workarounds_types.h | 1 + > drivers/gpu/drm/i915/gt/uc/intel_guc.h| 1 + > drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 199 +- > drivers/gpu/drm/i915/i915_reg.h | 1 + > 5 files changed, 222 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c > b/drivers/gpu/drm/i915/gt/intel_workarounds.c > index 72562c233ad2..34738ccab8bd 100644 > --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c > +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c > @@ -150,13 +150,14 @@ static void _wa_add(struct i915_wa_list *wal, const > struct i915_wa *wa) > } > > static void wa_add(struct i915_wa_list *wal, i915_reg_t reg, > -u32 clear, u32 set, u32 read_mask) > +u32 clear, u32 set, u32 read_mask, bool masked_reg) > { > struct i915_wa wa = { > .reg = reg, > .clr = clear, > .set = set, > .read = read_mask, > + .masked_reg = masked_reg, > }; > > _wa_add(wal, &wa); > @@ -165,7 +166,7 @@ static void wa_add(struct i915_wa_list *wal, i915_reg_t > reg, > static void > wa_write_clr_set(struct i915_wa_list *wal, i915_reg_t reg, u32 clear, u32 > set) > { > - wa_add(wal, reg, clear, set, clear); > + wa_add(wal, reg, clear, set, clear, false); > } > > static void > @@ -200,20 +201,20 @@ wa_write_clr(struct i915_wa_list *wal, i915_reg_t reg, > u32 clr) > static void > wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val) > { > - wa_add(wal, reg, 0, _MASKED_BIT_ENABLE(val), val); > + wa_add(wal, reg, 0, _MASKED_BIT_ENABLE(val), val, true); > } > > static void > wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val) > { > - wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val); > + wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val, true); > } > > static void > wa_masked_field_set(struct i915_wa_list *wal, i915_reg_t reg, > u32 mask, u32 val) > { > - wa_add(wal, reg, 0, _MASKED_FIELD(mask, val), mask); > + wa_add(wal, reg, 0, _MASKED_FIELD(mask, val), mask, true); > } > > static void gen6_ctx_workarounds_init(struct intel_engine_cs *engine, > @@ -583,10 +584,10 @@ static void icl_ctx_workarounds_init(struct > intel_engine_cs *engine, >GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC); > > /* WaEnableFloatBlendOptimization:icl */ > - wa_write_clr_set(wal, > - GEN10_CACHE_MODE_SS, > - 0, /* write-only, so skip validation */ > - _MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE)); > + wa_add(wal, GEN10_CACHE_MODE_SS, 0, > +_MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE), > +0 /* write-only, so skip validation */, > +true); > > /* WaDisableGPGPUMidThreadPreemption:icl */ > wa_masked_field_set(wal, GEN8_CS_CHICKEN1, > @@ -631,7 +632,7 @@ static void gen12_ctx_gt_tuning_init(struct > intel_engine_cs *engine, > FF_MODE2, > FF_MODE2_TDS_TIMER_MASK, > FF_MODE2_TDS_TIMER_128, > -0); > +0, false); > } > > static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine, > @@ -669,7 +670,7 @@ static void gen12_ctx_workarounds_init(struct > intel_engine_cs *engine, > FF_MODE2, > FF_MODE2_GS_TIMER_MASK, > FF_MODE2_GS_TIMER_224, > -0); > +0, false); > > /* >* Wa_14012131227:dg1 > @@ -847,7 +848,7 @@ hsw_gt_workarounds_init(struct drm_i915_private *i915, > struct i915_wa_list *wal) > wa_add(wal, > HSW_ROW_CHICKEN3, 0, > _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE), > - 0 /* XXX does this reg exist? */); > +0 /* XXX does this reg exist? */, true); > > /* WaVSRefCountFullforceMissDisable:hsw */ > wa_write_clr(wal, GEN7_FF_THREAD_M
[PATCH] drivers/firmware: fix sysfb depends to prevent build failures
The Generic System Framebuffers support is built when the COMPILE_TEST option is enabled. But this wrongly assumes that all the architectures declare a struct screen_info. This is true for most architectures, but at least the following do not: arc, m68k, microblaze, openrisc, parisc and s390. By attempting to make this compile testeable on all architectures, it leads to linking errors as reported by the kernel test robot for parisc: All errors (new ones prefixed by >>): hppa-linux-ld: drivers/firmware/sysfb.o: in function `sysfb_init': (.init.text+0x24): undefined reference to `screen_info' >> hppa-linux-ld: (.init.text+0x28): undefined reference to `screen_info' To prevent these errors only allow sysfb to be built on systems that are going to need it, which are x86 BIOS and EFI. The EFI Kconfig symbol is used instead of (ARM || ARM64 || RISC) because some of these architectures only declare a struct screen_info if EFI is enabled. And also, because the sysfb code is only used for EFI on these architectures. For !EFI the "simple-framebuffer" device is registered by OF when parsing the Device Tree Blob (if a DT node for this is defined). Reported-by: kernel test robot Signed-off-by: Javier Martinez Canillas --- drivers/firmware/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index af6719cc576..897f5f25c64 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -254,7 +254,7 @@ config QCOM_SCM_DOWNLOAD_MODE_DEFAULT config SYSFB bool default y - depends on X86 || ARM || ARM64 || RISCV || COMPILE_TEST + depends on X86 || EFI config SYSFB_SIMPLEFB bool "Mark VGA/VBE/EFI FB as generic system framebuffer" -- 2.31.1
[PATCH v2 1/2] drm/msm/dsi: update dsi register header file for tpg
Update the DSI controller header XML file to add registers and bitfields to support rectangular checkered pattern generator. Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/dsi.xml.h | 94 +++ 1 file changed, 75 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index eadbcc7..ae299b7 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -8,25 +8,8 @@ This file was generated by the rules-ng-ng headergen tool in this git repository git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml (981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml (602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml (600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /local/mnt2/workspace2/abhinav/mesa_tool/mesa/src/freedreno/registers/dsi/dsi.xml ( 17500 bytes, from 2021-07-22 02:35:56) +- /local/mnt2/workspace2/abhinav/mesa_tool/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-07-13 18:03:11) Copyright (C) 2013-2021 by the following authors: - Rob Clark (robclark) @@ -105,6 +88,32 @@ enum dsi_lane_swap { LANE_SWAP_3210 = 7, }; +enum video_config_bpp { + VIDEO_CONFIG_18BPP = 0, + VIDEO_CONFIG_24BPP = 1, +}; + +enum video_pattern_sel { + VID_PRBS = 0, + VID_INCREMENTAL = 1, + VID_FIXED = 2, + VID_MDSS_GENERAL_PATTERN = 3, +}; + +enum cmd_mdp_stream0_pattern_sel { + CMD_MDP_PRBS = 0, + CMD_MDP_INCREMENTAL = 1, + CMD_MDP_FIXED = 2, + CMD_MDP_MDSS_GENERAL_PATTERN = 3, +}; + +enum cmd_dma_pattern_sel { + CMD_DMA_PRBS = 0, + CMD_DMA_INCREMENTAL = 1, + CMD_DMA_FIXED = 2, + CMD_DMA_CUSTOM_PATTERN_DMA_FIFO = 3, +}; + #define DSI_IRQ_CMD_DMA_DONE 0x0001 #define DSI_IRQ_MASK_CMD_DMA_DONE 0x0002 #define DSI_IRQ_CMD_MDP_DONE 0x0100 @@ -564,6 +573,53 @@ static inline uint32_t DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(enum dsi_lane_swap val) #define REG_DSI_PHY_RESET 0x0128 #define DSI_PHY_RESET_RESET0x0001 +#define REG_DSI_TEST_PATTERN_GEN_VIDEO_INIT_VAL 0x0160 + +#define REG_DSI_TPG_MAIN_CONTROL 0x0198 +#define DSI_TPG_MAIN_CONTROL_CHECKERED_RECTANGLE_PATTERN 0x0100 + +#define REG_DSI_TPG_VIDEO_CONFIG 0x01a0 +#define DSI_TPG_VIDEO_CONFIG_BPP__MASK 0x0003 +#define DSI_TPG_VIDEO_CONFIG_BPP__SHIFT
[PATCH v2 2/2] drm/msm/dsi: add support for dsi test pattern generator
During board bringups its useful to have a DSI test pattern generator to isolate a DPU vs a DSI issue and focus on the relevant hardware block. To facilitate this, add an API which triggers the DSI controller test pattern. The expected output is a rectangular checkered pattern. This has been validated on a single DSI video mode panel by calling it right after drm_panel_enable() which is also the ideal location to use this as the DSI host and the panel have been initialized by then. Further validation on dual DSI and command mode panel is pending. If there are any fix ups needed for those, it shall be applied on top of this change. Changes in v2: - generate the new dsi.xml.h and update the bitfield names Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/dsi.h | 3 ++ drivers/gpu/drm/msm/dsi/dsi_host.c| 61 +++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 13 3 files changed, 77 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 9b8e9b0..663ccbd 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -84,6 +84,7 @@ void msm_dsi_manager_setup_encoder(int id); int msm_dsi_manager_register(struct msm_dsi *msm_dsi); void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi); bool msm_dsi_manager_validate_current_config(u8 id); +void msm_dsi_manager_tpg_enable(void); /* msm dsi */ static inline bool msm_dsi_device_connected(struct msm_dsi *msm_dsi) @@ -148,6 +149,8 @@ int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host); int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi); int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi); void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host); +void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host); + /* dsi phy */ struct msm_dsi_phy; struct msm_dsi_phy_shared_timings { diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index ed504fe..e0a3581 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -2495,3 +2495,64 @@ void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_ho pm_runtime_put_sync(&msm_host->pdev->dev); } + +static void msm_dsi_host_video_test_pattern_setup(struct msm_dsi_host *msm_host) +{ + u32 reg; + + reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL); + + dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_VIDEO_INIT_VAL, 0xff); + /* draw checkered rectangle pattern */ + dsi_write(msm_host, REG_DSI_TPG_MAIN_CONTROL, + DSI_TPG_MAIN_CONTROL_CHECKERED_RECTANGLE_PATTERN); + /* use 24-bit RGB test pttern */ + dsi_write(msm_host, REG_DSI_TPG_VIDEO_CONFIG, + DSI_TPG_VIDEO_CONFIG_BPP(VIDEO_CONFIG_24BPP) | + DSI_TPG_VIDEO_CONFIG_RGB); + + reg |= DSI_TEST_PATTERN_GEN_CTRL_VIDEO_PATTERN_SEL(VID_MDSS_GENERAL_PATTERN); + dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, reg); + + DBG("Video test pattern setup done\n"); +} + +static void msm_dsi_host_cmd_test_pattern_setup(struct msm_dsi_host *msm_host) +{ + u32 reg; + + reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL); + + /* initial value for test pattern */ + dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0, 0xff); + + reg |= DSI_TEST_PATTERN_GEN_CTRL_CMD_MDP_STREAM0_PATTERN_SEL(CMD_MDP_MDSS_GENERAL_PATTERN); + + dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, reg); + /* draw checkered rectangle pattern */ + dsi_write(msm_host, REG_DSI_TPG_MAIN_CONTROL2, + DSI_TPG_MAIN_CONTROL2_CMD_MDP0_CHECKERED_RECTANGLE_PATTERN); + + DBG("Cmd test pattern setup done\n"); +} + +void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host) +{ + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + bool is_video_mode = !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO); + u32 reg; + + if (is_video_mode) + msm_dsi_host_video_test_pattern_setup(msm_host); + else + msm_dsi_host_cmd_test_pattern_setup(msm_host); + + reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL); + /* enable the test pattern generator */ + dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, (reg | DSI_TEST_PATTERN_GEN_CTRL_EN)); + + /* for command mode need to trigger one frame from tpg */ + if (!is_video_mode) + dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER, + DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER_SW_TRIGGER); +} diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 4ebfedc..db80de6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -441,6 +441,19 @@ static void ds
[PATCH] drm/msm/dp: Initialize the INTF_CONFIG register
Some bootloaders set the widebus enable bit in the INTF_CONFIG register, but configuration of widebus isn't yet supported ensure that the register has a known value, with widebus disabled. Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support") Signed-off-by: Bjorn Andersson --- drivers/gpu/drm/msm/dp/dp_catalog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 23458b0ddc37..37cb1102a0ca 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -747,6 +747,7 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog) dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, dp_catalog->width_blanking); dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active); + dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0); return 0; } -- 2.29.2
[PATCH 5/5] drm/msm/dp: Allow sub-regions to be specified in DT
Not all platforms has P0 at an offset of 0x1000 from the base address, so add support for specifying each sub-region in DT. The code falls back to the predefined offsets in the case that only a single reg is specified, in order to support existing DT. Signed-off-by: Bjorn Andersson --- drivers/gpu/drm/msm/dp/dp_parser.c | 49 +++--- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index 1a10901ae574..fc8a6452f641 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -63,18 +63,45 @@ static int dp_parser_ctrl_res(struct dp_parser *parser) return PTR_ERR(dss->ahb); } - if (dss->ahb_len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) { - DRM_ERROR("legacy memory region not large enough\n"); - return -EINVAL; - } + dss->aux = dp_ioremap(pdev, 1, &dss->aux_len); + if (IS_ERR(dss->aux)) { + /* +* The initial binding had a single reg, but in order to +* support variation in the sub-region sizes this was split. +* dp_ioremap() will fail with -ENODEV here if only a single +* reg is specified, so fill in the sub-region offsets and +* lengths based on this single region. +*/ + if (PTR_ERR(dss->aux) == -ENODEV) { + if (dss->ahb_len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) { + DRM_ERROR("legacy memory region not large enough\n"); + return -EINVAL; + } + + dss->ahb_len = DP_DEFAULT_AHB_SIZE; + dss->aux = dss->ahb + DP_DEFAULT_AUX_OFFSET; + dss->aux_len = DP_DEFAULT_AUX_SIZE; + dss->link = dss->ahb + DP_DEFAULT_LINK_OFFSET; + dss->link_len = DP_DEFAULT_LINK_SIZE; + dss->p0 = dss->ahb + DP_DEFAULT_P0_OFFSET; + dss->p0_len = DP_DEFAULT_P0_SIZE; + } else { + DRM_ERROR("unable to remap aux region: %pe\n", dss->aux); + return PTR_ERR(dss->aux); + } + } else { + dss->link = dp_ioremap(pdev, 2, &dss->link_len); + if (IS_ERR(dss->link)) { + DRM_ERROR("unable to remap link region: %pe\n", dss->link); + return PTR_ERR(dss->link); + } - dss->ahb_len = DP_DEFAULT_AHB_SIZE; - dss->aux = dss->ahb + DP_DEFAULT_AUX_OFFSET; - dss->aux_len = DP_DEFAULT_AUX_SIZE; - dss->link = dss->ahb + DP_DEFAULT_LINK_OFFSET; - dss->link_len = DP_DEFAULT_LINK_SIZE; - dss->p0 = dss->ahb + DP_DEFAULT_P0_OFFSET; - dss->p0_len = DP_DEFAULT_P0_SIZE; + dss->p0 = dp_ioremap(pdev, 3, &dss->p0_len); + if (IS_ERR(dss->p0)) { + DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0); + return PTR_ERR(dss->p0); + } + } io->phy = devm_phy_get(&pdev->dev, "dp"); if (IS_ERR(io->phy)) -- 2.29.2
[PATCH 4/5] drm/msm/dp: Store each subblock in the io region
Not all platforms has DP_P0 at offset 0x1000 from the beginning of the DP block. So dss_io_data into representing each of the sub-regions, to make it possible in the next patch to specify each of the sub-regions individually. Signed-off-by: Bjorn Andersson --- drivers/gpu/drm/msm/dp/dp_catalog.c | 64 + drivers/gpu/drm/msm/dp/dp_parser.c | 30 -- drivers/gpu/drm/msm/dp/dp_parser.h | 10 - 3 files changed, 54 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index ca96e3514790..23458b0ddc37 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -24,15 +24,6 @@ #define DP_INTERRUPT_STATUS_ACK_SHIFT 1 #define DP_INTERRUPT_STATUS_MASK_SHIFT 2 -#define MSM_DP_CONTROLLER_AHB_OFFSET 0x -#define MSM_DP_CONTROLLER_AHB_SIZE 0x0200 -#define MSM_DP_CONTROLLER_AUX_OFFSET 0x0200 -#define MSM_DP_CONTROLLER_AUX_SIZE 0x0200 -#define MSM_DP_CONTROLLER_LINK_OFFSET 0x0400 -#define MSM_DP_CONTROLLER_LINK_SIZE0x0C00 -#define MSM_DP_CONTROLLER_P0_OFFSET0x1000 -#define MSM_DP_CONTROLLER_P0_SIZE 0x0400 - #define DP_INTERRUPT_STATUS1 \ (DP_INTR_AUX_I2C_DONE| \ DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \ @@ -66,82 +57,77 @@ void dp_catalog_snapshot(struct dp_catalog *dp_catalog, struct msm_disp_state *d { struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); + struct dss_io_data *dss = &catalog->io->dp_controller; - msm_disp_snapshot_add_block(disp_state, catalog->io->dp_controller.len, - catalog->io->dp_controller.base, "dp_ctrl"); + msm_disp_snapshot_add_block(disp_state, dss->ahb_len, dss->ahb, "dp_ahb"); + msm_disp_snapshot_add_block(disp_state, dss->aux_len, dss->aux, "dp_aux"); + msm_disp_snapshot_add_block(disp_state, dss->link_len, dss->link, "dp_link"); + msm_disp_snapshot_add_block(disp_state, dss->p0_len, dss->p0, "dp_p0"); } static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset) { - offset += MSM_DP_CONTROLLER_AUX_OFFSET; - return readl_relaxed(catalog->io->dp_controller.base + offset); + return readl_relaxed(catalog->io->dp_controller.aux + offset); } static inline void dp_write_aux(struct dp_catalog_private *catalog, u32 offset, u32 data) { - offset += MSM_DP_CONTROLLER_AUX_OFFSET; /* * To make sure aux reg writes happens before any other operation, * this function uses writel() instread of writel_relaxed() */ - writel(data, catalog->io->dp_controller.base + offset); + writel(data, catalog->io->dp_controller.aux + offset); } static inline u32 dp_read_ahb(struct dp_catalog_private *catalog, u32 offset) { - offset += MSM_DP_CONTROLLER_AHB_OFFSET; - return readl_relaxed(catalog->io->dp_controller.base + offset); + return readl_relaxed(catalog->io->dp_controller.ahb + offset); } static inline void dp_write_ahb(struct dp_catalog_private *catalog, u32 offset, u32 data) { - offset += MSM_DP_CONTROLLER_AHB_OFFSET; /* * To make sure phy reg writes happens before any other operation, * this function uses writel() instread of writel_relaxed() */ - writel(data, catalog->io->dp_controller.base + offset); + writel(data, catalog->io->dp_controller.ahb + offset); } static inline void dp_write_p0(struct dp_catalog_private *catalog, u32 offset, u32 data) { - offset += MSM_DP_CONTROLLER_P0_OFFSET; /* * To make sure interface reg writes happens before any other operation, * this function uses writel() instread of writel_relaxed() */ - writel(data, catalog->io->dp_controller.base + offset); + writel(data, catalog->io->dp_controller.p0 + offset); } static inline u32 dp_read_p0(struct dp_catalog_private *catalog, u32 offset) { - offset += MSM_DP_CONTROLLER_P0_OFFSET; /* * To make sure interface reg writes happens before any other operation, * this function uses writel() instread of writel_relaxed() */ - return readl_relaxed(catalog->io->dp_controller.base + offset); + return readl_relaxed(catalog->io->dp_controller.p0 + offset); } static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset) { - offset += MSM_DP_CONTROLLER_LINK_OFFSET; - return readl_relaxed(catalog->io->dp_controller.base + offset); + return readl_relaxed(catalog->io->dp_controller.link + offset); } static inline void dp_write_link(struct dp_catalog_private *catalog, u32 offset, u32 data) { - offset += MSM_DP_CONTROLLER_LINK_OFFSET
[PATCH 2/5] drm/msm/dp: Use devres for ioremap()
The non-devres version of ioremap is used, which requires manual cleanup. But the code paths leading here is mixed with other devres users, so rely on this for ioremap as well to simplify the code. Signed-off-by: Bjorn Andersson --- drivers/gpu/drm/msm/dp/dp_parser.c | 29 - 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index 0519dd3ac3c3..c064ced78278 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -32,7 +32,7 @@ static int msm_dss_ioremap(struct platform_device *pdev, } io_data->len = (u32)resource_size(res); - io_data->base = ioremap(res->start, io_data->len); + io_data->base = devm_ioremap(&pdev->dev, res->start, io_data->len); if (!io_data->base) { DRM_ERROR("%pS->%s: ioremap failed\n", __builtin_return_address(0), __func__); @@ -42,22 +42,6 @@ static int msm_dss_ioremap(struct platform_device *pdev, return 0; } -static void msm_dss_iounmap(struct dss_io_data *io_data) -{ - if (io_data->base) { - iounmap(io_data->base); - io_data->base = NULL; - } - io_data->len = 0; -} - -static void dp_parser_unmap_io_resources(struct dp_parser *parser) -{ - struct dp_io *io = &parser->io; - - msm_dss_iounmap(&io->dp_controller); -} - static int dp_parser_ctrl_res(struct dp_parser *parser) { int rc = 0; @@ -67,19 +51,14 @@ static int dp_parser_ctrl_res(struct dp_parser *parser) rc = msm_dss_ioremap(pdev, &io->dp_controller); if (rc) { DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc); - goto err; + return rc; } io->phy = devm_phy_get(&pdev->dev, "dp"); - if (IS_ERR(io->phy)) { - rc = PTR_ERR(io->phy); - goto err; - } + if (IS_ERR(io->phy)) + return PTR_ERR(io->phy); return 0; -err: - dp_parser_unmap_io_resources(parser); - return rc; } static int dp_parser_misc(struct dp_parser *parser) -- 2.29.2
[PATCH 1/5] dt-bindings: msm/dp: Change reg definition
reg was defined as one region covering the entire DP block, but the memory map is actually split in 4 regions and obviously the size of these regions differs between platforms. Switch the reg to require that all four regions are specified instead. It is expected that the implementation will handle existing DTBs, even though the schema defines the new layout. Signed-off-by: Bjorn Andersson --- .../bindings/display/msm/dp-controller.yaml | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index 64d8d9e5e47a..a6e41be038fc 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -19,7 +19,11 @@ properties: - qcom,sc7180-dp reg: -maxItems: 1 +items: + - description: ahb register block + - description: aux register block + - description: link register block + - description: p0 register block interrupts: maxItems: 1 @@ -100,7 +104,10 @@ examples: displayport-controller@ae9 { compatible = "qcom,sc7180-dp"; -reg = <0xae9 0x1400>; +reg = <0xae9 0x200>, + <0xae90200 0x200>, + <0xae90400 0xc00>, + <0xae91000 0x400>; interrupt-parent = <&mdss>; interrupts = <12>; clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, -- 2.29.2
[PATCH 3/5] drm/msm/dp: Refactor ioremap wrapper
In order to deal with multiple memory ranges in the following commit change the ioremap wrapper to not poke directly into the dss_io_data struct. Signed-off-by: Bjorn Andersson --- drivers/gpu/drm/msm/dp/dp_parser.c | 28 ++-- drivers/gpu/drm/msm/dp/dp_parser.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index c064ced78278..e68dacef547c 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -19,39 +19,39 @@ static const struct dp_regulator_cfg sdm845_dp_reg_cfg = { }, }; -static int msm_dss_ioremap(struct platform_device *pdev, - struct dss_io_data *io_data) +static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len) { struct resource *res = NULL; + void __iomem *base; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, idx); if (!res) { DRM_ERROR("%pS->%s: msm_dss_get_res failed\n", __builtin_return_address(0), __func__); - return -ENODEV; + return ERR_PTR(-ENODEV); } - io_data->len = (u32)resource_size(res); - io_data->base = devm_ioremap(&pdev->dev, res->start, io_data->len); - if (!io_data->base) { + base = devm_ioremap_resource(&pdev->dev, res); + if (!base) { DRM_ERROR("%pS->%s: ioremap failed\n", __builtin_return_address(0), __func__); - return -EIO; + return ERR_PTR(-EIO); } - return 0; + *len = resource_size(res); + return base; } static int dp_parser_ctrl_res(struct dp_parser *parser) { - int rc = 0; struct platform_device *pdev = parser->pdev; struct dp_io *io = &parser->io; + struct dss_io_data *dss = &io->dp_controller; - rc = msm_dss_ioremap(pdev, &io->dp_controller); - if (rc) { - DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc); - return rc; + dss->base = dp_ioremap(pdev, 0, &dss->len); + if (IS_ERR(dss->base)) { + DRM_ERROR("unable to remap dp io region: %pe\n", dss->base); + return PTR_ERR(dss->base); } io->phy = devm_phy_get(&pdev->dev, "dp"); diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h index 34b49628bbaf..dc62e70b1640 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.h +++ b/drivers/gpu/drm/msm/dp/dp_parser.h @@ -26,7 +26,7 @@ enum dp_pm_type { }; struct dss_io_data { - u32 len; + size_t len; void __iomem *base; }; -- 2.29.2
[PATCH 0/5] drm/msm/dp: Allow variation in register regions
It turns out that sc8180x (among others) doesn't have the same internal layout of the 4 subblocks. This series therefor modifies the binding to require all four regions to be described individually and then extends the driver to read these four regions. The driver will fall back to read the old single-reg format and apply the original offsets and sizes. Bjorn Andersson (5): dt-bindings: msm/dp: Change reg definition drm/msm/dp: Use devres for ioremap() drm/msm/dp: Refactor ioremap wrapper drm/msm/dp: Store each subblock in the io region drm/msm/dp: Allow sub-regions to be specified in DT .../bindings/display/msm/dp-controller.yaml | 11 +- drivers/gpu/drm/msm/dp/dp_catalog.c | 64 --- drivers/gpu/drm/msm/dp/dp_parser.c| 102 +++--- drivers/gpu/drm/msm/dp/dp_parser.h| 10 +- 4 files changed, 102 insertions(+), 85 deletions(-) -- 2.29.2
Re: [PATCH 06/14] drm/i915/guc/slpc: Enable SLPC and add related H2G events
Hi Vinay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on drm-tip/drm-tip] [cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next drm/drm-next v5.14-rc2 next-20210721] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip config: x86_64-rhel-8.3-kselftests (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/14352081e4f18759e70413f3be4151d623c97b8c git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528 git checkout 14352081e4f18759e70413f3be4151d623c97b8c # save the attached .config to linux build tree make W=1 ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:217:5: warning: no previous >> prototype for 'slpc_decode_min_freq' [-Wmissing-prototypes] 217 | u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) | ^~~~ >> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:229:5: warning: no previous >> prototype for 'slpc_decode_max_freq' [-Wmissing-prototypes] 229 | u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) | ^~~~ vim +/slpc_decode_min_freq +217 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 216 > 217 u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) 218 { 219 struct slpc_shared_data *data = slpc->vaddr; 220 221 GEM_BUG_ON(!slpc->vma); 222 223 return DIV_ROUND_CLOSEST( 224 REG_FIELD_GET(SLPC_MIN_UNSLICE_FREQ_MASK, 225 data->task_state_data.freq) * 226 GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER); 227 } 228 > 229 u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) 230 { 231 struct slpc_shared_data *data = slpc->vaddr; 232 233 GEM_BUG_ON(!slpc->vma); 234 235 return DIV_ROUND_CLOSEST( 236 REG_FIELD_GET(SLPC_MAX_UNSLICE_FREQ_MASK, 237 data->task_state_data.freq) * 238 GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER); 239 } 240 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel compatibles
On Wed, Jul 21, 2021 at 04:03:40PM +0200, Maxime Ripard wrote: > The binding mentions that all the drivers using that driver must use a > vendor-specific compatible but never enforces it, nor documents the > vendor-specific compatibles. > > Let's make we document all of them, and that the binding will create an > error if we add one that isn't. > > Cc: dri-devel@lists.freedesktop.org > Cc: Laurent Pinchart > Cc: Sam Ravnborg > Cc: Thierry Reding > Signed-off-by: Maxime Ripard > --- > .../bindings/display/panel/lvds.yaml | 18 -- > 1 file changed, 12 insertions(+), 6 deletions(-) > > diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml > b/Documentation/devicetree/bindings/display/panel/lvds.yaml > index 49460c9dceea..d1513111eb48 100644 > --- a/Documentation/devicetree/bindings/display/panel/lvds.yaml > +++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml > @@ -31,12 +31,18 @@ allOf: > > properties: >compatible: > -contains: > - const: panel-lvds > -description: > - Shall contain "panel-lvds" in addition to a mandatory panel-specific > - compatible string defined in individual panel bindings. The > "panel-lvds" > - value shall never be used on its own. > +items: > + - enum: > + - advantech,idk-1110wr At least this one is documented elsewhere. You can add 'minItems: 2' if you want to just enforce having 2 compatibles. Or do: items: - {} - const: panel-lvds Which also enforces the order. > + - advantech,idk-2121wr > + - auo,b101ew05 > + - innolux,ee101ia-01d > + - mitsubishi,aa104xd12 > + - mitsubishi,aa121td01 > + - sgd,gktw70sdae4se > + - sharp,lq150x1lg11 > + - tbs,a711-panel > + - const: panel-lvds > >data-mapping: > enum: > -- > 2.31.1 > >
Re: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel compatibles
On Wed, 21 Jul 2021 16:03:40 +0200, Maxime Ripard wrote: > The binding mentions that all the drivers using that driver must use a > vendor-specific compatible but never enforces it, nor documents the > vendor-specific compatibles. > > Let's make we document all of them, and that the binding will create an > error if we add one that isn't. > > Cc: dri-devel@lists.freedesktop.org > Cc: Laurent Pinchart > Cc: Sam Ravnborg > Cc: Thierry Reding > Signed-off-by: Maxime Ripard > --- > .../bindings/display/panel/lvds.yaml | 18 -- > 1 file changed, 12 insertions(+), 6 deletions(-) > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13): yamllint warnings/errors: dtschema/dtc warnings/errors: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml: panel: compatible: ['sharp,lq150x1lg11'] is too short From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml: panel: 'data-mapping' is a required property From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml: panel: 'width-mm' is a required property From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml: panel: 'height-mm' is a required property From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml: panel: 'panel-timing' is a required property From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/sharp,lq150x1lg11.example.dt.yaml: panel: 'oneOf' conditional failed, one must be fixed: 'port' is a required property 'ports' is a required property From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/panel/lvds.yaml \ndoc reference errors (make refcheckdocs): See https://patchwork.ozlabs.org/patch/1508254 This check can fail if there are any dependencies. The base for a patch series is generally the most recent rc1. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit.
Re: [PATCH v2 3/3] drm/panel: Add ilitek ili9341 panel driver
Hi Noralf Thanks for your time to review my patch. On Thu, 22 Jul 2021 at 01:42, Noralf Trønnes wrote: > > > > Den 21.07.2021 09.41, skrev dillon.min...@gmail.com: > > From: Dillon Min > > > > This driver combine tiny/ili9341.c mipi_dbi_interface driver > > with mipi_dpi_interface driver, can support ili9341 with serial > > mode or parallel rgb interface mode by register configuration. > > > > Cc: Linus Walleij > > Signed-off-by: Dillon Min > > --- > > > +static const struct of_device_id ili9341_of_match[] = { > > + { > > + .compatible = "st,sf-tc240t-9370-t", > > + .data = &ili9341_stm32f429_disco_data, > > + }, > > + { > > + /* porting from tiny/ili9341.c > > + * for original mipi dbi compitable > > + */ > > + .compatible = "adafruit,yx240qv29", > > I don't understand this, now there will be 2 drivers that support the > same display? There is no reason to create two drivers to support the same display. To support only-dbi and dbi+dpi panel at drm/panel or drm/tiny both fine with me. > > AFAICT drm/tiny/ili9341.c is just copied into this driver, is the plan > to remove the tiny/ driver? If so I couldn't see this mentioned anywhere. Yes, I'd like to merge the code from drm/tiny/ili9341.c to this driver (to make a single driver to support different bus). I have two purpose to extend the feature drm/tiny/ili9341.c - keep compatible = "adafruit,yx240qv29", add bus mode dts bindings (panel_bus) to define the interface which host wants to use. such as panel_bus="dbi" or "rgb" or "i80" for this case, i will add dpi code to drm/tiny/ili9341.c. - merge tiny/ili9341.c to this driver,remove drm/tiny/ili9341.c, add new dts compatible string to support other interfaces. just like what i'm doing now. I have no idea about your plan on drm/tiny drivers, actually some of these panels under the diny folder can support both dbi and dbi+dpi (much faster, need more pins). no doubt the requirement to support dpi is always there. What is your preference? Thanks & Regards Dillon > > Noralf. > > > + .data = NULL, > > + }, > > +}; > > +MODULE_DEVICE_TABLE(of, ili9341_of_match);
[PATCH v4] drm/mediatek: Fix cursor plane didn't update
The cursor plane should use the current plane state in atomic_async_update because it would not be the new plane state in the global atomic state since _swap_state happened when those hook are run. Fix cursor plane issue by below modification: 1. Remove plane_helper_funcs->atomic_update(plane, state) in mtk_drm_crtc_async_update. 2. Add mtk_drm_update_new_state in to mtk_plane_atomic_async_update to update the cursor plane by current plane state hook and update others plane by the new_state. Fixes: 37418bf14c13 ("drm: Use state helper instead of the plane state pointer") Signed-off-by: jason-jh.lin Tested-by: Enric Balletbo i Serra --- Change in v4: - Fix compile warning: ../drivers/gpu/drm/mediatek/mtk_drm_crtc.c:578:39: warning: unused variable ‘plane_helper_funcs’ [-Wunused-variable --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 -- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 60 ++-- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 40df2c823187..515315505e3b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -532,13 +532,10 @@ void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane, struct drm_atomic_state *state) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); - const struct drm_plane_helper_funcs *plane_helper_funcs = - plane->helper_private; if (!mtk_crtc->enabled) return; - plane_helper_funcs->atomic_update(plane, state); mtk_drm_crtc_update_config(mtk_crtc, false); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index b5582dcf564c..e6dcb34d3052 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -110,6 +110,35 @@ static int mtk_plane_atomic_async_check(struct drm_plane *plane, true, true); } +static void mtk_plane_update_new_state(struct drm_plane_state *new_state, + struct mtk_plane_state *mtk_plane_state) +{ + struct drm_framebuffer *fb = new_state->fb; + struct drm_gem_object *gem; + struct mtk_drm_gem_obj *mtk_gem; + unsigned int pitch, format; + dma_addr_t addr; + + gem = fb->obj[0]; + mtk_gem = to_mtk_gem_obj(gem); + addr = mtk_gem->dma_addr; + pitch = fb->pitches[0]; + format = fb->format->format; + + addr += (new_state->src.x1 >> 16) * fb->format->cpp[0]; + addr += (new_state->src.y1 >> 16) * pitch; + + mtk_plane_state->pending.enable = true; + mtk_plane_state->pending.pitch = pitch; + mtk_plane_state->pending.format = format; + mtk_plane_state->pending.addr = addr; + mtk_plane_state->pending.x = new_state->dst.x1; + mtk_plane_state->pending.y = new_state->dst.y1; + mtk_plane_state->pending.width = drm_rect_width(&new_state->dst); + mtk_plane_state->pending.height = drm_rect_height(&new_state->dst); + mtk_plane_state->pending.rotation = new_state->rotation; +} + static void mtk_plane_atomic_async_update(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -126,8 +155,10 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane, plane->state->src_h = new_state->src_h; plane->state->src_w = new_state->src_w; swap(plane->state->fb, new_state->fb); - new_plane_state->pending.async_dirty = true; + mtk_plane_update_new_state(new_state, new_plane_state); + wmb(); /* Make sure the above parameters are set before update */ + new_plane_state->pending.async_dirty = true; mtk_drm_crtc_async_update(new_state->crtc, plane, state); } @@ -189,14 +220,8 @@ static void mtk_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane); struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(new_state); - struct drm_crtc *crtc = new_state->crtc; - struct drm_framebuffer *fb = new_state->fb; - struct drm_gem_object *gem; - struct mtk_drm_gem_obj *mtk_gem; - unsigned int pitch, format; - dma_addr_t addr; - if (!crtc || WARN_ON(!fb)) + if (!new_state->crtc || WARN_ON(!new_state->fb)) return; if (!new_state->visible) { @@ -204,24 +229,7 @@ static void mtk_plane_atomic_update(struct drm_plane *plane, return; } - gem = fb->obj[0]; - mtk_gem = to_mtk_gem_obj(gem); - addr = mtk_gem->dma_addr; - pitch = fb->pitches[0]; - format = fb->format->format;
Re: [PATCH 09/14] drm/i915/guc/slpc: Add debugfs for SLPC info
Hi Vinay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on drm-tip/drm-tip] [cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next drm/drm-next v5.14-rc2 next-20210721] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip config: x86_64-randconfig-a016-20210720 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project c781eb153bfbd1b52b03efe34f56bbeccbb8aba6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://github.com/0day-ci/linux/commit/1c6f8cf3c2757db7a87fceef08834f4e0e14f2f9 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528 git checkout 1c6f8cf3c2757db7a87fceef08834f4e0e14f2f9 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c:67:6: warning: no previous >> prototype for function 'intel_eval_slpc_support' [-Wmissing-prototypes] bool intel_eval_slpc_support(void *data) ^ drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c:67:1: note: declare 'static' if the function is not intended to be used outside of this translation unit bool intel_eval_slpc_support(void *data) ^ static 1 warning generated. -- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:238:5: warning: no previous prototype for function 'slpc_decode_min_freq' [-Wmissing-prototypes] u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) ^ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:238:1: note: declare 'static' if the function is not intended to be used outside of this translation unit u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) ^ static drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:250:5: warning: no previous prototype for function 'slpc_decode_max_freq' [-Wmissing-prototypes] u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) ^ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:250:1: note: declare 'static' if the function is not intended to be used outside of this translation unit u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) ^ static >> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:445:17: warning: variable 'data' >> is uninitialized when used here [-Wuninitialized] slpc_tasks = &data->task_state_data; ^~~~ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:436:31: note: initialize the variable 'data' to silence this warning struct slpc_shared_data *data; ^ = NULL 3 warnings generated. vim +/intel_eval_slpc_support +67 drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c 66 > 67 bool intel_eval_slpc_support(void *data) 68 { 69 struct intel_guc *guc; 70 71 guc = (struct intel_guc *)data; 72 return intel_guc_slpc_is_used(guc); 73 } 74 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH 02/14] drm/i915/guc/slpc: Initial definitions for SLPC
On 7/21/2021 10:24 AM, Michal Wajdeczko wrote: On 21.07.2021 18:11, Vinay Belgaumkar wrote: Add macros to check for SLPC support. This feature is currently supported for Gen12+ and enabled whenever GuC submission is enabled/selected. Include templates for SLPC init/fini and enable. v2: Move SLPC helper functions to intel_guc_slpc.c/.h. Define basic template for SLPC structure in intel_guc_slpc_types.h. Fix copyright (Michal W) Signed-off-by: Vinay Belgaumkar Signed-off-by: Sundaresan Sujaritha Signed-off-by: Daniele Ceraolo Spurio drm/i915/guc/slpc: Lay out slpc init/enable/fini Declare init/fini and enable function templates. v2: Rebase Signed-off-by: Vinay Belgaumkar Signed-off-by: Sundaresan Sujaritha --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/gt/uc/intel_guc.c| 2 + drivers/gpu/drm/i915/gt/uc/intel_guc.h| 4 ++ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 63 +++ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h | 33 ++ .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h | 15 + drivers/gpu/drm/i915/gt/uc/intel_uc.c | 6 +- drivers/gpu/drm/i915/gt/uc/intel_uc.h | 2 + 8 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc_types.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index ab7679957623..d8eac4468df9 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -186,6 +186,7 @@ i915-y += gt/uc/intel_uc.o \ gt/uc/intel_guc_fw.o \ gt/uc/intel_guc_log.o \ gt/uc/intel_guc_log_debugfs.o \ + gt/uc/intel_guc_slpc.o \ gt/uc/intel_guc_submission.o \ gt/uc/intel_huc.o \ gt/uc/intel_huc_debugfs.o \ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c index 979128e28372..39bc3c16057b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -7,6 +7,7 @@ #include "gt/intel_gt_irq.h" #include "gt/intel_gt_pm_irq.h" #include "intel_guc.h" +#include "intel_guc_slpc.h" #include "intel_guc_ads.h" #include "intel_guc_submission.h" #include "i915_drv.h" @@ -157,6 +158,7 @@ void intel_guc_init_early(struct intel_guc *guc) intel_guc_ct_init_early(&guc->ct); intel_guc_log_init_early(&guc->log); intel_guc_submission_init_early(guc); + intel_guc_slpc_init_early(&guc->slpc); mutex_init(&guc->send_mutex); spin_lock_init(&guc->irq_lock); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 9c62c68fb132..8cecfad9d7b1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -15,6 +15,7 @@ #include "intel_guc_ct.h" #include "intel_guc_log.h" #include "intel_guc_reg.h" +#include "intel_guc_slpc_types.h" #include "intel_uc_fw.h" #include "i915_utils.h" #include "i915_vma.h" @@ -30,6 +31,7 @@ struct intel_guc { struct intel_uc_fw fw; struct intel_guc_log log; struct intel_guc_ct ct; + struct intel_guc_slpc slpc; /* Global engine used to submit requests to GuC */ struct i915_sched_engine *sched_engine; @@ -57,6 +59,8 @@ struct intel_guc { bool submission_supported; bool submission_selected; + bool slpc_supported; + bool slpc_selected; struct i915_vma *ads_vma; struct __guc_ads_blob *ads_blob; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c new file mode 100644 index ..d9feb430ce35 --- /dev/null +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2021 Intel Corporation + */ + +#include "i915_drv.h" +#include "intel_guc_slpc.h" +#include "gt/intel_gt.h" + +static inline struct intel_guc *slpc_to_guc(struct intel_guc_slpc *slpc) +{ + return container_of(slpc, struct intel_guc, slpc); +} + +static bool __detect_slpc_supported(struct intel_guc *guc) +{ + /* GuC SLPC is unavailable for pre-Gen12 */ + return guc->submission_supported && + GRAPHICS_VER(guc_to_gt(guc)->i915) >= 12; +} + +static bool __guc_slpc_selected(struct intel_guc *guc) +{ + if (!intel_guc_slpc_is_supported(guc)) + return false; + + return guc->submission_selected; +} + +void intel_guc_slpc_init_early(struct intel_guc_slpc *slpc) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + + guc->slpc_supported = __detect_slpc_supported(guc); + guc->slpc_selected = __guc_slpc_selected(guc); +} + +int intel_guc_slpc_init(struct intel_guc_slpc *slpc) +{ + return 0; +} + +/* + * intel_guc_slpc_enable() - Start SLPC + * @s
Re: [PATCH] drm/mediatek: dpi: fix NULL dereference in mtk_dpi_bridge_atomic_check
Hi, Frank: Frank Wunderlich 於 2021年7月12日 週一 下午4:08寫道: > > From: Frank Wunderlich > > bridge->driver_private is not set (NULL) so use bridge_to_dpi(bridge) > like it's done in bridge_atomic_get_output_bus_fmts Applied to mediatek-drm-fixes [1], thanks. [1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-fixes Regards, Chun-Kuang. > > Fixes: ec8747c52434 ("drm/mediatek: dpi: Add bus format negotiation") > Signed-off-by: Frank Wunderlich > --- > drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c > b/drivers/gpu/drm/mediatek/mtk_dpi.c > index bced555648b0..a2eca1f66984 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c > @@ -605,7 +605,7 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge > *bridge, >struct drm_crtc_state *crtc_state, >struct drm_connector_state *conn_state) > { > - struct mtk_dpi *dpi = bridge->driver_private; > + struct mtk_dpi *dpi = bridge_to_dpi(bridge); > unsigned int out_bus_format; > > out_bus_format = bridge_state->output_bus_cfg.format; > -- > 2.25.1 > > > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek
Re: [PATCH 06/18] drm/i915/guc: Implement GuC context operations for new inteface
On 7/20/2021 6:51 PM, John Harrison wrote: On 7/20/2021 15:39, Matthew Brost wrote: Implement GuC context operations which includes GuC specific operations alloc, pin, unpin, and destroy. v2: (Daniel Vetter) - Use msleep_interruptible rather than cond_resched in busy loop (Michal) - Remove C++ style comment v3: (Matthew Brost) - Drop GUC_ID_START (John Harrison) - Fix a bunch of typos - Use drm_err rather than drm_dbg for G2H errors (Daniele) - Fix ;; typo - Clean up sched state functions - Add lockdep for guc_id functions - Don't call __release_guc_id when guc_id is invalid - Use MISSING_CASE - Add comment in guc_context_pin - Use shorter path to rpm (Daniele / CI) - Don't call release_guc_id on an invalid guc_id in destroy Signed-off-by: John Harrison Signed-off-by: Matthew Brost --- drivers/gpu/drm/i915/gt/intel_context.c | 5 + drivers/gpu/drm/i915/gt/intel_context_types.h | 22 +- drivers/gpu/drm/i915/gt/intel_lrc_reg.h | 1 - drivers/gpu/drm/i915/gt/uc/intel_guc.h | 40 ++ drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 4 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 667 -- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/i915_request.c | 1 + 8 files changed, 686 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index bd63813c8a80..32fd6647154b 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -384,6 +384,11 @@ intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine) mutex_init(&ce->pin_mutex); + spin_lock_init(&ce->guc_state.lock); + + ce->guc_id = GUC_INVALID_LRC_ID; + INIT_LIST_HEAD(&ce->guc_id_link); + i915_active_init(&ce->active, __intel_context_active, __intel_context_retire, 0); } diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 6d99631d19b9..606c480aec26 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -96,6 +96,7 @@ struct intel_context { #define CONTEXT_BANNED 6 #define CONTEXT_FORCE_SINGLE_SUBMISSION 7 #define CONTEXT_NOPREEMPT 8 +#define CONTEXT_LRCA_DIRTY 9 struct { u64 timeout_us; @@ -138,14 +139,29 @@ struct intel_context { u8 wa_bb_page; /* if set, page num reserved for context workarounds */ + struct { + /** lock: protects everything in guc_state */ + spinlock_t lock; + /** + * sched_state: scheduling state of this context using GuC + * submission + */ + u8 sched_state; + } guc_state; + /* GuC scheduling state flags that do not require a lock. */ atomic_t guc_sched_state_no_lock; + /* GuC LRC descriptor ID */ + u16 guc_id; + + /* GuC LRC descriptor reference count */ + atomic_t guc_id_ref; + /* - * GuC LRC descriptor ID - Not assigned in this patch but future patches - * in the series will. + * GuC ID link - in list when unpinned but guc_id still valid in GuC */ - u16 guc_id; + struct list_head guc_id_link; }; #endif /* __INTEL_CONTEXT_TYPES__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h index 41e5350a7a05..49d4857ad9b7 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h @@ -87,7 +87,6 @@ #define GEN11_CSB_WRITE_PTR_MASK (GEN11_CSB_PTR_MASK << 0) #define MAX_CONTEXT_HW_ID (1 << 21) /* exclusive */ -#define MAX_GUC_CONTEXT_HW_ID (1 << 20) /* exclusive */ #define GEN11_MAX_CONTEXT_HW_ID (1 << 11) /* exclusive */ /* in Gen12 ID 0x7FF is reserved to indicate idle */ #define GEN12_MAX_CONTEXT_HW_ID (GEN11_MAX_CONTEXT_HW_ID - 1) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 8c7b92f699f1..30773cd699f5 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -7,6 +7,7 @@ #define _INTEL_GUC_H_ #include +#include #include "intel_uncore.h" #include "intel_guc_fw.h" @@ -44,6 +45,14 @@ struct intel_guc { void (*disable)(struct intel_guc *guc); } interrupts; + /* + * contexts_lock protects the pool of free guc ids and a linked list of + * guc ids available to be stolen + */ + spinlock_t contexts_lock; + struct ida guc_ids; + struct list_head guc_id_list; + bool submission_selected; struct i915_vma *ads_vma; @@ -101,6 +110,34 @@ intel_guc_send_and_receive(struct intel_guc *guc, const u32 *action, u32 len, response_buf, response_buf_size, 0); } +static inline int intel_guc_send_busy_loop(struct intel_guc* guc, +
Re: [PATCH 06/51] drm/i915/guc: Implement GuC context operations for new inteface
On 7/19/2021 9:04 PM, Matthew Brost wrote: On Mon, Jul 19, 2021 at 05:51:46PM -0700, Daniele Ceraolo Spurio wrote: On 7/16/2021 1:16 PM, Matthew Brost wrote: Implement GuC context operations which includes GuC specific operations alloc, pin, unpin, and destroy. v2: (Daniel Vetter) - Use msleep_interruptible rather than cond_resched in busy loop (Michal) - Remove C++ style comment Signed-off-by: John Harrison Signed-off-by: Matthew Brost --- drivers/gpu/drm/i915/gt/intel_context.c | 5 + drivers/gpu/drm/i915/gt/intel_context_types.h | 22 +- drivers/gpu/drm/i915/gt/intel_lrc_reg.h | 1 - drivers/gpu/drm/i915/gt/uc/intel_guc.h| 40 ++ drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 4 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 666 -- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/i915_request.c | 1 + 8 files changed, 685 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index bd63813c8a80..32fd6647154b 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -384,6 +384,11 @@ intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine) mutex_init(&ce->pin_mutex); + spin_lock_init(&ce->guc_state.lock); + + ce->guc_id = GUC_INVALID_LRC_ID; + INIT_LIST_HEAD(&ce->guc_id_link); + i915_active_init(&ce->active, __intel_context_active, __intel_context_retire, 0); } diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 6d99631d19b9..606c480aec26 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -96,6 +96,7 @@ struct intel_context { #define CONTEXT_BANNED 6 #define CONTEXT_FORCE_SINGLE_SUBMISSION 7 #define CONTEXT_NOPREEMPT8 +#define CONTEXT_LRCA_DIRTY 9 struct { u64 timeout_us; @@ -138,14 +139,29 @@ struct intel_context { u8 wa_bb_page; /* if set, page num reserved for context workarounds */ + struct { + /** lock: protects everything in guc_state */ + spinlock_t lock; + /** +* sched_state: scheduling state of this context using GuC +* submission +*/ + u8 sched_state; + } guc_state; + /* GuC scheduling state flags that do not require a lock. */ atomic_t guc_sched_state_no_lock; + /* GuC LRC descriptor ID */ + u16 guc_id; + + /* GuC LRC descriptor reference count */ + atomic_t guc_id_ref; + /* -* GuC LRC descriptor ID - Not assigned in this patch but future patches -* in the series will. +* GuC ID link - in list when unpinned but guc_id still valid in GuC */ - u16 guc_id; + struct list_head guc_id_link; }; #endif /* __INTEL_CONTEXT_TYPES__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h index 41e5350a7a05..49d4857ad9b7 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h @@ -87,7 +87,6 @@ #define GEN11_CSB_WRITE_PTR_MASK (GEN11_CSB_PTR_MASK << 0) #define MAX_CONTEXT_HW_ID(1 << 21) /* exclusive */ -#define MAX_GUC_CONTEXT_HW_ID (1 << 20) /* exclusive */ #define GEN11_MAX_CONTEXT_HW_ID (1 << 11) /* exclusive */ /* in Gen12 ID 0x7FF is reserved to indicate idle */ #define GEN12_MAX_CONTEXT_HW_ID (GEN11_MAX_CONTEXT_HW_ID - 1) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 8c7b92f699f1..30773cd699f5 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -7,6 +7,7 @@ #define _INTEL_GUC_H_ #include +#include #include "intel_uncore.h" #include "intel_guc_fw.h" @@ -44,6 +45,14 @@ struct intel_guc { void (*disable)(struct intel_guc *guc); } interrupts; + /* +* contexts_lock protects the pool of free guc ids and a linked list of +* guc ids available to be stolen +*/ + spinlock_t contexts_lock; + struct ida guc_ids; + struct list_head guc_id_list; + bool submission_selected; struct i915_vma *ads_vma; @@ -101,6 +110,34 @@ intel_guc_send_and_receive(struct intel_guc *guc, const u32 *action, u32 len, response_buf, response_buf_size, 0); } +static inline int intel_guc_send_busy_loop(struct intel_guc* guc, + const u32 *action, + u32 len, + bool loop) +{ + int err; + unsigned int sleep_
Re: [PATCH 06/14] drm/i915/guc/slpc: Enable SLPC and add related H2G events
Hi Vinay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on drm-tip/drm-tip] [cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next drm/drm-next v5.14-rc2 next-20210721] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip config: x86_64-randconfig-a016-20210720 (attached as .config) compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project c781eb153bfbd1b52b03efe34f56bbeccbb8aba6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://github.com/0day-ci/linux/commit/14352081e4f18759e70413f3be4151d623c97b8c git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Vinay-Belgaumkar/drm-i915-guc-Enable-GuC-based-power-management-features/20210722-001528 git checkout 14352081e4f18759e70413f3be4151d623c97b8c # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:217:5: warning: no previous >> prototype for function 'slpc_decode_min_freq' [-Wmissing-prototypes] u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) ^ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:217:1: note: declare 'static' if the function is not intended to be used outside of this translation unit u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) ^ static >> drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:229:5: warning: no previous >> prototype for function 'slpc_decode_max_freq' [-Wmissing-prototypes] u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) ^ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c:229:1: note: declare 'static' if the function is not intended to be used outside of this translation unit u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) ^ static 2 warnings generated. vim +/slpc_decode_min_freq +217 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c 216 > 217 u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) 218 { 219 struct slpc_shared_data *data = slpc->vaddr; 220 221 GEM_BUG_ON(!slpc->vma); 222 223 return DIV_ROUND_CLOSEST( 224 REG_FIELD_GET(SLPC_MIN_UNSLICE_FREQ_MASK, 225 data->task_state_data.freq) * 226 GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER); 227 } 228 > 229 u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) 230 { 231 struct slpc_shared_data *data = slpc->vaddr; 232 233 GEM_BUG_ON(!slpc->vma); 234 235 return DIV_ROUND_CLOSEST( 236 REG_FIELD_GET(SLPC_MAX_UNSLICE_FREQ_MASK, 237 data->task_state_data.freq) * 238 GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER); 239 } 240 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH v2 3/3] drm/panel: Add ilitek ili9341 panel driver
Hi Sam, Thanks for your time on my code review. On Thu, 22 Jul 2021 at 00:56, Sam Ravnborg wrote: > > Hi Dillon, > > On Wed, Jul 21, 2021 at 03:41:28PM +0800, dillon.min...@gmail.com wrote: > > From: Dillon Min > > > > This driver combine tiny/ili9341.c mipi_dbi_interface driver > > with mipi_dpi_interface driver, can support ili9341 with serial > > mode or parallel rgb interface mode by register configuration. > > > > Cc: Linus Walleij > > Signed-off-by: Dillon Min > > I have not looked at the driver before, sorry for being late. > A few nits in the following. That's fine. thanks. > > Sam > > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > Spaces between blocks of includes. > So linux/* goes in one block, video/* in next block, drm/* in the last > block. > Sort alphabetically in each block. I will add this change to v3. thanks. > > > + > > +/** > > + * struct ili9341_config - the system specific ILI9341 configuration > > + * @max_spi_speed: 1000 > > + */ > Unless you plan to pull this into our kernel-doc there is really no need > for a kernel-doc marker. On the other hand W=1 builds will tell if you > missed something. So there are arguments both ways. This driver was following the drm/panel/panel-ilitek-ili9322.c style, I didn't realize the /** ... */ is the kernel-doc marker before. just because W=1 report some warnings, so i add all this marker to struct ili9341_config I will remove all the kernel-doc markers, and try to build with W=1 again, thanks. > > > +struct ili9341_config { > > + u32 max_spi_speed; > > + /** @mode: the drm display mode */ > > + const struct drm_display_mode mode; > > + /** @ca: TODO: need comments for this register */ > > + u8 ca[ILI9341_CA_LEN]; > > + /** @power_b: TODO: need comments for this register */ > > + u8 power_b[ILI9341_POWER_B_LEN]; > > + /** @power_seq: TODO: need comments for this register */ > > + u8 power_seq[ILI9341_POWER_SEQ_LEN]; > > + /** @dtca: TODO: need comments for this register */ > > + u8 dtca[ILI9341_DTCA_LEN]; > > + /** @dtcb: TODO: need comments for this register */ > > + u8 dtcb[ILI9341_DTCB_LEN]; > > + /** @power_a: TODO: need comments for this register */ > > + u8 power_a[ILI9341_POWER_A_LEN]; > > + /** @frc: Frame Rate Control (In Normal Mode/Full Colors) (B1h) */ > > + u8 frc[ILI9341_FRC_LEN]; > > + /** @prc: TODO: need comments for this register */ > > + u8 prc; > > + /** @dfc_1: B6h DISCTRL (Display Function Control) */ > > + u8 dfc_1[ILI9341_DFC_1_LEN]; > > + /** @power_1: Power Control 1 (C0h) */ > > + u8 power_1; > > + /** @power_2: Power Control 2 (C1h) */ > > + u8 power_2; > > + /** @vcom_1: VCOM Control 1(C5h) */ > > + u8 vcom_1[ILI9341_VCOM_1_LEN]; > > + /** @vcom_2: VCOM Control 2(C7h) */ > > + u8 vcom_2; > > + /** @address_mode: Memory Access Control (36h) */ > > + u8 address_mode; > > + /** @g3amma_en: TODO: need comments for this register */ > > + u8 g3amma_en; > > + /** @rgb_interface: RGB Interface Signal Control (B0h) */ > > + u8 rgb_interface; > > + /** @dfc_2: refer to dfc_1 */ > > + u8 dfc_2[ILI9341_DFC_2_LEN]; > > + /** @column_addr: Column Address Set (2Ah) */ > > + u8 column_addr[ILI9341_COLUMN_ADDR_LEN]; > > + /** @page_addr: Page Address Set (2Bh) */ > > + u8 page_addr[ILI9341_PAGE_ADDR_LEN]; > > + /** @interface: Interface Control (F6h) */ > > + u8 interface[ILI9341_INTERFACE_LEN]; > > + /** @pixel_format: This command sets the pixel format for the RGB */ > > + /* image data used by > > + */ > > + u8 pixel_format; > > + /** @gamma_curve: This command is used to select the desired Gamma */ > > + /* curve for the > > + */ > Make this a single comment block. Okay. > > > + u8 gamma_curve; > > + /** @pgamma: Positive Gamma Correction (E0h) */ > > + u8 pgamma[ILI9341_PGAMMA_LEN]; > > + /** @ngamma: Negative Gamma Correction (E1h) */ > > + u8 ngamma[ILI9341_NGAMMA_LEN]; > > +}; > > + > > +struct ili9341 { > > + struct device *dev; > We will have struct device * both in drm_panel and in ili9341. > You could brop the one in ili9341. Okay, I will use the dev from 'struct drm_panel'. > > > + const struct ili9341_config *conf; > > + struct drm_panel panel; > > + struct gpio_desc *reset_gpio; > > + struct gpio_desc *dc_gpio; > > + struct mipi_dbi *dbi; > > + u32 max_spi_speed; > > + struct regulator_bulk_data supplies[3]; > > +}; > > + > > +/* > > + * The Stm32f429-disco board has a panel ili9341 connected to ltdc > > controller > > + */ > > +static const struct ili9341_config ili9341_stm32f429_disco_data = { > > + .max_spi_s
[PATCH v4] drm/msm/dp: add logs across DP driver for ease of debugging
From: Maitreyee Rao Add trace points across the MSM DP driver to help debug interop issues. Changes in v4: - Changed goto statement and used if else-if Signed-off-by: Maitreyee Rao --- drivers/gpu/drm/msm/dp/dp_catalog.c | 8 ++-- drivers/gpu/drm/msm/dp/dp_ctrl.c| 5 - drivers/gpu/drm/msm/dp/dp_display.c | 14 ++ drivers/gpu/drm/msm/dp/dp_link.c| 35 ++- drivers/gpu/drm/msm/dp/dp_power.c | 3 +++ 5 files changed, 37 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 32f3575..958d3fa3 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -372,6 +372,7 @@ void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); + DRM_DEBUG_DP("enable=%d\n", enable); if (enable) { /* * To make sure link reg writes happens before other operation, @@ -580,6 +581,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, config = (en ? config | intr_mask : config & ~intr_mask); + DRM_DEBUG_DP("intr_mask=%#x config=%#x\n", intr_mask, config); dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK, config & DP_DP_HPD_INT_MASK); } @@ -610,6 +612,7 @@ u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog) u32 status; status = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS); + DRM_DEBUG_DP("aux status: %#x\n", status); status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT; status &= DP_DP_HPD_STATE_STATUS_BITS_MASK; @@ -685,6 +688,7 @@ void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog *dp_catalog, /* Make sure to clear the current pattern before starting a new one */ dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0); + DRM_DEBUG_DP("pattern: %#x\n", pattern); switch (pattern) { case DP_PHY_TEST_PATTERN_D10_2: dp_write_link(catalog, REG_DP_STATE_CTRL, @@ -745,7 +749,7 @@ void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog *dp_catalog, DP_STATE_CTRL_LINK_TRAINING_PATTERN4); break; default: - DRM_DEBUG_DP("No valid test pattern requested:0x%x\n", pattern); + DRM_DEBUG_DP("No valid test pattern requested: %#x\n", pattern); break; } } @@ -928,7 +932,7 @@ void dp_catalog_audio_config_acr(struct dp_catalog *dp_catalog) select = dp_catalog->audio_data; acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14); - DRM_DEBUG_DP("select = 0x%x, acr_ctrl = 0x%x\n", select, acr_ctrl); + DRM_DEBUG_DP("select: %#x, acr_ctrl: %#x\n", select, acr_ctrl); dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl); } diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 2a8955c..72de71a 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -122,7 +122,7 @@ void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl) IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES)) pr_warn("PUSH_IDLE pattern timedout\n"); - pr_debug("mainlink off done\n"); + DRM_DEBUG_DP("mainlink off done\n"); } static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl) @@ -1013,6 +1013,8 @@ static int dp_ctrl_update_vx_px(struct dp_ctrl_private *ctrl) u32 voltage_swing_level = link->phy_params.v_level; u32 pre_emphasis_level = link->phy_params.p_level; + DRM_DEBUG_DP("voltage level: %d emphasis level: %d\n", voltage_swing_level, + pre_emphasis_level); ret = dp_catalog_ctrl_update_vx_px(ctrl->catalog, voltage_swing_level, pre_emphasis_level); @@ -1384,6 +1386,7 @@ int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset) if (reset) dp_catalog_ctrl_reset(ctrl->catalog); + DRM_DEBUG_DP("flip=%d\n", flip); dp_catalog_ctrl_phy_reset(ctrl->catalog); phy_init(phy); dp_catalog_ctrl_enable_irq(ctrl->catalog, true); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index cf9c645..f0a81f7 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -275,6 +275,8 @@ static bool dp_display_is_ds_bridge(struct dp_panel *panel) static bool dp_display_is_sink_count_zero(struct dp_display_private *dp) { + DRM_DEBUG_DP("present=%#x sink_count=%d\n", dp->panel->dpcd[DP_DOWNSTREAMPORT_PRESENT], + dp->link->sink_count); return dp_display_is_ds_bridge(dp->panel) && (dp->link->sink_count == 0); } @@ -320,6 +322,7 @@ static int dp_display_send_hpd_notification(s
Re: [PATCH 2/4] drm/i915/gt: nuke unused legacy engine hw_id
On Wed, Jul 21, 2021 at 03:47:22PM -0700, Matt Roper wrote: On Tue, Jul 20, 2021 at 04:20:12PM -0700, Lucas De Marchi wrote: The engine hw_id is only used by RING_FAULT_REG(), which is not used since GRAPHICS_VER == 8. We tend to keep adding new defines just to be consistent, but let's try to remove them and let them defined to 0 when not used. s/when not used/for engines that only exist on gen8+ platforms/ Reviewed-by: Matt Roper For historical reference, we did use hw_id on gen8+ platforms too until relatively recently --- it was used to set the engine's guc_id as well up until: commit c784e5249e773689e38d2bc1749f08b986621a26 Author: John Harrison Date: Wed Oct 28 07:58:24 2020 -0700 drm/i915/guc: Update to use firmware v49.0.1 thanks for digging this, I will add that to the commit message as well. Lucas De Marchi
Re: [PATCH v2 3/3] drm/panel: Add ilitek ili9341 panel driver
Hi Jagan Thanks for your time to review my code. On Wed, 21 Jul 2021 at 23:48, Jagan Teki wrote: > > On Wed, Jul 21, 2021 at 1:11 PM wrote: > > > > From: Dillon Min > > > > This driver combine tiny/ili9341.c mipi_dbi_interface driver > > with mipi_dpi_interface driver, can support ili9341 with serial > > mode or parallel rgb interface mode by register configuration. > > > > Cc: Linus Walleij > > Signed-off-by: Dillon Min > > --- > > changes in v2: > > - replace vcc regulator to three bulk regulators(vci, vddi, vddi-led) > > according to linus suggestion, thanks. > > > > drivers/gpu/drm/panel/Kconfig| 12 + > > drivers/gpu/drm/panel/Makefile | 1 + > > drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 778 > > +++ > > 3 files changed, 791 insertions(+) > > create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c > > > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > > index ef87d92cdf49..eb34b8d1b19a 100644 > > --- a/drivers/gpu/drm/panel/Kconfig > > +++ b/drivers/gpu/drm/panel/Kconfig > > @@ -124,6 +124,18 @@ config DRM_PANEL_ILITEK_IL9322 > > Say Y here if you want to enable support for Ilitek IL9322 > > QVGA (320x240) RGB, YUV and ITU-T BT.656 panels. > > > > +config DRM_PANEL_ILITEK_ILI9341 > > + tristate "Ilitek ILI9341 240x320 QVGA panels" > > + depends on OF && SPI > > + depends on DRM_KMS_HELPER > > + depends on DRM_KMS_CMA_HELPER > > + depends on BACKLIGHT_CLASS_DEVICE > > + select DRM_MIPI_DBI > > + help > > + Say Y here if you want to enable support for Ilitek IL9341 > > + QVGA (240x320) RGB panels. support serial & parallel rgb > > + interface. > > + > > config DRM_PANEL_ILITEK_ILI9881C > > tristate "Ilitek ILI9881C-based panels" > > depends on OF > > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > > index cae4d976c069..0ecde184665d 100644 > > --- a/drivers/gpu/drm/panel/Makefile > > +++ b/drivers/gpu/drm/panel/Makefile > > @@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += > > panel-elida-kd35t133.o > > obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o > > obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += > > panel-feiyang-fy07024di26a30d.o > > obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o > > +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o > > obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o > > obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o > > obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o > > diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c > > b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c > > new file mode 100644 > > index ..717b0b930e2f > > --- /dev/null > > +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c > > @@ -0,0 +1,778 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Ilitek ILI9341 TFT LCD drm_panel driver. > > + * > > + * This panel can be configured to support: > > + * - 16-bit parallel RGB interface > > + * - 18-bit parallel RGB interface > > + * - 4-line serial spi interface > > + * > > + * Copyright (C) 2021 Dillon Min > > + * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c > > + * the reuse of DBI abstraction part referred from Linus's patch > > + * "drm/panel: s6e63m0: Switch to DBI abstraction for SPI" > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > + > > +#define ILI9341_RGB_INTERFACE 0xb0 /* RGB Interface Signal Control */ > > +#define ILI9341_FRC0xb1 /* Frame Rate Control register */ > > +#define ILI9341_DFC0xb6 /* Display Function Control register > > */ > > +#define ILI9341_POWER1 0xc0 /* Power Control 1 register */ > > +#define ILI9341_POWER2 0xc1 /* Power Control 2 register */ > > +#define ILI9341_VCOM1 0xc5 /* VCOM Control 1 register */ > > +#define ILI9341_VCOM2 0xc7 /* VCOM Control 2 register */ > > +#define ILI9341_POWERA 0xcb /* Power control A register */ > > +#define ILI9341_POWERB 0xcf /* Power control B register */ > > +#define ILI9341_PGAMMA 0xe0 /* Positive Gamma Correction > > register */ > > +#define ILI9341_NGAMMA 0xe1 /* Negative Gamma Correction > > register */ > > +#define ILI9341_DTCA 0xe8 /* Driver timing control A */ > > +#define ILI9341_DTCB 0xea /* Driver timing control B */ > > +#define ILI9341_POWER_SEQ 0xed /* Power on sequence register */ > > +#define ILI9341_3GAMMA_EN 0xf2 /* 3 Gamma enable register */ > > +#define ILI9341_INTER
Re: [PATCH 4/4] drm/i915/gt: nuke gen6_hw_id
On Tue, Jul 20, 2021 at 04:20:14PM -0700, Lucas De Marchi wrote: > This is only used by GRAPHICS_VER == 6 and GRAPHICS_VER == 7. All other > recent platforms do not depend on this field, so it doesn't make much > sense to keep it generic like that. Instead, just do a mapping from > engine class to HW ID in the single place that is needed. > > Signed-off-by: Lucas De Marchi > --- > drivers/gpu/drm/i915/gt/intel_engine_cs.c| 6 -- > drivers/gpu/drm/i915/gt/intel_engine_types.h | 8 > drivers/gpu/drm/i915/i915_reg.h | 4 +++- > 3 files changed, 3 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > index 508221de411c..0a04e8d90e9e 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > @@ -42,7 +42,6 @@ > > #define MAX_MMIO_BASES 3 > struct engine_info { > - u8 gen6_hw_id; > u8 class; > u8 instance; > /* mmio bases table *must* be sorted in reverse graphics_ver order */ > @@ -54,7 +53,6 @@ struct engine_info { > > static const struct engine_info intel_engines[] = { > [RCS0] = { > - .gen6_hw_id = RCS0_HW, > .class = RENDER_CLASS, > .instance = 0, > .mmio_bases = { > @@ -62,7 +60,6 @@ static const struct engine_info intel_engines[] = { > }, > }, > [BCS0] = { > - .gen6_hw_id = BCS0_HW, > .class = COPY_ENGINE_CLASS, > .instance = 0, > .mmio_bases = { > @@ -70,7 +67,6 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VCS0] = { > - .gen6_hw_id = VCS0_HW, > .class = VIDEO_DECODE_CLASS, > .instance = 0, > .mmio_bases = { > @@ -102,7 +98,6 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VECS0] = { > - .gen6_hw_id = VECS0_HW, > .class = VIDEO_ENHANCEMENT_CLASS, > .instance = 0, > .mmio_bases = { > @@ -290,7 +285,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum > intel_engine_id id) > engine->i915 = i915; > engine->gt = gt; > engine->uncore = gt->uncore; > - engine->gen6_hw_id = info->gen6_hw_id; > guc_class = engine_class_to_guc_class(info->class); > engine->guc_id = MAKE_GUC_ID(guc_class, info->instance); > engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases); > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > index 266422d8d1b1..64330bfb7641 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > @@ -28,13 +28,6 @@ > #include "intel_wakeref.h" > #include "intel_workarounds_types.h" > > -/* Legacy HW Engine ID */ > - > -#define RCS0_HW 0 > -#define VCS0_HW 1 > -#define BCS0_HW 2 > -#define VECS0_HW 3 > - > /* Gen11+ HW Engine class + instance */ > #define RENDER_CLASS 0 > #define VIDEO_DECODE_CLASS 1 > @@ -268,7 +261,6 @@ struct intel_engine_cs { > > intel_engine_mask_t mask; > > - u8 gen6_hw_id; > u8 class; > u8 instance; > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 8750ffce9d61..d91386f4828e 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -2572,7 +2572,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) > #define ARB_MODE_BWGTLB_DISABLE (1 << 9) > #define ARB_MODE_SWIZZLE_BDW (1 << 1) > #define RENDER_HWS_PGA_GEN7 _MMIO(0x04080) > -#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * > (engine)->gen6_hw_id) > + > +#define _GEN6_ENGINE_CLASS_TO_ID(class) _PICK((class), 0, 1, 3, 2) > +#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * > _GEN6_ENGINE_CLASS_TO_ID((engine)->class)) If you want to make this more clear to someone reading it down the road, you could always do something explicit like: #define _RING_FAULT_REG_RCS0x4094 #define _RING_FAULT_REG_VCS0x4194 #define _RING_FAULT_REG_BCS0x4294 #define _RING_FAULT_REG_VECS 0x4394 #define RING_FAULT_REG(engine) _MMIO(_PICK((engine)->class, \ _RING_FAULT_REG_RCS, \ _RING_FAULT_REG_VCS, \ _RING_FAULT_REG_VECS, \ _RING_FAULT_REG_BCS)) But in general, Reviewed-by: Matt Roper > #define GEN8_RING_FAULT_REG _MMIO(0x4094) > #define GEN12_RING_FAULT_REG _MMIO(0xcec4) > #define GEN8_RING_FAULT_ENGINE_ID(x) (((x) >> 12) & 0x7) > -- > 2.31.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platfor
Re: [PATCH 3/4] drm/i915/gt: rename legacy engine->hw_id to engine->gen6_hw_id
On Tue, Jul 20, 2021 at 04:20:13PM -0700, Lucas De Marchi wrote: > We kept adding new engines and for that increasing hw_id unnecessarily: > it's not used since GRAPHICS_VER == 8. Prepend "gen6" to the field and > try to pack it in the structs to give a hint this field is actually not > used in recent platforms. > > Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper although if we apply patch #4 we could probably drop this intermediate step. Matt > --- > drivers/gpu/drm/i915/gt/intel_engine_cs.c| 12 ++-- > drivers/gpu/drm/i915/gt/intel_engine_types.h | 2 +- > drivers/gpu/drm/i915/i915_reg.h | 2 +- > 3 files changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > index a11f69f2e46e..508221de411c 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > @@ -42,7 +42,7 @@ > > #define MAX_MMIO_BASES 3 > struct engine_info { > - unsigned int hw_id; > + u8 gen6_hw_id; > u8 class; > u8 instance; > /* mmio bases table *must* be sorted in reverse graphics_ver order */ > @@ -54,7 +54,7 @@ struct engine_info { > > static const struct engine_info intel_engines[] = { > [RCS0] = { > - .hw_id = RCS0_HW, > + .gen6_hw_id = RCS0_HW, > .class = RENDER_CLASS, > .instance = 0, > .mmio_bases = { > @@ -62,7 +62,7 @@ static const struct engine_info intel_engines[] = { > }, > }, > [BCS0] = { > - .hw_id = BCS0_HW, > + .gen6_hw_id = BCS0_HW, > .class = COPY_ENGINE_CLASS, > .instance = 0, > .mmio_bases = { > @@ -70,7 +70,7 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VCS0] = { > - .hw_id = VCS0_HW, > + .gen6_hw_id = VCS0_HW, > .class = VIDEO_DECODE_CLASS, > .instance = 0, > .mmio_bases = { > @@ -102,7 +102,7 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VECS0] = { > - .hw_id = VECS0_HW, > + .gen6_hw_id = VECS0_HW, > .class = VIDEO_ENHANCEMENT_CLASS, > .instance = 0, > .mmio_bases = { > @@ -290,7 +290,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum > intel_engine_id id) > engine->i915 = i915; > engine->gt = gt; > engine->uncore = gt->uncore; > - engine->hw_id = info->hw_id; > + engine->gen6_hw_id = info->gen6_hw_id; > guc_class = engine_class_to_guc_class(info->class); > engine->guc_id = MAKE_GUC_ID(guc_class, info->instance); > engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases); > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > index a107eb58ffa2..266422d8d1b1 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > @@ -264,11 +264,11 @@ struct intel_engine_cs { > enum intel_engine_id id; > enum intel_engine_id legacy_idx; > > - unsigned int hw_id; > unsigned int guc_id; > > intel_engine_mask_t mask; > > + u8 gen6_hw_id; > u8 class; > u8 instance; > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 943fe485c662..8750ffce9d61 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -2572,7 +2572,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) > #define ARB_MODE_BWGTLB_DISABLE (1 << 9) > #define ARB_MODE_SWIZZLE_BDW (1 << 1) > #define RENDER_HWS_PGA_GEN7 _MMIO(0x04080) > -#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * (engine)->hw_id) > +#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * > (engine)->gen6_hw_id) > #define GEN8_RING_FAULT_REG _MMIO(0x4094) > #define GEN12_RING_FAULT_REG _MMIO(0xcec4) > #define GEN8_RING_FAULT_ENGINE_ID(x) (((x) >> 12) & 0x7) > -- > 2.31.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation (916) 356-2795
Re: [PATCH 2/4] drm/i915/gt: nuke unused legacy engine hw_id
On Tue, Jul 20, 2021 at 04:20:12PM -0700, Lucas De Marchi wrote: > The engine hw_id is only used by RING_FAULT_REG(), which is not used > since GRAPHICS_VER == 8. We tend to keep adding new defines just to be > consistent, but let's try to remove them and let them defined to 0 when > not used. s/when not used/for engines that only exist on gen8+ platforms/ Reviewed-by: Matt Roper For historical reference, we did use hw_id on gen8+ platforms too until relatively recently --- it was used to set the engine's guc_id as well up until: commit c784e5249e773689e38d2bc1749f08b986621a26 Author: John Harrison Date: Wed Oct 28 07:58:24 2020 -0700 drm/i915/guc: Update to use firmware v49.0.1 Matt > > Signed-off-by: Lucas De Marchi > --- > drivers/gpu/drm/i915/gt/intel_engine_cs.c| 4 > drivers/gpu/drm/i915/gt/intel_engine_types.h | 4 > 2 files changed, 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > index d561573ed98c..a11f69f2e46e 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > @@ -80,7 +80,6 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VCS1] = { > - .hw_id = VCS1_HW, > .class = VIDEO_DECODE_CLASS, > .instance = 1, > .mmio_bases = { > @@ -89,7 +88,6 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VCS2] = { > - .hw_id = VCS2_HW, > .class = VIDEO_DECODE_CLASS, > .instance = 2, > .mmio_bases = { > @@ -97,7 +95,6 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VCS3] = { > - .hw_id = VCS3_HW, > .class = VIDEO_DECODE_CLASS, > .instance = 3, > .mmio_bases = { > @@ -114,7 +111,6 @@ static const struct engine_info intel_engines[] = { > }, > }, > [VECS1] = { > - .hw_id = VECS1_HW, > .class = VIDEO_ENHANCEMENT_CLASS, > .instance = 1, > .mmio_bases = { > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > index 1cb9c3b70b29..a107eb58ffa2 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > @@ -34,10 +34,6 @@ > #define VCS0_HW 1 > #define BCS0_HW 2 > #define VECS0_HW 3 > -#define VCS1_HW 4 > -#define VCS2_HW 6 > -#define VCS3_HW 7 > -#define VECS1_HW 12 > > /* Gen11+ HW Engine class + instance */ > #define RENDER_CLASS 0 > -- > 2.31.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation (916) 356-2795
Re: [v2 3/3] drm/msm/dsi: Add DSI support for SC7280
Quoting Rajeev Nandan (2021-06-22 05:42:28) > Add support for v2.5.0 DSI block in the SC7280 SoC. > > Signed-off-by: Rajeev Nandan > Reviewed-by: Dmitry Baryshkov > --- Reviewed-by: Stephen Boyd
Re: [v2 2/3] drm/msm/dsi: Add PHY configuration for SC7280
Quoting Rajeev Nandan (2021-06-22 05:42:27) > The SC7280 SoC uses the 7nm (V4.1) DSI PHY driver with > different enable|disable regulator loads. > > Signed-off-by: Rajeev Nandan > Reviewed-by: Dmitry Baryshkov > --- Reviewed-by: Stephen Boyd
Re: [v2 1/3] dt-bindings: msm/dsi: Add sc7280 7nm dsi phy
Quoting Rajeev Nandan (2021-06-22 05:42:26) > The SC7280 SoC uses the 7nm (V4.1) DSI PHY driver. > > Signed-off-by: Rajeev Nandan > --- Reviewed-by: Stephen Boyd
Re: [PATCH 1/4] drm/i915/gt: fix platform prefix
On Tue, Jul 20, 2021 at 04:20:11PM -0700, Lucas De Marchi wrote: > gen8_clear_engine_error_register() is actually not used by > GRAPHICS_VER >= 8, since for those we are using another register that is > not engine-dependent. Fix the platform prefix, to make clear we are not > using any GEN6_RING_FAULT_REG_* one GRAPHICS_VER >= 8. > > Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper > --- > drivers/gpu/drm/i915/gt/intel_gt.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c > b/drivers/gpu/drm/i915/gt/intel_gt.c > index e714e21c0a4d..a8efdd44e9cf 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt.c > @@ -205,7 +205,7 @@ static void clear_register(struct intel_uncore *uncore, > i915_reg_t reg) > intel_uncore_rmw(uncore, reg, 0, 0); > } > > -static void gen8_clear_engine_error_register(struct intel_engine_cs *engine) > +static void gen6_clear_engine_error_register(struct intel_engine_cs *engine) > { > GEN6_RING_FAULT_REG_RMW(engine, RING_FAULT_VALID, 0); > GEN6_RING_FAULT_REG_POSTING_READ(engine); > @@ -251,7 +251,7 @@ intel_gt_clear_error_registers(struct intel_gt *gt, > enum intel_engine_id id; > > for_each_engine_masked(engine, gt, engine_mask, id) > - gen8_clear_engine_error_register(engine); > + gen6_clear_engine_error_register(engine); > } > } > > -- > 2.31.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation (916) 356-2795
[PATCH][next] drm: Fix space indentations, replace with tabs
From: Colin Ian King A couple of statements are indented with spaces, clean this up by replacing spaces with tabs. Signed-off-by: Colin Ian King --- drivers/gpu/drm/drm_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index f454e0424086..c023da67ca7a 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -834,8 +834,8 @@ long drm_ioctl(struct file *filp, if (drm_dev_is_unplugged(dev)) return -ENODEV; - if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE) - return -ENOTTY; + if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE) + return -ENOTTY; is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; -- 2.31.1
Re: [PATCH v3] drm/msm/dp: add logs across DP driver for ease of debugging
Hello Stephen, Thanks again for the review comments On 2021-07-20 22:31, Stephen Boyd wrote: Quoting maitreye (2021-07-20 15:39:30) diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c index be986da..316e8e6 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.c +++ b/drivers/gpu/drm/msm/dp/dp_link.c @@ -1036,43 +1036,46 @@ int dp_link_process_request(struct dp_link *dp_link) if (link->request.test_requested == DP_TEST_LINK_EDID_READ) { dp_link->sink_request |= DP_TEST_LINK_EDID_READ; - return ret; + goto out; } ret = dp_link_process_ds_port_status_change(link); if (!ret) { dp_link->sink_request |= DS_PORT_STATUS_CHANGED; - return ret; + goto out; } ret = dp_link_process_link_training_request(link); if (!ret) { dp_link->sink_request |= DP_TEST_LINK_TRAINING; - return ret; + goto out; } ret = dp_link_process_phy_test_pattern_request(link); if (!ret) { dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN; - return ret; + goto out; } ret = dp_link_process_link_status_update(link); if ret == 0 we go into the if below and goto out. if (!ret) { dp_link->sink_request |= DP_LINK_STATUS_UPDATED; - return ret; + goto out; } At this point ret != 0 due to the goto above. if (dp_link_is_video_pattern_requested(link)) { - ret = 0; And now we've removed the ret = 0 assignment from here. dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN; + goto out; And then we goto out. Isn't this a behavior change? Still feels like we should be using if/else-if logic here instead of this goto maze. } if (dp_link_is_audio_pattern_requested(link)) { dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN; - return -EINVAL; + ret = -EINVAL; + goto out; } +out: + DRM_DEBUG_DP("sink request=%#x", dp_link->sink_request); return ret; } Thank you. I see what you are saying, and yes it makes sense, I'll change it to if else-if logic.
[pull] amdgpu drm-fixes-5.14
Hi Dave, Daniel, Updates for 5.14. Mostly fixes for new asics added in 5.14. The following changes since commit 876d98e5511d8cfd12fc617a6717e7a8ea07be17: Merge tag 'drm-intel-fixes-2021-07-15' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes (2021-07-16 10:53:02 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-fixes-5.14-2021-07-21 for you to fetch changes up to d80cded9cc25f841d5250d2e94a7b42be1e81c97: drm/amdgpu - Corrected the video codecs array name for yellow carp (2021-07-21 17:47:28 -0400) amd-drm-fixes-5.14-2021-07-21: amdgpu: - Yellow Carp updates - Add some Yellow Carp DIDs - Beige Goby updates - CIK 10bit 4K regression fix - GFX10 golden settings updates - eDP panel regression fix - Misc display fixes - Aldebaran fix Aaron Liu (2): drm/amdgpu: update yellow carp external rev_id handling drm/amdgpu: add yellow carp pci id (v2) Bindu Ramamurthy (2): drm/amd/display: Populate socclk entries for dcn3.02/3.03 drm/amd/display: Populate dtbclk entries for dcn3.02/3.03 Camille Cho (1): drm/amd/display: Only set default brightness for OLED Eric Yang (2): drm/amd/display: implement workaround for riommu related hang drm/amd/display: change zstate allow msg condition Lijo Lazar (1): drm/amd/pm: Support board calibration on aldebaran Likun Gao (1): drm/amdgpu: update golden setting for sienna_cichlid Liviu Dudau (1): drm/amd/display: Fix 10bit 4K display on CIK GPUs Mikita Lipski (1): drm/amd/display: Remove MALL function from DCN3.1 Nevenko Stupar (1): drm/amd/display: Line Buffer changes Nicholas Kazlauskas (3): drm/amd/display: Fix max vstartup calculation for modes with borders drm/amd/display: Query VCO frequency from register for DCN3.1 drm/amd/display: Update bounding box for DCN3.1 Stylon Wang (1): drm/amd/display: Fix ASSR regression on embedded panels Tao Zhou (2): drm/amdgpu: update gc golden setting for dimgrey_cavefish drm/amd/pm: update DRIVER_IF_VERSION for beige_goby Veerabadhran Gopalakrishnan (3): amdgpu/nv.c - Added video codec support for Yellow Carp amdgpu/nv.c - Optimize code for video codec support structure drm/amdgpu - Corrected the video codecs array name for yellow carp Victor Lu (1): drm/amd/display: Fix comparison error in dcn21 DML Xiaojian Du (1): drm/amdgpu: update the golden setting for vangogh drivers/gpu/drm/amd/amdgpu/amdgpu.h| 7 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 4 + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 3 + drivers/gpu/drm/amd/amdgpu/nv.c| 248 + drivers/gpu/drm/amd/amdgpu/soc15.c | 176 ++- .../amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 4 + .../amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 59 - .../amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h | 54 - drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 12 +- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/dc.h| 10 +- drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | 4 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 7 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 50 +++-- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c | 16 -- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h | 3 +- .../drm/amd/display/dc/dcn302/dcn302_resource.c| 13 +- .../drm/amd/display/dc/dcn303/dcn303_resource.c| 13 +- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 18 ++ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h | 1 + drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c | 3 +- .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 4 + .../amd/display/dc/dml/dcn21/display_mode_vba_21.c | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/transform.h | 3 + .../drm/amd/display/dc/inc/hw_sequencer_private.h | 1 + drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h | 3 +- drivers/gpu/drm/amd/pm/inc/smu_types.h | 3 +- drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 46 +++- 29 files changed, 288 insertions(+), 483 deletions(-)
[PATCH 18/18] drm/i915: Add intel_context tracing
Add intel_context tracing. These trace points are particular helpful when debugging the GuC firmware and can be enabled via CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS kernel config option. Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/intel_context.c | 6 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 ++ drivers/gpu/drm/i915/i915_trace.h | 145 ++ 3 files changed, 165 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index 91349d071e0e..251ff7eea22d 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -8,6 +8,7 @@ #include "i915_drv.h" #include "i915_globals.h" +#include "i915_trace.h" #include "intel_context.h" #include "intel_engine.h" @@ -28,6 +29,7 @@ static void rcu_context_free(struct rcu_head *rcu) { struct intel_context *ce = container_of(rcu, typeof(*ce), rcu); + trace_intel_context_free(ce); kmem_cache_free(global.slab_ce, ce); } @@ -46,6 +48,7 @@ intel_context_create(struct intel_engine_cs *engine) return ERR_PTR(-ENOMEM); intel_context_init(ce, engine); + trace_intel_context_create(ce); return ce; } @@ -268,6 +271,8 @@ int __intel_context_do_pin_ww(struct intel_context *ce, GEM_BUG_ON(!intel_context_is_pinned(ce)); /* no overflow! */ + trace_intel_context_do_pin(ce); + err_unlock: mutex_unlock(&ce->pin_mutex); err_post_unpin: @@ -323,6 +328,7 @@ void __intel_context_do_unpin(struct intel_context *ce, int sub) */ intel_context_get(ce); intel_context_active_release(ce); + trace_intel_context_do_unpin(ce); intel_context_put(ce); } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index d47a8358c831..26aadad10b12 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -344,6 +344,7 @@ static int guc_add_request(struct intel_guc *guc, struct i915_request *rq) err = intel_guc_send_nb(guc, action, len, g2h_len_dw); if (!enabled && !err) { + trace_intel_context_sched_enable(ce); atomic_inc(&guc->outstanding_submission_g2h); set_context_enabled(ce); } else if (!enabled) { @@ -815,6 +816,8 @@ static int register_context(struct intel_context *ce) u32 offset = intel_guc_ggtt_offset(guc, guc->lrc_desc_pool) + ce->guc_id * sizeof(struct guc_lrc_desc); + trace_intel_context_register(ce); + return __guc_action_register_context(guc, ce->guc_id, offset); } @@ -835,6 +838,8 @@ static int deregister_context(struct intel_context *ce, u32 guc_id) { struct intel_guc *guc = ce_to_guc(ce); + trace_intel_context_deregister(ce); + return __guc_action_deregister_context(guc, guc_id); } @@ -908,6 +913,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce) * registering this context. */ if (context_registered) { + trace_intel_context_steal_guc_id(ce); set_context_wait_for_deregister_to_register(ce); intel_context_get(ce); @@ -971,6 +977,7 @@ static void __guc_context_sched_disable(struct intel_guc *guc, GEM_BUG_ON(guc_id == GUC_INVALID_LRC_ID); + trace_intel_context_sched_disable(ce); intel_context_get(ce); guc_submission_send_busy_loop(guc, action, ARRAY_SIZE(action), @@ -1133,6 +1140,9 @@ static void __guc_signal_context_fence(struct intel_context *ce) lockdep_assert_held(&ce->guc_state.lock); + if (!list_empty(&ce->guc_state.fences)) + trace_intel_context_fence_release(ce); + list_for_each_entry(rq, &ce->guc_state.fences, guc_fence_link) i915_sw_fence_complete(&rq->submit); @@ -1538,6 +1548,8 @@ int intel_guc_deregister_done_process_msg(struct intel_guc *guc, if (unlikely(!ce)) return -EPROTO; + trace_intel_context_deregister_done(ce); + if (context_wait_for_deregister_to_register(ce)) { struct intel_runtime_pm *runtime_pm = &ce->engine->gt->i915->runtime_pm; @@ -1589,6 +1601,8 @@ int intel_guc_sched_done_process_msg(struct intel_guc *guc, return -EPROTO; } + trace_intel_context_sched_done(ce); + if (context_pending_enable(ce)) { clr_context_pending_enable(ce); } else if (context_pending_disable(ce)) { diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 478f5427531d..68b70626c3e2 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -895,6 +895,91 @@ TRACE_EVENT(i915_request_out,
[PATCH 15/18] drm/i915/guc: Update intel_gt_wait_for_idle to work with GuC
When running the GuC the GPU can't be considered idle if the GuC still has contexts pinned. As such, a call has been added in intel_gt_wait_for_idle to idle the UC and in turn the GuC by waiting for the number of unpinned contexts to go to zero. v2: rtimeout -> remaining_timeout v3: Drop unnecessary includes, guc_submission_busy_loop -> guc_submission_send_busy_loop, drop negatie timeout trick, move a refactor of guc_context_unpin to earlier path (John H) v4: Add stddef.h back into intel_gt_requests.h, sort circuit idle function if not in GuC submission mode Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 3 +- drivers/gpu/drm/i915/gt/intel_gt.c| 19 drivers/gpu/drm/i915/gt/intel_gt.h| 2 + drivers/gpu/drm/i915/gt/intel_gt_requests.c | 21 ++--- drivers/gpu/drm/i915/gt/intel_gt_requests.h | 9 +- drivers/gpu/drm/i915/gt/uc/intel_guc.h| 4 + drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 1 + drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 4 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 88 +-- drivers/gpu/drm/i915/gt/uc/intel_uc.h | 5 ++ drivers/gpu/drm/i915/i915_gem_evict.c | 1 + .../gpu/drm/i915/selftests/igt_live_test.c| 2 +- .../gpu/drm/i915/selftests/mock_gem_device.c | 3 +- 13 files changed, 134 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 2f3b7dc7b0e6..5130e8ed9564 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -645,7 +645,8 @@ mmap_offset_attach(struct drm_i915_gem_object *obj, goto insert; /* Attempt to reap some mmap space from dead objects */ - err = intel_gt_retire_requests_timeout(&i915->gt, MAX_SCHEDULE_TIMEOUT); + err = intel_gt_retire_requests_timeout(&i915->gt, MAX_SCHEDULE_TIMEOUT, + NULL); if (err) goto err; diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index e714e21c0a4d..acfdd53b2678 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -585,6 +585,25 @@ static void __intel_gt_disable(struct intel_gt *gt) GEM_BUG_ON(intel_gt_pm_is_awake(gt)); } +int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout) +{ + long remaining_timeout; + + /* If the device is asleep, we have no requests outstanding */ + if (!intel_gt_pm_is_awake(gt)) + return 0; + + while ((timeout = intel_gt_retire_requests_timeout(gt, timeout, + &remaining_timeout)) > 0) { + cond_resched(); + if (signal_pending(current)) + return -EINTR; + } + + return timeout ? timeout : intel_uc_wait_for_idle(>->uc, + remaining_timeout); +} + int intel_gt_init(struct intel_gt *gt) { int err; diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h index e7aabe0cc5bf..74e771871a9b 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.h +++ b/drivers/gpu/drm/i915/gt/intel_gt.h @@ -48,6 +48,8 @@ void intel_gt_driver_release(struct intel_gt *gt); void intel_gt_driver_late_release(struct intel_gt *gt); +int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout); + void intel_gt_check_and_clear_faults(struct intel_gt *gt); void intel_gt_clear_error_registers(struct intel_gt *gt, intel_engine_mask_t engine_mask); diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.c b/drivers/gpu/drm/i915/gt/intel_gt_requests.c index 647eca9d867a..edb881d75630 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_requests.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.c @@ -130,7 +130,8 @@ void intel_engine_fini_retire(struct intel_engine_cs *engine) GEM_BUG_ON(engine->retire); } -long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout) +long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout, + long *remaining_timeout) { struct intel_gt_timelines *timelines = >->timelines; struct intel_timeline *tl, *tn; @@ -195,22 +196,10 @@ out_active: spin_lock(&timelines->lock); if (flush_submission(gt, timeout)) /* Wait, there's more! */ active_count++; - return active_count ? timeout : 0; -} - -int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout) -{ - /* If the device is asleep, we have no requests outstanding */ - if (!intel_gt_pm_is_awake(gt)) - return 0; - - while ((timeout = intel_gt_retire_requests_timeout(gt, timeout)) > 0) { - cond_resched(); - if (signal_p
[PATCH 16/18] drm/i915/guc: Update GuC debugfs to support new GuC
Update GuC debugfs to support the new GuC structures. v2: (John Harrison) - Remove intel_lrc_reg.h include from i915_debugfs.c (Michal) - Rename GuC debugfs functions Signed-off-by: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 22 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 3 + .../gpu/drm/i915/gt/uc/intel_guc_debugfs.c| 23 +++- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 55 +++ .../gpu/drm/i915/gt/uc/intel_guc_submission.h | 5 ++ 5 files changed, 107 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index b6bbbdb4c689..8bb6b1bbcea1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -1174,3 +1174,25 @@ void intel_guc_ct_event_handler(struct intel_guc_ct *ct) ct_try_receive_message(ct); } + +void intel_guc_ct_print_info(struct intel_guc_ct *ct, +struct drm_printer *p) +{ + drm_printf(p, "CT %s\n", enableddisabled(ct->enabled)); + + if (!ct->enabled) + return; + + drm_printf(p, "H2G Space: %u\n", + atomic_read(&ct->ctbs.send.space) * 4); + drm_printf(p, "Head: %u\n", + ct->ctbs.send.desc->head); + drm_printf(p, "Tail: %u\n", + ct->ctbs.send.desc->tail); + drm_printf(p, "G2H Space: %u\n", + atomic_read(&ct->ctbs.recv.space) * 4); + drm_printf(p, "Head: %u\n", + ct->ctbs.recv.desc->head); + drm_printf(p, "Tail: %u\n", + ct->ctbs.recv.desc->tail); +} diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h index 2758ee849a59..f709a19c7e21 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h @@ -16,6 +16,7 @@ struct i915_vma; struct intel_guc; +struct drm_printer; /** * DOC: Command Transport (CT). @@ -114,4 +115,6 @@ int intel_guc_ct_send(struct intel_guc_ct *ct, const u32 *action, u32 len, u32 *response_buf, u32 response_buf_size, u32 flags); void intel_guc_ct_event_handler(struct intel_guc_ct *ct); +void intel_guc_ct_print_info(struct intel_guc_ct *ct, struct drm_printer *p); + #endif /* _INTEL_GUC_CT_H_ */ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c index fe7cb7b29a1e..7a454c91a736 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_debugfs.c @@ -9,6 +9,8 @@ #include "intel_guc.h" #include "intel_guc_debugfs.h" #include "intel_guc_log_debugfs.h" +#include "gt/uc/intel_guc_ct.h" +#include "gt/uc/intel_guc_submission.h" static int guc_info_show(struct seq_file *m, void *data) { @@ -22,16 +24,35 @@ static int guc_info_show(struct seq_file *m, void *data) drm_puts(&p, "\n"); intel_guc_log_info(&guc->log, &p); - /* Add more as required ... */ + if (!intel_guc_submission_is_used(guc)) + return 0; + + intel_guc_ct_print_info(&guc->ct, &p); + intel_guc_submission_print_info(guc, &p); return 0; } DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_info); +static int guc_registered_contexts_show(struct seq_file *m, void *data) +{ + struct intel_guc *guc = m->private; + struct drm_printer p = drm_seq_file_printer(m); + + if (!intel_guc_submission_is_used(guc)) + return -ENODEV; + + intel_guc_submission_print_context_info(guc, &p); + + return 0; +} +DEFINE_GT_DEBUGFS_ATTRIBUTE(guc_registered_contexts); + void intel_guc_debugfs_register(struct intel_guc *guc, struct dentry *root) { static const struct debugfs_gt_file files[] = { { "guc_info", &guc_info_fops, NULL }, + { "guc_registered_contexts", &guc_registered_contexts_fops, NULL }, }; if (!intel_guc_is_supported(guc)) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index e4ce21c9b7ef..e6e5364beb1c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -1609,3 +1609,58 @@ int intel_guc_sched_done_process_msg(struct intel_guc *guc, return 0; } + +void intel_guc_submission_print_info(struct intel_guc *guc, +struct drm_printer *p) +{ + struct i915_sched_engine *sched_engine = guc->sched_engine; + struct rb_node *rb; + unsigned long flags; + + if (!sched_engine) + return; + + drm_printf(p, "GuC Number Outstanding Submission G2H: %u\n", + atomic_read(&guc->outstanding_submission_g2h)); + drm_printf(p, "GuC tasklet count: %u\n\n", + atomic_read(&sche
[PATCH 11/18] drm/i915: Disable preempt busywait when using GuC scheduling
Disable preempt busywait when using GuC scheduling. This isn't needed as the GuC controls preemption when scheduling. v2: (John H): - Fix commit message Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c index a69f5c438c72..b29eb9fd0009 100644 --- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c @@ -506,7 +506,8 @@ gen8_emit_fini_breadcrumb_tail(struct i915_request *rq, u32 *cs) *cs++ = MI_USER_INTERRUPT; *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; - if (intel_engine_has_semaphores(rq->engine)) + if (intel_engine_has_semaphores(rq->engine) && + !intel_uc_uses_guc_submission(&rq->engine->gt->uc)) cs = emit_preempt_busywait(rq, cs); rq->tail = intel_ring_offset(rq, cs); @@ -598,7 +599,8 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, u32 *cs) *cs++ = MI_USER_INTERRUPT; *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; - if (intel_engine_has_semaphores(rq->engine)) + if (intel_engine_has_semaphores(rq->engine) && + !intel_uc_uses_guc_submission(&rq->engine->gt->uc)) cs = gen12_emit_preempt_busywait(rq, cs); rq->tail = intel_ring_offset(rq, cs); -- 2.28.0
[PATCH 05/18] drm/i915/guc: Add bypass tasklet submission path to GuC
Add bypass tasklet submission path to GuC. The tasklet is only used if H2G channel has backpresure. Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 37 +++ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index ca0717166a27..53b4a5eb4a85 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -172,6 +172,12 @@ static int guc_add_request(struct intel_guc *guc, struct i915_request *rq) return err; } +static inline void guc_set_lrc_tail(struct i915_request *rq) +{ + rq->context->lrc_reg_state[CTX_RING_TAIL] = + intel_ring_set_tail(rq->ring, rq->tail); +} + static inline int rq_prio(const struct i915_request *rq) { return rq->sched.attr.priority; @@ -215,8 +221,7 @@ static int guc_dequeue_one_context(struct intel_guc *guc) } done: if (submit) { - last->context->lrc_reg_state[CTX_RING_TAIL] = - intel_ring_set_tail(last->ring, last->tail); + guc_set_lrc_tail(last); resubmit: /* * We only check for -EBUSY here even though it is possible for @@ -496,20 +501,36 @@ static inline void queue_request(struct i915_sched_engine *sched_engine, set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); } +static int guc_bypass_tasklet_submit(struct intel_guc *guc, +struct i915_request *rq) +{ + int ret; + + __i915_request_submit(rq); + + trace_i915_request_in(rq, 0); + + guc_set_lrc_tail(rq); + ret = guc_add_request(guc, rq); + if (ret == -EBUSY) + guc->stalled_request = rq; + + return ret; +} + static void guc_submit_request(struct i915_request *rq) { struct i915_sched_engine *sched_engine = rq->engine->sched_engine; + struct intel_guc *guc = &rq->engine->gt->uc.guc; unsigned long flags; /* Will be called from irq-context when using foreign fences. */ spin_lock_irqsave(&sched_engine->lock, flags); - queue_request(sched_engine, rq, rq_prio(rq)); - - GEM_BUG_ON(i915_sched_engine_is_empty(sched_engine)); - GEM_BUG_ON(list_empty(&rq->sched.link)); - - tasklet_hi_schedule(&sched_engine->tasklet); + if (guc->stalled_request || !i915_sched_engine_is_empty(sched_engine)) + queue_request(sched_engine, rq, rq_prio(rq)); + else if (guc_bypass_tasklet_submit(guc, rq) == -EBUSY) + tasklet_hi_schedule(&sched_engine->tasklet); spin_unlock_irqrestore(&sched_engine->lock, flags); } -- 2.28.0
[PATCH 13/18] drm/i915/guc: Disable semaphores when using GuC scheduling
Semaphores are an optimization and not required for basic GuC submission to work properly. Disable until we have time to do the implementation to enable semaphores and tune them for performance. Also long direction is just to delete semaphores from the i915 so another reason to not enable these for GuC submission. This patch fixes an existing bugs where I915_ENGINE_HAS_SEMAPHORES was not honored correctly. v2: Reword commit message v3: (John H) - Add text to commit indicating this also fixing an existing bug v4: (John H) - s/bug/bugs Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 7d6f52d8a801..64659802d4df 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -799,7 +799,8 @@ static int intel_context_set_gem(struct intel_context *ce, } if (ctx->sched.priority >= I915_PRIORITY_NORMAL && - intel_engine_has_timeslices(ce->engine)) + intel_engine_has_timeslices(ce->engine) && + intel_engine_has_semaphores(ce->engine)) __set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); if (IS_ACTIVE(CONFIG_DRM_I915_REQUEST_TIMEOUT) && @@ -1778,7 +1779,8 @@ static void __apply_priority(struct intel_context *ce, void *arg) if (!intel_engine_has_timeslices(ce->engine)) return; - if (ctx->sched.priority >= I915_PRIORITY_NORMAL) + if (ctx->sched.priority >= I915_PRIORITY_NORMAL && + intel_engine_has_semaphores(ce->engine)) intel_context_set_use_semaphores(ce); else intel_context_clear_use_semaphores(ce); -- 2.28.0
[PATCH 14/18] drm/i915/guc: Ensure G2H response has space in buffer
Ensure G2H response has space in the buffer before sending H2G CTB as the GuC can't handle any backpressure on the G2H interface. v2: (Matthew) - s/INTEL_GUC_SEND/INTEL_GUC_CT_SEND v3: (Matthew) - Add G2H credit accounting to blocking path, add g2h_release_space helper (John H) - CTB_G2H_BUFFER_SIZE / 4 == G2H_ROOM_BUFFER_SIZE Signed-off-by: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc.h| 8 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 94 +++ drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 11 ++- drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 4 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 13 ++- 5 files changed, 104 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 4d470ebeda95..451797c62b41 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -96,10 +96,11 @@ inline int intel_guc_send(struct intel_guc *guc, const u32 *action, u32 len) } static -inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 len) +inline int intel_guc_send_nb(struct intel_guc *guc, const u32 *action, u32 len, +u32 g2h_len_dw) { return intel_guc_ct_send(&guc->ct, action, len, NULL, 0, -INTEL_GUC_CT_SEND_NB); +MAKE_SEND_FLAGS(g2h_len_dw)); } static inline int @@ -113,6 +114,7 @@ intel_guc_send_and_receive(struct intel_guc *guc, const u32 *action, u32 len, static inline int intel_guc_send_busy_loop(struct intel_guc *guc, const u32 *action, u32 len, + u32 g2h_len_dw, bool loop) { int err; @@ -130,7 +132,7 @@ static inline int intel_guc_send_busy_loop(struct intel_guc *guc, might_sleep_if(loop && not_atomic); retry: - err = intel_guc_send_nb(guc, action, len); + err = intel_guc_send_nb(guc, action, len, g2h_len_dw); if (unlikely(err == -EBUSY && loop)) { if (likely(not_atomic)) { if (msleep_interruptible(sleep_period_ms)) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index 019b25ff1888..75f69c28056e 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -73,6 +73,7 @@ static inline struct drm_device *ct_to_drm(struct intel_guc_ct *ct) #define CTB_DESC_SIZE ALIGN(sizeof(struct guc_ct_buffer_desc), SZ_2K) #define CTB_H2G_BUFFER_SIZE(SZ_4K) #define CTB_G2H_BUFFER_SIZE(4 * CTB_H2G_BUFFER_SIZE) +#define G2H_ROOM_BUFFER_SIZE (CTB_G2H_BUFFER_SIZE / 4) struct ct_request { struct list_head link; @@ -129,23 +130,27 @@ static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc) static void guc_ct_buffer_reset(struct intel_guc_ct_buffer *ctb) { + u32 space; + ctb->broken = false; ctb->tail = 0; ctb->head = 0; - ctb->space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size); + space = CIRC_SPACE(ctb->tail, ctb->head, ctb->size) - ctb->resv_space; + atomic_set(&ctb->space, space); guc_ct_buffer_desc_init(ctb->desc); } static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb, struct guc_ct_buffer_desc *desc, - u32 *cmds, u32 size_in_bytes) + u32 *cmds, u32 size_in_bytes, u32 resv_space) { GEM_BUG_ON(size_in_bytes % 4); ctb->desc = desc; ctb->cmds = cmds; ctb->size = size_in_bytes / 4; + ctb->resv_space = resv_space / 4; guc_ct_buffer_reset(ctb); } @@ -226,6 +231,7 @@ int intel_guc_ct_init(struct intel_guc_ct *ct) struct guc_ct_buffer_desc *desc; u32 blob_size; u32 cmds_size; + u32 resv_space; void *blob; u32 *cmds; int err; @@ -250,19 +256,23 @@ int intel_guc_ct_init(struct intel_guc_ct *ct) desc = blob; cmds = blob + 2 * CTB_DESC_SIZE; cmds_size = CTB_H2G_BUFFER_SIZE; - CT_DEBUG(ct, "%s desc %#tx cmds %#tx size %u\n", "send", -ptrdiff(desc, blob), ptrdiff(cmds, blob), cmds_size); + resv_space = 0; + CT_DEBUG(ct, "%s desc %#tx cmds %#tx size %u/%u\n", "send", +ptrdiff(desc, blob), ptrdiff(cmds, blob), cmds_size, +resv_space); - guc_ct_buffer_init(&ct->ctbs.send, desc, cmds, cmds_size); + guc_ct_buffer_init(&ct->ctbs.send, desc, cmds, cmds_size, resv_space); /* store pointers to desc and cmds for recv ctb */ desc = blob + CTB_DESC_SIZE; cmds = blob + 2 * CTB_DESC_SIZE + CTB_H2G_BUFFER_SIZE;
[PATCH 10/18] drm/i915/guc: Extend deregistration fence to schedule disable
Extend the deregistration context fence to fence whne a GuC context has scheduling disable pending. v2: (John H) - Update comment why we check the pin count within spin lock Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 40 +++ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 2f393d9dba0d..fc0b36ab1e68 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -930,7 +930,22 @@ static void guc_context_sched_disable(struct intel_context *ce) goto unpin; spin_lock_irqsave(&ce->guc_state.lock, flags); + + /* +* We have to check if the context has been pinned again as another pin +* operation is allowed to pass this function. Checking the pin count, +* within ce->guc_state.lock, synchronizes this function with +* guc_request_alloc ensuring a request doesn't slip through the +* 'context_pending_disable' fence. Checking within the spin lock (can't +* sleep) ensures another process doesn't pin this context and generate +* a request before we set the 'context_pending_disable' flag here. +*/ + if (unlikely(atomic_add_unless(&ce->pin_count, -2, 2))) { + spin_unlock_irqrestore(&ce->guc_state.lock, flags); + return; + } guc_id = prep_context_pending_disable(ce); + spin_unlock_irqrestore(&ce->guc_state.lock, flags); with_intel_runtime_pm(runtime_pm, wakeref) @@ -1135,19 +1150,22 @@ static int guc_request_alloc(struct i915_request *rq) out: /* * We block all requests on this context if a G2H is pending for a -* context deregistration as the GuC will fail a context registration -* while this G2H is pending. Once a G2H returns, the fence is released -* that is blocking these requests (see guc_signal_context_fence). +* schedule disable or context deregistration as the GuC will fail a +* schedule enable or context registration if either G2H is pending +* respectfully. Once a G2H returns, the fence is released that is +* blocking these requests (see guc_signal_context_fence). * -* We can safely check the below field outside of the lock as it isn't -* possible for this field to transition from being clear to set but +* We can safely check the below fields outside of the lock as it isn't +* possible for these fields to transition from being clear to set but * converse is possible, hence the need for the check within the lock. */ - if (likely(!context_wait_for_deregister_to_register(ce))) + if (likely(!context_wait_for_deregister_to_register(ce) && + !context_pending_disable(ce))) return 0; spin_lock_irqsave(&ce->guc_state.lock, flags); - if (context_wait_for_deregister_to_register(ce)) { + if (context_wait_for_deregister_to_register(ce) || + context_pending_disable(ce)) { i915_sw_fence_await(&rq->submit); list_add_tail(&rq->guc_fence_link, &ce->guc_state.fences); @@ -1491,10 +1509,18 @@ int intel_guc_sched_done_process_msg(struct intel_guc *guc, if (context_pending_enable(ce)) { clr_context_pending_enable(ce); } else if (context_pending_disable(ce)) { + /* +* Unpin must be done before __guc_signal_context_fence, +* otherwise a race exists between the requests getting +* submitted + retired before this unpin completes resulting in +* the pin_count going to zero and the context still being +* enabled. +*/ intel_context_sched_disable_unpin(ce); spin_lock_irqsave(&ce->guc_state.lock, flags); clr_context_pending_disable(ce); + __guc_signal_context_fence(ce); spin_unlock_irqrestore(&ce->guc_state.lock, flags); } -- 2.28.0
[PATCH 17/18] drm/i915/guc: Add trace point for GuC submit
Add trace point for GuC submit. Extended existing request trace points to include submit fence value,, guc_id, and ring tail value. v2: Fix white space alignment in i915_request_add trace point v3: Delete dep_from , dep_to (Tvrtko) Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 3 +++ drivers/gpu/drm/i915/i915_trace.h | 23 +++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index e6e5364beb1c..d47a8358c831 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -418,6 +418,7 @@ static int guc_dequeue_one_context(struct intel_guc *guc) guc->stalled_request = last; return false; } + trace_i915_request_guc_submit(last); } guc->stalled_request = NULL; @@ -638,6 +639,8 @@ static int guc_bypass_tasklet_submit(struct intel_guc *guc, ret = guc_add_request(guc, rq); if (ret == -EBUSY) guc->stalled_request = rq; + else + trace_i915_request_guc_submit(rq); return ret; } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 6778ad2a14a4..478f5427531d 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -794,30 +794,40 @@ DECLARE_EVENT_CLASS(i915_request, TP_STRUCT__entry( __field(u32, dev) __field(u64, ctx) +__field(u32, guc_id) __field(u16, class) __field(u16, instance) __field(u32, seqno) +__field(u32, tail) ), TP_fast_assign( __entry->dev = rq->engine->i915->drm.primary->index; __entry->class = rq->engine->uabi_class; __entry->instance = rq->engine->uabi_instance; + __entry->guc_id = rq->context->guc_id; __entry->ctx = rq->fence.context; __entry->seqno = rq->fence.seqno; + __entry->tail = rq->tail; ), - TP_printk("dev=%u, engine=%u:%u, ctx=%llu, seqno=%u", + TP_printk("dev=%u, engine=%u:%u, guc_id=%u, ctx=%llu, seqno=%u, tail=%u", __entry->dev, __entry->class, __entry->instance, - __entry->ctx, __entry->seqno) + __entry->guc_id, __entry->ctx, __entry->seqno, + __entry->tail) ); DEFINE_EVENT(i915_request, i915_request_add, - TP_PROTO(struct i915_request *rq), - TP_ARGS(rq) +TP_PROTO(struct i915_request *rq), +TP_ARGS(rq) ); #if defined(CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS) +DEFINE_EVENT(i915_request, i915_request_guc_submit, +TP_PROTO(struct i915_request *rq), +TP_ARGS(rq) +); + DEFINE_EVENT(i915_request, i915_request_submit, TP_PROTO(struct i915_request *rq), TP_ARGS(rq) @@ -887,6 +897,11 @@ TRACE_EVENT(i915_request_out, #else #if !defined(TRACE_HEADER_MULTI_READ) +static inline void +trace_i915_request_guc_submit(struct i915_request *rq) +{ +} + static inline void trace_i915_request_submit(struct i915_request *rq) { -- 2.28.0
[PATCH 07/18] drm/i915/guc: Insert fence on context when deregistering
Sometimes during context pinning a context with the same guc_id is registered with the GuC. In this a case deregister must be done before the context can be registered. A fence is inserted on all requests while the deregister is in flight. Once the G2H is received indicating the deregistration is complete the context is registered and the fence is released. v2: (John H) - Fix commit message Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/intel_context.c | 1 + drivers/gpu/drm/i915/gt/intel_context_types.h | 5 ++ .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 51 ++- drivers/gpu/drm/i915/i915_request.h | 8 +++ 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index 32fd6647154b..ad7197c5910f 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -385,6 +385,7 @@ intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine) mutex_init(&ce->pin_mutex); spin_lock_init(&ce->guc_state.lock); + INIT_LIST_HEAD(&ce->guc_state.fences); ce->guc_id = GUC_INVALID_LRC_ID; INIT_LIST_HEAD(&ce->guc_id_link); diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 606c480aec26..e0e3a937f709 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -147,6 +147,11 @@ struct intel_context { * submission */ u8 sched_state; + /* +* fences: maintains of list of requests that have a submit +* fence related to GuC submission +*/ + struct list_head fences; } guc_state; /* GuC scheduling state flags that do not require a lock. */ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 463613a414d2..a0871b800153 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -935,6 +935,30 @@ static const struct intel_context_ops guc_context_ops = { .destroy = guc_context_destroy, }; +static void __guc_signal_context_fence(struct intel_context *ce) +{ + struct i915_request *rq; + + lockdep_assert_held(&ce->guc_state.lock); + + list_for_each_entry(rq, &ce->guc_state.fences, guc_fence_link) + i915_sw_fence_complete(&rq->submit); + + INIT_LIST_HEAD(&ce->guc_state.fences); +} + +static void guc_signal_context_fence(struct intel_context *ce) +{ + unsigned long flags; + + GEM_BUG_ON(!context_wait_for_deregister_to_register(ce)); + + spin_lock_irqsave(&ce->guc_state.lock, flags); + clr_context_wait_for_deregister_to_register(ce); + __guc_signal_context_fence(ce); + spin_unlock_irqrestore(&ce->guc_state.lock, flags); +} + static bool context_needs_register(struct intel_context *ce, bool new_guc_id) { return new_guc_id || test_bit(CONTEXT_LRCA_DIRTY, &ce->flags) || @@ -945,6 +969,7 @@ static int guc_request_alloc(struct i915_request *rq) { struct intel_context *ce = rq->context; struct intel_guc *guc = ce_to_guc(ce); + unsigned long flags; int ret; GEM_BUG_ON(!intel_context_is_pinned(rq->context)); @@ -989,7 +1014,7 @@ static int guc_request_alloc(struct i915_request *rq) * increment (in pin_guc_id) is needed to seal a race with unpin_guc_id. */ if (atomic_add_unless(&ce->guc_id_ref, 1, 0)) - return 0; + goto out; ret = pin_guc_id(guc, ce); /* returns 1 if new guc_id assigned */ if (unlikely(ret < 0)) @@ -1005,6 +1030,28 @@ static int guc_request_alloc(struct i915_request *rq) clear_bit(CONTEXT_LRCA_DIRTY, &ce->flags); +out: + /* +* We block all requests on this context if a G2H is pending for a +* context deregistration as the GuC will fail a context registration +* while this G2H is pending. Once a G2H returns, the fence is released +* that is blocking these requests (see guc_signal_context_fence). +* +* We can safely check the below field outside of the lock as it isn't +* possible for this field to transition from being clear to set but +* converse is possible, hence the need for the check within the lock. +*/ + if (likely(!context_wait_for_deregister_to_register(ce))) + return 0; + + spin_lock_irqsave(&ce->guc_state.lock, flags); + if (context_wait_for_deregister_to_register(ce)) { + i915_sw_fence_await(&rq->submit); + + list_add_tail(&rq->guc_fence_link, &ce->guc_state.fences); + } + spin_unlock_ir
[PATCH 03/18] drm/i915/guc: Add LRC descriptor context lookup array
Add LRC descriptor context lookup array which can resolve the intel_context from the LRC descriptor index. In addition to lookup, it can determine if the LRC descriptor context is currently registered with the GuC by checking if an entry for a descriptor index is present. Future patches in the series will make use of this array. v2: (Michal) - "linux/xarray.h" -> - s/lrc/LRC (John H) - Fix commit message Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc.h| 5 +++ .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 32 +-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 2625d2d5959f..35783558d261 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -6,6 +6,8 @@ #ifndef _INTEL_GUC_H_ #define _INTEL_GUC_H_ +#include + #include "intel_uncore.h" #include "intel_guc_fw.h" #include "intel_guc_fwif.h" @@ -46,6 +48,9 @@ struct intel_guc { struct i915_vma *lrc_desc_pool; void *lrc_desc_pool_vaddr; + /* guc_id to intel_context lookup */ + struct xarray context_lookup; + /* Control params for fw initialization */ u32 params[GUC_CTL_MAX_DWORDS]; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index ed5d8ab3624f..23a94a896a0b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -65,8 +65,6 @@ static inline struct i915_priolist *to_priolist(struct rb_node *rb) return rb_entry(rb, struct i915_priolist, node); } -/* Future patches will use this function */ -__maybe_unused static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc *guc, u32 index) { struct guc_lrc_desc *base = guc->lrc_desc_pool_vaddr; @@ -76,6 +74,15 @@ static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc *guc, u32 index) return &base[index]; } +static inline struct intel_context *__get_context(struct intel_guc *guc, u32 id) +{ + struct intel_context *ce = xa_load(&guc->context_lookup, id); + + GEM_BUG_ON(id >= GUC_MAX_LRC_DESCRIPTORS); + + return ce; +} + static int guc_lrc_desc_pool_create(struct intel_guc *guc) { u32 size; @@ -96,6 +103,25 @@ static void guc_lrc_desc_pool_destroy(struct intel_guc *guc) i915_vma_unpin_and_release(&guc->lrc_desc_pool, I915_VMA_RELEASE_MAP); } +static inline void reset_lrc_desc(struct intel_guc *guc, u32 id) +{ + struct guc_lrc_desc *desc = __get_lrc_desc(guc, id); + + memset(desc, 0, sizeof(*desc)); + xa_erase_irq(&guc->context_lookup, id); +} + +static inline bool lrc_desc_registered(struct intel_guc *guc, u32 id) +{ + return __get_context(guc, id); +} + +static inline void set_lrc_desc_registered(struct intel_guc *guc, u32 id, + struct intel_context *ce) +{ + xa_store_irq(&guc->context_lookup, id, ce, GFP_ATOMIC); +} + static void guc_add_request(struct intel_guc *guc, struct i915_request *rq) { /* Leaving stub as this function will be used in future patches */ @@ -400,6 +426,8 @@ int intel_guc_submission_init(struct intel_guc *guc) */ GEM_BUG_ON(!guc->lrc_desc_pool); + xa_init_flags(&guc->context_lookup, XA_FLAGS_LOCK_IRQ); + return 0; } -- 2.28.0
[PATCH 06/18] drm/i915/guc: Implement GuC context operations for new inteface
Implement GuC context operations which includes GuC specific operations alloc, pin, unpin, and destroy. v2: (Daniel Vetter) - Use msleep_interruptible rather than cond_resched in busy loop (Michal) - Remove C++ style comment v3: (Matthew Brost) - Drop GUC_ID_START (John Harrison) - Fix a bunch of typos - Use drm_err rather than drm_dbg for G2H errors (Daniele) - Fix ;; typo - Clean up sched state functions - Add lockdep for guc_id functions - Don't call __release_guc_id when guc_id is invalid - Use MISSING_CASE - Add comment in guc_context_pin - Use shorter path to rpm (Daniele / CI) - Don't call release_guc_id on an invalid guc_id in destroy v4: (Daniel Vetter) - Add FIXME comment Signed-off-by: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/intel_context.c | 5 + drivers/gpu/drm/i915/gt/intel_context_types.h | 22 +- drivers/gpu/drm/i915/gt/intel_lrc_reg.h | 1 - drivers/gpu/drm/i915/gt/uc/intel_guc.h| 47 ++ drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 4 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 670 -- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/i915_request.c | 1 + 8 files changed, 696 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index bd63813c8a80..32fd6647154b 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -384,6 +384,11 @@ intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine) mutex_init(&ce->pin_mutex); + spin_lock_init(&ce->guc_state.lock); + + ce->guc_id = GUC_INVALID_LRC_ID; + INIT_LIST_HEAD(&ce->guc_id_link); + i915_active_init(&ce->active, __intel_context_active, __intel_context_retire, 0); } diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 6d99631d19b9..606c480aec26 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -96,6 +96,7 @@ struct intel_context { #define CONTEXT_BANNED 6 #define CONTEXT_FORCE_SINGLE_SUBMISSION7 #define CONTEXT_NOPREEMPT 8 +#define CONTEXT_LRCA_DIRTY 9 struct { u64 timeout_us; @@ -138,14 +139,29 @@ struct intel_context { u8 wa_bb_page; /* if set, page num reserved for context workarounds */ + struct { + /** lock: protects everything in guc_state */ + spinlock_t lock; + /** +* sched_state: scheduling state of this context using GuC +* submission +*/ + u8 sched_state; + } guc_state; + /* GuC scheduling state flags that do not require a lock. */ atomic_t guc_sched_state_no_lock; + /* GuC LRC descriptor ID */ + u16 guc_id; + + /* GuC LRC descriptor reference count */ + atomic_t guc_id_ref; + /* -* GuC LRC descriptor ID - Not assigned in this patch but future patches -* in the series will. +* GuC ID link - in list when unpinned but guc_id still valid in GuC */ - u16 guc_id; + struct list_head guc_id_link; }; #endif /* __INTEL_CONTEXT_TYPES__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h index 41e5350a7a05..49d4857ad9b7 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc_reg.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc_reg.h @@ -87,7 +87,6 @@ #define GEN11_CSB_WRITE_PTR_MASK (GEN11_CSB_PTR_MASK << 0) #define MAX_CONTEXT_HW_ID (1 << 21) /* exclusive */ -#define MAX_GUC_CONTEXT_HW_ID (1 << 20) /* exclusive */ #define GEN11_MAX_CONTEXT_HW_ID(1 << 11) /* exclusive */ /* in Gen12 ID 0x7FF is reserved to indicate idle */ #define GEN12_MAX_CONTEXT_HW_ID(GEN11_MAX_CONTEXT_HW_ID - 1) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 8c7b92f699f1..7fd6c3e343e4 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -7,6 +7,7 @@ #define _INTEL_GUC_H_ #include +#include #include "intel_uncore.h" #include "intel_guc_fw.h" @@ -44,6 +45,14 @@ struct intel_guc { void (*disable)(struct intel_guc *guc); } interrupts; + /* +* contexts_lock protects the pool of free guc ids and a linked list of +* guc ids available to be stolen +*/ + spinlock_t contexts_lock; + struct ida guc_ids; + struct list_head guc_id_list; + bool submission_selected; struct i915_vma *ads_vma; @@ -101,6 +110,41 @@ intel_guc_send_and_receive(struct intel_guc *guc, const u32 *action, u32 len,
[PATCH 08/18] drm/i915/guc: Defer context unpin until scheduling is disabled
With GuC scheduling, it isn't safe to unpin a context while scheduling is enabled for that context as the GuC may touch some of the pinned state (e.g. LRC). To ensure scheduling isn't enabled when an unpin is done, a call back is added to intel_context_unpin when pin count == 1 to disable scheduling for that context. When the response CTB is received it is safe to do the final unpin. Future patches may add a heuristic / delay to schedule the disable call back to avoid thrashing on schedule enable / disable. v2: (John H) - s/drm_dbg/drm_err (Daneiel) - Clean up sched state function Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/intel_context.c | 4 +- drivers/gpu/drm/i915/gt/intel_context.h | 27 +++- drivers/gpu/drm/i915/gt/intel_context_types.h | 2 + drivers/gpu/drm/i915/gt/uc/intel_guc.h| 2 + drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 3 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 146 +- 6 files changed, 180 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index ad7197c5910f..3d5b4116617f 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -306,9 +306,9 @@ int __intel_context_do_pin(struct intel_context *ce) return err; } -void intel_context_unpin(struct intel_context *ce) +void __intel_context_do_unpin(struct intel_context *ce, int sub) { - if (!atomic_dec_and_test(&ce->pin_count)) + if (!atomic_sub_and_test(sub, &ce->pin_count)) return; CE_TRACE(ce, "unpin\n"); diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h index b10cbe8fee99..974ef85320c2 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.h +++ b/drivers/gpu/drm/i915/gt/intel_context.h @@ -113,7 +113,32 @@ static inline void __intel_context_pin(struct intel_context *ce) atomic_inc(&ce->pin_count); } -void intel_context_unpin(struct intel_context *ce); +void __intel_context_do_unpin(struct intel_context *ce, int sub); + +static inline void intel_context_sched_disable_unpin(struct intel_context *ce) +{ + __intel_context_do_unpin(ce, 2); +} + +static inline void intel_context_unpin(struct intel_context *ce) +{ + if (!ce->ops->sched_disable) { + __intel_context_do_unpin(ce, 1); + } else { + /* +* Move ownership of this pin to the scheduling disable which is +* an async operation. When that operation completes the above +* intel_context_sched_disable_unpin is called potentially +* unpinning the context. +*/ + while (!atomic_add_unless(&ce->pin_count, -1, 1)) { + if (atomic_cmpxchg(&ce->pin_count, 1, 2) == 1) { + ce->ops->sched_disable(ce); + break; + } + } + } +} void intel_context_enter_engine(struct intel_context *ce); void intel_context_exit_engine(struct intel_context *ce); diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index e0e3a937f709..4a5518d295c2 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -43,6 +43,8 @@ struct intel_context_ops { void (*enter)(struct intel_context *ce); void (*exit)(struct intel_context *ce); + void (*sched_disable)(struct intel_context *ce); + void (*reset)(struct intel_context *ce); void (*destroy)(struct kref *kref); }; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 7fd6c3e343e4..4d470ebeda95 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -248,6 +248,8 @@ int intel_guc_reset_engine(struct intel_guc *guc, int intel_guc_deregister_done_process_msg(struct intel_guc *guc, const u32 *msg, u32 len); +int intel_guc_sched_done_process_msg(struct intel_guc *guc, +const u32 *msg, u32 len); void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index 28ff82c5be45..019b25ff1888 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -932,6 +932,9 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r ret = intel_guc_deregister_done_process_msg(guc, payload, len); break; + case INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE: + ret = intel_guc_sched_done_process
[PATCH 09/18] drm/i915/guc: Disable engine barriers with GuC during unpin
Disable engine barriers for unpinning with GuC. This feature isn't needed with the GuC as it disables context scheduling before unpinning which guarantees the HW will not reference the context. Hence it is not necessary to defer unpinning until a kernel context request completes on each engine in the context engine mask. Cc: John Harrison Signed-off-by: Matthew Brost Signed-off-by: Daniele Ceraolo Spurio Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/intel_context.c| 2 +- drivers/gpu/drm/i915/gt/selftest_context.c | 10 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index 3d5b4116617f..91349d071e0e 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -80,7 +80,7 @@ static int intel_context_active_acquire(struct intel_context *ce) __i915_active_acquire(&ce->active); - if (intel_context_is_barrier(ce)) + if (intel_context_is_barrier(ce) || intel_engine_uses_guc(ce->engine)) return 0; /* Preallocate tracking nodes */ diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c index 26685b927169..fa7b99a671dd 100644 --- a/drivers/gpu/drm/i915/gt/selftest_context.c +++ b/drivers/gpu/drm/i915/gt/selftest_context.c @@ -209,7 +209,13 @@ static int __live_active_context(struct intel_engine_cs *engine) * This test makes sure that the context is kept alive until a * subsequent idle-barrier (emitted when the engine wakeref hits 0 * with no more outstanding requests). +* +* In GuC submission mode we don't use idle barriers and we instead +* get a message from the GuC to signal that it is safe to unpin the +* context from memory. */ + if (intel_engine_uses_guc(engine)) + return 0; if (intel_engine_pm_is_awake(engine)) { pr_err("%s is awake before starting %s!\n", @@ -357,7 +363,11 @@ static int __live_remote_context(struct intel_engine_cs *engine) * on the context image remotely (intel_context_prepare_remote_request), * which inserts foreign fences into intel_context.active, does not * clobber the idle-barrier. +* +* In GuC submission mode we don't use idle barriers. */ + if (intel_engine_uses_guc(engine)) + return 0; if (intel_engine_pm_is_awake(engine)) { pr_err("%s is awake before starting %s!\n", -- 2.28.0
[PATCH 12/18] drm/i915/guc: Ensure request ordering via completion fences
If two requests are on the same ring, they are explicitly ordered by the HW. So, a submission fence is sufficient to ensure ordering when using the new GuC submission interface. Conversely, if two requests share a timeline and are on the same physical engine but different context this doesn't ensure ordering on the new GuC submission interface. So, a completion fence needs to be used to ensure ordering. v2: (Daniele) - Don't delete spin lock v3: (Daniele) - Delete forward dec Signed-off-by: John Harrison Signed-off-by: Matthew Brost Reviewed-by: Daniele Ceraolo Spurio --- drivers/gpu/drm/i915/i915_request.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index ef26724fe980..c55dea0edb09 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -432,6 +432,7 @@ void i915_request_retire_upto(struct i915_request *rq) do { tmp = list_first_entry(&tl->requests, typeof(*tmp), link); + GEM_BUG_ON(!i915_request_completed(tmp)); } while (i915_request_retire(tmp) && tmp != rq); } @@ -1463,7 +1464,8 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from) return ret; } - if (is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask))) + if (!intel_engine_uses_guc(to->engine) && + is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask))) ret = await_request_submit(to, from); else ret = emit_semaphore_wait(to, from, I915_FENCE_GFP); @@ -1622,6 +1624,8 @@ __i915_request_add_to_timeline(struct i915_request *rq) prev = to_request(__i915_active_fence_set(&timeline->last_request, &rq->fence)); if (prev && !__i915_request_is_complete(prev)) { + bool uses_guc = intel_engine_uses_guc(rq->engine); + /* * The requests are supposed to be kept in order. However, * we need to be wary in case the timeline->last_request @@ -1632,7 +1636,9 @@ __i915_request_add_to_timeline(struct i915_request *rq) i915_seqno_passed(prev->fence.seqno, rq->fence.seqno)); - if (is_power_of_2(READ_ONCE(prev->engine)->mask | rq->engine->mask)) + if ((!uses_guc && +is_power_of_2(READ_ONCE(prev->engine)->mask | rq->engine->mask)) || + (uses_guc && prev->context == rq->context)) i915_sw_fence_await_sw_fence(&rq->submit, &prev->submit, &rq->submitq); -- 2.28.0
[PATCH 04/18] drm/i915/guc: Implement GuC submission tasklet
Implement GuC submission tasklet for new interface. The new GuC interface uses H2G to submit contexts to the GuC. Since H2G use a single channel, a single tasklet is used for the submission path. Also the per engine interrupt handler has been updated to disable the rescheduling of the physical engine tasklet, when using GuC scheduling, as the physical engine tasklet is no longer used. In this patch the field, guc_id, has been added to intel_context and is not assigned. Patches later in the series will assign this value. v2: (John Harrison) - Clean up some comments v3: (John Harrison) - More comment cleanups Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/intel_context_types.h | 9 + drivers/gpu/drm/i915/gt/uc/intel_guc.h| 4 + .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 231 +- 3 files changed, 127 insertions(+), 117 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 90026c177105..6d99631d19b9 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -137,6 +137,15 @@ struct intel_context { struct intel_sseu sseu; u8 wa_bb_page; /* if set, page num reserved for context workarounds */ + + /* GuC scheduling state flags that do not require a lock. */ + atomic_t guc_sched_state_no_lock; + + /* +* GuC LRC descriptor ID - Not assigned in this patch but future patches +* in the series will. +*/ + u16 guc_id; }; #endif /* __INTEL_CONTEXT_TYPES__ */ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 35783558d261..8c7b92f699f1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -30,6 +30,10 @@ struct intel_guc { struct intel_guc_log log; struct intel_guc_ct ct; + /* Global engine used to submit requests to GuC */ + struct i915_sched_engine *sched_engine; + struct i915_request *stalled_request; + /* intel_guc_recv interrupt related state */ spinlock_t irq_lock; unsigned int msg_enabled_mask; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 23a94a896a0b..ca0717166a27 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -60,6 +60,31 @@ #define GUC_REQUEST_SIZE 64 /* bytes */ +/* + * Below is a set of functions which control the GuC scheduling state which do + * not require a lock as all state transitions are mutually exclusive. i.e. It + * is not possible for the context pinning code and submission, for the same + * context, to be executing simultaneously. We still need an atomic as it is + * possible for some of the bits to changing at the same time though. + */ +#define SCHED_STATE_NO_LOCK_ENABLEDBIT(0) +static inline bool context_enabled(struct intel_context *ce) +{ + return (atomic_read(&ce->guc_sched_state_no_lock) & + SCHED_STATE_NO_LOCK_ENABLED); +} + +static inline void set_context_enabled(struct intel_context *ce) +{ + atomic_or(SCHED_STATE_NO_LOCK_ENABLED, &ce->guc_sched_state_no_lock); +} + +static inline void clr_context_enabled(struct intel_context *ce) +{ + atomic_and((u32)~SCHED_STATE_NO_LOCK_ENABLED, + &ce->guc_sched_state_no_lock); +} + static inline struct i915_priolist *to_priolist(struct rb_node *rb) { return rb_entry(rb, struct i915_priolist, node); @@ -122,37 +147,29 @@ static inline void set_lrc_desc_registered(struct intel_guc *guc, u32 id, xa_store_irq(&guc->context_lookup, id, ce, GFP_ATOMIC); } -static void guc_add_request(struct intel_guc *guc, struct i915_request *rq) +static int guc_add_request(struct intel_guc *guc, struct i915_request *rq) { - /* Leaving stub as this function will be used in future patches */ -} + int err; + struct intel_context *ce = rq->context; + u32 action[3]; + int len = 0; + bool enabled = context_enabled(ce); -/* - * When we're doing submissions using regular execlists backend, writing to - * ELSP from CPU side is enough to make sure that writes to ringbuffer pages - * pinned in mappable aperture portion of GGTT are visible to command streamer. - * Writes done by GuC on our behalf are not guaranteeing such ordering, - * therefore, to ensure the flush, we're issuing a POSTING READ. - */ -static void flush_ggtt_writes(struct i915_vma *vma) -{ - if (i915_vma_is_map_and_fenceable(vma)) - intel_uncore_posting_read_fw(vma->vm->gt->uncore, -GUC_STATUS); -} + if (!enabled) { + action[len++] = INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_SET; + action[len++] = ce
[PATCH 01/18] drm/i915/guc: Add new GuC interface defines and structures
Add new GuC interface defines and structures while maintaining old ones in parallel. Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h | 14 +++ drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 42 +++ 2 files changed, 56 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h index 2d6198e63ebe..57e18babdf4b 100644 --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h @@ -124,10 +124,24 @@ enum intel_guc_action { INTEL_GUC_ACTION_FORCE_LOG_BUFFER_FLUSH = 0x302, INTEL_GUC_ACTION_ENTER_S_STATE = 0x501, INTEL_GUC_ACTION_EXIT_S_STATE = 0x502, + INTEL_GUC_ACTION_GLOBAL_SCHED_POLICY_CHANGE = 0x506, + INTEL_GUC_ACTION_SCHED_CONTEXT = 0x1000, + INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_SET = 0x1001, + INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE = 0x1002, + INTEL_GUC_ACTION_SCHED_ENGINE_MODE_SET = 0x1003, + INTEL_GUC_ACTION_SCHED_ENGINE_MODE_DONE = 0x1004, + INTEL_GUC_ACTION_SET_CONTEXT_PRIORITY = 0x1005, + INTEL_GUC_ACTION_SET_CONTEXT_EXECUTION_QUANTUM = 0x1006, + INTEL_GUC_ACTION_SET_CONTEXT_PREEMPTION_TIMEOUT = 0x1007, + INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION = 0x1008, + INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION = 0x1009, INTEL_GUC_ACTION_SLPC_REQUEST = 0x3003, INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000, + INTEL_GUC_ACTION_REGISTER_CONTEXT = 0x4502, + INTEL_GUC_ACTION_DEREGISTER_CONTEXT = 0x4503, INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER = 0x4505, INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506, + INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600, INTEL_GUC_ACTION_LIMIT }; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h index 617ec601648d..3e060d5958cc 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h @@ -17,6 +17,9 @@ #include "abi/guc_communication_ctb_abi.h" #include "abi/guc_messages_abi.h" +#define GUC_CONTEXT_DISABLE0 +#define GUC_CONTEXT_ENABLE 1 + #define GUC_CLIENT_PRIORITY_KMD_HIGH 0 #define GUC_CLIENT_PRIORITY_HIGH 1 #define GUC_CLIENT_PRIORITY_KMD_NORMAL 2 @@ -26,6 +29,9 @@ #define GUC_MAX_STAGE_DESCRIPTORS 1024 #defineGUC_INVALID_STAGE_IDGUC_MAX_STAGE_DESCRIPTORS +#define GUC_MAX_LRC_DESCRIPTORS65535 +#defineGUC_INVALID_LRC_ID GUC_MAX_LRC_DESCRIPTORS + #define GUC_RENDER_ENGINE 0 #define GUC_VIDEO_ENGINE 1 #define GUC_BLITTER_ENGINE 2 @@ -237,6 +243,42 @@ struct guc_stage_desc { u64 desc_private; } __packed; +#define CONTEXT_REGISTRATION_FLAG_KMD BIT(0) + +#define CONTEXT_POLICY_DEFAULT_EXECUTION_QUANTUM_US 100 +#define CONTEXT_POLICY_DEFAULT_PREEMPTION_TIME_US 50 + +/* Preempt to idle on quantum expiry */ +#define CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLEBIT(0) + +/* + * GuC Context registration descriptor. + * FIXME: This is only required to exist during context registration. + * The current 1:1 between guc_lrc_desc and LRCs for the lifetime of the LRC + * is not required. + */ +struct guc_lrc_desc { + u32 hw_context_desc; + u32 slpm_perf_mode_hint;/* SPLC v1 only */ + u32 slpm_freq_hint; + u32 engine_submit_mask; /* In logical space */ + u8 engine_class; + u8 reserved0[3]; + u32 priority; + u32 process_desc; + u32 wq_addr; + u32 wq_size; + u32 context_flags; /* CONTEXT_REGISTRATION_* */ + /* Time for one workload to execute. (in micro seconds) */ + u32 execution_quantum; + /* Time to wait for a preemption request to complete before issuing a +* reset. (in micro seconds). +*/ + u32 preemption_timeout; + u32 policy_flags; /* CONTEXT_POLICY_* */ + u32 reserved1[19]; +} __packed; + #define GUC_POWER_UNSPECIFIED 0 #define GUC_POWER_D0 1 #define GUC_POWER_D1 2 -- 2.28.0
[PATCH 00/18] Series to merge a subset of GuC submission
The first 18 patches [1] are basically ready to merge. v2: Address NITs, add missing RBs, fix checkpatch warnings Signed-off-by: Matthew Brost [1] https://patchwork.freedesktop.org/series/91840/ Matthew Brost (18): drm/i915/guc: Add new GuC interface defines and structures drm/i915/guc: Remove GuC stage descriptor, add LRC descriptor drm/i915/guc: Add LRC descriptor context lookup array drm/i915/guc: Implement GuC submission tasklet drm/i915/guc: Add bypass tasklet submission path to GuC drm/i915/guc: Implement GuC context operations for new inteface drm/i915/guc: Insert fence on context when deregistering drm/i915/guc: Defer context unpin until scheduling is disabled drm/i915/guc: Disable engine barriers with GuC during unpin drm/i915/guc: Extend deregistration fence to schedule disable drm/i915: Disable preempt busywait when using GuC scheduling drm/i915/guc: Ensure request ordering via completion fences drm/i915/guc: Disable semaphores when using GuC scheduling drm/i915/guc: Ensure G2H response has space in buffer drm/i915/guc: Update intel_gt_wait_for_idle to work with GuC drm/i915/guc: Update GuC debugfs to support new GuC drm/i915/guc: Add trace point for GuC submit drm/i915: Add intel_context tracing drivers/gpu/drm/i915/gem/i915_gem_context.c |6 +- drivers/gpu/drm/i915/gem/i915_gem_mman.c |3 +- drivers/gpu/drm/i915/gt/gen8_engine_cs.c |6 +- drivers/gpu/drm/i915/gt/intel_context.c | 18 +- drivers/gpu/drm/i915/gt/intel_context.h | 27 +- drivers/gpu/drm/i915/gt/intel_context_types.h | 32 + drivers/gpu/drm/i915/gt/intel_gt.c| 19 + drivers/gpu/drm/i915/gt/intel_gt.h|2 + drivers/gpu/drm/i915/gt/intel_gt_requests.c | 21 +- drivers/gpu/drm/i915/gt/intel_gt_requests.h |9 +- drivers/gpu/drm/i915/gt/intel_lrc_reg.h |1 - drivers/gpu/drm/i915/gt/selftest_context.c| 10 + .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h | 14 + drivers/gpu/drm/i915/gt/uc/intel_guc.h| 72 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 124 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 18 +- .../gpu/drm/i915/gt/uc/intel_guc_debugfs.c| 23 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 89 +- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 1290 ++--- .../gpu/drm/i915/gt/uc/intel_guc_submission.h |5 + drivers/gpu/drm/i915/gt/uc/intel_uc.h |5 + drivers/gpu/drm/i915/i915_gem_evict.c |1 + drivers/gpu/drm/i915/i915_reg.h |1 + drivers/gpu/drm/i915/i915_request.c | 11 +- drivers/gpu/drm/i915/i915_request.h |8 + drivers/gpu/drm/i915/i915_trace.h | 168 ++- .../gpu/drm/i915/selftests/igt_live_test.c|2 +- .../gpu/drm/i915/selftests/mock_gem_device.c |3 +- 28 files changed, 1707 insertions(+), 281 deletions(-) -- 2.28.0
[PATCH 02/18] drm/i915/guc: Remove GuC stage descriptor, add LRC descriptor
Remove old GuC stage descriptor, add LRC descriptor which will be used by the new GuC interface implemented in this patch series. v2: (John Harrison) - s/lrc/LRC/g Cc: John Harrison Signed-off-by: Matthew Brost Reviewed-by: John Harrison --- drivers/gpu/drm/i915/gt/uc/intel_guc.h| 4 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 65 - .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 72 ++- 3 files changed, 25 insertions(+), 116 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 72e4653222e2..2625d2d5959f 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -43,8 +43,8 @@ struct intel_guc { struct i915_vma *ads_vma; struct __guc_ads_blob *ads_blob; - struct i915_vma *stage_desc_pool; - void *stage_desc_pool_vaddr; + struct i915_vma *lrc_desc_pool; + void *lrc_desc_pool_vaddr; /* Control params for fw initialization */ u32 params[GUC_CTL_MAX_DWORDS]; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h index 3e060d5958cc..3489b390ae77 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h @@ -26,9 +26,6 @@ #define GUC_CLIENT_PRIORITY_NORMAL 3 #define GUC_CLIENT_PRIORITY_NUM4 -#define GUC_MAX_STAGE_DESCRIPTORS 1024 -#defineGUC_INVALID_STAGE_IDGUC_MAX_STAGE_DESCRIPTORS - #define GUC_MAX_LRC_DESCRIPTORS65535 #defineGUC_INVALID_LRC_ID GUC_MAX_LRC_DESCRIPTORS @@ -181,68 +178,6 @@ struct guc_process_desc { u32 reserved[30]; } __packed; -/* engine id and context id is packed into guc_execlist_context.context_id*/ -#define GUC_ELC_CTXID_OFFSET 0 -#define GUC_ELC_ENGINE_OFFSET 29 - -/* The execlist context including software and HW information */ -struct guc_execlist_context { - u32 context_desc; - u32 context_id; - u32 ring_status; - u32 ring_lrca; - u32 ring_begin; - u32 ring_end; - u32 ring_next_free_location; - u32 ring_current_tail_pointer_value; - u8 engine_state_submit_value; - u8 engine_state_wait_value; - u16 pagefault_count; - u16 engine_submit_queue_count; -} __packed; - -/* - * This structure describes a stage set arranged for a particular communication - * between uKernel (GuC) and Driver (KMD). Technically, this is known as a - * "GuC Context descriptor" in the specs, but we use the term "stage descriptor" - * to avoid confusion with all the other things already named "context" in the - * driver. A static pool of these descriptors are stored inside a GEM object - * (stage_desc_pool) which is held for the entire lifetime of our interaction - * with the GuC, being allocated before the GuC is loaded with its firmware. - */ -struct guc_stage_desc { - u32 sched_common_area; - u32 stage_id; - u32 pas_id; - u8 engines_used; - u64 db_trigger_cpu; - u32 db_trigger_uk; - u64 db_trigger_phy; - u16 db_id; - - struct guc_execlist_context lrc[GUC_MAX_ENGINES_NUM]; - - u8 attribute; - - u32 priority; - - u32 wq_sampled_tail_offset; - u32 wq_total_submit_enqueues; - - u32 process_desc; - u32 wq_addr; - u32 wq_size; - - u32 engine_presence; - - u8 engine_suspended; - - u8 reserved0[3]; - u64 reserved1[1]; - - u64 desc_private; -} __packed; - #define CONTEXT_REGISTRATION_FLAG_KMD BIT(0) #define CONTEXT_POLICY_DEFAULT_EXECUTION_QUANTUM_US 100 diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index e9c237b18692..ed5d8ab3624f 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -65,57 +65,35 @@ static inline struct i915_priolist *to_priolist(struct rb_node *rb) return rb_entry(rb, struct i915_priolist, node); } -static struct guc_stage_desc *__get_stage_desc(struct intel_guc *guc, u32 id) +/* Future patches will use this function */ +__maybe_unused +static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc *guc, u32 index) { - struct guc_stage_desc *base = guc->stage_desc_pool_vaddr; + struct guc_lrc_desc *base = guc->lrc_desc_pool_vaddr; - return &base[id]; -} - -static int guc_stage_desc_pool_create(struct intel_guc *guc) -{ - u32 size = PAGE_ALIGN(sizeof(struct guc_stage_desc) * - GUC_MAX_STAGE_DESCRIPTORS); + GEM_BUG_ON(index >= GUC_MAX_LRC_DESCRIPTORS); - return intel_guc_allocate_and_map_vma(guc, size, &guc->stage_desc_pool, - &guc->stage_desc_pool_vaddr); + return &base[index]; } -static void guc_stage_desc_
Re: [PATCH 12/18] drm/i915/guc: Ensure request ordering via completion fences
On 7/20/2021 3:39 PM, Matthew Brost wrote: If two requests are on the same ring, they are explicitly ordered by the HW. So, a submission fence is sufficient to ensure ordering when using the new GuC submission interface. Conversely, if two requests share a timeline and are on the same physical engine but different context this doesn't ensure ordering on the new GuC submission interface. So, a completion fence needs to be used to ensure ordering. v2: (Daniele) - Don't delete spin lock Signed-off-by: John Harrison Signed-off-by: Matthew Brost --- drivers/gpu/drm/i915/i915_request.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index ef26724fe980..3ecdc9180d8f 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -432,6 +432,7 @@ void i915_request_retire_upto(struct i915_request *rq) do { tmp = list_first_entry(&tl->requests, typeof(*tmp), link); + GEM_BUG_ON(!i915_request_completed(tmp)); } while (i915_request_retire(tmp) && tmp != rq); } @@ -1380,6 +1381,9 @@ i915_request_await_external(struct i915_request *rq, struct dma_fence *fence) return err; } +static int +i915_request_await_request(struct i915_request *to, struct i915_request *from); + I missed it in the previous rev, but this forward decl seems unneeded. With it dropped: Reviewed-by: Daniele Ceraolo Spurio Daniele int i915_request_await_execution(struct i915_request *rq, struct dma_fence *fence) @@ -1463,7 +1467,8 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from) return ret; } - if (is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask))) + if (!intel_engine_uses_guc(to->engine) && + is_power_of_2(to->execution_mask | READ_ONCE(from->execution_mask))) ret = await_request_submit(to, from); else ret = emit_semaphore_wait(to, from, I915_FENCE_GFP); @@ -1622,6 +1627,8 @@ __i915_request_add_to_timeline(struct i915_request *rq) prev = to_request(__i915_active_fence_set(&timeline->last_request, &rq->fence)); if (prev && !__i915_request_is_complete(prev)) { + bool uses_guc = intel_engine_uses_guc(rq->engine); + /* * The requests are supposed to be kept in order. However, * we need to be wary in case the timeline->last_request @@ -1632,7 +1639,8 @@ __i915_request_add_to_timeline(struct i915_request *rq) i915_seqno_passed(prev->fence.seqno, rq->fence.seqno)); - if (is_power_of_2(READ_ONCE(prev->engine)->mask | rq->engine->mask)) + if ((!uses_guc && is_power_of_2(READ_ONCE(prev->engine)->mask | rq->engine->mask)) || + (uses_guc && prev->context == rq->context)) i915_sw_fence_await_sw_fence(&rq->submit, &prev->submit, &rq->submitq);
Re: [PATCH v5 09/15] drm/i915/pxp: Implement PXP irq handler
On 7/21/2021 11:59 AM, Rodrigo Vivi wrote: On Thu, Jul 15, 2021 at 09:10:28PM -0700, Daniele Ceraolo Spurio wrote: From: "Huang, Sean Z" The HW will generate a teardown interrupt when session termination is required, which requires i915 to submit a terminating batch. Once the HW is done with the termination it will generate another interrupt, at which point it is safe to re-create the session. Since the termination and re-creation flow is something we want to trigger from the driver as well, use a common work function that can be called both from the irq handler and from the driver set-up flows, which has the addded benefit of allowing us to skip any extra locks because the work itself serializes the operations. v2: use struct completion instead of bool (Chris) v3: drop locks, clean up functions and improve comments (Chris), move to common work function. v4: improve comments, simplify wait logic (Rodrigo) v5: unconditionally set interrupts, I didn't find this... this looks the same as v4 It's a very minor change in intel_pxp_irq_enable, the regs were set inside the if statement before in this patch and moved outside in a later patch, now they're outside to begin. rename state_attacked var (Rodrigo) thanks Signed-off-by: Huang, Sean Z Signed-off-by: Daniele Ceraolo Spurio Cc: Chris Wilson Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi #v4 anyway, this patch looks good to me... Reviewed-by: Rodrigo Vivi Thanks! Daniele --- drivers/gpu/drm/i915/Makefile| 1 + drivers/gpu/drm/i915/gt/intel_gt_irq.c | 7 ++ drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/pxp/intel_pxp.c | 66 +++-- drivers/gpu/drm/i915/pxp/intel_pxp.h | 8 ++ drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 99 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 32 +++ drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++- drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 5 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 8 +- drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 18 11 files changed, 283 insertions(+), 16 deletions(-) create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 44d3a2bcb64c..1714089a10f0 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -279,6 +279,7 @@ i915-y += i915_perf.o i915-$(CONFIG_DRM_I915_PXP) += \ pxp/intel_pxp.o \ pxp/intel_pxp_cmd.o \ + pxp/intel_pxp_irq.o \ pxp/intel_pxp_session.o \ pxp/intel_pxp_tee.o diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c index c13462274fe8..96f0e9172a09 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c @@ -13,6 +13,7 @@ #include "intel_lrc_reg.h" #include "intel_uncore.h" #include "intel_rps.h" +#include "pxp/intel_pxp_irq.h" static void guc_irq_handler(struct intel_guc *guc, u16 iir) { @@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance, if (instance == OTHER_GTPM_INSTANCE) return gen11_rps_irq_handler(>->rps, iir); + if (instance == OTHER_KCR_INSTANCE) + return intel_pxp_irq_handler(>->pxp, iir); + WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n", instance, iir); } @@ -190,6 +194,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt) intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK, ~0); intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0); intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK, ~0); + + intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0); + intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK, ~0); } void gen11_gt_irq_postinstall(struct intel_gt *gt) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 943fe485c662..2c583f2d410d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8051,6 +8051,7 @@ enum { /* irq instances for OTHER_CLASS */ #define OTHER_GUC_INSTANCE0 #define OTHER_GTPM_INSTANCE 1 +#define OTHER_KCR_INSTANCE 4 #define GEN11_INTR_IDENTITY_REG(x) _MMIO(0x190060 + ((x) * 4)) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index 26176d43a02d..b0c7edc10cc3 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -2,7 +2,9 @@ /* * Copyright(c) 2020 Intel Corporation. */ +#include #include "intel_pxp.h" +#include "intel_pxp_irq.h" #include "intel_pxp_session.h" #include "intel_pxp_tee.h" #include "gt/intel_context.h" @@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp) mutex_init(&pxp->tee_
Re: [RESEND PATCH v6 07/14] drm/etnaviv: Change buffer dump checks to target syslog
Am Mittwoch, dem 21.07.2021 um 13:55 -0400 schrieb Sean Paul: > From: Sean Paul > > Since the logs protected by these checks specifically target syslog, > use the new drm_debug_syslog_enabled() call to avoid triggering > these prints when only trace is enabled. > > Signed-off-by: Sean Paul Acked-by: Lucas Stach > Link: > https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-8-s...@poorly.run > #v5 > > Changes in v5: > -Added to the set > Changes in v6: > -None > --- > drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c > b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c > index 76d38561c910..7713474800e8 100644 > --- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c > +++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c > @@ -353,7 +353,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 > exec_state, > > lockdep_assert_held(&gpu->lock); > > - if (drm_debug_enabled(DRM_UT_DRIVER)) > + if (drm_debug_syslog_enabled(DRM_UT_DRIVER)) > etnaviv_buffer_dump(gpu, buffer, 0, 0x50); > > link_target = etnaviv_cmdbuf_get_va(cmdbuf, > @@ -509,13 +509,13 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 > exec_state, >etnaviv_cmdbuf_get_va(buffer, > &gpu->mmu_context->cmdbuf_mapping) >+ buffer->user_size - 4); > > - if (drm_debug_enabled(DRM_UT_DRIVER)) > + if (drm_debug_syslog_enabled(DRM_UT_DRIVER)) > pr_info("stream link to 0x%08x @ 0x%08x %p\n", > return_target, > etnaviv_cmdbuf_get_va(cmdbuf, > &gpu->mmu_context->cmdbuf_mapping), > cmdbuf->vaddr); > > - if (drm_debug_enabled(DRM_UT_DRIVER)) { > + if (drm_debug_syslog_enabled(DRM_UT_DRIVER)) { > print_hex_dump(KERN_INFO, "cmd ", DUMP_PREFIX_OFFSET, 16, 4, > cmdbuf->vaddr, cmdbuf->size, 0); > > @@ -534,6 +534,6 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 > exec_state, > VIV_FE_LINK_HEADER_PREFETCH(link_dwords), > link_target); > > - if (drm_debug_enabled(DRM_UT_DRIVER)) > + if (drm_debug_syslog_enabled(DRM_UT_DRIVER)) > etnaviv_buffer_dump(gpu, buffer, 0, 0x50); > }
Re: [Intel-gfx] [PATCH 5/7] drm/i915/gem/ttm: Respect the objection region in placement_from_obj
On Wed, Jul 21, 2021 at 10:11 PM Jason Ekstrand wrote: > > On Mon, Jul 19, 2021 at 8:35 AM Matthew Auld > wrote: > > > > On Fri, 16 Jul 2021 at 20:49, Jason Ekstrand wrote: > > > > > > On Fri, Jul 16, 2021 at 1:45 PM Matthew Auld > > > wrote: > > > > > > > > On Fri, 16 Jul 2021 at 18:39, Jason Ekstrand > > > > wrote: > > > > > > > > > > On Fri, Jul 16, 2021 at 11:00 AM Matthew Auld > > > > > wrote: > > > > > > > > > > > > On Fri, 16 Jul 2021 at 16:52, Matthew Auld > > > > > > wrote: > > > > > > > > > > > > > > On Fri, 16 Jul 2021 at 15:10, Jason Ekstrand > > > > > > > wrote: > > > > > > > > > > > > > > > > On Fri, Jul 16, 2021 at 8:54 AM Matthew Auld > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > On Thu, 15 Jul 2021 at 23:39, Jason Ekstrand > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > Whenever we had a user object (n_placements > 0), we were > > > > > > > > > > ignoring > > > > > > > > > > obj->mm.region and always putting obj->placements[0] as the > > > > > > > > > > requested > > > > > > > > > > region. For LMEM+SMEM objects, this was causing them to > > > > > > > > > > get shoved into > > > > > > > > > > LMEM on every i915_ttm_get_pages() even when SMEM was > > > > > > > > > > requested by, say, > > > > > > > > > > i915_gem_object_migrate(). > > > > > > > > > > > > > > > > > > i915_ttm_migrate calls i915_ttm_place_from_region() directly > > > > > > > > > with the > > > > > > > > > requested region, so there shouldn't be an issue with > > > > > > > > > migration right? > > > > > > > > > Do you have some more details? > > > > > > > > > > > > > > > > With i915_ttm_migrate directly, no. But, in the last patch in > > > > > > > > the > > > > > > > > series, we're trying to migrate LMEM+SMEM buffers into SMEM on > > > > > > > > attach() and pin it there. This blows up in a very unexpected > > > > > > > > (IMO) > > > > > > > > way. The flow goes something like this: > > > > > > > > > > > > > > > > - Client attempts a dma-buf import from another device > > > > > > > > - In attach() we call i915_gem_object_migrate() which calls > > > > > > > > i915_ttm_migrate() which migrates as requested. > > > > > > > > - Once the migration is complete, we call > > > > > > > > i915_gem_object_pin_pages() > > > > > > > > which calls i915_ttm_get_pages() which depends on > > > > > > > > i915_ttm_placement_from_obj() and so migrates it right back to > > > > > > > > LMEM. > > > > > > > > > > > > > > The mm.pages must be NULL here, otherwise it would just increment > > > > > > > the > > > > > > > pages_pin_count? > > > > > > > > > > Given that the test is using the four_underscores version, it > > > > > doesn't have that check. However, this executes after we've done the > > > > > dma-buf import which pinned pages. So we should definitely have > > > > > pages. > > > > > > > > We shouldn't call four_underscores() if we might already have > > > > pages though. Under non-TTM that would leak the pages, and in TTM we > > > > might hit the WARN_ON(mm->pages) in __i915_ttm_get_pages(), if for > > > > example nothing was moved. I take it we can't just call pin_pages()? > > > > Four scary underscores usually means "don't call this in normal code". > > > > > > I've switched the four_underscores call to a __two_underscores in > > > the selftests and it had no effect, good or bad. But, still, probably > > > better to call that one. > > > > > > > > > > > > > > > > > > > > > > > > Maybe the problem here is actually that our TTM code isn't > > > > > > > > respecting > > > > > > > > obj->mm.pages_pin_count? > > > > > > > > > > > > > > I think if the resource is moved, we always nuke the mm.pages > > > > > > > after > > > > > > > being notified of the move. Also TTM is also not allowed to move > > > > > > > pinned buffers. > > > > > > > > > > > > > > I guess if we are evicted/swapped, so assuming we are not holding > > > > > > > the > > > > > > > object lock, and it's not pinned, the future call to get_pages() > > > > > > > will > > > > > > > see mm.pages = NULL, even though the ttm_resource is still there, > > > > > > > and > > > > > > > because we prioritise the placements[0], instead of mm.region we > > > > > > > end > > > > > > > up moving it for no good reason. But in your case you are holding > > > > > > > the > > > > > > > lock, or it's pinned? Also is this just with the selftest, or > > > > > > > something real? > > > > > > > > > > > > Or at least in the selftest I see i915_gem_object_get_pages() > > > > > > which doesn't even consider the mm.pages AFAIK. > > > > > > > > > > The bogus migration is happening as part of the > > > > > __i915_gem_object_get_pages() (2 __underscores) call in > > > > > i915_gem_dmabuf_attach (see last patch). That code is attempting to > > > > > migrate the BO to SMEM and then pin it there using the obvious calls > > > > > to do so. However, in the pin_pages call, it gets implicitly migrated > > > > > back to LMEM thanks to
Re: [PATCH 3/4] drm/i915/userptr: Probe existence of backing struct pages upon creation
On Thu, Jul 15, 2021 at 5:16 AM Matthew Auld wrote: > > From: Chris Wilson > > Jason Ekstrand requested a more efficient method than userptr+set-domain > to determine if the userptr object was backed by a complete set of pages > upon creation. To be more efficient than simply populating the userptr > using get_user_pages() (as done by the call to set-domain or execbuf), > we can walk the tree of vm_area_struct and check for gaps or vma not > backed by struct page (VM_PFNMAP). The question is how to handle > VM_MIXEDMAP which may be either struct page or pfn backed... > > With discrete are going to drop support for set_domain(), so offering a > way to probe the pages, without having to resort to dummy batches has > been requested. > > v2: > - add new query param for the PROPBE flag, so userspace can easily > check if the kernel supports it(Jason). > - use mmap_read_{lock, unlock}. > - add some kernel-doc. > > Testcase: igt/gem_userptr_blits/probe > Signed-off-by: Chris Wilson > Signed-off-by: Matthew Auld > Cc: Thomas Hellström > Cc: Maarten Lankhorst > Cc: Tvrtko Ursulin > Cc: Jordan Justen > Cc: Kenneth Graunke > Cc: Jason Ekstrand > Cc: Daniel Vetter > Cc: Ramalingam C > --- > drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 40 - > drivers/gpu/drm/i915/i915_getparam.c| 3 ++ > include/uapi/drm/i915_drm.h | 18 ++ > 3 files changed, 60 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > index 56edfeff8c02..fd6880328596 100644 > --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > @@ -422,6 +422,33 @@ static const struct drm_i915_gem_object_ops > i915_gem_userptr_ops = { > > #endif > > +static int > +probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len) > +{ > + const unsigned long end = addr + len; > + struct vm_area_struct *vma; > + int ret = -EFAULT; > + > + mmap_read_lock(mm); > + for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { > + if (vma->vm_start > addr) Why isn't this > end? Are we somehow guaranteed that one vma covers the entire range? > + break; > + > + if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) > + break; > + > + if (vma->vm_end >= end) { > + ret = 0; > + break; > + } > + > + addr = vma->vm_end; > + } > + mmap_read_unlock(mm); > + > + return ret; > +} > + > /* > * Creates a new mm object that wraps some normal memory from the process > * context - user memory. > @@ -477,7 +504,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, > } > > if (args->flags & ~(I915_USERPTR_READ_ONLY | > - I915_USERPTR_UNSYNCHRONIZED)) > + I915_USERPTR_UNSYNCHRONIZED | > + I915_USERPTR_PROBE)) > return -EINVAL; > > if (i915_gem_object_size_2big(args->user_size)) > @@ -504,6 +532,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev, > return -ENODEV; > } > > + if (args->flags & I915_USERPTR_PROBE) { > + /* > +* Check that the range pointed to represents real struct > +* pages and not iomappings (at this moment in time!) > +*/ > + ret = probe_range(current->mm, args->user_ptr, > args->user_size); > + if (ret) > + return ret; > + } > + > #ifdef CONFIG_MMU_NOTIFIER > obj = i915_gem_object_alloc(); > if (obj == NULL) > diff --git a/drivers/gpu/drm/i915/i915_getparam.c > b/drivers/gpu/drm/i915/i915_getparam.c > index 24e18219eb50..d6d2e1a10d14 100644 > --- a/drivers/gpu/drm/i915/i915_getparam.c > +++ b/drivers/gpu/drm/i915/i915_getparam.c > @@ -163,6 +163,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void > *data, > case I915_PARAM_PERF_REVISION: > value = i915_perf_ioctl_version(); > break; > + case I915_PARAM_HAS_USERPTR_PROBE: > + value = true; > + break; > default: > DRM_DEBUG("Unknown parameter %d\n", param->param); > return -EINVAL; > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index e20eeeca7a1c..2e4112bf4d38 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -674,6 +674,9 @@ typedef struct drm_i915_irq_wait { > */ > #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55 > > +/* Query if the kernel supports the I915_USERPTR_PROBE flag. */ > +#define I915_PARAM_HAS_USERPTR_PROBE 56 > + > /* Must be kept compact -- no holes and well documented */ > > typedef struct drm_i915_getparam { > @@ -2178,12 +2181,27
Re: [PATCH] drm/i915: Ditch i915 globals shrink infrastructure
On Wed, Jul 21, 2021 at 10:17 PM Jason Ekstrand wrote: > > On Wed, Jul 21, 2021 at 1:32 PM Daniel Vetter wrote: > > > > This essentially reverts > > > > commit 84a1074920523430f9dc30ff907f4801b4820072 > > Author: Chris Wilson > > Date: Wed Jan 24 11:36:08 2018 + > > > > drm/i915: Shrink the GEM kmem_caches upon idling > > > > mm/vmscan.c:do_shrink_slab() is a thing, if there's an issue with it > > then we need to fix that there, not hand-roll our own slab shrinking > > code in i915. > > > > Noticed while reviewing a patch set from Jason to fix up some issues > > in our i915_init() and i915_exit() module load/cleanup code. Now that > > i915_globals.c isn't any different than normal init/exit functions, we > > should convert them over to one unified table and remove > > i915_globals.[hc] entirely. > > Mind throwing in a comment somewhere about how i915 is one of only two > users of kmem_cache_shrink() in the entire kernel? That also seems to > be pretty good evidence that it's not useful. I missed one, there's also on in kunit (I think just got in, it's from this year at least per commit). That one seems actually legit, it's a selftest for some statistics around slabs I think, so has a legit reason to carefully control the state and trim anything that just hangs around. I'll add something and push when CI approves. > Reviewed-by: Jason Ekstrand > > Feel free to land at-will and I'll deal with merge conflicts on my end. I think if we can land this, then yours, then I type the conversion to explicit init/exit and we're done. -Daniel > > > Cc: David Airlie > > Cc: Jason Ekstrand > > Signed-off-by: Daniel Vetter > > --- > > drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 -- > > drivers/gpu/drm/i915/gem/i915_gem_object.c | 6 -- > > drivers/gpu/drm/i915/gt/intel_context.c | 6 -- > > drivers/gpu/drm/i915/gt/intel_gt_pm.c | 4 - > > drivers/gpu/drm/i915/i915_active.c | 6 -- > > drivers/gpu/drm/i915/i915_globals.c | 95 - > > drivers/gpu/drm/i915/i915_globals.h | 3 - > > drivers/gpu/drm/i915/i915_request.c | 7 -- > > drivers/gpu/drm/i915/i915_scheduler.c | 7 -- > > drivers/gpu/drm/i915/i915_vma.c | 6 -- > > 10 files changed, 146 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c > > b/drivers/gpu/drm/i915/gem/i915_gem_context.c > > index 7d6f52d8a801..bf2a2319353a 100644 > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c > > @@ -2280,18 +2280,12 @@ i915_gem_engines_iter_next(struct > > i915_gem_engines_iter *it) > > #include "selftests/i915_gem_context.c" > > #endif > > > > -static void i915_global_gem_context_shrink(void) > > -{ > > - kmem_cache_shrink(global.slab_luts); > > -} > > - > > static void i915_global_gem_context_exit(void) > > { > > kmem_cache_destroy(global.slab_luts); > > } > > > > static struct i915_global_gem_context global = { { > > - .shrink = i915_global_gem_context_shrink, > > .exit = i915_global_gem_context_exit, > > } }; > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c > > b/drivers/gpu/drm/i915/gem/i915_gem_object.c > > index 9da7b288b7ed..5c21cff33199 100644 > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c > > @@ -664,18 +664,12 @@ void i915_gem_init__objects(struct drm_i915_private > > *i915) > > INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); > > } > > > > -static void i915_global_objects_shrink(void) > > -{ > > - kmem_cache_shrink(global.slab_objects); > > -} > > - > > static void i915_global_objects_exit(void) > > { > > kmem_cache_destroy(global.slab_objects); > > } > > > > static struct i915_global_object global = { { > > - .shrink = i915_global_objects_shrink, > > .exit = i915_global_objects_exit, > > } }; > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_context.c > > b/drivers/gpu/drm/i915/gt/intel_context.c > > index bd63813c8a80..c1338441cc1d 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_context.c > > +++ b/drivers/gpu/drm/i915/gt/intel_context.c > > @@ -398,18 +398,12 @@ void intel_context_fini(struct intel_context *ce) > > i915_active_fini(&ce->active); > > } > > > > -static void i915_global_context_shrink(void) > > -{ > > - kmem_cache_shrink(global.slab_ce); > > -} > > - > > static void i915_global_context_exit(void) > > { > > kmem_cache_destroy(global.slab_ce); > > } > > > > static struct i915_global_context global = { { > > - .shrink = i915_global_context_shrink, > > .exit = i915_global_context_exit, > > } }; > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c > > b/drivers/gpu/drm/i915/gt/intel_gt_pm.c > > index aef3084e8b16..d86825437516 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c > > @@ -67,8 +67,6 @@ stati
Re: [PATCH] drm/i915: Ditch i915 globals shrink infrastructure
On Wed, Jul 21, 2021 at 1:32 PM Daniel Vetter wrote: > > This essentially reverts > > commit 84a1074920523430f9dc30ff907f4801b4820072 > Author: Chris Wilson > Date: Wed Jan 24 11:36:08 2018 + > > drm/i915: Shrink the GEM kmem_caches upon idling > > mm/vmscan.c:do_shrink_slab() is a thing, if there's an issue with it > then we need to fix that there, not hand-roll our own slab shrinking > code in i915. > > Noticed while reviewing a patch set from Jason to fix up some issues > in our i915_init() and i915_exit() module load/cleanup code. Now that > i915_globals.c isn't any different than normal init/exit functions, we > should convert them over to one unified table and remove > i915_globals.[hc] entirely. Mind throwing in a comment somewhere about how i915 is one of only two users of kmem_cache_shrink() in the entire kernel? That also seems to be pretty good evidence that it's not useful. Reviewed-by: Jason Ekstrand Feel free to land at-will and I'll deal with merge conflicts on my end. > Cc: David Airlie > Cc: Jason Ekstrand > Signed-off-by: Daniel Vetter > --- > drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 -- > drivers/gpu/drm/i915/gem/i915_gem_object.c | 6 -- > drivers/gpu/drm/i915/gt/intel_context.c | 6 -- > drivers/gpu/drm/i915/gt/intel_gt_pm.c | 4 - > drivers/gpu/drm/i915/i915_active.c | 6 -- > drivers/gpu/drm/i915/i915_globals.c | 95 - > drivers/gpu/drm/i915/i915_globals.h | 3 - > drivers/gpu/drm/i915/i915_request.c | 7 -- > drivers/gpu/drm/i915/i915_scheduler.c | 7 -- > drivers/gpu/drm/i915/i915_vma.c | 6 -- > 10 files changed, 146 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c > b/drivers/gpu/drm/i915/gem/i915_gem_context.c > index 7d6f52d8a801..bf2a2319353a 100644 > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c > @@ -2280,18 +2280,12 @@ i915_gem_engines_iter_next(struct > i915_gem_engines_iter *it) > #include "selftests/i915_gem_context.c" > #endif > > -static void i915_global_gem_context_shrink(void) > -{ > - kmem_cache_shrink(global.slab_luts); > -} > - > static void i915_global_gem_context_exit(void) > { > kmem_cache_destroy(global.slab_luts); > } > > static struct i915_global_gem_context global = { { > - .shrink = i915_global_gem_context_shrink, > .exit = i915_global_gem_context_exit, > } }; > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c > b/drivers/gpu/drm/i915/gem/i915_gem_object.c > index 9da7b288b7ed..5c21cff33199 100644 > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c > @@ -664,18 +664,12 @@ void i915_gem_init__objects(struct drm_i915_private > *i915) > INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); > } > > -static void i915_global_objects_shrink(void) > -{ > - kmem_cache_shrink(global.slab_objects); > -} > - > static void i915_global_objects_exit(void) > { > kmem_cache_destroy(global.slab_objects); > } > > static struct i915_global_object global = { { > - .shrink = i915_global_objects_shrink, > .exit = i915_global_objects_exit, > } }; > > diff --git a/drivers/gpu/drm/i915/gt/intel_context.c > b/drivers/gpu/drm/i915/gt/intel_context.c > index bd63813c8a80..c1338441cc1d 100644 > --- a/drivers/gpu/drm/i915/gt/intel_context.c > +++ b/drivers/gpu/drm/i915/gt/intel_context.c > @@ -398,18 +398,12 @@ void intel_context_fini(struct intel_context *ce) > i915_active_fini(&ce->active); > } > > -static void i915_global_context_shrink(void) > -{ > - kmem_cache_shrink(global.slab_ce); > -} > - > static void i915_global_context_exit(void) > { > kmem_cache_destroy(global.slab_ce); > } > > static struct i915_global_context global = { { > - .shrink = i915_global_context_shrink, > .exit = i915_global_context_exit, > } }; > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c > b/drivers/gpu/drm/i915/gt/intel_gt_pm.c > index aef3084e8b16..d86825437516 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c > @@ -67,8 +67,6 @@ static int __gt_unpark(struct intel_wakeref *wf) > > GT_TRACE(gt, "\n"); > > - i915_globals_unpark(); > - > /* > * It seems that the DMC likes to transition between the DC states a > lot > * when there are no connected displays (no active power domains) > during > @@ -116,8 +114,6 @@ static int __gt_park(struct intel_wakeref *wf) > GEM_BUG_ON(!wakeref); > intel_display_power_put_async(i915, POWER_DOMAIN_GT_IRQ, wakeref); > > - i915_globals_park(); > - > return 0; > } > > diff --git a/drivers/gpu/drm/i915/i915_active.c > b/drivers/gpu/drm/i915/i915_active.c > index b1aa1c482c32..91723123ae9f 100644 > --- a/drivers/gpu/drm/i915/i915_active.c > +++ b/drivers/gpu/drm/i915/i915_a
Re: [Intel-gfx] [PATCH 6/6] drm/i915: Make the kmem slab for i915_buddy_block a global
On Wed, Jul 21, 2021 at 1:56 PM Daniel Vetter wrote: > > On Wed, Jul 21, 2021 at 05:25:41PM +0100, Matthew Auld wrote: > > On 21/07/2021 16:23, Jason Ekstrand wrote: > > > There's no reason that I can tell why this should be per-i915_buddy_mm > > > and doing so causes KMEM_CACHE to throw dmesg warnings because it tries > > > to create a debugfs entry with the name i915_buddy_block multiple times. > > > We could handle this by carefully giving each slab its own name but that > > > brings its own pain because then we have to store that string somewhere > > > and manage the lifetimes of the different slabs. The most likely > > > outcome would be a global atomic which we increment to get a new name or > > > something like that. > > > > > > The much easier solution is to use the i915_globals system like we do > > > for every other slab in i915. This ensures that we have exactly one of > > > them for each i915 driver load and it gets neatly created on module load > > > and destroyed on module unload. Using the globals system also means > > > that its now tied into the shrink handler so we can properly respond to > > > low-memory situations. > > > > > > Signed-off-by: Jason Ekstrand > > > Fixes: 88be9a0a06b7 ("drm/i915/ttm: add ttm_buddy_man") > > > Cc: Matthew Auld > > > Cc: Christian König > > > > It was intentionally ripped it out with the idea that we would be moving the > > buddy stuff into ttm, and so part of that was trying to get rid of the some > > of the i915 specifics, like this globals thing. > > > > Reviewed-by: Matthew Auld > > I just sent out a patch to put i915_globals on a diet, so maybe we can > hold this patch here a bit when there's other reasons for why this is > special? This is required to get rid of the dmesg warnings. > Or at least no make this use the i915_globals stuff and instead just link > up the init/exit function calls directly into Jason's new table, so that > we don't have a merge conflict here? I'm happy to deal with merge conflicts however they land. --Jason > -Daniel > > > > > > --- > > > drivers/gpu/drm/i915/i915_buddy.c | 44 ++--- > > > drivers/gpu/drm/i915/i915_buddy.h | 3 +- > > > drivers/gpu/drm/i915/i915_globals.c | 2 ++ > > > 3 files changed, 38 insertions(+), 11 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/i915/i915_buddy.c > > > b/drivers/gpu/drm/i915/i915_buddy.c > > > index 29dd7d0310c1f..911feedad4513 100644 > > > --- a/drivers/gpu/drm/i915/i915_buddy.c > > > +++ b/drivers/gpu/drm/i915/i915_buddy.c > > > @@ -8,8 +8,14 @@ > > > #include "i915_buddy.h" > > > #include "i915_gem.h" > > > +#include "i915_globals.h" > > > #include "i915_utils.h" > > > +static struct i915_global_buddy { > > > + struct i915_global base; > > > + struct kmem_cache *slab_blocks; > > > +} global; > > > + > > > static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_mm > > > *mm, > > > struct i915_buddy_block > > > *parent, > > > unsigned int order, > > > @@ -19,7 +25,7 @@ static struct i915_buddy_block *i915_block_alloc(struct > > > i915_buddy_mm *mm, > > > GEM_BUG_ON(order > I915_BUDDY_MAX_ORDER); > > > - block = kmem_cache_zalloc(mm->slab_blocks, GFP_KERNEL); > > > + block = kmem_cache_zalloc(global.slab_blocks, GFP_KERNEL); > > > if (!block) > > > return NULL; > > > @@ -34,7 +40,7 @@ static struct i915_buddy_block *i915_block_alloc(struct > > > i915_buddy_mm *mm, > > > static void i915_block_free(struct i915_buddy_mm *mm, > > > struct i915_buddy_block *block) > > > { > > > - kmem_cache_free(mm->slab_blocks, block); > > > + kmem_cache_free(global.slab_blocks, block); > > > } > > > static void mark_allocated(struct i915_buddy_block *block) > > > @@ -85,15 +91,11 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 > > > size, u64 chunk_size) > > > GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER); > > > - mm->slab_blocks = KMEM_CACHE(i915_buddy_block, SLAB_HWCACHE_ALIGN); > > > - if (!mm->slab_blocks) > > > - return -ENOMEM; > > > - > > > mm->free_list = kmalloc_array(mm->max_order + 1, > > > sizeof(struct list_head), > > > GFP_KERNEL); > > > if (!mm->free_list) > > > - goto out_destroy_slab; > > > + return -ENOMEM; > > > for (i = 0; i <= mm->max_order; ++i) > > > INIT_LIST_HEAD(&mm->free_list[i]); > > > @@ -145,8 +147,6 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 > > > size, u64 chunk_size) > > > kfree(mm->roots); > > > out_free_list: > > > kfree(mm->free_list); > > > -out_destroy_slab: > > > - kmem_cache_destroy(mm->slab_blocks); > > > return -ENOMEM; > > > } > > > @@ -161,7 +161,6 @@ void i915_buddy_fini(struct i915_buddy_mm *mm) > > > kfree(mm->roots); > > > kfree(mm->free_list); > > > - km
[PATCH 7/7] drm/i915/gem: Migrate to system at dma-buf attach time (v7)
From: Thomas Hellström Until we support p2p dma or as a complement to that, migrate data to system memory at dma-buf attach time if possible. v2: - Rebase on dynamic exporter. Update the igt_dmabuf_import_same_driver selftest to migrate if we are LMEM capable. v3: - Migrate also in the pin() callback. v4: - Migrate in attach v5: (jason) - Lock around the migration v6: (jason) - Move the can_migrate check outside the lock - Rework the selftests to test more migration conditions. In particular, SMEM, LMEM, and LMEM+SMEM are all checked. v7: (mauld) - Misc style nits Signed-off-by: Thomas Hellström Signed-off-by: Michael J. Ruhl Reported-by: kernel test robot Signed-off-by: Jason Ekstrand Reviewed-by: Jason Ekstrand --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 23 - .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 87 ++- 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 59dc56ae14d6b..afa34111de02e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -164,8 +164,29 @@ static int i915_gem_dmabuf_attach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) { struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf); + struct i915_gem_ww_ctx ww; + int err; + + if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM)) + return -EOPNOTSUPP; + + for_i915_gem_ww(&ww, err, true) { + err = i915_gem_object_lock(obj, &ww); + if (err) + continue; + + err = i915_gem_object_migrate(obj, &ww, INTEL_REGION_SMEM); + if (err) + continue; - return i915_gem_object_pin_pages_unlocked(obj); + err = i915_gem_object_wait_migration(obj, 0); + if (err) + continue; + + err = i915_gem_object_pin_pages(obj); + } + + return err; } static void i915_gem_dmabuf_detach(struct dma_buf *dmabuf, diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c index d4ce01e6ee854..ffae7df5e4d7d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c @@ -85,9 +85,63 @@ static int igt_dmabuf_import_self(void *arg) return err; } -static int igt_dmabuf_import_same_driver(void *arg) +static int igt_dmabuf_import_same_driver_lmem(void *arg) { struct drm_i915_private *i915 = arg; + struct intel_memory_region *lmem = i915->mm.regions[INTEL_REGION_LMEM]; + struct drm_i915_gem_object *obj; + struct drm_gem_object *import; + struct dma_buf *dmabuf; + int err; + + if (!lmem) + return 0; + + force_different_devices = true; + + obj = __i915_gem_object_create_user(i915, PAGE_SIZE, &lmem, 1); + if (IS_ERR(obj)) { + pr_err("__i915_gem_object_create_user failed with err=%ld\n", + PTR_ERR(dmabuf)); + err = PTR_ERR(obj); + goto out_ret; + } + + dmabuf = i915_gem_prime_export(&obj->base, 0); + if (IS_ERR(dmabuf)) { + pr_err("i915_gem_prime_export failed with err=%ld\n", + PTR_ERR(dmabuf)); + err = PTR_ERR(dmabuf); + goto out; + } + + /* +* We expect an import of an LMEM-only object to fail with +* -EOPNOTSUPP because it can't be migrated to SMEM. +*/ + import = i915_gem_prime_import(&i915->drm, dmabuf); + if (!IS_ERR(import)) { + drm_gem_object_put(import); + pr_err("i915_gem_prime_import succeeded when it shouldn't have\n"); + err = -EINVAL; + } else if (PTR_ERR(import) != -EOPNOTSUPP) { + pr_err("i915_gem_prime_import failed with the wrong err=%ld\n", + PTR_ERR(import)); + err = PTR_ERR(import); + } + + dma_buf_put(dmabuf); +out: + i915_gem_object_put(obj); +out_ret: + force_different_devices = false; + return err; +} + +static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915, +struct intel_memory_region **regions, +unsigned int num_regions) +{ struct drm_i915_gem_object *obj, *import_obj; struct drm_gem_object *import; struct dma_buf *dmabuf; @@ -97,8 +151,12 @@ static int igt_dmabuf_import_same_driver(void *arg) int err; force_different_devices = true; - obj = i915_gem_object_create_shmem(i915, PAGE_SIZE); + + obj = __i915_gem_object_create_user(i915, PAGE_SIZE, + regions, num_regi
[PATCH 6/7] drm/i915/gem: Correct the locking and pin pattern for dma-buf (v8)
From: Thomas Hellström If our exported dma-bufs are imported by another instance of our driver, that instance will typically have the imported dma-bufs locked during dma_buf_map_attachment(). But the exporter also locks the same reservation object in the map_dma_buf() callback, which leads to recursive locking. So taking the lock inside _pin_pages_unlocked() is incorrect. Additionally, the current pinning code path is contrary to the defined way that pinning should occur. Remove the explicit pin/unpin from the map/umap functions and move them to the attach/detach allowing correct locking to occur, and to match the static dma-buf drm_prime pattern. Add a live selftest to exercise both dynamic and non-dynamic exports. v2: - Extend the selftest with a fake dynamic importer. - Provide real pin and unpin callbacks to not abuse the interface. v3: (ruhl) - Remove the dynamic export support and move the pinning into the attach/detach path. v4: (ruhl) - Put pages does not need to assert on the dma-resv v5: (jason) - Lock around dma_buf_unmap_attachment() when emulating a dynamic importer in the subtests. - Use pin_pages_unlocked v6: (jason) - Use dma_buf_attach instead of dma_buf_attach_dynamic in the selftests v7: (mauld) - Use __i915_gem_object_get_pages (2 __underscores) instead of the 4 underscore version in the selftests v8: (mauld) - Drop the kernel doc from the static i915_gem_dmabuf_attach function - Add missing "err = PTR_ERR()" to a bunch of selftest error cases Reported-by: Michael J. Ruhl Signed-off-by: Thomas Hellström Signed-off-by: Michael J. Ruhl Signed-off-by: Jason Ekstrand Reviewed-by: Jason Ekstrand --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 37 -- .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 109 +- 2 files changed, 132 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 616c3a2f1baf0..59dc56ae14d6b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -12,6 +12,8 @@ #include "i915_gem_object.h" #include "i915_scatterlist.h" +I915_SELFTEST_DECLARE(static bool force_different_devices;) + static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf) { return to_intel_bo(buf->priv); @@ -25,15 +27,11 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme struct scatterlist *src, *dst; int ret, i; - ret = i915_gem_object_pin_pages_unlocked(obj); - if (ret) - goto err; - /* Copy sg so that we make an independent mapping */ st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); if (st == NULL) { ret = -ENOMEM; - goto err_unpin_pages; + goto err; } ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL); @@ -58,8 +56,6 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme sg_free_table(st); err_free: kfree(st); -err_unpin_pages: - i915_gem_object_unpin_pages(obj); err: return ERR_PTR(ret); } @@ -68,13 +64,9 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, struct sg_table *sg, enum dma_data_direction dir) { - struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf); - dma_unmap_sgtable(attachment->dev, sg, dir, DMA_ATTR_SKIP_CPU_SYNC); sg_free_table(sg); kfree(sg); - - i915_gem_object_unpin_pages(obj); } static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map) @@ -168,7 +160,25 @@ static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direct return err; } +static int i915_gem_dmabuf_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attach) +{ + struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf); + + return i915_gem_object_pin_pages_unlocked(obj); +} + +static void i915_gem_dmabuf_detach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attach) +{ + struct drm_i915_gem_object *obj = dma_buf_to_obj(dmabuf); + + i915_gem_object_unpin_pages(obj); +} + static const struct dma_buf_ops i915_dmabuf_ops = { + .attach = i915_gem_dmabuf_attach, + .detach = i915_gem_dmabuf_detach, .map_dma_buf = i915_gem_map_dma_buf, .unmap_dma_buf = i915_gem_unmap_dma_buf, .release = drm_gem_dmabuf_release, @@ -204,6 +214,8 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) struct sg_table *pages; unsigned int sg_page_sizes; + assert_object_held(obj); + pages = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL); if (IS_ERR(
[PATCH 5/7] drm/i915/gem/ttm: Respect the objection region in placement_from_obj
Whenever we had a user object (n_placements > 0), we were ignoring obj->mm.region and always putting obj->placements[0] as the requested region. For LMEM+SMEM objects, this was causing them to get shoved into LMEM on every i915_ttm_get_pages() even when SMEM was requested by, say, i915_gem_object_migrate(). Signed-off-by: Jason Ekstrand Cc: Thomas Hellström Cc: Matthew Auld Cc: Maarten Lankhorst --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index f253b11e9e367..b76bdd978a5cc 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -150,8 +150,7 @@ i915_ttm_placement_from_obj(const struct drm_i915_gem_object *obj, unsigned int i; placement->num_placement = 1; - i915_ttm_place_from_region(num_allowed ? obj->mm.placements[0] : - obj->mm.region, requested, flags); + i915_ttm_place_from_region(obj->mm.region, requested, flags); /* Cache this on object? */ placement->num_busy_placement = num_allowed; -- 2.31.1
[PATCH 4/7] drm/i915/gem: Unify user object creation (v3)
Instead of hand-rolling the same three calls in each function, pull them into an i915_gem_object_create_user helper. Apart from re-ordering of the placements array ENOMEM check, there should be no functional change. v2 (Matthew Auld): - Add the call to i915_gem_flush_free_objects() from i915_gem_dumb_create() in a separate patch - Move i915_gem_object_alloc() below the simple error checks v3 (Matthew Auld): - Add __ to i915_gem_object_create_user and kerneldoc which warns the caller that it's not validating anything. Signed-off-by: Jason Ekstrand Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_create.c | 119 ++--- drivers/gpu/drm/i915/gem/i915_gem_object.h | 4 + 2 files changed, 58 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c index adcce37c04b8d..23fee13a33844 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c @@ -11,13 +11,14 @@ #include "i915_trace.h" #include "i915_user_extensions.h" -static u32 object_max_page_size(struct drm_i915_gem_object *obj) +static u32 object_max_page_size(struct intel_memory_region **placements, + unsigned int n_placements) { u32 max_page_size = 0; int i; - for (i = 0; i < obj->mm.n_placements; i++) { - struct intel_memory_region *mr = obj->mm.placements[i]; + for (i = 0; i < n_placements; i++) { + struct intel_memory_region *mr = placements[i]; GEM_BUG_ON(!is_power_of_2(mr->min_page_size)); max_page_size = max_t(u32, max_page_size, mr->min_page_size); @@ -81,22 +82,46 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj, return 0; } -static int -i915_gem_setup(struct drm_i915_gem_object *obj, u64 size) +/** + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT + * @i915: i915 private + * @size: size of the buffer, in bytes + * @placements: possible placement regions, in priority order + * @n_placements: number of possible placement regions + * + * This function is exposed primarily for selftests and does very little + * error checking. It is assumed that the set of placement regions has + * already been verified to be valid. + */ +struct drm_i915_gem_object * +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size, + struct intel_memory_region **placements, + unsigned int n_placements) { - struct intel_memory_region *mr = obj->mm.placements[0]; + struct intel_memory_region *mr = placements[0]; + struct drm_i915_gem_object *obj; unsigned int flags; int ret; - size = round_up(size, object_max_page_size(obj)); + i915_gem_flush_free_objects(i915); + + size = round_up(size, object_max_page_size(placements, n_placements)); if (size == 0) - return -EINVAL; + return ERR_PTR(-EINVAL); /* For most of the ABI (e.g. mmap) we think in system pages */ GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE)); if (i915_gem_object_size_2big(size)) - return -E2BIG; + return ERR_PTR(-E2BIG); + + obj = i915_gem_object_alloc(); + if (!obj) + return ERR_PTR(-ENOMEM); + + ret = object_set_placements(obj, placements, n_placements); + if (ret) + goto object_free; /* * I915_BO_ALLOC_USER will make sure the object is cleared before @@ -106,12 +131,18 @@ i915_gem_setup(struct drm_i915_gem_object *obj, u64 size) ret = mr->ops->init_object(mr, obj, size, 0, flags); if (ret) - return ret; + goto object_free; GEM_BUG_ON(size != obj->base.size); trace_i915_gem_object_create(obj); - return 0; + return obj; + +object_free: + if (obj->mm.n_placements > 1) + kfree(obj->mm.placements); + i915_gem_object_free(obj); + return ERR_PTR(ret); } int @@ -124,7 +155,6 @@ i915_gem_dumb_create(struct drm_file *file, enum intel_memory_type mem_type; int cpp = DIV_ROUND_UP(args->bpp, 8); u32 format; - int ret; switch (cpp) { case 1: @@ -151,32 +181,19 @@ i915_gem_dumb_create(struct drm_file *file, if (args->pitch < args->width) return -EINVAL; - i915_gem_flush_free_objects(i915); - args->size = mul_u32_u32(args->pitch, args->height); mem_type = INTEL_MEMORY_SYSTEM; if (HAS_LMEM(to_i915(dev))) mem_type = INTEL_MEMORY_LOCAL; - obj = i915_gem_object_alloc(); - if (!obj) - return -ENOMEM; - mr = intel_memory_region_by_type(to_i915(dev), mem_type); - ret = object_set_placements(obj, &mr, 1); - if (ret) - goto object_f
[PATCH 3/7] drm/i915/gem: Call i915_gem_flush_free_objects() in i915_gem_dumb_create()
This doesn't really fix anything serious since the chances of a client creating and destroying a mass of dumb BOs is pretty low. However, it is called by the other two create IOCTLs to garbage collect old objects. Call it here too for consistency. Signed-off-by: Jason Ekstrand Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_create.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c index aa687b10dcd45..adcce37c04b8d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c @@ -151,6 +151,8 @@ i915_gem_dumb_create(struct drm_file *file, if (args->pitch < args->width) return -EINVAL; + i915_gem_flush_free_objects(i915); + args->size = mul_u32_u32(args->pitch, args->height); mem_type = INTEL_MEMORY_SYSTEM; -- 2.31.1
[PATCH 2/7] drm/i915/gem: Refactor placement setup for i915_gem_object_create* (v2)
Since we don't allow changing the set of regions after creation, we can make ext_set_placements() build up the region set directly in the create_ext and assign it to the object later. This is similar to what we did for contexts with the proto-context only simpler because there's no funny object shuffling. This will be used in the next patch to allow us to de-duplicate a bunch of code. Also, since we know the maximum number of regions up-front, we can use a fixed-size temporary array for the regions. This simplifies memory management a bit for this new delayed approach. v2 (Matthew Auld): - Get rid of MAX_N_PLACEMENTS - Drop kfree(placements) from set_placements() v3 (Matthew Auld): - Properly set ext_data->n_placements Signed-off-by: Jason Ekstrand Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_create.c | 82 -- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c index 51f92e4b1a69d..aa687b10dcd45 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c @@ -27,10 +27,13 @@ static u32 object_max_page_size(struct drm_i915_gem_object *obj) return max_page_size; } -static void object_set_placements(struct drm_i915_gem_object *obj, - struct intel_memory_region **placements, - unsigned int n_placements) +static int object_set_placements(struct drm_i915_gem_object *obj, +struct intel_memory_region **placements, +unsigned int n_placements) { + struct intel_memory_region **arr; + unsigned int i; + GEM_BUG_ON(!n_placements); /* @@ -44,9 +47,20 @@ static void object_set_placements(struct drm_i915_gem_object *obj, obj->mm.placements = &i915->mm.regions[mr->id]; obj->mm.n_placements = 1; } else { - obj->mm.placements = placements; + arr = kmalloc_array(n_placements, + sizeof(struct intel_memory_region *), + GFP_KERNEL); + if (!arr) + return -ENOMEM; + + for (i = 0; i < n_placements; i++) + arr[i] = placements[i]; + + obj->mm.placements = arr; obj->mm.n_placements = n_placements; } + + return 0; } static int i915_gem_publish(struct drm_i915_gem_object *obj, @@ -148,7 +162,9 @@ i915_gem_dumb_create(struct drm_file *file, return -ENOMEM; mr = intel_memory_region_by_type(to_i915(dev), mem_type); - object_set_placements(obj, &mr, 1); + ret = object_set_placements(obj, &mr, 1); + if (ret) + goto object_free; ret = i915_gem_setup(obj, args->size); if (ret) @@ -184,7 +200,9 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, return -ENOMEM; mr = intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM); - object_set_placements(obj, &mr, 1); + ret = object_set_placements(obj, &mr, 1); + if (ret) + goto object_free; ret = i915_gem_setup(obj, args->size); if (ret) @@ -199,7 +217,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, struct create_ext { struct drm_i915_private *i915; - struct drm_i915_gem_object *vanilla_object; + struct intel_memory_region *placements[INTEL_REGION_UNKNOWN]; + unsigned int n_placements; }; static void repr_placements(char *buf, size_t size, @@ -230,8 +249,7 @@ static int set_placements(struct drm_i915_gem_create_ext_memory_regions *args, struct drm_i915_private *i915 = ext_data->i915; struct drm_i915_gem_memory_class_instance __user *uregions = u64_to_user_ptr(args->regions); - struct drm_i915_gem_object *obj = ext_data->vanilla_object; - struct intel_memory_region **placements; + struct intel_memory_region *placements[INTEL_REGION_UNKNOWN]; u32 mask; int i, ret = 0; @@ -245,6 +263,8 @@ static int set_placements(struct drm_i915_gem_create_ext_memory_regions *args, ret = -EINVAL; } + BUILD_BUG_ON(ARRAY_SIZE(i915->mm.regions) != ARRAY_SIZE(placements)); + BUILD_BUG_ON(ARRAY_SIZE(ext_data->placements) != ARRAY_SIZE(placements)); if (args->num_regions > ARRAY_SIZE(i915->mm.regions)) { drm_dbg(&i915->drm, "num_regions is too large\n"); ret = -EINVAL; @@ -253,21 +273,13 @@ static int set_placements(struct drm_i915_gem_create_ext_memory_regions *args, if (ret) return ret; - placements = kmalloc_array(args->num_regions, - sizeof(struct intel_memory_region *), -
[PATCH 1/7] drm/i915/gem: Check object_can_migrate from object_migrate
We don't roll them together entirely because there are still a couple cases where we want a separate can_migrate check. For instance, the display code checks that you can migrate a buffer to LMEM before it accepts it in fb_create. The dma-buf import code also uses it to do an early check and return a different error code if someone tries to attach a LMEM-only dma-buf to another driver. However, no one actually wants to call object_migrate when can_migrate has failed. The stated intention is for self-tests but none of those actually take advantage of this unsafe migration. Signed-off-by: Jason Ekstrand Cc: Daniel Vetter Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/gem/i915_gem_object.c| 13 ++--- .../gpu/drm/i915/gem/selftests/i915_gem_migrate.c | 15 --- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 9da7b288b7ede..f2244ae09a613 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -584,12 +584,6 @@ bool i915_gem_object_can_migrate(struct drm_i915_gem_object *obj, * completed yet, and to accomplish that, i915_gem_object_wait_migration() * must be called. * - * This function is a bit more permissive than i915_gem_object_can_migrate() - * to allow for migrating objects where the caller knows exactly what is - * happening. For example within selftests. More specifically this - * function allows migrating I915_BO_ALLOC_USER objects to regions - * that are not in the list of allowable regions. - * * Note: the @ww parameter is not used yet, but included to make sure * callers put some effort into obtaining a valid ww ctx if one is * available. @@ -616,11 +610,8 @@ int i915_gem_object_migrate(struct drm_i915_gem_object *obj, if (obj->mm.region == mr) return 0; - if (!i915_gem_object_evictable(obj)) - return -EBUSY; - - if (!obj->ops->migrate) - return -EOPNOTSUPP; + if (!i915_gem_object_can_migrate(obj, id)) + return -EINVAL; return obj->ops->migrate(obj, mr); } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c index 0b7144d2991ca..28a700f08b49a 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c @@ -61,11 +61,6 @@ static int igt_create_migrate(struct intel_gt *gt, enum intel_region_id src, if (err) continue; - if (!i915_gem_object_can_migrate(obj, dst)) { - err = -EINVAL; - continue; - } - err = i915_gem_object_migrate(obj, &ww, dst); if (err) continue; @@ -114,11 +109,6 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, return err; if (i915_gem_object_is_lmem(obj)) { - if (!i915_gem_object_can_migrate(obj, INTEL_REGION_SMEM)) { - pr_err("object can't migrate to smem.\n"); - return -EINVAL; - } - err = i915_gem_object_migrate(obj, ww, INTEL_REGION_SMEM); if (err) { pr_err("Object failed migration to smem\n"); @@ -137,11 +127,6 @@ static int lmem_pages_migrate_one(struct i915_gem_ww_ctx *ww, } } else { - if (!i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM)) { - pr_err("object can't migrate to lmem.\n"); - return -EINVAL; - } - err = i915_gem_object_migrate(obj, ww, INTEL_REGION_LMEM); if (err) { pr_err("Object failed migration to lmem\n"); -- 2.31.1
[PATCH 0/7] drm/i915: Migrate memory to SMEM when imported cross-device (v8)
This patch series fixes an issue with discrete graphics on Intel where we allowed dma-buf import while leaving the object in local memory. This breaks down pretty badly if the import happened on a different physical device. v7: - Drop "drm/i915/gem/ttm: Place new BOs in the requested region" - Add a new "drm/i915/gem: Call i915_gem_flush_free_objects() in i915_gem_dumb_create()" - Misc. review feedback from Matthew Auld v8: - Misc. review feedback from Matthew Auld Jason Ekstrand (5): drm/i915/gem: Check object_can_migrate from object_migrate drm/i915/gem: Refactor placement setup for i915_gem_object_create* (v2) drm/i915/gem: Call i915_gem_flush_free_objects() in i915_gem_dumb_create() drm/i915/gem: Unify user object creation (v3) drm/i915/gem/ttm: Respect the objection region in placement_from_obj Thomas Hellström (2): drm/i915/gem: Correct the locking and pin pattern for dma-buf (v8) drm/i915/gem: Migrate to system at dma-buf attach time (v7) drivers/gpu/drm/i915/gem/i915_gem_create.c| 177 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c| 58 -- drivers/gpu/drm/i915/gem/i915_gem_object.c| 13 +- drivers/gpu/drm/i915/gem/i915_gem_object.h| 4 + drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 3 +- .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 190 +- .../drm/i915/gem/selftests/i915_gem_migrate.c | 15 -- 7 files changed, 330 insertions(+), 130 deletions(-) -- 2.31.1
Re: [PATCH 5/7] drm/i915/gem/ttm: Respect the objection region in placement_from_obj
On Mon, Jul 19, 2021 at 8:35 AM Matthew Auld wrote: > > On Fri, 16 Jul 2021 at 20:49, Jason Ekstrand wrote: > > > > On Fri, Jul 16, 2021 at 1:45 PM Matthew Auld > > wrote: > > > > > > On Fri, 16 Jul 2021 at 18:39, Jason Ekstrand wrote: > > > > > > > > On Fri, Jul 16, 2021 at 11:00 AM Matthew Auld > > > > wrote: > > > > > > > > > > On Fri, 16 Jul 2021 at 16:52, Matthew Auld > > > > > wrote: > > > > > > > > > > > > On Fri, 16 Jul 2021 at 15:10, Jason Ekstrand > > > > > > wrote: > > > > > > > > > > > > > > On Fri, Jul 16, 2021 at 8:54 AM Matthew Auld > > > > > > > wrote: > > > > > > > > > > > > > > > > On Thu, 15 Jul 2021 at 23:39, Jason Ekstrand > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > Whenever we had a user object (n_placements > 0), we were > > > > > > > > > ignoring > > > > > > > > > obj->mm.region and always putting obj->placements[0] as the > > > > > > > > > requested > > > > > > > > > region. For LMEM+SMEM objects, this was causing them to get > > > > > > > > > shoved into > > > > > > > > > LMEM on every i915_ttm_get_pages() even when SMEM was > > > > > > > > > requested by, say, > > > > > > > > > i915_gem_object_migrate(). > > > > > > > > > > > > > > > > i915_ttm_migrate calls i915_ttm_place_from_region() directly > > > > > > > > with the > > > > > > > > requested region, so there shouldn't be an issue with migration > > > > > > > > right? > > > > > > > > Do you have some more details? > > > > > > > > > > > > > > With i915_ttm_migrate directly, no. But, in the last patch in the > > > > > > > series, we're trying to migrate LMEM+SMEM buffers into SMEM on > > > > > > > attach() and pin it there. This blows up in a very unexpected > > > > > > > (IMO) > > > > > > > way. The flow goes something like this: > > > > > > > > > > > > > > - Client attempts a dma-buf import from another device > > > > > > > - In attach() we call i915_gem_object_migrate() which calls > > > > > > > i915_ttm_migrate() which migrates as requested. > > > > > > > - Once the migration is complete, we call > > > > > > > i915_gem_object_pin_pages() > > > > > > > which calls i915_ttm_get_pages() which depends on > > > > > > > i915_ttm_placement_from_obj() and so migrates it right back to > > > > > > > LMEM. > > > > > > > > > > > > The mm.pages must be NULL here, otherwise it would just increment > > > > > > the > > > > > > pages_pin_count? > > > > > > > > Given that the test is using the four_underscores version, it > > > > doesn't have that check. However, this executes after we've done the > > > > dma-buf import which pinned pages. So we should definitely have > > > > pages. > > > > > > We shouldn't call four_underscores() if we might already have > > > pages though. Under non-TTM that would leak the pages, and in TTM we > > > might hit the WARN_ON(mm->pages) in __i915_ttm_get_pages(), if for > > > example nothing was moved. I take it we can't just call pin_pages()? > > > Four scary underscores usually means "don't call this in normal code". > > > > I've switched the four_underscores call to a __two_underscores in > > the selftests and it had no effect, good or bad. But, still, probably > > better to call that one. > > > > > > > > > > > > > > > > > > > > Maybe the problem here is actually that our TTM code isn't > > > > > > > respecting > > > > > > > obj->mm.pages_pin_count? > > > > > > > > > > > > I think if the resource is moved, we always nuke the mm.pages after > > > > > > being notified of the move. Also TTM is also not allowed to move > > > > > > pinned buffers. > > > > > > > > > > > > I guess if we are evicted/swapped, so assuming we are not holding > > > > > > the > > > > > > object lock, and it's not pinned, the future call to get_pages() > > > > > > will > > > > > > see mm.pages = NULL, even though the ttm_resource is still there, > > > > > > and > > > > > > because we prioritise the placements[0], instead of mm.region we end > > > > > > up moving it for no good reason. But in your case you are holding > > > > > > the > > > > > > lock, or it's pinned? Also is this just with the selftest, or > > > > > > something real? > > > > > > > > > > Or at least in the selftest I see i915_gem_object_get_pages() > > > > > which doesn't even consider the mm.pages AFAIK. > > > > > > > > The bogus migration is happening as part of the > > > > __i915_gem_object_get_pages() (2 __underscores) call in > > > > i915_gem_dmabuf_attach (see last patch). That code is attempting to > > > > migrate the BO to SMEM and then pin it there using the obvious calls > > > > to do so. However, in the pin_pages call, it gets implicitly migrated > > > > back to LMEM thanks to i915_ttm_get_pages(). Why is _get_pages() > > > > migrating things at all? > > > > > > Not sure yet, but __two_underscores() checks if > > > i915_gem_object_has_pages() before actually calling into > > > i915_ttm_get_pages(), so the mm.pages would have to be NULL here for > > > some reason, so best guess is something to do
Re: [PATCH] backlight: pwm_bl: Avoid backlight flicker if backlight control GPIO is input
On 7/21/21 9:01 PM, Marek Vasut wrote: [...] @@ -486,18 +500,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) goto err_alloc; } - /* - * If the GPIO is not known to be already configured as output, that - * is, if gpiod_get_direction returns either 1 or -EINVAL, change the - * direction to output and set the GPIO as active. - * Do not force the GPIO to active when it was already output as it - * could cause backlight flickering or we would enable the backlight too - * early. Leave the decision of the initial backlight state for later. - */ - if (pb->enable_gpio && - gpiod_get_direction(pb->enable_gpio) != 0) - gpiod_direction_output(pb->enable_gpio, 1); pwm_backlight_initial_power_state() is still called after pwm_apply_state() in pwm_backlight_probe(), so that might still be too late, no ? The initial pwm_apply_state() is essentially a nop or, perhaps, a sanity check if you prefer to think if it that way. It can change the PWM period in some (non-DT) cases but only if the PWM is not already running... and the change of period should not start it running. All right, let me give this a try. ACK, for this case I have here, this works too. Can you submit a proper patch, including my AB/TB and I think also the Fixes tag ?
Re: [PATCH 3/4] drm/i915/userptr: Probe existence of backing struct pages upon creation
Thanks! Series is: Acked-by: Kenneth Graunke https://gitlab.freedesktop.org/kwg/mesa/-/commits/iris-userptr-probe is an untested Mesa branch that makes use of the new probe uAPI. On Thursday, July 15, 2021 3:15:35 AM PDT Matthew Auld wrote: > From: Chris Wilson > > Jason Ekstrand requested a more efficient method than userptr+set-domain > to determine if the userptr object was backed by a complete set of pages > upon creation. To be more efficient than simply populating the userptr > using get_user_pages() (as done by the call to set-domain or execbuf), > we can walk the tree of vm_area_struct and check for gaps or vma not > backed by struct page (VM_PFNMAP). The question is how to handle > VM_MIXEDMAP which may be either struct page or pfn backed... > > With discrete are going to drop support for set_domain(), so offering a > way to probe the pages, without having to resort to dummy batches has > been requested. > > v2: > - add new query param for the PROPBE flag, so userspace can easily > check if the kernel supports it(Jason). > - use mmap_read_{lock, unlock}. > - add some kernel-doc. > > Testcase: igt/gem_userptr_blits/probe > Signed-off-by: Chris Wilson > Signed-off-by: Matthew Auld > Cc: Thomas Hellström > Cc: Maarten Lankhorst > Cc: Tvrtko Ursulin > Cc: Jordan Justen > Cc: Kenneth Graunke > Cc: Jason Ekstrand > Cc: Daniel Vetter > Cc: Ramalingam C > --- > drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 40 - > drivers/gpu/drm/i915/i915_getparam.c| 3 ++ > include/uapi/drm/i915_drm.h | 18 ++ > 3 files changed, 60 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > index 56edfeff8c02..fd6880328596 100644 > --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > @@ -422,6 +422,33 @@ static const struct drm_i915_gem_object_ops > i915_gem_userptr_ops = { > > #endif > > +static int > +probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len) > +{ > + const unsigned long end = addr + len; > + struct vm_area_struct *vma; > + int ret = -EFAULT; > + > + mmap_read_lock(mm); > + for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { > + if (vma->vm_start > addr) > + break; > + > + if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) > + break; > + > + if (vma->vm_end >= end) { > + ret = 0; > + break; > + } > + > + addr = vma->vm_end; > + } > + mmap_read_unlock(mm); > + > + return ret; > +} > + > /* > * Creates a new mm object that wraps some normal memory from the process > * context - user memory. > @@ -477,7 +504,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, > } > > if (args->flags & ~(I915_USERPTR_READ_ONLY | > - I915_USERPTR_UNSYNCHRONIZED)) > + I915_USERPTR_UNSYNCHRONIZED | > + I915_USERPTR_PROBE)) > return -EINVAL; > > if (i915_gem_object_size_2big(args->user_size)) > @@ -504,6 +532,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev, > return -ENODEV; > } > > + if (args->flags & I915_USERPTR_PROBE) { > + /* > + * Check that the range pointed to represents real struct > + * pages and not iomappings (at this moment in time!) > + */ > + ret = probe_range(current->mm, args->user_ptr, args->user_size); > + if (ret) > + return ret; > + } > + > #ifdef CONFIG_MMU_NOTIFIER > obj = i915_gem_object_alloc(); > if (obj == NULL) > diff --git a/drivers/gpu/drm/i915/i915_getparam.c > b/drivers/gpu/drm/i915/i915_getparam.c > index 24e18219eb50..d6d2e1a10d14 100644 > --- a/drivers/gpu/drm/i915/i915_getparam.c > +++ b/drivers/gpu/drm/i915/i915_getparam.c > @@ -163,6 +163,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void > *data, > case I915_PARAM_PERF_REVISION: > value = i915_perf_ioctl_version(); > break; > + case I915_PARAM_HAS_USERPTR_PROBE: > + value = true; > + break; > default: > DRM_DEBUG("Unknown parameter %d\n", param->param); > return -EINVAL; > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index e20eeeca7a1c..2e4112bf4d38 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -674,6 +674,9 @@ typedef struct drm_i915_irq_wait { > */ > #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55 > > +/* Query if the kernel supports the I915_USERPTR_PROBE flag. */ > +#define I915_PARAM_HAS_USERPTR_PROBE 56 > + > /* Must be kept compact -- no holes and well documented */ > > typedef struct drm_i915_getparam
Re: [PATCH 3/4] drm/i915/userptr: Probe existence of backing struct pages upon creation
Thanks for this! Series is: Acked-by: Kenneth Graunke https://gitlab.freedesktop.org/kwg/mesa/-/commits/iris-userptr-probe is an untested branch that uses the new probe API in Mesa. On Thursday, July 15, 2021 3:15:35 AM PDT Matthew Auld wrote: > From: Chris Wilson > > Jason Ekstrand requested a more efficient method than userptr+set-domain > to determine if the userptr object was backed by a complete set of pages > upon creation. To be more efficient than simply populating the userptr > using get_user_pages() (as done by the call to set-domain or execbuf), > we can walk the tree of vm_area_struct and check for gaps or vma not > backed by struct page (VM_PFNMAP). The question is how to handle > VM_MIXEDMAP which may be either struct page or pfn backed... > > With discrete are going to drop support for set_domain(), so offering a > way to probe the pages, without having to resort to dummy batches has > been requested. > > v2: > - add new query param for the PROPBE flag, so userspace can easily > check if the kernel supports it(Jason). > - use mmap_read_{lock, unlock}. > - add some kernel-doc. > > Testcase: igt/gem_userptr_blits/probe > Signed-off-by: Chris Wilson > Signed-off-by: Matthew Auld > Cc: Thomas Hellström > Cc: Maarten Lankhorst > Cc: Tvrtko Ursulin > Cc: Jordan Justen > Cc: Kenneth Graunke > Cc: Jason Ekstrand > Cc: Daniel Vetter > Cc: Ramalingam C > --- > drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 40 - > drivers/gpu/drm/i915/i915_getparam.c| 3 ++ > include/uapi/drm/i915_drm.h | 18 ++ > 3 files changed, 60 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > index 56edfeff8c02..fd6880328596 100644 > --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c > @@ -422,6 +422,33 @@ static const struct drm_i915_gem_object_ops > i915_gem_userptr_ops = { > > #endif > > +static int > +probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len) > +{ > + const unsigned long end = addr + len; > + struct vm_area_struct *vma; > + int ret = -EFAULT; > + > + mmap_read_lock(mm); > + for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { > + if (vma->vm_start > addr) > + break; > + > + if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) > + break; > + > + if (vma->vm_end >= end) { > + ret = 0; > + break; > + } > + > + addr = vma->vm_end; > + } > + mmap_read_unlock(mm); > + > + return ret; > +} > + > /* > * Creates a new mm object that wraps some normal memory from the process > * context - user memory. > @@ -477,7 +504,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, > } > > if (args->flags & ~(I915_USERPTR_READ_ONLY | > - I915_USERPTR_UNSYNCHRONIZED)) > + I915_USERPTR_UNSYNCHRONIZED | > + I915_USERPTR_PROBE)) > return -EINVAL; > > if (i915_gem_object_size_2big(args->user_size)) > @@ -504,6 +532,16 @@ i915_gem_userptr_ioctl(struct drm_device *dev, > return -ENODEV; > } > > + if (args->flags & I915_USERPTR_PROBE) { > + /* > + * Check that the range pointed to represents real struct > + * pages and not iomappings (at this moment in time!) > + */ > + ret = probe_range(current->mm, args->user_ptr, args->user_size); > + if (ret) > + return ret; > + } > + > #ifdef CONFIG_MMU_NOTIFIER > obj = i915_gem_object_alloc(); > if (obj == NULL) > diff --git a/drivers/gpu/drm/i915/i915_getparam.c > b/drivers/gpu/drm/i915/i915_getparam.c > index 24e18219eb50..d6d2e1a10d14 100644 > --- a/drivers/gpu/drm/i915/i915_getparam.c > +++ b/drivers/gpu/drm/i915/i915_getparam.c > @@ -163,6 +163,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void > *data, > case I915_PARAM_PERF_REVISION: > value = i915_perf_ioctl_version(); > break; > + case I915_PARAM_HAS_USERPTR_PROBE: > + value = true; > + break; > default: > DRM_DEBUG("Unknown parameter %d\n", param->param); > return -EINVAL; > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index e20eeeca7a1c..2e4112bf4d38 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -674,6 +674,9 @@ typedef struct drm_i915_irq_wait { > */ > #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55 > > +/* Query if the kernel supports the I915_USERPTR_PROBE flag. */ > +#define I915_PARAM_HAS_USERPTR_PROBE 56 > + > /* Must be kept compact -- no holes and well documented */ > > typedef struct drm_i915_getpa
Re: [Linaro-mm-sig] [PATCH] drm/msm: Add fence->wait() op
On Wed, Jul 21, 2021 at 09:34:43AM -0700, Rob Clark wrote: > On Wed, Jul 21, 2021 at 12:59 AM Daniel Vetter wrote: > > > > On Wed, Jul 21, 2021 at 12:32 AM Rob Clark wrote: > > > > > > On Tue, Jul 20, 2021 at 1:55 PM Daniel Vetter wrote: > > > > > > > > On Tue, Jul 20, 2021 at 8:26 PM Rob Clark wrote: > > > > > > > > > > On Tue, Jul 20, 2021 at 11:03 AM Christian König > > > > > wrote: > > > > > > > > > > > > Hi Rob, > > > > > > > > > > > > Am 20.07.21 um 17:07 schrieb Rob Clark: > > > > > > > From: Rob Clark > > > > > > > > > > > > > > Somehow we had neither ->wait() nor dma_fence_signal() calls, and > > > > > > > no > > > > > > > one noticed. Oops. > > > > > > > > > > > > > > > > > > I'm not sure if that is a good idea. > > > > > > > > > > > > The dma_fence->wait() callback is pretty much deprecated and should > > > > > > not > > > > > > be used any more. > > > > > > > > > > > > What exactly do you need that for? > > > > > > > > > > Well, the alternative is to track the set of fences which have > > > > > signalling enabled, and then figure out which ones to signal, which > > > > > seems like a lot more work, vs just re-purposing the wait > > > > > implementation we already have for non-dma_fence cases ;-) > > > > > > > > > > Why is the ->wait() callback (pretty much) deprecated? > > > > > > > > Because if you need it that means for your driver dma_fence_add_cb is > > > > broken, which means a _lot_ of things don't work. Like dma_buf poll > > > > (compositors have patches to start using that), and I think > > > > drm/scheduler also becomes rather unhappy. > > > > > > I'm starting to page back in how this works.. fence cb's aren't broken > > > (which is also why dma_fence_wait() was not completely broken), > > > because in retire_submits() we call > > > dma_fence_is_signaled(submit->hw_fence). > > > > > > But the reason that the custom wait function cleans up a tiny bit of > > > jank is that the wait_queue_head_t gets signaled earlier, before we > > > start iterating the submits and doing all that retire_submit() stuff > > > (unpin/unref bo's, etc). I suppose I could just split things up to > > > call dma_fence_signal() earlier, and *then* do the retire_submits() > > > stuff. > > > > Yeah reducing the latency there sounds like a good idea. > > -Daniel > > > > Hmm, no, turns out that isn't the problem.. or, well, it is probably a > good idea to call drm_fence_signal() earlier. But it seems like > waking up from wait_event_* is faster than wake_up_state(wait->task, > TASK_NORMAL). I suppose the wake_up_state() approach still needs for > the scheduler to get around to schedule the runnable task. > > So for now, I'm going back to my own wait function (plus earlier > drm_fence_signal()) > > Before removing dma_fence_opps::wait(), I guess we want to re-think > dma_fence_default_wait().. but I think that would require a > dma_fence_context base class (rather than just a raw integer). Uh that's not great ... can't we fix this instead of papering over it in drivers? Aside from maybe different wakeup flags it all is supposed to work exactly the same underneath, and whether using a wait queue or not really shouldn't matter. -Daniel > > BR, > -R > > > > > > > BR, > > > -R > > > > > > > It essentially exists only for old drivers where ->enable_signalling > > > > is unreliable and we paper over that with a retry loop in ->wait and > > > > pray no one notices that it's too butchered. The proper fix is to have > > > > a driver thread to guarantee that ->enable_signalling works reliable, > > > > so you don't need a ->wait. > > > > > > > > Can you type up a kerneldoc patch for dma_fence_ops->wait to hammer > > > > this in please? > > > > -Daniel > > > > > > > > > > > > > > BR, > > > > > -R > > > > > > > > > > > Regards, > > > > > > Christian. > > > > > > > > > > > > > > > > > > > > Note that this removes the !timeout case, which has not been used > > > > > > > in > > > > > > > a long time. > > > > > > > > > > > > > > > > > > > > > > > > > > Signed-off-by: Rob Clark > > > > > > > --- > > > > > > > drivers/gpu/drm/msm/msm_fence.c | 59 > > > > > > > +++-- > > > > > > > 1 file changed, 34 insertions(+), 25 deletions(-) > > > > > > > > > > > > > > diff --git a/drivers/gpu/drm/msm/msm_fence.c > > > > > > > b/drivers/gpu/drm/msm/msm_fence.c > > > > > > > index cd59a5918038..8ee96b90ded6 100644 > > > > > > > --- a/drivers/gpu/drm/msm/msm_fence.c > > > > > > > +++ b/drivers/gpu/drm/msm/msm_fence.c > > > > > > > @@ -38,11 +38,10 @@ static inline bool fence_completed(struct > > > > > > > msm_fence_context *fctx, uint32_t fenc > > > > > > > return (int32_t)(fctx->completed_fence - fence) >= 0; > > > > > > > } > > > > > > > > > > > > > > -/* legacy path for WAIT_FENCE ioctl: */ > > > > > > > -int msm_wait_fence(struct msm_fence_context *fctx, uint32_t > > > > > > > fence, > > > > > > > - ktime_t *timeout, bool interruptible) > > > > > > > +static signed long wa
Re: [PATCH] backlight: pwm_bl: Avoid backlight flicker if backlight control GPIO is input
On 7/21/21 6:43 PM, Daniel Thompson wrote: On Wed, Jul 21, 2021 at 05:09:57PM +0200, Marek Vasut wrote: On 7/21/21 12:49 PM, Daniel Thompson wrote: However, on the basis of making things less fragile, I think the underlying problem here is the assumption that it is safe to modify enable_gpio before the driver has imposed state upon the PWM (this assumption has always been made and, in addition to systems where the BL has a phandle will also risks flicker problems on systems where power_pwm_on_delay is not zero). It is safe to modify the GPIO into defined state, but that defined state is not always out/enabled, that defined state depends on the hardware. It is only safe to do this once we know what the initial value should be and I'm not sure that value can comes exclusively from reading the pin. I agree, it is far from perfect, but so is the current code. Agreed. Current handling of enable pin isn't right. However, see below regarding the floating backlight enable pin. This patch does not change the assumption that we can configure the GPIO before we modify the PWM state. This means it won't fix the problem for cases there the pin is HiZ by default but whose GPIOD_ASIS state is neither input nor output. That is correct, for pin that is floating, we lost. But then I would argue that if your backlight-enable GPIO is floating, the hardware is buggy, I would expect some pull resistor to keep the backlight off on power on on that GPIO. I didn't say that the pin was floating. I said that the pin was in a HiZ state meaning it could still be subject to pull up/down. However there are cases, such as when the regulator is off, where I think it is entirely legitimate for the enable pin to be floating. The current driver does the wrong thing here if the pin is set as input since if the regulator is off the initial enable_gpio value should be 0. Oh, right, that's a valid point. So if the pin is input, we can basically toss a coin. I don't think it is quite as bad as that: if the PWM and regulator are enabled then it is not okay for this pin to be floating. So then we would have to check the regulator and pwm state, however Linux driver for those can reinit both the regulator and pwm block, so we are growing more and more heuristics. [...] I think a reasonably elegant approach can be reached by making pwm_backlight_initial_power_state() responsible for ensuring enable_gpio matches the observed hardware state (taking into account both the pin state and the regulator). I think this will fix both your flicker concerns whilst permitting the legitimate cases for a floating pin. Something like: I think we are getting closer, but there is extra problem to this. diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index e48fded3e414..8d8959a70e44 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -409,6 +409,33 @@ static bool pwm_backlight_is_linear(struct platform_pwm_backlight_data *data) static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb) { struct device_node *node = pb->dev->of_node; + bool active = true; + + /* +* If the enable GPIO is present, observable (either as input +* or output) and off then the backlight is not currently active. +* */ + if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0) + active = false; This will fail on iMX GPIO controller, where if the GPIO is output, you can read its state, but by default that state is what you wrote into the GPIO output value register, not what is the actual value on the pin (i.e. consider you have a strong pull resistor that overpowers the driver). To have a GPIO which is output and sample the actual pin value, you have to tweak the pinmux and enable the SION bit, then you get the actual value. But that is specific to the iMX GPIO controller/pinmux. You're describing a situation where we own a GPIO output pin and the value we believe we are driving into the pin is not being achieved due to some additional factor. E.g. disabled PWM or regulator. Do we need to care about that? It sounds like the backlight driver won't work properly in this case since whatever value we set the enable_gpio then it will stay at the same value. Possibly. [...] @@ -486,18 +500,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) goto err_alloc; } - /* -* If the GPIO is not known to be already configured as output, that -* is, if gpiod_get_direction returns either 1 or -EINVAL, change the -* direction to output and set the GPIO as active. -* Do not force the GPIO to active when it was already output as it -* could cause backlight flickering or we would enable the backlight too -* early. Leave the decision of the initial backlight state for later. -*/ - if (pb->enable_gp
Re: [PATCH v5 09/15] drm/i915/pxp: Implement PXP irq handler
On Thu, Jul 15, 2021 at 09:10:28PM -0700, Daniele Ceraolo Spurio wrote: > From: "Huang, Sean Z" > > The HW will generate a teardown interrupt when session termination is > required, which requires i915 to submit a terminating batch. Once the HW > is done with the termination it will generate another interrupt, at > which point it is safe to re-create the session. > > Since the termination and re-creation flow is something we want to > trigger from the driver as well, use a common work function that can be > called both from the irq handler and from the driver set-up flows, which > has the addded benefit of allowing us to skip any extra locks because > the work itself serializes the operations. > > v2: use struct completion instead of bool (Chris) > v3: drop locks, clean up functions and improve comments (Chris), > move to common work function. > v4: improve comments, simplify wait logic (Rodrigo) > v5: unconditionally set interrupts, I didn't find this... this looks the same as v4 > rename state_attacked var (Rodrigo) thanks > > Signed-off-by: Huang, Sean Z > Signed-off-by: Daniele Ceraolo Spurio > Cc: Chris Wilson > Cc: Rodrigo Vivi > Reviewed-by: Rodrigo Vivi #v4 anyway, this patch looks good to me... Reviewed-by: Rodrigo Vivi > --- > drivers/gpu/drm/i915/Makefile| 1 + > drivers/gpu/drm/i915/gt/intel_gt_irq.c | 7 ++ > drivers/gpu/drm/i915/i915_reg.h | 1 + > drivers/gpu/drm/i915/pxp/intel_pxp.c | 66 +++-- > drivers/gpu/drm/i915/pxp/intel_pxp.h | 8 ++ > drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 99 > drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 32 +++ > drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++- > drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 5 +- > drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 8 +- > drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 18 > 11 files changed, 283 insertions(+), 16 deletions(-) > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 44d3a2bcb64c..1714089a10f0 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -279,6 +279,7 @@ i915-y += i915_perf.o > i915-$(CONFIG_DRM_I915_PXP) += \ > pxp/intel_pxp.o \ > pxp/intel_pxp_cmd.o \ > + pxp/intel_pxp_irq.o \ > pxp/intel_pxp_session.o \ > pxp/intel_pxp_tee.o > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c > b/drivers/gpu/drm/i915/gt/intel_gt_irq.c > index c13462274fe8..96f0e9172a09 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c > @@ -13,6 +13,7 @@ > #include "intel_lrc_reg.h" > #include "intel_uncore.h" > #include "intel_rps.h" > +#include "pxp/intel_pxp_irq.h" > > static void guc_irq_handler(struct intel_guc *guc, u16 iir) > { > @@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 > instance, > if (instance == OTHER_GTPM_INSTANCE) > return gen11_rps_irq_handler(>->rps, iir); > > + if (instance == OTHER_KCR_INSTANCE) > + return intel_pxp_irq_handler(>->pxp, iir); > + > WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n", > instance, iir); > } > @@ -190,6 +194,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt) > intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK, ~0); > intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0); > intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK, ~0); > + > + intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0); > + intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK, ~0); > } > > void gen11_gt_irq_postinstall(struct intel_gt *gt) > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 943fe485c662..2c583f2d410d 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -8051,6 +8051,7 @@ enum { > /* irq instances for OTHER_CLASS */ > #define OTHER_GUC_INSTANCE 0 > #define OTHER_GTPM_INSTANCE 1 > +#define OTHER_KCR_INSTANCE 4 > > #define GEN11_INTR_IDENTITY_REG(x) _MMIO(0x190060 + ((x) * 4)) > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c > b/drivers/gpu/drm/i915/pxp/intel_pxp.c > index 26176d43a02d..b0c7edc10cc3 100644 > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c > @@ -2,7 +2,9 @@ > /* > * Copyright(c) 2020 Intel Corporation. > */ > +#include > #include "intel_pxp.h" > +#include "intel_pxp_irq.h" > #include "intel_pxp_session.h" > #include "intel_pxp_tee.h" > #include "gt/intel_context.h" > @@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp) > > mutex_init(&pxp->tee_mutex); > > + /* > + * we'll use the completion to check if there is a termination p
Re: [Intel-gfx] [PATCH 6/6] drm/i915: Make the kmem slab for i915_buddy_block a global
On Wed, Jul 21, 2021 at 05:25:41PM +0100, Matthew Auld wrote: > On 21/07/2021 16:23, Jason Ekstrand wrote: > > There's no reason that I can tell why this should be per-i915_buddy_mm > > and doing so causes KMEM_CACHE to throw dmesg warnings because it tries > > to create a debugfs entry with the name i915_buddy_block multiple times. > > We could handle this by carefully giving each slab its own name but that > > brings its own pain because then we have to store that string somewhere > > and manage the lifetimes of the different slabs. The most likely > > outcome would be a global atomic which we increment to get a new name or > > something like that. > > > > The much easier solution is to use the i915_globals system like we do > > for every other slab in i915. This ensures that we have exactly one of > > them for each i915 driver load and it gets neatly created on module load > > and destroyed on module unload. Using the globals system also means > > that its now tied into the shrink handler so we can properly respond to > > low-memory situations. > > > > Signed-off-by: Jason Ekstrand > > Fixes: 88be9a0a06b7 ("drm/i915/ttm: add ttm_buddy_man") > > Cc: Matthew Auld > > Cc: Christian König > > It was intentionally ripped it out with the idea that we would be moving the > buddy stuff into ttm, and so part of that was trying to get rid of the some > of the i915 specifics, like this globals thing. > > Reviewed-by: Matthew Auld I just sent out a patch to put i915_globals on a diet, so maybe we can hold this patch here a bit when there's other reasons for why this is special? Or at least no make this use the i915_globals stuff and instead just link up the init/exit function calls directly into Jason's new table, so that we don't have a merge conflict here? -Daniel > > > --- > > drivers/gpu/drm/i915/i915_buddy.c | 44 ++--- > > drivers/gpu/drm/i915/i915_buddy.h | 3 +- > > drivers/gpu/drm/i915/i915_globals.c | 2 ++ > > 3 files changed, 38 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_buddy.c > > b/drivers/gpu/drm/i915/i915_buddy.c > > index 29dd7d0310c1f..911feedad4513 100644 > > --- a/drivers/gpu/drm/i915/i915_buddy.c > > +++ b/drivers/gpu/drm/i915/i915_buddy.c > > @@ -8,8 +8,14 @@ > > #include "i915_buddy.h" > > #include "i915_gem.h" > > +#include "i915_globals.h" > > #include "i915_utils.h" > > +static struct i915_global_buddy { > > + struct i915_global base; > > + struct kmem_cache *slab_blocks; > > +} global; > > + > > static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_mm *mm, > > struct i915_buddy_block > > *parent, > > unsigned int order, > > @@ -19,7 +25,7 @@ static struct i915_buddy_block *i915_block_alloc(struct > > i915_buddy_mm *mm, > > GEM_BUG_ON(order > I915_BUDDY_MAX_ORDER); > > - block = kmem_cache_zalloc(mm->slab_blocks, GFP_KERNEL); > > + block = kmem_cache_zalloc(global.slab_blocks, GFP_KERNEL); > > if (!block) > > return NULL; > > @@ -34,7 +40,7 @@ static struct i915_buddy_block *i915_block_alloc(struct > > i915_buddy_mm *mm, > > static void i915_block_free(struct i915_buddy_mm *mm, > > struct i915_buddy_block *block) > > { > > - kmem_cache_free(mm->slab_blocks, block); > > + kmem_cache_free(global.slab_blocks, block); > > } > > static void mark_allocated(struct i915_buddy_block *block) > > @@ -85,15 +91,11 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, > > u64 chunk_size) > > GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER); > > - mm->slab_blocks = KMEM_CACHE(i915_buddy_block, SLAB_HWCACHE_ALIGN); > > - if (!mm->slab_blocks) > > - return -ENOMEM; > > - > > mm->free_list = kmalloc_array(mm->max_order + 1, > > sizeof(struct list_head), > > GFP_KERNEL); > > if (!mm->free_list) > > - goto out_destroy_slab; > > + return -ENOMEM; > > for (i = 0; i <= mm->max_order; ++i) > > INIT_LIST_HEAD(&mm->free_list[i]); > > @@ -145,8 +147,6 @@ int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, > > u64 chunk_size) > > kfree(mm->roots); > > out_free_list: > > kfree(mm->free_list); > > -out_destroy_slab: > > - kmem_cache_destroy(mm->slab_blocks); > > return -ENOMEM; > > } > > @@ -161,7 +161,6 @@ void i915_buddy_fini(struct i915_buddy_mm *mm) > > kfree(mm->roots); > > kfree(mm->free_list); > > - kmem_cache_destroy(mm->slab_blocks); > > } > > static int split_block(struct i915_buddy_mm *mm, > > @@ -410,3 +409,28 @@ int i915_buddy_alloc_range(struct i915_buddy_mm *mm, > > #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) > > #include "selftests/i915_buddy.c" > > #endif > > + > > +static void i915_global_buddy_shrink(void) > > +{ > > + kmem_cache_shrink(global.slab_blocks); > > +}
Re: [PATCH v5 03/15] drm/i915/pxp: define PXP device flag and kconfig
On Thu, Jul 15, 2021 at 09:10:22PM -0700, Daniele Ceraolo Spurio wrote: > Ahead of the PXP implementation, define the relevant define flag and > kconfig option. > > v2: flip kconfig default to N. Some machines have IFWIs that do not > support PXP, so we need it to be an opt-in until we add support to query > the caps from the mei device. ack > > Signed-off-by: Daniele Ceraolo Spurio > Reviewed-by: Rodrigo Vivi #v1 rvb still valid > --- > drivers/gpu/drm/i915/Kconfig | 11 +++ > drivers/gpu/drm/i915/i915_drv.h | 4 > drivers/gpu/drm/i915/intel_device_info.h | 1 + > 3 files changed, 16 insertions(+) > > diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig > index f960f5d7664e..5987c3d5d9fb 100644 > --- a/drivers/gpu/drm/i915/Kconfig > +++ b/drivers/gpu/drm/i915/Kconfig > @@ -131,6 +131,17 @@ config DRM_I915_GVT_KVMGT > Choose this option if you want to enable KVMGT support for > Intel GVT-g. > > +config DRM_I915_PXP > + bool "Enable Intel PXP support for Intel Gen12+ platform" > + depends on DRM_I915 > + depends on INTEL_MEI && INTEL_MEI_PXP > + default n > + help > + PXP (Protected Xe Path) is an i915 component, available on GEN12+ > + GPUs, that helps to establish the hardware protected session and > + manage the status of the alive software session, as well as its life > + cycle. > + > menu "drm/i915 Debugging" > depends on DRM_I915 > depends on EXPERT > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index c4747f4407ef..772f9f0b6ddb 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1752,6 +1752,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, > > #define HAS_VRR(i915)(GRAPHICS_VER(i915) >= 12) > > +#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \ > +INTEL_INFO(dev_priv)->has_pxp) && \ > +VDBOX_MASK(&dev_priv->gt) > + > /* Only valid when HAS_DISPLAY() is true */ > #define INTEL_DISPLAY_ENABLED(dev_priv) \ > (drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), > !(dev_priv)->params.disable_display) > diff --git a/drivers/gpu/drm/i915/intel_device_info.h > b/drivers/gpu/drm/i915/intel_device_info.h > index bd83004c78b6..8e9597008b8a 100644 > --- a/drivers/gpu/drm/i915/intel_device_info.h > +++ b/drivers/gpu/drm/i915/intel_device_info.h > @@ -129,6 +129,7 @@ enum intel_ppgtt_type { > func(has_logical_ring_elsq); \ > func(has_master_unit_irq); \ > func(has_pooled_eu); \ > + func(has_pxp); \ > func(has_rc6); \ > func(has_rc6p); \ > func(has_rps); \ > -- > 2.32.0 >
Re: [PATCH v5 07/15] drm/i915/pxp: Create the arbitrary session after boot
On Thu, Jul 15, 2021 at 09:10:26PM -0700, Daniele Ceraolo Spurio wrote: > From: "Huang, Sean Z" > > Create the arbitrary session, with the fixed session id 0xf, after > system boot, for the case that application allocates the protected > buffer without establishing any protection session. Because the > hardware requires at least one alive session for protected buffer > creation. This arbitrary session will need to be re-created after > teardown or power event because hardware encryption key won't be > valid after such cases. > > The session ID is exposed as part of the uapi so it can be used as part > of userspace commands. > > v2: use gt->uncore->rpm (Chris) > v3: s/arb_is_in_play/arb_is_valid (Chris), move set-up to the new > init_hw function > v4: move interface defs to separate header, set arb_is valid to false > on fini (Rodrigo) > v5: handle async component binding > > Signed-off-by: Huang, Sean Z > Signed-off-by: Daniele Ceraolo Spurio > Cc: Chris Wilson > Cc: Rodrigo Vivi > Reviewed-by: Rodrigo Vivi #v4 > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/pxp/intel_pxp.c | 7 ++ > drivers/gpu/drm/i915/pxp/intel_pxp.h | 5 ++ > drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 74 > drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 15 > drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 87 +++ > drivers/gpu/drm/i915/pxp/intel_pxp_tee.h | 3 + > .../drm/i915/pxp/intel_pxp_tee_interface.h| 37 > drivers/gpu/drm/i915/pxp/intel_pxp_types.h| 12 +++ > include/uapi/drm/i915_drm.h | 3 + > 10 files changed, 244 insertions(+) > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.c > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.h > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 05eb6b7753cc..946b56cff9cf 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -278,6 +278,7 @@ i915-y += i915_perf.o > # Protected execution platform (PXP) support > i915-$(CONFIG_DRM_I915_PXP) += \ > pxp/intel_pxp.o \ > + pxp/intel_pxp_session.o \ > pxp/intel_pxp_tee.o > > # Post-mortem debug and GPU hang state capture > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c > b/drivers/gpu/drm/i915/pxp/intel_pxp.c > index 66a98feb33ab..e1370f323126 100644 > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c > @@ -3,6 +3,7 @@ > * Copyright(c) 2020 Intel Corporation. > */ > #include "intel_pxp.h" > +#include "intel_pxp_session.h" > #include "intel_pxp_tee.h" > #include "gt/intel_context.h" > #include "i915_drv.h" > @@ -65,6 +66,8 @@ void intel_pxp_init(struct intel_pxp *pxp) > if (!HAS_PXP(gt->i915)) > return; > > + mutex_init(&pxp->tee_mutex); > + > ret = create_vcs_context(pxp); > if (ret) > return; > @@ -86,6 +89,8 @@ void intel_pxp_fini(struct intel_pxp *pxp) > if (!intel_pxp_is_enabled(pxp)) > return; > > + pxp->arb_is_valid = false; > + > intel_pxp_tee_component_fini(pxp); > > destroy_vcs_context(pxp); > @@ -94,6 +99,8 @@ void intel_pxp_fini(struct intel_pxp *pxp) > void intel_pxp_init_hw(struct intel_pxp *pxp) > { > kcr_pxp_enable(pxp_to_gt(pxp)); > + > + intel_pxp_create_arb_session(pxp); > } > > void intel_pxp_fini_hw(struct intel_pxp *pxp) > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h > b/drivers/gpu/drm/i915/pxp/intel_pxp.h > index 5427c3b28aa9..8eeb65af78b1 100644 > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h > @@ -19,6 +19,11 @@ static inline bool intel_pxp_is_enabled(const struct > intel_pxp *pxp) > return pxp->ce; > } > > +static inline bool intel_pxp_is_active(const struct intel_pxp *pxp) > +{ > + return pxp->arb_is_valid; > +} > + > #ifdef CONFIG_DRM_I915_PXP > void intel_pxp_init(struct intel_pxp *pxp); > void intel_pxp_fini(struct intel_pxp *pxp); > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c > b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c > new file mode 100644 > index ..3331868f354c > --- /dev/null > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c > @@ -0,0 +1,74 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright(c) 2020, Intel Corporation. All rights reserved. > + */ > + > +#include "drm/i915_drm.h" > +#include "i915_drv.h" > + > +#include "intel_pxp.h" > +#include "intel_pxp_session.h" > +#include "intel_pxp_tee.h" > +#include "intel_pxp_types.h" > + > +#define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define > */ > + > +#define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */ > + > +static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id) > +{ > + struct intel_gt *
Re: [PATCH v5 05/15] drm/i915/pxp: Implement funcs to create the TEE channel
On Thu, Jul 15, 2021 at 09:10:24PM -0700, Daniele Ceraolo Spurio wrote: > From: "Huang, Sean Z" > > Implement the funcs to create the TEE channel, so kernel can > send the TEE commands directly to TEE for creating the arbitrary > (default) session. > > v2: fix locking, don't pollute dev_priv (Chris) > > v3: wait for mei PXP component to be bound. > > v4: drop the wait, as the component might be bound after i915 load > completes. We'll instead check when sending a tee message. ack > > Signed-off-by: Huang, Sean Z > Signed-off-by: Daniele Ceraolo Spurio > Cc: Chris Wilson > Reviewed-by: Rodrigo Vivi #v2 rvb still valid > --- > drivers/gpu/drm/i915/Makefile | 3 +- > drivers/gpu/drm/i915/pxp/intel_pxp.c | 13 > drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 77 ++ > drivers/gpu/drm/i915/pxp/intel_pxp_tee.h | 14 > drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 3 + > 5 files changed, 109 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index fe054918837d..05eb6b7753cc 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -277,7 +277,8 @@ i915-y += i915_perf.o > > # Protected execution platform (PXP) support > i915-$(CONFIG_DRM_I915_PXP) += \ > - pxp/intel_pxp.o > + pxp/intel_pxp.o \ > + pxp/intel_pxp_tee.o > > # Post-mortem debug and GPU hang state capture > i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c > b/drivers/gpu/drm/i915/pxp/intel_pxp.c > index 7b2053902146..400deaea2d8a 100644 > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c > @@ -3,6 +3,7 @@ > * Copyright(c) 2020 Intel Corporation. > */ > #include "intel_pxp.h" > +#include "intel_pxp_tee.h" > #include "gt/intel_context.h" > #include "i915_drv.h" > > @@ -50,7 +51,16 @@ void intel_pxp_init(struct intel_pxp *pxp) > if (ret) > return; > > + ret = intel_pxp_tee_component_init(pxp); > + if (ret) > + goto out_context; > + > drm_info(>->i915->drm, "Protected Xe Path (PXP) protected content > support initialized\n"); > + > + return; > + > +out_context: > + destroy_vcs_context(pxp); > } > > void intel_pxp_fini(struct intel_pxp *pxp) > @@ -58,5 +68,8 @@ void intel_pxp_fini(struct intel_pxp *pxp) > if (!intel_pxp_is_enabled(pxp)) > return; > > + intel_pxp_tee_component_fini(pxp); > + > destroy_vcs_context(pxp); > + > } > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > new file mode 100644 > index ..21916ec0f6ff > --- /dev/null > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c > @@ -0,0 +1,77 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright(c) 2020 Intel Corporation. > + */ > + > +#include > +#include "drm/i915_pxp_tee_interface.h" > +#include "drm/i915_component.h" > +#include "i915_drv.h" > +#include "intel_pxp.h" > +#include "intel_pxp_tee.h" > + > +static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev) > +{ > + return &kdev_to_i915(i915_kdev)->gt.pxp; > +} > + > +/** > + * i915_pxp_tee_component_bind - bind function to pass the function pointers > to pxp_tee > + * @i915_kdev: pointer to i915 kernel device > + * @tee_kdev: pointer to tee kernel device > + * @data: pointer to pxp_tee_master containing the function pointers > + * > + * This bind function is called during the system boot or resume from system > sleep. > + * > + * Return: return 0 if successful. > + */ > +static int i915_pxp_tee_component_bind(struct device *i915_kdev, > +struct device *tee_kdev, void *data) > +{ > + struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev); > + > + pxp->pxp_component = data; > + pxp->pxp_component->tee_dev = tee_kdev; > + > + return 0; > +} > + > +static void i915_pxp_tee_component_unbind(struct device *i915_kdev, > + struct device *tee_kdev, void *data) > +{ > + struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev); > + > + pxp->pxp_component = NULL; > +} > + > +static const struct component_ops i915_pxp_tee_component_ops = { > + .bind = i915_pxp_tee_component_bind, > + .unbind = i915_pxp_tee_component_unbind, > +}; > + > +int intel_pxp_tee_component_init(struct intel_pxp *pxp) > +{ > + int ret; > + struct intel_gt *gt = pxp_to_gt(pxp); > + struct drm_i915_private *i915 = gt->i915; > + > + ret = component_add_typed(i915->drm.dev, &i915_pxp_tee_component_ops, > + I915_COMPONENT_PXP); > + if (ret < 0) { > + drm_err(&i915->drm, "Failed to add PXP component (%d)\n", ret); > + return ret; > +
Re: [PATCH] backlight: pwm_bl: Avoid backlight flicker if backlight control GPIO is input
On 7/21/21 6:12 PM, Daniel Thompson wrote: On Wed, Jul 21, 2021 at 05:09:57PM +0200, Marek Vasut wrote: On 7/21/21 12:49 PM, Daniel Thompson wrote: I'm not sure that's correct, we can simply say that any new uses of the pwm-backlight should specify the initial GPIO configuration, and for the legacy ones, use whatever is in the code now. I'm not 100% against the idea... however if we still have to get the code to read state from the hardware right for legacy cases that means we have to do the same work but with fewer people testing it. We can do something like this: if (of_property_read_bool(np, "enable-active-high")) gpiod_direction_output(pb->enable_gpio, 1); else if (of_property_read_bool(np, "enable-active-low")) gpiod_direction_output(pb->enable_gpio, 0); else { WARN_ON_ONCE("Fix your DT"); // or some such notification ... legacy code path ... } Note that I picked the same DT prop names as drivers/gpio/gpiolib-of.c of_gpio_flags_quirks() uses, because we are headed into similar mess here I'm afraid. I don't quite understand what you mean here. We are using gpiolib so for us there is no concept of active-high or active-low. The only concept for us is whether enable_gpio is asserted or not. It would look the same -- just substitute in "enable-on-boot" and "disable-on-boot" DT property. What the DT property would be describing is purely whether the bootloader left the backlight on or off. Rather, it would simply control what is the default state of the backlight enable GPIO (enabled/disabled). This sails very close to the edge of what is in-scope for DT (at least it does it we can read the inherited state directly from the hardware). The problem with reading it out of hardware is that the hardware might be in undefined state and expects Linux to define that state, so that does not always work. Hence my initial suggestion to add a DT property to define the state up front, instead of using these fragile heuristics. What it also means decisions about the DT bindings are more about whether, if the backlight is lit up, the bootloader should also disclose what it thinks it has established as the PWM duty cycle as well. Please also consider the case where bootloader configures total minimum of the hardware to start Linux as soon as possible, i.e. it puts Linux in DRAM and jumps to Linux. Overall I have fairly grave concerns that this simply moves fragility into the bootloader rather then reducing it. Wait a minute, I think we disconnected somewhere. I would rather prefer to remove the fragility and bootloader dependency altogether, exactly to avoid depending on the state the bootloader left the hardware in.
Re: [Intel-gfx] [PATCH 4/4] drm/i915/gt: nuke gen6_hw_id
On Wed, Jul 21, 2021 at 10:25:59AM +0100, Tvrtko Ursulin wrote: On 21/07/2021 00:20, Lucas De Marchi wrote: This is only used by GRAPHICS_VER == 6 and GRAPHICS_VER == 7. All other recent platforms do not depend on this field, so it doesn't make much sense to keep it generic like that. Instead, just do a mapping from engine class to HW ID in the single place that is needed. Signed-off-by: Lucas De Marchi --- drivers/gpu/drm/i915/gt/intel_engine_cs.c| 6 -- drivers/gpu/drm/i915/gt/intel_engine_types.h | 8 drivers/gpu/drm/i915/i915_reg.h | 4 +++- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 508221de411c..0a04e8d90e9e 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -42,7 +42,6 @@ #define MAX_MMIO_BASES 3 struct engine_info { - u8 gen6_hw_id; u8 class; u8 instance; /* mmio bases table *must* be sorted in reverse graphics_ver order */ @@ -54,7 +53,6 @@ struct engine_info { static const struct engine_info intel_engines[] = { [RCS0] = { - .gen6_hw_id = RCS0_HW, .class = RENDER_CLASS, .instance = 0, .mmio_bases = { @@ -62,7 +60,6 @@ static const struct engine_info intel_engines[] = { }, }, [BCS0] = { - .gen6_hw_id = BCS0_HW, .class = COPY_ENGINE_CLASS, .instance = 0, .mmio_bases = { @@ -70,7 +67,6 @@ static const struct engine_info intel_engines[] = { }, }, [VCS0] = { - .gen6_hw_id = VCS0_HW, .class = VIDEO_DECODE_CLASS, .instance = 0, .mmio_bases = { @@ -102,7 +98,6 @@ static const struct engine_info intel_engines[] = { }, }, [VECS0] = { - .gen6_hw_id = VECS0_HW, .class = VIDEO_ENHANCEMENT_CLASS, .instance = 0, .mmio_bases = { @@ -290,7 +285,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id) engine->i915 = i915; engine->gt = gt; engine->uncore = gt->uncore; - engine->gen6_hw_id = info->gen6_hw_id; guc_class = engine_class_to_guc_class(info->class); engine->guc_id = MAKE_GUC_ID(guc_class, info->instance); engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases); diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h index 266422d8d1b1..64330bfb7641 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -28,13 +28,6 @@ #include "intel_wakeref.h" #include "intel_workarounds_types.h" -/* Legacy HW Engine ID */ - -#define RCS0_HW0 -#define VCS0_HW1 -#define BCS0_HW2 -#define VECS0_HW 3 - /* Gen11+ HW Engine class + instance */ #define RENDER_CLASS 0 #define VIDEO_DECODE_CLASS 1 @@ -268,7 +261,6 @@ struct intel_engine_cs { intel_engine_mask_t mask; - u8 gen6_hw_id; u8 class; u8 instance; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8750ffce9d61..d91386f4828e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2572,7 +2572,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define ARB_MODE_BWGTLB_DISABLE (1 << 9) #define ARB_MODE_SWIZZLE_BDW (1 << 1) #define RENDER_HWS_PGA_GEN7_MMIO(0x04080) -#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * (engine)->gen6_hw_id) + +#define _GEN6_ENGINE_CLASS_TO_ID(class) _PICK((class), 0, 1, 3, 2) +#define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100 * _GEN6_ENGINE_CLASS_TO_ID((engine)->class)) Makes sense to me. Maybe HW_ID and HW_CLASS in the macro name? Not sure. I can do that... I think I avoided it because it makes the macro very big. Anyway, this should be called in just one place, so it doesn't matter much... I can add it. Only open I have is why the "Gen11+ HW Engine class + instance" comment and now we would tie that, allegedly Gen11 concept, with Gen6-7. Care to do some digging? Not sure. This comes from 3d7b3039741d ("drm/i915: Move engine IDs out of i915_reg.h") that I reviewed :-o Cc'ing Daniele. I don't see "class" as a Gen11+ thing. Is it just that those numbers started to make sense for gen11? Since a) we are using the class even for GRAPHICS_VER < 11 b) the legacy HW IDs shouldn't be used anywhere else anymore we could 1) move the legacy defines back to i915_reg.h 2) use them in the macro above (IMO would slightly improve the readability of that _PICK() call) 3) Remove the "Gen11+" comment in the _CLASS macros to avoid misunderstandings Thoughts? thanks Lucas De Marchi